diff --git a/include/polarssl/config.h b/include/polarssl/config.h index ad088a9b4..58e8cff08 100644 --- a/include/polarssl/config.h +++ b/include/polarssl/config.h @@ -220,6 +220,22 @@ //#define POLARSSL_SHA256_ALT //#define POLARSSL_SHA512_ALT +/** + * \def POLARSSL_RSASSA_PSS_CERTIFICATES + * + * Enable parsing and verification of X.509 certificates and CRLs signed with + * RSASSA-PSS. + * + * This is disabled by default since it breaks binary compatibility with the + * 1.3.x line. If you choose to enable it, you will need to rebuild your + * application against the new header files, relinking will not be enough. + * + * TODO: actually disable it when done working on this branch ,) + * + * Uncomment this macro to allow using RSASSA-PSS in certificates. + */ +#define POLARSSL_RSASSA_PSS_CERTIFICATES + /** * \def POLARSSL_AES_ROM_TABLES * diff --git a/include/polarssl/oid.h b/include/polarssl/oid.h index 32b0340c7..863cfda72 100644 --- a/include/polarssl/oid.h +++ b/include/polarssl/oid.h @@ -207,6 +207,9 @@ #define OID_PKCS9_EMAIL OID_PKCS9 "\x01" /**< emailAddress AttributeType ::= { pkcs-9 1 } */ +/* RFC 4055 */ +#define OID_RSASSA_PSS OID_PKCS1 "\x0a" /**< id-RSASSA-PSS ::= { pkcs-1 10 } */ + /* * Digest algorithms */ diff --git a/include/polarssl/pk.h b/include/polarssl/pk.h index 7014e420e..1309f70da 100644 --- a/include/polarssl/pk.h +++ b/include/polarssl/pk.h @@ -99,6 +99,7 @@ typedef enum { POLARSSL_PK_ECKEY_DH, POLARSSL_PK_ECDSA, POLARSSL_PK_RSA_ALT, + POLARSSL_PK_RSASSA_PSS, } pk_type_t; /** diff --git a/include/polarssl/x509.h b/include/polarssl/x509.h index 759234816..5a9ed7dce 100644 --- a/include/polarssl/x509.h +++ b/include/polarssl/x509.h @@ -276,6 +276,8 @@ int x509_get_name( unsigned char **p, const unsigned char *end, x509_name *cur ); int x509_get_alg_null( unsigned char **p, const unsigned char *end, x509_buf *alg ); +int x509_get_alg( unsigned char **p, const unsigned char *end, + x509_buf *alg, x509_buf *params ); int x509_get_sig( unsigned char **p, const unsigned char *end, x509_buf *sig ); int x509_get_sig_alg( const x509_buf *sig_oid, md_type_t *md_alg, pk_type_t *pk_alg ); diff --git a/include/polarssl/x509_crt.h b/include/polarssl/x509_crt.h index 0081d36c4..09cc9829b 100644 --- a/include/polarssl/x509_crt.h +++ b/include/polarssl/x509_crt.h @@ -93,6 +93,9 @@ typedef struct _x509_crt x509_buf sig; /**< Signature: hash of the tbs part signed with the private key. */ md_type_t sig_md; /**< Internal representation of the MD algorithm of the signature algorithm, e.g. POLARSSL_MD_SHA256 */ pk_type_t sig_pk /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. POLARSSL_PK_RSA */; +#if defined(POLARSSL_RSASSA_PSS_CERTIFICATES) + x509_buf sig_params; /**< Parameters for the signature algorithm */ +#endif struct _x509_crt *next; /**< Next certificate in the CA-chain. */ } diff --git a/library/oid.c b/library/oid.c index a93188727..9d50cf5de 100644 --- a/library/oid.c +++ b/library/oid.c @@ -363,6 +363,10 @@ static const oid_sig_alg_t oid_sig_alg[] = { ADD_LEN( OID_ECDSA_SHA512 ), "ecdsa-with-SHA512", "ECDSA with SHA512" }, POLARSSL_MD_SHA512, POLARSSL_PK_ECDSA, }, + { + { ADD_LEN( OID_RSASSA_PSS ), "RSASSA-PSS", "RSASSA-PSS" }, + POLARSSL_MD_NONE, POLARSSL_PK_RSASSA_PSS, + }, { { NULL, 0, NULL, NULL }, 0, 0, diff --git a/library/x509.c b/library/x509.c index 92e52c318..991551865 100644 --- a/library/x509.c +++ b/library/x509.c @@ -123,6 +123,20 @@ int x509_get_alg_null( unsigned char **p, const unsigned char *end, return( 0 ); } +/* + * Parse an algorithm identifier with (optional) paramaters + */ +int x509_get_alg( unsigned char **p, const unsigned char *end, + x509_buf *alg, x509_buf *params ) +{ + int ret; + + if( ( ret = asn1_get_alg( p, end, alg, params ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_ALG + ret ); + + return( 0 ); +} + /* * AttributeTypeAndValue ::= SEQUENCE { * type AttributeType, diff --git a/library/x509_crt.c b/library/x509_crt.c index 79460682a..b9f226b07 100644 --- a/library/x509_crt.c +++ b/library/x509_crt.c @@ -534,6 +534,9 @@ static int x509_crt_parse_der_core( x509_crt *crt, const unsigned char *buf, int ret; size_t len; unsigned char *p, *end, *crt_end; + x509_buf sig_params; + + memset( &sig_params, 0, sizeof( x509_buf ) ); /* * Check for valid input @@ -597,7 +600,8 @@ static int x509_crt_parse_der_core( x509_crt *crt, const unsigned char *buf, */ if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 || ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 || - ( ret = x509_get_alg_null( &p, end, &crt->sig_oid1 ) ) != 0 ) + ( ret = x509_get_alg( &p, end, &crt->sig_oid1, + &crt->sig_params ) ) != 0 ) { x509_crt_free( crt ); return( ret ); @@ -738,14 +742,16 @@ static int x509_crt_parse_der_core( x509_crt *crt, const unsigned char *buf, * signatureAlgorithm AlgorithmIdentifier, * signatureValue BIT STRING */ - if( ( ret = x509_get_alg_null( &p, end, &crt->sig_oid2 ) ) != 0 ) + if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2, &sig_params ) ) != 0 ) { x509_crt_free( crt ); return( ret ); } if( crt->sig_oid1.len != crt->sig_oid2.len || - memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 ) + memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 || + crt->sig_params.len != sig_params.len || + memcmp( crt->sig_params.p, sig_params.p, sig_params.len ) != 0 ) { x509_crt_free( crt ); return( POLARSSL_ERR_X509_SIG_MISMATCH ); diff --git a/tests/data_files/server9.crt b/tests/data_files/server9.crt new file mode 100644 index 000000000..a6f9fbc76 --- /dev/null +++ b/tests/data_files/server9.crt @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDBTCCAeegAwIBAgIBFjATBgkqhkiG9w0BAQowBqIEAgIA6jA7MQswCQYDVQQG +EwJOTDERMA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3Qg +Q0EwHhcNMTQwMTIwMTMzODE2WhcNMjQwMTE4MTMzODE2WjA0MQswCQYDVQQGEwJO +TDERMA8GA1UEChMIUG9sYXJTU0wxEjAQBgNVBAMTCWxvY2FsaG9zdDCBnzANBgkq +hkiG9w0BAQEFAAOBjQAwgYkCgYEA3RGKn5m6sGjKKuo7am1Zl+1OyVTkDe7OoH2g +HqroDsK7E0DbihKOiRMkpcX1+tj1kNfIysvF/pMdr9oSI3NSeUYauqBXK3YWMbOo +r+c4mwiLY5k6CiXuRdIYWLq5kxrt1FiaYxs3/PcUCJ+FZUnzWTJt0eDobd5S7Wa0 +qQvaQJUCAwEAAaOBkjCBjzAJBgNVHRMEAjAAMB0GA1UdDgQWBBTu88f1HxWlTUeJ +wdMiY7Lfp869UTBjBgNVHSMEXDBagBS0WuSls97SUva51aaVD+s+vMf9/6E/pD0w +OzELMAkGA1UEBhMCTkwxETAPBgNVBAoTCFBvbGFyU1NMMRkwFwYDVQQDExBQb2xh +clNTTCBUZXN0IENBggEAMBMGCSqGSIb3DQEBCjAGogQCAgDqA4IBAQDAog/jXydR +vDIugTzBXtfVK0CEX8iyQ4cVzQmXWSne8204v943K5D2hktSBkjdQUdcnVvVgLR6 +te50jV89ptN/NofX+fo9fhSRN9vGgQVWzOOFiO0zcThy749pirJu1Kq5OJdthIyW +Pu0UCz5G0k3kTp0JPevGlsNc8S9Ak1tFuB0IPJjrbfODWHS2LDuO+dB6gpkNTdrj +88ogYtBsN4D5gsXBRUfobXokUwejBwLrD6XwyQx+0bMwSCxgHEhxvuUkx1vdlXGw +JG3aF92u8mIxoKSAPaPdqy930mQvmpUWcN5Y1IMbtEGoQCKMYgosFcazJpJcjnX1 +o4Hl/lqjwCEG +-----END CERTIFICATE----- diff --git a/tests/data_files/server9.key b/tests/data_files/server9.key new file mode 100644 index 000000000..e005864f9 --- /dev/null +++ b/tests/data_files/server9.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXQIBAAKBgQDdEYqfmbqwaMoq6jtqbVmX7U7JVOQN7s6gfaAequgOwrsTQNuK +Eo6JEySlxfX62PWQ18jKy8X+kx2v2hIjc1J5Rhq6oFcrdhYxs6iv5zibCItjmToK +Je5F0hhYurmTGu3UWJpjGzf89xQIn4VlSfNZMm3R4Oht3lLtZrSpC9pAlQIDAQAB +AoGAHFCE2tBL0xB45Go/1e/Pi9//OVZAJ3Cw0mmEuqjVNB7I6zxhYhviWbgz92+V +g92KBlU9CIx0/ZhGMyHRNO0uYNEZUJyM8zItoo/nmU31+VaHOGgpei04HZrn1Nmw +QS01FVrn9wzKR/5qeEBmxE7rVMDQo8QLnllC3jXzIVUtX4ECQQD2g9dleWYbqIQe +Q9paXxzvODhCzNtQwD0PnOKc54Nu4zm3JI45REtunmG8et+Ncms9RycTjNlWPGJT +62jgaJexAkEA5ZMNv4u9NNRfZprmlNyvjSOf+w7fdKzhcnkHbGkfLnFdc7vq0XFC +nwORsdjpOvWQUwrV2Cw8Pl4rKa4B4iqUJQJBAMVti6maU3udN8qhXxP3js3LwctG +E/OVMpH5fMha5jl9w/B4V2tn1d3O/MmdwsKeu2JFRPd0W2+kRr+dDs6DFdECQQC1 +3g9QJRWY2n1RPXlZiJKSDxzXuOqQ9bwMAZE98vE+y5Qq8T2O+li6vAsZhysNCChz +gOvzuudmyRcMh8r6Lpz5AkAUKK3gYtJFiVH2arRig3JjZJqixgSTolMT1n+HG4uM +tnBqBiEBVwBxEqaohla/rHR5joZCdcDN8xq0yeTQyLH9 +-----END RSA PRIVATE KEY----- diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data index c0f894832..7531587d1 100644 --- a/tests/suites/test_suite_x509parse.data +++ b/tests/suites/test_suite_x509parse.data @@ -42,6 +42,10 @@ X509 Certificate information SHA512 Digest depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_RSA_C x509_cert_info:"data_files/cert_sha512.crt":"cert. version \: 3\nserial number \: 0B\nissuer name \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nsubject name \: C=NL, O=PolarSSL, CN=PolarSSL Cert SHA512\nissued on \: 2011-02-12 14\:44\:07\nexpires on \: 2021-02-12 14\:44\:07\nsigned using \: RSA with SHA-512\nRSA key size \: 2048 bits\nbasic constraints \: CA=false\n" +X509 Certificate information RSA-PSS, SHA1 Digest +depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_RSA_C +x509_cert_info:"data_files/server9.crt":"cert. version \: 3\nserial number \: 16\nissuer name \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nsubject name \: C=NL, O=PolarSSL, CN=localhost\nissued on \: 2014-01-20 13\:38\:16\nexpires on \: 2024-01-18 13\:38\:16\nsigned using \: RSASSA-PSS\nRSA key size \: 1024 bits\n" + X509 Certificate information EC, SHA1 Digest depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP256R1_ENABLED x509_cert_info:"data_files/server5-sha1.crt":"cert. version \: 3\nserial number \: 12\nissuer name \: C=NL, O=PolarSSL, CN=Polarssl Test EC CA\nsubject name \: C=NL, O=PolarSSL, CN=localhost\nissued on \: 2013-09-24 16\:21\:27\nexpires on \: 2023-09-22 16\:21\:27\nsigned using \: ECDSA with SHA1\nEC key size \: 256 bits\nbasic constraints \: CA=false\n"