tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

CTLogVerifierTest.cpp (3785B)


      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/. */
      6 
      7 #include "CTLogVerifier.h"
      8 #include "CTTestUtils.h"
      9 #include "nss.h"
     10 #include "signature_cache_ffi.h"
     11 
     12 #include "gtest/gtest.h"
     13 
     14 namespace mozilla {
     15 namespace ct {
     16 
     17 using namespace pkix;
     18 
     19 class CTLogVerifierTest : public ::testing::Test {
     20 public:
     21  void SetUp() override {
     22    // Does nothing if NSS is already initialized.
     23    if (NSS_NoDB_Init(nullptr) != SECSuccess) {
     24      abort();
     25    }
     26 
     27    mSignatureCache = signature_cache_new(1);
     28 
     29    ASSERT_EQ(Success, mLog.Init(InputForBuffer(GetTestPublicKey())));
     30    ASSERT_EQ(GetTestPublicKeyId(), mLog.keyId());
     31  }
     32 
     33  void TearDown() override { signature_cache_free(mSignatureCache); }
     34 
     35 protected:
     36  CTLogVerifier mLog =
     37      CTLogVerifier(-1, CTLogState::Admissible, CTLogFormat::RFC6962, 0);
     38  // For some reason, the templating makes it impossible to use UniquePtr here.
     39  SignatureCache* mSignatureCache;
     40 };
     41 
     42 TEST_F(CTLogVerifierTest, VerifiesCertSCT) {
     43  LogEntry certEntry;
     44  GetX509CertLogEntry(certEntry);
     45 
     46  SignedCertificateTimestamp certSct;
     47  GetX509CertSCT(certSct);
     48 
     49  EXPECT_EQ(Success, mLog.Verify(certEntry, certSct, mSignatureCache));
     50 }
     51 
     52 TEST_F(CTLogVerifierTest, VerifiesPrecertSCT) {
     53  LogEntry precertEntry;
     54  GetPrecertLogEntry(precertEntry);
     55 
     56  SignedCertificateTimestamp precertSct;
     57  GetPrecertSCT(precertSct);
     58 
     59  EXPECT_EQ(Success, mLog.Verify(precertEntry, precertSct, mSignatureCache));
     60 }
     61 
     62 TEST_F(CTLogVerifierTest, FailsInvalidTimestamp) {
     63  LogEntry certEntry;
     64  GetX509CertLogEntry(certEntry);
     65 
     66  SignedCertificateTimestamp certSct;
     67  GetX509CertSCT(certSct);
     68 
     69  // Mangle the timestamp, so that it should fail signature validation.
     70  certSct.timestamp = 0;
     71 
     72  EXPECT_EQ(pkix::Result::ERROR_BAD_SIGNATURE,
     73            mLog.Verify(certEntry, certSct, mSignatureCache));
     74 }
     75 
     76 TEST_F(CTLogVerifierTest, FailsInvalidSignature) {
     77  LogEntry certEntry;
     78  GetX509CertLogEntry(certEntry);
     79 
     80  // Mangle the value of the signature, making the underlying signature
     81  // verification code return ERROR_BAD_SIGNATURE.
     82  SignedCertificateTimestamp certSct;
     83  GetX509CertSCT(certSct);
     84  certSct.signature.signatureData[20] ^= '\xFF';
     85  EXPECT_EQ(pkix::Result::ERROR_BAD_SIGNATURE,
     86            mLog.Verify(certEntry, certSct, mSignatureCache));
     87 
     88  // Mangle the encoding of the signature, making the underlying implementation
     89  // return ERROR_BAD_DER. We still expect the verifier to return
     90  // ERROR_BAD_SIGNATURE.
     91  SignedCertificateTimestamp certSct2;
     92  GetX509CertSCT(certSct2);
     93  certSct2.signature.signatureData[0] ^= '\xFF';
     94  EXPECT_EQ(pkix::Result::ERROR_BAD_SIGNATURE,
     95            mLog.Verify(certEntry, certSct2, mSignatureCache));
     96 }
     97 
     98 TEST_F(CTLogVerifierTest, FailsInvalidLogID) {
     99  LogEntry certEntry;
    100  GetX509CertLogEntry(certEntry);
    101 
    102  SignedCertificateTimestamp certSct;
    103  GetX509CertSCT(certSct);
    104 
    105  // Mangle the log ID, which should cause it to match a different log before
    106  // attempting signature validation.
    107  certSct.logId.push_back('\x0');
    108 
    109  EXPECT_EQ(pkix::Result::FATAL_ERROR_INVALID_ARGS,
    110            mLog.Verify(certEntry, certSct, mSignatureCache));
    111 }
    112 
    113 // Test that excess data after the public key is rejected.
    114 TEST_F(CTLogVerifierTest, ExcessDataInPublicKey) {
    115  Buffer key = GetTestPublicKey();
    116  std::string extra = "extra";
    117  key.insert(key.end(), extra.begin(), extra.end());
    118 
    119  CTLogVerifier log(-1, CTLogState::Admissible, CTLogFormat::RFC6962, 0);
    120  EXPECT_NE(Success, log.Init(InputForBuffer(key)));
    121 }
    122 
    123 }  // namespace ct
    124 }  // namespace mozilla