--- a/security/manager/ssl/nsNSSCallbacks.cpp
+++ b/security/manager/ssl/nsNSSCallbacks.cpp
@@ -1062,19 +1062,20 @@ AccumulateCipherSuite(Telemetry::Histogr
// 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 if the peer's server certificate verified
// as extended validation or not. To address this, we attempt to build a
// verified EV certificate chain here using as much of the original context as
// possible (e.g. stapled OCSP responses, SCTs, the hostname, the first party
// domain, etc.). Note that because we are on the socket thread, this must not
// cause any network requests, hence the use of FLAG_LOCAL_ONLY.
+// Similarly, we need to determine the certificate's CT status.
static void
-DetermineEVStatusAndSetNewCert(RefPtr<nsSSLStatus> sslStatus, PRFileDesc* fd,
- nsNSSSocketInfo* infoObject)
+DetermineEVAndCTStatusAndSetNewCert(RefPtr<nsSSLStatus> sslStatus,
+ PRFileDesc* fd, nsNSSSocketInfo* infoObject)
{
MOZ_ASSERT(sslStatus);
MOZ_ASSERT(fd);
MOZ_ASSERT(infoObject);
if (!sslStatus || !fd || !infoObject) {
return;
}
@@ -1110,41 +1111,52 @@ DetermineEVStatusAndSetNewCert(RefPtr<ns
int flags = mozilla::psm::CertVerifier::FLAG_LOCAL_ONLY |
mozilla::psm::CertVerifier::FLAG_MUST_BE_EV;
if (!infoObject->SharedState().IsOCSPStaplingEnabled() ||
!infoObject->SharedState().IsOCSPMustStapleEnabled()) {
flags |= CertVerifier::FLAG_TLS_IGNORE_STATUS_REQUEST;
}
SECOidTag evOidPolicy;
+ CertificateTransparencyInfo certificateTransparencyInfo;
UniqueCERTCertList unusedBuiltChain;
const bool saveIntermediates = false;
mozilla::pkix::Result rv = certVerifier->VerifySSLServerCert(
cert,
stapledOCSPResponse,
sctsFromTLSExtension,
mozilla::pkix::Now(),
infoObject,
infoObject->GetHostNameRaw(),
unusedBuiltChain,
saveIntermediates,
flags,
infoObject->GetOriginAttributes(),
- &evOidPolicy);
+ &evOidPolicy,
+ nullptr, // OCSP stapling telemetry
+ nullptr, // key size telemetry
+ nullptr, // SHA-1 telemetry
+ nullptr, // pinning telemetry
+ &certificateTransparencyInfo);
RefPtr<nsNSSCertificate> nssc(nsNSSCertificate::Create(cert.get()));
if (rv == Success && evOidPolicy != SEC_OID_UNKNOWN) {
+ sslStatus->SetCertificateTransparencyInfo(certificateTransparencyInfo);
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
("HandshakeCallback using NEW cert %p (is EV)", nssc.get()));
sslStatus->SetServerCert(nssc, EVStatus::EV);
} else {
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
("HandshakeCallback using NEW cert %p (is not EV)", nssc.get()));
sslStatus->SetServerCert(nssc, EVStatus::NotEV);
}
+
+ if (rv == Success) {
+ sslStatus->SetCertificateTransparencyInfo(certificateTransparencyInfo);
+ }
}
void HandshakeCallback(PRFileDesc* fd, void* client_data) {
nsNSSShutDownPreventionLock locker;
SECStatus rv;
nsNSSSocketInfo* infoObject = (nsNSSSocketInfo*) fd->higher->secret;
@@ -1285,17 +1297,17 @@ void HandshakeCallback(PRFileDesc* fd, v
infoObject->GetPort());
}
}
if (status->HasServerCert()) {
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
("HandshakeCallback KEEPING existing cert\n"));
} else {
- DetermineEVStatusAndSetNewCert(status, fd, infoObject);
+ DetermineEVAndCTStatusAndSetNewCert(status, fd, infoObject);
}
bool domainMismatch;
bool untrusted;
bool notValidAtThisTime;
// These all return NS_OK, so don't even bother checking the return values.
Unused << status->GetIsDomainMismatch(&domainMismatch);
Unused << status->GetIsUntrusted(&untrusted);