Compare commits

...

No commits in common. "imports/c8-beta/opensc-0.19.0-7.el8" and "c8" have entirely different histories.

25 changed files with 6051 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;
+ }
+ r = file->size;
+ sc_file_free(file);
+ /* Ignore too large files */
+ if (r > MAX_FILE_SIZE) {
+ r = SC_ERROR_INVALID_DATA;
+ }
+ return r;
+}
+
@ -230,7 +277,7 @@ diff -up opensc-0.19.0/src/libopensc/card-idprime.c.idprime opensc-0.19.0/src/li
+ new_object.df[0] = start[0];
+ new_object.df[1] = start[1];
+ /* Second two bytes refer to the object size */
+ new_object.length = bebytes2ushort(&start[2]);
+ new_object.length = bebytes2ushort(&start[2]);
+ sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "df=%s, len=%u",
+ sc_dump_hex(new_object.df, sizeof(new_object.df)), new_object.length);
+ /* in minidriver, mscp/kxcNN or kscNN lists certificates */
@ -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,13 +298,13 @@ 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);
+ 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. */
@ -424,13 +481,15 @@ diff -up opensc-0.19.0/src/libopensc/card-idprime.c.idprime opensc-0.19.0/src/li
+ r = iso_ops->select_file(card, &cardid_path, &file);
+ if (r != SC_SUCCESS || file->size != IDPRIME_CARDID_LEN) { /* The cardid is always 16 B */
+ sc_file_free(file);
+ LOG_FUNC_RETURN(card->ctx, SC_ERROR_WRONG_LENGTH);
+ LOG_FUNC_RETURN(card->ctx, SC_ERROR_WRONG_LENGTH);
+ }
+
+ r = iso_ops->read_binary(card, 0, buf, file->size, 0);
+ sc_file_free(file);
+ if (r < 1) {
+ LOG_FUNC_RETURN(card->ctx, r);
+ 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);
+ }
+
@ -460,14 +519,14 @@ diff -up opensc-0.19.0/src/libopensc/card-idprime.c.idprime opensc-0.19.0/src/li
+ r = iso_ops->select_file(card, &tinfo_path, &file);
+ if (r != SC_SUCCESS || file->size == 0) {
+ sc_file_free(file);
+ LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
+ LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
+ }
+
+ /* First two bytes lists 0x01, the second indicates length */
+ r = iso_ops->read_binary(card, 0, buf, 2, 0);
+ r = iso_ops->read_binary(card, 0, buf, 2, 0);
+ if (r < 2 || buf[1] > file->size) { /* make sure we do not overrun */
+ sc_file_free(file);
+ LOG_FUNC_RETURN(card->ctx, r);
+ LOG_FUNC_RETURN(card->ctx, r);
+ }
+ sc_file_free(file);
+
@ -479,7 +538,7 @@ diff -up opensc-0.19.0/src/libopensc/card-idprime.c.idprime opensc-0.19.0/src/li
+ r = iso_ops->read_binary(card, 2, (unsigned char *)*tname, buf[1], 0);
+ if (r < 1) {
+ free(*tname);
+ LOG_FUNC_RETURN(card->ctx, r);
+ LOG_FUNC_RETURN(card->ctx, r);
+ }
+
+ if ((*tname)[r-1] != '\0') {
@ -527,15 +586,14 @@ 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);
+ priv->cache_buf = NULL;
+ }
+ priv->cache_buf_len = 0;
+ priv->cached = 0;
+ /* forget any old cached values */
+ if (priv->cache_buf) {
+ free(priv->cache_buf);
+ priv->cache_buf = NULL;
+ }
+ priv->cache_buf_len = 0;
+ priv->cached = 0;
+
+ 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
@ -561,7 +619,7 @@ diff -up opensc-0.19.0/src/libopensc/card-idprime.c.idprime opensc-0.19.0/src/li
+ int size;
+
+ sc_log(card->ctx, "called; %"SC_FORMAT_LEN_SIZE_T"u bytes at offset %d",
+ count, offset);
+ count, offset);
+
+ if (!priv->cached && offset == 0) {
+ // this function is called to read and uncompress the certificate
@ -583,7 +641,7 @@ diff -up opensc-0.19.0/src/libopensc/card-idprime.c.idprime opensc-0.19.0/src/li
+ r = sc_decompress_alloc(&priv->cache_buf, &(priv->cache_buf_len),
+ buffer+4, priv->file_size-4, COMPRESSION_AUTO);
+ if (r != SC_SUCCESS) {
+ sc_log(card->ctx, "Zlib error: %d", r);
+ sc_log(card->ctx, "Zlib error: %d", r);
+ LOG_FUNC_RETURN(card->ctx, r);
+ }
+ if (priv->cache_buf_len != expectedsize) {
@ -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);
+
@ -766,8 +824,8 @@ diff -up opensc-0.19.0/src/libopensc/card-idprime.c.idprime opensc-0.19.0/src/li
+ }
+ LOG_FUNC_CALLED(card->ctx);
+ sc_log(card->ctx,
+ "IDPrime decipher: in-len %"SC_FORMAT_LEN_SIZE_T"u, out-len %"SC_FORMAT_LEN_SIZE_T"u",
+ crgram_len, outlen);
+ "IDPrime decipher: in-len %"SC_FORMAT_LEN_SIZE_T"u, out-len %"SC_FORMAT_LEN_SIZE_T"u",
+ crgram_len, outlen);
+
+ sbuf = malloc(crgram_len + 1);
+ if (sbuf == NULL)
@ -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);
+ }
+ 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,11 +1833,11 @@ 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;
- default:
- default:
- oaep_params.hashAlg = CKM_SHA_1;
- /* fall through */
- case CKM_SHA_1:
@ -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

View File

@ -0,0 +1,31 @@
commit 6903aebfddc466d966c7b865fae34572bf3ed23e
Author: Frank Morgner <frankmorgner@gmail.com>
Date: Thu Jul 30 02:21:17 2020 +0200
Heap-buffer-overflow WRITE
fixes https://oss-fuzz.com/testcase-detail/5088104168554496
diff --git a/src/libopensc/pkcs15-oberthur.c b/src/libopensc/pkcs15-oberthur.c
index a873aaa0..2fb32b8d 100644
--- a/src/libopensc/pkcs15-oberthur.c
+++ b/src/libopensc/pkcs15-oberthur.c
@@ -271,11 +271,15 @@ sc_oberthur_read_file(struct sc_pkcs15_card *p15card, const char *in_path,
rv = sc_read_binary(card, 0, *out, sz, 0);
}
else {
- int rec;
- int offs = 0;
- int rec_len = file->record_length;
+ size_t rec;
+ size_t offs = 0;
+ size_t rec_len = file->record_length;
for (rec = 1; ; rec++) {
+ if (rec > file->record_count) {
+ rv = 0;
+ break;
+ }
rv = sc_read_record(card, rec, *out + offs + 2, rec_len, SC_RECORD_BY_REC_NR);
if (rv == SC_ERROR_RECORD_NOT_FOUND) {
rv = 0;

View File

@ -0,0 +1,42 @@
commit ed55fcd2996930bf58b9bb57e9ba7b1f3a753c43
Author: Frank Morgner <frankmorgner@gmail.com>
Date: Mon May 18 17:25:32 2020 +0200
fixed invalid read
fixes https://oss-fuzz.com/testcase-detail/5765246676631552
diff --git a/src/libopensc/pkcs15-gemsafeGPK.c b/src/libopensc/pkcs15-gemsafeGPK.c
index e13f3b87..4b80daf2 100644
--- a/src/libopensc/pkcs15-gemsafeGPK.c
+++ b/src/libopensc/pkcs15-gemsafeGPK.c
@@ -205,7 +205,7 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card)
u8 sysrec[7];
int num_keyinfo = 0;
- keyinfo kinfo[8]; /* will loook for 8 keys */
+ keyinfo kinfo[9]; /* will look for 9 keys */
u8 modulus_buf[ 1 + 1024 / 8]; /* tag+modulus */
u8 *cp;
char buf[256];
@@ -255,9 +255,9 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card)
/* There may be more then one key in the directory. */
/* we need to find them so we can associate them with the */
- /* the certificate. The files are 0007 to 000f */
+ /* the certificate. The files are 0007 to 000F */
- for (i = 7; i < 16; i++) {
+ for (i = 0x7; i <= 0xF; i++) {
path.value[0] = 0x00;
path.value[1] = i;
path.len = 2;
@@ -297,7 +297,7 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card)
while (j--)
*cp++ = modulus_buf[j + 1];
num_keyinfo++;
- }
+ }
/* Get the gemsafe data with the cert */
sc_format_path("3F000200004", &path);

View File

@ -0,0 +1,21 @@
commit 9d294de90d1cc66956389856e60b6944b27b4817
Author: Frank Morgner <frankmorgner@gmail.com>
Date: Thu Jun 4 10:04:10 2020 +0200
prevent out of bounds write
fixes https://oss-fuzz.com/testcase-detail/5226571123392512
diff --git a/src/libopensc/card-tcos.c b/src/libopensc/card-tcos.c
index 673c2493..e88c80bd 100644
--- a/src/libopensc/card-tcos.c
+++ b/src/libopensc/card-tcos.c
@@ -623,6 +623,8 @@ static int tcos_decipher(sc_card_t *card, const u8 * crgram, size_t crgram_len,
apdu.data = sbuf;
apdu.lc = apdu.datalen = crgram_len+1;
sbuf[0] = tcos3 ? 0x00 : ((data->pad_flags & SC_ALGORITHM_RSA_PAD_PKCS1) ? 0x81 : 0x02);
+ if (sizeof sbuf - 1 < crgram_len)
+ return SC_ERROR_INVALID_ARGUMENTS;
memcpy(sbuf+1, crgram, crgram_len);
r = sc_transmit_apdu(card, &apdu);

View File

@ -0,0 +1,50 @@
From 81944d1529202bd28359bede57c0a15deb65ba8a Mon Sep 17 00:00:00 2001
From: fullwaywang <fullwaywang@tencent.com>
Date: Mon, 29 May 2023 10:38:48 +0800
Subject: [PATCH] pkcs15init: correct left length calculation to fix buffer
overrun bug. Fixes #2785
---
src/pkcs15init/pkcs15-cardos.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/pkcs15init/pkcs15-cardos.c b/src/pkcs15init/pkcs15-cardos.c
index 9715cf390f..f41f73c349 100644
--- a/src/pkcs15init/pkcs15-cardos.c
+++ b/src/pkcs15init/pkcs15-cardos.c
@@ -872,7 +872,7 @@ static int cardos_have_verifyrc_package(sc_card_t *card)
sc_apdu_t apdu;
u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
int r;
- const u8 *p = rbuf, *q;
+ const u8 *p = rbuf, *q, *pp;
size_t len, tlen = 0, ilen = 0;
sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0x01, 0x88);
@@ -888,13 +888,13 @@ static int cardos_have_verifyrc_package(sc_card_t *card)
return 0;
while (len != 0) {
- p = sc_asn1_find_tag(card->ctx, p, len, 0xe1, &tlen);
- if (p == NULL)
+ pp = sc_asn1_find_tag(card->ctx, p, len, 0xe1, &tlen);
+ if (pp == NULL)
return 0;
if (card->type == SC_CARD_TYPE_CARDOS_M4_3) {
/* the verifyRC package on CardOS 4.3B use Manufacturer ID 0x01 */
/* and Package Number 0x07 */
- q = sc_asn1_find_tag(card->ctx, p, tlen, 0x01, &ilen);
+ q = sc_asn1_find_tag(card->ctx, pp, tlen, 0x01, &ilen);
if (q == NULL || ilen != 4)
return 0;
if (q[0] == 0x07)
@@ -902,7 +902,7 @@ static int cardos_have_verifyrc_package(sc_card_t *card)
} else if (card->type == SC_CARD_TYPE_CARDOS_M4_4) {
/* the verifyRC package on CardOS 4.4 use Manufacturer ID 0x03 */
/* and Package Number 0x02 */
- q = sc_asn1_find_tag(card->ctx, p, tlen, 0x03, &ilen);
+ q = sc_asn1_find_tag(card->ctx, pp, tlen, 0x03, &ilen);
if (q == NULL || ilen != 4)
return 0;
if (q[0] == 0x02)

View File

@ -0,0 +1,102 @@
diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c
index 099923e5..61e69c88 100644
--- a/src/libopensc/card-cac.c
+++ b/src/libopensc/card-cac.c
@@ -1793,7 +1793,7 @@ static int cac_find_and_initialize(sc_card_t *card, int initialize)
}
r = cac_process_ACA(card, priv);
if (r == SC_SUCCESS) {
- card->type = SC_CARD_TYPE_CAC_II;
+ card->type = SC_CARD_TYPE_CAC_ALT_HID;
card->drv_data = priv;
return r;
}
@@ -1869,6 +1869,8 @@ static int cac_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries
* FIPS 201 4.1.6.1 (numeric only) and * FIPS 140-2
* (6 character minimum) requirements.
*/
+ sc_apdu_t apdu;
+ u8 sbuf[SC_MAX_APDU_BUFFER_SIZE];
struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
if (data->cmd == SC_PIN_CMD_CHANGE) {
@@ -1881,6 +1883,18 @@ static int cac_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries
return SC_ERROR_INVALID_DATA;
}
}
+
+ /* We can change the PIN of Giesecke & Devrient CAC ALT tokens
+ * with a bit non-standard APDU */
+ if (card->type == SC_CARD_TYPE_CAC_ALT_HID) {
+ int r = 0;
+ r = iso7816_build_pin_apdu(card, &apdu, data, sbuf, sizeof(sbuf));
+ if (r < 0)
+ return r;
+ /* it requires P1 = 0x01 completely against the ISO specs */
+ apdu.p1 = 0x01;
+ data->apdu = &apdu;
+ }
}
return iso_drv->ops->pin_cmd(card, data, tries_left);
diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h
index 0ec25a46..16846d15 100644
--- a/src/libopensc/cards.h
+++ b/src/libopensc/cards.h
@@ -244,6 +244,7 @@ enum {
SC_CARD_TYPE_CAC_GENERIC,
SC_CARD_TYPE_CAC_I,
SC_CARD_TYPE_CAC_II,
+ SC_CARD_TYPE_CAC_ALT_HID,
/* nPA cards */
SC_CARD_TYPE_NPA = 34000,
diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c
index b1a0e88f..d41613b2 100644
--- a/src/libopensc/iso7816.c
+++ b/src/libopensc/iso7816.c
@@ -1017,7 +1017,7 @@ iso7816_decipher(struct sc_card *card,
}
-static int
+int
iso7816_build_pin_apdu(struct sc_card *card, struct sc_apdu *apdu,
struct sc_pin_cmd_data *data, u8 *buf, size_t buf_len)
{
diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h
index b519c5d5..8ebf9fbd 100644
--- a/src/libopensc/opensc.h
+++ b/src/libopensc/opensc.h
@@ -1664,6 +1664,19 @@ int iso7816_update_binary_sfid(sc_card_t *card, unsigned char sfid,
* */
int iso7816_logout(sc_card_t *card, unsigned char pin_reference);
+/*
+ * @brief Format PIN APDU for modifiction by card driver
+ *
+ * @param[in] card card
+ * @param[in] apdu apdu structure to update with PIN APDU
+ * @param[in] data pin command data to set into the APDU
+ * @param[in] buf buffer for APDU data field
+ * @param[in] buf_len maximum buffer length
+ */
+int
+iso7816_build_pin_apdu(struct sc_card *card, struct sc_apdu *apdu,
+ struct sc_pin_cmd_data *data, u8 *buf, size_t buf_len);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/libopensc/pkcs15-cac.c b/src/libopensc/pkcs15-cac.c
index ccb27994..05056ea9 100644
--- a/src/libopensc/pkcs15-cac.c
+++ b/src/libopensc/pkcs15-cac.c
@@ -79,6 +79,7 @@ static const char * cac_get_name(int type)
switch (type) {
case SC_CARD_TYPE_CAC_I: return ("CAC I");
case SC_CARD_TYPE_CAC_II: return ("CAC II");
+ case SC_CARD_TYPE_CAC_ALT_HID: return ("CAC ALT HID");
default: break;
}
return ("CAC");

View File

@ -0,0 +1,102 @@
From f1bcadfbe9d156adbe509b0860511ee41add0c67 Mon Sep 17 00:00:00 2001
From: Frank Morgner <frankmorgner@gmail.com>
Date: Tue, 10 Mar 2020 12:13:29 +0100
Subject: [PATCH] pkcs11: don't try to allocate 0 byte with calloc
fixes #1978
---
src/pkcs11/pkcs11-global.c | 7 ++++++-
win32/Make.rules.mak | 4 ++--
win32/winconfig.h.in | 2 ++
3 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/src/pkcs11/pkcs11-global.c b/src/pkcs11/pkcs11-global.c
index a3260314f8..671890309f 100644
--- a/src/pkcs11/pkcs11-global.c
+++ b/src/pkcs11/pkcs11-global.c
@@ -456,6 +456,13 @@ CK_RV C_GetSlotList(CK_BBOOL tokenPresent, /* only slots with token prese
card_detect_all();
+ if (list_empty(&virtual_slots)) {
+ sc_log(context, "returned 0 slots\n");
+ *pulCount = 0;
+ rv = CKR_OK;
+ goto out;
+ }
+
found = calloc(list_size(&virtual_slots), sizeof(CK_SLOT_ID));
if (found == NULL) {
diff --git a/win32/Make.rules.mak b/win32/Make.rules.mak
index 4f4971a72d..c6b1aac340 100644
--- a/win32/Make.rules.mak
+++ b/win32/Make.rules.mak
@@ -1,7 +1,7 @@
OPENSC_FEATURES = pcsc
#Include support for minidriver
-MINIDRIVER_DEF = /DENABLE_MINIDRIVER
+#MINIDRIVER_DEF = /DENABLE_MINIDRIVER
#Build MSI with the Windows Installer XML (WIX) toolkit, requires WIX >= 3.9
!IF "$(WIX)" == ""
@@ -33,7 +33,7 @@ WIX_LIBS = "$(WIX)\SDK\$(WIXVSVER)\lib\$(PLATFORM)\dutil.lib" "$(WIX)\SDK\$(WIXV
SM_DEF = /DENABLE_SM
#Build with debugging support
-#DEBUG_DEF = /DDEBUG
+DEBUG_DEF = /DDEBUG
# If you want support for OpenSSL (needed for pkcs15-init tool, software hashing in PKCS#11 library and verification):
# - download and build OpenSSL
diff --git a/win32/winconfig.h.in b/win32/winconfig.h.in
index 94ed9b5475..fa682c5bcc 100644
--- a/win32/winconfig.h.in
+++ b/win32/winconfig.h.in
@@ -103,6 +103,8 @@
#define DEFAULT_ONEPIN_PKCS11_PROVIDER "@DEFAULT_ONEPIN_PKCS11_PROVIDER@"
#endif
+#define PKCS11_THREAD_LOCKING
+
#ifndef DEFAULT_SM_MODULE
#define DEFAULT_SM_MODULE "@DEFAULT_SM_MODULE@"
#endif
commit 500ecd3d127975379e2310626c3ce94c3e7035ea
Author: Jakub Jelen <jjelen@redhat.com>
Date: Wed Nov 25 13:49:08 2020 +0100
pkcs11-tool: Avoid calloc with 0 argument
diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c
index 4015aaf1..89244795 100644
--- a/src/tools/pkcs11-tool.c
+++ b/src/tools/pkcs11-tool.c
@@ -1270,15 +1270,18 @@ static void list_slots(int tokens, int refresh, int print)
if (rv != CKR_OK)
p11_fatal("C_GetSlotList(NULL)", rv);
free(p11_slots);
- p11_slots = calloc(p11_num_slots, sizeof(CK_SLOT_ID));
- if (p11_slots == NULL) {
- perror("calloc failed");
- exit(1);
+ p11_slots = NULL;
+ if (p11_num_slots > 0) {
+ p11_slots = calloc(p11_num_slots, sizeof(CK_SLOT_ID));
+ if (p11_slots == NULL) {
+ perror("calloc failed");
+ exit(1);
+ }
+ rv = p11->C_GetSlotList(tokens, p11_slots, &p11_num_slots);
+ if (rv != CKR_OK)
+ p11_fatal("C_GetSlotList()", rv);
}
- rv = p11->C_GetSlotList(tokens, p11_slots, &p11_num_slots);
- if (rv != CKR_OK)
- p11_fatal("C_GetSlotList()", rv);
}
if (!print)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,85 @@
From 2a28dcd3f6e4af7a5b2d7d7810b26b6321dd1bf1 Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Tue, 10 Nov 2020 14:44:43 +0100
Subject: [PATCH 1/3] ctx: Use more standard cache directory
https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
---
src/libopensc/ctx.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c
index 6b57170f01..d6058c070e 100644
--- a/src/libopensc/ctx.c
+++ b/src/libopensc/ctx.c
@@ -1008,7 +1008,12 @@ int sc_get_cache_dir(sc_context_t *ctx, char *buf, size_t bufsize)
}
#ifndef _WIN32
- cache_dir = ".eid/cache";
+ cache_dir = getenv("XDG_CACHE_HOME");
+ if (cache_dir != NULL && cache_dir[0] != '\0') {
+ snprintf(buf, bufsize, "%s/%s", cache_dir, "opensc");
+ return SC_SUCCESS;
+ }
+ cache_dir = ".cache/opensc";
homedir = getenv("HOME");
#else
cache_dir = "eid-cache";
@@ -1020,7 +1025,7 @@ int sc_get_cache_dir(sc_context_t *ctx, char *buf, size_t bufsize)
homedir = temp_path;
}
#endif
- if (homedir == NULL)
+ if (homedir == NULL || homedir[0] == '\0')
return SC_ERROR_INTERNAL;
if (snprintf(buf, bufsize, "%s/%s", homedir, cache_dir) < 0)
return SC_ERROR_BUFFER_TOO_SMALL;
From 7c1c6f6be47f55693647827259edcacc98761371 Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Tue, 10 Nov 2020 15:07:42 +0100
Subject: [PATCH 3/3] doc: Update documentation about the cache location
---
doc/files/opensc.conf.5.xml.in | 9 +++++++--
2 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/doc/files/opensc.conf.5.xml.in b/doc/files/opensc.conf.5.xml.in
index 118922a877..791f11669a 100644
--- a/doc/files/opensc.conf.5.xml.in
+++ b/doc/files/opensc.conf.5.xml.in
@@ -1116,12 +1116,17 @@ app <replaceable>application</replaceable> {
<itemizedlist>
<listitem>
<para>
- <filename><envar>HOME</envar>/.eid/cache/</filename> (Unix)
+ <filename><envar>$XDG_CACHE_HOME</envar>/opensc/</filename> (If <envar>$XDG_CACHE_HOME</envar> is defined)
</para>
</listitem>
<listitem>
<para>
- <filename><envar>USERPROFILE</envar>\.eid-cache\</filename> (Windows)
+ <filename><envar>$HOME</envar>/.cache/opensc/</filename> (Unix)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <filename><envar>$USERPROFILE</envar>\.eid-cache\</filename> (Windows)
</para>
</listitem>
</itemizedlist>
diff -up opensc-0.20.0/etc/opensc.conf.file-cache opensc-0.20.0/etc/opensc.conf
--- opensc-0.20.0/etc/opensc.conf.file-cache 2020-11-20 16:49:30.995526825 +0100
+++ opensc-0.20.0/etc/opensc.conf 2020-11-20 16:50:07.665053280 +0100
@@ -2,7 +2,7 @@ app default {
# debug = 3;
# debug_file = opensc-debug.txt;
framework pkcs15 {
- # use_file_caching = true;
+ use_file_caching = true;
}
reader_driver pcsc {
# The pinpad is disabled by default,

View File

@ -0,0 +1,25 @@
From 34dad7f543f006ad269ce1f935a9e8d3e3a83db7 Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Mon, 3 Feb 2020 16:40:51 +0100
Subject: [PATCH] idprime: Add missing terminator in ATR list
Thanks oss-fuzz
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=20510
---
src/libopensc/card-idprime.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c
index 744d5189b9..9f5adde9d2 100644
--- a/src/libopensc/card-idprime.c
+++ b/src/libopensc/card-idprime.c
@@ -52,6 +52,7 @@ static const struct sc_atr_table idprime_atrs[] = {
"ff:ff:00:ff:ff:ff:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:ff:ff",
"Gemalto IDPrime MD 8840, 3840, 3810, 840 and 830 Cards",
SC_CARD_TYPE_IDPRIME_GENERIC, 0, NULL },
+ { NULL, NULL, NULL, 0, 0, NULL }
};
static const sc_path_t idprime_path = {

View File

@ -0,0 +1,24 @@
commit 8d4af9eb0b799f22b25783e8e1b7af329b5a917b
Author: Frank Morgner <frankmorgner@gmail.com>
Date: Fri Jan 31 12:15:53 2020 +0100
pkcs11: fixed right padding of token label with ' '
fixes https://github.com/OpenSC/OpenSC/issues/1922
diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c
index e94eeeff..a1951c2e 100644
--- a/src/pkcs11/framework-pkcs15.c
+++ b/src/pkcs11/framework-pkcs15.c
@@ -1122,9 +1122,10 @@ pkcs15_init_slot(struct sc_pkcs15_card *p15card, struct sc_pkcs11_slot *slot,
max_tokeninfo_len);
slot->token_info.label[max_tokeninfo_len] = ' ';
slot->token_info.label[max_tokeninfo_len+1] = '(';
- slot->token_info.label[max_tokeninfo_len+2+pin_len] = ')';
strcpy_bp(slot->token_info.label+max_tokeninfo_len+2,
auth->label, pin_len);
+ strcpy_bp(slot->token_info.label+max_tokeninfo_len+2+pin_len,
+ ")", 32 - max_tokeninfo_len-2-pin_len);
}
} else {
/* PIN label is empty or just says non-useful "PIN",

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,96 @@
From bff98ff078a99e6864ba1a598fd7dc9af4a9476b Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Thu, 7 Sep 2023 13:23:04 +0200
Subject: [PATCH] cache: Honor the file offset when writing cache
When the reads are not consecutive, avoid caching anything after the gaps.
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
---
src/libopensc/pkcs15-cache.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/src/libopensc/pkcs15-cache.c b/src/libopensc/pkcs15-cache.c
index 6ebe35a8af..61af35fc5a 100644
--- a/src/libopensc/pkcs15-cache.c
+++ b/src/libopensc/pkcs15-cache.c
@@ -195,6 +195,7 @@ int sc_pkcs15_cache_file(struct sc_pkcs15_card *p15card,
{
char fname[PATH_MAX];
int r;
+ long len;
FILE *f;
size_t c;
@@ -202,22 +203,33 @@ int sc_pkcs15_cache_file(struct sc_pkcs15_card *p15card,
if (r != 0)
return r;
- f = fopen(fname, "wb");
+ f = fopen(fname, "ab");
/* If the open failed because the cache directory does
* not exist, create it and a re-try the fopen() call.
*/
if (f == NULL && errno == ENOENT) {
if ((r = sc_make_cache_dir(p15card->card->ctx)) < 0)
return r;
- f = fopen(fname, "wb");
+ f = fopen(fname, "ab");
}
if (f == NULL)
return 0;
+ /* we opened the file for appending so we should be at the end of file.
+ * The ftell() will give use the length of the file */
+ len = ftell(f);
+ if (len > path->index) {
+ /* override previous cache records on this location */
+ fseek(f, path->index, SEEK_SET);
+ } else if (path->index > len) {
+ /* We miss some bytes so we will not cache this chunk */
+ return 0;
+ }
+
c = fwrite(buf, 1, bufsize, f);
fclose(f);
if (c != bufsize) {
- sc_log(p15card->card->ctx,
+ sc_log(p15card->card->ctx,
"fwrite() wrote only %"SC_FORMAT_LEN_SIZE_T"u bytes",
c);
unlink(fname);
From 0875c69295ef28b45fb682b37cede58fc36b7a1a Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Fri, 15 Sep 2023 19:17:53 +0200
Subject: [PATCH] pkcs15-cache: Avoid fd leaks and check return values
CID 401725
CID 401726
Thanks coverity
---
src/libopensc/pkcs15-cache.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/libopensc/pkcs15-cache.c b/src/libopensc/pkcs15-cache.c
index 61af35fc5a..bae5797fe2 100644
--- a/src/libopensc/pkcs15-cache.c
+++ b/src/libopensc/pkcs15-cache.c
@@ -220,9 +220,14 @@ int sc_pkcs15_cache_file(struct sc_pkcs15_card *p15card,
len = ftell(f);
if (len > path->index) {
/* override previous cache records on this location */
- fseek(f, path->index, SEEK_SET);
+ r = fseek(f, path->index, SEEK_SET);
+ if (r != 0) {
+ fclose(f);
+ return 0;
+ }
} else if (path->index > len) {
/* We miss some bytes so we will not cache this chunk */
+ fclose(f);
return 0;
}

View File

@ -0,0 +1,485 @@
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index 5153428dc..9ecbffe8f 100644
--- a/src/common/Makefile.am
+++ b/src/common/Makefile.am
@@ -8,7 +8,8 @@ dist_noinst_DATA = \
LICENSE.compat_getopt compat_getopt.txt \
compat_getopt_main.c \
README.compat_strlcpy compat_strlcpy.3
-noinst_HEADERS = compat_strlcat.h compat_strlcpy.h compat_strnlen.h compat_getpass.h compat_getopt.h simclist.h libpkcs11.h libscdl.h
+noinst_HEADERS = compat_strlcat.h compat_strlcpy.h compat_strnlen.h compat_getpass.h \
+ compat_getopt.h simclist.h libpkcs11.h libscdl.h constant-time.h
AM_CPPFLAGS = -I$(top_srcdir)/src
@@ -43,7 +44,8 @@ TIDY_FILES = \
compat_report_rangecheckfailure.c \
compat___iob_func.c \
simclist.c simclist.h \
- libpkcs11.c libscdl.c
+ libpkcs11.c libscdl.c \
+ constant-time.h
check-local:
if [ -x "$(CLANGTIDY)" ]; then clang-tidy -config='' -header-filter=.* $(TIDY_FILES) -- $(TIDY_FLAGS); fi
diff --git a/src/common/constant-time.h b/src/common/constant-time.h
new file mode 100644
index 0000000000..40c3e500c2
--- /dev/null
+++ b/src/common/constant-time.h
@@ -0,0 +1,134 @@
+/* Original source: https://github.com/openssl/openssl/blob/9890cc42daff5e2d0cad01ac4bf78c391f599a6e/include/internal/constant_time.h */
+
+#ifndef CONSTANT_TIME_H
+#define CONSTANT_TIME_H
+
+#include <stdlib.h>
+#include <string.h>
+
+#if !defined(inline)
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+#define constant_inline inline
+#elif defined(__GNUC__) && __GNUC__ >= 2
+#elif defined(__GNUC__) && __GNUC__ >= 2
+#elif defined(_MSC_VER)
+#define constant_inline __inline
+#else
+#define constant_inline
+#endif
+#else /* use what caller wants as inline may be from config.h */
+#define constant_inline inline /* inline */
+#endif
+
+/*-
+ * The boolean methods return a bitmask of all ones (0xff...f) for true
+ * and 0 for false. For example,
+ * if (a < b) {
+ * c = a;
+ * } else {
+ * c = b;
+ * }
+ * can be written as
+ * unsigned int lt = constant_time_lt(a, b);
+ * c = constant_time_select(lt, a, b);
+ */
+
+static constant_inline unsigned int
+value_barrier(unsigned int a)
+{
+ volatile unsigned int r = a;
+ return r;
+}
+
+static constant_inline size_t
+value_barrier_s(size_t a)
+{
+ volatile size_t r = a;
+ return r;
+}
+
+/* MSB */
+static constant_inline size_t
+constant_time_msb_s(size_t a)
+{
+ return 0 - (a >> (sizeof(a) * 8 - 1));
+}
+
+static constant_inline unsigned int
+constant_time_msb(unsigned int a)
+{
+ return 0 - (a >> (sizeof(a) * 8 - 1));
+}
+
+/* Select */
+static constant_inline unsigned int
+constant_time_select(unsigned int mask, unsigned int a, unsigned int b)
+{
+ return (value_barrier(mask) & a) | (value_barrier(~mask) & b);
+}
+
+static constant_inline unsigned char
+constant_time_select_8(unsigned char mask, unsigned char a, unsigned char b)
+{
+ return (unsigned char)constant_time_select(mask, a, b);
+}
+
+static constant_inline size_t
+constant_time_select_s(size_t mask, size_t a, size_t b)
+{
+ return (value_barrier_s(mask) & a) | (value_barrier_s(~mask) & b);
+}
+
+/* Zero */
+static constant_inline unsigned int
+constant_time_is_zero(unsigned int a)
+{
+ return constant_time_msb(~a & (a - 1));
+}
+
+static constant_inline size_t
+constant_time_is_zero_s(size_t a)
+{
+ return constant_time_msb_s(~a & (a - 1));
+}
+
+/* Comparison*/
+static constant_inline size_t
+constant_time_lt_s(size_t a, size_t b)
+{
+ return constant_time_msb_s(a ^ ((a ^ b) | ((a - b) ^ b)));
+}
+
+static constant_inline unsigned int
+constant_time_lt(unsigned int a, unsigned int b)
+{
+ return constant_time_msb(a ^ ((a ^ b) | ((a - b) ^ b)));
+}
+
+static constant_inline unsigned int
+constant_time_ge(unsigned int a, unsigned int b)
+{
+ return ~constant_time_lt(a, b);
+}
+
+/* Equality*/
+
+static constant_inline unsigned int
+constant_time_eq(unsigned int a, unsigned int b)
+{
+ return constant_time_is_zero(a ^ b);
+}
+
+static constant_inline size_t
+constant_time_eq_s(size_t a, size_t b)
+{
+ return constant_time_is_zero_s(a ^ b);
+}
+
+static constant_inline unsigned int
+constant_time_eq_i(int a, int b)
+{
+ return constant_time_eq((unsigned int)a, (unsigned int)b);
+}
+
+#endif /* CONSTANT_TIME_H */
diff --git a/src/libopensc/internal.h b/src/libopensc/internal.h
index 74014235a..13eccfa1a 100644
--- a/src/libopensc/internal.h
+++ b/src/libopensc/internal.h
@@ -168,6 +168,8 @@ int sc_pkcs1_strip_01_padding(struct sc_context *ctx, const u8 *in_dat, size_t i
u8 *out_dat, size_t *out_len);
int sc_pkcs1_strip_02_padding(struct sc_context *ctx, const u8 *data, size_t len,
u8 *out_dat, size_t *out_len);
+int sc_pkcs1_strip_02_padding_constant_time(sc_context_t *ctx, unsigned int n, const u8 *data,
+ unsigned int data_len, u8 *out, unsigned int *out_len);
int sc_pkcs1_strip_digest_info_prefix(unsigned int *algorithm,
const u8 *in_dat, size_t in_len, u8 *out_dat, size_t *out_len);
diff --git a/src/libopensc/padding.c b/src/libopensc/padding.c
index ca47733a4e..ddb3061134 100644
--- a/src/libopensc/padding.c
+++ b/src/libopensc/padding.c
@@ -32,10 +32,13 @@
#include <string.h>
#include <stdlib.h>
+#include "common/constant-time.h"
#include "internal.h"
/* TODO doxygen comments */
+#define SC_PKCS1_PADDING_MIN_SIZE 11
+
/*
* Prefixes for pkcs-v1 signatures
*/
@@ -144,44 +147,82 @@ sc_pkcs1_strip_01_padding(struct sc_cont
}
-/* remove pkcs1 BT02 padding (adding BT02 padding is currently not
- * needed/implemented) */
+/* Remove pkcs1 BT02 padding (adding BT02 padding is currently not
+ * needed/implemented) in constant-time.
+ * Original source: https://github.com/openssl/openssl/blob/9890cc42daff5e2d0cad01ac4bf78c391f599a6e/crypto/rsa/rsa_pk1.c#L171 */
int
-sc_pkcs1_strip_02_padding(sc_context_t *ctx, const u8 *data, size_t len, u8 *out, size_t *out_len)
+sc_pkcs1_strip_02_padding_constant_time(sc_context_t *ctx, unsigned int n, const u8 *data, unsigned int data_len, u8 *out, unsigned int *out_len)
{
- unsigned int n = 0;
-
+ unsigned int i = 0;
+ u8 *msg, *msg_orig = NULL;
+ unsigned int good, found_zero_byte, mask;
+ unsigned int zero_index = 0, msg_index, mlen = -1, len = 0;
LOG_FUNC_CALLED(ctx);
- if (data == NULL || len < 3)
+
+ if (data == NULL || data_len <= 0 || data_len > n || n < SC_PKCS1_PADDING_MIN_SIZE)
LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL);
- /* skip leading zero byte */
- if (*data == 0) {
- data++;
- len--;
+ msg = msg_orig = calloc(n, sizeof(u8));
+ if (msg == NULL)
+ LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL);
+
+ /*
+ * We can not check length of input data straight away and still we need to read
+ * from input even when the input is not as long as needed to keep the time constant.
+ * If data has wrong size, it is padded by zeroes from left and the following checks
+ * do not pass.
+ */
+ len = data_len;
+ for (data += len, msg += n, i = 0; i < n; i++) {
+ mask = ~constant_time_is_zero(len);
+ len -= 1 & mask;
+ data -= 1 & mask;
+ *--msg = *data & mask;
+ }
+ // check first byte to be 0x00
+ good = constant_time_is_zero(msg[0]);
+ // check second byte to be 0x02
+ good &= constant_time_eq(msg[1], 2);
+
+ // find zero byte after random data in padding
+ found_zero_byte = 0;
+ for (i = 2; i < n; i++) {
+ unsigned int equals0 = constant_time_is_zero(msg[i]);
+ zero_index = constant_time_select(~found_zero_byte & equals0, i, zero_index);
+ found_zero_byte |= equals0;
}
- if (data[0] != 0x02)
- LOG_FUNC_RETURN(ctx, SC_ERROR_WRONG_PADDING);
- /* skip over padding bytes */
- for (n = 1; n < len && data[n]; n++)
- ;
- /* Must be at least 8 pad bytes */
- if (n >= len || n < 9)
- LOG_FUNC_RETURN(ctx, SC_ERROR_WRONG_PADDING);
- n++;
- if (out == NULL)
- /* just check the padding */
- LOG_FUNC_RETURN(ctx, SC_SUCCESS);
- /* Now move decrypted contents to head of buffer */
- if (*out_len < len - n)
- LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL);
- *out_len = len - n;
- memmove(out, data + n, *out_len);
+ // zero_index stands for index of last found zero
+ good &= constant_time_ge(zero_index, 2 + 8);
+
+ // start of the actual message in data
+ msg_index = zero_index + 1;
+
+ // length of message
+ mlen = data_len - msg_index;
+
+ // check that message fits into out buffer
+ good &= constant_time_ge(*out_len, mlen);
+
+ // move the result in-place by |num|-SC_PKCS1_PADDING_MIN_SIZE-|mlen| bytes to the left.
+ *out_len = constant_time_select(constant_time_lt(n - SC_PKCS1_PADDING_MIN_SIZE, *out_len),
+ n - SC_PKCS1_PADDING_MIN_SIZE, *out_len);
+ for (msg_index = 1; msg_index < n - SC_PKCS1_PADDING_MIN_SIZE; msg_index <<= 1) {
+ mask = ~constant_time_eq(msg_index & (n - SC_PKCS1_PADDING_MIN_SIZE - mlen), 0);
+ for (i = SC_PKCS1_PADDING_MIN_SIZE; i < n - msg_index; i++)
+ msg[i] = constant_time_select_8(mask, msg[i + msg_index], msg[i]);
+ }
+ // move message into out buffer, if good
+ for (i = 0; i < *out_len; i++) {
+ unsigned int msg_index;
+ // when out is longer than message in data, use some bogus index in msg
+ mask = good & constant_time_lt(i, mlen);
+ msg_index = constant_time_select(mask, i + SC_PKCS1_PADDING_MIN_SIZE, 0); // to now overflow msg buffer
+ out[i] = constant_time_select_8(mask, msg[msg_index], out[i]);
+ }
- sc_log(ctx, "stripped output(%"SC_FORMAT_LEN_SIZE_T"u): %s", len - n,
- sc_dump_hex(out, len - n));
- LOG_FUNC_RETURN(ctx, len - n);
+ free(msg_orig);
+ return constant_time_select(good, mlen, SC_ERROR_WRONG_PADDING);
}
/* add/remove DigestInfo prefix */
diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c
index a019af460f..f7ee819d65 100644
--- a/src/libopensc/pkcs15-sec.c
+++ b/src/libopensc/pkcs15-sec.c
@@ -286,12 +286,14 @@ int sc_pkcs15_decipher(struct sc_pkcs15_
/* Strip any padding */
if (pad_flags & SC_ALGORITHM_RSA_PAD_PKCS1) {
- size_t s = r;
- r = sc_pkcs1_strip_02_padding(ctx, out, s, out, &s);
- LOG_TEST_RET(ctx, r, "Invalid PKCS#1 padding");
+ unsigned int s = r;
+ unsigned int key_size = (unsigned int)alg_info->key_length;
+ r = sc_pkcs1_strip_02_padding_constant_time(ctx, key_size / 8, out, s, out, &s);
+ /* for keeping PKCS#1 v1.5 depadding constant-time, do not log error here */
}
- LOG_FUNC_RETURN(ctx, r);
+ /* do not log error code to prevent side channel attack */
+ return r;
}
/* derive one key from another. RSA can use decipher, so this is for only ECDH
diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c
index f75a3dbaec..632681df63 100644
--- a/src/pkcs11/framework-pkcs15.c
+++ b/src/pkcs11/framework-pkcs15.c
@@ -18,6 +18,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "common/constant-time.h"
#include "config.h"
#include <stdlib.h>
#include <string.h>
@@ -4174,7 +4175,8 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_se
struct pkcs15_fw_data *fw_data = NULL;
struct pkcs15_prkey_object *prkey;
unsigned char decrypted[512]; /* FIXME: Will not work for keys above 4096 bits */
- int buff_too_small, rv, flags = 0, prkey_has_path = 0;
+ int rv, flags = 0, prkey_has_path = 0;
+ CK_ULONG mask, good, rv_pkcs11;
sc_log(context, "Initiating decryption.");
@@ -4246,27 +4248,54 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_se
rv = sc_pkcs15_decipher(fw_data->p15_card, prkey->prv_p15obj, flags,
pEncryptedData, ulEncryptedDataLen, decrypted, sizeof(decrypted));
- if (rv < 0 && !sc_pkcs11_conf.lock_login && !prkey_has_path)
+ /* skip for PKCS#1 v1.5 padding prevent side channel attack */
+ if (!(flags & SC_ALGORITHM_RSA_PAD_PKCS1) &&
+ rv < 0 && !sc_pkcs11_conf.lock_login && !prkey_has_path)
if (reselect_app_df(fw_data->p15_card) == SC_SUCCESS)
rv = sc_pkcs15_decipher(fw_data->p15_card, prkey->prv_p15obj, flags,
pEncryptedData, ulEncryptedDataLen, decrypted, sizeof(decrypted));
sc_unlock(p11card->card);
- sc_log(context, "Decryption complete. Result %d.", rv);
+ sc_log(context, "Decryption complete.");
- if (rv < 0)
+ /* Handle following code in constant-time
return sc_to_cryptoki_error(rv, "C_Decrypt");
+ * to prevent Marvin attack for PKCS#1 v1.5 padding. */
- buff_too_small = (*pulDataLen < (CK_ULONG)rv);
- *pulDataLen = rv;
- if (pData == NULL_PTR)
- return CKR_OK;
- if (buff_too_small)
- return CKR_BUFFER_TOO_SMALL;
- memcpy(pData, decrypted, *pulDataLen);
-
- return CKR_OK;
+ /* only padding error must be handled in constant-time way,
+ * other error can be returned straight away */
+ if ((~constant_time_eq_i(rv, SC_ERROR_WRONG_PADDING) & constant_time_lt_s(sizeof(decrypted), (size_t)rv)))
+ return sc_to_cryptoki_error(rv, "C_Decrypt");
+
+ /* check rv for padding error */
+ good = ~constant_time_eq_i(rv, SC_ERROR_WRONG_PADDING);
+ rv_pkcs11 = sc_to_cryptoki_error(SC_ERROR_WRONG_PADDING, "C_Decrypt");
+ rv_pkcs11 = constant_time_select_s(good, CKR_OK, rv_pkcs11);
+
+ if (pData == NULL_PTR) {
+ /* set length only if no error */
+ *pulDataLen = constant_time_select_s(good, rv, *pulDataLen);
+ /* return error only if original rv < 0 */
+ return rv_pkcs11;
+ }
+
+ /* check whether *pulDataLen < rv and set return value for small output buffer */
+ mask = good & constant_time_lt_s(*pulDataLen, rv);
+ rv_pkcs11 = constant_time_select_s(mask, CKR_BUFFER_TOO_SMALL, rv_pkcs11);
+ good &= ~mask;
+
+ /* move everything from decrypted into out buffer constant-time, if rv is ok */
+ for (CK_ULONG i = 0; i < *pulDataLen; i++) { /* iterate over whole pData to not disclose real depadded length */
+ CK_ULONG msg_index;
+ mask = good & constant_time_lt_s(i, sizeof(decrypted)); /* i should be in the bounds of decrypted */
+ mask &= constant_time_lt_s(i, constant_time_select_s(good, rv, 0)); /* check that is in bounds of depadded message */
+ msg_index = constant_time_select_s(mask, i, 0);
+ pData[i] = constant_time_select_8(mask, decrypted[msg_index], pData[i]);
+ }
+ *pulDataLen = constant_time_select_s(good, rv, *pulDataLen);
+ /* do not log error code to prevent side channel attack */
+ return rv_pkcs11;
}
diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c
index 03495265a4..d3f0434231 100644
--- a/src/pkcs11/mechanism.c
+++ b/src/pkcs11/mechanism.c
@@ -23,6 +23,7 @@
#include <stdlib.h>
#include <string.h>
+#include "common/constant-time.h"
#include "sc-pkcs11.h"
/* Also used for verification data */
@@ -1089,7 +1090,9 @@ sc_pkcs11_decr(struct sc_pkcs11_session
rv = op->type->decrypt(op, pEncryptedData, ulEncryptedDataLen,
pData, pulDataLen);
- if (rv != CKR_BUFFER_TOO_SMALL && pData != NULL)
+ /* terminate session for any return value except CKR_BUFFER_TOO_SMALL,
+ * perform check in time side-channel free way to prevent Marvin attack */
+ if (!constant_time_eq_s(rv, CKR_BUFFER_TOO_SMALL) && pData != NULL)
session_stop_operation(session, SC_PKCS11_OPERATION_DECRYPT);
return rv;
diff --git a/src/pkcs11/pkcs11-object.c b/src/pkcs11/pkcs11-object.c
index f04c0b4c56..b023911213 100644
--- a/src/pkcs11/pkcs11-object.c
+++ b/src/pkcs11/pkcs11-object.c
@@ -926,7 +926,8 @@ CK_RV C_Decrypt(CK_SESSION_HANDLE hSessi
rv = reset_login_state(session->slot, rv);
}
- sc_log(context, "C_Decrypt() = %s", lookup_enum ( RV_T, rv ));
+ /* do not log error code to prevent side channel attack */
+ sc_log(context, "C_Decrypt() finished");
sc_pkcs11_unlock();
return rv;
}
diff --git a/src/pkcs11/misc.c b/src/pkcs11/misc.c
index 5ca1176b1d..1d893d6181 100644
--- a/src/pkcs11/misc.c
+++ b/src/pkcs11/misc.c
@@ -23,6 +23,7 @@
#include <stdlib.h>
#include <string.h>
+#include "common/constant-time.h"
#include "sc-pkcs11.h"
#define DUMP_TEMPLATE_MAX 32
@@ -174,7 +175,7 @@ CK_RV reset_login_state(struct sc_pkcs11_slot *slot, CK_RV rv)
slot->p11card->framework->logout(slot);
}
- if (rv == CKR_USER_NOT_LOGGED_IN) {
+ if (constant_time_eq_s(rv, CKR_USER_NOT_LOGGED_IN)) {
slot->login_user = -1;
pop_all_login_states(slot);
}

View File

@ -0,0 +1,107 @@
From 868f76fb31255fd3fdacfc3e476452efeb61c3e7 Mon Sep 17 00:00:00 2001
From: Frank Morgner <frankmorgner@gmail.com>
Date: Wed, 21 Jun 2023 12:27:23 +0200
Subject: [PATCH] Fixed PIN authentication bypass
If two processes are accessing a token, then one process may leave the
card usable with an authenticated PIN so that a key may sign/decrypt any
data. This is especially the case if the token does not support a way of
resetting the authentication status (logout).
We have some tracking of the authentication status in software via
PKCS#11, Minidriver (os-wise) and CryptoTokenKit, which is why a
PIN-prompt will appear even though the card may technically be unlocked
as described in the above example. However, before this change, an empty
PIN was not verified (likely yielding an error during PIN-verification),
but it was just checked whether the PIN is authenticated. This defeats
the purpose of the PIN verification, because an empty PIN is not the
correct one. Especially during OS Logon, we don't want that kind of
shortcut, but we want the user to verify the correct PIN (even though
the token was left unattended and authentication at the computer).
This essentially reverts commit e6f7373ef066cfab6e3162e8b5f692683db23864.
---
src/libopensc/pkcs15-pin.c | 13 -------------
1 file changed, 13 deletions(-)
diff --git a/src/libopensc/pkcs15-pin.c b/src/libopensc/pkcs15-pin.c
index 80a185fecd..393234efe4 100644
--- a/src/libopensc/pkcs15-pin.c
+++ b/src/libopensc/pkcs15-pin.c
@@ -307,19 +307,6 @@ sc_pkcs15_verify_pin(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *pi
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_PIN_REFERENCE);
auth_info = (struct sc_pkcs15_auth_info *)pin_obj->data;
- /*
- * if pin cache is disabled, we can get here with no PIN data.
- * in this case, to avoid error or unnecessary pin prompting on pinpad,
- * check if the PIN has been already verified and the access condition
- * is still open on card.
- */
- if (pinlen == 0) {
- r = sc_pkcs15_get_pin_info(p15card, pin_obj);
-
- if (r == SC_SUCCESS && auth_info->logged_in == SC_PIN_STATE_LOGGED_IN)
- LOG_FUNC_RETURN(ctx, r);
- }
-
r = _validate_pin(p15card, auth_info, pinlen);
if (r)
From 80cc5d30635f0d2c92b5099c0f9dc680d0ffce2f Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Tue, 24 Oct 2023 11:13:08 +0200
Subject: [PATCH] pkcs15init: Check login status before asking for a pin
The original code block from e6f7373 is still needed when pkcs15init
layer checks ACLs for PKCS#15 objects, but it should be kept out of
the libopensc, which is used for more authentication code paths
and can be used for PIN bypass.
---
src/libopensc/pkcs15-pin.c | 1 +
src/pkcs15init/pkcs15-lib.c | 16 ++++++++++++++++
2 files changed, 17 insertions(+)
diff --git a/src/libopensc/pkcs15-pin.c b/src/libopensc/pkcs15-pin.c
index 393234efe..b26e57236 100644
--- a/src/libopensc/pkcs15-pin.c
+++ b/src/libopensc/pkcs15-pin.c
@@ -307,6 +307,7 @@ sc_pkcs15_verify_pin(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *pi
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_PIN_REFERENCE);
auth_info = (struct sc_pkcs15_auth_info *)pin_obj->data;
+ /* Check the provided pin matches pin requirements */
r = _validate_pin(p15card, auth_info, pinlen);
if (r)
diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c
index 9148b83b5..cca11d1f1 100644
--- a/src/pkcs15init/pkcs15-lib.c
+++ b/src/pkcs15init/pkcs15-lib.c
@@ -3958,6 +3958,22 @@ sc_pkcs15init_verify_secret(struct sc_profile *profile, struct sc_pkcs15_card *p
found:
if (pin_obj) {
+ /*
+ * If pin cache is disabled or the reader is using pinpad, we can get here
+ * with no PIN data. This is ok as we can not asynchronously invoke the prompt
+ * (unless the pinpad is in use).
+ * In this case, check if the PIN has been already verified and
+ * the access condition is still open on card.
+ */
+ if (pinsize == 0) {
+ r = sc_pkcs15_get_pin_info(p15card, pin_obj);
+ /* update local copy of auth info */
+ memcpy(&auth_info, pin_obj->data, sizeof(auth_info));
+
+ if (r == SC_SUCCESS && auth_info.logged_in == SC_PIN_STATE_LOGGED_IN)
+ LOG_FUNC_RETURN(ctx, r);
+ }
+
r = sc_pkcs15_verify_pin(p15card, pin_obj, use_pinpad || pinsize == 0 ? NULL : pinbuf, use_pinpad ? 0 : pinsize);
LOG_TEST_RET(ctx, r, "Cannot validate pkcs15 PIN");
}
--
2.43.0

View File

@ -0,0 +1,855 @@
From 245efe608d083fd4e4ec96793fdefd218e26fde7 Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Thu, 17 Aug 2023 13:54:42 +0200
Subject: [PATCH] pkcs15: Avoid buffer overflow when getting last update
Thanks oss-fuzz
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=60769
---
src/libopensc/pkcs15.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c
index eb7fc6afc..4215b733a 100644
--- a/src/libopensc/pkcs15.c
+++ b/src/libopensc/pkcs15.c
@@ -532,7 +532,7 @@ sc_pkcs15_get_lastupdate(struct sc_pkcs15_card *p15card)
struct sc_context *ctx = p15card->card->ctx;
struct sc_file *file = NULL;
struct sc_asn1_entry asn1_last_update[C_ASN1_LAST_UPDATE_SIZE];
- unsigned char *content, last_update[32];
+ unsigned char *content, last_update[32] = {0};
size_t lupdate_len = sizeof(last_update) - 1;
int r, content_len;
size_t size;
@@ -569,9 +569,11 @@ sc_pkcs15_get_lastupdate(struct sc_pkcs15_card *p15card)
if (r < 0)
return NULL;
- p15card->tokeninfo->last_update.gtime = strdup((char *)last_update);
- if (!p15card->tokeninfo->last_update.gtime)
- return NULL;
+ if (asn1_last_update[0].flags & SC_ASN1_PRESENT) {
+ p15card->tokeninfo->last_update.gtime = strdup((char *)last_update);
+ if (!p15card->tokeninfo->last_update.gtime)
+ return NULL;
+ }
done:
sc_log(ctx, "lastUpdate.gtime '%s'", p15card->tokeninfo->last_update.gtime);
return p15card->tokeninfo->last_update.gtime;
2.41.0
From 440ca666eff10cc7011901252d20f3fc4ea23651 Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Thu, 17 Aug 2023 13:41:36 +0200
Subject: [PATCH] setcos: Avoid buffer underflow
Thanks oss-fuzz
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=60672
---
src/pkcs15init/pkcs15-setcos.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/pkcs15init/pkcs15-setcos.c b/src/pkcs15init/pkcs15-setcos.c
index 1b56afe6d..1907b47f9 100644
--- a/src/pkcs15init/pkcs15-setcos.c
+++ b/src/pkcs15init/pkcs15-setcos.c
@@ -349,6 +349,10 @@ setcos_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
/* Replace the path of instantiated key template by the path from the object data. */
memcpy(&file->path, &key_info->path, sizeof(file->path));
+ if (file->path.len < 2) {
+ sc_file_free(file);
+ LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Invalid path");
+ }
file->id = file->path.value[file->path.len - 2] * 0x100
+ file->path.value[file->path.len - 1];
--
2.41.0
From 41d61da8481582e12710b5858f8b635e0a71ab5e Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Wed, 20 Sep 2023 10:13:57 +0200
Subject: [PATCH] oberthur: Avoid buffer overflow
Thanks oss-fuzz
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=60650
---
src/pkcs15init/pkcs15-oberthur.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/pkcs15init/pkcs15-oberthur.c b/src/pkcs15init/pkcs15-oberthur.c
index ad2cabd53..c441ab1e7 100644
--- a/src/pkcs15init/pkcs15-oberthur.c
+++ b/src/pkcs15init/pkcs15-oberthur.c
@@ -715,6 +715,9 @@ cosm_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
if (object->type != SC_PKCS15_TYPE_PRKEY_RSA)
LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Create key failed: RSA only supported");
+ if (key_info->path.len < 2)
+ LOG_TEST_RET(ctx, SC_ERROR_OBJECT_NOT_VALID, "The path needs to be at least to bytes long");
+
sc_log(ctx, "create private key ID:%s", sc_pkcs15_print_id(&key_info->id));
/* Here, the path of private key file should be defined.
* Nevertheless, we need to instantiate private key to get the ACLs. */
--
2.41.0
From 88880db0307a07e33cf2e1592bb029e9c170dfea Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= <vhanulik@redhat.com>
Date: Wed, 21 Jun 2023 15:48:27 +0200
Subject: [PATCH] pkcs15-pubkey: free DER value when parsing public key fails
The der value might be allocated in asn1_decode_entry()
but it is not released when errror occurs.
Thanks OSS-Fuzz
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=59615
---
src/libopensc/pkcs15-pubkey.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c
index 4a0ddffbe..7107c47cb 100644
--- a/src/libopensc/pkcs15-pubkey.c
+++ b/src/libopensc/pkcs15-pubkey.c
@@ -351,6 +351,8 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card,
err:
if (r < 0) {
sc_pkcs15_free_pubkey_info(info);
+ if (der->len)
+ free(der->value);
}
LOG_FUNC_RETURN(ctx, r);
--
2.41.0
From 638a5007a5d240d6fa901aa822cfeef94fe36e85 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= <vhanulik@redhat.com>
Date: Thu, 10 Aug 2023 12:20:33 +0200
Subject: [PATCH] pkcs15-pubkey.c: Avoid double-free
Thanks OSS-Fuzz
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=60616
---
src/libopensc/pkcs15-pubkey.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c
index 7107c47cb..49b514968 100644
--- a/src/libopensc/pkcs15-pubkey.c
+++ b/src/libopensc/pkcs15-pubkey.c
@@ -351,8 +351,12 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card,
err:
if (r < 0) {
sc_pkcs15_free_pubkey_info(info);
- if (der->len)
+ if (der->len) {
free(der->value);
+ /* der points to obj->content */
+ obj->content.value = NULL;
+ obj->content.len = 0;
+ }
}
LOG_FUNC_RETURN(ctx, r);
--
2.41.0
From c449a181a6988cc1e8dc8764d23574e48cdc3fa6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= <vhanulik@redhat.com>
Date: Mon, 19 Jun 2023 16:14:51 +0200
Subject: [PATCH] pkcs15-cflex: check path length to prevent underflow
Thanks OSS-Fuzz
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=58932
---
src/pkcs15init/pkcs15-cflex.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/pkcs15init/pkcs15-cflex.c b/src/pkcs15init/pkcs15-cflex.c
index d06568073..ce1d48e62 100644
--- a/src/pkcs15init/pkcs15-cflex.c
+++ b/src/pkcs15init/pkcs15-cflex.c
@@ -56,6 +56,9 @@ cflex_delete_file(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *d
int r = 0;
/* Select the parent DF */
path = df->path;
+ if (path.len < 2) {
+ return SC_ERROR_INVALID_ARGUMENTS;
+ }
path.len -= 2;
r = sc_select_file(p15card->card, &path, &parent);
if (r < 0)
--
2.41.0
From 5631e9843c832a99769def85b7b9b68b4e3e3959 Mon Sep 17 00:00:00 2001
From: Veronika Hanulikova <xhanulik@fi.muni.cz>
Date: Fri, 3 Mar 2023 16:07:38 +0100
Subject: [PATCH] Check length of string before making copy
Thanks OSS-Fuzz
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=55851
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=55998
---
src/pkcs15init/profile.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c
index 2b793b028..3bad1e853 100644
--- a/src/pkcs15init/profile.c
+++ b/src/pkcs15init/profile.c
@@ -1575,7 +1575,10 @@ do_acl(struct state *cur, int argc, char **argv)
while (argc--) {
unsigned int op, method, id;
+ if (strlen(*argv) >= sizeof(oper))
+ goto bad;
strlcpy(oper, *argv++, sizeof(oper));
+
if ((what = strchr(oper, '=')) == NULL)
goto bad;
*what++ = '\0';
@@ -2288,6 +2291,9 @@ get_authid(struct state *cur, const char *value,
return get_uint(cur, value, type);
}
+ if (strlen(value) >= sizeof(temp))
+ return 1;
+
n = strcspn(value, "0123456789x");
strlcpy(temp, value, (sizeof(temp) > n) ? n + 1 : sizeof(temp));
--
2.41.0
From e7f81d86dcdc751f4737f4b29a99bfc54d29c5c9 Mon Sep 17 00:00:00 2001
From: Frank Morgner <frankmorgner@gmail.com>
Date: Thu, 8 Dec 2022 00:45:31 +0100
Subject: [PATCH] muscle: prevent out of bounds write
fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=53631
---
src/libopensc/muscle.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/libopensc/muscle.c b/src/libopensc/muscle.c
index 7af279a0a..61a4ec24d 100644
--- a/src/libopensc/muscle.c
+++ b/src/libopensc/muscle.c
@@ -127,7 +127,7 @@ int msc_zero_object(sc_card_t *card, msc_id objectId, size_t dataLength)
{
u8 zeroBuffer[MSC_MAX_APDU];
size_t i;
- size_t max_write_unit = MSC_MAX_SEND - 9; /* - 9 for object ID+length */
+ size_t max_write_unit = MIN(MSC_MAX_APDU, MSC_MAX_SEND - 9); /* - 9 for object ID+length */
memset(zeroBuffer, 0, max_write_unit);
for(i = 0; i < dataLength; i += max_write_unit) {
--
2.41.0
From df5a176bfdf8c52ba89c7fef1f82f6f3b9312bc1 Mon Sep 17 00:00:00 2001
From: Veronika Hanulikova <xhanulik@fi.muni.cz>
Date: Fri, 10 Feb 2023 11:47:34 +0100
Subject: [PATCH] Check array bounds
Thanks OSS-Fuzz
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=54312
---
src/libopensc/muscle.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/libopensc/muscle.c b/src/libopensc/muscle.c
index 61a4ec24d..9d01e0c11 100644
--- a/src/libopensc/muscle.c
+++ b/src/libopensc/muscle.c
@@ -181,6 +181,9 @@ int msc_partial_update_object(sc_card_t *card, msc_id objectId, int offset, cons
sc_apdu_t apdu;
int r;
+ if (dataLength + 9 > MSC_MAX_APDU)
+ return SC_ERROR_INVALID_ARGUMENTS;
+
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x54, 0x00, 0x00);
apdu.lc = dataLength + 9;
if (card->ctx->debug >= 2)
--
2.41.0
From 578aed8391ef117ca64a9e0cba8e5c264368a0ec Mon Sep 17 00:00:00 2001
From: Frank Morgner <frankmorgner@gmail.com>
Date: Thu, 8 Dec 2022 00:27:18 +0100
Subject: [PATCH] sc_pkcs15init_rmdir: prevent out of bounds write
fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=53927
---
src/pkcs15init/pkcs15-lib.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c
index 91cee3731..3df03c6e1 100644
--- a/src/pkcs15init/pkcs15-lib.c
+++ b/src/pkcs15init/pkcs15-lib.c
@@ -685,6 +685,8 @@ sc_pkcs15init_rmdir(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
path = df->path;
path.len += 2;
+ if (path.len > SC_MAX_PATH_SIZE)
+ return SC_ERROR_INTERNAL;
nfids = r / 2;
while (r >= 0 && nfids--) {
--
2.41.0
From 4013a807492568bf9907cfb3df41f130ac83c7b9 Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Wed, 15 Nov 2023 10:53:46 +0100
Subject: [PATCH] setcos: Avoid writing behind the path buffer end
The path->value buffer is fixed to 16 bytes so it is not always possible
to append 2 more bytes. Doing so overruns the buffer, writing into the
ACL block, crashing during the cleanup.
Thanks oss-fuzz
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=64181
---
src/pkcs15init/pkcs15-setcos.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/pkcs15init/pkcs15-setcos.c b/src/pkcs15init/pkcs15-setcos.c
index 70a28048b..1eeeda064 100644
--- a/src/pkcs15init/pkcs15-setcos.c
+++ b/src/pkcs15init/pkcs15-setcos.c
@@ -287,6 +287,10 @@ setcos_new_file(sc_profile_t *profile, sc_card_t *card,
file->id += num;
p = &file->path;
*p = profile->df_info->file->path;
+ if (p->len + 2 > SC_MAX_PATH_SIZE) {
+ sc_file_free(file);
+ return SC_ERROR_INVALID_DATA;
+ }
p->value[p->len++] = (u8) (file->id / 256);
p->value[p->len++] = (u8) (file->id % 256);
--
2.42.0
From 8fc2c20c3f895569eeb58328bb882aec07325d3b Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Tue, 7 Nov 2023 17:48:27 +0100
Subject: [PATCH] iasecc: Avoid another buffer overflow
thanks oss-fuzz
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=63949
---
src/libopensc/iasecc-sdo.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/libopensc/iasecc-sdo.c b/src/libopensc/iasecc-sdo.c
index a41c3c2d3..86032f5a8 100644
--- a/src/libopensc/iasecc-sdo.c
+++ b/src/libopensc/iasecc-sdo.c
@@ -44,7 +44,8 @@ iasecc_parse_acls(struct sc_card *card, struct iasecc_sdo_docp *docp, int flags)
{
struct sc_context *ctx = card->ctx;
struct iasecc_extended_tlv *acls = &docp->acls_contact;
- int ii, offs;
+ int ii;
+ size_t offs;
unsigned char mask = 0x40;
if (flags)
@@ -56,8 +57,12 @@ iasecc_parse_acls(struct sc_card *card, struct iasecc_sdo_docp *docp, int flags)
docp->amb = *(acls->value + 0);
memset(docp->scbs, 0xFF, sizeof(docp->scbs));
for (ii=0, offs = 1; ii<7; ii++, mask >>= 1)
- if (mask & docp->amb)
+ if (mask & docp->amb) {
+ if (offs >= acls->size) {
+ LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA);
+ }
docp->scbs[ii] = *(acls->value + offs++);
+ }
sc_log(ctx, "iasecc_parse_docp() SCBs %02X:%02X:%02X:%02X:%02X:%02X:%02X",
docp->scbs[0],docp->scbs[1],docp->scbs[2],docp->scbs[3],
--
2.42.0
From 83b9129bd3cfc6ac57d5554e015c3df85f5076dc Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Wed, 11 Oct 2023 08:57:45 +0200
Subject: [PATCH] iassecc: Verify buffer lengths before use
Thanks oss-fuzz
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=63163
---
src/libopensc/iasecc-sdo.c | 55 +++++++++++++++++++++-----------------
1 file changed, 31 insertions(+), 24 deletions(-)
diff --git a/src/libopensc/iasecc-sdo.c b/src/libopensc/iasecc-sdo.c
index 3eeb03b91..a6e6c2677 100644
--- a/src/libopensc/iasecc-sdo.c
+++ b/src/libopensc/iasecc-sdo.c
@@ -36,7 +36,7 @@
#include "iasecc.h"
#include "iasecc-sdo.h"
-static int iasecc_parse_size(unsigned char *data, size_t *out);
+static int iasecc_parse_size(unsigned char *data, size_t data_len, size_t *out);
static int
@@ -330,7 +330,7 @@ iasecc_se_parse(struct sc_card *card, unsigned char *data, size_t data_len, stru
LOG_FUNC_CALLED(ctx);
if (*data == IASECC_SDO_TEMPLATE_TAG) {
- size_size = iasecc_parse_size(data + 1, &size);
+ size_size = iasecc_parse_size(data + 1, data_len - 1, &size);
LOG_TEST_RET(ctx, size_size, "parse error: invalid size data of IASECC_SDO_TEMPLATE");
data += size_size + 1;
@@ -345,7 +345,7 @@ iasecc_se_parse(struct sc_card *card, unsigned char *data, size_t data_len, stru
if ((*(data + 1) & 0x7F) != IASECC_SDO_CLASS_SE)
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA);
- size_size = iasecc_parse_size(data + 3, &size);
+ size_size = iasecc_parse_size(data + 3, data_len - 3, &size);
LOG_TEST_RET(ctx, size_size, "parse error: invalid SDO SE data size");
if (data_len != size + size_size + 3)
@@ -365,7 +365,7 @@ iasecc_se_parse(struct sc_card *card, unsigned char *data, size_t data_len, stru
LOG_FUNC_RETURN(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
}
- size_size = iasecc_parse_size(data + 1, &size);
+ size_size = iasecc_parse_size(data + 1, data_len - 1, &size);
LOG_TEST_RET(ctx, size_size, "parse error: invalid size data");
if (data_len != size + size_size + 1)
@@ -387,17 +387,17 @@ iasecc_se_parse(struct sc_card *card, unsigned char *data, size_t data_len, stru
static int
-iasecc_parse_size(unsigned char *data, size_t *out)
+iasecc_parse_size(unsigned char *data, size_t data_len, size_t *out)
{
- if (*data < 0x80) {
+ if (*data < 0x80 && data_len > 0) {
*out = *data;
return 1;
}
- else if (*data == 0x81) {
+ else if (*data == 0x81 && data_len > 1) {
*out = *(data + 1);
return 2;
}
- else if (*data == 0x82) {
+ else if (*data == 0x82 && data_len > 2) {
*out = *(data + 1) * 0x100 + *(data + 2);
return 3;
}
@@ -407,14 +407,18 @@ iasecc_parse_size(unsigned char *data, size_t *out)
static int
-iasecc_parse_get_tlv(struct sc_card *card, unsigned char *data, struct iasecc_extended_tlv *tlv)
+iasecc_parse_get_tlv(struct sc_card *card, unsigned char *data, size_t data_len, struct iasecc_extended_tlv *tlv)
{
struct sc_context *ctx = card->ctx;
size_t size_len, tag_len;
memset(tlv, 0, sizeof(*tlv));
sc_log(ctx, "iasecc_parse_get_tlv() called for tag 0x%X", *data);
+ if (data_len < 1)
+ LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA);
if ((*data == 0x7F) || (*data == 0x5F)) {
+ if (data_len < 2)
+ LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA);
tlv->tag = *data * 0x100 + *(data + 1);
tag_len = 2;
}
@@ -424,8 +428,11 @@ iasecc_parse_get_tlv(struct sc_card *card, unsigned char *data, struct iasecc_ex
}
sc_log(ctx, "iasecc_parse_get_tlv() tlv->tag 0x%X", tlv->tag);
- size_len = iasecc_parse_size(data + tag_len, &tlv->size);
+ size_len = iasecc_parse_size(data + tag_len, data_len - tag_len, &tlv->size);
LOG_TEST_RET(ctx, size_len, "parse error: invalid size data");
+ if (tag_len + size_len + tlv->size > data_len) {
+ LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA);
+ }
tlv->value = calloc(1, tlv->size);
if (!tlv->value)
@@ -452,7 +459,7 @@ iasecc_parse_chv(struct sc_card *card, unsigned char *data, size_t data_len, str
while(offs < data_len) {
struct iasecc_extended_tlv tlv;
- rv = iasecc_parse_get_tlv(card, data + offs, &tlv);
+ rv = iasecc_parse_get_tlv(card, data + offs, data_len - offs, &tlv);
LOG_TEST_RET(ctx, rv, "iasecc_parse_chv() get and parse TLV error");
sc_log(ctx,
@@ -486,7 +493,7 @@ iasecc_parse_prvkey(struct sc_card *card, unsigned char *data, size_t data_len,
while(offs < data_len) {
struct iasecc_extended_tlv tlv;
- rv = iasecc_parse_get_tlv(card, data + offs, &tlv);
+ rv = iasecc_parse_get_tlv(card, data + offs, data_len - offs, &tlv);
LOG_TEST_RET(ctx, rv, "iasecc_parse_prvkey() get and parse TLV error");
sc_log(ctx,
@@ -516,7 +523,7 @@ iasecc_parse_pubkey(struct sc_card *card, unsigned char *data, size_t data_len,
while(offs < data_len) {
struct iasecc_extended_tlv tlv;
- rv = iasecc_parse_get_tlv(card, data + offs, &tlv);
+ rv = iasecc_parse_get_tlv(card, data + offs, data_len - offs, &tlv);
LOG_TEST_RET(ctx, rv, "iasecc_parse_pubkey() get and parse TLV error");
sc_log(ctx,
@@ -554,7 +561,7 @@ iasecc_parse_keyset(struct sc_card *card, unsigned char *data, size_t data_len,
while(offs < data_len) {
struct iasecc_extended_tlv tlv;
- rv = iasecc_parse_get_tlv(card, data + offs, &tlv);
+ rv = iasecc_parse_get_tlv(card, data + offs, data_len - offs, &tlv);
LOG_TEST_RET(ctx, rv, "iasecc_parse_keyset() get and parse TLV error");
sc_log(ctx,
@@ -586,7 +593,7 @@ iasecc_parse_docp(struct sc_card *card, unsigned char *data, size_t data_len, st
while(offs < data_len) {
struct iasecc_extended_tlv tlv;
- rv = iasecc_parse_get_tlv(card, data + offs, &tlv);
+ rv = iasecc_parse_get_tlv(card, data + offs, data_len - offs, &tlv);
LOG_TEST_RET(ctx, rv, "iasecc_parse_get_tlv() get and parse TLV error");
sc_log(ctx,
@@ -641,7 +648,7 @@ iasecc_parse_docp(struct sc_card *card, unsigned char *data, size_t data_len, st
static int
-iasecc_sdo_parse_data(struct sc_card *card, unsigned char *data, struct iasecc_sdo *sdo)
+iasecc_sdo_parse_data(struct sc_card *card, unsigned char *data, size_t data_len, struct iasecc_sdo *sdo)
{
struct sc_context *ctx = card->ctx;
struct iasecc_extended_tlv tlv;
@@ -650,7 +657,7 @@ iasecc_sdo_parse_data(struct sc_card *card, unsigned char *data, struct iasecc_s
LOG_FUNC_CALLED(ctx);
sc_log(ctx, "iasecc_sdo_parse_data() class %X; ref %X", sdo->sdo_class, sdo->sdo_ref);
- tlv_size = iasecc_parse_get_tlv(card, data, &tlv);
+ tlv_size = iasecc_parse_get_tlv(card, data, data_len, &tlv);
LOG_TEST_RET(ctx, tlv_size, "parse error: get TLV");
sc_log(ctx, "iasecc_sdo_parse_data() tlv.tag 0x%X", tlv.tag);
@@ -735,7 +742,7 @@ iasecc_sdo_parse(struct sc_card *card, unsigned char *data, size_t data_len, str
LOG_FUNC_CALLED(ctx);
if (*data == IASECC_SDO_TEMPLATE_TAG) {
- size_size = iasecc_parse_size(data + 1, &size);
+ size_size = iasecc_parse_size(data + 1, data_len - 1, &size);
LOG_TEST_RET(ctx, size_size, "parse error: invalid size data of IASECC_SDO_TEMPLATE");
data += size_size + 1;
@@ -754,7 +761,7 @@ iasecc_sdo_parse(struct sc_card *card, unsigned char *data, size_t data_len, str
if (sdo->sdo_ref != (*(data + 2) & 0x3F))
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA);
- size_size = iasecc_parse_size(data + 3, &size);
+ size_size = iasecc_parse_size(data + 3, data_len - 3, &size);
LOG_TEST_RET(ctx, size_size, "parse error: invalid size data");
if (data_len != size + size_size + 3)
@@ -766,7 +773,7 @@ iasecc_sdo_parse(struct sc_card *card, unsigned char *data, size_t data_len, str
offs = 3 + size_size;
for (; offs < data_len;) {
- rv = iasecc_sdo_parse_data(card, data + offs, sdo);
+ rv = iasecc_sdo_parse_data(card, data + offs, data_len - offs, sdo);
LOG_TEST_RET(ctx, rv, "parse error: invalid SDO data");
offs += rv;
@@ -812,7 +819,7 @@ iasecc_sdo_allocate_and_parse(struct sc_card *card, unsigned char *data, size_t
if (data_len == 3)
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
- size_size = iasecc_parse_size(data + 3, &size);
+ size_size = iasecc_parse_size(data + 3, data_len - 3, &size);
LOG_TEST_RET(ctx, size_size, "parse error: invalid size data");
if (data_len != size + size_size + 3)
@@ -824,7 +831,7 @@ iasecc_sdo_allocate_and_parse(struct sc_card *card, unsigned char *data, size_t
offs = 3 + size_size;
for (; offs < data_len;) {
- rv = iasecc_sdo_parse_data(card, data + offs, sdo);
+ rv = iasecc_sdo_parse_data(card, data + offs, data_len - offs, sdo);
LOG_TEST_RET(ctx, rv, "parse error: invalid SDO data");
offs += rv;
@@ -1222,7 +1229,7 @@ iasecc_sdo_parse_card_answer(struct sc_context *ctx, unsigned char *data, size_t
memset(out, 0, sizeof(*out));
for (offs=0; offs<data_len; ) {
- size_size = iasecc_parse_size(data + 1, &size);
+ size_size = iasecc_parse_size(data + 1, data_len - 1, &size);
if (*(data + offs) == IASECC_CARD_ANSWER_TAG_DATA ) {
if (size > sizeof(out->data))
@@ -1293,7 +1300,7 @@ iasecc_docp_copy(struct sc_context *ctx, struct iasecc_sdo_docp *in, struct iase
int rv;
LOG_FUNC_CALLED(ctx);
- if (!in || !out)
+ if (!in || !out)
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
memset(out, 0, sizeof(struct iasecc_sdo_docp));
--
2.42.0
From fbda61d0d276dc98b9d1d1e6810bbd21d19e3859 Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Fri, 27 Oct 2023 13:23:18 +0200
Subject: [PATCH] iasecc: Avoid buffer overflow with invalid data
Thanks oss-fuzz
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=63587
---
src/libopensc/iasecc-sdo.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/libopensc/iasecc-sdo.c b/src/libopensc/iasecc-sdo.c
index 1e01c0df5..479b3c23b 100644
--- a/src/libopensc/iasecc-sdo.c
+++ b/src/libopensc/iasecc-sdo.c
@@ -371,15 +371,15 @@ iasecc_se_parse(struct sc_card *card, unsigned char *data, size_t data_len, stru
static int
iasecc_parse_size(unsigned char *data, size_t data_len, size_t *out)
{
- if (*data < 0x80 && data_len > 0) {
+ if (data_len > 0 && *data < 0x80) {
*out = *data;
return 1;
}
- else if (*data == 0x81 && data_len > 1) {
+ else if (data_len > 1 && *data == 0x81) {
*out = *(data + 1);
return 2;
}
- else if (*data == 0x82 && data_len > 2) {
+ else if (data_len > 2 && *data == 0x82) {
*out = *(data + 1) * 0x100 + *(data + 2);
return 3;
}
--
2.42.0
From 2a4921ab23fd0853f327517636c50de947548161 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= <vhanulik@redhat.com>
Date: Tue, 29 Aug 2023 14:40:21 +0200
Subject: [PATCH] iasecc: Check length of data when parsing crt
Thanks OSS-Fuzz
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=61797
---
src/libopensc/iasecc-sdo.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/libopensc/iasecc-sdo.c b/src/libopensc/iasecc-sdo.c
index b3e567dd5..3eeb03b91 100644
--- a/src/libopensc/iasecc-sdo.c
+++ b/src/libopensc/iasecc-sdo.c
@@ -204,7 +204,7 @@ iasecc_sdo_free(struct sc_card *card, struct iasecc_sdo *sdo)
static int
-iasecc_crt_parse(struct sc_card *card, unsigned char *data, struct iasecc_se_info *se)
+iasecc_crt_parse(struct sc_card *card, unsigned char *data, size_t data_len, struct iasecc_se_info *se)
{
struct sc_context *ctx = card->ctx;
struct sc_crt crt;
@@ -212,11 +212,16 @@ iasecc_crt_parse(struct sc_card *card, unsigned char *data, struct iasecc_se_inf
sc_log(ctx, "iasecc_crt_parse(0x%X) called", *data);
+ if (data_len < 2)
+ LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA);
+
memset(&crt, 0, sizeof(crt));
crt.tag = *(data + 0);
len = *(data + 1);
for(offs = 2; offs < len + 2; offs += 3) {
+ if ((size_t) offs + 2 >= data_len)
+ LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA);
sc_log(ctx, "iasecc_crt_parse(0x%X) CRT %X -> %X", *data, *(data + offs), *(data + offs + 2));
if (*(data + offs) == IASECC_CRT_TAG_USAGE) {
crt.usage = *(data + offs + 2);
@@ -368,7 +373,7 @@ iasecc_se_parse(struct sc_card *card, unsigned char *data, size_t data_len, stru
offs = 1 + size_size;
for (; offs < data_len;) {
- rv = iasecc_crt_parse(card, data + offs, se);
+ rv = iasecc_crt_parse(card, data + offs, data_len - offs, se);
LOG_TEST_RET(ctx, rv, "parse error: invalid SE data");
offs += rv;
--
2.42.0
From 6085994384a7171c5c68f6718d9db10ed77c5af1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= <vhanulik@redhat.com>
Date: Thu, 10 Aug 2023 13:56:24 +0200
Subject: [PATCH] card-entersafe.c: Free modulus buffer in case of error
Thanks OSS-Fuzz
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=60680
---
src/libopensc/card-entersafe.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c
index eb31f7146..168894abd 100644
--- a/src/libopensc/card-entersafe.c
+++ b/src/libopensc/card-entersafe.c
@@ -1423,12 +1423,18 @@ static int entersafe_gen_key(sc_card_t *card, sc_entersafe_gen_key_data *data)
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_OUT_OF_MEMORY);
p=rbuf;
- if (*p!='E')
+ if (*p!='E') {
+ free(data->modulus);
+ data->modulus = NULL;
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_DATA);
+ }
p+=2+p[1];
/* N */
- if (*p!='N')
+ if (*p!='N') {
+ free(data->modulus);
+ data->modulus = NULL;
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_DATA);
+ }
++p;
if(*p++>0x80)
{
--
2.42.0
From 50f0985f6343eeac4044661d56807ee9286db42c Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Sun, 8 Oct 2023 19:08:39 +0200
Subject: [PATCH] entersafe: Avoid buffer overflow during keygen
Thanks oss-fuzz
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=63104
---
src/libopensc/card-entersafe.c | 54 ++++++++++++++++++++--------------
1 file changed, 32 insertions(+), 22 deletions(-)
diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c
index 168894abd..feb9ebe18 100644
--- a/src/libopensc/card-entersafe.c
+++ b/src/libopensc/card-entersafe.c
@@ -1374,8 +1374,9 @@ static int entersafe_gen_key(sc_card_t *card, sc_entersafe_gen_key_data *data)
int r;
size_t len = data->key_length >> 3;
sc_apdu_t apdu;
- u8 rbuf[300];
+ u8 rbuf[300] = {0};
u8 sbuf[4],*p;
+ size_t plen = 0;
SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
@@ -1418,40 +1419,49 @@ static int entersafe_gen_key(sc_card_t *card, sc_entersafe_gen_key_data *data)
LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
LOG_TEST_RET(card->ctx, sc_check_sw(card,apdu.sw1,apdu.sw2),"EnterSafe get pukey failed");
- data->modulus = malloc(len);
- if (!data->modulus)
- SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_OUT_OF_MEMORY);
-
- p=rbuf;
- if (*p!='E') {
- free(data->modulus);
- data->modulus = NULL;
+ p = rbuf;
+ plen = apdu.resplen;
+ if (*p != 'E') {
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_DATA);
}
- p+=2+p[1];
+ if ((size_t)(p - rbuf) + 2 + p[1] >= plen) {
+ SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_DATA);
+ }
+ p += 2 + p[1];
/* N */
- if (*p!='N') {
- free(data->modulus);
- data->modulus = NULL;
+ if (*p != 'N') {
+ SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_DATA);
+ }
+ if ((size_t)(p - rbuf) + 2 >= plen) {
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_DATA);
}
++p;
- if(*p++>0x80)
+ if (*p++ > 0x80)
{
- u8 len_bytes=(*(p-1))&0x0f;
- size_t module_len=0;
- while(len_bytes!=0)
+ u8 len_bytes = (*(p - 1)) & 0x0f;
+ size_t module_len = 0;
+ if ((size_t)(p - rbuf) + len_bytes >= plen) {
+ SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_DATA);
+ }
+ while (len_bytes != 0)
{
- module_len=module_len<<8;
- module_len+=*p++;
+ module_len = module_len << 8;
+ module_len += *p++;
--len_bytes;
}
}
- entersafe_reverse_buffer(p,len);
- memcpy(data->modulus,p,len);
+ if ((p - rbuf) + len >= plen) {
+ SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_DATA);
+ }
- SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_SUCCESS);
+ data->modulus = malloc(len);
+ if (!data->modulus)
+ SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_OUT_OF_MEMORY);
+ entersafe_reverse_buffer(p, len);
+ memcpy(data->modulus, p, len);
+
+ SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS);
}
static int entersafe_get_serialnr(sc_card_t *card, sc_serial_number_t *serial)
--
2.42.0

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: 8%{?dist}
Summary: Smart card library and applications
Group: System Environment/Libraries
@ -11,26 +11,76 @@ 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
# https://github.com/OpenSC/OpenSC/pull/2129
Patch10: opensc-0.20.0-cac-pin-change.patch
# https://github.com/OpenSC/OpenSC/commit/6903aebf
Patch11: opensc-0.20.0-CVE-2020-26570.patch
# https://github.com/OpenSC/OpenSC/commit/ed55fcd2
Patch12: opensc-0.20.0-CVE-2020-26571.patch
# https://github.com/OpenSC/OpenSC/commit/9d294de9
Patch13: opensc-0.20.0-CVE-2020-26572.patch
# https://github.com/OpenSC/OpenSC/commit/8d4af9eb
Patch14: opensc-0.20.0-label-padding.patch
# https://github.com/OpenSC/OpenSC/commit/f1bcadfb
# https://github.com/OpenSC/OpenSC/pull/2166
Patch15: opensc-0.20.0-calloc0.patch
# https://github.com/OpenSC/OpenSC/pull/2148
# + configuration change by default
Patch16: opensc-0.20.0-file-cache.patch
# https://github.com/OpenSC/OpenSC/pull/1929
Patch17: opensc-0.20.0-idprime.patch
# https://github.com/OpenSC/OpenSC/pull/2787
Patch18: opensc-0.20.0-CVE-2023-2977.patch
# 31d8c2dfd14ed01b430def2f46cc718ef4b595fc
# 8f4a6c703b5ae7d4f44cf33c85330171afa917bf
# https://github.com/OpenSC/OpenSC/pull/1970 without the first and last commits
# https://github.com/OpenSC/OpenSC/pull/1923
# https://github.com/OpenSC/OpenSC/pull/2051
# https://github.com/OpenSC/OpenSC/pull/2077
# https://github.com/OpenSC/OpenSC/pull/2418
# https://github.com/OpenSC/OpenSC/pull/2600
# c2e00e9071952b30ed6d58d9b7670eb3d93ea6fb
# https://github.com/OpenSC/OpenSC/pull/2740
## OpenSC notify build issues
# 5e79a2a4abdd523cfff19824718bbb0d8ced7320
# 843779fe6e0f345f483f9ce9c9739913502391eb
# 7936bdef15c71139a6a6159cabaf9e6101565add
# 1202eceeefd5ffab45648d41ed0a3076cac10920
# 295f399304644e6b0acde267ac410d0aae4a1aee
# ca01aa7a8edc8280a5ceadebb472c2e3c198d8c2
Patch19: opensc-0.20.0-reader-removal.patch
# https://github.com/OpenSC/OpenSC/commit/bff98ff078a99e6864ba1a598fd7dc9af4a9476b
# https://github.com/OpenSC/OpenSC/commit/0875c69295ef28b45fb682b37cede58fc36b7a1a
Patch20: %{name}-0.23.0-cache-offsets.patch
# https://github.com/OpenSC/OpenSC/commit/868f76fb31255fd3fdacfc3e476452efeb61c3e7
# https://github.com/OpenSC/OpenSC/commit/80cc5d30635f0d2c92b5099c0f9dc680d0ffce2f
Patch21: %{name}-0.23.0-pin-bypass.patch
# https://github.com/OpenSC/OpenSC/commit/245efe608d083fd4e4ec96793fdefd218e26fde7
# https://github.com/OpenSC/OpenSC/commit/440ca666eff10cc7011901252d20f3fc4ea23651
# https://github.com/OpenSC/OpenSC/commit/41d61da8481582e12710b5858f8b635e0a71ab5e
# https://github.com/OpenSC/OpenSC/commit/88880db0307a07e33cf2e1592bb029e9c170dfea
# https://github.com/OpenSC/OpenSC/commit/638a5007a5d240d6fa901aa822cfeef94fe36e85
# https://github.com/OpenSC/OpenSC/commit/c449a181a6988cc1e8dc8764d23574e48cdc3fa6
# https://github.com/OpenSC/OpenSC/commit/5631e9843c832a99769def85b7b9b68b4e3e3959
# https://github.com/OpenSC/OpenSC/commit/e7f81d86dcdc751f4737f4b29a99bfc54d29c5c9
# https://github.com/OpenSC/OpenSC/commit/df5a176bfdf8c52ba89c7fef1f82f6f3b9312bc1
# https://github.com/OpenSC/OpenSC/commit/578aed8391ef117ca64a9e0cba8e5c264368a0ec
# https://github.com/OpenSC/OpenSC/commit/013a807492568bf9907cfb3df41f130ac83c7b9
# https://github.com/OpenSC/OpenSC/commit/fc2c20c3f895569eeb58328bb882aec07325d3b
# https://github.com/OpenSC/OpenSC/commit/3b9129bd3cfc6ac57d5554e015c3df85f5076dc
# https://github.com/OpenSC/OpenSC/commit/bda61d0d276dc98b9d1d1e6810bbd21d19e3859
# https://github.com/OpenSC/OpenSC/commit/a4921ab23fd0853f327517636c50de947548161
# https://github.com/OpenSC/OpenSC/commit/085994384a7171c5c68f6718d9db10ed77c5af1
# https://github.com/OpenSC/OpenSC/commit/0f0985f6343eeac4044661d56807ee9286db42c
Patch22: %{name}-0.23.0-pkcs15init.patch
# https://github.com/OpenSC/OpenSC/pull/2948
# https://github.com/OpenSC/OpenSC/pull/3016
Patch23: %{name}-0.23.0-constant-time-pkcs1.patch
BuildRequires: pcsc-lite-devel
BuildRequires: readline-devel
@ -40,6 +90,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 +109,23 @@ 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
%patch10 -p1 -b .cac-pin-change
%patch11 -p1 -b .CVE-2020-26570
%patch12 -p1 -b .CVE-2020-26571
%patch13 -p1 -b .CVE-2020-26572
%patch14 -p1 -b .padding
%patch15 -p1 -b .calloc0
%patch16 -p1 -b .file-cache
%patch17 -p1 -b .idprime
%patch18 -p1 -b .CVE-2023-2977
%patch19 -p1 -b .reader-removal
%patch20 -p1 -b .cache-offsets
%patch21 -p1 -b .pin-bypass
%patch22 -p1 -b .pkcs15init
%patch23 -p1 -b .constant-time-pkcs1.5
cp -p src/pkcs15init/README ./README.pkcs15init
cp -p src/scconf/README.scconf .
@ -80,6 +140,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 +184,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 +249,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 +284,38 @@ fi
%changelog
* Thu Feb 08 2024 Veronika Hanulikova <vhanulik@redhat.com> - 0.20.0-8
- Fix CVE-2023-5992: Side-channel leaks while stripping encryption PKCS#1.5 padding
* Thu Nov 30 2023 Jakub Jelen <jjelen@redhat.com> - 0.20.0-7
- Fix file caching with different offsets (RHEL-4077)
- Fix CVE-2023-40660: Potential PIN bypass
- Fix CVE-2023-40661: Dynamic analyzers reports in pkcs15init
- Fix CVE-2023-5992: Marvin: Side-channel leaks while stripping encryption PKCS#1.5 padding
* Tue Jul 11 2023 Jakub Jelen <jjelen@redhat.com> - 0.20.0-6
- Fix introduced issues tagged by coverity (RHEL-765)
* Thu Jun 15 2023 Jakub Jelen <jjelen@redhat.com> - 0.20.0-5
- Avoid potential crash because of missing list terminator (#2196234)
- Fix CVE-2023-2977: potential buffer overrun in pkcs15 cardos_have_verifyrc_package (#2211093)
- Backport upstream changes regarding to reader removal (#2097048)
* Fri Nov 20 2020 Jakub Jelen <jjelen@redhat.com> - 0.20.0-4
- Use file cache by default (#1892810)
- Avoid calloc with 0 argument (#1895401)
* Tue Oct 20 2020 Jakub Jelen <jjelen@redhat.com> - 0.20.0-3
- Support PIN change for HID Alt tokens (#1830901)
- Fix CVE-2020-26570, CVE-2020-26571 and CVE-2020-26572
- Fix right padding of token labels of some cards (#1877973)
* 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)