Result MultiLogCTVerifier::AddLog(Input publicKey) { 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::VerifySingleSCT(SignedCertificateTimestamp&& sct, const LogEntry& expectedEntry, Time time, CTVerifyResult& result) { CTLogVerifier* matchingLog = nullptr; for (auto& log : mLogs) { if (log.keyId() == sct.logId) { matchingLog = &log; break; } } if (!matchingLog) { // SCT does not match any known log. return StoreVerifiedSct(result, Move(sct), SignedCertificateTimestamp::VerificationStatus::UnknownLog); } if (!matchingLog->SignatureParametersMatch(sct.signature)) { // SCT signature parameters do not match the log's. return StoreVerifiedSct(result, Move(sct), SignedCertificateTimestamp::VerificationStatus::InvalidSignature); } Result rv = matchingLog->Verify(expectedEntry, sct); if (rv != Success) { if (rv == Result::ERROR_BAD_SIGNATURE) { return StoreVerifiedSct(result, Move(sct), SignedCertificateTimestamp::VerificationStatus::InvalidSignature); } return rv; } // |sct.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. if (sctTime > time) { return StoreVerifiedSct(result, Move(sct), SignedCertificateTimestamp::VerificationStatus::InvalidTimestamp); } return StoreVerifiedSct(result, Move(sct), SignedCertificateTimestamp::VerificationStatus::OK); }
Result MultiLogCTVerifier::VerifySingleSCT(SignedCertificateTimestamp&& sct, const LogEntry& expectedEntry, uint64_t time, CTVerifyResult& result) { CTLogVerifier* matchingLog = nullptr; for (auto& log : mLogs) { if (log.keyId() == sct.logId) { matchingLog = &log; break; } } if (!matchingLog) { // SCT does not match any known log. return StoreVerifiedSct(result, Move(sct), SCTVerifyStatus::UnknownLog); } if (!matchingLog->SignatureParametersMatch(sct.signature)) { // SCT signature parameters do not match the log's. return StoreVerifiedSct(result, Move(sct), SCTVerifyStatus::Invalid); } Result rv = matchingLog->Verify(expectedEntry, sct); if (rv != Success) { if (rv == Result::ERROR_BAD_SIGNATURE) { return StoreVerifiedSct(result, Move(sct), SCTVerifyStatus::Invalid); } return rv; } // SCT verified ok, just make sure the timestamp is legitimate. if (sct.timestamp > time) { return StoreVerifiedSct(result, Move(sct), SCTVerifyStatus::Invalid); } return StoreVerifiedSct(result, Move(sct), SCTVerifyStatus::OK); }