Bug 932176: Add preference to control whether OCSP GET is used, off by default, r=cviecco, a=bbajaj
authorBrian Smith <brian@briansmith.org>
Tue, 12 Nov 2013 18:28:20 -0800
changeset 161326 bf6158f1ffc81ff0b2f806c570121e39095ddb31
parent 161325 7c8ba61dabfe4736d950eef6fa5de91aa7148fd4
child 161327 5926bf365a2ecb4aa2b3156369ae11e5a3d5d317
push id4606
push userbrian@briansmith.org
push dateSun, 17 Nov 2013 22:21:05 +0000
treeherdermozilla-aurora@5926bf365a2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscviecco, bbajaj
bugs932176
milestone27.0a2
Bug 932176: Add preference to control whether OCSP GET is used, off by default, r=cviecco, a=bbajaj
netwerk/base/public/security-prefs.js
security/manager/ssl/src/CertVerifier.cpp
security/manager/ssl/src/CertVerifier.h
security/manager/ssl/src/nsNSSComponent.cpp
--- a/netwerk/base/public/security-prefs.js
+++ b/netwerk/base/public/security-prefs.js
@@ -56,8 +56,9 @@ pref("security.ssl3.ecdhe_rsa_aes_128_gc
 
 pref("security.default_personal_cert",   "Ask Every Time");
 pref("security.remember_cert_checkbox_default_setting", true);
 pref("security.ask_for_password",        0);
 pref("security.password_lifetime",       30);
 
 pref("security.OCSP.enabled", 1);
 pref("security.OCSP.require", false);
+pref("security.OCSP.GET.enabled", false);
--- a/security/manager/ssl/src/CertVerifier.cpp
+++ b/security/manager/ssl/src/CertVerifier.cpp
@@ -20,24 +20,26 @@ extern CERTCertList* getRootsForOid(SECO
 
 const CertVerifier::Flags CertVerifier::FLAG_LOCAL_ONLY = 1;
 
 CertVerifier::CertVerifier(missing_cert_download_config mcdc,
                            crl_download_config cdc,
                            ocsp_download_config odc,
                            ocsp_strict_config osc,
                            any_revo_fresh_config arfc,
-                           const char *firstNetworkRevocationMethod)
+                           const char *firstNetworkRevocationMethod,
+                           ocsp_get_config ogc)
   : mMissingCertDownloadEnabled(mcdc == missing_cert_download_on)
   , mCRLDownloadEnabled(cdc == crl_download_allowed)
   , mOCSPDownloadEnabled(odc == ocsp_on)
   , mOCSPStrict(osc == ocsp_strict)
   , mRequireRevocationInfo(arfc == any_revo_strict)
   , mCRLFirst(firstNetworkRevocationMethod != nullptr &&
               !strcmp("crl", firstNetworkRevocationMethod))
+  , mOCSPGETEnabled(ogc == ocsp_get_enabled)
 {
   MOZ_COUNT_CTOR(CertVerifier);
 }
 
 CertVerifier::~CertVerifier()
 {
   MOZ_COUNT_DTOR(CertVerifier);
 }
@@ -225,18 +227,21 @@ CertVerifier::VerifyCert(CERTCertificate
           CERT_REV_M_ALLOW_NETWORK_FETCHING : CERT_REV_M_FORBID_NETWORK_FETCHING)
       | CERT_REV_M_ALLOW_IMPLICIT_DEFAULT_SOURCE
       | CERT_REV_M_REQUIRE_INFO_ON_MISSING_SOURCE
       | CERT_REV_M_IGNORE_MISSING_FRESH_INFO
       | CERT_REV_M_STOP_TESTING_ON_FRESH_INFO;
  
     rev.leafTests.cert_rev_flags_per_method[cert_revocation_method_crl] =
     rev.chainTests.cert_rev_flags_per_method[cert_revocation_method_crl] = revMethodFlags;
+
     rev.leafTests.cert_rev_flags_per_method[cert_revocation_method_ocsp] =
-    rev.chainTests.cert_rev_flags_per_method[cert_revocation_method_ocsp] = revMethodFlags;
+    rev.chainTests.cert_rev_flags_per_method[cert_revocation_method_ocsp]
+      = revMethodFlags
+      | (mOCSPGETEnabled ? 0 : CERT_REV_M_FORCE_POST_METHOD_FOR_OCSP);
 
     rev.leafTests.cert_rev_method_independent_flags =
     rev.chainTests.cert_rev_method_independent_flags =
       // avoiding the network is good, let's try local first
       CERT_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST
       // is overall revocation requirement strict or relaxed?
       |  CERT_REV_MI_REQUIRE_SOME_FRESH_INFO_AVAILABLE
       ;
@@ -337,16 +342,18 @@ CertVerifier::VerifyCert(CERTCertificate
        CERT_REV_M_FAIL_ON_MISSING_FRESH_INFO : CERT_REV_M_IGNORE_MISSING_FRESH_INFO)
 
     // ocsp success is sufficient
     | CERT_REV_M_STOP_TESTING_ON_FRESH_INFO
 
     // ocsp enabled controls network fetching, too
     | ((mOCSPDownloadEnabled && !localOnly) ?
         CERT_REV_M_ALLOW_NETWORK_FETCHING : CERT_REV_M_FORBID_NETWORK_FETCHING)
+    
+    | (mOCSPGETEnabled ? 0 : CERT_REV_M_FORCE_POST_METHOD_FOR_OCSP);
     ;
 
   rev.leafTests.preferred_methods[0] =
   rev.chainTests.preferred_methods[0] =
     mCRLFirst ? cert_revocation_method_crl : cert_revocation_method_ocsp;
 
   rev.leafTests.cert_rev_method_independent_flags =
   rev.chainTests.cert_rev_method_independent_flags =
--- a/security/manager/ssl/src/CertVerifier.h
+++ b/security/manager/ssl/src/CertVerifier.h
@@ -34,32 +34,35 @@ public:
                        /*optional out*/ SECOidTag *evOidPolicy = nullptr ,
                        /*optional out*/ CERTVerifyLog *verifyLog = nullptr);
 
   enum missing_cert_download_config { missing_cert_download_off = 0, missing_cert_download_on };
   enum crl_download_config { crl_local_only = 0, crl_download_allowed };
   enum ocsp_download_config { ocsp_off = 0, ocsp_on };
   enum ocsp_strict_config { ocsp_relaxed = 0, ocsp_strict };
   enum any_revo_fresh_config { any_revo_relaxed = 0, any_revo_strict };
+  enum ocsp_get_config { ocsp_get_disabled = 0, ocsp_get_enabled = 1 };
 
   bool IsOCSPDownloadEnabled() const { return mOCSPDownloadEnabled; }
 
 private:
   CertVerifier(missing_cert_download_config ac, crl_download_config cdc,
                ocsp_download_config odc, ocsp_strict_config osc,
                any_revo_fresh_config arfc,
-               const char *firstNetworkRevocationMethod);
+               const char *firstNetworkRevocationMethod,
+               ocsp_get_config ogc);
   ~CertVerifier();
 
   const bool mMissingCertDownloadEnabled;
   const bool mCRLDownloadEnabled;
   const bool mOCSPDownloadEnabled;
   const bool mOCSPStrict;
   const bool mRequireRevocationInfo;
   const bool mCRLFirst;
+  const bool mOCSPGETEnabled;
   friend class ::nsNSSComponent;
 };
 
 MOZ_WARN_UNUSED_RESULT TemporaryRef<CertVerifier> GetDefaultCertVerifier();
 
 } } // namespace mozilla::psm
 
 #endif // mozilla_psm__CertVerifier_h
--- a/security/manager/ssl/src/nsNSSComponent.cpp
+++ b/security/manager/ssl/src/nsNSSComponent.cpp
@@ -935,28 +935,34 @@ void nsNSSComponent::setValidationOption
                            : ocspMode_FailureIsNotAVerificationFailure);
 
   int OCSPTimeoutSeconds = 3;
   if (ocspRequired || anyFreshRequired) {
     OCSPTimeoutSeconds = 10;
   }
   CERT_SetOCSPTimeout(OCSPTimeoutSeconds);
 
+  // XXX: Always use POST for OCSP; see bug 871954 for undoing this.
+  bool ocspGetEnabled = Preferences::GetBool("security.OCSP.GET.enabled", false);
+  CERT_ForcePostMethodForOCSP(!ocspGetEnabled);
+
   mDefaultCertVerifier = new CertVerifier(
       aiaDownloadEnabled ? 
         CertVerifier::missing_cert_download_on : CertVerifier::missing_cert_download_off,
       crlDownloading ?
         CertVerifier::crl_download_allowed : CertVerifier::crl_local_only,
       ocspEnabled ? 
         CertVerifier::ocsp_on : CertVerifier::ocsp_off,
       ocspRequired ? 
         CertVerifier::ocsp_strict : CertVerifier::ocsp_relaxed,
       anyFreshRequired ?
         CertVerifier::any_revo_strict : CertVerifier::any_revo_relaxed,
-      firstNetworkRevo.get());
+      firstNetworkRevo.get(),
+      ocspGetEnabled ?
+        CertVerifier::ocsp_get_enabled : CertVerifier::ocsp_get_disabled);
 
   /*
     * The new defaults might change the validity of already established SSL sessions,
     * let's not reuse them.
     */
   SSL_ClearSessionCache();
 }
 
@@ -1653,16 +1659,17 @@ nsNSSComponent::Observe(nsISupports *aSu
 //                                                  FALSE_START_ENABLED_DEFAULT);
       SSL_OptionSetDefault(SSL_ENABLE_FALSE_START, false);
     } else if (prefName.Equals("security.OCSP.enabled")
                || prefName.Equals("security.CRL_download.enabled")
                || prefName.Equals("security.fresh_revocation_info.require")
                || prefName.Equals("security.missing_cert_download.enabled")
                || prefName.Equals("security.first_network_revocation_method")
                || prefName.Equals("security.OCSP.require")
+               || prefName.Equals("security.OCSP.GET.enabled")
                || prefName.Equals("security.ssl.enable_ocsp_stapling")) {
       MutexAutoLock lock(mutex);
       setValidationOptions();
     } else if (prefName.Equals("network.ntlm.send-lm-response")) {
       bool sendLM = Preferences::GetBool("network.ntlm.send-lm-response",
                                          SEND_LM_DEFAULT);
       nsNTLMAuthModule::SetSendLM(sendLM);
     } else {