123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233 |
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- #include "MultiLogCTVerifier.h"
- #include <stdint.h>
- #include "CTLogVerifier.h"
- #include "CTObjectsExtractor.h"
- #include "CTSerialization.h"
- #include "CTTestUtils.h"
- #include "gtest/gtest.h"
- #include "mozilla/EnumSet.h"
- #include "mozilla/Move.h"
- #include "nss.h"
- namespace mozilla { namespace ct {
- using namespace mozilla::pkix;
- class MultiLogCTVerifierTest : public ::testing::Test
- {
- public:
- MultiLogCTVerifierTest()
- : mNow(Time::uninitialized)
- {}
- void SetUp() override
- {
- // Does nothing if NSS is already initialized.
- MOZ_RELEASE_ASSERT(NSS_NoDB_Init(nullptr) == SECSuccess);
- ASSERT_EQ(Success, mVerifier.AddLog(InputForBuffer(GetTestPublicKey())));
- mTestCert = GetDEREncodedX509Cert();
- mEmbeddedCert = GetDEREncodedTestEmbeddedCert();
- mCaCert = GetDEREncodedCACert();
- mCaCertSPKI = ExtractCertSPKI(mCaCert);
- mIntermediateCert = GetDEREncodedIntermediateCert();
- mIntermediateCertSPKI = ExtractCertSPKI(mIntermediateCert);
- // Set the current time making sure all test timestamps are in the past.
- mNow = TimeFromEpochInSeconds(1451606400u); // Date.parse("2016-01-01")/1000
- }
- void CheckForSingleVerifiedSCTInResult(const CTVerifyResult& result,
- SignedCertificateTimestamp::Origin origin)
- {
- EXPECT_EQ(0U, result.decodingErrors);
- ASSERT_EQ(1U, result.scts.length());
- EXPECT_EQ(SignedCertificateTimestamp::VerificationStatus::OK,
- result.scts[0].verificationStatus);
- EXPECT_EQ(origin, result.scts[0].origin);
- }
- // Writes an SCTList containing a single |sct| into |output|.
- void EncodeSCTListForTesting(Input sct, Buffer& output)
- {
- Vector<Input> list;
- ASSERT_TRUE(list.append(Move(sct)));
- ASSERT_EQ(Success, EncodeSCTList(list, output));
- }
- void GetSCTListWithInvalidLogID(Buffer& result)
- {
- result.clear();
- Buffer sct(GetTestSignedCertificateTimestamp());
- // Change a byte inside the Log ID part of the SCT so it does
- // not match the log used in the tests.
- sct[15] ^= '\xFF';
- EncodeSCTListForTesting(InputForBuffer(sct), result);
- }
- void CheckPrecertVerification(const Buffer& cert, const Buffer& issuerSPKI)
- {
- Buffer sctList;
- ExtractEmbeddedSCTList(cert, sctList);
- ASSERT_FALSE(sctList.empty());
- CTVerifyResult result;
- ASSERT_EQ(Success,
- mVerifier.Verify(InputForBuffer(cert), InputForBuffer(issuerSPKI),
- InputForBuffer(sctList), Input(), Input(),
- mNow, result));
- CheckForSingleVerifiedSCTInResult(result,
- SignedCertificateTimestamp::Origin::Embedded);
- }
- protected:
- MultiLogCTVerifier mVerifier;
- Buffer mTestCert;
- Buffer mEmbeddedCert;
- Buffer mCaCert;
- Buffer mCaCertSPKI;
- Buffer mIntermediateCert;
- Buffer mIntermediateCertSPKI;
- Time mNow;
- };
- // Test that an embedded SCT can be extracted and the extracted SCT contains
- // the expected data. This tests the ExtractEmbeddedSCTList function from
- // CTTestUtils.h that other tests here rely upon.
- TEST_F(MultiLogCTVerifierTest, ExtractEmbeddedSCT)
- {
- SignedCertificateTimestamp sct;
- // Extract the embedded SCT.
- Buffer sctList;
- ExtractEmbeddedSCTList(mEmbeddedCert, sctList);
- ASSERT_FALSE(sctList.empty());
- Reader sctReader;
- ASSERT_EQ(Success, DecodeSCTList(InputForBuffer(sctList), sctReader));
- Input sctItemInput;
- ASSERT_EQ(Success, ReadSCTListItem(sctReader, sctItemInput));
- EXPECT_TRUE(sctReader.AtEnd()); // we only expect one sct in the list
- Reader sctItemReader(sctItemInput);
- ASSERT_EQ(Success, DecodeSignedCertificateTimestamp(sctItemReader, sct));
- // Make sure the SCT contains the expected data.
- EXPECT_EQ(SignedCertificateTimestamp::Version::V1, sct.version);
- EXPECT_EQ(GetTestPublicKeyId(), sct.logId);
- uint64_t expectedTimestamp = 1365181456275;
- EXPECT_EQ(expectedTimestamp, sct.timestamp);
- }
- TEST_F(MultiLogCTVerifierTest, VerifiesEmbeddedSCT)
- {
- CheckPrecertVerification(mEmbeddedCert, mCaCertSPKI);
- }
- TEST_F(MultiLogCTVerifierTest, VerifiesEmbeddedSCTWithPreCA)
- {
- CheckPrecertVerification(GetDEREncodedTestEmbeddedWithPreCACert(),
- mCaCertSPKI);
- }
- TEST_F(MultiLogCTVerifierTest, VerifiesEmbeddedSCTWithIntermediate)
- {
- CheckPrecertVerification(GetDEREncodedTestEmbeddedWithIntermediateCert(),
- mIntermediateCertSPKI);
- }
- TEST_F(MultiLogCTVerifierTest, VerifiesEmbeddedSCTWithIntermediateAndPreCA)
- {
- CheckPrecertVerification(GetDEREncodedTestEmbeddedWithIntermediatePreCACert(),
- mIntermediateCertSPKI);
- }
- TEST_F(MultiLogCTVerifierTest, VerifiesSCTFromOCSP)
- {
- Buffer sct(GetTestSignedCertificateTimestamp());
- Buffer sctList;
- EncodeSCTListForTesting(InputForBuffer(sct), sctList);
- CTVerifyResult result;
- ASSERT_EQ(Success,
- mVerifier.Verify(InputForBuffer(mTestCert), Input(),
- Input(), InputForBuffer(sctList), Input(),
- mNow, result));
- CheckForSingleVerifiedSCTInResult(result,
- SignedCertificateTimestamp::Origin::OCSPResponse);
- }
- TEST_F(MultiLogCTVerifierTest, VerifiesSCTFromTLS)
- {
- Buffer sct(GetTestSignedCertificateTimestamp());
- Buffer sctList;
- EncodeSCTListForTesting(InputForBuffer(sct), sctList);
- CTVerifyResult result;
- ASSERT_EQ(Success,
- mVerifier.Verify(InputForBuffer(mTestCert), Input(),
- Input(), Input(), InputForBuffer(sctList),
- mNow, result));
- CheckForSingleVerifiedSCTInResult(result,
- SignedCertificateTimestamp::Origin::TLSExtension);
- }
- TEST_F(MultiLogCTVerifierTest, VerifiesSCTFromMultipleSources)
- {
- Buffer sct(GetTestSignedCertificateTimestamp());
- Buffer sctList;
- EncodeSCTListForTesting(InputForBuffer(sct), sctList);
- CTVerifyResult result;
- ASSERT_EQ(Success,
- mVerifier.Verify(InputForBuffer(mTestCert), Input(), Input(),
- InputForBuffer(sctList), InputForBuffer(sctList),
- mNow, result));
- // The result should contain verified SCTs from TLS and OCSP origins.
- EnumSet<SignedCertificateTimestamp::Origin> origins;
- for (const SignedCertificateTimestamp& sct : result.scts) {
- EXPECT_EQ(SignedCertificateTimestamp::VerificationStatus::OK,
- sct.verificationStatus);
- origins += sct.origin;
- }
- EXPECT_FALSE(
- origins.contains(SignedCertificateTimestamp::Origin::Embedded));
- EXPECT_TRUE(
- origins.contains(SignedCertificateTimestamp::Origin::OCSPResponse));
- EXPECT_TRUE(
- origins.contains(SignedCertificateTimestamp::Origin::TLSExtension));
- }
- TEST_F(MultiLogCTVerifierTest, IdentifiesSCTFromUnknownLog)
- {
- Buffer sctList;
- GetSCTListWithInvalidLogID(sctList);
- CTVerifyResult result;
- ASSERT_EQ(Success,
- mVerifier.Verify(InputForBuffer(mTestCert), Input(),
- Input(), Input(), InputForBuffer(sctList),
- mNow, result));
- EXPECT_EQ(0U, result.decodingErrors);
- ASSERT_EQ(1U, result.scts.length());
- EXPECT_EQ(SignedCertificateTimestamp::VerificationStatus::UnknownLog,
- result.scts[0].verificationStatus);
- }
- } } // namespace mozilla::ct
|