--- a/security/certverifier/CTSerialization.cpp
+++ b/security/certverifier/CTSerialization.cpp
@@ -506,20 +506,16 @@ DecodeSignedCertificateTimestamp(Reader&
return rv;
}
rv = InputToBuffer(extensions, result.extensions);
if (rv != Success) {
return rv;
}
result.timestamp = timestamp;
- result.origin = SignedCertificateTimestamp::Origin::Unknown;
- result.verificationStatus =
- SignedCertificateTimestamp::VerificationStatus::None;
-
output = Move(result);
return Success;
}
Result
EncodeSCTList(const Vector<pkix::Input>& scts, Buffer& output)
{
// Find out the total size of the SCT list to be written so we can
--- a/security/certverifier/CTVerifyResult.cpp
+++ b/security/certverifier/CTVerifyResult.cpp
@@ -1,18 +1,26 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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 "CTVerifyResult.h"
+#include <stdint.h>
+
namespace mozilla { namespace ct {
+VerifiedSCT::VerifiedSCT()
+ : status(Status::None)
+ , origin(Origin::Unknown)
+{
+}
+
void
CTVerifyResult::Reset()
{
- scts.clear();
+ verifiedScts.clear();
decodingErrors = 0;
}
} } // namespace mozilla::ct
--- a/security/certverifier/CTVerifyResult.h
+++ b/security/certverifier/CTVerifyResult.h
@@ -7,25 +7,59 @@
#ifndef CTVerifyResult_h
#define CTVerifyResult_h
#include "mozilla/Vector.h"
#include "SignedCertificateTimestamp.h"
namespace mozilla { namespace ct {
-typedef Vector<SignedCertificateTimestamp> SCTList;
+// 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();
+
+ // The original SCT.
+ SignedCertificateTimestamp sct;
+
+ enum class Status {
+ None,
+ // The SCT is from a known log, and the signature is valid.
+ Valid,
+ // 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;
+};
+
+typedef Vector<VerifiedSCT> VerifiedSCTList;
// Holds Signed Certificate Timestamps verification results.
class CTVerifyResult
{
public:
- // SCTs that were processed during the verification. For each SCT,
- // the verification result is stored in its |verificationStatus| field.
- SCTList scts;
+ // SCTs that were processed during the verification along with their
+ // verification results.
+ VerifiedSCTList verifiedScts;
// The verifier makes the best effort to extract the available SCTs
// from the binary sources provided to it.
// If some SCT cannot be extracted due to encoding errors, the verifier
// proceeds to the next available one. In other words, decoding errors are
// effectively ignored.
// Note that a serialized SCT may fail to decode for a "legitimate" reason,
// e.g. if the SCT is from a future version of the Certificate Transparency
--- a/security/certverifier/CertVerifier.cpp
+++ b/security/certverifier/CertVerifier.cpp
@@ -4,16 +4,17 @@
* 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 "CertVerifier.h"
#include <stdint.h>
#include "CTKnownLogs.h"
+#include "CTLogVerifier.h"
#include "ExtendedValidation.h"
#include "MultiLogCTVerifier.h"
#include "NSSCertDBTrustDomain.h"
#include "NSSErrorsService.h"
#include "cert.h"
#include "mozilla/Assertions.h"
#include "mozilla/Casting.h"
#include "nsNSSComponent.h"
@@ -159,21 +160,29 @@ CertVerifier::LoadKnownCTLogs()
for (const CTLogInfo& log : kCTLogList) {
Input publicKey;
Result rv = publicKey.Init(
BitwiseCast<const uint8_t*, const char*>(log.logKey), log.logKeyLength);
if (rv != Success) {
MOZ_ASSERT_UNREACHABLE("Failed reading a log key for a known CT Log");
continue;
}
- rv = mCTVerifier->AddLog(publicKey);
+
+ CTLogVerifier logVerifier;
+ rv = logVerifier.Init(publicKey);
if (rv != Success) {
MOZ_ASSERT_UNREACHABLE("Failed initializing a known CT Log");
continue;
}
+
+ rv = mCTVerifier->AddLog(Move(logVerifier));
+ if (rv != Success) {
+ MOZ_ASSERT_UNREACHABLE("Failed activating a known CT Log");
+ continue;
+ }
}
}
Result
CertVerifier::VerifySignedCertificateTimestamps(
NSSCertDBTrustDomain& trustDomain, const UniqueCERTCertList& builtChain,
Input sctsFromTLS, Time time,
/*optional out*/ CertificateTransparencyInfo* ctInfo)
@@ -253,45 +262,45 @@ CertVerifier::VerifySignedCertificateTim
result);
if (rv != Success) {
MOZ_LOG(gCertVerifierLog, LogLevel::Debug,
("SCT verification failed with fatal error %i\n", rv));
return rv;
}
if (MOZ_LOG_TEST(gCertVerifierLog, LogLevel::Debug)) {
- size_t verifiedCount = 0;
+ size_t validCount = 0;
size_t unknownLogCount = 0;
size_t invalidSignatureCount = 0;
size_t invalidTimestampCount = 0;
- for (const SignedCertificateTimestamp& sct : result.scts) {
- switch (sct.verificationStatus) {
- case SignedCertificateTimestamp::VerificationStatus::OK:
- verifiedCount++;
+ for (const VerifiedSCT& verifiedSct : result.verifiedScts) {
+ switch (verifiedSct.status) {
+ case VerifiedSCT::Status::Valid:
+ validCount++;
break;
- case SignedCertificateTimestamp::VerificationStatus::UnknownLog:
+ case VerifiedSCT::Status::UnknownLog:
unknownLogCount++;
break;
- case SignedCertificateTimestamp::VerificationStatus::InvalidSignature:
+ case VerifiedSCT::Status::InvalidSignature:
invalidSignatureCount++;
break;
- case SignedCertificateTimestamp::VerificationStatus::InvalidTimestamp:
+ case VerifiedSCT::Status::InvalidTimestamp:
invalidTimestampCount++;
break;
- case SignedCertificateTimestamp::VerificationStatus::None:
+ case VerifiedSCT::Status::None:
default:
- MOZ_ASSERT_UNREACHABLE("Unexpected SCT verificationStatus");
+ MOZ_ASSERT_UNREACHABLE("Unexpected SCT verification status");
}
}
MOZ_LOG(gCertVerifierLog, LogLevel::Debug,
("SCT verification result: "
- "verified=%zu unknownLog=%zu "
+ "valid=%zu unknownLog=%zu "
"invalidSignature=%zu invalidTimestamp=%zu "
"decodingErrors=%zu\n",
- verifiedCount, unknownLogCount,
+ validCount, unknownLogCount,
invalidSignatureCount, invalidTimestampCount,
result.decodingErrors));
}
if (ctInfo) {
ctInfo->processedSCTs = true;
ctInfo->verifyResult = Move(result);
}
--- a/security/certverifier/MultiLogCTVerifier.cpp
+++ b/security/certverifier/MultiLogCTVerifier.cpp
@@ -10,37 +10,32 @@
#include "CTSerialization.h"
#include "mozilla/Assertions.h"
#include "mozilla/Move.h"
namespace mozilla { namespace ct {
using namespace mozilla::pkix;
-// Note: this moves |sct| to the target list in |result|, invalidating |sct|.
+// Note: this moves |verifiedSct| to the target list in |result|.
static Result
StoreVerifiedSct(CTVerifyResult& result,
- SignedCertificateTimestamp&& sct,
- SignedCertificateTimestamp::VerificationStatus status)
+ VerifiedSCT&& verifiedSct,
+ VerifiedSCT::Status status)
{
- sct.verificationStatus = status;
- if (!result.scts.append(Move(sct))) {
+ verifiedSct.status = status;
+ if (!result.verifiedScts.append(Move(verifiedSct))) {
return Result::FATAL_ERROR_NO_MEMORY;
}
return Success;
}
Result
-MultiLogCTVerifier::AddLog(Input publicKey)
+MultiLogCTVerifier::AddLog(CTLogVerifier&& log)
{
- CTLogVerifier log;
- Result rv = log.Init(publicKey);
- if (rv != Success) {
- return rv;
- }
if (!mLogs.append(Move(log))) {
return Result::FATAL_ERROR_NO_MEMORY;
}
return Success;
}
Result
MultiLogCTVerifier::Verify(Input cert,
@@ -60,55 +55,52 @@ MultiLogCTVerifier::Verify(Input cert,
if (issuerSubjectPublicKeyInfo.GetLength() > 0 &&
sctListFromCert.GetLength() > 0) {
LogEntry precertEntry;
rv = GetPrecertLogEntry(cert, issuerSubjectPublicKeyInfo, precertEntry);
if (rv != Success) {
return rv;
}
rv = VerifySCTs(sctListFromCert, precertEntry,
- SignedCertificateTimestamp::Origin::Embedded, time,
- result);
+ VerifiedSCT::Origin::Embedded, time, result);
if (rv != Success) {
return rv;
}
}
LogEntry x509Entry;
rv = GetX509LogEntry(cert, x509Entry);
if (rv != Success) {
return rv;
}
// Verify SCTs from a stapled OCSP response
if (sctListFromOCSPResponse.GetLength() > 0) {
rv = VerifySCTs(sctListFromOCSPResponse, x509Entry,
- SignedCertificateTimestamp::Origin::OCSPResponse, time,
- result);
+ VerifiedSCT::Origin::OCSPResponse, time, result);
if (rv != Success) {
return rv;
}
}
// Verify SCTs from a TLS extension
if (sctListFromTLSExtension.GetLength() > 0) {
rv = VerifySCTs(sctListFromTLSExtension, x509Entry,
- SignedCertificateTimestamp::Origin::TLSExtension, time,
- result);
+ VerifiedSCT::Origin::TLSExtension, time, result);
if (rv != Success) {
return rv;
}
}
return Success;
}
Result
MultiLogCTVerifier::VerifySCTs(Input encodedSctList,
const LogEntry& expectedEntry,
- SignedCertificateTimestamp::Origin origin,
+ VerifiedSCT::Origin origin,
Time time,
CTVerifyResult& result)
{
Reader listReader;
Result rv = DecodeSCTList(encodedSctList, listReader);
if (rv != Success) {
result.decodingErrors++;
return Success;
@@ -124,70 +116,76 @@ MultiLogCTVerifier::VerifySCTs(Input enc
Reader encodedSctReader(encodedSct);
SignedCertificateTimestamp sct;
rv = DecodeSignedCertificateTimestamp(encodedSctReader, sct);
if (rv != Success) {
result.decodingErrors++;
continue;
}
- sct.origin = origin;
- rv = VerifySingleSCT(Move(sct), expectedEntry, time, result);
+ rv = VerifySingleSCT(Move(sct), expectedEntry, origin, time, result);
if (rv != Success) {
return rv;
}
}
return Success;
}
Result
MultiLogCTVerifier::VerifySingleSCT(SignedCertificateTimestamp&& sct,
const LogEntry& expectedEntry,
+ VerifiedSCT::Origin origin,
Time time,
CTVerifyResult& result)
{
+ VerifiedSCT verifiedSct;
+ verifiedSct.origin = origin;
+ verifiedSct.sct = Move(sct);
+
CTLogVerifier* matchingLog = nullptr;
for (auto& log : mLogs) {
- if (log.keyId() == sct.logId) {
+ if (log.keyId() == verifiedSct.sct.logId) {
matchingLog = &log;
break;
}
}
if (!matchingLog) {
// SCT does not match any known log.
- return StoreVerifiedSct(result, Move(sct),
- SignedCertificateTimestamp::VerificationStatus::UnknownLog);
+ return StoreVerifiedSct(result, Move(verifiedSct),
+ VerifiedSCT::Status::UnknownLog);
}
- if (!matchingLog->SignatureParametersMatch(sct.signature)) {
+ if (!matchingLog->SignatureParametersMatch(verifiedSct.sct.signature)) {
// SCT signature parameters do not match the log's.
- return StoreVerifiedSct(result, Move(sct),
- SignedCertificateTimestamp::VerificationStatus::InvalidSignature);
+ return StoreVerifiedSct(result, Move(verifiedSct),
+ VerifiedSCT::Status::InvalidSignature);
}
- Result rv = matchingLog->Verify(expectedEntry, sct);
+ Result rv = matchingLog->Verify(expectedEntry, verifiedSct.sct);
if (rv != Success) {
if (rv == Result::ERROR_BAD_SIGNATURE) {
- return StoreVerifiedSct(result, Move(sct),
- SignedCertificateTimestamp::VerificationStatus::InvalidSignature);
+ return StoreVerifiedSct(result, Move(verifiedSct),
+ VerifiedSCT::Status::InvalidSignature);
}
return rv;
}
- // |sct.timestamp| is measured in milliseconds since the epoch,
+ // Make sure the timestamp is legitimate (not in the future).
+ // SCT's |timestamp| is measured in milliseconds since the epoch,
// ignoring leap seconds. When converting it to a second-level precision
// pkix::Time, we need to round it either up or down. In our case, rounding up
- // is more "secure", although practically it does not matter.
- Time sctTime = TimeFromEpochInSeconds((sct.timestamp + 999u) / 1000u);
-
- // SCT verified ok, just make sure the timestamp is legitimate.
+ // (towards the future) is more "secure", although practically
+ // it does not matter.
+ Time sctTime =
+ TimeFromEpochInSeconds((verifiedSct.sct.timestamp + 999u) / 1000u);
if (sctTime > time) {
- return StoreVerifiedSct(result, Move(sct),
- SignedCertificateTimestamp::VerificationStatus::InvalidTimestamp);
+ return StoreVerifiedSct(result, Move(verifiedSct),
+ VerifiedSCT::Status::InvalidTimestamp);
}
- return StoreVerifiedSct(result, Move(sct),
- SignedCertificateTimestamp::VerificationStatus::OK);
+ // SCT verified ok.
+ return StoreVerifiedSct(result, Move(verifiedSct),
+ VerifiedSCT::Status::Valid);
}
} } // namespace mozilla::ct
--- a/security/certverifier/MultiLogCTVerifier.h
+++ b/security/certverifier/MultiLogCTVerifier.h
@@ -18,17 +18,17 @@
namespace mozilla { namespace ct {
// A Certificate Transparency verifier that can verify Signed Certificate
// Timestamps from multiple logs.
class MultiLogCTVerifier
{
public:
// Adds a new log to the list of known logs to verify against.
- pkix::Result AddLog(pkix::Input publicKey);
+ pkix::Result AddLog(CTLogVerifier&& log);
// Verifies SCTs embedded in the certificate itself, SCTs embedded in a
// stapled OCSP response, and SCTs obtained via the
// signed_certificate_timestamp TLS extension on the given |cert|.
//
// A certificate is permitted but not required to use multiple sources for
// SCTs. It is expected that most certificates will use only one source
// (embedding, TLS extension or OCSP stapling).
@@ -61,24 +61,25 @@ public:
CTVerifyResult& result);
private:
// Verifies a list of SCTs from |encodedSctList| over |expectedEntry|,
// 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,
- SignedCertificateTimestamp::Origin origin,
+ 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,
+ VerifiedSCT::Origin origin,
pkix::Time time,
CTVerifyResult& result);
// The list of known logs.
Vector<CTLogVerifier> mLogs;
};
} } // namespace mozilla::ct
--- a/security/certverifier/SignedCertificateTimestamp.cpp
+++ b/security/certverifier/SignedCertificateTimestamp.cpp
@@ -33,13 +33,14 @@ namespace mozilla {
bool
operator==(const ct::Buffer& a, const ct::Buffer& b)
{
return (a.empty() && b.empty()) ||
(a.length() == b.length() && memcmp(a.begin(), b.begin(), a.length()) == 0);
}
bool
-operator!=(const ct::Buffer& a, const ct::Buffer& b) {
+operator!=(const ct::Buffer& a, const ct::Buffer& b)
+{
return !(a == b);
}
} // namespace mozilla
--- a/security/certverifier/SignedCertificateTimestamp.h
+++ b/security/certverifier/SignedCertificateTimestamp.h
@@ -80,42 +80,16 @@ struct SignedCertificateTimestamp
Version version;
Buffer logId;
// "timestamp" is the current time in milliseconds, measured since the epoch,
// ignoring leap seconds. See RFC 6962, Section 3.2.
uint64_t timestamp;
Buffer extensions;
DigitallySigned signature;
-
- // Supplementary fields, not defined in CT RFC. Set during the various
- // stages of processing the received SCTs.
-
- enum class Origin {
- Unknown,
- Embedded,
- TLSExtension,
- OCSPResponse
- };
-
- enum class VerificationStatus {
- None,
- // The SCT is from a known log, and the signature is valid.
- OK,
- // 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 SCT are considered invalid (see RFC 6962, Section 5.2).
- InvalidTimestamp
- };
-
- Origin origin;
- VerificationStatus verificationStatus;
};
inline pkix::Result BufferToInput(const Buffer& buffer, pkix::Input& input)
{
return input.Init(buffer.begin(), buffer.length());
}
--- a/security/certverifier/tests/gtest/MultiLogCTVerifierTest.cpp
+++ b/security/certverifier/tests/gtest/MultiLogCTVerifierTest.cpp
@@ -28,37 +28,38 @@ public:
: 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())));
+ CTLogVerifier log;
+ ASSERT_EQ(Success, log.Init(InputForBuffer(GetTestPublicKey())));
+ ASSERT_EQ(Success, mVerifier.AddLog(Move(log)));
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)
+ void CheckForSingleValidSCTInResult(const CTVerifyResult& result,
+ VerifiedSCT::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);
+ ASSERT_EQ(1U, result.verifiedScts.length());
+ EXPECT_EQ(VerifiedSCT::Status::Valid, result.verifiedScts[0].status);
+ EXPECT_EQ(origin, result.verifiedScts[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));
@@ -80,18 +81,17 @@ public:
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);
+ CheckForSingleValidSCTInResult(result, VerifiedSCT::Origin::Embedded);
}
protected:
MultiLogCTVerifier mVerifier;
Buffer mTestCert;
Buffer mEmbeddedCert;
Buffer mCaCert;
Buffer mCaCertSPKI;
@@ -161,73 +161,66 @@ TEST_F(MultiLogCTVerifierTest, VerifiesS
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);
+ CheckForSingleValidSCTInResult(result, VerifiedSCT::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);
+ CheckForSingleValidSCTInResult(result, VerifiedSCT::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;
+ EnumSet<VerifiedSCT::Origin> origins;
+ for (const VerifiedSCT& verifiedSct : result.verifiedScts) {
+ EXPECT_EQ(VerifiedSCT::Status::Valid, verifiedSct.status);
+ origins += verifiedSct.origin;
}
- EXPECT_FALSE(
- origins.contains(SignedCertificateTimestamp::Origin::Embedded));
- EXPECT_TRUE(
- origins.contains(SignedCertificateTimestamp::Origin::OCSPResponse));
- EXPECT_TRUE(
- origins.contains(SignedCertificateTimestamp::Origin::TLSExtension));
+ EXPECT_FALSE(origins.contains(VerifiedSCT::Origin::Embedded));
+ EXPECT_TRUE(origins.contains(VerifiedSCT::Origin::OCSPResponse));
+ EXPECT_TRUE(origins.contains(VerifiedSCT::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);
+ ASSERT_EQ(1U, result.verifiedScts.length());
+ EXPECT_EQ(VerifiedSCT::Status::UnknownLog, result.verifiedScts[0].status);
}
} } // namespace mozilla::ct
--- a/security/manager/ssl/SSLServerCertVerification.cpp
+++ b/security/manager/ssl/SSLServerCertVerification.cpp
@@ -1222,52 +1222,52 @@ GatherSuccessfulValidationTelemetry(cons
{
GatherBaselineRequirementsTelemetry(certList);
GatherEKUTelemetry(certList);
GatherRootCATelemetry(certList);
GatherEndEntityTelemetry(certList);
}
void
-GatherTelemetryForSingleSCT(const ct::SignedCertificateTimestamp& sct)
+GatherTelemetryForSingleSCT(const ct::VerifiedSCT& verifiedSct)
{
// See SSL_SCTS_ORIGIN in Histograms.json.
uint32_t origin = 0;
- switch (sct.origin) {
- case ct::SignedCertificateTimestamp::Origin::Embedded:
+ switch (verifiedSct.origin) {
+ case ct::VerifiedSCT::Origin::Embedded:
origin = 1;
break;
- case ct::SignedCertificateTimestamp::Origin::TLSExtension:
+ case ct::VerifiedSCT::Origin::TLSExtension:
origin = 2;
break;
- case ct::SignedCertificateTimestamp::Origin::OCSPResponse:
+ case ct::VerifiedSCT::Origin::OCSPResponse:
origin = 3;
break;
default:
- MOZ_ASSERT_UNREACHABLE("Unexpected SCT::Origin type");
+ 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 (sct.verificationStatus) {
- case ct::SignedCertificateTimestamp::VerificationStatus::OK:
+ switch (verifiedSct.status) {
+ case ct::VerifiedSCT::Status::Valid:
verificationStatus = 1;
break;
- case ct::SignedCertificateTimestamp::VerificationStatus::UnknownLog:
+ case ct::VerifiedSCT::Status::UnknownLog:
verificationStatus = 2;
break;
- case ct::SignedCertificateTimestamp::VerificationStatus::InvalidSignature:
+ case ct::VerifiedSCT::Status::InvalidSignature:
verificationStatus = 3;
break;
- case ct::SignedCertificateTimestamp::VerificationStatus::InvalidTimestamp:
+ case ct::VerifiedSCT::Status::InvalidTimestamp:
verificationStatus = 4;
break;
default:
- MOZ_ASSERT_UNREACHABLE("Unexpected SCT::VerificationStatus type");
+ MOZ_ASSERT_UNREACHABLE("Unexpected VerifiedSCT::Status type");
}
Telemetry::Accumulate(Telemetry::SSL_SCTS_VERIFICATION_STATUS,
verificationStatus);
}
void
GatherCertificateTransparencyTelemetry(const UniqueCERTCertList& certList,
const CertificateTransparencyInfo& info)
@@ -1278,28 +1278,29 @@ GatherCertificateTransparencyTelemetry(c
}
if (!info.processedSCTs) {
// We didn't receive any SCT data for this connection.
Telemetry::Accumulate(Telemetry::SSL_SCTS_PER_CONNECTION, 0);
return;
}
- for (const ct::SignedCertificateTimestamp& sct : info.verifyResult.scts) {
+ for (const ct::VerifiedSCT& sct : info.verifyResult.verifiedScts) {
GatherTelemetryForSingleSCT(sct);
}
// 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);
}
// Handle the histogram of SCTs counts.
- uint32_t sctsCount = static_cast<uint32_t>(info.verifyResult.scts.length());
+ uint32_t sctsCount =
+ static_cast<uint32_t>(info.verifyResult.verifiedScts.length());
// Note that sctsCount can be 0 in case we've received SCT binary data,
// but it failed to parse (e.g. due to unsupported CT protocol version).
Telemetry::Accumulate(Telemetry::SSL_SCTS_PER_CONNECTION, sctsCount);
}
// Note: Takes ownership of |peerCertChain| if SECSuccess is not returned.
SECStatus
AuthCertificate(CertVerifier& certVerifier,
--- a/security/manager/ssl/nsSSLStatus.cpp
+++ b/security/manager/ssl/nsSSLStatus.cpp
@@ -1,21 +1,21 @@
/* -*- Mode: C++; tab-width: 2; 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 "CTVerifyResult.h"
#include "mozilla/Casting.h"
#include "nsSSLStatus.h"
#include "nsIClassInfoImpl.h"
#include "nsIObjectOutputStream.h"
#include "nsIObjectInputStream.h"
#include "nsNSSCertificate.h"
-#include "SignedCertificateTimestamp.h"
#include "ssl.h"
NS_IMETHODIMP
nsSSLStatus::GetServerCert(nsIX509Cert** aServerCert)
{
NS_ENSURE_ARG_POINTER(aServerCert);
nsCOMPtr<nsIX509Cert> cert = mServerCert;
@@ -325,53 +325,53 @@ nsSSLStatus::SetServerCert(nsNSSCertific
mIsEV = (aEVStatus == EVStatus::EV);
mHasIsEVStatus = true;
}
void
nsSSLStatus::SetCertificateTransparencyInfo(
const mozilla::psm::CertificateTransparencyInfo& info)
{
- using mozilla::ct::SignedCertificateTimestamp;
+ using mozilla::ct::VerifiedSCT;
if (!info.enabled) {
// CT disabled.
mCertificateTransparencyStatus =
nsISSLStatus::CERTIFICATE_TRANSPARENCY_NOT_APPLICABLE;
return;
}
if (!info.processedSCTs) {
// No SCTs processed on the connection.
mCertificateTransparencyStatus =
nsISSLStatus::CERTIFICATE_TRANSPARENCY_NONE;
return;
}
- bool hasOKSCTs = false;
+ bool hasValidSCTs = false;
bool hasUnknownLogSCTs = false;
bool hasInvalidSCTs = false;
- for (const SignedCertificateTimestamp& sct : info.verifyResult.scts) {
- switch (sct.verificationStatus) {
- case SignedCertificateTimestamp::VerificationStatus::OK:
- hasOKSCTs = true;
+ for (const VerifiedSCT& verifiedSct : info.verifyResult.verifiedScts) {
+ switch (verifiedSct.status) {
+ case VerifiedSCT::Status::Valid:
+ hasValidSCTs = true;
break;
- case SignedCertificateTimestamp::VerificationStatus::UnknownLog:
+ case VerifiedSCT::Status::UnknownLog:
hasUnknownLogSCTs = true;
break;
- case SignedCertificateTimestamp::VerificationStatus::InvalidSignature:
- case SignedCertificateTimestamp::VerificationStatus::InvalidTimestamp:
+ case VerifiedSCT::Status::InvalidSignature:
+ case VerifiedSCT::Status::InvalidTimestamp:
hasInvalidSCTs = true;
break;
default:
- MOZ_ASSERT_UNREACHABLE("Unexpected SCT::VerificationStatus type");
+ MOZ_ASSERT_UNREACHABLE("Unexpected VerifiedSCT::Status type");
}
}
- if (hasOKSCTs) {
+ if (hasValidSCTs) {
mCertificateTransparencyStatus =
nsISSLStatus::CERTIFICATE_TRANSPARENCY_OK;
} else if (hasUnknownLogSCTs) {
mCertificateTransparencyStatus =
nsISSLStatus::CERTIFICATE_TRANSPARENCY_UNKNOWN_LOG;
} else if (hasInvalidSCTs) {
mCertificateTransparencyStatus =
nsISSLStatus::CERTIFICATE_TRANSPARENCY_INVALID;