Add x509parse_{,public}_key{,file}()

Also make previously public *_ec functions private.
diff --git a/include/polarssl/x509.h b/include/polarssl/x509.h
index 240b9bb..f0c0e7a 100644
--- a/include/polarssl/x509.h
+++ b/include/polarssl/x509.h
@@ -472,9 +472,9 @@
 
 /** \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 @@
  *
  * \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 55149e4..179ff95 100644
--- a/library/x509parse.c
+++ b/library/x509parse.c
@@ -511,12 +511,14 @@
     /*
      * 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 @@
     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 @@
         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 @@
 }
 
 /*
- * 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 @@
     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 @@
     /*
      * 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 @@
         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 @@
 /*
  * 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 @@
         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 @@
 /*
  * 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 @@
 }
 #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 57653f7..2baf764 100644
--- a/tests/suites/test_suite_x509parse.function
+++ b/tests/suites/test_suite_x509parse.function
@@ -182,42 +182,48 @@
 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