Commit f60b2a2b authored by Simon Zünd's avatar Simon Zünd Committed by Commit Bot

[devtools] Instrument Trust Token operations in network service

This CL adds a new "TrustTokenOperationResult" mojo structure that
is emitted in a new NetworkServiceClient event. The structure is used
to convey the exact operation status as well as additional
operation-dependent data to DevTools to allow better Trust Token
debugging.

Follow up CLs will pipe the event all the way through to the DevTools
network handler and instrument the redemption and signing operations.

R=davidvc@chromium.org

Bug: chromium:1126824
Change-Id: I04dd881a74221b3f96a9eea74e39b2d50c9ee20c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2513593
Commit-Queue: Simon Zünd <szuend@chromium.org>
Reviewed-by: default avatarSigurd Schneider <sigurds@chromium.org>
Reviewed-by: default avatarMatt Menke <mmenke@chromium.org>
Reviewed-by: default avatarDavid Van Cleve <davidvc@chromium.org>
Reviewed-by: default avatarMike West <mkwst@chromium.org>
Cr-Commit-Position: refs/heads/master@{#830530}
parent db709f04
...@@ -260,4 +260,13 @@ void NetworkServiceClient::OnCorsPreflightRequestCompleted( ...@@ -260,4 +260,13 @@ void NetworkServiceClient::OnCorsPreflightRequestCompleted(
process_id, render_frame_id, devtools_request_id, status); process_id, render_frame_id, devtools_request_id, status);
} }
void NetworkServiceClient::OnTrustTokenOperationDone(
int32_t process_id,
int32_t routing_id,
const std::string& devtools_request_id,
network::mojom::TrustTokenOperationResultPtr result) {
// TODO(crbug.com/1126824): Implement by forwarding to a
// devtools_instrumentation method.
}
} // namespace content } // namespace content
...@@ -81,6 +81,12 @@ class CONTENT_EXPORT NetworkServiceClient ...@@ -81,6 +81,12 @@ class CONTENT_EXPORT NetworkServiceClient
const base::UnguessableToken& devtool_request_id, const base::UnguessableToken& devtool_request_id,
const network::URLLoaderCompletionStatus& status) override; const network::URLLoaderCompletionStatus& status) override;
void OnTrustTokenOperationDone(
int32_t process_id,
int32_t routing_id,
const std::string& devtool_request_id,
network::mojom::TrustTokenOperationResultPtr result) override;
// net::CertDatabase::Observer implementation: // net::CertDatabase::Observer implementation:
void OnCertDBChanged() override; void OnCertDBChanged() override;
......
...@@ -106,6 +106,15 @@ interface NetworkServiceClient { ...@@ -106,6 +106,15 @@ interface NetworkServiceClient {
int32 render_frame_id, int32 render_frame_id,
mojo_base.mojom.UnguessableToken devtool_request_id, mojo_base.mojom.UnguessableToken devtool_request_id,
URLLoaderCompletionStatus status); URLLoaderCompletionStatus status);
// Called to send the result of a successful or failed Trust Token
// operation. Only called when |devtools_request_id| is available on the
// original request.
OnTrustTokenOperationDone(
int32 process_id,
int32 routing_id,
string devtool_request_id,
TrustTokenOperationResult result);
}; };
// Values for configuring HTTP authentication that can only be set once. // Values for configuring HTTP authentication that can only be set once.
......
...@@ -262,3 +262,18 @@ struct FulfillTrustTokenIssuanceAnswer { ...@@ -262,3 +262,18 @@ struct FulfillTrustTokenIssuanceAnswer {
// response header. Otherwise, its value is indeterminate. // response header. Otherwise, its value is indeterminate.
string response; string response;
}; };
// TrustTokenOperationResult contains all the information required by
// DevTools. Which fields are set depend on |type| and |status|.
struct TrustTokenOperationResult {
// Required.
TrustTokenOperationType type;
TrustTokenOperationStatus status;
// Shared among the different operation types.
url.mojom.Origin? issuer;
url.mojom.Origin? top_level_origin;
// In case of TrustTokenOperationType::kIssuance.
int32 issued_token_count = 0;
};
...@@ -65,4 +65,10 @@ void TestNetworkServiceClient::OnCorsPreflightRequestCompleted( ...@@ -65,4 +65,10 @@ void TestNetworkServiceClient::OnCorsPreflightRequestCompleted(
const base::UnguessableToken& devtool_request_id, const base::UnguessableToken& devtool_request_id,
const network::URLLoaderCompletionStatus& status) {} const network::URLLoaderCompletionStatus& status) {}
void TestNetworkServiceClient::OnTrustTokenOperationDone(
int32_t process_id,
int32_t routing_id,
const std::string& devtool_request_id,
network::mojom::TrustTokenOperationResultPtr result) {}
} // namespace network } // namespace network
...@@ -62,6 +62,11 @@ class TestNetworkServiceClient : public network::mojom::NetworkServiceClient { ...@@ -62,6 +62,11 @@ class TestNetworkServiceClient : public network::mojom::NetworkServiceClient {
int32_t routing_id, int32_t routing_id,
const base::UnguessableToken& devtool_request_id, const base::UnguessableToken& devtool_request_id,
const network::URLLoaderCompletionStatus& status) override; const network::URLLoaderCompletionStatus& status) override;
void OnTrustTokenOperationDone(
int32_t process_id,
int32_t routing_id,
const std::string& devtool_request_id,
network::mojom::TrustTokenOperationResultPtr result) override;
private: private:
mojo::Receiver<mojom::NetworkServiceClient> receiver_; mojo::Receiver<mojom::NetworkServiceClient> receiver_;
......
...@@ -47,4 +47,10 @@ void OperationTimingRequestHelperWrapper::FinishFinalize( ...@@ -47,4 +47,10 @@ void OperationTimingRequestHelperWrapper::FinishFinalize(
std::move(done).Run(status); std::move(done).Run(status);
} }
mojom::TrustTokenOperationResultPtr
OperationTimingRequestHelperWrapper::CollectOperationResultWithStatus(
mojom::TrustTokenOperationStatus status) {
return helper_->CollectOperationResultWithStatus(status);
}
} // namespace network } // namespace network
...@@ -32,6 +32,9 @@ class OperationTimingRequestHelperWrapper : public TrustTokenRequestHelper { ...@@ -32,6 +32,9 @@ class OperationTimingRequestHelperWrapper : public TrustTokenRequestHelper {
mojom::URLResponseHead* response, mojom::URLResponseHead* response,
base::OnceCallback<void(mojom::TrustTokenOperationStatus)> done) override; base::OnceCallback<void(mojom::TrustTokenOperationStatus)> done) override;
mojom::TrustTokenOperationResultPtr CollectOperationResultWithStatus(
mojom::TrustTokenOperationStatus status) override;
private: private:
// Records timing metrics, then calls the callback. // Records timing metrics, then calls the callback.
void FinishBegin( void FinishBegin(
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#define SERVICES_NETWORK_TRUST_TOKENS_TRUST_TOKEN_REQUEST_HELPER_H_ #define SERVICES_NETWORK_TRUST_TOKENS_TRUST_TOKEN_REQUEST_HELPER_H_
#include "base/callback_forward.h" #include "base/callback_forward.h"
#include "services/network/public/mojom/trust_tokens.mojom-shared.h" #include "services/network/public/mojom/trust_tokens.mojom.h"
#include "services/network/public/mojom/url_response_head.mojom-forward.h" #include "services/network/public/mojom/url_response_head.mojom-forward.h"
namespace net { namespace net {
...@@ -41,6 +41,12 @@ class TrustTokenRequestHelper { ...@@ -41,6 +41,12 @@ class TrustTokenRequestHelper {
virtual void Finalize( virtual void Finalize(
mojom::URLResponseHead* response, mojom::URLResponseHead* response,
base::OnceCallback<void(mojom::TrustTokenOperationStatus)> done) = 0; base::OnceCallback<void(mojom::TrustTokenOperationStatus)> done) = 0;
// Provides operation specific information to DevTools. The |status| of an
// operation is passed inline to the "done" callback and not stored on the
// helper. Thus, it always needs to be provided explicitly.
virtual mojom::TrustTokenOperationResultPtr CollectOperationResultWithStatus(
mojom::TrustTokenOperationStatus status) = 0;
}; };
} // namespace network } // namespace network
......
...@@ -321,9 +321,11 @@ void TrustTokenRequestIssuanceHelper::OnDelegateConfirmIssuanceCallComplete( ...@@ -321,9 +321,11 @@ void TrustTokenRequestIssuanceHelper::OnDelegateConfirmIssuanceCallComplete(
token_store_->AddTokens(*issuer_, base::make_span(maybe_tokens->tokens), token_store_->AddTokens(*issuer_, base::make_span(maybe_tokens->tokens),
maybe_tokens->body_of_verifying_key); maybe_tokens->body_of_verifying_key);
num_obtained_tokens_ = maybe_tokens->tokens.size();
net_log_.EndEvent( net_log_.EndEvent(
net::NetLogEventType::TRUST_TOKEN_OPERATION_FINALIZE_ISSUANCE, net::NetLogEventType::TRUST_TOKEN_OPERATION_FINALIZE_ISSUANCE,
[num_obtained_tokens = maybe_tokens->tokens.size()]() { [num_obtained_tokens = *num_obtained_tokens_]() {
base::Value ret = CreateLogValue("Success"); base::Value ret = CreateLogValue("Success");
ret.SetIntKey("# tokens obtained", num_obtained_tokens); ret.SetIntKey("# tokens obtained", num_obtained_tokens);
return ret; return ret;
...@@ -371,4 +373,21 @@ void TrustTokenRequestIssuanceHelper::DoneFinalizingLocallyFulfilledIssuance( ...@@ -371,4 +373,21 @@ void TrustTokenRequestIssuanceHelper::DoneFinalizingLocallyFulfilledIssuance(
std::move(done).Run(status); std::move(done).Run(status);
} }
mojom::TrustTokenOperationResultPtr
TrustTokenRequestIssuanceHelper::CollectOperationResultWithStatus(
mojom::TrustTokenOperationStatus status) {
mojom::TrustTokenOperationResultPtr operation_result =
mojom::TrustTokenOperationResult::New();
operation_result->status = status;
operation_result->type = mojom::TrustTokenOperationType::kIssuance;
operation_result->top_level_origin = top_level_origin_;
if (issuer_) {
operation_result->issuer = *issuer_;
}
if (num_obtained_tokens_) {
operation_result->issued_token_count = *num_obtained_tokens_;
}
return operation_result;
}
} // namespace network } // namespace network
...@@ -187,6 +187,9 @@ class TrustTokenRequestIssuanceHelper : public TrustTokenRequestHelper { ...@@ -187,6 +187,9 @@ class TrustTokenRequestIssuanceHelper : public TrustTokenRequestHelper {
struct CryptographerAndBlindedTokens; struct CryptographerAndBlindedTokens;
struct CryptographerAndUnblindedTokens; struct CryptographerAndUnblindedTokens;
mojom::TrustTokenOperationResultPtr CollectOperationResultWithStatus(
mojom::TrustTokenOperationStatus status) override;
private: private:
// Continuation of |Begin| after asynchronous key commitment fetching // Continuation of |Begin| after asynchronous key commitment fetching
// concludes. // concludes.
...@@ -275,6 +278,7 @@ class TrustTokenRequestIssuanceHelper : public TrustTokenRequestHelper { ...@@ -275,6 +278,7 @@ class TrustTokenRequestIssuanceHelper : public TrustTokenRequestHelper {
is_current_os_callback_; is_current_os_callback_;
net::NetLogWithSource net_log_; net::NetLogWithSource net_log_;
base::Optional<size_t> num_obtained_tokens_;
base::WeakPtrFactory<TrustTokenRequestIssuanceHelper> weak_ptr_factory_{this}; base::WeakPtrFactory<TrustTokenRequestIssuanceHelper> weak_ptr_factory_{this};
}; };
......
...@@ -261,4 +261,18 @@ TrustTokenRequestRedemptionHelper::RetrieveSingleToken() { ...@@ -261,4 +261,18 @@ TrustTokenRequestRedemptionHelper::RetrieveSingleToken() {
return matching_tokens.front(); return matching_tokens.front();
} }
mojom::TrustTokenOperationResultPtr
TrustTokenRequestRedemptionHelper::CollectOperationResultWithStatus(
mojom::TrustTokenOperationStatus status) {
mojom::TrustTokenOperationResultPtr operation_result =
mojom::TrustTokenOperationResult::New();
operation_result->status = status;
operation_result->type = mojom::TrustTokenOperationType::kRedemption;
operation_result->top_level_origin = top_level_origin_;
if (issuer_) {
operation_result->issuer = *issuer_;
}
return operation_result;
}
} // namespace network } // namespace network
...@@ -175,6 +175,9 @@ class TrustTokenRequestRedemptionHelper : public TrustTokenRequestHelper { ...@@ -175,6 +175,9 @@ class TrustTokenRequestRedemptionHelper : public TrustTokenRequestHelper {
mojom::URLResponseHead* response, mojom::URLResponseHead* response,
base::OnceCallback<void(mojom::TrustTokenOperationStatus)> done) override; base::OnceCallback<void(mojom::TrustTokenOperationStatus)> done) override;
mojom::TrustTokenOperationResultPtr CollectOperationResultWithStatus(
mojom::TrustTokenOperationStatus status) override;
private: private:
// Continuation of |Begin| after asynchronous key commitment fetching // Continuation of |Begin| after asynchronous key commitment fetching
// concludes. // concludes.
......
...@@ -604,4 +604,15 @@ TrustTokenRequestSigningHelper::GetSignature( ...@@ -604,4 +604,15 @@ TrustTokenRequestSigningHelper::GetSignature(
return signer_->Sign(key_bytes, base::make_span(signing_data)); return signer_->Sign(key_bytes, base::make_span(signing_data));
} }
mojom::TrustTokenOperationResultPtr
TrustTokenRequestSigningHelper::CollectOperationResultWithStatus(
mojom::TrustTokenOperationStatus status) {
mojom::TrustTokenOperationResultPtr operation_result =
mojom::TrustTokenOperationResult::New();
operation_result->status = status;
operation_result->type = mojom::TrustTokenOperationType::kRedemption;
operation_result->top_level_origin = params_.toplevel;
return operation_result;
}
} // namespace network } // namespace network
...@@ -215,6 +215,9 @@ class TrustTokenRequestSigningHelper : public TrustTokenRequestHelper { ...@@ -215,6 +215,9 @@ class TrustTokenRequestSigningHelper : public TrustTokenRequestHelper {
mojom::URLResponseHead* response, mojom::URLResponseHead* response,
base::OnceCallback<void(mojom::TrustTokenOperationStatus)> done) override; base::OnceCallback<void(mojom::TrustTokenOperationStatus)> done) override;
mojom::TrustTokenOperationResultPtr CollectOperationResultWithStatus(
mojom::TrustTokenOperationStatus status) override;
private: private:
// Given issuer-to-redemption-record and issuer-to-signature maps, returns a // Given issuer-to-redemption-record and issuer-to-signature maps, returns a
// Trust Tokens signature header, a serialized Structured Headers Draft 15 // Trust Tokens signature header, a serialized Structured Headers Draft 15
......
...@@ -843,6 +843,16 @@ void URLLoader::OnDoneConstructingTrustTokenHelper( ...@@ -843,6 +843,16 @@ void URLLoader::OnDoneConstructingTrustTokenHelper(
FROM_HERE, base::BindOnce(&URLLoader::NotifyCompleted, FROM_HERE, base::BindOnce(&URLLoader::NotifyCompleted,
weak_ptr_factory_.GetWeakPtr(), weak_ptr_factory_.GetWeakPtr(),
net::ERR_TRUST_TOKEN_OPERATION_FAILED)); net::ERR_TRUST_TOKEN_OPERATION_FAILED));
if (network_service_client_ && devtools_request_id()) {
mojom::TrustTokenOperationResultPtr operation_result =
mojom::TrustTokenOperationResult::New();
operation_result->status = *trust_token_status_;
operation_result->type = type;
network_service_client_->OnTrustTokenOperationDone(
GetProcessId(), GetRenderFrameId(), devtools_request_id().value(),
std::move(operation_result));
}
return; return;
} }
...@@ -857,6 +867,14 @@ void URLLoader::OnDoneConstructingTrustTokenHelper( ...@@ -857,6 +867,14 @@ void URLLoader::OnDoneConstructingTrustTokenHelper(
void URLLoader::OnDoneBeginningTrustTokenOperation( void URLLoader::OnDoneBeginningTrustTokenOperation(
mojom::TrustTokenOperationStatus status) { mojom::TrustTokenOperationStatus status) {
trust_token_status_ = status; trust_token_status_ = status;
// In case the operation failed or we hit the cache, the DevTools event is
// emitted from here. Otherwise the DevTools event is always emitted from
// |OnDoneFinalizeTrustTokenOperation|.
if (status != mojom::TrustTokenOperationStatus::kOk) {
MaybeSendTrustTokenOperationResultToDevTools();
}
if (status == mojom::TrustTokenOperationStatus::kOk) { if (status == mojom::TrustTokenOperationStatus::kOk) {
ScheduleStart(); ScheduleStart();
} else if (status == mojom::TrustTokenOperationStatus::kAlreadyExists) { } else if (status == mojom::TrustTokenOperationStatus::kAlreadyExists) {
...@@ -1257,6 +1275,8 @@ void URLLoader::OnDoneFinalizingTrustTokenOperation( ...@@ -1257,6 +1275,8 @@ void URLLoader::OnDoneFinalizingTrustTokenOperation(
mojom::TrustTokenOperationStatus status) { mojom::TrustTokenOperationStatus status) {
trust_token_status_ = status; trust_token_status_ = status;
MaybeSendTrustTokenOperationResultToDevTools();
if (status != mojom::TrustTokenOperationStatus::kOk) { if (status != mojom::TrustTokenOperationStatus::kOk) {
NotifyCompleted(net::ERR_TRUST_TOKEN_OPERATION_FAILED); NotifyCompleted(net::ERR_TRUST_TOKEN_OPERATION_FAILED);
// |this| may have been deleted. // |this| may have been deleted.
...@@ -1265,6 +1285,20 @@ void URLLoader::OnDoneFinalizingTrustTokenOperation( ...@@ -1265,6 +1285,20 @@ void URLLoader::OnDoneFinalizingTrustTokenOperation(
ContinueOnResponseStarted(); ContinueOnResponseStarted();
} }
void URLLoader::MaybeSendTrustTokenOperationResultToDevTools() {
CHECK(trust_token_helper_ && trust_token_status_);
if (!network_service_client_ || !devtools_request_id())
return;
mojom::TrustTokenOperationResultPtr operation_result =
trust_token_helper_->CollectOperationResultWithStatus(
*trust_token_status_);
network_service_client_->OnTrustTokenOperationDone(
GetProcessId(), GetRenderFrameId(), devtools_request_id().value(),
std::move(operation_result));
}
void URLLoader::ContinueOnResponseStarted() { void URLLoader::ContinueOnResponseStarted() {
MojoCreateDataPipeOptions options; MojoCreateDataPipeOptions options;
options.struct_size = sizeof(MojoCreateDataPipeOptions); options.struct_size = sizeof(MojoCreateDataPipeOptions);
......
...@@ -293,6 +293,7 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) URLLoader ...@@ -293,6 +293,7 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) URLLoader
// Continuation of |OnResponseStarted| after possibly asynchronously // Continuation of |OnResponseStarted| after possibly asynchronously
// concluding the request's Trust Tokens operation. // concluding the request's Trust Tokens operation.
void ContinueOnResponseStarted(); void ContinueOnResponseStarted();
void MaybeSendTrustTokenOperationResultToDevTools();
void ScheduleStart(); void ScheduleStart();
void ReadMore(); void ReadMore();
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment