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:
Manuel Pégourié-Gonnard 2013-07-01 19:45:45 +02:00
parent f838eeda09
commit 73c0cda346
3 changed files with 95 additions and 22 deletions

View file

@ -233,6 +233,40 @@ static int x509_get_ecparams( unsigned char **p, const unsigned char *end,
return( 0 ); 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 { * AttributeTypeAndValue ::= SEQUENCE {
* type AttributeType, * type AttributeType,
@ -2633,6 +2667,59 @@ int x509parse_key_ec( ecp_keypair *eckey,
return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT ); 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, &params_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 * Parse a public EC key
*/ */
@ -2640,14 +2727,12 @@ int x509parse_public_key_ec( ecp_keypair *eckey,
const unsigned char *key, size_t keylen ) const unsigned char *key, size_t keylen )
{ {
int ret; int ret;
size_t len;
unsigned char *p, *end;
x509_buf alg_oid;
#if defined(POLARSSL_PEM_C) #if defined(POLARSSL_PEM_C)
size_t len;
pem_context pem; pem_context pem;
pem_init( &pem ); pem_init( &pem );
ret = pem_read_buffer( &pem, /* TODO: check header */ ret = pem_read_buffer( &pem,
"-----BEGIN PUBLIC KEY-----", "-----BEGIN PUBLIC KEY-----",
"-----END PUBLIC KEY-----", "-----END PUBLIC KEY-----",
key, NULL, 0, &len ); key, NULL, 0, &len );
@ -2657,6 +2742,7 @@ int x509parse_public_key_ec( ecp_keypair *eckey,
/* /*
* Was PEM encoded * Was PEM encoded
*/ */
key = pem.buf;
keylen = pem.buflen; keylen = pem.buflen;
} }
else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) 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 ); pem_free( &pem );
return( ret ); return( ret );
} }
p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
#else
p = (unsigned char *) key;
#endif #endif
end = p + keylen;
/* TODO: parse key */ if( ( ret = x509parse_public_key_ec_der ( eckey, key, keylen ) ) != 0 ||
(void) alg_oid; ( ret = ecp_check_pubkey( &eckey->grp, &eckey->Q ) ) != 0 )
(void) end;
(void) eckey;
if( ( ret = ecp_check_pubkey( &eckey->grp, &eckey->Q ) ) != 0 )
{ {
#if defined(POLARSSL_PEM_C)
pem_free( &pem );
#endif
ecp_keypair_free( eckey ); ecp_keypair_free( eckey );
return( ret );
} }
#if defined(POLARSSL_PEM_C) #if defined(POLARSSL_PEM_C)
pem_free( &pem ); pem_free( &pem );
#endif #endif
return( 0 ); return( ret );
} }
#endif /* defined(POLARSSL_ECP_C) */ #endif /* defined(POLARSSL_ECP_C) */

Binary file not shown.

View file

@ -1,4 +1,4 @@
-----BEGIN PUBLIC KEY----- -----BEGIN PUBLIC KEY-----
ME4wEAYHKoZIzj0CAQYFK4EEACEDOgAEb3GKqedAJ2/1CRdhjIRhQO+4erL49GlI MEkwEwYHKoZIzj0CAQYIKoZIzj0DAQEDMgAEvHl9s65/COw9SWtPtBGz9iClWKUB
QrBg7frKWrc6ZrnjgXgdHt68Tux/2IyRuff+lvGn32s= 4CItCM/g3Irsixp78kvpKVHMW6G+uyR0kJrg
-----END PUBLIC KEY----- -----END PUBLIC KEY-----