diff --git a/include/polarssl/x509.h b/include/polarssl/x509.h index 240b9bbba..f0c0e7aac 100644 --- a/include/polarssl/x509.h +++ b/include/polarssl/x509.h @@ -472,9 +472,9 @@ int x509parse_public_keyfile_rsa( rsa_context *rsa, const char *path ); /** \ingroup x509_module */ /** - * \brief Parse a private EC key + * \brief Parse a private key * - * \param eckey EC key to be initialized + * \param ctx key to be initialized * \param key input buffer * \param keylen size of the buffer * \param pwd password for decryption (optional) @@ -482,46 +482,46 @@ int x509parse_public_keyfile_rsa( rsa_context *rsa, const char *path ); * * \return 0 if successful, or a specific X509 or PEM error code */ -int x509parse_key_ec( ecp_keypair *eckey, - const unsigned char *key, size_t keylen, - const unsigned char *pwd, size_t pwdlen ); +int x509parse_key( pk_context *ctx, + const unsigned char *key, size_t keylen, + const unsigned char *pwd, size_t pwdlen ); /** \ingroup x509_module */ /** - * \brief Load and parse a private EC key + * \brief Load and parse a private key * - * \param eckey EC key to be initialized + * \param ctx key to be initialized * \param path filename to read the private key from * \param password password to decrypt the file (can be NULL) * * \return 0 if successful, or a specific X509 or PEM error code */ -int x509parse_keyfile_ec( ecp_keypair *eckey, - const char *path, const char *password ); +int x509parse_keyfile( pk_context *ctx, + const char *path, const char *password ); /** \ingroup x509_module */ /** - * \brief Parse a public EC key + * \brief Parse a public key * - * \param eckey EC key to be initialized + * \param ctx key to be initialized * \param key input buffer * \param keylen size of the buffer * * \return 0 if successful, or a specific X509 or PEM error code */ -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 ); /** \ingroup x509_module */ /** - * \brief Load and parse a public EC key + * \brief Load and parse a public key * - * \param eckey EC key to be initialized + * \param ctx key to be initialized * \param path filename to read the private key from * * \return 0 if successful, or a specific X509 or PEM error code */ -int x509parse_public_keyfile_ec( ecp_keypair *eckey, const char *path ); +int x509parse_public_keyfile( pk_context *ctx, const char *path ); /** \ingroup x509_module */ /** diff --git a/library/x509parse.c b/library/x509parse.c index 55149e48b..179ff959d 100644 --- a/library/x509parse.c +++ b/library/x509parse.c @@ -511,12 +511,14 @@ static int x509_get_pubkey( unsigned char **p, /* * only RSA public keys handled at this time */ - if( oid_get_pk_alg( pk_alg_oid, &pk_alg ) != 0 || - pk_alg != POLARSSL_PK_RSA ) + if( oid_get_pk_alg( pk_alg_oid, &pk_alg ) != 0 ) { return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG ); } + if (pk_alg != POLARSSL_PK_RSA ) + return( POLARSSL_ERR_X509_CERT_INVALID_ALG ); + if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 ) return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret ); @@ -2079,12 +2081,11 @@ int x509parse_public_keyfile_rsa( rsa_context *rsa, const char *path ) return( ret ); } -#if defined(POLARSSL_ECP_C) /* - * Load and parse a private EC key + * Load and parse a private key */ -int x509parse_keyfile_ec( ecp_keypair *eckey, - const char *path, const char *pwd ) +int x509parse_keyfile( pk_context *ctx, + const char *path, const char *pwd ) { int ret; size_t n; @@ -2094,9 +2095,9 @@ int x509parse_keyfile_ec( ecp_keypair *eckey, return( ret ); if( pwd == NULL ) - ret = x509parse_key_ec( eckey, buf, n, NULL, 0 ); + ret = x509parse_key( ctx, buf, n, NULL, 0 ); else - ret = x509parse_key_ec( eckey, buf, n, + ret = x509parse_key( ctx, buf, n, (const unsigned char *) pwd, strlen( pwd ) ); memset( buf, 0, n + 1 ); @@ -2106,9 +2107,9 @@ int x509parse_keyfile_ec( ecp_keypair *eckey, } /* - * Load and parse a public EC key + * Load and parse a public key */ -int x509parse_public_keyfile_ec( ecp_keypair *eckey, const char *path ) +int x509parse_public_keyfile( pk_context *ctx, const char *path ) { int ret; size_t n; @@ -2117,14 +2118,14 @@ int x509parse_public_keyfile_ec( ecp_keypair *eckey, const char *path ) if ( (ret = load_file( path, &buf, &n ) ) != 0 ) return( ret ); - ret = x509parse_public_key_ec( eckey, buf, n ); + ret = x509parse_public_key( ctx, buf, n ); memset( buf, 0, n + 1 ); free( buf ); return( ret ); } -#endif /* defined(POLARSSL_ECP_C) */ + #endif /* POLARSSL_FS_IO */ /* @@ -2259,12 +2260,14 @@ static int x509parse_key_pkcs8_unencrypted_der( /* * only RSA keys handled at this time */ - if( oid_get_pk_alg( &pk_alg_oid, &pk_alg ) != 0 || - pk_alg != POLARSSL_PK_RSA ) + 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 */ @@ -2791,7 +2794,7 @@ static int x509parse_key_pkcs8_unencrypted_der_ec( return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG ); if( pk_alg != POLARSSL_PK_ECKEY && pk_alg != POLARSSL_PK_ECKEY_DH ) - return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG ); + return( POLARSSL_ERR_X509_CERT_INVALID_ALG ); if( pk_alg == POLARSSL_PK_ECKEY_DH ) eck->alg = POLARSSL_ECP_KEY_ALG_ECDH; @@ -2853,9 +2856,9 @@ static int x509parse_key_pkcs8_encrypted_der_ec( /* * Parse a private EC key */ -int x509parse_key_ec( ecp_keypair *eck, - const unsigned char *key, size_t keylen, - const unsigned char *pwd, size_t pwdlen ) +static int x509parse_key_ec( ecp_keypair *eck, + const unsigned char *key, size_t keylen, + const unsigned char *pwd, size_t pwdlen ) { int ret; @@ -2994,7 +2997,7 @@ static int x509parse_public_key_ec_der( ecp_keypair *key, return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG ); if( alg != POLARSSL_PK_ECKEY && alg != POLARSSL_PK_ECKEY_DH ) - return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG ); + return( POLARSSL_ERR_X509_CERT_INVALID_ALG ); if( alg == POLARSSL_PK_ECKEY_DH ) key->alg = POLARSSL_ECP_KEY_ALG_ECDH; @@ -3016,8 +3019,8 @@ static int x509parse_public_key_ec_der( ecp_keypair *key, /* * Parse a public EC key */ -int x509parse_public_key_ec( ecp_keypair *eckey, - const unsigned char *key, size_t keylen ) +static int x509parse_public_key_ec( ecp_keypair *eckey, + const unsigned char *key, size_t keylen ) { int ret; #if defined(POLARSSL_PEM_C) @@ -3059,6 +3062,58 @@ int x509parse_public_key_ec( ecp_keypair *eckey, } #endif /* defined(POLARSSL_ECP_C) */ +/* + * Parse a private key + */ +int x509parse_key( pk_context *ctx, + const unsigned char *key, size_t keylen, + const unsigned char *pwd, size_t pwdlen ) +{ + int ret; + + if ( ( ret = pk_set_type( ctx, POLARSSL_PK_RSA ) ) != 0 ) + return( ret ); + + 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 ); +} + +/* + * Parse a public key + */ +int x509parse_public_key( pk_context *ctx, + const unsigned char *key, size_t keylen ) +{ + int ret; + + if ( ( ret = pk_set_type( ctx, POLARSSL_PK_RSA ) ) != 0 ) + return( ret ); + + 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 ); +} + #if defined(POLARSSL_DHM_C) /* * Parse DHM parameters diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function index 57653f798..2baf76416 100644 --- a/tests/suites/test_suite_x509parse.function +++ b/tests/suites/test_suite_x509parse.function @@ -182,42 +182,48 @@ END_CASE BEGIN_CASE x509parse_public_keyfile_ec:key_file:result { - ecp_keypair eckey; + pk_context ctx; int res; - ecp_keypair_init( &eckey ); + pk_init( &ctx ); - res = x509parse_public_keyfile_ec( &eckey, {key_file} ); + res = x509parse_public_keyfile( &ctx, {key_file} ); TEST_ASSERT( res == {result} ); if( res == 0 ) { - TEST_ASSERT( ecp_check_pubkey( &eckey.grp, &eckey.Q ) == 0 ); + ecp_keypair *eckey; + TEST_ASSERT( ctx.type == POLARSSL_PK_ECKEY ); + eckey = (ecp_keypair *) ctx.data; + TEST_ASSERT( ecp_check_pubkey( &eckey->grp, &eckey->Q ) == 0 ); } - ecp_keypair_free( &eckey ); + pk_free( &ctx ); } END_CASE BEGIN_CASE x509parse_keyfile_ec:key_file:password:result { - ecp_keypair eckey; + pk_context ctx; int res; - ecp_keypair_init( &eckey ); + pk_init( &ctx ); - res = x509parse_keyfile_ec( &eckey, {key_file}, {password} ); + res = x509parse_keyfile( &ctx, {key_file}, {password} ); TEST_ASSERT( res == {result} ); if( res == 0 ) { - TEST_ASSERT( ecp_check_prvkey( &eckey.grp, &eckey.d ) == 0 ); + ecp_keypair *eckey; + TEST_ASSERT( ctx.type == POLARSSL_PK_ECKEY ); + eckey = (ecp_keypair *) ctx.data; + TEST_ASSERT( ecp_check_prvkey( &eckey->grp, &eckey->d ) == 0 ); } - ecp_keypair_free( &eckey ); + pk_free( &ctx ); } END_CASE