[crypto] Allow for OID-identified elliptic curve algorithms

Elliptic curves in X.509 certificates are identified via the
id-ecPublicKey object identifier (1.2.840.10045.2.1), with the
specific elliptic curve identified via a second OID in the algorithm
parameters.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown
2025-11-27 16:39:52 +00:00
parent e6610b793a
commit 64f936d5df
3 changed files with 75 additions and 6 deletions

View File

@@ -83,6 +83,19 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define EINFO_ENOTTY_ALGORITHM \
__einfo_uniqify ( EINFO_ENOTTY, 0x01, "Inappropriate algorithm" )
/** "ecPublicKey" object identifier */
static uint8_t oid_ecpublickey[] = { ASN1_OID_ECPUBLICKEY };
/** Generic elliptic curve container algorithm
*
* The actual curve to be used is identified via the algorithm
* parameters, rather than the top-level OID.
*/
struct asn1_algorithm ecpubkey_algorithm __asn1_algorithm = {
.name = "ecPublicKey",
.oid = ASN1_CURSOR ( oid_ecpublickey ),
};
/**
* Start parsing ASN.1 object
*
@@ -624,20 +637,66 @@ int asn1_signature_algorithm ( const struct asn1_cursor *cursor,
return 0;
}
/**
* Parse ASN.1 OID-identified elliptic curve algorithm
*
* @v cursor ASN.1 object cursor
* @ret algorithm Algorithm
* @ret rc Return status code
*/
int asn1_curve_algorithm ( const struct asn1_cursor *cursor,
struct asn1_algorithm **algorithm ) {
struct asn1_cursor curve;
/* Elliptic curves are identified as either:
*
* - the algorithm "id-ecPublicKey" with the actual curve
* specified in the algorithm parameters, or
*
* - a standalone object identifier for the curve
*/
if ( asn1_check_algorithm ( cursor, &ecpubkey_algorithm,
&curve ) != 0 ) {
memcpy ( &curve, cursor, sizeof ( curve ) );
}
/* Identify curve */
asn1_enter ( &curve, ASN1_OID );
*algorithm = asn1_find_algorithm ( &curve );
if ( ! *algorithm ) {
DBGC ( cursor, "ASN1 %p unrecognised EC algorithm:\n",
cursor );
DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
return -ENOTSUP_ALGORITHM;
}
/* Check algorithm has an elliptic curve */
if ( ! (*algorithm)->curve ) {
DBGC ( cursor, "ASN1 %p algorithm %s is not an elliptic curve "
"algorithm:\n", cursor, (*algorithm)->name );
DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
return -ENOTTY_ALGORITHM;
}
return 0;
}
/**
* Check ASN.1 OID-identified algorithm
*
* @v cursor ASN.1 object cursor
* @v expected Expected algorithm
* @ret params Algorithm parameters, or NULL
* @ret rc Return status code
*/
int asn1_check_algorithm ( const struct asn1_cursor *cursor,
struct asn1_algorithm *expected ) {
struct asn1_algorithm *expected,
struct asn1_cursor *params ) {
struct asn1_algorithm *actual;
int rc;
/* Parse algorithm */
if ( ( rc = asn1_algorithm ( cursor, &actual, NULL ) ) != 0 )
if ( ( rc = asn1_algorithm ( cursor, &actual, params ) ) != 0 )
return rc;
/* Check algorithm matches */

View File

@@ -194,8 +194,8 @@ static int rsa_parse_mod_exp ( struct asn1_cursor *modulus,
asn1_skip_any ( &cursor );
/* Enter privateKey, if present */
if ( asn1_check_algorithm ( &cursor,
&rsa_encryption_algorithm ) == 0 ) {
if ( asn1_check_algorithm ( &cursor, &rsa_encryption_algorithm,
NULL ) == 0 ) {
/* Skip privateKeyAlgorithm */
asn1_skip_any ( &cursor );

View File

@@ -127,9 +127,15 @@ struct asn1_builder_header {
#define ASN1_OID_TRIPLE( value ) \
( 0x80 | ( ( (value) >> 14 ) & 0x7f ) ), ASN1_OID_DOUBLE ( (value) )
/** ASN.1 OID for ecPublicKey (1.2.840.10045.2.1) */
#define ASN1_OID_ECPUBLICKEY \
ASN1_OID_INITIAL ( 1, 2 ), ASN1_OID_DOUBLE ( 840 ), \
ASN1_OID_DOUBLE ( 10045 ), ASN1_OID_SINGLE ( 2 ), \
ASN1_OID_SINGLE ( 1 )
/** ASN.1 OID for prime256v1 (1.2.840.10045.3.1.7) */
#define ASN1_OID_PRIME256V1 \
ASN1_OID_INITIAL ( 1, 1 ), ASN1_OID_DOUBLE ( 840 ), \
ASN1_OID_INITIAL ( 1, 2 ), ASN1_OID_DOUBLE ( 840 ), \
ASN1_OID_DOUBLE ( 10045 ), ASN1_OID_SINGLE ( 3 ), \
ASN1_OID_SINGLE ( 1 ), ASN1_OID_SINGLE ( 7 )
@@ -426,6 +432,7 @@ extern struct asn1_algorithm oid_sha512_algorithm __asn1_algorithm;
extern struct asn1_algorithm oid_sha224_algorithm __asn1_algorithm;
extern struct asn1_algorithm oid_sha512_224_algorithm __asn1_algorithm;
extern struct asn1_algorithm oid_sha512_256_algorithm __asn1_algorithm;
extern struct asn1_algorithm ecpubkey_algorithm __asn1_algorithm;
/**
* Invalidate ASN.1 object cursor
@@ -497,8 +504,11 @@ extern int asn1_cipher_algorithm ( const struct asn1_cursor *cursor,
struct asn1_cursor *params );
extern int asn1_signature_algorithm ( const struct asn1_cursor *cursor,
struct asn1_algorithm **algorithm );
extern int asn1_curve_algorithm ( const struct asn1_cursor *cursor,
struct asn1_algorithm **algorithm );
extern int asn1_check_algorithm ( const struct asn1_cursor *cursor,
struct asn1_algorithm *expected );
struct asn1_algorithm *expected,
struct asn1_cursor *params );
extern int asn1_parse_cbc ( struct asn1_algorithm *algorithm,
struct asn1_cursor *params );
extern int asn1_parse_gcm ( struct asn1_algorithm *algorithm,