diff --git a/appveyor.yml b/appveyor.yml
index 01762cb3..bf528b20 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -82,7 +82,10 @@ build_script:
# build libeac.lib as a static library
xcopy C:\openpace C:\openpace-${env:OPENSSL_PF} /e /i /y /s
cd C:\openpace-${env:OPENSSL_PF}\src
- cl /IC:\OpenSSL-${env:OPENSSL_PF}\include /I. /DX509DIR=\`"/\`" /DCVCDIR=\`"/\`" /W3 /D_CRT_SECURE_NO_DEPRECATE /DWIN32_LEAN_AND_MEAN /GS /MT /DHAVE_ASN1_STRING_GET0_DATA=1 /DHAVE_DECL_OPENSSL_ZALLOC=1 /DHAVE_DH_GET0_KEY=1 /DHAVE_DH_GET0_PQG=1 /DHAVE_DH_SET0_KEY=1 /DHAVE_DH_SET0_PQG=1 /DHAVE_ECDSA_SIG_GET0=1 /DHAVE_ECDSA_SIG_SET0=1 /DHAVE_EC_KEY_METHOD=1 /DHAVE_RSA_GET0_KEY=1 /DHAVE_RSA_SET0_KEY=1 /c ca_lib.c cv_cert.c cvc_lookup.c x509_lookup.c eac_asn1.c eac.c eac_ca.c eac_dh.c eac_ecdh.c eac_kdf.c eac_lib.c eac_print.c eac_util.c misc.c pace.c pace_lib.c pace_mappings.c ri.c ri_lib.c ta.c ta_lib.c objects.c ssl_compat.c
+ # OpenSSL 1.1.0
+ #cl /IC:\OpenSSL-${env:OPENSSL_PF}\include /I. /DX509DIR=\`"/\`" /DCVCDIR=\`"/\`" /W3 /D_CRT_SECURE_NO_DEPRECATE /DWIN32_LEAN_AND_MEAN /GS /MT /DHAVE_ASN1_STRING_GET0_DATA=1 /DHAVE_DECL_OPENSSL_ZALLOC=1 /DHAVE_DH_GET0_KEY=1 /DHAVE_DH_GET0_PQG=1 /DHAVE_DH_SET0_KEY=1 /DHAVE_DH_SET0_PQG=1 /DHAVE_ECDSA_SIG_GET0=1 /DHAVE_ECDSA_SIG_SET0=1 /DHAVE_EC_KEY_METHOD=1 /DHAVE_RSA_GET0_KEY=1 /DHAVE_RSA_SET0_KEY=1 /c ca_lib.c cv_cert.c cvc_lookup.c x509_lookup.c eac_asn1.c eac.c eac_ca.c eac_dh.c eac_ecdh.c eac_kdf.c eac_lib.c eac_print.c eac_util.c misc.c pace.c pace_lib.c pace_mappings.c ri.c ri_lib.c ta.c ta_lib.c objects.c ssl_compat.c
+ # OpenSSL 1.0.2
+ cl /IC:\OpenSSL-${env:OPENSSL_PF}\include /I. /DX509DIR=\`"/\`" /DCVCDIR=\`"/\`" /W3 /D_CRT_SECURE_NO_DEPRECATE /DWIN32_LEAN_AND_MEAN /GS /MT /c ca_lib.c cv_cert.c cvc_lookup.c x509_lookup.c eac_asn1.c eac.c eac_ca.c eac_dh.c eac_ecdh.c eac_kdf.c eac_lib.c eac_print.c eac_util.c misc.c pace.c pace_lib.c pace_mappings.c ri.c ri_lib.c ta.c ta_lib.c objects.c ssl_compat.c
lib /out:libeac.lib ca_lib.obj cv_cert.obj cvc_lookup.obj x509_lookup.obj eac_asn1.obj eac.obj eac_ca.obj eac_dh.obj eac_ecdh.obj eac_kdf.obj eac_lib.obj eac_print.obj eac_util.obj misc.obj pace.obj pace_lib.obj pace_mappings.obj ri.obj ri_lib.obj ta.obj ta_lib.obj objects.obj ssl_compat.obj
cd C:\projects\OpenSC
}
diff --git a/configure.ac b/configure.ac
index bbedd37c..3cdd4342 100644
--- a/configure.ac
+++ b/configure.ac
@@ -862,7 +862,11 @@ if test "${enable_sm}" = "yes"; then
fi
if test "${with_pkcs11_provider}" = "detect"; then
- DEFAULT_PKCS11_PROVIDER="opensc-pkcs11${DYN_LIB_EXT}"
+ if test "${WIN32}" != "yes"; then
+ DEFAULT_PKCS11_PROVIDER="opensc-pkcs11${DYN_LIB_EXT}"
+ else
+ DEFAULT_PKCS11_PROVIDER="%PROGRAMFILES%\\\OpenSC Project\\\OpenSC\\\pkcs11\\\opensc-pkcs11.dll"
+ fi
else
DEFAULT_PKCS11_PROVIDER="${with_pkcs11_provider}"
fi
diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml
index 471b9b4d..037c9551 100644
--- a/doc/tools/pkcs11-tool.1.xml
+++ b/doc/tools/pkcs11-tool.1.xml
@@ -71,6 +71,14 @@
Hash some data.
+
+
+ mechanism
+
+ Specify hash algorithm used with
+ RSA-PKCS-PSS signature. Default is SHA-1.
+
+
id,
@@ -116,7 +124,7 @@
- specification
+ specification
Specify the type and length of the key to create, for example rsa:1024 or EC:prime256v1.
@@ -212,6 +220,17 @@
of mechanisms supported by your token.
+
+
+ function
+
+ Use the specified Message Generation
+ Function (MGF) function
+ for RSA-PSS signatures. Supported arguments are MGF1-SHA1
+ to MGF1-SHA512 if supported by the driver.
+ The default is based on the hash selection.
+
+
mod
@@ -309,6 +328,17 @@
Derive a secret key using another key and some data.
+
+
+ bytes
+
+ Specify how many bytes of salt should
+ be used in RSA-PSS signatures. Accepts two special values:
+ "-1" means salt length equals to digest length,
+ "-2" means use maximum permissible length.
+ Default is digest length (-1).
+
+
id
diff --git a/etc/opensc.conf.in b/etc/opensc.conf.in
index 96615160..c24d65f9 100644
--- a/etc/opensc.conf.in
+++ b/etc/opensc.conf.in
@@ -1160,6 +1160,11 @@ app tokend {
# Default: 300
#
# score = 10;
+
+ # Tokend ignore to read PIN protected certificate that is set SC_PKCS15_CO_FLAG_PRIVATE flag.
+ # Default: true
+ #
+ # ignore_private_certificate = false;
}
}
diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c
index ed15ba0a..82f5c786 100644
--- a/src/libopensc/card-cac.c
+++ b/src/libopensc/card-cac.c
@@ -390,9 +390,7 @@ static int cac_apdu_io(sc_card_t *card, int ins, int p1, int p2,
goto err;
}
- if (apdu.sw1 == 0x61) {
- r = sc_check_sw(card, apdu.sw1, apdu.sw2);
- }
+ r = sc_check_sw(card, apdu.sw1, apdu.sw2);
if (r < 0) {
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Card returned error ");
@@ -606,9 +604,14 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx,
/* SPICE smart card emulator only presents CAC-1 cards with the old CAC-1 interface as
* certs. If we are a cac 1 card, use the old interface */
r = cac_cac1_get_certificate(card, &val, &val_len);
- if (r < 0)
+ if (r == SC_ERROR_INS_NOT_SUPPORTED) {
+ /* The CACv1 instruction is not recognized. Try with CACv2 */
+ card->type = SC_CARD_TYPE_CAC_II;
+ } else if (r < 0)
goto done;
+ }
+ if ((card->type == SC_CARD_TYPE_CAC_I) && (priv->object_type == CAC_OBJECT_TYPE_CERT)) {
r = cac_cac1_get_cert_tag(card, val_len, &tl, &tl_len);
if (r < 0)
goto done;
@@ -1106,6 +1109,7 @@ static int cac_select_file_by_type(sc_card_t *card, const sc_path_t *in_path, sc
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
if (apdu.sw1 == 0x6A && apdu.sw2 == 0x86) {
apdu.p2 = 0x00;
+ apdu.resplen = sizeof(buf);
if (sc_transmit_apdu(card, &apdu) == SC_SUCCESS)
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
}
diff --git a/src/libopensc/card-cardos.c b/src/libopensc/card-cardos.c
index 41e28835..07719173 100644
--- a/src/libopensc/card-cardos.c
+++ b/src/libopensc/card-cardos.c
@@ -59,6 +59,7 @@ static struct sc_atr_table cardos_atrs[] = {
/* CardOS v5.0 */
{ "3b:d2:18:00:81:31:fe:58:c9:01:14", NULL, NULL, SC_CARD_TYPE_CARDOS_V5_0, 0, NULL},
/* CardOS v5.3 */
+ { "3b:d2:18:00:81:31:fe:58:c9:02:17", NULL, NULL, SC_CARD_TYPE_CARDOS_V5_0, 0, NULL},
{ "3b:d2:18:00:81:31:fe:58:c9:03:16", NULL, NULL, SC_CARD_TYPE_CARDOS_V5_0, 0, NULL},
{ NULL, NULL, NULL, 0, 0, NULL }
};
@@ -171,7 +172,7 @@ static int cardos_init(sc_card_t *card)
sc_apdu_t apdu;
u8 rbuf[2];
- card->name = "CardOS M4";
+ card->name = "Atos CardOS";
card->cla = 0x00;
/* Set up algorithm info. */
diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c
index 84ab6456..7feab598 100644
--- a/src/libopensc/card-epass2003.c
+++ b/src/libopensc/card-epass2003.c
@@ -98,6 +98,8 @@ typedef struct epass2003_exdata_st {
unsigned char sk_enc[16]; /* encrypt session key */
unsigned char sk_mac[16]; /* mac session key */
unsigned char icv_mac[16]; /* instruction counter vector(for sm) */
+ unsigned char currAlg; /* current Alg */
+ unsigned int ecAlgFlags; /* Ec Alg mechanism type*/
} epass2003_exdata;
#define REVERSE_ORDER4(x) ( \
@@ -170,6 +172,7 @@ static const struct sc_card_error epass2003_errors[] = {
static int epass2003_transmit_apdu(struct sc_card *card, struct sc_apdu *apdu);
static int epass2003_select_file(struct sc_card *card, const sc_path_t * in_path, sc_file_t ** file_out);
int epass2003_refresh(struct sc_card *card);
+static int hash_data(const unsigned char *data, size_t datalen, unsigned char *hash, unsigned int mechanismType);
static int
epass2003_check_sw(struct sc_card *card, unsigned int sw1, unsigned int sw2)
@@ -403,6 +406,12 @@ sha1_digest(const unsigned char *input, size_t length, unsigned char *output)
return openssl_dig(EVP_sha1(), input, length, output);
}
+static int
+sha256_digest(const unsigned char *input, size_t length, unsigned char *output)
+{
+ return openssl_dig(EVP_sha256(), input, length, output);
+}
+
static int
gen_init_key(struct sc_card *card, unsigned char *key_enc, unsigned char *key_mac,
@@ -1140,6 +1149,7 @@ static int
epass2003_init(struct sc_card *card)
{
unsigned int flags;
+ unsigned int ext_flags;
unsigned char data[SC_MAX_APDU_BUFFER_SIZE] = { 0 };
size_t datalen = SC_MAX_APDU_BUFFER_SIZE;
epass2003_exdata *exdata = NULL;
@@ -1192,6 +1202,11 @@ epass2003_init(struct sc_card *card)
_sc_card_add_rsa_alg(card, 1024, flags, 0);
_sc_card_add_rsa_alg(card, 2048, flags, 0);
+ //set EC Alg Flags
+ flags = SC_ALGORITHM_ONBOARD_KEY_GEN|SC_ALGORITHM_ECDSA_HASH_SHA1|SC_ALGORITHM_ECDSA_HASH_SHA256|SC_ALGORITHM_ECDSA_HASH_NONE|SC_ALGORITHM_ECDSA_RAW;
+ ext_flags = 0;
+ _sc_card_add_ec_alg(card, 256, flags, ext_flags, NULL);
+
card->caps = SC_CARD_CAP_RNG | SC_CARD_CAP_APDU_EXT;
LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
@@ -1561,6 +1576,13 @@ epass2003_set_security_env(struct sc_card *card, const sc_security_env_t * env,
u8 *p;
unsigned short fid = 0;
int r, locked = 0;
+ epass2003_exdata *exdata = NULL;
+
+ if (!card->drv_data)
+ return SC_ERROR_INVALID_ARGUMENTS;
+
+ exdata = (epass2003_exdata *)card->drv_data;
+ exdata->currAlg = SC_ALGORITHM_RSA; //default algorithm
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0);
switch (env->operation) {
@@ -1590,6 +1612,28 @@ epass2003_set_security_env(struct sc_card *card, const sc_security_env_t * env,
apdu.lc = r;
apdu.datalen = r;
apdu.data = sbuf;
+
+ if (env->algorithm == SC_ALGORITHM_EC)
+ {
+ apdu.p2 = 0xB6;
+ exdata->currAlg = SC_ALGORITHM_EC;
+ if(env->algorithm_flags | SC_ALGORITHM_ECDSA_HASH_SHA1)
+ {
+ sbuf[2] = 0x91;
+ exdata->ecAlgFlags = SC_ALGORITHM_ECDSA_HASH_SHA1;
+ }
+ else if (env->algorithm_flags | SC_ALGORITHM_ECDSA_HASH_SHA256)
+ {
+ sbuf[2] = 0x92;
+ exdata->ecAlgFlags = SC_ALGORITHM_ECDSA_HASH_SHA256;
+ }
+ else
+ {
+ sc_log(card->ctx, "%0x Alg Not Support! ", env->algorithm_flags);
+ goto err;
+ }
+ }
+
if (se_num > 0) {
r = sc_lock(card);
LOG_TEST_RET(card->ctx, r, "sc_lock() failed");
@@ -1640,7 +1684,55 @@ static int epass2003_decipher(struct sc_card *card, const u8 * data, size_t data
struct sc_apdu apdu;
u8 rbuf[SC_MAX_APDU_BUFFER_SIZE] = { 0 };
u8 sbuf[SC_MAX_APDU_BUFFER_SIZE] = { 0 };
+ epass2003_exdata *exdata = NULL;
+
+ LOG_FUNC_CALLED(card->ctx);
+
+ if (!card->drv_data)
+ return SC_ERROR_INVALID_ARGUMENTS;
+
+ exdata = (epass2003_exdata *)card->drv_data;
+ if(exdata->currAlg == SC_ALGORITHM_EC)
+ {
+ unsigned char hash[HASH_LEN] = { 0 };
+ if(exdata->ecAlgFlags | SC_ALGORITHM_ECDSA_HASH_SHA1)
+ {
+ hash_data(data, datalen, hash, SC_ALGORITHM_ECDSA_HASH_SHA1);
+ sc_format_apdu(card, &apdu, SC_APDU_CASE_3,0x2A, 0x9E, 0x9A);
+ memset(sbuf, 0, sizeof(sbuf));
+ memcpy(sbuf, hash, 0x14);
+ apdu.data = sbuf;
+ apdu.lc = 0x14;
+ apdu.datalen = 0x14;
+ }
+ else if (exdata->ecAlgFlags | SC_ALGORITHM_ECDSA_HASH_SHA256)
+ {
+ hash_data(data, datalen, hash, SC_ALGORITHM_ECDSA_HASH_SHA256);
+ sc_format_apdu(card, &apdu, SC_APDU_CASE_3,0x2A, 0x9E, 0x9A);
+ memset(sbuf, 0, sizeof(sbuf));
+ memcpy(sbuf, hash, 0x20);
+ apdu.data = sbuf;
+ apdu.lc = 0x20;
+ apdu.datalen = 0x20;
+ }
+ else
+ {
+ return SC_ERROR_NOT_SUPPORTED;
+ }
+ apdu.resp = rbuf;
+ apdu.resplen = sizeof(rbuf);
+ apdu.le = 0;
+
+ r = sc_transmit_apdu_t(card, &apdu);
+ LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
+ if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
+ size_t len = apdu.resplen > outlen ? outlen : apdu.resplen;
+ memcpy(out, apdu.resp, len);
+ LOG_FUNC_RETURN(card->ctx, len);
+ }
+ LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2));
+ }
sc_format_apdu(card, &apdu, SC_APDU_CASE_4_EXT, 0x2A, 0x80, 0x86);
apdu.resp = rbuf;
apdu.resplen = sizeof(rbuf);
@@ -1862,11 +1954,13 @@ epass2003_construct_fci(struct sc_card *card, const sc_file_t * file,
}
else if (file->type == SC_FILE_TYPE_INTERNAL_EF) {
- if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_CRT) {
+ if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_CRT ||
+ file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_CRT) {
buf[0] = 0x11;
buf[1] = 0x00;
}
- else if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC) {
+ else if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC ||
+ file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC) {
buf[0] = 0x12;
buf[1] = 0x00;
}
@@ -1903,7 +1997,9 @@ epass2003_construct_fci(struct sc_card *card, const sc_file_t * file,
}
else if (file->type == SC_FILE_TYPE_INTERNAL_EF) {
if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_CRT ||
- file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC) {
+ file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC||
+ file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_CRT||
+ file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC) {
buf[0] = (file->size >> 8) & 0xFF;
buf[1] = file->size & 0xFF;
sc_asn1_put_tag(0x85, buf, 2, p, *outlen - (p - out), &p);
@@ -1942,13 +2038,14 @@ epass2003_construct_fci(struct sc_card *card, const sc_file_t * file,
ops[3] = SC_AC_OP_DELETE;
}
else if (file->type == SC_FILE_TYPE_INTERNAL_EF) {
- if (file->ef_structure ==
- SC_CARDCTL_OBERTHUR_KEY_RSA_CRT) {
+ if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_CRT ||
+ file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_CRT) {
ops[1] = SC_AC_OP_UPDATE;
ops[2] = SC_AC_OP_CRYPTO;
ops[3] = SC_AC_OP_DELETE;
}
- else if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC) {
+ else if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC||
+ file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC) {
ops[0] = SC_AC_OP_READ;
ops[1] = SC_AC_OP_UPDATE;
ops[2] = SC_AC_OP_CRYPTO;
@@ -1973,13 +2070,22 @@ epass2003_construct_fci(struct sc_card *card, const sc_file_t * file,
buf[ii] = rv;
}
sc_asn1_put_tag(0x86, buf, sizeof(ops), p, *outlen - (p - out), &p);
+ if(file->size == 256)
+ {
+ out[4]= 0x13;
+ }
}
/* VT ??? */
- if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC) {
+ if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC||
+ file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC) {
unsigned char data[2] = {0x00, 0x66};
sc_asn1_put_tag(0x87, data, sizeof(data), p, *outlen - (p - out), &p);
+ if(file->size == 256)
+ {
+ out[4]= 0x14;
+ }
}
out[1] = p - out - 2;
@@ -2129,19 +2235,36 @@ internal_write_rsa_key(struct sc_card *card, unsigned short fid, struct sc_pkcs1
static int
-hash_data(unsigned char *data, size_t datalen, unsigned char *hash)
+hash_data(const unsigned char *data, size_t datalen, unsigned char *hash, unsigned int mechanismType)
{
- unsigned char data_hash[24] = { 0 };
- size_t len = 0;
if ((NULL == data) || (NULL == hash))
return SC_ERROR_INVALID_ARGUMENTS;
- sha1_digest(data, datalen, data_hash);
+ if(mechanismType | SC_ALGORITHM_ECDSA_HASH_SHA1)
+ {
+ unsigned char data_hash[24] = { 0 };
+ size_t len = 0;
- len = REVERSE_ORDER4(datalen);
- memcpy(&data_hash[20], &len, 4);
- memcpy(hash, data_hash, 24);
+ sha1_digest(data, datalen, data_hash);
+ len = REVERSE_ORDER4(datalen);
+ memcpy(&data_hash[20], &len, 4);
+ memcpy(hash, data_hash, 24);
+ }
+ else if(mechanismType | SC_ALGORITHM_ECDSA_HASH_SHA256)
+ {
+ unsigned char data_hash[36] = { 0 };
+ size_t len = 0;
+
+ sha256_digest(data, datalen, data_hash);
+ len = REVERSE_ORDER4(datalen);
+ memcpy(&data_hash[32], &len, 4);
+ memcpy(hash, data_hash, 36);
+ }
+ else
+ {
+ return SC_ERROR_NOT_SUPPORTED;
+ }
return SC_SUCCESS;
}
@@ -2214,7 +2337,7 @@ internal_install_pin(struct sc_card *card, sc_epass2003_wkey_data * pin)
int r;
unsigned char hash[HASH_LEN] = { 0 };
- r = hash_data(pin->key_data.es_secret.key_val, pin->key_data.es_secret.key_len, hash);
+ r = hash_data(pin->key_data.es_secret.key_val, pin->key_data.es_secret.key_len, hash, SC_ALGORITHM_ECDSA_HASH_SHA1);
LOG_TEST_RET(card->ctx, r, "hash data failed");
r = install_secret_key(card, 0x04, pin->key_data.es_secret.kid,
@@ -2265,7 +2388,14 @@ epass2003_gen_key(struct sc_card *card, sc_epass2003_gen_key_data * data)
LOG_FUNC_CALLED(card->ctx);
- sbuf[0] = 0x01;
+ if(len == 256)
+ {
+ sbuf[0] = 0x02;
+ }
+ else
+ {
+ sbuf[0] = 0x01;
+ }
sbuf[1] = (u8) ((len >> 8) & 0xff);
sbuf[2] = (u8) (len & 0xff);
sbuf[3] = (u8) ((data->prkey_id >> 8) & 0xFF);
@@ -2285,6 +2415,10 @@ epass2003_gen_key(struct sc_card *card, sc_epass2003_gen_key_data * data)
/* read public key */
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xb4, 0x02, 0x00);
+ if(len == 256)
+ {
+ apdu.p1 = 0x00;
+ }
apdu.cla = 0x80;
apdu.lc = apdu.datalen = 2;
apdu.data = &sbuf[5];
@@ -2349,6 +2483,7 @@ epass2003_card_ctl(struct sc_card *card, unsigned long cmd, void *ptr)
{
LOG_FUNC_CALLED(card->ctx);
+ sc_log(card->ctx, "cmd is %0lx", cmd);
switch (cmd) {
case SC_CARDCTL_ENTERSAFE_WRITE_KEY:
return epass2003_write_key(card, (sc_epass2003_wkey_data *) ptr);
@@ -2474,7 +2609,7 @@ external_key_auth(struct sc_card *card, unsigned char kid,
r = sc_get_challenge(card, random, 8);
LOG_TEST_RET(card->ctx, r, "get challenge external_key_auth failed");
- r = hash_data(data, datalen, hash);
+ r = hash_data(data, datalen, hash, SC_ALGORITHM_ECDSA_HASH_SHA1);
LOG_TEST_RET(card->ctx, r, "hash data failed");
des3_encrypt_cbc(hash, HASH_LEN, iv, random, 8, tmp_data);
@@ -2501,7 +2636,7 @@ update_secret_key(struct sc_card *card, unsigned char ktype, unsigned char kid,
unsigned char tmp_data[256] = { 0 };
unsigned char maxtries = 0;
- r = hash_data(data, datalen, hash);
+ r = hash_data(data, datalen, hash, SC_ALGORITHM_ECDSA_HASH_SHA1);
LOG_TEST_RET(card->ctx, r, "hash data failed");
r = get_external_key_maxtries(card, &maxtries);
diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c
index 923cf3bd..a10de902 100644
--- a/src/libopensc/card-gids.c
+++ b/src/libopensc/card-gids.c
@@ -1879,13 +1879,13 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) {
u8 apduSetRandomResponse[256];
u8* randomR2 = apduSetRandomResponse+4;
u8 apduSendReponse[40 + 4] = {0x7C,0x2A,0x82,0x28};
- // according to the specification, the z size (z1||z2) should be 14 bytes
- // but because the buffer must be a multiple of the 3DES block size (8 bytes), 7 isn't working
u8 z1[8];
u8 buffer[16+16+8];
u8* buffer2 = apduSendReponse + 4;
int buffer2size = 40;
u8 apduSendResponseResponse[256];
+ u8 buffer3[16+16+8];
+ int buffer3size = 40;
sc_apdu_t apdu;
const EVP_CIPHER *cipher;
@@ -1923,8 +1923,10 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) {
SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return");
// compute the half size of the mutual authentication secret
- r = RAND_bytes(z1, sizeof(z1));
+ r = RAND_bytes(z1, 7);
SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to set computer random");
+ // set the padding
+ z1[7] = 0x80;
// Encrypt R2||R1||Z1
memcpy(buffer, randomR2, 16);
@@ -1963,6 +1965,47 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) {
r = sc_transmit_apdu(card, &apdu);
SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return");
+
+ if (apdu.resplen != 44)
+ {
+ sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Expecting a response len of 44 - found %d",(int) apdu.resplen);
+ SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL);
+ }
+ // init crypto
+ ctx = EVP_CIPHER_CTX_new();
+ if (ctx == NULL) {
+ SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL);
+ }
+ if (!EVP_DecryptInit(ctx, cipher, key, NULL)) {
+ EVP_CIPHER_CTX_free(ctx);
+ SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL);
+ }
+ EVP_CIPHER_CTX_set_padding(ctx,0);
+ if (!EVP_DecryptUpdate(ctx, buffer3, &buffer3size, apdu.resp + 4, apdu.resplen - 4)) {
+ sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "unable to decrypt data");
+ EVP_CIPHER_CTX_free(ctx);
+ SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_PIN_CODE_INCORRECT);
+ }
+ if(!EVP_DecryptFinal(ctx, buffer3+buffer3size, &buffer3size)) {
+ sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "unable to decrypt final data");
+ EVP_CIPHER_CTX_free(ctx);
+ SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_PIN_CODE_INCORRECT);
+ }
+ sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "data has been decrypted using the key");
+ if (memcmp(buffer3, randomR1, 16) != 0) {
+ sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "R1 doesn't match");
+ SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_PIN_CODE_INCORRECT);
+ }
+ if (memcmp(buffer3 + 16, randomR2, 16) != 0) {
+ sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "R2 doesn't match");
+ SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_PIN_CODE_INCORRECT);
+ }
+ if (buffer[39] != 0x80) {
+ sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Padding not found");
+ SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_PIN_CODE_INCORRECT);
+ }
+ EVP_CIPHER_CTX_free(ctx);
+ ctx = NULL;
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS);
#endif
diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c
index 9b97c18f..ea61db3c 100644
--- a/src/libopensc/card-iasecc.c
+++ b/src/libopensc/card-iasecc.c
@@ -264,6 +264,9 @@ iasecc_select_mf(struct sc_card *card, struct sc_file **file_out)
apdu.resplen = sizeof(apdu_resp);
apdu.resp = apdu_resp;
+ if (card->type == SC_CARD_TYPE_IASECC_MI2)
+ apdu.p2 = 0x04;
+
rv = sc_transmit_apdu(card, &apdu);
LOG_TEST_RET(card->ctx, rv, "APDU transmit failed");
rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
@@ -513,75 +516,21 @@ iasecc_init_oberthur(struct sc_card *card)
}
-static int
-iasecc_init_sagem(struct sc_card *card)
-{
- struct sc_context *ctx = card->ctx;
- unsigned int flags;
- int rv = 0;
-
- LOG_FUNC_CALLED(ctx);
-
- flags = IASECC_CARD_DEFAULT_FLAGS;
-
- _sc_card_add_rsa_alg(card, 1024, flags, 0x10001);
- _sc_card_add_rsa_alg(card, 2048, flags, 0x10001);
-
- card->caps = SC_CARD_CAP_RNG;
- card->caps |= SC_CARD_CAP_APDU_EXT;
- card->caps |= SC_CARD_CAP_USE_FCI_AC;
-
- rv = iasecc_parse_ef_atr(card);
- if (rv == SC_ERROR_FILE_NOT_FOUND) {
- rv = iasecc_select_mf(card, NULL);
- LOG_TEST_RET(ctx, rv, "MF selection error");
-
- rv = iasecc_parse_ef_atr(card);
- }
- LOG_TEST_RET(ctx, rv, "IASECC: ATR parse failed");
-
- LOG_FUNC_RETURN(ctx, SC_SUCCESS);
-}
-
-
-static int
-iasecc_init_amos(struct sc_card *card)
-{
- struct sc_context *ctx = card->ctx;
- unsigned int flags;
- int rv = 0;
-
- LOG_FUNC_CALLED(ctx);
-
- flags = IASECC_CARD_DEFAULT_FLAGS;
-
- _sc_card_add_rsa_alg(card, 1024, flags, 0x10001);
- _sc_card_add_rsa_alg(card, 2048, flags, 0x10001);
-
- card->caps = SC_CARD_CAP_RNG;
- card->caps |= SC_CARD_CAP_APDU_EXT;
- card->caps |= SC_CARD_CAP_USE_FCI_AC;
-
- rv = iasecc_parse_ef_atr(card);
- if (rv == SC_ERROR_FILE_NOT_FOUND) {
- rv = iasecc_select_mf(card, NULL);
- LOG_TEST_RET(ctx, rv, "MF selection error");
-
- rv = iasecc_parse_ef_atr(card);
- }
-
- LOG_TEST_RET(ctx, rv, "IASECC: ATR parse failed");
- LOG_FUNC_RETURN(ctx, SC_SUCCESS);
-}
-
static int
iasecc_mi_match(struct sc_card *card)
{
struct sc_context *ctx = card->ctx;
+ unsigned char resp[0x100];
+ size_t resp_len;
+ int rv = 0;
LOG_FUNC_CALLED(ctx);
- if (!card->ef_atr)
+ resp_len = sizeof(resp);
+ rv = iasecc_select_aid(card, &MIIASECC_AID, resp, &resp_len);
+ LOG_TEST_RET(ctx, rv, "IASECC: failed to select MI IAS/ECC applet");
+
+ if (!card->ef_atr)
card->ef_atr = calloc(1, sizeof(struct sc_ef_atr));
if (!card->ef_atr)
LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
@@ -592,13 +541,12 @@ iasecc_mi_match(struct sc_card *card)
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
}
+
static int
-iasecc_init_mi(struct sc_card *card)
+iasecc_init_amos_or_sagem(struct sc_card *card)
{
struct sc_context *ctx = card->ctx;
unsigned int flags;
- unsigned char resp[0x100];
- size_t resp_len;
int rv = 0;
LOG_FUNC_CALLED(ctx);
@@ -612,16 +560,27 @@ iasecc_init_mi(struct sc_card *card)
card->caps |= SC_CARD_CAP_APDU_EXT;
card->caps |= SC_CARD_CAP_USE_FCI_AC;
- resp_len = sizeof(resp);
- rv = iasecc_select_aid(card, &MIIASECC_AID, resp, &resp_len);
- LOG_TEST_RET(ctx, rv, "Could not select MI's AID");
+ if (card->type == SC_CARD_TYPE_IASECC_MI) {
+ rv = iasecc_mi_match(card);
+ if (rv)
+ card->type = SC_CARD_TYPE_IASECC_MI2;
+ else
+ LOG_FUNC_RETURN(ctx, SC_SUCCESS);
+ }
- rv = iasecc_mi_match(card);
- LOG_TEST_RET(ctx, rv, "Could not match MI's AID");
+ rv = iasecc_parse_ef_atr(card);
+ if (rv == SC_ERROR_FILE_NOT_FOUND) {
+ rv = iasecc_select_mf(card, NULL);
+ LOG_TEST_RET(ctx, rv, "MF selection error");
+
+ rv = iasecc_parse_ef_atr(card);
+ }
+ LOG_TEST_RET(ctx, rv, "IASECC: ATR parse failed");
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
}
+
static int
iasecc_init(struct sc_card *card)
{
@@ -642,11 +601,11 @@ iasecc_init(struct sc_card *card)
else if (card->type == SC_CARD_TYPE_IASECC_OBERTHUR)
rv = iasecc_init_oberthur(card);
else if (card->type == SC_CARD_TYPE_IASECC_SAGEM)
- rv = iasecc_init_sagem(card);
+ rv = iasecc_init_amos_or_sagem(card);
else if (card->type == SC_CARD_TYPE_IASECC_AMOS)
- rv = iasecc_init_amos(card);
+ rv = iasecc_init_amos_or_sagem(card);
else if (card->type == SC_CARD_TYPE_IASECC_MI)
- rv = iasecc_init_mi(card);
+ rv = iasecc_init_amos_or_sagem(card);
else
LOG_FUNC_RETURN(ctx, SC_ERROR_NO_CARD_SUPPORT);
@@ -950,7 +909,8 @@ iasecc_select_file(struct sc_card *card, const struct sc_path *path,
&& card->type != SC_CARD_TYPE_IASECC_OBERTHUR
&& card->type != SC_CARD_TYPE_IASECC_SAGEM
&& card->type != SC_CARD_TYPE_IASECC_AMOS
- && card->type != SC_CARD_TYPE_IASECC_MI)
+ && card->type != SC_CARD_TYPE_IASECC_MI
+ && card->type != SC_CARD_TYPE_IASECC_MI2)
LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Unsupported card");
if (lpath.type == SC_PATH_TYPE_FILE_ID) {
@@ -963,6 +923,8 @@ iasecc_select_file(struct sc_card *card, const struct sc_path *path,
apdu.p2 = 0x04;
if (card->type == SC_CARD_TYPE_IASECC_MI)
apdu.p2 = 0x04;
+ if (card->type == SC_CARD_TYPE_IASECC_MI2)
+ apdu.p2 = 0x04;
}
else if (lpath.type == SC_PATH_TYPE_FROM_CURRENT) {
apdu.p1 = 0x09;
@@ -972,6 +934,8 @@ iasecc_select_file(struct sc_card *card, const struct sc_path *path,
apdu.p2 = 0x04;
if (card->type == SC_CARD_TYPE_IASECC_MI)
apdu.p2 = 0x04;
+ if (card->type == SC_CARD_TYPE_IASECC_MI2)
+ apdu.p2 = 0x04;
}
else if (lpath.type == SC_PATH_TYPE_PARENT) {
apdu.p1 = 0x03;
@@ -982,6 +946,8 @@ iasecc_select_file(struct sc_card *card, const struct sc_path *path,
apdu.p1 = 0x04;
if (card->type == SC_CARD_TYPE_IASECC_AMOS)
apdu.p2 = 0x04;
+ if (card->type == SC_CARD_TYPE_IASECC_MI2)
+ apdu.p2 = 0x04;
}
else {
sc_log(ctx, "Invalid PATH type: 0x%X", lpath.type);
diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c
index 5a417913..fc741924 100644
--- a/src/libopensc/card-sc-hsm.c
+++ b/src/libopensc/card-sc-hsm.c
@@ -68,62 +68,62 @@ static struct sc_atr_table sc_hsm_atrs[] = {
{
"3B:84:80:01:47:6f:49:44:00",
"FF:FF:FF:FF:FF:FF:FF:FF:00",
- "GoID", SC_CARD_TYPE_SC_HSM_SOC, 0, NULL
+ "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL
},
{
"3B:85:80:01:47:6f:49:44:00:00",
"FF:FF:FF:FF:FF:FF:FF:FF:00:00",
- "GoID", SC_CARD_TYPE_SC_HSM_SOC, 0, NULL
+ "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL
},
{
"3B:86:80:01:47:6f:49:44:00:00:00",
"FF:FF:FF:FF:FF:FF:FF:FF:00:00:00",
- "GoID", SC_CARD_TYPE_SC_HSM_SOC, 0, NULL
+ "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL
},
{
"3B:87:80:01:47:6f:49:44:00:00:00:00",
"FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00",
- "GoID", SC_CARD_TYPE_SC_HSM_SOC, 0, NULL
+ "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL
},
{
"3B:88:80:01:47:6f:49:44:00:00:00:00:00",
"FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00",
- "GoID", SC_CARD_TYPE_SC_HSM_SOC, 0, NULL
+ "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL
},
{
"3B:89:80:01:47:6f:49:44:00:00:00:00:00:00",
"FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00",
- "GoID", SC_CARD_TYPE_SC_HSM_SOC, 0, NULL
+ "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL
},
{
"3B:8a:80:01:47:6f:49:44:00:00:00:00:00:00:00",
"FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00",
- "GoID", SC_CARD_TYPE_SC_HSM_SOC, 0, NULL
+ "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL
},
{
"3B:8b:80:01:47:6f:49:44:00:00:00:00:00:00:00:00",
"FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00",
- "GoID", SC_CARD_TYPE_SC_HSM_SOC, 0, NULL
+ "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL
},
{
"3B:8c:80:01:47:6f:49:44:00:00:00:00:00:00:00:00:00",
"FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00:00",
- "GoID", SC_CARD_TYPE_SC_HSM_SOC, 0, NULL
+ "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL
},
{
"3B:8d:80:01:47:6f:49:44:00:00:00:00:00:00:00:00:00:00",
"FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00:00:00",
- "GoID", SC_CARD_TYPE_SC_HSM_SOC, 0, NULL
+ "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL
},
{
"3B:8e:80:01:47:6f:49:44:00:00:00:00:00:00:00:00:00:00:00",
"FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00:00:00:00",
- "GoID", SC_CARD_TYPE_SC_HSM_SOC, 0, NULL
+ "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL
},
{
"3B:8f:80:01:47:6f:49:44:00:00:00:00:00:00:00:00:00:00:00:00",
"FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00:00:00:00:00",
- "GoID", SC_CARD_TYPE_SC_HSM_SOC, 0, NULL
+ "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL
},
{NULL, NULL, NULL, 0, 0, NULL}
};
@@ -305,30 +305,62 @@ static int sc_hsm_soc_change(sc_card_t *card, struct sc_pin_cmd_data *data,
sc_path_t path;
int r;
- /* Select MinBioClient */
- r = sc_hsm_soc_select_minbioclient(card);
- LOG_TEST_RET(card->ctx, r, "Could not select MinBioClient application");
+ if (card->type == SC_CARD_TYPE_SC_HSM_SOC) {
+ /* Select MinBioClient */
+ r = sc_hsm_soc_select_minbioclient(card);
+ LOG_TEST_RET(card->ctx, r, "Could not select MinBioClient application");
- /* verify PIN */
- sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x20, 0x00, 0x80);
- r = sc_transmit_apdu(card, &apdu);
- LOG_TEST_GOTO_ERR(card->ctx, r, "APDU transmit failed");
- r = sc_check_sw(card, apdu.sw1, apdu.sw2);
- LOG_TEST_GOTO_ERR(card->ctx, r, "Could not verify PIN");
+ /* verify PIN */
+ sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x20, 0x00, 0x80);
+ r = sc_transmit_apdu(card, &apdu);
+ LOG_TEST_GOTO_ERR(card->ctx, r, "APDU transmit failed");
+ r = sc_check_sw(card, apdu.sw1, apdu.sw2);
+ LOG_TEST_GOTO_ERR(card->ctx, r, "Could not verify PIN");
- /* change PIN */
- sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x24, 0x01, 0x80);
- r = sc_transmit_apdu(card, &apdu);
- LOG_TEST_GOTO_ERR(card->ctx, r, "APDU transmit failed");
- r = sc_check_sw(card, apdu.sw1, apdu.sw2);
- LOG_TEST_GOTO_ERR(card->ctx, r, "Could not change PIN");
+ /* change PIN */
+ sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x24, 0x01, 0x80);
+ r = sc_transmit_apdu(card, &apdu);
+ LOG_TEST_GOTO_ERR(card->ctx, r, "APDU transmit failed");
+ r = sc_check_sw(card, apdu.sw1, apdu.sw2);
+ LOG_TEST_GOTO_ERR(card->ctx, r, "Could not change PIN");
+ } else {
+#ifdef ENABLE_SM
+ unsigned sm_mode = card->sm_ctx.sm_mode;
+#endif
+
+ /* verify PIN */
+ sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x20, 0x00, 0x85);
+ apdu.cla = 0x80;
+ r = sc_transmit_apdu(card, &apdu);
+ LOG_TEST_GOTO_ERR(card->ctx, r, "APDU transmit failed");
+
+#ifdef ENABLE_SM
+ /* temporary disable SM, change reference data does not reach the applet */
+ card->sm_ctx.sm_mode = SM_MODE_NONE;
+#endif
+
+ /* change PIN */
+ sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x24, 0x01, 0x85);
+ apdu.cla = 0x80;
+ r = sc_transmit_apdu(card, &apdu);
+#ifdef ENABLE_SM
+ /* restore SM if possible */
+ card->sm_ctx.sm_mode = sm_mode;
+#endif
+ LOG_TEST_GOTO_ERR(card->ctx, r, "APDU transmit failed");
+ r = sc_check_sw(card, apdu.sw1, apdu.sw2);
+ LOG_TEST_GOTO_ERR(card->ctx, r, "Could not change PIN");
+ }
err:
- /* Select SC-HSM */
- sc_path_set(&path, SC_PATH_TYPE_DF_NAME, sc_hsm_aid.value, sc_hsm_aid.len, 0, 0);
- LOG_TEST_RET(card->ctx,
- sc_hsm_select_file_ex(card, &path, 1, NULL),
- "Could not select SmartCard-HSM application");
+ if (card->type == SC_CARD_TYPE_SC_HSM_SOC) {
+ /* Select SC-HSM */
+ sc_path_set(&path, SC_PATH_TYPE_DF_NAME,
+ sc_hsm_aid.value, sc_hsm_aid.len, 0, 0);
+ LOG_TEST_RET(card->ctx,
+ sc_hsm_select_file_ex(card, &path, 1, NULL),
+ "Could not select SmartCard-HSM application");
+ }
return r;
}
@@ -340,6 +372,10 @@ static int sc_hsm_soc_unblock(sc_card_t *card, struct sc_pin_cmd_data *data,
sc_path_t path;
int r;
+ if (card->type == SC_CARD_TYPE_SC_HSM_GOID) {
+ return SC_ERROR_NOT_SUPPORTED;
+ }
+
/* Select MinBioClient */
r = sc_hsm_soc_select_minbioclient(card);
LOG_TEST_RET(card->ctx, r, "Could not select MinBioClient application");
@@ -375,19 +411,24 @@ static int sc_hsm_soc_biomatch(sc_card_t *card, struct sc_pin_cmd_data *data,
u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
int r;
- sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x20, 0x00, 0x85);
- apdu.cla = 0x80;
- apdu.data = (unsigned char*)"\x7F\x24\x00";
- apdu.datalen = 3;
- apdu.lc = 3;
- apdu.resplen = 0;
+ if (card->type == SC_CARD_TYPE_SC_HSM_SOC) {
+ sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x20, 0x00, 0x85);
+ apdu.cla = 0x80;
+ apdu.data = (unsigned char*)"\x7F\x24\x00";
+ apdu.datalen = 3;
+ apdu.lc = 3;
+ apdu.resplen = 0;
- r = sc_transmit_apdu(card, &apdu);
- LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
- /* ignore the actual status bytes */
+ r = sc_transmit_apdu(card, &apdu);
+ LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
+ /* ignore the actual status bytes */
+ }
/* JCOP's SM accelerator is incapable of using case 1 APDU in SM */
sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0x20, 0x00, 0x81);
+ if (card->type == SC_CARD_TYPE_SC_HSM_GOID) {
+ apdu.cla = 0x80;
+ }
apdu.resp = rbuf;
apdu.resplen = sizeof rbuf;
r = sc_transmit_apdu(card, &apdu);
@@ -564,8 +605,9 @@ static int sc_hsm_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data,
/* For contactless cards always establish a secure channel before PIN
* verification. Also, Session PIN generation requires SM. */
- if ((card->type == SC_CARD_TYPE_SC_HSM_SOC || card->reader->uid.len
- || cmd == SC_PIN_CMD_GET_SESSION_PIN)
+ if ((card->type == SC_CARD_TYPE_SC_HSM_SOC
+ || card->type == SC_CARD_TYPE_SC_HSM_GOID
+ || card->reader->uid.len || cmd == SC_PIN_CMD_GET_SESSION_PIN)
&& (data->cmd != SC_PIN_CMD_GET_INFO)
#ifdef ENABLE_SM
&& card->sm_ctx.sm_mode != SM_MODE_TRANSMIT
@@ -1501,7 +1543,7 @@ static int sc_hsm_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr)
static int sc_hsm_init(struct sc_card *card)
{
-#ifdef _WIN32
+#if defined(ENABLE_OPENPACE) && defined(_WIN32)
char expanded_val[PATH_MAX];
size_t expanded_len = PATH_MAX;
#endif
@@ -1575,7 +1617,8 @@ static int sc_hsm_init(struct sc_card *card)
}
card->max_send_size = 1431; // 1439 buffer size - 8 byte TLV because of odd ins in UPDATE BINARY
- if (card->type == SC_CARD_TYPE_SC_HSM_SOC) {
+ if (card->type == SC_CARD_TYPE_SC_HSM_SOC
+ || card->type == SC_CARD_TYPE_SC_HSM_GOID) {
card->max_recv_size = 0x0630; // SoC Proxy forces this limit
} else {
card->max_recv_size = 0; // Card supports sending with extended length APDU and without limit
diff --git a/src/libopensc/cardctl.h b/src/libopensc/cardctl.h
index 9a58427b..b647b053 100644
--- a/src/libopensc/cardctl.h
+++ b/src/libopensc/cardctl.h
@@ -490,7 +490,9 @@ enum SC_CARDCTL_OBERTHUR_KEY_TYPE {
SC_CARDCTL_OBERTHUR_KEY_RSA_SFM,
SC_CARDCTL_OBERTHUR_KEY_RSA_CRT,
SC_CARDCTL_OBERTHUR_KEY_DSA_PUBLIC,
- SC_CARDCTL_OBERTHUR_KEY_DSA_PRIVATE
+ SC_CARDCTL_OBERTHUR_KEY_DSA_PRIVATE,
+ SC_CARDCTL_OBERTHUR_KEY_EC_CRT,
+ SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC
};
struct sc_cardctl_oberthur_genkey_info {
diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h
index f7c78dd8..0cc7650e 100644
--- a/src/libopensc/cards.h
+++ b/src/libopensc/cards.h
@@ -200,10 +200,12 @@ enum {
SC_CARD_TYPE_IASECC_SAGEM,
SC_CARD_TYPE_IASECC_AMOS,
SC_CARD_TYPE_IASECC_MI,
+ SC_CARD_TYPE_IASECC_MI2,
/* SmartCard-HSM */
SC_CARD_TYPE_SC_HSM = 26000,
SC_CARD_TYPE_SC_HSM_SOC = 26001,
+ SC_CARD_TYPE_SC_HSM_GOID = 26002,
/* Spanish DNIe card */
SC_CARD_TYPE_DNIE_BASE = 27000,
diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h
index bd2eb500..209e4aba 100644
--- a/src/libopensc/opensc.h
+++ b/src/libopensc/opensc.h
@@ -163,6 +163,7 @@ extern "C" {
struct sc_supported_algo_info {
unsigned int reference;
unsigned int mechanism;
+ struct sc_object_id *parameters; /* OID for ECC, NULL for RSA */
unsigned int operations;
struct sc_object_id algo_id;
unsigned int algo_ref;
diff --git a/src/libopensc/pkcs15-cac.c b/src/libopensc/pkcs15-cac.c
index fa76ec34..fd463a9b 100644
--- a/src/libopensc/pkcs15-cac.c
+++ b/src/libopensc/pkcs15-cac.c
@@ -139,7 +139,7 @@ cac_alg_flags_from_algorithm(int algorithm)
/* map a cert usage and algorithm to public and private key usages */
static int
-cac_map_usage(unsigned long long cert_usage, int algorithm, unsigned int *pub_usage_ptr, unsigned int *pr_usage_ptr, int allow_nonrepudiation)
+cac_map_usage(unsigned int cert_usage, int algorithm, unsigned int *pub_usage_ptr, unsigned int *pr_usage_ptr, int allow_nonrepudiation)
{
unsigned int pub_usage = 0, pr_usage = 0;
unsigned int alg_flags = cac_alg_flags_from_algorithm(algorithm);
@@ -184,7 +184,7 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card)
};
/* oid for key usage */
static const struct sc_object_id usage_type = {{ 2, 5, 29, 15, -1 }};
- unsigned long long usage;
+ unsigned int usage;
/*
@@ -323,8 +323,8 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card)
prkey_info.path.len += 2;
}
pubkey_info.native = 1;
- pubkey_info.key_reference = ((int)obj_info.id.value[0]) << 8 || obj_info.id.value[1];
- prkey_info.key_reference = ((int)obj_info.id.value[0]) << 8 || obj_info.id.value[1];
+ pubkey_info.key_reference = ((int)obj_info.id.value[0]) << 8 | obj_info.id.value[1];
+ prkey_info.key_reference = ((int)obj_info.id.value[0]) << 8 | obj_info.id.value[1];
prkey_info.native = 1;
memcpy(cert_obj.label, obj_info.app_label, sizeof(obj_info.app_label));
@@ -401,7 +401,7 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card)
usage = 0xd9ULL; /* basic default usage */
}
cac_map_usage(usage, cert_out->key->algorithm, &pubkey_info.usage, &prkey_info.usage, 1);
- sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "cert %s: cert_usage=0x%llx, pub_usage=0x%x priv_usage=0x%x\n",
+ sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "cert %s: cert_usage=0x%x, pub_usage=0x%x priv_usage=0x%x\n",
sc_dump_hex(cert_info.id.value, cert_info.id.len),
usage, pubkey_info.usage, prkey_info.usage);
if (cert_out->key->algorithm != SC_ALGORITHM_RSA) {
diff --git a/src/libopensc/pkcs15-cert.c b/src/libopensc/pkcs15-cert.c
index 5a607e16..b7b16bb7 100644
--- a/src/libopensc/pkcs15-cert.c
+++ b/src/libopensc/pkcs15-cert.c
@@ -310,13 +310,13 @@ sc_pkcs15_get_extension(struct sc_context *ctx, struct sc_pkcs15_cert *cert,
int
sc_pkcs15_get_bitstring_extension(struct sc_context *ctx,
struct sc_pkcs15_cert *cert, const struct sc_object_id *type,
- unsigned long long *value, int *is_critical)
+ unsigned int *value, int *is_critical)
{
int r;
u8 *bit_string = NULL;
size_t bit_string_len=0, val_len = sizeof(*value);
struct sc_asn1_entry asn1_bit_string[] = {
- { "bitString", SC_ASN1_BIT_STRING, SC_ASN1_TAG_BIT_STRING, 0, value, &val_len },
+ { "bitString", SC_ASN1_BIT_FIELD, SC_ASN1_TAG_BIT_STRING, 0, value, &val_len },
{ NULL, 0, 0, 0, NULL, NULL }
};
diff --git a/src/libopensc/pkcs15-piv.c b/src/libopensc/pkcs15-piv.c
index d38d7ba7..73fc2d48 100644
--- a/src/libopensc/pkcs15-piv.c
+++ b/src/libopensc/pkcs15-piv.c
@@ -104,7 +104,7 @@ typedef struct common_key_info_st {
int pubkey_from_file;
int key_alg;
unsigned int pubkey_len;
- unsigned long long cert_keyUsage; /* x509 key usage as defined in certificate */
+ unsigned int cert_keyUsage; /* x509 key usage as defined in certificate */
int cert_keyUsage_present; /* 1 if keyUsage found in certificate */
int pub_usage;
int priv_usage;
@@ -359,7 +359,7 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card)
};
static const pindata pins[] = {
- { "01", "PIV Card Holder pin", "", 0x80,
+ { "01", "PIN", "", 0x80,
/* label, flag and ref will change if using global pin */
SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
8, 4, 8,
@@ -613,7 +613,7 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card)
char buf[SC_MAX_SERIALNR * 2 + 1];
common_key_info ckis[PIV_NUM_CERTS_AND_KEYS];
int follows_nist_fascn = 0;
-
+ char *token_name = NULL;
SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
@@ -765,6 +765,28 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card)
sc_pkcs15_free_certificate(cert_out);
continue;
}
+
+ /* set the token name to the name of the CN of the first certificate */
+ if (!token_name) {
+ u8 * cn_name = NULL;
+ size_t cn_len = 0;
+ static const struct sc_object_id cn_oid = {{ 2, 5, 4, 3, -1 }};
+ r = sc_pkcs15_get_name_from_dn(card->ctx, cert_out->subject,
+ cert_out->subject_len, &cn_oid, &cn_name, &cn_len);
+ if (r == SC_SUCCESS) {
+ token_name = malloc (cn_len+1);
+ if (!token_name) {
+ SC_FUNC_RETURN(card->ctx,
+ SC_ERROR_OUT_OF_MEMORY, r);
+ }
+ memcpy(token_name, cn_name, cn_len);
+ free(cn_name);
+ token_name[cn_len] = 0;
+ free(p15card->tokeninfo->label);
+ p15card->tokeninfo->label = token_name;
+ }
+ }
+
/*
* get keyUsage if present save in ckis[i]
* Will only use it if this in a non FED issued card
@@ -773,13 +795,11 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card)
if (follows_nist_fascn == 0) {
struct sc_object_id keyUsage_oid={{2,5,29,15,-1}};
- unsigned long long *value;
int r = 0;
- value = &ckis[i].cert_keyUsage;
r = sc_pkcs15_get_bitstring_extension(card->ctx, cert_out,
&keyUsage_oid,
- value, NULL);
+ &ckis[i].cert_keyUsage, NULL);
if ( r >= 0)
ckis[i].cert_keyUsage_present = 1;
/* TODO if no key usage, we could set all uses */
@@ -932,7 +952,7 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card)
pin_info.attrs.pin.reference = pin_ref;
pin_info.attrs.pin.flags &= ~SC_PKCS15_PIN_FLAG_LOCAL;
label = "Global PIN";
- }
+ }
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "DEE Adding pin %d label=%s",i, label);
strncpy(pin_obj.label, label, SC_PKCS15_MAX_LABEL_SIZE - 1);
pin_obj.flags = pins[i].obj_flags;
diff --git a/src/libopensc/pkcs15-sc-hsm.c b/src/libopensc/pkcs15-sc-hsm.c
index 26eaa058..dd428fac 100644
--- a/src/libopensc/pkcs15-sc-hsm.c
+++ b/src/libopensc/pkcs15-sc-hsm.c
@@ -606,13 +606,13 @@ static int sc_pkcs15emu_sc_hsm_add_prkd(sc_pkcs15_card_t * p15card, u8 keyid) {
/* Try to select a related EF containing the PKCS#15 description of the key */
len = sizeof efbin;
r = read_file(p15card, fid, efbin, &len, 1);
- LOG_TEST_RET(card->ctx, r, "Could not read EF.PRKD");
+ LOG_TEST_RET(card->ctx, r, "Skipping optional EF.PRKD");
ptr = efbin;
memset(&prkd, 0, sizeof(prkd));
r = sc_pkcs15_decode_prkdf_entry(p15card, &prkd, (const u8 **)&ptr, &len);
- LOG_TEST_RET(card->ctx, r, "Could not decode EF.PRKD");
+ LOG_TEST_RET(card->ctx, r, "Skipping optional EF.PRKD");
/* All keys require user PIN authentication */
prkd.auth_id.len = 1;
@@ -642,8 +642,6 @@ static int sc_pkcs15emu_sc_hsm_add_prkd(sc_pkcs15_card_t * p15card, u8 keyid) {
r = read_file(p15card, fid, efbin, &len, 0);
LOG_TEST_RET(card->ctx, r, "Could not read EF");
- LOG_TEST_RET(card->ctx, r, "Could not read EF");
-
if (efbin[0] == 0x67) { /* Decode CSR and create public key object */
sc_pkcs15emu_sc_hsm_add_pubkey(p15card, efbin, len, key_info, prkd.label);
free(key_info);
@@ -702,13 +700,13 @@ static int sc_pkcs15emu_sc_hsm_add_dcod(sc_pkcs15_card_t * p15card, u8 id) {
/* Try to select a related EF containing the PKCS#15 description of the data */
len = sizeof efbin;
r = read_file(p15card, fid, efbin, &len, 1);
- LOG_TEST_RET(card->ctx, r, "Could not read EF.DCOD");
+ LOG_TEST_RET(card->ctx, r, "Skipping optional EF.DCOD");
ptr = efbin;
memset(&data_obj, 0, sizeof(data_obj));
r = sc_pkcs15_decode_dodf_entry(p15card, &data_obj, &ptr, &len);
- LOG_TEST_RET(card->ctx, r, "Could not decode EF.DCOD");
+ LOG_TEST_RET(card->ctx, r, "Could not decode optional EF.DCOD");
data_info = (sc_pkcs15_data_info_t *)data_obj.data;
@@ -741,13 +739,13 @@ static int sc_pkcs15emu_sc_hsm_add_cd(sc_pkcs15_card_t * p15card, u8 id) {
/* Try to select a related EF containing the PKCS#15 description of the data */
len = sizeof efbin;
r = read_file(p15card, fid, efbin, &len, 1);
- LOG_TEST_RET(card->ctx, r, "Could not read EF.DCOD");
+ LOG_TEST_RET(card->ctx, r, "Skipping optional EF.DCOD");
ptr = efbin;
memset(&obj, 0, sizeof(obj));
r = sc_pkcs15_decode_cdf_entry(p15card, &obj, &ptr, &len);
- LOG_TEST_RET(card->ctx, r, "Could not decode EF.CD");
+ LOG_TEST_RET(card->ctx, r, "Skipping optional EF.CDOD");
cert_info = (sc_pkcs15_cert_info_t *)obj.data;
@@ -772,10 +770,10 @@ static int sc_pkcs15emu_sc_hsm_read_tokeninfo (sc_pkcs15_card_t * p15card)
/* Read token info */
len = sizeof efbin;
r = read_file(p15card, (u8 *) "\x2F\x03", efbin, &len, 1);
- LOG_TEST_RET(card->ctx, r, "Could not read EF.TokenInfo");
+ LOG_TEST_RET(card->ctx, r, "Skipping optional EF.TokenInfo");
r = sc_pkcs15_parse_tokeninfo(card->ctx, p15card->tokeninfo, efbin, len);
- LOG_TEST_RET(card->ctx, r, "Could not decode EF.TokenInfo");
+ LOG_TEST_RET(card->ctx, r, "Skipping optional EF.TokenInfo");
LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
}
@@ -835,7 +833,7 @@ static int sc_pkcs15emu_sc_hsm_init (sc_pkcs15_card_t * p15card)
} else {
len = sizeof efbin;
r = read_file(p15card, (u8 *) "\x2F\x02", efbin, &len, 1);
- LOG_TEST_RET(card->ctx, r, "Could not select EF.C_DevAut");
+ LOG_TEST_RET(card->ctx, r, "Skipping optional EF.C_DevAut");
/* save EF_C_DevAut for further use */
ptr = realloc(priv->EF_C_DevAut, len);
@@ -941,7 +939,8 @@ static int sc_pkcs15emu_sc_hsm_init (sc_pkcs15_card_t * p15card)
LOG_FUNC_RETURN(card->ctx, r);
- if (card->type == SC_CARD_TYPE_SC_HSM_SOC) {
+ if (card->type == SC_CARD_TYPE_SC_HSM_SOC
+ || card->type == SC_CARD_TYPE_SC_HSM_GOID) {
/* SC-HSM of this type always has a PIN-Pad */
r = SC_SUCCESS;
} else {
@@ -998,7 +997,8 @@ int sc_pkcs15emu_sc_hsm_init_ex(sc_pkcs15_card_t *p15card,
return sc_pkcs15emu_sc_hsm_init(p15card);
} else {
if (p15card->card->type != SC_CARD_TYPE_SC_HSM
- && p15card->card->type != SC_CARD_TYPE_SC_HSM_SOC) {
+ && p15card->card->type != SC_CARD_TYPE_SC_HSM_SOC
+ && p15card->card->type != SC_CARD_TYPE_SC_HSM_GOID) {
return SC_ERROR_WRONG_CARD;
}
return sc_pkcs15emu_sc_hsm_init(p15card);
diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c
index 2ce34b6c..ba99c8af 100644
--- a/src/libopensc/pkcs15.c
+++ b/src/libopensc/pkcs15.c
@@ -50,13 +50,19 @@ static const struct sc_asn1_entry c_asn1_twlabel[] = {
static const struct sc_asn1_entry c_asn1_algorithm_info[7] = {
{ "reference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL },
{ "algorithmPKCS#11", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL },
- { "parameters", SC_ASN1_NULL, SC_ASN1_TAG_NULL, 0, NULL, NULL },
+ { "parameters", SC_ASN1_CHOICE, 0, 0, NULL, NULL },
{ "supportedOperations",SC_ASN1_BIT_FIELD, SC_ASN1_TAG_BIT_STRING, 0, NULL, NULL },
{ "objId", SC_ASN1_OBJECT, SC_ASN1_TAG_OBJECT, SC_ASN1_OPTIONAL, NULL, NULL },
{ "algRef", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL }
};
+static const struct sc_asn1_entry c_asn1_algorithm_info_parameters[3] = {
+ { "PKCS15RSAParameters",SC_ASN1_NULL, SC_ASN1_TAG_NULL, 0, NULL, NULL },
+ { "PKCS15ECParameters", SC_ASN1_OBJECT, SC_ASN1_TAG_OBJECT, 0, NULL, NULL },
+ { NULL, 0, 0, 0, NULL, NULL }
+};
+
/*
* in src/libopensc/types.h SC_MAX_SUPPORTED_ALGORITHMS defined as 8
*/
@@ -134,9 +140,11 @@ int sc_pkcs15_parse_tokeninfo(sc_context_t *ctx,
u8 preferred_language[3];
size_t lang_length = sizeof(preferred_language);
struct sc_asn1_entry asn1_supported_algorithms[SC_MAX_SUPPORTED_ALGORITHMS + 1],
- asn1_algo_infos[SC_MAX_SUPPORTED_ALGORITHMS][7];
+ asn1_algo_infos[SC_MAX_SUPPORTED_ALGORITHMS][7],
+ asn1_algo_infos_parameters[SC_MAX_SUPPORTED_ALGORITHMS][3];
size_t reference_len = sizeof(ti->supported_algos[0].reference);
size_t mechanism_len = sizeof(ti->supported_algos[0].mechanism);
+ size_t parameter_len = sizeof(ti->supported_algos[0].parameters);
size_t operations_len = sizeof(ti->supported_algos[0].operations);
size_t algo_ref_len = sizeof(ti->supported_algos[0].algo_ref);
@@ -152,14 +160,22 @@ int sc_pkcs15_parse_tokeninfo(sc_context_t *ctx,
sc_format_asn1_entry(asn1_twlabel, label, &label_len, 0);
sc_copy_asn1_entry(c_asn1_profile_indication, asn1_profile_indication);
- for (ii=0; iisupported_algos[ii].reference, &reference_len, 0);
sc_format_asn1_entry(asn1_algo_infos[ii] + 1, &ti->supported_algos[ii].mechanism, &mechanism_len, 0);
- sc_format_asn1_entry(asn1_algo_infos[ii] + 2, NULL, NULL, 0);
+ sc_format_asn1_entry(asn1_algo_infos[ii] + 2,
+ asn1_algo_infos_parameters[ii], NULL, 0);
+ sc_format_asn1_entry(asn1_algo_infos_parameters[ii] + 0,
+ NULL, NULL, 0);
+ sc_format_asn1_entry(asn1_algo_infos_parameters[ii] + 1,
+ &ti->supported_algos[ii].parameters, ¶meter_len, 0);
sc_format_asn1_entry(asn1_algo_infos[ii] + 3, &ti->supported_algos[ii].operations, &operations_len, 0);
sc_format_asn1_entry(asn1_algo_infos[ii] + 4, &ti->supported_algos[ii].algo_id, NULL, 1);
sc_format_asn1_entry(asn1_algo_infos[ii] + 5, &ti->supported_algos[ii].algo_ref, &algo_ref_len, 0);
@@ -270,9 +286,11 @@ sc_pkcs15_encode_tokeninfo(sc_context_t *ctx, sc_pkcs15_tokeninfo_t *ti,
struct sc_asn1_entry asn1_toki_attrs[C_ASN1_TOKI_ATTRS_SIZE];
struct sc_asn1_entry asn1_tokeninfo[2];
struct sc_asn1_entry asn1_supported_algorithms[SC_MAX_SUPPORTED_ALGORITHMS + 1],
- asn1_algo_infos[SC_MAX_SUPPORTED_ALGORITHMS][7];
+ asn1_algo_infos[SC_MAX_SUPPORTED_ALGORITHMS][7],
+ asn1_algo_infos_parameters[SC_MAX_SUPPORTED_ALGORITHMS][3];
size_t reference_len = sizeof(ti->supported_algos[0].reference);
size_t mechanism_len = sizeof(ti->supported_algos[0].mechanism);
+ size_t parameter_len = sizeof(ti->supported_algos[0].parameters);
size_t operations_len = sizeof(ti->supported_algos[0].operations);
size_t algo_ref_len = sizeof(ti->supported_algos[0].algo_ref);
struct sc_asn1_entry asn1_last_update[C_ASN1_LAST_UPDATE_SIZE];
@@ -283,14 +301,22 @@ sc_pkcs15_encode_tokeninfo(sc_context_t *ctx, sc_pkcs15_tokeninfo_t *ti,
sc_copy_asn1_entry(c_asn1_last_update, asn1_last_update);
sc_copy_asn1_entry(c_asn1_profile_indication, asn1_profile_indication);
- for (ii=0; iisupported_algos[ii].reference; ii++)
+ for (ii=0; iisupported_algos[ii].reference; ii++) {
sc_copy_asn1_entry(c_asn1_algorithm_info, asn1_algo_infos[ii]);
+ sc_copy_asn1_entry(c_asn1_algorithm_info_parameters,
+ asn1_algo_infos_parameters[ii]);
+ }
sc_copy_asn1_entry(c_asn1_supported_algorithms, asn1_supported_algorithms);
for (ii=0; iisupported_algos[ii].reference; ii++) {
sc_format_asn1_entry(asn1_algo_infos[ii] + 0, &ti->supported_algos[ii].reference, &reference_len, 1);
sc_format_asn1_entry(asn1_algo_infos[ii] + 1, &ti->supported_algos[ii].mechanism, &mechanism_len, 1);
- sc_format_asn1_entry(asn1_algo_infos[ii] + 2, NULL, NULL, 0);
+ sc_format_asn1_entry(asn1_algo_infos[ii] + 2,
+ asn1_algo_infos_parameters[ii], NULL, 0);
+ sc_format_asn1_entry(asn1_algo_infos_parameters[ii] + 0,
+ NULL, NULL, 0);
+ sc_format_asn1_entry(asn1_algo_infos_parameters[ii] + 1,
+ &ti->supported_algos[ii].parameters, ¶meter_len, 0);
sc_format_asn1_entry(asn1_algo_infos[ii] + 3, &ti->supported_algos[ii].operations, &operations_len, 1);
sc_format_asn1_entry(asn1_algo_infos[ii] + 4, &ti->supported_algos[ii].algo_id, NULL, 1);
sc_format_asn1_entry(asn1_algo_infos[ii] + 5, &ti->supported_algos[ii].algo_ref, &algo_ref_len, 1);
@@ -1059,15 +1085,17 @@ sc_pkcs15_bind_internal(struct sc_pkcs15_card *p15card, struct sc_aid *aid)
}
if (err < 0) {
err = sc_read_binary(card, 0, buf, len, 0);
- if (err < 0) {
- sc_log(ctx, "read EF(ODF) file error: %s", sc_strerror(err));
- goto end;
- }
- else if (err < 2) {
- err = SC_ERROR_PKCS15_APP_NOT_FOUND;
- sc_log(ctx, "Invalid content of EF(ODF): %s", sc_strerror(err));
+ if (err < 2) {
+ if (err < 0) {
+ sc_log(ctx, "read EF(ODF) file error: %s", sc_strerror(err));
+ } else {
+ err = SC_ERROR_PKCS15_APP_NOT_FOUND;
+ sc_log(ctx, "Invalid content of EF(ODF): %s", sc_strerror(err));
+ }
goto end;
}
+ /* sc_read_binary may return less than requested */
+ len = err;
if (p15card->opts.use_file_cache) {
sc_pkcs15_cache_file(p15card, &tmppath, buf, len);
@@ -1125,20 +1153,21 @@ sc_pkcs15_bind_internal(struct sc_pkcs15_card *p15card, struct sc_aid *aid)
}
if (err < 0) {
err = sc_read_binary(card, 0, buf, len, 0);
- if (err < 0) {
- sc_log(ctx, "read EF(TokenInfo) file error: %s", sc_strerror(err));
- goto end;
- }
if (err <= 2) {
- err = SC_ERROR_PKCS15_APP_NOT_FOUND;
- sc_log(ctx, "Invalid content of EF(TokenInfo): %s", sc_strerror(err));
+ if (err < 0) {
+ sc_log(ctx, "read EF(TokenInfo) file error: %s", sc_strerror(err));
+ } else {
+ err = SC_ERROR_PKCS15_APP_NOT_FOUND;
+ sc_log(ctx, "Invalid content of EF(TokenInfo): %s", sc_strerror(err));
+ }
goto end;
}
+ /* sc_read_binary may return less than requested */
+ len = err;
if (p15card->opts.use_file_cache) {
sc_pkcs15_cache_file(p15card, &tmppath, buf, len);
}
- err = len;
}
memset(&tokeninfo, 0, sizeof(tokeninfo));
@@ -2392,7 +2421,7 @@ sc_pkcs15_read_file(struct sc_pkcs15_card *p15card, const struct sc_path *in_pat
sc_file_free(file);
- if (p15card->opts.use_file_cache) {
+ if (len && p15card->opts.use_file_cache) {
sc_pkcs15_cache_file(p15card, in_path, data, len);
}
}
diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h
index 7d922c39..b6a2dd34 100644
--- a/src/libopensc/pkcs15.h
+++ b/src/libopensc/pkcs15.h
@@ -738,7 +738,7 @@ int sc_pkcs15_get_extension(struct sc_context *ctx,
int sc_pkcs15_get_bitstring_extension(struct sc_context *ctx,
struct sc_pkcs15_cert *cert,
const struct sc_object_id *type,
- unsigned long long *value,
+ unsigned int *value,
int *is_critical);
/* sc_pkcs15_create_cdf: Creates a new certificate DF on a card pointed
* by . Information about the file, such as the file ID, is read
diff --git a/src/libopensc/sm.c b/src/libopensc/sm.c
index a5f53de1..877a5ef1 100644
--- a/src/libopensc/sm.c
+++ b/src/libopensc/sm.c
@@ -31,6 +31,7 @@
#include "asn1.h"
#include "sm.h"
+#ifdef ENABLE_SM
static const struct sc_asn1_entry c_asn1_sm_response[4] = {
{ "encryptedData", SC_ASN1_OCTET_STRING, SC_ASN1_CTX | 7, SC_ASN1_OPTIONAL, NULL, NULL },
{ "statusWord", SC_ASN1_OCTET_STRING, SC_ASN1_CTX | 0x19, 0, NULL, NULL },
@@ -38,7 +39,6 @@ static const struct sc_asn1_entry c_asn1_sm_response[4] = {
{ NULL, 0, 0, 0, NULL, NULL }
};
-#ifdef ENABLE_SM
int
sc_sm_parse_answer(struct sc_card *card, unsigned char *resp_data, size_t resp_len,
struct sm_card_response *out)
@@ -157,7 +157,7 @@ sc_sm_single_transmit(struct sc_card *card, struct sc_apdu *apdu)
}
/* send APDU flagged as NO_SM */
- sm_apdu->flags |= SC_APDU_FLAGS_NO_SM;
+ sm_apdu->flags |= SC_APDU_FLAGS_NO_SM | SC_APDU_FLAGS_NO_RETRY_WL;
rv = sc_transmit_apdu(card, sm_apdu);
if (rv < 0) {
card->sm_ctx.ops.free_sm_apdu(card, apdu, &sm_apdu);
diff --git a/src/minidriver/Makefile.am b/src/minidriver/Makefile.am
index ac774e39..e0922e0f 100644
--- a/src/minidriver/Makefile.am
+++ b/src/minidriver/Makefile.am
@@ -7,9 +7,9 @@ if ENABLE_MINIDRIVER
lib_LTLIBRARIES = opensc-minidriver@LIBRARY_BITNESS@.la
# Do we need this on bin? Why can't we
# put it in dedicated directory
-dist_sbin_SCRIPTS = opensc-minidriver.inf minidriver-westcos.reg minidriver-sc-hsm.reg minidriver-feitian.reg
+dist_sbin_SCRIPTS = opensc-minidriver.inf
else
-dist_noinst_DATA = opensc-minidriver.inf minidriver-westcos.reg minidriver-sc-hsm.reg minidriver-feitian.reg
+dist_noinst_DATA = opensc-minidriver.inf
endif
AM_CFLAGS = $(OPTIONAL_OPENSSL_CFLAGS)
diff --git a/src/minidriver/minidriver-feitian.reg b/src/minidriver/minidriver-feitian.reg
deleted file mode 100644
index 446ef1cf..00000000
--- a/src/minidriver/minidriver-feitian.reg
+++ /dev/null
@@ -1,30 +0,0 @@
-Windows Registry Editor Version 5.00
-
-[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Calais\SmartCards\ePass2003]
-"ATR"=hex:3b,9f,95,81,31,fe,9f,00,66,46,53,05,01,00,11,71,df,00,00,03,6a,82,f8
-"ATRMask"=hex,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff
-"Crypto Provider"="Microsoft Base Smart Card Crypto Provider"
-"Smart Card Key Storage Provider"="Microsoft Smart Card Key Storage Provider"
-"80000001"="opensc-minidriver.dll"
-
-[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Cryptography\Calais\SmartCards\ePass2003]
-"ATR"=hex:3b,9f,95,81,31,fe,9f,00,66,46,53,05,01,00,11,71,df,00,00,03,6a,82,f8
-"ATRMask"=hex:ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,00,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff
-"Crypto Provider"="Microsoft Base Smart Card Crypto Provider"
-"Smart Card Key Storage Provider"="Microsoft Smart Card Key Storage Provider"
-"80000001"="opensc-minidriver.dll"
-
-
-[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Calais\SmartCards\FTCOS/PK-01C]
-"ATR"=hex:3b,9f,95,81,31,fe,9f,00,65,46,53,05,00,06,71,df,00,00,00,00,00,00,00
-"ATRMask"=hex:ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,00,ff,ff,ff,ff,ff,ff,00,00,00,00
-"Crypto Provider"="Microsoft Base Smart Card Crypto Provider"
-"Smart Card Key Storage Provider"="Microsoft Smart Card Key Storage Provider"
-"80000001"="opensc-minidriver.dll"
-
-[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Cryptography\Calais\SmartCards\FTCOS/PK-01C]
-"ATR"=hex:3b,9f,95,81,31,fe,9f,00,65,46,53,05,00,06,71,df,00,00,00,00,00,00,00
-"ATRMask"=hex:ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,00,ff,ff,ff,ff,ff,ff,00,00,00,00
-"Crypto Provider"="Microsoft Base Smart Card Crypto Provider"
-"Smart Card Key Storage Provider"="Microsoft Smart Card Key Storage Provider"
-"80000001"="opensc-minidriver.dll"
diff --git a/src/minidriver/minidriver-italian-cns.reg b/src/minidriver/minidriver-italian-cns.reg
deleted file mode 100644
index 3bca8d4a..00000000
--- a/src/minidriver/minidriver-italian-cns.reg
+++ /dev/null
@@ -1,33 +0,0 @@
-Windows Registry Editor Version 5.00
-
-[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Cryptography\Calais\SmartCards\CPS]
-"Crypto Provider"="Microsoft Base Smart Card Crypto Provider"
-"Smart Card Key Storage Provider"="Microsoft Smart Card Key Storage Provider"
-"80000001"="opensc-minidriver.dll"
-"ATR"=hex:3b,ff,18,00,ff,c1,0a,31,fe,55,00,6b,05,08,c8,0c,01,11,01,43,4e,53,10,\
- 31,80,05
-"ATRMask"=hex:ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,\
- ff,ff,ff,ff,ff
-
-[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Cryptography\Calais\SmartCards\CPS-Athena]
-"Crypto Provider"="Microsoft Base Smart Card Crypto Provider"
-"Smart Card Key Storage Provider"="Microsoft Smart Card Key Storage Provider"
-"80000001"="opensc-minidriver.dll"
-"ATR"=hex:3b,df,18,00,81,31,fe,7d,00,6b,02,0c,01,82,01,11,01,43,4e,53,10,31,80,fc
-"ATRMask"=hex:ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff
-
-[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Calais\SmartCards\CPS]
-"Crypto Provider"="Microsoft Base Smart Card Crypto Provider"
-"Smart Card Key Storage Provider"="Microsoft Smart Card Key Storage Provider"
-"80000001"="opensc-minidriver.dll"
-"ATR"=hex:3b,ff,18,00,ff,c1,0a,31,fe,55,00,6b,05,08,c8,0c,01,11,01,43,4e,53,10,\
- 31,80,05
-"ATRMask"=hex:ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,\
- ff,ff,ff,ff,ff
-
-[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Calais\SmartCards\CPS-Athena]
-"Crypto Provider"="Microsoft Base Smart Card Crypto Provider"
-"Smart Card Key Storage Provider"="Microsoft Smart Card Key Storage Provider"
-"80000001"="opensc-minidriver.dll"
-"ATR"=hex:3b,df,18,00,81,31,fe,7d,00,6b,02,0c,01,82,01,11,01,43,4e,53,10,31,80,fc
-"ATRMask"=hex:ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff
diff --git a/src/minidriver/minidriver-sc-hsm.reg b/src/minidriver/minidriver-sc-hsm.reg
deleted file mode 100644
index 38598b2c..00000000
Binary files a/src/minidriver/minidriver-sc-hsm.reg and /dev/null differ
diff --git a/src/minidriver/minidriver-westcos.reg b/src/minidriver/minidriver-westcos.reg
deleted file mode 100644
index 840daee6..00000000
--- a/src/minidriver/minidriver-westcos.reg
+++ /dev/null
@@ -1,7 +0,0 @@
-Windows Registry Editor Version 5.00
-
-[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Calais\SmartCards\CEV WESTCOS]
-"80000001"="opensc-minidriver.dll"
-"ATR"=hex:3f,69,00,00,00,64,01,00,00,00,80,90,00
-"ATRMask"=hex:ff,ff,ff,ff,ff,ff,ff,00,00,00,f0,ff,ff
-"Crypto Provider"="Microsoft Base Smart Card Crypto Provider"
diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c
index b9157f92..7058e23c 100644
--- a/src/minidriver/minidriver.c
+++ b/src/minidriver/minidriver.c
@@ -30,9 +30,9 @@
#pragma managed(push, off)
#endif
-
#include
#include
+#include
#include
#include
@@ -77,6 +77,13 @@ HINSTANCE g_inst;
#define MD_MAX_KEY_CONTAINERS 12
#define MD_CARDID_SIZE 16
+#define MD_ROLE_USER_SIGN (ROLE_ADMIN + 1)
+/*
+ * must be higher than MD_ROLE_USER_SIGN and
+ * less than or equal MAX_PINS
+ */
+#define MD_MAX_PINS MAX_PINS
+
#define MD_UTC_TIME_LENGTH_MAX 16
#define MD_CARDCF_LENGTH (sizeof(CARD_CACHE_FILE_FORMAT))
@@ -175,7 +182,9 @@ struct md_guid_conversion md_static_conversions[MD_MAX_CONVERSIONS] = {0};
typedef struct _VENDOR_SPECIFIC
{
- struct sc_pkcs15_object *obj_user_pin, *obj_sopin;
+ BOOL initialized;
+
+ struct sc_pkcs15_object *pin_objs[MD_MAX_PINS];
struct sc_context *ctx;
struct sc_reader *reader;
@@ -246,10 +255,11 @@ static const struct sc_asn1_entry c_asn1_md_container[C_ASN1_MD_CONTAINER_SIZE]
static DWORD md_translate_OpenSC_to_Windows_error(int OpenSCerror,
DWORD dwDefaulCode);
-static int associate_card(PCARD_DATA pCardData);
-static int disassociate_card(PCARD_DATA pCardData);
+static DWORD associate_card(PCARD_DATA pCardData);
+static void disassociate_card(PCARD_DATA pCardData);
static DWORD md_pkcs15_delete_object(PCARD_DATA pCardData, struct sc_pkcs15_object *obj);
static DWORD md_fs_init(PCARD_DATA pCardData);
+static void md_fs_finalize(PCARD_DATA pCardData);
#if defined(_MSC_VER) && _MSC_VER < 1900
#define snprintf _snprintf
@@ -336,22 +346,91 @@ static void loghex(PCARD_DATA pCardData, int level, PBYTE data, size_t len)
logprintf(pCardData, level, " %04X %s\n", a, line);
}
-/*
- * check if the card has been removed, or the
- * caller has changed the handles.
- * if so, then free up all previous card info
- * and reestablish
- */
-static int
-check_reader_status(PCARD_DATA pCardData)
+static DWORD reinit_card(PCARD_DATA pCardData)
+{
+ VENDOR_SPECIFIC *vs;
+ DWORD r;
+
+ if (!pCardData)
+ return SCARD_E_INVALID_PARAMETER;
+
+ vs = (VENDOR_SPECIFIC *)(pCardData->pvVendorSpecific);
+ if (!vs)
+ return SCARD_E_INVALID_PARAMETER;
+
+ logprintf(pCardData, 2, "trying to reinit card\n");
+
+ if (vs->initialized) {
+ disassociate_card(pCardData);
+ md_fs_finalize(pCardData);
+ }
+
+ r = associate_card(pCardData);
+ if (r != SCARD_S_SUCCESS)
+ return r;
+
+ r = md_fs_init(pCardData);
+ if (r != SCARD_S_SUCCESS) {
+ logprintf(pCardData, 1,
+ "reinit_card md_fs_init failed, r = 0x%lX\n",
+ (unsigned long)r);
+ disassociate_card(pCardData);
+ return r;
+ }
+
+ return SCARD_S_SUCCESS;
+}
+
+static DWORD reinit_card_for(PCARD_DATA pCardData, const char *name)
+{
+ DWORD r;
+
+ r = reinit_card(pCardData);
+ if (r != SCARD_S_SUCCESS)
+ logprintf(pCardData, 1,
+ "%s was called, but unable to initialize card, r = %u\n",
+ name, (unsigned int)r);
+
+ return r;
+}
+
+static DWORD check_card_status(PCARD_DATA pCardData, const char *name)
+{
+ VENDOR_SPECIFIC *vs;
+
+ if (!pCardData)
+ return SCARD_E_INVALID_PARAMETER;
+
+ vs = (VENDOR_SPECIFIC *)(pCardData->pvVendorSpecific);
+ if (!vs)
+ return SCARD_E_INVALID_PARAMETER;
+
+ if (vs->initialized)
+ return SCARD_S_SUCCESS;
+
+ return reinit_card_for(pCardData, name);
+}
+
+/*
+ * check if the card is OK, has been removed, or the
+ * caller has changed the handles.
+ * if so, then try to reinit card
+ */
+static DWORD
+check_card_reader_status(PCARD_DATA pCardData, const char *name)
{
- int r = SCARD_S_SUCCESS;
VENDOR_SPECIFIC *vs = NULL;
+ DWORD dwRet;
+ int r;
logprintf(pCardData, 4, "check_reader_status\n");
if(!pCardData)
return SCARD_E_INVALID_PARAMETER;
+ dwRet = check_card_status(pCardData, name);
+ if (dwRet != SCARD_S_SUCCESS)
+ return dwRet;
+
vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
if(!vs)
return SCARD_E_INVALID_PARAMETER;
@@ -364,34 +443,36 @@ check_reader_status(PCARD_DATA pCardData)
logprintf(pCardData, 1, "HANDLES CHANGED from 0x%08X 0x%08X\n",
(unsigned int)vs->hSCardCtx,
(unsigned int)vs->hScard);
-
- /* Basically a mini AcquireContext */
- r = disassociate_card(pCardData);
- logprintf(pCardData, 1, "disassociate_card r = 0x%08X\n", r);
- r = associate_card(pCardData); /* need to check return codes */
- if (r != SCARD_S_SUCCESS)
- return r;
- logprintf(pCardData, 1, "associate_card r = 0x%08X\n", r);
- /* Rebuild 'soft' fs - in case changed */
- r = md_fs_init(pCardData);
- logprintf(pCardData, 1, "md_fs_init r = 0x%08X\n", r);
- }
- else if (vs->reader) {
- /* This should always work, as BaseCSP should be checking for removal too */
- r = sc_detect_card_presence(vs->reader);
- logprintf(pCardData, 2,
- "check_reader_status r=%d flags 0x%08X\n", r,
- (unsigned int)vs->reader->flags);
+ return reinit_card_for(pCardData, name);
}
- return r;
+ /* This should always work, as BaseCSP should be checking for removal too */
+ r = sc_detect_card_presence(vs->reader);
+ logprintf(pCardData, 2,
+ "check_reader_status r=%d flags 0x%08X\n", r,
+ (unsigned int)vs->reader->flags);
+ if (r < 0)
+ return md_translate_OpenSC_to_Windows_error(r,
+ SCARD_F_INTERNAL_ERROR);
+
+ if (!(r & SC_READER_CARD_PRESENT)) {
+ /*
+ * if there is really no card present it may not make sense to
+ * try initializing the card but since it won't hurt let's try
+ * it anyway for completeness
+ */
+ logprintf(pCardData, 1, "no card present? trying to reinit\n");
+ return reinit_card_for(pCardData, name);
+ }
+
+ return SCARD_S_SUCCESS;
}
static DWORD
md_get_pin_by_role(PCARD_DATA pCardData, PIN_ID role, struct sc_pkcs15_object **ret_obj)
{
VENDOR_SPECIFIC *vs;
- int rv = SC_SUCCESS;
+ int rv;
if (!pCardData)
return SCARD_E_INVALID_PARAMETER;
@@ -400,43 +481,65 @@ md_get_pin_by_role(PCARD_DATA pCardData, PIN_ID role, struct sc_pkcs15_object **
if (!ret_obj)
return SCARD_E_INVALID_PARAMETER;
- *ret_obj = NULL;
-
- if (role == ROLE_USER) {
- if (!vs->obj_user_pin) {
- /* Get 'global' User PIN; if no, get the 'local' one */
- rv = sc_pkcs15_find_pin_by_flags(vs->p15card, SC_PKCS15_PIN_TYPE_FLAGS_PIN_GLOBAL,
- SC_PKCS15_PIN_TYPE_FLAGS_MASK, NULL, &vs->obj_user_pin);
- if (rv)
- rv = sc_pkcs15_find_pin_by_flags(vs->p15card, SC_PKCS15_PIN_TYPE_FLAGS_PIN_LOCAL,
- SC_PKCS15_PIN_TYPE_FLAGS_MASK, NULL, &vs->obj_user_pin);
- }
-
- *ret_obj = vs->obj_user_pin;
+ /* please keep me in sync with _get_auth_object_by_name() in pkcs11/framework-pkcs15.c */
+ if (role == ROLE_USER) {
+ /* Get 'global' User PIN; if no, get the 'local' one */
+ rv = sc_pkcs15_find_pin_by_flags(vs->p15card, SC_PKCS15_PIN_TYPE_FLAGS_PIN_GLOBAL,
+ SC_PKCS15_PIN_TYPE_FLAGS_MASK, NULL, ret_obj);
+ if (rv)
+ rv = sc_pkcs15_find_pin_by_flags(vs->p15card, SC_PKCS15_PIN_TYPE_FLAGS_PIN_LOCAL,
+ SC_PKCS15_PIN_TYPE_FLAGS_MASK, NULL, ret_obj);
}
- else if (role == ROLE_ADMIN) {
- /* Get SO PIN; if no, get the 'global' PUK; if no get the 'local' one */
- if (!vs->obj_sopin) {
- rv = sc_pkcs15_find_pin_by_flags(vs->p15card, SC_PKCS15_PIN_TYPE_FLAGS_SOPIN,
- SC_PKCS15_PIN_TYPE_FLAGS_SOPIN, NULL, &vs->obj_sopin);
- if (rv)
- rv = sc_pkcs15_find_pin_by_flags(vs->p15card, SC_PKCS15_PIN_TYPE_FLAGS_PUK_GLOBAL,
- SC_PKCS15_PIN_TYPE_FLAGS_MASK, NULL, &vs->obj_sopin);
- if (rv)
- rv = sc_pkcs15_find_pin_by_flags(vs->p15card, SC_PKCS15_PIN_TYPE_FLAGS_PUK_LOCAL,
- SC_PKCS15_PIN_TYPE_FLAGS_MASK, NULL, &vs->obj_sopin);
- }
+ else if (role == MD_ROLE_USER_SIGN) {
+ int idx = 0;
- *ret_obj = vs->obj_sopin;
+ /* Get the 'global' user PIN */
+ rv = sc_pkcs15_find_pin_by_flags(vs->p15card, SC_PKCS15_PIN_TYPE_FLAGS_PIN_GLOBAL,
+ SC_PKCS15_PIN_TYPE_FLAGS_MASK, NULL, ret_obj);
+ if (!rv) {
+ /* Global (user) PIN exists, get the local one -- sign PIN */
+ rv = sc_pkcs15_find_pin_by_flags(vs->p15card, SC_PKCS15_PIN_TYPE_FLAGS_PIN_LOCAL,
+ SC_PKCS15_PIN_TYPE_FLAGS_MASK, NULL, ret_obj);
+ }
+ else {
+ /* No global PIN, try to get first local one -- user PIN */
+ rv = sc_pkcs15_find_pin_by_flags(vs->p15card, SC_PKCS15_PIN_TYPE_FLAGS_PIN_LOCAL,
+ SC_PKCS15_PIN_TYPE_FLAGS_MASK, &idx, ret_obj);
+ if (!rv) {
+ /* User PIN is local, try to get the second local -- sign PIN */
+ idx++;
+ rv = sc_pkcs15_find_pin_by_flags(vs->p15card, SC_PKCS15_PIN_TYPE_FLAGS_PIN_LOCAL,
+ SC_PKCS15_PIN_TYPE_FLAGS_MASK, &idx, ret_obj);
+ }
+ }
+ }
+ else if (role == ROLE_ADMIN) {
+ /* Get SO PIN; if no, get the 'global' PUK; if no get the 'local' one */
+ rv = sc_pkcs15_find_so_pin(vs->p15card, ret_obj);
+ if (rv)
+ rv = sc_pkcs15_find_pin_by_flags(vs->p15card, SC_PKCS15_PIN_TYPE_FLAGS_PUK_GLOBAL,
+ SC_PKCS15_PIN_TYPE_FLAGS_MASK, NULL, ret_obj);
+ if (rv)
+ rv = sc_pkcs15_find_pin_by_flags(vs->p15card, SC_PKCS15_PIN_TYPE_FLAGS_PUK_LOCAL,
+ SC_PKCS15_PIN_TYPE_FLAGS_MASK, NULL, ret_obj);
}
else {
- logprintf(pCardData, 2, "cannot get PIN object: unsupported role\n");
+ logprintf(pCardData, 2,
+ "cannot get PIN object: unsupported role %u\n",
+ (unsigned int)role);
return SCARD_E_UNSUPPORTED_FEATURE;
}
- return (rv == SC_SUCCESS) ? SCARD_S_SUCCESS : SCARD_E_UNSUPPORTED_FEATURE;
-}
+ if (rv)
+ return SCARD_E_UNSUPPORTED_FEATURE;
+ if (*ret_obj)
+ logprintf(pCardData, 7, "Returning PIN '%.*s' for role %u\n",
+ (int) sizeof (*ret_obj)->label, (*ret_obj)->label,
+ (unsigned int)role);
+
+ return SCARD_S_SUCCESS;
+}
static const char *
md_get_config_str(PCARD_DATA pCardData, enum ui_str id)
@@ -565,6 +668,9 @@ md_get_config_bool(PCARD_DATA pCardData, char *flag_name, unsigned flag, BOOL re
}
vs = (VENDOR_SPECIFIC*) pCardData->pvVendorSpecific;
+ if (!vs)
+ return ret;
+
if (vs->ctx && vs->reader) {
struct sc_atr atr;
scconf_block *atrblock;
@@ -674,6 +780,9 @@ md_contguid_get_guid_from_card(PCARD_DATA pCardData, struct sc_pkcs15_object *pr
size_t guid_len = MAX_CONTAINER_NAME_LEN+1;
vs = (VENDOR_SPECIFIC*) pCardData->pvVendorSpecific;
+ if (!vs)
+ return SCARD_E_INVALID_PARAMETER;
+
rv = sc_pkcs15_get_object_guid(vs->p15card, prkey, 1, (unsigned char*) szGuid, &guid_len);
if (rv) {
logprintf(pCardData, 2, "md_contguid_get_guid_from_card(): error %d\n", rv);
@@ -776,6 +885,9 @@ md_cont_flags_from_key(PCARD_DATA pCardData, struct sc_pkcs15_object *key_obj, u
int rv;
vs = (VENDOR_SPECIFIC*) pCardData->pvVendorSpecific;
+ if (!vs)
+ return SCARD_E_INVALID_PARAMETER;
+
prkey_info = (struct sc_pkcs15_prkey_info *)key_obj->data;
*cont_flags = CONTAINER_MAP_VALID_CONTAINER;
@@ -803,6 +915,9 @@ md_fs_find_directory(PCARD_DATA pCardData, struct md_directory *parent, char *na
return SCARD_E_INVALID_PARAMETER;
vs = pCardData->pvVendorSpecific;
+ if (!vs)
+ return SCARD_E_INVALID_PARAMETER;
+
if (!parent)
parent = &vs->root;
@@ -982,6 +1097,8 @@ md_fs_delete_file(PCARD_DATA pCardData, char *parent, char *name)
return SCARD_E_INVALID_PARAMETER;
vs = pCardData->pvVendorSpecific;
+ if (!vs)
+ return SCARD_E_INVALID_PARAMETER;
dwret = md_fs_find_directory(pCardData, NULL, parent, &dir);
if (dwret != SCARD_S_SUCCESS) {
@@ -1042,7 +1159,7 @@ md_fs_delete_file(PCARD_DATA pCardData, char *parent, char *name)
return dwret;
}
-static DWORD
+static void
md_fs_finalize(PCARD_DATA pCardData)
{
VENDOR_SPECIFIC *vs;
@@ -1050,9 +1167,11 @@ md_fs_finalize(PCARD_DATA pCardData)
struct md_directory *dir = NULL, *dir_to_rm;
if (!pCardData)
- return SCARD_E_INVALID_PARAMETER;
+ return;
vs = pCardData->pvVendorSpecific;
+ if (!vs)
+ return;
file = vs->root.files;
while (file != NULL) {
@@ -1060,6 +1179,7 @@ md_fs_finalize(PCARD_DATA pCardData)
file = file->next;
md_fs_free_file(pCardData, file_to_rm);
}
+ vs->root.files = NULL;
dir = vs->root.subdirs;
while(dir) {
@@ -1073,7 +1193,7 @@ md_fs_finalize(PCARD_DATA pCardData)
dir = dir->next;
pCardData->pfnCspFree(dir_to_rm);
}
- return 0;
+ vs->root.subdirs = NULL;
}
/*
@@ -1091,6 +1211,8 @@ md_pkcs15_update_containers(PCARD_DATA pCardData, unsigned char *blob, size_t si
return SCARD_E_INVALID_PARAMETER;
vs = pCardData->pvVendorSpecific;
+ if (!vs)
+ return SCARD_E_INVALID_PARAMETER;
nn_records = (int) size/sizeof(CONTAINER_MAP_RECORD);
if (nn_records > MD_MAX_KEY_CONTAINERS)
@@ -1137,6 +1259,9 @@ md_pkcs15_delete_object(PCARD_DATA pCardData, struct sc_pkcs15_object *obj)
if (!pCardData)
return SCARD_E_INVALID_PARAMETER;
vs = pCardData->pvVendorSpecific;
+ if (!vs)
+ return SCARD_E_INVALID_PARAMETER;
+
card = vs->p15card->card;
if (!obj)
@@ -1217,6 +1342,9 @@ md_set_cardid(PCARD_DATA pCardData, struct md_file *file)
return SCARD_E_INVALID_PARAMETER;
vs = pCardData->pvVendorSpecific;
+ if (!vs)
+ return SCARD_E_INVALID_PARAMETER;
+
if (vs->p15card->tokeninfo && vs->p15card->tokeninfo->serial_number) {
unsigned char sn_bin[SC_MAX_SERIALNR];
unsigned char cardid_bin[MD_CARDID_SIZE];
@@ -1468,6 +1596,8 @@ md_fs_add_msroots(PCARD_DATA pCardData, struct md_file **head)
return SCARD_E_INVALID_PARAMETER;
vs = (VENDOR_SPECIFIC *) pCardData->pvVendorSpecific;
+ if (!vs)
+ return SCARD_E_INVALID_PARAMETER;
rv = sc_pkcs15_get_objects(vs->p15card, SC_PKCS15_TYPE_CERT_X509, prkey_objs, MD_MAX_KEY_CONTAINERS);
if (rv < 0) {
@@ -1501,6 +1631,14 @@ md_fs_add_msroots(PCARD_DATA pCardData, struct md_file **head)
static DWORD
md_set_cmapfile(PCARD_DATA pCardData, struct md_file *file)
{
+ typedef enum { SCF_NONE,
+ SCF_NONDEFAULT_SIGN_PIN,
+ SCF_NONDEFAULT_OTHER_PIN,
+ SCF_NONDEFAULT_USER_PIN,
+ SCF_DEFAULT_SIGN_PIN,
+ SCF_DEFAULT_OTHER_PIN,
+ SCF_DEFAULT_USER_PIN
+ } pin_mode_t;
VENDOR_SPECIFIC *vs;
PCONTAINER_MAP_RECORD p;
unsigned char *cmap_buf = NULL;
@@ -1509,12 +1647,35 @@ md_set_cmapfile(PCARD_DATA pCardData, struct md_file *file)
int ii, rv, conts_num, found_default = 0;
/* struct sc_pkcs15_data *data_object; */
struct sc_pkcs15_object *prkey_objs[MD_MAX_KEY_CONTAINERS];
+ pin_mode_t pin_mode = SCF_NONE;
+ int pin_cont_idx = -1;
if (!pCardData || !file)
return SCARD_E_INVALID_PARAMETER;
logprintf(pCardData, 2, "set 'cmapfile'\n");
vs = pCardData->pvVendorSpecific;
+ if (!vs)
+ return SCARD_E_INVALID_PARAMETER;
+
+ dwret = md_get_pin_by_role(pCardData, ROLE_USER, &vs->pin_objs[ROLE_USER]);
+ if (dwret != SCARD_S_SUCCESS) {
+ logprintf(pCardData, 2, "Cannot get User PIN object");
+ return dwret;
+ }
+
+ dwret = md_get_pin_by_role(pCardData, MD_ROLE_USER_SIGN, &vs->pin_objs[MD_ROLE_USER_SIGN]);
+ if (dwret != SCARD_S_SUCCESS) {
+ logprintf(pCardData, 2, "Cannot get Sign PIN object -- ignored");
+ vs->pin_objs[MD_ROLE_USER_SIGN] = NULL;
+ }
+
+ dwret = md_get_pin_by_role(pCardData, ROLE_ADMIN, &vs->pin_objs[ROLE_ADMIN]);
+ if (dwret != SCARD_S_SUCCESS) {
+ logprintf(pCardData, 2, "Cannot get Admin PIN object -- ignored");
+ vs->pin_objs[ROLE_ADMIN] = NULL;
+ }
+
cmap_len = MD_MAX_KEY_CONTAINERS*sizeof(CONTAINER_MAP_RECORD);
cmap_buf = pCardData->pfnCspAlloc(cmap_len);
if(!cmap_buf)
@@ -1556,7 +1717,116 @@ md_set_cmapfile(PCARD_DATA pCardData, struct md_file *file)
dwret = md_cont_flags_from_key(pCardData, key_obj, &cont->flags);
if (dwret != SCARD_S_SUCCESS)
return dwret;
- if (cont->flags & CONTAINER_MAP_DEFAULT_CONTAINER)
+
+ logprintf(pCardData, 7, "Container[%i] is '%.*s' guid=%.*s\n", ii,
+ (int) sizeof key_obj->label, key_obj->label,
+ (int) sizeof cont->guid, cont->guid);
+
+ if (cont->flags & CONTAINER_MAP_VALID_CONTAINER &&
+ key_obj->auth_id.len > 0) {
+ struct sc_pkcs15_object *keypin_obj;
+ struct sc_pkcs15_auth_info *userpin_info =
+ (struct sc_pkcs15_auth_info *)vs->pin_objs[ROLE_USER]->data;
+ struct sc_pkcs15_auth_info *signpin_info =
+ vs->pin_objs[MD_ROLE_USER_SIGN] ?
+ (struct sc_pkcs15_auth_info *)vs->pin_objs[MD_ROLE_USER_SIGN]->data :
+ NULL;
+ struct sc_pkcs15_auth_info *adminpin_info =
+ vs->pin_objs[ROLE_ADMIN] ?
+ (struct sc_pkcs15_auth_info *)vs->pin_objs[ROLE_ADMIN]->data :
+ NULL;
+
+ if (sc_pkcs15_find_pin_by_auth_id(vs->p15card, &key_obj->auth_id, &keypin_obj))
+ logprintf(pCardData, 2,
+ "Container[%i] has an unknown auth id, might not work properly\n",
+ ii);
+ else {
+ size_t pinidx;
+ size_t pinidxempty = MD_MAX_PINS;
+ for (pinidx = 0; pinidx < MD_MAX_PINS; pinidx++) {
+ struct sc_pkcs15_auth_info *pin_info;
+
+ if (!vs->pin_objs[pinidx]) {
+ if (pinidxempty >= MD_MAX_PINS)
+ pinidxempty = pinidx;
+
+ continue;
+ }
+
+ pin_info =
+ (struct sc_pkcs15_auth_info *)vs->pin_objs[pinidx]->data;
+
+ if (sc_pkcs15_compare_id(&key_obj->auth_id,
+ &pin_info->auth_id))
+ break;
+ }
+
+ if (pinidx >= MD_MAX_PINS) {
+ if (pinidxempty >= MD_MAX_PINS)
+ logprintf(pCardData, 2,
+ "no free slot for container[%i] auth id, might not work properly\n",
+ ii);
+ else
+ vs->pin_objs[pinidxempty] = keypin_obj;
+ }
+
+ if (sc_pkcs15_compare_id(&key_obj->auth_id, &userpin_info->auth_id)) {
+ pin_mode_t pin_mode_n =
+ cont->flags & CONTAINER_MAP_DEFAULT_CONTAINER ?
+ SCF_DEFAULT_USER_PIN : SCF_NONDEFAULT_USER_PIN;
+
+ logprintf(pCardData, 7,
+ "Container[%i]%s is secured by User PIN\n",
+ ii,
+ cont->flags & CONTAINER_MAP_DEFAULT_CONTAINER ?
+ " (default)" : "");
+
+ if (pin_mode < pin_mode_n) {
+ pin_mode = pin_mode_n;
+ pin_cont_idx = ii;
+ }
+ } else if (signpin_info != NULL &&
+ sc_pkcs15_compare_id(&key_obj->auth_id, &signpin_info->auth_id)) {
+ pin_mode_t pin_mode_n =
+ cont->flags & CONTAINER_MAP_DEFAULT_CONTAINER ?
+ SCF_DEFAULT_SIGN_PIN : SCF_NONDEFAULT_SIGN_PIN;
+
+ logprintf(pCardData, 7,
+ "Container[%i]%s is secured by Sign PIN\n",
+ ii,
+ cont->flags & CONTAINER_MAP_DEFAULT_CONTAINER ?
+ " (default)" : "");
+
+ if (pin_mode < pin_mode_n) {
+ pin_mode = pin_mode_n;
+ pin_cont_idx = ii;
+ }
+ } else if (adminpin_info != NULL &&
+ sc_pkcs15_compare_id(&key_obj->auth_id, &adminpin_info->auth_id)) {
+ logprintf(pCardData, 2,
+ "Container[%i] is secured by Admin PIN, might not work properly\n",
+ ii);
+ } else {
+ pin_mode_t pin_mode_n =
+ cont->flags & CONTAINER_MAP_DEFAULT_CONTAINER ?
+ SCF_DEFAULT_OTHER_PIN : SCF_NONDEFAULT_OTHER_PIN;
+
+ logprintf(pCardData, 7,
+ "Container[%i]%s is secured by other PIN\n",
+ ii,
+ cont->flags & CONTAINER_MAP_DEFAULT_CONTAINER ?
+ " (default)" : "");
+
+ if (pin_mode < pin_mode_n) {
+ pin_mode = pin_mode_n;
+ pin_cont_idx = ii;
+ }
+ }
+ }
+ }
+
+ if (cont->flags & CONTAINER_MAP_VALID_CONTAINER &&
+ cont->flags & CONTAINER_MAP_DEFAULT_CONTAINER)
found_default = 1;
/* AT_KEYEXCHANGE is more general key usage,
@@ -1580,7 +1850,6 @@ md_set_cmapfile(PCARD_DATA pCardData, struct md_file *file)
cont->size_key_exchange = prkey_info->field_length;
}
- logprintf(pCardData, 7, "Container[%i]'s guid=%.*s\n", ii, (int) sizeof cont->guid, cont->guid);
logprintf(pCardData, 7,
"Container[%i]'s key-exchange:%"SC_FORMAT_LEN_SIZE_T"u, sign:%"SC_FORMAT_LEN_SIZE_T"u\n",
ii, cont->size_key_exchange, cont->size_sign);
@@ -1638,6 +1907,108 @@ md_set_cmapfile(PCARD_DATA pCardData, struct md_file *file)
}
}
#endif
+
+ /* if no default container was found promote the best one (PIN-wise) to default */
+ if (!found_default && (pin_mode == SCF_NONDEFAULT_SIGN_PIN ||
+ pin_mode == SCF_NONDEFAULT_OTHER_PIN ||
+ pin_mode == SCF_NONDEFAULT_USER_PIN)) {
+ struct md_pkcs15_container *cont =
+ &vs->p15_containers[pin_cont_idx];
+ cont->flags |= CONTAINER_MAP_DEFAULT_CONTAINER;
+
+ found_default = 1;
+
+ logprintf(pCardData, 7,
+ "Container[%i] promoted to default\n",
+ pin_cont_idx);
+
+ if (pin_mode == SCF_NONDEFAULT_SIGN_PIN)
+ pin_mode = SCF_DEFAULT_SIGN_PIN;
+ else if (pin_mode == SCF_NONDEFAULT_OTHER_PIN)
+ pin_mode = SCF_DEFAULT_OTHER_PIN;
+ else
+ pin_mode = SCF_DEFAULT_USER_PIN;
+ }
+
+ /* if all containers use non-user PINs we need to make the best container PIN the user (primary) one */
+ if (pin_mode == SCF_NONDEFAULT_SIGN_PIN ||
+ pin_mode == SCF_DEFAULT_SIGN_PIN ||
+ pin_mode == SCF_NONDEFAULT_OTHER_PIN ||
+ pin_mode == SCF_DEFAULT_OTHER_PIN) {
+ struct sc_pkcs15_object *user_pin_old =
+ vs->pin_objs[ROLE_USER];
+ struct sc_pkcs15_object *user_pin_new =
+ NULL;
+
+ if (pin_mode == SCF_NONDEFAULT_SIGN_PIN ||
+ pin_mode == SCF_DEFAULT_SIGN_PIN) {
+ user_pin_new = vs->pin_objs[MD_ROLE_USER_SIGN];
+ vs->pin_objs[MD_ROLE_USER_SIGN] = NULL;
+
+ logprintf(pCardData, 7,
+ "Sign PIN%s promoted to user one\n",
+ pin_mode == SCF_DEFAULT_SIGN_PIN ?
+ " (from default container)" : "");
+ } else {
+ struct sc_pkcs15_object *key_obj =
+ vs->p15_containers[pin_cont_idx].prkey_obj;
+ struct sc_pkcs15_object *keypin_obj;
+
+ if (sc_pkcs15_find_pin_by_auth_id(vs->p15card, &key_obj->auth_id, &keypin_obj))
+ logprintf(pCardData, 2,
+ "Cannot find container[%i] auth id again, might not work properly\n",
+ pin_cont_idx);
+ else {
+ size_t pinidx;
+
+ logprintf(pCardData, 7,
+ "Container[%i]%s PIN will be made the user one\n",
+ pin_cont_idx,
+ pin_mode == SCF_DEFAULT_OTHER_PIN ?
+ " (default)" : "");
+
+ for (pinidx = 0; pinidx < MD_MAX_PINS; pinidx++) {
+ struct sc_pkcs15_auth_info *pin_info;
+
+ if (!vs->pin_objs[pinidx])
+ continue;
+
+ pin_info =
+ (struct sc_pkcs15_auth_info *)vs->pin_objs[pinidx]->data;
+
+ if (sc_pkcs15_compare_id(&key_obj->auth_id,
+ &pin_info->auth_id)) {
+ vs->pin_objs[pinidx] = NULL;
+ break;
+ }
+ }
+
+ user_pin_new = keypin_obj;
+ }
+ }
+
+ if (user_pin_new) {
+ size_t pinidx;
+
+ vs->pin_objs[ROLE_USER] = user_pin_new;
+
+ for (pinidx = 0; pinidx < MD_MAX_PINS; pinidx++) {
+ if (vs->pin_objs[pinidx])
+ continue;
+
+ vs->pin_objs[pinidx] = user_pin_old;
+ break;
+ }
+
+ if (pinidx >= MD_MAX_PINS) {
+ logprintf(pCardData, 2,
+ "no free slot for previous User PIN, replacing last one\n");
+
+ vs->pin_objs[MD_MAX_PINS - 1] = user_pin_old;
+ }
+ }
+ }
+
/* Initialize 'CMAPFILE' content from the P15 containers */
p = (PCONTAINER_MAP_RECORD)cmap_buf;
for (ii=0; iiroot.files), "cardcf", EveryoneReadUserWriteAc, NULL, 0, &cardcf);
if (dwret != SCARD_S_SUCCESS)
- return dwret;
+ goto ret_cleanup;
dwret = md_set_cardcf(pCardData, cardcf);
if (dwret != SCARD_S_SUCCESS)
- return dwret;
+ goto ret_cleanup;
dwret = md_fs_add_file(pCardData, &(vs->root.files), "cardapps", EveryoneReadAdminWriteAc, NULL, 0, &cardapps);
if (dwret != SCARD_S_SUCCESS)
- return dwret;
+ goto ret_cleanup;
dwret = md_set_cardapps(pCardData, cardapps);
if (dwret != SCARD_S_SUCCESS)
- return dwret;
+ goto ret_cleanup;
dwret = md_fs_add_directory(pCardData, &(vs->root.subdirs), "mscp", UserCreateDeleteDirAc, &mscp);
if (dwret != SCARD_S_SUCCESS)
- return dwret;
+ goto ret_cleanup;
dwret = md_fs_add_file(pCardData, &(mscp->files), "cmapfile", EveryoneReadUserWriteAc, NULL, 0, &cmapfile);
if (dwret != SCARD_S_SUCCESS)
- return dwret;
+ goto ret_cleanup;
dwret = md_set_cmapfile(pCardData, cmapfile);
if (dwret != SCARD_S_SUCCESS)
- return dwret;
+ goto ret_cleanup;
#ifdef OPENSSL_VERSION_NUMBER
logprintf(pCardData, 3,
@@ -1750,6 +2121,10 @@ md_fs_init(PCARD_DATA pCardData)
"MD virtual file system initialized; Without OPENSSL\n");
#endif
return SCARD_S_SUCCESS;
+
+ret_cleanup:
+ md_fs_finalize(pCardData);
+ return dwret;
}
/* Create SC context */
@@ -1809,6 +2184,8 @@ md_free_space(PCARD_DATA pCardData, PCARD_FREE_SPACE_INFO pCardFreeSpaceInfo)
return ERROR_REVISION_MISMATCH;
vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
+ if (!vs)
+ return SCARD_E_INVALID_PARAMETER;
/* Count free containers */
for (idx=0, count=0; idxpvVendorSpecific);
+ if (!vs)
+ return SCARD_E_INVALID_PARAMETER;
if (flags & CARD_CREATE_CONTAINER_KEY_IMPORT) {
if (key_algo == SC_ALGORITHM_RSA) {
@@ -1958,7 +2337,7 @@ md_check_key_compatibility(PCARD_DATA pCardData, DWORD flags, DWORD key_type,
static DWORD
-md_pkcs15_generate_key(PCARD_DATA pCardData, DWORD idx, DWORD key_type, DWORD key_size)
+md_pkcs15_generate_key(PCARD_DATA pCardData, DWORD idx, DWORD key_type, DWORD key_size, PIN_ID PinId)
{
VENDOR_SPECIFIC *vs;
struct sc_card *card = NULL;
@@ -1970,13 +2349,19 @@ md_pkcs15_generate_key(PCARD_DATA pCardData, DWORD idx, DWORD key_type, DWORD ke
struct sc_pkcs15init_pubkeyargs pub_args;
struct md_pkcs15_container *cont = NULL;
int rv;
- DWORD dw, dwret = SCARD_F_INTERNAL_ERROR;
+ DWORD dwret = SCARD_F_INTERNAL_ERROR;
CHAR szGuid[MAX_CONTAINER_NAME_LEN +1] = "Default key label";
if (!pCardData)
return SCARD_E_INVALID_PARAMETER;
vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
+ if (!vs)
+ return SCARD_E_INVALID_PARAMETER;
+
+ if (PinId >= MD_MAX_PINS || !vs->pin_objs[PinId])
+ return SCARD_E_INVALID_PARAMETER;
+
card = vs->p15card->card;
memset(&pub_args, 0, sizeof(pub_args));
@@ -2029,12 +2414,7 @@ md_pkcs15_generate_key(PCARD_DATA pCardData, DWORD idx, DWORD key_type, DWORD ke
keygen_args.prkey_args.access_flags = MD_KEY_ACCESS;
- dw = md_get_pin_by_role(pCardData, ROLE_USER, &pin_obj);
- if (dw != SCARD_S_SUCCESS) {
- logprintf(pCardData, 2, "MdGenerateKey(): cannot get User PIN object");
- return dw;
- }
-
+ pin_obj = vs->pin_objs[PinId];
auth_info = (struct sc_pkcs15_auth_info *) pin_obj->data;
keygen_args.prkey_args.auth_id = pub_args.auth_id = auth_info->auth_id;
@@ -2095,9 +2475,8 @@ done:
return dwret;
}
-
static DWORD
-md_pkcs15_store_key(PCARD_DATA pCardData, DWORD idx, DWORD key_type, BYTE *blob, DWORD blob_size)
+md_pkcs15_store_key(PCARD_DATA pCardData, DWORD idx, DWORD key_type, BYTE *blob, DWORD blob_size, PIN_ID PinId)
{
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
VENDOR_SPECIFIC *vs;
@@ -2111,13 +2490,19 @@ md_pkcs15_store_key(PCARD_DATA pCardData, DWORD idx, DWORD key_type, BYTE *blob,
BYTE *ptr = blob;
EVP_PKEY *pkey=NULL;
int rv;
- DWORD dw, dwret = SCARD_F_INTERNAL_ERROR;
+ DWORD dwret = SCARD_F_INTERNAL_ERROR;
CHAR szGuid[MAX_CONTAINER_NAME_LEN +1] = "Default key label";
if (!pCardData)
return SCARD_E_INVALID_PARAMETER;
vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
+ if (!vs)
+ return SCARD_E_INVALID_PARAMETER;
+
+ if (PinId >= MD_MAX_PINS || !vs->pin_objs[PinId])
+ return SCARD_E_INVALID_PARAMETER;
+
card = vs->p15card->card;
pkey = b2i_PrivateKey((const unsigned char **)&ptr, blob_size);
@@ -2157,12 +2542,7 @@ md_pkcs15_store_key(PCARD_DATA pCardData, DWORD idx, DWORD key_type, BYTE *blob,
prkey_args.access_flags = MD_KEY_ACCESS;
- dw = md_get_pin_by_role(pCardData, ROLE_USER, &pin_obj);
- if (dw != SCARD_S_SUCCESS) {
- logprintf(pCardData, 2, "MdStoreKey(): cannot get User PIN object");
- return dw;
- }
-
+ pin_obj = vs->pin_objs[PinId];
prkey_args.auth_id = ((struct sc_pkcs15_auth_info *) pin_obj->data)->auth_id;
rv = sc_lock(card);
@@ -2255,6 +2635,9 @@ md_pkcs15_store_certificate(PCARD_DATA pCardData, char *file_name, unsigned char
logprintf(pCardData, 1, "MdStoreCert(): store certificate '%s'\n", file_name);
vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
+ if (!vs)
+ return SCARD_E_INVALID_PARAMETER;
+
card = vs->p15card->card;
memset(&args, 0, sizeof(args));
@@ -2324,6 +2707,9 @@ md_query_key_sizes(PCARD_DATA pCardData, DWORD dwKeySpec, CARD_KEY_SIZES *pKeySi
logprintf(pCardData, 1, "md_query_key_sizes: store dwKeySpec '%lu'\n",
(unsigned long)dwKeySpec);
vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
+ if (!vs)
+ return SCARD_E_INVALID_PARAMETER;
+
count = vs->p15card->card->algorithm_count;
pKeySizes->dwVersion = CARD_KEY_SIZES_CURRENT_VERSION;
@@ -2752,7 +3138,10 @@ DWORD WINAPI CardDeleteContext(__inout PCARD_DATA pCardData)
if(!vs)
return SCARD_E_INVALID_PARAMETER;
- disassociate_card(pCardData);
+ if (vs->initialized) {
+ disassociate_card(pCardData);
+ md_fs_finalize(pCardData);
+ }
if(vs->ctx) {
logprintf(pCardData, 6, "release context\n");
@@ -2763,7 +3152,6 @@ DWORD WINAPI CardDeleteContext(__inout PCARD_DATA pCardData)
logprintf(pCardData, 1, "**********************************************************************\n");
- md_fs_finalize(pCardData);
pCardData->pfnCspFree(pCardData->pvVendorSpecific);
pCardData->pvVendorSpecific = NULL;
@@ -2783,11 +3171,13 @@ DWORD WINAPI CardQueryCapabilities(__in PCARD_DATA pCardData,
if (!pCardData || !pCardCapabilities)
return SCARD_E_INVALID_PARAMETER;
- dwret = md_card_capabilities(pCardData, pCardCapabilities);
+ dwret = check_card_status(pCardData, "CardQueryCapabilities");
if (dwret != SCARD_S_SUCCESS)
return dwret;
- check_reader_status(pCardData);
+ dwret = md_card_capabilities(pCardData, pCardCapabilities);
+ if (dwret != SCARD_S_SUCCESS)
+ return dwret;
return SCARD_S_SUCCESS;
}
@@ -2808,6 +3198,10 @@ DWORD WINAPI CardDeleteContainer(__in PCARD_DATA pCardData,
if (!pCardData)
return SCARD_E_INVALID_PARAMETER;
+ dwret = check_card_reader_status(pCardData, "CardDeleteContainer");
+ if (dwret != SCARD_S_SUCCESS)
+ return dwret;
+
if (bContainerIndex >= MD_MAX_KEY_CONTAINERS)
return SCARD_E_INVALID_PARAMETER;
@@ -2840,26 +3234,44 @@ DWORD WINAPI CardDeleteContainer(__in PCARD_DATA pCardData,
return SCARD_S_SUCCESS;
}
-
-DWORD WINAPI CardCreateContainer(__in PCARD_DATA pCardData,
- __in BYTE bContainerIndex,
- __in DWORD dwFlags,
- __in DWORD dwKeySpec,
- __in DWORD dwKeySize,
- __in PBYTE pbKeyData)
+/** The CardCreateContainerEx function creates a new key container that the
+container index identifies and the bContainerIndex parameter specifies. The function
+associates the key container with the PIN that the PinId parameter specified.
+This function is useful if the card-edge does not allow for changing the key attributes
+after the key container is created. This function replaces the need to call
+CardSetContainerProperty to set the CCP_PIN_IDENTIFIER property CardCreateContainer
+is called.
+The caller of this function can provide the key material that the card imports.
+This is useful in those situations in which the card either does not support internal
+key generation or the caller requests that the key be archived in the card.*/
+DWORD WINAPI CardCreateContainerEx(__in PCARD_DATA pCardData,
+ __in BYTE bContainerIndex,
+ __in DWORD dwFlags,
+ __in DWORD dwKeySpec,
+ __in DWORD dwKeySize,
+ __in PBYTE pbKeyData,
+ __in PIN_ID PinId)
{
DWORD dwret;
if (!pCardData)
return SCARD_E_INVALID_PARAMETER;
+ if (PinId == ROLE_ADMIN)
+ return SCARD_W_SECURITY_VIOLATION;
+
+ dwret = check_card_reader_status(pCardData, "CardCreateContainerEx");
+ if (dwret != SCARD_S_SUCCESS)
+ return dwret;
+
logprintf(pCardData, 1, "\nP:%lu T:%lu pCardData:%p ",
(unsigned long)GetCurrentProcessId(),
(unsigned long)GetCurrentThreadId(), pCardData);
logprintf(pCardData, 1,
- "CardCreateContainerEx(idx:%u,flags:%lX,type:%lX,size:%lu,data:%p)\n",
+ "CardCreateContainerEx(idx:%u,flags:%lX,type:%lX,size:%lu,data:%p,pin:%u)\n",
(unsigned int)bContainerIndex, (unsigned long)dwFlags,
- (unsigned long)dwKeySpec, (unsigned long)dwKeySize, pbKeyData);
+ (unsigned long)dwKeySpec, (unsigned long)dwKeySize, pbKeyData,
+ (unsigned int)PinId);
if (pbKeyData) {
logprintf(pCardData, 7, "Key data\n");
@@ -2888,7 +3300,7 @@ DWORD WINAPI CardCreateContainer(__in PCARD_DATA pCardData,
}
if (dwFlags & CARD_CREATE_CONTAINER_KEY_GEN) {
- dwret = md_pkcs15_generate_key(pCardData, bContainerIndex, dwKeySpec, dwKeySize);
+ dwret = md_pkcs15_generate_key(pCardData, bContainerIndex, dwKeySpec, dwKeySize, PinId);
if (dwret != SCARD_S_SUCCESS) {
logprintf(pCardData, 1, "key generation failed\n");
return dwret;
@@ -2896,7 +3308,7 @@ DWORD WINAPI CardCreateContainer(__in PCARD_DATA pCardData,
logprintf(pCardData, 1, "key generated\n");
}
else if ((dwFlags & CARD_CREATE_CONTAINER_KEY_IMPORT) && (pbKeyData != NULL)) {
- dwret = md_pkcs15_store_key(pCardData, bContainerIndex, dwKeySpec, pbKeyData, dwKeySize);
+ dwret = md_pkcs15_store_key(pCardData, bContainerIndex, dwKeySpec, pbKeyData, dwKeySize, PinId);
if (dwret != SCARD_S_SUCCESS) {
logprintf(pCardData, 1, "key store failed\n");
return dwret;
@@ -2912,6 +3324,17 @@ DWORD WINAPI CardCreateContainer(__in PCARD_DATA pCardData,
return SCARD_S_SUCCESS;
}
+DWORD WINAPI CardCreateContainer(__in PCARD_DATA pCardData,
+ __in BYTE bContainerIndex,
+ __in DWORD dwFlags,
+ __in DWORD dwKeySpec,
+ __in DWORD dwKeySize,
+ __in PBYTE pbKeyData)
+{
+ return CardCreateContainerEx(pCardData, bContainerIndex, dwFlags,
+ dwKeySpec, dwKeySize, pbKeyData,
+ ROLE_USER);
+}
typedef struct {
PUBLICKEYSTRUC publickeystruc;
@@ -2923,7 +3346,7 @@ DWORD WINAPI CardGetContainerInfo(__in PCARD_DATA pCardData, __in BYTE bContaine
{
VENDOR_SPECIFIC *vs = NULL;
DWORD sz = 0;
- DWORD ret = SCARD_F_UNKNOWN_ERROR;
+ DWORD ret;
struct md_pkcs15_container *cont = NULL;
struct sc_pkcs15_der pubkey_der;
struct sc_pkcs15_prkey_info *prkey_info = NULL;
@@ -2934,6 +3357,10 @@ DWORD WINAPI CardGetContainerInfo(__in PCARD_DATA pCardData, __in BYTE bContaine
if (!pContainerInfo)
return SCARD_E_INVALID_PARAMETER;
+ ret = check_card_reader_status(pCardData, "CardGetContainerInfo");
+ if (ret != SCARD_S_SUCCESS)
+ return ret;
+
logprintf(pCardData, 1, "\nP:%lu T:%lu pCardData:%p ",
(unsigned long)GetCurrentProcessId(),
(unsigned long)GetCurrentThreadId(), pCardData);
@@ -2954,6 +3381,9 @@ DWORD WINAPI CardGetContainerInfo(__in PCARD_DATA pCardData, __in BYTE bContaine
pContainerInfo->dwVersion = CONTAINER_INFO_CURRENT_VERSION;
vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
+ if (!vs)
+ return SCARD_E_INVALID_PARAMETER;
+
cont = &vs->p15_containers[bContainerIndex];
if (!cont->prkey_obj) {
@@ -2962,13 +3392,9 @@ DWORD WINAPI CardGetContainerInfo(__in PCARD_DATA pCardData, __in BYTE bContaine
return SCARD_E_NO_KEY_CONTAINER;
}
- if (vs->p15card == NULL) {
- return SCARD_F_INTERNAL_ERROR;
- }
-
+ ret = SCARD_F_UNKNOWN_ERROR;
prkey_info = (struct sc_pkcs15_prkey_info *)cont->prkey_obj->data;
- check_reader_status(pCardData);
pubkey_der.value = NULL;
pubkey_der.len = 0;
@@ -3203,6 +3629,7 @@ DWORD WINAPI CardGetChallenge(__in PCARD_DATA pCardData,
__out PDWORD pcbChallengeData)
{
VENDOR_SPECIFIC *vs;
+ DWORD dwret;
int rv;
logprintf(pCardData, 1, "\nP:%lu T:%lu pCardData:%p ",
@@ -3215,9 +3642,13 @@ DWORD WINAPI CardGetChallenge(__in PCARD_DATA pCardData,
if (!ppbChallengeData || !pcbChallengeData)
return SCARD_E_INVALID_PARAMETER;
- vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
+ dwret = check_card_reader_status(pCardData, "CardGetChallenge");
+ if (dwret != SCARD_S_SUCCESS)
+ return dwret;
- check_reader_status(pCardData);
+ vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
+ if (!vs)
+ return SCARD_E_INVALID_PARAMETER;
*pcbChallengeData = 8;
@@ -3365,14 +3796,12 @@ DWORD WINAPI CardChangeAuthenticator(__in PCARD_DATA pCardData,
cRetryCount, pcAttemptsRemaining);
}
-/* this function is not called on purpose.
-If a deauthentication is not possible, it should be set to NULL in CardAcquireContext.
-Because this function do nothing - it is not called.
-Note: the PIN freshnesh will be managed by the Base CSP*/
+/* Note: the PIN freshness will be managed by the Base CSP */
DWORD WINAPI CardDeauthenticate(__in PCARD_DATA pCardData,
__in LPWSTR pwszUserId,
__in DWORD dwFlags)
{
+ DWORD dwret;
VENDOR_SPECIFIC* vs = NULL;
int rv;
logprintf(pCardData, 1, "\nP:%ld T:%ld pCardData:%p ",
@@ -3384,7 +3813,13 @@ DWORD WINAPI CardDeauthenticate(__in PCARD_DATA pCardData,
if(!pCardData)
return SCARD_E_INVALID_PARAMETER;
+ dwret = check_card_reader_status(pCardData, "CardDeauthenticate");
+ if (dwret != SCARD_S_SUCCESS)
+ return dwret;
+
vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
+ if (!vs)
+ return SCARD_E_INVALID_PARAMETER;
sc_pkcs15_pincache_clear(vs->p15card);
@@ -3434,6 +3869,10 @@ DWORD WINAPI CardCreateFile(__in PCARD_DATA pCardData,
NULLSTR(pszDirectoryName), NULLSTR(pszFileName),
(unsigned long)cbInitialCreationSize, AccessCondition);
+ dwret = check_card_status(pCardData, "CardCreateFile");
+ if (dwret != SCARD_S_SUCCESS)
+ return dwret;
+
dwret = md_fs_find_directory(pCardData, NULL, pszDirectoryName, &dir);
if (dwret != SCARD_S_SUCCESS) {
logprintf(pCardData, 1, "CardCreateFile() cannot find parent directory '%s'", NULLSTR(pszDirectoryName));
@@ -3456,6 +3895,7 @@ DWORD WINAPI CardReadFile(__in PCARD_DATA pCardData,
__out PDWORD pcbData)
{
struct md_file *file = NULL;
+ DWORD dwret;
logprintf(pCardData, 1, "\nP:%lu T:%lu pCardData:%p ",
(unsigned long)GetCurrentProcessId(),
@@ -3475,7 +3915,9 @@ DWORD WINAPI CardReadFile(__in PCARD_DATA pCardData,
if (dwFlags)
return SCARD_E_INVALID_PARAMETER;
- check_reader_status(pCardData);
+ dwret = check_card_reader_status(pCardData, "CardReadFile");
+ if (dwret != SCARD_S_SUCCESS)
+ return dwret;
md_fs_find_file(pCardData, pszDirectoryName, pszFileName, &file);
if (!file) {
@@ -3526,7 +3968,9 @@ DWORD WINAPI CardWriteFile(__in PCARD_DATA pCardData,
(unsigned long)GetCurrentThreadId(), pCardData);
logprintf(pCardData, 1, "CardWriteFile() dirName:'%s', fileName:'%s' \n", NULLSTR(pszDirectoryName), NULLSTR(pszFileName));
- check_reader_status(pCardData);
+ dwret = check_card_reader_status(pCardData, "CardWriteFile");
+ if (dwret != SCARD_S_SUCCESS)
+ return dwret;
if (pbData && cbData) {
logprintf(pCardData, 1, "CardWriteFile try to write (%lu):\n",
@@ -3578,7 +4022,9 @@ DWORD WINAPI CardDeleteFile(__in PCARD_DATA pCardData,
if(!pCardData)
return SCARD_E_INVALID_PARAMETER;
- check_reader_status(pCardData);
+ dwret = check_card_reader_status(pCardData, "CardDeleteFile");
+ if (dwret != SCARD_S_SUCCESS)
+ return dwret;
dwret = md_fs_delete_file(pCardData, pszDirectoryName, pszFileName);
if (dwret != SCARD_S_SUCCESS) {
@@ -3599,6 +4045,7 @@ DWORD WINAPI CardEnumFiles(__in PCARD_DATA pCardData,
__in DWORD dwFlags)
{
VENDOR_SPECIFIC *vs = NULL;
+ DWORD dwret;
char mstr[0x100];
struct md_directory *dir = NULL;
struct md_file *file = NULL;
@@ -3620,7 +4067,13 @@ DWORD WINAPI CardEnumFiles(__in PCARD_DATA pCardData,
return SCARD_E_INVALID_PARAMETER;
}
+ dwret = check_card_status(pCardData, "CardEnumFiles");
+ if (dwret != SCARD_S_SUCCESS)
+ return dwret;
+
vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
+ if (!vs)
+ return SCARD_E_INVALID_PARAMETER;
memset(mstr, 0, sizeof(mstr));
@@ -3658,6 +4111,7 @@ DWORD WINAPI CardGetFileInfo(__in PCARD_DATA pCardData,
__in LPSTR pszFileName,
__inout PCARD_FILE_INFO pCardFileInfo)
{
+ DWORD dwret;
struct md_file *file = NULL;
logprintf(pCardData, 1, "\nP:%lu T:%lu pCardData:%p ",
@@ -3665,6 +4119,10 @@ DWORD WINAPI CardGetFileInfo(__in PCARD_DATA pCardData,
(unsigned long)GetCurrentThreadId(), pCardData);
logprintf(pCardData, 1, "CardGetFileInfo(dirName:'%s',fileName:'%s', out %p)\n", NULLSTR(pszDirectoryName), NULLSTR(pszFileName), pCardFileInfo);
+ dwret = check_card_status(pCardData, "CardGetFileInfo");
+ if (dwret != SCARD_S_SUCCESS)
+ return dwret;
+
md_fs_find_file(pCardData, pszDirectoryName, pszFileName, &file);
if (!file) {
logprintf(pCardData, 2, "CardWriteFile(): file '%s' not found in '%s'\n", NULLSTR(pszFileName), NULLSTR(pszDirectoryName));
@@ -3695,7 +4153,9 @@ DWORD WINAPI CardQueryFreeSpace(__in PCARD_DATA pCardData, __in DWORD dwFlags,
if (!pCardData)
return SCARD_E_INVALID_PARAMETER;
- check_reader_status(pCardData);
+ dwret = check_card_status(pCardData, "CardQueryFreeSpace");
+ if (dwret != SCARD_S_SUCCESS)
+ return dwret;
dwret = md_free_space(pCardData, pCardFreeSpaceInfo);
if (dwret != SCARD_S_SUCCESS) {
@@ -3731,6 +4191,10 @@ DWORD WINAPI CardQueryKeySizes(__in PCARD_DATA pCardData,
if ( dwKeySpec == 0 )
return SCARD_E_INVALID_PARAMETER;
+ dwret = check_card_status(pCardData, "CardQueryKeySizes");
+ if (dwret != SCARD_S_SUCCESS)
+ return dwret;
+
dwret = md_query_key_sizes(pCardData, dwKeySpec, pKeySizes);
if (dwret != SCARD_S_SUCCESS)
return dwret;
@@ -3745,6 +4209,7 @@ DWORD WINAPI CardRSADecrypt(__in PCARD_DATA pCardData,
__inout PCARD_RSA_DECRYPT_INFO pInfo)
{
+ DWORD dwret;
int r, opt_crypt_flags = 0;
unsigned ui;
VENDOR_SPECIFIC *vs;
@@ -3771,14 +4236,18 @@ DWORD WINAPI CardRSADecrypt(__in PCARD_DATA pCardData,
if (pInfo->dwKeySpec != AT_KEYEXCHANGE)
return SCARD_E_INVALID_PARAMETER;
+ dwret = check_card_reader_status(pCardData, "CardRSADecrypt");
+ if (dwret != SCARD_S_SUCCESS)
+ return dwret;
+
vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
+ if (!vs)
+ return SCARD_E_INVALID_PARAMETER;
/* check if the container exists */
if (pInfo->bContainerIndex >= MD_MAX_KEY_CONTAINERS)
return SCARD_E_NO_KEY_CONTAINER;
- check_reader_status(pCardData);
-
logprintf(pCardData, 2,
"CardRSADecrypt dwVersion=%lu, bContainerIndex=%u, dwKeySpec=%lu pbData=%p, cbData=%lu\n",
(unsigned long)pInfo->dwVersion,
@@ -3926,6 +4395,7 @@ DWORD WINAPI CardRSADecrypt(__in PCARD_DATA pCardData,
DWORD WINAPI CardSignData(__in PCARD_DATA pCardData, __inout PCARD_SIGNING_INFO pInfo)
{
+ DWORD dwret;
VENDOR_SPECIFIC *vs;
ALG_ID hashAlg;
sc_pkcs15_prkey_info_t *prkey_info;
@@ -3963,6 +4433,10 @@ DWORD WINAPI CardSignData(__in PCARD_DATA pCardData, __inout PCARD_SIGNING_INFO
if (pInfo->dwSigningFlags & ~(CARD_PADDING_INFO_PRESENT | CARD_PADDING_NONE | CARD_BUFFER_SIZE_ONLY | CARD_PADDING_PKCS1 | CARD_PADDING_PSS | CARD_PADDING_OAEP))
return SCARD_E_INVALID_PARAMETER;
+ dwret = check_card_reader_status(pCardData, "CardSignData");
+ if (dwret != SCARD_S_SUCCESS)
+ return dwret;
+
logprintf(pCardData, 2,
"CardSignData dwVersion=%lu, bContainerIndex=%u, dwKeySpec=%lu, dwSigningFlags=0x%08X, aiHashAlg=0x%08X\n",
(unsigned long)pInfo->dwVersion,
@@ -3978,6 +4452,9 @@ DWORD WINAPI CardSignData(__in PCARD_DATA pCardData, __inout PCARD_SIGNING_INFO
hashAlg = pInfo->aiHashAlg;
vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
+ if (!vs)
+ return SCARD_E_INVALID_PARAMETER;
+
if (pInfo->bContainerIndex >= MD_MAX_KEY_CONTAINERS)
return SCARD_E_NO_KEY_CONTAINER;
@@ -3986,8 +4463,6 @@ DWORD WINAPI CardSignData(__in PCARD_DATA pCardData, __inout PCARD_SIGNING_INFO
return SCARD_E_NO_KEY_CONTAINER;
prkey_info = (struct sc_pkcs15_prkey_info *)(pkey->data);
- check_reader_status(pCardData);
-
logprintf(pCardData, 2, "pInfo->dwVersion = %lu\n",
(unsigned long)pInfo->dwVersion);
@@ -4183,6 +4658,7 @@ DWORD WINAPI CardSignData(__in PCARD_DATA pCardData, __inout PCARD_SIGNING_INFO
DWORD WINAPI CardConstructDHAgreement(__in PCARD_DATA pCardData,
__inout PCARD_DH_AGREEMENT_INFO pAgreementInfo)
{
+ DWORD dwret;
VENDOR_SPECIFIC *vs;
struct sc_pkcs15_object *pkey = NULL;
int r, opt_derive_flags = 0;
@@ -4211,14 +4687,18 @@ DWORD WINAPI CardConstructDHAgreement(__in PCARD_DATA pCardData,
&& pCardData->dwVersion == CARD_DATA_CURRENT_VERSION)
return ERROR_REVISION_MISMATCH;
+ dwret = check_card_reader_status(pCardData, "CardConstructDHAgreement");
+ if (dwret != SCARD_S_SUCCESS)
+ return dwret;
+
vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
+ if (!vs)
+ return SCARD_E_INVALID_PARAMETER;
/* check if the container exists */
if (pAgreementInfo->bContainerIndex >= MD_MAX_KEY_CONTAINERS)
return SCARD_E_NO_KEY_CONTAINER;
- check_reader_status(pCardData);
-
logprintf(pCardData, 2, "CardConstructDHAgreement dwVersion=%lu, dwKeySpec=%u pbData=%p, cbData=%lu\n",
(unsigned long)pAgreementInfo->dwVersion,
(unsigned int)pAgreementInfo->bContainerIndex,
@@ -4754,6 +5234,8 @@ DWORD WINAPI CardDeriveKey(__in PCARD_DATA pCardData,
return ERROR_REVISION_MISMATCH;*/
vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
+ if (!vs)
+ return SCARD_E_INVALID_PARAMETER;
/* check if the agreement index is ok */
if (pAgreementInfo->bSecretAgreementIndex >= vs->allocatedAgreements) {
@@ -4924,6 +5406,8 @@ DWORD WINAPI CardDestroyDHAgreement(
if (dwFlags)
return SCARD_E_INVALID_PARAMETER;
vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
+ if (!vs)
+ return SCARD_E_INVALID_PARAMETER;
if (bSecretAgreementIndex >= vs->allocatedAgreements) {
return SCARD_E_INVALID_PARAMETER;
@@ -4962,6 +5446,7 @@ DWORD WINAPI CardAuthenticateEx(__in PCARD_DATA pCardData,
__out_opt PDWORD pcbSessionPin,
__out_opt PDWORD pcAttemptsRemaining)
{
+ DWORD dwret;
VENDOR_SPECIFIC *vs;
struct sc_pkcs15_object *pin_obj = NULL;
struct sc_pkcs15_auth_info *auth_info = NULL;
@@ -4977,17 +5462,25 @@ DWORD WINAPI CardAuthenticateEx(__in PCARD_DATA pCardData,
if (!pCardData)
return SCARD_E_INVALID_PARAMETER;
+ dwret = check_card_reader_status(pCardData, "CardAuthenticateEx");
+ if (dwret != SCARD_S_SUCCESS)
+ return dwret;
+
logprintf(pCardData, 2,
"CardAuthenticateEx: PinId=%u, dwFlags=0x%08X, cbPinData=%lu, Attempts %s\n",
(unsigned int)PinId, (unsigned int)dwFlags,
(unsigned long)cbPinData, pcAttemptsRemaining ? "YES" : "NO");
vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
+ if (!vs)
+ return SCARD_E_INVALID_PARAMETER;
- r = check_reader_status(pCardData);
+ if (PinId >= MD_MAX_PINS)
+ return SCARD_E_INVALID_PARAMETER;
- if ((vs->p15card) == NULL)
- return SCARD_F_INTERNAL_ERROR;
+ pin_obj = vs->pin_objs[PinId];
+ if (!pin_obj)
+ return SCARD_E_INVALID_PARAMETER;
#if 0
/* TODO do we need to return SCARD_E_UNSUPPORTED_FEATURE if the card
@@ -5003,6 +5496,10 @@ DWORD WINAPI CardAuthenticateEx(__in PCARD_DATA pCardData,
if (dwFlags & ~(CARD_AUTHENTICATE_GENERATE_SESSION_PIN | CARD_AUTHENTICATE_SESSION_PIN | CARD_PIN_SILENT_CONTEXT))
return SCARD_E_INVALID_PARAMETER;
+ if (dwFlags & CARD_AUTHENTICATE_GENERATE_SESSION_PIN &&
+ (ppbSessionPin == NULL || pcbSessionPin == NULL))
+ return SCARD_E_INVALID_PARAMETER;
+
/* using a pin pad */
if (NULL == pbPinData) {
if (!(vs->reader->capabilities & SC_READER_CAP_PIN_PAD
@@ -5014,20 +5511,9 @@ DWORD WINAPI CardAuthenticateEx(__in PCARD_DATA pCardData,
}
}
- if (PinId != ROLE_USER)
- return SCARD_E_INVALID_PARAMETER;
-
if(pcAttemptsRemaining)
(*pcAttemptsRemaining) = (DWORD) -1;
- r = md_get_pin_by_role(pCardData, PinId, &pin_obj);
- if (r != SCARD_S_SUCCESS) {
- logprintf(pCardData, 2, "Cannot get User PIN object");
- return r;
- }
-
- if (!pin_obj)
- return SCARD_F_INTERNAL_ERROR;
auth_info = (struct sc_pkcs15_auth_info *)pin_obj->data;
/* save the pin type */
auth_method = auth_info->auth_method;
@@ -5046,34 +5532,49 @@ DWORD WINAPI CardAuthenticateEx(__in PCARD_DATA pCardData,
cbPinData = 0;
} else {
/* seems we have a real session pin, set the pin type accordingly */
- logprintf(pCardData, 2, "use real session pin with %d bytes", cbPinData);
+ logprintf(pCardData, 2,
+ "use real session pin with %lu bytes",
+ (unsigned long)cbPinData);
auth_info->auth_method = SC_AC_SESSION;
}
}
/* set the session pin according to the minidriver specification */
if (dwFlags & CARD_AUTHENTICATE_GENERATE_SESSION_PIN) {
+ size_t session_pin_len = SC_MAX_PIN_SIZE;
+
logprintf(pCardData, 2, "generating session pin");
- if (ppbSessionPin) *ppbSessionPin = pCardData->pfnCspAlloc(SC_MAX_PIN_SIZE);
- if (ppbSessionPin) *pcbSessionPin = SC_MAX_PIN_SIZE;
- r = md_dialog_perform_pin_operation(pCardData, SC_PIN_CMD_GET_SESSION_PIN, vs->p15card, pin_obj, (const u8 *) pbPinData, cbPinData,
- ppbSessionPin && *ppbSessionPin ? *ppbSessionPin : NULL, pcbSessionPin, DisplayPinpadUI, PinId);
+ *ppbSessionPin = pCardData->pfnCspAlloc(SC_MAX_PIN_SIZE);
+ r = md_dialog_perform_pin_operation(pCardData,
+ SC_PIN_CMD_GET_SESSION_PIN,
+ vs->p15card, pin_obj,
+ (const u8 *) pbPinData,
+ cbPinData,
+ *ppbSessionPin,
+ *ppbSessionPin != NULL ?
+ &session_pin_len : NULL,
+ DisplayPinpadUI, PinId);
if (r) {
- if (ppbSessionPin) {
+ if (*ppbSessionPin != NULL) {
pCardData->pfnCspFree(*ppbSessionPin);
*ppbSessionPin = NULL;
}
- if (pcbSessionPin) *pcbSessionPin = 0;
+ *pcbSessionPin = 0;
logprintf(pCardData, 2, "generating session pin failed");
} else {
- if (pcbSessionPin && *pcbSessionPin) {
- logprintf(pCardData, 2, "generated session pin with %d bytes", *pcbSessionPin);
+ if (*ppbSessionPin != NULL && session_pin_len > 0) {
+ logprintf(pCardData, 2,
+ "generated session pin with %"SC_FORMAT_LEN_SIZE_T"u bytes",
+ session_pin_len);
+
+ *pcbSessionPin = session_pin_len;
} else {
logprintf(pCardData, 2, "session pin not supported");
- if (ppbSessionPin) {
+ if (*ppbSessionPin != NULL) {
pCardData->pfnCspFree(*ppbSessionPin);
*ppbSessionPin = NULL;
}
+ *pcbSessionPin = 0;
}
}
} else {
@@ -5103,16 +5604,16 @@ DWORD WINAPI CardAuthenticateEx(__in PCARD_DATA pCardData,
logprintf(pCardData, 2, "Pin code correct.\n");
/* set the session pin according to the minidriver specification */
- if (dwFlags == CARD_AUTHENTICATE_GENERATE_SESSION_PIN
- && pcbSessionPin && *pcbSessionPin == 0
+ if (dwFlags & CARD_AUTHENTICATE_GENERATE_SESSION_PIN
+ && *pcbSessionPin == 0
&& (vs->reader->capabilities & SC_READER_CAP_PIN_PAD
|| vs->p15card->card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH)) {
/* If we could not generate a real session PIN, set it to a special
* value for pinpad authentication to force a new pinpad authentication */
- *pcbSessionPin = sizeof(MAGIC_SESSION_PIN);
- if (ppbSessionPin) {
- *ppbSessionPin = pCardData->pfnCspAlloc(sizeof(MAGIC_SESSION_PIN));
- if (ppbSessionPin) memcpy(*ppbSessionPin, MAGIC_SESSION_PIN, sizeof(MAGIC_SESSION_PIN));
+ *ppbSessionPin = pCardData->pfnCspAlloc(sizeof(MAGIC_SESSION_PIN));
+ if (*ppbSessionPin != NULL) {
+ memcpy(*ppbSessionPin, MAGIC_SESSION_PIN, sizeof(MAGIC_SESSION_PIN));
+ *pcbSessionPin = sizeof(MAGIC_SESSION_PIN);
}
}
@@ -5131,12 +5632,13 @@ DWORD WINAPI CardChangeAuthenticatorEx(__in PCARD_DATA pCardData,
__in DWORD cRetryCount,
__out_opt PDWORD pcAttemptsRemaining)
{
+ DWORD dwret;
VENDOR_SPECIFIC *vs = NULL;
- DWORD dw_rv;
struct sc_pkcs15_object *pin_obj = NULL;
int rv;
struct sc_pkcs15_auth_info *auth_info;
BOOL DisplayPinpadUI = FALSE;
+ size_t target_len = cbTargetData;
logprintf(pCardData, 1, "\nP:%lu T:%lu pCardData:%p ",
(unsigned long)GetCurrentProcessId(),
@@ -5145,6 +5647,15 @@ DWORD WINAPI CardChangeAuthenticatorEx(__in PCARD_DATA pCardData,
if (!pCardData)
return SCARD_E_INVALID_PARAMETER;
+
+ dwret = check_card_reader_status(pCardData, "CardChangeAuthenticatorEx");
+ if (dwret != SCARD_S_SUCCESS)
+ return dwret;
+
+ vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
+ if (!vs)
+ return SCARD_E_INVALID_PARAMETER;
+
if (!(dwFlags & PIN_CHANGE_FLAG_UNBLOCK) && !(dwFlags & PIN_CHANGE_FLAG_CHANGEPIN)){
logprintf(pCardData, 1, "Unknown flag\n");
return SCARD_E_INVALID_PARAMETER;
@@ -5153,12 +5664,11 @@ DWORD WINAPI CardChangeAuthenticatorEx(__in PCARD_DATA pCardData,
return SCARD_E_INVALID_PARAMETER;
if (dwFlags & PIN_CHANGE_FLAG_UNBLOCK && dwAuthenticatingPinId == dwTargetPinId)
return SCARD_E_INVALID_PARAMETER;
- if (dwAuthenticatingPinId != ROLE_USER && dwAuthenticatingPinId != ROLE_ADMIN)
+ if (dwAuthenticatingPinId >= MD_MAX_PINS || dwTargetPinId >= MD_MAX_PINS)
return SCARD_E_INVALID_PARAMETER;
- if (dwTargetPinId != ROLE_USER && dwTargetPinId != ROLE_ADMIN) {
- logprintf(pCardData, 1, "Only ROLE_USER or ROLE_ADMIN is supported\n");
+ if (!vs->pin_objs[dwAuthenticatingPinId] || !vs->pin_objs[dwTargetPinId])
return SCARD_E_INVALID_PARAMETER;
- }
+
/* according to the spec: cRetryCount MUST be zero */
if (cRetryCount)
return SCARD_E_INVALID_PARAMETER;
@@ -5170,11 +5680,6 @@ DWORD WINAPI CardChangeAuthenticatorEx(__in PCARD_DATA pCardData,
(unsigned int)dwTargetPinId, (unsigned long)cbTargetData,
pcAttemptsRemaining ? "YES" : "NO");
-
- check_reader_status(pCardData);
-
- vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
-
if (!(vs->reader->capabilities & SC_READER_CAP_PIN_PAD
|| vs->p15card->card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH)) {
if (pbAuthenticatingPinData == NULL || cbAuthenticatingPinData == 0) {
@@ -5195,20 +5700,22 @@ DWORD WINAPI CardChangeAuthenticatorEx(__in PCARD_DATA pCardData,
}
}
- dw_rv = md_get_pin_by_role(pCardData, dwTargetPinId, &pin_obj);
- if (dw_rv != SCARD_S_SUCCESS) {
- logprintf(pCardData, 2, "Cannot get User PIN object %s", (dwTargetPinId==ROLE_ADMIN?"admin":"user"));
- return dw_rv;
- }
- if (!pin_obj)
- return SCARD_F_INTERNAL_ERROR;
+ pin_obj = vs->pin_objs[dwTargetPinId];
if(pcAttemptsRemaining)
(*pcAttemptsRemaining) = (DWORD) -1;
- rv = md_dialog_perform_pin_operation(pCardData, (dwFlags & PIN_CHANGE_FLAG_UNBLOCK ? SC_PIN_CMD_UNBLOCK:SC_PIN_CMD_CHANGE),
- vs->p15card, pin_obj, (const u8 *) pbAuthenticatingPinData, cbAuthenticatingPinData, pbTargetData, &cbTargetData, DisplayPinpadUI, dwTargetPinId);
-
+ /* FIXME: this does not enforce dwAuthenticatingPinId */
+ rv = md_dialog_perform_pin_operation(pCardData,
+ (dwFlags & PIN_CHANGE_FLAG_UNBLOCK ?
+ SC_PIN_CMD_UNBLOCK :
+ SC_PIN_CMD_CHANGE),
+ vs->p15card, pin_obj,
+ (const u8 *) pbAuthenticatingPinData,
+ cbAuthenticatingPinData,
+ pbTargetData, &target_len,
+ DisplayPinpadUI, dwTargetPinId);
+
if (rv) {
logprintf(pCardData, 2, "Failed to %s %s PIN: '%s' (%i)\n",
(dwFlags & PIN_CHANGE_FLAG_CHANGEPIN?"change":"unblock"),
@@ -5252,6 +5759,7 @@ DWORD WINAPI CardGetContainerProperty(__in PCARD_DATA pCardData,
__out PDWORD pdwDataLen,
__in DWORD dwFlags)
{
+ DWORD dwret;
VENDOR_SPECIFIC *vs = NULL;
struct md_pkcs15_container *cont = NULL;
@@ -5260,9 +5768,13 @@ DWORD WINAPI CardGetContainerProperty(__in PCARD_DATA pCardData,
(unsigned long)GetCurrentThreadId(), pCardData);
logprintf(pCardData, 1, "CardGetContainerProperty\n");
- check_reader_status(pCardData);
+ if (!pCardData)
+ return SCARD_E_INVALID_PARAMETER;
+
+ dwret = check_card_status(pCardData, "CardGetContainerProperty");
+ if (dwret != SCARD_S_SUCCESS)
+ return dwret;
- if (!pCardData) return SCARD_E_INVALID_PARAMETER;
logprintf(pCardData, 2,
"CardGetContainerProperty bContainerIndex=%u, wszProperty=%S, cbData=%lu, dwFlags=0x%08X\n",
(unsigned int)bContainerIndex, NULLWSTR(wszProperty),
@@ -5278,6 +5790,9 @@ DWORD WINAPI CardGetContainerProperty(__in PCARD_DATA pCardData,
/* the test for the existence of containers is redondant with the one made in CardGetContainerInfo but CCP_PIN_IDENTIFIER does not do it */
vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
+ if (!vs)
+ return SCARD_E_INVALID_PARAMETER;
+
cont = &vs->p15_containers[bContainerIndex];
if (!cont->prkey_obj) {
@@ -5303,7 +5818,34 @@ DWORD WINAPI CardGetContainerProperty(__in PCARD_DATA pCardData,
*pdwDataLen = sizeof(*p);
if (cbData < sizeof(*p))
return ERROR_INSUFFICIENT_BUFFER;
- *p = ROLE_USER;
+
+ if (cont->prkey_obj->auth_id.len == 0)
+ *p = ROLE_EVERYONE;
+ else {
+ size_t pinidx;
+ for (pinidx = 0; pinidx < MD_MAX_PINS; pinidx++) {
+ struct sc_pkcs15_auth_info *pin_info;
+
+ if (!vs->pin_objs[pinidx])
+ continue;
+
+ pin_info =
+ (struct sc_pkcs15_auth_info *)vs->pin_objs[pinidx]->data;
+
+ if (sc_pkcs15_compare_id(&cont->prkey_obj->auth_id,
+ &pin_info->auth_id))
+ break;
+ }
+
+ if (pinidx >= MD_MAX_PINS) {
+ logprintf(pCardData, 2,
+ "Could not find container %i PIN, returning no PIN needed, might not work properly\n",
+ bContainerIndex);
+ *p = ROLE_EVERYONE;
+ } else
+ *p = (PIN_ID)pinidx;
+ }
+
logprintf(pCardData, 2, "Return Pin id %u\n",
(unsigned int)*p);
return SCARD_S_SUCCESS;
@@ -5350,9 +5892,13 @@ DWORD WINAPI CardGetProperty(__in PCARD_DATA pCardData,
if (!pbData || !pdwDataLen)
return SCARD_E_INVALID_PARAMETER;
- vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
+ dwret = check_card_reader_status(pCardData, "CardGetProperty");
+ if (dwret != SCARD_S_SUCCESS)
+ return dwret;
- check_reader_status(pCardData);
+ vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
+ if (!vs)
+ return SCARD_E_INVALID_PARAMETER;
if (wcscmp(CP_CARD_FREE_SPACE,wszProperty) == 0) {
PCARD_FREE_SPACE_INFO pCardFreeSpaceInfo = (PCARD_FREE_SPACE_INFO )pbData;
@@ -5461,22 +6007,17 @@ DWORD WINAPI CardGetProperty(__in PCARD_DATA pCardData,
if (p->dwVersion != PIN_INFO_CURRENT_VERSION)
return ERROR_REVISION_MISMATCH;
+ if (dwFlags >= MD_MAX_PINS)
+ return SCARD_E_INVALID_PARAMETER;
+
+ if (!vs->pin_objs[dwFlags])
+ return SCARD_E_INVALID_PARAMETER;
+
p->PinType = vs->reader->capabilities & SC_READER_CAP_PIN_PAD
|| vs->p15card->card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH
? ExternalPinType : AlphaNumericPinType;
p->dwFlags = 0;
switch (dwFlags) {
- case ROLE_USER:
- logprintf(pCardData, 2,
- "returning info on PIN ROLE_USER ( Auth ) [%lu]\n",
- (unsigned long)dwFlags);
- p->PinPurpose = DigitalSignaturePin;
- p->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION;
- p->PinCachePolicy.dwPinCachePolicyInfo = 0;
- p->PinCachePolicy.PinCachePolicyType = PinCacheNormal;
- p->dwChangePermission = CREATE_PIN_SET(ROLE_USER);
- p->dwUnblockPermission = CREATE_PIN_SET(ROLE_ADMIN);
- break;
case ROLE_ADMIN:
logprintf(pCardData, 2,
"returning info on PIN ROLE_ADMIN ( Unblock ) [%lu]\n",
@@ -5489,19 +6030,40 @@ DWORD WINAPI CardGetProperty(__in PCARD_DATA pCardData,
p->dwUnblockPermission = 0;
break;
default:
- logprintf(pCardData, 0,
- "Invalid Pin number %lu requested\n",
+ logprintf(pCardData, 2,
+ "returning info on normal PIN [%lu]\n",
(unsigned long)dwFlags);
- return SCARD_E_INVALID_PARAMETER;
+
+ if (dwFlags == ROLE_USER)
+ p->PinPurpose = PrimaryCardPin;
+ else if (dwFlags == MD_ROLE_USER_SIGN)
+ p->PinPurpose = DigitalSignaturePin;
+ else
+ p->PinPurpose = AuthenticationPin;
+
+ p->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION;
+ p->PinCachePolicy.dwPinCachePolicyInfo = 0;
+ p->PinCachePolicy.PinCachePolicyType = PinCacheNormal;
+ p->dwChangePermission = CREATE_PIN_SET(dwFlags);
+ p->dwUnblockPermission = CREATE_PIN_SET(ROLE_ADMIN);
+ break;
}
}
else if (wcscmp(CP_CARD_LIST_PINS,wszProperty) == 0) {
PPIN_SET p = (PPIN_SET) pbData;
+ size_t pinidx;
if (pdwDataLen)
*pdwDataLen = sizeof(*p);
if (cbData < sizeof(*p))
return ERROR_INSUFFICIENT_BUFFER;
- SET_PIN(*p, ROLE_USER);
+
+ memset(p, 0, sizeof(*p));
+ for (pinidx = 0; pinidx < MD_MAX_PINS; pinidx++) {
+ if (!vs->pin_objs[pinidx])
+ continue;
+
+ SET_PIN(*p, (PIN_ID)pinidx);
+ }
}
else if (wcscmp(CP_CARD_AUTHENTICATED_STATE,wszProperty) == 0) {
PPIN_SET p = (PPIN_SET) pbData;
@@ -5516,8 +6078,12 @@ DWORD WINAPI CardGetProperty(__in PCARD_DATA pCardData,
else if (wcscmp(CP_CARD_PIN_STRENGTH_VERIFY,wszProperty) == 0) {
DWORD *p = (DWORD *)pbData;
- if (dwFlags != ROLE_USER)
+ if (dwFlags >= MD_MAX_PINS)
return SCARD_E_INVALID_PARAMETER;
+
+ if (!vs->pin_objs[dwFlags])
+ return SCARD_E_INVALID_PARAMETER;
+
if (pdwDataLen)
*pdwDataLen = sizeof(*p);
if (cbData < sizeof(*p))
@@ -5583,6 +6149,8 @@ DWORD WINAPI CardSetProperty(__in PCARD_DATA pCardData,
(unsigned long)dwFlags);
vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
+ if (!vs)
+ return SCARD_E_INVALID_PARAMETER;
if (!wszProperty)
return SCARD_E_INVALID_PARAMETER;
@@ -5890,35 +6458,6 @@ DWORD WINAPI CardProcessEncryptedData(
return SCARD_E_UNSUPPORTED_FEATURE;
}
-/** The CardCreateContainerEx function creates a new key container that the
-container index identifies and the bContainerIndex parameter specifies. The function
-associates the key container with the PIN that the PinId parameter specified.
-This function is useful if the card-edge does not allow for changing the key attributes
-after the key container is created. This function replaces the need to call
-CardSetContainerProperty to set the CCP_PIN_IDENTIFIER property CardCreateContainer
-is called.
-The caller of this function can provide the key material that the card imports.
-This is useful in those situations in which the card either does not support internal
-key generation or the caller requests that the key be archived in the card.*/
-
-DWORD WINAPI CardCreateContainerEx(
- __in PCARD_DATA pCardData,
- __in BYTE bContainerIndex,
- __in DWORD dwFlags,
- __in DWORD dwKeySpec,
- __in DWORD dwKeySize,
- __in PBYTE pbKeyData,
- __in PIN_ID PinId
-)
-{
- if (PinId == ROLE_ADMIN)
- return SCARD_W_SECURITY_VIOLATION;
- if (PinId != ROLE_USER)
- return SCARD_E_INVALID_PARAMETER;
- /* basically CardCreateContainerEx is CardCreateContainer + the PinId */
- return CardCreateContainer(pCardData, bContainerIndex, dwFlags, dwKeySpec, dwKeySize, pbKeyData);
-}
-
DWORD WINAPI CardAcquireContext(__inout PCARD_DATA pCardData, __in DWORD dwFlags)
{
VENDOR_SPECIFIC *vs;
@@ -5926,7 +6465,7 @@ DWORD WINAPI CardAcquireContext(__inout PCARD_DATA pCardData, __in DWORD dwFlags
if (!pCardData)
return SCARD_E_INVALID_PARAMETER;
- if (dwFlags)
+ if (dwFlags & ~CARD_SECURE_KEY_INJECTION_NO_CARD_MODE)
return SCARD_E_INVALID_PARAMETER;
if (!(dwFlags & CARD_SECURE_KEY_INJECTION_NO_CARD_MODE)) {
if( pCardData->hSCardCtx == 0) {
@@ -5993,11 +6532,8 @@ DWORD WINAPI CardAcquireContext(__inout PCARD_DATA pCardData, __in DWORD dwFlags
(unsigned long)pCardData->dwVersion);
dwret = md_create_context(pCardData, vs);
- if (dwret != SCARD_S_SUCCESS) {
- pCardData->pfnCspFree(pCardData->pvVendorSpecific);
- pCardData->pvVendorSpecific = NULL;
- return dwret;
- }
+ if (dwret != SCARD_S_SUCCESS)
+ goto ret_free;
md_static_data.flags &= ~MD_STATIC_FLAG_CONTEXT_DELETED;
pCardData->pfnCardDeleteContext = CardDeleteContext;
@@ -6028,18 +6564,12 @@ DWORD WINAPI CardAcquireContext(__inout PCARD_DATA pCardData, __in DWORD dwFlags
pCardData->pfnCardConstructDHAgreement = CardConstructDHAgreement;
dwret = associate_card(pCardData);
- if (dwret != SCARD_S_SUCCESS) {
- pCardData->pfnCspFree(pCardData->pvVendorSpecific);
- pCardData->pvVendorSpecific = NULL;
- return dwret;
- }
+ if (dwret != SCARD_S_SUCCESS)
+ goto ret_release;
dwret = md_fs_init(pCardData);
- if (dwret != SCARD_S_SUCCESS) {
- pCardData->pfnCspFree(pCardData->pvVendorSpecific);
- pCardData->pvVendorSpecific = NULL;
- return dwret;
- }
+ if (dwret != SCARD_S_SUCCESS)
+ goto ret_disassoc;
logprintf(pCardData, 1, "OpenSC init done.\n");
logprintf(pCardData, 1, "Supplied version %lu - version used %lu.\n",
@@ -6077,19 +6607,35 @@ DWORD WINAPI CardAcquireContext(__inout PCARD_DATA pCardData, __in DWORD dwFlags
}
return SCARD_S_SUCCESS;
+
+ret_disassoc:
+ disassociate_card(pCardData);
+
+ret_release:
+ sc_release_context(vs->ctx);
+ md_static_data.flags |= MD_STATIC_FLAG_CONTEXT_DELETED;
+
+ret_free:
+ pCardData->pfnCspFree(pCardData->pvVendorSpecific);
+ pCardData->pvVendorSpecific = NULL;
+ return dwret;
}
-static int associate_card(PCARD_DATA pCardData)
+static DWORD associate_card(PCARD_DATA pCardData)
{
VENDOR_SPECIFIC *vs;
- DWORD dw;
int r;
+ struct sc_app_info *app_generic;
+ struct sc_aid *aid;
logprintf(pCardData, 1, "associate_card\n");
if (!pCardData)
return SCARD_E_INVALID_PARAMETER;
vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
+ if (!vs)
+ return SCARD_E_INVALID_PARAMETER;
+
/*
* set the addresses of the reader and card handles
* Our pcsc code will use these when we call sc_ctx_use_reader
@@ -6110,63 +6656,65 @@ static int associate_card(PCARD_DATA pCardData)
}
/* set the provided reader and card handles into ctx */
- logprintf(pCardData, 5, "sc_ctx_use_reader %d\n", sc_ctx_use_reader(vs->ctx, &vs->hSCardCtx, &vs->hScard));
+ r = sc_ctx_use_reader(vs->ctx, &vs->hSCardCtx, &vs->hScard);
+ if (r != SC_SUCCESS) {
+ logprintf(pCardData, 0, "sc_ctx_use_reader() failed with %d\n", r);
+ return SCARD_E_COMM_DATA_LOST;
+ }
/* should be only one reader */
logprintf(pCardData, 5, "sc_ctx_get_reader_count(ctx): %d\n", sc_ctx_get_reader_count(vs->ctx));
vs->reader = sc_ctx_get_reader(vs->ctx, 0);
- if(vs->reader) {
- struct sc_app_info *app_generic = NULL;
- struct sc_aid *aid = NULL;
+ if (!vs->reader)
+ return SCARD_E_COMM_DATA_LOST;
- r = sc_connect_card(vs->reader, &(vs->card));
- if(r) {
- logprintf(pCardData, 0, "Cannot connect card in reader '%s'\n", NULLSTR(vs->reader->name));
- return SCARD_E_UNKNOWN_CARD;
- }
- logprintf(pCardData, 3, "Connected card in '%s'\n", NULLSTR(vs->reader->name));
-
- app_generic = sc_pkcs15_get_application_by_type(vs->card, "generic");
- if (app_generic)
- logprintf(pCardData, 3, "Use generic application '%s'\n", app_generic->label);
- aid = app_generic ? &app_generic->aid : NULL;
-
- r = sc_pkcs15_bind(vs->card, aid, &(vs->p15card));
- logprintf(pCardData, 2, "PKCS#15 initialization result: %d, %s\n", r, sc_strerror(r));
+ r = sc_connect_card(vs->reader, &(vs->card));
+ if (r != SC_SUCCESS) {
+ logprintf(pCardData, 0, "Cannot connect card in reader '%s'\n", NULLSTR(vs->reader->name));
+ return SCARD_E_UNKNOWN_CARD;
}
+ logprintf(pCardData, 3, "Connected card in '%s'\n", NULLSTR(vs->reader->name));
- if(vs->card == NULL || vs->p15card == NULL) {
- logprintf(pCardData, 0, "Card unknown.\n");
+ app_generic = sc_pkcs15_get_application_by_type(vs->card, "generic");
+ if (app_generic)
+ logprintf(pCardData, 3, "Use generic application '%s'\n", app_generic->label);
+ aid = app_generic ? &app_generic->aid : NULL;
+
+ r = sc_pkcs15_bind(vs->card, aid, &(vs->p15card));
+ logprintf(pCardData, 2, "PKCS#15 initialization result: %d, %s\n", r, sc_strerror(r));
+ if (r != SC_SUCCESS) {
+ logprintf(pCardData, 0, "PKCS#15 init failed.\n");
+ sc_disconnect_card(vs->card);
return SCARD_E_UNKNOWN_CARD;
}
- dw = md_get_pin_by_role(pCardData, ROLE_USER, &vs->obj_user_pin);
- if (dw != SCARD_S_SUCCESS) {
- logprintf(pCardData, 2, "Cannot get User PIN object");
- return dw;
- }
-
- dw = md_get_pin_by_role(pCardData, ROLE_USER, &vs->obj_sopin);
- if (dw != SCARD_S_SUCCESS)
- logprintf(pCardData, 2, "Cannot get ADMIN PIN object -- ignored");
+ vs->initialized = TRUE;
return SCARD_S_SUCCESS;
-
}
-static int disassociate_card(PCARD_DATA pCardData)
+static void disassociate_card(PCARD_DATA pCardData)
{
VENDOR_SPECIFIC *vs;
+ if (!pCardData) {
+ logprintf(pCardData, 1,
+ "disassociate_card called without card data\n");
+ return;
+ }
+
logprintf(pCardData, 1, "disassociate_card\n");
- if (!pCardData)
- return SCARD_E_INVALID_PARAMETER;
vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
+ if (!vs) {
+ logprintf(pCardData, 1,
+ "disassociate_card called without vendor specific data\n");
+ return;
+ }
- vs->obj_user_pin = NULL;
- vs->obj_sopin = NULL;
+ memset(vs->pin_objs, 0, sizeof(vs->pin_objs));
+ memset(vs->p15_containers, 0, sizeof(vs->p15_containers));
EnterCriticalSection(&md_static_data.hScard_lock);
@@ -6186,10 +6734,9 @@ static int disassociate_card(PCARD_DATA pCardData)
vs->hSCardCtx = -1;
vs->hScard = -1;
+ vs->initialized = FALSE;
LeaveCriticalSection(&md_static_data.hScard_lock);
-
- return SCARD_S_SUCCESS;
}
@@ -6245,4 +6792,3 @@ BOOL APIENTRY DllMain( HINSTANCE hinstDLL,
#pragma managed(pop)
#endif
#endif
-
diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c
index 2f0ddc2b..34d92cb5 100644
--- a/src/pkcs11/framework-pkcs15.c
+++ b/src/pkcs11/framework-pkcs15.c
@@ -1043,6 +1043,7 @@ pkcs15_init_slot(struct sc_pkcs15_card *p15card, struct sc_pkcs11_slot *slot,
struct sc_pkcs15_auth_info *pin_info = NULL;
char label[64];
+ sc_log(context, "Called");
pkcs15_init_token_info(p15card, &slot->token_info);
slot->token_info.flags |= CKF_TOKEN_INITIALIZED;
if (auth != NULL)
@@ -1067,9 +1068,10 @@ pkcs15_init_slot(struct sc_pkcs15_card *p15card, struct sc_pkcs11_slot *slot,
pin_info = NULL;
}
else {
- if (auth->label[0])
+ if (auth->label[0] && strncmp(auth->label, "PIN", 4) != 0)
snprintf(label, sizeof(label), "%.*s (%s)", (int) sizeof auth->label, auth->label, p15card->tokeninfo->label);
else
+ /* The PIN label is empty or says just non-useful "PIN" */
snprintf(label, sizeof(label), "%s", p15card->tokeninfo->label);
slot->token_info.flags |= CKF_LOGIN_REQUIRED;
}
@@ -1230,6 +1232,7 @@ _get_auth_object_by_name(struct sc_pkcs15_card *p15card, char *name)
struct sc_pkcs15_object *out = NULL;
int rv = SC_ERROR_OBJECT_NOT_FOUND;
+ /* please keep me in sync with md_get_pin_by_role() in minidriver */
if (!strcmp(name, "UserPIN")) {
/* Try to get 'global' PIN; if no, get the 'local' one */
rv = sc_pkcs15_find_pin_by_flags(p15card, SC_PKCS15_PIN_TYPE_FLAGS_PIN_GLOBAL,
diff --git a/src/pkcs11/pkcs11-display.c b/src/pkcs11/pkcs11-display.c
index a05a7f93..753c05fa 100644
--- a/src/pkcs11/pkcs11-display.c
+++ b/src/pkcs11/pkcs11-display.c
@@ -521,6 +521,14 @@ static enum_specs ck_mec_s[] = {
{ CKM_VENDOR_DEFINED , "CKM_VENDOR_DEFINED " }
};
+static enum_specs ck_mgf_s[] = {
+ { CKG_MGF1_SHA1 , "CKG_MGF1_SHA1 " },
+ { CKG_MGF1_SHA224, "CKG_MGF1_SHA224" },
+ { CKG_MGF1_SHA256, "CKG_MGF1_SHA256" },
+ { CKG_MGF1_SHA384, "CKG_MGF1_SHA384" },
+ { CKG_MGF1_SHA512, "CKG_MGF1_SHA512" },
+};
+
static enum_specs ck_err_s[] = {
{ CKR_OK, "CKR_OK" },
{ CKR_CANCEL, "CKR_CANCEL" },
@@ -630,6 +638,7 @@ enum_spec ck_types[] = {
{ KEY_T, ck_key_s, sizeof(ck_key_s) / SZ_SPECS, "CK_KEY_TYPE" },
{ CRT_T, ck_crt_s, sizeof(ck_crt_s) / SZ_SPECS, "CK_CERTIFICATE_TYPE" },
{ MEC_T, ck_mec_s, sizeof(ck_mec_s) / SZ_SPECS, "CK_MECHANISM_TYPE" },
+ { MGF_T, ck_mgf_s, sizeof(ck_mgf_s) / SZ_SPECS, "CK_RSA_PKCS_MGF_TYPE"},
{ USR_T, ck_usr_s, sizeof(ck_usr_s) / SZ_SPECS, "CK_USER_TYPE" },
{ STA_T, ck_sta_s, sizeof(ck_sta_s) / SZ_SPECS, "CK_STATE" },
{ RV_T, ck_err_s, sizeof(ck_err_s) / SZ_SPECS, "CK_RV" },
diff --git a/src/pkcs11/pkcs11-display.h b/src/pkcs11/pkcs11-display.h
index 0f7bc5fb..9473ce9c 100644
--- a/src/pkcs11/pkcs11-display.h
+++ b/src/pkcs11/pkcs11-display.h
@@ -56,6 +56,7 @@ enum ck_type{
KEY_T,
CRT_T,
MEC_T,
+ MGF_T,
USR_T,
STA_T,
RV_T
diff --git a/src/pkcs11/pkcs11-global.c b/src/pkcs11/pkcs11-global.c
index 5f04a7f1..24074ab5 100644
--- a/src/pkcs11/pkcs11-global.c
+++ b/src/pkcs11/pkcs11-global.c
@@ -264,7 +264,6 @@ CK_RV C_Initialize(CK_VOID_PTR pInitArgs)
list_attributes_seeker(&sessions, session_list_seeker);
/* List of slots */
- list_init(&virtual_slots);
if (0 != list_init(&virtual_slots)) {
rv = CKR_HOST_MEMORY;
goto out;
diff --git a/src/pkcs11/pkcs11-opensc.h b/src/pkcs11/pkcs11-opensc.h
index 33beb6a3..6f0954dd 100644
--- a/src/pkcs11/pkcs11-opensc.h
+++ b/src/pkcs11/pkcs11-opensc.h
@@ -2,13 +2,22 @@
#define PKCS11_OPENSC_H
/* OpenSC specific extensions */
+/*
+ * define OpenSC specific Vendor Defined extensions
+ * to make unique OpenSC flags, attribures, mechanisms, etc.
+ *
+ * Netscape used NSSCK_VENDOR_NSS 0x4E534350 "NSCP"
+ */
+
+#define SC_VENDOR_DEFINED 0x4F534300 /* OSC */
+
/*
* In PKCS#11 there is no CKA_ attribute dedicated to the NON-REPUDIATION flag.
* We need this flag in PKCS#15/libopensc to make dinstinction between
* 'signature' and 'qualified signature' key slots.
*/
-#define CKA_OPENSC_NON_REPUDIATION (CKA_VENDOR_DEFINED | 1UL)
+#define CKA_OPENSC_NON_REPUDIATION (CKA_VENDOR_DEFINED | SC_VENDOR_DEFINED | 1UL)
-#define CKA_SPKI (CKA_VENDOR_DEFINED | 2UL)
+#define CKA_SPKI (CKA_VENDOR_DEFINED | SC_VENDOR_DEFINED | 2UL)
#endif
diff --git a/src/pkcs11/pkcs11-spy.c b/src/pkcs11/pkcs11-spy.c
index 1aed6389..8011f047 100644
--- a/src/pkcs11/pkcs11-spy.c
+++ b/src/pkcs11/pkcs11-spy.c
@@ -172,7 +172,7 @@ init_spy(void)
}
}
- if( (rc == ERROR_SUCCESS) && (temp_len < PATH_MAX) )
+ if( (rc == ERROR_SUCCESS) && (temp_len < PATH_MAX) )
output = temp_path;
RegCloseKey( hKey );
}
@@ -969,6 +969,24 @@ C_SignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HA
enter("C_SignInit");
spy_dump_ulong_in("hSession", hSession);
fprintf(spy_output, "pMechanism->type=%s\n", lookup_enum(MEC_T, pMechanism->mechanism));
+ switch (pMechanism->mechanism) {
+ case CKM_RSA_PKCS_PSS:
+ case CKM_SHA1_RSA_PKCS_PSS:
+ case CKM_SHA256_RSA_PKCS_PSS:
+ case CKM_SHA384_RSA_PKCS_PSS:
+ case CKM_SHA512_RSA_PKCS_PSS:
+ if (pMechanism->pParameter != NULL) {
+ CK_RSA_PKCS_PSS_PARAMS *param =
+ (CK_RSA_PKCS_PSS_PARAMS *) pMechanism->pParameter;
+ fprintf(spy_output, "pMechanism->pParameter->hashAlg=%s\n",
+ lookup_enum(MEC_T, param->hashAlg));
+ fprintf(spy_output, "pMechanism->pParameter->mgf=%s\n",
+ lookup_enum(MGF_T, param->mgf));
+ fprintf(spy_output, "pMechanism->pParameter->sLen=%lu\n",
+ param->sLen);
+ }
+ break;
+ }
spy_dump_ulong_in("hKey", hKey);
rv = po->C_SignInit(hSession, pMechanism, hKey);
return retne(rv);
diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h
index 74b13c68..d24597b2 100644
--- a/src/pkcs11/pkcs11.h
+++ b/src/pkcs11/pkcs11.h
@@ -153,6 +153,8 @@ extern "C" {
#define ck_mechanism_type_t CK_MECHANISM_TYPE
+#define ck_rsa_pkcs_mgf_type_t CK_RSA_PKCS_MGF_TYPE
+
#define ck_mechanism _CK_MECHANISM
#define parameter pParameter
#define parameter_len ulParameterLen
@@ -478,6 +480,8 @@ struct ck_date
typedef unsigned long ck_mechanism_type_t;
+typedef unsigned long int ck_rsa_pkcs_mgf_type_t;
+
#define CKM_RSA_PKCS_KEY_PAIR_GEN (0UL)
#define CKM_RSA_PKCS (1UL)
#define CKM_RSA_9796 (2UL)
@@ -508,6 +512,8 @@ typedef unsigned long ck_mechanism_type_t;
#define CKM_SHA256_RSA_PKCS_PSS (0x43UL)
#define CKM_SHA384_RSA_PKCS_PSS (0x44UL)
#define CKM_SHA512_RSA_PKCS_PSS (0x45UL)
+#define CKM_SHA224_RSA_PKCS (0x46UL)
+#define CKM_SHA224_RSA_PKCS_PSS (0x47UL)
#define CKM_RC2_KEY_GEN (0x100UL)
#define CKM_RC2_ECB (0x101UL)
#define CKM_RC2_CBC (0x102UL)
@@ -553,6 +559,9 @@ typedef unsigned long ck_mechanism_type_t;
#define CKM_SHA256 (0x250UL)
#define CKM_SHA256_HMAC (0x251UL)
#define CKM_SHA256_HMAC_GENERAL (0x252UL)
+#define CKM_SHA224 (0x255UL)
+#define CKM_SHA224_HMAC (0x256UL)
+#define CKM_SHA224_HMAC_GENERAL (0x257UL)
#define CKM_SHA384 (0x260UL)
#define CKM_SHA384_HMAC (0x261UL)
#define CKM_SHA384_HMAC_GENERAL (0x262UL)
@@ -755,6 +764,17 @@ typedef struct CK_ECDH1_DERIVE_PARAMS {
unsigned char * pPublicData;
} CK_ECDH1_DERIVE_PARAMS;
+typedef struct CK_RSA_PKCS_PSS_PARAMS {
+ ck_mechanism_type_t hashAlg;
+ unsigned long mgf;
+ unsigned long sLen;
+} CK_RSA_PKCS_PSS_PARAMS;
+
+#define CKG_MGF1_SHA1 (0x00000001UL)
+#define CKG_MGF1_SHA224 (0x00000005UL)
+#define CKG_MGF1_SHA256 (0x00000002UL)
+#define CKG_MGF1_SHA384 (0x00000003UL)
+#define CKG_MGF1_SHA512 (0x00000004UL)
typedef unsigned long ck_rv_t;
@@ -1292,6 +1312,8 @@ typedef struct ck_date *CK_DATE_PTR;
typedef ck_mechanism_type_t *CK_MECHANISM_TYPE_PTR;
+typedef ck_rsa_pkcs_mgf_type_t *CK_RSA_PKCS_MGF_TYPE_PTR;
+
typedef struct ck_mechanism CK_MECHANISM;
typedef struct ck_mechanism *CK_MECHANISM_PTR;
@@ -1362,6 +1384,8 @@ typedef struct ck_c_initialize_args *CK_C_INITIALIZE_ARGS_PTR;
#undef ck_mechanism_type_t
+#undef ck_rsa_pkcs_mgf_type_t
+
#undef ck_mechanism
#undef parameter
#undef parameter_len
diff --git a/src/pkcs11/sc-pkcs11.h b/src/pkcs11/sc-pkcs11.h
index 834573bf..49297596 100644
--- a/src/pkcs11/sc-pkcs11.h
+++ b/src/pkcs11/sc-pkcs11.h
@@ -36,12 +36,6 @@
extern "C" {
#endif
-#if defined(_WIN32) || defined(USE_CYGWIN)
-#define PKCS11_DEFAULT_MODULE_NAME "opensc-pkcs11.dll"
-#else
-#define PKCS11_DEFAULT_MODULE_NAME "opensc-pkcs11.so"
-#endif
-
#define SC_PKCS11_PIN_UNBLOCK_NOT_ALLOWED 0
#define SC_PKCS11_PIN_UNBLOCK_UNLOGGED_SETPIN 1
#define SC_PKCS11_PIN_UNBLOCK_SCONTEXT_SETPIN 2
diff --git a/src/pkcs15init/pkcs15-epass2003.c b/src/pkcs15init/pkcs15-epass2003.c
index 3be5ab85..786a7125 100644
--- a/src/pkcs15init/pkcs15-epass2003.c
+++ b/src/pkcs15init/pkcs15-epass2003.c
@@ -312,6 +312,16 @@ cosm_new_file(struct sc_profile *profile, struct sc_card *card,
num);
while (1) {
switch (type) {
+ case SC_PKCS15_TYPE_PRKEY_EC:
+ desc = "RSA private key";
+ _template = "private-key";
+ structure = SC_CARDCTL_OBERTHUR_KEY_EC_CRT;
+ break;
+ case SC_PKCS15_TYPE_PUBKEY_EC:
+ desc = "RSA public key";
+ _template = "public-key";
+ structure = SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC;
+ break;
case SC_PKCS15_TYPE_PRKEY_RSA:
desc = "RSA private key";
_template = "private-key";
@@ -497,11 +507,14 @@ static int epass2003_pkcs15_generate_key(struct sc_profile *profile,
SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
- if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA)
+ if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA && obj->type != SC_PKCS15_TYPE_PRKEY_EC)
return SC_ERROR_NOT_SUPPORTED;
+ if(obj->type == SC_PKCS15_TYPE_PRKEY_EC && keybits == 0)
+ keybits = 256; //EC key length is 256 ...
+
/* allocate key object */
- r = cosm_new_file(profile, card, SC_PKCS15_TYPE_PRKEY_RSA, idx, &file);
+ r = cosm_new_file(profile, card, obj->type, idx, &file); //replace SC_PKCS15_TYPE_PRKEY_RSA with obj->type
SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_NORMAL, r,
"create key: failed to allocate new key object");
file->size = keybits;
@@ -525,11 +538,18 @@ static int epass2003_pkcs15_generate_key(struct sc_profile *profile,
"index %"SC_FORMAT_LEN_SIZE_T"u; keybits %"SC_FORMAT_LEN_SIZE_T"u\n",
idx, keybits);
if (keybits < 1024 || keybits > 2048 || (keybits % 0x20)) {
- sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL,
- "Unsupported key size %"SC_FORMAT_LEN_SIZE_T"u\n",
- keybits);
- r = SC_ERROR_INVALID_ARGUMENTS;
- goto err;
+ if(obj->type == SC_PKCS15_TYPE_PRKEY_EC && keybits == 256)
+ {
+ sc_log(card->ctx, "current Alg is EC,Only support 256 ..\n");
+ }
+ else
+ {
+ sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL,
+ "Unsupported key size %"SC_FORMAT_LEN_SIZE_T"u\n",
+ keybits);
+ r = SC_ERROR_INVALID_ARGUMENTS;
+ goto err;
+ }
}
path = key_info->path;
@@ -549,12 +569,23 @@ static int epass2003_pkcs15_generate_key(struct sc_profile *profile,
SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_NORMAL, r,
"generate key: pkcs15init_authenticate(SC_AC_OP_CREATE) failed");
- if ((r = cosm_new_file(profile, card, SC_PKCS15_TYPE_PUBKEY_RSA, idx,
- &pukf)) < 0) {
+ if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA )
+ {
+
+ r = cosm_new_file(profile, card, SC_PKCS15_TYPE_PUBKEY_EC, idx, &pukf);
+ }
+ else
+ {
+
+ r = cosm_new_file(profile, card, SC_PKCS15_TYPE_PUBKEY_RSA, idx, &pukf);
+ }
+
+ if (r < 0) {
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,
"generate key: create temporary pukf failed\n");
goto err;
}
+
pukf->size = keybits;
pukf->id = pukf->path.value[pukf->path.len - 2] * 0x100
+ pukf->path.value[pukf->path.len - 1];
diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c
index 9339aebb..5dfe2be6 100644
--- a/src/pkcs15init/pkcs15-lib.c
+++ b/src/pkcs15init/pkcs15-lib.c
@@ -4211,7 +4211,7 @@ sc_pkcs15init_read_info(struct sc_card *card, struct sc_profile *profile)
}
if (r >= 0)
- r = sc_pkcs15init_parse_info(card, mem, len, profile);
+ r = sc_pkcs15init_parse_info(card, mem, r, profile);
if (mem)
free(mem);
diff --git a/src/tools/cardos-tool.c b/src/tools/cardos-tool.c
index c3c6406b..cccc76d3 100644
--- a/src/tools/cardos-tool.c
+++ b/src/tools/cardos-tool.c
@@ -188,6 +188,9 @@ static int cardos_info(void)
printf(" (that's CardOS M4.4)\n");
} else if (apdu.resp[0] == 0xc9 && apdu.resp[1] == 0x01) {
printf(" (that's CardOS V5.0)\n");
+ } else if (apdu.resp[0] == 0xc9 &&
+ (apdu.resp[1] == 0x02 || apdu.resp[1] == 0x03)) {
+ printf(" (that's CardOS V5.3)\n");
} else {
printf(" (unknown Version)\n");
}
diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c
index f1ff0efb..dfd6913d 100644
--- a/src/tools/pkcs11-tool.c
+++ b/src/tools/pkcs11-tool.c
@@ -26,10 +26,11 @@
#include
#ifndef _WIN32
-#include
#include
#include
+#include
#else
+#include
#include
#endif
@@ -133,6 +134,7 @@ enum {
OPT_KEY_USAGE_DECRYPT,
OPT_KEY_USAGE_DERIVE,
OPT_PRIVATE,
+ OPT_SENSITIVE,
OPT_TEST_HOTPLUG,
OPT_UNLOCK_PIN,
OPT_PUK,
@@ -145,6 +147,9 @@ enum {
OPT_TEST_FORK,
OPT_GENERATE_KEY,
OPT_GENERATE_RANDOM,
+ OPT_HASH_ALGORITHM,
+ OPT_MGF,
+ OPT_SALT,
};
static const struct option options[] = {
@@ -161,6 +166,9 @@ static const struct option options[] = {
{ "derive", 0, NULL, OPT_DERIVE },
{ "derive-pass-der", 0, NULL, OPT_DERIVE_PASS_DER },
{ "mechanism", 1, NULL, 'm' },
+ { "hash-algorithm", 1, NULL, OPT_HASH_ALGORITHM },
+ { "mgf", 1, NULL, OPT_MGF },
+ { "salt-len", 1, NULL, OPT_SALT },
{ "login", 0, NULL, 'l' },
{ "login-type", 1, NULL, OPT_LOGIN_TYPE },
@@ -203,6 +211,7 @@ static const struct option options[] = {
{ "moz-cert", 1, NULL, 'z' },
{ "verbose", 0, NULL, 'v' },
{ "private", 0, NULL, OPT_PRIVATE },
+ { "sensitive", 0, NULL, OPT_SENSITIVE },
{ "test-ec", 0, NULL, OPT_TEST_EC },
#ifndef _WIN32
{ "test-fork", 0, NULL, OPT_TEST_FORK },
@@ -226,6 +235,9 @@ static const char *option_help[] = {
"Derive a secret key using another key and some data",
"Derive ECDHpass DER encoded pubkey for compatibility with some PKCS#11 implementations",
"Specify mechanism (use -M for a list of supported mechanisms)",
+ "Specify hash algorithm used with RSA-PKCS-PSS signature",
+ "Specify MGF (Message Generation Function) used for RSA-PSS signatures (possible values are MGF1-SHA1 to MGF1-SHA512)",
+ "Specify how many bytes should be used for salt in RSA-PSS signatures (default is digest size)",
"Log into the token first",
"Specify login type ('so', 'user', 'context-specific'; default:'user')",
@@ -268,6 +280,7 @@ static const char *option_help[] = {
"Test Mozilla-like keypair gen and cert req, =certfile",
"Verbose operation. (Set OPENSC_DEBUG to enable OpenSC specific debugging)",
"Set the CKA_PRIVATE attribute (object is only viewable after a login)",
+ "Set the CKA_SENSITIVE attribute (object cannot be revealed in plaintext)",
"Test EC (best used with the --login or --pin option)",
#ifndef _WIN32
"Test forking and calling C_Initialize() in the child",
@@ -307,6 +320,7 @@ static char * opt_subject = NULL;
static char * opt_key_type = NULL;
static char * opt_sig_format = NULL;
static int opt_is_private = 0;
+static int opt_is_sensitive = 0;
static int opt_test_hotplug = 0;
static int opt_login_type = -1;
static int opt_key_usage_sign = 0;
@@ -315,6 +329,10 @@ static int opt_key_usage_derive = 0;
static int opt_key_usage_default = 1; /* uses defaults if no opt_key_usage options */
static int opt_derive_pass_der = 0;
static unsigned long opt_random_bytes = 0;
+static CK_MECHANISM_TYPE opt_hash_alg = 0;
+static unsigned long opt_mgf = 0;
+static long salt_len = 0;
+static int salt_len_given = 0; /* 0 - not given, 1 - given with input parameters */
static void *module = NULL;
static CK_FUNCTION_LIST_PTR p11 = NULL;
@@ -405,6 +423,8 @@ static const char * p11_utf8_to_local(CK_UTF8CHAR *, size_t);
static const char * p11_flag_names(struct flag_info *, CK_FLAGS);
static const char * p11_mechanism_to_name(CK_MECHANISM_TYPE);
static CK_MECHANISM_TYPE p11_name_to_mechanism(const char *);
+static const char * p11_mgf_to_name(CK_RSA_PKCS_MGF_TYPE);
+static CK_MECHANISM_TYPE p11_name_to_mgf(const char *);
static void p11_perror(const char *, CK_RV);
static const char * CKR2Str(CK_ULONG res);
static int p11_test(CK_SESSION_HANDLE session);
@@ -537,6 +557,9 @@ int main(int argc, char * argv[])
CK_RV rv;
#ifdef _WIN32
+ char expanded_val[PATH_MAX];
+ DWORD expanded_len;
+
if(_setmode(_fileno(stdout), _O_BINARY ) == -1)
util_fatal("Cannot set FMODE to O_BINARY");
if(_setmode(_fileno(stdin), _O_BINARY ) == -1)
@@ -669,6 +692,16 @@ int main(int argc, char * argv[])
opt_mechanism_used = 1;
opt_mechanism = p11_name_to_mechanism(optarg);
break;
+ case OPT_HASH_ALGORITHM:
+ opt_hash_alg = p11_name_to_mechanism(optarg);
+ break;
+ case OPT_MGF:
+ opt_mgf = p11_name_to_mgf(optarg);
+ break;
+ case OPT_SALT:
+ salt_len = (CK_ULONG) strtoul(optarg, NULL, 0);
+ salt_len_given = 1;
+ break;
case 'o':
opt_output = optarg;
break;
@@ -804,6 +837,9 @@ int main(int argc, char * argv[])
case OPT_PRIVATE:
opt_is_private = 1;
break;
+ case OPT_SENSITIVE:
+ opt_is_sensitive = 1;
+ break;
case OPT_TEST_HOTPLUG:
opt_test_hotplug = 1;
action_count++;
@@ -844,6 +880,13 @@ int main(int argc, char * argv[])
if (action_count == 0)
util_print_usage_and_die(app_name, options, option_help, NULL);
+#ifdef _WIN32
+ expanded_len = PATH_MAX;
+ expanded_len = ExpandEnvironmentStringsA(opt_module, expanded_val, expanded_len);
+ if (0 < expanded_len && expanded_len < sizeof expanded_val)
+ opt_module = expanded_val;
+#endif
+
module = C_LoadModule(opt_module, &p11);
if (module == NULL)
util_fatal("Failed to load pkcs11 module");
@@ -1318,7 +1361,7 @@ static int login(CK_SESSION_HANDLE session, int login_type)
pin_flags=info.flags & (
CKF_SO_PIN_COUNT_LOW |
CKF_SO_PIN_FINAL_TRY |
- CKF_SO_PIN_LOCKED |
+ CKF_SO_PIN_LOCKED |
CKF_SO_PIN_TO_BE_CHANGED);
if(pin_flags)
printf("WARNING: %s\n",p11_token_info_flags(pin_flags));
@@ -1329,7 +1372,7 @@ static int login(CK_SESSION_HANDLE session, int login_type)
pin_flags=info.flags & (
CKF_USER_PIN_COUNT_LOW |
CKF_USER_PIN_FINAL_TRY |
- CKF_USER_PIN_LOCKED |
+ CKF_USER_PIN_LOCKED |
CKF_USER_PIN_TO_BE_CHANGED);
if(pin_flags)
printf("WARNING: %s\n",p11_token_info_flags(pin_flags));
@@ -1591,15 +1634,45 @@ static int unlock_pin(CK_SLOT_ID slot, CK_SESSION_HANDLE sess, int login_type)
return 0;
}
+/* return digest length in bytes */
+static unsigned long figure_pss_salt_length(const int hash) {
+ unsigned long sLen = 0;
+ switch (hash) {
+ case CKM_SHA_1:
+ sLen = 20;
+ break;
+ case CKM_SHA224:
+ sLen = 28;
+ break;
+ case CKM_SHA256:
+ sLen = 32;
+ break;
+ case CKM_SHA384:
+ sLen = 48;
+ break;
+ case CKM_SHA512:
+ sLen = 64;
+ break;
+ default:
+ util_fatal("Unknown hash algorithm '%s' for RSA-PSS signatures",
+ p11_mechanism_to_name(hash));
+ break;
+ }
+ return sLen;
+}
+
static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session,
CK_OBJECT_HANDLE key)
{
unsigned char in_buffer[1025], sig_buffer[512];
CK_MECHANISM mech;
+ CK_RSA_PKCS_PSS_PARAMS pss_params;
CK_RV rv;
CK_ULONG sig_len;
int fd, r;
+ unsigned long hashlen = 0, modlen = 0;
+
if (!opt_mechanism_used)
if (!find_mechanism(slot, CKF_SIGN|CKF_HW, NULL, 0, &opt_mechanism))
util_fatal("Sign mechanism not supported");
@@ -1607,6 +1680,93 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session,
fprintf(stderr, "Using signature algorithm %s\n", p11_mechanism_to_name(opt_mechanism));
memset(&mech, 0, sizeof(mech));
mech.mechanism = opt_mechanism;
+ pss_params.hashAlg = 0;
+
+ if (opt_hash_alg != 0 && opt_mechanism != CKM_RSA_PKCS_PSS)
+ util_fatal("The hash-algorithm is applicable only to "
+ "RSA-PKCS-PSS mechanism");
+
+ /* set "default" MGF and hash algorithms. We can overwrite MGF later */
+ switch (opt_mechanism) {
+ case CKM_RSA_PKCS_PSS:
+ pss_params.hashAlg = opt_hash_alg;
+
+ switch (opt_hash_alg) {
+ case CKM_SHA256:
+ pss_params.mgf = CKG_MGF1_SHA256;
+ break;
+ case CKM_SHA384:
+ pss_params.mgf = CKG_MGF1_SHA384;
+ break;
+ case CKM_SHA512:
+ pss_params.mgf = CKG_MGF1_SHA512;
+ break;
+ default:
+ /* the PSS should use SHA-1 if not specified */
+ pss_params.hashAlg = CKM_SHA_1;
+ /* fallthrough */
+ case CKM_SHA_1:
+ pss_params.mgf = CKG_MGF1_SHA1;
+ }
+ break;
+
+ case CKM_SHA1_RSA_PKCS_PSS:
+ pss_params.hashAlg = CKM_SHA_1;
+ pss_params.mgf = CKG_MGF1_SHA1;
+ break;
+
+ case CKM_SHA256_RSA_PKCS_PSS:
+ pss_params.hashAlg = CKM_SHA256;
+ pss_params.mgf = CKG_MGF1_SHA256;
+ break;
+
+ case CKM_SHA384_RSA_PKCS_PSS:
+ pss_params.hashAlg = CKM_SHA384;
+ pss_params.mgf = CKG_MGF1_SHA384;
+ break;
+
+ case CKM_SHA512_RSA_PKCS_PSS:
+ pss_params.hashAlg = CKM_SHA512;
+ pss_params.mgf = CKG_MGF1_SHA512;
+ break;
+ }
+
+ /* One of RSA-PSS mechanisms above: They need parameters */
+ if (pss_params.hashAlg) {
+ if (opt_mgf != 0)
+ pss_params.mgf = opt_mgf;
+
+ hashlen = figure_pss_salt_length(pss_params.hashAlg);
+
+ if (salt_len_given == 1) { /* salt size explicitly given */
+ if (salt_len < 0 && salt_len != -1 && salt_len != -2)
+ util_fatal("Salt length must be greater or equal \
+to zero, or equal to -1 (meaning: use digest size) or to -2 \
+(meaning: use maximum permissible size");
+
+ modlen = (get_private_key_length(session, key) + 7) / 8;
+ switch(salt_len) {
+ case -1: /* salt size equals to digest size */
+ pss_params.sLen = hashlen;
+ break;
+ case -2: /* maximum permissible salt len */
+ pss_params.sLen = modlen - hashlen -2;
+ break;
+ default: /* use given size but its value must be >= 0 */
+ pss_params.sLen = salt_len;
+ break;
+ } /* end switch (salt_len_given) */
+ } else { /* use default: salt len of digest size */
+ pss_params.sLen = hashlen;
+ }
+
+ mech.pParameter = &pss_params;
+ mech.ulParameterLen = sizeof(pss_params);
+ fprintf(stderr, "PSS parameters: hashAlg=%s, mgf=%s, salt=%lu B\n",
+ p11_mechanism_to_name(pss_params.hashAlg),
+ p11_mgf_to_name(pss_params.mgf),
+ pss_params.sLen);
+ }
if (opt_input == NULL)
fd = 0;
@@ -1659,7 +1819,7 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session,
util_fatal("failed to open %s: %m", opt_output);
}
- if (opt_mechanism == CKM_ECDSA || opt_mechanism == CKM_ECDSA_SHA1) {
+ if (opt_mechanism == CKM_ECDSA || opt_mechanism == CKM_ECDSA_SHA1 || opt_mechanism == CKM_ECDSA_SHA256 || opt_mechanism == CKM_ECDSA_SHA384 || opt_mechanism == CKM_ECDSA_SHA512) {
if (opt_sig_format && (!strcmp(opt_sig_format, "openssl") || !strcmp(opt_sig_format, "sequence"))) {
unsigned char *seq;
size_t seqlen;
@@ -2028,6 +2188,7 @@ gen_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hSecretKey
CK_MECHANISM mechanism = {CKM_AES_KEY_GEN, NULL_PTR, 0};
CK_OBJECT_CLASS secret_key_class = CKO_SECRET_KEY;
CK_BBOOL _true = TRUE;
+ CK_BBOOL _false = FALSE;
CK_KEY_TYPE key_type = CKK_AES;
CK_ULONG key_length;
CK_ATTRIBUTE keyTemplate[20] = {
@@ -2102,6 +2263,15 @@ gen_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hSecretKey
util_fatal("Unknown key type %s", type);
}
+ if (opt_is_sensitive != 0) {
+ FILL_ATTR(keyTemplate[n_attr], CKA_SENSITIVE, &_true, sizeof(_true));
+ n_attr++;
+ }
+ else {
+ FILL_ATTR(keyTemplate[n_attr], CKA_SENSITIVE, &_false, sizeof(_false));
+ n_attr++;
+ }
+
FILL_ATTR(keyTemplate[n_attr], CKA_ENCRYPT, &_true, sizeof(_true));
n_attr++;
FILL_ATTR(keyTemplate[n_attr], CKA_DECRYPT, &_true, sizeof(_true));
@@ -4310,14 +4480,14 @@ static int test_signature(CK_SESSION_HANDLE sess)
break;
case CKM_RSA_X_509:
dataLen = modLenBytes;
+ pseudo_randomize(data, dataLen);
break;
default:
dataLen = sizeof(data); /* let's hope it's OK */
+ pseudo_randomize(data, dataLen);
break;
}
- pseudo_randomize(data, dataLen);
-
if (firstMechType == CKM_RSA_X_509) {
/* make sure our data is smaller than the modulus */
data[0] = 0x00;
@@ -4836,7 +5006,7 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session,
return 0;
if (EVP_PKEY_size(pkey) > (int)sizeof(encrypted)) {
- fprintf(stderr, "Ciphertext buffer too small\n");
+ printf("Ciphertext buffer too small\n");
EVP_PKEY_free(pkey);
return 0;
}
@@ -4847,14 +5017,14 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session,
#endif
EVP_PKEY_free(pkey);
if (((int) encrypted_len) <= 0) {
- fprintf(stderr, "Encryption failed, returning\n");
+ printf("Encryption failed, returning\n");
return 0;
}
mech.mechanism = mech_type;
rv = p11->C_DecryptInit(session, &mech, privKeyObject);
- if (rv == CKR_MECHANISM_INVALID) {
- fprintf(stderr, "Mechanism not supported\n");
+ if (rv == CKR_MECHANISM_INVALID || rv == CKR_MECHANISM_PARAM_INVALID) {
+ printf("Mechanism not supported\n");
return 0;
}
if (rv != CKR_OK)
@@ -5621,10 +5791,10 @@ static struct mech_info p11_mechanisms[] = {
{ CKM_RSA_X9_31, "RSA-X9-31", NULL },
{ CKM_SHA1_RSA_X9_31, "SHA1-RSA-X9-31", NULL },
{ CKM_RSA_PKCS_PSS, "RSA-PKCS-PSS", NULL },
- { CKM_SHA1_RSA_PKCS_PSS, "SHA1-RSA-PKCS-PSS", NULL },
- { CKM_SHA256_RSA_PKCS, "SHA256-RSA-PKCS-PSS", NULL },
- { CKM_SHA384_RSA_PKCS, "SHA384-RSA-PKCS-PSS", NULL },
- { CKM_SHA512_RSA_PKCS, "SHA512-RSA-PKCS-PSS", NULL },
+ { CKM_SHA1_RSA_PKCS_PSS, "SHA1-RSA-PKCS-PSS", "rsa-pss-sha1" },
+ { CKM_SHA256_RSA_PKCS_PSS,"SHA256-RSA-PKCS-PSS", "rsa-pss-sha256" },
+ { CKM_SHA384_RSA_PKCS_PSS,"SHA384-RSA-PKCS-PSS", "rsa-pss-sha384" },
+ { CKM_SHA512_RSA_PKCS_PSS,"SHA512-RSA-PKCS-PSS", "rsa-pss-sha512" },
{ CKM_DSA_KEY_PAIR_GEN, "DSA-KEY-PAIR-GEN", NULL },
{ CKM_DSA, "DSA", NULL },
{ CKM_DSA_SHA1, "DSA-SHA1", NULL },
@@ -5671,8 +5841,11 @@ static struct mech_info p11_mechanisms[] = {
{ CKM_SHA_1_HMAC, "SHA-1-HMAC", NULL },
{ CKM_SHA_1_HMAC_GENERAL, "SHA-1-HMAC-GENERAL", NULL },
{ CKM_SHA256, "SHA256", NULL },
+ { CKM_SHA256_HMAC, "SHA256-HMAC", NULL },
{ CKM_SHA384, "SHA384", NULL },
+ { CKM_SHA384_HMAC, "SHA384-HMAC", NULL },
{ CKM_SHA512, "SHA512", NULL },
+ { CKM_SHA512_HMAC, "SHA512-HMAC", NULL },
{ CKM_RIPEMD128, "RIPEMD128", NULL },
{ CKM_RIPEMD128_HMAC, "RIPEMD128-HMAC", NULL },
{ CKM_RIPEMD128_HMAC_GENERAL,"RIPEMD128-HMAC-GENERAL", NULL },
@@ -5770,7 +5943,7 @@ static struct mech_info p11_mechanisms[] = {
{ CKM_ECDSA_SHA1, "ECDSA-SHA1", NULL },
{ CKM_ECDSA_SHA224, "ECDSA-SHA224", NULL },
{ CKM_ECDSA_SHA256, "ECDSA-SHA256", NULL },
- { CKM_ECDSA_SHA384, "ECDSA-SHA348", NULL },
+ { CKM_ECDSA_SHA384, "ECDSA-SHA384", NULL },
{ CKM_ECDSA_SHA512, "ECDSA-SHA512", NULL },
{ CKM_ECDH1_DERIVE, "ECDH1-DERIVE", NULL },
{ CKM_ECDH1_COFACTOR_DERIVE,"ECDH1-COFACTOR-DERIVE", NULL },
@@ -5798,6 +5971,15 @@ static struct mech_info p11_mechanisms[] = {
{ 0, NULL, NULL }
};
+static struct mech_info p11_mgf[] = {
+ { CKG_MGF1_SHA1, "MGF1-SHA1", NULL },
+ { CKG_MGF1_SHA224, "MGF1-SHA224", NULL },
+ { CKG_MGF1_SHA256, "MGF1-SHA256", NULL },
+ { CKG_MGF1_SHA384, "MGF1-SHA384", NULL },
+ { CKG_MGF1_SHA512, "MGF1-SHA512", NULL },
+ { 0, NULL, NULL }
+};
+
static const char *p11_mechanism_to_name(CK_MECHANISM_TYPE mech)
{
static char temp[64];
@@ -5824,6 +6006,30 @@ static CK_MECHANISM_TYPE p11_name_to_mechanism(const char *name)
return 0; /* gcc food */
}
+static CK_RSA_PKCS_MGF_TYPE p11_name_to_mgf(const char *name)
+{
+ struct mech_info *mi;
+
+ for (mi = p11_mgf; mi->name; mi++) {
+ if (!strcasecmp(mi->name, name))
+ return mi->mech;
+ }
+ util_fatal("Unknown PKCS11 MGF \"%s\"", name);
+}
+
+static const char *p11_mgf_to_name(CK_RSA_PKCS_MGF_TYPE mgf)
+{
+ static char temp[64];
+ struct mech_info *mi;
+
+ for (mi = p11_mgf; mi->name; mi++) {
+ if (mi->mech == mgf)
+ return mi->name;
+ }
+ snprintf(temp, sizeof(temp), "mgf-0x%lX", (unsigned long) mgf);
+ return temp;
+}
+
static const char * CKR2Str(CK_ULONG res)
{
switch (res) {
diff --git a/src/tools/util.c b/src/tools/util.c
index f5a03700..9c9f37c8 100644
--- a/src/tools/util.c
+++ b/src/tools/util.c
@@ -232,7 +232,8 @@ void util_hex_dump_asc(FILE *f, const u8 *in, size_t count, int addr)
}
}
-void util_print_usage_and_die(const char *app_name, const struct option options[],
+NORETURN void
+util_print_usage_and_die(const char *app_name, const struct option options[],
const char *option_help[], const char *args)
{
int i;
@@ -343,7 +344,7 @@ const char * util_acl_to_str(const sc_acl_entry_t *e)
return line;
}
-void
+NORETURN void
util_fatal(const char *fmt, ...)
{
va_list ap;
diff --git a/src/tools/util.h b/src/tools/util.h
index b9078087..d3a15570 100644
--- a/src/tools/util.h
+++ b/src/tools/util.h
@@ -23,15 +23,28 @@
extern "C" {
#endif
+#if _MSC_VER >= 1310
+/* MS Visual Studio 2003/.NET Framework 1.1 or newer */
+# define NORETURN _declspec( noreturn)
+#elif __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ >= 5)) || (defined __clang__)
+# define NORETURN __attribute__ ((noreturn))
+#elif __cplusplus >= 201103L
+# define NORETURN [[noreturn]]
+#elif __STDC_VERSION__ >= 201112L
+# define NORETURN _Noreturn
+#else
+# define NORETURN
+#endif
+
void util_print_binary(FILE *f, const u8 *buf, int count);
void util_hex_dump(FILE *f, const u8 *in, int len, const char *sep);
void util_hex_dump_asc(FILE *f, const u8 *in, size_t count, int addr);
-void util_print_usage_and_die(const char *app_name, const struct option options[],
+NORETURN void util_print_usage_and_die(const char *app_name, const struct option options[],
const char *option_help[], const char *args);
const char * util_acl_to_str(const struct sc_acl_entry *e);
void util_warn(const char *fmt, ...);
void util_error(const char *fmt, ...);
-void util_fatal(const char *fmt, ...);
+NORETURN void util_fatal(const char *fmt, ...);
/* All singing all dancing card connect routine */
int util_connect_card_ex(struct sc_context *, struct sc_card **, const char *reader_id, int do_wait, int do_lock, int verbose);
int util_connect_card(struct sc_context *, struct sc_card **, const char *reader_id, int do_wait, int verbose);
diff --git a/win32/Make.rules.mak b/win32/Make.rules.mak
index 2c14ad6f..00f076d6 100644
--- a/win32/Make.rules.mak
+++ b/win32/Make.rules.mak
@@ -45,15 +45,27 @@ OPENSSL_STATIC_DIR = static
!IF "$(DEBUG_DEF)" == "/DDEBUG"
!IF "$(PLATFORM)" == "x86"
-OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libcrypto32MTd.lib user32.lib advapi32.lib crypt32.lib ws2_32.lib
+# OpenSSL 1.0.2
+OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libeay32MTd.lib user32.lib advapi32.lib crypt32.lib ws2_32.lib
+# OpenSSL 1.1.0
+#OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libcrypto32MTd.lib user32.lib advapi32.lib crypt32.lib ws2_32.lib
!ELSE
-OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libcrypto64MTd.lib user32.lib advapi32.lib crypt32.lib ws2_32.lib
+# OpenSSL 1.0.2
+OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libeay32MTd.lib user32.lib advapi32.lib crypt32.lib ws2_32.lib
+# OpenSSL 1.1.0
+#OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libcrypto64MTd.lib user32.lib advapi32.lib crypt32.lib ws2_32.lib
!ENDIF
!ELSE
!IF "$(PLATFORM)" == "x86"
-OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libcrypto32MT.lib user32.lib advapi32.lib crypt32.lib ws2_32.lib
+# OpenSSL 1.0.2
+OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libeay32MT.lib user32.lib advapi32.lib crypt32.lib ws2_32.lib
+# OpenSSL 1.1.0
+#OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libcrypto32MT.lib user32.lib advapi32.lib crypt32.lib ws2_32.lib
!ELSE
-OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libcrypto64MT.lib user32.lib advapi32.lib crypt32.lib ws2_32.lib
+# OpenSSL 1.0.2
+OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libeay32MT.lib user32.lib advapi32.lib crypt32.lib ws2_32.lib
+# OpenSSL 1.1.0
+#OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libcrypto64MT.lib user32.lib advapi32.lib crypt32.lib ws2_32.lib
!ENDIF
!ENDIF
diff --git a/win32/OpenSC.wxs.in b/win32/OpenSC.wxs.in
index 9c17ebce..cd02ab5f 100644
--- a/win32/OpenSC.wxs.in
+++ b/win32/OpenSC.wxs.in
@@ -7,7 +7,6 @@
-
@@ -17,7 +16,6 @@
-
@@ -59,56 +57,10 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -122,6 +74,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -300,6 +293,15 @@
+
+
+
+
+
+
+
+
+