- RSASSA-PSS verification now properly handles salt lengths other than hlen
diff --git a/library/x509parse.c b/library/x509parse.c
index e330743..df671ef 100644
--- a/library/x509parse.c
+++ b/library/x509parse.c
@@ -1827,8 +1827,6 @@
#endif
end = p + keylen;
- memset( rsa, 0, sizeof( rsa_context ) );
-
/*
* RSAPrivateKey ::= SEQUENCE {
* version Version,
@@ -1942,6 +1940,116 @@
}
/*
+ * Parse a public RSA key
+ */
+int x509parse_public_key( rsa_context *rsa, const unsigned char *key, int keylen )
+{
+ int ret, 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_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 );
+}
+
+/*
+ * Load and parse a public RSA key
+ */
+int x509parse_public_keyfile( rsa_context *rsa, const char *path )
+{
+ int ret;
+ size_t n;
+ unsigned char *buf;
+
+ if ( load_file( path, &buf, &n ) )
+ return( 1 );
+
+ ret = x509parse_public_key( rsa, buf, (int) n );
+
+ memset( buf, 0, n + 1 );
+ free( buf );
+
+ return( ret );
+}
+
+/*
* Parse DHM parameters
*/
int x509parse_dhm( dhm_context *dhm, const unsigned char *dhmin, int dhminlen )