Merge support for enabling / disabling renegotiation support at compile-time
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 7eec364..91ce32d 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -2797,7 +2797,7 @@
      * 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 defined(POLARSSL_SSL_RENEGOTIATION) && defined(POLARSSL_SSL_CLI_C)
     if( ssl->endpoint == SSL_IS_CLIENT &&
         ssl->renegotiation == SSL_RENEGOTIATION )
     {
@@ -2817,7 +2817,7 @@
             return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE );
         }
     }
-#endif /* POLARSSL_SSL_CLI_C */
+#endif /* POLARSSL_SSL_RENEGOTIATION && POLARSSL_SSL_CLI_C */
 
     if( ssl->authmode != SSL_VERIFY_NONE )
     {
@@ -3260,11 +3260,13 @@
     polarssl_free( ssl->handshake );
     ssl->handshake = NULL;
 
+#if defined(POLARSSL_SSL_RENEGOTIATION)
     if( ssl->renegotiation == SSL_RENEGOTIATION )
     {
         ssl->renegotiation =  SSL_RENEGOTIATION_DONE;
         ssl->renego_records_seen = 0;
     }
+#endif
 
     /*
      * Switch in our now active transform context
@@ -3329,8 +3331,10 @@
     // TODO TLS/1.2 Hash length is determined by cipher suite (Page 63)
     hash_len = ( ssl->minor_ver == SSL_MINOR_VERSION_0 ) ? 36 : 12;
 
+#if defined(POLARSSL_SSL_RENEGOTIATION)
     ssl->verify_data_len = hash_len;
     memcpy( ssl->own_verify_data, ssl->out_msg + 4, hash_len );
+#endif
 
     ssl->out_msglen  = 4 + hash_len;
     ssl->out_msgtype = SSL_MSG_HANDSHAKE;
@@ -3454,8 +3458,10 @@
         return( POLARSSL_ERR_SSL_BAD_HS_FINISHED );
     }
 
+#if defined(POLARSSL_SSL_RENEGOTIATION)
     ssl->verify_data_len = hash_len;
     memcpy( ssl->peer_verify_data, buf, hash_len );
+#endif
 
     if( ssl->handshake->resume != 0 )
     {
@@ -3607,7 +3613,11 @@
 
     ssl_set_ciphersuites( ssl, ssl_list_ciphersuites() );
 
+#if defined(POLARSSL_SSL_RENEGOTIATION)
     ssl->renego_max_records = SSL_RENEGO_MAX_RECORDS_DEFAULT;
+    memset( ssl->renego_period, 0xFF, 7 );
+    ssl->renego_period[7] = 0x00;
+#endif
 
 #if defined(POLARSSL_DHM_C)
     if( ( ret = mpi_read_string( &ssl->dhm_P, 16,
@@ -3681,12 +3691,16 @@
     int ret;
 
     ssl->state = SSL_HELLO_REQUEST;
+
+#if defined(POLARSSL_SSL_RENEGOTIATION)
     ssl->renegotiation = SSL_INITIAL_HANDSHAKE;
-    ssl->secure_renegotiation = SSL_LEGACY_RENEGOTIATION;
+    ssl->renego_records_seen = 0;
 
     ssl->verify_data_len = 0;
-    memset( ssl->own_verify_data, 0, 36 );
-    memset( ssl->peer_verify_data, 0, 36 );
+    memset( ssl->own_verify_data, 0, SSL_VERIFY_DATA_MAX_LEN );
+    memset( ssl->peer_verify_data, 0, SSL_VERIFY_DATA_MAX_LEN );
+#endif
+    ssl->secure_renegotiation = SSL_LEGACY_RENEGOTIATION;
 
     ssl->in_offt = NULL;
 
@@ -3707,8 +3721,6 @@
     ssl->transform_in = NULL;
     ssl->transform_out = NULL;
 
-    ssl->renego_records_seen = 0;
-
     memset( ssl->out_ctr, 0, SSL_BUFFER_LEN );
     memset( ssl->in_ctr, 0, SSL_BUFFER_LEN );
 
@@ -4251,21 +4263,29 @@
 }
 #endif /* POLARSSL_SSL_TRUNCATED_HMAC */
 
-void ssl_set_renegotiation( ssl_context *ssl, int renegotiation )
-{
-    ssl->disable_renegotiation = renegotiation;
-}
-
 void ssl_legacy_renegotiation( ssl_context *ssl, int allow_legacy )
 {
     ssl->allow_legacy_renegotiation = allow_legacy;
 }
 
+#if defined(POLARSSL_SSL_RENEGOTIATION)
+void ssl_set_renegotiation( ssl_context *ssl, int renegotiation )
+{
+    ssl->disable_renegotiation = renegotiation;
+}
+
 void ssl_set_renegotiation_enforced( ssl_context *ssl, int max_records )
 {
     ssl->renego_max_records = max_records;
 }
 
+void ssl_set_renegotiation_period( ssl_context *ssl,
+                                   const unsigned char period[8] )
+{
+    memcpy( ssl->renego_period, period, 8 );
+}
+#endif /* POLARSSL_SSL_RENEGOTIATION */
+
 #if defined(POLARSSL_SSL_SESSION_TICKETS)
 int ssl_set_session_tickets( ssl_context *ssl, int use_tickets )
 {
@@ -4400,6 +4420,7 @@
     return( ret );
 }
 
+#if defined(POLARSSL_SSL_RENEGOTIATION)
 #if defined(POLARSSL_SSL_SRV_C)
 /*
  * Write HelloRequest to request renegotiation on server
@@ -4513,6 +4534,30 @@
 }
 
 /*
+ * Check record counters and renegotiate if they're above the limit.
+ */
+static int ssl_check_ctr_renegotiate( ssl_context *ssl )
+{
+    if( ssl->state != SSL_HANDSHAKE_OVER ||
+        ssl->renegotiation == SSL_RENEGOTIATION_PENDING ||
+        ssl->disable_renegotiation == SSL_RENEGOTIATION_DISABLED )
+    {
+        return( 0 );
+    }
+
+    // TODO: adapt for DTLS
+    if( memcmp( ssl->in_ctr,  ssl->renego_period, 8 ) <= 0 &&
+        memcmp( ssl->out_ctr, ssl->renego_period, 8 ) <= 0 )
+    {
+        return( 0 );
+    }
+
+    SSL_DEBUG_MSG( 0, ( "record counter limit reached: renegotiate" ) );
+    return( ssl_renegotiate( ssl ) );
+}
+#endif /* POLARSSL_SSL_RENEGOTIATION */
+
+/*
  * Receive application data decrypted from the SSL layer
  */
 int ssl_read( ssl_context *ssl, unsigned char *buf, size_t len )
@@ -4522,6 +4567,14 @@
 
     SSL_DEBUG_MSG( 2, ( "=> read" ) );
 
+#if defined(POLARSSL_SSL_RENEGOTIATION)
+    if( ( ret = ssl_check_ctr_renegotiate( ssl ) ) != 0 )
+    {
+        SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret );
+        return( ret );
+    }
+#endif
+
     if( ssl->state != SSL_HANDSHAKE_OVER )
     {
         ret = ssl_handshake( ssl );
@@ -4566,6 +4619,7 @@
             }
         }
 
+#if defined(POLARSSL_SSL_RENEGOTIATION)
         if( ssl->in_msgtype == SSL_MSG_HANDSHAKE )
         {
             SSL_DEBUG_MSG( 1, ( "received handshake message" ) );
@@ -4648,6 +4702,7 @@
                 return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
             }
         }
+#endif /* POLARSSL_SSL_RENEGOTIATION */
 
         /* Fatal and closure alerts handled by ssl_read_record() */
         if( ssl->in_msgtype == SSL_MSG_ALERT )
@@ -4694,6 +4749,14 @@
 
     SSL_DEBUG_MSG( 2, ( "=> write" ) );
 
+#if defined(POLARSSL_SSL_RENEGOTIATION)
+    if( ( ret = ssl_check_ctr_renegotiate( ssl ) ) != 0 )
+    {
+        SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret );
+        return( ret );
+    }
+#endif
+
     if( ssl->state != SSL_HANDSHAKE_OVER )
     {
         if( ( ret = ssl_handshake( ssl ) ) != 0 )