Skip to content

Commit

Permalink
pkcs15-pubkey.c - return EC_POINT as OCTET STRING by default
Browse files Browse the repository at this point in the history
 On branch X25519-improvements-2
 Changes to be committed:
	modified:   libopensc/pkcs15-pubkey.c
  • Loading branch information
dengert committed Aug 27, 2024
1 parent 47e2150 commit 8d046b6
Showing 1 changed file with 13 additions and 6 deletions.
19 changes: 13 additions & 6 deletions src/libopensc/pkcs15-pubkey.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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");
Expand All @@ -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.
*/
Expand All @@ -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);
}

Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 8d046b6

Please sign in to comment.