Commit c85159a3 authored by Kyle Nekritz's avatar Kyle Nekritz Committed by Facebook Github Bot 4

Use false start with ALPN.

Summary: All the work we do in SSLContext to check the cipher and NPN usage is actually completely unnecessary since OpenSSL internally checks the cipher and use of ALPN/NPN after you set the SSL_MODE option (see `ssl3_can_cutthrough()` in ssl_lib.c). This just sets the option on the SSLContext instead.

Reviewed By: siyengar

Differential Revision: D3002063

fb-gh-sync-id: 4514faf9ed2eb42a6e41d9e682b2c8aa52c46691
shipit-source-id: 4514faf9ed2eb42a6e41d9e682b2c8aa52c46691
parent 4e0e47bb
...@@ -510,66 +510,6 @@ int SSLContext::advertisedNextProtocolCallback(SSL* ssl, ...@@ -510,66 +510,6 @@ int SSLContext::advertisedNextProtocolCallback(SSL* ssl,
return SSL_TLSEXT_ERR_OK; return SSL_TLSEXT_ERR_OK;
} }
#if defined(SSL_MODE_HANDSHAKE_CUTTHROUGH) && \
FOLLY_SSLCONTEXT_USE_TLS_FALSE_START
SSLContext::SSLFalseStartChecker::SSLFalseStartChecker() :
ciphers_{
TLS1_CK_DHE_DSS_WITH_AES_128_SHA,
TLS1_CK_DHE_RSA_WITH_AES_128_SHA,
TLS1_CK_DHE_DSS_WITH_AES_256_SHA,
TLS1_CK_DHE_RSA_WITH_AES_256_SHA,
TLS1_CK_DHE_DSS_WITH_AES_128_SHA256,
TLS1_CK_DHE_RSA_WITH_AES_128_SHA256,
TLS1_CK_DHE_DSS_WITH_AES_256_SHA256,
TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256,
TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384,
TLS1_CK_DHE_DSS_WITH_AES_128_GCM_SHA256,
TLS1_CK_DHE_DSS_WITH_AES_256_GCM_SHA384,
TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA,
TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA,
TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256,
TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384,
TLS1_CK_ECDH_ECDSA_WITH_AES_128_SHA256,
TLS1_CK_ECDH_ECDSA_WITH_AES_256_SHA384,
TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
} {
length_ = sizeof(ciphers_)/sizeof(ciphers_[0]);
width_ = sizeof(ciphers_[0]);
qsort(ciphers_, length_, width_, compare_ulong);
}
bool SSLContext::SSLFalseStartChecker::canUseFalseStartWithCipher(
const SSL_CIPHER *cipher) {
unsigned long cid = cipher->id;
unsigned long *r =
(unsigned long*)bsearch(&cid, ciphers_, length_, width_, compare_ulong);
return r != nullptr;
}
int
SSLContext::SSLFalseStartChecker::compare_ulong(const void *x, const void *y) {
if (*(unsigned long *)x < *(unsigned long *)y) {
return -1;
}
if (*(unsigned long *)x > *(unsigned long *)y) {
return 1;
}
return 0;
};
bool SSLContext::canUseFalseStartWithCipher(const SSL_CIPHER *cipher) {
return falseStartChecker_.canUseFalseStartWithCipher(cipher);
}
#endif
int SSLContext::selectNextProtocolCallback(SSL* ssl, int SSLContext::selectNextProtocolCallback(SSL* ssl,
unsigned char** out, unsigned char** out,
unsigned char* outlen, unsigned char* outlen,
...@@ -606,14 +546,6 @@ int SSLContext::selectNextProtocolCallback(SSL* ssl, ...@@ -606,14 +546,6 @@ int SSLContext::selectNextProtocolCallback(SSL* ssl,
if (retval != OPENSSL_NPN_NEGOTIATED) { if (retval != OPENSSL_NPN_NEGOTIATED) {
VLOG(3) << "SSLContext::selectNextProcolCallback() " VLOG(3) << "SSLContext::selectNextProcolCallback() "
<< "unable to pick a next protocol."; << "unable to pick a next protocol.";
#if defined(SSL_MODE_HANDSHAKE_CUTTHROUGH) && \
FOLLY_SSLCONTEXT_USE_TLS_FALSE_START
} else {
const SSL_CIPHER *cipher = ssl->s3->tmp.new_cipher;
if (cipher && ctx->canUseFalseStartWithCipher(cipher)) {
SSL_set_mode(ssl, SSL_MODE_HANDSHAKE_CUTTHROUGH);
}
#endif
} }
return SSL_TLSEXT_ERR_OK; return SSL_TLSEXT_ERR_OK;
} }
...@@ -766,6 +698,12 @@ void SSLContext::setSSLLockTypes(std::map<int, SSLLockType> inLockTypes) { ...@@ -766,6 +698,12 @@ void SSLContext::setSSLLockTypes(std::map<int, SSLLockType> inLockTypes) {
lockTypes() = inLockTypes; lockTypes() = inLockTypes;
} }
#if defined(SSL_MODE_HANDSHAKE_CUTTHROUGH)
void SSLContext::enableFalseStart() {
SSL_CTX_set_mode(ctx_, SSL_MODE_HANDSHAKE_CUTTHROUGH);
}
#endif
void SSLContext::markInitialized() { void SSLContext::markInitialized() {
std::lock_guard<std::mutex> g(initMutex()); std::lock_guard<std::mutex> g(initMutex());
initialized_ = true; initialized_ = true;
......
...@@ -376,11 +376,6 @@ class SSLContext { ...@@ -376,11 +376,6 @@ class SSLContext {
*/ */
void unsetNextProtocols(); void unsetNextProtocols();
void deleteNextProtocolsStrings(); void deleteNextProtocolsStrings();
#if defined(SSL_MODE_HANDSHAKE_CUTTHROUGH) && \
FOLLY_SSLCONTEXT_USE_TLS_FALSE_START
bool canUseFalseStartWithCipher(const SSL_CIPHER *cipher);
#endif
#endif // OPENSSL_NPN_NEGOTIATED #endif // OPENSSL_NPN_NEGOTIATED
/** /**
...@@ -437,6 +432,15 @@ class SSLContext { ...@@ -437,6 +432,15 @@ class SSLContext {
bool checkPeerName() { return checkPeerName_; } bool checkPeerName() { return checkPeerName_; }
std::string peerFixedName() { return peerFixedName_; } std::string peerFixedName() { return peerFixedName_; }
#if defined(SSL_MODE_HANDSHAKE_CUTTHROUGH)
/**
* Enable TLS false start, saving a roundtrip for full handshakes. Will only
* be used if the server uses NPN or ALPN, and a strong forward-secure cipher
* is negotiated.
*/
void enableFalseStart();
#endif
/** /**
* Helper to match a hostname versus a pattern. * Helper to match a hostname versus a pattern.
*/ */
...@@ -512,28 +516,6 @@ class SSLContext { ...@@ -512,28 +516,6 @@ class SSLContext {
#endif #endif
size_t pickNextProtocols(); size_t pickNextProtocols();
#if defined(SSL_MODE_HANDSHAKE_CUTTHROUGH) && \
FOLLY_SSLCONTEXT_USE_TLS_FALSE_START
// This class contains all allowed ciphers for SSL false start. Call its
// `canUseFalseStartWithCipher` to check for cipher qualification.
class SSLFalseStartChecker {
public:
SSLFalseStartChecker();
bool canUseFalseStartWithCipher(const SSL_CIPHER *cipher);
private:
static int compare_ulong(const void *x, const void *y);
// All ciphers that are allowed to use false start.
unsigned long ciphers_[47];
unsigned int length_;
unsigned int width_;
};
SSLFalseStartChecker falseStartChecker_;
#endif
#endif // OPENSSL_NPN_NEGOTIATED #endif // OPENSSL_NPN_NEGOTIATED
static int passwordCallback(char* password, int size, int, void* data); static int passwordCallback(char* password, int size, int, void* data);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment