From d056ce0e3e0de9f45157cc1cc25982db4620d7d8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Wed, 29 Oct 2014 22:29:20 +0100
Subject: [PATCH 01/57] Use seq_num as AEAD nonce by default

---
 ChangeLog                 |  6 ++++++
 include/polarssl/config.h | 12 ++++++++++++
 library/ssl_tls.c         | 13 +++++++++++++
 3 files changed, 31 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index fd83b9e60..fdcf028b5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 PolarSSL ChangeLog (Sorted per branch, date)
 
+= PolarSSL 1.3.z branch
+
+Changes
+   * Use deterministic nonces for AEAD ciphers in TLS by default (possible to
+     switch back to random with POLARSSL_SSL_AEAD_RANDOM_IV in config.h).
+
 = PolarSSL 1.3.9 released 2014-10-20
 Security
    * Lowest common hash was selected from signature_algorithms extension in
diff --git a/include/polarssl/config.h b/include/polarssl/config.h
index 50b4e339e..fa15b37c3 100644
--- a/include/polarssl/config.h
+++ b/include/polarssl/config.h
@@ -781,6 +781,18 @@
  */
 #define POLARSSL_SELF_TEST
 
+/**
+ * \def POLARSSL_SSL_AEAD_RANDOM_IV
+ *
+ * Generate a random IV rather than using the record sequence number as a
+ * nonce for ciphersuites using and AEAD algorithm (GCM or CCM).
+ *
+ * Using the sequence number is generally recommended.
+ *
+ * Uncomment this macro to always use random IVs with AEAD ciphersuites.
+ */
+//#define POLARSSL_SSL_AEAD_RANDOM_IV
+
 /**
  * \def POLARSSL_SSL_ALL_ALERT_MESSAGES
  *
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 5f080defe..6689894df 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -1137,6 +1137,7 @@ static int ssl_encrypt_buf( ssl_context *ssl )
         /*
          * Generate IV
          */
+#if defined(POLARSSL_SSL_AEAD_RANDOM_IV)
         ret = ssl->f_rng( ssl->p_rng,
                 ssl->transform_out->iv_enc + ssl->transform_out->fixed_ivlen,
                 ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen );
@@ -1146,6 +1147,18 @@ static int ssl_encrypt_buf( ssl_context *ssl )
         memcpy( ssl->out_iv,
                 ssl->transform_out->iv_enc + ssl->transform_out->fixed_ivlen,
                 ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen );
+#else
+        if( ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen != 8 )
+        {
+            /* Reminder if we ever add an AEAD mode with a different size */
+            SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+            return( POLARSSL_ERR_SSL_INTERNAL_ERROR );
+        }
+
+        memcpy( ssl->transform_out->iv_enc + ssl->transform_out->fixed_ivlen,
+                             ssl->out_ctr, 8 );
+        memcpy( ssl->out_iv, ssl->out_ctr, 8 );
+#endif
 
         SSL_DEBUG_BUF( 4, "IV used", ssl->out_iv,
                 ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen );

From e10e06d8630f7ac3e1778346749036342241f016 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Thu, 6 Nov 2014 18:15:12 +0100
Subject: [PATCH 02/57] Blind RSA operations even without CRT

---
 ChangeLog              |  1 +
 include/polarssl/rsa.h |  2 --
 library/rsa.c          | 20 +++++---------------
 3 files changed, 6 insertions(+), 17 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index fdcf028b5..23cbbacc5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -5,6 +5,7 @@ PolarSSL ChangeLog (Sorted per branch, date)
 Changes
    * Use deterministic nonces for AEAD ciphers in TLS by default (possible to
      switch back to random with POLARSSL_SSL_AEAD_RANDOM_IV in config.h).
+   * Blind RSA private operations even when POLARSSL_RSA_NO_CRT is defined.
 
 = PolarSSL 1.3.9 released 2014-10-20
 Security
diff --git a/include/polarssl/rsa.h b/include/polarssl/rsa.h
index c06c7d505..bad60092e 100644
--- a/include/polarssl/rsa.h
+++ b/include/polarssl/rsa.h
@@ -99,10 +99,8 @@ typedef struct
     mpi RP;                     /*!<  cached R^2 mod P  */
     mpi RQ;                     /*!<  cached R^2 mod Q  */
 
-#if !defined(POLARSSL_RSA_NO_CRT)
     mpi Vi;                     /*!<  cached blinding value     */
     mpi Vf;                     /*!<  cached un-blinding value  */
-#endif
 
     int padding;                /*!<  RSA_PKCS_V15 for 1.5 padding and
                                       RSA_PKCS_v21 for OAEP/PSS         */
diff --git a/library/rsa.c b/library/rsa.c
index 958085c8a..3006e9031 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -275,7 +275,6 @@ cleanup:
     return( 0 );
 }
 
-#if !defined(POLARSSL_RSA_NO_CRT)
 /*
  * Generate or update blinding values, see section 10 of:
  *  KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
@@ -329,7 +328,6 @@ cleanup:
 
     return( ret );
 }
-#endif /* !POLARSSL_RSA_NO_CRT */
 
 /*
  * Do an RSA private key operation
@@ -343,7 +341,6 @@ int rsa_private( rsa_context *ctx,
     int ret;
     size_t olen;
     mpi T, T1, T2;
-#if !defined(POLARSSL_RSA_NO_CRT)
     mpi *Vi, *Vf;
 
     /*
@@ -361,7 +358,6 @@ int rsa_private( rsa_context *ctx,
     Vi = &ctx->Vi;
     Vf = &ctx->Vf;
 #endif
-#endif /* !POLARSSL_RSA_NO_CRT */
 
     mpi_init( &T ); mpi_init( &T1 ); mpi_init( &T2 );
 
@@ -372,11 +368,6 @@ int rsa_private( rsa_context *ctx,
         return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
     }
 
-#if defined(POLARSSL_RSA_NO_CRT)
-    ((void) f_rng);
-    ((void) p_rng);
-    MPI_CHK( mpi_exp_mod( &T, &T, &ctx->D, &ctx->N, &ctx->RN ) );
-#else
     if( f_rng != NULL )
     {
         /*
@@ -388,6 +379,9 @@ int rsa_private( rsa_context *ctx,
         MPI_CHK( mpi_mod_mpi( &T, &T, &ctx->N ) );
     }
 
+#if defined(POLARSSL_RSA_NO_CRT)
+    MPI_CHK( mpi_exp_mod( &T, &T, &ctx->D, &ctx->N, &ctx->RN ) );
+#else
     /*
      * faster decryption using the CRT
      *
@@ -409,6 +403,7 @@ int rsa_private( rsa_context *ctx,
      */
     MPI_CHK( mpi_mul_mpi( &T1, &T, &ctx->Q ) );
     MPI_CHK( mpi_add_mpi( &T, &T2, &T1 ) );
+#endif /* POLARSSL_RSA_NO_CRT */
 
     if( f_rng != NULL )
     {
@@ -419,14 +414,13 @@ int rsa_private( rsa_context *ctx,
         MPI_CHK( mpi_mul_mpi( &T, &T, Vf ) );
         MPI_CHK( mpi_mod_mpi( &T, &T, &ctx->N ) );
     }
-#endif /* POLARSSL_RSA_NO_CRT */
 
     olen = ctx->len;
     MPI_CHK( mpi_write_binary( &T, output, olen ) );
 
 cleanup:
     mpi_free( &T ); mpi_free( &T1 ); mpi_free( &T2 );
-#if !defined(POLARSSL_RSA_NO_CRT) && defined(POLARSSL_THREADING_C)
+#if defined(POLARSSL_THREADING_C)
     mpi_free( &Vi_copy ); mpi_free( &Vf_copy );
 #endif
 
@@ -1425,10 +1419,8 @@ int rsa_copy( rsa_context *dst, const rsa_context *src )
     MPI_CHK( mpi_copy( &dst->RP, &src->RP ) );
     MPI_CHK( mpi_copy( &dst->RQ, &src->RQ ) );
 
-#if !defined(POLARSSL_RSA_NO_CRT)
     MPI_CHK( mpi_copy( &dst->Vi, &src->Vi ) );
     MPI_CHK( mpi_copy( &dst->Vf, &src->Vf ) );
-#endif
 
     dst->padding = src->padding;
     dst->hash_id = src->hash_id;
@@ -1445,9 +1437,7 @@ cleanup:
  */
 void rsa_free( rsa_context *ctx )
 {
-#if !defined(POLARSSL_RSA_NO_CRT)
     mpi_free( &ctx->Vi ); mpi_free( &ctx->Vf );
-#endif
     mpi_free( &ctx->RQ ); mpi_free( &ctx->RP ); mpi_free( &ctx->RN );
     mpi_free( &ctx->QP ); mpi_free( &ctx->DQ ); mpi_free( &ctx->DP );
     mpi_free( &ctx->Q  ); mpi_free( &ctx->P  ); mpi_free( &ctx->D );

From 2f8d1f9fc3799a347f671cf2b498e1ec6fcab1c9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Thu, 6 Nov 2014 14:02:51 +0100
Subject: [PATCH 03/57] Add rsa_check_pub_priv()

---
 include/polarssl/rsa.h               | 11 +++++
 library/rsa.c                        | 20 ++++++++
 tests/suites/test_suite_rsa.data     | 15 ++++++
 tests/suites/test_suite_rsa.function | 68 ++++++++++++++++++++++++++++
 4 files changed, 114 insertions(+)

diff --git a/include/polarssl/rsa.h b/include/polarssl/rsa.h
index bad60092e..e636c8055 100644
--- a/include/polarssl/rsa.h
+++ b/include/polarssl/rsa.h
@@ -189,6 +189,17 @@ int rsa_check_pubkey( const rsa_context *ctx );
  */
 int rsa_check_privkey( const rsa_context *ctx );
 
+/**
+ * \brief          Check a public-private RSA key pair.
+ *                 Check each of the contexts, and make sure they match.
+ *
+ * \param pub      RSA context holding the public key
+ * \param prv      RSA context holding the private key
+ *
+ * \return         0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ */
+int rsa_check_pub_priv( const rsa_context *pub, const rsa_context *prv );
+
 /**
  * \brief          Do an RSA public key operation
  *
diff --git a/library/rsa.c b/library/rsa.c
index 3006e9031..54babb51e 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -240,6 +240,26 @@ cleanup:
     return( 0 );
 }
 
+/*
+ * Check if contexts holding a public and private key match
+ */
+int rsa_check_pub_priv( const rsa_context *pub, const rsa_context *prv )
+{
+    if( rsa_check_pubkey( pub ) != 0 ||
+        rsa_check_privkey( prv ) != 0 )
+    {
+        return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
+    }
+
+    if( mpi_cmp_mpi( &pub->N, &prv->N ) != 0 ||
+        mpi_cmp_mpi( &pub->E, &prv->E ) != 0 )
+    {
+        return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
+    }
+
+    return( 0 );
+}
+
 /*
  * Do an RSA public key operation
  */
diff --git a/tests/suites/test_suite_rsa.data b/tests/suites/test_suite_rsa.data
index 131e2738e..c76e5a0ce 100644
--- a/tests/suites/test_suite_rsa.data
+++ b/tests/suites/test_suite_rsa.data
@@ -318,6 +318,21 @@ rsa_check_pubkey:16:"00b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7
 RSA Check Public key #10 (E has size N)
 rsa_check_pubkey:16:"00b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034fb38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"00b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034fb38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":POLARSSL_ERR_RSA_KEY_CHECK_FAILED
 
+RSA Check Public-Private key #1 (Correct)
+rsa_check_pubpriv:2048:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":16:"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":16:"9A66CF76572A71A17475794FA1C8C70D987E581E990D772BB27C77C53FF1ECBB31260E9EDAFAEBC79991807E48918EAB8C3A5F03A600F30C69511546AE788EDF53168E2D035D300EDCD5E4BF3AA2A6D603EA0A7BD11E1C1089657306DF8A64E7F1BC6B266B825C1A6C5F0FC85775F4CF7ACD63367E42EAFE46511D58AD6DFE0F":16:"844DBDD20925D9164F9A1E2F707076C261CCA8337D0241392B38AE3C12342F3AC14F8FD6DF4A1C36839662BD0D227344CD55A32AE5DBD2309A9A2B8A2C82BE6DDDDCE81D1B694775D9047AA765CA0C6E1BB8E61C8B7BE27ED711E8EE2FEAD87F3491F76A6D2262C14189EACDFD4CEFE0BF9D0A5B49857E0ED22CBEB98DC8D45B":16:"4951A7B174DF972C37BADCC38457B5EDD1F078BC613E75CE25E08814E12461C7A1C189A70EB8138294298D141244C7A9DE31AB4F6D38B40B04D6353CD30F77ADBF66BBDE41C7BE463C5E30AAA3F7BAD6CEE99506DEAAFA2F335C1B1C5C88B8ABB0D0387EE0D1B4E7027F7F085A025CEDB5CCE18B88C0462F1C3C910D47C0D4AB":0
+
+RSA Check Public-Private key #2 (Public no N)
+rsa_check_pubpriv:2048:16:"":16:"3":16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":16:"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":16:"9A66CF76572A71A17475794FA1C8C70D987E581E990D772BB27C77C53FF1ECBB31260E9EDAFAEBC79991807E48918EAB8C3A5F03A600F30C69511546AE788EDF53168E2D035D300EDCD5E4BF3AA2A6D603EA0A7BD11E1C1089657306DF8A64E7F1BC6B266B825C1A6C5F0FC85775F4CF7ACD63367E42EAFE46511D58AD6DFE0F":16:"844DBDD20925D9164F9A1E2F707076C261CCA8337D0241392B38AE3C12342F3AC14F8FD6DF4A1C36839662BD0D227344CD55A32AE5DBD2309A9A2B8A2C82BE6DDDDCE81D1B694775D9047AA765CA0C6E1BB8E61C8B7BE27ED711E8EE2FEAD87F3491F76A6D2262C14189EACDFD4CEFE0BF9D0A5B49857E0ED22CBEB98DC8D45B":16:"4951A7B174DF972C37BADCC38457B5EDD1F078BC613E75CE25E08814E12461C7A1C189A70EB8138294298D141244C7A9DE31AB4F6D38B40B04D6353CD30F77ADBF66BBDE41C7BE463C5E30AAA3F7BAD6CEE99506DEAAFA2F335C1B1C5C88B8ABB0D0387EE0D1B4E7027F7F085A025CEDB5CCE18B88C0462F1C3C910D47C0D4AB":POLARSSL_ERR_RSA_KEY_CHECK_FAILED
+
+RSA Check Public-Private key #3 (Private no N)
+rsa_check_pubpriv:2048:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"":16:"3":16:"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":16:"9A66CF76572A71A17475794FA1C8C70D987E581E990D772BB27C77C53FF1ECBB31260E9EDAFAEBC79991807E48918EAB8C3A5F03A600F30C69511546AE788EDF53168E2D035D300EDCD5E4BF3AA2A6D603EA0A7BD11E1C1089657306DF8A64E7F1BC6B266B825C1A6C5F0FC85775F4CF7ACD63367E42EAFE46511D58AD6DFE0F":16:"844DBDD20925D9164F9A1E2F707076C261CCA8337D0241392B38AE3C12342F3AC14F8FD6DF4A1C36839662BD0D227344CD55A32AE5DBD2309A9A2B8A2C82BE6DDDDCE81D1B694775D9047AA765CA0C6E1BB8E61C8B7BE27ED711E8EE2FEAD87F3491F76A6D2262C14189EACDFD4CEFE0BF9D0A5B49857E0ED22CBEB98DC8D45B":16:"4951A7B174DF972C37BADCC38457B5EDD1F078BC613E75CE25E08814E12461C7A1C189A70EB8138294298D141244C7A9DE31AB4F6D38B40B04D6353CD30F77ADBF66BBDE41C7BE463C5E30AAA3F7BAD6CEE99506DEAAFA2F335C1B1C5C88B8ABB0D0387EE0D1B4E7027F7F085A025CEDB5CCE18B88C0462F1C3C910D47C0D4AB":POLARSSL_ERR_RSA_KEY_CHECK_FAILED
+
+RSA Check Public-Private key #4 (N mismatch)
+rsa_check_pubpriv:2048:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034e":16:"3":16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":16:"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":16:"9A66CF76572A71A17475794FA1C8C70D987E581E990D772BB27C77C53FF1ECBB31260E9EDAFAEBC79991807E48918EAB8C3A5F03A600F30C69511546AE788EDF53168E2D035D300EDCD5E4BF3AA2A6D603EA0A7BD11E1C1089657306DF8A64E7F1BC6B266B825C1A6C5F0FC85775F4CF7ACD63367E42EAFE46511D58AD6DFE0F":16:"844DBDD20925D9164F9A1E2F707076C261CCA8337D0241392B38AE3C12342F3AC14F8FD6DF4A1C36839662BD0D227344CD55A32AE5DBD2309A9A2B8A2C82BE6DDDDCE81D1B694775D9047AA765CA0C6E1BB8E61C8B7BE27ED711E8EE2FEAD87F3491F76A6D2262C14189EACDFD4CEFE0BF9D0A5B49857E0ED22CBEB98DC8D45B":16:"4951A7B174DF972C37BADCC38457B5EDD1F078BC613E75CE25E08814E12461C7A1C189A70EB8138294298D141244C7A9DE31AB4F6D38B40B04D6353CD30F77ADBF66BBDE41C7BE463C5E30AAA3F7BAD6CEE99506DEAAFA2F335C1B1C5C88B8ABB0D0387EE0D1B4E7027F7F085A025CEDB5CCE18B88C0462F1C3C910D47C0D4AB":POLARSSL_ERR_RSA_KEY_CHECK_FAILED
+
+RSA Check Public-Private key #5 (E mismatch)
+rsa_check_pubpriv:2048:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"17":16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":16:"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":16:"9A66CF76572A71A17475794FA1C8C70D987E581E990D772BB27C77C53FF1ECBB31260E9EDAFAEBC79991807E48918EAB8C3A5F03A600F30C69511546AE788EDF53168E2D035D300EDCD5E4BF3AA2A6D603EA0A7BD11E1C1089657306DF8A64E7F1BC6B266B825C1A6C5F0FC85775F4CF7ACD63367E42EAFE46511D58AD6DFE0F":16:"844DBDD20925D9164F9A1E2F707076C261CCA8337D0241392B38AE3C12342F3AC14F8FD6DF4A1C36839662BD0D227344CD55A32AE5DBD2309A9A2B8A2C82BE6DDDDCE81D1B694775D9047AA765CA0C6E1BB8E61C8B7BE27ED711E8EE2FEAD87F3491F76A6D2262C14189EACDFD4CEFE0BF9D0A5B49857E0ED22CBEB98DC8D45B":16:"4951A7B174DF972C37BADCC38457B5EDD1F078BC613E75CE25E08814E12461C7A1C189A70EB8138294298D141244C7A9DE31AB4F6D38B40B04D6353CD30F77ADBF66BBDE41C7BE463C5E30AAA3F7BAD6CEE99506DEAAFA2F335C1B1C5C88B8ABB0D0387EE0D1B4E7027F7F085A025CEDB5CCE18B88C0462F1C3C910D47C0D4AB":POLARSSL_ERR_RSA_KEY_CHECK_FAILED
+
 RSA Private (Correct)
 rsa_private:"59779fd2a39e56640c4fc1e67b60aeffcecd78aed7ad2bdfa464e93d04198d48466b8da7445f25bfa19db2844edd5c8f539cf772cc132b483169d390db28a43bc4ee0f038f6568ffc87447746cb72fefac2d6d90ee3143a915ac4688028805905a68eb8f8a96674b093c495eddd8704461eaa2b345efbb2ad6930acd8023f870":2048:16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":"48ce62658d82be10737bd5d3579aed15bc82617e6758ba862eeb12d049d7bacaf2f62fce8bf6e980763d1951f7f0eae3a493df9890d249314b39d00d6ef791de0daebf2c50f46e54aeb63a89113defe85de6dbe77642aae9f2eceb420f3a47a56355396e728917f17876bb829fabcaeef8bf7ef6de2ff9e84e6108ea2e52bbb62b7b288efa0a3835175b8b08fac56f7396eceb1c692d419ecb79d80aef5bc08a75d89de9f2b2d411d881c0e3ffad24c311a19029d210d3d3534f1b626f982ea322b4d1cfba476860ef20d4f672f38c371084b5301b429b747ea051a619e4430e0dac33c12f9ee41ca4d81a4f6da3e495aa8524574bdc60d290dd1f7a62e90a67":0
 
diff --git a/tests/suites/test_suite_rsa.function b/tests/suites/test_suite_rsa.function
index 9b3d05af8..bafacac9d 100644
--- a/tests/suites/test_suite_rsa.function
+++ b/tests/suites/test_suite_rsa.function
@@ -590,6 +590,74 @@ exit:
 }
 /* END_CASE */
 
+/* BEGIN_CASE */
+void rsa_check_pubpriv( int mod, int radix_Npub, char *input_Npub,
+                        int radix_Epub, char *input_Epub,
+                        int radix_P, char *input_P, int radix_Q,
+                        char *input_Q, int radix_N, char *input_N,
+                        int radix_E, char *input_E, int radix_D, char *input_D,
+                        int radix_DP, char *input_DP, int radix_DQ,
+                        char *input_DQ, int radix_QP, char *input_QP,
+                        int result )
+{
+    rsa_context pub, prv;
+
+    rsa_init( &pub, RSA_PKCS_V15, 0 );
+    rsa_init( &prv, RSA_PKCS_V15, 0 );
+
+    pub.len = mod / 8;
+    prv.len = mod / 8;
+
+    if( strlen( input_Npub ) )
+    {
+        TEST_ASSERT( mpi_read_string( &pub.N, radix_Npub, input_Npub ) == 0 );
+    }
+    if( strlen( input_Epub ) )
+    {
+        TEST_ASSERT( mpi_read_string( &pub.E, radix_Epub, input_Epub ) == 0 );
+    }
+
+    if( strlen( input_P ) )
+    {
+        TEST_ASSERT( mpi_read_string( &prv.P, radix_P, input_P ) == 0 );
+    }
+    if( strlen( input_Q ) )
+    {
+        TEST_ASSERT( mpi_read_string( &prv.Q, radix_Q, input_Q ) == 0 );
+    }
+    if( strlen( input_N ) )
+    {
+        TEST_ASSERT( mpi_read_string( &prv.N, radix_N, input_N ) == 0 );
+    }
+    if( strlen( input_E ) )
+    {
+        TEST_ASSERT( mpi_read_string( &prv.E, radix_E, input_E ) == 0 );
+    }
+    if( strlen( input_D ) )
+    {
+        TEST_ASSERT( mpi_read_string( &prv.D, radix_D, input_D ) == 0 );
+    }
+    if( strlen( input_DP ) )
+    {
+        TEST_ASSERT( mpi_read_string( &prv.DP, radix_DP, input_DP ) == 0 );
+    }
+    if( strlen( input_DQ ) )
+    {
+        TEST_ASSERT( mpi_read_string( &prv.DQ, radix_DQ, input_DQ ) == 0 );
+    }
+    if( strlen( input_QP ) )
+    {
+        TEST_ASSERT( mpi_read_string( &prv.QP, radix_QP, input_QP ) == 0 );
+    }
+
+    TEST_ASSERT( rsa_check_pub_priv( &pub, &prv ) == result );
+
+exit:
+    rsa_free( &pub );
+    rsa_free( &prv );
+}
+/* END_CASE */
+
 /* BEGIN_CASE depends_on:POLARSSL_CTR_DRBG_C:POLARSSL_ENTROPY_C */
 void rsa_gen_key( int nrbits, int exponent, int result)
 {

From 30668d688d0b80c4f070535bcb675aff381d1216 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Thu, 6 Nov 2014 15:25:32 +0100
Subject: [PATCH 04/57] Add ecp_check_pub_priv()

---
 include/polarssl/ecp.h               | 12 ++++++++
 library/ecp.c                        | 42 ++++++++++++++++++++++++++++
 tests/suites/test_suite_ecp.data     | 27 ++++++++++++++++++
 tests/suites/test_suite_ecp.function | 26 +++++++++++++++++
 4 files changed, 107 insertions(+)

diff --git a/include/polarssl/ecp.h b/include/polarssl/ecp.h
index 7192f1e6c..9b83bc51b 100644
--- a/include/polarssl/ecp.h
+++ b/include/polarssl/ecp.h
@@ -635,6 +635,18 @@ int ecp_gen_keypair( ecp_group *grp, mpi *d, ecp_point *Q,
 int ecp_gen_key( ecp_group_id grp_id, ecp_keypair *key,
                 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
 
+/**
+ * \brief           Check a public-private key pair
+ *
+ * \param pub       Keypair structure holding a public key
+ * \param prv       Keypair structure holding a private (plus public) key
+ *
+ * \return          0 if successfull (keys are valid and match), or
+ *                  POLARSSL_ERR_ECP_BAD_INPUT_DATA, or
+ *                  a POLARSSL_ERR_ECP_XXX or POLARSSL_ERR_MPI_XXX code.
+ */
+int ecp_check_pub_priv( const ecp_keypair *pub, const ecp_keypair *prv );
+
 #if defined(POLARSSL_SELF_TEST)
 /**
  * \brief          Checkup routine
diff --git a/library/ecp.c b/library/ecp.c
index ece781d5e..41e25e9e0 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -1897,6 +1897,48 @@ int ecp_gen_key( ecp_group_id grp_id, ecp_keypair *key,
     return( ecp_gen_keypair( &key->grp, &key->d, &key->Q, f_rng, p_rng ) );
 }
 
+/*
+ * Check a public-private key pair
+ */
+int ecp_check_pub_priv( const ecp_keypair *pub, const ecp_keypair *prv )
+{
+    int ret;
+    ecp_point Q;
+    ecp_group grp;
+
+    if( pub->grp.id == POLARSSL_ECP_DP_NONE ||
+        pub->grp.id != prv->grp.id ||
+        mpi_cmp_mpi( &pub->Q.X, &prv->Q.X ) ||
+        mpi_cmp_mpi( &pub->Q.Y, &prv->Q.Y ) ||
+        mpi_cmp_mpi( &pub->Q.Z, &prv->Q.Z ) )
+    {
+        return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
+    }
+
+    ecp_point_init( &Q );
+    ecp_group_init( &grp );
+
+    /* ecp_mul() needs a non-const group... */
+    ecp_group_copy( &grp, &prv->grp );
+
+    /* Also checks d is valid */
+    MPI_CHK( ecp_mul( &grp, &Q, &prv->d, &prv->grp.G, NULL, NULL ) );
+
+    if( mpi_cmp_mpi( &Q.X, &prv->Q.X ) ||
+        mpi_cmp_mpi( &Q.Y, &prv->Q.Y ) ||
+        mpi_cmp_mpi( &Q.Z, &prv->Q.Z ) )
+    {
+        ret = POLARSSL_ERR_ECP_BAD_INPUT_DATA;
+        goto cleanup;
+    }
+
+cleanup:
+    ecp_point_free( &Q );
+    ecp_group_free( &grp );
+
+    return( ret );
+}
+
 #if defined(POLARSSL_SELF_TEST)
 
 /*
diff --git a/tests/suites/test_suite_ecp.data b/tests/suites/test_suite_ecp.data
index d871a8dfc..a5dc528e4 100644
--- a/tests/suites/test_suite_ecp.data
+++ b/tests/suites/test_suite_ecp.data
@@ -324,6 +324,33 @@ ECP check privkey #11 (montgomery, OK)
 depends_on:POLARSSL_ECP_DP_M255_ENABLED
 ecp_check_privkey:POLARSSL_ECP_DP_M255:"7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8":0
 
+ECP check public-private #1 (OK)
+depends_on:POLARSSL_ECP_DP_SECP256R1_ENABLED
+ecp_check_pub_priv:POLARSSL_ECP_DP_SECP256R1:"37cc56d976091e5a723ec7592dff206eee7cf9069174d0ad14b5f76822596292":"4ee500d82311ffea2fd2345d5d16bd8a88c26b770d55cd8a2a0efa01c8b4edff":POLARSSL_ECP_DP_SECP256R1:"00f12a1320760270a83cbffd53f6031ef76a5d86c8a204f2c30ca9ebf51f0f0ea7":"37cc56d976091e5a723ec7592dff206eee7cf9069174d0ad14b5f76822596292":"4ee500d82311ffea2fd2345d5d16bd8a88c26b770d55cd8a2a0efa01c8b4edff":0
+
+ECP check public-private #2 (group none)
+ecp_check_pub_priv:POLARSSL_ECP_DP_NONE:"37cc56d976091e5a723ec7592dff206eee7cf9069174d0ad14b5f76822596292":"4ee500d82311ffea2fd2345d5d16bd8a88c26b770d55cd8a2a0efa01c8b4edff":POLARSSL_ECP_DP_NONE:"00f12a1320760270a83cbffd53f6031ef76a5d86c8a204f2c30ca9ebf51f0f0ea7":"37cc56d976091e5a723ec7592dff206eee7cf9069174d0ad14b5f76822596292":"4ee500d82311ffea2fd2345d5d16bd8a88c26b770d55cd8a2a0efa01c8b4edff":POLARSSL_ERR_ECP_BAD_INPUT_DATA
+
+ECP check public-private #3 (group mismatch)
+depends_on:POLARSSL_ECP_DP_SECP256R1_ENABLED:POLARSSL_ECP_DP_SECP384R1_ENABLED
+ecp_check_pub_priv:POLARSSL_ECP_DP_SECP384R1:"37cc56d976091e5a723ec7592dff206eee7cf9069174d0ad14b5f76822596292":"4ee500d82311ffea2fd2345d5d16bd8a88c26b770d55cd8a2a0efa01c8b4edff":POLARSSL_ECP_DP_SECP256R1:"00f12a1320760270a83cbffd53f6031ef76a5d86c8a204f2c30ca9ebf51f0f0ea7":"37cc56d976091e5a723ec7592dff206eee7cf9069174d0ad14b5f76822596292":"4ee500d82311ffea2fd2345d5d16bd8a88c26b770d55cd8a2a0efa01c8b4edff":POLARSSL_ERR_ECP_BAD_INPUT_DATA
+
+ECP check public-private #4 (Qx mismatch)
+depends_on:POLARSSL_ECP_DP_SECP256R1_ENABLED
+ecp_check_pub_priv:POLARSSL_ECP_DP_SECP256R1:"37cc56d976091e5a723ec7592dff206eee7cf9069174d0ad14b5f76822596293":"4ee500d82311ffea2fd2345d5d16bd8a88c26b770d55cd8a2a0efa01c8b4edff":POLARSSL_ECP_DP_SECP256R1:"00f12a1320760270a83cbffd53f6031ef76a5d86c8a204f2c30ca9ebf51f0f0ea7":"37cc56d976091e5a723ec7592dff206eee7cf9069174d0ad14b5f76822596292":"4ee500d82311ffea2fd2345d5d16bd8a88c26b770d55cd8a2a0efa01c8b4edff":POLARSSL_ERR_ECP_BAD_INPUT_DATA
+
+ECP check public-private #5 (Qy mismatch)
+depends_on:POLARSSL_ECP_DP_SECP256R1_ENABLED
+ecp_check_pub_priv:POLARSSL_ECP_DP_SECP256R1:"37cc56d976091e5a723ec7592dff206eee7cf9069174d0ad14b5f76822596292":"4ee500d82311ffea2fd2345d5d16bd8a88c26b770d55cd8a2a0efa01c8b4edfe":POLARSSL_ECP_DP_SECP256R1:"00f12a1320760270a83cbffd53f6031ef76a5d86c8a204f2c30ca9ebf51f0f0ea7":"37cc56d976091e5a723ec7592dff206eee7cf9069174d0ad14b5f76822596292":"4ee500d82311ffea2fd2345d5d16bd8a88c26b770d55cd8a2a0efa01c8b4edff":POLARSSL_ERR_ECP_BAD_INPUT_DATA
+
+ECP check public-private #6 (wrong Qx)
+depends_on:POLARSSL_ECP_DP_SECP256R1_ENABLED
+ecp_check_pub_priv:POLARSSL_ECP_DP_SECP256R1:"37cc56d976091e5a723ec7592dff206eee7cf9069174d0ad14b5f76822596293":"4ee500d82311ffea2fd2345d5d16bd8a88c26b770d55cd8a2a0efa01c8b4edff":POLARSSL_ECP_DP_SECP256R1:"00f12a1320760270a83cbffd53f6031ef76a5d86c8a204f2c30ca9ebf51f0f0ea7":"37cc56d976091e5a723ec7592dff206eee7cf9069174d0ad14b5f76822596293":"4ee500d82311ffea2fd2345d5d16bd8a88c26b770d55cd8a2a0efa01c8b4edff":POLARSSL_ERR_ECP_BAD_INPUT_DATA
+
+ECP check public-private #7 (wrong Qy)
+depends_on:POLARSSL_ECP_DP_SECP256R1_ENABLED
+ecp_check_pub_priv:POLARSSL_ECP_DP_SECP256R1:"37cc56d976091e5a723ec7592dff206eee7cf9069174d0ad14b5f76822596292":"4ee500d82311ffea2fd2345d5d16bd8a88c26b770d55cd8a2a0efa01c8b4edfe":POLARSSL_ECP_DP_SECP256R1:"00f12a1320760270a83cbffd53f6031ef76a5d86c8a204f2c30ca9ebf51f0f0ea7":"37cc56d976091e5a723ec7592dff206eee7cf9069174d0ad14b5f76822596292":"4ee500d82311ffea2fd2345d5d16bd8a88c26b770d55cd8a2a0efa01c8b4edfe":POLARSSL_ERR_ECP_BAD_INPUT_DATA
+
 ECP gen keypair
 depends_on:POLARSSL_ECP_DP_SECP192R1_ENABLED
 ecp_gen_keypair:POLARSSL_ECP_DP_SECP192R1
diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function
index 62dc6065e..1c22a846d 100644
--- a/tests/suites/test_suite_ecp.function
+++ b/tests/suites/test_suite_ecp.function
@@ -598,6 +598,32 @@ exit:
 }
 /* END_CASE */
 
+/* BEGIN_CASE */
+void ecp_check_pub_priv( int id_pub, char *Qx_pub, char *Qy_pub,
+                         int id, char *d, char *Qx, char *Qy, int ret )
+{
+    ecp_keypair pub, prv;
+
+    ecp_keypair_init( &pub );
+    ecp_keypair_init( &prv );
+
+    if( id_pub != POLARSSL_ECP_DP_NONE )
+        TEST_ASSERT( ecp_use_known_dp( &pub.grp, id_pub ) == 0 );
+    TEST_ASSERT( ecp_point_read_string( &pub.Q, 16, Qx_pub, Qy_pub ) == 0 );
+
+    if( id != POLARSSL_ECP_DP_NONE )
+        TEST_ASSERT( ecp_use_known_dp( &prv.grp, id ) == 0 );
+    TEST_ASSERT( ecp_point_read_string( &prv.Q, 16, Qx, Qy ) == 0 );
+    TEST_ASSERT( mpi_read_string( &prv.d, 16, d ) == 0 );
+
+    TEST_ASSERT( ecp_check_pub_priv( &pub, &prv ) == ret );
+
+exit:
+    ecp_keypair_free( &pub );
+    ecp_keypair_free( &prv );
+}
+/* END_CASE */
+
 /* BEGIN_CASE */
 void ecp_gen_keypair( int id )
 {

From 70bdadf54bd5f1997354a81b3de031d38065b00b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Thu, 6 Nov 2014 16:51:20 +0100
Subject: [PATCH 05/57] Add pk_check_pair()

---
 include/polarssl/pk.h               | 13 +++++++++++++
 library/pk.c                        | 20 ++++++++++++++++++++
 library/pk_wrap.c                   | 17 +++++++++++++++++
 tests/suites/test_suite_pk.data     | 20 ++++++++++++++++++++
 tests/suites/test_suite_pk.function | 18 ++++++++++++++++++
 5 files changed, 88 insertions(+)

diff --git a/include/polarssl/pk.h b/include/polarssl/pk.h
index 754dda219..0ff5f1e6c 100644
--- a/include/polarssl/pk.h
+++ b/include/polarssl/pk.h
@@ -177,6 +177,9 @@ typedef struct
                          int (*f_rng)(void *, unsigned char *, size_t),
                          void *p_rng );
 
+    /** Check public-private key pair */
+    int (*check_pair_func)( const void *pub, const void *prv );
+
     /** Allocate a new context */
     void * (*ctx_alloc_func)( void );
 
@@ -426,6 +429,16 @@ int pk_encrypt( pk_context *ctx,
                 unsigned char *output, size_t *olen, size_t osize,
                 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
 
+/**
+ * \brief           Check if a public-private pair of keys matches.
+ *
+ * \param pub       Context holding a public key.
+ * \param prv       Context holding a private (and public) key.
+ *
+ * \return          0 on success or POLARSSL_ERR_PK_BAD_INPUT_DATA
+ */
+int pk_check_pair( const pk_context *pub, const pk_context *prv );
+
 /**
  * \brief           Export debug information
  *
diff --git a/library/pk.c b/library/pk.c
index 4aba3aa6d..513d8cadd 100644
--- a/library/pk.c
+++ b/library/pk.c
@@ -300,6 +300,26 @@ int pk_encrypt( pk_context *ctx,
                 output, olen, osize, f_rng, p_rng ) );
 }
 
+/*
+ * Check public-private key pair
+ */
+int pk_check_pair( const pk_context *pub, const pk_context *prv )
+{
+    if( pub == NULL || pub->pk_info == NULL ||
+        prv == NULL || prv->pk_info == NULL )
+    {
+        return( POLARSSL_ERR_PK_BAD_INPUT_DATA );
+    }
+
+    if( pub->pk_info != prv->pk_info ||
+        pub->pk_info->check_pair_func == NULL )
+    {
+        return( POLARSSL_ERR_PK_TYPE_MISMATCH );
+    }
+
+    return( pub->pk_info->check_pair_func( pub->pk_ctx, prv->pk_ctx ) );
+}
+
 /*
  * Get key size in bits
  */
diff --git a/library/pk_wrap.c b/library/pk_wrap.c
index 5e9ff605e..0d2a368ad 100644
--- a/library/pk_wrap.c
+++ b/library/pk_wrap.c
@@ -125,6 +125,12 @@ static int rsa_encrypt_wrap( void *ctx,
                 f_rng, p_rng, RSA_PUBLIC, ilen, input, output ) );
 }
 
+static int rsa_check_pair_wrap( const void *pub, const void *prv )
+{
+    return( rsa_check_pub_priv( (const rsa_context *) pub,
+                                (const rsa_context *) prv ) );
+}
+
 static void *rsa_alloc_wrap( void )
 {
     void *ctx = polarssl_malloc( sizeof( rsa_context ) );
@@ -163,6 +169,7 @@ const pk_info_t rsa_info = {
     rsa_sign_wrap,
     rsa_decrypt_wrap,
     rsa_encrypt_wrap,
+    rsa_check_pair_wrap,
     rsa_alloc_wrap,
     rsa_free_wrap,
     rsa_debug,
@@ -234,6 +241,12 @@ static int eckey_sign_wrap( void *ctx, md_type_t md_alg,
 
 #endif /* POLARSSL_ECDSA_C */
 
+static int eckey_check_pair( const void *pub, const void *prv )
+{
+    return( ecp_check_pub_priv( (const ecp_keypair *) pub,
+                                (const ecp_keypair *) prv ) );
+}
+
 static void *eckey_alloc_wrap( void )
 {
     void *ctx = polarssl_malloc( sizeof( ecp_keypair ) );
@@ -271,6 +284,7 @@ const pk_info_t eckey_info = {
 #endif
     NULL,
     NULL,
+    eckey_check_pair,
     eckey_alloc_wrap,
     eckey_free_wrap,
     eckey_debug,
@@ -294,6 +308,7 @@ const pk_info_t eckeydh_info = {
     NULL,
     NULL,
     NULL,
+    eckey_check_pair,
     eckey_alloc_wrap,       /* Same underlying key structure */
     eckey_free_wrap,        /* Same underlying key structure */
     eckey_debug,            /* Same underlying key structure */
@@ -367,6 +382,7 @@ const pk_info_t ecdsa_info = {
     ecdsa_sign_wrap,
     NULL,
     NULL,
+    eckey_check_pair,   /* Compatible key structures */
     ecdsa_alloc_wrap,
     ecdsa_free_wrap,
     eckey_debug,        /* Compatible key structures */
@@ -444,6 +460,7 @@ const pk_info_t rsa_alt_info = {
     rsa_alt_sign_wrap,
     rsa_alt_decrypt_wrap,
     NULL,
+    NULL,                   /* No public key */
     rsa_alt_alloc_wrap,
     rsa_alt_free_wrap,
     NULL,
diff --git a/tests/suites/test_suite_pk.data b/tests/suites/test_suite_pk.data
index 47640a687..73694d29d 100644
--- a/tests/suites/test_suite_pk.data
+++ b/tests/suites/test_suite_pk.data
@@ -130,3 +130,23 @@ Verify ext RSA #12 (PKCS1 v1.5, good)
 depends_on:POLARSSL_SHA1_C:POLARSSL_PKCS1_V15
 pk_rsa_verify_ext_test_vec:"206ef4bf396c6087f8229ef196fd35f37ccb8de5efcdb238f20d556668f114257a11fbe038464a67830378e62ae9791453953dac1dbd7921837ba98e84e856eb80ed9487e656d0b20c28c8ba5e35db1abbed83ed1c7720a97701f709e3547a4bfcabca9c89c57ad15c3996577a0ae36d7c7b699035242f37954646c1cd5c08ac":POLARSSL_MD_SHA1:1024:16:"e28a13548525e5f36dccb24ecb7cc332cc689dfd64012604c9c7816d72a16c3f5fcdc0e86e7c03280b1c69b586ce0cd8aec722cc73a5d3b730310bf7dfebdc77ce5d94bbc369dc18a2f7b07bd505ab0f82224aef09fdc1e5063234255e0b3c40a52e9e8ae60898eb88a766bdd788fe9493d8fd86bcdd2884d5c06216c65469e5":16:"3":"5abc01f5de25b70867ff0c24e222c61f53c88daf42586fddcd56f3c4588f074be3c328056c063388688b6385a8167957c6e5355a510e005b8a851d69c96b36ec6036644078210e5d7d326f96365ee0648882921492bc7b753eb9c26cdbab37555f210df2ca6fec1b25b463d38b81c0dcea202022b04af5da58aa03d77be949b7":POLARSSL_PK_RSA:-1:RSA_SALT_LEN_ANY:0
 
+Check pair #1 (EC, OK)
+depends_on:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP256R1_ENABLED
+pk_check_pair:"data_files/ec_256_pub.pem":"data_files/ec_256_prv.pem":0
+
+Check pair #2 (EC, bad)
+depends_on:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP256R1_ENABLED
+pk_check_pair:"data_files/ec_256_pub.pem":"data_files/server5.key":POLARSSL_ERR_ECP_BAD_INPUT_DATA
+
+Check pair #3 (RSA, OK)
+depends_on:POLARSSL_RSA_C
+pk_check_pair:"data_files/server1.pubkey":"data_files/server1.key":0
+
+Check pair #4 (RSA, bad)
+depends_on:POLARSSL_RSA_C
+pk_check_pair:"data_files/server1.pubkey":"data_files/server2.key":POLARSSL_ERR_RSA_KEY_CHECK_FAILED
+
+Check pair #5 (RSA vs EC)
+depends_on:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP256R1_ENABLED:POLARSSL_RSA_C
+pk_check_pair:"data_files/ec_256_pub.pem":"data_files/server1.key":POLARSSL_ERR_PK_TYPE_MISMATCH
+
diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function
index dc7dee94e..352169c24 100644
--- a/tests/suites/test_suite_pk.function
+++ b/tests/suites/test_suite_pk.function
@@ -80,6 +80,24 @@ exit:
 }
 /* END_CASE */
 
+/* BEGIN_CASE depends_on:POLARSSL_PK_PARSE_C */
+void pk_check_pair( char *pub_file, char *prv_file, int ret )
+{
+    pk_context pub, prv;
+
+    pk_init( &pub );
+    pk_init( &prv );
+
+    TEST_ASSERT( pk_parse_public_keyfile( &pub, pub_file ) == 0 );
+    TEST_ASSERT( pk_parse_keyfile( &prv, prv_file, NULL ) == 0 );
+
+    TEST_ASSERT( pk_check_pair( &pub, &prv ) == ret );
+
+    pk_free( &pub );
+    pk_free( &prv );
+}
+/* END_CASE */
+
 /* BEGIN_CASE depends_on:POLARSSL_RSA_C */
 void pk_rsa_verify_test_vec( char *message_hex_string, int digest,
                        int mod, int radix_N, char *input_N, int radix_E,

From 27e3edbe2c48a6ebd246e58e161df562bdf97045 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Thu, 6 Nov 2014 17:32:48 +0100
Subject: [PATCH 06/57] Check key/cert pair in ssl_set_own_cert()

---
 library/ssl_tls.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 6689894df..33d4678c1 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -3751,7 +3751,7 @@ int ssl_set_own_cert( ssl_context *ssl, x509_crt *own_cert,
     key_cert->cert = own_cert;
     key_cert->key  = pk_key;
 
-    return( 0 );
+    return( pk_check_pair( &key_cert->cert->pk, key_cert->key ) );
 }
 
 #if defined(POLARSSL_RSA_C)
@@ -3780,7 +3780,7 @@ int ssl_set_own_cert_rsa( ssl_context *ssl, x509_crt *own_cert,
     key_cert->cert = own_cert;
     key_cert->key_own_alloc = 1;
 
-    return( 0 );
+    return( pk_check_pair( &key_cert->cert->pk, key_cert->key ) );
 }
 #endif /* POLARSSL_RSA_C */
 
@@ -3809,7 +3809,7 @@ int ssl_set_own_cert_alt( ssl_context *ssl, x509_crt *own_cert,
     key_cert->cert = own_cert;
     key_cert->key_own_alloc = 1;
 
-    return( 0 );
+    return( pk_check_pair( &key_cert->cert->pk, key_cert->key ) );
 }
 #endif /* POLARSSL_X509_CRT_PARSE_C */
 

From a1efcb084ff359fce06acf8c41ae96560b137ecd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Sat, 8 Nov 2014 17:08:08 +0100
Subject: [PATCH 07/57] Implement pk_check_pair() for RSA-alt

---
 library/pk.c                        | 16 ++++++++-----
 library/pk_wrap.c                   | 35 ++++++++++++++++++++++++++---
 tests/suites/test_suite_pk.function | 11 ++++++++-
 3 files changed, 53 insertions(+), 9 deletions(-)

diff --git a/library/pk.c b/library/pk.c
index 513d8cadd..a37f58e12 100644
--- a/library/pk.c
+++ b/library/pk.c
@@ -306,18 +306,24 @@ int pk_encrypt( pk_context *ctx,
 int pk_check_pair( const pk_context *pub, const pk_context *prv )
 {
     if( pub == NULL || pub->pk_info == NULL ||
-        prv == NULL || prv->pk_info == NULL )
+        prv == NULL || prv->pk_info == NULL ||
+        prv->pk_info->check_pair_func == NULL )
     {
         return( POLARSSL_ERR_PK_BAD_INPUT_DATA );
     }
 
-    if( pub->pk_info != prv->pk_info ||
-        pub->pk_info->check_pair_func == NULL )
+    if( prv->pk_info->type == POLARSSL_PK_RSA_ALT )
     {
-        return( POLARSSL_ERR_PK_TYPE_MISMATCH );
+        if( pub->pk_info->type != POLARSSL_PK_RSA )
+            return( POLARSSL_ERR_PK_TYPE_MISMATCH );
+    }
+    else
+    {
+        if( pub->pk_info != prv->pk_info )
+            return( POLARSSL_ERR_PK_TYPE_MISMATCH );
     }
 
-    return( pub->pk_info->check_pair_func( pub->pk_ctx, prv->pk_ctx ) );
+    return( prv->pk_info->check_pair_func( pub->pk_ctx, prv->pk_ctx ) );
 }
 
 /*
diff --git a/library/pk_wrap.c b/library/pk_wrap.c
index 0d2a368ad..a75ab3248 100644
--- a/library/pk_wrap.c
+++ b/library/pk_wrap.c
@@ -117,10 +117,11 @@ static int rsa_encrypt_wrap( void *ctx,
                     unsigned char *output, size_t *olen, size_t osize,
                     int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
 {
-    ((void) osize);
-
     *olen = ((rsa_context *) ctx)->len;
 
+    if( *olen > osize )
+        return( POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE );
+
     return( rsa_pkcs1_encrypt( (rsa_context *) ctx,
                 f_rng, p_rng, RSA_PUBLIC, ilen, input, output ) );
 }
@@ -435,6 +436,34 @@ static int rsa_alt_decrypt_wrap( void *ctx,
                 RSA_PRIVATE, olen, input, output, osize ) );
 }
 
+static int rsa_alt_check_pair( const void *pub, const void *prv )
+{
+    unsigned char sig[POLARSSL_MPI_MAX_SIZE];
+    unsigned char hash[32];
+    size_t sig_len = 0;
+    int ret;
+
+    if( rsa_alt_get_size( prv ) != rsa_get_size( pub ) )
+        return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
+
+    memset( hash, 0x2a, sizeof( hash ) );
+
+    if( ( ret = rsa_alt_sign_wrap( (void *) prv, POLARSSL_MD_NONE,
+                                   hash, sizeof( hash ),
+                                   sig, &sig_len, NULL, NULL ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    if( rsa_verify_wrap( (void *) pub, POLARSSL_MD_NONE,
+                         hash, sizeof( hash ), sig, sig_len ) != 0 )
+    {
+        return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
+    }
+
+    return( 0 );
+}
+
 static void *rsa_alt_alloc_wrap( void )
 {
     void *ctx = polarssl_malloc( sizeof( rsa_alt_context ) );
@@ -460,7 +489,7 @@ const pk_info_t rsa_alt_info = {
     rsa_alt_sign_wrap,
     rsa_alt_decrypt_wrap,
     NULL,
-    NULL,                   /* No public key */
+    rsa_alt_check_pair,
     rsa_alt_alloc_wrap,
     rsa_alt_free_wrap,
     NULL,
diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function
index 352169c24..c88d36588 100644
--- a/tests/suites/test_suite_pk.function
+++ b/tests/suites/test_suite_pk.function
@@ -83,18 +83,27 @@ exit:
 /* BEGIN_CASE depends_on:POLARSSL_PK_PARSE_C */
 void pk_check_pair( char *pub_file, char *prv_file, int ret )
 {
-    pk_context pub, prv;
+    pk_context pub, prv, alt;
 
     pk_init( &pub );
     pk_init( &prv );
+    pk_init( &alt );
 
     TEST_ASSERT( pk_parse_public_keyfile( &pub, pub_file ) == 0 );
     TEST_ASSERT( pk_parse_keyfile( &prv, prv_file, NULL ) == 0 );
 
     TEST_ASSERT( pk_check_pair( &pub, &prv ) == ret );
 
+    if( pk_get_type( &prv ) == POLARSSL_PK_RSA )
+    {
+        TEST_ASSERT( pk_init_ctx_rsa_alt( &alt, pk_rsa( prv ),
+                     rsa_decrypt_func, rsa_sign_func, rsa_key_len_func ) == 0 );
+        TEST_ASSERT( pk_check_pair( &pub, &alt ) == ret );
+    }
+
     pk_free( &pub );
     pk_free( &prv );
+    pk_free( &alt );
 }
 /* END_CASE */
 

From 7c13d69cb59bedbf343074304e3dfb36c11bc351 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Wed, 12 Nov 2014 00:01:34 +0100
Subject: [PATCH 08/57] Fix dependency issues

---
 library/pk_wrap.c                   | 6 ++++++
 tests/suites/test_suite_pk.function | 8 +++++++-
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/library/pk_wrap.c b/library/pk_wrap.c
index a75ab3248..7776f0114 100644
--- a/library/pk_wrap.c
+++ b/library/pk_wrap.c
@@ -436,6 +436,7 @@ static int rsa_alt_decrypt_wrap( void *ctx,
                 RSA_PRIVATE, olen, input, output, osize ) );
 }
 
+#if defined(POLARSSL_RSA_C)
 static int rsa_alt_check_pair( const void *pub, const void *prv )
 {
     unsigned char sig[POLARSSL_MPI_MAX_SIZE];
@@ -463,6 +464,7 @@ static int rsa_alt_check_pair( const void *pub, const void *prv )
 
     return( 0 );
 }
+#endif /* POLARSSL_RSA_C */
 
 static void *rsa_alt_alloc_wrap( void )
 {
@@ -489,7 +491,11 @@ const pk_info_t rsa_alt_info = {
     rsa_alt_sign_wrap,
     rsa_alt_decrypt_wrap,
     NULL,
+#if defined(POLARSSL_RSA_C)
     rsa_alt_check_pair,
+#else
+    NULL,
+#endif
     rsa_alt_alloc_wrap,
     rsa_alt_free_wrap,
     NULL,
diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function
index c88d36588..fb86c99f7 100644
--- a/tests/suites/test_suite_pk.function
+++ b/tests/suites/test_suite_pk.function
@@ -1,6 +1,10 @@
 /* BEGIN_HEADER */
 #include <polarssl/pk.h>
 
+/* For error codes */
+#include <polarssl/ecp.h>
+#include <polarssl/rsa.h>
+
 static int rnd_std_rand( void *rng_state, unsigned char *output, size_t len );
 
 #define RSA_KEY_SIZE 512
@@ -80,7 +84,7 @@ exit:
 }
 /* END_CASE */
 
-/* BEGIN_CASE depends_on:POLARSSL_PK_PARSE_C */
+/* BEGIN_CASE depends_on:POLARSSL_PK_PARSE_C:POLARSSL_FS_IO */
 void pk_check_pair( char *pub_file, char *prv_file, int ret )
 {
     pk_context pub, prv, alt;
@@ -94,12 +98,14 @@ void pk_check_pair( char *pub_file, char *prv_file, int ret )
 
     TEST_ASSERT( pk_check_pair( &pub, &prv ) == ret );
 
+#if defined(POLARSSL_RSA_C)
     if( pk_get_type( &prv ) == POLARSSL_PK_RSA )
     {
         TEST_ASSERT( pk_init_ctx_rsa_alt( &alt, pk_rsa( prv ),
                      rsa_decrypt_func, rsa_sign_func, rsa_key_len_func ) == 0 );
         TEST_ASSERT( pk_check_pair( &pub, &alt ) == ret );
     }
+#endif
 
     pk_free( &pub );
     pk_free( &prv );

From de1712587504406fe56685a3c4567849d83db241 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Sat, 8 Nov 2014 17:58:24 +0100
Subject: [PATCH 09/57] Update ChangeLog for pk_check_pair() & Co

---
 ChangeLog | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index 23cbbacc5..20436d771 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,10 +2,14 @@ PolarSSL ChangeLog (Sorted per branch, date)
 
 = PolarSSL 1.3.z branch
 
+Features
+   * Add function pk_check_pair() to test if public and private keys match.
+
 Changes
    * Use deterministic nonces for AEAD ciphers in TLS by default (possible to
      switch back to random with POLARSSL_SSL_AEAD_RANDOM_IV in config.h).
    * Blind RSA private operations even when POLARSSL_RSA_NO_CRT is defined.
+   * ssl_set_own_cert() now returns an error on key-certificate mismatch.
 
 = PolarSSL 1.3.9 released 2014-10-20
 Security

From 54f6e562e6989ce61d2279652630eff47def999b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Mon, 10 Nov 2014 12:15:39 +0100
Subject: [PATCH 10/57] Fix CFLAGS with cmake and gcc

---
 CMakeLists.txt | 4 ++--
 ChangeLog      | 4 ++++
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9e1158c77..147f104f8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,7 +4,7 @@ project(POLARSSL C)
 string(REGEX MATCH "Clang" CMAKE_COMPILER_IS_CLANG "${CMAKE_C_COMPILER_ID}")
 
 if(CMAKE_COMPILER_IS_GNUCC)
-  set(CMAKE_C_FLAGS "-Wall -Wextra -W -Wdeclaration-after-statement -Wlogical-op -Wwrite-strings")
+  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -W -Wdeclaration-after-statement -Wwrite-strings -Wlogical-op")
   set(CMAKE_C_FLAGS_RELEASE "-O2")
   set(CMAKE_C_FLAGS_DEBUG "-g3 -O0")
   set(CMAKE_C_FLAGS_COVERAGE "-g3 -O0 --coverage")
@@ -14,7 +14,7 @@ if(CMAKE_COMPILER_IS_GNUCC)
 endif(CMAKE_COMPILER_IS_GNUCC)
 
 if(CMAKE_COMPILER_IS_CLANG)
-  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -W -Wdeclaration-after-statement -Wpointer-arith -Wwrite-strings -Wdocumentation -Wunreachable-code")
+  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -W -Wdeclaration-after-statement -Wwrite-strings -Wpointer-arith -Wdocumentation -Wunreachable-code")
   set(CMAKE_C_FLAGS_RELEASE "-O2")
   set(CMAKE_C_FLAGS_DEBUG "-g3 -O0")
   set(CMAKE_C_FLAGS_COVERAGE "-g3 -O0 --coverage")
diff --git a/ChangeLog b/ChangeLog
index 20436d771..f38c0cff9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -5,6 +5,10 @@ PolarSSL ChangeLog (Sorted per branch, date)
 Features
    * Add function pk_check_pair() to test if public and private keys match.
 
+Bugfix
+   * User set CFLAGS were ignore by Cmake with gcc (introduced in 1.3.9, found
+     by Julian Ospald).
+
 Changes
    * Use deterministic nonces for AEAD ciphers in TLS by default (possible to
      switch back to random with POLARSSL_SSL_AEAD_RANDOM_IV in config.h).

From d6197a37e08e2c183ee308fdabf162a536966228 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Mon, 10 Nov 2014 13:02:22 +0100
Subject: [PATCH 11/57] Detect undefined behaviours too in ASan builds

---
 CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 147f104f8..a2e60aa3c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -18,7 +18,7 @@ if(CMAKE_COMPILER_IS_CLANG)
   set(CMAKE_C_FLAGS_RELEASE "-O2")
   set(CMAKE_C_FLAGS_DEBUG "-g3 -O0")
   set(CMAKE_C_FLAGS_COVERAGE "-g3 -O0 --coverage")
-  set(CMAKE_C_FLAGS_ASAN "-fsanitize=address -fno-omit-frame-pointer -g3 -O1 -Werror")
+  set(CMAKE_C_FLAGS_ASAN "-fsanitize=address -fsanitize=undefined -fno-sanitize-recover -fno-omit-frame-pointer -g3 -O1 -Werror")
   set(CMAKE_C_FLAGS_CHECK "-O1 -Werror")
 endif(CMAKE_COMPILER_IS_CLANG)
 

From b31b61b9e8359402a8124572d1a94c48d9ebb776 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Mon, 10 Nov 2014 13:05:43 +0100
Subject: [PATCH 12/57] Fix potential undefined behaviour in Camellia

---
 ChangeLog          |  1 +
 library/camellia.c | 16 ++++++++--------
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index f38c0cff9..bc0bbd0f8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -8,6 +8,7 @@ Features
 Bugfix
    * User set CFLAGS were ignore by Cmake with gcc (introduced in 1.3.9, found
      by Julian Ospald).
+   * Fix potential undefined behaviour in Camellia.
 
 Changes
    * Use deterministic nonces for AEAD ciphers in TLS by default (possible to
diff --git a/library/camellia.c b/library/camellia.c
index a4968f411..3956a405b 100644
--- a/library/camellia.c
+++ b/library/camellia.c
@@ -304,14 +304,14 @@ static void camellia_feistel( const uint32_t x[2], const uint32_t k[2],
     I0 = x[0] ^ k[0];
     I1 = x[1] ^ k[1];
 
-    I0 = (SBOX1((I0 >> 24) & 0xFF) << 24) |
-         (SBOX2((I0 >> 16) & 0xFF) << 16) |
-         (SBOX3((I0 >>  8) & 0xFF) <<  8) |
-         (SBOX4((I0      ) & 0xFF)      );
-    I1 = (SBOX2((I1 >> 24) & 0xFF) << 24) |
-         (SBOX3((I1 >> 16) & 0xFF) << 16) |
-         (SBOX4((I1 >>  8) & 0xFF) <<  8) |
-         (SBOX1((I1      ) & 0xFF)      );
+    I0 = ((uint32_t) SBOX1((I0 >> 24) & 0xFF) << 24) |
+         ((uint32_t) SBOX2((I0 >> 16) & 0xFF) << 16) |
+         ((uint32_t) SBOX3((I0 >>  8) & 0xFF) <<  8) |
+         ((uint32_t) SBOX4((I0      ) & 0xFF)      );
+    I1 = ((uint32_t) SBOX2((I1 >> 24) & 0xFF) << 24) |
+         ((uint32_t) SBOX3((I1 >> 16) & 0xFF) << 16) |
+         ((uint32_t) SBOX4((I1 >>  8) & 0xFF) <<  8) |
+         ((uint32_t) SBOX1((I1      ) & 0xFF)      );
 
     I0 ^= (I1 << 8) | (I1 >> 24);
     I1 ^= (I0 << 16) | (I0 >> 16);

From e9599796210c734021c1c32dbb25778ce0b885c8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Mon, 10 Nov 2014 13:43:55 +0100
Subject: [PATCH 13/57] Fix ECDSA sign buffer size

---
 ChangeLog       | 2 ++
 library/ecdsa.c | 2 +-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index bc0bbd0f8..d3b7124b4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -9,6 +9,8 @@ Bugfix
    * User set CFLAGS were ignore by Cmake with gcc (introduced in 1.3.9, found
      by Julian Ospald).
    * Fix potential undefined behaviour in Camellia.
+   * Fix potential failure in ECDSA signatures when POLARSSL_ECP_MAX_BITS is a
+     multiple of 8 (found by Gergely Budai).
 
 Changes
    * Use deterministic nonces for AEAD ciphers in TLS by default (possible to
diff --git a/library/ecdsa.c b/library/ecdsa.c
index 5af7f6b53..e9880efd2 100644
--- a/library/ecdsa.c
+++ b/library/ecdsa.c
@@ -333,7 +333,7 @@ cleanup:
 #if POLARSSL_ECP_MAX_BYTES > 124
 #error "POLARSSL_ECP_MAX_BYTES bigger than expected, please fix MAX_SIG_LEN"
 #endif
-#define MAX_SIG_LEN ( 3 + 2 * ( 2 + POLARSSL_ECP_MAX_BYTES ) )
+#define MAX_SIG_LEN ( 3 + 2 * ( 3 + POLARSSL_ECP_MAX_BYTES ) )
 
 /*
  * Convert a signature (given by context) to ASN.1

From 49aa99e6536bd867dbb01fa7c7f023dc90cbeb69 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Mon, 10 Nov 2014 16:40:16 +0100
Subject: [PATCH 14/57] Fix exit codes in cert_app

---
 programs/x509/cert_app.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/programs/x509/cert_app.c b/programs/x509/cert_app.c
index 5f8636b10..1ab7cc759 100644
--- a/programs/x509/cert_app.c
+++ b/programs/x509/cert_app.c
@@ -188,6 +188,7 @@ int main( int argc, char *argv[] )
     {
     usage:
         printf( USAGE );
+        ret = 2;
         goto exit;
     }
 
@@ -500,6 +501,9 @@ exit:
     fflush( stdout ); getchar();
 #endif
 
+    if( ret < 0 )
+        ret = 1;
+
     return( ret );
 }
 #endif /* POLARSSL_BIGNUM_C && POLARSSL_ENTROPY_C && POLARSSL_SSL_TLS_C &&

From e9271e683536619bbec55d14ac004fdf218b61ce Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Tue, 11 Nov 2014 22:21:27 +0100
Subject: [PATCH 15/57] Add a MemSan Cmake build type

Detects uninitialised memory reads. Available only with Clang on Linux x86_64
for now. Experimental but seems usable enough.
---
 CMakeLists.txt | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index a2e60aa3c..1596226c0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -19,11 +19,13 @@ if(CMAKE_COMPILER_IS_CLANG)
   set(CMAKE_C_FLAGS_DEBUG "-g3 -O0")
   set(CMAKE_C_FLAGS_COVERAGE "-g3 -O0 --coverage")
   set(CMAKE_C_FLAGS_ASAN "-fsanitize=address -fsanitize=undefined -fno-sanitize-recover -fno-omit-frame-pointer -g3 -O1 -Werror")
+  # note: can add -fsanitize-memory-track-origins=2 for debugging with memsan
+  set(CMAKE_C_FLAGS_MEMSAN "-fsanitize=memory -fno-omit-frame-pointer -fno-optimize-sibling-calls -g3 -O1 -Werror")
   set(CMAKE_C_FLAGS_CHECK "-O1 -Werror")
 endif(CMAKE_COMPILER_IS_CLANG)
 
 set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE}
-    CACHE STRING "Choose the type of build: None Debug Release Coverage ASan Check CheckFull"
+    CACHE STRING "Choose the type of build: None Debug Release Coverage ASan MemSan Check CheckFull"
     FORCE)
 
 if(CMAKE_BUILD_TYPE STREQUAL "Coverage")

From 0369a5291b525d2739e4ccb388761baaee86793f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Tue, 11 Nov 2014 22:17:26 +0100
Subject: [PATCH 16/57] Fix uninitialised pointer dereference

---
 ChangeLog                              | 5 +++++
 library/asn1parse.c                    | 2 ++
 tests/suites/test_suite_x509parse.data | 4 ++++
 3 files changed, 11 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index d3b7124b4..9821551c5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,11 @@ PolarSSL ChangeLog (Sorted per branch, date)
 
 = PolarSSL 1.3.z branch
 
+Security
+   * Fix remotely-triggerable uninitialised pointer dereference caused by
+     crafted X.509 certificate (server is not affected if it doesn't ask for a
+     client certificate) (found using Codenomicon Defensics).
+
 Features
    * Add function pk_check_pair() to test if public and private keys match.
 
diff --git a/library/asn1parse.c b/library/asn1parse.c
index a3a2b56a2..e2117bfa1 100644
--- a/library/asn1parse.c
+++ b/library/asn1parse.c
@@ -278,6 +278,8 @@ int asn1_get_sequence_of( unsigned char **p,
             if( cur->next == NULL )
                 return( POLARSSL_ERR_ASN1_MALLOC_FAILED );
 
+            memset( cur->next, 0, sizeof( asn1_sequence ) );
+
             cur = cur->next;
         }
     }
diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data
index 4cc924fa4..c2bb7f320 100644
--- a/tests/suites/test_suite_x509parse.data
+++ b/tests/suites/test_suite_x509parse.data
@@ -869,6 +869,10 @@ X509 Certificate ASN1 (TBSCertificate v3, ext BasicContraint tag, octet len mism
 depends_on:POLARSSL_RSA_C
 x509parse_crt:"3081a230819fa0030201028204deadbeef300d06092a864886f70d0101020500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092A864886F70D010101050003190030160210ffffffffffffffffffffffffffffffff0202ffffa101aaa201bba317301530130603551d130101010409300702010102010100":"":POLARSSL_ERR_X509_INVALID_EXTENSIONS + POLARSSL_ERR_ASN1_LENGTH_MISMATCH
 
+X509 Certificate ASN1 (ExtKeyUsage, bad second tag)
+depends_on:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP256R1_ENABLED
+x509parse_crt:"3081de3081dba003020102020900ebdbcd14105e1839300906072a8648ce3d0401300f310d300b0603550403130454657374301e170d3134313131313230353935345a170d3234313130383230353935345a300f310d300b06035504031304546573743059301306072a8648ce3d020106082a8648ce3d0301070342000437cc56d976091e5a723ec7592dff206eee7cf9069174d0ad14b5f768225962924ee500d82311ffea2fd2345d5d16bd8a88c26b770d55cd8a2a0efa01c8b4edffa321301f301d0603551d250416301406082b0601050507030107082b06010505070302":"":POLARSSL_ERR_X509_INVALID_EXTENSIONS + POLARSSL_ERR_ASN1_UNEXPECTED_TAG
+
 X509 Certificate ASN1 (correct pubkey, no sig_alg)
 depends_on:POLARSSL_RSA_C
 x509parse_crt:"308183308180a0030201008204deadbeef300d06092a864886f70d0101020500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092A864886F70D010101050003190030160210ffffffffffffffffffffffffffffffff0202ffff":"":POLARSSL_ERR_X509_INVALID_ALG + POLARSSL_ERR_ASN1_OUT_OF_DATA

From b134060f90ee0e47a63a36f0c36334edeed4a110 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Tue, 11 Nov 2014 23:11:16 +0100
Subject: [PATCH 17/57] Fix memory leak with crafted X.509 certs

---
 ChangeLog                              | 3 +++
 library/x509_crt.c                     | 3 +++
 tests/suites/test_suite_x509parse.data | 4 ++++
 3 files changed, 10 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index 9821551c5..f06f582d1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,6 +6,9 @@ Security
    * Fix remotely-triggerable uninitialised pointer dereference caused by
      crafted X.509 certificate (server is not affected if it doesn't ask for a
      client certificate) (found using Codenomicon Defensics).
+   * Fix remotely-triggerable memory leak caused by crafted X.509 certificates
+     (server is not affected if it doesn't ask for a client certificate)
+     (found using Codenomicon Defensics).
 
 Features
    * Add function pk_check_pair() to test if public and private keys match.
diff --git a/library/x509_crt.c b/library/x509_crt.c
index 88d7f04c7..525d250fb 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -359,6 +359,9 @@ static int x509_get_subject_alt_name( unsigned char **p,
         /* Allocate and assign next pointer */
         if( cur->buf.p != NULL )
         {
+            if( cur->next != NULL )
+                return( POLARSSL_ERR_X509_INVALID_EXTENSIONS );
+
             cur->next = (asn1_sequence *) polarssl_malloc(
                  sizeof( asn1_sequence ) );
 
diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data
index c2bb7f320..b7f6791af 100644
--- a/tests/suites/test_suite_x509parse.data
+++ b/tests/suites/test_suite_x509parse.data
@@ -873,6 +873,10 @@ X509 Certificate ASN1 (ExtKeyUsage, bad second tag)
 depends_on:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP256R1_ENABLED
 x509parse_crt:"3081de3081dba003020102020900ebdbcd14105e1839300906072a8648ce3d0401300f310d300b0603550403130454657374301e170d3134313131313230353935345a170d3234313130383230353935345a300f310d300b06035504031304546573743059301306072a8648ce3d020106082a8648ce3d0301070342000437cc56d976091e5a723ec7592dff206eee7cf9069174d0ad14b5f768225962924ee500d82311ffea2fd2345d5d16bd8a88c26b770d55cd8a2a0efa01c8b4edffa321301f301d0603551d250416301406082b0601050507030107082b06010505070302":"":POLARSSL_ERR_X509_INVALID_EXTENSIONS + POLARSSL_ERR_ASN1_UNEXPECTED_TAG
 
+X509 Certificate ASN1 (SubjectAltName repeated)
+depends_on:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP256R1_ENABLED
+x509parse_crt:"3081fd3081faa003020102020900a8b31ff37d09a37f300906072a8648ce3d0401300f310d300b0603550403130454657374301e170d3134313131313231333731365a170d3234313130383231333731365a300f310d300b06035504031304546573743059301306072a8648ce3d020106082a8648ce3d0301070342000437cc56d976091e5a723ec7592dff206eee7cf9069174d0ad14b5f768225962924ee500d82311ffea2fd2345d5d16bd8a88c26b770d55cd8a2a0efa01c8b4edffa321301f301d0603551d11041630148208666f6f2e7465737482086261722e74657374301d0603551d11041630148208666f6f2e7465737482086261722e74657374":"":POLARSSL_ERR_X509_INVALID_EXTENSIONS
+
 X509 Certificate ASN1 (correct pubkey, no sig_alg)
 depends_on:POLARSSL_RSA_C
 x509parse_crt:"308183308180a0030201008204deadbeef300d06092a864886f70d0101020500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092A864886F70D010101050003190030160210ffffffffffffffffffffffffffffffff0202ffff":"":POLARSSL_ERR_X509_INVALID_ALG + POLARSSL_ERR_ASN1_OUT_OF_DATA

From d681443f69080ec68f2323e7f53fae2f863d69ee Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Wed, 12 Nov 2014 01:25:31 +0100
Subject: [PATCH 18/57] Fix potential stack overflow

---
 ChangeLog      |  7 +++++--
 library/x509.c | 46 +++++++++++++++++++++++++---------------------
 2 files changed, 30 insertions(+), 23 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index f06f582d1..a8cb94a20 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,10 +4,13 @@ PolarSSL ChangeLog (Sorted per branch, date)
 
 Security
    * Fix remotely-triggerable uninitialised pointer dereference caused by
-     crafted X.509 certificate (server is not affected if it doesn't ask for a
+     crafted X.509 certificate (TLS server is not affected if it doesn't ask for a
      client certificate) (found using Codenomicon Defensics).
    * Fix remotely-triggerable memory leak caused by crafted X.509 certificates
-     (server is not affected if it doesn't ask for a client certificate)
+     (TLS server is not affected if it doesn't ask for a client certificate)
+     (found using Codenomicon Defensics).
+   * Fix potential stack overflow while parsing crafted X.509 certificates
+     (TLS server is not affected if it doesn't ask for a client certificate)
      (found using Codenomicon Defensics).
 
 Features
diff --git a/library/x509.c b/library/x509.c
index 941472c9d..89ba7633d 100644
--- a/library/x509.c
+++ b/library/x509.c
@@ -421,35 +421,39 @@ int x509_get_name( unsigned char **p, const unsigned char *end,
     size_t set_len;
     const unsigned char *end_set;
 
-    /*
-     * parse first SET, restricted to 1 element
-     */
-    if( ( ret = asn1_get_tag( p, end, &set_len,
-            ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
-        return( POLARSSL_ERR_X509_INVALID_NAME + ret );
+    /* don't use recursion, we'd risk stack overflow if not optimized */
+    while( 1 )
+    {
+        /*
+         * parse first SET, restricted to 1 element
+         */
+        if( ( ret = asn1_get_tag( p, end, &set_len,
+                ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
+            return( POLARSSL_ERR_X509_INVALID_NAME + ret );
 
-    end_set  = *p + set_len;
+        end_set  = *p + set_len;
 
-    if( ( ret = x509_get_attr_type_value( p, end_set, cur ) ) != 0 )
-        return( ret );
+        if( ( ret = x509_get_attr_type_value( p, end_set, cur ) ) != 0 )
+            return( ret );
 
-    if( *p != end_set )
-        return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
+        if( *p != end_set )
+            return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
 
-    /*
-     * recurse until end of SEQUENCE is reached
-     */
-    if( *p == end )
-        return( 0 );
+        /*
+         * continue until end of SEQUENCE is reached
+         */
+        if( *p == end )
+            return( 0 );
 
-    cur->next = (x509_name *) polarssl_malloc( sizeof( x509_name ) );
+        cur->next = (x509_name *) polarssl_malloc( sizeof( x509_name ) );
 
-    if( cur->next == NULL )
-        return( POLARSSL_ERR_X509_MALLOC_FAILED );
+        if( cur->next == NULL )
+            return( POLARSSL_ERR_X509_MALLOC_FAILED );
 
-    memset( cur->next, 0, sizeof( x509_name ) );
+        memset( cur->next, 0, sizeof( x509_name ) );
 
-    return( x509_get_name( p, end, cur->next ) );
+        cur = cur->next;
+    }
 }
 
 /*

From 8a5e3d4a4011f3f2142e15a23ad98fa7c7753b6e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Wed, 12 Nov 2014 17:47:28 +0100
Subject: [PATCH 19/57] Forbid repeated X.509 extensions

---
 ChangeLog                              | 1 +
 library/x509_crt.c                     | 4 ++++
 tests/suites/test_suite_x509parse.data | 4 ++++
 3 files changed, 9 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index a8cb94a20..6f55c3297 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -28,6 +28,7 @@ Changes
      switch back to random with POLARSSL_SSL_AEAD_RANDOM_IV in config.h).
    * Blind RSA private operations even when POLARSSL_RSA_NO_CRT is defined.
    * ssl_set_own_cert() now returns an error on key-certificate mismatch.
+   * Forbid repeated extensions in X.509 certificates.
 
 = PolarSSL 1.3.9 released 2014-10-20
 Security
diff --git a/library/x509_crt.c b/library/x509_crt.c
index 525d250fb..5273c3a57 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -481,6 +481,10 @@ static int x509_get_crt_ext( unsigned char **p,
             continue;
         }
 
+        /* Forbid repeated extensions */
+        if( ( crt->ext_types & ext_type ) != 0 )
+            return( POLARSSL_ERR_X509_INVALID_EXTENSIONS );
+
         crt->ext_types |= ext_type;
 
         switch( ext_type )
diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data
index b7f6791af..097a86171 100644
--- a/tests/suites/test_suite_x509parse.data
+++ b/tests/suites/test_suite_x509parse.data
@@ -877,6 +877,10 @@ X509 Certificate ASN1 (SubjectAltName repeated)
 depends_on:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP256R1_ENABLED
 x509parse_crt:"3081fd3081faa003020102020900a8b31ff37d09a37f300906072a8648ce3d0401300f310d300b0603550403130454657374301e170d3134313131313231333731365a170d3234313130383231333731365a300f310d300b06035504031304546573743059301306072a8648ce3d020106082a8648ce3d0301070342000437cc56d976091e5a723ec7592dff206eee7cf9069174d0ad14b5f768225962924ee500d82311ffea2fd2345d5d16bd8a88c26b770d55cd8a2a0efa01c8b4edffa321301f301d0603551d11041630148208666f6f2e7465737482086261722e74657374301d0603551d11041630148208666f6f2e7465737482086261722e74657374":"":POLARSSL_ERR_X509_INVALID_EXTENSIONS
 
+X509 Certificate ASN1 (ExtKeyUsage repeated)
+depends_on:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP256R1_ENABLED
+x509parse_crt:"3081fd3081faa003020102020900ebdbcd14105e1839300906072a8648ce3d0401300f310d300b0603550403130454657374301e170d3134313131313230353935345a170d3234313130383230353935345a300f310d300b06035504031304546573743059301306072a8648ce3d020106082a8648ce3d0301070342000437cc56d976091e5a723ec7592dff206eee7cf9069174d0ad14b5f768225962924ee500d82311ffea2fd2345d5d16bd8a88c26b770d55cd8a2a0efa01c8b4edffa340303e301d0603551d250416301406082b0601050507030106082b06010505070302301d0603551d250416301406082b0601050507030106082b06010505070302":"":POLARSSL_ERR_X509_INVALID_EXTENSIONS
+
 X509 Certificate ASN1 (correct pubkey, no sig_alg)
 depends_on:POLARSSL_RSA_C
 x509parse_crt:"308183308180a0030201008204deadbeef300d06092a864886f70d0101020500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092A864886F70D010101050003190030160210ffffffffffffffffffffffffffffffff0202ffff":"":POLARSSL_ERR_X509_INVALID_ALG + POLARSSL_ERR_ASN1_OUT_OF_DATA

From f631bbc1da168a6a61b4ee9152a673cb64194396 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Wed, 12 Nov 2014 18:35:31 +0100
Subject: [PATCH 20/57] Make x509_string_cmp() iterative

---
 library/x509_crt.c | 37 +++++++++++++++++++++----------------
 1 file changed, 21 insertions(+), 16 deletions(-)

diff --git a/library/x509_crt.c b/library/x509_crt.c
index 5273c3a57..6193ecd12 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -1636,25 +1636,30 @@ static int x509_string_cmp( const x509_buf *a, const x509_buf *b )
  */
 static int x509_name_cmp( const x509_name *a, const x509_name *b )
 {
-    if( a == NULL && b == NULL )
-        return( 0 );
-
-    if( a == NULL || b == NULL )
-        return( -1 );
-
-    /* type */
-    if( a->oid.tag != b->oid.tag ||
-        a->oid.len != b->oid.len ||
-        memcmp( a->oid.p, b->oid.p, b->oid.len ) != 0 )
+    /* Avoid recursion, it might not be optimised by the compiler */
+    while( a != NULL || b != NULL )
     {
-        return( -1 );
+        if( a == NULL || b == NULL )
+            return( -1 );
+
+        /* type */
+        if( a->oid.tag != b->oid.tag ||
+            a->oid.len != b->oid.len ||
+            memcmp( a->oid.p, b->oid.p, b->oid.len ) != 0 )
+        {
+            return( -1 );
+        }
+
+        /* value */
+        if( x509_string_cmp( &a->val, &b->val ) != 0 )
+            return( -1 );
+
+        a = a->next;
+        b = b->next;
     }
 
-    /* value */
-    if( x509_string_cmp( &a->val, &b->val ) != 0 )
-        return( -1 );
-
-    return( x509_name_cmp( a->next, b->next ) );
+    /* a == NULL == b */
+    return( 0 );
 }
 
 /*

From 5924f9f81076bda203fd7075342d40c26cf180d3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Wed, 12 Nov 2014 22:27:18 +0100
Subject: [PATCH 21/57] Add script to find malloc() not followed by init

---
 scripts/malloc-init.pl | 70 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 70 insertions(+)
 create mode 100755 scripts/malloc-init.pl

diff --git a/scripts/malloc-init.pl b/scripts/malloc-init.pl
new file mode 100755
index 000000000..1fa1cf315
--- /dev/null
+++ b/scripts/malloc-init.pl
@@ -0,0 +1,70 @@
+#!/usr/bin/perl
+
+# Check for malloc calls not shortly followed by initialisation.
+#
+# Known limitations:
+# - false negative: can't see allocations spanning more than one line
+# - possible false negatives, see patterns
+# - false positive: malloc-malloc-init-init is not accepted
+# - false positives: "non-standard" init functions (eg, the things being
+# initialised is not the first arg, or initialise struct members)
+#
+# Since false positives are expected, the results must be manually reviewed.
+#
+# Typical usage: scripts/malloc-init.pl library/*.c
+
+use warnings;
+use strict;
+
+use utf8;
+use open qw(:std utf8);
+
+my $limit = 7;
+my $inits = qr/memset|memcpy|_init|fread|base64_..code/;
+
+# cases to bear in mind:
+#
+# 0. foo = malloc(...); memset( foo, ... );
+# 1. *foo = malloc(...); memset( *foo, ... );
+# 2. type *foo = malloc(...); memset( foo, ...);
+# 3. foo = malloc(...); foo_init( (type *) foo );
+# 4. foo = malloc(...); for(i=0..n) { init( &foo[i] ); }
+#
+# The chosen patterns are a bit relaxed, but unlikely to cause false positives
+# in real code (initialising *foo or &foo instead of foo will likely be caught
+# by functional tests).
+#
+my $id = qr/([a-zA-Z-0-9_\->\.]*)/;
+my $prefix = qr/\s(?:\*?|\&?|\([a-z_]* \*\))\s*/;
+
+my $name;
+my $line;
+my @bad;
+
+die "Usage: $0 file.c [...]\n" unless @ARGV;
+
+while (my $file = shift @ARGV)
+{
+    open my $fh, "<", $file or die "read $file failed: $!\n";
+    while (<$fh>)
+    {
+        if( /polarssl_malloc\(/ ) {
+            if( /$id\s*=.*polarssl_malloc\(/ ) {
+                push @bad, "$file:$line:$name" if $name;
+                $name = $1;
+                $line = $.;
+            } else {
+                push @bad, "$file:$.:???" unless /return polarssl_malloc/;
+            }
+        } elsif( $name && /(?:$inits)\($prefix\Q$name\E\b/ ) {
+            undef $name;
+        } elsif( $name && $. - $line > $limit ) {
+            push @bad, "$file:$line:$name";
+            undef $name;
+            undef $line;
+        }
+    }
+    close $fh or die;
+}
+
+print "$_\n" for @bad;

From e5b0fc18472b9780a0563b1a5550f039264e88da Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Wed, 12 Nov 2014 22:27:42 +0100
Subject: [PATCH 22/57] Make malloc-init script a bit happier

---
 library/asn1write.c |  4 ++--
 library/ssl_cache.c | 13 +++++--------
 library/ssl_tls.c   |  8 ++++----
 library/x509_crl.c  |  6 +++---
 library/x509_crt.c  |  2 +-
 5 files changed, 15 insertions(+), 18 deletions(-)

diff --git a/library/asn1write.c b/library/asn1write.c
index ebc0e9766..d3ece60c7 100644
--- a/library/asn1write.c
+++ b/library/asn1write.c
@@ -327,6 +327,8 @@ asn1_named_data *asn1_store_named_data( asn1_named_data **head,
             return( NULL );
         }
 
+        memcpy( cur->oid.p, oid, oid_len );
+
         cur->val.len = val_len;
         cur->val.p = polarssl_malloc( val_len );
         if( cur->val.p == NULL )
@@ -336,8 +338,6 @@ asn1_named_data *asn1_store_named_data( asn1_named_data **head,
             return( NULL );
         }
 
-        memcpy( cur->oid.p, oid, oid_len );
-
         cur->next = *head;
         *head = cur;
     }
diff --git a/library/ssl_cache.c b/library/ssl_cache.c
index 836b68511..5868e693b 100644
--- a/library/ssl_cache.c
+++ b/library/ssl_cache.c
@@ -105,10 +105,8 @@ int ssl_cache_get( void *data, ssl_session *session )
          */
         if( entry->peer_cert.p != NULL )
         {
-            session->peer_cert =
-                (x509_crt *) polarssl_malloc( sizeof(x509_crt) );
-
-            if( session->peer_cert == NULL )
+            if( ( session->peer_cert = (x509_crt *) polarssl_malloc(
+                                 sizeof(x509_crt) ) ) == NULL )
             {
                 ret = 1;
                 goto exit;
@@ -226,8 +224,7 @@ int ssl_cache_set( void *data, const ssl_session *session )
             /*
              * max_entries not reached, create new entry
              */
-            cur = (ssl_cache_entry *)
-                        polarssl_malloc( sizeof(ssl_cache_entry) );
+            cur = (ssl_cache_entry *) polarssl_malloc( sizeof(ssl_cache_entry) );
             if( cur == NULL )
             {
                 ret = 1;
@@ -264,8 +261,8 @@ int ssl_cache_set( void *data, const ssl_session *session )
      */
     if( session->peer_cert != NULL )
     {
-        cur->peer_cert.p = (unsigned char *)
-                                polarssl_malloc( session->peer_cert->raw.len );
+        cur->peer_cert.p = (unsigned char *) polarssl_malloc(
+                            session->peer_cert->raw.len );
         if( cur->peer_cert.p == NULL )
         {
             ret = 1;
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 33d4678c1..89688867a 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -3341,14 +3341,14 @@ static int ssl_handshake_init( ssl_context *ssl )
      */
     if( ssl->transform_negotiate == NULL )
     {
-        ssl->transform_negotiate =
-            (ssl_transform *) polarssl_malloc( sizeof(ssl_transform) );
+        ssl->transform_negotiate = (ssl_transform *) polarssl_malloc(
+                             sizeof(ssl_transform) );
     }
 
     if( ssl->session_negotiate == NULL )
     {
-        ssl->session_negotiate =
-            (ssl_session *) polarssl_malloc( sizeof(ssl_session) );
+        ssl->session_negotiate = (ssl_session *) polarssl_malloc(
+                           sizeof(ssl_session) );
     }
 
     if( ssl->handshake == NULL )
diff --git a/library/x509_crl.c b/library/x509_crl.c
index 7dd53c2f6..b9a5c1373 100644
--- a/library/x509_crl.c
+++ b/library/x509_crl.c
@@ -243,8 +243,8 @@ static int x509_get_entries( unsigned char **p,
             if( cur_entry->next == NULL )
                 return( POLARSSL_ERR_X509_MALLOC_FAILED );
 
+            memset( cur_entry->next, 0, sizeof( x509_crl_entry ) );
             cur_entry = cur_entry->next;
-            memset( cur_entry, 0, sizeof( x509_crl_entry ) );
         }
     }
 
@@ -294,8 +294,8 @@ int x509_crl_parse( x509_crl *chain, const unsigned char *buf, size_t buflen )
             return( POLARSSL_ERR_X509_MALLOC_FAILED );
         }
 
+        x509_crl_init( crl->next );
         crl = crl->next;
-        x509_crl_init( crl );
     }
 
 #if defined(POLARSSL_PEM_PARSE_C)
@@ -532,8 +532,8 @@ int x509_crl_parse( x509_crl *chain, const unsigned char *buf, size_t buflen )
             return( POLARSSL_ERR_X509_MALLOC_FAILED );
         }
 
+        x509_crl_init( crl->next );
         crl = crl->next;
-        x509_crl_init( crl );
 
         return( x509_crl_parse( crl, buf, buflen ) );
     }
diff --git a/library/x509_crt.c b/library/x509_crt.c
index 6193ecd12..2d72f6acd 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -819,8 +819,8 @@ int x509_crt_parse_der( x509_crt *chain, const unsigned char *buf,
             return( POLARSSL_ERR_X509_MALLOC_FAILED );
 
         prev = crt;
+        x509_crt_init( crt->next );
         crt = crt->next;
-        x509_crt_init( crt );
     }
 
     if( ( ret = x509_crt_parse_der_core( crt, buf, buflen ) ) != 0 )

From fd60a5c6211bf8f2a1d53348bbda314af17bd94c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Wed, 12 Nov 2014 22:54:24 +0100
Subject: [PATCH 23/57] Add script finding recursive functions

---
 scripts/recursion.pl | 43 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)
 create mode 100755 scripts/recursion.pl

diff --git a/scripts/recursion.pl b/scripts/recursion.pl
new file mode 100755
index 000000000..d75a4ef44
--- /dev/null
+++ b/scripts/recursion.pl
@@ -0,0 +1,43 @@
+#!/usr/bin/perl
+
+# Find functions making recursive calls to themselves.
+# (Multiple recursion where a() calls b() which calls a() not covered.)
+#
+# When the recursion depth might depend on data controlled by the attacker in
+# an unbounded way, those functions should use interation instead.
+#
+# Typical usage: scripts/recursion.pl library/*.c
+
+use warnings;
+use strict;
+
+use utf8;
+use open qw(:std utf8);
+
+# exclude functions that are ok:
+# - mpi_write_hlp: bounded by size of mpi, a compile-time constant
+my $known_ok = qr/mpi_write_hlp/;
+
+my $cur_name;
+my $inside;
+my @funcs;
+
+die "Usage: $0 file.c [...]\n" unless @ARGV;
+
+while (<>)
+{
+    if( /^[^\/#{}\s]/ && ! /\[.*]/ ) {
+        chomp( $cur_name = $_ ) unless $inside;
+    } elsif( /^{/ && $cur_name ) {
+        $inside = 1;
+        $cur_name =~ s/.* ([^ ]*)\(.*/$1/;
+    } elsif( /^}/ && $inside ) {
+        undef $inside;
+        undef $cur_name;
+    } elsif( $inside && /\b\Q$cur_name\E\([^)]/ ) {
+        push @funcs, $cur_name unless /$known_ok/;
+    }
+}
+
+print "$_\n" for @funcs;
+exit @funcs;

From 705b70f122f113377e3ff4187facd242e4324c37 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Thu, 13 Nov 2014 13:35:50 +0100
Subject: [PATCH 24/57] Add new build modes for sanitizers

---
 CMakeLists.txt | 30 ++++++++++++++++--------------
 1 file changed, 16 insertions(+), 14 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1596226c0..4a6b6c32d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -5,27 +5,29 @@ string(REGEX MATCH "Clang" CMAKE_COMPILER_IS_CLANG "${CMAKE_C_COMPILER_ID}")
 
 if(CMAKE_COMPILER_IS_GNUCC)
   set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -W -Wdeclaration-after-statement -Wwrite-strings -Wlogical-op")
-  set(CMAKE_C_FLAGS_RELEASE "-O2")
-  set(CMAKE_C_FLAGS_DEBUG "-g3 -O0")
-  set(CMAKE_C_FLAGS_COVERAGE "-g3 -O0 --coverage")
-  set(CMAKE_C_FLAGS_ASAN "-fsanitize=address -fno-omit-frame-pointer -g3 -O1 -Werror")
-  set(CMAKE_C_FLAGS_CHECK "-O1 -Werror")
-  set(CMAKE_C_FLAGS_CHECKFULL "${CMAKE_C_FLAGS_CHECK} -Wcast-qual")
+  set(CMAKE_C_FLAGS_RELEASE     "-O2")
+  set(CMAKE_C_FLAGS_DEBUG       "-O0 -g3")
+  set(CMAKE_C_FLAGS_COVERAGE    "-O0 -g3 --coverage")
+  set(CMAKE_C_FLAGS_ASAN        "-Werror -fsanitize=address -fno-common -O3")
+  set(CMAKE_C_FLAGS_ASANDBG     "-Werror -fsanitize=address -fno-common -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls ")
+  set(CMAKE_C_FLAGS_CHECK       "-Werror -O1")
+  set(CMAKE_C_FLAGS_CHECKFULL   "${CMAKE_C_FLAGS_CHECK} -Wcast-qual")
 endif(CMAKE_COMPILER_IS_GNUCC)
 
 if(CMAKE_COMPILER_IS_CLANG)
   set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -W -Wdeclaration-after-statement -Wwrite-strings -Wpointer-arith -Wdocumentation -Wunreachable-code")
-  set(CMAKE_C_FLAGS_RELEASE "-O2")
-  set(CMAKE_C_FLAGS_DEBUG "-g3 -O0")
-  set(CMAKE_C_FLAGS_COVERAGE "-g3 -O0 --coverage")
-  set(CMAKE_C_FLAGS_ASAN "-fsanitize=address -fsanitize=undefined -fno-sanitize-recover -fno-omit-frame-pointer -g3 -O1 -Werror")
-  # note: can add -fsanitize-memory-track-origins=2 for debugging with memsan
-  set(CMAKE_C_FLAGS_MEMSAN "-fsanitize=memory -fno-omit-frame-pointer -fno-optimize-sibling-calls -g3 -O1 -Werror")
-  set(CMAKE_C_FLAGS_CHECK "-O1 -Werror")
+  set(CMAKE_C_FLAGS_RELEASE     "-O2")
+  set(CMAKE_C_FLAGS_DEBUG       "-O0 -g3")
+  set(CMAKE_C_FLAGS_COVERAGE    "-O0 -g3 --coverage")
+  set(CMAKE_C_FLAGS_ASAN        "-Werror -fsanitize=address -fno-common -fsanitize=undefined -fno-sanitize-recover -O3")
+  set(CMAKE_C_FLAGS_ASANDBG     "-Werror -fsanitize=address -fno-common -fsanitize=undefined -fno-sanitize-recover -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls ")
+  set(CMAKE_C_FLAGS_MEMSAN      "-Werror -fsanitize=memory -O3")
+  set(CMAKE_C_FLAGS_MEMSANDBG   "-Werror -fsanitize=memory -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize-memory-track-origins=2")
+  set(CMAKE_C_FLAGS_CHECK       "-Werror -O1")
 endif(CMAKE_COMPILER_IS_CLANG)
 
 set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE}
-    CACHE STRING "Choose the type of build: None Debug Release Coverage ASan MemSan Check CheckFull"
+    CACHE STRING "Choose the type of build: None Debug Release Coverage ASan ASanDbg MemSan MemSanDbg Check CheckFull"
     FORCE)
 
 if(CMAKE_BUILD_TYPE STREQUAL "Coverage")

From ca89d89a1065e2a8171dbc2248a99585c626a109 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Thu, 13 Nov 2014 13:56:05 +0100
Subject: [PATCH 25/57] Document build modes better

---
 README.rst | 23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/README.rst b/README.rst
index 8dd823c9c..2abec3c17 100644
--- a/README.rst
+++ b/README.rst
@@ -39,7 +39,7 @@ In order to build the source using CMake, just enter at the command line::
 
     make
 
-There are 5 different active build modes specified within the CMake buildsystem:
+There are many different build modes available within the CMake buildsystem. Most of them are available for gcc and clang, though some are compiler-specific:
 
 - Release.
   This generates the default code without any unnecessary information in the binary files.
@@ -49,8 +49,20 @@ There are 5 different active build modes specified within the CMake buildsystem:
   This generates code coverage information in addition to debug information.
 - ASan.
   This instruments the code with AddressSanitizer to check for memory errors.
+  (This includes LeakSanitizer, with recent version of gcc and clang.)
+  (With recent version of clang, this mode also intruments the code with
+  UndefinedSanitizer to check for undefined behaviour.)
+- ASanDbg.
+  Same as ASan but slower, with debug information and better stack traces.
+- MemSan.
+  This intruments the code with MemorySanitizer to check for uninitialised
+  memory reads. Experimental, needs recent clang on Linux/x86_64.
+- MemSanDbg.
+  Same as ASan but slower, with debug information, better stack traces and
+  origin tracking.
 - Check.
-  This activates more compiler warnings and treats them as errors.
+  This activates the compiler warnings that depend on optimisation and treats
+  all warnings as errors.
 
 Switching build modes in CMake is simple. For debug mode, enter at the command line:
 
@@ -77,6 +89,13 @@ Tests
 
 PolarSSL includes an elaborate test suite in *tests/* that initially requires Perl to generate the tests files (e.g. *test_suite_mpi.c*). These files are generates from a **function file** (e.g. *suites/test_suite_mpi.function*) and a **data file** (e.g. *suites/test_suite_mpi.data*). The **function file** contains the template for each test function. The **data file** contains the test cases, specified as parameters that should be pushed into a template function.
 
+For machines with a Unix shell and OpenSSL (and optionnally GnuTLS) installed, additional test scripts are available:
+
+- *tests/ssl-opt.sh* runs integration tests for various TLS options (renegotiation, resumption, etc.) and tests interoperability of these options with other implementations.
+- *tests/compat.sh* tests interoperability of every ciphersuite with other implementations.
+- *tests/scripts/test-ref-configs.pl* test builds in various reduced configurations.
+- *tests/scripts/all.sh* runs a combination of the above tests with various build options (eg ASan).
+
 Configurations
 ==============
 

From 6cf11642a4b14ac0ef7fd494a2257141954c4f6f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Fri, 14 Nov 2014 12:29:59 +0100
Subject: [PATCH 26/57] Update README to mention config.pl

---
 README.rst | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/README.rst b/README.rst
index 2abec3c17..43253bef6 100644
--- a/README.rst
+++ b/README.rst
@@ -2,6 +2,15 @@
 README for PolarSSL
 ===================
 
+Configuration
+=============
+
+PolarSSL should build out of the box on most systems. Some platform specific options are available in the fully-documented configuration file *include/polarssl/config.h*, which is also the place where features can be selected.
+This file can be edited manually, or in a more programmatic way using the Perl
+script *scripts/config.pl* (use *--help* for usage instructions).
+
+Compiler options can be set using standard variables such as *CC* and *CFLAGS* when using the Make and CMake build system (see below).
+
 Compiling
 =========
 

From 052ae25e5683e537501c217e90f1d33b59afc9f1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Fri, 14 Nov 2014 13:09:41 +0100
Subject: [PATCH 27/57] Avoid advertising private option

---
 scripts/config.pl | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/scripts/config.pl b/scripts/config.pl
index d04be59c8..8998fd6b0 100755
--- a/scripts/config.pl
+++ b/scripts/config.pl
@@ -6,10 +6,11 @@ use warnings;
 use strict;
 
 my $usage = <<EOU;
-$0 [-f <file>] full
 $0 [-f <file>] unset <name>
 $0 [-f <file>] set <name> [<value>]
 EOU
+# for our eyes only:
+# $0 [-f <file>] full
 
 # Things that shouldn't be enabled with "full".
 # Notes:

From e80083cafaa385b7dabbee6134c96e7ae93295f1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Fri, 14 Nov 2014 13:52:32 +0100
Subject: [PATCH 28/57] Add precision about cmake cache

---
 README.rst         | 5 +++++
 configs/README.txt | 2 +-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/README.rst b/README.rst
index 43253bef6..6d18f540d 100644
--- a/README.rst
+++ b/README.rst
@@ -77,6 +77,11 @@ Switching build modes in CMake is simple. For debug mode, enter at the command l
 
     cmake -D CMAKE_BUILD_TYPE:String="Debug" .
 
+Note that, with CMake, if you want to change the compiler or its options after you already ran CMake, you need to clear its cache first, eg (using GNU find)::
+
+    find . -iname '*cmake*' -not -name CMakeLists.txt -exec rm -rf {} +
+    CC=gcc CFLAGS='-fstack-protector-strong -Wa,--noexecstack' cmake .
+
 In order to run the tests, enter::
 
     make test
diff --git a/configs/README.txt b/configs/README.txt
index bab500d8d..f543002b7 100644
--- a/configs/README.txt
+++ b/configs/README.txt
@@ -18,7 +18,7 @@ them, you can pick one of the following methods:
 
    Or, using cmake:
 
-    rm CMakeCache.txt
+    find . -iname '*cmake*' -not -name CMakeLists.txt -exec rm -rf {} +
     CFLAGS="-I$PWD/configs -DPOLARSSL_CONFIG_FILE='<foo.h>'" cmake .
     make
 

From 98aa19148c06c52ac137092a956cf22db54201c1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Fri, 14 Nov 2014 16:34:36 +0100
Subject: [PATCH 29/57] Adjust warnings in different modes

---
 CMakeLists.txt         | 2 +-
 library/CMakeLists.txt | 5 ++---
 tests/CMakeLists.txt   | 6 +-----
 3 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4a6b6c32d..551aa1a52 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -15,7 +15,7 @@ if(CMAKE_COMPILER_IS_GNUCC)
 endif(CMAKE_COMPILER_IS_GNUCC)
 
 if(CMAKE_COMPILER_IS_CLANG)
-  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -W -Wdeclaration-after-statement -Wwrite-strings -Wpointer-arith -Wdocumentation -Wunreachable-code")
+  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -W -Wdeclaration-after-statement -Wwrite-strings -Wpointer-arith")
   set(CMAKE_C_FLAGS_RELEASE     "-O2")
   set(CMAKE_C_FLAGS_DEBUG       "-O0 -g3")
   set(CMAKE_C_FLAGS_COVERAGE    "-O0 -g3 --coverage")
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index 33d96b47f..f562ca6f4 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -78,12 +78,11 @@ set(libs ws2_32)
 endif(WIN32)
 
 if(CMAKE_COMPILER_IS_GNUCC)
-  set(CMAKE_C_FLAGS_CHECK "${CMAKE_C_FLAGS_CHECK} -Wmissing-declarations -Wmissing-prototypes")
-  set(CMAKE_C_FLAGS_CHECKFULL "${CMAKE_C_FLAGS_CHECK} -Wcast-qual")
+  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wmissing-declarations -Wmissing-prototypes")
 endif(CMAKE_COMPILER_IS_GNUCC)
 
 if(CMAKE_COMPILER_IS_CLANG)
-  set(CMAKE_C_FLAGS_CHECK "${CMAKE_C_FLAGS_CHECK} -Wmissing-declarations -Wmissing-prototypes")
+  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wmissing-declarations -Wmissing-prototypes -Wdocumentation -Wunreachable-code")
 endif(CMAKE_COMPILER_IS_CLANG)
 
 if (NOT USE_STATIC_POLARSSL_LIBRARY AND NOT USE_SHARED_POLARSSL_LIBRARY)
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 2e4d9d4a9..7887e21fc 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -29,11 +29,7 @@ function(add_test_suite suite_name)
     add_test(${data_name}-suite test_suite_${data_name})
 endfunction(add_test_suite)
 
-set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function -Wno-unused-value")
-set(CMAKE_C_FLAGS_CHECK "${CMAKE_C_FLAGS_CHECK} -Wno-unused-function -Wno-unused-value")
-if(CMAKE_COMPILER_IS_CLANG)
-    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unreachable-code")
-endif(CMAKE_COMPILER_IS_CLANG)
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function")
 
 add_test_suite(aes aes.ecb)
 add_test_suite(aes aes.cbc)

From 403a86f73dc3d3ac830fb89c4c6d8439f1943b67 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Mon, 17 Nov 2014 12:46:49 +0100
Subject: [PATCH 30/57] ssl_server2: exit cleanly on SIGINT too

---
 programs/ssl/ssl_server2.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 721dab42e..cb69b3339 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -656,8 +656,9 @@ int main( int argc, char *argv[] )
 #endif
 
 #if !defined(_WIN32)
-    /* Abort cleanly on SIGTERM */
+    /* Abort cleanly on SIGTERM and SIGINT */
     signal( SIGTERM, term_handler );
+    signal( SIGINT, term_handler );
 #endif
 
     if( argc == 0 )
@@ -1412,7 +1413,7 @@ reset:
 #if !defined(_WIN32)
         if( received_sigterm )
         {
-            printf( " interrupted by SIGTERM\n" );
+            printf( " interrupted by signal\n" );
             ret = 0;
             goto exit;
         }

From 3a3066c3eebe6f67f66f3bd33d76f35fbd79c7e4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Sat, 20 Sep 2014 12:03:00 +0200
Subject: [PATCH 31/57] ssl_server2 now exits on signal during a read too

---
 programs/ssl/ssl_server2.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index cb69b3339..0b8852ab6 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -572,7 +572,7 @@ int psk_callback( void *p_info, ssl_context *ssl,
 }
 #endif /* POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED */
 
-static int listen_fd;
+static int listen_fd, client_fd = -1;
 
 /* Interruption handler to ensure clean exit (for valgrind testing) */
 #if !defined(_WIN32)
@@ -582,13 +582,13 @@ void term_handler( int sig )
     ((void) sig);
     received_sigterm = 1;
     net_close( listen_fd ); /* causes net_accept() to abort */
+    net_close( client_fd ); /* causes net_read() to abort */
 }
 #endif
 
 int main( int argc, char *argv[] )
 {
     int ret = 0, len, written, frags, exchanges;
-    int client_fd = -1;
     int version_suites[4][2];
     unsigned char buf[IO_BUF_LEN];
 #if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
@@ -1386,6 +1386,15 @@ int main( int argc, char *argv[] )
     printf( " ok\n" );
 
 reset:
+#if !defined(_WIN32)
+    if( received_sigterm )
+    {
+        printf( " interrupted by SIGTERM\n" );
+        ret = 0;
+        goto exit;
+    }
+#endif
+
 #ifdef POLARSSL_ERROR_C
     if( ret != 0 )
     {

From 8c9223df84fe06f40f1355b3e96694f78197041f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Wed, 19 Nov 2014 10:17:21 +0100
Subject: [PATCH 32/57] Add text view to debug_print_buf()

---
 ChangeLog                          |  1 +
 library/debug.c                    | 12 ++++++++++--
 tests/suites/test_suite_debug.data | 10 +++++-----
 3 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 6f55c3297..893c7c1c6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -29,6 +29,7 @@ Changes
    * Blind RSA private operations even when POLARSSL_RSA_NO_CRT is defined.
    * ssl_set_own_cert() now returns an error on key-certificate mismatch.
    * Forbid repeated extensions in X.509 certificates.
+   * debug_print_buf() now prints a text view in addition to hexadecimal.
 
 = PolarSSL 1.3.9 released 2014-10-20
 Security
diff --git a/library/debug.c b/library/debug.c
index a81f502bf..865bd5447 100644
--- a/library/debug.c
+++ b/library/debug.c
@@ -123,6 +123,7 @@ void debug_print_buf( const ssl_context *ssl, int level,
                       unsigned char *buf, size_t len )
 {
     char str[512];
+    char txt[17];
     size_t i, maxlen = sizeof( str ) - 1, idx = 0;
 
     if( ssl->f_dbg == NULL || level > debug_threshold )
@@ -138,6 +139,7 @@ void debug_print_buf( const ssl_context *ssl, int level,
     ssl->f_dbg( ssl->p_dbg, level, str );
 
     idx = 0;
+    memset( txt, 0, sizeof( txt ) );
     for( i = 0; i < len; i++ )
     {
         if( i >= 4096 )
@@ -147,9 +149,11 @@ void debug_print_buf( const ssl_context *ssl, int level,
         {
             if( i > 0 )
             {
-                snprintf( str + idx, maxlen - idx, "\n" );
+                snprintf( str + idx, maxlen - idx, "  %s\n", txt );
                 ssl->f_dbg( ssl->p_dbg, level, str );
+
                 idx = 0;
+                memset( txt, 0, sizeof( txt ) );
             }
 
             if( debug_log_mode == POLARSSL_DEBUG_LOG_FULL )
@@ -162,11 +166,15 @@ void debug_print_buf( const ssl_context *ssl, int level,
 
         idx += snprintf( str + idx, maxlen - idx, " %02x",
                          (unsigned int) buf[i] );
+        txt[i % 16] = ( buf[i] > 31 && buf[i] < 127 ) ? buf[i] : '.' ;
     }
 
     if( len > 0 )
     {
-        snprintf( str + idx, maxlen - idx, "\n" );
+        for( /* i = i */; i % 16 != 0; i++ )
+            idx += snprintf( str + idx, maxlen - idx, "   " );
+
+        snprintf( str + idx, maxlen - idx, "  %s\n", txt );
         ssl->f_dbg( ssl->p_dbg, level, str );
     }
 }
diff --git a/tests/suites/test_suite_debug.data b/tests/suites/test_suite_debug.data
index 9b49f6a48..26d85cb63 100644
--- a/tests/suites/test_suite_debug.data
+++ b/tests/suites/test_suite_debug.data
@@ -32,19 +32,19 @@ Debug print buffer #1
 debug_print_buf:POLARSSL_DEBUG_LOG_FULL:"MyFile":999:"Test return value":"":"MyFile(0999)\: dumping 'Test return value' (0 bytes)\n"
 
 Debug print buffer #2
-debug_print_buf:POLARSSL_DEBUG_LOG_FULL:"MyFile":999:"Test return value":"00":"MyFile(0999)\: dumping 'Test return value' (1 bytes)\nMyFile(0999)\: 0000\:  00\n"
+debug_print_buf:POLARSSL_DEBUG_LOG_FULL:"MyFile":999:"Test return value":"00":"MyFile(0999)\: dumping 'Test return value' (1 bytes)\nMyFile(0999)\: 0000\:  00                                               .\n"
 
 Debug print buffer #3
-debug_print_buf:POLARSSL_DEBUG_LOG_FULL:"MyFile":999:"Test return value":"000102030405060708090A0B0C0D0E0F":"MyFile(0999)\: dumping 'Test return value' (16 bytes)\nMyFile(0999)\: 0000\:  00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n"
+debug_print_buf:POLARSSL_DEBUG_LOG_FULL:"MyFile":999:"Test return value":"000102030405060708090A0B0C0D0E0F":"MyFile(0999)\: dumping 'Test return value' (16 bytes)\nMyFile(0999)\: 0000\:  00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f  ................\n"
 
 Debug print buffer #4
-debug_print_buf:POLARSSL_DEBUG_LOG_FULL:"MyFile":999:"Test return value":"000102030405060708090A0B0C0D0E0F00":"MyFile(0999)\: dumping 'Test return value' (17 bytes)\nMyFile(0999)\: 0000\:  00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\nMyFile(0999)\: 0010\:  00\n"
+debug_print_buf:POLARSSL_DEBUG_LOG_FULL:"MyFile":999:"Test return value":"000102030405060708090A0B0C0D0E0F00":"MyFile(0999)\: dumping 'Test return value' (17 bytes)\nMyFile(0999)\: 0000\:  00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f  ................\nMyFile(0999)\: 0010\:  00                                               .\n"
 
 Debug print buffer #5
-debug_print_buf:POLARSSL_DEBUG_LOG_FULL:"MyFile":999:"Test return value":"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F00":"MyFile(0999)\: dumping 'Test return value' (49 bytes)\nMyFile(0999)\: 0000\:  00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\nMyFile(0999)\: 0010\:  00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\nMyFile(0999)\: 0020\:  00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\nMyFile(0999)\: 0030\:  00\n"
+debug_print_buf:POLARSSL_DEBUG_LOG_FULL:"MyFile":999:"Test return value":"000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F30":"MyFile(0999)\: dumping 'Test return value' (49 bytes)\nMyFile(0999)\: 0000\:  00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f  ................\nMyFile(0999)\: 0010\:  10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f  ................\nMyFile(0999)\: 0020\:  20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f   !"#$%&'()*+,-./\nMyFile(0999)\: 0030\:  30                                               0\n"
 
 Debug print buffer #5 (raw)
-debug_print_buf:POLARSSL_DEBUG_LOG_RAW:"MyFile":999:"Test return value":"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F00":"dumping 'Test return value' (49 bytes)\n0000\:  00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n0010\:  00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n0020\:  00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n0030\:  00\n"
+debug_print_buf:POLARSSL_DEBUG_LOG_RAW:"MyFile":999:"Test return value":"000102030405060708090A0B0C0D0E0F707172737475767778797A7B7C7D7E7F8081828384858687F8F9FAFBFCFDFEFF00":"dumping 'Test return value' (49 bytes)\n0000\:  00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f  ................\n0010\:  70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f  pqrstuvwxyz{|}~.\n0020\:  80 81 82 83 84 85 86 87 f8 f9 fa fb fc fd fe ff  ................\n0030\:  00                                               .\n"
 
 Debug print certificate #1 (RSA)
 depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_BASE64_C:POLARSSL_RSA_C

From 4be3449dbcc41253c8dfc35dd14fcfe5434db789 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Wed, 19 Nov 2014 12:52:43 +0100
Subject: [PATCH 33/57] Add Readme about X.509 test files

---
 tests/data_files/Readme-x509.txt | 85 ++++++++++++++++++++++++++++++++
 tests/data_files/server6.pem     | 13 -----
 2 files changed, 85 insertions(+), 13 deletions(-)
 create mode 100644 tests/data_files/Readme-x509.txt
 delete mode 100644 tests/data_files/server6.pem

diff --git a/tests/data_files/Readme-x509.txt b/tests/data_files/Readme-x509.txt
new file mode 100644
index 000000000..3022aae7c
--- /dev/null
+++ b/tests/data_files/Readme-x509.txt
@@ -0,0 +1,85 @@
+This documents the X.509 CAs, certificates, and CRLS used for testing.
+
+Certification authorities
+-------------------------
+
+There are two main CAs for use as trusted roots:
+- test-ca.crt aka "C=NL, O=PolarSSL, CN=PolarSSL Test CA"
+  uses a RSA-2048 key
+- test-ca2*.crt aka "C=NL, O=PolarSSL, CN=Polarssl Test EC CA"
+  uses an EC key with NIST P-384 (aka secp384r1)
+  variants used to test the keyUsage extension
+The files test-ca_cat12 and test-ca_cat21 contain them concatenated both ways.
+
+Two intermediate CAs are signed by them:
+- test-int-ca.crt "C=NL, O=PolarSSL, CN=PolarSSL Test Intermediate CA"
+  uses RSA-4096, signed by test-ca2
+- test-int-ca2.crt "C=NL, O=PolarSSL, CN=PolarSSL Test Intermediate EC CA"
+  uses an EC key with NIST P-256, signed by test-ca
+
+Finally, other CAs for specific purposes:
+- enco-ca-prstr.pem: has its CN encoded as a printable string, but child cert
+  enco-cert-utf8str.pem has its issuer's CN encoded as a UTF-8 string.
+- test-ca-v1.crt: v1 "CA", signs
+    server1-v1.crt: v1 "intermediate CA", signs
+        server2-v1*.crt: EE cert (without of with chain in same file)
+
+End-entity certificates
+-----------------------
+
+Short information fields:
+
+- name or pattern
+- issuing CA:   1   -> test-ca.crt
+                2   -> test-ca2.crt
+                I1  -> test-int-ca.crt
+                I2  -> test-int-ca2.crt
+                O   -> other
+- key type: R -> RSA, E -> EC
+- C -> there is a CRL revoking this cert (see below)
+- L -> CN=localhost (useful for local test servers)
+- P1, P2 if the file include parent (resp. parent + grandparent)
+- free-form comments
+
+List of certificates:
+
+- cert_example_multi*.crt: 1/O R: subjectAltName
+- cert_example_wildcard.crt: 1 R: wildcard in subject's CN
+- cert_md*.crt, cert_sha*.crt: 1 R: signature hash
+- cert_v1_with_ext.crt: 1 R: v1 with extensions (illegal)
+- cli2.crt: 2 E: basic
+- enco-cert-utf8str.pem: see enco-ca-prstr.pem above
+- server1*.crt: 1* R C*: misc *(server1-v1 see test-ca-v1.crt above)
+    *CRL for: .cert_type.crt, .crt, .key_usage.crt, .v1.crt
+- server2-v1*.crt: O R: see test-ca-v1.crt above
+- server2*.crt: 1 R L: misc
+- server3.crt: 1 E L: EC cert signed by RSA CA
+- server4.crt: 2 R L: RSA cert signed by EC CA
+- server5*.crt: 2* E L: misc *(except server5-selfsigned)
+    -sha*: hashes
+    -eku*: extendeKeyUsage (cli/srv = www client/server, cs = codesign, etc)
+    -ku*: keyUsage (ds = signatures, ke/ka = key exchange/agreement)
+- server6-ss-child.crt: O E: "child" of non-CA server5-selfsigned
+- server6.crt, server6.pem: 2 E L C: revoked
+- server7*.crt: I1 E L P1*: EC signed by RSA signed by EC *(except 7.crt)
+    *_space: with PEM error(s)
+- server8*.crt: I2 R L: RSA signed by EC signed by RSA (P1 for _int-ca2)
+- server9*.crt: 1 R C* L P1*: signed using RSASSA-PSS
+    *CRL for: 9.crt, -badsign, -with-ca (P1)
+
+Certificate revocation lists
+----------------------------
+
+Signing CA in parentheses (same meaning as certificates).
+
+- crl-ec-sha*: (2) server6.crt
+- crl-future.pem: (2) server6.crt + unkown
+- crl-rsa-pss-*.pem: (1) server9{,badsign,with-ca}.crt + cert_sha384.crt + unknown
+- crl.pem, crl_expired.pem: (1) server1{,.cert_type,.key_usage,.v1}.crt + unknown
+- crl_md*.pem: crl_sha*.pem: (1) same as crl.pem
+- crt_cat_*.pem: (1+2) concatenations in various orders:
+    ec = crl-ec-sha256.pem, ecfut = crl-future.pem
+    rsa = crl.pem, rsabadpem = same with pem error, rsaexp = crl_expired.pem
+
+Note: crl_future would revoke server9 and cert_sha384.crt if signed by CA 1
+      crl-rsa-pss* would revoke server6.crt if signed by CA 2
diff --git a/tests/data_files/server6.pem b/tests/data_files/server6.pem
deleted file mode 100644
index f78cb1043..000000000
--- a/tests/data_files/server6.pem
+++ /dev/null
@@ -1,13 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIB3TCCAZSgAwIBAgIBGDAJBgcqhkjOPQQBMD4xCzAJBgNVBAYTAk5MMREwDwYD
-VQQKEwhQb2xhclNTTDEcMBoGA1UEAxMTUG9sYXJTU0wgVGVzdCBFQyBDQTAeFw0x
-MzA4MDgxNjQ0MTBaFw0yMzA4MDYxNjQ0MTBaMDQxCzAJBgNVBAYTAk5MMREwDwYD
-VQQKEwhQb2xhclNTTDESMBAGA1UEAxMJbG9jYWxob3N0MEkwEwYHKoZIzj0CAQYI
-KoZIzj0DAQEDMgAEE2sIbSZOSEinZM3q2MMOy8egM8Y9BAcsuwxO9UpS1B8nT9u1
-1bvjTh5VQAgJAU+Oo4GdMIGaMAkGA1UdEwQCMAAwHQYDVR0OBBYEFDYreWnU1s1J
-AG49ALPOQliFaJahMG4GA1UdIwRnMGWAFNCkRpkIZ/H0utlW6GcwC/zvJRZjoUKk
-QDA+MQswCQYDVQQGEwJOTDERMA8GA1UEChMIUG9sYXJTU0wxHDAaBgNVBAMTE1Bv
-bGFyU1NMIFRlc3QgRUMgQ0GCCQClZwiM/hcKsjAJBgcqhkjOPQQBAzgAMDUCGQDq
-PIUaCr8u28R7V0G/TEOklXgPawdiY4ICGDzmBegZHs7BcNwENa1fn4JYUdTPqKwl
-LA==
------END CERTIFICATE-----

From 57a5d60abbc3169a1baf15b933120d8b269efcf2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Wed, 19 Nov 2014 14:04:09 +0100
Subject: [PATCH 34/57] Add tests for concatenated CRLs

---
 tests/data_files/crl_cat_ec-rsa.pem       | 21 ++++++++++++++++++++
 tests/data_files/crl_cat_ecfut-rsa.pem    | 22 +++++++++++++++++++++
 tests/data_files/crl_cat_rsa-ec.pem       | 21 ++++++++++++++++++++
 tests/data_files/crl_cat_rsabadpem-ec.pem | 21 ++++++++++++++++++++
 tests/data_files/crt_cat_rsaexp-ec.pem    | 21 ++++++++++++++++++++
 tests/suites/test_suite_x509parse.data    | 24 +++++++++++++++++++++++
 6 files changed, 130 insertions(+)
 create mode 100644 tests/data_files/crl_cat_ec-rsa.pem
 create mode 100644 tests/data_files/crl_cat_ecfut-rsa.pem
 create mode 100644 tests/data_files/crl_cat_rsa-ec.pem
 create mode 100644 tests/data_files/crl_cat_rsabadpem-ec.pem
 create mode 100644 tests/data_files/crt_cat_rsaexp-ec.pem

diff --git a/tests/data_files/crl_cat_ec-rsa.pem b/tests/data_files/crl_cat_ec-rsa.pem
new file mode 100644
index 000000000..3cda8ff03
--- /dev/null
+++ b/tests/data_files/crl_cat_ec-rsa.pem
@@ -0,0 +1,21 @@
+-----BEGIN X509 CRL-----
+MIIBcTCB9wIBATAKBggqhkjOPQQDAjA+MQswCQYDVQQGEwJOTDERMA8GA1UEChMI
+UG9sYXJTU0wxHDAaBgNVBAMTE1BvbGFyc3NsIFRlc3QgRUMgQ0EXDTEzMDkyNDE2
+MzEwOFoXDTIzMDkyMjE2MzEwOFowFDASAgEKFw0xMzA5MjQxNjI4MzhaoHIwcDBu
+BgNVHSMEZzBlgBSdbSAkSQE/K8t4tRm8fiTJ2/s2fKFCpEAwPjELMAkGA1UEBhMC
+TkwxETAPBgNVBAoTCFBvbGFyU1NMMRwwGgYDVQQDExNQb2xhcnNzbCBUZXN0IEVD
+IENBggkAwUPifmJDzOgwCgYIKoZIzj0EAwIDaQAwZgIxAKuQ684s7gyhtxKJr6Ln
+S2BQ02f1jjPHrZVdXaZvm3C5tGi2cKkoK1aMiyC3LsRCuAIxAIMhj0TmcuIZr5fX
+g5RByD7zUnZBpoEAdgxFy4JPJ2IViWOPekSGh8b/JY1VNS6Zbw==
+-----END X509 CRL-----
+-----BEGIN X509 CRL-----
+MIIBqzCBlDANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDERMA8GA1UEChMI
+UG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EXDTExMDIyMDEwMjI1
+OVoXDTE5MTEyNTEwMjI1OVowKDASAgEBFw0xMTAyMTIxNDQ0MDdaMBICAQMXDTEx
+MDIxMjE0NDQwN1owDQYJKoZIhvcNAQEFBQADggEBAJYuWdKPdblMVWCnxpMnchuL
+dqWzK2BA0RelCaGjpxuwX3NmLDm+5hKja/DJxaRqTOf4RSC3kcX8CdIldsLO96dz
+//wAQdFPDhy6AFT5vKTO8ItPHDb7qFOqFqpeJi5XN1yoZGTB1ei0mgD3xBaKbp6U
+yCOZJSIFomt7piT4GcgWVHLUmpyHDDeodNhYPrN0jf2mr+ECd9fQJYdz1qm0Xx+Q
+NbKXDiPRmPX0qVleCZSeSp1JAmU4GoCO+96qQUpjgll+6xWya3UNj61f9sh0Zzr7
+5ug2LZo5uBM/LpNR1K3TLxNCcg7uUPTn9r143d7ivJhPl3tEJn4PXjv6mlLoOgU=
+-----END X509 CRL-----
diff --git a/tests/data_files/crl_cat_ecfut-rsa.pem b/tests/data_files/crl_cat_ecfut-rsa.pem
new file mode 100644
index 000000000..87b8c2944
--- /dev/null
+++ b/tests/data_files/crl_cat_ecfut-rsa.pem
@@ -0,0 +1,22 @@
+-----BEGIN X509 CRL-----
+MIIBgzCCAQoCAQEwCQYHKoZIzj0EATA+MQswCQYDVQQGEwJOTDERMA8GA1UEChMI
+UG9sYXJTU0wxHDAaBgNVBAMTE1BvbGFyc3NsIFRlc3QgRUMgQ0EXDTMyMDMxMDEx
+MDUxNVoXDTQyMDMwODExMDUxNVowKDASAgEKFw0xMzA5MjQxNjI4MzhaMBICARYX
+DTE0MDEyMDEzNDMwNVqgcjBwMG4GA1UdIwRnMGWAFJ1tICRJAT8ry3i1Gbx+JMnb
++zZ8oUKkQDA+MQswCQYDVQQGEwJOTDERMA8GA1UEChMIUG9sYXJTU0wxHDAaBgNV
+BAMTE1BvbGFyc3NsIFRlc3QgRUMgQ0GCCQDBQ+J+YkPM6DAJBgcqhkjOPQQBA2gA
+MGUCMQCmsvNsOQdbGpmzpeZlKU9lDP6yyWenrI/89swZYogE3cSPob4tOzeYg38i
+or91IPgCMD7N/0Qz6Nq2IgBtZORLgsA0ltK+W6AOS+/EIhvGuXV8uguUyYknl4vb
++cE+lWxhCQ==
+-----END X509 CRL-----
+-----BEGIN X509 CRL-----
+MIIBqzCBlDANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDERMA8GA1UEChMI
+UG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EXDTExMDIyMDEwMjI1
+OVoXDTE5MTEyNTEwMjI1OVowKDASAgEBFw0xMTAyMTIxNDQ0MDdaMBICAQMXDTEx
+MDIxMjE0NDQwN1owDQYJKoZIhvcNAQEFBQADggEBAJYuWdKPdblMVWCnxpMnchuL
+dqWzK2BA0RelCaGjpxuwX3NmLDm+5hKja/DJxaRqTOf4RSC3kcX8CdIldsLO96dz
+//wAQdFPDhy6AFT5vKTO8ItPHDb7qFOqFqpeJi5XN1yoZGTB1ei0mgD3xBaKbp6U
+yCOZJSIFomt7piT4GcgWVHLUmpyHDDeodNhYPrN0jf2mr+ECd9fQJYdz1qm0Xx+Q
+NbKXDiPRmPX0qVleCZSeSp1JAmU4GoCO+96qQUpjgll+6xWya3UNj61f9sh0Zzr7
+5ug2LZo5uBM/LpNR1K3TLxNCcg7uUPTn9r143d7ivJhPl3tEJn4PXjv6mlLoOgU=
+-----END X509 CRL-----
diff --git a/tests/data_files/crl_cat_rsa-ec.pem b/tests/data_files/crl_cat_rsa-ec.pem
new file mode 100644
index 000000000..ded369d89
--- /dev/null
+++ b/tests/data_files/crl_cat_rsa-ec.pem
@@ -0,0 +1,21 @@
+-----BEGIN X509 CRL-----
+MIIBqzCBlDANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDERMA8GA1UEChMI
+UG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EXDTExMDIyMDEwMjI1
+OVoXDTE5MTEyNTEwMjI1OVowKDASAgEBFw0xMTAyMTIxNDQ0MDdaMBICAQMXDTEx
+MDIxMjE0NDQwN1owDQYJKoZIhvcNAQEFBQADggEBAJYuWdKPdblMVWCnxpMnchuL
+dqWzK2BA0RelCaGjpxuwX3NmLDm+5hKja/DJxaRqTOf4RSC3kcX8CdIldsLO96dz
+//wAQdFPDhy6AFT5vKTO8ItPHDb7qFOqFqpeJi5XN1yoZGTB1ei0mgD3xBaKbp6U
+yCOZJSIFomt7piT4GcgWVHLUmpyHDDeodNhYPrN0jf2mr+ECd9fQJYdz1qm0Xx+Q
+NbKXDiPRmPX0qVleCZSeSp1JAmU4GoCO+96qQUpjgll+6xWya3UNj61f9sh0Zzr7
+5ug2LZo5uBM/LpNR1K3TLxNCcg7uUPTn9r143d7ivJhPl3tEJn4PXjv6mlLoOgU=
+-----END X509 CRL-----
+-----BEGIN X509 CRL-----
+MIIBcTCB9wIBATAKBggqhkjOPQQDAjA+MQswCQYDVQQGEwJOTDERMA8GA1UEChMI
+UG9sYXJTU0wxHDAaBgNVBAMTE1BvbGFyc3NsIFRlc3QgRUMgQ0EXDTEzMDkyNDE2
+MzEwOFoXDTIzMDkyMjE2MzEwOFowFDASAgEKFw0xMzA5MjQxNjI4MzhaoHIwcDBu
+BgNVHSMEZzBlgBSdbSAkSQE/K8t4tRm8fiTJ2/s2fKFCpEAwPjELMAkGA1UEBhMC
+TkwxETAPBgNVBAoTCFBvbGFyU1NMMRwwGgYDVQQDExNQb2xhcnNzbCBUZXN0IEVD
+IENBggkAwUPifmJDzOgwCgYIKoZIzj0EAwIDaQAwZgIxAKuQ684s7gyhtxKJr6Ln
+S2BQ02f1jjPHrZVdXaZvm3C5tGi2cKkoK1aMiyC3LsRCuAIxAIMhj0TmcuIZr5fX
+g5RByD7zUnZBpoEAdgxFy4JPJ2IViWOPekSGh8b/JY1VNS6Zbw==
+-----END X509 CRL-----
diff --git a/tests/data_files/crl_cat_rsabadpem-ec.pem b/tests/data_files/crl_cat_rsabadpem-ec.pem
new file mode 100644
index 000000000..a035e1899
--- /dev/null
+++ b/tests/data_files/crl_cat_rsabadpem-ec.pem
@@ -0,0 +1,21 @@
+-----BEGIN X509 CRL-----
+MIIBqzCBlDANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDERMA8GA1UEChMI
+UG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EXDTExMDIyMDEwMjI1
+OVoXDTE5MTEyNTEwMjI1OVowKDASAgEBFw0xMTAyMTIxNDQ0MDdaMBICAQMXDTEx
+MDIxMjE0NDQwN1owDQYJKoZIhvcNAQEFBQADggEBAJYuWdKPdblMVWCnxpMnchuL
+dqWzK2BA0RelCaGjpxuwX3NmLDm+5hKja/DJxaRqTOf4RSC3kcX8CdIldsLO96dz
+//wAQdFPDhy6AFT5vKTO8ItPHDb7qFOqFqpeJi5XN1yoZGTB1ei0mgD3xBaKbp6U
+yCOZJSIFomt7piT4GcgWVHLUmpyHDDeodNhYPrN0jf2mr+ECd9fQJYdz1qm0Xx+Q
+NbKXDiPRmPX0qVleCZSeSp1JAmU4GoCO+96qQUpjgll+6xWya3UNj61f9sh0Zzr7
+5ug2LZo5uBM/LpNR1K3TLxNCcg7uUPTn9r143d7ivJhPl3tEJn4PXjv6mlLoOgU
+-----END X509 CRL-----
+-----BEGIN X509 CRL-----
+MIIBcTCB9wIBATAKBggqhkjOPQQDAjA+MQswCQYDVQQGEwJOTDERMA8GA1UEChMI
+UG9sYXJTU0wxHDAaBgNVBAMTE1BvbGFyc3NsIFRlc3QgRUMgQ0EXDTEzMDkyNDE2
+MzEwOFoXDTIzMDkyMjE2MzEwOFowFDASAgEKFw0xMzA5MjQxNjI4MzhaoHIwcDBu
+BgNVHSMEZzBlgBSdbSAkSQE/K8t4tRm8fiTJ2/s2fKFCpEAwPjELMAkGA1UEBhMC
+TkwxETAPBgNVBAoTCFBvbGFyU1NMMRwwGgYDVQQDExNQb2xhcnNzbCBUZXN0IEVD
+IENBggkAwUPifmJDzOgwCgYIKoZIzj0EAwIDaQAwZgIxAKuQ684s7gyhtxKJr6Ln
+S2BQ02f1jjPHrZVdXaZvm3C5tGi2cKkoK1aMiyC3LsRCuAIxAIMhj0TmcuIZr5fX
+g5RByD7zUnZBpoEAdgxFy4JPJ2IViWOPekSGh8b/JY1VNS6Zbw==
+-----END X509 CRL-----
diff --git a/tests/data_files/crt_cat_rsaexp-ec.pem b/tests/data_files/crt_cat_rsaexp-ec.pem
new file mode 100644
index 000000000..4f74c9ac2
--- /dev/null
+++ b/tests/data_files/crt_cat_rsaexp-ec.pem
@@ -0,0 +1,21 @@
+-----BEGIN X509 CRL-----
+MIIBqzCBlDANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDERMA8GA1UEChMI
+UG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EXDTExMDIyMDEwMjQx
+OVoXDTExMDIyMDExMjQxOVowKDASAgEBFw0xMTAyMTIxNDQ0MDdaMBICAQMXDTEx
+MDIxMjE0NDQwN1owDQYJKoZIhvcNAQEFBQADggEBAKgP1XmCIPbfY1/UO+SVFQir
+jArZ94QnQdoan4tJ29d8DmTxJ+z9/KyWNoGeOwc9P/2GQQaZahQOBr0f6lYd67Ct
+wFVh/Q2zF8FgRcrQV7u/vJM33Q2yEsQkMGlM7rE5lC972vUKWu/NKq8bN9W/tWxZ
+SFbvTXpv024aI0IRudpOCALnIy8SFhVb2/52IN2uR6qrFizDexMEdSckgpHuJzGS
+IiANhIMn5LdQYJFjPgBzQU12tDdgzcpxtGhT10y4uQre+UbSjw+iVyml3issw59k
+OSmkWFb06LamRC215JAMok3YQO5RnxCR8EjqPcJr+7+O9a1O1++yiaitg4bUjEA=
+-----END X509 CRL-----
+-----BEGIN X509 CRL-----
+MIIBcTCB9wIBATAKBggqhkjOPQQDAjA+MQswCQYDVQQGEwJOTDERMA8GA1UEChMI
+UG9sYXJTU0wxHDAaBgNVBAMTE1BvbGFyc3NsIFRlc3QgRUMgQ0EXDTEzMDkyNDE2
+MzEwOFoXDTIzMDkyMjE2MzEwOFowFDASAgEKFw0xMzA5MjQxNjI4MzhaoHIwcDBu
+BgNVHSMEZzBlgBSdbSAkSQE/K8t4tRm8fiTJ2/s2fKFCpEAwPjELMAkGA1UEBhMC
+TkwxETAPBgNVBAoTCFBvbGFyU1NMMRwwGgYDVQQDExNQb2xhcnNzbCBUZXN0IEVD
+IENBggkAwUPifmJDzOgwCgYIKoZIzj0EAwIDaQAwZgIxAKuQ684s7gyhtxKJr6Ln
+S2BQ02f1jjPHrZVdXaZvm3C5tGi2cKkoK1aMiyC3LsRCuAIxAIMhj0TmcuIZr5fX
+g5RByD7zUnZBpoEAdgxFy4JPJ2IViWOPekSGh8b/JY1VNS6Zbw==
+-----END X509 CRL-----
diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data
index 097a86171..21c9fba60 100644
--- a/tests/suites/test_suite_x509parse.data
+++ b/tests/suites/test_suite_x509parse.data
@@ -646,6 +646,30 @@ X509 Certificate verification #75 (encoding mismatch)
 depends_on:POLARSSL_PEM_PARSE_C
 x509_verify:"data_files/enco-cert-utf8str.pem":"data_files/enco-ca-prstr.pem":"data_files/crl.pem":"NULL":0:0:"NULL"
 
+X509 Certificate verification #76 (multiple CRLs, not revoked)
+depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_ECDSA_C:POLARSSL_ECP_DP_SECP384R1_ENABLED:POLARSSL_ECP_DP_SECP256R1_ENABLED:POLARSSL_SHA256_C:POLARSSL_RSA_C
+x509_verify:"data_files/server5.crt":"data_files/test-ca_cat12.crt":"data_files/crl_cat_ec-rsa.pem":"NULL":0:0:"NULL"
+
+X509 Certificate verification #77 (multiple CRLs, revoked)
+depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_ECDSA_C:POLARSSL_ECP_DP_SECP384R1_ENABLED:POLARSSL_ECP_DP_SECP256R1_ENABLED:POLARSSL_SHA256_C:POLARSSL_RSA_C
+x509_verify:"data_files/server6.crt":"data_files/test-ca_cat12.crt":"data_files/crl_cat_ec-rsa.pem":"NULL":POLARSSL_ERR_X509_CERT_VERIFY_FAILED:BADCERT_REVOKED:"NULL"
+
+X509 Certificate verification #78 (multiple CRLs, revoked by second)
+depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_ECDSA_C:POLARSSL_ECP_DP_SECP384R1_ENABLED:POLARSSL_ECP_DP_SECP256R1_ENABLED:POLARSSL_SHA256_C:POLARSSL_RSA_C
+x509_verify:"data_files/server6.crt":"data_files/test-ca_cat12.crt":"data_files/crl_cat_rsa-ec.pem":"NULL":POLARSSL_ERR_X509_CERT_VERIFY_FAILED:BADCERT_REVOKED:"NULL"
+
+X509 Certificate verification #79 (multiple CRLs, revoked by future)
+depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_ECDSA_C:POLARSSL_ECP_DP_SECP384R1_ENABLED:POLARSSL_ECP_DP_SECP256R1_ENABLED:POLARSSL_SHA256_C:POLARSSL_RSA_C
+x509_verify:"data_files/server6.crt":"data_files/test-ca_cat12.crt":"data_files/crl_cat_ecfut-rsa.pem":"NULL":POLARSSL_ERR_X509_CERT_VERIFY_FAILED:BADCERT_REVOKED|BADCRL_FUTURE:"NULL"
+
+X509 Certificate verification #80 (multiple CRLs, first future, revoked by second)
+depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_ECDSA_C:POLARSSL_ECP_DP_SECP384R1_ENABLED:POLARSSL_ECP_DP_SECP256R1_ENABLED:POLARSSL_SHA256_C:POLARSSL_RSA_C
+x509_verify:"data_files/server1.crt":"data_files/test-ca_cat12.crt":"data_files/crl_cat_ecfut-rsa.pem":"NULL":POLARSSL_ERR_X509_CERT_VERIFY_FAILED:BADCERT_REVOKED:"NULL"
+
+X509 Certificate verification #81 (multiple CRLs, none relevant)
+depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_ECDSA_C:POLARSSL_ECP_DP_SECP384R1_ENABLED:POLARSSL_ECP_DP_SECP256R1_ENABLED:POLARSSL_SHA256_C:POLARSSL_RSA_C
+x509_verify:"data_files/enco-cert-utf8str.pem":"data_files/enco-ca-prstr.pem":"data_files/crl_cat_rsa-ec.pem":"NULL":0:0:"NULL"
+
 X509 Parse Selftest
 depends_on:POLARSSL_SHA1_C:POLARSSL_PEM_PARSE_C:POLARSSL_CERTS_C
 x509_selftest:

From 426d4ae7ff9960441b4d5837d0df34d3f8882855 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Wed, 19 Nov 2014 16:58:28 +0100
Subject: [PATCH 35/57] Split x509_crl_parse_der() out of x509_crl_parse()

---
 ChangeLog                   |   1 +
 include/polarssl/x509_crl.h |  25 +++++--
 library/x509_crl.c          | 136 +++++++++++++++++-------------------
 3 files changed, 86 insertions(+), 76 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 893c7c1c6..d1a87be76 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -15,6 +15,7 @@ Security
 
 Features
    * Add function pk_check_pair() to test if public and private keys match.
+   * Add x509_crl_parse_der().
 
 Bugfix
    * User set CFLAGS were ignore by Cmake with gcc (introduced in 1.3.9, found
diff --git a/include/polarssl/x509_crl.h b/include/polarssl/x509_crl.h
index 9f597a855..4ddbafc37 100644
--- a/include/polarssl/x509_crl.h
+++ b/include/polarssl/x509_crl.h
@@ -100,11 +100,23 @@ typedef struct _x509_crl
 x509_crl;
 
 /**
- * \brief          Parse one or more CRLs and add them
- *                 to the chained list
+ * \brief          Parse a DER-encoded CRL and append it to the chained list
  *
  * \param chain    points to the start of the chain
- * \param buf      buffer holding the CRL data
+ * \param buf      buffer holding the CRL data in DER format
+ * \param buflen   size of the buffer
+ *
+ * \return         0 if successful, or a specific X509 or PEM error code
+ */
+int x509_crl_parse_der( x509_crl *chain,
+                        const unsigned char *buf, size_t buflen );
+/**
+ * \brief          Parse one or more CRLs and append them to the chained list
+ *
+ * \note           Mutliple CRLs are accepted only if using PEM format
+ *
+ * \param chain    points to the start of the chain
+ * \param buf      buffer holding the CRL data in PEM or DER format
  * \param buflen   size of the buffer
  *
  * \return         0 if successful, or a specific X509 or PEM error code
@@ -113,11 +125,12 @@ int x509_crl_parse( x509_crl *chain, const unsigned char *buf, size_t buflen );
 
 #if defined(POLARSSL_FS_IO)
 /**
- * \brief          Load one or more CRLs and add them
- *                 to the chained list
+ * \brief          Load one or more CRLs and append them to the chained list
+ *
+ * \note           Mutliple CRLs are accepted only if using PEM format
  *
  * \param chain    points to the start of the chain
- * \param path     filename to read the CRLs from
+ * \param path     filename to read the CRLs from (in PEM or DER encoding)
  *
  * \return         0 if successful, or a specific X509 or PEM error code
  */
diff --git a/library/x509_crl.c b/library/x509_crl.c
index b9a5c1373..6ad9d0026 100644
--- a/library/x509_crl.c
+++ b/library/x509_crl.c
@@ -252,25 +252,16 @@ static int x509_get_entries( unsigned char **p,
 }
 
 /*
- * Parse one or more CRLs and add them to the chained list
+ * Parse one  CRLs in DER format and append it to the chained list
  */
-int x509_crl_parse( x509_crl *chain, const unsigned char *buf, size_t buflen )
+int x509_crl_parse_der( x509_crl *chain,
+                        const unsigned char *buf, size_t buflen )
 {
     int ret;
     size_t len;
     unsigned char *p, *end;
-    x509_crl *crl;
     x509_buf sig_params1, sig_params2;
-
-#if defined(POLARSSL_PEM_PARSE_C)
-    size_t use_len;
-    pem_context pem;
-#endif
-
-    memset( &sig_params1, 0, sizeof( x509_buf ) );
-    memset( &sig_params2, 0, sizeof( x509_buf ) );
-
-    crl = chain;
+    x509_crl *crl = chain;
 
     /*
      * Check for valid input
@@ -278,12 +269,15 @@ int x509_crl_parse( x509_crl *chain, const unsigned char *buf, size_t buflen )
     if( crl == NULL || buf == NULL )
         return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
 
-    while( crl->version != 0 && crl->next != NULL )
-        crl = crl->next;
+    memset( &sig_params1, 0, sizeof( x509_buf ) );
+    memset( &sig_params2, 0, sizeof( x509_buf ) );
 
     /*
      * Add new CRL on the end of the chain if needed.
      */
+    while( crl->version != 0 && crl->next != NULL )
+        crl = crl->next;
+
     if( crl->version != 0 && crl->next == NULL )
     {
         crl->next = (x509_crl *) polarssl_malloc( sizeof( x509_crl ) );
@@ -298,53 +292,18 @@ int x509_crl_parse( x509_crl *chain, const unsigned char *buf, size_t buflen )
         crl = crl->next;
     }
 
-#if defined(POLARSSL_PEM_PARSE_C)
-    pem_init( &pem );
-    ret = pem_read_buffer( &pem,
-                           "-----BEGIN X509 CRL-----",
-                           "-----END X509 CRL-----",
-                           buf, NULL, 0, &use_len );
+    /*
+     * Copy raw DER-encoded CRL
+     */
+    if( ( p = polarssl_malloc( buflen ) ) == NULL )
+        return( POLARSSL_ERR_X509_MALLOC_FAILED );
 
-    if( ret == 0 )
-    {
-        /*
-         * Was PEM encoded
-         */
-        buflen -= use_len;
-        buf += use_len;
-
-        /*
-         * Steal PEM buffer
-         */
-        p = pem.buf;
-        pem.buf = NULL;
-        len = pem.buflen;
-        pem_free( &pem );
-    }
-    else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
-    {
-        pem_free( &pem );
-        return( ret );
-    }
-    else
-#endif /* POLARSSL_PEM_PARSE_C */
-    {
-        /*
-         * nope, copy the raw DER data
-         */
-        p = (unsigned char *) polarssl_malloc( len = buflen );
-
-        if( p == NULL )
-            return( POLARSSL_ERR_X509_MALLOC_FAILED );
-
-        memcpy( p, buf, buflen );
-
-        buflen = 0;
-    }
+    memcpy( p, buf, buflen );
 
     crl->raw.p = p;
-    crl->raw.len = len;
-    end = p + len;
+    crl->raw.len = buflen;
+
+    end = p + buflen;
 
     /*
      * CertificateList  ::=  SEQUENCE  {
@@ -522,21 +481,58 @@ int x509_crl_parse( x509_crl *chain, const unsigned char *buf, size_t buflen )
                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
     }
 
-    if( buflen > 0 )
+    return( 0 );
+}
+
+/*
+ * Parse one or more CRLs and add them to the chained list
+ */
+int x509_crl_parse( x509_crl *chain, const unsigned char *buf, size_t buflen )
+{
+    int ret;
+
+    if( chain == NULL || buf == NULL )
+        return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
+
+#if defined(POLARSSL_PEM_PARSE_C)
+    size_t use_len;
+    pem_context pem;
+
+    pem_init( &pem );
+    ret = pem_read_buffer( &pem,
+                           "-----BEGIN X509 CRL-----",
+                           "-----END X509 CRL-----",
+                           buf, NULL, 0, &use_len );
+
+    if( ret == 0 )
     {
-        crl->next = (x509_crl *) polarssl_malloc( sizeof( x509_crl ) );
+        /*
+         * Was PEM encoded
+         */
+        buflen -= use_len;
+        buf += use_len;
 
-        if( crl->next == NULL )
-        {
-            x509_crl_free( crl );
-            return( POLARSSL_ERR_X509_MALLOC_FAILED );
-        }
+        if( ( ret = x509_crl_parse_der( chain, pem.buf, pem.buflen ) ) != 0 )
+            return( ret );
 
-        x509_crl_init( crl->next );
-        crl = crl->next;
-
-        return( x509_crl_parse( crl, buf, buflen ) );
+        pem_free( &pem );
     }
+    else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
+    {
+        pem_free( &pem );
+        return( ret );
+    }
+    else
+#endif /* POLARSSL_PEM_PARSE_C */
+    {
+        if( ( ret = x509_crl_parse_der( chain, buf, buflen ) ) != 0 )
+            return( ret );
+
+        buflen = 0;
+    }
+
+    if( buflen > 0 )
+        return( x509_crl_parse( chain, buf, buflen ) );
 
     return( 0 );
 }

From 6ed2d926298dcffca1485fbc2d0ae7ec579a2026 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Wed, 19 Nov 2014 19:05:03 +0100
Subject: [PATCH 36/57] Make x509_crl_parse() iterative

---
 library/x509_crl.c | 72 ++++++++++++++++++++++++----------------------
 1 file changed, 37 insertions(+), 35 deletions(-)

diff --git a/library/x509_crl.c b/library/x509_crl.c
index 6ad9d0026..c8101b546 100644
--- a/library/x509_crl.c
+++ b/library/x509_crl.c
@@ -489,52 +489,54 @@ int x509_crl_parse_der( x509_crl *chain,
  */
 int x509_crl_parse( x509_crl *chain, const unsigned char *buf, size_t buflen )
 {
+#if defined(POLARSSL_PEM_PARSE_C)
     int ret;
+    size_t use_len;
+    pem_context pem;
+    int is_pem = 0;
 
     if( chain == NULL || buf == NULL )
         return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
 
-#if defined(POLARSSL_PEM_PARSE_C)
-    size_t use_len;
-    pem_context pem;
-
-    pem_init( &pem );
-    ret = pem_read_buffer( &pem,
-                           "-----BEGIN X509 CRL-----",
-                           "-----END X509 CRL-----",
-                           buf, NULL, 0, &use_len );
-
-    if( ret == 0 )
+    do
     {
-        /*
-         * Was PEM encoded
-         */
-        buflen -= use_len;
-        buf += use_len;
+        pem_init( &pem );
+        ret = pem_read_buffer( &pem,
+                               "-----BEGIN X509 CRL-----",
+                               "-----END X509 CRL-----",
+                               buf, NULL, 0, &use_len );
 
-        if( ( ret = x509_crl_parse_der( chain, pem.buf, pem.buflen ) ) != 0 )
+        if( ret == 0 )
+        {
+            /*
+             * Was PEM encoded
+             */
+            is_pem = 1;
+
+            buflen -= use_len;
+            buf += use_len;
+
+            if( ( ret = x509_crl_parse_der( chain,
+                                            pem.buf, pem.buflen ) ) != 0 )
+            {
+                return( ret );
+            }
+
+            pem_free( &pem );
+        }
+        else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
+        {
+            pem_free( &pem );
             return( ret );
+        }
+    }
+    while( is_pem && buflen > 0 );
 
-        pem_free( &pem );
-    }
-    else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
-    {
-        pem_free( &pem );
-        return( ret );
-    }
+    if( is_pem )
+        return( 0 );
     else
 #endif /* POLARSSL_PEM_PARSE_C */
-    {
-        if( ( ret = x509_crl_parse_der( chain, buf, buflen ) ) != 0 )
-            return( ret );
-
-        buflen = 0;
-    }
-
-    if( buflen > 0 )
-        return( x509_crl_parse( chain, buf, buflen ) );
-
-    return( 0 );
+        return( x509_crl_parse_der( chain, buf, buflen ) );
 }
 
 #if defined(POLARSSL_FS_IO)

From 5c2aa10c153a7a67b2dd816ce39880d2ed40ce2d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Wed, 19 Nov 2014 19:15:22 +0100
Subject: [PATCH 37/57] Fix curve dependency issues in X.509 test suite

---
 tests/suites/test_suite_x509parse.data | 42 +++++++++++++-------------
 1 file changed, 21 insertions(+), 21 deletions(-)

diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data
index 21c9fba60..072a667d3 100644
--- a/tests/suites/test_suite_x509parse.data
+++ b/tests/suites/test_suite_x509parse.data
@@ -219,23 +219,23 @@ depends_on:POLARSSL_PEM_PARSE_C
 x509_csr_info:"data_files/server1.req.sha512":"CSR version   \: 1\nsubject name  \: C=NL, O=PolarSSL, CN=PolarSSL Server 1\nsigned using  \: RSA with SHA-512\nRSA key size  \: 2048 bits\n"
 
 X509 CSR Information EC with SHA1
-depends_on:POLARSSL_ECP_C:POLARSSL_PEM_PARSE_C
+depends_on:POLARSSL_ECP_C:POLARSSL_PEM_PARSE_C:POLARSSL_ECP_DP_SECP256R1_ENABLED
 x509_csr_info:"data_files/server5.req.sha1":"CSR version   \: 1\nsubject name  \: C=NL, O=PolarSSL, CN=localhost\nsigned using  \: ECDSA with SHA1\nEC key size   \: 256 bits\n"
 
 X509 CSR Information EC with SHA224
-depends_on:POLARSSL_ECP_C:POLARSSL_PEM_PARSE_C
+depends_on:POLARSSL_ECP_C:POLARSSL_PEM_PARSE_C:POLARSSL_ECP_DP_SECP256R1_ENABLED
 x509_csr_info:"data_files/server5.req.sha224":"CSR version   \: 1\nsubject name  \: C=NL, O=PolarSSL, CN=localhost\nsigned using  \: ECDSA with SHA224\nEC key size   \: 256 bits\n"
 
 X509 CSR Information EC with SHA256
-depends_on:POLARSSL_ECP_C:POLARSSL_PEM_PARSE_C
+depends_on:POLARSSL_ECP_C:POLARSSL_PEM_PARSE_C:POLARSSL_ECP_DP_SECP256R1_ENABLED
 x509_csr_info:"data_files/server5.req.sha256":"CSR version   \: 1\nsubject name  \: C=NL, O=PolarSSL, CN=localhost\nsigned using  \: ECDSA with SHA256\nEC key size   \: 256 bits\n"
 
 X509 CSR Information EC with SHA384
-depends_on:POLARSSL_ECP_C:POLARSSL_PEM_PARSE_C
+depends_on:POLARSSL_ECP_C:POLARSSL_PEM_PARSE_C:POLARSSL_ECP_DP_SECP256R1_ENABLED
 x509_csr_info:"data_files/server5.req.sha384":"CSR version   \: 1\nsubject name  \: C=NL, O=PolarSSL, CN=localhost\nsigned using  \: ECDSA with SHA384\nEC key size   \: 256 bits\n"
 
 X509 CSR Information EC with SHA512
-depends_on:POLARSSL_ECP_C:POLARSSL_PEM_PARSE_C
+depends_on:POLARSSL_ECP_C:POLARSSL_PEM_PARSE_C:POLARSSL_ECP_DP_SECP256R1_ENABLED
 x509_csr_info:"data_files/server5.req.sha512":"CSR version   \: 1\nsubject name  \: C=NL, O=PolarSSL, CN=localhost\nsigned using  \: ECDSA with SHA512\nEC key size   \: 256 bits\n"
 
 X509 CSR Information RSA-PSS with SHA1
@@ -607,7 +607,7 @@ depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_X509_RSASSA_PSS_SUPPORT:POLARSSL_SHA1_C
 x509_verify:"data_files/server9-badsign.crt":"data_files/test-ca.crt":"data_files/crl.pem":"NULL":POLARSSL_ERR_X509_CERT_VERIFY_FAILED:BADCERT_NOT_TRUSTED:"NULL"
 
 X509 Certificate verification #66 (RSASSA-PSS, SHA1, no RSA CA)
-depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_X509_RSASSA_PSS_SUPPORT:POLARSSL_SHA1_C:POLARSSL_ECP_C
+depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_X509_RSASSA_PSS_SUPPORT:POLARSSL_SHA1_C:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP384R1_ENABLED
 x509_verify:"data_files/server9.crt":"data_files/test-ca2.crt":"data_files/crl.pem":"NULL":POLARSSL_ERR_X509_CERT_VERIFY_FAILED:BADCERT_NOT_TRUSTED:"NULL"
 
 X509 Certificate verification #67 (Valid, RSASSA-PSS, all defaults)
@@ -635,11 +635,11 @@ depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_RSA_C:POLARSSL_PKCS1_V15:POLARSSL_SHA25
 x509_verify:"data_files/server2-v1-chain.crt":"data_files/test-ca-v1.crt":"data_files/crl.pem":"NULL":POLARSSL_ERR_X509_CERT_VERIFY_FAILED:BADCERT_NOT_TRUSTED:"NULL"
 
 X509 Certificate verification #73 (selfsigned trusted without CA bit)
-depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_ECDSA_C:POLARSSL_SHA256_C
+depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_ECDSA_C:POLARSSL_SHA256_C:POLARSSL_ECP_DP_SECP256R1_ENABLED
 x509_verify:"data_files/server5-selfsigned.crt":"data_files/server5-selfsigned.crt":"data_files/crl.pem":"NULL":0:0:"NULL"
 
 X509 Certificate verification #74 (signed by selfsigned trusted without CA bit)
-depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_ECDSA_C:POLARSSL_SHA256_C
+depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_ECDSA_C:POLARSSL_SHA256_C:POLARSSL_ECP_DP_SECP256R1_ENABLED
 x509_verify:"data_files/server6-ss-child.crt":"data_files/server5-selfsigned.crt":"data_files/crl.pem":"NULL":POLARSSL_ERR_X509_CERT_VERIFY_FAILED:BADCERT_NOT_TRUSTED:"NULL"
 
 X509 Certificate verification #75 (encoding mismatch)
@@ -1226,7 +1226,7 @@ X509 RSASSA-PSS parameters ASN1 (trailerField not 1)
 x509_parse_rsassa_pss_params:"A303020102":ASN1_CONSTRUCTED | ASN1_SEQUENCE:POLARSSL_MD_SHA1:POLARSSL_MD_SHA1:20:POLARSSL_ERR_X509_INVALID_ALG
 
 X509 CSR ASN.1 (OK)
-depends_on:POLARSSL_ECP_C
+depends_on:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP256R1_ENABLED
 x509_csr_parse:"308201183081BF0201003034310B3009060355040613024E4C3111300F060355040A1308506F6C617253534C31123010060355040313096C6F63616C686F73743059301306072A8648CE3D020106082A8648CE3D0301070342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFFA029302706092A864886F70D01090E311A301830090603551D1304023000300B0603551D0F0404030205E0300906072A8648CE3D04010349003046022100B49FD8C8F77ABFA871908DFBE684A08A793D0F490A43D86FCF2086E4F24BB0C2022100F829D5CCD3742369299E6294394717C4B723A0F68B44E831B6E6C3BCABF97243":"CSR version   \: 1\nsubject name  \: C=NL, O=PolarSSL, CN=localhost\nsigned using  \: ECDSA with SHA1\nEC key size   \: 256 bits\n":0
 
 X509 CSR ASN.1 (bad first tag)
@@ -1272,51 +1272,51 @@ X509 CSR ASN.1 (bad SubjectPublicKeyInfo: overlong)
 x509_csr_parse:"30173014020100300D310B3009060355040613024E4C300100":"":POLARSSL_ERR_PK_KEY_INVALID_FORMAT + POLARSSL_ERR_ASN1_OUT_OF_DATA
 
 X509 CSR ASN.1 (bad attributes: missing)
-depends_on:POLARSSL_ECP_C
+depends_on:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP256R1_ENABLED
 x509_csr_parse:"3081973081940201003034310B3009060355040613024E4C3111300F060355040A1308506F6C617253534C31123010060355040313096C6F63616C686F73743059301306072A8648CE3D020106082A8648CE3D0301070342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFF":"":POLARSSL_ERR_X509_INVALID_FORMAT + POLARSSL_ERR_ASN1_OUT_OF_DATA
 
 X509 CSR ASN.1 (bad attributes: bad tag)
-depends_on:POLARSSL_ECP_C
+depends_on:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP256R1_ENABLED
 x509_csr_parse:"3081993081960201003034310B3009060355040613024E4C3111300F060355040A1308506F6C617253534C31123010060355040313096C6F63616C686F73743059301306072A8648CE3D020106082A8648CE3D0301070342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFF0500":"":POLARSSL_ERR_X509_INVALID_FORMAT + POLARSSL_ERR_ASN1_UNEXPECTED_TAG
 
 X509 CSR ASN.1 (bad attributes: overlong)
-depends_on:POLARSSL_ECP_C
+depends_on:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP256R1_ENABLED
 x509_csr_parse:"30819A3081960201003034310B3009060355040613024E4C3111300F060355040A1308506F6C617253534C31123010060355040313096C6F63616C686F73743059301306072A8648CE3D020106082A8648CE3D0301070342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFFA00100":"":POLARSSL_ERR_X509_INVALID_FORMAT + POLARSSL_ERR_ASN1_OUT_OF_DATA
 
 X509 CSR ASN.1 (bad sigAlg: missing)
-depends_on:POLARSSL_ECP_C
+depends_on:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP256R1_ENABLED
 x509_csr_parse:"3081C23081BF0201003034310B3009060355040613024E4C3111300F060355040A1308506F6C617253534C31123010060355040313096C6F63616C686F73743059301306072A8648CE3D020106082A8648CE3D0301070342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFFA029302706092A864886F70D01090E311A301830090603551D1304023000300B0603551D0F0404030205E0":"":POLARSSL_ERR_X509_INVALID_ALG + POLARSSL_ERR_ASN1_OUT_OF_DATA
 
 X509 CSR ASN.1 (bad sigAlg: not a sequence)
-depends_on:POLARSSL_ECP_C
+depends_on:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP256R1_ENABLED
 x509_csr_parse:"3081C43081BF0201003034310B3009060355040613024E4C3111300F060355040A1308506F6C617253534C31123010060355040313096C6F63616C686F73743059301306072A8648CE3D020106082A8648CE3D0301070342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFFA029302706092A864886F70D01090E311A301830090603551D1304023000300B0603551D0F0404030205E03100":"":POLARSSL_ERR_X509_INVALID_ALG + POLARSSL_ERR_ASN1_UNEXPECTED_TAG
 
 X509 CSR ASN.1 (bad sigAlg: overlong)
-depends_on:POLARSSL_ECP_C
+depends_on:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP256R1_ENABLED
 x509_csr_parse:"3081C43081BF0201003034310B3009060355040613024E4C3111300F060355040A1308506F6C617253534C31123010060355040313096C6F63616C686F73743059301306072A8648CE3D020106082A8648CE3D0301070342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFFA029302706092A864886F70D01090E311A301830090603551D1304023000300B0603551D0F0404030205E03001":"":POLARSSL_ERR_X509_INVALID_ALG + POLARSSL_ERR_ASN1_OUT_OF_DATA
 
 X509 CSR ASN.1 (bad sigAlg: unknown)
-depends_on:POLARSSL_ECP_C
+depends_on:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP256R1_ENABLED
 x509_csr_parse:"3081CD3081BF0201003034310B3009060355040613024E4C3111300F060355040A1308506F6C617253534C31123010060355040313096C6F63616C686F73743059301306072A8648CE3D020106082A8648CE3D0301070342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFFA029302706092A864886F70D01090E311A301830090603551D1304023000300B0603551D0F0404030205E0300906072A8648CE3D04FF":"":POLARSSL_ERR_X509_UNKNOWN_SIG_ALG
 
 X509 CSR ASN.1 (bad sig: missing)
-depends_on:POLARSSL_ECP_C
+depends_on:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP256R1_ENABLED
 x509_csr_parse:"3081CD3081BF0201003034310B3009060355040613024E4C3111300F060355040A1308506F6C617253534C31123010060355040313096C6F63616C686F73743059301306072A8648CE3D020106082A8648CE3D0301070342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFFA029302706092A864886F70D01090E311A301830090603551D1304023000300B0603551D0F0404030205E0300906072A8648CE3D0401":"":POLARSSL_ERR_X509_INVALID_SIGNATURE + POLARSSL_ERR_ASN1_OUT_OF_DATA
 
 X509 CSR ASN.1 (bad sig: not a bit string)
-depends_on:POLARSSL_ECP_C
+depends_on:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP256R1_ENABLED
 x509_csr_parse:"3081CF3081BF0201003034310B3009060355040613024E4C3111300F060355040A1308506F6C617253534C31123010060355040313096C6F63616C686F73743059301306072A8648CE3D020106082A8648CE3D0301070342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFFA029302706092A864886F70D01090E311A301830090603551D1304023000300B0603551D0F0404030205E0300906072A8648CE3D04010400":"":POLARSSL_ERR_X509_INVALID_SIGNATURE + POLARSSL_ERR_ASN1_UNEXPECTED_TAG
 
 X509 CSR ASN.1 (bad sig: overlong)
-depends_on:POLARSSL_ECP_C
+depends_on:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP256R1_ENABLED
 x509_csr_parse:"3081CF3081BF0201003034310B3009060355040613024E4C3111300F060355040A1308506F6C617253534C31123010060355040313096C6F63616C686F73743059301306072A8648CE3D020106082A8648CE3D0301070342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFFA029302706092A864886F70D01090E311A301830090603551D1304023000300B0603551D0F0404030205E0300906072A8648CE3D04010301":"":POLARSSL_ERR_X509_INVALID_SIGNATURE + POLARSSL_ERR_ASN1_OUT_OF_DATA
 
 X509 CSR ASN.1 (extra data after signature)
-depends_on:POLARSSL_ECP_C
+depends_on:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP256R1_ENABLED
 x509_csr_parse:"308201193081BF0201003034310B3009060355040613024E4C3111300F060355040A1308506F6C617253534C31123010060355040313096C6F63616C686F73743059301306072A8648CE3D020106082A8648CE3D0301070342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFFA029302706092A864886F70D01090E311A301830090603551D1304023000300B0603551D0F0404030205E0300906072A8648CE3D04010349003046022100B49FD8C8F77ABFA871908DFBE684A08A793D0F490A43D86FCF2086E4F24BB0C2022100F829D5CCD3742369299E6294394717C4B723A0F68B44E831B6E6C3BCABF9724300":"":POLARSSL_ERR_X509_INVALID_FORMAT + POLARSSL_ERR_ASN1_LENGTH_MISMATCH
 
 X509 File parse (no issues)
-depends_on:POLARSSL_ECP_C
+depends_on:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP256R1_ENABLED
 x509parse_crt_file:"data_files/server7_int-ca.crt":0
 
 X509 File parse (extra space in one certificate)

From 2727dc1e09909fc54e877739e27366ee1fc2e120 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Wed, 19 Nov 2014 20:02:46 +0100
Subject: [PATCH 38/57] Add script to test depends on individual curves

---
 tests/scripts/curves.pl | 45 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)
 create mode 100755 tests/scripts/curves.pl

diff --git a/tests/scripts/curves.pl b/tests/scripts/curves.pl
new file mode 100755
index 000000000..1f489a387
--- /dev/null
+++ b/tests/scripts/curves.pl
@@ -0,0 +1,45 @@
+#!/usr/bin/perl
+
+# test dependencies on individual curves in tests
+# - build
+# - run test suite
+#
+# Usage: tests/scripts/curves.pl
+
+use warnings;
+use strict;
+
+-d 'library' && -d 'include' && -d 'tests' or die "Must be run from root\n";
+
+my $sed_cmd = 's/^#define \(POLARSSL_ECP_DP.*_ENABLED\)/\1/p';
+my $config_h = 'include/polarssl/config.h';
+my @curves = split( /\s+/, `sed -n -e '$sed_cmd' $config_h` );
+
+my $test = system( "grep -i cmake Makefile >/dev/null" ) ? 'check' : 'test';
+
+system( "cp $config_h $config_h.bak" ) and die;
+sub abort {
+    system( "mv $config_h.bak $config_h" ) and warn "$config_h not restored\n";
+    die $_[0];
+}
+
+for my $curve (@curves) {
+    system( "cp $config_h.bak $config_h" ) and die "$config_h not restored\n";
+    system( "make clean" ) and die;
+
+    print "\n******************************************\n";
+    print "* Testing without curve: $curve\n";
+    print "******************************************\n";
+
+    system( "scripts/config.pl unset $curve" )
+        and abort "Failed to disable $curve\n";
+
+    system( "make polarssl" ) and abort "Failed to build lib: $curve\n";
+    system( "cd tests && make" ) and abort "Failed to build tests: $curve\n";
+    system( "make $test" ) and abort "Failed test suite: $curve\n";
+
+}
+
+system( "mv $config_h.bak $config_h" ) and die "$config_h not restored\n";
+system( "make clean" ) and die;
+exit 0;

From cf4de32f58d30dc15d759cca6d9b3ce5b9989504 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Wed, 19 Nov 2014 20:03:55 +0100
Subject: [PATCH 39/57] Fix depends on individual curves in tests

---
 tests/suites/test_suite_debug.data   | 4 ++--
 tests/suites/test_suite_pkwrite.data | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/tests/suites/test_suite_debug.data b/tests/suites/test_suite_debug.data
index 26d85cb63..e0b3bd638 100644
--- a/tests/suites/test_suite_debug.data
+++ b/tests/suites/test_suite_debug.data
@@ -55,11 +55,11 @@ depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_BASE64_C:POLARSSL_RSA_C
 debug_print_crt:POLARSSL_DEBUG_LOG_RAW:"data_files/server1.crt":"MyFile":999:"PREFIX_":"PREFIX_ #1\:\ncert. version     \: 3\nserial number     \: 01\nissuer name       \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nsubject name      \: C=NL, O=PolarSSL, CN=PolarSSL Server 1\nissued  on        \: 2011-02-12 14\:44\:06\nexpires on        \: 2021-02-12 14\:44\:06\nsigned using      \: RSA with SHA1\nRSA key size      \: 2048 bits\nbasic constraints \: CA=false\nvalue of 'crt->rsa.N' (2048 bits) is\:\n a9 02 1f 3d 40 6a d5 55 53 8b fd 36 ee 82 65 2e\n 15 61 5e 89 bf b8 e8 45 90 db ee 88 16 52 d3 f1\n 43 50 47 96 12 59 64 87 6b fd 2b e0 46 f9 73 be\n dd cf 92 e1 91 5b ed 66 a0 6f 89 29 79 45 80 d0\n 83 6a d5 41 43 77 5f 39 7c 09 04 47 82 b0 57 39\n 70 ed a3 ec 15 19 1e a8 33 08 47 c1 05 42 a9 fd\n 4c c3 b4 df dd 06 1f 4d 10 51 40 67 73 13 0f 40\n f8 6d 81 25 5f 0a b1 53 c6 30 7e 15 39 ac f9 5a\n ee 7f 92 9e a6 05 5b e7 13 97 85 b5 23 92 d9 d4\n 24 06 d5 09 25 89 75 07 dd a6 1a 8f 3f 09 19 be\n ad 65 2c 64 eb 95 9b dc fe 41 5e 17 a6 da 6c 5b\n 69 cc 02 ba 14 2c 16 24 9c 4a dc cd d0 f7 52 67\n 73 f1 2d a0 23 fd 7e f4 31 ca 2d 70 ca 89 0b 04\n db 2e a6 4f 70 6e 9e ce bd 58 89 e2 53 59 9e 6e\n 5a 92 65 e2 88 3f 0c 94 19 a3 dd e5 e8 9d 95 13\n ed 29 db ab 70 12 dc 5a ca 6b 17 ab 52 82 54 b1\nvalue of 'crt->rsa.E' (17 bits) is\:\n 01 00 01\n"
 
 Debug print certificate #2 (EC)
-depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_BASE64_C:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP192R1_ENABLED
+depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_BASE64_C:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP384R1_ENABLED
 debug_print_crt:POLARSSL_DEBUG_LOG_FULL:"data_files/test-ca2.crt":"MyFile":999:"PREFIX_":"MyFile(0999)\: PREFIX_ #1\:\nMyFile(0999)\: cert. version     \: 3\nMyFile(0999)\: serial number     \: C1\:43\:E2\:7E\:62\:43\:CC\:E8\nMyFile(0999)\: issuer name       \: C=NL, O=PolarSSL, CN=Polarssl Test EC CA\nMyFile(0999)\: subject name      \: C=NL, O=PolarSSL, CN=Polarssl Test EC CA\nMyFile(0999)\: issued  on        \: 2013-09-24 15\:49\:48\nMyFile(0999)\: expires on        \: 2023-09-22 15\:49\:48\nMyFile(0999)\: signed using      \: ECDSA with SHA256\nMyFile(0999)\: EC key size       \: 384 bits\nMyFile(0999)\: basic constraints \: CA=true\nMyFile(0999)\: value of 'crt->eckey.Q(X)' (384 bits) is\:\nMyFile(0999)\:  c3 da 2b 34 41 37 58 2f 87 56 fe fc 89 ba 29 43\nMyFile(0999)\:  4b 4e e0 6e c3 0e 57 53 33 39 58 d4 52 b4 91 95\nMyFile(0999)\:  39 0b 23 df 5f 17 24 62 48 fc 1a 95 29 ce 2c 2d\nMyFile(0999)\: value of 'crt->eckey.Q(Y)' (384 bits) is\:\nMyFile(0999)\:  87 c2 88 52 80 af d6 6a ab 21 dd b8 d3 1c 6e 58\nMyFile(0999)\:  b8 ca e8 b2 69 8e f3 41 ad 29 c3 b4 5f 75 a7 47\nMyFile(0999)\:  6f d5 19 29 55 69 9a 53 3b 20 b4 66 16 60 33 1e\n"
 
 Debug print certificate #2 (EC, raw)
-depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_BASE64_C:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP192R1_ENABLED
+depends_on:POLARSSL_PEM_PARSE_C:POLARSSL_BASE64_C:POLARSSL_ECP_C:POLARSSL_ECP_DP_SECP384R1_ENABLED
 debug_print_crt:POLARSSL_DEBUG_LOG_RAW:"data_files/test-ca2.crt":"MyFile":999:"PREFIX_":"PREFIX_ #1\:\ncert. version     \: 3\nserial number     \: C1\:43\:E2\:7E\:62\:43\:CC\:E8\nissuer name       \: C=NL, O=PolarSSL, CN=Polarssl Test EC CA\nsubject name      \: C=NL, O=PolarSSL, CN=Polarssl Test EC CA\nissued  on        \: 2013-09-24 15\:49\:48\nexpires on        \: 2023-09-22 15\:49\:48\nsigned using      \: ECDSA with SHA256\nEC key size       \: 384 bits\nbasic constraints \: CA=true\nvalue of 'crt->eckey.Q(X)' (384 bits) is\:\n c3 da 2b 34 41 37 58 2f 87 56 fe fc 89 ba 29 43\n 4b 4e e0 6e c3 0e 57 53 33 39 58 d4 52 b4 91 95\n 39 0b 23 df 5f 17 24 62 48 fc 1a 95 29 ce 2c 2d\nvalue of 'crt->eckey.Q(Y)' (384 bits) is\:\n 87 c2 88 52 80 af d6 6a ab 21 dd b8 d3 1c 6e 58\n b8 ca e8 b2 69 8e f3 41 ad 29 c3 b4 5f 75 a7 47\n 6f d5 19 29 55 69 9a 53 3b 20 b4 66 16 60 33 1e\n"
 
 Debug print mpi #1
diff --git a/tests/suites/test_suite_pkwrite.data b/tests/suites/test_suite_pkwrite.data
index a4d49e7f3..d1738acf3 100644
--- a/tests/suites/test_suite_pkwrite.data
+++ b/tests/suites/test_suite_pkwrite.data
@@ -35,5 +35,5 @@ depends_on:POLARSSL_ECP_C:POLARSSL_BASE64_C:POLARSSL_ECP_DP_SECP521R1_ENABLED
 pk_write_key_check:"data_files/ec_521_prv.pem"
 
 Private key write check EC Brainpool 512 bits
-depends_on:POLARSSL_ECP_C:POLARSSL_BASE64_C:POLARSSL_ECP_DP_SECP192R1_ENABLED
+depends_on:POLARSSL_ECP_C:POLARSSL_BASE64_C:POLARSSL_ECP_DP_BP512R1_ENABLED
 pk_write_key_check:"data_files/ec_bp512_prv.pem"

From 9bda9b3b92e61001365d7dced4e862ba03963239 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Thu, 20 Nov 2014 13:10:22 +0100
Subject: [PATCH 40/57] Rework all.sh to use MSan instead of valgrind

---
 tests/scripts/all.sh | 68 +++++++++++++++++++++-----------------------
 1 file changed, 33 insertions(+), 35 deletions(-)

diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 38ea62870..28e136685 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -6,8 +6,8 @@
 # CMake configuration. After this script is run, the CMake cache is lost and
 # CMake is not initialised any more!
 #
-# Assumes gcc and clang (recent enough for using ASan) are available,
-# as well as cmake and valgrind.
+# Assumes gcc and clang (recent enough for using ASan with gcc and MemSen with
+# clang) are available, as well as cmake and GNU find.
 
 # Abort on errors (and uninitiliased variables)
 set -eu
@@ -24,12 +24,9 @@ MEMORY=0
 
 while [ $# -gt 0 ]; do
     case "$1" in
-        -m1)
+        -m*)
             MEMORY=1
             ;;
-        -m2)
-            MEMORY=2
-            ;;
         *)
             echo "Unknown argument: '$1'" >&2
             echo "Use the source, Luke!" >&2
@@ -60,7 +57,8 @@ msg()
 {
     echo ""
     echo "******************************************************************"
-    echo "* $1"
+    echo "* $1 "
+    echo -n "* "; date
     echo "******************************************************************"
 }
 
@@ -72,28 +70,20 @@ msg()
 #
 # Indicative running times are given for reference.
 
-msg "build: cmake, -Werror (gcc)" # ~ 1 min
+msg "build: cmake, gcc, ASan" # ~ 1 min
 cleanup
-CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Check .
+CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
 make
 
-msg "test: main suites with valgrind" # ~ 2 min 10s
-make memcheck
-
-msg "build: with ASan (clang)" # ~ 1 min
-cleanup
-CC=clang cmake -D CMAKE_BUILD_TYPE:String=ASan .
-make
+msg "test: main suites and selftest (ASan build)" # ~ 10s + 30s
+make test
+programs/test/selftest
 
 msg "test: ssl-opt.sh (ASan build)" # ~ 1 min 10s
 cd tests
 ./ssl-opt.sh
 cd ..
 
-msg "test: main suites and selftest (ASan build)" # ~ 10s + 30s
-make test
-programs/test/selftest
-
 msg "test: ref-configs (ASan build)" # ~ 4 min 45 s
 tests/scripts/test-ref-configs.pl
 
@@ -107,15 +97,15 @@ cd tests
 ./compat.sh
 cd ..
 
-msg "build: cmake, full config" # ~ 40s
+msg "build: cmake, full config, clang" # ~ 40s
 cleanup
 cp "$CONFIG_H" "$CONFIG_BAK"
 scripts/config.pl full
 scripts/config.pl unset POLARSSL_MEMORY_BACKTRACE # too slow for tests
-cmake -D CMAKE_BUILD_TYPE:String=Check .
+CC=clang cmake -D CMAKE_BUILD_TYPE:String=Check .
 make
 
-msg "test: main suites (full config)"
+msg "test: main suites (full config)" # ~ 30s (?)
 make test
 
 msg "test: ssl-opt.sh default (full config)"
@@ -132,22 +122,30 @@ msg "build: Unix make, -O2 (gcc)" # ~ 30s
 cleanup
 CC=gcc make
 
-# Optional parts that take a long time to run
+msg "build: MSan (clang)" # ~ 1 min 30s
+cleanup
+cp "$CONFIG_H" "$CONFIG_BAK"
+scripts/config.pl unset POLARSSL_AESNI_C # memsan doesn't grok asm
+CC=clang cmake -D CMAKE_BUILD_TYPE:String=MemSan .
+make
 
-if [ "$MEMORY" -ge 1 ]; then
-    msg "test: ssl-opt --memcheck (-02 build)" # ~ 8 min
+msg "test: main suites (MSan)" # ~ 15s
+make test
+
+msg "test: ssl-opt.sh (MSan)" # ~ 1 min
+cd tests
+./ssl-opt.sh
+cd ..
+
+# Optional part(s)
+
+if [ "$MEMORY" -gt 0 ]; then
+    msg "test: compat.sh (MSan)" # ~ 6 min 20s
     cd tests
-    ./ssl-opt.sh --memcheck
+    ./compat.sh
     cd ..
-
-    if [ "$MEMORY" -ge 2 ]; then
-        msg "test: compat --memcheck (-02 build)" # ~ 42 min
-        cd tests
-        ./compat.sh --memcheck
-        cd ..
-    fi
 fi
 
-echo "Done."
+msg "Done, cleaning up"
 cleanup
 

From 246978d97df9c80c1ffdb7e8349ae42497af37a7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Thu, 20 Nov 2014 13:29:53 +0100
Subject: [PATCH 41/57] Add curves.pl to all.sh

---
 tests/scripts/all.sh | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 28e136685..d265e7cf8 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -84,7 +84,7 @@ cd tests
 ./ssl-opt.sh
 cd ..
 
-msg "test: ref-configs (ASan build)" # ~ 4 min 45 s
+msg "test/build: ref-configs (ASan build)" # ~ 4 min 45 s
 tests/scripts/test-ref-configs.pl
 
 # Most issues are likely to be caught at this point
@@ -108,16 +108,21 @@ make
 msg "test: main suites (full config)" # ~ 30s (?)
 make test
 
-msg "test: ssl-opt.sh default (full config)"
+msg "test: ssl-opt.sh default (full config)" # < 5s
 cd tests
 ./ssl-opt.sh -f Default
 cd ..
 
-msg "test: compat.sh 3DES & NULL (full config)"
+msg "test: compat.sh 3DES & NULL (full config)" # ~ 2 min
 cd tests
 ./compat.sh -e '^$' -f 'NULL\|3DES-EDE-CBC\|DES-CBC3'
 cd ..
 
+msg "test/build: curves.pl (gcc)" # ~ 5 min (?)
+cleanup
+cmake -D CMAKE_BUILD_TYPE:String=Debug .
+tests/scripts/curves.pl
+
 msg "build: Unix make, -O2 (gcc)" # ~ 30s
 cleanup
 CC=gcc make

From 89d69b398ce52956f21eddb0586d75ba9c2b1f2f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Thu, 20 Nov 2014 13:48:53 +0100
Subject: [PATCH 42/57] Fix 3DES -> DES in all.sh (+ time estimates)

---
 tests/scripts/all.sh | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index d265e7cf8..0f5713d70 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -63,41 +63,41 @@ msg()
 }
 
 # The test ordering tries to optimize for the following criteria:
-# 1. Catch possible problems early, by running first test that run quickly
+# 1. Catch possible problems early, by running first tests that run quickly
 #    and/or are more likely to fail than others (eg I use Clang most of the
 #    time, so start with a GCC build).
 # 2. Minimize total running time, by avoiding useless rebuilds
 #
 # Indicative running times are given for reference.
 
-msg "build: cmake, gcc, ASan" # ~ 1 min
+msg "build: cmake, gcc, ASan" # ~ 1 min 50s
 cleanup
 CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
 make
 
-msg "test: main suites and selftest (ASan build)" # ~ 10s + 30s
+msg "test: main suites and selftest (ASan build)" # ~ 50s
 make test
 programs/test/selftest
 
-msg "test: ssl-opt.sh (ASan build)" # ~ 1 min 10s
+msg "test: ssl-opt.sh (ASan build)" # ~ 1 min
 cd tests
 ./ssl-opt.sh
 cd ..
 
-msg "test/build: ref-configs (ASan build)" # ~ 4 min 45 s
+msg "test/build: ref-configs (ASan build)" # ~ 6 min 20s
 tests/scripts/test-ref-configs.pl
 
-# Most issues are likely to be caught at this point
+# Most frequent issues are likely to be caught at this point
 
 msg "build: with ASan (rebuild after ref-configs)" # ~ 1 min
 make
 
-msg "test: compat.sh (ASan build)" # ~ 7 min 30s
+msg "test: compat.sh (ASan build)" # ~ 6 min
 cd tests
 ./compat.sh
 cd ..
 
-msg "build: cmake, full config, clang" # ~ 40s
+msg "build: cmake, full config, clang" # ~ 50s
 cleanup
 cp "$CONFIG_H" "$CONFIG_BAK"
 scripts/config.pl full
@@ -105,15 +105,15 @@ scripts/config.pl unset POLARSSL_MEMORY_BACKTRACE # too slow for tests
 CC=clang cmake -D CMAKE_BUILD_TYPE:String=Check .
 make
 
-msg "test: main suites (full config)" # ~ 30s (?)
+msg "test: main suites (full config)" # ~ 5s
 make test
 
-msg "test: ssl-opt.sh default (full config)" # < 5s
+msg "test: ssl-opt.sh default (full config)" # ~ 1s
 cd tests
 ./ssl-opt.sh -f Default
 cd ..
 
-msg "test: compat.sh 3DES & NULL (full config)" # ~ 2 min
+msg "test: compat.sh DES & NULL (full config)" # ~ 2 min
 cd tests
 ./compat.sh -e '^$' -f 'NULL\|3DES-EDE-CBC\|DES-CBC3'
 cd ..
@@ -127,14 +127,14 @@ msg "build: Unix make, -O2 (gcc)" # ~ 30s
 cleanup
 CC=gcc make
 
-msg "build: MSan (clang)" # ~ 1 min 30s
+msg "build: MSan (clang)" # ~ 1 min 20s
 cleanup
 cp "$CONFIG_H" "$CONFIG_BAK"
 scripts/config.pl unset POLARSSL_AESNI_C # memsan doesn't grok asm
 CC=clang cmake -D CMAKE_BUILD_TYPE:String=MemSan .
 make
 
-msg "test: main suites (MSan)" # ~ 15s
+msg "test: main suites (MSan)" # ~ 10s
 make test
 
 msg "test: ssl-opt.sh (MSan)" # ~ 1 min

From fd6c85c3eb39a59231843bcabc46e5fcbfba30d5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Thu, 20 Nov 2014 16:34:20 +0100
Subject: [PATCH 43/57] Set a compile-time limit to X.509 chain length

---
 ChangeLog                 |  2 ++
 include/polarssl/config.h |  3 +++
 include/polarssl/x509.h   | 12 ++++++++++++
 library/x509_crt.c        |  7 +++++++
 4 files changed, 24 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index d1a87be76..1b6770a73 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -16,6 +16,8 @@ Security
 Features
    * Add function pk_check_pair() to test if public and private keys match.
    * Add x509_crl_parse_der().
+   * Add compile-time option POLARSSL_X509_MAX_INTERMEDIATE_CA to limit the
+     length of an X.509 verification chain.
 
 Bugfix
    * User set CFLAGS were ignore by Cmake with gcc (introduced in 1.3.9, found
diff --git a/include/polarssl/config.h b/include/polarssl/config.h
index fa15b37c3..a0ec2f3cc 100644
--- a/include/polarssl/config.h
+++ b/include/polarssl/config.h
@@ -2185,6 +2185,9 @@
 /* Debug options */
 //#define POLARSSL_DEBUG_DFL_MODE POLARSSL_DEBUG_LOG_FULL /**< Default log: Full or Raw */
 
+/* X509 options */
+//#define POLARSSL_X509_MAX_INTERMEDIATE_CA   8   /**< Maximum number of intermediate CAs in a verification chain. */
+
 /* \} name SECTION: Module configuration options */
 
 #include "check_config.h"
diff --git a/include/polarssl/x509.h b/include/polarssl/x509.h
index 9b0bcb78a..3fe682039 100644
--- a/include/polarssl/x509.h
+++ b/include/polarssl/x509.h
@@ -45,6 +45,18 @@
  * \{
  */
 
+#if !defined(POLARSSL_X509_MAX_INTERMEDIATE_CA)
+/**
+ * Maximum number of intermediate CAs in a verification chain.
+ * That is, maximum length of the chain, excluding the end-entity certificate
+ * and the trusted root certificate.
+ *
+ * Set this to a low value to prevent an adversary from making you waste
+ * resources verifying an overlong certificate chain.
+ */
+#define POLARSSL_X509_MAX_INTERMEDIATE_CA   8
+#endif
+
 /**
  * \name X509 Error codes
  * \{
diff --git a/library/x509_crt.c b/library/x509_crt.c
index 2d72f6acd..4d20889b8 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -1834,6 +1834,13 @@ static int x509_crt_verify_child(
     x509_crt *grandparent;
     const md_info_t *md_info;
 
+    /* path_cnt is 0 for the first intermediate CA */
+    if( 1 + path_cnt > POLARSSL_X509_MAX_INTERMEDIATE_CA )
+    {
+        *flags |= BADCERT_NOT_TRUSTED;
+        return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
+    }
+
     if( x509_time_expired( &child->valid_to ) )
         *flags |= BADCERT_EXPIRED;
 

From 10c44d767d62520385401cbc710436b2cd210dcc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Thu, 20 Nov 2014 17:30:37 +0100
Subject: [PATCH 44/57] Allow x509_crt_verify_child() in recursion.pl

---
 scripts/recursion.pl | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/scripts/recursion.pl b/scripts/recursion.pl
index d75a4ef44..2c39c1434 100755
--- a/scripts/recursion.pl
+++ b/scripts/recursion.pl
@@ -16,7 +16,8 @@ use open qw(:std utf8);
 
 # exclude functions that are ok:
 # - mpi_write_hlp: bounded by size of mpi, a compile-time constant
-my $known_ok = qr/mpi_write_hlp/;
+# - x509_crt_verify_child: bounded by POLARSSL_X509_MAX_INTERMEDIATE_CA
+my $known_ok = qr/mpi_write_hlp|x509_crt_verify_child/;
 
 my $cur_name;
 my $inside;

From ea29d152c7716e8d066c5a4d3275ee846c056bec Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Thu, 20 Nov 2014 17:32:33 +0100
Subject: [PATCH 45/57] Add recursion.pl to all.sh

---
 tests/scripts/all.sh | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 0f5713d70..ebb8d973e 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -70,6 +70,9 @@ msg()
 #
 # Indicative running times are given for reference.
 
+msg "test: recursion.pl" # < 1s
+scripts/recursion.pl library/*.c
+
 msg "build: cmake, gcc, ASan" # ~ 1 min 50s
 cleanup
 CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .

From d16d1cb96abe2cf2012f7307400a14298c3f0c04 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Thu, 20 Nov 2014 18:15:05 +0100
Subject: [PATCH 46/57] Use more #ifdef's on CLI_C and SRV_C in ssl_tls.c

---
 include/polarssl/ssl.h |  6 ++++++
 library/ssl_tls.c      | 47 +++++++++++++++++++++++++++++++++++++-----
 2 files changed, 48 insertions(+), 5 deletions(-)

diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h
index 194e94471..219060ddc 100644
--- a/include/polarssl/ssl.h
+++ b/include/polarssl/ssl.h
@@ -1024,6 +1024,7 @@ void ssl_set_bio( ssl_context *ssl,
         int (*f_recv)(void *, unsigned char *, size_t), void *p_recv,
         int (*f_send)(void *, const unsigned char *, size_t), void *p_send );
 
+#if defined(POLARSSL_SSL_SRV_C)
 /**
  * \brief          Set the session cache callbacks (server-side only)
  *                 If not set, no session resuming is done.
@@ -1064,7 +1065,9 @@ void ssl_set_bio( ssl_context *ssl,
 void ssl_set_session_cache( ssl_context *ssl,
         int (*f_get_cache)(void *, ssl_session *), void *p_get_cache,
         int (*f_set_cache)(void *, const ssl_session *), void *p_set_cache );
+#endif /* POLARSSL_SSL_SRV_C */
 
+#if defined(POLARSSL_SSL_CLI_C)
 /**
  * \brief          Request resumption of session (client-side only)
  *                 Session data is copied from presented session structure.
@@ -1080,6 +1083,7 @@ void ssl_set_session_cache( ssl_context *ssl,
  * \sa             ssl_get_session()
  */
 int ssl_set_session( ssl_context *ssl, const ssl_session *session );
+#endif /* POLARSSL_SSL_CLI_C */
 
 /**
  * \brief               Set the list of allowed ciphersuites and the preference
@@ -1578,6 +1582,7 @@ const char *ssl_get_version( const ssl_context *ssl );
 const x509_crt *ssl_get_peer_cert( const ssl_context *ssl );
 #endif /* POLARSSL_X509_CRT_PARSE_C */
 
+#if defined(POLARSSL_SSL_CLI_C)
 /**
  * \brief          Save session in order to resume it later (client-side only)
  *                 Session data is copied to presented session structure.
@@ -1595,6 +1600,7 @@ const x509_crt *ssl_get_peer_cert( const ssl_context *ssl );
  * \sa             ssl_set_session()
  */
 int ssl_get_session( const ssl_context *ssl, ssl_session *session );
+#endif /* POLARSSL_SSL_CLI_C */
 
 /**
  * \brief          Perform the SSL handshake
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 89688867a..b59f7af62 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -599,6 +599,7 @@ int ssl_derive_keys( ssl_context *ssl )
     /*
      * Finally setup the cipher contexts, IVs and MAC secrets.
      */
+#if defined(POLARSSL_SSL_CLI_C)
     if( ssl->endpoint == SSL_IS_CLIENT )
     {
         key1 = keyblk + transform->maclen * 2;
@@ -617,6 +618,9 @@ int ssl_derive_keys( ssl_context *ssl )
                 iv_copy_len );
     }
     else
+#endif /* POLARSSL_SSL_CLI_C */
+#if defined(POLARSSL_SSL_SRV_C)
+    if( ssl->endpoint == SSL_IS_SERVER )
     {
         key1 = keyblk + transform->maclen * 2 + transform->keylen;
         key2 = keyblk + transform->maclen * 2;
@@ -633,6 +637,12 @@ int ssl_derive_keys( ssl_context *ssl )
         memcpy( transform->iv_enc, key1 + transform->keylen + iv_copy_len,
                 iv_copy_len );
     }
+    else
+#endif /* POLARSSL_SSL_SRV_C */
+    {
+        SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+        return( POLARSSL_ERR_SSL_INTERNAL_ERROR );
+    }
 
 #if defined(POLARSSL_SSL_PROTO_SSL3)
     if( ssl->minor_ver == SSL_MINOR_VERSION_0 )
@@ -2362,6 +2372,7 @@ int ssl_write_certificate( ssl_context *ssl )
         return( 0 );
     }
 
+#if defined(POLARSSL_SSL_CLI_C)
     if( ssl->endpoint == SSL_IS_CLIENT )
     {
         if( ssl->client_auth == 0 )
@@ -2389,7 +2400,9 @@ int ssl_write_certificate( ssl_context *ssl )
         }
 #endif /* POLARSSL_SSL_PROTO_SSL3 */
     }
-    else /* SSL_IS_SERVER */
+#endif /* POLARSSL_SSL_CLI_C */
+#if defined(POLARSSL_SSL_SRV_C)
+    if( ssl->endpoint == SSL_IS_SERVER )
     {
         if( ssl_own_cert( ssl ) == NULL )
         {
@@ -2397,6 +2410,7 @@ int ssl_write_certificate( ssl_context *ssl )
             return( POLARSSL_ERR_SSL_CERTIFICATE_REQUIRED );
         }
     }
+#endif
 
     SSL_DEBUG_CRT( 3, "own certificate", ssl_own_cert( ssl ) );
 
@@ -2472,6 +2486,7 @@ int ssl_parse_certificate( ssl_context *ssl )
         return( 0 );
     }
 
+#if defined(POLARSSL_SSL_SRV_C)
     if( ssl->endpoint == SSL_IS_SERVER &&
         ( ssl->authmode == SSL_VERIFY_NONE ||
           ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK ) )
@@ -2481,6 +2496,7 @@ int ssl_parse_certificate( ssl_context *ssl )
         ssl->state++;
         return( 0 );
     }
+#endif
 
     if( ( ret = ssl_read_record( ssl ) ) != 0 )
     {
@@ -2490,6 +2506,7 @@ int ssl_parse_certificate( ssl_context *ssl )
 
     ssl->state++;
 
+#if defined(POLARSSL_SSL_SRV_C)
 #if defined(POLARSSL_SSL_PROTO_SSL3)
     /*
      * Check if the client sent an empty certificate
@@ -2534,6 +2551,7 @@ int ssl_parse_certificate( ssl_context *ssl )
     }
 #endif /* POLARSSL_SSL_PROTO_TLS1 || POLARSSL_SSL_PROTO_TLS1_1 || \
           POLARSSL_SSL_PROTO_TLS1_2 */
+#endif /* POLARSSL_SSL_SRV_C */
 
     if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
     {
@@ -2612,6 +2630,7 @@ int ssl_parse_certificate( ssl_context *ssl )
      * On client, make sure the server cert doesn't change during renego to
      * avoid "triple handshake" attack: https://secure-resumption.com/
      */
+#if defined(POLARSSL_SSL_CLI_C)
     if( ssl->endpoint == SSL_IS_CLIENT &&
         ssl->renegotiation == SSL_RENEGOTIATION )
     {
@@ -2631,6 +2650,7 @@ int ssl_parse_certificate( ssl_context *ssl )
             return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE );
         }
     }
+#endif /* POLARSSL_SSL_CLI_C */
 
     if( ssl->authmode != SSL_VERIFY_NONE )
     {
@@ -3149,10 +3169,14 @@ int ssl_write_finished( ssl_context *ssl )
      */
     if( ssl->handshake->resume != 0 )
     {
+#if defined(POLARSSL_SSL_CLI_C)
         if( ssl->endpoint == SSL_IS_CLIENT )
             ssl->state = SSL_HANDSHAKE_WRAPUP;
-        else
+#endif
+#if defined(POLARSSL_SSL_SRV_C)
+        if( ssl->endpoint == SSL_IS_SERVER )
             ssl->state = SSL_CLIENT_CHANGE_CIPHER_SPEC;
+#endif
     }
     else
         ssl->state++;
@@ -3262,11 +3286,14 @@ int ssl_parse_finished( ssl_context *ssl )
 
     if( ssl->handshake->resume != 0 )
     {
+#if defined(POLARSSL_SSL_CLI_C)
         if( ssl->endpoint == SSL_IS_CLIENT )
             ssl->state = SSL_CLIENT_CHANGE_CIPHER_SPEC;
-
+#endif
+#if defined(POLARSSL_SSL_SRV_C)
         if( ssl->endpoint == SSL_IS_SERVER )
             ssl->state = SSL_HANDSHAKE_WRAPUP;
+#endif
     }
     else
         ssl->state++;
@@ -3604,7 +3631,8 @@ void ssl_set_endpoint( ssl_context *ssl, int endpoint )
 {
     ssl->endpoint   = endpoint;
 
-#if defined(POLARSSL_SSL_SESSION_TICKETS)
+#if defined(POLARSSL_SSL_SESSION_TICKETS) && \
+    defined(POLARSSL_SSL_CLI_C)
     if( endpoint == SSL_IS_CLIENT )
         ssl->session_tickets = SSL_SESSION_TICKETS_ENABLED;
 #endif
@@ -3651,6 +3679,7 @@ void ssl_set_bio( ssl_context *ssl,
     ssl->p_send     = p_send;
 }
 
+#if defined(POLARSSL_SSL_SRV_C)
 void ssl_set_session_cache( ssl_context *ssl,
         int (*f_get_cache)(void *, ssl_session *), void *p_get_cache,
         int (*f_set_cache)(void *, const ssl_session *), void *p_set_cache )
@@ -3660,7 +3689,9 @@ void ssl_set_session_cache( ssl_context *ssl,
     ssl->f_set_cache = f_set_cache;
     ssl->p_set_cache = p_set_cache;
 }
+#endif /* POLARSSL_SSL_SRV_C */
 
+#if defined(POLARSSL_SSL_CLI_C)
 int ssl_set_session( ssl_context *ssl, const ssl_session *session )
 {
     int ret;
@@ -3680,6 +3711,7 @@ int ssl_set_session( ssl_context *ssl, const ssl_session *session )
 
     return( 0 );
 }
+#endif /* POLARSSL_SSL_CLI_C */
 
 void ssl_set_ciphersuites( ssl_context *ssl, const int *ciphersuites )
 {
@@ -4037,8 +4069,10 @@ int ssl_set_session_tickets( ssl_context *ssl, int use_tickets )
 {
     ssl->session_tickets = use_tickets;
 
+#if defined(POLARSSL_SSL_CLI_C)
     if( ssl->endpoint == SSL_IS_CLIENT )
         return( 0 );
+#endif
 
     if( ssl->f_rng == NULL )
         return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
@@ -4105,6 +4139,7 @@ const x509_crt *ssl_get_peer_cert( const ssl_context *ssl )
 }
 #endif /* POLARSSL_X509_CRT_PARSE_C */
 
+#if defined(POLARSSL_SSL_CLI_C)
 int ssl_get_session( const ssl_context *ssl, ssl_session *dst )
 {
     if( ssl == NULL ||
@@ -4117,6 +4152,7 @@ int ssl_get_session( const ssl_context *ssl, ssl_session *dst )
 
     return( ssl_session_copy( dst, ssl->session ) );
 }
+#endif /* POLARSSL_SSL_CLI_C */
 
 /*
  * Perform a single step of the SSL handshake
@@ -4129,7 +4165,6 @@ int ssl_handshake_step( ssl_context *ssl )
     if( ssl->endpoint == SSL_IS_CLIENT )
         ret = ssl_handshake_client_step( ssl );
 #endif
-
 #if defined(POLARSSL_SSL_SRV_C)
     if( ssl->endpoint == SSL_IS_SERVER )
         ret = ssl_handshake_server_step( ssl );
@@ -4330,6 +4365,7 @@ int ssl_read( ssl_context *ssl, unsigned char *buf, size_t len )
         {
             SSL_DEBUG_MSG( 1, ( "received handshake message" ) );
 
+#if defined(POLARSSL_SSL_CLI_C)
             if( ssl->endpoint == SSL_IS_CLIENT &&
                 ( ssl->in_msg[0] != SSL_HS_HELLO_REQUEST ||
                   ssl->in_hslen != 4 ) )
@@ -4337,6 +4373,7 @@ int ssl_read( ssl_context *ssl, unsigned char *buf, size_t len )
                 SSL_DEBUG_MSG( 1, ( "handshake received (not HelloRequest)" ) );
                 return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
             }
+#endif
 
             if( ssl->disable_renegotiation == SSL_RENEGOTIATION_DISABLED ||
                 ( ssl->secure_renegotiation == SSL_LEGACY_RENEGOTIATION &&

From 6b298e6cc1fc6ffcf0b7da5759002c36195ecb0c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Thu, 20 Nov 2014 18:28:50 +0100
Subject: [PATCH 47/57] Update comment from draft to RFC

---
 include/polarssl/config.h | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/include/polarssl/config.h b/include/polarssl/config.h
index a0ec2f3cc..9852aa9c9 100644
--- a/include/polarssl/config.h
+++ b/include/polarssl/config.h
@@ -913,8 +913,7 @@
 /**
  * \def POLARSSL_SSL_ALPN
  *
- * Enable support for Application Layer Protocol Negotiation.
- * draft-ietf-tls-applayerprotoneg-05
+ * Enable support for RFC 7301 Application Layer Protocol Negotiation.
  *
  * Comment this macro to disable support for ALPN.
  */

From 3e9449350ca1a27b33a83287211e104cf51959a3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Thu, 20 Nov 2014 18:29:41 +0100
Subject: [PATCH 48/57] Fix comment on resumption

---
 include/polarssl/ssl.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h
index 219060ddc..a4cd70e5c 100644
--- a/include/polarssl/ssl.h
+++ b/include/polarssl/ssl.h
@@ -1027,7 +1027,8 @@ void ssl_set_bio( ssl_context *ssl,
 #if defined(POLARSSL_SSL_SRV_C)
 /**
  * \brief          Set the session cache callbacks (server-side only)
- *                 If not set, no session resuming is done.
+ *                 If not set, no session resuming is done (except if session
+ *                 tickets are enabled too).
  *
  *                 The session cache has the responsibility to check for stale
  *                 entries based on timeout. See RFC 5246 for recommendations.

From 150c4f62f18389cef133bd078f306cfd807b1551 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Fri, 21 Nov 2014 09:14:52 +0100
Subject: [PATCH 49/57] Clarify documentation a bit

---
 include/polarssl/ecp.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/include/polarssl/ecp.h b/include/polarssl/ecp.h
index 9b83bc51b..6dec5bd9c 100644
--- a/include/polarssl/ecp.h
+++ b/include/polarssl/ecp.h
@@ -413,6 +413,8 @@ int ecp_point_read_binary( const ecp_group *grp, ecp_point *P,
  * \param buf       $(Start of input buffer)
  * \param len       Buffer length
  *
+ * \note            buf is updated to point right after the ECPoint on exit
+ *
  * \return          O if successful,
  *                  POLARSSL_ERR_MPI_XXX if initialization failed
  *                  POLARSSL_ERR_ECP_BAD_INPUT_DATA if input is invalid
@@ -479,6 +481,8 @@ int ecp_use_known_dp( ecp_group *grp, ecp_group_id index );
  * \param buf       &(Start of input buffer)
  * \param len       Buffer length
  *
+ * \note            buf is updated to point right after ECParameters on exit
+ *
  * \return          O if successful,
  *                  POLARSSL_ERR_MPI_XXX if initialization failed
  *                  POLARSSL_ERR_ECP_BAD_INPUT_DATA if input is invalid

From cb7da352fddf956dc1a8d936632d29215c60627e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Fri, 21 Nov 2014 09:16:00 +0100
Subject: [PATCH 50/57] Fix typo in #ifdef

Since length is checked afterwards anyway, no security risk here
---
 include/polarssl/ssl.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h
index a4cd70e5c..f4f8f01c9 100644
--- a/include/polarssl/ssl.h
+++ b/include/polarssl/ssl.h
@@ -444,7 +444,7 @@ union _ssl_premaster_secret
 #if defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED)
     unsigned char _pms_rsa_psk[52 + POLARSSL_PSK_MAX_LEN];      /* RFC 4279 4 */
 #endif
-#if defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED)
+#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
     unsigned char _pms_ecdhe_psk[4 + POLARSSL_ECP_MAX_BYTES
                                    + POLARSSL_PSK_MAX_LEN];     /* RFC 5489 2 */
 #endif

From 2457fa09157a65a915cc6b4a99926fa30a3a52d0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Fri, 21 Nov 2014 09:23:11 +0100
Subject: [PATCH 51/57] Create ticket keys only if enabled

---
 library/ssl_tls.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index b59f7af62..a24351e8b 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -4074,6 +4074,9 @@ int ssl_set_session_tickets( ssl_context *ssl, int use_tickets )
         return( 0 );
 #endif
 
+    if( use_tickets == SSL_SESSION_TICKETS_DISABLED )
+        return( 0 );
+
     if( ssl->f_rng == NULL )
         return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
 

From 9439f93ea44f71539c2bf3c0e08732ff92fdab43 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Fri, 21 Nov 2014 09:49:43 +0100
Subject: [PATCH 52/57] Use pk_load_file() in X509

Saves a bit of ROM. X509 depends on PK anyway.
---
 include/polarssl/pk.h   |  8 ++++++++
 include/polarssl/x509.h |  1 -
 library/pkparse.c       |  6 +++---
 library/x509.c          | 44 -----------------------------------------
 library/x509_crl.c      |  2 +-
 library/x509_crt.c      |  2 +-
 library/x509_csr.c      |  2 +-
 7 files changed, 14 insertions(+), 51 deletions(-)

diff --git a/include/polarssl/pk.h b/include/polarssl/pk.h
index 0ff5f1e6c..b29eb74f5 100644
--- a/include/polarssl/pk.h
+++ b/include/polarssl/pk.h
@@ -638,6 +638,14 @@ int pk_write_pubkey( unsigned char **p, unsigned char *start,
                      const pk_context *key );
 #endif /* POLARSSL_PK_WRITE_C */
 
+/*
+ * Internal module functions. You probably do not want to use these unless you
+ * know you do.
+ */
+#if defined(POLARSSL_FS_IO)
+int pk_load_file( const char *path, unsigned char **buf, size_t *n );
+#endif
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/polarssl/x509.h b/include/polarssl/x509.h
index 3fe682039..5f7188140 100644
--- a/include/polarssl/x509.h
+++ b/include/polarssl/x509.h
@@ -307,7 +307,6 @@ int x509_get_serial( unsigned char **p, const unsigned char *end,
                      x509_buf *serial );
 int x509_get_ext( unsigned char **p, const unsigned char *end,
                   x509_buf *ext, int tag );
-int x509_load_file( const char *path, unsigned char **buf, size_t *n );
 int x509_sig_alg_gets( char *buf, size_t size, const x509_buf *sig_oid,
                        pk_type_t pk_alg, md_type_t md_alg,
                        const void *sig_opts );
diff --git a/library/pkparse.c b/library/pkparse.c
index 29217a28a..6cfab8b39 100644
--- a/library/pkparse.c
+++ b/library/pkparse.c
@@ -71,7 +71,7 @@ static void polarssl_zeroize( void *v, size_t n ) {
 /*
  * Load all data from a file into a given buffer.
  */
-static int load_file( const char *path, unsigned char **buf, size_t *n )
+int pk_load_file( const char *path, unsigned char **buf, size_t *n )
 {
     FILE *f;
     long size;
@@ -120,7 +120,7 @@ int pk_parse_keyfile( pk_context *ctx,
     size_t n;
     unsigned char *buf;
 
-    if( ( ret = load_file( path, &buf, &n ) ) != 0 )
+    if( ( ret = pk_load_file( path, &buf, &n ) ) != 0 )
         return( ret );
 
     if( pwd == NULL )
@@ -144,7 +144,7 @@ int pk_parse_public_keyfile( pk_context *ctx, const char *path )
     size_t n;
     unsigned char *buf;
 
-    if( ( ret = load_file( path, &buf, &n ) ) != 0 )
+    if( ( ret = pk_load_file( path, &buf, &n ) ) != 0 )
         return( ret );
 
     ret = pk_parse_public_key( ctx, buf, n );
diff --git a/library/x509.c b/library/x509.c
index 89ba7633d..78cf02dee 100644
--- a/library/x509.c
+++ b/library/x509.c
@@ -636,50 +636,6 @@ int x509_get_ext( unsigned char **p, const unsigned char *end,
     return( 0 );
 }
 
-#if defined(POLARSSL_FS_IO)
-/*
- * Load all data from a file into a given buffer.
- */
-int x509_load_file( const char *path, unsigned char **buf, size_t *n )
-{
-    FILE *f;
-    long size;
-
-    if( ( f = fopen( path, "rb" ) ) == NULL )
-        return( POLARSSL_ERR_X509_FILE_IO_ERROR );
-
-    fseek( f, 0, SEEK_END );
-    if( ( size = ftell( f ) ) == -1 )
-    {
-        fclose( f );
-        return( POLARSSL_ERR_X509_FILE_IO_ERROR );
-    }
-    fseek( f, 0, SEEK_SET );
-
-    *n = (size_t) size;
-
-    if( *n + 1 == 0 ||
-        ( *buf = (unsigned char *) polarssl_malloc( *n + 1 ) ) == NULL )
-    {
-        fclose( f );
-        return( POLARSSL_ERR_X509_MALLOC_FAILED );
-    }
-
-    if( fread( *buf, 1, *n, f ) != *n )
-    {
-        fclose( f );
-        polarssl_free( *buf );
-        return( POLARSSL_ERR_X509_FILE_IO_ERROR );
-    }
-
-    fclose( f );
-
-    (*buf)[*n] = '\0';
-
-    return( 0 );
-}
-#endif /* POLARSSL_FS_IO */
-
 #if defined(_MSC_VER) && !defined snprintf && !defined(EFIX64) && \
     !defined(EFI32)
 #include <stdarg.h>
diff --git a/library/x509_crl.c b/library/x509_crl.c
index c8101b546..a0bf9f47c 100644
--- a/library/x509_crl.c
+++ b/library/x509_crl.c
@@ -549,7 +549,7 @@ int x509_crl_parse_file( x509_crl *chain, const char *path )
     size_t n;
     unsigned char *buf;
 
-    if( ( ret = x509_load_file( path, &buf, &n ) ) != 0 )
+    if( ( ret = pk_load_file( path, &buf, &n ) ) != 0 )
         return( ret );
 
     ret = x509_crl_parse( chain, buf, n );
diff --git a/library/x509_crt.c b/library/x509_crt.c
index 4d20889b8..aba9c696d 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -953,7 +953,7 @@ int x509_crt_parse_file( x509_crt *chain, const char *path )
     size_t n;
     unsigned char *buf;
 
-    if( ( ret = x509_load_file( path, &buf, &n ) ) != 0 )
+    if( ( ret = pk_load_file( path, &buf, &n ) ) != 0 )
         return( ret );
 
     ret = x509_crt_parse( chain, buf, n );
diff --git a/library/x509_csr.c b/library/x509_csr.c
index 0b4f771f9..583112115 100644
--- a/library/x509_csr.c
+++ b/library/x509_csr.c
@@ -310,7 +310,7 @@ int x509_csr_parse_file( x509_csr *csr, const char *path )
     size_t n;
     unsigned char *buf;
 
-    if( ( ret = x509_load_file( path, &buf, &n ) ) != 0 )
+    if( ( ret = pk_load_file( path, &buf, &n ) ) != 0 )
         return( ret );
 
     ret = x509_csr_parse( csr, buf, n );

From e423246e7faabc25b1948eae8ccac632db108549 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Fri, 21 Nov 2014 09:52:23 +0100
Subject: [PATCH 53/57] Fix net_usleep for durations greater than 1 second

---
 library/net.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/library/net.c b/library/net.c
index 3f0e448ba..2c77138c4 100644
--- a/library/net.c
+++ b/library/net.c
@@ -496,12 +496,12 @@ int net_set_nonblock( int fd )
 void net_usleep( unsigned long usec )
 {
     struct timeval tv;
-    tv.tv_sec  = 0;
+    tv.tv_sec  = usec / 1000000;
 #if !defined(_WIN32) && ( defined(__unix__) || defined(__unix) || \
     ( defined(__APPLE__) && defined(__MACH__) ) )
-    tv.tv_usec = (suseconds_t) usec;
+    tv.tv_usec = (suseconds_t) usec % 1000000;
 #else
-    tv.tv_usec = usec;
+    tv.tv_usec = usec % 1000000;
 #endif
     select( 0, NULL, NULL, NULL, &tv );
 }

From 60346be2a3e7757f227a02bba5a6d4432d419682 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Fri, 21 Nov 2014 11:38:37 +0100
Subject: [PATCH 54/57] Improve debugging message.

This actually prints only the payload, not the potential IV and/or MAC,
so (to me at least) it's much less confusing
---
 library/ssl_tls.c | 12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index a24351e8b..736eac668 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -1044,6 +1044,9 @@ static int ssl_encrypt_buf( ssl_context *ssl )
 
     SSL_DEBUG_MSG( 2, ( "=> encrypt buf" ) );
 
+    SSL_DEBUG_BUF( 4, "before encrypt: output payload",
+                      ssl->out_msg, ssl->out_msglen );
+
     /*
      * Add MAC before encrypt, except for AEAD modes
      */
@@ -1102,9 +1105,6 @@ static int ssl_encrypt_buf( ssl_context *ssl )
                             "including %d bytes of padding",
                        ssl->out_msglen, 0 ) );
 
-        SSL_DEBUG_BUF( 4, "before encrypt: output payload",
-                       ssl->out_msg, ssl->out_msglen );
-
         if( ( ret = cipher_crypt( &ssl->transform_out->cipher_ctx_enc,
                                    ssl->transform_out->iv_enc,
                                    ssl->transform_out->ivlen,
@@ -1185,9 +1185,6 @@ static int ssl_encrypt_buf( ssl_context *ssl )
                             "including %d bytes of padding",
                        ssl->out_msglen, 0 ) );
 
-        SSL_DEBUG_BUF( 4, "before encrypt: output payload",
-                       ssl->out_msg, ssl->out_msglen );
-
         /*
          * Encrypt and authenticate
          */
@@ -1268,9 +1265,6 @@ static int ssl_encrypt_buf( ssl_context *ssl )
                             ssl->out_msglen, ssl->transform_out->ivlen,
                             padlen + 1 ) );
 
-        SSL_DEBUG_BUF( 4, "before encrypt: output payload",
-                       ssl->out_iv, ssl->out_msglen );
-
         if( ( ret = cipher_crypt( &ssl->transform_out->cipher_ctx_enc,
                                    ssl->transform_out->iv_enc,
                                    ssl->transform_out->ivlen,

From f29e5de09d38fbf854b658ecb10a9ac54d24db2c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Fri, 21 Nov 2014 11:54:41 +0100
Subject: [PATCH 55/57] Cosmetics in ssl_server2

---
 programs/ssl/ssl_server2.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 0b8852ab6..ba1f29c3f 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -1710,6 +1710,9 @@ exit:
     }
 #endif
 
+    printf( "  . Cleaning up..." );
+    fflush( stdout );
+
     if( client_fd != -1 )
         net_close( client_fd );
 
@@ -1748,6 +1751,8 @@ exit:
     memory_buffer_alloc_free();
 #endif
 
+    printf( " done.\n" );
+
 #if defined(_WIN32)
     printf( "  + Press Enter to exit this program.\n" );
     fflush( stdout ); getchar();

From d3b90f797d8444e716cc2186ff47b1411fbf3398 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Mon, 24 Nov 2014 11:54:02 +0100
Subject: [PATCH 56/57] Fix bug in ssl_client2 reconnect option

---
 programs/ssl/ssl_client2.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 5b7a488c9..56c46d700 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -1219,8 +1219,8 @@ reconnect:
             goto exit;
         }
 
-        if( ( ret = net_connect( &server_fd, opt.server_name,
-                        opt.server_port ) ) != 0 )
+        if( ( ret = net_connect( &server_fd, opt.server_addr,
+                                             opt.server_port ) ) != 0 )
         {
             printf( " failed\n  ! net_connect returned -0x%x\n\n", -ret );
             goto exit;

From d94232389e60acdf90046a494b112edce74cc56c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= <mpg@elzevir.fr>
Date: Tue, 2 Dec 2014 11:57:29 +0100
Subject: [PATCH 57/57] Skip signature_algorithms ext if PSK only

---
 ChangeLog                           |  2 ++
 include/polarssl/ssl_ciphersuites.h | 15 ++++++++++++++-
 library/ssl_cli.c                   | 12 +++++++++---
 library/ssl_srv.c                   | 12 ++++++++----
 4 files changed, 33 insertions(+), 8 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 1b6770a73..d5134a596 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -33,6 +33,8 @@ Changes
    * ssl_set_own_cert() now returns an error on key-certificate mismatch.
    * Forbid repeated extensions in X.509 certificates.
    * debug_print_buf() now prints a text view in addition to hexadecimal.
+   * Skip writing and parsing signature_algorithm extension if none of the
+     key exchanges enabled needs certificates.
 
 = PolarSSL 1.3.9 released 2014-10-20
 Security
diff --git a/include/polarssl/ssl_ciphersuites.h b/include/polarssl/ssl_ciphersuites.h
index c4f1ffe64..191596f6c 100644
--- a/include/polarssl/ssl_ciphersuites.h
+++ b/include/polarssl/ssl_ciphersuites.h
@@ -233,7 +233,9 @@ extern "C" {
 #define TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8      0xC0AE  /**< TLS 1.2 */
 #define TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8      0xC0AF  /**< TLS 1.2 */
 
-/* Reminder: update _ssl_premaster_secret when adding a new key exchange */
+/* Reminder: update _ssl_premaster_secret when adding a new key exchange.
+ * Reminder: update POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED below.
+ */
 typedef enum {
     POLARSSL_KEY_EXCHANGE_NONE = 0,
     POLARSSL_KEY_EXCHANGE_RSA,
@@ -248,6 +250,17 @@ typedef enum {
     POLARSSL_KEY_EXCHANGE_ECDH_ECDSA,
 } key_exchange_type_t;
 
+#if defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED)          || \
+    defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED)      || \
+    defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED)    || \
+    defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)  || \
+    defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED)      || \
+    defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED)    || \
+    defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED)     || \
+    defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
+#define POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED
+#endif
+
 typedef struct _ssl_ciphersuite_t ssl_ciphersuite_t;
 
 #define POLARSSL_CIPHERSUITE_WEAK       0x01    /**< Weak ciphersuite flag  */
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 27abb3efe..39e593a43 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -142,7 +142,11 @@ static void ssl_write_renegotiation_ext( ssl_context *ssl,
     *olen = 5 + ssl->verify_data_len;
 }
 
-#if defined(POLARSSL_SSL_PROTO_TLS1_2)
+/*
+ * Only if we handle at least one key exchange that needs signatures.
+ */
+#if defined(POLARSSL_SSL_PROTO_TLS1_2) && \
+    defined(POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED)
 static void ssl_write_signature_algorithms_ext( ssl_context *ssl,
                                                 unsigned char *buf,
                                                 size_t *olen )
@@ -236,7 +240,8 @@ static void ssl_write_signature_algorithms_ext( ssl_context *ssl,
 
     *olen = 6 + sig_alg_len;
 }
-#endif /* POLARSSL_SSL_PROTO_TLS1_2 */
+#endif /* POLARSSL_SSL_PROTO_TLS1_2 &&
+          POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED */
 
 #if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C)
 static void ssl_write_supported_elliptic_curves_ext( ssl_context *ssl,
@@ -628,7 +633,8 @@ static int ssl_write_client_hello( ssl_context *ssl )
     ssl_write_renegotiation_ext( ssl, p + 2 + ext_len, &olen );
     ext_len += olen;
 
-#if defined(POLARSSL_SSL_PROTO_TLS1_2)
+#if defined(POLARSSL_SSL_PROTO_TLS1_2) && \
+    defined(POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED)
     ssl_write_signature_algorithms_ext( ssl, p + 2 + ext_len, &olen );
     ext_len += olen;
 #endif
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 01b0aca20..21f3c1357 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -465,7 +465,8 @@ static int ssl_parse_renegotiation_info( ssl_context *ssl,
     return( 0 );
 }
 
-#if defined(POLARSSL_SSL_PROTO_TLS1_2)
+#if defined(POLARSSL_SSL_PROTO_TLS1_2) && \
+    defined(POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED)
 static int ssl_parse_signature_algorithms_ext( ssl_context *ssl,
                                                const unsigned char *buf,
                                                size_t len )
@@ -509,7 +510,8 @@ have_sig_alg:
 
     return( 0 );
 }
-#endif /* POLARSSL_SSL_PROTO_TLS1_2 */
+#endif /* POLARSSL_SSL_PROTO_TLS1_2 &&
+          POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED */
 
 #if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C)
 static int ssl_parse_supported_elliptic_curves( ssl_context *ssl,
@@ -1402,7 +1404,8 @@ static int ssl_parse_client_hello( ssl_context *ssl )
                 return( ret );
             break;
 
-#if defined(POLARSSL_SSL_PROTO_TLS1_2)
+#if defined(POLARSSL_SSL_PROTO_TLS1_2) && \
+    defined(POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED)
         case TLS_EXT_SIG_ALG:
             SSL_DEBUG_MSG( 3, ( "found signature_algorithms extension" ) );
             if( ssl->renegotiation == SSL_RENEGOTIATION )
@@ -1412,7 +1415,8 @@ static int ssl_parse_client_hello( ssl_context *ssl )
             if( ret != 0 )
                 return( ret );
             break;
-#endif /* POLARSSL_SSL_PROTO_TLS1_2 */
+#endif /* POLARSSL_SSL_PROTO_TLS1_2 &&
+          POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED */
 
 #if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C)
         case TLS_EXT_SUPPORTED_ELLIPTIC_CURVES: