From fcab621995d55d8873a02a96d5a8157f38469ebb Mon Sep 17 00:00:00 2001
From: Todd Short <tshort@akamai.com>
Date: Mon, 23 Mar 2015 18:00:08 -0400
Subject: [PATCH 10/26] Add DISALLOW_RENEGOTIATION option

Add support to disallow renegotiation in openssl
The bit definition may need to change when pulled.

(cherry picked from commit 7bbf1ff458ef7464582257e6bcb4d28138b02255)

Conflicts:
	apps/s_server.c
	ssl/t1_lib.c
---
 apps/s_server.c           | 8 ++++++++
 include/openssl/ssl.h     | 4 ++++
 ssl/record/rec_layer_s3.c | 4 +++-
 ssl/t1_lib.c              | 3 ++-
 4 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/apps/s_server.c b/apps/s_server.c
index 5c9949c..78ec1bd 100644
--- a/apps/s_server.c
+++ b/apps/s_server.c
@@ -833,6 +833,7 @@ typedef enum OPTION_choice {
     OPT_S_ENUM,
     OPT_V_ENUM,
     OPT_X_ENUM,
+    OPT_DISALLOW_RENEG,
     OPT_IPV4, OPT_IPV6
 } OPTION_CHOICE;
 
@@ -982,6 +983,7 @@ OPTIONS s_server_options[] = {
     OPT_X_OPTIONS,
     {"4", OPT_IPV4, '-', "Use IPv4 sockets"},
     {"6", OPT_IPV6, '-', "Use IPv6 sockets"},
+    {"disallow_renegotiation", OPT_DISALLOW_RENEG, '-', "Disallow use of any renegotiation"},
     {NULL}
 };
 
@@ -1039,6 +1041,7 @@ int s_server_main(int argc, char *argv[])
     char *srp_verifier_file = NULL;
 #endif
     int family = AF_UNSPEC;
+    int disallow_reneg = 0;
 
     local_argc = argc;
     local_argv = argv;
@@ -1444,6 +1447,9 @@ int s_server_main(int argc, char *argv[])
         case OPT_IPV6:
             family = AF_INET6;
             break;
+        case OPT_DISALLOW_RENEG:
+            disallow_reneg = 1;
+            break;
         }
     }
     argc = opt_num_rest();
@@ -1645,6 +1651,8 @@ int s_server_main(int argc, char *argv[])
         BIO_printf(bio_err, "id_prefix '%s' set.\n", session_id_prefix);
     }
     SSL_CTX_set_quiet_shutdown(ctx, 1);
+    if (disallow_reneg)
+        SSL_CTX_set_options(ctx, SSL_OP_DISALLOW_RENEGOTIATION);
     if (exc)
         ssl_ctx_set_excert(ctx, exc);
 
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index a8744e4..4968c94 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -445,6 +445,10 @@ typedef int (*custom_ext_parse_cb) (SSL *s, unsigned int ext_type,
 
 # define SSL_OP_NO_SSL_MASK (SSL_OP_NO_SSLv3|\
         SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1|SSL_OP_NO_TLSv1_2)
+/*
+ * As server, disallow renegotiation (secure and legacy)
+ */
+# define SSL_OP_DISALLOW_RENEGOTIATION                   0x40000000L
 
 /*
  * These next two were never actually used for anything since SSLeay zap so
diff --git a/ssl/record/rec_layer_s3.c b/ssl/record/rec_layer_s3.c
index 4caa398..ec245fc 100644
--- a/ssl/record/rec_layer_s3.c
+++ b/ssl/record/rec_layer_s3.c
@@ -1290,6 +1290,7 @@ int ssl3_readv_bytes(SSL *s, int type, ssl_bucket *buckets,
          */
         goto start;
     }
+
     /*
      * If we are a server and get a client hello when renegotiation isn't
      * allowed send back a no renegotiation alert and carry on. WARNING:
@@ -1302,7 +1303,8 @@ int ssl3_readv_bytes(SSL *s, int type, ssl_bucket *buckets,
         (s->rlayer.handshake_fragment_len >= 4) &&
         (s->rlayer.handshake_fragment[0] == SSL3_MT_CLIENT_HELLO) &&
         (s->session != NULL) && (s->session->cipher != NULL) &&
-        !(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
+        (!(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION) ||
+         (s->options & SSL_OP_DISALLOW_RENEGOTIATION))) {
         SSL3_RECORD_set_length(rr, 0);
         ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_RENEGOTIATION);
         goto start;
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index 7053c4a..f485224 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -1533,7 +1533,8 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
     if (ret >= limit)
         return NULL;            /* this really never occurs, but ... */
 
-    if (s->s3->send_connection_binding) {
+    if (!(s->options & SSL_OP_DISALLOW_RENEGOTIATION) &&
+        s->s3->send_connection_binding) {
         int el;
 
         if (!ssl_add_serverhello_renegotiate_ext(s, 0, &el, 0)) {
-- 
2.3.2 (Apple Git-55)

