Bug 1788290 - Record whether OCSP requests were made whilst making a TLS connection. r=keeler,necko-reviewers.

Differential Revision: https://phabricator.services.mozilla.com/D156105
This commit is contained in:
Dennis Jackson 2022-09-02 14:16:07 +00:00
parent ff2c027bd0
commit 0e389c049e
15 changed files with 155 additions and 38 deletions

View File

@ -80,6 +80,13 @@ interface nsITransportSecurityInfo : nsISupports {
[must_use]
readonly attribute nsITransportSecurityInfo_OverridableErrorCategory overridableErrorCategory;
/**
* True if OCSP requests were made to query the status of certificates
* used in this connection.
*/
[must_use]
readonly attribute boolean madeOCSPRequests;
/**
* True only if (and after) serverCert was successfully validated as
* Extended Validation (EV).

View File

@ -459,7 +459,8 @@ Result CertVerifier::VerifyCert(
/*optional out*/ KeySizeStatus* keySizeStatus,
/*optional out*/ PinningTelemetryInfo* pinningTelemetryInfo,
/*optional out*/ CertificateTransparencyInfo* ctInfo,
/*optional out*/ bool* isBuiltChainRootBuiltInRoot) {
/*optional out*/ bool* isBuiltChainRootBuiltInRoot,
/*optional out*/ bool* madeOCSPRequests) {
MOZ_LOG(gCertVerifierLog, LogLevel::Debug, ("Top of VerifyCert\n"));
MOZ_ASSERT(usage == certificateUsageSSLServer || !(flags & FLAG_MUST_BE_EV));
@ -497,6 +498,10 @@ Result CertVerifier::VerifyCert(
*isBuiltChainRootBuiltInRoot = false;
}
if (madeOCSPRequests) {
*madeOCSPRequests = false;
}
Input certDER;
Result rv = certDER.Init(certBytes.Elements(), certBytes.Length());
if (rv != Success) {
@ -547,6 +552,10 @@ Result CertVerifier::VerifyCert(
trustDomain, certDER, time, EndEntityOrCA::MustBeEndEntity,
KeyUsage::digitalSignature, KeyPurposeId::id_kp_clientAuth,
CertPolicyId::anyPolicy, stapledOCSPResponse);
if (madeOCSPRequests) {
*madeOCSPRequests |=
trustDomain.GetOCSPFetchStatus() == OCSPFetchStatus::Fetched;
}
break;
}
@ -579,6 +588,10 @@ Result CertVerifier::VerifyCert(
KeyUsage::keyAgreement, // (EC)DH
KeyPurposeId::id_kp_serverAuth, evPolicy, stapledOCSPResponse,
ocspStaplingStatus);
if (madeOCSPRequests) {
*madeOCSPRequests |=
trustDomain.GetOCSPFetchStatus() == OCSPFetchStatus::Fetched;
}
if (rv == Success) {
rv = VerifyCertificateTransparencyPolicy(
trustDomain, builtChain, sctsFromTLSInput, time, ctInfo);
@ -634,6 +647,10 @@ Result CertVerifier::VerifyCert(
KeyUsage::keyAgreement, //(EC)DH
KeyPurposeId::id_kp_serverAuth, CertPolicyId::anyPolicy,
stapledOCSPResponse, ocspStaplingStatus);
if (madeOCSPRequests) {
*madeOCSPRequests |=
trustDomain.GetOCSPFetchStatus() == OCSPFetchStatus::Fetched;
}
if (rv != Success && !IsFatalError(rv) &&
rv != Result::ERROR_REVOKED_CERTIFICATE &&
trustDomain.GetIsErrorDueToDistrustedCAPolicy()) {
@ -677,6 +694,10 @@ Result CertVerifier::VerifyCert(
rv = BuildCertChain(trustDomain, certDER, time, EndEntityOrCA::MustBeCA,
KeyUsage::keyCertSign, KeyPurposeId::id_kp_serverAuth,
CertPolicyId::anyPolicy, stapledOCSPResponse);
if (madeOCSPRequests) {
*madeOCSPRequests |=
trustDomain.GetOCSPFetchStatus() == OCSPFetchStatus::Fetched;
}
break;
}
@ -698,6 +719,10 @@ Result CertVerifier::VerifyCert(
KeyUsage::nonRepudiation, KeyPurposeId::id_kp_emailProtection,
CertPolicyId::anyPolicy, stapledOCSPResponse);
}
if (madeOCSPRequests) {
*madeOCSPRequests |=
trustDomain.GetOCSPFetchStatus() == OCSPFetchStatus::Fetched;
}
break;
}
@ -724,6 +749,10 @@ Result CertVerifier::VerifyCert(
KeyPurposeId::id_kp_emailProtection,
CertPolicyId::anyPolicy, stapledOCSPResponse);
}
if (madeOCSPRequests) {
*madeOCSPRequests |=
trustDomain.GetOCSPFetchStatus() == OCSPFetchStatus::Fetched;
}
break;
}
@ -785,7 +814,8 @@ Result CertVerifier::VerifySSLServerCert(
/*optional out*/ KeySizeStatus* keySizeStatus,
/*optional out*/ PinningTelemetryInfo* pinningTelemetryInfo,
/*optional out*/ CertificateTransparencyInfo* ctInfo,
/*optional out*/ bool* isBuiltChainRootBuiltInRoot) {
/*optional out*/ bool* isBuiltChainRootBuiltInRoot,
/*optional out*/ bool* madeOCSPRequests) {
// XXX: MOZ_ASSERT(pinarg);
MOZ_ASSERT(!hostname.IsEmpty());
@ -815,7 +845,7 @@ Result CertVerifier::VerifySSLServerCert(
extraCertificates, stapledOCSPResponse, sctsFromTLS,
originAttributes, evStatus, ocspStaplingStatus, keySizeStatus,
pinningTelemetryInfo, ctInfo,
&isBuiltChainRootBuiltInRootLocal);
&isBuiltChainRootBuiltInRootLocal, madeOCSPRequests);
if (rv != Success) {
// we don't use the certificate for path building, so this parameter doesn't
// matter

View File

@ -162,7 +162,8 @@ class CertVerifier {
/*optional out*/ KeySizeStatus* keySizeStatus = nullptr,
/*optional out*/ PinningTelemetryInfo* pinningTelemetryInfo = nullptr,
/*optional out*/ CertificateTransparencyInfo* ctInfo = nullptr,
/*optional out*/ bool* isBuiltChainRootBuiltInRoot = nullptr);
/*optional out*/ bool* isBuiltChainRootBuiltInRoot = nullptr,
/*optional out*/ bool* madeOCSPRequests = nullptr);
mozilla::pkix::Result VerifySSLServerCert(
const nsTArray<uint8_t>& peerCert, mozilla::pkix::Time time, void* pinarg,
@ -182,7 +183,8 @@ class CertVerifier {
/*optional out*/ KeySizeStatus* keySizeStatus = nullptr,
/*optional out*/ PinningTelemetryInfo* pinningTelemetryInfo = nullptr,
/*optional out*/ CertificateTransparencyInfo* ctInfo = nullptr,
/*optional out*/ bool* isBuiltChainRootBuiltInRoot = nullptr);
/*optional out*/ bool* isBuiltChainRootBuiltInRoot = nullptr,
/*optional out*/ bool* madeOCSPRequests = nullptr);
enum OcspDownloadConfig { ocspOff = 0, ocspOn = 1, ocspEVOnly = 2 };
enum OcspStrictConfig { ocspRelaxed = 0, ocspStrict };

View File

@ -103,7 +103,8 @@ NSSCertDBTrustDomain::NSSCertDBTrustDomain(
mOCSPStaplingStatus(CertVerifier::OCSP_STAPLING_NEVER_CHECKED),
mSCTListFromCertificate(),
mSCTListFromOCSPStapling(),
mBuiltInRootsModule(SECMOD_FindModule(kRootModuleName)) {}
mBuiltInRootsModule(SECMOD_FindModule(kRootModuleName)),
mOCSPFetchStatus(OCSPFetchStatus::NotFetched) {}
static void FindRootsWithSubject(UniqueSECMODModule& rootsModule,
SECItem subject,
@ -1012,6 +1013,7 @@ Result NSSCertDBTrustDomain::SynchronousCheckRevocationWithServer(
Vector<uint8_t> ocspResponse;
Input response;
mOCSPFetchStatus = OCSPFetchStatus::Fetched;
rv = DoOCSPRequest(aiaLocation, mOriginAttributes, ocspRequestBytes,
ocspRequestLength, GetOCSPTimeout(), ocspResponse);
if (rv == Success &&

View File

@ -49,6 +49,11 @@ enum class NetscapeStepUpPolicy : uint32_t {
NeverMatch = 3,
};
enum class OCSPFetchStatus : uint16_t {
NotFetched = 0,
Fetched = 1,
};
SECStatus InitializeNSS(const nsACString& dir, NSSDBConfig nssDbConfig,
PKCS11DBConfig pkcs11DbConfig);
@ -239,6 +244,8 @@ class NSSCertDBTrustDomain : public mozilla::pkix::TrustDomain {
bool GetIsErrorDueToDistrustedCAPolicy() const;
OCSPFetchStatus GetOCSPFetchStatus() { return mOCSPFetchStatus; }
private:
Result CheckCRLiteStash(
const nsTArray<uint8_t>& issuerSubjectPublicKeyInfoBytes,
@ -311,6 +318,8 @@ class NSSCertDBTrustDomain : public mozilla::pkix::TrustDomain {
// The built-in roots module, if available.
UniqueSECMODModule mBuiltInRootsModule;
OCSPFetchStatus mOCSPFetchStatus;
};
} // namespace psm

View File

@ -19,10 +19,10 @@ child:
async OnVerifiedSSLServerCertSuccess(ByteArray[] aBuiltCertChain,
uint16_t aCertTransparencyStatus,
uint8_t aEVStatus,
bool isBuiltCertChainRootBuiltInRoot);
bool isBuiltCertChainRootBuiltInRoot, bool aMadeOCSPRequests);
async OnVerifiedSSLServerCertFailure(int32_t aFinalError,
uint32_t aOverridableErrorCategory);
uint32_t aOverridableErrorCategory, bool aMadeOCSPRequests);
async __delete__();
};

View File

@ -594,7 +594,8 @@ Result AuthCertificate(
/*out*/ nsTArray<nsTArray<uint8_t>>& builtCertChain,
/*out*/ EVStatus& evStatus,
/*out*/ CertificateTransparencyInfo& certificateTransparencyInfo,
/*out*/ bool& aIsBuiltCertChainRootBuiltInRoot) {
/*out*/ bool& aIsBuiltCertChainRootBuiltInRoot,
/*out*/ bool& aMadeOCSPRequests) {
CertVerifier::OCSPStaplingStatus ocspStaplingStatus =
CertVerifier::OCSP_STAPLING_NEVER_CHECKED;
KeySizeStatus keySizeStatus = KeySizeStatus::NeverChecked;
@ -614,7 +615,8 @@ Result AuthCertificate(
Some(std::move(peerCertsBytes)), stapledOCSPResponse,
sctsFromTLSExtension, dcInfo, aOriginAttributes, &evStatus,
&ocspStaplingStatus, &keySizeStatus, &pinningTelemetryInfo,
&certificateTransparencyInfo, &aIsBuiltCertChainRootBuiltInRoot);
&certificateTransparencyInfo, &aIsBuiltCertChainRootBuiltInRoot,
&aMadeOCSPRequests);
CollectCertTelemetry(rv, evStatus, ocspStaplingStatus, keySizeStatus,
pinningTelemetryInfo, builtCertChain,
@ -761,13 +763,15 @@ SSLServerCertVerificationJob::Run() {
EVStatus evStatus;
CertificateTransparencyInfo certificateTransparencyInfo;
bool isCertChainRootBuiltInRoot = false;
bool madeOCSPRequests = false;
nsTArray<nsTArray<uint8_t>> builtChainBytesArray;
nsTArray<uint8_t> certBytes(mPeerCertChain.ElementAt(0).Clone());
Result rv = AuthCertificate(
*certVerifier, mPinArg, certBytes, mPeerCertChain, mHostName,
mOriginAttributes, mStapledOCSPResponse, mSCTsFromTLSExtension, mDCInfo,
mProviderFlags, mTime, mCertVerifierFlags, builtChainBytesArray, evStatus,
certificateTransparencyInfo, isCertChainRootBuiltInRoot);
certificateTransparencyInfo, isCertChainRootBuiltInRoot,
madeOCSPRequests);
if (rv == Success) {
Telemetry::AccumulateTimeDelta(
@ -781,7 +785,7 @@ SSLServerCertVerificationJob::Run() {
certificateTransparencyInfo),
evStatus, true, 0,
nsITransportSecurityInfo::OverridableErrorCategory::ERROR_UNSET,
isCertChainRootBuiltInRoot, mProviderFlags);
isCertChainRootBuiltInRoot, mProviderFlags, madeOCSPRequests);
return NS_OK;
}
@ -802,7 +806,7 @@ SSLServerCertVerificationJob::Run() {
std::move(builtChainBytesArray), std::move(mPeerCertChain),
nsITransportSecurityInfo::CERTIFICATE_TRANSPARENCY_NOT_APPLICABLE,
EVStatus::NotEV, false, finalError, overridableErrorCategory, false,
mProviderFlags);
mProviderFlags, madeOCSPRequests);
return NS_OK;
}
@ -1033,7 +1037,8 @@ void SSLServerCertVerificationResult::Dispatch(
bool aSucceeded, PRErrorCode aFinalError,
nsITransportSecurityInfo::OverridableErrorCategory
aOverridableErrorCategory,
bool aIsBuiltCertChainRootBuiltInRoot, uint32_t aProviderFlags) {
bool aIsBuiltCertChainRootBuiltInRoot, uint32_t aProviderFlags,
bool aMadeOCSPRequests) {
mBuiltChain = std::move(aBuiltChain);
mPeerCertChain = std::move(aPeerCertChain);
mCertificateTransparencyStatus = aCertificateTransparencyStatus;
@ -1043,6 +1048,7 @@ void SSLServerCertVerificationResult::Dispatch(
mOverridableErrorCategory = aOverridableErrorCategory;
mIsBuiltCertChainRootBuiltInRoot = aIsBuiltCertChainRootBuiltInRoot;
mProviderFlags = aProviderFlags;
mMadeOCSPRequests = aMadeOCSPRequests;
if (mSucceeded && mBuiltChain.IsEmpty()) {
MOZ_ASSERT_UNREACHABLE(
@ -1085,6 +1091,8 @@ SSLServerCertVerificationResult::Run() {
SaveIntermediateCerts(mBuiltChain);
}
mInfoObject->SetMadeOCSPRequest(mMadeOCSPRequests);
if (mSucceeded) {
// Certificate verification succeeded. Delete any potential record of
// certificate error bits.

View File

@ -52,7 +52,7 @@ class BaseSSLServerCertVerificationResult {
nsITransportSecurityInfo::OverridableErrorCategory
aOverridableErrorCategory,
bool aIsBuiltCertChainRootBuiltInRoot,
uint32_t aProviderFlags) = 0;
uint32_t aProviderFlags, bool aMadeOCSPRequests) = 0;
};
// Dispatched to the STS thread to notify the infoObject of the verification
@ -76,8 +76,8 @@ class SSLServerCertVerificationResult final
bool aSucceeded, PRErrorCode aFinalError,
nsITransportSecurityInfo::OverridableErrorCategory
aOverridableErrorCategory,
bool aIsBuiltCertChainRootBuiltInRoot,
uint32_t aProviderFlags) override;
bool aIsBuiltCertChainRootBuiltInRoot, uint32_t aProviderFlags,
bool aMadeOCSPRequests) override;
private:
~SSLServerCertVerificationResult() = default;
@ -92,6 +92,7 @@ class SSLServerCertVerificationResult final
nsITransportSecurityInfo::OverridableErrorCategory mOverridableErrorCategory;
bool mIsBuiltCertChainRootBuiltInRoot;
uint32_t mProviderFlags;
bool mMadeOCSPRequests;
};
class SSLServerCertVerificationJob : public Runnable {

View File

@ -54,6 +54,7 @@ TransportSecurityInfo::TransportSecurityInfo()
mSignatureSchemeName(),
mIsAcceptedEch(false),
mIsDelegatedCredential(false),
mMadeOCSPRequests(false),
mNPNCompleted(false),
mResumed(false),
mIsBuiltCertChainRootBuiltInRoot(false),
@ -205,7 +206,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("8").get());
rv = aStream->WriteWStringZ(NS_ConvertUTF8toUTF16("9").get());
if (NS_FAILED(rv)) {
return rv;
}
@ -292,6 +293,11 @@ TransportSecurityInfo::Write(nsIObjectOutputStream* aStream) {
return rv;
}
rv = aStream->WriteBoolean(mMadeOCSPRequests);
if (NS_FAILED(rv)) {
return rv;
}
return NS_OK;
}
@ -790,6 +796,15 @@ TransportSecurityInfo::Read(nsIObjectInputStream* aStream) {
}
}
if (serVersionParsedToInt >= 9) {
rv = aStream->ReadBoolean(&mMadeOCSPRequests);
CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv),
"Deserialization should not fail");
if (NS_FAILED(rv)) {
return rv;
}
}
return NS_OK;
}
@ -822,6 +837,7 @@ void TransportSecurityInfo::SerializeToIPC(IPC::MessageWriter* aWriter) {
WriteParam(aWriter, mIsBuiltCertChainRootBuiltInRoot);
WriteParam(aWriter, mIsAcceptedEch);
WriteParam(aWriter, mPeerId);
WriteParam(aWriter, mMadeOCSPRequests);
}
bool TransportSecurityInfo::DeserializeFromIPC(IPC::MessageReader* aReader) {
@ -848,7 +864,8 @@ bool TransportSecurityInfo::DeserializeFromIPC(IPC::MessageReader* aReader) {
!ReadParam(aReader, &mNPNCompleted) ||
!ReadParam(aReader, &mNegotiatedNPN) || !ReadParam(aReader, &mResumed) ||
!ReadParam(aReader, &mIsBuiltCertChainRootBuiltInRoot) ||
!ReadParam(aReader, &mIsAcceptedEch) || !ReadParam(aReader, &mPeerId)) {
!ReadParam(aReader, &mIsAcceptedEch) || !ReadParam(aReader, &mPeerId) ||
!ReadParam(aReader, &mMadeOCSPRequests)) {
return false;
}
@ -1179,6 +1196,14 @@ TransportSecurityInfo::GetCertificateTransparencyStatus(
return NS_OK;
}
NS_IMETHODIMP
TransportSecurityInfo::GetMadeOCSPRequests(bool* aMadeOCSPRequests) {
MutexAutoLock lock(mMutex);
*aMadeOCSPRequests = mMadeOCSPRequests;
return NS_OK;
}
// static
uint16_t TransportSecurityInfo::ConvertCertificateTransparencyInfoToStatus(
const mozilla::psm::CertificateTransparencyInfo& info) {

View File

@ -105,6 +105,11 @@ class TransportSecurityInfo : public nsITransportSecurityInfo,
mCertificateTransparencyStatus = aCertificateTransparencyStatus;
}
void SetMadeOCSPRequest(bool aMadeOCSPRequests) {
MutexAutoLock lock(mMutex);
mMadeOCSPRequests = aMadeOCSPRequests;
}
void SetResumed(bool aResumed);
Atomic<OverridableErrorCategory> mOverridableErrorCategory;
@ -134,6 +139,7 @@ class TransportSecurityInfo : public nsITransportSecurityInfo,
bool mIsAcceptedEch MOZ_GUARDED_BY(mMutex);
bool mIsDelegatedCredential MOZ_GUARDED_BY(mMutex);
bool mMadeOCSPRequests MOZ_GUARDED_BY(mMutex);
nsCOMPtr<nsIInterfaceRequestor> mCallbacks MOZ_GUARDED_BY(mMutex);
nsTArray<RefPtr<nsIX509Cert>> mSucceededCertChain MOZ_GUARDED_BY(mMutex);

View File

@ -28,7 +28,8 @@ VerifySSLServerCertChild::VerifySSLServerCertChild(
ipc::IPCResult VerifySSLServerCertChild::RecvOnVerifiedSSLServerCertSuccess(
nsTArray<ByteArray>&& aBuiltCertChain,
const uint16_t& aCertTransparencyStatus, const uint8_t& aEVStatus,
const bool& aIsBuiltCertChainRootBuiltInRoot) {
const bool& aIsBuiltCertChainRootBuiltInRoot,
const bool& aMadeOCSPRequests) {
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
("[%p] VerifySSLServerCertChild::RecvOnVerifiedSSLServerCertSuccess",
this));
@ -42,19 +43,20 @@ ipc::IPCResult VerifySSLServerCertChild::RecvOnVerifiedSSLServerCertSuccess(
std::move(certBytesArray), std::move(mPeerCertChain),
aCertTransparencyStatus, static_cast<EVStatus>(aEVStatus), true, 0,
nsITransportSecurityInfo::OverridableErrorCategory::ERROR_UNSET,
aIsBuiltCertChainRootBuiltInRoot, mProviderFlags);
aIsBuiltCertChainRootBuiltInRoot, mProviderFlags, aMadeOCSPRequests);
return IPC_OK();
}
ipc::IPCResult VerifySSLServerCertChild::RecvOnVerifiedSSLServerCertFailure(
const int32_t& aFinalError, const uint32_t& aOverridableErrorCategory) {
const int32_t& aFinalError, const uint32_t& aOverridableErrorCategory,
const bool& aMadeOCSPRequests) {
mResultTask->Dispatch(
nsTArray<nsTArray<uint8_t>>(), std::move(mPeerCertChain),
nsITransportSecurityInfo::CERTIFICATE_TRANSPARENCY_NOT_APPLICABLE,
EVStatus::NotEV, false, aFinalError,
static_cast<nsITransportSecurityInfo::OverridableErrorCategory>(
aOverridableErrorCategory),
false, mProviderFlags);
false, mProviderFlags, aMadeOCSPRequests);
return IPC_OK();
}

View File

@ -33,10 +33,12 @@ class VerifySSLServerCertChild : public PVerifySSLServerCertChild {
ipc::IPCResult RecvOnVerifiedSSLServerCertSuccess(
nsTArray<ByteArray>&& aBuiltCertChain,
const uint16_t& aCertTransparencyStatus, const uint8_t& aEVStatus,
const bool& aIsBuiltCertChainRootBuiltInRoot);
const bool& aIsBuiltCertChainRootBuiltInRoot,
const bool& aMadeOCSPRequests);
ipc::IPCResult RecvOnVerifiedSSLServerCertFailure(
const int32_t& aFinalError, const uint32_t& aOverridableErrorCategory);
const int32_t& aFinalError, const uint32_t& aOverridableErrorCategory,
const bool& aMadeOCSPRequests);
private:
~VerifySSLServerCertChild() = default;

View File

@ -32,7 +32,7 @@ void VerifySSLServerCertParent::OnVerifiedSSLServerCert(
const nsTArray<ByteArray>& aBuiltCertChain,
uint16_t aCertificateTransparencyStatus, uint8_t aEVStatus, bool aSucceeded,
PRErrorCode aFinalError, uint32_t aOverridableErrorCategory,
bool aIsBuiltCertChainRootBuiltInRoot) {
bool aIsBuiltCertChainRootBuiltInRoot, bool aMadeOCSPRequests) {
AssertIsOnBackgroundThread();
if (!CanSend()) {
@ -42,10 +42,10 @@ void VerifySSLServerCertParent::OnVerifiedSSLServerCert(
if (aSucceeded) {
Unused << SendOnVerifiedSSLServerCertSuccess(
aBuiltCertChain, aCertificateTransparencyStatus, aEVStatus,
aIsBuiltCertChainRootBuiltInRoot);
aIsBuiltCertChainRootBuiltInRoot, aMadeOCSPRequests);
} else {
Unused << SendOnVerifiedSSLServerCertFailure(aFinalError,
aOverridableErrorCategory);
Unused << SendOnVerifiedSSLServerCertFailure(
aFinalError, aOverridableErrorCategory, aMadeOCSPRequests);
}
Unused << Send__delete__(this);
}
@ -68,8 +68,8 @@ class IPCServerCertVerificationResult final
bool aSucceeded, PRErrorCode aFinalError,
nsITransportSecurityInfo::OverridableErrorCategory
aOverridableErrorCategory,
bool aIsBuiltCertChainRootBuiltInRoot,
uint32_t aProviderFlags) override;
bool aIsBuiltCertChainRootBuiltInRoot, uint32_t aProviderFlags,
bool aMadeOCSPRequests) override;
private:
~IPCServerCertVerificationResult() = default;
@ -85,7 +85,8 @@ void IPCServerCertVerificationResult::Dispatch(
bool aSucceeded, PRErrorCode aFinalError,
nsITransportSecurityInfo::OverridableErrorCategory
aOverridableErrorCategory,
bool aIsBuiltCertChainRootBuiltInRoot, uint32_t aProviderFlags) {
bool aIsBuiltCertChainRootBuiltInRoot, uint32_t aProviderFlags,
bool aMadeOCSPRequests) {
nsTArray<ByteArray> builtCertChain;
if (aSucceeded) {
for (auto& cert : aBuiltChain) {
@ -99,7 +100,7 @@ void IPCServerCertVerificationResult::Dispatch(
[parent(mParent), builtCertChain{std::move(builtCertChain)},
aCertificateTransparencyStatus, aEVStatus, aSucceeded, aFinalError,
aOverridableErrorCategory, aIsBuiltCertChainRootBuiltInRoot,
aProviderFlags]() {
aMadeOCSPRequests, aProviderFlags]() {
if (aSucceeded &&
!(aProviderFlags & nsISocketProvider::NO_PERMANENT_STORAGE)) {
nsTArray<nsTArray<uint8_t>> certBytesArray;
@ -114,7 +115,7 @@ void IPCServerCertVerificationResult::Dispatch(
builtCertChain, aCertificateTransparencyStatus,
static_cast<uint8_t>(aEVStatus), aSucceeded, aFinalError,
static_cast<uint32_t>(aOverridableErrorCategory),
aIsBuiltCertChainRootBuiltInRoot);
aIsBuiltCertChainRootBuiltInRoot, aMadeOCSPRequests);
}),
NS_DISPATCH_NORMAL);
MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(nrv));

View File

@ -44,7 +44,8 @@ class VerifySSLServerCertParent : public PVerifySSLServerCertParent {
uint8_t aEVStatus, bool aSucceeded,
PRErrorCode aFinalError,
uint32_t aOverridableErrorCategory,
bool aIsBuiltCertChainRootBuiltInRoot);
bool aIsBuiltCertChainRootBuiltInRoot,
bool aMadeOCSPRequests);
private:
virtual ~VerifySSLServerCertParent();

View File

@ -48,11 +48,25 @@ function run_test() {
function add_tests() {
add_connection_test(
"ocsp-stapling-none.example.com",
SEC_ERROR_OCSP_BAD_SIGNATURE
SEC_ERROR_OCSP_BAD_SIGNATURE,
function() {},
function(aTransportSecurityInfo) {
Assert.ok(
aTransportSecurityInfo.madeOCSPRequests,
"An OCSP Request should have been made."
);
}
);
add_connection_test(
"ocsp-stapling-none.example.com",
SEC_ERROR_OCSP_BAD_SIGNATURE
SEC_ERROR_OCSP_BAD_SIGNATURE,
function() {},
function(aTransportSecurityInfo) {
Assert.ok(
!aTransportSecurityInfo.madeOCSPRequests,
"An OCSP Request should not have been made."
);
}
);
add_test(function() {
equal(
@ -69,6 +83,13 @@ function add_tests() {
add_connection_test(
"ocsp-stapling-none.example.com",
SEC_ERROR_OCSP_MALFORMED_RESPONSE
SEC_ERROR_OCSP_MALFORMED_RESPONSE,
function() {},
function(aTransportSecurityInfo) {
Assert.ok(
aTransportSecurityInfo.madeOCSPRequests,
"An OCSP Request should have been made."
);
}
);
}