Fix obtaining key_length i.e. field_length pkcs15-openpgp

card-opennpgp.c and pkcs15-openpgp.c have a strang way of
using sc_object_id_t to store what they call a binary_oid
or oid_binary.  It is used to convert the EC curve asn1
returned in the cxdata.

This code uses asn1_decode_object_id to use sc_object_id_t
as used in the rest of the code.

The code and ec_curve tabes in card-openpgp.c where not changed.

pkcs15-openpgp.c was channge si to can use:
algorithm_info = sc_card_find_ec_alg(card, 0, &oid);
to retried the key_length to add to the pubkey and prkey entries.
The EC and EDDSA needs (i.e. field_length)  to run.

 On branch eddsa
 Your branch is up to date with 'Jakuje/eddsa'.

 Changes to be committed:
	modified:   card.c
	modified:   pkcs15-openpgp.c
This commit is contained in:
Doug Engert 2020-03-18 20:21:06 -05:00 committed by Jakub Jelen
parent 091b7670eb
commit 0380142482
2 changed files with 71 additions and 43 deletions

View File

@ -1154,13 +1154,13 @@ sc_algorithm_info_t * sc_card_find_alg(sc_card_t *card,
if (info->algorithm != algorithm)
continue;
if (info->key_length != key_length)
continue;
if (param) {
if (info->algorithm == SC_ALGORITHM_EC || info->algorithm == SC_ALGORITHM_EDDSA)
if(!sc_compare_oid((struct sc_object_id *)param, &info->u._ec.params.id))
continue;
if(sc_compare_oid((struct sc_object_id *)param, &info->u._ec.params.id))
return info;
}
if (info->key_length != key_length)
continue;
return info;
}
return NULL;

View File

@ -70,7 +70,7 @@ static const pgp_pin_cfg_t pin_cfg_v2[3] = {
{ "Admin PIN", 0x03, PGP_ADMIN_PIN_FLAGS, 8, 2 }
};
struct sc_object_id curve25519_binary_oid = {{0x2B, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01, -1}};
static struct sc_object_id curve25519_oid = {{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}};
#define PGP_SIG_PRKEY_USAGE (SC_PKCS15_PRKEY_USAGE_SIGN \
| SC_PKCS15_PRKEY_USAGE_SIGNRECOVER \
@ -259,7 +259,7 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card)
if ((r = read_file(card, "006E:0073:00C5", c5data, sizeof(c5data))) < 0)
goto failed;
if (r < 60) {
sc_log(ctx,
sc_log(ctx,
"finger print bytes have unexpected length (expected 60, got %d)\n", r);
return SC_ERROR_OBJECT_NOT_VALID;
}
@ -291,8 +291,9 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card)
/* only add valid keys, i.e. those with a legal algorithm identifier & finger print */
if (j >= 0 && cxdata[0] != 0) {
struct sc_object_id oid;
int k;
struct sc_algorithm_info * algorithm_info; /* no need to free */
algorithm_info = NULL;
prkey_info.id.len = 1;
prkey_info.id.value[0] = i + 1;
prkey_info.usage = key_cfg[i].prkey_usage;
@ -304,11 +305,32 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card)
prkey_obj.auth_id.len = 1;
prkey_obj.auth_id.value[0] = key_cfg[i].prkey_pin;
/* need to get size from algorithms using oid */
r = sc_asn1_decode_object_id(&cxdata[1], cxdata_len-1, &oid);
switch (cxdata[0]) {
case SC_OPENPGP_KEYALGO_ECDSA:
case SC_OPENPGP_KEYALGO_ECDH:
if((algorithm_info = sc_card_find_ec_alg(card, 0, &oid)))
prkey_info.field_length = algorithm_info->key_length;
else {
sc_log(ctx, "algorithim not found");
goto failed;
}
break;
case SC_OPENPGP_KEYALGO_EDDSA:
if ((algorithm_info = sc_card_find_eddsa_alg(card, 0, &oid)))
prkey_info.field_length = algorithm_info->key_length;
else {
sc_log(ctx, "algorithim not found");
goto failed;
}
break;
}
switch (cxdata[0]) {
case SC_OPENPGP_KEYALGO_EDDSA:
/* TODO Store the OID from cxdata + 1 ?? */
/* assuming Ed25519 as it is the only supported now */
prkey_info.field_length = 255;
/* Filter out invalid usage: ED does not support anything but sign */
prkey_info.usage &= PGP_SIG_PRKEY_USAGE;
r = sc_pkcs15emu_add_eddsa_prkey(p15card, &prkey_obj, &prkey_info);
@ -316,28 +338,22 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card)
case SC_OPENPGP_KEYALGO_ECDH:
/* This can result in either ECDSA key or EC_MONTGOMERY
* so we need to check OID */
sc_init_oid(&oid);
/* Create copy of oid */
for (k = 0; k < (cxdata_len-1) && k < SC_MAX_OBJECT_ID_OCTETS; k++) {
oid.value[k] = cxdata[k+1]; /* ignore first byte of blob (algo ID) */
}
if (sc_compare_oid(&oid, &curve25519_binary_oid)) {
if (sc_compare_oid(&oid, &curve25519_oid)) {
/* This can do only DERIVE */
prkey_info.usage = SC_PKCS15_PRKEY_USAGE_DERIVE;
prkey_info.field_length = 255;
r = sc_pkcs15emu_add_xeddsa_prkey(p15card, &prkey_obj, &prkey_info);
break;
}
/* fall through */
case SC_OPENPGP_KEYALGO_ECDSA:
/* TODO Store the OID from cxdata + 1 ?? */
/* EC keys can do derive, but not really encrypt */
prkey_info.usage |= SC_PKCS15_PRKEY_USAGE_DERIVE;
prkey_info.usage &= ~PGP_ENC_PRKEY_USAGE;
r = sc_pkcs15emu_add_ec_prkey(p15card, &prkey_obj, &prkey_info);
break;
case SC_OPENPGP_KEYALGO_ECDSA:
prkey_info.usage = SC_PKCS15_PRKEY_USAGE_SIGN;
r = sc_pkcs15emu_add_ec_prkey(p15card, &prkey_obj, &prkey_info);
break;
case SC_OPENPGP_KEYALGO_RSA:
if (r >= 3) {
if (cxdata_len >= 3) {
prkey_info.modulus_length = bebytes2ushort(cxdata + 1);
r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info);
break;
@ -380,8 +396,9 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card)
/* only add valid keys, i.e. those with a legal algorithm identifier & finger print */
if (j >= 0 && cxdata[0] != 0) {
struct sc_object_id oid;
int k;
struct sc_algorithm_info * algorithm_info; /* no need to free */
algorithm_info = NULL;
pubkey_info.id.len = 1;
pubkey_info.id.value[0] = i + 1;
pubkey_info.usage = key_cfg[i].pubkey_usage;
@ -390,11 +407,31 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card)
strlcpy(pubkey_obj.label, key_cfg[i].label, sizeof(pubkey_obj.label));
pubkey_obj.flags = SC_PKCS15_CO_FLAG_MODIFIABLE;
r = sc_asn1_decode_object_id(&cxdata[1], cxdata_len-1, &oid);
switch (cxdata[0]) {
case SC_OPENPGP_KEYALGO_ECDSA:
case SC_OPENPGP_KEYALGO_ECDH:
if((algorithm_info = sc_card_find_ec_alg(card, 0, &oid)))
pubkey_info.field_length = algorithm_info->key_length;
else {
sc_log(ctx, "algorithim not found");
goto failed;
}
break;
case SC_OPENPGP_KEYALGO_EDDSA:
if ((algorithm_info = sc_card_find_eddsa_alg(card, 0, &oid)))
pubkey_info.field_length = algorithm_info->key_length;
else {
sc_log(ctx, "algorithim not found");
goto failed;
}
break;
}
switch (cxdata[0]) {
case SC_OPENPGP_KEYALGO_EDDSA:
/* TODO Store the OID from cxdata + 1 ?? */
/* assuming Ed25519 as it is the only supported now */
pubkey_info.field_length = 255;
/* Filter out invalid usage: ED does not support anything but sign */
pubkey_info.usage &= PGP_SIG_PUBKEY_USAGE;
r = sc_pkcs15emu_add_eddsa_pubkey(p15card, &pubkey_obj, &pubkey_info);
@ -402,32 +439,23 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card)
case SC_OPENPGP_KEYALGO_ECDH:
/* This can result in either ECDSA key or EC_MONTGOMERY
* so we need to check OID */
sc_init_oid(&oid);
/* Create copy of oid */
for (k = 0; k < (cxdata_len-1) && k < SC_MAX_OBJECT_ID_OCTETS; k++) {
oid.value[k] = cxdata[k+1]; /* ignore first byte of blob (algo ID) */
}
if (sc_compare_oid(&oid, &curve25519_binary_oid)) {
if (sc_compare_oid(&oid, &curve25519_oid)) {
/* XXX What can this key do? */
pubkey_info.usage = 0;
pubkey_info.field_length = 255;
pubkey_info.usage = SC_PKCS15_PRKEY_USAGE_DERIVE;
r = sc_pkcs15emu_add_xeddsa_pubkey(p15card, &pubkey_obj, &pubkey_info);
break;
}
/* fall through */
pubkey_info.usage = SC_PKCS15_PRKEY_USAGE_DERIVE;
r = sc_pkcs15emu_add_ec_pubkey(p15card, &pubkey_obj, &pubkey_info);
break;
case SC_OPENPGP_KEYALGO_ECDSA:
/* TODO Store the OID from cxdata + 1 ?? */
/* EC keys can not do encrypt */
pubkey_info.usage &= ~PGP_ENC_PUBKEY_USAGE;
pubkey_info.usage = PGP_SIG_PUBKEY_USAGE;
r = sc_pkcs15emu_add_ec_pubkey(p15card, &pubkey_obj, &pubkey_info);
break;
case SC_OPENPGP_KEYALGO_RSA:
if (r >= 3) {
pubkey_info.modulus_length = bebytes2ushort(cxdata + 1);
r = sc_pkcs15emu_add_rsa_pubkey(p15card, &pubkey_obj, &pubkey_info);
break;
}
/* Fallthrough */
pubkey_info.modulus_length = bebytes2ushort(cxdata + 1);
r = sc_pkcs15emu_add_rsa_pubkey(p15card, &pubkey_obj, &pubkey_info);
break;
default:
sc_log(ctx, "Invalid algorithm identifier %x (length = %d)",
cxdata[0], r);
@ -473,7 +501,7 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card)
failed:
if (r < 0) {
sc_log(card->ctx,
sc_log(card->ctx,
"Failed to initialize OpenPGP emulation: %s\n",
sc_strerror(r));
}