зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1485652
- Reimplement IsAcceptableForHost r=keeler
Differential Revision: https://phabricator.services.mozilla.com/D67949
This commit is contained in:
Родитель
88e6dd92b0
Коммит
b0ac2c6c92
|
@ -335,5 +335,16 @@ FuzzySecurityInfo::GetPeerId(nsACString& aResult) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP FuzzySecurityInfo::SetIsBuiltCertChainRootBuiltInRoot(
|
||||
bool aIsBuiltInRoot) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP FuzzySecurityInfo::GetIsBuiltCertChainRootBuiltInRoot(
|
||||
bool* aIsBuiltInRoot) {
|
||||
*aIsBuiltInRoot = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -154,6 +154,7 @@ nsresult SSLTokensCache::Put(const nsACString& aKey, const uint8_t* aToken,
|
|||
return rv;
|
||||
}
|
||||
|
||||
Maybe<bool> isBuiltCertChainRootBuiltInRoot;
|
||||
if (!succeededCertArray.IsEmpty()) {
|
||||
succeededCertChainBytes.emplace();
|
||||
for (const auto& cert : succeededCertArray) {
|
||||
|
@ -164,6 +165,13 @@ nsresult SSLTokensCache::Put(const nsACString& aKey, const uint8_t* aToken,
|
|||
}
|
||||
succeededCertChainBytes->AppendElement(std::move(rawCert));
|
||||
}
|
||||
|
||||
bool builtInRoot = false;
|
||||
rv = aSecInfo->GetIsBuiltCertChainRootBuiltInRoot(&builtInRoot);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
isBuiltCertChainRootBuiltInRoot.emplace(builtInRoot);
|
||||
}
|
||||
|
||||
bool isEV;
|
||||
|
@ -207,6 +215,9 @@ nsresult SSLTokensCache::Put(const nsACString& aKey, const uint8_t* aToken,
|
|||
rec->mSessionCacheInfo.mCertificateTransparencyStatus =
|
||||
certificateTransparencyStatus;
|
||||
|
||||
rec->mSessionCacheInfo.mIsBuiltCertChainRootBuiltInRoot =
|
||||
std::move(isBuiltCertChainRootBuiltInRoot);
|
||||
|
||||
gInstance->mCacheSize += rec->Size();
|
||||
|
||||
gInstance->LogStats();
|
||||
|
|
|
@ -23,6 +23,7 @@ struct SessionCacheInfo {
|
|||
nsITransportSecurityInfo::CERTIFICATE_TRANSPARENCY_NOT_APPLICABLE;
|
||||
nsTArray<uint8_t> mServerCertBytes;
|
||||
Maybe<nsTArray<nsTArray<uint8_t>>> mSucceededCertChainBytes;
|
||||
Maybe<bool> mIsBuiltCertChainRootBuiltInRoot;
|
||||
};
|
||||
|
||||
class SSLTokensCache : public nsIMemoryReporter {
|
||||
|
|
|
@ -244,6 +244,8 @@ static const char* gCallbackSecurityPrefs[] = {
|
|||
"security.ssl.enable_ocsp_stapling",
|
||||
"security.ssl.enable_ocsp_must_staple",
|
||||
"security.pki.certificate_transparency.mode",
|
||||
"security.cert_pinning.enforcement_level",
|
||||
"security.pki.name_matching_mode",
|
||||
nullptr,
|
||||
};
|
||||
|
||||
|
@ -325,7 +327,9 @@ void nsIOService::OnTLSPrefChange(const char* aPref, void* aSelf) {
|
|||
LOG(("HandleTLSPrefChange done"));
|
||||
} else if (pref.EqualsLiteral("security.ssl.enable_ocsp_stapling") ||
|
||||
pref.EqualsLiteral("security.ssl.enable_ocsp_must_staple") ||
|
||||
pref.EqualsLiteral("security.pki.certificate_transparency.mode")) {
|
||||
pref.EqualsLiteral("security.pki.certificate_transparency.mode") ||
|
||||
pref.EqualsLiteral("security.cert_pinning.enforcement_level") ||
|
||||
pref.EqualsLiteral("security.pki.name_matching_mode")) {
|
||||
SetValidationOptionsCommon();
|
||||
}
|
||||
nsNSSComponent::ClearSSLExternalAndInternalSessionCacheNative();
|
||||
|
|
|
@ -104,4 +104,9 @@ interface nsITransportSecurityInfo : nsISupports {
|
|||
* True iff the connection was resumed using the resumption token.
|
||||
*/
|
||||
readonly attribute boolean resumed;
|
||||
|
||||
/**
|
||||
* True iff the succeededCertChain is built in root.
|
||||
*/
|
||||
attribute boolean isBuiltCertChainRootBuiltInRoot;
|
||||
};
|
||||
|
|
|
@ -903,13 +903,18 @@ Result CertVerifier::VerifySSLServerCert(
|
|||
/*optional out*/ SHA1ModeResult* sha1ModeResult,
|
||||
/*optional out*/ PinningTelemetryInfo* pinningTelemetryInfo,
|
||||
/*optional out*/ CertificateTransparencyInfo* ctInfo,
|
||||
/*optional out*/ CRLiteTelemetryInfo* crliteInfo) {
|
||||
/*optional out*/ CRLiteTelemetryInfo* crliteInfo,
|
||||
/*optional out*/ bool* isBuiltCertChainRootBuiltInRoot) {
|
||||
MOZ_ASSERT(peerCert);
|
||||
// XXX: MOZ_ASSERT(pinarg);
|
||||
MOZ_ASSERT(!hostname.IsEmpty());
|
||||
|
||||
SECOidTag evPolicyOidTag = SEC_OID_UNKNOWN;
|
||||
|
||||
if (isBuiltCertChainRootBuiltInRoot) {
|
||||
*isBuiltCertChainRootBuiltInRoot = false;
|
||||
}
|
||||
|
||||
if (evOidPolicy) {
|
||||
*evOidPolicy = evPolicyOidTag;
|
||||
}
|
||||
|
@ -998,6 +1003,11 @@ Result CertVerifier::VerifySSLServerCert(
|
|||
if (rv != Success) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (isBuiltCertChainRootBuiltInRoot) {
|
||||
*isBuiltCertChainRootBuiltInRoot = isBuiltInRoot;
|
||||
}
|
||||
|
||||
BRNameMatchingPolicy nameMatchingPolicy(
|
||||
isBuiltInRoot ? mNameMatchingMode
|
||||
: BRNameMatchingPolicy::Mode::DoNotEnforce);
|
||||
|
|
|
@ -227,7 +227,8 @@ class CertVerifier {
|
|||
/*optional out*/ SHA1ModeResult* sha1ModeResult = nullptr,
|
||||
/*optional out*/ PinningTelemetryInfo* pinningTelemetryInfo = nullptr,
|
||||
/*optional out*/ CertificateTransparencyInfo* ctInfo = nullptr,
|
||||
/*optional out*/ CRLiteTelemetryInfo* crliteInfo = nullptr);
|
||||
/*optional out*/ CRLiteTelemetryInfo* crliteInfo = nullptr,
|
||||
/*optional out*/ bool* isBuiltCertChainRootBuiltInRoot = nullptr);
|
||||
|
||||
enum PinningMode {
|
||||
pinningDisabled = 0,
|
||||
|
|
|
@ -5,8 +5,12 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "CommonSocketControl.h"
|
||||
|
||||
#include "BRNameMatchingPolicy.h"
|
||||
#include "PublicKeyPinningService.h"
|
||||
#include "SharedCertVerifier.h"
|
||||
#include "nsNSSComponent.h"
|
||||
#include "SharedSSLState.h"
|
||||
#include "sslt.h"
|
||||
#include "ssl.h"
|
||||
|
||||
|
@ -139,36 +143,58 @@ CommonSocketControl::IsAcceptableForHost(const nsACString& hostname,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// Attempt to verify the joinee's certificate using the joining hostname.
|
||||
// This ensures that any hostname-specific verification logic (e.g. key
|
||||
// pinning) is satisfied by the joinee's certificate chain.
|
||||
// This verification only uses local information; since we're on the network
|
||||
// thread, we would be blocking on ourselves if we attempted any network i/o.
|
||||
// TODO(bug 1056935): The certificate chain built by this verification may be
|
||||
// different than the certificate chain originally built during the joined
|
||||
// connection's TLS handshake. Consequently, we may report a wrong and/or
|
||||
// misleading certificate chain for HTTP transactions coalesced onto this
|
||||
// connection. This may become problematic in the future. For example,
|
||||
// if/when we begin relying on intermediate certificates being stored in the
|
||||
// securityInfo of a cached HTTPS response, that cached certificate chain may
|
||||
// actually be the wrong chain. We should consider having JoinConnection
|
||||
// return the certificate chain built here, so that the calling Necko code
|
||||
// can associate the correct certificate chain with the HTTP transactions it
|
||||
// is trying to join onto this connection.
|
||||
RefPtr<psm::SharedCertVerifier> certVerifier(psm::GetDefaultCertVerifier());
|
||||
if (!certVerifier) {
|
||||
// An empty mSucceededCertChain means the server certificate verification
|
||||
// failed before, so don't join in this case.
|
||||
if (mSucceededCertChain.IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
psm::CertVerifier::Flags flags = psm::CertVerifier::FLAG_LOCAL_ONLY;
|
||||
UniqueCERTCertList unusedBuiltChain;
|
||||
mozilla::pkix::Result result =
|
||||
certVerifier->VerifySSLServerCert(nssCert, mozilla::pkix::Now(),
|
||||
nullptr, // pinarg
|
||||
hostname, unusedBuiltChain, flags);
|
||||
if (result != mozilla::pkix::Success) {
|
||||
|
||||
// See where CheckCertHostname() is called in
|
||||
// CertVerifier::VerifySSLServerCert. We are doing the same hostname-specific
|
||||
// checks here. If any hostname-specific checks are added to
|
||||
// CertVerifier::VerifySSLServerCert we need to add them here too.
|
||||
Input serverCertInput;
|
||||
mozilla::pkix::Result rv =
|
||||
serverCertInput.Init(nssCert->derCert.data, nssCert->derCert.len);
|
||||
if (rv != Success) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
Input hostnameInput;
|
||||
rv = hostnameInput.Init(
|
||||
BitwiseCast<const uint8_t*, const char*>(hostname.BeginReading()),
|
||||
hostname.Length());
|
||||
if (rv != Success) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mozilla::psm::BRNameMatchingPolicy nameMatchingPolicy(
|
||||
mIsBuiltCertChainRootBuiltInRoot
|
||||
? mozilla::psm::PublicSSLState()->NameMatchingMode()
|
||||
: mozilla::psm::BRNameMatchingPolicy::Mode::DoNotEnforce);
|
||||
rv = CheckCertHostname(serverCertInput, hostnameInput, nameMatchingPolicy);
|
||||
if (rv != Success) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mozilla::psm::CertVerifier::PinningMode pinningMode =
|
||||
mozilla::psm::PublicSSLState()->PinningMode();
|
||||
if (pinningMode != mozilla::psm::CertVerifier::pinningDisabled) {
|
||||
bool chainHasValidPins;
|
||||
bool enforceTestMode =
|
||||
(pinningMode == mozilla::psm::CertVerifier::pinningEnforceTestMode);
|
||||
nsresult nsrv = mozilla::psm::PublicKeyPinningService::ChainHasValidPins(
|
||||
mSucceededCertChain, PromiseFlatCString(hostname).BeginReading(), Now(),
|
||||
enforceTestMode, GetOriginAttributes(), chainHasValidPins, nullptr);
|
||||
if (NS_FAILED(nsrv)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!chainHasValidPins) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// All tests pass
|
||||
*_retval = true;
|
||||
return NS_OK;
|
||||
|
|
|
@ -18,7 +18,8 @@ refcounted protocol PVerifySSLServerCert
|
|||
child:
|
||||
async OnVerifiedSSLServerCertSuccess(ByteArray[] aBuiltCertChain,
|
||||
uint16_t aCertTransparencyStatus,
|
||||
uint8_t aEVStatus);
|
||||
uint8_t aEVStatus,
|
||||
bool isBuiltCertChainRootBuiltInRoot);
|
||||
|
||||
async OnVerifiedSSLServerCertFailure(uint32_t aFinalError,
|
||||
uint32_t aCollectedErrors);
|
||||
|
|
|
@ -1043,7 +1043,7 @@ static void AuthCertificateSetResults(
|
|||
nsTArray<nsTArray<uint8_t>>&& aBuiltCertChain,
|
||||
nsTArray<nsTArray<uint8_t>>&& aPeerCertChain,
|
||||
uint16_t aCertificateTransparencyStatus, EVStatus aEvStatus,
|
||||
bool aSucceeded) {
|
||||
bool aSucceeded, bool aIsCertChainRootBuiltInRoot) {
|
||||
MOZ_ASSERT(aInfoObject);
|
||||
|
||||
if (aSucceeded) {
|
||||
|
@ -1057,6 +1057,8 @@ static void AuthCertificateSetResults(
|
|||
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
|
||||
("AuthCertificate setting NEW cert %p", aCert));
|
||||
|
||||
aInfoObject->SetIsBuiltCertChainRootBuiltInRoot(
|
||||
aIsCertChainRootBuiltInRoot);
|
||||
aInfoObject->SetCertificateTransparencyStatus(
|
||||
aCertificateTransparencyStatus);
|
||||
} else {
|
||||
|
@ -1078,7 +1080,8 @@ Result AuthCertificate(
|
|||
Time time, uint32_t certVerifierFlags,
|
||||
/*out*/ UniqueCERTCertList& builtCertChain,
|
||||
/*out*/ SECOidTag& evOidPolicy,
|
||||
/*out*/ CertificateTransparencyInfo& certificateTransparencyInfo) {
|
||||
/*out*/ CertificateTransparencyInfo& certificateTransparencyInfo,
|
||||
/*out*/ bool& aIsCertChainRootBuiltInRoot) {
|
||||
MOZ_ASSERT(cert);
|
||||
|
||||
// We want to avoid storing any intermediate cert information when browsing
|
||||
|
@ -1105,7 +1108,8 @@ Result AuthCertificate(
|
|||
Some(peerCertsBytes), stapledOCSPResponse, sctsFromTLSExtension, dcInfo,
|
||||
aOriginAttributes, saveIntermediates, &evOidPolicy, &ocspStaplingStatus,
|
||||
&keySizeStatus, &sha1ModeResult, &pinningTelemetryInfo,
|
||||
&certificateTransparencyInfo, &crliteTelemetryInfo);
|
||||
&certificateTransparencyInfo, &crliteTelemetryInfo,
|
||||
&aIsCertChainRootBuiltInRoot);
|
||||
|
||||
CollectCertTelemetry(rv, evOidPolicy, ocspStaplingStatus, keySizeStatus,
|
||||
sha1ModeResult, pinningTelemetryInfo, builtCertChain,
|
||||
|
@ -1296,11 +1300,12 @@ SSLServerCertVerificationJob::Run() {
|
|||
UniqueCERTCertList builtCertChain;
|
||||
SECOidTag evOidPolicy;
|
||||
CertificateTransparencyInfo certificateTransparencyInfo;
|
||||
bool isCertChainRootBuiltInRoot = false;
|
||||
Result rv = AuthCertificate(
|
||||
*certVerifier, mPinArg, mCert, mPeerCertChain, mHostName,
|
||||
mOriginAttributes, mStapledOCSPResponse, mSCTsFromTLSExtension, mDCInfo,
|
||||
mProviderFlags, mTime, mCertVerifierFlags, builtCertChain, evOidPolicy,
|
||||
certificateTransparencyInfo);
|
||||
certificateTransparencyInfo, isCertChainRootBuiltInRoot);
|
||||
|
||||
RefPtr<nsNSSCertificate> nsc = nsNSSCertificate::Create(mCert.get());
|
||||
nsTArray<nsTArray<uint8_t>> certBytesArray;
|
||||
|
@ -1318,7 +1323,7 @@ SSLServerCertVerificationJob::Run() {
|
|||
nsc, std::move(certBytesArray), std::move(mPeerCertChain),
|
||||
TransportSecurityInfo::ConvertCertificateTransparencyInfoToStatus(
|
||||
certificateTransparencyInfo),
|
||||
evStatus, true, 0, 0);
|
||||
evStatus, true, 0, 0, isCertChainRootBuiltInRoot);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1336,7 +1341,7 @@ SSLServerCertVerificationJob::Run() {
|
|||
mResultTask->Dispatch(
|
||||
nsc, std::move(certBytesArray), std::move(mPeerCertChain),
|
||||
nsITransportSecurityInfo::CERTIFICATE_TRANSPARENCY_NOT_APPLICABLE,
|
||||
EVStatus::NotEV, false, finalError, collectedErrors);
|
||||
EVStatus::NotEV, false, finalError, collectedErrors, false);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1561,7 +1566,8 @@ void SSLServerCertVerificationResult::Dispatch(
|
|||
nsNSSCertificate* aCert, nsTArray<nsTArray<uint8_t>>&& aBuiltChain,
|
||||
nsTArray<nsTArray<uint8_t>>&& aPeerCertChain,
|
||||
uint16_t aCertificateTransparencyStatus, EVStatus aEVStatus,
|
||||
bool aSucceeded, PRErrorCode aFinalError, uint32_t aCollectedErrors) {
|
||||
bool aSucceeded, PRErrorCode aFinalError, uint32_t aCollectedErrors,
|
||||
bool aIsCertChainRootBuiltInRoot) {
|
||||
mCert = aCert;
|
||||
mBuiltChain = std::move(aBuiltChain);
|
||||
mPeerCertChain = std::move(aPeerCertChain);
|
||||
|
@ -1570,6 +1576,7 @@ void SSLServerCertVerificationResult::Dispatch(
|
|||
mSucceeded = aSucceeded;
|
||||
mFinalError = aFinalError;
|
||||
mCollectedErrors = aCollectedErrors;
|
||||
mIsBuiltCertChainRootBuiltInRoot = aIsCertChainRootBuiltInRoot;
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIEventTarget> stsTarget =
|
||||
|
@ -1594,9 +1601,10 @@ SSLServerCertVerificationResult::Run() {
|
|||
MOZ_ASSERT(onSTSThread);
|
||||
#endif
|
||||
|
||||
AuthCertificateSetResults(
|
||||
mInfoObject, mCert, std::move(mBuiltChain), std::move(mPeerCertChain),
|
||||
mCertificateTransparencyStatus, mEVStatus, mSucceeded);
|
||||
AuthCertificateSetResults(mInfoObject, mCert, std::move(mBuiltChain),
|
||||
std::move(mPeerCertChain),
|
||||
mCertificateTransparencyStatus, mEVStatus,
|
||||
mSucceeded, mIsBuiltCertChainRootBuiltInRoot);
|
||||
|
||||
if (!mSucceeded && mCollectedErrors != 0) {
|
||||
mInfoObject->SetStatusErrorBits(mCert, mCollectedErrors);
|
||||
|
|
|
@ -49,7 +49,8 @@ class BaseSSLServerCertVerificationResult {
|
|||
nsTArray<nsTArray<uint8_t>>&& aPeerCertChain,
|
||||
uint16_t aCertificateTransparencyStatus,
|
||||
EVStatus aEVStatus, bool aSucceeded,
|
||||
PRErrorCode aFinalError, uint32_t aCollectedErrors) = 0;
|
||||
PRErrorCode aFinalError, uint32_t aCollectedErrors,
|
||||
bool aIsBuiltCertChainRootBuiltInRoot) = 0;
|
||||
};
|
||||
|
||||
// Dispatched to the STS thread to notify the infoObject of the verification
|
||||
|
@ -72,7 +73,8 @@ class SSLServerCertVerificationResult final
|
|||
nsTArray<nsTArray<uint8_t>>&& aPeerCertChain,
|
||||
uint16_t aCertificateTransparencyStatus, EVStatus aEVStatus,
|
||||
bool aSucceeded, PRErrorCode aFinalError,
|
||||
uint32_t aCollectedErrors) override;
|
||||
uint32_t aCollectedErrors,
|
||||
bool aIsBuiltCertChainRootBuiltInRoot) override;
|
||||
|
||||
private:
|
||||
~SSLServerCertVerificationResult() = default;
|
||||
|
@ -86,6 +88,7 @@ class SSLServerCertVerificationResult final
|
|||
bool mSucceeded;
|
||||
PRErrorCode mFinalError;
|
||||
uint32_t mCollectedErrors;
|
||||
bool mIsBuiltCertChainRootBuiltInRoot;
|
||||
};
|
||||
|
||||
class SSLServerCertVerificationJob : public Runnable {
|
||||
|
|
|
@ -36,6 +36,12 @@ class SharedSSLState {
|
|||
void SetSignedCertTimestampsEnabled(bool signedCertTimestampsEnabled) {
|
||||
mSignedCertTimestampsEnabled = signedCertTimestampsEnabled;
|
||||
}
|
||||
void SetPinningMode(CertVerifier::PinningMode aPinningMode) {
|
||||
mPinningMode = aPinningMode;
|
||||
}
|
||||
void SetNameMatchingMode(BRNameMatchingPolicy::Mode aMode) {
|
||||
mNameMatchingMode = aMode;
|
||||
}
|
||||
|
||||
// The following methods may be called from any thread
|
||||
bool SocketCreated();
|
||||
|
@ -46,6 +52,8 @@ class SharedSSLState {
|
|||
bool IsSignedCertTimestampsEnabled() const {
|
||||
return mSignedCertTimestampsEnabled;
|
||||
}
|
||||
CertVerifier::PinningMode PinningMode() { return mPinningMode; }
|
||||
BRNameMatchingPolicy::Mode NameMatchingMode() { return mNameMatchingMode; }
|
||||
|
||||
private:
|
||||
~SharedSSLState();
|
||||
|
@ -63,6 +71,8 @@ class SharedSSLState {
|
|||
bool mOCSPStaplingEnabled;
|
||||
bool mOCSPMustStapleEnabled;
|
||||
bool mSignedCertTimestampsEnabled;
|
||||
CertVerifier::PinningMode mPinningMode;
|
||||
BRNameMatchingPolicy::Mode mNameMatchingMode;
|
||||
};
|
||||
|
||||
SharedSSLState* PublicSSLState();
|
||||
|
|
|
@ -58,6 +58,7 @@ TransportSecurityInfo::TransportSecurityInfo()
|
|||
mMutex("TransportSecurityInfo::mMutex"),
|
||||
mNPNCompleted(false),
|
||||
mResumed(false),
|
||||
mIsBuiltCertChainRootBuiltInRoot(false),
|
||||
mSecurityState(nsIWebProgressListener::STATE_IS_INSECURE),
|
||||
mErrorCode(0),
|
||||
mPort(0) {}
|
||||
|
@ -193,7 +194,7 @@ TransportSecurityInfo::Write(nsIObjectOutputStream* aStream) {
|
|||
// Re-purpose mErrorMessageCached to represent serialization version
|
||||
// If string doesn't match exact version it will be treated as older
|
||||
// serialization.
|
||||
rv = aStream->WriteWStringZ(NS_ConvertUTF8toUTF16("4").get());
|
||||
rv = aStream->WriteWStringZ(NS_ConvertUTF8toUTF16("5").get());
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -273,6 +274,11 @@ TransportSecurityInfo::Write(nsIObjectOutputStream* aStream) {
|
|||
return rv;
|
||||
}
|
||||
|
||||
rv = aStream->WriteBoolean(mIsBuiltCertChainRootBuiltInRoot);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -532,7 +538,8 @@ TransportSecurityInfo::Read(nsIObjectInputStream* aStream) {
|
|||
|
||||
// moved from nsISSLStatus
|
||||
if (!serVersion.EqualsASCII("1") && !serVersion.EqualsASCII("2") &&
|
||||
!serVersion.EqualsASCII("3") && !serVersion.EqualsASCII("4")) {
|
||||
!serVersion.EqualsASCII("3") && !serVersion.EqualsASCII("4") &&
|
||||
!serVersion.EqualsASCII("5")) {
|
||||
// nsISSLStatus may be present
|
||||
rv = ReadSSLStatus(aStream);
|
||||
CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv),
|
||||
|
@ -608,7 +615,8 @@ TransportSecurityInfo::Read(nsIObjectInputStream* aStream) {
|
|||
"Deserialization should not fail");
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!serVersion.EqualsASCII("3") && !serVersion.EqualsASCII("4")) {
|
||||
if (!serVersion.EqualsASCII("3") && !serVersion.EqualsASCII("4") &&
|
||||
!serVersion.EqualsASCII("5")) {
|
||||
// The old data structure of certList(nsIX509CertList) presents
|
||||
rv = ReadCertList(aStream, mSucceededCertChain);
|
||||
CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv),
|
||||
|
@ -626,7 +634,8 @@ TransportSecurityInfo::Read(nsIObjectInputStream* aStream) {
|
|||
}
|
||||
}
|
||||
// END moved from nsISSLStatus
|
||||
if (!serVersion.EqualsASCII("3") && !serVersion.EqualsASCII("4")) {
|
||||
if (!serVersion.EqualsASCII("3") && !serVersion.EqualsASCII("4") &&
|
||||
!serVersion.EqualsASCII("5")) {
|
||||
// The old data structure of certList(nsIX509CertList) presents
|
||||
rv = ReadCertList(aStream, mFailedCertChain);
|
||||
CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv),
|
||||
|
@ -645,7 +654,7 @@ TransportSecurityInfo::Read(nsIObjectInputStream* aStream) {
|
|||
|
||||
// mIsDelegatedCredential added in bug 1562773
|
||||
if (serVersion.EqualsASCII("2") || serVersion.EqualsASCII("3") ||
|
||||
serVersion.EqualsASCII("4")) {
|
||||
serVersion.EqualsASCII("4") || serVersion.EqualsASCII("5")) {
|
||||
rv = aStream->ReadBoolean(&mIsDelegatedCredential);
|
||||
CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv),
|
||||
"Deserialization should not fail");
|
||||
|
@ -655,7 +664,7 @@ TransportSecurityInfo::Read(nsIObjectInputStream* aStream) {
|
|||
}
|
||||
|
||||
// mNPNCompleted, mNegotiatedNPN, mResumed added in bug 1584104
|
||||
if (serVersion.EqualsASCII("4")) {
|
||||
if (serVersion.EqualsASCII("4") || serVersion.EqualsASCII("5")) {
|
||||
rv = aStream->ReadBoolean(&mNPNCompleted);
|
||||
CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv),
|
||||
"Deserialization should not fail");
|
||||
|
@ -678,6 +687,16 @@ TransportSecurityInfo::Read(nsIObjectInputStream* aStream) {
|
|||
}
|
||||
}
|
||||
|
||||
// mIsBuiltCertChainRootBuiltInRoot added in bug 1485652
|
||||
if (serVersion.EqualsASCII("5")) {
|
||||
rv = aStream->ReadBoolean(&mIsBuiltCertChainRootBuiltInRoot);
|
||||
CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv),
|
||||
"Deserialization should not fail");
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -709,6 +728,7 @@ void TransportSecurityInfo::SerializeToIPC(IPC::Message* aMsg) {
|
|||
WriteParam(aMsg, mNPNCompleted);
|
||||
WriteParam(aMsg, mNegotiatedNPN);
|
||||
WriteParam(aMsg, mResumed);
|
||||
WriteParam(aMsg, mIsBuiltCertChainRootBuiltInRoot);
|
||||
}
|
||||
|
||||
bool TransportSecurityInfo::DeserializeFromIPC(const IPC::Message* aMsg,
|
||||
|
@ -737,7 +757,8 @@ bool TransportSecurityInfo::DeserializeFromIPC(const IPC::Message* aMsg,
|
|||
!ReadParam(aMsg, aIter, &mIsDelegatedCredential) ||
|
||||
!ReadParam(aMsg, aIter, &mNPNCompleted) ||
|
||||
!ReadParam(aMsg, aIter, &mNegotiatedNPN) ||
|
||||
!ReadParam(aMsg, aIter, &mResumed)) {
|
||||
!ReadParam(aMsg, aIter, &mResumed) ||
|
||||
!ReadParam(aMsg, aIter, &mIsBuiltCertChainRootBuiltInRoot)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -956,6 +977,19 @@ nsresult TransportSecurityInfo::SetSucceededCertChain(
|
|||
return CreateCertChain(mSucceededCertChain, std::move(aCertList));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP TransportSecurityInfo::SetIsBuiltCertChainRootBuiltInRoot(
|
||||
bool aIsBuiltInRoot) {
|
||||
mIsBuiltCertChainRootBuiltInRoot = aIsBuiltInRoot;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP TransportSecurityInfo::GetIsBuiltCertChainRootBuiltInRoot(
|
||||
bool* aIsBuiltInRoot) {
|
||||
NS_ENSURE_ARG_POINTER(aIsBuiltInRoot);
|
||||
*aIsBuiltInRoot = mIsBuiltCertChainRootBuiltInRoot;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TransportSecurityInfo::GetCipherName(nsACString& aCipherName) {
|
||||
if (!mHaveCipherSuiteAndProtocol) {
|
||||
|
|
|
@ -130,6 +130,7 @@ class TransportSecurityInfo : public nsITransportSecurityInfo,
|
|||
bool mNPNCompleted;
|
||||
nsCString mNegotiatedNPN;
|
||||
bool mResumed;
|
||||
bool mIsBuiltCertChainRootBuiltInRoot;
|
||||
|
||||
private:
|
||||
uint32_t mSecurityState;
|
||||
|
|
|
@ -28,7 +28,8 @@ VerifySSLServerCertChild::VerifySSLServerCertChild(
|
|||
|
||||
ipc::IPCResult VerifySSLServerCertChild::RecvOnVerifiedSSLServerCertSuccess(
|
||||
nsTArray<ByteArray>&& aBuiltCertChain,
|
||||
const uint16_t& aCertTransparencyStatus, const uint8_t& aEVStatus) {
|
||||
const uint16_t& aCertTransparencyStatus, const uint8_t& aEVStatus,
|
||||
const bool& aIsBuiltCertChainRootBuiltInRoot) {
|
||||
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
|
||||
("[%p] VerifySSLServerCertChild::RecvOnVerifiedSSLServerCertSuccess",
|
||||
this));
|
||||
|
@ -41,7 +42,8 @@ ipc::IPCResult VerifySSLServerCertChild::RecvOnVerifiedSSLServerCertSuccess(
|
|||
|
||||
mResultTask->Dispatch(nsc, std::move(certBytesArray),
|
||||
std::move(mPeerCertChain), aCertTransparencyStatus,
|
||||
static_cast<EVStatus>(aEVStatus), true, 0, 0);
|
||||
static_cast<EVStatus>(aEVStatus), true, 0, 0,
|
||||
aIsBuiltCertChainRootBuiltInRoot);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
@ -57,7 +59,7 @@ ipc::IPCResult VerifySSLServerCertChild::RecvOnVerifiedSSLServerCertFailure(
|
|||
mResultTask->Dispatch(
|
||||
nsc, nsTArray<nsTArray<uint8_t>>(), std::move(mPeerCertChain),
|
||||
nsITransportSecurityInfo::CERTIFICATE_TRANSPARENCY_NOT_APPLICABLE,
|
||||
EVStatus::NotEV, false, aFinalError, aCollectedErrors);
|
||||
EVStatus::NotEV, false, aFinalError, aCollectedErrors, false);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,8 @@ class VerifySSLServerCertChild : public PVerifySSLServerCertChild {
|
|||
|
||||
ipc::IPCResult RecvOnVerifiedSSLServerCertSuccess(
|
||||
nsTArray<ByteArray>&& aBuiltCertChain,
|
||||
const uint16_t& aCertTransparencyStatus, const uint8_t& aEVStatus);
|
||||
const uint16_t& aCertTransparencyStatus, const uint8_t& aEVStatus,
|
||||
const bool& aIsBuiltCertChainRootBuiltInRoot);
|
||||
|
||||
ipc::IPCResult RecvOnVerifiedSSLServerCertFailure(
|
||||
const uint32_t& aFinalError, const uint32_t& aCollectedErrors);
|
||||
|
|
|
@ -31,7 +31,8 @@ VerifySSLServerCertParent::VerifySSLServerCertParent() {}
|
|||
void VerifySSLServerCertParent::OnVerifiedSSLServerCert(
|
||||
const nsTArray<ByteArray>& aBuiltCertChain,
|
||||
uint16_t aCertificateTransparencyStatus, uint8_t aEVStatus, bool aSucceeded,
|
||||
PRErrorCode aFinalError, uint32_t aCollectedErrors) {
|
||||
PRErrorCode aFinalError, uint32_t aCollectedErrors,
|
||||
bool aIsBuiltCertChainRootBuiltInRoot) {
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
if (!CanSend()) {
|
||||
|
@ -40,7 +41,8 @@ void VerifySSLServerCertParent::OnVerifiedSSLServerCert(
|
|||
|
||||
if (aSucceeded) {
|
||||
Unused << SendOnVerifiedSSLServerCertSuccess(
|
||||
aBuiltCertChain, aCertificateTransparencyStatus, aEVStatus);
|
||||
aBuiltCertChain, aCertificateTransparencyStatus, aEVStatus,
|
||||
aIsBuiltCertChainRootBuiltInRoot);
|
||||
} else {
|
||||
Unused << SendOnVerifiedSSLServerCertFailure(aFinalError, aCollectedErrors);
|
||||
}
|
||||
|
@ -64,7 +66,8 @@ class IPCServerCertVerificationResult final
|
|||
nsTArray<nsTArray<uint8_t>>&& aPeerCertChain,
|
||||
uint16_t aCertificateTransparencyStatus, EVStatus aEVStatus,
|
||||
bool aSucceeded, PRErrorCode aFinalError,
|
||||
uint32_t aCollectedErrors) override;
|
||||
uint32_t aCollectedErrors,
|
||||
bool aIsBuiltCertChainRootBuiltInRoot) override;
|
||||
|
||||
private:
|
||||
~IPCServerCertVerificationResult() = default;
|
||||
|
@ -77,7 +80,8 @@ void IPCServerCertVerificationResult::Dispatch(
|
|||
nsNSSCertificate* aCert, nsTArray<nsTArray<uint8_t>>&& aBuiltChain,
|
||||
nsTArray<nsTArray<uint8_t>>&& aPeerCertChain,
|
||||
uint16_t aCertificateTransparencyStatus, EVStatus aEVStatus,
|
||||
bool aSucceeded, PRErrorCode aFinalError, uint32_t aCollectedErrors) {
|
||||
bool aSucceeded, PRErrorCode aFinalError, uint32_t aCollectedErrors,
|
||||
bool aIsBuiltCertChainRootBuiltInRoot) {
|
||||
nsTArray<ByteArray> builtCertChain;
|
||||
if (aSucceeded) {
|
||||
for (auto& cert : aBuiltChain) {
|
||||
|
@ -90,11 +94,11 @@ void IPCServerCertVerificationResult::Dispatch(
|
|||
"psm::VerifySSLServerCertParent::OnVerifiedSSLServerCert",
|
||||
[parent(mParent), builtCertChain{std::move(builtCertChain)},
|
||||
aCertificateTransparencyStatus, aEVStatus, aSucceeded, aFinalError,
|
||||
aCollectedErrors]() {
|
||||
aCollectedErrors, aIsBuiltCertChainRootBuiltInRoot]() {
|
||||
parent->OnVerifiedSSLServerCert(
|
||||
builtCertChain, aCertificateTransparencyStatus,
|
||||
static_cast<uint8_t>(aEVStatus), aSucceeded, aFinalError,
|
||||
aCollectedErrors);
|
||||
aCollectedErrors, aIsBuiltCertChainRootBuiltInRoot);
|
||||
}),
|
||||
NS_DISPATCH_NORMAL);
|
||||
MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(nrv));
|
||||
|
|
|
@ -44,7 +44,8 @@ class VerifySSLServerCertParent : public PVerifySSLServerCertParent {
|
|||
uint16_t aCertificateTransparencyStatus,
|
||||
uint8_t aEVStatus, bool aSucceeded,
|
||||
PRErrorCode aFinalError,
|
||||
uint32_t aCollectedErrors);
|
||||
uint32_t aCollectedErrors,
|
||||
bool aIsBuiltCertChainRootBuiltInRoot);
|
||||
|
||||
private:
|
||||
virtual ~VerifySSLServerCertParent();
|
||||
|
|
|
@ -1106,6 +1106,7 @@ static void RebuildVerifiedCertificateInformation(PRFileDesc* fd,
|
|||
CertificateTransparencyInfo certificateTransparencyInfo;
|
||||
UniqueCERTCertList builtChain;
|
||||
const bool saveIntermediates = false;
|
||||
bool isBuiltCertChainRootBuiltInRoot = false;
|
||||
mozilla::pkix::Result rv = certVerifier->VerifySSLServerCert(
|
||||
cert, mozilla::pkix::Now(), infoObject, infoObject->GetHostName(),
|
||||
builtChain, flags, maybePeerCertsBytes, stapledOCSPResponse,
|
||||
|
@ -1115,7 +1116,9 @@ static void RebuildVerifiedCertificateInformation(PRFileDesc* fd,
|
|||
nullptr, // key size telemetry
|
||||
nullptr, // SHA-1 telemetry
|
||||
nullptr, // pinning telemetry
|
||||
&certificateTransparencyInfo);
|
||||
&certificateTransparencyInfo,
|
||||
nullptr, // CRLite telemetry,
|
||||
&isBuiltCertChainRootBuiltInRoot);
|
||||
|
||||
if (rv != Success) {
|
||||
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
|
||||
|
@ -1141,6 +1144,8 @@ static void RebuildVerifiedCertificateInformation(PRFileDesc* fd,
|
|||
nsTArray<nsTArray<uint8_t>> certBytesArray =
|
||||
TransportSecurityInfo::CreateCertBytesArray(builtChain);
|
||||
infoObject->SetSucceededCertChain(std::move(certBytesArray));
|
||||
infoObject->SetIsBuiltCertChainRootBuiltInRoot(
|
||||
isBuiltCertChainRootBuiltInRoot);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1232,6 +1237,11 @@ static void RebuildCertificateInfoFromSSLTokenCache(
|
|||
aInfoObject->SetSucceededCertChain(
|
||||
std::move(*info.mSucceededCertChainBytes));
|
||||
}
|
||||
|
||||
if (info.mIsBuiltCertChainRootBuiltInRoot) {
|
||||
aInfoObject->SetIsBuiltCertChainRootBuiltInRoot(
|
||||
*info.mIsBuiltCertChainRootBuiltInRoot);
|
||||
}
|
||||
}
|
||||
|
||||
void HandshakeCallback(PRFileDesc* fd, void* client_data) {
|
||||
|
|
|
@ -1262,6 +1262,33 @@ void SetValidationOptionsCommon() {
|
|||
ctMode != CertVerifier::CertificateTransparencyMode::Disabled;
|
||||
PublicSSLState()->SetSignedCertTimestampsEnabled(sctsEnabled);
|
||||
PrivateSSLState()->SetSignedCertTimestampsEnabled(sctsEnabled);
|
||||
|
||||
CertVerifier::PinningMode pinningMode =
|
||||
static_cast<CertVerifier::PinningMode>(
|
||||
Preferences::GetInt("security.cert_pinning.enforcement_level",
|
||||
CertVerifier::pinningDisabled));
|
||||
if (pinningMode > CertVerifier::pinningEnforceTestMode) {
|
||||
pinningMode = CertVerifier::pinningDisabled;
|
||||
}
|
||||
PublicSSLState()->SetPinningMode(pinningMode);
|
||||
PrivateSSLState()->SetPinningMode(pinningMode);
|
||||
|
||||
BRNameMatchingPolicy::Mode nameMatchingMode =
|
||||
static_cast<BRNameMatchingPolicy::Mode>(Preferences::GetInt(
|
||||
"security.pki.name_matching_mode",
|
||||
static_cast<int32_t>(BRNameMatchingPolicy::Mode::DoNotEnforce)));
|
||||
switch (nameMatchingMode) {
|
||||
case BRNameMatchingPolicy::Mode::Enforce:
|
||||
case BRNameMatchingPolicy::Mode::EnforceAfter23August2015:
|
||||
case BRNameMatchingPolicy::Mode::EnforceAfter23August2016:
|
||||
case BRNameMatchingPolicy::Mode::DoNotEnforce:
|
||||
break;
|
||||
default:
|
||||
nameMatchingMode = BRNameMatchingPolicy::Mode::DoNotEnforce;
|
||||
break;
|
||||
}
|
||||
PublicSSLState()->SetNameMatchingMode(nameMatchingMode);
|
||||
PrivateSSLState()->SetNameMatchingMode(nameMatchingMode);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
@ -1383,14 +1410,6 @@ void nsNSSComponent::setValidationOptions(
|
|||
Telemetry::Accumulate(Telemetry::CERT_OCSP_REQUIRED, ocspRequired);
|
||||
}
|
||||
|
||||
CertVerifier::PinningMode pinningMode =
|
||||
static_cast<CertVerifier::PinningMode>(
|
||||
Preferences::GetInt("security.cert_pinning.enforcement_level",
|
||||
CertVerifier::pinningDisabled));
|
||||
if (pinningMode > CertVerifier::pinningEnforceTestMode) {
|
||||
pinningMode = CertVerifier::pinningDisabled;
|
||||
}
|
||||
|
||||
CertVerifier::SHA1Mode sha1Mode =
|
||||
static_cast<CertVerifier::SHA1Mode>(Preferences::GetInt(
|
||||
"security.pki.sha1_enforcement_level",
|
||||
|
@ -1412,21 +1431,6 @@ void nsNSSComponent::setValidationOptions(
|
|||
sha1Mode = CertVerifier::SHA1Mode::Forbidden;
|
||||
}
|
||||
|
||||
BRNameMatchingPolicy::Mode nameMatchingMode =
|
||||
static_cast<BRNameMatchingPolicy::Mode>(Preferences::GetInt(
|
||||
"security.pki.name_matching_mode",
|
||||
static_cast<int32_t>(BRNameMatchingPolicy::Mode::DoNotEnforce)));
|
||||
switch (nameMatchingMode) {
|
||||
case BRNameMatchingPolicy::Mode::Enforce:
|
||||
case BRNameMatchingPolicy::Mode::EnforceAfter23August2015:
|
||||
case BRNameMatchingPolicy::Mode::EnforceAfter23August2016:
|
||||
case BRNameMatchingPolicy::Mode::DoNotEnforce:
|
||||
break;
|
||||
default:
|
||||
nameMatchingMode = BRNameMatchingPolicy::Mode::DoNotEnforce;
|
||||
break;
|
||||
}
|
||||
|
||||
NetscapeStepUpPolicy netscapeStepUpPolicy =
|
||||
static_cast<NetscapeStepUpPolicy>(Preferences::GetUint(
|
||||
"security.pki.netscape_step_up_policy",
|
||||
|
@ -1476,8 +1480,9 @@ void nsNSSComponent::setValidationOptions(
|
|||
softTimeout, hardTimeout, proofOfLock);
|
||||
|
||||
mDefaultCertVerifier = new SharedCertVerifier(
|
||||
odc, osc, softTimeout, hardTimeout, certShortLifetimeInDays, pinningMode,
|
||||
sha1Mode, nameMatchingMode, netscapeStepUpPolicy, ctMode,
|
||||
odc, osc, softTimeout, hardTimeout, certShortLifetimeInDays,
|
||||
PublicSSLState()->PinningMode(), sha1Mode,
|
||||
PublicSSLState()->NameMatchingMode(), netscapeStepUpPolicy, ctMode,
|
||||
distrustedCAPolicy, crliteMode, mEnterpriseCerts);
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче