- Added Secure Renegotiation (RFC 5746)

diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h
index 2201bde..3d6e42c 100644
--- a/include/polarssl/ssl.h
+++ b/include/polarssl/ssl.h
@@ -30,7 +30,6 @@
 #include <time.h>
 
 #include "net.h"
-#include "dhm.h"
 #include "rsa.h"
 #include "md5.h"
 #include "sha1.h"
@@ -39,6 +38,10 @@
 #include "x509.h"
 #include "config.h"
 
+#if defined(POLARSSL_DHM_C)
+#include "dhm.h"
+#endif
+
 #if defined(POLARSSL_PKCS11_C)
 #include "pkcs11.h"
 #endif
@@ -110,6 +113,18 @@
 #define SSL_VERIFY_OPTIONAL             1
 #define SSL_VERIFY_REQUIRED             2
 
+#define SSL_INITIAL_HANDSHAKE           0
+#define SSL_RENEGOTIATION               1
+
+#define SSL_LEGACY_RENEGOTIATION        0
+#define SSL_SECURE_RENEGOTIATION        1
+
+#define SSL_RENEGOTIATION_ENABLED       0
+#define SSL_RENEGOTIATION_DISABLED      1
+
+#define SSL_NO_LEGACY_RENEGOTIATION     0
+#define SSL_ALLOW_LEGACY_RENEGOTIATION  1
+
 #define SSL_MAX_CONTENT_LEN         16384
 
 /*
@@ -164,6 +179,8 @@
 #define SSL_EDH_RSA_AES_128_GCM_SHA256  0x9E
 #define SSL_EDH_RSA_AES_256_GCM_SHA384  0x9F
 
+#define SSL_EMPTY_RENEGOTIATION_INFO    0xFF   /**< renegotiation info ext */ 
+
 /*
  * Supported Signature and Hash algorithms (For TLS 1.2)
  */
@@ -233,6 +250,8 @@
 
 #define TLS_EXT_SIG_ALG                13
 
+#define TLS_EXT_RENEGOTIATION_INFO 0xFF01
+
 /*
  * SSL state machine
  */
@@ -253,12 +272,15 @@
     SSL_SERVER_CHANGE_CIPHER_SPEC,
     SSL_SERVER_FINISHED,
     SSL_FLUSH_BUFFERS,
+    SSL_HANDSHAKE_WRAPUP,
     SSL_HANDSHAKE_OVER
 }
 ssl_states;
 
 typedef struct _ssl_session ssl_session;
 typedef struct _ssl_context ssl_context;
+typedef struct _ssl_transform ssl_transform;
+typedef struct _ssl_handshake_params ssl_handshake_params;
 
 /*
  * This structure is used for session resuming.
@@ -271,15 +293,83 @@
     size_t length;              /*!< session id length  */
     unsigned char id[32];       /*!< session identifier */
     unsigned char master[48];   /*!< the master secret  */
+    x509_cert *peer_cert;       /*!< peer X.509 cert chain */
     ssl_session *next;          /*!< next session entry */
 };
 
+/*
+ * This structure contains a full set of runtime transform parameters
+ * either in negotiation or active.
+ */
+struct _ssl_transform
+{
+    /*
+     * Session specific crypto layer
+     */
+    unsigned int keylen;                /*!<  symmetric key length    */
+    size_t minlen;                      /*!<  min. ciphertext length  */
+    size_t ivlen;                       /*!<  IV length               */
+    size_t fixed_ivlen;                 /*!<  Fixed part of IV (AEAD) */
+    size_t maclen;                      /*!<  MAC length              */
+
+    unsigned char iv_enc[16];           /*!<  IV (encryption)         */
+    unsigned char iv_dec[16];           /*!<  IV (decryption)         */
+
+    unsigned char mac_enc[32];          /*!<  MAC (encryption)        */
+    unsigned char mac_dec[32];          /*!<  MAC (decryption)        */
+
+    unsigned long ctx_enc[134];         /*!<  encryption context      */
+    unsigned long ctx_dec[134];         /*!<  decryption context      */
+
+    /*
+     * Session specific compression layer
+     */
+#if defined(POLARSSL_ZLIB_SUPPORT)
+    z_stream ctx_deflate;               /*!<  compression context     */
+    z_stream ctx_inflate;               /*!<  decompression context   */
+#endif
+};
+
+/*
+ * This structure contains the parameters only needed during handshake.
+ */
+struct _ssl_handshake_params
+{
+    /*
+     * Handshake specific crypto variables
+     */
+#if defined(POLARSSL_DHM_C)
+    dhm_context dhm_ctx;                /*!<  DHM key exchange        */
+#endif
+
+    /*
+     * Checksum contexts
+     */
+     md5_context fin_md5;
+    sha1_context fin_sha1;
+    sha2_context fin_sha2;
+    sha4_context fin_sha4;
+
+    void (*update_checksum)(ssl_context *, unsigned char *, size_t);
+    void (*calc_verify)(ssl_context *, unsigned char *);
+    void (*calc_finished)(ssl_context *, unsigned char *, int);
+    int  (*tls_prf)(unsigned char *, size_t, char *,
+                    unsigned char *, size_t,
+                    unsigned char *, size_t);
+
+    size_t pmslen;                      /*!<  premaster length        */
+
+    unsigned char randbytes[64];        /*!<  random bytes            */
+    unsigned char premaster[256];       /*!<  premaster secret        */
+};
+
 struct _ssl_context
 {
     /*
      * Miscellaneous
      */
     int state;                  /*!< SSL handshake: current state     */
+    int renegotiation;          /*!< Initial or renegotiation         */
 
     int major_ver;              /*!< equal to  SSL_MAJOR_VERSION_3    */
     int minor_ver;              /*!< either 0 (SSL3) or 1 (TLS1.0)    */
@@ -307,10 +397,24 @@
      */
     int resume;                         /*!<  session resuming flag   */
     int timeout;                        /*!<  sess. expiration time   */
-    ssl_session *session;               /*!<  current session data    */
+    ssl_session *session_in;            /*!<  current session data (in)   */
+    ssl_session *session_out;           /*!<  current session data (out)  */
+    ssl_session *session;               /*!<  negotiated session data     */
+    ssl_session *session_negotiate;     /*!<  session data in negotiation */
     int (*s_get)(ssl_context *);        /*!<  (server) get callback   */
     int (*s_set)(ssl_context *);        /*!<  (server) set callback   */
 
+    ssl_handshake_params *handshake;    /*!<  params required only during
+                                              the handshake process        */
+
+    /*
+     * Record layer transformations
+     */
+    ssl_transform *transform_in;        /*!<  current transform params (in)   */
+    ssl_transform *transform_out;       /*!<  current transform params (in)   */
+    ssl_transform *transform;           /*!<  negotiated transform params     */
+    ssl_transform *transform_negotiate; /*!<  transform params in negotiation */
+
     /*
      * Record layer (incoming data)
      */
@@ -347,51 +451,22 @@
     x509_cert *own_cert;                /*!<  own X.509 certificate   */
     x509_cert *ca_chain;                /*!<  own trusted CA chain    */
     x509_crl *ca_crl;                   /*!<  trusted CA CRLs         */
-    x509_cert *peer_cert;               /*!<  peer X.509 cert chain   */
     const char *peer_cn;                /*!<  expected peer CN        */
 
+    /*
+     * User settings
+     */
     int endpoint;                       /*!<  0: client, 1: server    */
     int authmode;                       /*!<  verification mode       */
     int client_auth;                    /*!<  flag for client auth.   */
     int verify_result;                  /*!<  verification result     */
-
-    /*
-     * Crypto layer
-     */
-    dhm_context dhm_ctx;                /*!<  DHM key exchange        */
-    unsigned char ctx_checksum[500];    /*!<  Checksum context(s)     */
-
-    void (*update_checksum)(ssl_context *, unsigned char *, size_t);
-    void (*calc_verify)(ssl_context *, unsigned char *);
-    void (*calc_finished)(ssl_context *, unsigned char *, int);
-    int  (*tls_prf)(unsigned char *, size_t, char *,
-                    unsigned char *, size_t,
-                    unsigned char *, size_t);
-
-    int do_crypt;                       /*!<  en(de)cryption flag     */
+    int disable_renegotiation;          /*!<  enable/disable renegotiation   */
+    int allow_legacy_renegotiation;     /*!<  allow legacy renegotiation     */
     const int *ciphersuites;            /*!<  allowed ciphersuites    */
-    size_t pmslen;                      /*!<  premaster length        */
-    unsigned int keylen;                /*!<  symmetric key length    */
-    size_t minlen;                      /*!<  min. ciphertext length  */
-    size_t ivlen;                       /*!<  IV length               */
-    size_t fixed_ivlen;                 /*!<  Fixed part of IV (AEAD) */
-    size_t maclen;                      /*!<  MAC length              */
 
-    unsigned char randbytes[64];        /*!<  random bytes            */
-    unsigned char premaster[256];       /*!<  premaster secret        */
-
-    unsigned char iv_enc[16];           /*!<  IV (encryption)         */
-    unsigned char iv_dec[16];           /*!<  IV (decryption)         */
-
-    unsigned char mac_enc[32];          /*!<  MAC (encryption)        */
-    unsigned char mac_dec[32];          /*!<  MAC (decryption)        */
-
-    unsigned long ctx_enc[134];         /*!<  encryption context      */
-    unsigned long ctx_dec[134];         /*!<  decryption context      */
-
-#if defined(POLARSSL_ZLIB_SUPPORT)
-    z_stream ctx_deflate;               /*!<  compression context     */
-    z_stream ctx_inflate;               /*!<  decompression context   */
+#if defined(POLARSSL_DHM_C)
+    mpi dhm_P;                          /*!<  prime modulus for DHM   */
+    mpi dhm_G;                          /*!<  generator for DHM       */
 #endif
 
     /*
@@ -399,6 +474,15 @@
      */
     unsigned char *hostname;
     size_t         hostname_len;
+
+    /*
+     * Secure renegotiation
+     */
+    int secure_renegotiation;           /*!<  does peer support legacy or
+                                              secure renegotiation           */
+    size_t verify_data_len;             /*!<  length of verify data stored   */
+    char own_verify_data[36];           /*!<  previous handshake verify data */
+    char peer_verify_data[36];          /*!<  previous handshake verify data */
 };
 
 #ifdef __cplusplus
@@ -465,7 +549,8 @@
  *                 pointers and data.
  *
  * \param ssl      SSL context
- * \return         0 if successful, or POLARSSL_ERR_SSL_HW_ACCEL_FAILED or
+ * \return         0 if successful, or POLASSL_ERR_SSL_MALLOC_FAILED,
+                   POLARSSL_ERR_SSL_HW_ACCEL_FAILED or
  *                 POLARSSL_ERR_SSL_COMPRESSION_FAILED
  */
 int ssl_session_reset( ssl_context *ssl );
@@ -614,6 +699,7 @@
                        pkcs11_context *pkcs11_key );
 #endif
 
+#if defined(POLARSSL_DHM_C)
 /**
  * \brief          Set the Diffie-Hellman public P and G values,
  *                 read as hexadecimal strings (server-side only)
@@ -636,6 +722,7 @@
  * \return         0 if successful
  */
 int ssl_set_dh_param_ctx( ssl_context *ssl, dhm_context *dhm_ctx );
+#endif
 
 /**
  * \brief          Set hostname for ServerName TLS Extension
@@ -660,6 +747,29 @@
 void ssl_set_max_version( ssl_context *ssl, int major, int minor );
 
 /**
+ * \brief          Enable / Disable renegotiation support for connection
+ *                 (Default: SSL_RENEGOTIATION_ENABLED)
+ *
+ * \param ssl      SSL context
+ * \param renegotiation     Enable or disable (SSL_RENEGOTIATION_ENABLED or
+ *                                             SSL_RENEGOTIATION_DISABLED)
+ */
+void ssl_set_renegotiation( ssl_context *ssl, int renegotiation );
+
+/**
+ * \brief          Prevent or allow legacy renegotiation.
+ *                 (Default: SSL_NO_LEGACY_RENEGOTIATION)
+ *                 Allowing legacy renegotiation makes the connection
+ *                 vulnerable to specific man in the middle attacks.
+ *                 (See RFC 5746)
+ *
+ * \param ssl      SSL context
+ * \param allow_legacy  Prevent or allow (SSL_NO_LEGACY_RENEGOTIATION or
+ *                                        SSL_ALLOW_LEGACY_RENEGOTIATION)
+ */
+void ssl_legacy_renegotiation( ssl_context *ssl, int allow_legacy );
+
+/**
  * \brief          Return the number of data bytes available to read
  *
  * \param ssl      SSL context
@@ -710,6 +820,15 @@
 int ssl_handshake( ssl_context *ssl );
 
 /**
+ * \brief          Perform an SSL renegotiation on the running connection
+ *
+ * \param ssl      SSL context
+ *
+ * \return         0 if succesful, or any ssl_handshake() return value.
+ */
+int ssl_renegotiate( ssl_context *ssl );
+
+/**
  * \brief          Read at most 'len' application data bytes
  *
  * \param ssl      SSL context
@@ -758,17 +877,42 @@
 int ssl_close_notify( ssl_context *ssl );
 
 /**
- * \brief          Free an SSL context
+ * \brief          Free referenced items in an SSL context and clear memory
  *
  * \param ssl      SSL context
  */
 void ssl_free( ssl_context *ssl );
 
+/**
+ * \brief          Free referenced items in an SSL session and free all
+ *                 sessions in the chain. Memory is cleared
+ *
+ * \param session  SSL session
+ */
+void ssl_session_free( ssl_session *session );
+
+/**
+ * \brief           Free referenced items in an SSL transform context and clear
+ *                  memory
+ *
+ * \param transform SSL transform context
+ */
+void ssl_transform_free( ssl_transform *transform );
+
+/**
+ * \brief           Free referenced items in an SSL handshake context and clear
+ *                  memory
+ *
+ * \param handshake SSL handshake context
+ */
+void ssl_handshake_free( ssl_handshake_params *handshake );
+
 /*
  * Internal functions (do not call directly)
  */
 int ssl_handshake_client( ssl_context *ssl );
 int ssl_handshake_server( ssl_context *ssl );
+void ssl_handshake_wrapup( ssl_context *ssl );
 
 int ssl_derive_keys( ssl_context *ssl );
 
@@ -791,8 +935,7 @@
 int ssl_parse_finished( ssl_context *ssl );
 int ssl_write_finished( ssl_context *ssl );
 
-void ssl_kickstart_checksum( ssl_context *ssl, int ciphersuite,
-                             unsigned char *input_buf, size_t len );
+void ssl_optimize_checksum( ssl_context *ssl, int ciphersuite );
 
 #ifdef __cplusplus
 }