Merge branch 'parse-ec-crt' into development
diff --git a/include/polarssl/asn1.h b/include/polarssl/asn1.h
index ae498d0..195ebcb 100644
--- a/include/polarssl/asn1.h
+++ b/include/polarssl/asn1.h
@@ -213,6 +213,19 @@
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 <tag>"
* Updated the pointer to immediately behind the full sequence tag.
*
diff --git a/include/polarssl/ecp.h b/include/polarssl/ecp.h
index c1f08c9..7bd9bd5 100644
--- a/include/polarssl/ecp.h
+++ b/include/polarssl/ecp.h
@@ -95,18 +95,12 @@
* \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 @@
* 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 @@
*/
#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 a39055b..0c3dab2 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 00f8cfc..df3fc44 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 @@
*/
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 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 @@
* \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 f0c0e7a..3315535 100644
--- a/include/polarssl/x509.h
+++ b/include/polarssl/x509.h
@@ -211,8 +211,7 @@
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_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 @@
* \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 5b86aa6..f6b79ef 100644
--- a/library/asn1parse.c
+++ b/library/asn1parse.c
@@ -209,6 +209,24 @@
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 <tag>"
diff --git a/library/debug.c b/library/debug.c
index 23b9019..8e3dd03 100644
--- a/library/debug.c
+++ b/library/debug.c
@@ -250,11 +250,25 @@
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 9e7a967..1468312 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -101,7 +101,6 @@
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 @@
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 0a739b5..560c54c 100644
--- a/library/error.c
+++ b/library/error.c
@@ -250,6 +250,8 @@
#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 449b3e1..750ece8 100644
--- a/library/oid.c
+++ b/library/oid.c
@@ -299,6 +299,26 @@
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 @@
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 71505ed..78ff5e9 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 <stdlib.h>
@@ -46,6 +49,7 @@
ctx->type = POLARSSL_PK_NONE;
ctx->data = NULL;
+ ctx->dont_free = 0;
}
/*
@@ -56,26 +60,27 @@
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 @@
*/
int pk_set_type( pk_context *ctx, pk_type_t type )
{
- size_t size = 0;
+ size_t size;
- switch( type )
- {
+ if( ctx->type == type )
+ return( 0 );
+
+ if( ctx->type != POLARSSL_PK_NONE )
+ return( POLARSSL_ERR_PK_TYPE_MISMATCH );
+
#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 @@
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 66ebcef..aeba799 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -1072,8 +1072,12 @@
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 @@
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 @@
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 @@
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 c6a8273..2aef9c4 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -1968,7 +1968,11 @@
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 @@
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 c5f9049..a11c064 100644
--- a/library/x509parse.c
+++ b/library/x509parse.c
@@ -160,47 +160,59 @@
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_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 @@
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_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 @@
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 @@
*
* 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 @@
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 @@
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 @@
* 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 @@
* 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 );
@@ -2038,50 +2072,6 @@
}
/*
- * 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
*/
int x509parse_keyfile( pk_context *ctx,
@@ -2126,8 +2116,36 @@
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 @@
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 @@
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 @@
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 @@
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 @@
#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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
* 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 x509parse_public_key( pk_context *ctx,
+ const unsigned char *key, size_t keylen )
{
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 ret;
+ unsigned char *p;
#if defined(POLARSSL_PEM_C)
size_t len;
pem_context pem;
@@ -3047,12 +2710,9 @@
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 @@
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 @@
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 @@
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 @@
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 @@
{
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 @@
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 bf4684b..ec824c9 100644
--- a/programs/test/ssl_cert_test.c
+++ b/programs/test/ssl_cert_test.c
@@ -206,19 +206,28 @@
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 0000000..c47c496
--- /dev/null
+++ b/tests/data_files/test-ca2.crt
Binary files differ
diff --git a/tests/data_files/test-ca2.key b/tests/data_files/test-ca2.key
new file mode 100644
index 0000000..2725398
--- /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 824db64..7a309ce 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 def0021..bf13719 100644
--- a/tests/suites/test_suite_x509parse.data
+++ b/tests/suites/test_suite_x509parse.data
@@ -187,39 +187,39 @@
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 @@
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 @@
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 @@
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 @@
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