aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlessandro Ghedini <alessandro@ghedini.me>2015-02-14 16:59:01 +0100
committerKamil Dudka <kdudka@redhat.com>2015-03-20 20:14:35 +0100
commit185914fd317043d64d48155fb3dfbba4e8a7a294 (patch)
tree6111d460ac4dcb6910f1af0140f351977ea530cc
parent4dcd25e138e9c18a4c96cb78bca5749d8431699f (diff)
nss: add support for TLS False Start
-rw-r--r--lib/vtls/nss.c78
-rw-r--r--lib/vtls/nssg.h3
2 files changed, 81 insertions, 0 deletions
diff --git a/lib/vtls/nss.c b/lib/vtls/nss.c
index 841d6b75d..22d3730a8 100644
--- a/lib/vtls/nss.c
+++ b/lib/vtls/nss.c
@@ -728,6 +728,64 @@ static void HandshakeCallback(PRFileDesc *sock, void *arg)
}
}
+static SECStatus CanFalseStartCallback(PRFileDesc *sock, void *client_data,
+ PRBool *canFalseStart)
+{
+ struct connectdata *conn = client_data;
+ struct SessionHandle *data = conn->data;
+
+ SSLChannelInfo channelInfo;
+ SSLCipherSuiteInfo cipherInfo;
+
+ SECStatus rv;
+ PRBool negotiatedExtension;
+
+ *canFalseStart = PR_FALSE;
+
+ if(SSL_GetChannelInfo(sock, &channelInfo, sizeof(channelInfo)) != SECSuccess)
+ return SECFailure;
+
+ if(SSL_GetCipherSuiteInfo(channelInfo.cipherSuite, &cipherInfo,
+ sizeof(cipherInfo)) != SECSuccess)
+ return SECFailure;
+
+ /* Prevent version downgrade attacks from TLS 1.2, and avoid False Start for
+ * TLS 1.3 and later. See https://bugzilla.mozilla.org/show_bug.cgi?id=861310
+ */
+ if(channelInfo.protocolVersion != SSL_LIBRARY_VERSION_TLS_1_2)
+ goto end;
+
+ /* Only allow ECDHE key exchange algorithm.
+ * See https://bugzilla.mozilla.org/show_bug.cgi?id=952863 */
+ if(cipherInfo.keaType != ssl_kea_ecdh)
+ goto end;
+
+ /* Prevent downgrade attacks on the symmetric cipher. We do not allow CBC
+ * mode due to BEAST, POODLE, and other attacks on the MAC-then-Encrypt
+ * design. See https://bugzilla.mozilla.org/show_bug.cgi?id=1109766 */
+ if(cipherInfo.symCipher != ssl_calg_aes_gcm)
+ goto end;
+
+ /* Enforce ALPN or NPN to do False Start, as an indicator of server
+ * compatibility. */
+ rv = SSL_HandshakeNegotiatedExtension(sock, ssl_app_layer_protocol_xtn,
+ &negotiatedExtension);
+ if(rv != SECSuccess || !negotiatedExtension) {
+ rv = SSL_HandshakeNegotiatedExtension(sock, ssl_next_proto_nego_xtn,
+ &negotiatedExtension);
+ }
+
+ if(rv != SECSuccess || !negotiatedExtension)
+ goto end;
+
+ *canFalseStart = PR_TRUE;
+
+ infof(data, "Trying TLS False Start\n");
+
+end:
+ return SECSuccess;
+}
+
static void display_cert_info(struct SessionHandle *data,
CERTCertificate *cert)
{
@@ -1652,6 +1710,18 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
goto error;
#endif
+#ifdef SSL_ENABLE_FALSE_START
+ if(data->set.ssl.falsestart) {
+ if(SSL_OptionSet(connssl->handle, SSL_ENABLE_FALSE_START, PR_TRUE)
+ != SECSuccess)
+ goto error;
+
+ if(SSL_SetCanFalseStartCallback(connssl->handle, CanFalseStartCallback,
+ conn) != SECSuccess)
+ goto error;
+ }
+#endif
+
#if defined(SSL_ENABLE_NPN) || defined(SSL_ENABLE_ALPN)
if(data->set.ssl_enable_npn || data->set.ssl_enable_alpn) {
int cur = 0;
@@ -1929,4 +1999,12 @@ bool Curl_nss_cert_status_request(void)
#endif
}
+bool Curl_nss_false_start(void) {
+#ifdef SSL_ENABLE_FALSE_START
+ return TRUE;
+#else
+ return FALSE;
+#endif
+}
+
#endif /* USE_NSS */
diff --git a/lib/vtls/nssg.h b/lib/vtls/nssg.h
index 38e75456f..d0e74124e 100644
--- a/lib/vtls/nssg.h
+++ b/lib/vtls/nssg.h
@@ -58,6 +58,8 @@ void Curl_nss_md5sum(unsigned char *tmp, /* input */
bool Curl_nss_cert_status_request(void);
+bool Curl_nss_false_start(void);
+
/* Set the API backend definition to NSS */
#define CURL_SSL_BACKEND CURLSSLBACKEND_NSS
@@ -88,6 +90,7 @@ bool Curl_nss_cert_status_request(void);
#define curlssl_random(x,y,z) Curl_nss_random(x,y,z)
#define curlssl_md5sum(a,b,c,d) Curl_nss_md5sum(a,b,c,d)
#define curlssl_cert_status_request() Curl_nss_cert_status_request()
+#define curlssl_false_start() Curl_nss_false_start()
#endif /* USE_NSS */
#endif /* HEADER_CURL_NSSG_H */