diff --git a/include/polarssl/pk.h b/include/polarssl/pk.h index 707f138d4..4e52a75d2 100644 --- a/include/polarssl/pk.h +++ b/include/polarssl/pk.h @@ -27,6 +27,12 @@ #ifndef POLARSSL_PK_H #define POLARSSL_PK_H +#include "config.h" + +#if defined(POLARSSL_RSA_C) +#include "rsa.h" +#endif + #define POLARSSL_ERR_PK_MALLOC_FAILED -0x2F80 /**< Memory alloation failed. */ #define POLARSSL_ERR_PK_TYPE_MISMATCH -0x2F00 /**< Type mismatch, eg attempt to use a RSA key as EC, or to modify key type */ @@ -53,8 +59,9 @@ typedef enum { */ typedef struct { - pk_type_t type; /**< Public key type */ - void * data; /**< Public key data */ + pk_type_t type; /**< Public key type */ + void * data; /**< Public key data */ + int dont_free; /**< True if data must not be freed */ } pk_context; /** @@ -82,6 +89,21 @@ void pk_free( pk_context *ctx ); */ int pk_set_type( pk_context *ctx, pk_type_t type ); +#if defined(POLARSSL_RSA_C) +/** + * \brief Wrap a RSA context in a PK context + * + * \param ctx PK context to initiliaze + * \param rsa RSA context to use + * + * \note The PK context must be freshly initialized. + * + * \return O on success, + * POLARSSL_ERR_PK_TYPE_MISMATCH if ctx was not empty. + */ +int pk_wrap_rsa( pk_context *ctx, const rsa_context *rsa); +#endif + #ifdef __cplusplus } #endif diff --git a/library/pk.c b/library/pk.c index 0591b3f1c..6762c75bb 100644 --- a/library/pk.c +++ b/library/pk.c @@ -46,6 +46,7 @@ void pk_init( pk_context *ctx ) ctx->type = POLARSSL_PK_NONE; ctx->data = NULL; + ctx->dont_free = 0; } /* @@ -75,7 +76,8 @@ void pk_free( pk_context *ctx ) #endif } - free( ctx-> data ); + if( ! ctx->dont_free ) + free( ctx->data ); ctx->type = POLARSSL_PK_NONE; ctx->data = NULL; @@ -121,3 +123,20 @@ int pk_set_type( pk_context *ctx, pk_type_t type ) return( 0 ); } + +#if defined(POLARSSL_RSA_C) +/* + * Wrap an RSA context in a PK context + */ +int pk_wrap_rsa( pk_context *ctx, const rsa_context *rsa) +{ + if( ctx->type != POLARSSL_PK_NONE ) + return( POLARSSL_ERR_PK_TYPE_MISMATCH ); + + ctx->type = POLARSSL_PK_RSA; + ctx->data = (rsa_context *) rsa; + ctx->dont_free = 1; + + return( 0 ); +} +#endif diff --git a/library/x509parse.c b/library/x509parse.c index 605e40c42..9e05f98cb 100644 --- a/library/x509parse.c +++ b/library/x509parse.c @@ -660,56 +660,18 @@ static int x509_get_pubkey( unsigned char **p, } /* - * SubjectPublicKeyInfo ::= SEQUENCE { - * algorithm AlgorithmIdentifier, - * subjectPublicKey BIT STRING } + * Get an RSA public key (compatibility wrapper) */ static int x509_get_pubkey_rsa( unsigned char **p, const unsigned char *end, rsa_context *rsa ) { - int ret; - size_t len; - x509_buf pk_alg_oid; - pk_type_t pk_alg = POLARSSL_PK_NONE; + pk_context pk_ctx; - if( ( ret = asn1_get_tag( p, end, &len, - ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) - { - return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret ); - } + pk_init( &pk_ctx ); + pk_wrap_rsa( &pk_ctx, rsa ); - end = *p + len; - - if( ( ret = asn1_get_alg_null( p, end, &pk_alg_oid ) ) != 0 ) - return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret ); - - /* - * only RSA public keys handled at this time - */ - if( oid_get_pk_alg( &pk_alg_oid, &pk_alg ) != 0 ) - { - return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG ); - } - - if (pk_alg != POLARSSL_PK_RSA ) - return( POLARSSL_ERR_X509_CERT_INVALID_ALG ); - - if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 ) - return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret ); - - if( ( end - *p ) < 1 ) - return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + - POLARSSL_ERR_ASN1_OUT_OF_DATA ); - - if( *p + len != end ) - return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + - POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); - - if( *(*p)++ != 0 ) - return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY ); - - return( x509_get_rsapubkey( p, end, rsa ) ); + return( x509_get_pubkey( p, end, &pk_ctx ) ); } static int x509_get_sig( unsigned char **p, @@ -2675,51 +2637,12 @@ int x509parse_key_rsa( rsa_context *rsa, int x509parse_public_key_rsa( rsa_context *rsa, const unsigned char *key, size_t keylen ) { - int ret; - size_t len; - unsigned char *p, *end; -#if defined(POLARSSL_PEM_C) - pem_context pem; + pk_context pk_ctx; - pem_init( &pem ); - ret = pem_read_buffer( &pem, - "-----BEGIN PUBLIC KEY-----", - "-----END PUBLIC KEY-----", - key, NULL, 0, &len ); + pk_init( &pk_ctx ); + pk_wrap_rsa( &pk_ctx, rsa ); - if( ret == 0 ) - { - /* - * Was PEM encoded - */ - keylen = pem.buflen; - } - else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) - { - pem_free( &pem ); - return( ret ); - } - - p = ( ret == 0 ) ? pem.buf : (unsigned char *) key; -#else - p = (unsigned char *) key; -#endif - end = p + keylen; - - if( ( ret = x509_get_pubkey_rsa( &p, end, rsa ) ) != 0 ) - { -#if defined(POLARSSL_PEM_C) - pem_free( &pem ); -#endif - rsa_free( rsa ); - return( ret ); - } - -#if defined(POLARSSL_PEM_C) - pem_free( &pem ); -#endif - - return( 0 ); + return( x509parse_public_key( &pk_ctx, key, keylen ) ); } #if defined(POLARSSL_ECP_C) diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data index def0021d4..0f95e1027 100644 --- a/tests/suites/test_suite_x509parse.data +++ b/tests/suites/test_suite_x509parse.data @@ -511,7 +511,7 @@ X509 Certificate ASN1 (TBSCertificate, valid subject, no pubkeyinfo) x509parse_crt:"30563054a0030201028204deadbeef300d06092a864886f70d0101020500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374":"":POLARSSL_ERR_X509_CERT_INVALID_FORMAT + POLARSSL_ERR_ASN1_OUT_OF_DATA X509 Certificate ASN1 (TBSCertificate, pubkey, no alg) -x509parse_crt:"30583056a0030201028204deadbeef300d06092a864886f70d0101020500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a300806001304546573743000":"":POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + POLARSSL_ERR_ASN1_OUT_OF_DATA +x509parse_crt:"30583056a0030201028204deadbeef300d06092a864886f70d0101020500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a300806001304546573743000":"":POLARSSL_ERR_X509_CERT_INVALID_ALG + POLARSSL_ERR_ASN1_OUT_OF_DATA X509 Certificate ASN1 (TBSCertificate, valid subject, unknown pk alg) x509parse_crt:"30673065a0030201028204deadbeef300d06092a864886f70d0101020500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374300f300d06092A864886F70D0101000500":"":POLARSSL_ERR_X509_UNKNOWN_PK_ALG