From ab6345e765dbe7e2766d48bdb8dcd7ad9e862183 Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin Date: Tue, 17 Mar 2020 09:33:36 +0100 Subject: public_key: Make OTP-PKIX RSASSA-PSS aware --- lib/public_key/asn1/OTP-PKIX.asn1 | 18 ++++++++- lib/public_key/src/public_key.erl | 44 ++++++++++++++-------- lib/public_key/test/public_key_SUITE.erl | 15 +++++++- .../test/public_key_SUITE_data/rsa_pss_pss_key.pem | 29 ++++++++++++++ 4 files changed, 87 insertions(+), 19 deletions(-) create mode 100644 lib/public_key/test/public_key_SUITE_data/rsa_pss_pss_key.pem (limited to 'lib/public_key') diff --git a/lib/public_key/asn1/OTP-PKIX.asn1 b/lib/public_key/asn1/OTP-PKIX.asn1 index ff3250b383..e1d8f2e121 100644 --- a/lib/public_key/asn1/OTP-PKIX.asn1 +++ b/lib/public_key/asn1/OTP-PKIX.asn1 @@ -122,7 +122,9 @@ IMPORTS sha224WithRSAEncryption, sha256WithRSAEncryption, sha384WithRSAEncryption, - sha512WithRSAEncryption + sha512WithRSAEncryption, + id-RSASSA-PSS, + RSASSA-PSS-params FROM PKCS-1 { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-1(1) @@ -341,6 +343,7 @@ SupportedSignatureAlgorithms SIGNATURE-ALGORITHM-CLASS ::= { sha256-with-rsa-encryption | sha384-with-rsa-encryption | sha512-with-rsa-encryption | + rsassa-pss | ecdsa-with-sha1 | ecdsa-with-sha224 | ecdsa-with-sha256 | @@ -348,7 +351,7 @@ SupportedSignatureAlgorithms SIGNATURE-ALGORITHM-CLASS ::= { ecdsa-with-sha512 } SupportedPublicKeyAlgorithms PUBLIC-KEY-ALGORITHM-CLASS ::= { - dsa | rsa-encryption | dh | kea | ec-public-key } + dsa | rsa-encryption | rsa-pss | dh | kea | ec-public-key } -- DSA Keys and Signatures @@ -430,6 +433,11 @@ SupportedPublicKeyAlgorithms PUBLIC-KEY-ALGORITHM-CLASS ::= { ID sha512WithRSAEncryption TYPE NULL } + rsassa-pss SIGNATURE-ALGORITHM-CLASS ::= { + ID id-RSASSA-PSS + TYPE RSASSA-PSS-params } + + -- Certificate.signature -- See PKCS #1 (RFC 2313). XXX @@ -440,6 +448,11 @@ SupportedPublicKeyAlgorithms PUBLIC-KEY-ALGORITHM-CLASS ::= { TYPE NULL PUBLIC-KEY-TYPE RSAPublicKey } + rsa-pss PUBLIC-KEY-ALGORITHM-CLASS ::= { + ID id-RSASSA-PSS + TYPE RSASSA-PSS-params + PUBLIC-KEY-TYPE RSAPublicKey } + -- -- Diffie-Hellman Keys -- @@ -494,6 +507,7 @@ SupportedPublicKeyAlgorithms PUBLIC-KEY-ALGORITHM-CLASS ::= { ID ecdsa-with-SHA512 TYPE EcpkParameters } -- XXX Must be empty and not NULL + FIELD-ID-CLASS ::= CLASS { &id OBJECT IDENTIFIER UNIQUE, &Type } diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl index 996cf9db2c..e399c73d40 100644 --- a/lib/public_key/src/public_key.erl +++ b/lib/public_key/src/public_key.erl @@ -292,6 +292,12 @@ der_priv_key_decode({'PrivateKeyInfo', v1, der_priv_key_decode({'PrivateKeyInfo', v1, {'PrivateKeyInfo_privateKeyAlgorithm', ?'rsaEncryption', _}, PrivKey, _}) -> der_decode('RSAPrivateKey', PrivKey); +der_priv_key_decode({'PrivateKeyInfo', v1, + {'PrivateKeyInfo_privateKeyAlgorithm', ?'id-RSASSA-PSS', + {asn1_OPENTYPE, Parameters}}, PrivKey, _}) -> + Key = der_decode('RSAPrivateKey', PrivKey), + Params = der_decode('RSASSA-PSS-params', Parameters), + {Key, Params}; der_priv_key_decode({'PrivateKeyInfo', v1, {'PrivateKeyInfo_privateKeyAlgorithm', ?'id-dsa', {asn1_OPENTYPE, Parameters}}, PrivKey, _}) -> {params, #'Dss-Parms'{p=P, q=Q, g=G}} = der_decode('DSAParams', Parameters), @@ -307,34 +313,40 @@ der_priv_key_decode(PKCS8Key) -> %% %% Description: Encodes a public key entity with asn1 DER encoding. %%-------------------------------------------------------------------- - der_encode('PrivateKeyInfo', #'DSAPrivateKey'{p=P, q=Q, g=G, x=X}) -> der_encode('PrivateKeyInfo', - {'PrivateKeyInfo', v1, - {'PrivateKeyInfo_privateKeyAlgorithm', ?'id-dsa', - {asn1_OPENTYPE, der_encode('Dss-Parms', #'Dss-Parms'{p=P, q=Q, g=G})}}, + {'PrivateKeyInfo', v1, + {'PrivateKeyInfo_privateKeyAlgorithm', ?'id-dsa', + {asn1_OPENTYPE, der_encode('Dss-Parms', #'Dss-Parms'{p=P, q=Q, g=G})}}, der_encode('Prime-p', X), asn1_NOVALUE}); der_encode('PrivateKeyInfo', #'RSAPrivateKey'{} = PrivKey) -> der_encode('PrivateKeyInfo', - {'PrivateKeyInfo', v1, - {'PrivateKeyInfo_privateKeyAlgorithm', ?'rsaEncryption', {asn1_OPENTYPE, ?DER_NULL}}, - der_encode('RSAPrivateKey', PrivKey), asn1_NOVALUE}); + {'PrivateKeyInfo', v1, + {'PrivateKeyInfo_privateKeyAlgorithm', ?'rsaEncryption', + {asn1_OPENTYPE, ?DER_NULL}}, + der_encode('RSAPrivateKey', PrivKey), asn1_NOVALUE}); +der_encode('PrivateKeyInfo', {#'RSAPrivateKey'{} = PrivKey, Parameters}) -> + der_encode('PrivateKeyInfo', + {'PrivateKeyInfo', v1, + {'PrivateKeyInfo_privateKeyAlgorithm', ?'id-RSASSA-PSS', + {asn1_OPENTYPE, der_encode('RSASSA-PSS-params', Parameters)}}, + der_encode('RSAPrivateKey', PrivKey), asn1_NOVALUE}); der_encode('PrivateKeyInfo', #'ECPrivateKey'{parameters = Parameters} = PrivKey) -> der_encode('PrivateKeyInfo', - {'PrivateKeyInfo', v1, + {'PrivateKeyInfo', v1, {'PrivateKeyInfo_privateKeyAlgorithm', ?'id-ecPublicKey', - {asn1_OPENTYPE, der_encode('EcpkParameters', Parameters)}}, - der_encode('ECPrivateKey', PrivKey#'ECPrivateKey'{parameters = asn1_NOVALUE}), asn1_NOVALUE}); + {asn1_OPENTYPE, der_encode('EcpkParameters', Parameters)}}, + der_encode('ECPrivateKey', PrivKey#'ECPrivateKey'{parameters = asn1_NOVALUE}), + asn1_NOVALUE}); der_encode(Asn1Type, Entity) when (Asn1Type == 'PrivateKeyInfo') or (Asn1Type == 'EncryptedPrivateKeyInfo') -> try - {ok, Encoded} = 'PKCS-FRAME':encode(Asn1Type, Entity), - Encoded - catch + {ok, Encoded} = 'PKCS-FRAME':encode(Asn1Type, Entity), + Encoded + catch error:{badmatch, {error, _}} = Error -> - erlang:error(Error) - end; - + erlang:error(Error) + end; der_encode(Asn1Type, Entity) when is_atom(Asn1Type) -> try {ok, Encoded} = 'OTP-PUB-KEY':encode(Asn1Type, Entity), diff --git a/lib/public_key/test/public_key_SUITE.erl b/lib/public_key/test/public_key_SUITE.erl index 97a1f14de9..f797cf2725 100644 --- a/lib/public_key/test/public_key_SUITE.erl +++ b/lib/public_key/test/public_key_SUITE.erl @@ -56,7 +56,7 @@ all() -> ]. groups() -> - [{pem_decode_encode, [], [dsa_pem, rsa_pem, ec_pem, encrypted_pem, + [{pem_decode_encode, [], [dsa_pem, rsa_pem, rsa_pss_pss_pem, ec_pem, encrypted_pem, dh_pem, cert_pem, pkcs7_pem, pkcs10_pem, ec_pem2, rsa_priv_pkcs8, dsa_priv_pkcs8, ec_priv_pkcs8, ec_pem_encode_generated, @@ -204,6 +204,19 @@ rsa_pem(Config) when is_list(Config) -> RSARawPemNoEndNewLines = strip_superfluous_newlines(RSARawPem), RSARawPemNoEndNewLines = strip_superfluous_newlines(public_key:pem_encode([PubEntry1])). +rsa_pss_pss_pem() -> + [{doc, "RSA PKCS8 RSASSA-PSS private key decode/encode"}]. +rsa_pss_pss_pem(Config) when is_list(Config) -> + Datadir = proplists:get_value(data_dir, Config), + {ok, RsaPem} = file:read_file(filename:join(Datadir, "rsa_pss_pss_key.pem")), + [{'PrivateKeyInfo', DerRSAKey, not_encrypted} = Entry0 ] = public_key:pem_decode(RsaPem), + {RSAKey, Parms} = public_key:der_decode('PrivateKeyInfo', DerRSAKey), + {RSAKey, Parms} = public_key:pem_entry_decode(Entry0), + true = check_entry_type(RSAKey, 'RSAPrivateKey'), + PrivEntry0 = public_key:pem_entry_encode('PrivateKeyInfo', {RSAKey, Parms}), + RSAPemNoEndNewLines = strip_superfluous_newlines(RsaPem), + RSAPemNoEndNewLines = strip_superfluous_newlines(public_key:pem_encode([PrivEntry0])). + rsa_priv_pkcs8() -> [{doc, "RSA PKCS8 private key decode/encode"}]. rsa_priv_pkcs8(Config) when is_list(Config) -> diff --git a/lib/public_key/test/public_key_SUITE_data/rsa_pss_pss_key.pem b/lib/public_key/test/public_key_SUITE_data/rsa_pss_pss_key.pem new file mode 100644 index 0000000000..65032269c1 --- /dev/null +++ b/lib/public_key/test/public_key_SUITE_data/rsa_pss_pss_key.pem @@ -0,0 +1,29 @@ +-----BEGIN PRIVATE KEY----- +MIIE7wIBADA9BgkqhkiG9w0BAQowMKANMAsGCWCGSAFlAwQCAaEaMBgGCSqGSIb3 +DQEBCDALBglghkgBZQMEAgGiAwIBIASCBKkwggSlAgEAAoIBAQDDlygksUEAajpd +Vquo9XIAyTd9ZJ+55hNmhBfhn3lHz3ryPD+0XlgCE9qsKwfR7iYaqmnNilQnsxWp +MGXAgOlC1+w5zh8qHvrI5wX+A6U9N8leIOSgFuFNP0FMMG7I677QzRxGFqKX1o4V +73JWqnHCfnfHRyZY9xM0tYbJKNbRO7Hy4jKBPl3ptPHUoTltr4WYTOpgstcEamdi +iif+0U4bQvVltNg9pzFEjkAktTUGn92W5CgLnsbPXxBo6a/kUlHcgmhYbpOXEjCP +ufZLgsQo8iF2Bq8eWMEsByjr0chQjzrfZAUVtD8Hmh2uMVAPQFAHUkaLj2tHukL+ +s9tAaWKNAgMBAAECggEBAIzgfwWOtmb6HHfGSXY085wlUlZ696EKWsboNdtI5i4W +/1Mimi/sFC/K5SJFDCjlA4UJYZOuItdFYkCun1t8foaqx3cLQ98u2SuDWwmOzqG9 +YMjvoDy+viDJgtrBt8n4I0R5t/ezrgD3hPe/s/dAZRfVx6g9Ux2ZOLgqV57kT3X7 +6paEz3jrIMvuoXQCsi9Qh+eJQ23/sAcc7OHQ7uD8QJVudEBnSHQ+ttvOPXhr7tba +8NuNVa6E/KewkKHRAZqBTJolCVyPtWmvfaDwdJtunCvyR1w3Rv1adZLK4YRFz+vc +sOMK+K1c2aojA+/Fnba19inNq13j6Dwqmq8Ho7MZwHECgYEA6aSx7/93S1VGpxQ9 +KqFE4Fy9ylliC/hanc9qOcfEIo0tDus9lfpuPp+aOXML0msVkIfhCnaru32qtnaI +AQkIbPhSZFvC/i6BibpArXINbDzTS/46zZHehXskjWFGw+iRm/YI7MBuCmWzSnFO +YUwSKRIPKZKyXswFzP8RsQO/QbsCgYEA1k5SamQheuKdo/X40ShWTTOoDlpL4Sir +b2zTnEqlHyMv8c7w880hPf4P+0pqrKyf7jmEykJvp1qSAmyMUCWzrKTr8gQ2sMyb +zj90cEm++M5YIQh5lPJy4pGqmCliJXqkt+zT1xmnRASwMNQOnU2bBmXkve/ofb4M +dEwyig/nZFcCgYBLWPilTD6dhce+NBGxwMZkkKQIMKEk+RfIEs7QCXNgLSUdzZFT +36pT+caTxl1Go5AVxyw04qZpVZKLO1iK9O3Jrp9rjAgrTrYpw23+QWzAvjDqLfeq +ueMIKvlTus5GeacTo9mm+DvEkJ2sYTQEvrKQmilXn950IdmxDYUYD/xK5wKBgQDQ +5ON9BUGFUSQsUHVLG7CT7EhiRS41ubjyEfhrHm+53Ei9weQpIcjHbsERR8aXrmTu +h26i4QOI88XjSv+ymC19mfzLmcPdrnQpJL1RPvFCAZDyEhrBT1sg8rCBRcV/lv68 +scMEpuLecFt2HR5pwt3b7LJ9Wj8bYoctTaDt5va8XQKBgQDCr4hZB5haAcKmNm/g +PjlaLdrDEIuuBjxMzX1t3PXwsEene1cE731v6fbmrDUa8AuJyMY80xhGrTTDQfS3 +QOu/6wtcUv/JC/06OwEaUlT/kdYek+zYfBm3b1sKP3HVKSxCLTcPcC4aQoAFqbEy +3kuSVh03vVBdaP//qMPyeue17w== +-----END PRIVATE KEY----- -- cgit v1.2.1