diff --git a/include/polarssl/asn1.h b/include/polarssl/asn1.h index ae498d0cd..195ebcb84 100644 --- a/include/polarssl/asn1.h +++ b/include/polarssl/asn1.h @@ -212,6 +212,19 @@ int asn1_get_int( unsigned char **p, int asn1_get_bitstring( unsigned char **p, const unsigned char *end, asn1_bitstring *bs); +/** + * Retrieve a bitstring ASN.1 tag without unused bits and its value. + * Updates the pointer to the beginning of the bit/octet string. + * + * \param p The position in the ASN.1 data + * \param end End of data + * \param len Length of the actual bit/octect string in bytes + * + * \return 0 if successful or a specific ASN.1 error code. + */ +int asn1_get_bitstring_null( unsigned char **p, const unsigned char *end, + size_t *len ); + /** * Parses and splits an ASN.1 "SEQUENCE OF " * Updated the pointer to immediately behind the full sequence tag. diff --git a/include/polarssl/ecp.h b/include/polarssl/ecp.h index c1f08c9f7..7bd9bd587 100644 --- a/include/polarssl/ecp.h +++ b/include/polarssl/ecp.h @@ -95,18 +95,12 @@ ecp_group; * \brief ECP key pair structure * * A generic key pair that could be used for ECDSA, fixed ECDH, etc. - * Usage can be restricted to a particular algorithm by the 'alg' field, - * see POLARSSL_ECP_KEY_ALG_* constants (default: unrestricted). - * - * \sa ecdh_context - * \sa ecdsa_context */ typedef struct { ecp_group grp; /*!< Elliptic curve and base point */ mpi d; /*!< our secret value */ ecp_point Q; /*!< our public value */ - int alg; /*!< algorithm to use this key with */ } ecp_keypair; @@ -121,8 +115,10 @@ ecp_keypair; * parameters. Therefore, only well-known domain parameters from trusted * sources should be used. See ecp_use_known_dp(). * - * \note The values are taken from RFC 4492's enum NamedCurve. + * \note The values are taken from RFC 4492's enum NamedCurve, + * except NONE which is used to denote uninitialized groups. */ +#define POLARSSL_ECP_DP_NONE 0 #define POLARSSL_ECP_DP_SECP192R1 19 #define POLARSSL_ECP_DP_SECP224R1 21 #define POLARSSL_ECP_DP_SECP256R1 23 @@ -158,12 +154,6 @@ ecp_keypair; */ #define POLARSSL_ECP_TLS_NAMED_CURVE 3 /**< ECCurveType's named_curve */ -/* - * Algorithm identifiers from RFC 5480 for use with EC keys - */ -#define POLARSSL_ECP_KEY_ALG_UNRESTRICTED 0 /**< RFC 5480 2.1.1 */ -#define POLARSSL_ECP_KEY_ALG_ECDH 1 /**< RFC 5480 2.1.2 */ - #ifdef __cplusplus extern "C" { #endif diff --git a/include/polarssl/oid.h b/include/polarssl/oid.h index a39055b06..0c3dab216 100644 --- a/include/polarssl/oid.h +++ b/include/polarssl/oid.h @@ -276,6 +276,36 @@ * iso(1) identified-organization(3) certicom(132) curve(0) 35 } */ #define OID_EC_GRP_SECP521R1 OID_CERTICOM "\x00\x23" +/* + * ECDSA signature identifers, from RFC 5480 + */ +#define OID_ANSI_X9_62_SIG OID_ANSI_X9_62 "\x04" /* signatures(4) */ +#define OID_ANSI_X9_62_SIG_SHA2 OID_ANSI_X9_62_SIG "\x03" /* ecdsa-with-SHA2(3) */ + +/* ecdsa-with-SHA1 OBJECT IDENTIFIER ::= { + * iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4) 1 } */ +#define OID_ECDSA_SHA1 OID_ANSI_X9_62_SIG "\x01" + +/* ecdsa-with-SHA224 OBJECT IDENTIFIER ::= { + * iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4) + * ecdsa-with-SHA2(3) 1 } */ +#define OID_ECDSA_SHA224 OID_ANSI_X9_62_SIG_SHA2 "\x01" + +/* ecdsa-with-SHA256 OBJECT IDENTIFIER ::= { + * iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4) + * ecdsa-with-SHA2(3) 2 } */ +#define OID_ECDSA_SHA256 OID_ANSI_X9_62_SIG_SHA2 "\x02" + +/* ecdsa-with-SHA384 OBJECT IDENTIFIER ::= { + * iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4) + * ecdsa-with-SHA2(3) 3 } */ +#define OID_ECDSA_SHA384 OID_ANSI_X9_62_SIG_SHA2 "\x03" + +/* ecdsa-with-SHA512 OBJECT IDENTIFIER ::= { + * iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4) + * ecdsa-with-SHA2(3) 4 } */ +#define OID_ECDSA_SHA512 OID_ANSI_X9_62_SIG_SHA2 "\x04" + #ifdef __cplusplus extern "C" { #endif diff --git a/include/polarssl/pk.h b/include/polarssl/pk.h index 00f8cfcb1..df3fc44de 100644 --- a/include/polarssl/pk.h +++ b/include/polarssl/pk.h @@ -27,7 +27,35 @@ #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 */ + +#if defined(POLARSSL_RSA_C) +/** + * Quick access to an RSA context inside a PK context. + * + * \warning You must make sure the PK context actually holds an RSA context + * before using this macro! + */ +#define pk_rsa( pk ) ( (rsa_context *) (pk).data ) +#endif /* POLARSSL_RSA_C */ + +#if defined(POLARSSL_ECP_C) +/** + * Quick access to an EC context inside a PK context. + * + * \warning You must make sure the PK context actually holds an EC context + * before using this macro! + */ +#define pk_ec( pk ) ( (ecp_keypair *) (pk).data ) +#endif /* POLARSSL_ECP_C */ + #ifdef __cplusplus extern "C" { @@ -38,13 +66,10 @@ extern "C" { */ typedef enum { POLARSSL_PK_NONE=0, -#if defined(POLARSSL_RSA_C) POLARSSL_PK_RSA, -#endif -#if defined(POLARSSL_ECP_C) POLARSSL_PK_ECKEY, POLARSSL_PK_ECKEY_DH, -#endif + POLARSSL_PK_ECDSA, } pk_type_t; /** @@ -52,8 +77,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; /** @@ -72,10 +98,30 @@ void pk_free( pk_context *ctx ); * \param ctx Context to initialize * \param type Type of key * - * \return O on success, or POLARSSL_ERR_PK_MALLOC_FAILED + * \note Once the type of a key has been set, it cannot be reset. + * If you want to do so, you need to use pk_free() first. + * + * \return O on success, + * POLARSSL_ERR_PK_MALLOC_FAILED on memory allocation fail, + * POLARSSL_ERR_PK_TYPE_MISMATCH on attempts to reset type. */ 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 /* POLARSSL_RSA_C */ + #ifdef __cplusplus } #endif diff --git a/include/polarssl/x509.h b/include/polarssl/x509.h index f0c0e7aac..331553527 100644 --- a/include/polarssl/x509.h +++ b/include/polarssl/x509.h @@ -211,8 +211,7 @@ typedef struct _x509_cert x509_time valid_from; /**< Start time of certificate validity. */ x509_time valid_to; /**< End time of certificate validity. */ - x509_buf pk_oid; /**< Subject public key info. Includes the public key algorithm and the key itself. */ - rsa_context rsa; /**< Container for the RSA context. Only RSA is supported for public keys at this time. */ + pk_context pk; /**< Container for the public key context. */ x509_buf issuer_id; /**< Optional X.509 v2/v3 issuer unique identifier. */ x509_buf subject_id; /**< Optional X.509 v2/v3 subject unique identifier. */ @@ -417,6 +416,7 @@ int x509parse_crl( x509_crl *chain, const unsigned char *buf, size_t buflen ); */ int x509parse_crlfile( x509_crl *chain, const char *path ); +#if defined(POLARSSL_RSA_C) /** \ingroup x509_module */ /** * \brief Parse a private RSA key @@ -469,6 +469,7 @@ int x509parse_public_key_rsa( rsa_context *rsa, * \return 0 if successful, or a specific X509 or PEM error code */ int x509parse_public_keyfile_rsa( rsa_context *rsa, const char *path ); +#endif /* POLARSSL_RSA_C */ /** \ingroup x509_module */ /** diff --git a/library/asn1parse.c b/library/asn1parse.c index 5b86aa60e..f6b79efd7 100644 --- a/library/asn1parse.c +++ b/library/asn1parse.c @@ -209,6 +209,24 @@ int asn1_get_bitstring( unsigned char **p, const unsigned char *end, return 0; } +/* + * Get a bit string without unused bits + */ +int asn1_get_bitstring_null( unsigned char **p, const unsigned char *end, + size_t *len ) +{ + int ret; + + if( ( ret = asn1_get_tag( p, end, len, ASN1_BIT_STRING ) ) != 0 ) + return( ret ); + + if( --*len < 1 || *(*p)++ != 0 ) + return( POLARSSL_ERR_ASN1_INVALID_DATA ); + + return( 0 ); +} + + /* * Parses and splits an ASN.1 "SEQUENCE OF " diff --git a/library/debug.c b/library/debug.c index 23b901996..8e3dd03a9 100644 --- a/library/debug.c +++ b/library/debug.c @@ -250,11 +250,25 @@ void debug_print_crt( const ssl_context *ssl, int level, str[maxlen] = '\0'; ssl->f_dbg( ssl->p_dbg, level, str ); - debug_print_mpi( ssl, level, file, line, - "crt->rsa.N", &crt->rsa.N ); - - debug_print_mpi( ssl, level, file, line, - "crt->rsa.E", &crt->rsa.E ); +#if defined(POLARSSL_RSA_C) + if( crt->pk.type == POLARSSL_PK_RSA ) + { + debug_print_mpi( ssl, level, file, line, + "crt->rsa.N", &pk_rsa( crt->pk )->N ); + debug_print_mpi( ssl, level, file, line, + "crt->rsa.E", &pk_rsa( crt->pk )->E ); + } else +#endif /* POLARSSL_RSA_C */ +#if defined(POLARSSL_ECP_C) + if( crt->pk.type == POLARSSL_PK_ECKEY || + crt->pk.type == POLARSSL_PK_ECKEY_DH ) + { + debug_print_ecp( ssl, level, file, line, + "crt->eckey.Q", &pk_ec( crt->pk )->Q ); + } else +#endif /* POLARSSL_ECP_C */ + debug_print_msg( ssl, level, file, line, + "crt->pk.type is not valid" ); crt = crt->next; } diff --git a/library/ecp.c b/library/ecp.c index 9e7a96785..14683120a 100644 --- a/library/ecp.c +++ b/library/ecp.c @@ -101,7 +101,6 @@ void ecp_keypair_init( ecp_keypair *key ) ecp_group_init( &key->grp ); mpi_init( &key->d ); ecp_point_init( &key->Q ); - key->alg = POLARSSL_ECP_KEY_ALG_UNRESTRICTED; } /* @@ -142,7 +141,6 @@ void ecp_keypair_free( ecp_keypair *key ) ecp_group_free( &key->grp ); mpi_free( &key->d ); ecp_point_free( &key->Q ); - key->alg = POLARSSL_ECP_KEY_ALG_UNRESTRICTED; } /* diff --git a/library/error.c b/library/error.c index 0a739b5d5..560c54cff 100644 --- a/library/error.c +++ b/library/error.c @@ -250,6 +250,8 @@ void polarssl_strerror( int ret, char *buf, size_t buflen ) #if defined(POLARSSL_PK_C) if( use_ret == -(POLARSSL_ERR_PK_MALLOC_FAILED) ) snprintf( buf, buflen, "PK - Memory alloation failed" ); + if( use_ret == -(POLARSSL_ERR_PK_TYPE_MISMATCH) ) + snprintf( buf, buflen, "PK - Type mismatch, eg attempt to use a RSA key as EC, or to modify key type" ); #endif /* POLARSSL_PK_C */ #if defined(POLARSSL_PKCS12_C) diff --git a/library/oid.c b/library/oid.c index 449b3e1f0..750ece8e3 100644 --- a/library/oid.c +++ b/library/oid.c @@ -298,6 +298,26 @@ static const oid_sig_alg_t oid_sig_alg[] = { OID_RSA_SHA_OBS, "sha-1WithRSAEncryption", "RSA with SHA1" }, POLARSSL_MD_SHA1, POLARSSL_PK_RSA, }, + { + { OID_ECDSA_SHA1, "ecdsa-with-SHA1", "ECDSA with SHA1" }, + POLARSSL_MD_SHA1, POLARSSL_PK_ECDSA, + }, + { + { OID_ECDSA_SHA224, "ecdsa-with-SHA224", "ECDSA with SHA224" }, + POLARSSL_MD_SHA224, POLARSSL_PK_ECDSA, + }, + { + { OID_ECDSA_SHA256, "ecdsa-with-SHA256", "ECDSA with SHA256" }, + POLARSSL_MD_SHA256, POLARSSL_PK_ECDSA, + }, + { + { OID_ECDSA_SHA384, "ecdsa-with-SHA384", "ECDSA with SHA384" }, + POLARSSL_MD_SHA384, POLARSSL_PK_ECDSA, + }, + { + { OID_ECDSA_SHA512, "ecdsa-with-SHA512", "ECDSA with SHA512" }, + POLARSSL_MD_SHA512, POLARSSL_PK_ECDSA, + }, { { NULL, NULL, NULL }, 0, 0, @@ -571,8 +591,7 @@ int oid_get_numeric_string( char *buf, size_t size, for( i = 1; i < oid->len; i++ ) { /* Prevent overflow in value. */ - unsigned int v = value << 7; - if ( v < value ) + if ( ( ( value << 7 ) >> 7 ) != value ) return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL ); value <<= 7; diff --git a/library/pk.c b/library/pk.c index 71505ed2e..78ff5e97c 100644 --- a/library/pk.c +++ b/library/pk.c @@ -33,6 +33,9 @@ #if defined(POLARSSL_ECP_C) #include "polarssl/ecp.h" #endif +#if defined(POLARSSL_ECDSA_C) +#include "polarssl/ecdsa.h" +#endif #include @@ -46,6 +49,7 @@ void pk_init( pk_context *ctx ) ctx->type = POLARSSL_PK_NONE; ctx->data = NULL; + ctx->dont_free = 0; } /* @@ -56,26 +60,27 @@ void pk_free( pk_context *ctx ) if( ctx == NULL ) return; - switch( ctx->type ) - { - case POLARSSL_PK_NONE: - break; - #if defined(POLARSSL_RSA_C) - case POLARSSL_PK_RSA: - rsa_free( ctx->data ); - break; + if( ctx->type == POLARSSL_PK_RSA ) + rsa_free( ctx->data ); + else #endif - #if defined(POLARSSL_ECP_C) - case POLARSSL_PK_ECKEY: - case POLARSSL_PK_ECKEY_DH: - ecp_keypair_free( ctx->data ); - break; + if( ctx->type == POLARSSL_PK_ECKEY || ctx->type == POLARSSL_PK_ECKEY_DH ) + ecp_keypair_free( ctx->data ); + else #endif +#if defined(POLARSSL_ECDSA_C) + if( ctx->type == POLARSSL_PK_ECDSA ) + ecdsa_free( ctx->data ); + else +#endif + { + ; /* guard for the else's above */ } - free( ctx-> data ); + if( ! ctx->dont_free ) + free( ctx->data ); ctx->type = POLARSSL_PK_NONE; ctx->data = NULL; @@ -86,26 +91,30 @@ void pk_free( pk_context *ctx ) */ int pk_set_type( pk_context *ctx, pk_type_t type ) { - size_t size = 0; + size_t size; + + if( ctx->type == type ) + return( 0 ); + + if( ctx->type != POLARSSL_PK_NONE ) + return( POLARSSL_ERR_PK_TYPE_MISMATCH ); - switch( type ) - { #if defined(POLARSSL_RSA_C) - case POLARSSL_PK_RSA: - size = sizeof( rsa_context ); - break; + if( type == POLARSSL_PK_RSA ) + size = sizeof( rsa_context ); + else #endif - #if defined(POLARSSL_ECP_C) - case POLARSSL_PK_ECKEY: - case POLARSSL_PK_ECKEY_DH: - size = sizeof( ecp_keypair ); - break; + if( type == POLARSSL_PK_ECKEY || type == POLARSSL_PK_ECKEY_DH ) + size = sizeof( ecp_keypair ); + else #endif - - case POLARSSL_PK_NONE: - ; /* Should not happen */ - } +#if defined(POLARSSL_ECDSA_C) + if( type == POLARSSL_PK_ECDSA ) + size = sizeof( ecdsa_context ); + else +#endif + return( POLARSSL_ERR_PK_TYPE_MISMATCH ); if( ( ctx->data = malloc( size ) ) == NULL ) return( POLARSSL_ERR_PK_MALLOC_FAILED ); @@ -115,3 +124,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/ssl_cli.c b/library/ssl_cli.c index 66ebcefcb..aeba799cb 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -1072,8 +1072,12 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl ) return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } + /* EC NOT IMPLEMENTED YET */ + if( ssl->session_negotiate->peer_cert->pk.type != POLARSSL_PK_RSA ) + return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); + if( (unsigned int)( end - p ) != - ssl->session_negotiate->peer_cert->rsa.len ) + pk_rsa( ssl->session_negotiate->peer_cert->pk )->len ) { SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); @@ -1139,9 +1143,9 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl ) SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen ); - if( ( ret = rsa_pkcs1_verify( &ssl->session_negotiate->peer_cert->rsa, - RSA_PUBLIC, - md_alg, hashlen, hash, p ) ) != 0 ) + if( ( ret = rsa_pkcs1_verify( + pk_rsa( ssl->session_negotiate->peer_cert->pk ), + RSA_PUBLIC, md_alg, hashlen, hash, p ) ) != 0 ) { SSL_DEBUG_RET( 1, "rsa_pkcs1_verify", ret ); return( ret ); @@ -1516,8 +1520,12 @@ static int ssl_write_client_key_exchange( ssl_context *ssl ) if( ret != 0 ) return( ret ); + /* EC NOT IMPLEMENTED YET */ + if( ssl->session_negotiate->peer_cert->pk.type != POLARSSL_PK_RSA ) + return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); + i = 4; - n = ssl->session_negotiate->peer_cert->rsa.len; + n = pk_rsa( ssl->session_negotiate->peer_cert->pk )->len; if( ssl->minor_ver != SSL_MINOR_VERSION_0 ) { @@ -1526,12 +1534,11 @@ static int ssl_write_client_key_exchange( ssl_context *ssl ) ssl->out_msg[5] = (unsigned char)( n ); } - ret = rsa_pkcs1_encrypt( &ssl->session_negotiate->peer_cert->rsa, - ssl->f_rng, ssl->p_rng, - RSA_PUBLIC, - ssl->handshake->pmslen, - ssl->handshake->premaster, - ssl->out_msg + i ); + ret = rsa_pkcs1_encrypt( + pk_rsa( ssl->session_negotiate->peer_cert->pk ), + ssl->f_rng, ssl->p_rng, RSA_PUBLIC, + ssl->handshake->pmslen, ssl->handshake->premaster, + ssl->out_msg + i ); if( ret != 0 ) { SSL_DEBUG_RET( 1, "rsa_pkcs1_encrypt", ret ); diff --git a/library/ssl_srv.c b/library/ssl_srv.c index c6a827320..2aef9c415 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c @@ -1968,7 +1968,11 @@ static int ssl_parse_certificate_verify( ssl_context *ssl ) md_alg = POLARSSL_MD_NONE; } - n1 = ssl->session_negotiate->peer_cert->rsa.len; + /* EC NOT IMPLEMENTED YET */ + if( ssl->session_negotiate->peer_cert->pk.type != POLARSSL_PK_RSA ) + return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); + + n1 = pk_rsa( ssl->session_negotiate->peer_cert->pk )->len; n2 = ( ssl->in_msg[4 + n] << 8 ) | ssl->in_msg[5 + n]; if( n + n1 + 6 != ssl->in_hslen || n1 != n2 ) @@ -1977,8 +1981,9 @@ static int ssl_parse_certificate_verify( ssl_context *ssl ) return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); } - ret = rsa_pkcs1_verify( &ssl->session_negotiate->peer_cert->rsa, RSA_PUBLIC, - md_alg, hashlen, hash, ssl->in_msg + 6 + n ); + ret = rsa_pkcs1_verify( pk_rsa( ssl->session_negotiate->peer_cert->pk ), + RSA_PUBLIC, md_alg, hashlen, hash, + ssl->in_msg + 6 + n ); if( ret != 0 ) { SSL_DEBUG_RET( 1, "rsa_pkcs1_verify", ret ); diff --git a/library/x509parse.c b/library/x509parse.c index c5f9049df..a11c06488 100644 --- a/library/x509parse.c +++ b/library/x509parse.c @@ -160,47 +160,59 @@ static int x509_get_serial( unsigned char **p, return( 0 ); } -/* +/* Get a PK algorithm identifier + * * AlgorithmIdentifier ::= SEQUENCE { * algorithm OBJECT IDENTIFIER, * parameters ANY DEFINED BY algorithm OPTIONAL } - * - * If params_end is NULL, then parameters must be absent or ANS.1 NULL */ -static int x509_get_alg( unsigned char **p, - const unsigned char *end, - x509_buf *alg, const unsigned char **params_end ) +static int x509_get_pk_alg( unsigned char **p, + const unsigned char *end, + pk_type_t *pk_alg, x509_buf *params ) { int ret; - size_t len; + x509_buf alg_oid; - if( params_end == NULL ) { - if( ( ret = asn1_get_alg_null( p, end, alg ) ) != 0 ) - return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret ); + memset( params, 0, sizeof(asn1_buf) ); - return( 0 ); - } + if( ( ret = asn1_get_alg( p, end, &alg_oid, params ) ) != 0 ) + return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret ); - /* TODO: use asn1_get_alg */ - if( ( ret = asn1_get_tag( p, end, &len, - ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + if( oid_get_pk_alg( &alg_oid, pk_alg ) != 0 ) + return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG ); + + /* + * No parameters with RSA (only for EC) + */ + if( *pk_alg == POLARSSL_PK_RSA && + ( ( params->tag != ASN1_NULL && params->tag != 0 ) || + params->len != 0 ) ) { - return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret ); + return( POLARSSL_ERR_X509_CERT_INVALID_ALG ); } - end = *p + len; - alg->tag = **p; - - if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 0 ) - return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret ); - - alg->p = *p; - *p += alg->len; - - *params_end = end; return( 0 ); } +/* Get an algorithm identifier without parameters (eg for signatures) + * + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL } + */ +static int x509_get_alg_null( unsigned char **p, const unsigned char *end, + x509_buf *alg ) +{ + int ret; + + if( ( ret = asn1_get_alg_null( p, end, alg ) ) != 0 ) + return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret ); + + return( 0 ); +} + + +#if defined(POLARSSL_ECP_C) /* Get an EC group id from an ECParameters buffer * * ECParameters ::= CHOICE { @@ -210,62 +222,48 @@ static int x509_get_alg( unsigned char **p, * } */ static int x509_get_ecparams( unsigned char **p, const unsigned char *end, - ecp_group_id *grp_id ) + x509_buf *params ) { int ret; - x509_buf curve; - curve.tag = **p; + params->tag = **p; - if( ( ret = asn1_get_tag( p, end, &curve.len, ASN1_OID ) ) != 0 ) + if( ( ret = asn1_get_tag( p, end, ¶ms->len, ASN1_OID ) ) != 0 ) return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret ); - curve.p = *p; - *p += curve.len; + params->p = *p; + *p += params->len; if( *p != end ) return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); - if( ( ret = oid_get_ec_grp( &curve, grp_id ) ) != 0 ) - return( POLARSSL_ERR_X509_UNKNOWN_NAMED_CURVE ); - return( 0 ); } /* - * subjectPublicKey BIT STRING - * -- which, in our case, contains - * ECPoint ::= octet string (not ASN.1) + * Use EC parameters to initialise an EC group */ -static int x509_get_subpubkey_ec( unsigned char **p, const unsigned char *end, - const ecp_group *grp, ecp_point *pt ) +static int x509_use_ecparams( const x509_buf *params, ecp_group *grp ) { int ret; - size_t len; + ecp_group_id grp_id; - 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 ); + if( oid_get_ec_grp( params, &grp_id ) != 0 ) + return( POLARSSL_ERR_X509_UNKNOWN_NAMED_CURVE ); /* - * 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. + * grp may already be initilialized; if so, make sure IDs match */ - ++*p; - --len; + if( grp->id != POLARSSL_ECP_DP_NONE && grp->id != grp_id ) + return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT ); - if( ( ret = ecp_point_read_binary( grp, pt, - (const unsigned char *) *p, len ) ) != 0 ) - { - return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret ); - } + if( ( ret = ecp_use_known_dp( grp, grp_id ) ) != 0 ) + return( ret ); return( 0 ); } +#endif /* POLARSSL_ECP_C */ /* * AttributeTypeAndValue ::= SEQUENCE { @@ -490,6 +488,67 @@ static int x509_get_dates( unsigned char **p, return( 0 ); } +#if defined(POLARSSL_RSA_C) +/* + * RSAPublicKey ::= SEQUENCE { + * modulus INTEGER, -- n + * publicExponent INTEGER -- e + * } + */ +static int x509_get_rsapubkey( unsigned char **p, + const unsigned char *end, + rsa_context *rsa ) +{ + int ret; + size_t len; + + if( ( ret = asn1_get_tag( p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret ); + + if( *p + len != end ) + return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + if( ( ret = asn1_get_mpi( p, end, &rsa->N ) ) != 0 || + ( ret = asn1_get_mpi( p, end, &rsa->E ) ) != 0 ) + return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret ); + + if( ( ret = rsa_check_pubkey( rsa ) ) != 0 ) + return( ret ); + + rsa->len = mpi_size( &rsa->N ); + + return( 0 ); +} +#endif /* POLARSSL_RSA_C */ + +#if defined(POLARSSL_ECP_C) +/* + * EC public key is an EC point + */ +static int x509_get_ecpubkey( unsigned char **p, const unsigned char *end, + ecp_keypair *key ) +{ + int ret; + + if( ( ret = ecp_point_read_binary( &key->grp, &key->Q, + (const unsigned char *) *p, end - *p ) ) != 0 || + ( ret = ecp_check_pubkey( &key->grp, &key->Q ) ) != 0 ) + { + ecp_keypair_free( key ); + return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY ); + } + + /* + * We know ecp_point_read_binary consumed all bytes + */ + *p = (unsigned char *) end; + + return( 0 ); +} +#endif /* POLARSSL_ECP_C */ + /* * SubjectPublicKeyInfo ::= SEQUENCE { * algorithm AlgorithmIdentifier, @@ -497,63 +556,57 @@ static int x509_get_dates( unsigned char **p, */ static int x509_get_pubkey( unsigned char **p, const unsigned char *end, - x509_buf *pk_alg_oid, - mpi *N, mpi *E ) + pk_context *pk ) { int ret; size_t len; - unsigned char *end2; + x509_buf alg_params; pk_type_t pk_alg = POLARSSL_PK_NONE; - 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 ) + if( ( ret = asn1_get_tag( p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) { - return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG ); + return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret ); } - if (pk_alg != POLARSSL_PK_RSA ) - return( POLARSSL_ERR_X509_CERT_INVALID_ALG ); + end = *p + len; - if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 ) + if( ( ret = x509_get_pk_alg( p, end, &pk_alg, &alg_params ) ) != 0 ) + return( ret ); + + if( ( ret = asn1_get_bitstring_null( p, end, &len ) ) != 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 ); - - end2 = *p + len; - - if( *(*p)++ != 0 ) - return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY ); - - /* - * RSAPublicKey ::= SEQUENCE { - * modulus INTEGER, -- n - * publicExponent INTEGER -- e - * } - */ - if( ( ret = asn1_get_tag( p, end2, &len, - ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) - return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret ); - - if( *p + len != end2 ) + if( *p + len != end ) return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); - if( ( ret = asn1_get_mpi( p, end2, N ) ) != 0 || - ( ret = asn1_get_mpi( p, end2, E ) ) != 0 ) - return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret ); + if( ( ret = pk_set_type( pk, pk_alg ) ) != 0 ) + return( ret ); - if( *p != end ) - return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + - POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); +#if defined(POLARSSL_RSA_C) + if( pk_alg == POLARSSL_PK_RSA ) + { + ret = x509_get_rsapubkey( p, end, pk_rsa( *pk ) ); + } else +#endif /* POLARSSL_RSA_C */ +#if defined(POLARSSL_ECP_C) + if( pk_alg == POLARSSL_PK_ECKEY_DH || pk_alg == POLARSSL_PK_ECKEY ) + { + ret = x509_use_ecparams( &alg_params, &pk_ec( *pk )->grp ) || + x509_get_ecpubkey( p, end, pk_ec( *pk ) ); + } else +#endif /* POLARSSL_ECP_C */ + ret = POLARSSL_ERR_X509_UNKNOWN_PK_ALG; - return( 0 ); + if( ret == 0 && *p != end ) + ret = POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + POLARSSL_ERR_ASN1_LENGTH_MISMATCH; + + if( ret != 0 ) + pk_free( pk ); + + return( ret ); } static int x509_get_sig( unsigned char **p, @@ -569,13 +622,9 @@ static int x509_get_sig( unsigned char **p, sig->tag = **p; - if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 ) + if( ( ret = asn1_get_bitstring_null( p, end, &len ) ) != 0 ) return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE + ret ); - - if( --len < 1 || *(*p)++ != 0 ) - return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE ); - sig->len = len; sig->p = *p; @@ -1241,9 +1290,9 @@ static int x509parse_crt_der_core( x509_cert *crt, const unsigned char *buf, * * signature AlgorithmIdentifier */ - if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 || - ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 || - ( ret = x509_get_alg( &p, end, &crt->sig_oid1, NULL ) ) != 0 ) + if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 || + ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 || + ( ret = x509_get_alg_null( &p, end, &crt->sig_oid1 ) ) != 0 ) { x509_free( crt ); return( ret ); @@ -1318,32 +1367,14 @@ static int x509parse_crt_der_core( x509_cert *crt, const unsigned char *buf, crt->subject_raw.len = p - crt->subject_raw.p; /* - * SubjectPublicKeyInfo ::= SEQUENCE - * algorithm AlgorithmIdentifier, - * subjectPublicKey BIT STRING } + * SubjectPublicKeyInfo */ - if( ( ret = asn1_get_tag( &p, end, &len, - ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) - { - x509_free( crt ); - return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret ); - } - - if( ( ret = x509_get_pubkey( &p, p + len, &crt->pk_oid, - &crt->rsa.N, &crt->rsa.E ) ) != 0 ) + if( ( ret = x509_get_pubkey( &p, end, &crt->pk ) ) != 0 ) { x509_free( crt ); return( ret ); } - if( ( ret = rsa_check_pubkey( &crt->rsa ) ) != 0 ) - { - x509_free( crt ); - return( ret ); - } - - crt->rsa.len = mpi_size( &crt->rsa.N ); - /* * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, * -- If present, version shall be v2 or v3 @@ -1392,10 +1423,13 @@ static int x509parse_crt_der_core( x509_cert *crt, const unsigned char *buf, end = crt_end; /* + * } + * -- end of TBSCertificate + * * signatureAlgorithm AlgorithmIdentifier, * signatureValue BIT STRING */ - if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2, NULL ) ) != 0 ) + if( ( ret = x509_get_alg_null( &p, end, &crt->sig_oid2 ) ) != 0 ) { x509_free( crt ); return( ret ); @@ -1718,7 +1752,7 @@ int x509parse_crl( x509_crl *chain, const unsigned char *buf, size_t buflen ) * signature AlgorithmIdentifier */ if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 || - ( ret = x509_get_alg( &p, end, &crl->sig_oid1, NULL ) ) != 0 ) + ( ret = x509_get_alg_null( &p, end, &crl->sig_oid1 ) ) != 0 ) { x509_crl_free( crl ); return( ret ); @@ -1823,7 +1857,7 @@ int x509parse_crl( x509_crl *chain, const unsigned char *buf, size_t buflen ) * signatureAlgorithm AlgorithmIdentifier, * signatureValue BIT STRING */ - if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2, NULL ) ) != 0 ) + if( ( ret = x509_get_alg_null( &p, end, &crl->sig_oid2 ) ) != 0 ) { x509_crl_free( crl ); return( ret ); @@ -2037,50 +2071,6 @@ int x509parse_crlfile( x509_crl *chain, const char *path ) return( ret ); } -/* - * Load and parse a private RSA key - */ -int x509parse_keyfile_rsa( rsa_context *rsa, const char *path, const char *pwd ) -{ - int ret; - size_t n; - unsigned char *buf; - - if ( ( ret = load_file( path, &buf, &n ) ) != 0 ) - return( ret ); - - if( pwd == NULL ) - ret = x509parse_key_rsa( rsa, buf, n, NULL, 0 ); - else - ret = x509parse_key_rsa( rsa, buf, n, - (const unsigned char *) pwd, strlen( pwd ) ); - - memset( buf, 0, n + 1 ); - polarssl_free( buf ); - - return( ret ); -} - -/* - * Load and parse a public RSA key - */ -int x509parse_public_keyfile_rsa( rsa_context *rsa, const char *path ) -{ - int ret; - size_t n; - unsigned char *buf; - - if ( ( ret = load_file( path, &buf, &n ) ) != 0 ) - return( ret ); - - ret = x509parse_public_key_rsa( rsa, buf, n ); - - memset( buf, 0, n + 1 ); - polarssl_free( buf ); - - return( ret ); -} - /* * Load and parse a private key */ @@ -2126,8 +2116,36 @@ int x509parse_public_keyfile( pk_context *ctx, const char *path ) return( ret ); } +#if defined(POLARSSL_RSA_C) +/* + * Load and parse a private RSA key + */ +int x509parse_keyfile_rsa( rsa_context *rsa, const char *path, const char *pwd ) +{ + pk_context pk; + + pk_init( &pk ); + pk_wrap_rsa( &pk, rsa ); + + return( x509parse_keyfile( &pk, path, pwd ) ); +} + +/* + * Load and parse a public RSA key + */ +int x509parse_public_keyfile_rsa( rsa_context *rsa, const char *path ) +{ + pk_context pk; + + pk_init( &pk ); + pk_wrap_rsa( &pk, rsa ); + + return( x509parse_public_keyfile( &pk, path ) ); +} +#endif /* POLARSSL_RSA_C */ #endif /* POLARSSL_FS_IO */ +#if defined(POLARSSL_RSA_C) /* * Parse a PKCS#1 encoded private RSA key */ @@ -2206,39 +2224,33 @@ static int x509parse_key_pkcs1_der( rsa_context *rsa, return( 0 ); } +#endif /* POLARSSL_RSA_C */ +#if defined(POLARSSL_ECP_C) /* - * Parse an unencrypted PKCS#8 encoded private RSA key + * Parse a SEC1 encoded private EC key */ -static int x509parse_key_pkcs8_unencrypted_der( - rsa_context *rsa, - const unsigned char *key, - size_t keylen ) +static int x509parse_key_sec1_der( ecp_keypair *eck, + const unsigned char *key, + size_t keylen ) { int ret; + int version; size_t len; - unsigned char *p, *end; - x509_buf pk_alg_oid; - pk_type_t pk_alg = POLARSSL_PK_NONE; - - p = (unsigned char *) key; - end = p + keylen; + x509_buf params; + unsigned char *p = (unsigned char *) key; + unsigned char *end = p + keylen; + unsigned char *end2; /* - * This function parses the PrivatKeyInfo object (PKCS#8) + * RFC 5915, orf SEC1 Appendix C.4 * - * PrivateKeyInfo ::= SEQUENCE { - * version Version, - * algorithm AlgorithmIdentifier, - * PrivateKey BIT STRING - * } - * - * AlgorithmIdentifier ::= SEQUENCE { - * algorithm OBJECT IDENTIFIER, - * parameters ANY DEFINED BY algorithm OPTIONAL - * } - * - * The PrivateKey BIT STRING is a PKCS#1 RSAPrivateKey + * ECPrivateKey ::= SEQUENCE { + * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), + * privateKey OCTET STRING, + * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, + * publicKey [1] BIT STRING OPTIONAL + * } */ if( ( ret = asn1_get_tag( &p, end, &len, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) @@ -2248,56 +2260,171 @@ static int x509parse_key_pkcs8_unencrypted_der( end = p + len; - if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 ) + if( ( ret = asn1_get_int( &p, end, &version ) ) != 0 ) return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret ); - if( rsa->ver != 0 ) - return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret ); + if( version != 1 ) + return( POLARSSL_ERR_X509_KEY_INVALID_VERSION ); - if( ( ret = asn1_get_alg_null( &p, end, &pk_alg_oid ) ) != 0 ) - return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret ); - - /* - * only RSA 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 ); - - /* - * Get the OCTET STRING and parse the PKCS#1 format inside - */ if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 ) return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret ); - if( ( end - p ) < 1 ) + if( ( ret = mpi_read_binary( &eck->d, p, len ) ) != 0 ) { - return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + - POLARSSL_ERR_ASN1_OUT_OF_DATA ); + ecp_keypair_free( eck ); + return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret ); + } + + p += len; + + /* + * Is 'parameters' present? + */ + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) == 0 ) + { + if( ( ret = x509_get_ecparams( &p, p + len, ¶ms) ) != 0 || + ( ret = x509_use_ecparams( ¶ms, &eck->grp ) ) != 0 ) + { + ecp_keypair_free( eck ); + return( ret ); + } + } + else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) + { + ecp_keypair_free( eck ); + return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret ); + } + + /* + * Is 'publickey' present? + */ + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1 ) ) == 0 ) + { + end2 = p + len; + + if( ( ret = asn1_get_bitstring_null( &p, end2, &len ) ) != 0 ) + return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret ); + + if( p + len != end2 ) + return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + if( ( ret = x509_get_ecpubkey( &p, end2, eck ) ) != 0 ) + return( ret ); + } + else if ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) + { + ecp_keypair_free( eck ); + return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret ); + } + + if( ( ret = ecp_check_privkey( &eck->grp, &eck->d ) ) != 0 ) + { + ecp_keypair_free( eck ); + return( ret ); + } + + return 0; +} +#endif /* POLARSSL_ECP_C */ + +/* + * Parse an unencrypted PKCS#8 encoded private key + */ +static int x509parse_key_pkcs8_unencrypted_der( + pk_context *pk, + const unsigned char* key, + size_t keylen ) +{ + int ret, version; + size_t len; + x509_buf params; + unsigned char *p = (unsigned char *) key; + unsigned char *end = p + keylen; + pk_type_t pk_alg = POLARSSL_PK_NONE; + + /* + * This function parses the PrivatKeyInfo object (PKCS#8 v1.2 = RFC 5208) + * + * PrivateKeyInfo ::= SEQUENCE { + * version Version, + * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, + * privateKey PrivateKey, + * attributes [0] IMPLICIT Attributes OPTIONAL } + * + * Version ::= INTEGER + * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier + * PrivateKey ::= OCTET STRING + * + * The PrivateKey OCTET STRING is a SEC1 ECPrivateKey + */ + + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + { + return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret ); } end = p + len; - if( ( ret = x509parse_key_pkcs1_der( rsa, p, end - p ) ) != 0 ) + if( ( ret = asn1_get_int( &p, end, &version ) ) != 0 ) + return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret ); + + if( version != 0 ) + return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret ); + + if( ( ret = x509_get_pk_alg( &p, end, &pk_alg, ¶ms ) ) != 0 ) + return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret ); + + if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 ) + return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret ); + + if( len < 1 ) + return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + + POLARSSL_ERR_ASN1_OUT_OF_DATA ); + + if( ( ret = pk_set_type( pk, pk_alg ) ) != 0 ) return( ret ); - return( 0 ); +#if defined(POLARSSL_RSA_C) + if( pk_alg == POLARSSL_PK_RSA ) + { + if( ( ret = x509parse_key_pkcs1_der( pk_rsa( *pk ), p, len ) ) != 0 ) + { + pk_free( pk ); + return( ret ); + } + } else +#endif /* POLARSSL_RSA_C */ +#if defined(POLARSSL_ECP_C) + if( pk_alg == POLARSSL_PK_ECKEY || pk_alg == POLARSSL_PK_ECKEY_DH ) + { + if( ( ret = x509_use_ecparams( ¶ms, &pk_ec( *pk )->grp ) ) != 0 || + ( ret = x509parse_key_sec1_der( pk_ec( *pk ), p, len ) ) != 0 ) + { + pk_free( pk ); + return( ret ); + } + } else +#endif /* POLARSSL_ECP_C */ + return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG ); + + return 0; } /* - * Decrypt the content of a PKCS#8 EncryptedPrivateKeyInfo + * Parse an encrypted PKCS#8 encoded private key */ -static int x509parse_pkcs8_decrypt( unsigned char *buf, size_t buflen, - size_t *used_len, +static int x509parse_key_pkcs8_encrypted_der( + pk_context *pk, const unsigned char *key, size_t keylen, const unsigned char *pwd, size_t pwdlen ) { int ret; size_t len; + unsigned char buf[2048]; unsigned char *p, *end; x509_buf pbe_alg_oid, pbe_params; #if defined(POLARSSL_PKCS12_C) @@ -2305,7 +2432,7 @@ static int x509parse_pkcs8_decrypt( unsigned char *buf, size_t buflen, md_type_t md_alg; #endif - memset(buf, 0, buflen); + memset( buf, 0, sizeof( buf ) ); p = (unsigned char *) key; end = p + keylen; @@ -2341,7 +2468,7 @@ static int x509parse_pkcs8_decrypt( unsigned char *buf, size_t buflen, if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 ) return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret ); - if( len > buflen ) + if( len > sizeof( buf ) ) return( POLARSSL_ERR_X509_INVALID_INPUT ); /* @@ -2394,37 +2521,15 @@ static int x509parse_pkcs8_decrypt( unsigned char *buf, size_t buflen, #endif /* POLARSSL_PKCS5_C */ return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE ); - *used_len = len; - return( 0 ); + return( x509parse_key_pkcs8_unencrypted_der( pk, buf, len ) ); } /* - * Parse an encrypted PKCS#8 encoded private RSA key + * Parse a private key */ -static int x509parse_key_pkcs8_encrypted_der( - rsa_context *rsa, - const unsigned char *key, size_t keylen, - const unsigned char *pwd, size_t pwdlen ) -{ - int ret; - unsigned char buf[2048]; - size_t len = 0; - - if( ( ret = x509parse_pkcs8_decrypt( buf, sizeof( buf ), &len, - key, keylen, pwd, pwdlen ) ) != 0 ) - { - return( ret ); - } - - return( x509parse_key_pkcs8_unencrypted_der( rsa, buf, len ) ); -} - -/* - * Parse a private RSA key - */ -int x509parse_key_rsa( rsa_context *rsa, - const unsigned char *key, size_t keylen, - const unsigned char *pwd, size_t pwdlen ) +int x509parse_key( pk_context *pk, + const unsigned char *key, size_t keylen, + const unsigned char *pwd, size_t pwdlen ) { int ret; @@ -2433,15 +2538,19 @@ int x509parse_key_rsa( rsa_context *rsa, pem_context pem; pem_init( &pem ); + +#if defined(POLARSSL_RSA_C) ret = pem_read_buffer( &pem, "-----BEGIN RSA PRIVATE KEY-----", "-----END RSA PRIVATE KEY-----", key, pwd, pwdlen, &len ); if( ret == 0 ) { - if( ( ret = x509parse_key_pkcs1_der( rsa, pem.buf, pem.buflen ) ) != 0 ) + if( ( ret = pk_set_type( pk, POLARSSL_PK_RSA ) ) != 0 || + ( ret = x509parse_key_pkcs1_der( pk_rsa( *pk ), + pem.buf, pem.buflen ) ) != 0 ) { - rsa_free( rsa ); + pk_free( pk ); } pem_free( &pem ); @@ -2453,429 +2562,20 @@ int x509parse_key_rsa( rsa_context *rsa, return( POLARSSL_ERR_X509_PASSWORD_REQUIRED ); else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) return( ret ); - - ret = pem_read_buffer( &pem, - "-----BEGIN PRIVATE KEY-----", - "-----END PRIVATE KEY-----", - key, NULL, 0, &len ); - if( ret == 0 ) - { - if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa, - pem.buf, pem.buflen ) ) != 0 ) - { - rsa_free( rsa ); - } - - pem_free( &pem ); - return( ret ); - } - else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) - return( ret ); - - ret = pem_read_buffer( &pem, - "-----BEGIN ENCRYPTED PRIVATE KEY-----", - "-----END ENCRYPTED PRIVATE KEY-----", - key, NULL, 0, &len ); - if( ret == 0 ) - { - if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa, - pem.buf, pem.buflen, - pwd, pwdlen ) ) != 0 ) - { - rsa_free( rsa ); - } - - pem_free( &pem ); - return( ret ); - } - else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) - return( ret ); -#else - ((void) pwd); - ((void) pwdlen); -#endif /* POLARSSL_PEM_C */ - - /* - * At this point we only know it's not a PEM formatted key. Could be any - * of the known DER encoded private key formats - * - * We try the different DER format parsers to see if one passes without - * error - */ - if( ( ret = x509parse_key_pkcs8_encrypted_der( rsa, key, keylen, - pwd, pwdlen ) ) == 0 ) - { - return( 0 ); - } - - rsa_free( rsa ); - - if( ret == POLARSSL_ERR_X509_PASSWORD_MISMATCH ) - { - return( ret ); - } - - if( ( ret = x509parse_key_pkcs8_unencrypted_der( rsa, key, keylen ) ) == 0 ) - return( 0 ); - - rsa_free( rsa ); - - if( ( ret = x509parse_key_pkcs1_der( rsa, key, keylen ) ) == 0 ) - return( 0 ); - - rsa_free( rsa ); - - return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT ); -} - -/* - * Parse a public RSA key - */ -int x509parse_public_key_rsa( rsa_context *rsa, - 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) - pem_context pem; - - pem_init( &pem ); - ret = pem_read_buffer( &pem, - "-----BEGIN PUBLIC KEY-----", - "-----END PUBLIC KEY-----", - key, NULL, 0, &len ); - - 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; - - /* - * PublicKeyInfo ::= SEQUENCE { - * algorithm AlgorithmIdentifier, - * PublicKey BIT STRING - * } - * - * AlgorithmIdentifier ::= SEQUENCE { - * algorithm OBJECT IDENTIFIER, - * parameters ANY DEFINED BY algorithm OPTIONAL - * } - * - * RSAPublicKey ::= SEQUENCE { - * modulus INTEGER, -- n - * publicExponent INTEGER -- e - * } - */ - - if( ( ret = asn1_get_tag( &p, end, &len, - ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) - { -#if defined(POLARSSL_PEM_C) - pem_free( &pem ); -#endif - rsa_free( rsa ); - return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret ); - } - - if( ( ret = x509_get_pubkey( &p, end, &alg_oid, &rsa->N, &rsa->E ) ) != 0 ) - { -#if defined(POLARSSL_PEM_C) - pem_free( &pem ); -#endif - rsa_free( rsa ); - return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret ); - } - - if( ( ret = rsa_check_pubkey( rsa ) ) != 0 ) - { -#if defined(POLARSSL_PEM_C) - pem_free( &pem ); -#endif - rsa_free( rsa ); - return( ret ); - } - - rsa->len = mpi_size( &rsa->N ); - -#if defined(POLARSSL_PEM_C) - pem_free( &pem ); -#endif - - return( 0 ); -} +#endif /* POLARSSL_RSA_C */ #if defined(POLARSSL_ECP_C) -/* - * Parse a SEC1 encoded private EC key - */ -static int x509parse_key_sec1_der( ecp_keypair *eck, - const unsigned char *key, - size_t keylen ) -{ - int ret; - int version; - size_t len; - ecp_group_id grp_id; - unsigned char *p = (unsigned char *) key; - unsigned char *end = p + keylen; - - /* - * RFC 5915, orf SEC1 Appendix C.4 - * - * ECPrivateKey ::= SEQUENCE { - * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), - * privateKey OCTET STRING, - * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, - * publicKey [1] BIT STRING OPTIONAL - * } - */ - if( ( ret = asn1_get_tag( &p, end, &len, - ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) - { - return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret ); - } - - end = p + len; - - if( ( ret = asn1_get_int( &p, end, &version ) ) != 0 ) - return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret ); - - if( version != 1 ) - return( POLARSSL_ERR_X509_KEY_INVALID_VERSION ); - - if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 ) - return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret ); - - if( ( ret = mpi_read_binary( &eck->d, p, len ) ) != 0 ) - { - ecp_keypair_free( eck ); - return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret ); - } - - p += len; - - /* - * Is 'parameters' present? - */ - if( ( ret = asn1_get_tag( &p, end, &len, - ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) == 0 ) - { - if( ( ret = x509_get_ecparams( &p, p + len, &grp_id) ) != 0 ) - return( ret ); - - /* - * If we're wrapped in a bigger structure (eg PKCS#8), grp may have been - * defined externally. In this case, make sure both definitions match. - */ - if( eck->grp.id != 0 ) - { - if( eck->grp.id != grp_id ) - { - ecp_keypair_free( eck ); - return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret ); - } - } - else - { - if( ( ret = ecp_use_known_dp( &eck->grp, grp_id ) ) != 0 ) - { - ecp_keypair_free( eck ); - return( ret ); - } - } - } - else if ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) - { - ecp_keypair_free( eck ); - return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret ); - } - - /* - * Is 'publickey' present? - */ - if( ( ret = asn1_get_tag( &p, end, &len, - ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1 ) ) == 0 ) - { - if( ( ret = x509_get_subpubkey_ec( &p, p + len, &eck->grp, &eck->Q ) ) - != 0 ) - { - ecp_keypair_free( eck ); - return( ret ); - } - - if( ( ret = ecp_check_pubkey( &eck->grp, &eck->Q ) ) != 0 ) - { - ecp_keypair_free( eck ); - return( ret ); - } - } - else if ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) - { - ecp_keypair_free( eck ); - return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret ); - } - - if( ( ret = ecp_check_privkey( &eck->grp, &eck->d ) ) != 0 ) - { - ecp_keypair_free( eck ); - return( ret ); - } - - return 0; -} - -/* - * Parse an unencrypted PKCS#8 encoded private EC key - */ -static int x509parse_key_pkcs8_unencrypted_der_ec( - ecp_keypair *eck, - const unsigned char* key, - size_t keylen ) -{ - int ret, version; - size_t len; - x509_buf pk_alg_oid; - ecp_group_id grp_id; - const unsigned char *params_end; - unsigned char *p = (unsigned char *) key; - unsigned char *end = p + keylen; - pk_type_t pk_alg = POLARSSL_PK_NONE; - - /* - * This function parses the PrivatKeyInfo object (PKCS#8 v1.2 = RFC 5208) - * - * PrivateKeyInfo ::= SEQUENCE { - * version Version, - * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, - * privateKey PrivateKey, - * attributes [0] IMPLICIT Attributes OPTIONAL } - * - * Version ::= INTEGER - * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier - * PrivateKey ::= OCTET STRING - * - * The PrivateKey OCTET STRING is a SEC1 ECPrivateKey - */ - - if( ( ret = asn1_get_tag( &p, end, &len, - ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) - { - return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret ); - } - - end = p + len; - - if( ( ret = asn1_get_int( &p, end, &version ) ) != 0 ) - return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret ); - - if( version != 0 ) - return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret ); - - if( ( ret = x509_get_alg( &p, end, &pk_alg_oid, ¶ms_end ) ) != 0 ) - return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret ); - - if( oid_get_pk_alg( &pk_alg_oid, &pk_alg ) != 0 ) - return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG ); - - if( pk_alg != POLARSSL_PK_ECKEY && pk_alg != POLARSSL_PK_ECKEY_DH ) - return( POLARSSL_ERR_X509_CERT_INVALID_ALG ); - - if( pk_alg == POLARSSL_PK_ECKEY_DH ) - eck->alg = POLARSSL_ECP_KEY_ALG_ECDH; - - if( ( ret = x509_get_ecparams( &p, params_end, &grp_id ) ) != 0 ) - { - ecp_keypair_free( eck ); - return( ret ); - } - - if( ( ret = ecp_use_known_dp( &eck->grp, grp_id ) ) != 0 ) - { - ecp_keypair_free( eck ); - return( ret ); - } - - if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 ) - { - ecp_keypair_free( eck ); - return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret ); - } - - if( ( ret = x509parse_key_sec1_der( eck, p, len ) ) != 0 ) - { - ecp_keypair_free( eck ); - return( ret ); - } - - if( ( ret = ecp_check_privkey( &eck->grp, &eck->d ) ) != 0 ) - { - ecp_keypair_free( eck ); - return( ret ); - } - - return 0; -} - -/* - * Parse an encrypted PKCS#8 encoded private EC key - */ -static int x509parse_key_pkcs8_encrypted_der_ec( - ecp_keypair *eck, - const unsigned char *key, size_t keylen, - const unsigned char *pwd, size_t pwdlen ) -{ - int ret; - unsigned char buf[2048]; - size_t len = 0; - - if( ( ret = x509parse_pkcs8_decrypt( buf, sizeof( buf ), &len, - key, keylen, pwd, pwdlen ) ) != 0 ) - { - return( ret ); - } - - return( x509parse_key_pkcs8_unencrypted_der_ec( eck, buf, len ) ); -} - -/* - * Parse a private EC key - */ -static int x509parse_key_ec( ecp_keypair *eck, - const unsigned char *key, size_t keylen, - const unsigned char *pwd, size_t pwdlen ) -{ - int ret; - -#if defined(POLARSSL_PEM_C) - size_t len; - pem_context pem; - - pem_init( &pem ); ret = pem_read_buffer( &pem, "-----BEGIN EC PRIVATE KEY-----", "-----END EC PRIVATE KEY-----", key, pwd, pwdlen, &len ); if( ret == 0 ) { - if( ( ret = x509parse_key_sec1_der( eck, pem.buf, pem.buflen ) ) != 0 ) + if( ( ret = pk_set_type( pk, POLARSSL_PK_ECKEY ) ) != 0 || + ( ret = x509parse_key_sec1_der( pk_ec( *pk ), + pem.buf, pem.buflen ) ) != 0 ) { - ecp_keypair_free( eck ); + pk_free( pk ); } pem_free( &pem ); @@ -2887,6 +2587,7 @@ static int x509parse_key_ec( ecp_keypair *eck, return( POLARSSL_ERR_X509_PASSWORD_REQUIRED ); else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) return( ret ); +#endif /* POLARSSL_ECP_C */ ret = pem_read_buffer( &pem, "-----BEGIN PRIVATE KEY-----", @@ -2894,10 +2595,10 @@ static int x509parse_key_ec( ecp_keypair *eck, key, NULL, 0, &len ); if( ret == 0 ) { - if( ( ret = x509parse_key_pkcs8_unencrypted_der_ec( eck, + if( ( ret = x509parse_key_pkcs8_unencrypted_der( pk, pem.buf, pem.buflen ) ) != 0 ) { - ecp_keypair_free( eck ); + pk_free( pk ); } pem_free( &pem ); @@ -2912,11 +2613,11 @@ static int x509parse_key_ec( ecp_keypair *eck, key, NULL, 0, &len ); if( ret == 0 ) { - if( ( ret = x509parse_key_pkcs8_encrypted_der_ec( eck, + if( ( ret = x509parse_key_pkcs8_encrypted_der( pk, pem.buf, pem.buflen, pwd, pwdlen ) ) != 0 ) { - ecp_keypair_free( eck ); + pk_free( pk ); } pem_free( &pem ); @@ -2936,93 +2637,55 @@ static int x509parse_key_ec( ecp_keypair *eck, * We try the different DER format parsers to see if one passes without * error */ - if( ( ret = x509parse_key_pkcs8_encrypted_der_ec( eck, key, keylen, - pwd, pwdlen ) ) == 0 ) + if( ( ret = x509parse_key_pkcs8_encrypted_der( pk, key, keylen, + pwd, pwdlen ) ) == 0 ) { return( 0 ); } - ecp_keypair_free( eck ); + pk_free( pk ); if( ret == POLARSSL_ERR_X509_PASSWORD_MISMATCH ) { return( ret ); } - if( ( ret = x509parse_key_pkcs8_unencrypted_der_ec( eck, - key, keylen ) ) == 0 ) + if( ( ret = x509parse_key_pkcs8_unencrypted_der( pk, key, keylen ) ) == 0 ) return( 0 ); - ecp_keypair_free( eck ); + pk_free( pk ); - if( ( ret = x509parse_key_sec1_der( eck, key, keylen ) ) == 0 ) +#if defined(POLARSSL_RSA_C) + if( ( ret = pk_set_type( pk, POLARSSL_PK_RSA ) ) == 0 && + ( ret = x509parse_key_pkcs1_der( pk_rsa( *pk ), key, keylen ) ) == 0 ) + { return( 0 ); + } - ecp_keypair_free( eck ); + pk_free( pk ); +#endif /* POLARSSL_RSA_C */ + +#if defined(POLARSSL_ECP_C) + if( ( ret = pk_set_type( pk, POLARSSL_PK_ECKEY ) ) == 0 && + ( ret = x509parse_key_sec1_der( pk_ec( *pk ), key, keylen ) ) == 0 ) + { + return( 0 ); + } + + pk_free( pk ); +#endif /* POLARSSL_ECP_C */ return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT ); } /* - * Parse a public EC key in RFC 5480 format, der-encoded + * Parse a public key */ -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_CERT_INVALID_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 - */ -static int x509parse_public_key_ec( ecp_keypair *eckey, - const unsigned char *key, size_t keylen ) +int x509parse_public_key( pk_context *ctx, + const unsigned char *key, size_t keylen ) { int ret; + unsigned char *p; #if defined(POLARSSL_PEM_C) size_t len; pem_context pem; @@ -3047,12 +2710,9 @@ static int x509parse_public_key_ec( ecp_keypair *eckey, return( ret ); } #endif + p = (unsigned char *) key; - if( ( ret = x509parse_public_key_ec_der ( eckey, key, keylen ) ) != 0 || - ( ret = ecp_check_pubkey( &eckey->grp, &eckey->Q ) ) != 0 ) - { - ecp_keypair_free( eckey ); - } + ret = x509_get_pubkey( &p, p + keylen, ctx ); #if defined(POLARSSL_PEM_C) pem_free( &pem ); @@ -3060,59 +2720,37 @@ static int x509parse_public_key_ec( ecp_keypair *eckey, return( ret ); } -#endif /* defined(POLARSSL_ECP_C) */ +#if defined(POLARSSL_RSA_C) /* - * Parse a private key + * Parse a private RSA key */ -int x509parse_key( pk_context *ctx, - const unsigned char *key, size_t keylen, - const unsigned char *pwd, size_t pwdlen ) +int x509parse_key_rsa( rsa_context *rsa, + const unsigned char *key, size_t keylen, + const unsigned char *pwd, size_t pwdlen ) { - int ret; + pk_context pk; - if ( ( ret = pk_set_type( ctx, POLARSSL_PK_RSA ) ) != 0 ) - return( ret ); + pk_init( &pk ); + pk_wrap_rsa( &pk, rsa ); - if( ( ret = x509parse_key_rsa( ctx->data, key, keylen, pwd, pwdlen ) ) - == 0 ) - { - return( 0 ); - } - - if ( ( ret = pk_set_type( ctx, POLARSSL_PK_ECKEY ) ) != 0 ) - return( ret ); - - if( ( ret = x509parse_key_ec( ctx->data, key, keylen, pwd, pwdlen ) ) == 0 ) - { - return( 0 ); - } - - return( POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT ); + return( x509parse_key( &pk, key, keylen, pwd, pwdlen ) ); } /* - * Parse a public key + * Parse a public RSA key */ -int x509parse_public_key( pk_context *ctx, - const unsigned char *key, size_t keylen ) +int x509parse_public_key_rsa( rsa_context *rsa, + const unsigned char *key, size_t keylen ) { - int ret; + pk_context pk; - if ( ( ret = pk_set_type( ctx, POLARSSL_PK_RSA ) ) != 0 ) - return( ret ); + pk_init( &pk ); + pk_wrap_rsa( &pk, rsa ); - if( ( ret = x509parse_public_key_rsa( ctx->data, key, keylen ) ) == 0 ) - return( 0 ); - - if ( ( ret = pk_set_type( ctx, POLARSSL_PK_ECKEY ) ) != 0 ) - return( ret ); - - if( ( ret = x509parse_public_key_ec( ctx->data, key, keylen ) ) == 0 ) - return( 0 ); - - return( POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT ); + return( x509parse_public_key( &pk, key, keylen ) ); } +#endif /* POLARSSL_RSA_C */ #if defined(POLARSSL_DHM_C) /* @@ -3425,8 +3063,20 @@ int x509parse_cert_info( char *buf, size_t size, const char *prefix, ret = snprintf( p, n, desc ); SAFE_SNPRINTF(); - ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix, - (int) crt->rsa.N.n * (int) sizeof( t_uint ) * 8 ); +#if defined(POLARSSL_RSA_C) + if( crt->pk.type == POLARSSL_PK_RSA ) + ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix, + (int) pk_rsa( crt->pk )->N.n * (int) sizeof( t_uint ) * 8 ); + else +#endif /* POLARSSL_RSA_C */ +#if defined(POLARSSL_ECP_C) + if( crt->pk.type == POLARSSL_PK_ECKEY || + crt->pk.type == POLARSSL_PK_ECKEY_DH ) + ret = snprintf( p, n, "\n%sEC key size : %d bits\n", prefix, + (int) pk_ec( crt->pk )->grp.pbits ); + else +#endif /* POLARSSL_ECP_C */ + ret = snprintf(p, n, "\n%sPK type looks wrong!", prefix); SAFE_SNPRINTF(); return( (int) ( size - n ) ); @@ -3678,7 +3328,11 @@ static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca, md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash ); - if( !rsa_pkcs1_verify( &ca->rsa, RSA_PUBLIC, crl_list->sig_md, + /* EC NOT IMPLEMENTED YET */ + if( ca->pk.type != POLARSSL_PK_RSA ) + return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE ); + + if( !rsa_pkcs1_verify( pk_rsa( ca->pk ), RSA_PUBLIC, crl_list->sig_md, 0, hash, crl_list->sig.p ) == 0 ) { /* @@ -3796,7 +3450,11 @@ static int x509parse_verify_top( md( md_info, child->tbs.p, child->tbs.len, hash ); - if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, child->sig_md, + /* EC NOT IMPLEMENTED YET */ + if( trust_ca->pk.type != POLARSSL_PK_RSA ) + return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE ); + + if( rsa_pkcs1_verify( pk_rsa( trust_ca->pk ), RSA_PUBLIC, child->sig_md, 0, hash, child->sig.p ) != 0 ) { trust_ca = trust_ca->next; @@ -3872,9 +3530,15 @@ static int x509parse_verify_child( { md( md_info, child->tbs.p, child->tbs.len, hash ); - if( rsa_pkcs1_verify( &parent->rsa, RSA_PUBLIC, child->sig_md, 0, hash, - child->sig.p ) != 0 ) + /* EC NOT IMPLEMENTED YET */ + if( parent->pk.type != POLARSSL_PK_RSA ) + return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE ); + + if( rsa_pkcs1_verify( pk_rsa( parent->pk ), RSA_PUBLIC, child->sig_md, + 0, hash, child->sig.p ) != 0 ) + { *flags |= BADCERT_NOT_TRUSTED; + } } /* Check trusted CA's CRL for the given crt */ @@ -4049,7 +3713,7 @@ void x509_free( x509_cert *crt ) do { - rsa_free( &cert_cur->rsa ); + pk_free( &cert_cur->pk ); name_cur = cert_cur->issuer.next; while( name_cur != NULL ) diff --git a/programs/test/ssl_cert_test.c b/programs/test/ssl_cert_test.c index bf4684b2f..ec824c9eb 100644 --- a/programs/test/ssl_cert_test.c +++ b/programs/test/ssl_cert_test.c @@ -206,19 +206,28 @@ int main( int argc, char *argv[] ) printf( " ok\n" ); /* - * 1.5. Verify certificate validity with private key + * 1.6. Verify certificate validity with private key */ printf( " . Verify the client certificate with private key..." ); fflush( stdout ); - ret = mpi_cmp_mpi(&rsa.N, &clicert.rsa.N); + + /* EC NOT IMPLEMENTED YET */ + if( clicert.pk.type != POLARSSL_PK_RSA ) + { + printf( " failed\n ! certificate's key is not RSA\n\n" ); + ret = POLARSSL_ERR_X509_FEATURE_UNAVAILABLE; + goto exit; + } + + ret = mpi_cmp_mpi(&rsa.N, &pk_rsa( clicert.pk )->N); if( ret != 0 ) { printf( " failed\n ! mpi_cmp_mpi for N returned %d\n\n", ret ); goto exit; } - ret = mpi_cmp_mpi(&rsa.E, &clicert.rsa.E); + ret = mpi_cmp_mpi(&rsa.E, &pk_rsa( clicert.pk )->E); if( ret != 0 ) { printf( " failed\n ! mpi_cmp_mpi for E returned %d\n\n", ret ); diff --git a/tests/data_files/test-ca2.crt b/tests/data_files/test-ca2.crt new file mode 100644 index 000000000..c47c496bf Binary files /dev/null and b/tests/data_files/test-ca2.crt differ diff --git a/tests/data_files/test-ca2.key b/tests/data_files/test-ca2.key new file mode 100644 index 000000000..2725398e9 --- /dev/null +++ b/tests/data_files/test-ca2.key @@ -0,0 +1,8 @@ +-----BEGIN EC PARAMETERS----- +BggqhkjOPQMBAQ== +-----END EC PARAMETERS----- +-----BEGIN EC PRIVATE KEY----- +MF8CAQEEGKHCq9vcqkdzGdKSIUP2M9o/vu1rja5jxqAKBggqhkjOPQMBAaE0AzIA +BCE3lp+r1ONwYkoOGjPjecq5UMzgDvjDw+KtrrcnHI8HZZ1l09d33PIWFDY65Lbm +Fw== +-----END EC PRIVATE KEY----- diff --git a/tests/suites/test_suite_debug.data b/tests/suites/test_suite_debug.data index 824db6481..7a309cef7 100644 --- a/tests/suites/test_suite_debug.data +++ b/tests/suites/test_suite_debug.data @@ -1,7 +1,11 @@ -Debug print certificate #1 +Debug print certificate #1 (RSA) depends_on:POLARSSL_FS_IO:POLARSSL_PEM_C:POLARSSL_BASE64_C debug_print_crt:"data_files/server1.crt":"MyFile":999:"PREFIX_":"MyFile(0999)\: PREFIX_ #1\:\nMyFile(0999)\: cert. version \: 3\nMyFile(0999)\: serial number \: 01\nMyFile(0999)\: issuer name \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nMyFile(0999)\: subject name \: C=NL, O=PolarSSL, CN=PolarSSL Server 1\nMyFile(0999)\: issued on \: 2011-02-12 14\:44\:06\nMyFile(0999)\: expires on \: 2021-02-12 14\:44\:06\nMyFile(0999)\: signed using \: RSA with SHA1\nMyFile(0999)\: RSA key size \: 2048 bits\nMyFile(0999)\: value of 'crt->rsa.N' (2048 bits) is\:\nMyFile(0999)\: a9 02 1f 3d 40 6a d5 55 53 8b fd 36 ee 82 65 2e\nMyFile(0999)\: 15 61 5e 89 bf b8 e8 45 90 db ee 88 16 52 d3 f1\nMyFile(0999)\: 43 50 47 96 12 59 64 87 6b fd 2b e0 46 f9 73 be\nMyFile(0999)\: dd cf 92 e1 91 5b ed 66 a0 6f 89 29 79 45 80 d0\nMyFile(0999)\: 83 6a d5 41 43 77 5f 39 7c 09 04 47 82 b0 57 39\nMyFile(0999)\: 70 ed a3 ec 15 19 1e a8 33 08 47 c1 05 42 a9 fd\nMyFile(0999)\: 4c c3 b4 df dd 06 1f 4d 10 51 40 67 73 13 0f 40\nMyFile(0999)\: f8 6d 81 25 5f 0a b1 53 c6 30 7e 15 39 ac f9 5a\nMyFile(0999)\: ee 7f 92 9e a6 05 5b e7 13 97 85 b5 23 92 d9 d4\nMyFile(0999)\: 24 06 d5 09 25 89 75 07 dd a6 1a 8f 3f 09 19 be\nMyFile(0999)\: ad 65 2c 64 eb 95 9b dc fe 41 5e 17 a6 da 6c 5b\nMyFile(0999)\: 69 cc 02 ba 14 2c 16 24 9c 4a dc cd d0 f7 52 67\nMyFile(0999)\: 73 f1 2d a0 23 fd 7e f4 31 ca 2d 70 ca 89 0b 04\nMyFile(0999)\: db 2e a6 4f 70 6e 9e ce bd 58 89 e2 53 59 9e 6e\nMyFile(0999)\: 5a 92 65 e2 88 3f 0c 94 19 a3 dd e5 e8 9d 95 13\nMyFile(0999)\: ed 29 db ab 70 12 dc 5a ca 6b 17 ab 52 82 54 b1\nMyFile(0999)\: value of 'crt->rsa.E' (17 bits) is\:\nMyFile(0999)\: 01 00 01\n" +Debug print certificate #2 (EC) +depends_on:POLARSSL_FS_IO:POLARSSL_PEM_C:POLARSSL_BASE64_C:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP192R1_ENABLED +debug_print_crt:"data_files/test-ca2.crt":"MyFile":999:"PREFIX_":"MyFile(0999)\: PREFIX_ #1\:\nMyFile(0999)\: cert. version \: 1\nMyFile(0999)\: serial number \: F4\:15\:34\:66\:2E\:C7\:E9\:12\nMyFile(0999)\: issuer name \: CN=Test\nMyFile(0999)\: subject name \: CN=Test\nMyFile(0999)\: issued on \: 2013-07-10 09\:40\:19\nMyFile(0999)\: expires on \: 2023-07-08 09\:40\:19\nMyFile(0999)\: signed using \: ECDSA with SHA1\nMyFile(0999)\: EC key size \: 192 bits\nMyFile(0999)\: value of 'crt->eckey.Q(X)' (190 bits) is\:\nMyFile(0999)\: 21 37 96 9f ab d4 e3 70 62 4a 0e 1a 33 e3 79 ca\nMyFile(0999)\: b9 50 cc e0 0e f8 c3 c3\nMyFile(0999)\: value of 'crt->eckey.Q(Y)' (192 bits) is\:\nMyFile(0999)\: e2 ad ae b7 27 1c 8f 07 65 9d 65 d3 d7 77 dc f2\nMyFile(0999)\: 16 14 36 3a e4 b6 e6 17\nMyFile(0999)\: value of 'crt->eckey.Q(Z)' (1 bits) is\:\nMyFile(0999)\: 01\n" + Debug print mpi #1 debug_print_mpi:16:"01020304050607":"MyFile":999:"VALUE":"MyFile(0999)\: value of 'VALUE' (49 bits) is\:\nMyFile(0999)\: 01 02 03 04 05 06 07\n" diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data index def0021d4..bf13719b3 100644 --- a/tests/suites/test_suite_x509parse.data +++ b/tests/suites/test_suite_x509parse.data @@ -187,39 +187,39 @@ depends_on:POLARSSL_MD5_C:POLARSSL_PEM_C:POLARSSL_FS_IO x509parse_public_keyfile_rsa:"data_files/format_gen.pub":0 X509 Parse Public EC Key #1 (RFC 5480, DER) -depends_on:POLARSSL_ECP_C:POLARSSL_FS_IO +depends_on:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP192R1_ENABLED:POLARSSL_FS_IO x509parse_public_keyfile_ec:"data_files/ec_pub.der":0 X509 Parse Public EC Key #2 (RFC 5480, PEM) -depends_on:POLARSSL_PEM_C:POLARSSL_ECP_C:POLARSSL_FS_IO +depends_on:POLARSSL_PEM_C:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP192R1_ENABLED:POLARSSL_FS_IO x509parse_public_keyfile_ec:"data_files/ec_pub.pem":0 X509 Parse EC Key #1 (SEC1 DER) -depends_on:POLARSSL_FS_IO:POLARSSL_ECP_C +depends_on:POLARSSL_FS_IO:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP192R1_ENABLED x509parse_keyfile_ec:"data_files/ec_prv.sec1.der":NULL:0 X509 Parse EC Key #2 (SEC1 PEM) -depends_on:POLARSSL_PEM_C:POLARSSL_FS_IO:POLARSSL_ECP_C +depends_on:POLARSSL_PEM_C:POLARSSL_FS_IO:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP192R1_ENABLED x509parse_keyfile_ec:"data_files/ec_prv.sec1.pem":NULL:0 X509 Parse EC Key #3 (SEC1 PEM encrypted) -depends_on:POLARSSL_DES_C:POLARSSL_PEM_C:POLARSSL_FS_IO:POLARSSL_ECP_C +depends_on:POLARSSL_DES_C:POLARSSL_PEM_C:POLARSSL_FS_IO:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP192R1_ENABLED x509parse_keyfile_ec:"data_files/ec_prv.sec1.pw.pem":"polar":0 X509 Parse EC Key #4 (PKCS8 DER) -depends_on:POLARSSL_FS_IO:POLARSSL_ECP_C +depends_on:POLARSSL_FS_IO:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP192R1_ENABLED x509parse_keyfile_ec:"data_files/ec_prv.pk8.der":NULL:0 X509 Parse EC Key #5 (PKCS8 PEM) -depends_on:POLARSSL_PEM_C:POLARSSL_FS_IO:POLARSSL_ECP_C +depends_on:POLARSSL_PEM_C:POLARSSL_FS_IO:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP192R1_ENABLED x509parse_keyfile_ec:"data_files/ec_prv.pk8.pem":NULL:0 X509 Parse EC Key #6 (PKCS8 encrypted DER) -depends_on:POLARSSL_DES_C:POLARSSL_FS_IO:POLARSSL_ECP_C +depends_on:POLARSSL_DES_C:POLARSSL_FS_IO:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP192R1_ENABLED x509parse_keyfile_ec:"data_files/ec_prv.pk8.pw.der":"polar":0 X509 Parse EC Key #7 (PKCS8 encrypted PEM) -depends_on:POLARSSL_DES_C:POLARSSL_PEM_C:POLARSSL_FS_IO:POLARSSL_ECP_C +depends_on:POLARSSL_DES_C:POLARSSL_PEM_C:POLARSSL_FS_IO:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP192R1_ENABLED x509parse_keyfile_ec:"data_files/ec_prv.pk8.pw.pem":"polar":0 X509 Get Distinguished Name #1 @@ -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 @@ -523,7 +523,7 @@ X509 Certificate ASN1 (TBSCertificate, pubkey, no bitstring data) x509parse_crt:"30693067a0030201028204deadbeef300d06092a864886f70d0101020500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a300806001304546573743011300d06092A864886F70D01010105000300":"":POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + POLARSSL_ERR_ASN1_OUT_OF_DATA X509 Certificate ASN1 (TBSCertificate, pubkey, invalid bitstring start) -x509parse_crt:"306a3068a0030201028204deadbeef300d06092a864886f70d0101020500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a300806001304546573743012300d06092A864886F70D0101010500030101":"":POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +x509parse_crt:"306a3068a0030201028204deadbeef300d06092a864886f70d0101020500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a300806001304546573743012300d06092A864886F70D0101010500030101":"":POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + POLARSSL_ERR_ASN1_INVALID_DATA X509 Certificate ASN1 (TBSCertificate, pubkey, invalid internal bitstring length) x509parse_crt:"306d306ba0030201028204deadbeef300d06092a864886f70d0101020500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a300806001304546573743015300d06092A864886F70D0101010500030400300000":"":POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + POLARSSL_ERR_ASN1_LENGTH_MISMATCH @@ -595,7 +595,7 @@ X509 Certificate ASN1 (sig_alg, no sig) x509parse_crt:"308192308180a0030201008204deadbeef300d06092a864886f70d0101020500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092A864886F70D010101050003190030160210ffffffffffffffffffffffffffffffff0202ffff300d06092a864886f70d0101020500":"":POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE + POLARSSL_ERR_ASN1_OUT_OF_DATA X509 Certificate ASN1 (signature, invalid sig data) -x509parse_crt:"308195308180a0030201008204deadbeef300d06092a864886f70d0101020500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092A864886F70D010101050003190030160210ffffffffffffffffffffffffffffffff0202ffff300d06092a864886f70d0101020500030100":"":POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE +x509parse_crt:"308195308180a0030201008204deadbeef300d06092a864886f70d0101020500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092A864886F70D010101050003190030160210ffffffffffffffffffffffffffffffff0202ffff300d06092a864886f70d0101020500030100":"":POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE + POLARSSL_ERR_ASN1_INVALID_DATA X509 Certificate ASN1 (signature, data left) x509parse_crt:"308197308180a0030201008204deadbeef300d06092a864886f70d0101020500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092A864886F70D010101050003190030160210ffffffffffffffffffffffffffffffff0202ffff300d06092a864886f70d0101020500030200ff00":"":POLARSSL_ERR_X509_CERT_INVALID_FORMAT + POLARSSL_ERR_ASN1_LENGTH_MISMATCH @@ -633,6 +633,17 @@ x509parse_crt:"30819f308189a0030201008204deadbeef300d06092a864886f70d01010205003 X509 Certificate ASN1 (Name with unknown PKCS9 part) x509parse_crt:"30819f308189a0030201008204deadbeef300d06092a864886f70d010102050030153113301106092a864886f70d0109ab130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092A864886F70D010101050003190030160210ffffffffffffffffffffffffffffffff0202ffff300d06092a864886f70d0101020500030200ff":"cert. version \: 1\nserial number \: DE\:AD\:BE\:EF\nissuer name \: ?\?=Test\nsubject name \: ?\?=Test\nissued on \: 2009-01-01 00\:00\:00\nexpires on \: 2009-12-31 23\:59\:59\nsigned using \: RSA with MD2\nRSA key size \: 128 bits\n":0 +X509 Certificate ASN1 (ECDSA signature, RSA key) +x509parse_crt:"3081E630819E020103300906072A8648CE3D0401300F310D300B0603550403130454657374301E170D3133303731303039343631385A170D3233303730383039343631385A300F310D300B0603550403130454657374304C300D06092A864886F70D0101010500033B003038023100E8F546061D3B49BC2F6B7524B7EA4D73A8D5293EE8C64D9407B70B5D16BAEBC32B8205591EAB4E1EB57E9241883701250203010001300906072A8648CE3D0401033800303502186E18209AFBED14A0D9A796EFCAD68891E3CCD5F75815C833021900E92B4FD460B1994693243B9FFAD54729DE865381BDA41D25":"cert. version \: 1\nserial number \: 03\nissuer name \: CN=Test\nsubject name \: CN=Test\nissued on \: 2013-07-10 09\:46\:18\nexpires on \: 2023-07-08 09\:46\:18\nsigned using \: ECDSA with SHA1\nRSA key size \: 384 bits\n":0 + +X509 Certificate ASN1 (ECDSA signature, EC key) +depends_on:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP192R1_ENABLED +x509parse_crt:"3081EB3081A3020900F41534662EC7E912300906072A8648CE3D0401300F310D300B0603550403130454657374301E170D3133303731303039343031395A170D3233303730383039343031395A300F310D300B06035504031304546573743049301306072A8648CE3D020106082A8648CE3D030101033200042137969FABD4E370624A0E1A33E379CAB950CCE00EF8C3C3E2ADAEB7271C8F07659D65D3D777DCF21614363AE4B6E617300906072A8648CE3D04010338003035021858CC0F957946FE6A303D92885A456AA74C743C7B708CBD37021900FE293CAC21AF352D16B82EB8EA54E9410B3ABAADD9F05DD6":"cert. version \: 1\nserial number \: F4\:15\:34\:66\:2E\:C7\:E9\:12\nissuer name \: CN=Test\nsubject name \: CN=Test\nissued on \: 2013-07-10 09\:40\:19\nexpires on \: 2023-07-08 09\:40\:19\nsigned using \: ECDSA with SHA1\nEC key size \: 192 bits\n":0 + +X509 Certificate ASN1 (RSA signature, EC key) +depends_on:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP192R1_ENABLED +x509parse_crt:"3081E430819F020104300D06092A864886F70D0101050500300F310D300B0603550403130454657374301E170D3133303731303135303233375A170D3233303730383135303233375A300F310D300B06035504031304546573743049301306072A8648CE3D020106082A8648CE3D03010103320004E962551A325B21B50CF6B990E33D4318FD16677130726357A196E3EFE7107BCB6BDC6D9DB2A4DF7C964ACFE81798433D300D06092A864886F70D01010505000331001A6C18CD1E457474B2D3912743F44B571341A7859A0122774A8E19A671680878936949F904C9255BDD6FFFDB33A7E6D8":"cert. version \: 1\nserial number \: 04\nissuer name \: CN=Test\nsubject name \: CN=Test\nissued on \: 2013-07-10 15\:02\:37\nexpires on \: 2023-07-08 15\:02\:37\nsigned using \: RSA with SHA1\nEC key size \: 192 bits\n":0 + X509 CRL ASN1 (Incorrect first tag) x509parse_crl:"":"":POLARSSL_ERR_X509_CERT_INVALID_FORMAT