Skip to content

Commit 64f936d

Browse files
committed
[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>
1 parent e6610b7 commit 64f936d

3 files changed

Lines changed: 75 additions & 6 deletions

File tree

src/crypto/asn1.c

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,19 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
8383
#define EINFO_ENOTTY_ALGORITHM \
8484
__einfo_uniqify ( EINFO_ENOTTY, 0x01, "Inappropriate algorithm" )
8585

86+
/** "ecPublicKey" object identifier */
87+
static uint8_t oid_ecpublickey[] = { ASN1_OID_ECPUBLICKEY };
88+
89+
/** Generic elliptic curve container algorithm
90+
*
91+
* The actual curve to be used is identified via the algorithm
92+
* parameters, rather than the top-level OID.
93+
*/
94+
struct asn1_algorithm ecpubkey_algorithm __asn1_algorithm = {
95+
.name = "ecPublicKey",
96+
.oid = ASN1_CURSOR ( oid_ecpublickey ),
97+
};
98+
8699
/**
87100
* Start parsing ASN.1 object
88101
*
@@ -624,20 +637,66 @@ int asn1_signature_algorithm ( const struct asn1_cursor *cursor,
624637
return 0;
625638
}
626639

640+
/**
641+
* Parse ASN.1 OID-identified elliptic curve algorithm
642+
*
643+
* @v cursor ASN.1 object cursor
644+
* @ret algorithm Algorithm
645+
* @ret rc Return status code
646+
*/
647+
int asn1_curve_algorithm ( const struct asn1_cursor *cursor,
648+
struct asn1_algorithm **algorithm ) {
649+
struct asn1_cursor curve;
650+
651+
/* Elliptic curves are identified as either:
652+
*
653+
* - the algorithm "id-ecPublicKey" with the actual curve
654+
* specified in the algorithm parameters, or
655+
*
656+
* - a standalone object identifier for the curve
657+
*/
658+
if ( asn1_check_algorithm ( cursor, &ecpubkey_algorithm,
659+
&curve ) != 0 ) {
660+
memcpy ( &curve, cursor, sizeof ( curve ) );
661+
}
662+
663+
/* Identify curve */
664+
asn1_enter ( &curve, ASN1_OID );
665+
*algorithm = asn1_find_algorithm ( &curve );
666+
if ( ! *algorithm ) {
667+
DBGC ( cursor, "ASN1 %p unrecognised EC algorithm:\n",
668+
cursor );
669+
DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
670+
return -ENOTSUP_ALGORITHM;
671+
}
672+
673+
/* Check algorithm has an elliptic curve */
674+
if ( ! (*algorithm)->curve ) {
675+
DBGC ( cursor, "ASN1 %p algorithm %s is not an elliptic curve "
676+
"algorithm:\n", cursor, (*algorithm)->name );
677+
DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
678+
return -ENOTTY_ALGORITHM;
679+
}
680+
681+
return 0;
682+
}
683+
627684
/**
628685
* Check ASN.1 OID-identified algorithm
629686
*
630687
* @v cursor ASN.1 object cursor
631688
* @v expected Expected algorithm
689+
* @ret params Algorithm parameters, or NULL
632690
* @ret rc Return status code
633691
*/
634692
int asn1_check_algorithm ( const struct asn1_cursor *cursor,
635-
struct asn1_algorithm *expected ) {
693+
struct asn1_algorithm *expected,
694+
struct asn1_cursor *params ) {
636695
struct asn1_algorithm *actual;
637696
int rc;
638697

639698
/* Parse algorithm */
640-
if ( ( rc = asn1_algorithm ( cursor, &actual, NULL ) ) != 0 )
699+
if ( ( rc = asn1_algorithm ( cursor, &actual, params ) ) != 0 )
641700
return rc;
642701

643702
/* Check algorithm matches */

src/crypto/rsa.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,8 @@ static int rsa_parse_mod_exp ( struct asn1_cursor *modulus,
194194
asn1_skip_any ( &cursor );
195195

196196
/* Enter privateKey, if present */
197-
if ( asn1_check_algorithm ( &cursor,
198-
&rsa_encryption_algorithm ) == 0 ) {
197+
if ( asn1_check_algorithm ( &cursor, &rsa_encryption_algorithm,
198+
NULL ) == 0 ) {
199199

200200
/* Skip privateKeyAlgorithm */
201201
asn1_skip_any ( &cursor );

src/include/ipxe/asn1.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,15 @@ struct asn1_builder_header {
127127
#define ASN1_OID_TRIPLE( value ) \
128128
( 0x80 | ( ( (value) >> 14 ) & 0x7f ) ), ASN1_OID_DOUBLE ( (value) )
129129

130+
/** ASN.1 OID for ecPublicKey (1.2.840.10045.2.1) */
131+
#define ASN1_OID_ECPUBLICKEY \
132+
ASN1_OID_INITIAL ( 1, 2 ), ASN1_OID_DOUBLE ( 840 ), \
133+
ASN1_OID_DOUBLE ( 10045 ), ASN1_OID_SINGLE ( 2 ), \
134+
ASN1_OID_SINGLE ( 1 )
135+
130136
/** ASN.1 OID for prime256v1 (1.2.840.10045.3.1.7) */
131137
#define ASN1_OID_PRIME256V1 \
132-
ASN1_OID_INITIAL ( 1, 1 ), ASN1_OID_DOUBLE ( 840 ), \
138+
ASN1_OID_INITIAL ( 1, 2 ), ASN1_OID_DOUBLE ( 840 ), \
133139
ASN1_OID_DOUBLE ( 10045 ), ASN1_OID_SINGLE ( 3 ), \
134140
ASN1_OID_SINGLE ( 1 ), ASN1_OID_SINGLE ( 7 )
135141

@@ -426,6 +432,7 @@ extern struct asn1_algorithm oid_sha512_algorithm __asn1_algorithm;
426432
extern struct asn1_algorithm oid_sha224_algorithm __asn1_algorithm;
427433
extern struct asn1_algorithm oid_sha512_224_algorithm __asn1_algorithm;
428434
extern struct asn1_algorithm oid_sha512_256_algorithm __asn1_algorithm;
435+
extern struct asn1_algorithm ecpubkey_algorithm __asn1_algorithm;
429436

430437
/**
431438
* Invalidate ASN.1 object cursor
@@ -497,8 +504,11 @@ extern int asn1_cipher_algorithm ( const struct asn1_cursor *cursor,
497504
struct asn1_cursor *params );
498505
extern int asn1_signature_algorithm ( const struct asn1_cursor *cursor,
499506
struct asn1_algorithm **algorithm );
507+
extern int asn1_curve_algorithm ( const struct asn1_cursor *cursor,
508+
struct asn1_algorithm **algorithm );
500509
extern int asn1_check_algorithm ( const struct asn1_cursor *cursor,
501-
struct asn1_algorithm *expected );
510+
struct asn1_algorithm *expected,
511+
struct asn1_cursor *params );
502512
extern int asn1_parse_cbc ( struct asn1_algorithm *algorithm,
503513
struct asn1_cursor *params );
504514
extern int asn1_parse_gcm ( struct asn1_algorithm *algorithm,

0 commit comments

Comments
 (0)