зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset 25bb41b1999f (bug 1911005) for causing build bustage in CTPolicyEnforcer.cpp CLOSED TREE
This commit is contained in:
Родитель
692aabd2cf
Коммит
12f78bd3c2
|
@ -257,10 +257,11 @@ void CertVerifier::LoadKnownCTLogs() {
|
|||
continue;
|
||||
}
|
||||
|
||||
CTLogVerifier logVerifier;
|
||||
const CTLogOperatorInfo& logOperator =
|
||||
kCTLogOperatorList[log.operatorIndex];
|
||||
CTLogVerifier logVerifier(logOperator.id, log.state, log.timestamp);
|
||||
rv = logVerifier.Init(publicKey);
|
||||
rv = logVerifier.Init(publicKey, logOperator.id, log.status,
|
||||
log.disqualificationTime);
|
||||
if (rv != Success) {
|
||||
MOZ_ASSERT_UNREACHABLE("Failed initializing a known CT Log");
|
||||
continue;
|
||||
|
@ -363,25 +364,40 @@ Result CertVerifier::VerifyCertificateTransparencyPolicy(
|
|||
|
||||
if (MOZ_LOG_TEST(gCertVerifierLog, LogLevel::Debug)) {
|
||||
size_t validCount = 0;
|
||||
size_t retiredLogCount = 0;
|
||||
size_t unknownLogCount = 0;
|
||||
size_t disqualifiedLogCount = 0;
|
||||
size_t invalidSignatureCount = 0;
|
||||
size_t invalidTimestampCount = 0;
|
||||
for (const VerifiedSCT& verifiedSct : result.verifiedScts) {
|
||||
switch (verifiedSct.logState) {
|
||||
case CTLogState::Admissible:
|
||||
switch (verifiedSct.status) {
|
||||
case VerifiedSCT::Status::Valid:
|
||||
validCount++;
|
||||
break;
|
||||
case CTLogState::Retired:
|
||||
retiredLogCount++;
|
||||
case VerifiedSCT::Status::ValidFromDisqualifiedLog:
|
||||
disqualifiedLogCount++;
|
||||
break;
|
||||
case VerifiedSCT::Status::UnknownLog:
|
||||
unknownLogCount++;
|
||||
break;
|
||||
case VerifiedSCT::Status::InvalidSignature:
|
||||
invalidSignatureCount++;
|
||||
break;
|
||||
case VerifiedSCT::Status::InvalidTimestamp:
|
||||
invalidTimestampCount++;
|
||||
break;
|
||||
case VerifiedSCT::Status::None:
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Unexpected SCT verification status");
|
||||
}
|
||||
}
|
||||
MOZ_LOG(gCertVerifierLog, LogLevel::Debug,
|
||||
("SCT verification result: "
|
||||
"valid=%zu unknownLog=%zu retiredLog=%zu "
|
||||
"invalidSignature=%zu invalidTimestamp=%zu "
|
||||
"decodingErrors=%zu\n",
|
||||
validCount, result.sctsFromUnknownLogs, retiredLogCount,
|
||||
result.sctsWithInvalidSignatures, result.sctsWithInvalidTimestamps,
|
||||
result.decodingErrors));
|
||||
MOZ_LOG(
|
||||
gCertVerifierLog, LogLevel::Debug,
|
||||
("SCT verification result: "
|
||||
"valid=%zu unknownLog=%zu disqualifiedLog=%zu "
|
||||
"invalidSignature=%zu invalidTimestamp=%zu "
|
||||
"decodingErrors=%zu\n",
|
||||
validCount, unknownLogCount, disqualifiedLogCount,
|
||||
invalidSignatureCount, invalidTimestampCount, result.decodingErrors));
|
||||
}
|
||||
|
||||
BackCert endEntityBackCert(endEntityInput, EndEntityOrCA::MustBeEndEntity,
|
||||
|
|
|
@ -14,21 +14,16 @@
|
|||
|
||||
#include <stddef.h>
|
||||
|
||||
static const PRTime kCTExpirationTime = INT64_C(1729883443000000);
|
||||
|
||||
namespace mozilla::ct {
|
||||
|
||||
enum class CTLogState {
|
||||
Admissible, // Qualified, Usable, or ReadOnly
|
||||
Retired,
|
||||
};
|
||||
static const PRTime kCTExpirationTime = INT64_C(1729551936000000);
|
||||
|
||||
struct CTLogInfo {
|
||||
// See bug 1338873 about making these fields const.
|
||||
const char* name;
|
||||
CTLogState state;
|
||||
uint64_t timestamp;
|
||||
// Index within kCTLogOperatorList.
|
||||
mozilla::ct::CTLogStatus status;
|
||||
// 0 for qualified logs, disqualification time for disqualified logs
|
||||
// (in milliseconds, measured since the epoch, ignoring leap seconds).
|
||||
uint64_t disqualificationTime;
|
||||
size_t operatorIndex;
|
||||
const char* key;
|
||||
size_t keyLength;
|
||||
|
@ -41,9 +36,9 @@ struct CTLogOperatorInfo {
|
|||
};
|
||||
|
||||
const CTLogInfo kCTLogList[] = {
|
||||
{"Google 'Argon2024' log", CTLogState::Admissible,
|
||||
1667328840000, // 2022-11-01T18:54:00Z
|
||||
0, // operated by Google
|
||||
{"Google 'Argon2024' log", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
0, // operated by Google
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x1d\xb9\x6c\xa9\xcb\x69\x94\xc5\x5c"
|
||||
"\xe6\xb6\xa6\x03\xbb\xd2\xb8\xdc\x54\x43\x17\x28\x99\x0c\x06\x01\x50\x1d"
|
||||
|
@ -51,9 +46,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\xed\x04\xfb\xe5\x57\xba\x26\x04\xf6\x11\x52\xce\x14\x65\x3b\x2f\x76\x2b"
|
||||
"\xc0",
|
||||
91},
|
||||
{"Google 'Argon2025h1' log", CTLogState::Admissible,
|
||||
1701000000000, // 2023-11-26T12:00:00Z
|
||||
0, // operated by Google
|
||||
{"Google 'Argon2025h1' log", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
0, // operated by Google
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x20\x82\xa1\xf9\x67\x68\xa8\xe4\xdb"
|
||||
"\x94\x98\xe2\xe1\x68\x87\xe4\x09\x6d\x20\x35\x33\x38\x3c\xaf\x14\xaa\xd7"
|
||||
|
@ -61,9 +56,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\xfb\xae\xbe\xc8\x23\x52\x20\x2b\xaa\x44\x05\xfe\x54\xf9\xd5\xf1\x1d\x45"
|
||||
"\x9a",
|
||||
91},
|
||||
{"Google 'Argon2025h2' log", CTLogState::Admissible,
|
||||
1701000000000, // 2023-11-26T12:00:00Z
|
||||
0, // operated by Google
|
||||
{"Google 'Argon2025h2' log", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
0, // operated by Google
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xaf\xe4\xf3\x94\x2c\xdf\xa6\x27\xb5"
|
||||
"\xfe\xb2\x61\x83\x19\xc8\x21\x3a\x23\xa8\xa9\x3d\x54\xaf\xbc\x31\x9a\x1c"
|
||||
|
@ -71,9 +66,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\x56\x4e\x98\xe8\xaa\x26\x29\x36\x1e\x28\x60\x6f\xeb\x15\x6e\xf7\x7c\xd0"
|
||||
"\xba",
|
||||
91},
|
||||
{"Google 'Argon2026h1' log", CTLogState::Admissible,
|
||||
1721666666000, // 2024-07-22T16:44:26Z
|
||||
0, // operated by Google
|
||||
{"Google 'Argon2026h1' log", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
0, // operated by Google
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x07\xfc\x1e\xe8\x63\x8e\xff\x1c\x31"
|
||||
"\x8a\xfc\xb8\x1e\x19\x2b\x60\x50\x00\x3e\x8e\x9e\xda\x77\x37\xe3\xa5\xa8"
|
||||
|
@ -81,9 +76,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\x06\x4f\x64\x58\x75\x14\x5d\x56\x52\xe6\x6a\x2b\x14\x4c\xec\x81\xd1\xea"
|
||||
"\x3e",
|
||||
91},
|
||||
{"Google 'Argon2026h2' log", CTLogState::Admissible,
|
||||
1721666666000, // 2024-07-22T16:44:26Z
|
||||
0, // operated by Google
|
||||
{"Google 'Argon2026h2' log", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
0, // operated by Google
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x2a\x3a\x67\x8b\xfe\xba\x0c\x86\x2b"
|
||||
"\x4a\x51\x8a\xe9\x17\xfe\x7b\xa1\x76\x73\xfd\xbc\x65\x4b\xc3\x27\xbf\x4d"
|
||||
|
@ -91,9 +86,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\xf5\x35\x50\x9c\xa1\xd3\x49\x4d\x13\xd5\x3b\x6a\x0e\xea\x45\x9d\x24\x13"
|
||||
"\x22",
|
||||
91},
|
||||
{"Google 'Xenon2024' log", CTLogState::Admissible,
|
||||
1667328840000, // 2022-11-01T18:54:00Z
|
||||
0, // operated by Google
|
||||
{"Google 'Xenon2024' log", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
0, // operated by Google
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xb9\x60\xe0\x34\x1e\x35\xe4\x65\x00"
|
||||
"\x93\x4f\x90\x09\xbd\x5a\xec\x44\xdd\x8c\x0f\xce\xed\x11\x3e\x2a\x59\x46"
|
||||
|
@ -101,9 +96,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\xba\xbb\xf2\x54\xe2\xa8\x0c\x83\x08\x51\x06\xde\x21\x6d\x36\x50\x8e\x38"
|
||||
"\x4d",
|
||||
91},
|
||||
{"Google 'Xenon2025h1' log", CTLogState::Admissible,
|
||||
1701000000000, // 2023-11-26T12:00:00Z
|
||||
0, // operated by Google
|
||||
{"Google 'Xenon2025h1' log", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
0, // operated by Google
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x82\xe2\xce\x90\x40\x3f\x81\x0e\xdf"
|
||||
"\xea\xe1\x20\x2b\x5e\x2e\x30\x54\x46\x81\xb9\x58\xed\xaf\xbd\xff\x36\xa7"
|
||||
|
@ -111,9 +106,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\x12\xe6\x54\x78\x50\xdc\xff\x6d\xfd\x1c\xa7\xb6\x3a\x1f\xf9\x26\xa9\x1b"
|
||||
"\xbd",
|
||||
91},
|
||||
{"Google 'Xenon2025h2' log", CTLogState::Admissible,
|
||||
1701000000000, // 2023-11-26T12:00:00Z
|
||||
0, // operated by Google
|
||||
{"Google 'Xenon2025h2' log", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
0, // operated by Google
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x6b\xe0\xaf\xed\x06\x7c\x3d\xef\xd9"
|
||||
"\x0e\xe4\x58\x4b\x04\xd8\x2a\x47\x99\x90\x89\x7a\xb9\x36\xa5\x75\xc8\x04"
|
||||
|
@ -121,9 +116,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\xa0\x3e\x9d\x94\x1c\xb2\xb7\x4a\xf2\x51\xec\x40\xed\x62\x47\xa4\x03\x49"
|
||||
"\x86",
|
||||
91},
|
||||
{"Google 'Xenon2026h1' log", CTLogState::Admissible,
|
||||
1721666666000, // 2024-07-22T16:44:26Z
|
||||
0, // operated by Google
|
||||
{"Google 'Xenon2026h1' log", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
0, // operated by Google
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x3a\x1f\xc8\xbb\xce\xd5\x90\x47\x34"
|
||||
"\xca\xca\x01\x04\x27\x21\x1c\xe2\x29\x3d\x92\xbb\x91\x45\xc7\x5a\x3e\xa5"
|
||||
|
@ -131,9 +126,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\xeb\x03\x0a\x30\xcc\x63\x6c\xd9\x3c\xbe\xf5\x7b\x94\xba\x94\xd3\xbf\x88"
|
||||
"\x4c",
|
||||
91},
|
||||
{"Google 'Xenon2026h2' log", CTLogState::Admissible,
|
||||
1721666666000, // 2024-07-22T16:44:26Z
|
||||
0, // operated by Google
|
||||
{"Google 'Xenon2026h2' log", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
0, // operated by Google
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xe5\x77\x78\x95\x71\x28\xb3\x95\xc9"
|
||||
"\xa5\xcc\x7a\x4c\xe8\x32\x03\x96\x7b\xfc\x2e\x1d\xb9\xa4\xdb\x43\xa0\xbd"
|
||||
|
@ -141,9 +136,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\x8a\x72\x30\x65\x86\x43\x53\xdc\x11\x44\x18\x49\x98\x25\x68\xa7\x3c\x05"
|
||||
"\xbf",
|
||||
91},
|
||||
{"Cloudflare 'Nimbus2024' Log", CTLogState::Admissible,
|
||||
1669827600000, // 2022-11-30T17:00:00Z
|
||||
1, // operated by Cloudflare
|
||||
{"Cloudflare 'Nimbus2024' Log", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
1, // operated by Cloudflare
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x77\xb1\x9b\x7b\x8f\xe6\x8b\x35\xfe"
|
||||
"\x3a\x92\x29\x2d\xac\x8a\x8d\x51\x8a\x25\xfc\x93\xb6\xd7\xa0\x8b\x29\x37"
|
||||
|
@ -151,9 +146,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\xf6\x9e\x94\x25\xdd\x36\x81\xd1\xeb\x5d\x29\xc3\x2b\x44\xf1\x5b\xca\x15"
|
||||
"\x48",
|
||||
91},
|
||||
{"Cloudflare 'Nimbus2025'", CTLogState::Admissible,
|
||||
1702969200000, // 2023-12-19T07:00:00Z
|
||||
1, // operated by Cloudflare
|
||||
{"Cloudflare 'Nimbus2025'", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
1, // operated by Cloudflare
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x1a\x80\x1a\x15\x19\x19\x23\x79\xb4"
|
||||
"\xfa\xa0\x79\x8e\x8d\xd5\xc1\xdc\xc2\xb5\x96\x92\x7e\x94\xe0\xc3\x7e\x14"
|
||||
|
@ -161,9 +156,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\x81\x5b\x4a\x14\x41\xec\xaf\xa9\x5d\x0e\xab\x12\x19\x71\xcd\x43\xef\xbb"
|
||||
"\x97",
|
||||
91},
|
||||
{"DigiCert Yeti2024 Log", CTLogState::Admissible,
|
||||
1667328840000, // 2022-11-01T18:54:00Z
|
||||
2, // operated by DigiCert
|
||||
{"DigiCert Yeti2024 Log", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
2, // operated by DigiCert
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x57\xb8\xc1\x6f\x30\xa4\x7f\x2e\xe4"
|
||||
"\xf0\xd0\xd9\x60\x62\x13\x95\xe3\x7a\xe3\x4e\x53\xc3\xb3\xb8\x73\x85\xc1"
|
||||
|
@ -171,9 +166,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\x1b\x19\x44\x58\xb7\x00\x77\x60\x20\x1a\x72\xd8\x82\xde\xae\x9e\xb1\xc6"
|
||||
"\x4b",
|
||||
91},
|
||||
{"DigiCert Yeti2025 Log", CTLogState::Admissible,
|
||||
1667328840000, // 2022-11-01T18:54:00Z
|
||||
2, // operated by DigiCert
|
||||
{"DigiCert Yeti2025 Log", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
2, // operated by DigiCert
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xdf\x95\x00\x5e\x10\xc1\x01\xf7\x37"
|
||||
"\xe3\x10\x74\xd1\xff\xb2\xca\x90\xed\x32\x99\x5f\x0c\x39\xfe\xa1\xd1\x13"
|
||||
|
@ -181,9 +176,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\x95\x24\x7c\xd8\x91\x98\x48\x3b\xf0\xf0\xdf\x21\xf1\xb0\x81\x5a\x59\x25"
|
||||
"\x43",
|
||||
91},
|
||||
{"DigiCert Nessie2024 Log", CTLogState::Retired,
|
||||
1685404800000, // 2023-05-30T00:00:00Z
|
||||
2, // operated by DigiCert
|
||||
{"DigiCert Nessie2024 Log", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
2, // operated by DigiCert
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x2d\xfc\xa2\x7b\x36\xbf\x56\x91\xe9"
|
||||
"\xfe\x3f\xe8\x3d\xfc\xc3\xa7\xe0\x61\x52\xea\x2c\xe9\x05\xa3\x9f\x27\x17"
|
||||
|
@ -191,9 +186,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\x21\xfc\x41\x54\x84\xa3\x54\xd5\x2e\xb2\x7a\x16\x4b\x2a\x1f\x2b\x66\x04"
|
||||
"\x2b",
|
||||
91},
|
||||
{"DigiCert Nessie2025 Log", CTLogState::Admissible,
|
||||
1667328840000, // 2022-11-01T18:54:00Z
|
||||
2, // operated by DigiCert
|
||||
{"DigiCert Nessie2025 Log", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
2, // operated by DigiCert
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xf2\xf0\xf0\xa7\x8b\x81\x2e\x09\x39"
|
||||
"\x3b\x9f\x42\xda\x38\x44\x5f\xb4\xcc\xed\x36\xbb\xd8\x43\x7f\x16\x49\x57"
|
||||
|
@ -201,9 +196,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\x75\x80\xb7\x53\xa7\x85\xd5\xbc\xab\x47\x06\x55\xdb\xb5\xdf\x88\xa1\x6f"
|
||||
"\x38",
|
||||
91},
|
||||
{"DigiCert 'Wyvern2024h1' Log", CTLogState::Admissible,
|
||||
1718500000000, // 2024-06-16T01:06:40Z
|
||||
2, // operated by DigiCert
|
||||
{"DigiCert 'Wyvern2024h1' Log", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
2, // operated by DigiCert
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x68\xa6\x79\x14\xd1\x58\xe7\xab\xaa"
|
||||
"\x29\x69\x7f\x60\xed\x68\xe8\x10\xf6\x07\x84\xc0\xfb\x59\x04\x5a\x09\xc9"
|
||||
|
@ -211,9 +206,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\x35\xc1\x8e\xfc\x9f\xb4\x20\x24\xd7\x15\xac\x87\xf7\x1e\xc1\x0b\x3c\x76"
|
||||
"\x1a",
|
||||
91},
|
||||
{"DigiCert 'Wyvern2024h2' Log", CTLogState::Admissible,
|
||||
1718500000000, // 2024-06-16T01:06:40Z
|
||||
2, // operated by DigiCert
|
||||
{"DigiCert 'Wyvern2024h2' Log", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
2, // operated by DigiCert
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xa8\x73\x12\x9c\x54\xd0\x7a\x7d\xc5"
|
||||
"\xb5\x17\x2b\x71\x52\x89\x04\x90\xbb\x42\xf1\x9d\xf8\x1c\xde\x4c\xcf\x82"
|
||||
|
@ -221,9 +216,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\x98\x84\xce\x1c\xbe\xcf\x4f\x7a\xef\x15\xfa\xd0\xee\xed\xed\x07\xad\x71"
|
||||
"\x6d",
|
||||
91},
|
||||
{"DigiCert 'Wyvern2025h1' Log", CTLogState::Admissible,
|
||||
1718500000000, // 2024-06-16T01:06:40Z
|
||||
2, // operated by DigiCert
|
||||
{"DigiCert 'Wyvern2025h1' Log", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
2, // operated by DigiCert
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xa7\xcb\x80\x61\x86\x1b\x1f\xb5\xab"
|
||||
"\x2b\x20\x76\x59\x83\x66\x0e\xce\xae\xb8\x6f\x3b\x88\x02\xeb\x43\xf4\x87"
|
||||
|
@ -231,9 +226,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\x0d\x96\x58\x44\x9d\x3b\x8a\x80\xc5\xc8\xbe\xe1\x89\x46\x6b\x48\x4c\xd6"
|
||||
"\x09",
|
||||
91},
|
||||
{"DigiCert 'Wyvern2025h2' Log", CTLogState::Admissible,
|
||||
1718500000000, // 2024-06-16T01:06:40Z
|
||||
2, // operated by DigiCert
|
||||
{"DigiCert 'Wyvern2025h2' Log", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
2, // operated by DigiCert
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xe0\xdb\x41\xef\xe4\x04\xbd\xcb\x6b"
|
||||
"\x2e\x4c\xcc\xf1\x6c\xde\x41\x58\x7f\xfe\x94\xf6\x7a\xf6\x60\xed\x8b\x76"
|
||||
|
@ -241,9 +236,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\x1c\x63\xde\x95\xe2\x81\x69\x97\x8d\x1e\xa8\xb7\x66\x51\x25\x75\x4d\x78"
|
||||
"\x2e",
|
||||
91},
|
||||
{"DigiCert 'Sphinx2024h1' Log", CTLogState::Admissible,
|
||||
1718500000000, // 2024-06-16T01:06:40Z
|
||||
2, // operated by DigiCert
|
||||
{"DigiCert 'Sphinx2024h1' Log", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
2, // operated by DigiCert
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xc6\xe4\x29\x69\x98\xfe\x28\x92\x57"
|
||||
"\x12\x4d\x9e\xed\x0e\xe7\x32\xa2\xe6\x9c\x27\x78\xa4\x29\x7c\x99\xd5\xdb"
|
||||
|
@ -251,9 +246,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\x1d\xd8\x22\xa8\xd3\xeb\xc9\x22\x8e\x36\xfb\x4a\xb1\x70\x9c\x5d\xc1\xe8"
|
||||
"\x33",
|
||||
91},
|
||||
{"DigiCert 'Sphinx2024h2' Log", CTLogState::Admissible,
|
||||
1718500000000, // 2024-06-16T01:06:40Z
|
||||
2, // operated by DigiCert
|
||||
{"DigiCert 'Sphinx2024h2' Log", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
2, // operated by DigiCert
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xdb\x09\x41\x84\xe7\xd1\xf1\x5b\x25"
|
||||
"\x09\x7b\xe8\xc6\x98\x51\x5e\x29\x85\xfd\x81\xde\x89\xd7\xd0\x86\xa4\xb0"
|
||||
|
@ -261,9 +256,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\x3f\xd1\xe9\xd4\x09\x84\x81\xbe\xb6\xc1\xed\x1b\x17\xea\x26\x97\xba\xe9"
|
||||
"\x9a",
|
||||
91},
|
||||
{"DigiCert 'Sphinx2025h1' Log", CTLogState::Admissible,
|
||||
1718500000000, // 2024-06-16T01:06:40Z
|
||||
2, // operated by DigiCert
|
||||
{"DigiCert 'Sphinx2025h1' Log", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
2, // operated by DigiCert
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xe3\x2f\x1f\x4d\x89\x05\x75\x29\x78"
|
||||
"\xbb\x22\x3d\x07\x62\x51\x14\x70\x94\xe7\x3c\xea\xf5\xee\xae\xa6\x48\x9a"
|
||||
|
@ -271,9 +266,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\x45\x31\x17\xd3\x8d\xf2\xe7\xce\x18\x11\x58\x98\x2c\x60\x6f\x58\x20\x36"
|
||||
"\x6e",
|
||||
91},
|
||||
{"DigiCert 'Sphinx2025h2' Log", CTLogState::Admissible,
|
||||
1718500000000, // 2024-06-16T01:06:40Z
|
||||
2, // operated by DigiCert
|
||||
{"DigiCert 'Sphinx2025h2' Log", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
2, // operated by DigiCert
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x41\x8c\x50\x13\x54\xb1\x19\x05\xb7"
|
||||
"\x7f\x4a\x20\x6e\xa3\x75\x63\xca\x34\xf4\xcc\x74\xea\x32\x3b\xb6\x8b\x03"
|
||||
|
@ -281,9 +276,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\x1a\x27\x54\x85\x5d\xc1\x7b\x24\xa8\x34\xe3\xcd\x88\xce\xd4\x50\x1b\xbe"
|
||||
"\x69",
|
||||
91},
|
||||
{"Sectigo 'Sabre' CT log", CTLogState::Admissible,
|
||||
1715000000000, // 2024-05-06T12:53:20Z
|
||||
3, // operated by Sectigo
|
||||
{"Sectigo 'Sabre' CT log", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
3, // operated by Sectigo
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xf2\x6f\xd2\x89\x0f\x3f\xc5\xf8\x87"
|
||||
"\x1e\xab\x65\xb3\xd9\xbb\x17\x23\x8c\x06\x0e\x09\x55\x96\x3d\x0a\x08\xa2"
|
||||
|
@ -291,9 +286,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\xe1\x98\x80\xd0\xce\x24\x6d\x3e\x67\x9a\xe9\x37\x23\xce\x52\x93\x86\xda"
|
||||
"\x80",
|
||||
91},
|
||||
{"Sectigo 'Sabre2024h1'", CTLogState::Admissible,
|
||||
1701000000000, // 2023-11-26T12:00:00Z
|
||||
3, // operated by Sectigo
|
||||
{"Sectigo 'Sabre2024h1'", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
3, // operated by Sectigo
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x2c\x01\xf6\xce\x31\xbc\xaa\x14\x61"
|
||||
"\x51\xfe\x6b\x7a\x87\xae\xa6\xd3\x9b\xc7\x87\x2d\x0a\x5a\xc8\x4f\xb5\x54"
|
||||
|
@ -301,9 +296,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\x16\x1c\x70\x2e\xc8\xec\x53\x5a\x4c\x21\x4c\x7e\x27\x0b\x13\x14\x5e\xfc"
|
||||
"\x85",
|
||||
91},
|
||||
{"Sectigo 'Sabre2024h2'", CTLogState::Admissible,
|
||||
1701000000000, // 2023-11-26T12:00:00Z
|
||||
3, // operated by Sectigo
|
||||
{"Sectigo 'Sabre2024h2'", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
3, // operated by Sectigo
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x7a\x10\x4c\x8a\xe7\x22\x7b\x6d\x2a"
|
||||
"\xba\x8e\xfa\x6b\x4a\x81\xd5\x85\xae\x03\xef\xff\x4b\xfc\x4d\x53\x3d\xb7"
|
||||
|
@ -311,9 +306,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\xe1\x88\x37\xdf\xd4\xf3\x60\x65\xfc\xa0\x75\xf0\x20\x66\x8e\x4a\xcc\x19"
|
||||
"\xda",
|
||||
91},
|
||||
{"Sectigo 'Sabre2025h1'", CTLogState::Admissible,
|
||||
1701000000000, // 2023-11-26T12:00:00Z
|
||||
3, // operated by Sectigo
|
||||
{"Sectigo 'Sabre2025h1'", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
3, // operated by Sectigo
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x7e\x2f\x39\xf1\xe8\x23\x8e\xb3\x32"
|
||||
"\x04\xaf\x4d\x57\xf6\xdb\xc5\x74\xa4\x7a\x6d\x3b\x07\x51\x0c\x5a\xfb\x80"
|
||||
|
@ -321,9 +316,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\x41\xae\x70\xb3\x31\xa2\xe3\xfa\x3d\x5f\x2c\x5d\x04\xcd\xb4\x9d\x55\xab"
|
||||
"\x41",
|
||||
91},
|
||||
{"Sectigo 'Sabre2025h2'", CTLogState::Admissible,
|
||||
1701000000000, // 2023-11-26T12:00:00Z
|
||||
3, // operated by Sectigo
|
||||
{"Sectigo 'Sabre2025h2'", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
3, // operated by Sectigo
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x85\x13\x11\x2d\x7b\xf3\x93\x81\xe4"
|
||||
"\xb9\x7c\xd9\x64\x3b\xe7\xb5\x83\x99\x66\x79\x59\x47\x6a\x42\x5e\xd6\xbd"
|
||||
|
@ -331,9 +326,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\xaf\x89\x8b\xf5\x58\xd8\xba\xeb\x7b\x83\x52\xe9\xf4\xe0\xa5\xcd\xcd\x92"
|
||||
"\xcc",
|
||||
91},
|
||||
{"Sectigo 'Mammoth2024h1'", CTLogState::Retired,
|
||||
1706486400000, // 2024-01-29T00:00:00Z
|
||||
3, // operated by Sectigo
|
||||
{"Sectigo 'Mammoth2024h1'", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
3, // operated by Sectigo
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xa4\x59\x90\xf3\x71\x24\x24\xf7\xc3"
|
||||
"\x55\x27\x56\x9c\xa3\x59\x1e\xf7\xb7\x9f\xce\xab\x4e\x19\x66\x4d\xd0\x8a"
|
||||
|
@ -341,9 +336,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\x38\x54\x5a\xcf\x9f\x6b\x07\x90\xd0\x0e\x7e\x3d\x4c\x87\xb2\xe8\x3f\x07"
|
||||
"\xcc",
|
||||
91},
|
||||
{"Sectigo 'Mammoth2024h1b'", CTLogState::Admissible,
|
||||
1714320000000, // 2024-04-28T16:00:00Z
|
||||
3, // operated by Sectigo
|
||||
{"Sectigo 'Mammoth2024h1b'", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
3, // operated by Sectigo
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xa3\xd5\x07\x28\x7a\x04\x34\xae\xca"
|
||||
"\xbe\x80\x79\x4f\x3e\xf6\x41\xf4\x24\x04\xe1\xd6\x36\x5a\x1a\x09\xf2\xd1"
|
||||
|
@ -351,9 +346,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\x10\xe1\x8c\xec\xb2\x8a\x8c\xc8\xe7\xdd\xcd\xe2\x07\xf0\x4e\x16\x02\x57"
|
||||
"\x37",
|
||||
91},
|
||||
{"Sectigo 'Mammoth2024h2'", CTLogState::Admissible,
|
||||
1701000000000, // 2023-11-26T12:00:00Z
|
||||
3, // operated by Sectigo
|
||||
{"Sectigo 'Mammoth2024h2'", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
3, // operated by Sectigo
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x85\x66\x22\x24\x6e\xbe\x52\x62\x0a"
|
||||
"\xa0\xaf\xc3\x25\x1a\x36\x2e\xa7\x60\x89\xa2\x65\xbf\xa4\x5f\xbd\x85\x6a"
|
||||
|
@ -361,9 +356,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\x57\x8b\x63\x1a\x81\xc1\x41\x9d\x7d\xec\x01\x3a\xdb\xb9\xc1\x27\xf4\x65"
|
||||
"\x1e",
|
||||
91},
|
||||
{"Sectigo 'Mammoth2025h1'", CTLogState::Admissible,
|
||||
1701000000000, // 2023-11-26T12:00:00Z
|
||||
3, // operated by Sectigo
|
||||
{"Sectigo 'Mammoth2025h1'", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
3, // operated by Sectigo
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x13\x3c\x41\xb5\x30\x7d\x2e\x4a\xa1"
|
||||
"\xa8\x6b\xd2\xc5\x57\x6b\x98\xfe\x7e\xef\xd5\x21\xe2\xba\x5d\xb0\xba\x85"
|
||||
|
@ -371,9 +366,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\x9b\x4e\x72\x62\x4b\x3c\x0c\x32\xdd\x86\xfb\xeb\x3e\x66\xcd\x77\x58\x5b"
|
||||
"\xe5",
|
||||
91},
|
||||
{"Sectigo 'Mammoth2025h2'", CTLogState::Admissible,
|
||||
1701000000000, // 2023-11-26T12:00:00Z
|
||||
3, // operated by Sectigo
|
||||
{"Sectigo 'Mammoth2025h2'", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
3, // operated by Sectigo
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x88\xe2\xc7\xb3\xd7\x37\xa3\x91\xd7"
|
||||
"\xb3\xc5\xda\x07\x51\x04\x2b\x81\xed\xc2\x44\x3b\x75\xa0\xe6\x65\xe1\x4a"
|
||||
|
@ -381,49 +376,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\xb1\x15\x67\x66\xa0\x7c\x0b\x5b\x62\x7f\x6c\x9a\x6a\x30\x9b\x68\x02\x16"
|
||||
"\x6f",
|
||||
91},
|
||||
{"Sectigo 'Mammoth2026h1'", CTLogState::Admissible,
|
||||
1722312000000, // 2024-07-30T04:00:00Z
|
||||
3, // operated by Sectigo
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x9e\xcb\x0c\x8a\x51\xcc\x8a\xe2\x0b"
|
||||
"\xce\x85\xe6\xaf\x4d\x31\xdb\x1b\x6a\x4c\xfd\xb0\x79\x6b\x99\x97\xc0\x5d"
|
||||
"\xfb\x6e\x45\x50\x1d\x62\xaa\xc6\x9f\x9b\x6b\x05\x3d\xa2\xab\x2b\x5d\x88"
|
||||
"\x9b\x50\x28\xe2\x9e\x58\xa5\xa5\xfa\xf9\xe3\xfa\x15\x25\xe3\x14\x13\x32"
|
||||
"\xc4",
|
||||
91},
|
||||
{"Sectigo 'Mammoth2026h2'", CTLogState::Admissible,
|
||||
1722312000000, // 2024-07-30T04:00:00Z
|
||||
3, // operated by Sectigo
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xec\x83\x61\xf2\xd7\xb4\xbb\xe4\xe4"
|
||||
"\x3b\xeb\xc8\x63\x75\x98\xcf\x61\x90\x63\x14\x3d\x5f\x22\xdf\x74\xba\x50"
|
||||
"\xa7\x58\x9b\x69\x7d\xe6\x63\x89\x6d\xd9\xd7\x51\x84\x3f\xf8\x02\xd8\xc8"
|
||||
"\xff\xc2\x97\x71\xe5\x7e\x27\xf5\x72\xb1\x8f\x24\x27\x57\x0a\x0d\x74\xc0"
|
||||
"\xb6",
|
||||
91},
|
||||
{"Sectigo 'Sabre2026h1'", CTLogState::Admissible,
|
||||
1722312000000, // 2024-07-30T04:00:00Z
|
||||
3, // operated by Sectigo
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x84\x26\xbc\x36\xbd\xd8\x8d\x3c\x87"
|
||||
"\x9e\xe0\x10\xaf\xcd\x94\xd9\xd7\xb9\x51\x80\x34\x7e\xf7\x58\x5c\x73\xea"
|
||||
"\xeb\x09\x93\xb8\x10\x7b\x90\x9c\x7d\xc7\xcd\x96\x43\xed\x53\x6e\x95\x21"
|
||||
"\x46\x67\x51\xf0\xde\xb6\xc9\x9e\xaa\xe2\x80\x6d\xce\x25\x81\x34\xd7\x6a"
|
||||
"\x60",
|
||||
91},
|
||||
{"Sectigo 'Sabre2026h2'", CTLogState::Admissible,
|
||||
1722312000000, // 2024-07-30T04:00:00Z
|
||||
3, // operated by Sectigo
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xce\x35\xca\xec\x39\x07\x82\xda\x77"
|
||||
"\x27\x86\xe4\xf2\x7e\xc5\xdc\x38\xf2\x9b\xa9\xab\x8c\xa7\xc0\xed\x83\x1e"
|
||||
"\x3e\x6a\x1b\xc0\xf0\x95\x56\xba\x32\x33\x4c\x75\x7c\x09\x07\xe9\xe1\x3e"
|
||||
"\x65\x35\x63\xf0\x49\xbe\x72\xd1\xaa\x9d\xaf\x7d\x08\xc4\xb4\x8d\x59\x3d"
|
||||
"\x73",
|
||||
91},
|
||||
{"Let's Encrypt 'Oak2024H1' log", CTLogState::Admissible,
|
||||
1669827600000, // 2022-11-30T17:00:00Z
|
||||
4, // operated by Let's Encrypt
|
||||
{"Let's Encrypt 'Oak2024H1' log", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
4, // operated by Let's Encrypt
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x56\x43\xd7\x7e\x7b\xd4\x72\xb7\xba"
|
||||
"\xa9\x51\xbd\x36\x93\xb7\xe9\xb5\x92\x0f\xea\x5e\xb7\x45\xa3\x92\xfd\xc9"
|
||||
|
@ -431,9 +386,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\xe6\xeb\xa4\xe2\x7d\x24\x63\x9f\x46\xbf\x94\x73\x52\x8d\x96\xae\xa9\x26"
|
||||
"\xfd",
|
||||
91},
|
||||
{"Let's Encrypt 'Oak2024H2' log", CTLogState::Admissible,
|
||||
1669827600000, // 2022-11-30T17:00:00Z
|
||||
4, // operated by Let's Encrypt
|
||||
{"Let's Encrypt 'Oak2024H2' log", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
4, // operated by Let's Encrypt
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xd7\x73\xd6\x53\x47\xe9\xf3\xc9\xd5"
|
||||
"\x7c\x16\xc2\xd6\x8f\x70\x65\xfa\xf2\x51\x36\xa9\x13\x80\x2f\xed\xf9\x94"
|
||||
|
@ -441,9 +396,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\x71\xcb\xca\xbb\x9f\x9f\xf3\x5c\x2d\x1e\xa3\x81\x59\xaf\x92\xb3\x6d\x30"
|
||||
"\x68",
|
||||
91},
|
||||
{"Let's Encrypt 'Oak2025h1'", CTLogState::Admissible,
|
||||
1701000000000, // 2023-11-26T12:00:00Z
|
||||
4, // operated by Let's Encrypt
|
||||
{"Let's Encrypt 'Oak2025h1'", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
4, // operated by Let's Encrypt
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x29\xe0\x69\x53\xd7\xa3\x9c\x26\x88"
|
||||
"\x65\xe5\xf7\xf4\x4b\x1d\x17\x9b\xc3\xbd\xff\x04\x2d\x31\xdd\x2c\xfc\x62"
|
||||
|
@ -451,9 +406,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\xf9\x3c\x58\x54\x5b\x37\x10\xb1\xab\xd8\x83\xfb\x84\xf1\x95\x3f\x2e\x2f"
|
||||
"\x1c",
|
||||
91},
|
||||
{"Let's Encrypt 'Oak2025h2'", CTLogState::Admissible,
|
||||
1701000000000, // 2023-11-26T12:00:00Z
|
||||
4, // operated by Let's Encrypt
|
||||
{"Let's Encrypt 'Oak2025h2'", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
4, // operated by Let's Encrypt
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xb5\x76\x30\x07\xad\xc6\xc8\xd2\xe4"
|
||||
"\x4b\xd2\xf5\xbe\xa2\x8d\x9c\xfd\x74\xfa\x3a\xd6\xfa\x59\x5d\xb6\x1c\x60"
|
||||
|
@ -461,9 +416,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\xc9\xd7\x3d\xbb\xc1\xf7\x71\x86\x69\xf4\xb3\x5f\x90\x09\xaa\xae\xbd\x8d"
|
||||
"\xa9",
|
||||
91},
|
||||
{"Trust Asia Log2024-2", CTLogState::Admissible,
|
||||
1675411200000, // 2023-02-03T08:00:00Z
|
||||
5, // operated by TrustAsia
|
||||
{"Trust Asia Log2024-2", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
5, // operated by TrustAsia
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xa7\x64\xe2\x79\x81\x3f\x61\xd7\xec"
|
||||
"\xc6\xf8\x65\x28\x1d\xa0\xb4\x66\x33\xc3\x25\xd5\x0a\x95\x78\x9c\x8f\xfe"
|
||||
|
@ -471,9 +426,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\x0d\x2f\x8c\xab\xd7\x7f\x7a\x1e\xd9\x84\x33\x39\xe8\xfd\x89\x5f\x96\x48"
|
||||
"\x08",
|
||||
91},
|
||||
{"TrustAsia Log2025a", CTLogState::Admissible,
|
||||
1701000000000, // 2023-11-26T12:00:00Z
|
||||
5, // operated by TrustAsia
|
||||
{"TrustAsia Log2025a", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
5, // operated by TrustAsia
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x70\xe5\xb1\xa4\x09\x79\x2b\x9d\xf8"
|
||||
"\xa3\xa0\xdf\x18\xef\x95\x5d\x03\x6c\x7b\xa1\x91\xa9\xb8\x80\x7d\xec\x5c"
|
||||
|
@ -481,9 +436,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\x90\x58\xba\x22\xd5\xf9\xf5\x69\x54\xb7\xa8\x94\x4e\x32\x09\xae\x26\x11"
|
||||
"\x4d",
|
||||
91},
|
||||
{"TrustAsia Log2025b", CTLogState::Admissible,
|
||||
1701000000000, // 2023-11-26T12:00:00Z
|
||||
5, // operated by TrustAsia
|
||||
{"TrustAsia Log2025b", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
5, // operated by TrustAsia
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xaa\xa0\x8b\xdb\x67\x14\x5d\x97\x89"
|
||||
"\x1d\x08\x8d\x06\xd7\xc1\x94\x8e\xb0\xfa\x4c\x46\xd5\x53\x08\x78\x2b\x04"
|
||||
|
@ -491,9 +446,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\xbd\x2f\xa9\xcf\xe8\x7b\x5e\xe1\x4b\x60\xe5\x38\x43\x60\x97\xc1\x5b\x2f"
|
||||
"\x65",
|
||||
91},
|
||||
{"TrustAsia 'log2026a'", CTLogState::Admissible,
|
||||
1719964800000, // 2024-07-03T00:00:00Z
|
||||
5, // operated by TrustAsia
|
||||
{"TrustAsia 'log2026a'", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
5, // operated by TrustAsia
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xa7\x4e\x7a\xc9\xa6\x07\xf9\xff\x74"
|
||||
"\xec\x98\xcb\x49\xe1\x00\x24\xb3\x59\x2e\x83\xfd\xc0\x70\x35\x33\x4c\x63"
|
||||
|
@ -501,9 +456,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\x89\x17\xe8\x5b\x2e\xc5\xac\x00\x05\xc9\x76\x37\x45\x97\x03\x15\xff\x60"
|
||||
"\x59",
|
||||
91},
|
||||
{"TrustAsia 'log2026b'", CTLogState::Admissible,
|
||||
1719964800000, // 2024-07-03T00:00:00Z
|
||||
5, // operated by TrustAsia
|
||||
{"TrustAsia 'log2026b'", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
5, // operated by TrustAsia
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x0f\x12\x8c\xa9\xe6\xe3\xec\x62\xee"
|
||||
"\xdf\x58\xc8\x50\xe6\x26\x70\x76\x10\xb7\x04\x39\xb3\xa7\xf8\x4c\x73\x3b"
|
||||
|
@ -512,9 +467,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
"\x85",
|
||||
91},
|
||||
#ifdef DEBUG
|
||||
{"Mozilla Test RSA Log 1", CTLogState::Admissible,
|
||||
1721666666000, // 2024-07-22T16:44:26Z
|
||||
6, // operated by Mozilla Test Org 1
|
||||
{"Mozilla Test RSA Log 1", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
6, // operated by Mozilla Test Org 1
|
||||
"\x30\x82\x01\x22\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05"
|
||||
"\x00\x03\x82\x01\x0f\x00\x30\x82\x01\x0a\x02\x82\x01\x01\x00\xba\x88\x51"
|
||||
"\xa8\x44\x8e\x16\xd6\x41\xfd\x6e\xb6\x88\x06\x36\x10\x3d\x3c\x13\xd9\xea"
|
||||
|
@ -535,9 +490,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
294},
|
||||
#endif // DEBUG
|
||||
#ifdef DEBUG
|
||||
{"Mozilla Test EC Log", CTLogState::Admissible,
|
||||
1721666666000, // 2024-07-22T16:44:26Z
|
||||
6, // operated by Mozilla Test Org 1
|
||||
{"Mozilla Test EC Log", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
6, // operated by Mozilla Test Org 1
|
||||
"\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
|
||||
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x4f\xbf\xbb\xbb\x61\xe0\xf8\xf9\xb1"
|
||||
"\xa6\x0a\x59\xac\x87\x04\xe2\xec\x05\x0b\x42\x3e\x3c\xf7\x2e\x92\x3f\x2c"
|
||||
|
@ -547,9 +502,9 @@ const CTLogInfo kCTLogList[] = {
|
|||
91},
|
||||
#endif // DEBUG
|
||||
#ifdef DEBUG
|
||||
{"Mozilla Test RSA Log 2", CTLogState::Admissible,
|
||||
1721666666000, // 2024-07-22T16:44:26Z
|
||||
7, // operated by Mozilla Test Org 2
|
||||
{"Mozilla Test RSA Log 2", mozilla::ct::CTLogStatus::Included,
|
||||
0, // no disqualification time
|
||||
7, // operated by Mozilla Test Org 2
|
||||
"\x30\x82\x01\x22\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05"
|
||||
"\x00\x03\x82\x01\x0f\x00\x30\x82\x01\x0a\x02\x82\x01\x01\x00\xc1\x75\xc6"
|
||||
"\x52\x66\x09\x9f\x77\x08\x2a\x67\x91\xf1\xb8\x76\xc3\x7f\x5c\xe5\x38\xb0"
|
||||
|
@ -586,6 +541,4 @@ const CTLogOperatorInfo kCTLogOperatorList[] = {
|
|||
#endif // DEBUG
|
||||
};
|
||||
|
||||
} // namespace mozilla::ct
|
||||
|
||||
#endif // CTKnownLogs_h
|
||||
|
|
|
@ -13,13 +13,25 @@
|
|||
namespace mozilla {
|
||||
namespace ct {
|
||||
|
||||
// Signed integer sufficient to store the numeric ID of CT log operators.
|
||||
// Signed integer sufficient to store the numeric ID of CT log operators
|
||||
// as assigned at https://www.certificate-transparency.org/known-logs .
|
||||
// The assigned IDs are 0-based positive integers, so you can use special
|
||||
// values (such as -1) to indicate a "null" or unknown log ID.
|
||||
typedef int16_t CTLogOperatorId;
|
||||
|
||||
typedef std::vector<CTLogOperatorId> CTLogOperatorList;
|
||||
|
||||
// Current status of a CT log in regard to its inclusion in the
|
||||
// Known Logs List such as https://www.certificate-transparency.org/known-logs
|
||||
enum class CTLogStatus {
|
||||
// Status unknown or unavailable.
|
||||
Unknown,
|
||||
// Included in the list of known logs.
|
||||
Included,
|
||||
// Previously included, but disqualified at some point of time.
|
||||
Disqualified,
|
||||
};
|
||||
|
||||
} // namespace ct
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
|
@ -105,14 +105,30 @@ class SignatureParamsTrustDomain final : public TrustDomain {
|
|||
DigitallySigned::SignatureAlgorithm mSignatureAlgorithm;
|
||||
};
|
||||
|
||||
CTLogVerifier::CTLogVerifier(CTLogOperatorId operatorId, CTLogState state,
|
||||
uint64_t timestamp)
|
||||
CTLogVerifier::CTLogVerifier()
|
||||
: mSignatureAlgorithm(DigitallySigned::SignatureAlgorithm::Anonymous),
|
||||
mOperatorId(operatorId),
|
||||
mState(state),
|
||||
mTimestamp(timestamp) {}
|
||||
mOperatorId(-1),
|
||||
mDisqualified(false),
|
||||
mDisqualificationTime(UINT64_MAX) {}
|
||||
|
||||
Result CTLogVerifier::Init(Input subjectPublicKeyInfo,
|
||||
CTLogOperatorId operatorId, CTLogStatus logStatus,
|
||||
uint64_t disqualificationTime) {
|
||||
switch (logStatus) {
|
||||
case CTLogStatus::Included:
|
||||
mDisqualified = false;
|
||||
mDisqualificationTime = UINT64_MAX;
|
||||
break;
|
||||
case CTLogStatus::Disqualified:
|
||||
mDisqualified = true;
|
||||
mDisqualificationTime = disqualificationTime;
|
||||
break;
|
||||
case CTLogStatus::Unknown:
|
||||
default:
|
||||
assert(false);
|
||||
return Result::FATAL_ERROR_INVALID_ARGS;
|
||||
}
|
||||
|
||||
Result CTLogVerifier::Init(Input subjectPublicKeyInfo) {
|
||||
SignatureParamsTrustDomain trustDomain;
|
||||
Result rv = CheckSubjectPublicKeyInfo(subjectPublicKeyInfo, trustDomain,
|
||||
EndEntityOrCA::MustBeEndEntity);
|
||||
|
@ -156,6 +172,7 @@ Result CTLogVerifier::Init(Input subjectPublicKeyInfo) {
|
|||
return rv;
|
||||
}
|
||||
|
||||
mOperatorId = operatorId;
|
||||
return Success;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
#include <memory>
|
||||
|
||||
#include "CTKnownLogs.h"
|
||||
#include "CTLog.h"
|
||||
#include "CTUtils.h"
|
||||
#include "SignedCertificateTimestamp.h"
|
||||
|
@ -29,25 +28,28 @@ namespace ct {
|
|||
// on error.
|
||||
class CTLogVerifier {
|
||||
public:
|
||||
// |operatorId| The numeric ID of the log operator.
|
||||
// |logState| "Qualified", "Usable", "ReadOnly", or "Retired".
|
||||
// |timestamp| timestamp associated with logState.
|
||||
CTLogVerifier(CTLogOperatorId operatorId, CTLogState logState,
|
||||
uint64_t timestamp);
|
||||
CTLogVerifier();
|
||||
|
||||
// Initializes the verifier with the given subjectPublicKeyInfo.
|
||||
// Initializes the verifier with log-specific information. Only the public
|
||||
// key is used for verification, other parameters are purely informational.
|
||||
// |subjectPublicKeyInfo| is a DER-encoded SubjectPublicKeyInfo.
|
||||
// |operatorId| The numeric ID of the log operator as assigned at
|
||||
// https://www.certificate-transparency.org/known-logs .
|
||||
// |logStatus| Either "Included" or "Disqualified".
|
||||
// |disqualificationTime| Disqualification timestamp (for disqualified logs).
|
||||
// An error is returned if |subjectPublicKeyInfo| refers to an unsupported
|
||||
// public key.
|
||||
pkix::Result Init(pkix::Input subjectPublicKeyInfo);
|
||||
pkix::Result Init(pkix::Input subjectPublicKeyInfo,
|
||||
CTLogOperatorId operatorId, CTLogStatus logStatus,
|
||||
uint64_t disqualificationTime);
|
||||
|
||||
// Returns the log's key ID, which is a SHA256 hash of its public key.
|
||||
// See RFC 6962, Section 3.2.
|
||||
const Buffer& keyId() const { return mKeyId; }
|
||||
|
||||
CTLogOperatorId operatorId() const { return mOperatorId; }
|
||||
CTLogState state() const { return mState; }
|
||||
uint64_t timestamp() const { return mTimestamp; }
|
||||
bool isDisqualified() const { return mDisqualified; }
|
||||
uint64_t disqualificationTime() const { return mDisqualificationTime; }
|
||||
|
||||
// Verifies that |sct| contains a valid signature for |entry|.
|
||||
// |sct| must be signed by the verifier's log.
|
||||
|
@ -76,8 +78,8 @@ class CTLogVerifier {
|
|||
Buffer mKeyId;
|
||||
DigitallySigned::SignatureAlgorithm mSignatureAlgorithm;
|
||||
CTLogOperatorId mOperatorId;
|
||||
CTLogState mState;
|
||||
uint64_t mTimestamp;
|
||||
bool mDisqualified;
|
||||
uint64_t mDisqualificationTime;
|
||||
};
|
||||
|
||||
} // namespace ct
|
||||
|
|
|
@ -29,8 +29,8 @@ static size_t GetRequiredEmbeddedSctsCount(
|
|||
// Whether a valid embedded SCT is present in the list.
|
||||
static bool HasValidEmbeddedSct(const VerifiedSCTList& verifiedScts) {
|
||||
for (const VerifiedSCT& verifiedSct : verifiedScts) {
|
||||
if (verifiedSct.logState == CTLogState::Admissible &&
|
||||
verifiedSct.origin == SCTOrigin::Embedded) {
|
||||
if (verifiedSct.status == VerifiedSCT::Status::Valid &&
|
||||
verifiedSct.origin == VerifiedSCT::Origin::Embedded) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -40,9 +40,9 @@ static bool HasValidEmbeddedSct(const VerifiedSCTList& verifiedScts) {
|
|||
// Whether a valid non-embedded SCT is present in the list.
|
||||
static bool HasValidNonEmbeddedSct(const VerifiedSCTList& verifiedScts) {
|
||||
for (const VerifiedSCT& verifiedSct : verifiedScts) {
|
||||
if (verifiedSct.logState == CTLogState::Admissible &&
|
||||
(verifiedSct.origin == SCTOrigin::TLSExtension ||
|
||||
verifiedSct.origin == SCTOrigin::OCSPResponse)) {
|
||||
if (verifiedSct.status == VerifiedSCT::Status::Valid &&
|
||||
(verifiedSct.origin == VerifiedSCT::Origin::TLSExtension ||
|
||||
verifiedSct.origin == VerifiedSCT::Origin::OCSPResponse)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ static uint64_t GetEffectiveCertIssuanceTime(
|
|||
const VerifiedSCTList& verifiedScts) {
|
||||
uint64_t result = UINT64_MAX;
|
||||
for (const VerifiedSCT& verifiedSct : verifiedScts) {
|
||||
if (verifiedSct.logState == CTLogState::Admissible) {
|
||||
if (verifiedSct.status == VerifiedSCT::Status::Valid) {
|
||||
result = std::min(result, verifiedSct.sct.timestamp);
|
||||
}
|
||||
}
|
||||
|
@ -142,18 +142,18 @@ static uint64_t GetEffectiveCertIssuanceTime(
|
|||
|
||||
// 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.
|
||||
// makes sure the SCT is before the disqualification.
|
||||
static bool LogWasQualifiedForSct(const VerifiedSCT& verifiedSct,
|
||||
uint64_t certIssuanceTime) {
|
||||
switch (verifiedSct.logState) {
|
||||
case CTLogState::Admissible:
|
||||
return true;
|
||||
case CTLogState::Retired: {
|
||||
uint64_t logRetirementTime = verifiedSct.logTimestamp;
|
||||
return certIssuanceTime < logRetirementTime &&
|
||||
verifiedSct.sct.timestamp < logRetirementTime;
|
||||
}
|
||||
if (verifiedSct.status == VerifiedSCT::Status::Valid) {
|
||||
return true;
|
||||
}
|
||||
if (verifiedSct.status == VerifiedSCT::Status::ValidFromDisqualifiedLog) {
|
||||
uint64_t logDisqualificationTime = verifiedSct.logDisqualificationTime;
|
||||
return certIssuanceTime < logDisqualificationTime &&
|
||||
verifiedSct.sct.timestamp < logDisqualificationTime;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// "A certificate is CT Qualified if it is presented with at least two SCTs
|
||||
|
@ -198,7 +198,7 @@ static void CheckNonEmbeddedCompliance(const VerifiedSCTList& verifiedScts,
|
|||
size_t validSctsCount;
|
||||
CountLogsForSelectedScts(
|
||||
verifiedScts, validSctsCount, [](const VerifiedSCT& verifiedSct) -> bool {
|
||||
return verifiedSct.logState == CTLogState::Admissible;
|
||||
return verifiedSct.status == VerifiedSCT::Status::Valid;
|
||||
});
|
||||
|
||||
compliant = validSctsCount >= 2;
|
||||
|
@ -227,7 +227,7 @@ static void CheckEmbeddedCompliance(const VerifiedSCTList& verifiedScts,
|
|||
CountLogsForSelectedScts(
|
||||
verifiedScts, embeddedSctsCount,
|
||||
[certIssuanceTime](const VerifiedSCT& verifiedSct) -> bool {
|
||||
return verifiedSct.origin == SCTOrigin::Embedded &&
|
||||
return verifiedSct.origin == VerifiedSCT::Origin::Embedded &&
|
||||
LogWasQualifiedForSct(verifiedSct, certIssuanceTime);
|
||||
});
|
||||
|
||||
|
|
|
@ -11,24 +11,15 @@
|
|||
namespace mozilla {
|
||||
namespace ct {
|
||||
|
||||
VerifiedSCT::VerifiedSCT(SignedCertificateTimestamp&& sct, SCTOrigin origin,
|
||||
CTLogOperatorId logOperatorId, CTLogState logState,
|
||||
uint64_t logTimestamp)
|
||||
: sct(std::move(sct)),
|
||||
origin(origin),
|
||||
logOperatorId(logOperatorId),
|
||||
logState(logState),
|
||||
logTimestamp(logTimestamp) {}
|
||||
VerifiedSCT::VerifiedSCT()
|
||||
: status(Status::None),
|
||||
origin(Origin::Unknown),
|
||||
logOperatorId(-1),
|
||||
logDisqualificationTime(UINT64_MAX) {}
|
||||
|
||||
void CTVerifyResult::Reset() {
|
||||
verifiedScts.clear();
|
||||
decodingErrors = 0;
|
||||
sctsFromUnknownLogs = 0;
|
||||
sctsWithInvalidSignatures = 0;
|
||||
sctsWithInvalidTimestamps = 0;
|
||||
embeddedSCTs = 0;
|
||||
sctsFromTLSHandshake = 0;
|
||||
sctsFromOCSP = 0;
|
||||
}
|
||||
|
||||
} // namespace ct
|
||||
|
|
|
@ -9,33 +9,48 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
#include "CTKnownLogs.h"
|
||||
#include "CTLog.h"
|
||||
#include "SignedCertificateTimestamp.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace ct {
|
||||
|
||||
enum class SCTOrigin {
|
||||
Embedded,
|
||||
TLSExtension,
|
||||
OCSPResponse,
|
||||
};
|
||||
|
||||
// Holds a verified Signed Certificate Timestamp along with the verification
|
||||
// status (e.g. valid/invalid) and additional information related to the
|
||||
// verification.
|
||||
struct VerifiedSCT {
|
||||
VerifiedSCT(SignedCertificateTimestamp&& sct, SCTOrigin origin,
|
||||
CTLogOperatorId logOperatorId, CTLogState logState,
|
||||
uint64_t logTimestamp);
|
||||
VerifiedSCT();
|
||||
|
||||
// The original SCT.
|
||||
SignedCertificateTimestamp sct;
|
||||
SCTOrigin origin;
|
||||
|
||||
enum class Status {
|
||||
None,
|
||||
// The SCT is from a known log, and the signature is valid.
|
||||
Valid,
|
||||
// The SCT is from a known disqualified log, and the signature is valid.
|
||||
// For the disqualification time of the log see |logDisqualificationTime|.
|
||||
ValidFromDisqualifiedLog,
|
||||
// The SCT is from an unknown log and can not be verified.
|
||||
UnknownLog,
|
||||
// The SCT is from a known log, but the signature is invalid.
|
||||
InvalidSignature,
|
||||
// The SCT signature is valid, but the timestamp is in the future.
|
||||
// Such SCTs are considered invalid (see RFC 6962, Section 5.2).
|
||||
InvalidTimestamp,
|
||||
};
|
||||
|
||||
enum class Origin {
|
||||
Unknown,
|
||||
Embedded,
|
||||
TLSExtension,
|
||||
OCSPResponse,
|
||||
};
|
||||
|
||||
Status status;
|
||||
Origin origin;
|
||||
CTLogOperatorId logOperatorId;
|
||||
CTLogState logState;
|
||||
uint64_t logTimestamp;
|
||||
uint64_t logDisqualificationTime;
|
||||
};
|
||||
|
||||
typedef std::vector<VerifiedSCT> VerifiedSCTList;
|
||||
|
@ -59,19 +74,6 @@ class CTVerifyResult {
|
|||
// standard.
|
||||
// |decodingErrors| field counts the errors of the above kind.
|
||||
size_t decodingErrors;
|
||||
// The number of SCTs encountered from unknown logs.
|
||||
size_t sctsFromUnknownLogs;
|
||||
// The number of SCTs encountered with invalid signatures.
|
||||
size_t sctsWithInvalidSignatures;
|
||||
// The number of SCTs encountered with timestamps in the future.
|
||||
size_t sctsWithInvalidTimestamps;
|
||||
|
||||
// The number of SCTs that were embedded in the certificate.
|
||||
size_t embeddedSCTs;
|
||||
// The number of SCTs included in the TLS handshake.
|
||||
size_t sctsFromTLSHandshake;
|
||||
// The number of SCTs delivered via OCSP.
|
||||
size_t sctsFromOCSP;
|
||||
|
||||
void Reset();
|
||||
};
|
||||
|
|
|
@ -14,6 +14,13 @@ namespace ct {
|
|||
|
||||
using namespace mozilla::pkix;
|
||||
|
||||
// Note: this moves |verifiedSct| to the target list in |result|.
|
||||
static void StoreVerifiedSct(CTVerifyResult& result, VerifiedSCT&& verifiedSct,
|
||||
VerifiedSCT::Status status) {
|
||||
verifiedSct.status = status;
|
||||
result.verifiedScts.push_back(std::move(verifiedSct));
|
||||
}
|
||||
|
||||
void MultiLogCTVerifier::AddLog(CTLogVerifier&& log) {
|
||||
mLogs.push_back(std::move(log));
|
||||
}
|
||||
|
@ -36,8 +43,8 @@ Result MultiLogCTVerifier::Verify(Input cert, Input issuerSubjectPublicKeyInfo,
|
|||
if (rv != Success) {
|
||||
return rv;
|
||||
}
|
||||
rv = VerifySCTs(sctListFromCert, precertEntry, SCTOrigin::Embedded, time,
|
||||
result);
|
||||
rv = VerifySCTs(sctListFromCert, precertEntry,
|
||||
VerifiedSCT::Origin::Embedded, time, result);
|
||||
if (rv != Success) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -48,8 +55,8 @@ Result MultiLogCTVerifier::Verify(Input cert, Input issuerSubjectPublicKeyInfo,
|
|||
|
||||
// Verify SCTs from a stapled OCSP response
|
||||
if (sctListFromOCSPResponse.GetLength() > 0) {
|
||||
rv = VerifySCTs(sctListFromOCSPResponse, x509Entry, SCTOrigin::OCSPResponse,
|
||||
time, result);
|
||||
rv = VerifySCTs(sctListFromOCSPResponse, x509Entry,
|
||||
VerifiedSCT::Origin::OCSPResponse, time, result);
|
||||
if (rv != Success) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -57,8 +64,8 @@ Result MultiLogCTVerifier::Verify(Input cert, Input issuerSubjectPublicKeyInfo,
|
|||
|
||||
// Verify SCTs from a TLS extension
|
||||
if (sctListFromTLSExtension.GetLength() > 0) {
|
||||
rv = VerifySCTs(sctListFromTLSExtension, x509Entry, SCTOrigin::TLSExtension,
|
||||
time, result);
|
||||
rv = VerifySCTs(sctListFromTLSExtension, x509Entry,
|
||||
VerifiedSCT::Origin::TLSExtension, time, result);
|
||||
if (rv != Success) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -99,7 +106,7 @@ void DecodeSCTs(Input encodedSctList,
|
|||
|
||||
Result MultiLogCTVerifier::VerifySCTs(Input encodedSctList,
|
||||
const LogEntry& expectedEntry,
|
||||
SCTOrigin origin, Time time,
|
||||
VerifiedSCT::Origin origin, Time time,
|
||||
CTVerifyResult& result) {
|
||||
std::vector<SignedCertificateTimestamp> decodedSCTs;
|
||||
DecodeSCTs(encodedSctList, decodedSCTs, result.decodingErrors);
|
||||
|
@ -115,23 +122,15 @@ Result MultiLogCTVerifier::VerifySCTs(Input encodedSctList,
|
|||
|
||||
Result MultiLogCTVerifier::VerifySingleSCT(SignedCertificateTimestamp&& sct,
|
||||
const LogEntry& expectedEntry,
|
||||
SCTOrigin origin, Time time,
|
||||
CTVerifyResult& result) {
|
||||
switch (origin) {
|
||||
case SCTOrigin::Embedded:
|
||||
result.embeddedSCTs++;
|
||||
break;
|
||||
case SCTOrigin::TLSExtension:
|
||||
result.sctsFromTLSHandshake++;
|
||||
break;
|
||||
case SCTOrigin::OCSPResponse:
|
||||
result.sctsFromOCSP++;
|
||||
break;
|
||||
}
|
||||
VerifiedSCT::Origin origin,
|
||||
Time time, CTVerifyResult& result) {
|
||||
VerifiedSCT verifiedSct;
|
||||
verifiedSct.origin = origin;
|
||||
verifiedSct.sct = std::move(sct);
|
||||
|
||||
CTLogVerifier* matchingLog = nullptr;
|
||||
for (auto& log : mLogs) {
|
||||
if (log.keyId() == sct.logId) {
|
||||
if (log.keyId() == verifiedSct.sct.logId) {
|
||||
matchingLog = &log;
|
||||
break;
|
||||
}
|
||||
|
@ -139,20 +138,25 @@ Result MultiLogCTVerifier::VerifySingleSCT(SignedCertificateTimestamp&& sct,
|
|||
|
||||
if (!matchingLog) {
|
||||
// SCT does not match any known log.
|
||||
result.sctsFromUnknownLogs++;
|
||||
StoreVerifiedSct(result, std::move(verifiedSct),
|
||||
VerifiedSCT::Status::UnknownLog);
|
||||
return Success;
|
||||
}
|
||||
|
||||
if (!matchingLog->SignatureParametersMatch(sct.signature)) {
|
||||
verifiedSct.logOperatorId = matchingLog->operatorId();
|
||||
|
||||
if (!matchingLog->SignatureParametersMatch(verifiedSct.sct.signature)) {
|
||||
// SCT signature parameters do not match the log's.
|
||||
result.sctsWithInvalidSignatures++;
|
||||
StoreVerifiedSct(result, std::move(verifiedSct),
|
||||
VerifiedSCT::Status::InvalidSignature);
|
||||
return Success;
|
||||
}
|
||||
|
||||
Result rv = matchingLog->Verify(expectedEntry, sct);
|
||||
Result rv = matchingLog->Verify(expectedEntry, verifiedSct.sct);
|
||||
if (rv != Success) {
|
||||
if (rv == Result::ERROR_BAD_SIGNATURE) {
|
||||
result.sctsWithInvalidSignatures++;
|
||||
StoreVerifiedSct(result, std::move(verifiedSct),
|
||||
VerifiedSCT::Status::InvalidSignature);
|
||||
return Success;
|
||||
}
|
||||
return rv;
|
||||
|
@ -164,15 +168,25 @@ Result MultiLogCTVerifier::VerifySingleSCT(SignedCertificateTimestamp&& sct,
|
|||
// pkix::Time, we need to round it either up or down. In our case, rounding up
|
||||
// (towards the future) is more "secure", although practically
|
||||
// it does not matter.
|
||||
Time sctTime = TimeFromEpochInSeconds((sct.timestamp + 999u) / 1000u);
|
||||
Time sctTime =
|
||||
TimeFromEpochInSeconds((verifiedSct.sct.timestamp + 999u) / 1000u);
|
||||
if (sctTime > time) {
|
||||
result.sctsWithInvalidTimestamps++;
|
||||
StoreVerifiedSct(result, std::move(verifiedSct),
|
||||
VerifiedSCT::Status::InvalidTimestamp);
|
||||
return Success;
|
||||
}
|
||||
|
||||
VerifiedSCT verifiedSct(std::move(sct), origin, matchingLog->operatorId(),
|
||||
matchingLog->state(), matchingLog->timestamp());
|
||||
result.verifiedScts.push_back(std::move(verifiedSct));
|
||||
// SCT verified ok, see if the log is qualified. Since SCTs from
|
||||
// disqualified logs are treated as valid under certain circumstances (see
|
||||
// the CT Policy), the log qualification check must be the last one we do.
|
||||
if (matchingLog->isDisqualified()) {
|
||||
verifiedSct.logDisqualificationTime = matchingLog->disqualificationTime();
|
||||
StoreVerifiedSct(result, std::move(verifiedSct),
|
||||
VerifiedSCT::Status::ValidFromDisqualifiedLog);
|
||||
return Success;
|
||||
}
|
||||
|
||||
StoreVerifiedSct(result, std::move(verifiedSct), VerifiedSCT::Status::Valid);
|
||||
return Success;
|
||||
}
|
||||
|
||||
|
|
|
@ -68,14 +68,15 @@ class MultiLogCTVerifier {
|
|||
// placing the verification results in |result|. The SCTs in the list
|
||||
// come from |origin| (as will be reflected in the origin field of each SCT).
|
||||
pkix::Result VerifySCTs(pkix::Input encodedSctList,
|
||||
const LogEntry& expectedEntry, SCTOrigin origin,
|
||||
pkix::Time time, CTVerifyResult& result);
|
||||
const LogEntry& expectedEntry,
|
||||
VerifiedSCT::Origin origin, pkix::Time time,
|
||||
CTVerifyResult& result);
|
||||
|
||||
// Verifies a single, parsed SCT against all known logs.
|
||||
// Note: moves |sct| to the target list in |result|, invalidating |sct|.
|
||||
pkix::Result VerifySingleSCT(SignedCertificateTimestamp&& sct,
|
||||
const ct::LogEntry& expectedEntry,
|
||||
SCTOrigin origin, pkix::Time time,
|
||||
VerifiedSCT::Origin origin, pkix::Time time,
|
||||
CTVerifyResult& result);
|
||||
|
||||
// The list of known logs.
|
||||
|
|
|
@ -11,7 +11,6 @@ EXPORTS += [
|
|||
"BTTypes.h",
|
||||
"BTVerifier.h",
|
||||
"Buffer.h",
|
||||
"CTKnownLogs.h",
|
||||
"CTLog.h",
|
||||
"CTPolicyEnforcer.h",
|
||||
"CTVerifyResult.h",
|
||||
|
|
|
@ -23,12 +23,14 @@ class CTLogVerifierTest : public ::testing::Test {
|
|||
abort();
|
||||
}
|
||||
|
||||
ASSERT_EQ(Success, mLog.Init(InputForBuffer(GetTestPublicKey())));
|
||||
ASSERT_EQ(Success,
|
||||
mLog.Init(InputForBuffer(GetTestPublicKey()), -1 /*operator id*/,
|
||||
CTLogStatus::Included, 0 /*disqualification time*/));
|
||||
ASSERT_EQ(GetTestPublicKeyId(), mLog.keyId());
|
||||
}
|
||||
|
||||
protected:
|
||||
CTLogVerifier mLog = CTLogVerifier(-1, CTLogState::Admissible, 0);
|
||||
CTLogVerifier mLog;
|
||||
};
|
||||
|
||||
TEST_F(CTLogVerifierTest, VerifiesCertSCT) {
|
||||
|
@ -106,8 +108,10 @@ TEST_F(CTLogVerifierTest, ExcessDataInPublicKey) {
|
|||
std::string extra = "extra";
|
||||
key.insert(key.end(), extra.begin(), extra.end());
|
||||
|
||||
CTLogVerifier log(-1, CTLogState::Admissible, 0);
|
||||
EXPECT_NE(Success, log.Init(InputForBuffer(key)));
|
||||
CTLogVerifier log;
|
||||
EXPECT_NE(Success,
|
||||
log.Init(InputForBuffer(key), -1 /*operator id*/,
|
||||
CTLogStatus::Included, 0 /*disqualification time*/));
|
||||
}
|
||||
|
||||
} // namespace ct
|
||||
|
|
|
@ -30,7 +30,9 @@ class CTObjectsExtractorTest : public ::testing::Test {
|
|||
mCaCertSPKI = ExtractCertSPKI(mCaCert);
|
||||
|
||||
Buffer logPublicKey = GetTestPublicKey();
|
||||
ASSERT_EQ(Success, mLog.Init(InputForBuffer(logPublicKey)));
|
||||
ASSERT_EQ(Success,
|
||||
mLog.Init(InputForBuffer(logPublicKey), -1 /*operator id*/,
|
||||
CTLogStatus::Included, 0 /*disqualification time*/));
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -38,7 +40,7 @@ class CTObjectsExtractorTest : public ::testing::Test {
|
|||
Buffer mEmbeddedCert;
|
||||
Buffer mCaCert;
|
||||
Buffer mCaCertSPKI;
|
||||
CTLogVerifier mLog = CTLogVerifier(-1, CTLogState::Admissible, 0);
|
||||
CTLogVerifier mLog;
|
||||
};
|
||||
|
||||
TEST_F(CTObjectsExtractorTest, ExtractPrecert) {
|
||||
|
|
|
@ -44,26 +44,32 @@ class CTPolicyEnforcerTest : public ::testing::Test {
|
|||
}
|
||||
|
||||
void AddSct(VerifiedSCTList& verifiedScts, size_t logNo,
|
||||
CTLogOperatorId operatorId, SCTOrigin origin, uint64_t timestamp,
|
||||
CTLogState logState = CTLogState::Admissible) {
|
||||
SignedCertificateTimestamp sct;
|
||||
sct.version = SignedCertificateTimestamp::Version::V1;
|
||||
sct.timestamp = timestamp;
|
||||
CTLogOperatorId operatorId, VerifiedSCT::Origin origin,
|
||||
uint64_t timestamp,
|
||||
VerifiedSCT::Status status = VerifiedSCT::Status::Valid) {
|
||||
VerifiedSCT verifiedSct;
|
||||
verifiedSct.status = status;
|
||||
verifiedSct.origin = origin;
|
||||
verifiedSct.logOperatorId = operatorId;
|
||||
verifiedSct.logDisqualificationTime =
|
||||
status == VerifiedSCT::Status::ValidFromDisqualifiedLog
|
||||
? DISQUALIFIED_AT
|
||||
: UINT64_MAX;
|
||||
verifiedSct.sct.version = SignedCertificateTimestamp::Version::V1;
|
||||
verifiedSct.sct.timestamp = timestamp;
|
||||
Buffer logId;
|
||||
GetLogId(logId, logNo);
|
||||
sct.logId = std::move(logId);
|
||||
VerifiedSCT verifiedSct(std::move(sct), origin, operatorId, logState,
|
||||
LOG_TIMESTAMP);
|
||||
verifiedSct.sct.logId = std::move(logId);
|
||||
verifiedScts.push_back(std::move(verifiedSct));
|
||||
}
|
||||
|
||||
void AddMultipleScts(VerifiedSCTList& verifiedScts, size_t logsCount,
|
||||
uint8_t operatorsCount, SCTOrigin origin,
|
||||
uint64_t timestamp,
|
||||
CTLogState logState = CTLogState::Admissible) {
|
||||
void AddMultipleScts(
|
||||
VerifiedSCTList& verifiedScts, size_t logsCount, uint8_t operatorsCount,
|
||||
VerifiedSCT::Origin origin, uint64_t timestamp,
|
||||
VerifiedSCT::Status status = VerifiedSCT::Status::Valid) {
|
||||
for (size_t logNo = 0; logNo < logsCount; logNo++) {
|
||||
CTLogOperatorId operatorId = logNo % operatorsCount;
|
||||
AddSct(verifiedScts, logNo, operatorId, origin, timestamp, logState);
|
||||
AddSct(verifiedScts, logNo, operatorId, origin, timestamp, status);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,9 +99,9 @@ class CTPolicyEnforcerTest : public ::testing::Test {
|
|||
CTLogOperatorList NO_OPERATORS;
|
||||
CTLogOperatorList OPERATORS_1_AND_2;
|
||||
|
||||
const SCTOrigin ORIGIN_EMBEDDED = SCTOrigin::Embedded;
|
||||
const SCTOrigin ORIGIN_TLS = SCTOrigin::TLSExtension;
|
||||
const SCTOrigin ORIGIN_OCSP = SCTOrigin::OCSPResponse;
|
||||
const VerifiedSCT::Origin ORIGIN_EMBEDDED = VerifiedSCT::Origin::Embedded;
|
||||
const VerifiedSCT::Origin ORIGIN_TLS = VerifiedSCT::Origin::TLSExtension;
|
||||
const VerifiedSCT::Origin ORIGIN_OCSP = VerifiedSCT::Origin::OCSPResponse;
|
||||
|
||||
// 4 years of cert lifetime requires 5 SCTs for the embedded case.
|
||||
const size_t DEFAULT_MONTHS = 4 * 12L;
|
||||
|
@ -104,10 +110,10 @@ class CTPolicyEnforcerTest : public ::testing::Test {
|
|||
const uint64_t TIMESTAMP_1 = 1439596800000L;
|
||||
|
||||
// Date.parse("2016-04-15T00:00:00Z")
|
||||
const uint64_t LOG_TIMESTAMP = 1460678400000L;
|
||||
const uint64_t DISQUALIFIED_AT = 1460678400000L;
|
||||
|
||||
// Date.parse("2016-04-01T00:00:00Z")
|
||||
const uint64_t BEFORE_RETIREMENT = 1459468800000L;
|
||||
const uint64_t BEFORE_DISQUALIFIED = 1459468800000L;
|
||||
|
||||
// Date.parse("2016-04-16T00:00:00Z")
|
||||
const uint64_t AFTER_DISQUALIFIED = 1460764800000L;
|
||||
|
@ -200,23 +206,23 @@ TEST_F(CTPolicyEnforcerTest, DoesNotConformToCTPolicyNotEnoughFreshSCTs) {
|
|||
// SCT from before disqualification.
|
||||
scts.clear();
|
||||
AddSct(scts, LOG_1, OPERATOR_1, ORIGIN_TLS, TIMESTAMP_1);
|
||||
AddSct(scts, LOG_2, OPERATOR_2, ORIGIN_TLS, BEFORE_RETIREMENT,
|
||||
CTLogState::Retired);
|
||||
AddSct(scts, LOG_2, OPERATOR_2, ORIGIN_TLS, BEFORE_DISQUALIFIED,
|
||||
VerifiedSCT::Status::ValidFromDisqualifiedLog);
|
||||
CheckCompliance(scts, DEFAULT_MONTHS, NO_OPERATORS,
|
||||
CTPolicyCompliance::NotEnoughScts);
|
||||
// SCT from after disqualification.
|
||||
scts.clear();
|
||||
AddSct(scts, LOG_1, OPERATOR_1, ORIGIN_TLS, TIMESTAMP_1);
|
||||
AddSct(scts, LOG_2, OPERATOR_2, ORIGIN_TLS, AFTER_DISQUALIFIED,
|
||||
CTLogState::Retired);
|
||||
VerifiedSCT::Status::ValidFromDisqualifiedLog);
|
||||
CheckCompliance(scts, DEFAULT_MONTHS, NO_OPERATORS,
|
||||
CTPolicyCompliance::NotEnoughScts);
|
||||
|
||||
// Embedded SCT from before disqualification.
|
||||
scts.clear();
|
||||
AddSct(scts, LOG_1, OPERATOR_1, ORIGIN_TLS, TIMESTAMP_1);
|
||||
AddSct(scts, LOG_2, OPERATOR_2, ORIGIN_EMBEDDED, BEFORE_RETIREMENT,
|
||||
CTLogState::Retired);
|
||||
AddSct(scts, LOG_2, OPERATOR_2, ORIGIN_EMBEDDED, BEFORE_DISQUALIFIED,
|
||||
VerifiedSCT::Status::ValidFromDisqualifiedLog);
|
||||
CheckCompliance(scts, DEFAULT_MONTHS, NO_OPERATORS,
|
||||
CTPolicyCompliance::NotEnoughScts);
|
||||
|
||||
|
@ -224,7 +230,7 @@ TEST_F(CTPolicyEnforcerTest, DoesNotConformToCTPolicyNotEnoughFreshSCTs) {
|
|||
scts.clear();
|
||||
AddSct(scts, LOG_1, OPERATOR_1, ORIGIN_TLS, TIMESTAMP_1);
|
||||
AddSct(scts, LOG_2, OPERATOR_2, ORIGIN_EMBEDDED, AFTER_DISQUALIFIED,
|
||||
CTLogState::Retired);
|
||||
VerifiedSCT::Status::ValidFromDisqualifiedLog);
|
||||
CheckCompliance(scts, DEFAULT_MONTHS, NO_OPERATORS,
|
||||
CTPolicyCompliance::NotEnoughScts);
|
||||
}
|
||||
|
@ -238,8 +244,8 @@ TEST_F(CTPolicyEnforcerTest,
|
|||
AddSct(scts, LOG_2, OPERATOR_1, ORIGIN_EMBEDDED, TIMESTAMP_1);
|
||||
AddSct(scts, LOG_3, OPERATOR_1, ORIGIN_EMBEDDED, TIMESTAMP_1);
|
||||
AddSct(scts, LOG_4, OPERATOR_1, ORIGIN_EMBEDDED, TIMESTAMP_1);
|
||||
AddSct(scts, LOG_5, OPERATOR_2, ORIGIN_EMBEDDED, BEFORE_RETIREMENT,
|
||||
CTLogState::Retired);
|
||||
AddSct(scts, LOG_5, OPERATOR_2, ORIGIN_EMBEDDED, BEFORE_DISQUALIFIED,
|
||||
VerifiedSCT::Status::ValidFromDisqualifiedLog);
|
||||
|
||||
CheckCompliance(scts, DEFAULT_MONTHS, NO_OPERATORS,
|
||||
CTPolicyCompliance::Compliant);
|
||||
|
@ -255,7 +261,7 @@ TEST_F(CTPolicyEnforcerTest,
|
|||
AddSct(scts, LOG_3, OPERATOR_1, ORIGIN_EMBEDDED, TIMESTAMP_1);
|
||||
AddSct(scts, LOG_4, OPERATOR_1, ORIGIN_EMBEDDED, TIMESTAMP_1);
|
||||
AddSct(scts, LOG_5, OPERATOR_2, ORIGIN_EMBEDDED, AFTER_DISQUALIFIED,
|
||||
CTLogState::Retired);
|
||||
VerifiedSCT::Status::ValidFromDisqualifiedLog);
|
||||
|
||||
CheckCompliance(scts, DEFAULT_MONTHS, NO_OPERATORS,
|
||||
CTPolicyCompliance::NotEnoughScts);
|
||||
|
@ -267,7 +273,7 @@ TEST_F(CTPolicyEnforcerTest,
|
|||
|
||||
// 5 embedded SCTs required for DEFAULT_MONTHS.
|
||||
AddSct(scts, LOG_1, OPERATOR_1, ORIGIN_EMBEDDED, AFTER_DISQUALIFIED,
|
||||
CTLogState::Retired);
|
||||
VerifiedSCT::Status::ValidFromDisqualifiedLog);
|
||||
AddSct(scts, LOG_2, OPERATOR_1, ORIGIN_EMBEDDED, AFTER_DISQUALIFIED);
|
||||
AddSct(scts, LOG_3, OPERATOR_1, ORIGIN_EMBEDDED, AFTER_DISQUALIFIED);
|
||||
AddSct(scts, LOG_4, OPERATOR_1, ORIGIN_EMBEDDED, AFTER_DISQUALIFIED);
|
||||
|
|
|
@ -30,9 +30,10 @@ class MultiLogCTVerifierTest : public ::testing::Test {
|
|||
abort();
|
||||
}
|
||||
|
||||
CTLogVerifier log(mLogOperatorID, CTLogState::Admissible, 0);
|
||||
;
|
||||
ASSERT_EQ(Success, log.Init(InputForBuffer(GetTestPublicKey())));
|
||||
CTLogVerifier log;
|
||||
ASSERT_EQ(Success,
|
||||
log.Init(InputForBuffer(GetTestPublicKey()), mLogOperatorID,
|
||||
CTLogStatus::Included, 0 /*disqualification time*/));
|
||||
mVerifier.AddLog(std::move(log));
|
||||
|
||||
mTestCert = GetDEREncodedX509Cert();
|
||||
|
@ -48,10 +49,10 @@ class MultiLogCTVerifierTest : public ::testing::Test {
|
|||
}
|
||||
|
||||
void CheckForSingleValidSCTInResult(const CTVerifyResult& result,
|
||||
SCTOrigin origin) {
|
||||
VerifiedSCT::Origin origin) {
|
||||
EXPECT_EQ(0U, result.decodingErrors);
|
||||
ASSERT_EQ(1U, result.verifiedScts.size());
|
||||
EXPECT_EQ(CTLogState::Admissible, result.verifiedScts[0].logState);
|
||||
EXPECT_EQ(VerifiedSCT::Status::Valid, result.verifiedScts[0].status);
|
||||
EXPECT_EQ(origin, result.verifiedScts[0].origin);
|
||||
EXPECT_EQ(mLogOperatorID, result.verifiedScts[0].logOperatorId);
|
||||
}
|
||||
|
@ -82,7 +83,7 @@ class MultiLogCTVerifierTest : public ::testing::Test {
|
|||
mVerifier.Verify(InputForBuffer(cert), InputForBuffer(issuerSPKI),
|
||||
InputForBuffer(sctList), Input(), Input(), mNow,
|
||||
result));
|
||||
CheckForSingleValidSCTInResult(result, SCTOrigin::Embedded);
|
||||
CheckForSingleValidSCTInResult(result, VerifiedSCT::Origin::Embedded);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -156,7 +157,7 @@ TEST_F(MultiLogCTVerifierTest, VerifiesSCTFromOCSP) {
|
|||
mVerifier.Verify(InputForBuffer(mTestCert), Input(), Input(),
|
||||
InputForBuffer(sctList), Input(), mNow, result));
|
||||
|
||||
CheckForSingleValidSCTInResult(result, SCTOrigin::OCSPResponse);
|
||||
CheckForSingleValidSCTInResult(result, VerifiedSCT::Origin::OCSPResponse);
|
||||
}
|
||||
|
||||
TEST_F(MultiLogCTVerifierTest, VerifiesSCTFromTLS) {
|
||||
|
@ -169,7 +170,7 @@ TEST_F(MultiLogCTVerifierTest, VerifiesSCTFromTLS) {
|
|||
mVerifier.Verify(InputForBuffer(mTestCert), Input(), Input(),
|
||||
Input(), InputForBuffer(sctList), mNow, result));
|
||||
|
||||
CheckForSingleValidSCTInResult(result, SCTOrigin::TLSExtension);
|
||||
CheckForSingleValidSCTInResult(result, VerifiedSCT::Origin::TLSExtension);
|
||||
}
|
||||
|
||||
TEST_F(MultiLogCTVerifierTest, VerifiesSCTFromMultipleSources) {
|
||||
|
@ -187,17 +188,20 @@ TEST_F(MultiLogCTVerifierTest, VerifiesSCTFromMultipleSources) {
|
|||
size_t tlsExtensionCount = 0;
|
||||
size_t ocspResponseCount = 0;
|
||||
for (const VerifiedSCT& verifiedSct : result.verifiedScts) {
|
||||
EXPECT_EQ(CTLogState::Admissible, verifiedSct.logState);
|
||||
EXPECT_EQ(VerifiedSCT::Status::Valid, verifiedSct.status);
|
||||
switch (verifiedSct.origin) {
|
||||
case SCTOrigin::Embedded:
|
||||
case VerifiedSCT::Origin::Embedded:
|
||||
embeddedCount++;
|
||||
break;
|
||||
case SCTOrigin::TLSExtension:
|
||||
case VerifiedSCT::Origin::TLSExtension:
|
||||
tlsExtensionCount++;
|
||||
break;
|
||||
case SCTOrigin::OCSPResponse:
|
||||
case VerifiedSCT::Origin::OCSPResponse:
|
||||
ocspResponseCount++;
|
||||
break;
|
||||
case VerifiedSCT::Origin::Unknown:
|
||||
default:
|
||||
ASSERT_TRUE(false);
|
||||
}
|
||||
}
|
||||
EXPECT_EQ(embeddedCount, 0u);
|
||||
|
@ -215,15 +219,17 @@ TEST_F(MultiLogCTVerifierTest, IdentifiesSCTFromUnknownLog) {
|
|||
Input(), InputForBuffer(sctList), mNow, result));
|
||||
|
||||
EXPECT_EQ(0U, result.decodingErrors);
|
||||
EXPECT_EQ(0U, result.verifiedScts.size());
|
||||
EXPECT_EQ(1U, result.sctsFromUnknownLogs);
|
||||
ASSERT_EQ(1U, result.verifiedScts.size());
|
||||
EXPECT_EQ(VerifiedSCT::Status::UnknownLog, result.verifiedScts[0].status);
|
||||
}
|
||||
|
||||
TEST_F(MultiLogCTVerifierTest, IdentifiesSCTFromDisqualifiedLog) {
|
||||
MultiLogCTVerifier verifier;
|
||||
const uint64_t retiredTime = 12345u;
|
||||
CTLogVerifier log(mLogOperatorID, CTLogState::Retired, retiredTime);
|
||||
ASSERT_EQ(Success, log.Init(InputForBuffer(GetTestPublicKey())));
|
||||
CTLogVerifier log;
|
||||
const uint64_t disqualificationTime = 12345u;
|
||||
ASSERT_EQ(Success,
|
||||
log.Init(InputForBuffer(GetTestPublicKey()), mLogOperatorID,
|
||||
CTLogStatus::Disqualified, disqualificationTime));
|
||||
verifier.AddLog(std::move(log));
|
||||
|
||||
Buffer sct(GetTestSignedCertificateTimestamp());
|
||||
|
@ -237,8 +243,10 @@ TEST_F(MultiLogCTVerifierTest, IdentifiesSCTFromDisqualifiedLog) {
|
|||
|
||||
EXPECT_EQ(0U, result.decodingErrors);
|
||||
ASSERT_EQ(1U, result.verifiedScts.size());
|
||||
EXPECT_EQ(CTLogState::Retired, result.verifiedScts[0].logState);
|
||||
EXPECT_EQ(retiredTime, result.verifiedScts[0].logTimestamp);
|
||||
EXPECT_EQ(VerifiedSCT::Status::ValidFromDisqualifiedLog,
|
||||
result.verifiedScts[0].status);
|
||||
EXPECT_EQ(disqualificationTime,
|
||||
result.verifiedScts[0].logDisqualificationTime);
|
||||
EXPECT_EQ(mLogOperatorID, result.verifiedScts[0].logOperatorId);
|
||||
}
|
||||
|
||||
|
|
|
@ -438,15 +438,43 @@ static SECStatus BlockServerCertChangeForSpdy(
|
|||
}
|
||||
|
||||
void GatherTelemetryForSingleSCT(const ct::VerifiedSCT& verifiedSct) {
|
||||
// See SSL_SCTS_ORIGIN in Histograms.json.
|
||||
uint32_t origin = 0;
|
||||
switch (verifiedSct.origin) {
|
||||
case ct::VerifiedSCT::Origin::Embedded:
|
||||
origin = 1;
|
||||
break;
|
||||
case ct::VerifiedSCT::Origin::TLSExtension:
|
||||
origin = 2;
|
||||
break;
|
||||
case ct::VerifiedSCT::Origin::OCSPResponse:
|
||||
origin = 3;
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Unexpected VerifiedSCT::Origin type");
|
||||
}
|
||||
Telemetry::Accumulate(Telemetry::SSL_SCTS_ORIGIN, origin);
|
||||
|
||||
// See SSL_SCTS_VERIFICATION_STATUS in Histograms.json.
|
||||
uint32_t verificationStatus = 0;
|
||||
switch (verifiedSct.logState) {
|
||||
case ct::CTLogState::Admissible:
|
||||
switch (verifiedSct.status) {
|
||||
case ct::VerifiedSCT::Status::Valid:
|
||||
verificationStatus = 1;
|
||||
break;
|
||||
case ct::CTLogState::Retired:
|
||||
case ct::VerifiedSCT::Status::UnknownLog:
|
||||
verificationStatus = 2;
|
||||
break;
|
||||
case ct::VerifiedSCT::Status::InvalidSignature:
|
||||
verificationStatus = 3;
|
||||
break;
|
||||
case ct::VerifiedSCT::Status::InvalidTimestamp:
|
||||
verificationStatus = 4;
|
||||
break;
|
||||
case ct::VerifiedSCT::Status::ValidFromDisqualifiedLog:
|
||||
verificationStatus = 5;
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Unexpected VerifiedSCT::Status type");
|
||||
}
|
||||
Telemetry::Accumulate(Telemetry::SSL_SCTS_VERIFICATION_STATUS,
|
||||
verificationStatus);
|
||||
|
@ -464,30 +492,11 @@ void GatherCertificateTransparencyTelemetry(
|
|||
GatherTelemetryForSingleSCT(sct);
|
||||
}
|
||||
|
||||
// See SSL_SCTS_VERIFICATION_STATUS in Histograms.json.
|
||||
// Decoding errors are reported to the 0th bucket
|
||||
// of the SSL_SCTS_VERIFICATION_STATUS enumerated probe.
|
||||
for (size_t i = 0; i < info.verifyResult.decodingErrors; ++i) {
|
||||
Telemetry::Accumulate(Telemetry::SSL_SCTS_VERIFICATION_STATUS, 0);
|
||||
}
|
||||
for (size_t i = 0; i < info.verifyResult.sctsFromUnknownLogs; ++i) {
|
||||
Telemetry::Accumulate(Telemetry::SSL_SCTS_VERIFICATION_STATUS, 2);
|
||||
}
|
||||
for (size_t i = 0; i < info.verifyResult.sctsWithInvalidSignatures; ++i) {
|
||||
Telemetry::Accumulate(Telemetry::SSL_SCTS_VERIFICATION_STATUS, 3);
|
||||
}
|
||||
for (size_t i = 0; i < info.verifyResult.sctsWithInvalidTimestamps; ++i) {
|
||||
Telemetry::Accumulate(Telemetry::SSL_SCTS_VERIFICATION_STATUS, 4);
|
||||
}
|
||||
|
||||
// See SSL_SCTS_ORIGIN in Histograms.json.
|
||||
for (size_t i = 0; i < info.verifyResult.embeddedSCTs; ++i) {
|
||||
Telemetry::Accumulate(Telemetry::SSL_SCTS_ORIGIN, 1);
|
||||
}
|
||||
for (size_t i = 0; i < info.verifyResult.sctsFromTLSHandshake; ++i) {
|
||||
Telemetry::Accumulate(Telemetry::SSL_SCTS_ORIGIN, 2);
|
||||
}
|
||||
for (size_t i = 0; i < info.verifyResult.sctsFromOCSP; ++i) {
|
||||
Telemetry::Accumulate(Telemetry::SSL_SCTS_ORIGIN, 3);
|
||||
}
|
||||
|
||||
// Handle the histogram of SCTs counts.
|
||||
uint32_t sctsCount =
|
||||
|
|
|
@ -51,19 +51,14 @@ OUTPUT_TEMPLATE = """\
|
|||
|
||||
static const PRTime kCTExpirationTime = INT64_C($expiration_time);
|
||||
|
||||
namespace mozilla::ct {
|
||||
|
||||
enum class CTLogState {
|
||||
Admissible, // Qualified, Usable, or ReadOnly
|
||||
Retired,
|
||||
};
|
||||
|
||||
struct CTLogInfo {
|
||||
// See bug 1338873 about making these fields const.
|
||||
const char* name;
|
||||
CTLogState state;
|
||||
uint64_t timestamp;
|
||||
// Index within kCTLogOperatorList.
|
||||
mozilla::ct::CTLogStatus status;
|
||||
// 0 for qualified logs, disqualification time for disqualified logs
|
||||
// (in milliseconds, measured since the epoch, ignoring leap seconds).
|
||||
uint64_t disqualificationTime;
|
||||
size_t operatorIndex;
|
||||
const char* key;
|
||||
size_t keyLength;
|
||||
|
@ -83,13 +78,11 @@ const CTLogOperatorInfo kCTLogOperatorList[] = {
|
|||
$operators
|
||||
};
|
||||
|
||||
} // namespace mozilla::ct
|
||||
|
||||
#endif // $include_guard
|
||||
"""
|
||||
|
||||
|
||||
def get_timestamp(time_str):
|
||||
def get_disqualification_time(time_str):
|
||||
"""
|
||||
Convert a time string such as "2017-01-01T00:00:00Z" to an integer
|
||||
representing milliseconds since the epoch.
|
||||
|
@ -124,34 +117,13 @@ def get_operator_index(json_data, target_name):
|
|||
|
||||
|
||||
LOG_INFO_TEMPLATE = """\
|
||||
{$description, $state,
|
||||
$timestamp, // $timestamp_comment
|
||||
$operator_index,$spaces // $operator_comment
|
||||
{$description, $status,
|
||||
$disqualification_time, // $disqualification_time_comment
|
||||
$operator_index, // $operator_comment
|
||||
$indented_log_key,
|
||||
$log_key_len}"""
|
||||
|
||||
|
||||
class UnhandledLogStateException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def map_state(state):
|
||||
"""
|
||||
Maps a log state string to the appropriate CTLogState enum value or None,
|
||||
if the log state indicates that the log should not be included. Valid
|
||||
states to be included are 'qualified', 'usable', 'readonly', or 'retired'.
|
||||
Valid states that are not to be included are 'pending' or 'rejected'.
|
||||
"""
|
||||
if state == "qualified" or state == "usable" or state == "readonly":
|
||||
return "CTLogState::Admissible"
|
||||
elif state == "retired":
|
||||
return "CTLogState::Retired"
|
||||
elif state == "pending" or state == "rejected":
|
||||
return None
|
||||
else:
|
||||
raise UnhandledLogStateException("unhandled log state '%s'" % state)
|
||||
|
||||
|
||||
def get_log_info_structs(json_data):
|
||||
"""Return array of CTLogInfo initializers for the known logs."""
|
||||
tmpl = Template(LOG_INFO_TEMPLATE)
|
||||
|
@ -161,20 +133,24 @@ def get_log_info_structs(json_data):
|
|||
for log in operator["logs"]:
|
||||
log_key = base64.b64decode(log["key"])
|
||||
operator_index = get_operator_index(json_data, operator_name)
|
||||
state = list(log["state"].keys())[0]
|
||||
timestamp_comment = log["state"][state]["timestamp"]
|
||||
timestamp = get_timestamp(timestamp_comment)
|
||||
state = map_state(state)
|
||||
if state is None:
|
||||
continue
|
||||
if "disqualification_time" in log:
|
||||
status = "mozilla::ct::CTLogStatus::Disqualified"
|
||||
disqualification_time = get_disqualification_time(
|
||||
log["disqualification_time"]
|
||||
)
|
||||
disqualification_time_comment = 'Date.parse("{0}")'.format(
|
||||
log["disqualification_time"]
|
||||
)
|
||||
else:
|
||||
status = "mozilla::ct::CTLogStatus::Included"
|
||||
disqualification_time = 0
|
||||
disqualification_time_comment = "no disqualification time"
|
||||
is_test_log = "test_only" in operator and operator["test_only"]
|
||||
prefix = ""
|
||||
suffix = ","
|
||||
if is_test_log:
|
||||
prefix = "#ifdef DEBUG\n"
|
||||
suffix = ",\n#endif // DEBUG"
|
||||
num_spaces = len(str(timestamp)) - len(str(operator_index))
|
||||
spaces = " " * num_spaces
|
||||
toappend = tmpl.substitute(
|
||||
# Use json.dumps for C-escaping strings.
|
||||
# Not perfect but close enough.
|
||||
|
@ -183,10 +159,9 @@ def get_log_info_structs(json_data):
|
|||
operator_comment="operated by {0}".
|
||||
# The comment must not contain "/".
|
||||
format(operator_name).replace("/", "|"),
|
||||
state=state,
|
||||
timestamp=timestamp,
|
||||
spaces=spaces,
|
||||
timestamp_comment=timestamp_comment,
|
||||
status=status,
|
||||
disqualification_time=disqualification_time,
|
||||
disqualification_time_comment=disqualification_time_comment,
|
||||
# Maximum line width is 80.
|
||||
indented_log_key="\n".join(
|
||||
[' "{0}"'.format(l) for l in get_hex_lines(log_key, 74)]
|
||||
|
@ -259,11 +234,7 @@ def patch_in_test_logs(json_data):
|
|||
tIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXt
|
||||
jQIDAQAB
|
||||
""",
|
||||
"state": {
|
||||
"qualified": {
|
||||
"timestamp": "2024-07-22T16:44:26Z",
|
||||
},
|
||||
},
|
||||
"operated_by": [max_id + 1],
|
||||
},
|
||||
{
|
||||
"description": "Mozilla Test EC Log",
|
||||
|
@ -272,11 +243,7 @@ def patch_in_test_logs(json_data):
|
|||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAET7+7u2Hg+PmxpgpZrIcE4uwFC0I+
|
||||
PPcukj8sT3lLRVwqadIzRWw2xBGdBwbgDu3I0ZOQ15kbey0HowTqoEqmwA==
|
||||
""",
|
||||
"state": {
|
||||
"qualified": {
|
||||
"timestamp": "2024-07-22T16:44:26Z",
|
||||
},
|
||||
},
|
||||
"operated_by": [max_id + 1],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
@ -297,11 +264,7 @@ def patch_in_test_logs(json_data):
|
|||
gys1uJMPdLqQqovHYWckKrH9bWIUDRjEwLjGj8N0hFcyStfehuZVLx0eGR1xIWjT
|
||||
uwIDAQAB
|
||||
""",
|
||||
"state": {
|
||||
"qualified": {
|
||||
"timestamp": "2024-07-22T16:44:26Z",
|
||||
},
|
||||
},
|
||||
"operated_by": [max_id + 2],
|
||||
}
|
||||
],
|
||||
}
|
||||
|
@ -340,11 +303,7 @@ def run(args):
|
|||
Load the input JSON file and generate the C++ header according to the
|
||||
command line arguments.
|
||||
"""
|
||||
if args.json_file:
|
||||
print("Reading file: ", args.json_file)
|
||||
with open(args.json_file, "rb") as json_file:
|
||||
json_text = json_file.read()
|
||||
else:
|
||||
if args.url:
|
||||
json_text = get_content_at(args.url)
|
||||
signature = get_content_at(args.signature_url)
|
||||
key = read_rsa_key(args.key_file)
|
||||
|
@ -357,6 +316,10 @@ def run(args):
|
|||
print("Writing output: ", args.json_file_out)
|
||||
with open(args.json_file_out, "wb") as json_file_out:
|
||||
json_file_out.write(json_text)
|
||||
else:
|
||||
print("Reading file: ", args.json_file)
|
||||
with open(args.json_file, "rb") as json_file:
|
||||
json_text = json_file.read()
|
||||
|
||||
json_data = json.loads(json_text)
|
||||
patch_in_test_logs(json_data)
|
||||
|
@ -399,11 +362,10 @@ def parse_arguments_and_run():
|
|||
)
|
||||
arg_parser.add_argument(
|
||||
"--json-file",
|
||||
nargs="?",
|
||||
const=mozpath.join(
|
||||
default=mozpath.join(
|
||||
buildconfig.topsrcdir, "security", "manager", "tools", "log_list.json"
|
||||
),
|
||||
help="read the known CT logs JSON data from the specified file (default: %(const)s)",
|
||||
help="read the known CT logs JSON data from the specified file (default: %(default)s)",
|
||||
)
|
||||
arg_parser.add_argument(
|
||||
"--json-file-out",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"version": "40.3",
|
||||
"log_list_timestamp": "2024-08-02T12:55:10Z",
|
||||
"version": "39.9",
|
||||
"log_list_timestamp": "2024-07-29T12:55:53Z",
|
||||
"operators": [
|
||||
{
|
||||
"name": "Google",
|
||||
|
@ -578,70 +578,6 @@
|
|||
"start_inclusive": "2025-07-01T00:00:00Z",
|
||||
"end_exclusive": "2026-01-01T00:00:00Z"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Sectigo 'Mammoth2026h1'",
|
||||
"log_id": "JS+Uwisp6W6fQRpyBytpXFtS/5epDSVAu/zcUexN7gs=",
|
||||
"key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEnssMilHMiuILzoXmr00x2xtqTP2weWuZl8Bd+25FUB1iqsafm2sFPaKrK12Im1Ao4p5YpaX6+eP6FSXjFBMyxA==",
|
||||
"url": "https://mammoth2026h1.ct.sectigo.com/",
|
||||
"mmd": 86400,
|
||||
"state": {
|
||||
"qualified": {
|
||||
"timestamp": "2024-07-30T04:00:00Z"
|
||||
}
|
||||
},
|
||||
"temporal_interval": {
|
||||
"start_inclusive": "2026-01-01T00:00:00Z",
|
||||
"end_exclusive": "2026-07-01T00:00:00Z"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Sectigo 'Mammoth2026h2'",
|
||||
"log_id": "lLHBirDQV8R74KwEDh8svI3DdXJ7yVHyClJhJoY7pzw=",
|
||||
"key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE7INh8te0u+TkO+vIY3WYz2GQYxQ9XyLfdLpQp1ibaX3mY4lt2ddRhD/4AtjI/8KXceV+J/VysY8kJ1cKDXTAtg==",
|
||||
"url": "https://mammoth2026h2.ct.sectigo.com/",
|
||||
"mmd": 86400,
|
||||
"state": {
|
||||
"qualified": {
|
||||
"timestamp": "2024-07-30T04:00:00Z"
|
||||
}
|
||||
},
|
||||
"temporal_interval": {
|
||||
"start_inclusive": "2026-07-01T00:00:00Z",
|
||||
"end_exclusive": "2027-01-01T00:00:00Z"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Sectigo 'Sabre2026h1'",
|
||||
"log_id": "VmzVo3a+g9/jQrZ1xJwjJJinabrDgsurSaOHfZqzLQE=",
|
||||
"key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEhCa8Nr3YjTyHnuAQr82U2de5UYA0fvdYXHPq6wmTuBB7kJx9x82WQ+1TbpUhRmdR8N62yZ6q4oBtziWBNNdqYA==",
|
||||
"url": "https://sabre2026h1.ct.sectigo.com/",
|
||||
"mmd": 86400,
|
||||
"state": {
|
||||
"qualified": {
|
||||
"timestamp": "2024-07-30T04:00:00Z"
|
||||
}
|
||||
},
|
||||
"temporal_interval": {
|
||||
"start_inclusive": "2026-01-01T00:00:00Z",
|
||||
"end_exclusive": "2026-07-01T00:00:00Z"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Sectigo 'Sabre2026h2'",
|
||||
"log_id": "H1bRq5RwSkHdP+r99GmTVTAsFDG/5hNGCJ//rnldzC8=",
|
||||
"key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEzjXK7DkHgtp3J4bk8n7F3Djym6mrjKfA7YMePmobwPCVVroyM0x1fAkH6eE+ZTVj8Em+ctGqna99CMS0jVk9cw==",
|
||||
"url": "https://sabre2026h2.ct.sectigo.com/",
|
||||
"mmd": 86400,
|
||||
"state": {
|
||||
"qualified": {
|
||||
"timestamp": "2024-07-30T04:00:00Z"
|
||||
}
|
||||
},
|
||||
"temporal_interval": {
|
||||
"start_inclusive": "2026-07-01T00:00:00Z",
|
||||
"end_exclusive": "2027-01-01T00:00:00Z"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
Загрузка…
Ссылка в новой задаче