/*
- * "$Id$"
- *
* TLS support code for CUPS on OS X.
*
- * Copyright 2007-2015 by Apple Inc.
+ * Copyright 2007-2016 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
extern char **environ;
-/*
- * Test define - set to 1 to use SSLSetEnabledCiphers. Currently disabled (0)
- * because of <rdar://problem/18707430>.
- */
-
-#define USE_SET_ENABLED_CIPHERS 0
-
-
/*
* Local globals...
*/
/* Server cert keychain path */
static _cups_mutex_t tls_mutex = _CUPS_MUTEX_INITIALIZER;
/* Mutex for keychain/certs */
-static int tls_options = 0;/* Options for TLS connections */
#endif /* HAVE_SECKEYCHAINOPEN */
+static int tls_options = -1;/* Options for TLS connections */
/*
if (!keyParams)
goto cleanup;
- CFDictionaryAddValue(keyParams, kSecAttrKeyType, kSecAttrKeyTypeRSA);
+ CFDictionaryAddValue(keyParams, kSecAttrKeyType, kSecAttrKeyTypeECDSA);
CFDictionaryAddValue(keyParams, kSecAttrKeySizeInBits, CFSTR("2048"));
CFDictionaryAddValue(keyParams, kSecAttrLabel, CFSTR("CUPS Self-Signed Certificate"));
status, /* Status of command */
i; /* Looping var */
char command[1024], /* Command */
- *argv[4], /* Command-line arguments */
+ *argv[5], /* Command-line arguments */
*envp[1000], /* Environment variables */
days[32], /* CERTTOOL_EXPIRATION_DAYS env var */
keychain[1024], /* Keychain argument */
cups_file_t *fp; /* Seed/info file */
- DEBUG_printf(("cupsMakeServerCredentials(path=\"%s\", common_name=\"%s\", num_alt_names=%d, alt_names=%p, expiration_date=%d)", path, common_name, num_alt_names, alt_names, (int)expiration_date));
+ DEBUG_printf(("cupsMakeServerCredentials(path=\"%s\", common_name=\"%s\", num_alt_names=%d, alt_names=%p, expiration_date=%d)", path, common_name, num_alt_names, (void *)alt_names, (int)expiration_date));
(void)num_alt_names;
(void)alt_names;
"CUPS Self-Signed Certificate\n"
/* Enter key and certificate label */
"r\n" /* Generate RSA key pair */
- "2048\n" /* Key size in bits */
+ "2048\n" /* 2048 bit encryption key */
"y\n" /* OK (y = yes) */
"b\n" /* Usage (b=signing/encryption) */
- "s\n" /* Sign with SHA1 */
+ "2\n" /* Sign with SHA256 */
"y\n" /* OK (y = yes) */
"%s\n" /* Common name */
"\n" /* Country (default) */
int i; /* Looping var */
- DEBUG_printf(("httpCopyCredentials(http=%p, credentials=%p)", http, credentials));
+ DEBUG_printf(("httpCopyCredentials(http=%p, credentials=%p)", (void *)http, (void *)credentials));
if (credentials)
*credentials = NULL;
SecCertificateRef secCert; /* Certificate reference */
- DEBUG_printf(("httpCredentialsString(credentials=%p, buffer=%p, bufsize=" CUPS_LLFMT ")", credentials, buffer, CUPS_LLCAST bufsize));
+ DEBUG_printf(("httpCredentialsString(credentials=%p, buffer=%p, bufsize=" CUPS_LLFMT ")", (void *)credentials, (void *)buffer, CUPS_LLCAST bufsize));
if (!buffer)
return (0);
CFArrayRef list = NULL; /* Keychain list */
- DEBUG_printf(("httpLoadCredentials(path=\"%s\", credentials=%p, common_name=\"%s\")", path, credentials, common_name));
+ DEBUG_printf(("httpLoadCredentials(path=\"%s\", credentials=%p, common_name=\"%s\")", path, (void *)credentials, common_name));
if (!credentials)
return (-1);
CFArrayRef list = NULL; /* Keychain list */
- DEBUG_printf(("httpSaveCredentials(path=\"%s\", credentials=%p, common_name=\"%s\")", path, credentials, common_name));
+ DEBUG_printf(("httpSaveCredentials(path=\"%s\", credentials=%p, common_name=\"%s\")", path, (void *)credentials, common_name));
if (!credentials)
goto cleanup;
http_credential_t *credential; /* Credential data */
- DEBUG_printf(("7_httpTLSStart(http=%p)", http));
+ DEBUG_printf(("3_httpTLSStart(http=%p)", (void *)http));
+
+ if (tls_options < 0)
+ {
+ DEBUG_puts("4_httpTLSStart: Setting defaults.");
+ _cupsSetDefaults();
+ DEBUG_printf(("4_httpTLSStart: tls_options=%x", tls_options));
+ }
#ifdef HAVE_SECKEYCHAINOPEN
if (http->mode == _HTTP_MODE_SERVER && !tls_keychain)
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 */
case TLS_RSA_PSK_WITH_NULL_SHA256 :
case TLS_RSA_PSK_WITH_NULL_SHA384 :
case SSL_RSA_WITH_DES_CBC_MD5 :
+ DEBUG_printf(("4_httpTLSStart: Excluding insecure cipher suite %d", supported[i]));
break;
/* RC4 cipher suites that should only be used as a last resort */
case TLS_RSA_PSK_WITH_RC4_128_SHA :
if (tls_options & _HTTP_TLS_ALLOW_RC4)
enabled[num_enabled ++] = supported[i];
+ else
+ DEBUG_printf(("4_httpTLSStart: Excluding RC4 cipher suite %d", 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];
+ else
+ DEBUG_printf(("4_httpTLSStart: Excluding DH/DHE cipher suite %d", supported[i]));
+ break;
+
/* Anything else we'll assume is secure */
default :
enabled[num_enabled ++] = supported[i];
error = SSLSetEnabledCiphers(http->tls, enabled, num_enabled);
}
}
-#endif /* USE_SET_ENABLED_CIPHERS */
+#endif /* HAVE_SSLSETENABLEDCIPHERS */
if (!error && http->mode == _HTTP_MODE_CLIENT)
{
DEBUG_printf(("4_httpTLSStart: SSLSetCertificate, error=%d", (int)error));
}
- DEBUG_printf(("4_httpTLSStart: tls_credentials=%p", http->tls_credentials));
+ DEBUG_printf(("4_httpTLSStart: tls_credentials=%p", (void *)http->tls_credentials));
/*
* Let the server know which hostname/domain we are trying to connect to
size_t processed; /* Number of bytes processed */
- DEBUG_printf(("2_httpTLSWrite(http=%p, buf=%p, len=%d)", http, buf, len));
+ DEBUG_printf(("2_httpTLSWrite(http=%p, buf=%p, len=%d)", (void *)http, (void *)buf, len));
error = SSLWrite(http->tls, buf, (size_t)len, &processed);
/* TLS credentials */
- DEBUG_printf(("7http_tls_set_credentials(%p)", http));
+ DEBUG_printf(("7http_tls_set_credentials(%p)", (void *)http));
/*
* Prefer connection specific credentials...
return (result);
}
-
-
-/*
- * End of "$Id$".
- */