diff --git a/ChangeLog b/ChangeLog index a81e3a6ea..de9ba3c6d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,6 +8,7 @@ Features This allows reading encrypted PEM files produced by software that uses PBKDF2-SHA2, such as OpenSSL 1.1. Submitted by Antonio Quartulli, OpenVPN Inc. Fixes #1339 + * Add support for public keys encoded in PKCS#1 format. #1122 Bugfix * Fix the name of a DHE parameter that was accidentally changed in 2.7.0. diff --git a/library/pkparse.c b/library/pkparse.c index b4def4f91..aae178548 100644 --- a/library/pkparse.c +++ b/library/pkparse.c @@ -1348,11 +1348,45 @@ int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx, { int ret; unsigned char *p; +#if defined(MBEDTLS_RSA_C) + const mbedtls_pk_info_t *pk_info; +#endif #if defined(MBEDTLS_PEM_PARSE_C) size_t len; mbedtls_pem_context pem; mbedtls_pem_init( &pem ); +#if defined(MBEDTLS_RSA_C) + /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ + if( keylen == 0 || key[keylen - 1] != '\0' ) + ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; + else + ret = mbedtls_pem_read_buffer( &pem, + "-----BEGIN RSA PUBLIC KEY-----", + "-----END RSA PUBLIC KEY-----", + key, NULL, 0, &len ); + + if( ret == 0 ) + { + p = pem.buf; + if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == NULL ) + return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); + + if( ( ret = mbedtls_pk_setup( ctx, pk_info ) ) != 0 ) + return( ret ); + + if ( ( ret = pk_get_rsapubkey( &p, p + pem.buflen, mbedtls_pk_rsa( *ctx ) ) ) != 0 ) + mbedtls_pk_free( ctx ); + + mbedtls_pem_free( &pem ); + return( ret ); + } + else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) + { + mbedtls_pem_free( &pem ); + return( ret ); + } +#endif /* MBEDTLS_RSA_C */ /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ if( keylen == 0 || key[keylen - 1] != '\0' ) @@ -1368,23 +1402,43 @@ int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx, /* * Was PEM encoded */ - key = pem.buf; - keylen = pem.buflen; + p = pem.buf; + + ret = mbedtls_pk_parse_subpubkey( &p, p + pem.buflen, ctx ); + mbedtls_pem_free( &pem ); + return( ret ); } else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) { mbedtls_pem_free( &pem ); return( ret ); } + mbedtls_pem_free( &pem ); #endif /* MBEDTLS_PEM_PARSE_C */ + +#if defined(MBEDTLS_RSA_C) + if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == NULL ) + return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); + + if( ( ret = mbedtls_pk_setup( ctx, pk_info ) ) != 0 ) + return( ret ); + + p = (unsigned char *)key; + ret = pk_get_rsapubkey( &p, p + keylen, mbedtls_pk_rsa( *ctx ) ); + if( ret == 0 ) + { + return( ret ); + } + mbedtls_pk_free( ctx ); + if( ret != ( MBEDTLS_ERR_PK_INVALID_PUBKEY + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) ) + { + return( ret ); + } +#endif /* MBEDTLS_RSA_C */ p = (unsigned char *) key; ret = mbedtls_pk_parse_subpubkey( &p, p + keylen, ctx ); -#if defined(MBEDTLS_PEM_PARSE_C) - mbedtls_pem_free( &pem ); -#endif - return( ret ); } diff --git a/tests/data_files/Makefile b/tests/data_files/Makefile index 049e8cf00..0380633df 100644 --- a/tests/data_files/Makefile +++ b/tests/data_files/Makefile @@ -66,7 +66,21 @@ server2-sha256.crt: server2-rsa.csr $(OPENSSL) x509 -req -extfile $(cli_crt_extensions_file) -extensions cli-rsa -CA test-ca-sha256.crt -CAkey $(test_ca_key_file_rsa) -passin "pass:$(test_ca_pwd_rsa)" -set_serial 4 -days 3653 -sha256 -in server2-rsa.csr -out $@ all_final += server2-sha256.crt +rsa_pkcs1_2048_public.pem: server8.key + $(OPENSSL) rsa -in $< -outform PEM -RSAPublicKey_out -out $@ +all_final += rsa_pkcs1_2048_public.pem +rsa_pkcs1_2048_public.der: rsa_pkcs1_2048_public.pem + $(OPENSSL) rsa -RSAPublicKey_in -in $< -outform DER -RSAPublicKey_out -out $@ +all_final += rsa_pkcs1_2048_public.der + +rsa_pkcs8_2048_public.pem: server8.key + $(OPENSSL) rsa -in $< -outform PEM -pubout -out $@ +all_final += rsa_pkcs8_2048_public.pem + +rsa_pkcs8_2048_public.der: rsa_pkcs8_2048_public.pem + $(OPENSSL) rsa -pubin -in $< -outform DER -pubout -out $@ +all_final += rsa_pkcs8_2048_public.der ################################################################ #### Generate various RSA keys diff --git a/tests/data_files/rsa_pkcs1_2048_public.der b/tests/data_files/rsa_pkcs1_2048_public.der new file mode 100644 index 000000000..b6865144a Binary files /dev/null and b/tests/data_files/rsa_pkcs1_2048_public.der differ diff --git a/tests/data_files/rsa_pkcs1_2048_public.pem b/tests/data_files/rsa_pkcs1_2048_public.pem new file mode 100644 index 000000000..9040cb04d --- /dev/null +++ b/tests/data_files/rsa_pkcs1_2048_public.pem @@ -0,0 +1,8 @@ +-----BEGIN RSA PUBLIC KEY----- +MIIBCgKCAQEA2xx/LgvNv87RdRCgorjOfariBeB62ERjj7W9wLAZuTe4GUoO8V10 +gGdGhwbeW38GA73BjV4HFdRb9Nzlzz35wREsrmq5ir0dZ2YX6k692xWagofk8HjD +o4WHsP2fqZlf4zPszOoLtWFe8Ul+P6Mt6gEMzEKadpvE0DfTsRcBYQEWWX4cF8NT +/dFyy0xgFdp94uqtUO+O4ovUandV1nDZa7vx7jkEOKO94tHgZmvinEeZ6Sjmtvwu +ymdDhOjVg9admGsBPoHcPHrK+fOc99YoGyd4fMPQ1WOngTSJrSVqvfLq7fpX/OU0 +xsEPcS3SCBAbrURB4P55oGOTirFd6bDubwIDAQAB +-----END RSA PUBLIC KEY----- diff --git a/tests/data_files/rsa_pkcs8_1024_public.der b/tests/data_files/rsa_pkcs8_1024_public.der new file mode 100644 index 000000000..fe429985b Binary files /dev/null and b/tests/data_files/rsa_pkcs8_1024_public.der differ diff --git a/tests/data_files/rsa_pkcs8_2048_public.der b/tests/data_files/rsa_pkcs8_2048_public.der new file mode 100644 index 000000000..8644a5647 Binary files /dev/null and b/tests/data_files/rsa_pkcs8_2048_public.der differ diff --git a/tests/data_files/rsa_pkcs8_2048_public.pem b/tests/data_files/rsa_pkcs8_2048_public.pem new file mode 100644 index 000000000..f1e29cc6e --- /dev/null +++ b/tests/data_files/rsa_pkcs8_2048_public.pem @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2xx/LgvNv87RdRCgorjO +fariBeB62ERjj7W9wLAZuTe4GUoO8V10gGdGhwbeW38GA73BjV4HFdRb9Nzlzz35 +wREsrmq5ir0dZ2YX6k692xWagofk8HjDo4WHsP2fqZlf4zPszOoLtWFe8Ul+P6Mt +6gEMzEKadpvE0DfTsRcBYQEWWX4cF8NT/dFyy0xgFdp94uqtUO+O4ovUandV1nDZ +a7vx7jkEOKO94tHgZmvinEeZ6SjmtvwuymdDhOjVg9admGsBPoHcPHrK+fOc99Yo +Gyd4fMPQ1WOngTSJrSVqvfLq7fpX/OU0xsEPcS3SCBAbrURB4P55oGOTirFd6bDu +bwIDAQAB +-----END PUBLIC KEY----- diff --git a/tests/suites/test_suite_pkparse.data b/tests/suites/test_suite_pkparse.data index 1bf062704..496b5b318 100644 --- a/tests/suites/test_suite_pkparse.data +++ b/tests/suites/test_suite_pkparse.data @@ -939,8 +939,18 @@ depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha512.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT Parse Public RSA Key #1 (PKCS#8 wrapped) -depends_on:MBEDTLS_MD5_C:MBEDTLS_PEM_PARSE_C -pk_parse_public_keyfile_rsa:"data_files/format_gen.pub":0 +depends_on:MBEDTLS_PEM_PARSE_C +pk_parse_public_keyfile_rsa:"data_files/rsa_pkcs8_2048_public.pem":0 + +Parse Public RSA Key #1 (PKCS#8 wrapped, DER) +pk_parse_public_keyfile_rsa:"data_files/rsa_pkcs8_2048_public.der":0 + +Parse Public RSA Key #3 (PKCS#1 wrapped) +depends_on:MBEDTLS_PEM_PARSE_C +pk_parse_public_keyfile_rsa:"data_files/rsa_pkcs1_2048_public.pem":0 + +Parse Public RSA Key #4 (PKCS#1 wrapped, DER) +pk_parse_public_keyfile_rsa:"data_files/rsa_pkcs1_2048_public.der":0 Parse Public EC Key #1 (RFC 5480, DER) depends_on:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP192R1_ENABLED