From 73e283b4b1c57c9a556c24b4f8f17a19b04312c9 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 27 Mar 2020 11:13:30 +0100 Subject: [PATCH] openpgp: Correctly handle curve25519 keys --- src/libopensc/card.c | 6 +++-- src/libopensc/pkcs15-openpgp.c | 41 +++++++++++++++++++++++++++------- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/libopensc/card.c b/src/libopensc/card.c index cb7c8622..f2c6ca5a 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -1155,8 +1155,10 @@ sc_algorithm_info_t * sc_card_find_alg(sc_card_t *card, if (info->algorithm != algorithm) 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)) + if (info->algorithm == SC_ALGORITHM_EC || + info->algorithm == SC_ALGORITHM_EDDSA || + info->algorithm == SC_ALGORITHM_XEDDSA) + if (sc_compare_oid((struct sc_object_id *)param, &info->u._ec.params.id)) return info; } if (info->key_length != key_length) diff --git a/src/libopensc/pkcs15-openpgp.c b/src/libopensc/pkcs15-openpgp.c index b2c7ed41..5c1946c0 100644 --- a/src/libopensc/pkcs15-openpgp.c +++ b/src/libopensc/pkcs15-openpgp.c @@ -316,8 +316,18 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) } switch (cxdata[0]) { - case SC_OPENPGP_KEYALGO_ECDSA: case SC_OPENPGP_KEYALGO_ECDH: + if (sc_compare_oid(&oid, &curve25519_oid)) { + if ((algorithm_info = sc_card_find_xeddsa_alg(card, 0, &oid))) + prkey_info.field_length = algorithm_info->key_length; + else { + sc_log(ctx, "algorithm not found"); + continue; + } + break; + } + /* Fall through */ + case SC_OPENPGP_KEYALGO_ECDSA: if((algorithm_info = sc_card_find_ec_alg(card, 0, &oid))) prkey_info.field_length = algorithm_info->key_length; else { @@ -337,11 +347,11 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) switch (cxdata[0]) { case SC_OPENPGP_KEYALGO_EDDSA: - /* assuming Ed25519 as it is the only supported now */ - /* Filter out invalid usage: ED does not support anything but sign */ + /* Filter out invalid usage: EdDSA does not support anything but sign */ prkey_info.usage &= PGP_SIG_PRKEY_USAGE; r = sc_pkcs15emu_add_eddsa_prkey(p15card, &prkey_obj, &prkey_info); break; + case SC_OPENPGP_KEYALGO_ECDH: /* This can result in either ECDSA key or EC_MONTGOMERY * so we need to check OID */ @@ -355,10 +365,12 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) 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 (cxdata_len >= 3) { prkey_info.modulus_length = bebytes2ushort(cxdata + 1); @@ -381,7 +393,7 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) for (i = 0; i < 3; i++) { sc_pkcs15_pubkey_info_t pubkey_info; sc_pkcs15_object_t pubkey_obj; - u8 cxdata[10]; + u8 cxdata[12]; int cxdata_len = sizeof(cxdata); char path_template[] = "006E:0073:00Cx"; int j; @@ -424,8 +436,18 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) } switch (cxdata[0]) { - case SC_OPENPGP_KEYALGO_ECDSA: case SC_OPENPGP_KEYALGO_ECDH: + if (sc_compare_oid(&oid, &curve25519_oid)) { + if ((algorithm_info = sc_card_find_xeddsa_alg(card, 0, &oid))) + pubkey_info.field_length = algorithm_info->key_length; + else { + sc_log(ctx, "algorithm not found"); + continue; + } + break; + } + /* Fall through */ + case SC_OPENPGP_KEYALGO_ECDSA: if((algorithm_info = sc_card_find_ec_alg(card, 0, &oid))) pubkey_info.field_length = algorithm_info->key_length; else { @@ -467,9 +489,12 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) r = sc_pkcs15emu_add_ec_pubkey(p15card, &pubkey_obj, &pubkey_info); break; case SC_OPENPGP_KEYALGO_RSA: - pubkey_info.modulus_length = bebytes2ushort(cxdata + 1); - r = sc_pkcs15emu_add_rsa_pubkey(p15card, &pubkey_obj, &pubkey_info); - break; + if (cxdata_len >= 3) { + pubkey_info.modulus_length = bebytes2ushort(cxdata + 1); + r = sc_pkcs15emu_add_rsa_pubkey(p15card, &pubkey_obj, &pubkey_info); + break; + } + /* Fall through */ default: sc_log(ctx, "Invalid algorithm identifier %x (length = %d)", cxdata[0], r);