Add netlogs for 1-QWAC verification
Bug: 392931068 Change-Id: I5b77727e7b4b8f638c5f4814085557a4d9edd26e Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6330879 Reviewed-by: Nick Harper <nharper@chromium.org> Commit-Queue: Matt Mueller <mattm@chromium.org> Cr-Commit-Position: refs/heads/main@{#1431682}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
1063f78a04
commit
3d56577f8a
@ -734,19 +734,34 @@ class PathBuilderDelegateImpl : public bssl::SimplePathBuilderDelegate {
|
||||
|
||||
class QwacPathBuilderDelegateImpl : public bssl::SimplePathBuilderDelegate {
|
||||
public:
|
||||
// TODO(crbug.com/392931068): netlogs
|
||||
QwacPathBuilderDelegateImpl()
|
||||
explicit QwacPathBuilderDelegateImpl(const NetLogWithSource& net_log)
|
||||
: bssl::SimplePathBuilderDelegate(
|
||||
kMinRsaModulusLengthBits,
|
||||
bssl::SimplePathBuilderDelegate::DigestPolicy::kStrong) {}
|
||||
bssl::SimplePathBuilderDelegate::DigestPolicy::kStrong),
|
||||
net_log_(net_log) {}
|
||||
|
||||
void CheckPathAfterVerification(
|
||||
const bssl::CertPathBuilder& path_builder,
|
||||
bssl::CertPathBuilderResultPath* path) override {
|
||||
net_log_->BeginEvent(NetLogEventType::CERT_VERIFY_PROC_PATH_BUILT);
|
||||
|
||||
if (!Has1QwacPolicies(path->user_constrained_policy_set)) {
|
||||
path->errors.GetErrorsForCert(0)->AddError(kPathLacksQwacPolicy);
|
||||
}
|
||||
|
||||
net_log_->EndEvent(NetLogEventType::CERT_VERIFY_PROC_PATH_BUILT,
|
||||
[&] { return NetLogPathBuilderResultPath(*path); });
|
||||
}
|
||||
|
||||
bool IsDebugLogEnabled() override { return net_log_->IsCapturing(); }
|
||||
|
||||
void DebugLog(std::string_view msg) override {
|
||||
net_log_->AddEventWithStringParams(
|
||||
NetLogEventType::CERT_VERIFY_PROC_PATH_BUILDER_DEBUG, "debug", msg);
|
||||
}
|
||||
|
||||
private:
|
||||
raw_ref<const NetLogWithSource> net_log_;
|
||||
};
|
||||
|
||||
std::shared_ptr<const bssl::ParsedCertificate> ParseCertificateFromBuffer(
|
||||
@ -782,7 +797,8 @@ class CertVerifyProcBuiltin : public CertVerifyProc {
|
||||
#if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
|
||||
void MaybeVerify1QWAC(const bssl::CertPathBuilderResultPath* verified_path,
|
||||
const bssl::der::GeneralizedTime& der_verification_time,
|
||||
CertVerifyResult* verify_result);
|
||||
CertVerifyResult* verify_result,
|
||||
const NetLogWithSource& net_log);
|
||||
#endif
|
||||
|
||||
const scoped_refptr<CertNetFetcher> net_fetcher_;
|
||||
@ -1444,7 +1460,7 @@ int CertVerifyProcBuiltin::VerifyInternal(X509Certificate* input_cert,
|
||||
cur_attempt.use_system_time
|
||||
? der_verification_system_time
|
||||
: der_verification_custom_time,
|
||||
verify_result);
|
||||
verify_result, net_log);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -1455,10 +1471,10 @@ int CertVerifyProcBuiltin::VerifyInternal(X509Certificate* input_cert,
|
||||
void CertVerifyProcBuiltin::MaybeVerify1QWAC(
|
||||
const bssl::CertPathBuilderResultPath* verified_path,
|
||||
const bssl::der::GeneralizedTime& der_verification_time,
|
||||
CertVerifyResult* verify_result) {
|
||||
CertVerifyResult* verify_result,
|
||||
const NetLogWithSource& net_log) {
|
||||
CHECK(verified_path);
|
||||
CHECK(verified_path->IsValid());
|
||||
// TODO(crbug.com/392931068): netlogs
|
||||
// TODO(crbug.com/392931068): histograms
|
||||
|
||||
const std::shared_ptr<const bssl::ParsedCertificate>& target =
|
||||
@ -1505,7 +1521,13 @@ void CertVerifyProcBuiltin::MaybeVerify1QWAC(
|
||||
bssl::der::Input(bssl::kAnyPolicyOid)};
|
||||
// TODO(crbug.com/392931068): does not implement deadlines (right now there is
|
||||
// no OS or network interaction, so this should be fine.)
|
||||
QwacPathBuilderDelegateImpl path_builder_delegate;
|
||||
QwacPathBuilderDelegateImpl path_builder_delegate(net_log);
|
||||
|
||||
net_log.BeginEvent(NetLogEventType::CERT_VERIFY_PROC_PATH_BUILD_ATTEMPT, [&] {
|
||||
base::Value::Dict results;
|
||||
results.Set("is_qwac_attempt", true);
|
||||
return results;
|
||||
});
|
||||
|
||||
// Initialize the path builder.
|
||||
bssl::CertPathBuilder path_builder(
|
||||
@ -1520,6 +1542,9 @@ void CertVerifyProcBuiltin::MaybeVerify1QWAC(
|
||||
path_builder.SetIterationLimit(kPathBuilderIterationLimit);
|
||||
qwac_result = path_builder.Run();
|
||||
|
||||
net_log.EndEvent(NetLogEventType::CERT_VERIFY_PROC_PATH_BUILD_ATTEMPT,
|
||||
[&] { return NetLogPathBuilderResult(qwac_result); });
|
||||
|
||||
if (!qwac_result.HasValidPath()) {
|
||||
return;
|
||||
}
|
||||
|
@ -110,6 +110,32 @@ static std::string MakeRandomPath(std::string_view suffix) {
|
||||
return "/" + MakeRandomHexString(12) + std::string(suffix);
|
||||
}
|
||||
|
||||
#if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
|
||||
std::vector<std::string> ParseNetLogCertificatesList(
|
||||
const base::Value::List& list) {
|
||||
std::vector<std::string> result;
|
||||
for (const auto& pem_value : list) {
|
||||
if (!pem_value.is_string()) {
|
||||
result.push_back("Value is not a string");
|
||||
continue;
|
||||
}
|
||||
CertificateList certs = X509Certificate::CreateCertificateListFromBytes(
|
||||
base::as_byte_span(pem_value.GetString()),
|
||||
X509Certificate::Format::FORMAT_PEM_CERT_SEQUENCE);
|
||||
if (certs.empty()) {
|
||||
result.push_back("error decoding pem");
|
||||
continue;
|
||||
}
|
||||
if (certs.size() > 1) {
|
||||
result.push_back("multiple certs in pem");
|
||||
continue;
|
||||
}
|
||||
result.emplace_back(base::as_string_view(certs[0]->cert_span()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endif // BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
|
||||
|
||||
int VerifyOnWorkerThread(const scoped_refptr<CertVerifyProc>& verify_proc,
|
||||
scoped_refptr<X509Certificate> cert,
|
||||
const std::string& hostname,
|
||||
@ -1887,7 +1913,7 @@ class CertVerifyProcBuiltin1QwacTest
|
||||
};
|
||||
|
||||
TEST_P(CertVerifyProcBuiltin1QwacTest, OneQwacRequiresEutl) {
|
||||
// TODO(crbug.com/392931068): test netlogs, histograms
|
||||
// TODO(crbug.com/392931068): test histograms
|
||||
auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
|
||||
// intermediate->SetCertificatePolicies({"2.5.29.32.0"}); // anyPolicy
|
||||
|
||||
@ -2054,6 +2080,7 @@ TEST_P(CertVerifyProcBuiltin1QwacTest, OneQwacCanBuildAlternatePath) {
|
||||
intermediate->GetSubjectKeyIdentifier());
|
||||
AddMockEutlRoot(eutl_intermediate.GetCertBuffer());
|
||||
|
||||
RecordingNetLogObserver net_log_observer(NetLogCaptureMode::kDefault);
|
||||
CertVerifyResult verify_result;
|
||||
NetLogSource verify_net_log_source;
|
||||
TestCompletionCallback callback;
|
||||
@ -2072,7 +2099,86 @@ TEST_P(CertVerifyProcBuiltin1QwacTest, OneQwacCanBuildAlternatePath) {
|
||||
verify_result.verified_cert->intermediate_buffers()[0].get());
|
||||
EXPECT_EQ(root->GetCertBuffer(),
|
||||
verify_result.verified_cert->intermediate_buffers()[1].get());
|
||||
// TODO(crbug.com/392931068): test that the eutl chain was netlogged
|
||||
|
||||
auto events = net_log_observer.GetEntriesForSource(verify_net_log_source);
|
||||
|
||||
auto event = std::ranges::find(
|
||||
events, NetLogEventType::CERT_VERIFY_PROC_PATH_BUILD_ATTEMPT,
|
||||
&NetLogEntry::type);
|
||||
ASSERT_NE(event, events.end());
|
||||
EXPECT_EQ(net::NetLogEventPhase::BEGIN, event->phase);
|
||||
EXPECT_EQ(std::nullopt, event->params.FindBool("is_qwac_attempt"));
|
||||
|
||||
event = std::ranges::find(++event, events.end(),
|
||||
NetLogEventType::CERT_VERIFY_PROC_PATH_BUILT,
|
||||
&NetLogEntry::type);
|
||||
ASSERT_NE(event, events.end());
|
||||
EXPECT_EQ(net::NetLogEventPhase::BEGIN, event->phase);
|
||||
|
||||
event = std::ranges::find(++event, events.end(),
|
||||
NetLogEventType::CERT_VERIFY_PROC_PATH_BUILT,
|
||||
&NetLogEntry::type);
|
||||
ASSERT_NE(event, events.end());
|
||||
EXPECT_EQ(net::NetLogEventPhase::END, event->phase);
|
||||
EXPECT_EQ(true, event->params.FindBool("is_valid"));
|
||||
base::Value::List* pem_certs = event->params.FindList("certificates");
|
||||
ASSERT_TRUE(pem_certs);
|
||||
// The CERT_VERIFY_PROC_PATH_BUILT netlog for the main verification should
|
||||
// contain the TLS cert chain.
|
||||
EXPECT_THAT(ParseNetLogCertificatesList(*pem_certs),
|
||||
testing::ElementsAre(leaf->GetDER(), intermediate->GetDER(),
|
||||
root->GetDER()));
|
||||
|
||||
event = std::ranges::find(
|
||||
++event, events.end(),
|
||||
NetLogEventType::CERT_VERIFY_PROC_PATH_BUILD_ATTEMPT, &NetLogEntry::type);
|
||||
ASSERT_NE(event, events.end());
|
||||
EXPECT_EQ(net::NetLogEventPhase::END, event->phase);
|
||||
EXPECT_EQ(true, event->params.FindBool("has_valid_path"));
|
||||
|
||||
event = std::ranges::find(
|
||||
++event, events.end(),
|
||||
NetLogEventType::CERT_VERIFY_PROC_PATH_BUILD_ATTEMPT, &NetLogEntry::type);
|
||||
if (!GetParam()) {
|
||||
// If the feature flag wasn't enabled, there should only be one
|
||||
// CERT_VERIFY_PROC_PATH_BUILD_ATTEMPT.
|
||||
ASSERT_EQ(event, events.end());
|
||||
return;
|
||||
}
|
||||
ASSERT_NE(event, events.end());
|
||||
EXPECT_EQ(net::NetLogEventPhase::BEGIN, event->phase);
|
||||
EXPECT_EQ(true, event->params.FindBool("is_qwac_attempt"));
|
||||
|
||||
event = std::ranges::find(++event, events.end(),
|
||||
NetLogEventType::CERT_VERIFY_PROC_PATH_BUILT,
|
||||
&NetLogEntry::type);
|
||||
ASSERT_NE(event, events.end());
|
||||
EXPECT_EQ(net::NetLogEventPhase::BEGIN, event->phase);
|
||||
|
||||
event = std::ranges::find(++event, events.end(),
|
||||
NetLogEventType::CERT_VERIFY_PROC_PATH_BUILT,
|
||||
&NetLogEntry::type);
|
||||
ASSERT_NE(event, events.end());
|
||||
EXPECT_EQ(net::NetLogEventPhase::END, event->phase);
|
||||
EXPECT_EQ(true, event->params.FindBool("is_valid"));
|
||||
pem_certs = event->params.FindList("certificates");
|
||||
ASSERT_TRUE(pem_certs);
|
||||
// The CERT_VERIFY_PROC_PATH_BUILT netlog for the 1-QWAC verification should
|
||||
// contain the QWAC cert chain.
|
||||
EXPECT_THAT(ParseNetLogCertificatesList(*pem_certs),
|
||||
testing::ElementsAre(leaf->GetDER(), eutl_intermediate.GetDER()));
|
||||
|
||||
event = std::ranges::find(
|
||||
++event, events.end(),
|
||||
NetLogEventType::CERT_VERIFY_PROC_PATH_BUILD_ATTEMPT, &NetLogEntry::type);
|
||||
ASSERT_NE(event, events.end());
|
||||
EXPECT_EQ(net::NetLogEventPhase::END, event->phase);
|
||||
EXPECT_EQ(true, event->params.FindBool("has_valid_path"));
|
||||
|
||||
event = std::ranges::find(
|
||||
++event, events.end(),
|
||||
NetLogEventType::CERT_VERIFY_PROC_PATH_BUILD_ATTEMPT, &NetLogEntry::type);
|
||||
ASSERT_EQ(event, events.end());
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(, CertVerifyProcBuiltin1QwacTest, testing::Bool());
|
||||
|
@ -3873,6 +3873,7 @@ EVENT_TYPE(CERT_VERIFY_PROC_ADDITIONAL_CERT)
|
||||
// "digest_policy": <Specifies which digest methods are accepted in this
|
||||
// attempt.>
|
||||
// "is_ev_attempt": <True if this is an EV verification attempt.>
|
||||
// "is_qwac_attempt": <True if this is a QWAC verification attempt.>
|
||||
// "is_network_time_attempt": <True if this attempt used the network time.>
|
||||
// "network_time_value": <Int - time in milliseconds since the unix epoch,
|
||||
// only populated if is_network_time_attempt is
|
||||
|
Reference in New Issue
Block a user