import opensc-0.20.0-2.el8

This commit is contained in:
CentOS Sources 2020-11-03 06:45:30 -05:00 committed by Andrew Lukoshko
parent 6cb8f64c08
commit 93e75e7ae5
11 changed files with 1748 additions and 4955 deletions

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/opensc-0.19.0.tar.gz
SOURCES/opensc-0.20.0.tar.gz

View File

@ -1 +1 @@
56cd654550aed081eb8ed86edba86e6d766133c4 SOURCES/opensc-0.19.0.tar.gz
86bf24a556837fa94d8f9b5aa4be3c9e55d4d94d SOURCES/opensc-0.20.0.tar.gz

File diff suppressed because it is too large Load Diff

View File

@ -1,48 +0,0 @@
From 6c1b9094a6060d9d838bac9ea4f7c4c9e755c4ae Mon Sep 17 00:00:00 2001
From: Steve Ross <sross@forcepoint.com>
Date: Wed, 14 Nov 2018 11:59:43 -0600
Subject: [PATCH] Enable CoolKey driver to handle 2048-bit keys.
For a problem description, see <https://github.com/OpenSC/OpenSC/issues/1524>.
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(&params.head.object_id[0], object_id);
do {
ulong2bebytes(&params.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,

View File

@ -1,112 +0,0 @@
From 6691487cd7433b4ffc3a99124b5ecf92361b8a76 Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Tue, 9 Oct 2018 15:10:36 +0200
Subject: [PATCH 1/3] 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 eeab07e4f..bd4e03362 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 fab79b70ff45d02d99bc05863be57f8ca8f0acda Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Tue, 9 Oct 2018 15:58:12 +0200
Subject: [PATCH 2/3] coolkey: Improve card matching to avoid mismatches in
muscle
---
src/libopensc/card-coolkey.c | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c
index b97559cc3..2cf2362c8 100644
--- a/src/libopensc/card-coolkey.c
+++ b/src/libopensc/card-coolkey.c
@@ -2224,14 +2224,32 @@ static int coolkey_initialize(sc_card_t *card)
/* NOTE: returns a bool, 1 card matches, 0 it does not */
static int coolkey_match_card(sc_card_t *card)
{
+ sc_apdu_t apdu;
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) {
+ /* 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 98a1716768d11afd6d0e1e73bf8154dddfe915e9 Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Tue, 9 Oct 2018 16:01:57 +0200
Subject: [PATCH 3/3] 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 f24a61ca0..98e6038a7 100644
--- a/src/libopensc/ctx.c
+++ b/src/libopensc/ctx.c
@@ -128,6 +128,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. */
@@ -144,7 +145,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. */

View File

@ -1,446 +0,0 @@
diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c
index 49b593f9..299520d6 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-iasecc.c b/src/libopensc/card-iasecc.c
index 254f8aa5..7eb3f5d0 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,
diff --git a/src/libopensc/card-muscle.c b/src/libopensc/card-muscle.c
index c91b8d5e..be5b9f14 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;
}
diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c
index 61acedc8..a678b768 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); */
@@ -1481,7 +1485,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 +1534,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) {
@@ -2126,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;
}
@@ -2981,7 +2988,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;
@@ -3080,7 +3087,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
@@ -3464,7 +3477,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 */
diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c
index 626686a7..f24a61ca 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);
}
diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c
index 718d92ff..6abd2d76 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;
}
diff --git a/src/libopensc/pkcs15-cac.c b/src/libopensc/pkcs15-cac.c
index 93032113..f34425a5 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/libopensc/pkcs15-oberthur.c b/src/libopensc/pkcs15-oberthur.c
index 3415be7c..8c126e46 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);
diff --git a/src/pkcs15init/pkcs15-authentic.c b/src/pkcs15init/pkcs15-authentic.c
index ddccd032..0b6f9c17 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);
}
diff --git a/src/pkcs15init/pkcs15-myeid.c b/src/pkcs15init/pkcs15-myeid.c
index 29f9aa22..10258667 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) {
@@ -433,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;
@@ -451,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
@@ -742,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",
diff --git a/src/pkcs15init/pkcs15-oberthur-awp.c b/src/pkcs15init/pkcs15-oberthur-awp.c
index f9c96373..9b12f06c 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;
diff --git a/src/tools/npa-tool-cmdline.c b/src/tools/npa-tool-cmdline.c
index 117c6cb1..26eed929 100644
--- a/src/tools/npa-tool-cmdline.c
+++ b/src/tools/npa-tool-cmdline.c
@@ -1685,7 +1685,14 @@ void update_multiple_arg(void *field, char ***orig_field,
struct generic_list *tmp;
if (prev_given && list) {
+ char **old = *orig_field;
+ char *old_field = field;
*orig_field = (char **) realloc (*orig_field, (field_given + prev_given) * sizeof (char *));
+ if (*orig_field == NULL) {
+ free(*old);
+ fprintf(stderr, "Failed to allocate memory: aborting");
+ exit(1);
+ }
switch(arg_type) {
case ARG_INT:
@@ -1695,6 +1702,11 @@ void update_multiple_arg(void *field, char ***orig_field,
default:
break;
};
+ if (*((void **)field) == NULL) {
+ free(old_field);
+ fprintf(stderr, "Failed to allocate memory: aborting");
+ exit(1);
+ }
for (i = (prev_given - 1); i >= 0; --i)
{
diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c
index ac5292f9..7bc5a3ff 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;
}
diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c
index 6dc8213d..23a58ce6 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;
}
diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c
index 64525f6a..5795a8ba 100644
--- a/src/tools/pkcs11-tool.c
+++ b/src/tools/pkcs11-tool.c
@@ -2695,6 +2695,7 @@ 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);
+ certdata[certdata_len] = '\0';
if (certdata_len < 0)
util_fatal("Couldn't read from file \"%s\"", opt_attr_from_file);
fclose(f);
diff --git a/src/tools/sc-hsm-tool.c b/src/tools/sc-hsm-tool.c
index 02cdfcc6..2b424cf7 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)

View File

@ -1,609 +0,0 @@
diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c
index 03c83868f1..794472134c 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ä <juha.yrjola@iki.fi>
- * Copyright (C) 2005-2016 Douglas E. Engert <deengert@gmail.com>
+ * Copyright (C) 2005-2018 Douglas E. Engert <deengert@gmail.com>
* Copyright (C) 2006, Identity Alliance, Thomas Harning <thomas.harning@identityalliance.com>
* Copyright (C) 2007, EMC, Russell Larner <rlarner@rsa.com>
*
@@ -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,11 +2266,33 @@ 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);
+ /*
+ * 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;
@@ -2635,6 +2701,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 +3073,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 +3083,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 +3108,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 +3132,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 +3163,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 +3183,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 +3207,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 +3226,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 +3332,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 +3353,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 +3376,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 +3408,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 +3427,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 +3487,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 +3824,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,

View File

@ -1,7 +1,68 @@
diff -up opensc-0.19.0/src/libopensc/card-cac1.c.idprime opensc-0.19.0/src/libopensc/card-cac1.c
--- opensc-0.19.0/src/libopensc/card-cac1.c.idprime 2019-11-14 09:42:03.557198986 +0100
+++ opensc-0.19.0/src/libopensc/card-cac1.c 2019-11-14 09:42:03.563199045 +0100
@@ -59,6 +59,7 @@
diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am
index 49d122682f..a9f200c959 100644
--- a/src/libopensc/Makefile.am
+++ b/src/libopensc/Makefile.am
@@ -48,14 +48,14 @@ 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-npa.c card-esteid2018.c card-idprime.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 \
- pkcs15-coolkey.c pkcs15-din-66291.c \
+ pkcs15-coolkey.c pkcs15-din-66291.c pkcs15-idprime.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
@@ -131,14 +131,14 @@ TIDY_FILES = \
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 \
+ card-npa.c card-esteid2018.c card-idprime.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-coolkey.c pkcs15-din-66291.c pkcs15-idprime.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 487fbeb4a6..2e3c30c22b 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-npa.obj card-esteid2018.obj card-idprime.obj \
\
pkcs15-openpgp.obj pkcs15-starcert.obj \
pkcs15-tcos.obj pkcs15-esteid.obj pkcs15-gemsafeGPK.obj \
@@ -35,7 +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 \
+ pkcs15-esteid2018.obj pkcs15-idprime.obj \
compression.obj p15card-helper.obj sm.obj \
aux-data.obj \
$(TOPDIR)\win32\versioninfo.res
diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c
index d59b4337c8..2c9361df88 100644
--- a/src/libopensc/card-cac.c
+++ b/src/libopensc/card-cac.c
@@ -54,6 +54,7 @@
#endif
#include "iso7816.h"
#include "card-cac-common.h"
@ -9,10 +70,11 @@ diff -up opensc-0.19.0/src/libopensc/card-cac1.c.idprime opensc-0.19.0/src/libop
/*
* CAC hardware and APDU constants
diff -up opensc-0.19.0/src/libopensc/card-cac.c.idprime opensc-0.19.0/src/libopensc/card-cac.c
--- opensc-0.19.0/src/libopensc/card-cac.c.idprime 2019-11-14 09:42:03.556198976 +0100
+++ opensc-0.19.0/src/libopensc/card-cac.c 2019-11-14 09:42:03.563199045 +0100
@@ -59,6 +59,7 @@
diff --git a/src/libopensc/card-cac1.c b/src/libopensc/card-cac1.c
index 08d62b62cc..67035d64e6 100644
--- a/src/libopensc/card-cac1.c
+++ b/src/libopensc/card-cac1.c
@@ -54,6 +54,7 @@
#endif
#include "iso7816.h"
#include "card-cac-common.h"
@ -20,30 +82,12 @@ diff -up opensc-0.19.0/src/libopensc/card-cac.c.idprime opensc-0.19.0/src/libope
/*
* CAC hardware and APDU constants
diff -up opensc-0.19.0/src/libopensc/cardctl.h.idprime opensc-0.19.0/src/libopensc/cardctl.h
--- opensc-0.19.0/src/libopensc/cardctl.h.idprime 2018-09-13 13:52:42.000000000 +0200
+++ opensc-0.19.0/src/libopensc/cardctl.h 2019-11-14 09:42:03.563199045 +0100
@@ -303,6 +303,16 @@ enum {
SC_CARDCTL_GIDS_INITIALIZE,
SC_CARDCTL_GIDS_SET_ADMIN_KEY,
SC_CARDCTL_GIDS_AUTHENTICATE_ADMIN,
+
+ /*
+ * IDPrime specific calls
+ */
+ SC_CARDCTL_IDPRIME_BASE = _CTL_PREFIX('I', 'D', 'P'),
+ SC_CARDCTL_IDPRIME_INIT_GET_OBJECTS,
+ SC_CARDCTL_IDPRIME_GET_NEXT_OBJECT,
+ SC_CARDCTL_IDPRIME_FINAL_GET_OBJECTS,
+ SC_CARDCTL_IDPRIME_GET_TOKEN_NAME,
+
};
enum {
diff -up opensc-0.19.0/src/libopensc/card-idprime.c.idprime opensc-0.19.0/src/libopensc/card-idprime.c
--- opensc-0.19.0/src/libopensc/card-idprime.c.idprime 2019-11-14 09:42:03.563199045 +0100
+++ opensc-0.19.0/src/libopensc/card-idprime.c 2019-11-14 09:42:03.563199045 +0100
@@ -0,0 +1,789 @@
diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c
new file mode 100644
index 0000000000..7399830afd
--- /dev/null
+++ b/src/libopensc/card-idprime.c
@@ -0,0 +1,803 @@
+/*
+ * card-idprime.c: Support for Gemalto IDPrime smart cards
+ *
@ -124,6 +168,7 @@ diff -up opensc-0.19.0/src/libopensc/card-idprime.c.idprime opensc-0.19.0/src/li
+ 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 */
+} idprime_private_data_t;
+
@ -189,12 +234,14 @@ diff -up opensc-0.19.0/src/libopensc/card-idprime.c.idprime opensc-0.19.0/src/li
+ /* 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) {
+ sc_file_free(file);
+ LOG_FUNC_RETURN(card->ctx, r);
+ }
+ if (r == SC_SUCCESS) {
+ r = file->size;
+ }
+ sc_file_free(file);
+ /* Ignore too large files */
+ if (r > MAX_FILE_SIZE) {
+ r = SC_ERROR_INVALID_DATA;
+ }
+ return r;
+}
+
@ -244,7 +291,6 @@ diff -up opensc-0.19.0/src/libopensc/card-idprime.c.idprime opensc-0.19.0/src/li
+ /* The key reference is one bigger than the value found here for some reason */
+ new_object.key_reference = start[8] + 1;
+ }
+ new_object.fd++;
+ 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);
@ -252,12 +298,12 @@ diff -up opensc-0.19.0/src/libopensc/card-idprime.c.idprime opensc-0.19.0/src/li
+ /* 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));
+ priv->tinfo_present = 1;
+ sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found p11/tinfo object");
+ }
+ }
+ r = SC_SUCCESS;
+done:
+ if (buf)
+ free(buf);
+ LOG_FUNC_RETURN(card->ctx, r);
+}
@ -322,7 +368,18 @@ diff -up opensc-0.19.0/src/libopensc/card-idprime.c.idprime opensc-0.19.0/src/li
+
+ card->drv_data = priv;
+
+ card->name = "Gemalto IDPrime";
+ switch (card->type) {
+ case SC_CARD_TYPE_IDPRIME_V1:
+ card->name = "Gemalto IDPrime (OSv1)";
+ break;
+ case SC_CARD_TYPE_IDPRIME_V2:
+ card->name = "Gemalto IDPrime (OSv2)";
+ break;
+ case SC_CARD_TYPE_IDPRIME_GENERIC:
+ default:
+ card->name = "Gemalto IDPrime (generic)";
+ break;
+ }
+ card->cla = 0x00;
+
+ /* Set up algorithm info. */
@ -431,6 +488,8 @@ diff -up opensc-0.19.0/src/libopensc/card-idprime.c.idprime opensc-0.19.0/src/li
+ sc_file_free(file);
+ if (r < 1) {
+ LOG_FUNC_RETURN(card->ctx, r);
+ } else if (r != IDPRIME_CARDID_LEN) {
+ LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA);
+ }
+
+ serial->len = MIN(IDPRIME_CARDID_LEN, SC_MAX_SERIALNR);
@ -452,7 +511,7 @@ diff -up opensc-0.19.0/src/libopensc/card-idprime.c.idprime opensc-0.19.0/src/li
+ LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
+ }
+
+ if (memcmp(priv->tinfo_df, "\0\0", 2) == 0) {
+ if (!priv->tinfo_present) {
+ LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
+ }
+
@ -527,7 +586,6 @@ diff -up opensc-0.19.0/src/libopensc/card-idprime.c.idprime opensc-0.19.0/src/li
+
+ SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
+
+ 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);
@ -535,7 +593,7 @@ diff -up opensc-0.19.0/src/libopensc/card-idprime.c.idprime opensc-0.19.0/src/li
+ }
+ priv->cache_buf_len = 0;
+ priv->cached = 0;
+ }
+
+ r = iso_ops->select_file(card, in_path, file_out);
+ if (r == SC_SUCCESS && priv && file_out != NULL) {
+ /* Try to read first bytes of the file to fix FCI in case of
@ -686,7 +744,7 @@ diff -up opensc-0.19.0/src/libopensc/card-idprime.c.idprime opensc-0.19.0/src/li
+ int r;
+ struct sc_apdu apdu;
+ u8 *p;
+ u8 sbuf[4096]; /* needs work. for 3072 keys, needs 384+10 or so */
+ u8 sbuf[128]; /* 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);
+
@ -833,10 +891,32 @@ diff -up opensc-0.19.0/src/libopensc/card-idprime.c.idprime opensc-0.19.0/src/li
+{
+ return sc_get_driver();
+}
diff -up opensc-0.19.0/src/libopensc/cards.h.idprime opensc-0.19.0/src/libopensc/cards.h
--- opensc-0.19.0/src/libopensc/cards.h.idprime 2019-11-14 09:42:03.561199025 +0100
+++ opensc-0.19.0/src/libopensc/cards.h 2019-11-14 09:45:23.000180086 +0100
@@ -240,6 +240,7 @@ enum {
diff --git a/src/libopensc/cardctl.h b/src/libopensc/cardctl.h
index ac1969256b..7bba7e6687 100644
--- a/src/libopensc/cardctl.h
+++ b/src/libopensc/cardctl.h
@@ -303,6 +303,16 @@ enum {
SC_CARDCTL_GIDS_INITIALIZE,
SC_CARDCTL_GIDS_SET_ADMIN_KEY,
SC_CARDCTL_GIDS_AUTHENTICATE_ADMIN,
+
+ /*
+ * IDPrime specific calls
+ */
+ SC_CARDCTL_IDPRIME_BASE = _CTL_PREFIX('I', 'D', 'P'),
+ SC_CARDCTL_IDPRIME_INIT_GET_OBJECTS,
+ SC_CARDCTL_IDPRIME_GET_NEXT_OBJECT,
+ SC_CARDCTL_IDPRIME_FINAL_GET_OBJECTS,
+ SC_CARDCTL_IDPRIME_GET_TOKEN_NAME,
+
};
enum {
diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h
index 24d73c094a..cb0501c3aa 100644
--- a/src/libopensc/cards.h
+++ b/src/libopensc/cards.h
@@ -234,6 +234,7 @@ enum {
/* JPKI cards */
SC_CARD_TYPE_JPKI_BASE = 31000,
@ -844,10 +924,10 @@ diff -up opensc-0.19.0/src/libopensc/cards.h.idprime opensc-0.19.0/src/libopensc
SC_CARD_TYPE_COOLKEY_BASE = 32000,
SC_CARD_TYPE_COOLKEY_GENERIC,
@@ -253,6 +254,12 @@ enum {
SC_CARD_TYPE_NPA = 34000,
SC_CARD_TYPE_NPA_TEST,
SC_CARD_TYPE_NPA_ONLINE,
@@ -258,6 +259,12 @@ enum {
SC_CARD_TYPE_RUTOKEN_ECP_SC,
SC_CARD_TYPE_RUTOKEN_LITE,
SC_CARD_TYPE_RUTOKEN_LITE_SC,
+
+ /* IDPrime cards */
+ SC_CARD_TYPE_IDPRIME_BASE = 37000,
@ -857,69 +937,31 @@ diff -up opensc-0.19.0/src/libopensc/cards.h.idprime opensc-0.19.0/src/libopensc
};
extern sc_card_driver_t *sc_get_default_driver(void);
@@ -296,6 +303,7 @@ extern sc_card_driver_t *sc_get_coolkey_
extern sc_card_driver_t *sc_get_cac_driver(void);
@@ -301,6 +308,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_idprime_driver(void);
#ifdef __cplusplus
}
diff -up opensc-0.19.0/src/libopensc/ctx.c.idprime opensc-0.19.0/src/libopensc/ctx.c
--- opensc-0.19.0/src/libopensc/ctx.c.idprime 2019-11-14 09:42:03.564199055 +0100
+++ opensc-0.19.0/src/libopensc/ctx.c 2019-11-14 09:46:07.142618618 +0100
@@ -147,6 +147,7 @@ static const struct _sc_driver_entry int
{ "jpki", (void *(*)(void)) sc_get_jpki_driver },
{ "npa", (void *(*)(void)) sc_get_npa_driver },
{ "cac1", (void *(*)(void)) sc_get_cac1_driver },
diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c
index 40f573ed0f..4c5adc6e5f 100644
--- a/src/libopensc/ctx.c
+++ b/src/libopensc/ctx.c
@@ -128,6 +128,7 @@ static const struct _sc_driver_entry internal_card_drivers[] = {
{ "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 },
/* The default driver should be last, as it handles all the
* unrecognized cards. */
{ "default", (void *(*)(void)) sc_get_default_driver },
diff -up opensc-0.19.0/src/libopensc/Makefile.am.idprime opensc-0.19.0/src/libopensc/Makefile.am
--- opensc-0.19.0/src/libopensc/Makefile.am.idprime 2019-11-14 09:42:03.562199036 +0100
+++ opensc-0.19.0/src/libopensc/Makefile.am 2019-11-14 09:43:42.168178253 +0100
@@ -48,14 +48,14 @@ 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-idprime.c \
\
pkcs15-openpgp.c pkcs15-infocamere.c pkcs15-starcert.c \
pkcs15-tcos.c pkcs15-esteid.c pkcs15-postecert.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-coolkey.c pkcs15-din-66291.c pkcs15-idprime.c \
pkcs15-dnie.c pkcs15-gids.c pkcs15-iasecc.c pkcs15-jpki.c \
compression.c p15card-helper.c sm.c \
aux-data.c
diff -up opensc-0.19.0/src/libopensc/Makefile.mak.idprime opensc-0.19.0/src/libopensc/Makefile.mak
--- opensc-0.19.0/src/libopensc/Makefile.mak.idprime 2019-11-14 09:42:03.563199045 +0100
+++ opensc-0.19.0/src/libopensc/Makefile.mak 2019-11-14 09:44:42.339776109 +0100
@@ -27,14 +27,14 @@ 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-idprime.obj \
\
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-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-dnie.obj pkcs15-gids.obj pkcs15-iasecc.obj pkcs15-jpki.obj pkcs15-idprime.obj \
compression.obj p15card-helper.obj sm.obj \
aux-data.obj \
$(TOPDIR)\win32\versioninfo.res
diff -up opensc-0.19.0/src/libopensc/opensc.h.idprime opensc-0.19.0/src/libopensc/opensc.h
--- opensc-0.19.0/src/libopensc/opensc.h.idprime 2019-11-14 09:42:03.524198658 +0100
+++ opensc-0.19.0/src/libopensc/opensc.h 2019-11-14 09:42:03.564199055 +0100
@@ -98,12 +98,13 @@ extern "C" {
/* Here should be placed drivers that need some APDU transactions in the
* driver's `match_card()` function. */
diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h
index d8ec42174e..10bea0a013 100644
--- a/src/libopensc/opensc.h
+++ b/src/libopensc/opensc.h
@@ -107,12 +107,13 @@ extern "C" {
* 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
@ -934,10 +976,11 @@ diff -up opensc-0.19.0/src/libopensc/opensc.h.idprime opensc-0.19.0/src/libopens
/* If the card is willing to produce a cryptogram with the following
* hash values, set these flags accordingly. The interpretation of the hash
diff -up opensc-0.19.0/src/libopensc/padding.c.idprime opensc-0.19.0/src/libopensc/padding.c
--- opensc-0.19.0/src/libopensc/padding.c.idprime 2019-11-14 09:42:03.540198817 +0100
+++ opensc-0.19.0/src/libopensc/padding.c 2019-11-14 09:42:03.564199055 +0100
@@ -499,6 +499,7 @@ int sc_get_encoding_flags(sc_context_t *
diff --git a/src/libopensc/padding.c b/src/libopensc/padding.c
index 4a8fc17b9c..5bcb2bb8d9 100644
--- a/src/libopensc/padding.c
+++ b/src/libopensc/padding.c
@@ -499,6 +499,7 @@ int sc_get_encoding_flags(sc_context_t *ctx,
/* Use the card's raw RSA capability on the padded input */
*sflags = SC_ALGORITHM_RSA_PAD_NONE;
*pflags = iflags;
@ -945,10 +988,11 @@ diff -up opensc-0.19.0/src/libopensc/padding.c.idprime opensc-0.19.0/src/libopen
} else if ((caps & (SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE)) &&
(iflags & SC_ALGORITHM_RSA_PAD_PKCS1)) {
diff -up opensc-0.19.0/src/libopensc/pkcs15-cac.c.idprime opensc-0.19.0/src/libopensc/pkcs15-cac.c
--- opensc-0.19.0/src/libopensc/pkcs15-cac.c.idprime 2019-11-14 09:42:03.546198876 +0100
+++ opensc-0.19.0/src/libopensc/pkcs15-cac.c 2019-11-14 09:46:46.655011155 +0100
@@ -87,89 +87,6 @@ static const char * cac_get_name(int typ
diff --git a/src/libopensc/pkcs15-cac.c b/src/libopensc/pkcs15-cac.c
index d637dedf19..e8c13d5fea 100644
--- a/src/libopensc/pkcs15-cac.c
+++ b/src/libopensc/pkcs15-cac.c
@@ -84,89 +84,6 @@ static const char * cac_get_name(int type)
return ("CAC");
}
@ -1038,7 +1082,7 @@ diff -up opensc-0.19.0/src/libopensc/pkcs15-cac.c.idprime opensc-0.19.0/src/libo
static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card)
{
static const pindata pins[] = {
@@ -408,9 +325,9 @@ static int sc_pkcs15emu_cac_init(sc_pkcs
@@ -407,9 +324,9 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card)
r = sc_pkcs15_get_bitstring_extension(card->ctx, cert_out, &usage_type, &usage, NULL);
if (r < 0) {
@ -1047,13 +1091,14 @@ diff -up opensc-0.19.0/src/libopensc/pkcs15-cac.c.idprime opensc-0.19.0/src/libo
}
- cac_map_usage(usage, cert_out->key->algorithm, &pubkey_info.usage, &prkey_info.usage, 1);
+ sc_pkcs15_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);
diff -up opensc-0.19.0/src/libopensc/pkcs15-cert.c.idprime opensc-0.19.0/src/libopensc/pkcs15-cert.c
--- opensc-0.19.0/src/libopensc/pkcs15-cert.c.idprime 2018-09-13 13:52:42.000000000 +0200
+++ opensc-0.19.0/src/libopensc/pkcs15-cert.c 2019-11-14 09:42:03.565199065 +0100
@@ -257,6 +257,8 @@ sc_pkcs15_get_extension(struct sc_contex
diff --git a/src/libopensc/pkcs15-cert.c b/src/libopensc/pkcs15-cert.c
index 8606d14af0..7850fad8d8 100644
--- a/src/libopensc/pkcs15-cert.c
+++ b/src/libopensc/pkcs15-cert.c
@@ -257,6 +257,8 @@ sc_pkcs15_get_extension(struct sc_context *ctx, struct sc_pkcs15_cert *cert,
{ NULL, 0, 0, 0, NULL, NULL }
};
@ -1062,7 +1107,7 @@ diff -up opensc-0.19.0/src/libopensc/pkcs15-cert.c.idprime opensc-0.19.0/src/lib
for (next_ext = cert->extensions, next_ext_len = cert->extensions_len; next_ext_len; ) {
/* unwrap the set and point to the next ava */
ext = sc_asn1_skip_tag(ctx, &next_ext, &next_ext_len,
@@ -322,6 +324,8 @@ sc_pkcs15_get_bitstring_extension(struct
@@ -324,6 +326,8 @@ sc_pkcs15_get_bitstring_extension(struct sc_context *ctx,
{ NULL, 0, 0, 0, NULL, NULL }
};
@ -1071,7 +1116,7 @@ diff -up opensc-0.19.0/src/libopensc/pkcs15-cert.c.idprime opensc-0.19.0/src/lib
r = sc_pkcs15_get_extension(ctx, cert, type, &bit_string, &bit_string_len, is_critical);
LOG_TEST_RET(ctx, r, "Get extension error");
@@ -533,6 +537,88 @@ sc_pkcs15_encode_cdf_entry(sc_context_t
@@ -550,6 +554,88 @@ sc_pkcs15_encode_cdf_entry(sc_context_t *ctx, const struct sc_pkcs15_object *obj
return r;
}
@ -1160,22 +1205,11 @@ diff -up opensc-0.19.0/src/libopensc/pkcs15-cert.c.idprime opensc-0.19.0/src/lib
void
sc_pkcs15_free_certificate(struct sc_pkcs15_cert *cert)
diff -up opensc-0.19.0/src/libopensc/pkcs15.h.idprime opensc-0.19.0/src/libopensc/pkcs15.h
--- opensc-0.19.0/src/libopensc/pkcs15.h.idprime 2018-09-13 13:52:42.000000000 +0200
+++ opensc-0.19.0/src/libopensc/pkcs15.h 2019-11-14 09:42:03.565199065 +0100
@@ -732,6 +732,9 @@ int sc_pkcs15_get_name_from_dn(struct sc
const u8 *dn, size_t dn_len,
const struct sc_object_id *type,
u8 **name, size_t *name_len);
+int sc_pkcs15_map_usage(unsigned int cert_usage, int algorithm,
+ unsigned int *pub_usage_ptr, unsigned int *pr_usage_ptr,
+ int allow_nonrepudiation);
int sc_pkcs15_get_extension(struct sc_context *ctx,
struct sc_pkcs15_cert *cert,
const struct sc_object_id *type,
diff -up opensc-0.19.0/src/libopensc/pkcs15-idprime.c.idprime opensc-0.19.0/src/libopensc/pkcs15-idprime.c
--- opensc-0.19.0/src/libopensc/pkcs15-idprime.c.idprime 2019-11-14 09:42:03.565199065 +0100
+++ opensc-0.19.0/src/libopensc/pkcs15-idprime.c 2019-11-14 09:49:19.494529520 +0100
diff --git a/src/libopensc/pkcs15-idprime.c b/src/libopensc/pkcs15-idprime.c
new file mode 100644
index 0000000000..d882696997
--- /dev/null
+++ b/src/libopensc/pkcs15-idprime.c
@@ -0,0 +1,286 @@
+/*
+ * partial PKCS15 emulation for IDPrime cards.
@ -1212,6 +1246,8 @@ diff -up opensc-0.19.0/src/libopensc/pkcs15-idprime.c.idprime opensc-0.19.0/src/
+#include "pkcs15.h"
+
+#define CERT_LABEL_TEMPLATE "Certificate %d"
+#define PUBKEY_LABEL_TEMPLATE "Public key %d"
+#define PRIVKEY_LABEL_TEMPLATE "Private key %d"
+
+static int idprime_detect_card(sc_pkcs15_card_t *p15card)
+{
@ -1271,8 +1307,8 @@ diff -up opensc-0.19.0/src/libopensc/pkcs15-idprime.c.idprime opensc-0.19.0/src/
+ 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 = 12;
+ pin_info.attrs.pin.max_length = 12;
+ pin_info.attrs.pin.stored_length = 0;
+ pin_info.attrs.pin.max_length = 16;
+ pin_info.tries_left = -1;
+
+ sc_log(card->ctx, "IDPrime Adding pin with label=%s", pin_label);
@ -1339,8 +1375,8 @@ diff -up opensc-0.19.0/src/libopensc/pkcs15-idprime.c.idprime opensc-0.19.0/src/
+ prkey_info.native = 1;
+
+ snprintf(cert_obj.label, SC_PKCS15_MAX_LABEL_SIZE, CERT_LABEL_TEMPLATE, i+1);
+ snprintf(pubkey_obj.label, SC_PKCS15_MAX_LABEL_SIZE, CERT_LABEL_TEMPLATE, i+1);
+ snprintf(prkey_obj.label, SC_PKCS15_MAX_LABEL_SIZE, CERT_LABEL_TEMPLATE, i+1);
+ 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;
+ sc_pkcs15_format_id(pin_id, &prkey_obj.auth_id);
+
@ -1426,12 +1462,14 @@ diff -up opensc-0.19.0/src/libopensc/pkcs15-idprime.c.idprime opensc-0.19.0/src/
+ } 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);
+ r = sc_pkcs15emu_add_rsa_pubkey(p15card, &pubkey_obj, &pubkey_info);
+ if (r < 0)
+ goto fail;
+ r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info);
+ 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)
+ goto fail;
+ }
+
+ cert_out->key = NULL;
@ -1448,46 +1486,82 @@ diff -up opensc-0.19.0/src/libopensc/pkcs15-idprime.c.idprime opensc-0.19.0/src/
+}
+
+int sc_pkcs15emu_idprime_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;
+
+ LOG_FUNC_CALLED(ctx);
+
+ if (opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK)
+ return sc_pkcs15emu_idprime_init(p15card);
+ else {
+ if (idprime_detect_card(p15card))
+ return SC_ERROR_WRONG_CARD;
+ return sc_pkcs15emu_idprime_init(p15card);
+}
+}
diff -up opensc-0.19.0/src/libopensc/pkcs15-syn.c.idprime opensc-0.19.0/src/libopensc/pkcs15-syn.c
--- opensc-0.19.0/src/libopensc/pkcs15-syn.c.idprime 2019-11-14 09:42:03.565199065 +0100
+++ opensc-0.19.0/src/libopensc/pkcs15-syn.c 2019-11-14 09:47:10.851251524 +0100
@@ -45,6 +45,7 @@ struct sc_pkcs15_emulator_handler builti
{ "postecert", sc_pkcs15emu_postecert_init_ex },
diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c
index facb0a607c..279a001e9d 100644
--- a/src/libopensc/pkcs15-syn.c
+++ b/src/libopensc/pkcs15-syn.c
@@ -43,22 +43,23 @@ struct sc_pkcs15_emulator_handler builtin_emulators[] = {
{ "itacns", sc_pkcs15emu_itacns_init_ex },
{ "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 },
diff -up opensc-0.19.0/src/libopensc/pkcs15-syn.h.idprime opensc-0.19.0/src/libopensc/pkcs15-syn.h
--- opensc-0.19.0/src/libopensc/pkcs15-syn.h.idprime 2019-11-14 09:42:03.565199065 +0100
+++ opensc-0.19.0/src/libopensc/pkcs15-syn.h 2019-11-14 09:47:34.499486456 +0100
@@ -54,6 +54,7 @@ int sc_pkcs15emu_iasecc_init_ex(sc_pkcs1
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_idprime_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *, sc_pkcs15emu_opt_t *opts);
{ "atrust-acos",sc_pkcs15emu_atrust_acos_init_ex},
{ "tccardos", sc_pkcs15emu_tccardos_init_ex },
- { "entersafe", sc_pkcs15emu_entersafe_init_ex },
+ { "entersafe", sc_pkcs15emu_entersafe_init_ex },
{ "pteid", sc_pkcs15emu_pteid_init_ex },
{ "oberthur", sc_pkcs15emu_oberthur_init_ex },
{ "sc-hsm", sc_pkcs15emu_sc_hsm_init_ex },
- { "dnie", sc_pkcs15emu_dnie_init_ex },
- { "gids", sc_pkcs15emu_gids_init_ex },
- { "iasecc", sc_pkcs15emu_iasecc_init_ex },
- { "jpki", sc_pkcs15emu_jpki_init_ex },
+ { "dnie", sc_pkcs15emu_dnie_init_ex },
+ { "gids", sc_pkcs15emu_gids_init_ex },
+ { "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 },
- { "esteid2018", sc_pkcs15emu_esteid2018_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 6811b3dab1..ccaf693ca4 100644
--- a/src/libopensc/pkcs15-syn.h
+++ b/src/libopensc/pkcs15-syn.h
@@ -53,6 +53,7 @@ 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 *);
+int sc_pkcs15emu_idprime_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *);
struct sc_pkcs15_emulator_handler {
const char *name;
diff -up opensc-0.19.0/src/libopensc/simpletlv.h.idprime opensc-0.19.0/src/libopensc/simpletlv.h
--- opensc-0.19.0/src/libopensc/simpletlv.h.idprime 2018-09-13 13:52:42.000000000 +0200
+++ opensc-0.19.0/src/libopensc/simpletlv.h 2019-11-14 09:42:03.565199065 +0100
diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h
index f2ccc42aed..df1435ce92 100644
--- a/src/libopensc/pkcs15.h
+++ b/src/libopensc/pkcs15.h
@@ -754,6 +754,9 @@ int sc_pkcs15_get_name_from_dn(struct sc_context *ctx,
const u8 *dn, size_t dn_len,
const struct sc_object_id *type,
u8 **name, size_t *name_len);
+int sc_pkcs15_map_usage(unsigned int cert_usage, int algorithm,
+ unsigned int *pub_usage_ptr, unsigned int *pr_usage_ptr,
+ int allow_nonrepudiation);
int sc_pkcs15_get_extension(struct sc_context *ctx,
struct sc_pkcs15_cert *cert,
const struct sc_object_id *type,
diff --git a/src/libopensc/simpletlv.h b/src/libopensc/simpletlv.h
index a952779733..6bcd4f0856 100644
--- a/src/libopensc/simpletlv.h
+++ b/src/libopensc/simpletlv.h
@@ -29,7 +29,6 @@ extern "C" {
#endif
@ -1496,10 +1570,11 @@ diff -up opensc-0.19.0/src/libopensc/simpletlv.h.idprime opensc-0.19.0/src/libop
/*
* Create a tag/length file in Simple TLV based on the val_len content length
diff -up opensc-0.19.0/src/pkcs11/framework-pkcs15.c.idprime opensc-0.19.0/src/pkcs11/framework-pkcs15.c
--- opensc-0.19.0/src/pkcs11/framework-pkcs15.c.idprime 2019-11-14 09:42:03.537198787 +0100
+++ opensc-0.19.0/src/pkcs11/framework-pkcs15.c 2019-11-14 09:42:03.566199075 +0100
@@ -3796,7 +3796,7 @@ pkcs15_prkey_sign(struct sc_pkcs11_sessi
diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c
index 22081ffef1..e94eeeffec 100644
--- a/src/pkcs11/framework-pkcs15.c
+++ b/src/pkcs11/framework-pkcs15.c
@@ -3976,7 +3976,7 @@ pkcs15_prkey_sign(struct sc_pkcs11_session *session, void *obj,
/* Check the data length matches the selected hash */
rv = pkcs15_prkey_check_pss_param(pMechanism, (int)ulDataLen);
if (rv != CKR_OK) {
@ -1508,7 +1583,7 @@ diff -up opensc-0.19.0/src/pkcs11/framework-pkcs15.c.idprime opensc-0.19.0/src/p
"PSS parameters");
return rv;
}
@@ -3931,6 +3931,39 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_se
@@ -4179,6 +4179,39 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_session *session, void *obj,
case CKM_RSA_X_509:
flags |= SC_ALGORITHM_RSA_RAW;
break;
@ -1548,7 +1623,7 @@ diff -up opensc-0.19.0/src/pkcs11/framework-pkcs15.c.idprime opensc-0.19.0/src/p
default:
return CKR_MECHANISM_INVALID;
}
@@ -4100,6 +4133,7 @@ pkcs15_prkey_init_params(struct sc_pkcs1
@@ -4352,6 +4385,7 @@ pkcs15_prkey_init_params(struct sc_pkcs11_session *session,
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 };
@ -1556,7 +1631,7 @@ diff -up opensc-0.19.0/src/pkcs11/framework-pkcs15.c.idprime opensc-0.19.0/src/p
switch (pMechanism->mechanism) {
case CKM_RSA_PKCS_PSS:
@@ -4155,6 +4189,18 @@ pkcs15_prkey_init_params(struct sc_pkcs1
@@ -4407,6 +4441,26 @@ pkcs15_prkey_init_params(struct sc_pkcs11_session *session,
/* TODO support different salt lengths */
break;
@ -1566,16 +1641,24 @@ diff -up opensc-0.19.0/src/pkcs11/framework-pkcs15.c.idprime opensc-0.19.0/src/p
+ return CKR_MECHANISM_PARAM_INVALID;
+
+ oaep_params = (CK_RSA_PKCS_OAEP_PARAMS*)pMechanism->pParameter;
+ if (oaep_params->mgf < CKG_MGF1_SHA1 || oaep_params->mgf > CKG_MGF1_SHA224)
+ switch (oaep_params->mgf) {
+ case CKG_MGF1_SHA1:
+ case CKG_MGF1_SHA224:
+ case CKG_MGF1_SHA256:
+ case CKG_MGF1_SHA384:
+ case CKG_MGF1_SHA512:
+ /* OK */
+ break;
+ default:
+ return CKR_MECHANISM_PARAM_INVALID;
+
+ }
+ /* TODO support different salt lengths */
+ /* TODO is there something more to check */
+ break;
}
return CKR_OK;
}
@@ -5117,6 +5163,7 @@ register_mechanisms(struct sc_pkcs11_car
@@ -5619,6 +5673,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;
@ -1583,7 +1666,7 @@ diff -up opensc-0.19.0/src/pkcs11/framework-pkcs15.c.idprime opensc-0.19.0/src/p
#endif
}
@@ -5197,6 +5244,7 @@ register_mechanisms(struct sc_pkcs11_car
@@ -5699,6 +5754,7 @@ register_mechanisms(struct sc_pkcs11_card *p11card)
}
if (rsa_flags & SC_ALGORITHM_RSA_PAD_PSS) {
@ -1591,7 +1674,7 @@ diff -up opensc-0.19.0/src/pkcs11/framework-pkcs15.c.idprime opensc-0.19.0/src/p
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);
@@ -5233,6 +5281,18 @@ register_mechanisms(struct sc_pkcs11_car
@@ -5735,6 +5791,18 @@ register_mechanisms(struct sc_pkcs11_card *p11card)
if (rc != CKR_OK)
return rc;
}
@ -1610,11 +1693,12 @@ diff -up opensc-0.19.0/src/pkcs11/framework-pkcs15.c.idprime opensc-0.19.0/src/p
}
if (rsa_flags & SC_ALGORITHM_ONBOARD_KEY_GEN) {
diff -up opensc-0.19.0/src/pkcs11/mechanism.c.idprime opensc-0.19.0/src/pkcs11/mechanism.c
--- opensc-0.19.0/src/pkcs11/mechanism.c.idprime 2019-11-14 09:42:03.525198668 +0100
+++ opensc-0.19.0/src/pkcs11/mechanism.c 2019-11-14 09:42:03.566199075 +0100
@@ -803,6 +803,15 @@ sc_pkcs11_decr_init(struct sc_pkcs11_ses
memcpy(&operation->mechanism, pMechanism, sizeof(CK_MECHANISM));
diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c
index 358cad40fd..983d8dcbdf 100644
--- a/src/pkcs11/mechanism.c
+++ b/src/pkcs11/mechanism.c
@@ -811,6 +811,15 @@ sc_pkcs11_decr_init(struct sc_pkcs11_session *session,
}
rv = mt->decrypt_init(operation, key);
+ /* Validate the mechanism parameters */
@ -1629,10 +1713,99 @@ diff -up opensc-0.19.0/src/pkcs11/mechanism.c.idprime opensc-0.19.0/src/pkcs11/m
if (rv != CKR_OK)
session_stop_operation(session, SC_PKCS11_OPERATION_DECRYPT);
diff -up opensc-0.19.0/src/tools/opensc-tool.c.idprime opensc-0.19.0/src/tools/opensc-tool.c
--- opensc-0.19.0/src/tools/opensc-tool.c.idprime 2018-09-13 13:52:42.000000000 +0200
+++ opensc-0.19.0/src/tools/opensc-tool.c 2019-11-14 09:42:03.566199075 +0100
@@ -593,6 +593,7 @@ static int list_algorithms(void)
diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c
index bd4b39af74..22e639cf49 100644
--- a/src/tests/p11test/p11test_case_common.c
+++ b/src/tests/p11test/p11test_case_common.c
@@ -422,7 +422,7 @@ int search_objects(test_certs_t *objects, token_info_t *info,
CK_OBJECT_HANDLE object_handle = CK_INVALID_HANDLE;
CK_OBJECT_HANDLE_PTR object_handles = NULL;
unsigned long i = 0, objects_length = 0;
- int j;
+ int j, ret = -1;
/* FindObjects first
* https://wiki.oasis-open.org/pkcs11/CommonBugs
@@ -439,16 +439,18 @@ int search_objects(test_certs_t *objects, token_info_t *info,
break;
if (rv != CKR_OK) {
fprintf(stderr, "C_FindObjects: rv = 0x%.8lX\n", rv);
- return -1;
+ goto out;
}
/* store handle */
if (i >= objects_length) {
+ CK_OBJECT_HANDLE_PTR new_object_handles = NULL;
objects_length += 4; // do not realloc after each row
- object_handles = realloc(object_handles, objects_length * sizeof(CK_OBJECT_HANDLE));
- if (object_handles == NULL) {
+ new_object_handles = realloc(object_handles, objects_length * sizeof(CK_OBJECT_HANDLE));
+ if (new_object_handles == NULL) {
fail_msg("Realloc failed. Need to store object handles.\n");
- return -1;
+ goto out;
}
+ object_handles = new_object_handles;
}
object_handles[i++] = object_handle;
}
@@ -458,8 +460,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");
- free(object_handles);
- return -1;
+ goto out;
}
for (i = 0; i < objects_length; i++) {
@@ -476,8 +477,7 @@ int search_objects(test_certs_t *objects, token_info_t *info,
continue;
} else if (rv != CKR_OK) {
fail_msg("C_GetAttributeValue: rv = 0x%.8lX\n", rv);
- free(object_handles);
- return -1;
+ goto out;
}
/* Allocate memory to hold the data we want */
@@ -487,8 +487,7 @@ int search_objects(test_certs_t *objects, token_info_t *info,
template[j].pValue = malloc(template[j].ulValueLen);
if (template[j].pValue == NULL) {
fail_msg("malloc failed");
- free(object_handles);
- return -1;
+ goto out;
}
}
/* Call again to get actual attribute */
@@ -496,8 +495,7 @@ int search_objects(test_certs_t *objects, token_info_t *info,
&(template[j]), 1);
if (rv != CKR_OK) {
fail_msg("C_GetAttributeValue: rv = 0x%.8lX\n", rv);
- free(object_handles);
- return -1;
+ goto out;
}
}
@@ -506,8 +504,10 @@ int search_objects(test_certs_t *objects, token_info_t *info,
for (j = 0; j < template_size; j++)
free(template[j].pValue);
}
+ ret = 0;
+out:
free(object_handles);
- return 0;
+ return ret;
}
void search_for_all_objects(test_certs_t *objects, token_info_t *info)
diff --git a/src/tools/opensc-tool.c b/src/tools/opensc-tool.c
index f829332fd8..52b570d9bf 100644
--- a/src/tools/opensc-tool.c
+++ b/src/tools/opensc-tool.c
@@ -594,6 +594,7 @@ static int list_algorithms(void)
{ SC_ALGORITHM_RSA_PAD_PKCS1, "pkcs1" },
{ SC_ALGORITHM_RSA_PAD_ANSI, "ansi" },
{ SC_ALGORITHM_RSA_PAD_PSS, "pss" },
@ -1640,10 +1813,11 @@ diff -up opensc-0.19.0/src/tools/opensc-tool.c.idprime opensc-0.19.0/src/tools/o
{ SC_ALGORITHM_RSA_PAD_ISO9796, "iso9796" },
{ SC_ALGORITHM_RSA_HASH_SHA1, "sha1" },
{ SC_ALGORITHM_RSA_HASH_MD5, "MD5" },
diff -up opensc-0.19.0/src/tools/pkcs11-tool.c.idprime opensc-0.19.0/src/tools/pkcs11-tool.c
--- opensc-0.19.0/src/tools/pkcs11-tool.c.idprime 2019-11-14 09:42:03.550198916 +0100
+++ opensc-0.19.0/src/tools/pkcs11-tool.c 2019-11-14 09:50:17.950110055 +0100
@@ -2037,9 +2037,15 @@ static void decrypt_data(CK_SLOT_ID slot
diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c
index 92c8d8a506..6a8e27ee69 100644
--- a/src/tools/pkcs11-tool.c
+++ b/src/tools/pkcs11-tool.c
@@ -2127,9 +2127,15 @@ static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session,
case CKM_RSA_PKCS_OAEP:
oaep_params.hashAlg = opt_hash_alg;
switch (opt_hash_alg) {
@ -1659,7 +1833,7 @@ diff -up opensc-0.19.0/src/tools/pkcs11-tool.c.idprime opensc-0.19.0/src/tools/p
case CKM_SHA256:
oaep_params.mgf = CKG_MGF1_SHA256;
break;
@@ -2049,12 +2055,6 @@ static void decrypt_data(CK_SLOT_ID slot
@@ -2139,12 +2145,6 @@ static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session,
case CKM_SHA512:
oaep_params.mgf = CKG_MGF1_SHA512;
break;
@ -1671,4 +1845,4 @@ diff -up opensc-0.19.0/src/tools/pkcs11-tool.c.idprime opensc-0.19.0/src/tools/p
- break;
}
break;
case CKM_RSA_PKCS:
case CKM_RSA_X_509:

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -2,8 +2,8 @@
%define nssdb %{_sysconfdir}/pki/nssdb
Name: opensc
Version: 0.19.0
Release: 7%{?dist}
Version: 0.20.0
Release: 2%{?dist}
Summary: Smart card library and applications
Group: System Environment/Libraries
@ -11,26 +11,11 @@ License: LGPLv2+
URL: https://github.com/OpenSC/OpenSC/wiki
Source0: https://github.com/OpenSC/OpenSC/releases/download/%{version}/%{name}-%{version}.tar.gz
Source1: opensc.module
# https://github.com/OpenSC/OpenSC/pull/1435
# https://github.com/OpenSC/OpenSC/pull/1521
# parts of
# https://github.com/OpenSC/OpenSC/pull/1556
# https://github.com/OpenSC/OpenSC/pull/1503
# https://github.com/OpenSC/OpenSC/pull/1505
Patch2: opensc-0.19.0-rsa-pss.patch
# https://github.com/OpenSC/OpenSC/pull/1489
Patch3: opensc-0.19.0-coverity.patch
# https://github.com/OpenSC/OpenSC/pull/1500
Patch4: opensc-0.19.0-coolkey-matching.patch
# https://github.com/OpenSC/OpenSC/pull/1502
Patch5: opensc-0.19.0-cac1.patch
Patch6: opensc-0.19.0-pinpad.patch
# https://github.com/OpenSC/OpenSC/pull/1549
Patch7: opensc-0.19.0-dual.patch
# https://github.com/OpenSC/OpenSC/pull/1772
Patch8: opensc-0.19.0-idprime.patch
# https://github.com/OpenSC/OpenSC/pull/1532
Patch9: opensc-0.19.0-coolkey-2k.patch
# https://github.com/OpenSC/OpenSC/pull/1987
Patch9: opensc-0.20.0-cardos.patch
BuildRequires: pcsc-lite-devel
BuildRequires: readline-devel
@ -40,6 +25,7 @@ BuildRequires: docbook-style-xsl
BuildRequires: autoconf automake libtool gcc
BuildRequires: desktop-file-utils
BuildRequires: bash-completion
BuildRequires: zlib-devel
Requires: pcsc-lite-libs%{?_isa}
Requires: pcsc-lite
Obsoletes: mozilla-opensc-signer < 0.12.0
@ -58,14 +44,9 @@ every software/card that does so, too.
%prep
%setup -q
%patch2 -p1 -b .pss
%patch3 -p1 -b .coverity
%patch4 -p1 -b .coolkey-match
%patch5 -p1 -b .cac1
%patch6 -p1 -b .pinpad
%patch7 -p1 -b .dual
%patch8 -p1 -b .idprime
%patch9 -p1 -b .coolkey-2k
%patch9 -p1 -b .cardos
cp -p src/pkcs15init/README ./README.pkcs15init
cp -p src/scconf/README.scconf .
@ -80,6 +61,7 @@ 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
%configure --disable-static \
--disable-autostart-items \
--disable-assert \
--enable-pcsc \
--disable-tests \
@ -123,6 +105,11 @@ rm -rf %{buildroot}%{_datadir}/bash-completion/
rm -rf %{buildroot}%{_bindir}/npa-tool
rm -rf %{buildroot}%{_mandir}/man1/npa-tool.1*
# We use p11-kit for pkcs11 modules registration
rm -rf %{buildroot}%{_bindir}/pkcs11-register
# It is even missing the manual page
#rm -rf %{buildroot}%{_mandir}/man1/pkcs11-register.1*
desktop-file-validate %{buildroot}/%{_datadir}/applications/org.opensc.notify.desktop
%post
@ -183,6 +170,7 @@ fi
%{_bindir}/westcos-tool
%{_bindir}/egk-tool
%{_datadir}/applications/org.opensc.notify.desktop
%{_bindir}/goid-tool
%{_libdir}/lib*.so.*
%{_libdir}/opensc-pkcs11.so
%{_libdir}/pkcs11-spy.so
@ -217,6 +205,12 @@ fi
%changelog
* Wed May 27 2020 Jakub Jelen <jjelen@redhat.com> - 0.20.0-2
- Unbreak different CardOS 5 configurations supporting raw RSA (#1830856)
* Wed Apr 22 2020 Jakub Jelen <jjelen@redhat.com> - 0.20.0-1
- Rebase to current upstream release (#1810660)
* Mon Nov 25 2019 Jakub Jelen <jjelen@redhat.com> - 0.19.0-7
- Unbreak RSA-PSS mechanisms in -6 release (#1775673)