/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// Returns the number of embedded SCTs required to be present in a certificate. // For certificates with a lifetime of less than or equal to 180 days, only 2 // embedded SCTs are required. Otherwise 3 are required.
MOZ_RUNINIT const Duration ONE_HUNDRED_AND_EIGHTY_DAYS =
Duration(180 * Time::ONE_DAY_IN_SECONDS);
size_t GetRequiredEmbeddedSctsCount(Duration certLifetime) { // pkix::Duration doesn't define operator<=, hence phrasing this comparison // in an awkward way return ONE_HUNDRED_AND_EIGHTY_DAYS < certLifetime ? 3 : 2;
}
// Calculates the effective issuance time of connection's certificate using // the SCTs present on the connection (we can't rely on notBefore validity // field of the certificate since it can be backdated). // Used to determine whether to accept SCTs issued by past qualified logs. // The effective issuance time is defined as the earliest of all SCTs, // rather than the latest of embedded SCTs, in order to give CAs the benefit // of the doubt in the event a log is revoked in the midst of processing // a precertificate and issuing the certificate. // It is acceptable to ignore the origin of the SCTs because SCTs // delivered via OCSP/TLS extension will cover the full certificate, // which necessarily will exist only after the precertificate // has been logged and the actual certificate issued.
uint64_t GetEffectiveCertIssuanceTime(const VerifiedSCTList& verifiedScts) {
uint64_t result = UINT64_MAX; for (const VerifiedSCT& verifiedSct : verifiedScts) { if (verifiedSct.logState == CTLogState::Admissible) {
result = std::min(result, verifiedSct.sct.timestamp);
}
} return result;
}
// Checks if the log that issued the given SCT is "once or currently qualified" // (i.e. was qualified at the time of the certificate issuance). In addition, // makes sure the SCT is before the retirement timestamp. bool LogWasQualifiedForSct(const VerifiedSCT& verifiedSct,
uint64_t certIssuanceTime) { switch (verifiedSct.logState) { case CTLogState::Admissible: returntrue; case CTLogState::Retired: {
uint64_t logRetirementTime = verifiedSct.logTimestamp; return certIssuanceTime < logRetirementTime &&
verifiedSct.sct.timestamp < logRetirementTime;
}
}
MOZ_ASSERT_UNREACHABLE("verifiedSct.logState must be Admissible or Retired"); returnfalse;
}
// Qualification for embedded SCTs: // There must be at least one embedded SCT from a log that was Admissible (i.e. // Qualified, Usable, or ReadOnly) at the time of the check. // There must be at least N embedded SCTs from distinct logs that were // Admissible or Retired at the time of the check, where N depends on the // lifetime of the certificate. If the certificate lifetime is less than or // equal to 180 days, N is 2. Otherwise, N is 3. // Among these SCTs, at least two must be issued from distinct log operators.
CTPolicyCompliance EmbeddedSCTsCompliant(const VerifiedSCTList& verifiedScts,
uint64_t certIssuanceTime,
Duration certLifetime) {
size_t admissibleCount = 0;
size_t admissibleOrRetiredCount = 0;
std::set<CTLogOperatorId> logOperators;
std::set<Buffer> logIds; for (constauto& verifiedSct : verifiedScts) { if (verifiedSct.origin != SCTOrigin::Embedded) { continue;
} if (verifiedSct.logState != CTLogState::Admissible &&
!LogWasQualifiedForSct(verifiedSct, certIssuanceTime)) { continue;
} // Note that a single SCT can count for both the "from a log that was // admissible" case and the "from a log that was admissible or retired" // case. if (verifiedSct.logState == CTLogState::Admissible) {
admissibleCount++;
} if (LogWasQualifiedForSct(verifiedSct, certIssuanceTime)) {
admissibleOrRetiredCount++;
logIds.insert(verifiedSct.sct.logId);
}
logOperators.insert(verifiedSct.logOperatorId);
}
// Qualification for non-embedded SCTs (i.e. SCTs delivered via TLS handshake // or OCSP response): // There must be at least two SCTs from logs that were Admissible (i.e. // Qualified, Usable, or ReadOnly) at the time of the check. Among these SCTs, // at least two must be issued from distinct log operators.
CTPolicyCompliance NonEmbeddedSCTsCompliant( const VerifiedSCTList& verifiedScts) {
size_t admissibleCount = 0;
std::set<CTLogOperatorId> logOperators;
std::set<Buffer> logIds; for (constauto& verifiedSct : verifiedScts) { if (verifiedSct.origin == SCTOrigin::Embedded) { continue;
} if (verifiedSct.logState != CTLogState::Admissible) { continue;
}
admissibleCount++;
logIds.insert(verifiedSct.sct.logId);
logOperators.insert(verifiedSct.logOperatorId);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.