You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
204 lines
7.2 KiB
204 lines
7.2 KiB
From 6dc118e1c3b89c50cda1998de1d62fa6fa666e60 Mon Sep 17 00:00:00 2001 |
|
From: Jakub Jelen <jjelen@redhat.com> |
|
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 <jjelen@redhat.com> |
|
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);
|
|
|