From 8d046b6819c80c116a655ca5c692f371c8bea408 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 27 Aug 2024 08:05:16 -0500 Subject: [PATCH] pkcs15-pubkey.c - return EC_POINT as OCTET STRING by default On branch X25519-improvements-2 Changes to be committed: modified: libopensc/pkcs15-pubkey.c --- src/libopensc/pkcs15-pubkey.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 1195be4d43e..dc4daeacd82 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -541,16 +541,16 @@ static struct sc_asn1_entry c_asn1_gostr3410_pub_coefficients[C_ASN1_GOSTR3410_P /* accept either */ #define C_ASN1_EC_POINTQ_SIZE 3 static struct sc_asn1_entry c_asn1_ec_pointQ[C_ASN1_EC_POINTQ_SIZE] = { - { "ecpointQ", SC_ASN1_BIT_STRING_NI, SC_ASN1_TAG_BIT_STRING, SC_ASN1_OPTIONAL | SC_ASN1_ALLOC, NULL, NULL }, { "ecpointQ-OS", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_OPTIONAL | SC_ASN1_ALLOC, NULL, NULL }, + { "ecpointQ-BS", SC_ASN1_BIT_STRING_NI, SC_ASN1_TAG_BIT_STRING, SC_ASN1_OPTIONAL | SC_ASN1_ALLOC, NULL, NULL }, { NULL, 0, 0, 0, NULL, NULL } }; /* See RFC8410 */ #define C_ASN1_EDDSA_PUBKEY_SIZE 3 static struct sc_asn1_entry c_asn1_eddsa_pubkey[C_ASN1_EDDSA_PUBKEY_SIZE] = { - { "ecpointQ", SC_ASN1_BIT_STRING_NI, SC_ASN1_TAG_BIT_STRING, SC_ASN1_OPTIONAL | SC_ASN1_ALLOC, NULL, NULL }, { "ecpointQ-OS", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_OPTIONAL | SC_ASN1_ALLOC, NULL, NULL }, + { "ecpointQ-BS", SC_ASN1_BIT_STRING_NI, SC_ASN1_TAG_BIT_STRING, SC_ASN1_OPTIONAL | SC_ASN1_ALLOC, NULL, NULL }, { NULL, 0, 0, 0, NULL, NULL } }; // clang-format on @@ -665,6 +665,10 @@ sc_pkcs15_decode_pubkey_ec(sc_context_t *ctx, LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ASN1_OBJECT); } + /* if from bit string */ + if (asn1_ec_pointQ[1].flags & SC_ASN1_PRESENT) + ecpoint_len = (ecpoint_len + 7) / 8; + if (*ecpoint_data != 0x04) { free(ecpoint_data); LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Supported only uncompressed EC pointQ value"); @@ -690,7 +694,7 @@ sc_pkcs15_encode_pubkey_ec(sc_context_t *ctx, struct sc_pkcs15_pubkey_ec *key, * But some PKCS11 modules define a CKA_VALUE for a public key * and PKCS11 says ECPOINT is encoded as "DER-encoding of ANSI X9.62 ECPoint value Q" * But ANSI X9.62 (early draft at least) says encode as BIT STRING - * IETF encodes in SubjectPublicKeyInfo (SPKI) in BIT STRING + * IETF encodes it in SubjectPublicKeyInfo (SPKI) in BIT STRING * PKCS11 V3 does add CKA_PUBLIC_KEY_INFO as SPKI * For now return as OCTET STRING. */ @@ -699,11 +703,11 @@ sc_pkcs15_encode_pubkey_ec(sc_context_t *ctx, struct sc_pkcs15_pubkey_ec *key, LOG_FUNC_CALLED(ctx); sc_copy_asn1_entry(c_asn1_ec_pointQ, asn1_ec_pointQ); - if (gdb_test == 1) { - key_len = key->ecpointQ.len * 8; /* encode in bit string */ + if (gdb_test == 0) { + key_len = key->ecpointQ.len; sc_format_asn1_entry(asn1_ec_pointQ + 0, key->ecpointQ.value, &key_len, 1); } else { - key_len = key->ecpointQ.len; + key_len = key->ecpointQ.len * 8; /* encode in bit string */ sc_format_asn1_entry(asn1_ec_pointQ + 1, key->ecpointQ.value, &key_len, 1); } @@ -736,6 +740,9 @@ sc_pkcs15_decode_pubkey_eddsa(sc_context_t *ctx, LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ASN1_OBJECT); } + if ( asn1_ec_pointQ[1].flags & SC_ASN1_PRESENT) + ecpoint_len = (ecpoint_len + 7) /8; + key->ecpointQ.len = ecpoint_len; key->ecpointQ.value = ecpoint_data; key->params.field_length = ecpoint_len * 8;