1 // Copyright 2020 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef SERVICES_NETWORK_TRUST_TOKENS_TRUST_TOKEN_KEY_COMMITMENT_CONTROLLER_H_ 6 #define SERVICES_NETWORK_TRUST_TOKENS_TRUST_TOKEN_KEY_COMMITMENT_CONTROLLER_H_ 7 8 #include <memory> 9 #include <vector> 10 11 #include "base/callback.h" 12 #include "base/memory/weak_ptr.h" 13 #include "base/strings/string_piece_forward.h" 14 #include "services/network/public/cpp/simple_url_loader.h" 15 #include "services/network/public/mojom/trust_tokens.mojom-forward.h" 16 #include "url/gurl.h" 17 18 namespace mojom { 19 class URLLoaderFactory; 20 class URLResponseHead; 21 } // namespace mojom 22 23 namespace net { 24 struct NetworkTrafficAnnotationTag; 25 struct RedirectInfo; 26 class URLRequest; 27 } // namespace net 28 29 namespace network { 30 31 namespace internal { 32 33 // Creates a key commitment request for the given issuance 34 // or redemption request: 35 // 1. sets the LOAD_BYPASS_CACHE and LOAD_DISABLE_CACHE flags, 36 // so that the result doesn't check the cache and isn't cached itself 37 // 2. sets the URL to kTrustTokenKeyCommitmentWellKnownPath, resolved 38 // relative to the issuance or redemption origin 39 // 3. sets the key commitment request to be uncredentialed 40 // 4. copies |request|'s initiator to the key commitment request 41 // 5. sets the key commitment request's Origin header to equal |request|'s 42 // top-level origin. (This is so servers can make a decision about whether to 43 // reject issuance or redemption early, by making a general decision about 44 // whether they want to issue/redeem on the provided top-level origin.) 45 std::unique_ptr<ResourceRequest> CreateTrustTokenKeyCommitmentRequest( 46 const net::URLRequest& request, 47 const url::Origin& top_level_origin); 48 49 } // namespace internal 50 51 // TrustTokenKeyCommitmentController executes a single Trust Tokens key 52 // commitment request. 53 // 54 // This is an uncredentialed request to the above .well-known path 55 // relative to the origin of the Trust Tokens issuer involved in an issuance or 56 // redemption's origin; the request expects a key commitment response of the 57 // format defined in the Privacy Pass draft spec: 58 // https://github.com/alxdavids/draft-privacy-pass/blob/master/draft-privacy-pass.md. 59 // 60 // Lifetime: These are expected to be constructed when the client 61 // wishes to execute a request and destroyed immediately after the client 62 // receives its result. 63 class TrustTokenKeyCommitmentController final { 64 public: 65 // Class Parser parses HTTP response bodies obtained from key commitment 66 // registry queries. 67 class Parser { 68 public: 69 virtual ~Parser() = default; 70 virtual mojom::TrustTokenKeyCommitmentResultPtr Parse( 71 base::StringPiece response_body) = 0; 72 }; 73 74 // Constructor. Immediately starts a request: 75 // 1. builds a key commitment request using metadata from |request| (along 76 // with |top_level_origin|, which must be |request|'s initiating top level 77 // frame's origin); 78 // 2. uses |loader_factory| to send the key commitment request to 79 // |kTrustTokenKeyCommitmentWellKnownPath|, resolved relative to |request|'s 80 // origin; 81 // 3. uses |parser| to parse the result; 82 // 4. on completion or error, calls |completion_callback| with an error code 83 // and, if successful, a result. 84 struct Status { 85 enum class Value { 86 // There was an error parsing the key commitment endpoint's response. In 87 // particular, this occurs if servers deliberately return an empty or 88 // malformed response to short-circuit issuance or redemption. 89 kCouldntParse, 90 // The key commitment endpoint responded with a redirect, which is not 91 // permitted. 92 kGotRedirected, 93 // Success. 94 kOk, 95 // Connection error (|net_error| contains the specific error code). 96 kNetworkError, 97 } value; 98 int net_error; 99 }; 100 TrustTokenKeyCommitmentController( 101 base::OnceCallback<void(Status status, 102 mojom::TrustTokenKeyCommitmentResultPtr result)> 103 completion_callback, 104 const net::URLRequest& request, 105 const url::Origin& top_level_origin, 106 const net::NetworkTrafficAnnotationTag& traffic_annotation, 107 mojom::URLLoaderFactory* loader_factory, 108 std::unique_ptr<Parser> parser); 109 110 TrustTokenKeyCommitmentController(const TrustTokenKeyCommitmentController&) = 111 delete; 112 TrustTokenKeyCommitmentController& operator=( 113 const TrustTokenKeyCommitmentController&) = delete; 114 115 ~TrustTokenKeyCommitmentController(); 116 117 private: 118 void StartRequest(mojom::URLLoaderFactory* loader_factory); 119 120 // Callbacks provided to |url_loader_|: 121 122 // On redirect, fails (key commitment endpoints must not redirect 123 // their clients). 124 void HandleRedirect(const net::RedirectInfo& redirect_info, 125 const mojom::URLResponseHead& response_head, 126 std::vector<std::string>* to_be_removed_headers); 127 128 // On completion, parses the given response (if the request was 129 // successful). Calls |completion_callback_| with an error 130 void HandleResponseBody(std::unique_ptr<std::string> response_body); 131 132 // |url_loader_| performs the actual key commitment request. 133 std::unique_ptr<SimpleURLLoader> url_loader_; 134 135 // Parses the key commitment response if one is received. 136 std::unique_ptr<Parser> parser_; 137 138 base::OnceCallback<void(Status status, 139 mojom::TrustTokenKeyCommitmentResultPtr result)> 140 completion_callback_; 141 }; 142 143 } // namespace network 144 145 #endif // SERVICES_NETWORK_TRUST_TOKENS_TRUST_TOKEN_KEY_COMMITMENT_CONTROLLER_H_ 146