Complete x509parse_public_key_ec()
Warning: due to a bug in oid_descriptor_from_buf(), keys associated to some curves (secp224r1, secp384r1, secp521r1) are incorrectly rejected, since their namedCurve OID contains a nul byte.
This commit is contained in:
parent
f838eeda09
commit
73c0cda346
3 changed files with 95 additions and 22 deletions
|
@ -233,6 +233,40 @@ static int x509_get_ecparams( unsigned char **p, const unsigned char *end,
|
|||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* subjectPublicKey BIT STRING
|
||||
* -- which, in our case, contains
|
||||
* ECPoint ::= octet string (not ASN.1)
|
||||
*/
|
||||
static int x509_get_subpubkey_ec( unsigned char **p, const unsigned char *end,
|
||||
const ecp_group *grp, ecp_point *pt )
|
||||
{
|
||||
int ret;
|
||||
size_t len;
|
||||
|
||||
if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
|
||||
return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
|
||||
|
||||
if( *p + len != end )
|
||||
return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
|
||||
POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
|
||||
|
||||
/*
|
||||
* First byte in the content of BIT STRING is the nummber of padding bit.
|
||||
* Here it is always 0 since ECPoint is an octet string, so skip it.
|
||||
*/
|
||||
++*p;
|
||||
--len;
|
||||
|
||||
if( ( ret = ecp_point_read_binary( grp, pt,
|
||||
(const unsigned char *) *p, len ) ) != 0 )
|
||||
{
|
||||
return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* AttributeTypeAndValue ::= SEQUENCE {
|
||||
* type AttributeType,
|
||||
|
@ -2633,6 +2667,59 @@ int x509parse_key_ec( ecp_keypair *eckey,
|
|||
return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a public EC key in RFC 5480 format, der-encoded
|
||||
*/
|
||||
static int x509parse_public_key_ec_der( ecp_keypair *key,
|
||||
const unsigned char *buf, size_t len )
|
||||
{
|
||||
int ret;
|
||||
ecp_group_id grp_id;
|
||||
x509_buf alg_oid;
|
||||
pk_type_t alg = POLARSSL_PK_NONE;
|
||||
unsigned char *p = (unsigned char *) buf;
|
||||
unsigned char *end = p + len;
|
||||
const unsigned char *params_end;
|
||||
/*
|
||||
* SubjectPublicKeyInfo ::= SEQUENCE {
|
||||
* algorithm AlgorithmIdentifier,
|
||||
* subjectPublicKey BIT STRING
|
||||
* }
|
||||
* -- algorithm parameters are ECParameters
|
||||
* -- subjectPublicKey is an ECPoint
|
||||
*/
|
||||
if( ( ret = asn1_get_tag( &p, end, &len,
|
||||
ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
|
||||
{
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
|
||||
}
|
||||
|
||||
if( ( ret = x509_get_alg( &p, end, &alg_oid, ¶ms_end ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( oid_get_pk_alg( &alg_oid, &alg ) != 0 )
|
||||
return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
|
||||
|
||||
if( alg != POLARSSL_PK_ECKEY && alg != POLARSSL_PK_ECKEY_DH )
|
||||
return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
|
||||
|
||||
if ( alg == POLARSSL_PK_ECKEY_DH )
|
||||
key->alg = POLARSSL_ECP_KEY_ALG_ECDH;
|
||||
|
||||
if( ( ret = x509_get_ecparams( &p, params_end, &grp_id ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( ( ret = ecp_use_known_dp( &key->grp, grp_id ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( ( ret = x509_get_subpubkey_ec( &p, end, &key->grp, &key->Q ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a public EC key
|
||||
*/
|
||||
|
@ -2640,14 +2727,12 @@ int x509parse_public_key_ec( ecp_keypair *eckey,
|
|||
const unsigned char *key, size_t keylen )
|
||||
{
|
||||
int ret;
|
||||
size_t len;
|
||||
unsigned char *p, *end;
|
||||
x509_buf alg_oid;
|
||||
#if defined(POLARSSL_PEM_C)
|
||||
size_t len;
|
||||
pem_context pem;
|
||||
|
||||
pem_init( &pem );
|
||||
ret = pem_read_buffer( &pem, /* TODO: check header */
|
||||
ret = pem_read_buffer( &pem,
|
||||
"-----BEGIN PUBLIC KEY-----",
|
||||
"-----END PUBLIC KEY-----",
|
||||
key, NULL, 0, &len );
|
||||
|
@ -2657,6 +2742,7 @@ int x509parse_public_key_ec( ecp_keypair *eckey,
|
|||
/*
|
||||
* Was PEM encoded
|
||||
*/
|
||||
key = pem.buf;
|
||||
keylen = pem.buflen;
|
||||
}
|
||||
else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
|
||||
|
@ -2664,32 +2750,19 @@ int x509parse_public_key_ec( ecp_keypair *eckey,
|
|||
pem_free( &pem );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
|
||||
#else
|
||||
p = (unsigned char *) key;
|
||||
#endif
|
||||
end = p + keylen;
|
||||
|
||||
/* TODO: parse key */
|
||||
(void) alg_oid;
|
||||
(void) end;
|
||||
(void) eckey;
|
||||
|
||||
if( ( ret = ecp_check_pubkey( &eckey->grp, &eckey->Q ) ) != 0 )
|
||||
if( ( ret = x509parse_public_key_ec_der ( eckey, key, keylen ) ) != 0 ||
|
||||
( ret = ecp_check_pubkey( &eckey->grp, &eckey->Q ) ) != 0 )
|
||||
{
|
||||
#if defined(POLARSSL_PEM_C)
|
||||
pem_free( &pem );
|
||||
#endif
|
||||
ecp_keypair_free( eckey );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_PEM_C)
|
||||
pem_free( &pem );
|
||||
#endif
|
||||
|
||||
return( 0 );
|
||||
return( ret );
|
||||
}
|
||||
#endif /* defined(POLARSSL_ECP_C) */
|
||||
|
||||
|
|
Binary file not shown.
|
@ -1,4 +1,4 @@
|
|||
-----BEGIN PUBLIC KEY-----
|
||||
ME4wEAYHKoZIzj0CAQYFK4EEACEDOgAEb3GKqedAJ2/1CRdhjIRhQO+4erL49GlI
|
||||
QrBg7frKWrc6ZrnjgXgdHt68Tux/2IyRuff+lvGn32s=
|
||||
MEkwEwYHKoZIzj0CAQYIKoZIzj0DAQEDMgAEvHl9s65/COw9SWtPtBGz9iClWKUB
|
||||
4CItCM/g3Irsixp78kvpKVHMW6G+uyR0kJrg
|
||||
-----END PUBLIC KEY-----
|
||||
|
|
Loading…
Reference in a new issue