[pkg-opensc-commit] [opensc] 283/295: Support SKDF and secret key upload for MyEID cards
Eric Dorland
eric at moszumanska.debian.org
Sat Jun 24 21:11:40 UTC 2017
This is an automated email from the git hooks/post-receive script.
eric pushed a commit to branch master
in repository opensc.
commit 94973809c20d0290e4633f68219cae12b9c65325
Author: Timo Teräs <timo.teras at iki.fi>
Date: Fri Apr 14 10:42:30 2017 +0300
Support SKDF and secret key upload for MyEID cards
---
src/libopensc/card-myeid.c | 46 +++++++++---
src/libopensc/cardctl.h | 8 +-
src/pkcs15init/myeid.profile | 27 ++++++-
src/pkcs15init/pkcs15-myeid.c | 167 +++++++++++++++++++++++++-----------------
4 files changed, 160 insertions(+), 88 deletions(-)
diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c
index 65c108f..80c2821 100644
--- a/src/libopensc/card-myeid.c
+++ b/src/libopensc/card-myeid.c
@@ -43,6 +43,8 @@
#define LOAD_KEY_EC_PRIVATE 0x97
#define LOAD_KEY_EC_PUBLIC 0x96
+#define LOAD_KEY_SYMMETRIC 0xa0
+
#define MYEID_STATE_CREATION 0x01
#define MYEID_STATE_ACTIVATED 0x07
@@ -148,7 +150,6 @@ static int myeid_init(struct sc_card *card)
u8 appletInfo[20];
size_t appletInfoLen;
int r;
- unsigned short max_ecc_key_length = 256;
myeid_card_caps_t card_caps;
LOG_FUNC_CALLED(card->ctx);
@@ -183,16 +184,15 @@ static int myeid_init(struct sc_card *card)
_sc_card_add_rsa_alg(card, 2048, flags, 0);
memset(&card_caps, 0, sizeof(myeid_card_caps_t));
+ card_caps.max_ecc_key_length = 256;
+ card_caps.max_rsa_key_length = 2048;
if (card->version.fw_major >= 40) {
/* Since 4.0, we can query available algorithms and key sizes.
* Since 3.5.0 RSA up to 2048 and ECC up to 256 are always supported, so we check only max ECC key length. */
r = myeid_get_card_caps(card, &card_caps);
- if (r == SC_SUCCESS) {
- max_ecc_key_length = card_caps.max_ecc_key_length;
- }
- else {
+ if (r != SC_SUCCESS) {
sc_log(card->ctx, "Failed to get card capabilities. Using default max ECC key length 256.");
}
}
@@ -206,15 +206,28 @@ static int myeid_init(struct sc_card *card)
ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE | SC_ALGORITHM_EXT_EC_UNCOMPRESES;
for (i=0; ec_curves[i].curve_name != NULL; i++) {
- if (i == 2 && max_ecc_key_length < 384)
- continue;
- else if (i == 3 && max_ecc_key_length < 521)
- continue;
- else
- _sc_card_add_ec_alg(card, ec_curves[i].size, flags, ext_flags, &ec_curves[i].curve_oid);
+ if (card_caps.max_ecc_key_length >= ec_curves[i].size)
+ _sc_card_add_ec_alg(card, ec_curves[i].size, flags, ext_flags, &ec_curves[i].curve_oid);
}
}
+ /* show supported symmetric algorithms */
+ flags = 0;
+ if (card_caps.card_supported_features & MYEID_CARD_CAP_3DES) {
+ if (card_caps.max_des_key_length >= 56)
+ _sc_card_add_symmetric_alg(card, SC_ALGORITHM_DES, 56, flags);
+ if (card_caps.max_des_key_length >= 128)
+ _sc_card_add_symmetric_alg(card, SC_ALGORITHM_3DES, 128, flags);
+ if (card_caps.max_des_key_length >= 192)
+ _sc_card_add_symmetric_alg(card, SC_ALGORITHM_3DES, 192, flags);
+ }
+ if (card_caps.card_supported_features & MYEID_CARD_CAP_AES) {
+ if (card_caps.max_aes_key_length >= 128)
+ _sc_card_add_symmetric_alg(card, SC_ALGORITHM_AES, 128, flags);
+ if (card_caps.max_aes_key_length >= 256)
+ _sc_card_add_symmetric_alg(card, SC_ALGORITHM_AES, 256, flags);
+ }
+
/* State that we have an RNG */
card->caps |= SC_CARD_CAP_RNG | SC_CARD_CAP_ISO7816_PIN_INFO;
@@ -439,6 +452,8 @@ static int encode_file_structure(sc_card_t *card, const sc_file_t *file,
else {
delete = sc_file_get_acl_entry(file, SC_AC_OP_DELETE);
+ sc_log(card->ctx, "id (%X), type (%X)", file->id, file->type);
+
switch (file->type) {
case SC_FILE_TYPE_WORKING_EF:
@@ -1188,7 +1203,8 @@ static int myeid_loadkey(sc_card_t *card, int mode, u8* value, int value_len)
if(value != NULL &&
value[0] != 0x0 &&
- mode != LOAD_KEY_PUBLIC_EXPONENT)
+ mode != LOAD_KEY_PUBLIC_EXPONENT &&
+ mode != LOAD_KEY_SYMMETRIC)
sbuf[len++] = 0x0;
if(mode == LOAD_KEY_MODULUS && value_len >= 256)
@@ -1328,6 +1344,12 @@ static int myeid_generate_store_key(struct sc_card *card,
data->ecpublic_point_len)) >= 0)
LOG_FUNC_RETURN(card->ctx, r);
}
+ else if(data->key_type == SC_CARDCTL_MYEID_KEY_AES ||
+ data->key_type == SC_CARDCTL_MYEID_KEY_DES) {
+ if((r = myeid_loadkey(card, LOAD_KEY_SYMMETRIC, data->d,
+ data->d_len)) >= 0)
+ LOG_FUNC_RETURN(card->ctx, r);
+ }
}
LOG_FUNC_RETURN(card->ctx, r);
diff --git a/src/libopensc/cardctl.h b/src/libopensc/cardctl.h
index d67a83c..9a58427 100644
--- a/src/libopensc/cardctl.h
+++ b/src/libopensc/cardctl.h
@@ -878,7 +878,9 @@ typedef struct sc_rtecp_genkey_data {
*/
enum SC_CARDCTL_MYEID_KEY_TYPE {
SC_CARDCTL_MYEID_KEY_RSA = 0x11,
- SC_CARDCTL_MYEID_KEY_EC = 0x22
+ SC_CARDCTL_MYEID_KEY_DES = 0x19,
+ SC_CARDCTL_MYEID_KEY_EC = 0x22,
+ SC_CARDCTL_MYEID_KEY_AES = 0x29
};
struct sc_cardctl_myeid_data_obj {
@@ -907,8 +909,8 @@ typedef struct sc_rtecp_genkey_data {
unsigned int invq_len;
unsigned char *invq;
/* new for MyEID > 3.6.0 */
- unsigned char *d; /* EC private key */
- unsigned int d_len; /* EC */
+ unsigned char *d; /* EC private key / Symmetric key */
+ unsigned int d_len; /* EC / Symmetric */
unsigned char *ecpublic_point; /* EC public key */
unsigned int ecpublic_point_len; /* EC */
};
diff --git a/src/pkcs15init/myeid.profile b/src/pkcs15init/myeid.profile
index 8b84c95..2645261 100644
--- a/src/pkcs15init/myeid.profile
+++ b/src/pkcs15init/myeid.profile
@@ -36,6 +36,7 @@ option default {
cdf-trusted-size = 510;
prkdf-size = 1530;
pukdf-size = 1530;
+ skdf-size = 1530;
dodf-size = 1530;
}
}
@@ -136,6 +137,13 @@ filesystem {
acl = *=NEVER, READ=NONE, UPDATE=$PIN, DELETE=$SOPIN;
}
+ EF PKCS15-SKDF {
+ file-id = 4407;
+ structure = transparent;
+ size = $skdf-size;
+ acl = *=NEVER, READ=NONE, UPDATE=$PIN, DELETE=$SOPIN;
+ }
+
EF PKCS15-CDF {
file-id = 4403;
structure = transparent;
@@ -159,8 +167,14 @@ filesystem {
EF template-private-key {
type = internal-ef;
- file-id = 4B01;
- acl = CRYPTO=$PIN, UPDATE=$PIN, DELETE=$PIN, GENERATE=$PIN;
+ file-id = 4B01;
+ acl = CRYPTO=$PIN, UPDATE=$PIN, DELETE=$PIN, GENERATE=$PIN;
+ }
+
+ EF template-secret-key {
+ type = internal-ef;
+ file-id = 4D01;
+ acl = CRYPTO=$PIN, UPDATE=$PIN, DELETE=$PIN, GENERATE=$PIN;
}
EF template-public-key {
@@ -181,13 +195,18 @@ filesystem {
EF private-key {
file-id = 4B01;
type = internal-ef;
- acl = READ=NONE, UPDATE=$PIN, DELETE=$PIN, GENERATE=$PIN;
+ acl = CRYPTO=$PIN, UPDATE=$PIN, DELETE=$PIN, GENERATE=$PIN;
}
EF public-key {
- file-id = 5501;
+ file-id = 5501;
structure = transparent;
acl = READ=NONE, UPDATE=$PIN, DELETE=$PIN, GENERATE=$PIN;
}
+ EF secret-key {
+ file-id = 4D01;
+ type = internal-ef;
+ acl = CRYPTO=$PIN, UPDATE=$PIN, DELETE=$PIN, GENERATE=$PIN;
+ }
# Certificate template
EF certificate {
diff --git a/src/pkcs15init/pkcs15-myeid.c b/src/pkcs15init/pkcs15-myeid.c
index 200009a..3e4bb19 100644
--- a/src/pkcs15init/pkcs15-myeid.c
+++ b/src/pkcs15init/pkcs15-myeid.c
@@ -201,6 +201,7 @@ myeid_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df
static const char *create_dfs[] = {
"PKCS15-PrKDF",
"PKCS15-PuKDF",
+ "PKCS15-SKDF",
"PKCS15-CDF",
"PKCS15-CDF-TRUSTED",
"PKCS15-DODF",
@@ -210,6 +211,7 @@ myeid_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df
static const int create_dfs_val[] = {
SC_PKCS15_PRKDF,
SC_PKCS15_PUKDF,
+ SC_PKCS15_SKDF,
SC_PKCS15_CDF,
SC_PKCS15_CDF_TRUSTED,
SC_PKCS15_DODF
@@ -349,19 +351,33 @@ myeid_new_file(sc_profile_t *profile, sc_card_t *card,
sc_file_t *file;
sc_path_t *p;
char name[64];
- const char *tag;
+ const char *tag = NULL;
int r;
LOG_FUNC_CALLED(card->ctx);
- if (type == SC_PKCS15_TYPE_PRKEY_RSA || type == SC_PKCS15_TYPE_PRKEY_EC)
+ switch (type) {
+ case SC_PKCS15_TYPE_PRKEY_RSA:
+ case SC_PKCS15_TYPE_PRKEY_EC:
tag = "private-key";
- else if (type == SC_PKCS15_TYPE_PUBKEY_RSA || type == SC_PKCS15_TYPE_PUBKEY_EC)
+ break;
+ case SC_PKCS15_TYPE_PUBKEY_RSA:
+ case SC_PKCS15_TYPE_PUBKEY_EC:
tag = "public-key";
- else if ((type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_CERT)
- tag = "certificate";
- else if ((type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_DATA_OBJECT)
- tag = "data";
- else {
+ break;
+ case SC_PKCS15_TYPE_SKEY_GENERIC:
+ case SC_PKCS15_TYPE_SKEY_DES:
+ case SC_PKCS15_TYPE_SKEY_3DES:
+ tag = "secret-key";
+ break;
+ default:
+ if ((type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_CERT)
+ tag = "certificate";
+ else if ((type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_DATA_OBJECT)
+ tag = "data";
+ break;
+ }
+
+ if (!tag) {
sc_log(card->ctx, "Unsupported file type");
return SC_ERROR_INVALID_ARGUMENTS;
}
@@ -418,36 +434,37 @@ myeid_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
struct sc_pkcs15_object *object) {
struct sc_context *ctx = p15card->card->ctx;
struct sc_card *card = p15card->card;
- struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *) object->data;
+ struct sc_pkcs15_prkey_info *prkey_info = (struct sc_pkcs15_prkey_info *) object->data;
+ struct sc_pkcs15_skey_info *skey_info = (struct sc_pkcs15_skey_info *) object->data;
+ struct sc_pkcs15_id *id;
+ struct sc_path *path;
+ int *key_reference;
struct sc_file *file = NULL;
struct sc_pkcs15_object *pin_object = NULL;
struct sc_pkcs15_auth_info *pkcs15_auth_info = NULL;
- int keybits = key_info->modulus_length, r;
- int pin_reference = -1;
unsigned char sec_attrs[] = {0xFF, 0xFF, 0xFF};
+ int r, ef_structure, keybits = 0, pin_reference = -1;
LOG_FUNC_CALLED(card->ctx);
- /* Check that the card supports the requested modulus length */
switch (object->type) {
case SC_PKCS15_TYPE_PRKEY_RSA:
- if (sc_card_find_rsa_alg(p15card->card, keybits) == NULL)
- LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS,
- "Unsupported RSA key size");
+ ef_structure = SC_CARDCTL_MYEID_KEY_RSA;
+ keybits = prkey_info->modulus_length;
break;
case SC_PKCS15_TYPE_PRKEY_EC:
- /*
- Here the information about curve is not available, that's why algorithm is checked
- without curve OID.
- */
-
- if (key_info->field_length != 0)
- keybits = key_info->field_length;
- else
- key_info->field_length = keybits;
-
- if (sc_card_find_ec_alg(p15card->card, keybits, NULL) == NULL)
- LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Unsupported EC key size");
+ ef_structure = SC_CARDCTL_MYEID_KEY_EC;
+ keybits = prkey_info->field_length;
+ break;
+ case SC_PKCS15_TYPE_SKEY_DES:
+ case SC_PKCS15_TYPE_SKEY_3DES:
+ ef_structure = SC_CARDCTL_MYEID_KEY_DES;
+ keybits = skey_info->value_len;
+ break;
+ case SC_PKCS15_TYPE_SKEY_GENERIC:
+ keybits = skey_info->value_len;
+ /* FIXME */
+ ef_structure = SC_CARDCTL_MYEID_KEY_AES;
break;
default:
LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS,
@@ -455,27 +472,33 @@ myeid_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
break;
}
- sc_log(ctx, "create MyEID private key ID:%s", sc_pkcs15_print_id(&key_info->id));
+ if ((object->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_PRKEY) {
+ id = &prkey_info->id;
+ path = &prkey_info->path;
+ key_reference = &prkey_info->key_reference;
+ } else {
+ id = &skey_info->id;
+ path = &skey_info->path;
+ key_reference = &skey_info->key_reference;
+ }
+
+ sc_log(ctx, "create MyEID key ID:%s", sc_pkcs15_print_id(id));
/* Get the private key file */
- r = myeid_new_file(profile, card, object->type, key_info->key_reference, &file);
- LOG_TEST_RET(ctx, r, "Cannot get new MyEID private key file");
+ r = myeid_new_file(profile, card, object->type, *key_reference, &file);
+ LOG_TEST_RET(ctx, r, "Cannot get new MyEID key file");
if (!file || !file->path.len)
- LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Cannot determine private key file");
+ LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Cannot determine key file");
sc_log(ctx, "Key file size %d", keybits);
file->size = keybits;
+ file->ef_structure = ef_structure;
- if (object->type == SC_PKCS15_TYPE_PRKEY_RSA)
- file->ef_structure = SC_CARDCTL_MYEID_KEY_RSA;
- else if (object->type == SC_PKCS15_TYPE_PRKEY_EC)
- file->ef_structure = SC_CARDCTL_MYEID_KEY_EC;
-
- memcpy(&key_info->path.value, &file->path.value, file->path.len);
- key_info->key_reference = file->path.value[file->path.len - 1] & 0xFF;
+ memcpy(path->value, &file->path.value, file->path.len);
+ *key_reference = file->path.value[file->path.len - 1] & 0xFF;
- sc_log(ctx, "Path of MyEID private key file to create %s",
+ sc_log(ctx, "Path of MyEID key file to create %s",
sc_print_path(&file->path));
if (object->auth_id.len >= 1) {
@@ -513,7 +536,7 @@ myeid_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
/* Now create the key file */
r = sc_pkcs15init_create_file(profile, p15card, file);
sc_file_free(file);
- LOG_TEST_RET(ctx, r, "Cannot create MyEID private key file");
+ LOG_TEST_RET(ctx, r, "Cannot create MyEID key file");
LOG_FUNC_RETURN(ctx, r);
}
@@ -527,40 +550,28 @@ myeid_store_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
struct sc_pkcs15_prkey *prkey) {
struct sc_context *ctx = p15card->card->ctx;
struct sc_card *card = p15card->card;
- struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *) object->data;
struct sc_cardctl_myeid_gen_store_key_info args;
struct sc_file *file = NULL;
- int r, keybits = key_info->modulus_length;
+ struct sc_pkcs15_id *id;
+ struct sc_path *path;
+ int r;
LOG_FUNC_CALLED(ctx);
- switch (object->type) {
- case SC_PKCS15_TYPE_PRKEY_RSA:
- if (sc_card_find_rsa_alg(p15card->card, keybits) == NULL)
- LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Unsupported RSA key size");
- break;
- case SC_PKCS15_TYPE_PRKEY_EC:
- if (!sc_valid_oid(&prkey->u.ec.params.id))
- if (sc_pkcs15_fix_ec_parameters(ctx, &prkey->u.ec.params))
- LOG_FUNC_RETURN(ctx, SC_ERROR_OBJECT_NOT_VALID);
-
- if(key_info->field_length != 0)
- keybits = key_info->field_length;
- else
- key_info->field_length = keybits;
-
- if (sc_card_find_ec_alg(p15card->card, keybits, &prkey->u.ec.params.id) == NULL)
- LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Unsupported algorithm or key size");
- break;
- default:
- LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Store key failed: Unsupported key type");
- break;
+ if ((object->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_PRKEY) {
+ struct sc_pkcs15_prkey_info *prkey_info = (struct sc_pkcs15_prkey_info *) object->data;
+ id = &prkey_info->id;
+ path = &prkey_info->path;
+ } else {
+ struct sc_pkcs15_skey_info *skey_info = (struct sc_pkcs15_skey_info *) object->data;
+ id = &skey_info->id;
+ path = &skey_info->path;
}
sc_log(ctx, "store MyEID key with ID:%s and path:%s",
- sc_pkcs15_print_id(&key_info->id), sc_print_path(&key_info->path));
+ sc_pkcs15_print_id(id), sc_print_path(path));
- r = sc_select_file(card, &key_info->path, &file);
+ r = sc_select_file(card, path, &file);
LOG_TEST_RET(ctx, r, "Cannot store MyEID key: select key file failed");
r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE);
@@ -572,8 +583,9 @@ myeid_store_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
memset(&args, 0, sizeof (args));
args.op_type = OP_TYPE_STORE;
- if(object->type == SC_PKCS15_TYPE_PRKEY_RSA) {
- //args.key_len_bits = keybits;
+
+ switch (object->type) {
+ case SC_PKCS15_TYPE_PRKEY_RSA:
args.key_type = SC_CARDCTL_MYEID_KEY_RSA;
args.pubexp_len = prkey->u.rsa.exponent.len;
args.pubexp = prkey->u.rsa.exponent.data;
@@ -589,16 +601,33 @@ myeid_store_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
args.invq_len = prkey->u.rsa.iqmp.len;
args.invq = prkey->u.rsa.iqmp.data;
+ //args.key_len_bits = keybits;
args.key_len_bits = prkey->u.rsa.modulus.len;
args.mod = prkey->u.rsa.modulus.data;
- }
- else {
+ break;
+ case SC_PKCS15_TYPE_PRKEY_EC:
args.key_type = SC_CARDCTL_MYEID_KEY_EC;
args.d = prkey->u.ec.privateD.data;
args.d_len = prkey->u.ec.privateD.len;
args.ecpublic_point = prkey->u.ec.ecpointQ.value;
args.ecpublic_point_len = prkey->u.ec.ecpointQ.len;
args.key_len_bits = prkey->u.ec.params.field_length;
+ break;
+ case SC_PKCS15_TYPE_SKEY_GENERIC:
+ case SC_PKCS15_TYPE_SKEY_DES:
+ case SC_PKCS15_TYPE_SKEY_2DES:
+ case SC_PKCS15_TYPE_SKEY_3DES:
+ switch (prkey->algorithm) {
+ case SC_ALGORITHM_AES:
+ args.key_type = SC_CARDCTL_MYEID_KEY_AES;
+ break;
+ case SC_ALGORITHM_DES:
+ args.key_type = SC_CARDCTL_MYEID_KEY_DES;
+ break;
+ }
+ args.d = prkey->u.secret.data;
+ args.d_len = prkey->u.secret.data_len;
+ break;
}
/* Store RSA key */
r = sc_card_ctl(card, SC_CARDCTL_MYEID_GENERATE_STORE_KEY, &args);
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-opensc/opensc.git
More information about the pkg-opensc-commit
mailing list