Basic parsing of certs signed with RSASSA-PSS
diff --git a/include/polarssl/config.h b/include/polarssl/config.h
index 83f9dac..29ba54f 100644
--- a/include/polarssl/config.h
+++ b/include/polarssl/config.h
@@ -154,6 +154,22 @@
 //#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
  *
  * Store the AES tables in ROM.
diff --git a/include/polarssl/oid.h b/include/polarssl/oid.h
index f000b8e..669ad53 100644
--- a/include/polarssl/oid.h
+++ b/include/polarssl/oid.h
@@ -193,6 +193,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 8b84471..e4b5618 100644
--- a/include/polarssl/pk.h
+++ b/include/polarssl/pk.h
@@ -94,6 +94,7 @@
     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 a456537..c48e00a 100644
--- a/include/polarssl/x509.h
+++ b/include/polarssl/x509.h
@@ -254,6 +254,8 @@
                    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 ee8f9e6..916dc3b 100644
--- a/include/polarssl/x509_crt.h
+++ b/include/polarssl/x509_crt.h
@@ -89,6 +89,9 @@
     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 f943c6d..1078608 100644
--- a/library/oid.c
+++ b/library/oid.c
@@ -328,6 +328,10 @@
         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 2ba1e86..80390ae 100644
--- a/library/x509.c
+++ b/library/x509.c
@@ -119,6 +119,20 @@
 }
 
 /*
+ * 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,
  *    value    AttributeValue }
diff --git a/library/x509_crt.c b/library/x509_crt.c
index 27d5ec0..70c24f3 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -529,6 +529,9 @@
     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
@@ -592,7 +595,8 @@
      */
     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 );
@@ -733,14 +737,16 @@
      *  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 0000000..a6f9fbc
--- /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 0000000..e005864
--- /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 f9a5366..0f8e293 100644
--- a/tests/suites/test_suite_x509parse.data
+++ b/tests/suites/test_suite_x509parse.data
@@ -42,6 +42,10 @@
 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\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
 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\n"