OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/common/origin_trials/trial_token_validator.h" | 5 #include "content/common/origin_trials/trial_token_validator.h" |
6 | 6 |
7 #include "base/feature_list.h" | 7 #include "base/feature_list.h" |
8 #include "base/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" |
9 #include "base/time/time.h" | 9 #include "base/time/time.h" |
10 #include "content/common/origin_trials/trial_token.h" | 10 #include "content/common/origin_trials/trial_token.h" |
11 #include "content/public/common/content_client.h" | 11 #include "content/public/common/content_client.h" |
12 #include "content/public/common/content_features.h" | 12 #include "content/public/common/content_features.h" |
13 #include "content/public/common/origin_trial_policy.h" | 13 #include "content/public/common/origin_trial_policy.h" |
14 #include "content/public/common/origin_util.h" | 14 #include "content/public/common/origin_util.h" |
15 #include "net/http/http_response_headers.h" | 15 #include "net/http/http_response_headers.h" |
16 #include "net/url_request/url_request.h" | 16 #include "net/url_request/url_request.h" |
17 #include "third_party/WebKit/public/platform/WebOriginTrialTokenStatus.h" | 17 #include "third_party/WebKit/public/platform/WebOriginTrialTokenStatus.h" |
18 | 18 |
19 namespace content { | 19 namespace content { |
20 | 20 |
21 blink::WebOriginTrialTokenStatus TrialTokenValidator::ValidateToken( | 21 blink::WebOriginTrialTokenStatus TrialTokenValidator::ValidateToken( |
22 const std::string& token, | 22 const std::string& token, |
23 const url::Origin& origin, | 23 const url::Origin& origin, |
24 std::string* feature_name) { | 24 std::string* feature_name, |
| 25 base::Time current_time) { |
25 ContentClient* content_client = GetContentClient(); | 26 ContentClient* content_client = GetContentClient(); |
26 const OriginTrialPolicy* origin_trial_policy = | 27 const OriginTrialPolicy* origin_trial_policy = |
27 content_client->GetOriginTrialPolicy(); | 28 content_client->GetOriginTrialPolicy(); |
28 if (!origin_trial_policy) | 29 if (!origin_trial_policy) |
29 return blink::WebOriginTrialTokenStatus::kNotSupported; | 30 return blink::WebOriginTrialTokenStatus::kNotSupported; |
30 | 31 |
31 // TODO(iclelland): Allow for multiple signing keys, and iterate over all | 32 // TODO(iclelland): Allow for multiple signing keys, and iterate over all |
32 // active keys here. https://crbug.com/543220 | 33 // active keys here. https://crbug.com/543220 |
33 base::StringPiece public_key = origin_trial_policy->GetPublicKey(); | 34 base::StringPiece public_key = origin_trial_policy->GetPublicKey(); |
34 if (public_key.empty()) | 35 if (public_key.empty()) |
35 return blink::WebOriginTrialTokenStatus::kNotSupported; | 36 return blink::WebOriginTrialTokenStatus::kNotSupported; |
36 | 37 |
37 blink::WebOriginTrialTokenStatus status; | 38 blink::WebOriginTrialTokenStatus status; |
38 std::unique_ptr<TrialToken> trial_token = | 39 std::unique_ptr<TrialToken> trial_token = |
39 TrialToken::From(token, public_key, &status); | 40 TrialToken::From(token, public_key, &status); |
40 if (status != blink::WebOriginTrialTokenStatus::kSuccess) | 41 if (status != blink::WebOriginTrialTokenStatus::kSuccess) |
41 return status; | 42 return status; |
42 | 43 |
43 status = trial_token->IsValid(origin, base::Time::Now()); | 44 status = trial_token->IsValid(origin, current_time); |
44 if (status != blink::WebOriginTrialTokenStatus::kSuccess) | 45 if (status != blink::WebOriginTrialTokenStatus::kSuccess) |
45 return status; | 46 return status; |
46 | 47 |
47 if (origin_trial_policy->IsFeatureDisabled(trial_token->feature_name())) | 48 if (origin_trial_policy->IsFeatureDisabled(trial_token->feature_name())) |
48 return blink::WebOriginTrialTokenStatus::kFeatureDisabled; | 49 return blink::WebOriginTrialTokenStatus::kFeatureDisabled; |
49 | 50 |
50 if (origin_trial_policy->IsTokenDisabled(trial_token->signature())) | 51 if (origin_trial_policy->IsTokenDisabled(trial_token->signature())) |
51 return blink::WebOriginTrialTokenStatus::kTokenDisabled; | 52 return blink::WebOriginTrialTokenStatus::kTokenDisabled; |
52 | 53 |
53 *feature_name = trial_token->feature_name(); | 54 *feature_name = trial_token->feature_name(); |
54 return blink::WebOriginTrialTokenStatus::kSuccess; | 55 return blink::WebOriginTrialTokenStatus::kSuccess; |
55 } | 56 } |
56 | 57 |
57 bool TrialTokenValidator::RequestEnablesFeature( | 58 bool TrialTokenValidator::RequestEnablesFeature(const net::URLRequest* request, |
58 const net::URLRequest* request, | 59 base::StringPiece feature_name, |
59 base::StringPiece feature_name) { | 60 base::Time current_time) { |
60 // TODO(mek): Possibly cache the features that are availble for request in | 61 // TODO(mek): Possibly cache the features that are availble for request in |
61 // UserData associated with the request. | 62 // UserData associated with the request. |
62 return RequestEnablesFeature(request->url(), request->response_headers(), | 63 return RequestEnablesFeature(request->url(), request->response_headers(), |
63 feature_name); | 64 feature_name, current_time); |
64 } | 65 } |
65 | 66 |
66 bool TrialTokenValidator::RequestEnablesFeature( | 67 bool TrialTokenValidator::RequestEnablesFeature( |
67 const GURL& request_url, | 68 const GURL& request_url, |
68 const net::HttpResponseHeaders* response_headers, | 69 const net::HttpResponseHeaders* response_headers, |
69 base::StringPiece feature_name) { | 70 base::StringPiece feature_name, |
| 71 base::Time current_time) { |
70 if (!base::FeatureList::IsEnabled(features::kOriginTrials)) | 72 if (!base::FeatureList::IsEnabled(features::kOriginTrials)) |
71 return false; | 73 return false; |
72 | 74 |
73 if (!IsOriginSecure(request_url)) | 75 if (!IsOriginSecure(request_url)) |
74 return false; | 76 return false; |
75 | 77 |
76 url::Origin origin(request_url); | 78 url::Origin origin(request_url); |
77 size_t iter = 0; | 79 size_t iter = 0; |
78 std::string token; | 80 std::string token; |
79 while (response_headers->EnumerateHeader(&iter, "Origin-Trial", &token)) { | 81 while (response_headers->EnumerateHeader(&iter, "Origin-Trial", &token)) { |
80 std::string token_feature; | 82 std::string token_feature; |
81 // TODO(mek): Log the validation errors to histograms? | 83 // TODO(mek): Log the validation errors to histograms? |
82 if (ValidateToken(token, origin, &token_feature) == | 84 if (ValidateToken(token, origin, &token_feature, current_time) == |
83 blink::WebOriginTrialTokenStatus::kSuccess) | 85 blink::WebOriginTrialTokenStatus::kSuccess) |
84 if (token_feature == feature_name) | 86 if (token_feature == feature_name) |
85 return true; | 87 return true; |
86 } | 88 } |
87 return false; | 89 return false; |
88 } | 90 } |
89 | 91 |
90 std::unique_ptr<TrialTokenValidator::FeatureToTokensMap> | 92 std::unique_ptr<TrialTokenValidator::FeatureToTokensMap> |
91 TrialTokenValidator::GetValidTokensFromHeaders( | 93 TrialTokenValidator::GetValidTokensFromHeaders( |
92 const url::Origin& origin, | 94 const url::Origin& origin, |
93 const net::HttpResponseHeaders* headers) { | 95 const net::HttpResponseHeaders* headers, |
| 96 base::Time current_time) { |
94 std::unique_ptr<FeatureToTokensMap> tokens( | 97 std::unique_ptr<FeatureToTokensMap> tokens( |
95 base::MakeUnique<FeatureToTokensMap>()); | 98 base::MakeUnique<FeatureToTokensMap>()); |
96 if (!base::FeatureList::IsEnabled(features::kOriginTrials)) | 99 if (!base::FeatureList::IsEnabled(features::kOriginTrials)) |
97 return tokens; | 100 return tokens; |
98 | 101 |
99 if (!IsOriginSecure(origin.GetURL())) | 102 if (!IsOriginSecure(origin.GetURL())) |
100 return tokens; | 103 return tokens; |
101 | 104 |
102 size_t iter = 0; | 105 size_t iter = 0; |
103 std::string token; | 106 std::string token; |
104 while (headers->EnumerateHeader(&iter, "Origin-Trial", &token)) { | 107 while (headers->EnumerateHeader(&iter, "Origin-Trial", &token)) { |
105 std::string token_feature; | 108 std::string token_feature; |
106 if (TrialTokenValidator::ValidateToken(token, origin, &token_feature) == | 109 if (TrialTokenValidator::ValidateToken(token, origin, &token_feature, |
| 110 current_time) == |
107 blink::WebOriginTrialTokenStatus::kSuccess) { | 111 blink::WebOriginTrialTokenStatus::kSuccess) { |
108 (*tokens)[token_feature].push_back(token); | 112 (*tokens)[token_feature].push_back(token); |
109 } | 113 } |
110 } | 114 } |
111 return tokens; | 115 return tokens; |
112 } | 116 } |
113 | 117 |
114 std::unique_ptr<TrialTokenValidator::FeatureToTokensMap> | 118 std::unique_ptr<TrialTokenValidator::FeatureToTokensMap> |
115 TrialTokenValidator::GetValidTokens(const url::Origin& origin, | 119 TrialTokenValidator::GetValidTokens(const url::Origin& origin, |
116 const FeatureToTokensMap& tokens) { | 120 const FeatureToTokensMap& tokens, |
| 121 base::Time current_time) { |
117 std::unique_ptr<FeatureToTokensMap> out_tokens( | 122 std::unique_ptr<FeatureToTokensMap> out_tokens( |
118 base::MakeUnique<FeatureToTokensMap>()); | 123 base::MakeUnique<FeatureToTokensMap>()); |
119 if (!base::FeatureList::IsEnabled(features::kOriginTrials)) | 124 if (!base::FeatureList::IsEnabled(features::kOriginTrials)) |
120 return out_tokens; | 125 return out_tokens; |
121 | 126 |
122 if (!IsOriginSecure(origin.GetURL())) | 127 if (!IsOriginSecure(origin.GetURL())) |
123 return out_tokens; | 128 return out_tokens; |
124 | 129 |
125 for (const auto& feature : tokens) { | 130 for (const auto& feature : tokens) { |
126 for (const std::string& token : feature.second) { | 131 for (const std::string& token : feature.second) { |
127 std::string token_feature; | 132 std::string token_feature; |
128 if (TrialTokenValidator::ValidateToken(token, origin, &token_feature) == | 133 if (TrialTokenValidator::ValidateToken(token, origin, &token_feature, |
| 134 current_time) == |
129 blink::WebOriginTrialTokenStatus::kSuccess) { | 135 blink::WebOriginTrialTokenStatus::kSuccess) { |
130 DCHECK_EQ(token_feature, feature.first); | 136 DCHECK_EQ(token_feature, feature.first); |
131 (*out_tokens)[feature.first].push_back(token); | 137 (*out_tokens)[feature.first].push_back(token); |
132 } | 138 } |
133 } | 139 } |
134 } | 140 } |
135 return out_tokens; | 141 return out_tokens; |
136 } | 142 } |
137 | 143 |
138 } // namespace content | 144 } // namespace content |
OLD | NEW |