Bug 1941128 - Turn off network.dns.native_https_query on Mac again
[gecko.git] / security / ct / tests / gtest / MultiLogCTVerifierTest.cpp
blob133ee7e37258cd02472c5bd39fbf2f8e3de2052c
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "MultiLogCTVerifier.h"
9 #include <stdint.h>
11 #include "CTLogVerifier.h"
12 #include "CTObjectsExtractor.h"
13 #include "CTSerialization.h"
14 #include "CTTestUtils.h"
15 #include "gtest/gtest.h"
16 #include "nss.h"
18 namespace mozilla {
19 namespace ct {
21 using namespace mozilla::pkix;
23 class MultiLogCTVerifierTest : public ::testing::Test {
24 public:
25 MultiLogCTVerifierTest() : mNow(Time::uninitialized), mLogOperatorID(123) {}
27 void SetUp() override {
28 // Does nothing if NSS is already initialized.
29 if (NSS_NoDB_Init(nullptr) != SECSuccess) {
30 abort();
33 CTLogVerifier log(mLogOperatorID, CTLogState::Admissible, 0);
35 ASSERT_EQ(Success, log.Init(InputForBuffer(GetTestPublicKey())));
36 mVerifier.AddLog(std::move(log));
38 mTestCert = GetDEREncodedX509Cert();
39 mEmbeddedCert = GetDEREncodedTestEmbeddedCert();
40 mCaCert = GetDEREncodedCACert();
41 mCaCertSPKI = ExtractCertSPKI(mCaCert);
42 mIntermediateCert = GetDEREncodedIntermediateCert();
43 mIntermediateCertSPKI = ExtractCertSPKI(mIntermediateCert);
45 // Set the current time making sure all test timestamps are in the past.
46 mNow =
47 TimeFromEpochInSeconds(1451606400u); // Date.parse("2016-01-01")/1000
50 void CheckForSingleValidSCTInResult(const CTVerifyResult& result,
51 SCTOrigin origin) {
52 EXPECT_EQ(0U, result.decodingErrors);
53 ASSERT_EQ(1U, result.verifiedScts.size());
54 EXPECT_EQ(CTLogState::Admissible, result.verifiedScts[0].logState);
55 EXPECT_EQ(origin, result.verifiedScts[0].origin);
56 EXPECT_EQ(mLogOperatorID, result.verifiedScts[0].logOperatorId);
59 // Writes an SCTList containing a single |sct| into |output|.
60 void EncodeSCTListForTesting(Input sct, Buffer& output) {
61 std::vector<Input> list;
62 list.push_back(std::move(sct));
63 ASSERT_EQ(Success, EncodeSCTList(list, output));
66 void GetSCTListWithInvalidLogID(Buffer& result) {
67 result.clear();
68 Buffer sct(GetTestSignedCertificateTimestamp());
69 // Change a byte inside the Log ID part of the SCT so it does
70 // not match the log used in the tests.
71 sct[15] ^= '\xFF';
72 EncodeSCTListForTesting(InputForBuffer(sct), result);
75 void CheckPrecertVerification(const Buffer& cert, const Buffer& issuerSPKI) {
76 Buffer sctList;
77 ExtractEmbeddedSCTList(cert, sctList);
78 ASSERT_FALSE(sctList.empty());
80 CTVerifyResult result;
81 ASSERT_EQ(Success,
82 mVerifier.Verify(InputForBuffer(cert), InputForBuffer(issuerSPKI),
83 InputForBuffer(sctList), Input(), Input(), mNow,
84 result));
85 CheckForSingleValidSCTInResult(result, SCTOrigin::Embedded);
88 protected:
89 MultiLogCTVerifier mVerifier;
90 Buffer mTestCert;
91 Buffer mEmbeddedCert;
92 Buffer mCaCert;
93 Buffer mCaCertSPKI;
94 Buffer mIntermediateCert;
95 Buffer mIntermediateCertSPKI;
96 Time mNow;
97 CTLogOperatorId mLogOperatorID;
100 // Test that an embedded SCT can be extracted and the extracted SCT contains
101 // the expected data. This tests the ExtractEmbeddedSCTList function from
102 // CTTestUtils.h that other tests here rely upon.
103 TEST_F(MultiLogCTVerifierTest, ExtractEmbeddedSCT) {
104 SignedCertificateTimestamp sct;
106 // Extract the embedded SCT.
108 Buffer sctList;
109 ExtractEmbeddedSCTList(mEmbeddedCert, sctList);
110 ASSERT_FALSE(sctList.empty());
112 Reader sctReader;
113 ASSERT_EQ(Success, DecodeSCTList(InputForBuffer(sctList), sctReader));
114 Input sctItemInput;
115 ASSERT_EQ(Success, ReadSCTListItem(sctReader, sctItemInput));
116 EXPECT_TRUE(sctReader.AtEnd()); // we only expect one sct in the list
118 Reader sctItemReader(sctItemInput);
119 ASSERT_EQ(Success, DecodeSignedCertificateTimestamp(sctItemReader, sct));
121 // Make sure the SCT contains the expected data.
123 EXPECT_EQ(SignedCertificateTimestamp::Version::V1, sct.version);
124 EXPECT_EQ(GetTestPublicKeyId(), sct.logId);
126 uint64_t expectedTimestamp = 1365181456275;
127 EXPECT_EQ(expectedTimestamp, sct.timestamp);
130 TEST_F(MultiLogCTVerifierTest, VerifiesEmbeddedSCT) {
131 CheckPrecertVerification(mEmbeddedCert, mCaCertSPKI);
134 TEST_F(MultiLogCTVerifierTest, VerifiesEmbeddedSCTWithPreCA) {
135 CheckPrecertVerification(GetDEREncodedTestEmbeddedWithPreCACert(),
136 mCaCertSPKI);
139 TEST_F(MultiLogCTVerifierTest, VerifiesEmbeddedSCTWithIntermediate) {
140 CheckPrecertVerification(GetDEREncodedTestEmbeddedWithIntermediateCert(),
141 mIntermediateCertSPKI);
144 TEST_F(MultiLogCTVerifierTest, VerifiesEmbeddedSCTWithIntermediateAndPreCA) {
145 CheckPrecertVerification(GetDEREncodedTestEmbeddedWithIntermediatePreCACert(),
146 mIntermediateCertSPKI);
149 TEST_F(MultiLogCTVerifierTest, VerifiesSCTFromOCSP) {
150 Buffer sct(GetTestSignedCertificateTimestamp());
151 Buffer sctList;
152 EncodeSCTListForTesting(InputForBuffer(sct), sctList);
154 CTVerifyResult result;
155 ASSERT_EQ(Success,
156 mVerifier.Verify(InputForBuffer(mTestCert), Input(), Input(),
157 InputForBuffer(sctList), Input(), mNow, result));
159 CheckForSingleValidSCTInResult(result, SCTOrigin::OCSPResponse);
162 TEST_F(MultiLogCTVerifierTest, VerifiesSCTFromTLS) {
163 Buffer sct(GetTestSignedCertificateTimestamp());
164 Buffer sctList;
165 EncodeSCTListForTesting(InputForBuffer(sct), sctList);
167 CTVerifyResult result;
168 ASSERT_EQ(Success,
169 mVerifier.Verify(InputForBuffer(mTestCert), Input(), Input(),
170 Input(), InputForBuffer(sctList), mNow, result));
172 CheckForSingleValidSCTInResult(result, SCTOrigin::TLSExtension);
175 TEST_F(MultiLogCTVerifierTest, VerifiesSCTFromMultipleSources) {
176 Buffer sct(GetTestSignedCertificateTimestamp());
177 Buffer sctList;
178 EncodeSCTListForTesting(InputForBuffer(sct), sctList);
180 CTVerifyResult result;
181 ASSERT_EQ(Success, mVerifier.Verify(InputForBuffer(mTestCert), Input(),
182 Input(), InputForBuffer(sctList),
183 InputForBuffer(sctList), mNow, result));
185 // The result should contain verified SCTs from TLS and OCSP origins.
186 size_t embeddedCount = 0;
187 size_t tlsExtensionCount = 0;
188 size_t ocspResponseCount = 0;
189 for (const VerifiedSCT& verifiedSct : result.verifiedScts) {
190 EXPECT_EQ(CTLogState::Admissible, verifiedSct.logState);
191 switch (verifiedSct.origin) {
192 case SCTOrigin::Embedded:
193 embeddedCount++;
194 break;
195 case SCTOrigin::TLSExtension:
196 tlsExtensionCount++;
197 break;
198 case SCTOrigin::OCSPResponse:
199 ocspResponseCount++;
200 break;
203 EXPECT_EQ(embeddedCount, 0u);
204 EXPECT_TRUE(tlsExtensionCount > 0);
205 EXPECT_TRUE(ocspResponseCount > 0);
208 TEST_F(MultiLogCTVerifierTest, IdentifiesSCTFromUnknownLog) {
209 Buffer sctList;
210 GetSCTListWithInvalidLogID(sctList);
212 CTVerifyResult result;
213 ASSERT_EQ(Success,
214 mVerifier.Verify(InputForBuffer(mTestCert), Input(), Input(),
215 Input(), InputForBuffer(sctList), mNow, result));
217 EXPECT_EQ(0U, result.decodingErrors);
218 EXPECT_EQ(0U, result.verifiedScts.size());
219 EXPECT_EQ(1U, result.sctsFromUnknownLogs);
222 TEST_F(MultiLogCTVerifierTest, IdentifiesSCTFromDisqualifiedLog) {
223 MultiLogCTVerifier verifier;
224 const uint64_t retiredTime = 12345u;
225 CTLogVerifier log(mLogOperatorID, CTLogState::Retired, retiredTime);
226 ASSERT_EQ(Success, log.Init(InputForBuffer(GetTestPublicKey())));
227 verifier.AddLog(std::move(log));
229 Buffer sct(GetTestSignedCertificateTimestamp());
230 Buffer sctList;
231 EncodeSCTListForTesting(InputForBuffer(sct), sctList);
233 CTVerifyResult result;
234 ASSERT_EQ(Success,
235 verifier.Verify(InputForBuffer(mTestCert), Input(), Input(),
236 Input(), InputForBuffer(sctList), mNow, result));
238 EXPECT_EQ(0U, result.decodingErrors);
239 ASSERT_EQ(1U, result.verifiedScts.size());
240 EXPECT_EQ(CTLogState::Retired, result.verifiedScts[0].logState);
241 EXPECT_EQ(retiredTime, result.verifiedScts[0].logTimestamp);
242 EXPECT_EQ(mLogOperatorID, result.verifiedScts[0].logOperatorId);
245 } // namespace ct
246 } // namespace mozilla