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,
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,
unsigned char** out,
unsigned char* outlen,
......@@ -606,14 +546,6 @@ int SSLContext::selectNextProtocolCallback(SSL* ssl,
if (retval != OPENSSL_NPN_NEGOTIATED) {
VLOG(3) << "SSLContext::selectNextProcolCallback() "
<< "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;
}
......@@ -766,6 +698,12 @@ void SSLContext::setSSLLockTypes(std::map<int, SSLLockType> 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() {
std::lock_guard<std::mutex> g(initMutex());
initialized_ = true;
......
......@@ -376,11 +376,6 @@ class SSLContext {
*/
void unsetNextProtocols();
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
/**
......@@ -437,6 +432,15 @@ class SSLContext {
bool checkPeerName() { return checkPeerName_; }
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.
*/
......@@ -512,28 +516,6 @@ class SSLContext {
#endif
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
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