Bug 1321466 - provide client cert when using proxy with SSL r=keeler
authorJunior Hsu <juhsu@mozilla.com>
Sat, 17 Nov 2018 00:28:30 +0000
changeset 503483 d834c0fe16e536cf3cae25946056f3372285f127
parent 503482 02892fb6feaba4654eb127812b8a43147cc6690b
child 503484 7efd8b5c5b934ba3897fb33ac19720c07f4d4057
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskeeler
bugs1321466
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1321466 - provide client cert when using proxy with SSL r=keeler Differential Revision: https://phabricator.services.mozilla.com/D11950
security/manager/ssl/nsNSSIOLayer.cpp
--- a/security/manager/ssl/nsNSSIOLayer.cpp
+++ b/security/manager/ssl/nsNSSIOLayer.cpp
@@ -2438,31 +2438,33 @@ done:
   if (mRV == SECFailure) {
     mErrorCodeToReport = error;
   }
 }
 
 static PRFileDesc*
 nsSSLIOLayerImportFD(PRFileDesc* fd,
                      nsNSSSocketInfo* infoObject,
-                     const char* host)
+                     const char* host,
+                     bool haveHTTPSProxy)
 {
   PRFileDesc* sslSock = SSL_ImportFD(nullptr, fd);
   if (!sslSock) {
     MOZ_ASSERT_UNREACHABLE("NSS: Error importing socket");
     return nullptr;
   }
   SSL_SetPKCS11PinArg(sslSock, (nsIInterfaceRequestor*) infoObject);
   SSL_HandshakeCallback(sslSock, HandshakeCallback, infoObject);
   SSL_SetCanFalseStartCallback(sslSock, CanFalseStartCallback, infoObject);
 
   // Disable this hook if we connect anonymously. See bug 466080.
   uint32_t flags = 0;
   infoObject->GetProviderFlags(&flags);
-  if (flags & nsISocketProvider::ANONYMOUS_CONNECT) {
+  // Provide the client cert to HTTPS proxy no matter if it is anonymous.
+  if (flags & nsISocketProvider::ANONYMOUS_CONNECT && !haveHTTPSProxy) {
       SSL_GetClientAuthDataHook(sslSock, nullptr, infoObject);
   } else {
       SSL_GetClientAuthDataHook(sslSock,
                             (SSLGetClientAuthData) nsNSS_SSLGetClientAuthData,
                             infoObject);
   }
   if (flags & nsISocketProvider::MITM_OK) {
     MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
@@ -2698,36 +2700,41 @@ nsSSLIOLayerAddToSocket(int32_t family,
   infoObject->SetHostName(host);
   infoObject->SetPort(port);
   infoObject->SetOriginAttributes(originAttributes);
   if (allocatedState) {
     infoObject->SetSharedOwningReference(allocatedState);
   }
 
   bool haveProxy = false;
+  bool haveHTTPSProxy = false;
   if (proxy) {
-    nsCString proxyHost;
+    nsAutoCString proxyHost;
     proxy->GetHost(proxyHost);
     haveProxy = !proxyHost.IsEmpty();
+    nsAutoCString type;
+    haveHTTPSProxy = haveProxy &&
+                     NS_SUCCEEDED(proxy->GetType(type)) &&
+                     type.EqualsLiteral("https");
   }
 
   // A plaintext observer shim is inserted so we can observe some protocol
   // details without modifying nss
   plaintextLayer = PR_CreateIOLayerStub(nsSSLIOLayerHelpers::nsSSLPlaintextLayerIdentity,
                                         &nsSSLIOLayerHelpers::nsSSLPlaintextLayerMethods);
   if (plaintextLayer) {
     plaintextLayer->secret = (PRFilePrivate*) infoObject;
     stat = PR_PushIOLayer(fd, PR_TOP_IO_LAYER, plaintextLayer);
     if (stat == PR_FAILURE) {
       plaintextLayer->dtor(plaintextLayer);
       plaintextLayer = nullptr;
     }
   }
 
-  PRFileDesc* sslSock = nsSSLIOLayerImportFD(fd, infoObject, host);
+  PRFileDesc* sslSock = nsSSLIOLayerImportFD(fd, infoObject, host, haveHTTPSProxy);
   if (!sslSock) {
     MOZ_ASSERT_UNREACHABLE("NSS: Error importing socket");
     goto loser;
   }
 
   infoObject->SetFileDescPtr(sslSock);
 
   rv = nsSSLIOLayerSetOptions(sslSock, forSTARTTLS, haveProxy, host, port,