diff --git a/doc/ssl/SSL_CTX_set_options.pod b/doc/ssl/SSL_CTX_set_options.pod index 635b470e12453c1c7f8ed74a76374fb349e26d6d..63609f3a3192b71ee89ba6bd546a602bbcda3fa2 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 e0d82f23bdaf318d5de3cf27d6062e4184730b84..7e626e0fe7ced0962d965c23937575fcab516d47 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 71c480f4029e1a4587e5f44939398ba959310b4c..87ebbf3625900cf46b656df4d4426d4d9b0f08f8 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) {