Add SSL_OP_NO_ENCRYPT_THEN_MAC
authorDavid Woodhouse <David.Woodhouse@intel.com>
Thu, 13 Oct 2016 23:26:38 +0000 (00:26 +0100)
committerMatt Caswell <matt@openssl.org>
Mon, 17 Oct 2016 22:17:39 +0000 (23:17 +0100)
Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
doc/ssl/SSL_CTX_set_options.pod
include/openssl/ssl.h
ssl/t1_lib.c

index 635b470e12453c1c7f8ed74a76374fb349e26d6d..63609f3a3192b71ee89ba6bd546a602bbcda3fa2 100644 (file)
@@ -189,6 +189,14 @@ Allow legacy insecure renegotiation between OpenSSL and unpatched servers
 B<only>: this option is currently set by default. See the
 B<SECURE RENEGOTIATION> section for more details.
 
+=item SSL_OP_NO_ENCRYPT_THEN_MAC
+
+Normally clients and servers will transparently attempt to negotiate the
+RFC7366 Encrypt-then-MAC option on TLS and DTLS connection.
+
+If this option is set, Encrypt-then-MAC is disabled. Clients will not
+propose, and servers will not accept the extension.
+
 =back
 
 =head1 SECURE RENEGOTIATION
index e0d82f23bdaf318d5de3cf27d6062e4184730b84..7e626e0fe7ced0962d965c23937575fcab516d47 100644 (file)
@@ -318,6 +318,8 @@ typedef int (*custom_ext_parse_cb) (SSL *s, unsigned int ext_type,
 # define SSL_OP_NO_COMPRESSION                           0x00020000U
 /* Permit unsafe legacy renegotiation */
 # define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION        0x00040000U
+/* Disable encrypt-then-mac */
+# define SSL_OP_NO_ENCRYPT_THEN_MAC                      0x00080000U
 /* Does nothing: retained for compatibility */
 # define SSL_OP_SINGLE_ECDH_USE                          0x0
 /* Does nothing: retained for compatibility */
index 71c480f4029e1a4587e5f44939398ba959310b4c..87ebbf3625900cf46b656df4d4426d4d9b0f08f8 100644 (file)
@@ -1335,10 +1335,12 @@ int ssl_add_clienthello_tlsext(SSL *s, WPACKET *pkt, int *al)
         return 0;
     }
 
-    if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_encrypt_then_mac)
+    if (!(s->options & SSL_OP_NO_ENCRYPT_THEN_MAC)) {
+        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_encrypt_then_mac)
             || !WPACKET_put_bytes_u16(pkt, 0)) {
-        SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-        return 0;
+            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
     }
 
 #ifndef OPENSSL_NO_CT
@@ -2128,7 +2130,8 @@ static int ssl_scan_clienthello_tlsext(SSL *s, PACKET *pkt, int *al)
                 return 0;
         }
 #endif
-        else if (type == TLSEXT_TYPE_encrypt_then_mac)
+        else if (type == TLSEXT_TYPE_encrypt_then_mac &&
+                 !(s->options & SSL_OP_NO_ENCRYPT_THEN_MAC))
             s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC;
         /*
          * Note: extended master secret extension handled in
@@ -2448,7 +2451,8 @@ static int ssl_scan_serverhello_tlsext(SSL *s, PACKET *pkt, int *al)
 #endif
         else if (type == TLSEXT_TYPE_encrypt_then_mac) {
             /* Ignore if inappropriate ciphersuite */
-            if (s->s3->tmp.new_cipher->algorithm_mac != SSL_AEAD
+            if (!(s->options & SSL_OP_NO_ENCRYPT_THEN_MAC) &&
+                s->s3->tmp.new_cipher->algorithm_mac != SSL_AEAD
                 && s->s3->tmp.new_cipher->algorithm_enc != SSL_RC4)
                 s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC;
         } else if (type == TLSEXT_TYPE_extended_master_secret) {