From cde6145ba19a2fce039cf054a89e49f67c623c59 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 14 Oct 2016 00:26:38 +0100 Subject: [PATCH] Add SSL_OP_NO_ENCRYPT_THEN_MAC Reviewed-by: Tim Hudson Reviewed-by: Matt Caswell --- doc/ssl/SSL_CTX_set_options.pod | 8 ++++++++ include/openssl/ssl.h | 2 ++ ssl/t1_lib.c | 14 +++++++++----- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/doc/ssl/SSL_CTX_set_options.pod b/doc/ssl/SSL_CTX_set_options.pod index 635b470e12..63609f3a31 100644 --- a/doc/ssl/SSL_CTX_set_options.pod +++ b/doc/ssl/SSL_CTX_set_options.pod @@ -189,6 +189,14 @@ Allow legacy insecure renegotiation between OpenSSL and unpatched servers B: this option is currently set by default. See the B 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 diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index e0d82f23bd..7e626e0fe7 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -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 */ diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 71c480f402..87ebbf3625 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -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) { -- 2.34.1