Commit 185914fd authored by Alessandro Ghedini's avatar Alessandro Ghedini Committed by Kamil Dudka
Browse files

nss: add support for TLS False Start

parent 4dcd25e1
Loading
Loading
Loading
Loading
+78 −0
Original line number Diff line number Diff line
@@ -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 */
+3 −0
Original line number Diff line number Diff line
@@ -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 */