diff --git a/SOURCES/opensc-0.16.0-cac-alt.patch b/SOURCES/opensc-0.16.0-cac-alt.patch new file mode 100644 index 0000000..fccdbf9 --- /dev/null +++ b/SOURCES/opensc-0.16.0-cac-alt.patch @@ -0,0 +1,204 @@ +From 6dc118e1c3b89c50cda1998de1d62fa6fa666e60 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Fri, 3 Nov 2017 10:55:35 +0100 +Subject: [PATCH 1/3] 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 82f5c7869..bc0a754a5 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 68c52640a3eff078243fd2db627cf2d12fdd37de Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Mon, 6 Nov 2017 12:37:40 +0100 +Subject: [PATCH 2/3] 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 bc0a754a5..178150d35 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 b647b0537..b610eacc7 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 fd463a9b4..ff87a2345 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); diff --git a/SOURCES/opensc-0.16.0-coolkey-labels.patch b/SOURCES/opensc-0.16.0-coolkey-labels.patch new file mode 100644 index 0000000..81c9450 --- /dev/null +++ b/SOURCES/opensc-0.16.0-coolkey-labels.patch @@ -0,0 +1,68 @@ +From a4b6b9630eb2ee684bbf1560a93b3075c7eb58ab Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Tue, 4 Jul 2017 14:25:50 +0200 +Subject: [PATCH] [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 5064a0f4f..a5f457acd 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); + } + + diff --git a/SOURCES/opensc-0.16.0-infinite-loop.patch b/SOURCES/opensc-0.16.0-infinite-loop.patch new file mode 100644 index 0000000..732314d --- /dev/null +++ b/SOURCES/opensc-0.16.0-infinite-loop.patch @@ -0,0 +1,62 @@ +From 645f678af24fc1e0f1559e0384f57f8fd35836b4 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Fri, 21 Jul 2017 11:30:47 +0200 +Subject: [PATCH 1/4] cac: Make the retransmitted APDU valid by restoring the + resplen + +--- + 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 ed15ba0a8..47f9aaf0c 100644 +--- a/src/libopensc/card-cac.c ++++ b/src/libopensc/card-cac.c +@@ -1106,6 +1106,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 a57407a5257b24edf313a4839c523a19cd8b0dc5 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Fri, 21 Jul 2017 13:09:14 +0200 +Subject: [PATCH 2/4] cac: Check SWs for all the APDUs and report the errors to + underlying layers + +--- + src/libopensc/card-cac.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c +index 47f9aaf0c..f3b64a33d 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 "); +diff -up OpenSC-777e2a3751e3f6d53f056c98e9e20e42af674fb1/src/libopensc/card-cac.c.old OpenSC-777e2a3751e3f6d53f056c98e9e20e42af674fb1/src/libopensc/card-cac.c +--- OpenSC-777e2a3751e3f6d53f056c98e9e20e42af674fb1/src/libopensc/card-cac.c.old 2017-12-19 10:39:08.662925868 +0100 ++++ OpenSC-777e2a3751e3f6d53f056c98e9e20e42af674fb1/src/libopensc/card-cac.c 2017-12-19 10:39:58.665293224 +0100 +@@ -450,6 +450,10 @@ static int cac_read_file(sc_card_t *card + if (r < 0) { + goto fail; + } ++ if (len == 0) { ++ r = SC_ERROR_FILE_NOT_FOUND; ++ goto fail; ++ } + } + *out_len = size; + *out_buf = out; diff --git a/SOURCES/opensc-0.16.0-labels-from-dn.patch b/SOURCES/opensc-0.16.0-labels-from-dn.patch new file mode 100644 index 0000000..e0ed69d --- /dev/null +++ b/SOURCES/opensc-0.16.0-labels-from-dn.patch @@ -0,0 +1,137 @@ +From 066fdce95a3a58e312f52c4e14536b4b3a4f5e26 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Tue, 9 May 2017 16:46:16 +0200 +Subject: [PATCH 1/3] If the underlying PKCS#15 structure does not provide + label for a certificate, try to use DN from the certificate. + +--- + src/libopensc/libopensc.exports | 1 + + src/pkcs11/framework-pkcs15.c | 31 +++++++++++++++++++++++++++++++ + 2 files changed, 32 insertions(+) + +diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports +index 18f80374f..36cf57023 100644 +--- a/src/libopensc/libopensc.exports ++++ b/src/libopensc/libopensc.exports +@@ -208,6 +208,7 @@ sc_pkcs15_free_prkey_info + sc_pkcs15_free_pubkey + sc_pkcs15_free_pubkey_info + sc_pkcs15_get_application_by_type ++sc_pkcs15_get_name_from_dn + sc_pkcs15_get_object_guid + sc_pkcs15_get_object_id + sc_pkcs15_get_objects +diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c +index 42c509356..f9063c8cc 100644 +--- a/src/pkcs11/framework-pkcs15.c ++++ b/src/pkcs11/framework-pkcs15.c +@@ -553,6 +553,30 @@ public_key_created(struct pkcs15_fw_data *fw_data, const struct sc_pkcs15_id *id + return SC_ERROR_OBJECT_NOT_FOUND; + } + ++static void ++pkcs15_cert_extract_label(struct pkcs15_cert_object *cert) ++{ ++ if (!cert || !cert->cert_p15obj || !cert->cert_data) ++ return; ++ ++ sc_log(context, "pkcs15_cert_extract_label() called. Current label: %s", cert->cert_p15obj->label); ++ ++ /* if we didn't get a label, set one based on the CN */ ++ if (*cert->cert_p15obj->label == '\0') { /* can't be NULL -- static array */ ++ static const struct sc_object_id cn_oid = {{ 2, 5, 4, 3, -1 }}; ++ u8 *cn_name = NULL; ++ size_t cn_len = 0; ++ int rv = sc_pkcs15_get_name_from_dn(context, ++ cert->cert_data->subject, cert->cert_data->subject_len, ++ &cn_oid, &cn_name, &cn_len); ++ sc_log(context, "pkcs15_cert_extract_label(): Name from DN is %s", cn_name); ++ if (rv == SC_SUCCESS) { ++ memcpy(cert->cert_p15obj->label, cn_name, cn_len); ++ cert->cert_p15obj->label[cn_len] = '\0'; ++ } ++ free(cn_name); ++ } ++} + + static int + __pkcs15_create_cert_object(struct pkcs15_fw_data *fw_data, struct sc_pkcs15_object *cert, +@@ -606,6 +627,9 @@ __pkcs15_create_cert_object(struct pkcs15_fw_data *fw_data, struct sc_pkcs15_obj + obj2->pub_genfrom = object; + object->cert_pubkey = obj2; + ++ /* Find missing labels for certificate */ ++ pkcs15_cert_extract_label(object); ++ + if (cert_object != NULL) + *cert_object = (struct pkcs15_any_object *) object; + +@@ -877,6 +901,9 @@ check_cert_data_read(struct pkcs15_fw_data *fw_data, struct pkcs15_cert_object * + if (!obj2->pub_data) + rv = sc_pkcs15_pubkey_from_cert(context, &cert->cert_data->data, &obj2->pub_data); + ++ /* Find missing labels for certificate */ ++ pkcs15_cert_extract_label(cert); ++ + /* now that we have the cert and pub key, lets see if we can bind anything else */ + pkcs15_bind_related_objects(fw_data); + +@@ -3165,6 +3192,10 @@ pkcs15_cert_get_attribute(struct sc_pkcs11_session *session, void *object, CK_AT + *(CK_BBOOL*)attr->pValue = FALSE; + break; + case CKA_LABEL: ++ if (check_cert_data_read(fw_data, cert) != 0) { ++ attr->ulValueLen = 0; ++ return CKR_OK; ++ } + len = strnlen(cert->cert_p15obj->label, sizeof cert->cert_p15obj->label); + check_attribute_buffer(attr, len); + memcpy(attr->pValue, cert->cert_p15obj->label, len); + +From 4d8b75c1f0a901d661ed00b29175e2fdaee940ca Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Fri, 19 May 2017 17:52:09 +0200 +Subject: [PATCH 2/3] Properly check bounds for long DNs + +--- + 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 f9063c8cc..863ad02a1 100644 +--- a/src/pkcs11/framework-pkcs15.c ++++ b/src/pkcs11/framework-pkcs15.c +@@ -566,8 +566,9 @@ pkcs15_cert_extract_label(struct pkcs15_cert_object *cert) + int rv = sc_pkcs15_get_name_from_dn(context, + cert->cert_data->subject, cert->cert_data->subject_len, + &cn_oid, &cn_name, &cn_len); +- sc_log(context, "pkcs15_cert_extract_label(): Name from DN is %s", cn_name); + if (rv == SC_SUCCESS) { ++ sc_log(context, "pkcs15_cert_extract_label(): Name from DN is %s", 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 4621251bbff5cc1df826aa7fdc2aa7dfbae3c8ab Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Mon, 22 May 2017 09:46:56 +0200 +Subject: [PATCH 3/3] Missing include + +--- + 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 863ad02a1..ce890b7a1 100644 +--- a/src/pkcs11/framework-pkcs15.c ++++ b/src/pkcs11/framework-pkcs15.c +@@ -22,6 +22,7 @@ + #include + #include + #include "libopensc/log.h" ++#include "libopensc/internal.h" + #include "libopensc/asn1.h" + #include "libopensc/cardctl.h" + #include "common/compat_strnlen.h" + diff --git a/SOURCES/opensc-0.16.0-piv-cardholder-name.patch b/SOURCES/opensc-0.16.0-piv-cardholder-name.patch new file mode 100644 index 0000000..e1c358e --- /dev/null +++ b/SOURCES/opensc-0.16.0-piv-cardholder-name.patch @@ -0,0 +1,121 @@ +From bac1ced89dde5780ecb5014b3887e4fd81c7d81c Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Fri, 18 Aug 2017 13:49:57 +0200 +Subject: [PATCH 1/3] 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 d38d7ba73..7f9015dcc 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 74b070128c27e24aa67db041a049a9eee5dddcd6 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Fri, 18 Aug 2017 14:18:00 +0200 +Subject: [PATCH 2/3] 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 7f9015dcc..6f3c9199d 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,30 @@ 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_pkcs15_free_certificate(cert_out); ++ free(cn_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 78c2b7b970a8c2d841552926a7f4c386c31abeb8 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Mon, 21 Aug 2017 13:43:08 +0200 +Subject: [PATCH 3/3] 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 5b3cb32e5..8ded1125b 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; + } + diff --git a/SOURCES/opensc-0.16.0-simpletlv.patch b/SOURCES/opensc-0.16.0-simpletlv.patch new file mode 100644 index 0000000..04d1e7f --- /dev/null +++ b/SOURCES/opensc-0.16.0-simpletlv.patch @@ -0,0 +1,21 @@ +commit 602279acecb9aaff1154ac1e2993562741a57281 +Author: Jakub Jelen +Date: Tue Jan 2 11:08:31 2018 +0100 + + Skip correctly two bytes after reading 2b size + +diff --git a/src/libopensc/simpletlv.c b/src/libopensc/simpletlv.c +index f526a1cd..ab0401b5 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; diff --git a/SPECS/opensc.spec b/SPECS/opensc.spec index 576d4ee..db1479f 100644 --- a/SPECS/opensc.spec +++ b/SPECS/opensc.spec @@ -3,7 +3,7 @@ Name: opensc Version: 0.16.0 -Release: 5.20170227git%{shortcommit0}%{?dist} +Release: 8.20170227git%{shortcommit0}%{?dist} Summary: Smart card library and applications Group: System Environment/Libraries @@ -15,6 +15,18 @@ Source2: pkcs11-switch.sh Patch0: opensc-0.16.0-coverity.patch Patch1: opensc-0.16.0-cardos.patch Patch2: opensc-0.16.0-lock.patch +# Use label from certificate DN if there is none (#1448555) +Patch3: opensc-0.16.0-labels-from-dn.patch +# Use Cardholder name in the token label (#1449740) +Patch4: opensc-0.16.0-piv-cardholder-name.patch +# Avoid infinite loop when reading CAC cards (#1473335) +Patch5: opensc-0.16.0-infinite-loop.patch +# Workaround for CAC Alt tokens (#1473418) +Patch6: opensc-0.16.0-cac-alt.patch +# Copy labels from certificate (#1448555) +Patch7: opensc-0.16.0-coolkey-labels.patch +# Properly parse multi-byte length (#1473418) +Patch8: opensc-0.16.0-simpletlv.patch BuildRequires: pcsc-lite-devel BuildRequires: readline-devel @@ -42,6 +54,12 @@ every software/card that does so, too. %patch0 -p1 -b .coverity %patch1 -p1 -b .cardos %patch2 -p1 -b .lock +%patch3 -p1 -b .label +%patch4 -p1 -b .cardholder +%patch5 -p1 -b .infinite +%patch6 -p1 -b .cac-alt +%patch7 -p1 -b .coolkey-labels +%patch8 -p1 -b .simpletlv cp -p src/pkcs15init/README ./README.pkcs15init cp -p src/scconf/README.scconf . @@ -148,6 +166,21 @@ rm -rf %{buildroot}%{_sysconfdir}/bash_completion.d/ %changelog +* Wed Jan 03 2018 Jakub Jelen - 0.16.0-8.20170227git +- Copy labels from certificate (#1448555) +- Avoid infinite loop in CAC driver when reading non-CAC cards (#1473335) +- Properly parse Simple TLV structures in CAC driver (#1473418) + +* Tue Nov 07 2017 Jakub Jelen - 0.16.0-7.20170227git +- Fix issues reported by Coverity +- Use upstream accepted fix for CAC Alt tokens (#1473418) + +* Fri Nov 03 2017 Jakub Jelen - 0.16.0-6.20170227git +- Use label from certificate DN if there is none (#1448555) +- Use Cardholder name in the token label (#1449740) +- Avoid infinite loop when reading CAC cards (#1473335) +- Workaround for CAC Alt tokens (#1473418) + * Thu May 18 2017 Jakub Jelen - 0.16.0-5.20170227git - Add missing pkcs11-switch script