Index: content/common/origin_trials/trial_token.cc |
diff --git a/content/common/origin_trials/trial_token.cc b/content/common/origin_trials/trial_token.cc |
index 0a137edc68b43e780e572c1d083379c864921fc8..4e93efd89c4be2c51f33b795d24c14c3ab92d0cc 100644 |
--- a/content/common/origin_trials/trial_token.cc |
+++ b/content/common/origin_trials/trial_token.cc |
@@ -43,49 +43,64 @@ const uint8_t kVersion2 = 2; |
TrialToken::~TrialToken() {} |
-// static |
-std::unique_ptr<TrialToken> TrialToken::From(const std::string& token_text, |
- base::StringPiece public_key) { |
- std::unique_ptr<std::string> token_payload = Extract(token_text, public_key); |
- if (!token_payload) { |
- return nullptr; |
+// Static |
+TrialTokenStatus TrialToken::From(const std::string& token_text, |
+ base::StringPiece public_key, |
+ std::unique_ptr<TrialToken>& out_token) { |
+ std::unique_ptr<std::string> token_payload; |
+ TrialTokenStatus status = Extract(token_text, public_key, token_payload); |
+ if (status != TRIAL_TOKEN_STATUS_SUCCESS) { |
+ out_token.reset(); |
+ return status; |
} |
- return Parse(*token_payload); |
+ out_token = Parse(*token_payload); |
+ return out_token ? TRIAL_TOKEN_STATUS_SUCCESS : TRIAL_TOKEN_STATUS_MALFORMED; |
} |
-bool TrialToken::IsValidForFeature(const url::Origin& origin, |
- base::StringPiece feature_name, |
- const base::Time& now) const { |
- return ValidateOrigin(origin) && ValidateFeatureName(feature_name) && |
- ValidateDate(now); |
+TrialTokenStatus TrialToken::IsValidForFeature(const url::Origin& origin, |
+ base::StringPiece feature_name, |
+ const base::Time& now) const { |
+ // The order of these checks is intentional. For example, will only report a |
+ // token as expired if it is valid for the origin + feature combination. |
+ if (!ValidateOrigin(origin)) { |
+ return TRIAL_TOKEN_STATUS_WRONG_ORIGIN; |
+ } |
+ if (!ValidateFeatureName(feature_name)) { |
+ return TRIAL_TOKEN_STATUS_WRONG_FEATURE; |
+ } |
+ if (!ValidateDate(now)) { |
+ return TRIAL_TOKEN_STATUS_EXPIRED; |
+ } |
+ return TRIAL_TOKEN_STATUS_SUCCESS; |
} |
-std::unique_ptr<std::string> TrialToken::Extract( |
+TrialTokenStatus TrialToken::Extract( |
const std::string& token_payload, |
- base::StringPiece public_key) { |
+ base::StringPiece public_key, |
+ std::unique_ptr<std::string>& out_token_json) { |
if (token_payload.empty()) { |
- return nullptr; |
+ return TRIAL_TOKEN_STATUS_MALFORMED; |
} |
// Token is base64-encoded; decode first. |
std::string token_contents; |
if (!base::Base64Decode(token_payload, &token_contents)) { |
- return nullptr; |
+ return TRIAL_TOKEN_STATUS_MALFORMED; |
} |
// Only version 2 currently supported. |
if (token_contents.length() < (kVersionOffset + kVersionSize)) { |
- return nullptr; |
+ return TRIAL_TOKEN_STATUS_MALFORMED; |
} |
uint8_t version = token_contents[kVersionOffset]; |
if (version != kVersion2) { |
- return nullptr; |
+ return TRIAL_TOKEN_STATUS_MALFORMED; |
} |
// Token must be large enough to contain a version, signature, and payload |
// length. |
if (token_contents.length() < (kPayloadLengthOffset + kPayloadLengthSize)) { |
- return nullptr; |
+ return TRIAL_TOKEN_STATUS_MALFORMED; |
} |
// Extract the length of the signed data (Big-endian). |
@@ -94,7 +109,7 @@ std::unique_ptr<std::string> TrialToken::Extract( |
// Validate that the stated length matches the actual payload length. |
if (payload_length != token_contents.length() - kPayloadOffset) { |
- return nullptr; |
+ return TRIAL_TOKEN_STATUS_MALFORMED; |
} |
// Extract the version-specific contents of the token. |
@@ -110,12 +125,13 @@ std::unique_ptr<std::string> TrialToken::Extract( |
// Validate the signature on the data before proceeding. |
if (!TrialToken::ValidateSignature(signature, signed_data, public_key)) { |
- return nullptr; |
+ return TRIAL_TOKEN_STATUS_INVALID_SIGNATURE; |
} |
// Return just the payload, as a new string. |
- return base::WrapUnique( |
+ out_token_json.reset( |
new std::string(token_contents, kPayloadOffset, payload_length)); |
+ return TRIAL_TOKEN_STATUS_SUCCESS; |
} |
std::unique_ptr<TrialToken> TrialToken::Parse(const std::string& token_json) { |