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 "CTLogVerifier.h"
8 #include "CTTestUtils.h"
10 #include "signature_cache_ffi.h"
12 #include "gtest/gtest.h"
19 class CTLogVerifierTest
: public ::testing::Test
{
21 void SetUp() override
{
22 // Does nothing if NSS is already initialized.
23 if (NSS_NoDB_Init(nullptr) != SECSuccess
) {
27 mSignatureCache
= signature_cache_new(1);
29 ASSERT_EQ(Success
, mLog
.Init(InputForBuffer(GetTestPublicKey())));
30 ASSERT_EQ(GetTestPublicKeyId(), mLog
.keyId());
33 void TearDown() override
{ signature_cache_free(mSignatureCache
); }
36 CTLogVerifier mLog
= CTLogVerifier(-1, CTLogState::Admissible
, 0);
37 // For some reason, the templating makes it impossible to use UniquePtr here.
38 SignatureCache
* mSignatureCache
;
41 TEST_F(CTLogVerifierTest
, VerifiesCertSCT
) {
43 GetX509CertLogEntry(certEntry
);
45 SignedCertificateTimestamp certSct
;
46 GetX509CertSCT(certSct
);
48 EXPECT_EQ(Success
, mLog
.Verify(certEntry
, certSct
, mSignatureCache
));
51 TEST_F(CTLogVerifierTest
, VerifiesPrecertSCT
) {
52 LogEntry precertEntry
;
53 GetPrecertLogEntry(precertEntry
);
55 SignedCertificateTimestamp precertSct
;
56 GetPrecertSCT(precertSct
);
58 EXPECT_EQ(Success
, mLog
.Verify(precertEntry
, precertSct
, mSignatureCache
));
61 TEST_F(CTLogVerifierTest
, FailsInvalidTimestamp
) {
63 GetX509CertLogEntry(certEntry
);
65 SignedCertificateTimestamp certSct
;
66 GetX509CertSCT(certSct
);
68 // Mangle the timestamp, so that it should fail signature validation.
69 certSct
.timestamp
= 0;
71 EXPECT_EQ(pkix::Result::ERROR_BAD_SIGNATURE
,
72 mLog
.Verify(certEntry
, certSct
, mSignatureCache
));
75 TEST_F(CTLogVerifierTest
, FailsInvalidSignature
) {
77 GetX509CertLogEntry(certEntry
);
79 // Mangle the value of the signature, making the underlying signature
80 // verification code return ERROR_BAD_SIGNATURE.
81 SignedCertificateTimestamp certSct
;
82 GetX509CertSCT(certSct
);
83 certSct
.signature
.signatureData
[20] ^= '\xFF';
84 EXPECT_EQ(pkix::Result::ERROR_BAD_SIGNATURE
,
85 mLog
.Verify(certEntry
, certSct
, mSignatureCache
));
87 // Mangle the encoding of the signature, making the underlying implementation
88 // return ERROR_BAD_DER. We still expect the verifier to return
89 // ERROR_BAD_SIGNATURE.
90 SignedCertificateTimestamp certSct2
;
91 GetX509CertSCT(certSct2
);
92 certSct2
.signature
.signatureData
[0] ^= '\xFF';
93 EXPECT_EQ(pkix::Result::ERROR_BAD_SIGNATURE
,
94 mLog
.Verify(certEntry
, certSct2
, mSignatureCache
));
97 TEST_F(CTLogVerifierTest
, FailsInvalidLogID
) {
99 GetX509CertLogEntry(certEntry
);
101 SignedCertificateTimestamp certSct
;
102 GetX509CertSCT(certSct
);
104 // Mangle the log ID, which should cause it to match a different log before
105 // attempting signature validation.
106 certSct
.logId
.push_back('\x0');
108 EXPECT_EQ(pkix::Result::FATAL_ERROR_INVALID_ARGS
,
109 mLog
.Verify(certEntry
, certSct
, mSignatureCache
));
112 // Test that excess data after the public key is rejected.
113 TEST_F(CTLogVerifierTest
, ExcessDataInPublicKey
) {
114 Buffer key
= GetTestPublicKey();
115 std::string extra
= "extra";
116 key
.insert(key
.end(), extra
.begin(), extra
.end());
118 CTLogVerifier
log(-1, CTLogState::Admissible
, 0);
119 EXPECT_NE(Success
, log
.Init(InputForBuffer(key
)));
123 } // namespace mozilla