diff --git a/include/polarssl/asn1write.h b/include/polarssl/asn1write.h index 1eb7e69ed..d7f7b521a 100644 --- a/include/polarssl/asn1write.h +++ b/include/polarssl/asn1write.h @@ -115,17 +115,19 @@ int asn1_write_oid( unsigned char **p, unsigned char *start, /** * \brief Write an AlgorithmIdentifier sequence in ASN.1 format * Note: function works backwards in data buffer - * Note: Uses NULL as algorithm parameter * * \param p reference to current position pointer * \param start start of the buffer (for bounds-checking) * \param oid the OID of the algorithm * \param oid_len length of the OID + * \param par_len length of parameters, which must be already written. + * If 0, NULL parameters are added * * \return the length written or a negative error code */ int asn1_write_algorithm_identifier( unsigned char **p, unsigned char *start, - const char *oid, size_t oid_len ); + const char *oid, size_t oid_len, + size_t par_len ); /** * \brief Write a boolean tag (ASN1_BOOLEAN) and value in ASN.1 format diff --git a/include/polarssl/oid.h b/include/polarssl/oid.h index 6981237f7..ba0ce7d39 100644 --- a/include/polarssl/oid.h +++ b/include/polarssl/oid.h @@ -370,6 +370,18 @@ 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 ); +/** + * \brief Translate pk_type into PublicKeyAlgorithm OID + * + * \param pk_alg Public key type to look for + * \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_pk_alg( pk_type_t pk_alg, + const char **oid, size_t *olen ); + #if defined(POLARSSL_ECP_C) /** * \brief Translate NamedCurve OID into an EC group identifier @@ -382,9 +394,9 @@ 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 ); /** - * \brief Translate EC group identifier into NamedCurve OID + * \brief Translate EC group identifier into NamedCurve OID * - * \param grp_id EC group identifier + * \param grp_id EC group identifier * \param oid place to store ASN.1 OID string pointer * \param olen length of the OID * diff --git a/library/asn1write.c b/library/asn1write.c index f720a8067..d4c1d8d02 100644 --- a/library/asn1write.c +++ b/library/asn1write.c @@ -158,17 +158,17 @@ int asn1_write_oid( unsigned char **p, unsigned char *start, } int asn1_write_algorithm_identifier( unsigned char **p, unsigned char *start, - const char *oid, size_t oid_len ) + const char *oid, size_t oid_len, + size_t par_len ) { int ret; size_t len = 0; - // Write NULL - // - ASN1_CHK_ADD( len, asn1_write_null( p, start ) ); + if( par_len == 0 ) + ASN1_CHK_ADD( len, asn1_write_null( p, start ) ); + else + len += par_len; - // Write OID - // ASN1_CHK_ADD( len, asn1_write_oid( p, start, oid, oid_len ) ); ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); diff --git a/library/oid.c b/library/oid.c index 1aaf8e887..81b313e33 100644 --- a/library/oid.c +++ b/library/oid.c @@ -368,6 +368,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_GET_ATTR1(oid_get_pk_alg, oid_pk_alg_t, pk_alg, pk_type_t, pk_alg); +FN_OID_GET_OID_BY_ATTR1(oid_get_oid_by_pk_alg, oid_pk_alg_t, oid_pk_alg, pk_type_t, pk_alg); #if defined(POLARSSL_ECP_C) /* diff --git a/library/x509write.c b/library/x509write.c index 6be1bc48e..4eaeb5106 100644 --- a/library/x509write.c +++ b/library/x509write.c @@ -172,8 +172,8 @@ static int x509_write_ec_pubkey( unsigned char **p, unsigned char *start, * namedCurve OBJECT IDENTIFIER * } */ -static int x509_write_ec_algparam( unsigned char **p, unsigned char *start, - ecp_keypair *ec ) +static int x509_write_ec_param( unsigned char **p, unsigned char *start, + ecp_keypair *ec ) { int ret; size_t len = 0; @@ -489,7 +489,8 @@ int x509write_pubkey_der( pk_context *key, unsigned char *buf, size_t size ) { int ret; unsigned char *c; - size_t len = 0; + size_t len = 0, par_len = 0, oid_len; + const char *oid; c = buf + size; @@ -519,32 +520,21 @@ 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_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, - OID_PKCS1_RSA, OID_SIZE( OID_PKCS1_RSA ) ) ); - else -#endif + if( ( ret = oid_get_oid_by_pk_alg( pk_get_type( key ), + &oid, &oid_len ) ) != 0 ) + { + return( ret ); + } + #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; + ASN1_CHK_ADD( par_len, x509_write_ec_param( &c, buf, pk_ec( *key ) ) ); } - else #endif - return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE ); + + ASN1_CHK_ADD( len, asn1_write_algorithm_identifier( &c, buf, oid, oid_len, + par_len ) ); ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) ); ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); @@ -689,7 +679,7 @@ static int x509_write_sig( unsigned char **p, unsigned char *start, // Write OID // ASN1_CHK_ADD( len, asn1_write_algorithm_identifier( p, start, oid, - oid_len ) ); + oid_len, 0 ) ); return( len ); } @@ -937,7 +927,7 @@ int x509write_crt_der( x509write_cert *ctx, unsigned char *buf, size_t size ) * Signature ::= AlgorithmIdentifier */ ASN1_CHK_ADD( len, asn1_write_algorithm_identifier( &c, tmp_buf, - sig_oid, strlen( sig_oid ) ) ); + sig_oid, strlen( sig_oid ), 0 ) ); /* * Serial ::= INTEGER