зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1546816 - Part 2: Change nsNSSCallback to prepare for moving cert verifications to the parent process if the socket process performs network access. r=keeler
Differential Revision: https://phabricator.services.mozilla.com/D28742 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
7eedf007fd
Коммит
4c2b903df4
|
@ -1013,6 +1013,12 @@ static void AccumulateCipherSuite(Telemetry::HistogramID probe,
|
|||
Telemetry::Accumulate(probe, value);
|
||||
}
|
||||
|
||||
void RebuildVerifiedCertificateInformationResults(
|
||||
nsNSSSocketInfo* aInfoObject, const UniqueCERTCertificate& aCert,
|
||||
UniqueCERTCertList& aBuiltChain,
|
||||
const CertificateTransparencyInfo& aCertificateTransparencyInfo,
|
||||
SECOidTag aEvOidPolicy, bool aSucceeded);
|
||||
|
||||
// In the case of session resumption, the AuthCertificate hook has been bypassed
|
||||
// (because we've previously successfully connected to our peer). That being the
|
||||
// case, we unfortunately don't know what the verified certificate chain was, if
|
||||
|
@ -1079,26 +1085,36 @@ static void RebuildVerifiedCertificateInformation(PRFileDesc* fd,
|
|||
nullptr, // pinning telemetry
|
||||
&certificateTransparencyInfo);
|
||||
|
||||
if (rv != Success) {
|
||||
RebuildVerifiedCertificateInformationResults(infoObject, cert, builtChain,
|
||||
certificateTransparencyInfo,
|
||||
evOidPolicy, rv == Success);
|
||||
}
|
||||
|
||||
void RebuildVerifiedCertificateInformationResults(
|
||||
nsNSSSocketInfo* aInfoObject, const UniqueCERTCertificate& aCert,
|
||||
UniqueCERTCertList& aBuiltChain,
|
||||
const CertificateTransparencyInfo& aCertificateTransparencyInfo,
|
||||
SECOidTag aEvOidPolicy, bool aSucceeded) {
|
||||
if (!aSucceeded) {
|
||||
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
|
||||
("HandshakeCallback: couldn't rebuild verified certificate info"));
|
||||
}
|
||||
|
||||
RefPtr<nsNSSCertificate> nssc(nsNSSCertificate::Create(cert.get()));
|
||||
if (rv == Success && evOidPolicy != SEC_OID_UNKNOWN) {
|
||||
infoObject->SetCertificateTransparencyInfo(certificateTransparencyInfo);
|
||||
RefPtr<nsNSSCertificate> nssc(nsNSSCertificate::Create(aCert.get()));
|
||||
if (aSucceeded && aEvOidPolicy != SEC_OID_UNKNOWN) {
|
||||
aInfoObject->SetCertificateTransparencyInfo(aCertificateTransparencyInfo);
|
||||
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
|
||||
("HandshakeCallback using NEW cert %p (is EV)", nssc.get()));
|
||||
infoObject->SetServerCert(nssc, EVStatus::EV);
|
||||
aInfoObject->SetServerCert(nssc, EVStatus::EV);
|
||||
} else {
|
||||
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
|
||||
("HandshakeCallback using NEW cert %p (is not EV)", nssc.get()));
|
||||
infoObject->SetServerCert(nssc, EVStatus::NotEV);
|
||||
aInfoObject->SetServerCert(nssc, EVStatus::NotEV);
|
||||
}
|
||||
|
||||
if (rv == Success) {
|
||||
infoObject->SetCertificateTransparencyInfo(certificateTransparencyInfo);
|
||||
infoObject->SetSucceededCertChain(std::move(builtChain));
|
||||
if (aSucceeded) {
|
||||
aInfoObject->SetCertificateTransparencyInfo(aCertificateTransparencyInfo);
|
||||
aInfoObject->SetSucceededCertChain(std::move(aBuiltChain));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1154,6 +1170,10 @@ static nsresult IsCertificateDistrustImminent(nsIX509CertList* aCertList,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void CallAfterRebuildVerifiedCertificateInformation(
|
||||
nsNSSSocketInfo* aInfoObject, uint32_t aCumulativeSecurityState,
|
||||
PRBool aSiteSupportsSafeRenego);
|
||||
|
||||
void HandshakeCallback(PRFileDesc* fd, void* client_data) {
|
||||
SECStatus rv;
|
||||
|
||||
|
@ -1294,48 +1314,42 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) {
|
|||
RebuildVerifiedCertificateInformation(fd, infoObject);
|
||||
}
|
||||
|
||||
CallAfterRebuildVerifiedCertificateInformation(infoObject, state,
|
||||
siteSupportsSafeRenego);
|
||||
}
|
||||
|
||||
void CallAfterRebuildVerifiedCertificateInformation(
|
||||
nsNSSSocketInfo* aInfoObject, uint32_t aCumulativeSecurityState,
|
||||
PRBool aSiteSupportsSafeRenego) {
|
||||
|
||||
nsCOMPtr<nsIX509CertList> succeededCertChain;
|
||||
// This always returns NS_OK, but the list could be empty. This is a
|
||||
// best-effort check for now. Bug 731478 will reduce the incidence of empty
|
||||
// succeeded cert chains through better caching.
|
||||
Unused << infoObject->GetSucceededCertChain(
|
||||
Unused << aInfoObject->GetSucceededCertChain(
|
||||
getter_AddRefs(succeededCertChain));
|
||||
bool distrustImminent;
|
||||
nsresult srv =
|
||||
IsCertificateDistrustImminent(succeededCertChain, distrustImminent);
|
||||
if (NS_SUCCEEDED(srv) && distrustImminent) {
|
||||
state |= nsIWebProgressListener::STATE_CERT_DISTRUST_IMMINENT;
|
||||
aCumulativeSecurityState |= nsIWebProgressListener::STATE_CERT_DISTRUST_IMMINENT;
|
||||
}
|
||||
|
||||
bool domainMismatch;
|
||||
bool untrusted;
|
||||
bool notValidAtThisTime;
|
||||
// These all return NS_OK, so don't even bother checking the return values.
|
||||
Unused << infoObject->GetIsDomainMismatch(&domainMismatch);
|
||||
Unused << infoObject->GetIsUntrusted(&untrusted);
|
||||
Unused << infoObject->GetIsNotValidAtThisTime(¬ValidAtThisTime);
|
||||
Unused << aInfoObject->GetIsDomainMismatch(&domainMismatch);
|
||||
Unused << aInfoObject->GetIsUntrusted(&untrusted);
|
||||
Unused << aInfoObject->GetIsNotValidAtThisTime(¬ValidAtThisTime);
|
||||
// If we're here, the TLS handshake has succeeded. Thus if any of these
|
||||
// booleans are true, the user has added an override for a certificate error.
|
||||
if (domainMismatch || untrusted || notValidAtThisTime) {
|
||||
state |= nsIWebProgressListener::STATE_CERT_USER_OVERRIDDEN;
|
||||
aCumulativeSecurityState |= nsIWebProgressListener::STATE_CERT_USER_OVERRIDDEN;
|
||||
}
|
||||
|
||||
infoObject->SetSecurityState(state);
|
||||
aInfoObject->SetSecurityState(aCumulativeSecurityState);
|
||||
|
||||
// XXX Bug 883674: We shouldn't be formatting messages here in PSM; instead,
|
||||
// we should set a flag on the channel that higher (UI) level code can check
|
||||
// to log the warning. In particular, these warnings should go to the web
|
||||
// console instead of to the error console. Also, the warning is not
|
||||
// localized.
|
||||
if (!siteSupportsSafeRenego) {
|
||||
NS_ConvertASCIItoUTF16 msg(infoObject->GetHostName());
|
||||
msg.AppendLiteral(" : server does not support RFC 5746, see CVE-2009-3555");
|
||||
|
||||
nsContentUtils::LogSimpleConsoleError(
|
||||
msg, "SSL", !!infoObject->GetOriginAttributes().mPrivateBrowsingId,
|
||||
true /* from chrome context */);
|
||||
}
|
||||
|
||||
infoObject->NoteTimeUntilReady();
|
||||
infoObject->SetHandshakeCompleted();
|
||||
aInfoObject->NoteTimeUntilReady();
|
||||
aInfoObject->SetHandshakeCompleted();
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче