зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1794479 - Gather telemetry on the age of OCSP responses used to override CRLite. r=keeler
Defines the OCSP_AGE_AT_CRLITE_OVERRIDE histogram which records the age of an OCSP response, in hours, when CRLite says a certificate is revoked and OCSP says it's OK. Differential Revision: https://phabricator.services.mozilla.com/D158991
This commit is contained in:
Родитель
eb4bb28f8f
Коммит
59119c81d9
|
@ -845,9 +845,10 @@ Result NSSCertDBTrustDomain::CheckRevocationByOCSP(
|
|||
Result stapledOCSPResponseResult = Success;
|
||||
if (stapledOCSPResponse) {
|
||||
bool expired;
|
||||
uint32_t ageInHours;
|
||||
stapledOCSPResponseResult = VerifyAndMaybeCacheEncodedOCSPResponse(
|
||||
certID, time, maxOCSPLifetimeInDays, *stapledOCSPResponse,
|
||||
ResponseWasStapled, expired);
|
||||
ResponseWasStapled, expired, ageInHours);
|
||||
Telemetry::AccumulateCategorical(
|
||||
Telemetry::LABELS_CERT_REVOCATION_MECHANISMS::StapledOCSP);
|
||||
if (stapledOCSPResponseResult == Success) {
|
||||
|
@ -1067,9 +1068,10 @@ Result NSSCertDBTrustDomain::SynchronousCheckRevocationWithServer(
|
|||
// or unknown certificate, PR_GetError() will return the appropriate error.
|
||||
// We actually ignore expired here.
|
||||
bool expired;
|
||||
rv = VerifyAndMaybeCacheEncodedOCSPResponse(certID, time,
|
||||
maxOCSPLifetimeInDays, response,
|
||||
ResponseIsFromNetwork, expired);
|
||||
uint32_t ageInHours;
|
||||
rv = VerifyAndMaybeCacheEncodedOCSPResponse(
|
||||
certID, time, maxOCSPLifetimeInDays, response, ResponseIsFromNetwork,
|
||||
expired, ageInHours);
|
||||
|
||||
// If the CRLite filter covers the certificate, compare the CRLite result
|
||||
// with the OCSP fetching result. OCSP may have succeeded, said the
|
||||
|
@ -1088,6 +1090,11 @@ Result NSSCertDBTrustDomain::SynchronousCheckRevocationWithServer(
|
|||
// CRLite says the certificate is revoked, but OCSP says it is OK.
|
||||
Telemetry::AccumulateCategorical(
|
||||
Telemetry::LABELS_CRLITE_VS_OCSP_RESULT::CRLiteRevOCSPOk);
|
||||
|
||||
if (mCRLiteMode == CRLiteMode::ConfirmRevocations) {
|
||||
Telemetry::Accumulate(Telemetry::OCSP_AGE_AT_CRLITE_OVERRIDE,
|
||||
ageInHours);
|
||||
}
|
||||
}
|
||||
} else if (rv == Result::ERROR_REVOKED_CERTIFICATE) {
|
||||
if (crliteResult == Success) {
|
||||
|
@ -1183,7 +1190,8 @@ Result NSSCertDBTrustDomain::HandleOCSPFailure(
|
|||
Result NSSCertDBTrustDomain::VerifyAndMaybeCacheEncodedOCSPResponse(
|
||||
const CertID& certID, Time time, uint16_t maxLifetimeInDays,
|
||||
Input encodedResponse, EncodedResponseSource responseSource,
|
||||
/*out*/ bool& expired) {
|
||||
/*out*/ bool& expired,
|
||||
/*out*/ uint32_t& ageInHours) {
|
||||
Time thisUpdate(Time::uninitialized);
|
||||
Time validThrough(Time::uninitialized);
|
||||
|
||||
|
@ -1207,6 +1215,30 @@ Result NSSCertDBTrustDomain::VerifyAndMaybeCacheEncodedOCSPResponse(
|
|||
return Result::FATAL_ERROR_LIBRARY_FAILURE; // integer overflow
|
||||
}
|
||||
}
|
||||
// The `thisUpdate` field holds the latest time at which the server knew the
|
||||
// response was correct. The age of the response is the time that has elapsed
|
||||
// since. We only use this for the telemetry defined in Bug 1794479.
|
||||
uint64_t timeInSeconds;
|
||||
uint64_t thisUpdateInSeconds;
|
||||
uint64_t ageInSeconds;
|
||||
SecondsSinceEpochFromTime(time, &timeInSeconds);
|
||||
SecondsSinceEpochFromTime(thisUpdate, &thisUpdateInSeconds);
|
||||
if (timeInSeconds >= thisUpdateInSeconds) {
|
||||
ageInSeconds = timeInSeconds - thisUpdateInSeconds;
|
||||
// ageInHours is 32 bits because of the telemetry api.
|
||||
if (ageInSeconds > UINT32_MAX) {
|
||||
// We could divide by 3600 before checking the UINT32_MAX bound, but if
|
||||
// ageInSeconds is more than UINT32_MAX then there's been some sort of
|
||||
// error.
|
||||
ageInHours = UINT32_MAX;
|
||||
} else {
|
||||
// We start at 1 and divide with truncation to reserve ageInHours=0 for
|
||||
// the case where `thisUpdate` is in the future.
|
||||
ageInHours = 1 + ageInSeconds / (60 * 60);
|
||||
}
|
||||
} else {
|
||||
ageInHours = 0;
|
||||
}
|
||||
if (responseSource == ResponseIsFromNetwork || rv == Success ||
|
||||
rv == Result::ERROR_REVOKED_CERTIFICATE ||
|
||||
rv == Result::ERROR_OCSP_UNKNOWN_CERT) {
|
||||
|
|
|
@ -264,7 +264,8 @@ class NSSCertDBTrustDomain : public mozilla::pkix::TrustDomain {
|
|||
Result VerifyAndMaybeCacheEncodedOCSPResponse(
|
||||
const mozilla::pkix::CertID& certID, mozilla::pkix::Time time,
|
||||
uint16_t maxLifetimeInDays, mozilla::pkix::Input encodedResponse,
|
||||
EncodedResponseSource responseSource, /*out*/ bool& expired);
|
||||
EncodedResponseSource responseSource, /*out*/ bool& expired,
|
||||
/*out*/ uint32_t& ageInHours);
|
||||
TimeDuration GetOCSPTimeout() const;
|
||||
|
||||
Result CheckRevocationByCRLite(const mozilla::pkix::CertID& certID,
|
||||
|
|
|
@ -3415,6 +3415,19 @@
|
|||
"n_values": 16,
|
||||
"description": "SSL Handshake Key Exchange Algorithm for resumed handshake (null=0, rsa=1, dh=2, fortezza=3, ecdh=4)"
|
||||
},
|
||||
"OCSP_AGE_AT_CRLITE_OVERRIDE": {
|
||||
"record_in_processes": ["main", "socket"],
|
||||
"products": ["firefox", "fennec"],
|
||||
"alert_emails": ["seceng-telemetry@mozilla.com", "jschanck@mozilla.com"],
|
||||
"bug_numbers": [1794479],
|
||||
"expires_in_version": "113",
|
||||
"kind": "linear",
|
||||
"releaseChannelCollection": "opt-out",
|
||||
"low": 1,
|
||||
"high": 240,
|
||||
"n_buckets": 20,
|
||||
"description": "When OCSP and CRLite differ, how old is the OCSP response (in hours)?"
|
||||
},
|
||||
"CRLITE_VS_OCSP_RESULT": {
|
||||
"record_in_processes": ["main", "socket"],
|
||||
"products": ["firefox", "fennec"],
|
||||
|
|
Загрузка…
Ссылка в новой задаче