From ee6226a5cbe12e80205659984bfcc663375b27e6 Mon Sep 17 00:00:00 2001 From: msweet Date: Wed, 20 May 2015 01:20:52 +0000 Subject: [PATCH] Add SSLOptions to enable Diffie-Hellman key exchange and disable TLS/1.0. DH/DHE support is being made optional because of known security issues with short DH parameters. Since there is no way to conditionally use DH/DHE with a minimum number of bits, we just have to disable it by default. TLS/1.0 support can now be disabled due to known security issues with TLS/1.0. However, since TLS/1.1 and TLS/1.2 support is not universally available, we cannot simply disable TLS/1.0 like we did for SSL/3.0. git-svn-id: svn+ssh://src.apple.com/svn/cups/cups.org/trunk@12645 a1ca3aef-8c08-0410-bb20-df032aa958be --- CHANGES.txt | 4 ++- config-scripts/cups-ssl.m4 | 6 +++- config.h.in | 9 +++++- cups/http-private.h | 3 ++ cups/tls-darwin.c | 65 +++++++++++++++++++++++++++++++------- cups/tls-gnutls.c | 39 +++++++++++++---------- cups/tls-sspi.c | 10 ++++-- cups/usersys.c | 10 ++++-- man/client.conf.man.in | 12 ++++--- xcode/config.h | 13 +++++++- 10 files changed, 128 insertions(+), 43 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index f44a83e9b..36108c535 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,4 @@ -CHANGES.txt - 2.1b1 - 2015-05-06 +CHANGES.txt - 2.1b1 - 2015-05-19 -------------------------------- CHANGES IN CUPS V2.1b1 @@ -31,3 +31,5 @@ CHANGES IN CUPS V2.1b1 - The scheduler now validates ErrorPolicy values in config files (STR #4591) - Long cookies caused the web interface to stop working (STR #4619) + - Added SSLOptions values to allow Diffie-Hellman key exchange and + disable TLS/1.0 support. diff --git a/config-scripts/cups-ssl.m4 b/config-scripts/cups-ssl.m4 index f5f8d6405..d48681ea1 100644 --- a/config-scripts/cups-ssl.m4 +++ b/config-scripts/cups-ssl.m4 @@ -3,7 +3,7 @@ dnl "$Id$" dnl dnl TLS stuff for CUPS. dnl -dnl Copyright 2007-2014 by Apple Inc. +dnl Copyright 2007-2015 by Apple Inc. dnl Copyright 1997-2007 by Easy Software Products, all rights reserved. dnl dnl These coded instructions, statements, and computer programs are the @@ -53,6 +53,10 @@ if test x$enable_ssl != xno; then AC_DEFINE(HAVE_CSSMERRORSTRING) AC_DEFINE(HAVE_SECKEYCHAINOPEN)]) + + if test $uversion -ge 150; then + AC_DEFINE(HAVE_SSLSETENABLEDCIPHERS) + fi fi fi diff --git a/config.h.in b/config.h.in index 5c0a19e38..098574913 100644 --- a/config.h.in +++ b/config.h.in @@ -3,7 +3,7 @@ * * Configuration file for CUPS. * - * Copyright 2007-2014 by Apple Inc. + * Copyright 2007-2015 by Apple Inc. * Copyright 1997-2007 by Easy Software Products. * * These coded instructions, statements, and computer programs are the @@ -348,6 +348,13 @@ #undef HAVE_SECKEYCHAINOPEN +/* + * Do we have (a working) SSLSetEnabledCiphers function? + */ + +#undef HAVE_SSLSETENABLEDCIPHERS + + /* * Do we have libpaper? */ diff --git a/cups/http-private.h b/cups/http-private.h index dd6a8e2a0..39337dbcc 100644 --- a/cups/http-private.h +++ b/cups/http-private.h @@ -162,8 +162,11 @@ extern "C" { #define _HTTP_RESOLVE_FQDN 2 /* Resolve to a FQDN */ #define _HTTP_RESOLVE_FAXOUT 4 /* Resolve FaxOut service? */ +#define _HTTP_TLS_NONE 0 /* No TLS options */ #define _HTTP_TLS_ALLOW_RC4 1 /* Allow RC4 cipher suites */ #define _HTTP_TLS_ALLOW_SSL3 2 /* Allow SSL 3.0 */ +#define _HTTP_TLS_ALLOW_DH 4 /* Allow DH/DHE key negotiation */ +#define _HTTP_TLS_DENY_TLS10 16 /* Deny TLS 1.0 */ /* diff --git a/cups/tls-darwin.c b/cups/tls-darwin.c index b75684af7..2ad825484 100644 --- a/cups/tls-darwin.c +++ b/cups/tls-darwin.c @@ -26,14 +26,6 @@ extern char **environ; -/* - * Test define - set to 1 to use SSLSetEnabledCiphers. Currently disabled (0) - * because of . - */ - -#define USE_SET_ENABLED_CIPHERS 0 - - /* * Local globals... */ @@ -1061,11 +1053,20 @@ _httpTLSStart(http_t *http) /* I - HTTP connection */ if (!error) { - error = SSLSetProtocolVersionMin(http->tls, (tls_options & _HTTP_TLS_ALLOW_SSL3) ? kSSLProtocol3 : kTLSProtocol1); - DEBUG_printf(("4_httpTLSStart: SSLSetProtocolVersionMin, error=%d", (int)error)); + SSLProtocol minProtocol; + + if (tls_options & _HTTP_TLS_DENY_TLS10) + minProtocol = kTLSProtocol11; + else if (tls_options & _HTTP_TLS_ALLOW_SSL3) + minProtocol = kSSLProtocol3; + else + minProtocol = kTLSProtocol1; + + error = SSLSetProtocolVersionMin(http->tls, minProtocol); + DEBUG_printf(("4_httpTLSStart: SSLSetProtocolVersionMin(%d), error=%d", minProtocol, (int)error)); } -# if USE_SET_ENABLED_CIPHERS +# if HAVE_SSLSETENABLEDCIPHERS if (!error) { SSLCipherSuite supported[100]; /* Supported cipher suites */ @@ -1146,6 +1147,46 @@ _httpTLSStart(http_t *http) /* I - HTTP connection */ enabled[num_enabled ++] = supported[i]; break; + /* DH/DHE cipher suites that are problematic with parameters < 1024 bits */ + case TLS_DH_DSS_WITH_AES_128_CBC_SHA : + case TLS_DH_RSA_WITH_AES_128_CBC_SHA : + case TLS_DHE_DSS_WITH_AES_128_CBC_SHA : + case TLS_DHE_RSA_WITH_AES_128_CBC_SHA : + case TLS_DH_DSS_WITH_AES_256_CBC_SHA : + case TLS_DH_RSA_WITH_AES_256_CBC_SHA : + case TLS_DHE_DSS_WITH_AES_256_CBC_SHA : + case TLS_DHE_RSA_WITH_AES_256_CBC_SHA : + case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA : + case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA : + case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA : + case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA : + case TLS_DH_DSS_WITH_AES_128_CBC_SHA256 : + case TLS_DH_RSA_WITH_AES_128_CBC_SHA256 : + case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 : + case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 : + case TLS_DH_DSS_WITH_AES_256_CBC_SHA256 : + case TLS_DH_RSA_WITH_AES_256_CBC_SHA256 : + case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 : + case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 : + case TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA : + case TLS_DHE_PSK_WITH_AES_128_CBC_SHA : + case TLS_DHE_PSK_WITH_AES_256_CBC_SHA : + case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 : + case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 : + case TLS_DH_RSA_WITH_AES_128_GCM_SHA256 : + case TLS_DH_RSA_WITH_AES_256_GCM_SHA384 : + case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 : + case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 : + case TLS_DH_DSS_WITH_AES_128_GCM_SHA256 : + case TLS_DH_DSS_WITH_AES_256_GCM_SHA384 : + case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 : + case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 : + case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 : + case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 : + if (tls_options & _HTTP_TLS_ALLOW_DH) + enabled[num_enabled ++] = supported[i]; + break; + /* Anything else we'll assume is secure */ default : enabled[num_enabled ++] = supported[i]; @@ -1157,7 +1198,7 @@ _httpTLSStart(http_t *http) /* I - HTTP connection */ error = SSLSetEnabledCiphers(http->tls, enabled, num_enabled); } } -#endif /* USE_SET_ENABLED_CIPHERS */ +#endif /* HAVE_SSLSETENABLEDCIPHERS */ if (!error && http->mode == _HTTP_MODE_CLIENT) { diff --git a/cups/tls-gnutls.c b/cups/tls-gnutls.c index 124af4049..424fa4932 100644 --- a/cups/tls-gnutls.c +++ b/cups/tls-gnutls.c @@ -1028,6 +1028,8 @@ _httpTLSStart(http_t *http) /* I - Connection to server */ int status; /* Status of handshake */ gnutls_certificate_credentials_t *credentials; /* TLS credentials */ + char priority_string[1024]; + /* Priority string */ DEBUG_printf(("7_httpTLSStart(http=%p)", http)); @@ -1199,28 +1201,33 @@ _httpTLSStart(http_t *http) /* I - Connection to server */ return (-1); } -#ifdef HAVE_GNUTLS_PRIORITY_SET_DIRECT if (!tls_options) - gnutls_priority_set_direct(http->tls, "NORMAL:-ARCFOUR-128:+VERS-TLS-ALL:-VERS-SSL3.0", NULL); - else if ((tls_options & _HTTP_TLS_ALLOW_SSL3) && (tls_options & _HTTP_TLS_ALLOW_RC4)) - gnutls_priority_set_direct(http->tls, "NORMAL", NULL); - else if (tls_options & _HTTP_TLS_ALLOW_SSL3) - gnutls_priority_set_direct(http->tls, "NORMAL:-ARCFOUR-128:+VERS-TLS-ALL", NULL); + strlcpy(priority_string, "NORMAL:-ARCFOUR-128:+VERS-TLS-ALL:-VERS-SSL3.0", sizeof(priority_string)); else - gnutls_priority_set_direct(http->tls, "NORMAL:+VERS-TLS-ALL:-VERS-SSL3.0", NULL); + { + strlcpy(priority_string, "NORMAL", sizeof(priority_string)); + + if (tls_options & _HTTP_TLS_DENY_TLS10) + strlcat(priority_string, ":+VERS-TLS-ALL:-VERS-TLS1.0:-VERS-SSL3.0", sizeof(priority_string); + else if (tls_options & _HTTP_TLS_ALLOW_SSL3) + strlcat(priority_string, ":+VERS-TLS-ALL", sizeof(priority_string); + else + strlcat(priority_string, ":+VERS-TLS-ALL:-VERS-SSL3.0", sizeof(priority_string); + + if (!(tls_options & _HTTP_TLS_ALLOW_RC4)) + strlcat(priority_string, ":-ARCFOUR-128", sizeof(priority_string)); + + if (!(tls_options & _HTTP_TLS_ALLOW_DH)) + strlcat(priority_string, ":!DHE-RSA:!DHE-DSS:!ANON-DH", sizeof(priority_string)); + } + +#ifdef HAVE_GNUTLS_PRIORITY_SET_DIRECT + gnutls_priority_set_direct(http->tls, priority_string, NULL); #else gnutls_priority_t priority; /* Priority */ - if (!tls_options) - gnutls_priority_init(&priority, "NORMAL:-ARCFOUR-128:+VERS-TLS-ALL:-VERS-SSL3.0", NULL); - else if ((tls_options & _HTTP_TLS_ALLOW_SSL3) && (tls_options & _HTTP_TLS_ALLOW_RC4)) - gnutls_priority_init(&priority, "NORMAL", NULL); - else if (tls_options & _HTTP_TLS_ALLOW_SSL3) - gnutls_priority_init(&priority, "NORMAL:-ARCFOUR-128:+VERS-TLS-ALL", NULL); - else - gnutls_priority_init(&priority, "NORMAL:+VERS-TLS-ALL:-VERS-SSL3.0", NULL); - + gnutls_priority_init(&priority, priority_string, NULL); gnutls_priority_set(http->tls, priority); gnutls_priority_deinit(priority); #endif /* HAVE_GNUTLS_PRIORITY_SET_DIRECT */ diff --git a/cups/tls-sspi.c b/cups/tls-sspi.c index e8345e731..f5c44d0fb 100644 --- a/cups/tls-sspi.c +++ b/cups/tls-sspi.c @@ -1756,14 +1756,18 @@ http_sspi_find_credentials( #ifdef SP_PROT_TLS1_2_SERVER if (http->mode == _HTTP_MODE_SERVER) { - if (tls_options & _HTTP_TLS_ALLOW_SSL3) + if (tls_options & _HTTP_TLS_DENY_TLS10) + SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_SERVER | SP_PROT_TLS1_1_SERVER; + else if (tls_options & _HTTP_TLS_ALLOW_SSL3) SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_SERVER | SP_PROT_TLS1_1_SERVER | SP_PROT_TLS1_0_SERVER | SP_PROT_SSL3_SERVER; else SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_SERVER | SP_PROT_TLS1_1_SERVER | SP_PROT_TLS1_0_SERVER; } else { - if (tls_options & _HTTP_TLS_ALLOW_SSL3) + if (tls_options & _HTTP_TLS_DENY_TLS10) + SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_CLIENT | SP_PROT_TLS1_1_CLIENT; + else if (tls_options & _HTTP_TLS_ALLOW_SSL3) SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_CLIENT | SP_PROT_TLS1_1_CLIENT | SP_PROT_TLS1_0_CLIENT | SP_PROT_SSL3_CLIENT; else SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_CLIENT | SP_PROT_TLS1_1_CLIENT | SP_PROT_TLS1_0_CLIENT; @@ -1786,7 +1790,7 @@ http_sspi_find_credentials( } #endif /* SP_PROT_TLS1_2_SERVER */ - /* TODO: Support _HTTP_TLS_ALLOW_RC4 option; right now we'll rely on Windows registry to enable/disable RC4... */ + /* TODO: Support _HTTP_TLS_ALLOW_RC4 and _HTTP_TLS_ALLOW_DH options; right now we'll rely on Windows registry to enable/disable RC4/DH... */ /* * Create an SSPI credential. diff --git a/cups/usersys.c b/cups/usersys.c index 19f4520a9..42294a9e8 100644 --- a/cups/usersys.c +++ b/cups/usersys.c @@ -1209,10 +1209,10 @@ cups_set_ssl_options( const char *value) /* I - Value */ { /* - * SSLOptions [AllowRC4] [AllowSSL3] [None] + * SSLOptions [AllowRC4] [AllowSSL3] [AllowDH] [DenyTLS1.0] [None] */ - int options = 0; /* SSL/TLS options */ + int options = _HTTP_TLS_NONE; /* SSL/TLS options */ char temp[256], /* Copy of value */ *start, /* Start of option */ *end; /* End of option */ @@ -1241,8 +1241,12 @@ cups_set_ssl_options( options |= _HTTP_TLS_ALLOW_RC4; else if (!_cups_strcasecmp(start, "AllowSSL3")) options |= _HTTP_TLS_ALLOW_SSL3; + else if (!_cups_strcasecmp(start, "AllowDH")) + options |= _HTTP_TLS_ALLOW_DH; + else if (!_cups_strcasecmp(start, "DenyTLS1.0")) + options |= _HTTP_TLS_DENY_TLS10; else if (!_cups_strcasecmp(start, "None")) - options = 0; + options = _HTTP_TLS_NONE; } cc->ssl_options = options; diff --git a/man/client.conf.man.in b/man/client.conf.man.in index a7eadbc1e..39a811b04 100644 --- a/man/client.conf.man.in +++ b/man/client.conf.man.in @@ -3,7 +3,7 @@ .\" .\" client.conf man page for CUPS. .\" -.\" Copyright 2007-2014 by Apple Inc. +.\" Copyright 2007-2015 by Apple Inc. .\" Copyright 2006 by Easy Software Products. .\" .\" These coded instructions, statements, and computer programs are the @@ -12,14 +12,14 @@ .\" which should have been included with this file. If this file is .\" file is missing or damaged, see the license at "http://www.cups.org/". .\" -.TH client.conf 5 "CUPS" "20 October 2014" "Apple Inc." +.TH client.conf 5 "CUPS" "19 May 2015" "Apple Inc." .SH NAME client.conf \- client configuration file for cups (deprecated) .SH DESCRIPTION The \fBclient.conf\fR file configures the CUPS client and is normally located in the \fI/etc/cups\fR and/or \fI~/.cups\fR directories. Each line in the file can be a configuration directive, a blank line, or a comment. Comment lines start with the # character. .LP -\fBNote:\fR Starting with OS X 10.7, this file is only used by command-line and X11 applications. +\fBNote:\fR Starting with OS X 10.7, this file is only used by command-line and X11 applications plus the IPP backend. The \fBServerName\fR directive is not supported on OS X at all. .SS DIRECTIVES The following directives are understood by the client. Consult the online help for detailed descriptions: @@ -56,13 +56,15 @@ Specifies the address and optionally the port to use when connecting to the serv \fBServerName \fIhostname-or-ip-address\fR[\fI:port\fR]\fB/version=1.1\fR Specifies the address and optionally the port to use when connecting to a server running CUPS 1.3.12 and earlier. .TP 5 -\fBSSLOptions \fR[\fIAllowRC4\fR] [\fIAllowSSL3\fR] +\fBSSLOptions \fR[\fIAllowDH\fR] [\fIAllowRC4\fR] [\fIAllowSSL3\fR] [\fIDenyTLS1.0\fR] .TP 5 \fBSSLOptions None\fR Sets encryption options (only in /etc/cups/client.conf). By default, CUPS only supports encryption using TLS v1.0 or higher using known secure cipher suites. +The \fIAllowDH\fR option enables cipher suites using plain Diffie-Hellman key negotiation. The \fIAllowRC4\fR option enables the 128-bit RC4 cipher suites, which are required for some older clients that do not implement newer ones. The \fIAllowSSL3\fR option enables SSL v3.0, which is required for some older clients that do not support TLS v1.0. +The \fIDenyTLS1.0\fR option disables TLS v1.0 support - this sets the minimum protocol version to TLS v1.1. .TP 5 \fBUser \fIname\fR Specifies the default user name to use for requests. @@ -78,7 +80,7 @@ The \fBclient.conf\fR file is deprecated and will no longer be supported in a fu .BR cups (1), CUPS Online Help (http://localhost:631/help) .SH COPYRIGHT -Copyright \[co] 2007-2014 by Apple Inc. +Copyright \[co] 2007-2015 by Apple Inc. .\" .\" End of "$Id$". .\" diff --git a/xcode/config.h b/xcode/config.h index 50ff18422..0044da6b2 100644 --- a/xcode/config.h +++ b/xcode/config.h @@ -3,7 +3,7 @@ * * Configuration file for CUPS and Xcode. * - * Copyright 2007-2014 by Apple Inc. + * Copyright 2007-2015 by Apple Inc. * Copyright 1997-2007 by Easy Software Products. * * These coded instructions, statements, and computer programs are the @@ -16,6 +16,8 @@ #ifndef _CUPS_CONFIG_H_ #define _CUPS_CONFIG_H_ +#include + /* * Version of software... */ @@ -350,6 +352,15 @@ #define HAVE_SECKEYCHAINOPEN 1 +/* + * Do we have (a working) SSLSetEnabledCiphers function? + */ + +#ifdef AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER +# define HAVE_SSLSETENABLEDCIPHERS 1 +#endif /* AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER */ + + /* * Do we have libpaper? */ -- 2.39.2