From 23dc52c90386c7a80b6f025c48046f7079cec868 Mon Sep 17 00:00:00 2001 From: Yaroslav Isakov Date: Wed, 7 Apr 2021 19:29:07 +0200 Subject: [PATCH] Fixed OpenPGP logic for comparing OIDs It's better to leave oid comparison as it was before, and drop trailing zero byte after it, when reading from token. --- src/libopensc/card-openpgp.c | 10 +++++++--- src/libopensc/pkcs15-openpgp.c | 10 ++++++++++ src/libopensc/sc.c | 4 ++-- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index f54bf517..4fb8a995 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -613,7 +613,7 @@ pgp_parse_algo_attr_blob(sc_card_t *card, const pgp_blob_t *blob, /* SC_OPENPGP_KEYALGO_ECDH || SC_OPENPGP_KEYALGO_ECDSA || SC_OPENPGP_KEYALGO_EDDSA */ key_info->algorithm = blob->data[0]; - /* last byte is only set if pubkey import is supported, empty otherwise*/ + /* last byte is set to 0xFF if pubkey import is supported */ if (blob->data[blob->len-1] == SC_OPENPGP_KEYFORMAT_EC_STDPUB){ if (blob->len < 3) return SC_ERROR_INCORRECT_PARAMETERS; @@ -621,9 +621,14 @@ pgp_parse_algo_attr_blob(sc_card_t *card, const pgp_blob_t *blob, key_info->u.ec.keyformat = SC_OPENPGP_KEYFORMAT_EC_STDPUB; } else { + /* otherwise, last byte could be 00, so let's ignore it, as + * it is not part of OID */ if (blob->len < 2) return SC_ERROR_INCORRECT_PARAMETERS; - key_info->u.ec.oid_len = blob->len - 1; + if (blob->data[blob->len-1] == SC_OPENPGP_KEYFORMAT_EC_STD) + key_info->u.ec.oid_len = blob->len - 2; + else + key_info->u.ec.oid_len = blob->len - 1; key_info->u.ec.keyformat = SC_OPENPGP_KEYFORMAT_EC_STD; } @@ -1635,7 +1640,6 @@ pgp_get_pubkey_pem(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len) /* PKCS#11 3.0: 2.3.5 Edwards EC public keys only support the use * of the curveName selection to specify a curve name as defined * in [RFC 8032] */ - r = sc_pkcs15_encode_pubkey_as_spki(card->ctx, &p15pubkey, &data, &len); break; case SC_OPENPGP_KEYALGO_ECDH: diff --git a/src/libopensc/pkcs15-openpgp.c b/src/libopensc/pkcs15-openpgp.c index 5c1946c0..812b8ed8 100644 --- a/src/libopensc/pkcs15-openpgp.c +++ b/src/libopensc/pkcs15-openpgp.c @@ -309,6 +309,11 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) if (cxdata[0] == SC_OPENPGP_KEYALGO_ECDH || cxdata[0] == SC_OPENPGP_KEYALGO_ECDSA || cxdata[0] == SC_OPENPGP_KEYALGO_EDDSA) { + /* Last byte could be Import-Format of private key, let's ignore it, + * as it is not part of OID */ + if (cxdata[cxdata_len-1] == SC_OPENPGP_KEYFORMAT_EC_STD || + cxdata[cxdata_len-1] == SC_OPENPGP_KEYFORMAT_EC_STDPUB) + cxdata_len--; r = sc_asn1_decode_object_id(&cxdata[1], cxdata_len-1, &oid); if (r != SC_SUCCESS) { sc_log(ctx, "Failed to parse OID for elliptic curve algorithm"); @@ -429,6 +434,11 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) if (cxdata[0] == SC_OPENPGP_KEYALGO_ECDH || cxdata[0] == SC_OPENPGP_KEYALGO_ECDSA || cxdata[0] == SC_OPENPGP_KEYALGO_EDDSA) { + /* Last byte could be Import-Format of private key, let's ignore it, + * as it is not part of OID */ + if (cxdata[cxdata_len-1] == SC_OPENPGP_KEYFORMAT_EC_STD || + cxdata[cxdata_len-1] == SC_OPENPGP_KEYFORMAT_EC_STDPUB) + cxdata_len--; r = sc_asn1_decode_object_id(&cxdata[1], cxdata_len-1, &oid); if (r != SC_SUCCESS) { sc_log(ctx, "Failed to parse OID for elliptic curve algorithm"); diff --git a/src/libopensc/sc.c b/src/libopensc/sc.c index 29cd44e1..29f6b868 100644 --- a/src/libopensc/sc.c +++ b/src/libopensc/sc.c @@ -300,10 +300,10 @@ int sc_compare_oid(const struct sc_object_id *oid1, const struct sc_object_id *o } for (i = 0; i < SC_MAX_OBJECT_ID_OCTETS; i++) { - if ((oid1->value[i] == -1) || (oid2->value[i] == -1)) - break; if (oid1->value[i] != oid2->value[i]) return 0; + if (oid1->value[i] == -1) + break; } return 1;