bug 700693 - OCSP stapling PSM changes r=bsmith

This commit is contained in:
David Keeler 2013-06-17 16:45:49 -07:00
parent 4c52191bf3
commit a176617f97
6 changed files with 53 additions and 8 deletions

View File

@ -13,6 +13,7 @@ pref("security.ssl.treat_unsafe_negotiation_as_broken", false);
pref("security.ssl.require_safe_negotiation", false);
pref("security.ssl.warn_missing_rfc5746", 1);
pref("security.ssl.enable_false_start", false);
pref("security.ssl.enable_ocsp_stapling", true);
pref("security.ssl3.rsa_rc4_128_md5", true);
pref("security.ssl3.rsa_rc4_128_sha", true);

View File

@ -121,6 +121,7 @@
#include "secerr.h"
#include "secport.h"
#include "sslerr.h"
#include "ocsp.h"
#ifdef PR_LOGGING
extern PRLogModuleInfo* gPIPNSSLog;
@ -444,7 +445,8 @@ CreateCertErrorRunnable(PRErrorCode defaultErrorCodeToReport,
TransportSecurityInfo * infoObject,
CERTCertificate * cert,
const void * fdForLogging,
uint32_t providerFlags)
uint32_t providerFlags,
PRTime now)
{
MOZ_ASSERT(infoObject);
MOZ_ASSERT(cert);
@ -477,8 +479,6 @@ CreateCertErrorRunnable(PRErrorCode defaultErrorCodeToReport,
return nullptr;
}
PRTime now = PR_Now();
PLArenaPool *log_arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
PLArenaPoolCleanerFalseParam log_arena_cleaner(log_arena);
if (!log_arena) {
@ -1086,7 +1086,7 @@ SSLServerCertVerificationJob::Run()
}
if (error != 0) {
RefPtr<CertErrorRunnable> runnable(CreateCertErrorRunnable(
error, mInfoObject, mCert, mFdForLogging, mProviderFlags));
error, mInfoObject, mCert, mFdForLogging, mProviderFlags, PR_Now()));
if (!runnable) {
// CreateCertErrorRunnable set a new error code
error = PR_GetError();
@ -1162,7 +1162,28 @@ AuthCertificateHook(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer)
PR_SetError(PR_INVALID_STATE_ERROR, 0);
return SECFailure;
}
// This value of "now" is used both here for OCSP stapling and later
// when calling CreateCertErrorRunnable.
PRTime now = PR_Now();
PRBool enabled;
if (SECSuccess != SSL_OptionGet(fd, SSL_ENABLE_OCSP_STAPLING, &enabled)) {
return SECFailure;
}
if (enabled) {
// no ownership
const SECItemArray *csa = SSL_PeerStapledOCSPResponses(fd);
// we currently only support single stapled responses
if (csa && csa->len == 1) {
CERTCertDBHandle *handle = CERT_GetDefaultCertDB();
SECStatus cacheResult = CERT_CacheOCSPResponseFromSideChannel(
handle, serverCert, now, &csa->items[0], arg);
if (cacheResult != SECSuccess) {
return SECFailure;
}
}
}
if (BlockServerCertChangeForSpdy(socketInfo, serverCert) != SECSuccess)
return SECFailure;
@ -1209,7 +1230,7 @@ AuthCertificateHook(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer)
if (error != 0) {
RefPtr<CertErrorRunnable> runnable(CreateCertErrorRunnable(
error, socketInfo, serverCert,
static_cast<const void *>(fd), providerFlags));
static_cast<const void *>(fd), providerFlags, now));
if (!runnable) {
// CreateCertErrorRunnable sets a new error code when it fails
error = PR_GetError();

View File

@ -133,6 +133,7 @@ SharedSSLState::SharedSSLState()
: mClientAuthRemember(new nsClientAuthRememberService)
, mMutex("SharedSSLState::mMutex")
, mSocketCreated(false)
, mOCSPStaplingEnabled(false)
{
mIOLayerHelpers.Init();
mClientAuthRemember->Init();

View File

@ -36,12 +36,14 @@ public:
// Main-thread only
void ResetStoredData();
void NotePrivateBrowsingStatus();
void SetOCSPStaplingEnabled(bool enabled) { mOCSPStaplingEnabled = enabled; }
// The following methods may be called from any thread
bool SocketCreated();
void NoteSocketCreated();
static void NoteCertOverrideServiceInstantiated();
static void NoteCertDBServiceInstantiated();
bool IsOCSPStaplingEnabled() const { return mOCSPStaplingEnabled; }
private:
void Cleanup();
@ -55,6 +57,7 @@ private:
// reading/writing.
Mutex mMutex;
bool mSocketCreated;
bool mOCSPStaplingEnabled;
};
SharedSSLState* PublicSSLState();

View File

@ -891,6 +891,7 @@ setNonPkixOcspEnabled(int32_t ocspEnabled, nsIPrefBranch * pref)
#define MISSING_CERT_DOWNLOAD_DEFAULT false
#define FIRST_REVO_METHOD_DEFAULT "ocsp"
#define USE_NSS_LIBPKIX_DEFAULT false
#define OCSP_STAPLING_ENABLED_DEFAULT true
// Caller must hold a lock on nsNSSComponent::mutex when calling this function
void nsNSSComponent::setValidationOptions(nsIPrefBranch * pref)
@ -929,6 +930,17 @@ void nsNSSComponent::setValidationOptions(nsIPrefBranch * pref)
rv = pref->GetCharPref("security.first_network_revocation_method", getter_Copies(firstNetworkRevo));
if (NS_FAILED(rv))
firstNetworkRevo = FIRST_REVO_METHOD_DEFAULT;
bool ocspStaplingEnabled;
rv = pref->GetBoolPref("security.ssl.enable_ocsp_stapling", &ocspStaplingEnabled);
if (NS_FAILED(rv)) {
ocspStaplingEnabled = OCSP_STAPLING_ENABLED_DEFAULT;
}
if (!ocspEnabled) {
ocspStaplingEnabled = false;
}
PublicSSLState()->SetOCSPStaplingEnabled(ocspStaplingEnabled);
PrivateSSLState()->SetOCSPStaplingEnabled(ocspStaplingEnabled);
setNonPkixOcspEnabled(ocspEnabled, pref);
@ -1178,6 +1190,8 @@ nsNSSComponent::InitializeNSS(bool showWarningBox)
PK11_SetPasswordFunc(PK11PasswordPrompt);
SharedSSLState::GlobalInit();
// Register an observer so we can inform NSS when these prefs change
mPrefBranch->AddObserver("security.", this, false);
@ -1370,7 +1384,6 @@ nsNSSComponent::Init()
}
RememberCertErrorsTable::Init();
SharedSSLState::GlobalInit();
createBackgroundThreads();
if (!mCertVerificationThread)
@ -1656,7 +1669,8 @@ nsNSSComponent::Observe(nsISupports *aSubject, const char *aTopic,
|| 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.require")
|| prefName.Equals("security.ssl.enable_ocsp_stapling")) {
MutexAutoLock lock(mutex);
setValidationOptions(mPrefBranch);
} else if (prefName.Equals("network.ntlm.send-lm-response")) {

View File

@ -2553,6 +2553,11 @@ nsSSLIOLayerSetOptions(PRFileDesc *fd, bool forSTARTTLS,
}
infoObject->SetTLSEnabled(enabled);
enabled = infoObject->SharedState().IsOCSPStaplingEnabled();
if (SECSuccess != SSL_OptionSet(fd, SSL_ENABLE_OCSP_STAPLING, enabled)) {
return NS_ERROR_FAILURE;
}
if (SECSuccess != SSL_OptionSet(fd, SSL_HANDSHAKE_AS_CLIENT, true)) {
return NS_ERROR_FAILURE;
}