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