Bug 1010068 - Disable OCSP for DV certificates in Firefox for Android r=keeler

This commit is contained in:
Richard Barnes 2015-05-28 13:29:13 -07:00
parent 205dced600
commit 3824033dee
12 changed files with 55 additions and 32 deletions

View File

@ -474,6 +474,9 @@ pref("security.mixed_content.block_active_content", true);
// Enable pinning
pref("security.cert_pinning.enforcement_level", 1);
// Only fetch OCSP for EV certificates
pref("security.OCSP.enabled", 2);
// Override some named colors to avoid inverse OS themes
pref("ui.-moz-dialog", "#efebe7");
pref("ui.-moz-dialogtext", "#101010");

View File

@ -34,7 +34,7 @@ CertVerifier::CertVerifier(OcspDownloadConfig odc,
OcspGetConfig ogc,
uint32_t certShortLifetimeInDays,
PinningMode pinningMode)
: mOCSPDownloadEnabled(odc == ocspOn)
: mOCSPDownloadConfig(odc)
, mOCSPStrict(osc == ocspStrict)
, mOCSPGETEnabled(ogc == ocspGetEnabled)
, mCertShortLifetimeInDays(certShortLifetimeInDays)
@ -168,8 +168,11 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
return SECFailure;
}
NSSCertDBTrustDomain::OCSPFetching ocspFetching
= !mOCSPDownloadEnabled ||
// We configure the OCSP fetching modes separately for EV and non-EV
// verifications.
NSSCertDBTrustDomain::OCSPFetching defaultOCSPFetching
= (mOCSPDownloadConfig == ocspOff) ||
(mOCSPDownloadConfig == ocspEVOnly) ||
(flags & FLAG_LOCAL_ONLY) ? NSSCertDBTrustDomain::NeverFetchOCSP
: !mOCSPStrict ? NSSCertDBTrustDomain::FetchOCSPForDVSoftFail
: NSSCertDBTrustDomain::FetchOCSPForDVHardFail;
@ -194,7 +197,7 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
case certificateUsageSSLClient: {
// XXX: We don't really have a trust bit for SSL client authentication so
// just use trustEmail as it is the closest alternative.
NSSCertDBTrustDomain trustDomain(trustEmail, ocspFetching, mOCSPCache,
NSSCertDBTrustDomain trustDomain(trustEmail, defaultOCSPFetching, mOCSPCache,
pinArg, ocspGETConfig,
mCertShortLifetimeInDays,
pinningDisabled,
@ -214,15 +217,17 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
#ifndef MOZ_NO_EV_CERTS
// Try to validate for EV first.
NSSCertDBTrustDomain::OCSPFetching evOCSPFetching
= (mOCSPDownloadConfig == ocspOff) ||
(flags & FLAG_LOCAL_ONLY) ? NSSCertDBTrustDomain::LocalOnlyOCSPForEV
: NSSCertDBTrustDomain::FetchOCSPForEV;
CertPolicyId evPolicy;
SECOidTag evPolicyOidTag;
SECStatus srv = GetFirstEVPolicy(cert, evPolicy, evPolicyOidTag);
if (srv == SECSuccess) {
NSSCertDBTrustDomain
trustDomain(trustSSL,
ocspFetching == NSSCertDBTrustDomain::NeverFetchOCSP
? NSSCertDBTrustDomain::LocalOnlyOCSPForEV
: NSSCertDBTrustDomain::FetchOCSPForEV,
trustDomain(trustSSL, evOCSPFetching,
mOCSPCache, pinArg, ocspGETConfig,
mCertShortLifetimeInDays, mPinningMode, MIN_RSA_BITS,
hostname, builtChain);
@ -248,8 +253,8 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
}
// Now try non-EV.
NSSCertDBTrustDomain trustDomain(trustSSL, ocspFetching, mOCSPCache,
pinArg, ocspGETConfig,
NSSCertDBTrustDomain trustDomain(trustSSL, defaultOCSPFetching,
mOCSPCache, pinArg, ocspGETConfig,
mCertShortLifetimeInDays, mPinningMode,
MIN_RSA_BITS, hostname, builtChain);
rv = BuildCertChainForOneKeyUsage(trustDomain, certDER, time,
@ -268,8 +273,8 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
}
// If that failed, try again with a smaller minimum key size.
NSSCertDBTrustDomain trustDomainWeak(trustSSL, ocspFetching, mOCSPCache,
pinArg, ocspGETConfig,
NSSCertDBTrustDomain trustDomainWeak(trustSSL, defaultOCSPFetching,
mOCSPCache, pinArg, ocspGETConfig,
mCertShortLifetimeInDays,
mPinningMode, MIN_RSA_BITS_WEAK,
hostname, builtChain);
@ -293,8 +298,8 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
}
case certificateUsageSSLCA: {
NSSCertDBTrustDomain trustDomain(trustSSL, ocspFetching, mOCSPCache,
pinArg, ocspGETConfig,
NSSCertDBTrustDomain trustDomain(trustSSL, defaultOCSPFetching,
mOCSPCache, pinArg, ocspGETConfig,
mCertShortLifetimeInDays,
pinningDisabled, MIN_RSA_BITS_WEAK,
nullptr, builtChain);
@ -306,8 +311,8 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
}
case certificateUsageEmailSigner: {
NSSCertDBTrustDomain trustDomain(trustEmail, ocspFetching, mOCSPCache,
pinArg, ocspGETConfig,
NSSCertDBTrustDomain trustDomain(trustEmail, defaultOCSPFetching,
mOCSPCache, pinArg, ocspGETConfig,
mCertShortLifetimeInDays,
pinningDisabled, MIN_RSA_BITS_WEAK,
nullptr, builtChain);
@ -330,8 +335,8 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
// TODO: The higher level S/MIME processing should pass in which key
// usage it is trying to verify for, and base its algorithm choices
// based on the result of the verification(s).
NSSCertDBTrustDomain trustDomain(trustEmail, ocspFetching, mOCSPCache,
pinArg, ocspGETConfig,
NSSCertDBTrustDomain trustDomain(trustEmail, defaultOCSPFetching,
mOCSPCache, pinArg, ocspGETConfig,
mCertShortLifetimeInDays,
pinningDisabled, MIN_RSA_BITS_WEAK,
nullptr, builtChain);
@ -351,7 +356,7 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
}
case certificateUsageObjectSigner: {
NSSCertDBTrustDomain trustDomain(trustObjectSigning, ocspFetching,
NSSCertDBTrustDomain trustDomain(trustObjectSigning, defaultOCSPFetching,
mOCSPCache, pinArg, ocspGETConfig,
mCertShortLifetimeInDays,
pinningDisabled, MIN_RSA_BITS_WEAK,
@ -382,16 +387,16 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
eku = KeyPurposeId::id_kp_OCSPSigning;
}
NSSCertDBTrustDomain sslTrust(trustSSL, ocspFetching, mOCSPCache, pinArg,
ocspGETConfig, mCertShortLifetimeInDays,
NSSCertDBTrustDomain sslTrust(trustSSL, defaultOCSPFetching, mOCSPCache,
pinArg, ocspGETConfig, mCertShortLifetimeInDays,
pinningDisabled, MIN_RSA_BITS_WEAK,
nullptr, builtChain);
rv = BuildCertChain(sslTrust, certDER, time, endEntityOrCA,
keyUsage, eku, CertPolicyId::anyPolicy,
stapledOCSPResponse);
if (rv == Result::ERROR_UNKNOWN_ISSUER) {
NSSCertDBTrustDomain emailTrust(trustEmail, ocspFetching, mOCSPCache,
pinArg, ocspGETConfig,
NSSCertDBTrustDomain emailTrust(trustEmail, defaultOCSPFetching,
mOCSPCache, pinArg, ocspGETConfig,
mCertShortLifetimeInDays,
pinningDisabled, MIN_RSA_BITS_WEAK,
nullptr, builtChain);
@ -400,7 +405,7 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
stapledOCSPResponse);
if (rv == Result::ERROR_UNKNOWN_ISSUER) {
NSSCertDBTrustDomain objectSigningTrust(trustObjectSigning,
ocspFetching, mOCSPCache,
defaultOCSPFetching, mOCSPCache,
pinArg, ocspGETConfig,
mCertShortLifetimeInDays,
pinningDisabled,

View File

@ -75,12 +75,14 @@ public:
pinningEnforceTestMode = 3
};
enum OcspDownloadConfig { ocspOff = 0, ocspOn };
enum OcspDownloadConfig {
ocspOff = 0,
ocspOn = 1,
ocspEVOnly = 2
};
enum OcspStrictConfig { ocspRelaxed = 0, ocspStrict };
enum OcspGetConfig { ocspGetDisabled = 0, ocspGetEnabled = 1 };
bool IsOCSPDownloadEnabled() const { return mOCSPDownloadEnabled; }
CertVerifier(OcspDownloadConfig odc, OcspStrictConfig osc,
OcspGetConfig ogc, uint32_t certShortLifetimeInDays,
PinningMode pinningMode);
@ -88,7 +90,7 @@ public:
void ClearOCSPCache() { mOCSPCache.Clear(); }
const bool mOCSPDownloadEnabled;
const OcspDownloadConfig mOCSPDownloadConfig;
const bool mOCSPStrict;
const bool mOCSPGETEnabled;
const uint32_t mCertShortLifetimeInDays;

View File

@ -193,10 +193,15 @@ GetRevocationBehaviorFromPrefs(/*out*/ CertVerifier::OcspDownloadConfig* odc,
MOZ_ASSERT(ogc);
MOZ_ASSERT(certShortLifetimeInDays);
// 0 = disabled, otherwise enabled
*odc = Preferences::GetInt("security.OCSP.enabled", 1)
? CertVerifier::ocspOn
: CertVerifier::ocspOff;
// 0 = disabled
// 1 = enabled for everything (default)
// 2 = enabled for EV certificates only
int32_t ocspLevel = Preferences::GetInt("security.OCSP.enabled", 1);
switch (ocspLevel) {
case 0: *odc = CertVerifier::ocspOff; break;
case 2: *odc = CertVerifier::ocspEVOnly; break;
default: *odc = CertVerifier::ocspOn; break;
}
*osc = Preferences::GetBool("security.OCSP.require", false)
? CertVerifier::ocspStrict

View File

@ -68,6 +68,7 @@ function run_test() {
// setup and start ocsp responder
Services.prefs.setCharPref("network.dns.localDomains",
'www.example.com, crl.example.com');
Services.prefs.setIntPref("security.OCSP.enabled", 1);
add_test(function () {
clearOCSPCache();

View File

@ -132,6 +132,7 @@ function checkRSAChains(inadequateKeySize, adequateKeySize) {
function run_test() {
Services.prefs.setCharPref("network.dns.localDomains", "www.example.com");
Services.prefs.setIntPref("security.OCSP.enabled", 1);
checkRSAChains(2040, 2048);

View File

@ -16,6 +16,7 @@ function generateGoodOCSPResponse() {
function run_test() {
do_get_profile();
Services.prefs.setBoolPref("security.ssl.enable_ocsp_stapling", true);
Services.prefs.setIntPref("security.OCSP.enabled", 1);
add_tls_server_setup("OCSPStaplingServer");
let ocspResponder = new HttpServer();

View File

@ -37,6 +37,7 @@ function run_test() {
Services.prefs.setCharPref("network.dns.localDomains",
"www.example.com");
Services.prefs.setIntPref("security.OCSP.enabled", 1);
add_test(function() {
clearOCSPCache();

View File

@ -14,6 +14,7 @@ let gOCSPRequestCount = 0;
function run_test() {
do_get_profile();
Services.prefs.setBoolPref("security.OCSP.require", true);
Services.prefs.setIntPref("security.OCSP.enabled", 1);
// We don't actually make use of stapling in this test. This is just how we
// get a TLS connection.

View File

@ -27,6 +27,7 @@ function add_ocsp_test(aHost, aExpectedResult, aOCSPResponseToServe) {
do_get_profile();
Services.prefs.setBoolPref("security.ssl.enable_ocsp_stapling", true);
Services.prefs.setIntPref("security.OCSP.enabled", 1);
let args = [["good", "localhostAndExampleCom", "unused"],
["expiredresponse", "localhostAndExampleCom", "unused"],
["oldvalidperiod", "localhostAndExampleCom", "unused"],

View File

@ -26,6 +26,7 @@ let gSocketListener = {
function run_test() {
do_get_profile();
Services.prefs.setIntPref("security.OCSP.enabled", 1);
add_tls_server_setup("OCSPStaplingServer");

View File

@ -39,6 +39,7 @@ function run_test() {
Services.prefs.setCharPref("network.dns.localDomains",
"www.example.com");
Services.prefs.setIntPref("security.OCSP.enabled", 1);
add_test(function() {
clearOCSPCache();