Add EC support to x509write_pubkey

This commit is contained in:
Manuel Pégourié-Gonnard 2013-09-12 01:39:07 +02:00 committed by Paul Bakker
parent e1f821a6eb
commit 3837daec9e
6 changed files with 111 additions and 10 deletions

View file

@ -29,7 +29,7 @@
#include "asn1.h" #include "asn1.h"
#define ASN1_CHK_ADD(g, f) if( ( ret = f ) < 0 ) return( ret ); else g += ret #define ASN1_CHK_ADD(g, f) do { if( ( ret = f ) < 0 ) return( ret ); else g += ret; } while( 0 )
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {

View file

@ -133,6 +133,7 @@ ecp_keypair;
*/ */
#define POLARSSL_ECP_MAX_BITS 521 #define POLARSSL_ECP_MAX_BITS 521
#define POLARSSL_ECP_MAX_BYTES ( ( POLARSSL_ECP_MAX_BITS + 7 ) / 8 ) #define POLARSSL_ECP_MAX_BYTES ( ( POLARSSL_ECP_MAX_BITS + 7 ) / 8 )
#define POLARSSL_ECP_MAX_PT_LEN ( 2 * POLARSSL_ECP_MAX_BYTES + 1 )
/* /*
* Maximum window size (actually, NAF width) used for point multipliation. * Maximum window size (actually, NAF width) used for point multipliation.

View file

@ -370,8 +370,9 @@ int oid_get_attr_short_name( const asn1_buf *oid, const char **short_name );
*/ */
int oid_get_pk_alg( const asn1_buf *oid, pk_type_t *pk_alg ); int oid_get_pk_alg( const asn1_buf *oid, pk_type_t *pk_alg );
#if defined(POLARSSL_ECP_C)
/** /**
* \brief Translate ECParameters OID into an EC group identifier * \brief Translate NamedCurve OID into an EC group identifier
* *
* \param oid OID to use * \param oid OID to use
* \param grp_id place to store group id * \param grp_id place to store group id
@ -380,6 +381,19 @@ int oid_get_pk_alg( const asn1_buf *oid, pk_type_t *pk_alg );
*/ */
int oid_get_ec_grp( const asn1_buf *oid, ecp_group_id *grp_id ); int oid_get_ec_grp( const asn1_buf *oid, ecp_group_id *grp_id );
/**
* \brief Translate EC group identifier into NamedCurve OID
*
* \param grp_id EC group identifier
* \param oid place to store ASN.1 OID string pointer
* \param olen length of the OID
*
* \return 0 if successful, or POLARSSL_ERR_OID_NOT_FOUND
*/
int oid_get_oid_by_ec_grp( ecp_group_id grp_id,
const char **oid, size_t *olen );
#endif /* POLARSSL_ECP_C */
#if defined(POLARSSL_MD_C) #if defined(POLARSSL_MD_C)
/** /**
* \brief Translate SignatureAlgorithm OID into md_type and pk_type * \brief Translate SignatureAlgorithm OID into md_type and pk_type

View file

@ -369,6 +369,7 @@ static const oid_pk_alg_t oid_pk_alg[] =
FN_OID_TYPED_FROM_ASN1(oid_pk_alg_t, pk_alg, oid_pk_alg); FN_OID_TYPED_FROM_ASN1(oid_pk_alg_t, pk_alg, oid_pk_alg);
FN_OID_GET_ATTR1(oid_get_pk_alg, oid_pk_alg_t, pk_alg, pk_type_t, pk_alg); FN_OID_GET_ATTR1(oid_get_pk_alg, oid_pk_alg_t, pk_alg, pk_type_t, pk_alg);
#if defined(POLARSSL_ECP_C)
/* /*
* For namedCurve (RFC 5480) * For namedCurve (RFC 5480)
*/ */
@ -407,6 +408,8 @@ static const oid_ecp_grp_t oid_ecp_grp[] =
FN_OID_TYPED_FROM_ASN1(oid_ecp_grp_t, grp_id, oid_ecp_grp); FN_OID_TYPED_FROM_ASN1(oid_ecp_grp_t, grp_id, oid_ecp_grp);
FN_OID_GET_ATTR1(oid_get_ec_grp, oid_ecp_grp_t, grp_id, ecp_group_id, grp_id); FN_OID_GET_ATTR1(oid_get_ec_grp, oid_ecp_grp_t, grp_id, ecp_group_id, grp_id);
FN_OID_GET_OID_BY_ATTR1(oid_get_oid_by_ec_grp, oid_ecp_grp_t, oid_ecp_grp, ecp_group_id, grp_id);
#endif /* POLARSSL_ECP_C */
#if defined(POLARSSL_CIPHER_C) #if defined(POLARSSL_CIPHER_C)
/* /*

View file

@ -117,6 +117,7 @@ exit:
return( ret ); return( ret );
} }
#if defined(POLARSSL_RSA_C)
/* /*
* RSAPublicKey ::= SEQUENCE { * RSAPublicKey ::= SEQUENCE {
* modulus INTEGER, -- n * modulus INTEGER, -- n
@ -137,6 +138,56 @@ static int x509_write_rsa_pubkey( unsigned char **p, unsigned char *start,
return( len ); return( len );
} }
#endif /* POLARSSL_RSA_C */
#if defined(POLARSSL_ECP_C)
/*
* EC public key is an EC point
*/
static int x509_write_ec_pubkey( unsigned char **p, unsigned char *start,
ecp_keypair *ec )
{
int ret;
size_t len = 0;
unsigned char buf[POLARSSL_ECP_MAX_PT_LEN];
if( ( ret = ecp_point_write_binary( &ec->grp, &ec->Q,
POLARSSL_ECP_PF_UNCOMPRESSED,
&len, buf, sizeof( buf ) ) ) != 0 )
{
return( ret );
}
if( *p - start < (int) len )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
*p -= len;
memcpy( *p, buf, len );
return( len );
}
/*
* ECParameters ::= CHOICE {
* namedCurve OBJECT IDENTIFIER
* }
*/
static int x509_write_ec_algparam( unsigned char **p, unsigned char *start,
ecp_keypair *ec )
{
int ret;
size_t len = 0;
const char *oid;
size_t oid_len;
if( ( ret = oid_get_oid_by_ec_grp( ec->grp.id, &oid, &oid_len ) ) != 0 )
return( ret );
ASN1_CHK_ADD( len, asn1_write_oid( p, start, oid, oid_len ) );
return( len );
}
#endif /* POLARSSL_ECP_C */
void x509write_csr_init( x509write_csr *ctx ) void x509write_csr_init( x509write_csr *ctx )
{ {
@ -439,16 +490,20 @@ int x509write_pubkey_der( pk_context *key, unsigned char *buf, size_t size )
int ret; int ret;
unsigned char *c; unsigned char *c;
size_t len = 0; size_t len = 0;
rsa_context *rsa;
if( !pk_can_do( key, POLARSSL_PK_RSA ) )
return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
rsa = pk_rsa( *key );
c = buf + size; c = buf + size;
ASN1_CHK_ADD( len, x509_write_rsa_pubkey( &c, buf, rsa ) ); #if defined(POLARSSL_RSA_C)
if( pk_get_type( key ) == POLARSSL_PK_RSA )
ASN1_CHK_ADD( len, x509_write_rsa_pubkey( &c, buf, pk_rsa( *key ) ) );
else
#endif
#if defined(POLARSSL_ECP_C)
if( pk_get_type( key ) == POLARSSL_PK_ECKEY )
ASN1_CHK_ADD( len, x509_write_ec_pubkey( &c, buf, pk_ec( *key ) ) );
else
#endif
return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
if( c - buf < 1 ) if( c - buf < 1 )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
@ -464,8 +519,32 @@ int x509write_pubkey_der( pk_context *key, unsigned char *buf, size_t size )
ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) ); ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_BIT_STRING ) ); ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_BIT_STRING ) );
#if defined(POLARSSL_RSA_C)
if( pk_get_type( key ) == POLARSSL_PK_RSA )
ASN1_CHK_ADD( len, asn1_write_algorithm_identifier( &c, buf, ASN1_CHK_ADD( len, asn1_write_algorithm_identifier( &c, buf,
OID_PKCS1_RSA, OID_SIZE( OID_PKCS1_RSA ) ) ); OID_PKCS1_RSA, OID_SIZE( OID_PKCS1_RSA ) ) );
else
#endif
#if defined(POLARSSL_ECP_C)
if( pk_get_type( key ) == POLARSSL_PK_ECKEY )
{
size_t alg_len = 0;
ASN1_CHK_ADD( alg_len, x509_write_ec_algparam( &c, buf,
pk_ec( *key ) ) );
ASN1_CHK_ADD( alg_len, asn1_write_oid( &c, buf,
OID_EC_ALG_UNRESTRICTED, OID_SIZE( OID_EC_ALG_UNRESTRICTED ) ) );
ASN1_CHK_ADD( alg_len, asn1_write_len( &c, buf, alg_len ) );
ASN1_CHK_ADD( alg_len, asn1_write_tag( &c, buf,
ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
len += alg_len;
}
else
#endif
return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) ); ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );

View file

@ -33,3 +33,7 @@ x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1
Public key write check RSA Public key write check RSA
depends_on:POLARSSL_RSA_C:POLARSSL_BASE64_C depends_on:POLARSSL_RSA_C:POLARSSL_BASE64_C
x509_pubkey_check:"data_files/server1.pubkey" x509_pubkey_check:"data_files/server1.pubkey"
Public key write check EC
depends_on:POLARSSL_ECP_C:POLARSSL_BASE64_C
x509_pubkey_check:"data_files/ec_pub.pem"