Bug 1250568 - Adding ECDHE_PSK suites, r?keeler draft
authorMartin Thomson <martin.thomson@gmail.com>
Sat, 02 Apr 2016 20:51:53 -0300
changeset 347180 2adaa2ec995af11d9454663a028e6eb75a5a4212
parent 347179 aa4c0651ffc3dcc8ac1ebcc737a8afd22f057d14
child 347181 5a3e8b9b904f3d5a84a6f2e63906eedb08ee7722
push id14509
push usermartin.thomson@gmail.com
push dateSun, 03 Apr 2016 00:03:25 +0000
reviewerskeeler
bugs1250568
milestone48.0a1
Bug 1250568 - Adding ECDHE_PSK suites, r?keeler MozReview-Commit-ID: KELrFVzFOpd
security/manager/ssl/nsNSSCallbacks.cpp
security/manager/ssl/nsNSSComponent.cpp
--- a/security/manager/ssl/nsNSSCallbacks.cpp
+++ b/security/manager/ssl/nsNSSCallbacks.cpp
@@ -50,17 +50,17 @@ const uint32_t KEA_NOT_SUPPORTED = 1;
 class nsHTTPDownloadEvent : public nsRunnable {
 public:
   nsHTTPDownloadEvent();
   ~nsHTTPDownloadEvent();
 
   NS_IMETHOD Run();
 
   nsNSSHttpRequestSession *mRequestSession;
-  
+
   RefPtr<nsHTTPListener> mListener;
   bool mResponsibleForDoneSignal;
   TimeStamp mStartTime;
 };
 
 nsHTTPDownloadEvent::nsHTTPDownloadEvent()
 :mResponsibleForDoneSignal(true)
 {
@@ -117,17 +117,17 @@ nsHTTPDownloadEvent::Run()
     rv = NS_NewPostDataStream(getter_AddRefs(uploadStream),
                               false,
                               mRequestSession->mPostData);
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsCOMPtr<nsIUploadChannel> uploadChannel(do_QueryInterface(chan));
     NS_ENSURE_STATE(uploadChannel);
 
-    rv = uploadChannel->SetUploadStream(uploadStream, 
+    rv = uploadChannel->SetUploadStream(uploadStream,
                                         mRequestSession->mPostContentType,
                                         -1);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   // Do not use SPDY for internal security operations. It could result
   // in the silent upgrade to ssl, which in turn could require an SSL
   // operation to fulfill something like an OCSP fetch, which is an
@@ -149,17 +149,17 @@ nsHTTPDownloadEvent::Run()
 
   mResponsibleForDoneSignal = false;
   mListener->mResponsibleForDoneSignal = true;
 
   mListener->mLoadGroup = lg.get();
   NS_ADDREF(mListener->mLoadGroup);
   mListener->mLoadGroupOwnerThread = PR_GetCurrentThread();
 
-  rv = NS_NewStreamLoader(getter_AddRefs(mListener->mLoader), 
+  rv = NS_NewStreamLoader(getter_AddRefs(mListener->mLoader),
                           mListener);
 
   if (NS_SUCCEEDED(rv)) {
     mStartTime = TimeStamp::Now();
     rv = hchan->AsyncOpen2(mListener->mLoader);
   }
 
   if (NS_FAILED(rv)) {
@@ -417,46 +417,46 @@ nsNSSHttpRequestSession::internal_send_r
       // thread code that does not expect to be called re-entrantly. Your
       // app really shouldn't do that.
       NS_WARNING("Security network blocking I/O on Main Thread");
 
       // let's process events quickly
       wait_interval = PR_MicrosecondsToInterval(50);
     }
     else
-    { 
+    {
       // On a secondary thread, it's fine to wait some more for
       // for the condition variable.
       wait_interval = PR_MillisecondsToInterval(250);
     }
 
     while (waitFlag)
     {
       if (running_on_main_thread)
       {
         // Networking runs on the main thread, which we happen to block here.
-        // Processing events will allow the OCSP networking to run while we 
-        // are waiting. Thanks a lot to Darin Fisher for rewriting the 
+        // Processing events will allow the OCSP networking to run while we
+        // are waiting. Thanks a lot to Darin Fisher for rewriting the
         // thread manager. Thanks a lot to Christian Biesinger who
         // made me aware of this possibility. (kaie)
 
         MutexAutoUnlock unlock(waitLock);
         NS_ProcessNextEvent(nullptr);
       }
 
       waitCondition.Wait(wait_interval);
-      
+
       if (!waitFlag)
         break;
 
       if (!request_canceled)
       {
-        bool timeout = 
+        bool timeout =
           (PRIntervalTime)(PR_IntervalNow() - start_time) > mTimeoutInterval;
- 
+
         if (timeout)
         {
           request_canceled = true;
 
           RefPtr<nsCancelHTTPDownloadEvent> cancelevent(
             new nsCancelHTTPDownloadEvent);
           cancelevent->mListener = mListener;
           rv = NS_DispatchToMainThread(cancelevent);
@@ -609,17 +609,17 @@ nsHTTPListener::OnStreamComplete(nsIStre
   mResultCode = aStatus;
 
   FreeLoadGroup(false);
 
   nsCOMPtr<nsIRequest> req;
   nsCOMPtr<nsIHttpChannel> hchan;
 
   nsresult rv = aLoader->GetRequest(getter_AddRefs(req));
-  
+
   if (NS_FAILED(aStatus))
   {
     MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
            ("nsHTTPListener::OnStreamComplete status failed %d", aStatus));
   }
 
   if (NS_SUCCEEDED(rv))
     hchan = do_QueryInterface(req, &rv);
@@ -636,23 +636,23 @@ nsHTTPListener::OnStreamComplete(nsIStre
 
     unsigned int rcode;
     rv = hchan->GetResponseStatus(&rcode);
     if (NS_FAILED(rv))
       mHttpResponseCode = 500;
     else
       mHttpResponseCode = rcode;
 
-    hchan->GetResponseHeader(NS_LITERAL_CSTRING("Content-Type"), 
+    hchan->GetResponseHeader(NS_LITERAL_CSTRING("Content-Type"),
                                     mHttpResponseContentType);
   }
 
   if (mResponsibleForDoneSignal)
     send_done_signal();
-  
+
   return aStatus;
 }
 
 void nsHTTPListener::send_done_signal()
 {
   mResponsibleForDoneSignal = false;
 
   {
@@ -669,52 +669,52 @@ ShowProtectedAuthPrompt(PK11SlotInfo* sl
     NS_ERROR("ShowProtectedAuthPrompt called off the main thread");
     return nullptr;
   }
 
   char* protAuthRetVal = nullptr;
 
   // Get protected auth dialogs
   nsITokenDialogs* dialogs = 0;
-  nsresult nsrv = getNSSDialogs((void**)&dialogs, 
-                                NS_GET_IID(nsITokenDialogs), 
+  nsresult nsrv = getNSSDialogs((void**)&dialogs,
+                                NS_GET_IID(nsITokenDialogs),
                                 NS_TOKENDIALOGS_CONTRACTID);
   if (NS_SUCCEEDED(nsrv))
   {
     nsProtectedAuthThread* protectedAuthRunnable = new nsProtectedAuthThread();
     if (protectedAuthRunnable)
     {
       NS_ADDREF(protectedAuthRunnable);
 
       protectedAuthRunnable->SetParams(slot);
-      
+
       nsCOMPtr<nsIProtectedAuthThread> runnable = do_QueryInterface(protectedAuthRunnable);
       if (runnable)
       {
         nsrv = dialogs->DisplayProtectedAuth(ir, runnable);
-              
+
         // We call join on the thread,
         // so we can be sure that no simultaneous access will happen.
         protectedAuthRunnable->Join();
-              
+
         if (NS_SUCCEEDED(nsrv))
         {
           SECStatus rv = protectedAuthRunnable->GetResult();
           switch (rv)
           {
               case SECSuccess:
                   protAuthRetVal = ToNewCString(nsDependentCString(PK11_PW_AUTHENTICATED));
                   break;
               case SECWouldBlock:
                   protAuthRetVal = ToNewCString(nsDependentCString(PK11_PW_RETRY));
                   break;
               default:
                   protAuthRetVal = nullptr;
                   break;
-              
+
           }
         }
       }
 
       NS_RELEASE(protectedAuthRunnable);
     }
 
     NS_RELEASE(dialogs);
@@ -722,17 +722,17 @@ ShowProtectedAuthPrompt(PK11SlotInfo* sl
 
   return protAuthRetVal;
 }
 
 class PK11PasswordPromptRunnable : public SyncRunnableBase
                                  , public nsNSSShutDownObject
 {
 public:
-  PK11PasswordPromptRunnable(PK11SlotInfo* slot, 
+  PK11PasswordPromptRunnable(PK11SlotInfo* slot,
                              nsIInterfaceRequestor* ir)
     : mResult(nullptr),
       mSlot(slot),
       mIR(ir)
   {
   }
   virtual ~PK11PasswordPromptRunnable();
 
@@ -787,35 +787,35 @@ void PK11PasswordPromptRunnable::RunOnTa
     mResult = ShowProtectedAuthPrompt(mSlot, mIR);
     return;
   }
 
   nsAutoString promptString;
   nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
 
   if (NS_FAILED(rv))
-    return; 
+    return;
 
-  const char16_t* formatStrings[1] = { 
+  const char16_t* formatStrings[1] = {
     ToNewUnicode(NS_ConvertUTF8toUTF16(PK11_GetTokenName(mSlot)))
   };
   rv = nssComponent->PIPBundleFormatStringFromName("CertPassPrompt",
                                       formatStrings, 1,
                                       promptString);
   free(const_cast<char16_t*>(formatStrings[0]));
 
   if (NS_FAILED(rv))
     return;
 
   // Although the exact value is ignored, we must not pass invalid bool values
   // through XPConnect.
   bool checkState = false;
   rv = prompt->PromptPassword(nullptr, promptString.get(), &password, nullptr,
                               &checkState, &value);
-  
+
   if (NS_SUCCEEDED(rv) && value) {
     mResult = ToNewUTF8String(nsDependentString(password));
     free(password);
   }
 }
 
 char*
 PK11PasswordPrompt(PK11SlotInfo* slot, PRBool retry, void* arg)
@@ -1061,16 +1061,18 @@ AccumulateCipherSuite(Telemetry::ID prob
     case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA: value = 62; break;
     case TLS_RSA_WITH_AES_256_CBC_SHA: value = 63; break;
     case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA: value = 64; break;
     case SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA: value = 65; break;
     case TLS_RSA_WITH_3DES_EDE_CBC_SHA: value = 66; break;
     case TLS_RSA_WITH_SEED_CBC_SHA: value = 67; break;
     case TLS_RSA_WITH_RC4_128_SHA: value = 68; break;
     case TLS_RSA_WITH_RC4_128_MD5: value = 69; break;
+    // TLS 1.3 PSK resumption
+    case TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256: value = 70; break;
     // unknown
     default:
       value = 0;
       break;
   }
   MOZ_ASSERT(value != 0);
   Telemetry::Accumulate(probe, value);
 }
--- a/security/manager/ssl/nsNSSComponent.cpp
+++ b/security/manager/ssl/nsNSSComponent.cpp
@@ -1072,16 +1072,19 @@ static const CipherPref sCipherPrefs[] =
    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, true },
 
  { "security.ssl3.dhe_rsa_aes_128_sha",
    TLS_DHE_RSA_WITH_AES_128_CBC_SHA, true },
 
  { "security.ssl3.dhe_rsa_aes_256_sha",
    TLS_DHE_RSA_WITH_AES_256_CBC_SHA, true },
 
+ { "security.ssl3.ecdhe_psk_aes_128_gcm_sha256",
+   TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256, true },
+
  { "security.ssl3.ecdhe_rsa_rc4_128_sha",
    TLS_ECDHE_RSA_WITH_RC4_128_SHA, true, true }, // deprecated (RC4)
  { "security.ssl3.ecdhe_ecdsa_rc4_128_sha",
    TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, true, true }, // deprecated (RC4)
 
  { "security.ssl3.rsa_aes_128_sha",
    TLS_RSA_WITH_AES_128_CBC_SHA, true }, // deprecated (RSA key exchange)
  { "security.ssl3.rsa_aes_256_sha",
@@ -1089,16 +1092,17 @@ static const CipherPref sCipherPrefs[] =
  { "security.ssl3.rsa_des_ede3_sha",
    TLS_RSA_WITH_3DES_EDE_CBC_SHA, true }, // deprecated (RSA key exchange, 3DES)
 
  { "security.ssl3.rsa_rc4_128_sha",
    TLS_RSA_WITH_RC4_128_SHA, true, true }, // deprecated (RSA key exchange, RC4)
  { "security.ssl3.rsa_rc4_128_md5",
    TLS_RSA_WITH_RC4_128_MD5, true, true }, // deprecated (RSA key exchange, RC4, HMAC-MD5)
 
+
  // All the rest are disabled by default
 
  { nullptr, 0 } // end marker
 };
 
 // Bit flags indicating what weak ciphers are enabled.
 // The bit index will correspond to the index in sCipherPrefs.
 // Wrtten by the main thread, read from any threads.