Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(261)

Unified Diff: components/gcm_driver/crypto/encryption_header_parsers.cc

Issue 1509683002: Convert the encryption header parsers to be iterator-based. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Convert the encryption header parsers to be iterator-based. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: components/gcm_driver/crypto/encryption_header_parsers.cc
diff --git a/components/gcm_driver/crypto/encryption_header_parsers.cc b/components/gcm_driver/crypto/encryption_header_parsers.cc
index 1932527b9fefac8c389f27f7aedd87e2d8de97e6..4f199bd9f96939b7c65487fc9903f507f20fc70d 100644
--- a/components/gcm_driver/crypto/encryption_header_parsers.cc
+++ b/components/gcm_driver/crypto/encryption_header_parsers.cc
@@ -6,24 +6,21 @@
#include "base/base64url.h"
#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_piece.h"
+
#include "base/strings/string_util.h"
-#include "net/http/http_util.h"
+
namespace gcm {
namespace {
// The default record size in bytes, as defined in section two of
-// https://tools.ietf.org/html/draft-thomson-http-encryption-02.
+// https://tools.ietf.org/html/draft-thomson-http-encryption.
const uint64_t kDefaultRecordSizeBytes = 4096;
-// Decodes the string between |begin| and |end| using base64url, and writes the
-// decoded value to |*salt|. Returns whether the string could be decoded.
-bool ValueToDecodedString(const std::string::const_iterator& begin,
- const std::string::const_iterator& end,
- std::string* salt) {
- const base::StringPiece value(begin, end);
+// Decodes the string in |value| using base64url and writes the decoded value to
+// |*salt|. Returns whether the string is not empty and could be decoded.
+bool ValueToDecodedString(base::StringPiece value, std::string* salt) {
if (value.empty())
return false;
@@ -31,70 +28,67 @@ bool ValueToDecodedString(const std::string::const_iterator& begin,
value, base::Base64UrlDecodePolicy::IGNORE_PADDING, salt);
}
-// Parses the record size between |begin| and |end|, and writes the value to
-// |*rs|. The value must be an unsigned, 64-bit integer greater than zero that
-// does not start with a plus. Returns whether the record size was valid.
-bool RecordSizeToInt(const std::string::const_iterator& begin,
- const std::string::const_iterator& end,
- uint64_t* rs) {
- const base::StringPiece value(begin, end);
+// Parses the record size in |value| and writes the value to |*rs|. The value
+// must be a positive decimal integer greater than one that does not start
+// with a plus. Returns whether the record size was valid.
+bool RecordSizeToInt(base::StringPiece value, uint64_t* rs) {
if (value.empty())
return false;
- // Parsing the "rs" parameter uses stricter semantics than parsing rules for
- // normal integers, in that we want to reject values such as "+5" for
- // compatibility with UAs that use other number parsing mechanisms.
+ // Reject a leading plus, as the fact that the value must be positive is
+ // dictated by the specification.
if (value[0] == '+')
return false;
- if (!base::StringToUint64(value, rs))
+ uint64_t candidate_rs;
+ if (!base::StringToUint64(value, &candidate_rs))
return false;
- // The record size MUST be greater than 1.
- return *rs > 1;
+ // The record size MUST be greater than one byte.
+ if (candidate_rs <= 1)
+ return false;
+
+ *rs = candidate_rs;
+ return true;
}
-// Parses the string between |input_begin| and |input_end| according to the
-// extended ABNF syntax for the Encryption HTTP header, per the "parameter"
-// rule from RFC 7231 (https://tools.ietf.org/html/rfc7231).
-//
-// encryption_params = [ parameter *( ";" parameter ) ]
-//
-// This implementation applies the parameters defined in section 3.1 of the
-// HTTP encryption encoding document:
-//
-// https://tools.ietf.org/html/draft-thomson-http-encryption-02#section-3.1
-//
-// This means that the three supported parameters are:
-//
-// [ "keyid" "=" string ]
-// [ ";" "salt" "=" base64url ]
-// [ ";" "rs" "=" octet-count ]
-bool ParseEncryptionHeaderValuesImpl(std::string::const_iterator input_begin,
- std::string::const_iterator input_end,
- EncryptionHeaderValues* values) {
+} // namespace
+
+EncryptionHeaderIterator::EncryptionHeaderIterator(
+ std::string::const_iterator header_begin,
+ std::string::const_iterator header_end)
+ : iterator_(header_begin, header_end, ','),
+ rs_(kDefaultRecordSizeBytes) {}
+
+EncryptionHeaderIterator::~EncryptionHeaderIterator() {}
+
+bool EncryptionHeaderIterator::GetNext() {
+ keyid_.clear();
+ salt_.clear();
+ rs_ = kDefaultRecordSizeBytes;
+
+ if (!iterator_.GetNext())
+ return false;
+
net::HttpUtil::NameValuePairsIterator name_value_pairs(
- input_begin, input_end, ';',
+ iterator_.value_begin(), iterator_.value_end(), ';',
net::HttpUtil::NameValuePairsIterator::Values::REQUIRED,
net::HttpUtil::NameValuePairsIterator::Quotes::NOT_STRICT);
while (name_value_pairs.GetNext()) {
const base::StringPiece name(name_value_pairs.name_begin(),
name_value_pairs.name_end());
+ const base::StringPiece value(name_value_pairs.value_begin(),
+ name_value_pairs.value_end());
if (base::LowerCaseEqualsASCII(name, "keyid")) {
- values->keyid.assign(name_value_pairs.value_begin(),
- name_value_pairs.value_end());
+ value.CopyToString(&keyid_);
} else if (base::LowerCaseEqualsASCII(name, "salt")) {
- if (!ValueToDecodedString(name_value_pairs.value_begin(),
- name_value_pairs.value_end(), &values->salt)) {
+ if (!ValueToDecodedString(value, &salt_))
return false;
- }
} else if (base::LowerCaseEqualsASCII(name, "rs")) {
- if (!RecordSizeToInt(name_value_pairs.value_begin(),
- name_value_pairs.value_end(), &values->rs)) {
+ if (!RecordSizeToInt(value, &rs_))
return false;
- }
} else {
// Silently ignore unknown directives for forward compatibility.
}
@@ -103,48 +97,40 @@ bool ParseEncryptionHeaderValuesImpl(std::string::const_iterator input_begin,
return name_value_pairs.valid();
}
-// Parses the string between |input_begin| and |input_end| according to the
-// extended ABNF syntax for the Crypto-Key HTTP header, per the "parameter" rule
-// from RFC 7231 (https://tools.ietf.org/html/rfc7231).
-//
-// encryption_params = [ parameter *( ";" parameter ) ]
-//
-// This implementation applies the parameters defined in section 4 of the
-// HTTP encryption encoding document:
-//
-//https://tools.ietf.org/html/draft-thomson-http-encryption-02#section-4
-//
-// This means that the three supported parameters are:
-//
-// [ "keyid" "=" string ]
-// [ ";" "aesgcm128" "=" base64url ]
-// [ ";" "dh" "=" base64url ]
-bool ParseCryptoKeyHeaderValuesImpl(std::string::const_iterator input_begin,
- std::string::const_iterator input_end,
- CryptoKeyHeaderValues* values) {
+CryptoKeyHeaderIterator::CryptoKeyHeaderIterator(
+ std::string::const_iterator header_begin,
+ std::string::const_iterator header_end)
+ : iterator_(header_begin, header_end, ',') {}
+
+CryptoKeyHeaderIterator::~CryptoKeyHeaderIterator() {}
+
+bool CryptoKeyHeaderIterator::GetNext() {
+ keyid_.clear();
+ aesgcm128_.clear();
+ dh_.clear();
+
+ if (!iterator_.GetNext())
+ return false;
+
net::HttpUtil::NameValuePairsIterator name_value_pairs(
- input_begin, input_end, ';',
+ iterator_.value_begin(), iterator_.value_end(), ';',
net::HttpUtil::NameValuePairsIterator::Values::REQUIRED,
net::HttpUtil::NameValuePairsIterator::Quotes::NOT_STRICT);
while (name_value_pairs.GetNext()) {
const base::StringPiece name(name_value_pairs.name_begin(),
name_value_pairs.name_end());
+ const base::StringPiece value(name_value_pairs.value_begin(),
+ name_value_pairs.value_end());
if (base::LowerCaseEqualsASCII(name, "keyid")) {
- values->keyid.assign(name_value_pairs.value_begin(),
- name_value_pairs.value_end());
+ value.CopyToString(&keyid_);
} else if (base::LowerCaseEqualsASCII(name, "aesgcm128")) {
- if (!ValueToDecodedString(name_value_pairs.value_begin(),
- name_value_pairs.value_end(),
- &values->aesgcm128)) {
+ if (!ValueToDecodedString(value, &aesgcm128_))
return false;
- }
} else if (base::LowerCaseEqualsASCII(name, "dh")) {
- if (!ValueToDecodedString(name_value_pairs.value_begin(),
- name_value_pairs.value_end(), &values->dh)) {
+ if (!ValueToDecodedString(value, &dh_))
return false;
- }
} else {
// Silently ignore unknown directives for forward compatibility.
}
@@ -153,52 +139,4 @@ bool ParseCryptoKeyHeaderValuesImpl(std::string::const_iterator input_begin,
return name_value_pairs.valid();
}
-} // namespace
-
-bool ParseEncryptionHeader(const std::string& input,
- std::vector<EncryptionHeaderValues>* values) {
- DCHECK(values);
-
- std::vector<EncryptionHeaderValues> candidate_values;
-
- net::HttpUtil::ValuesIterator value_iterator(input.begin(), input.end(), ',');
- while (value_iterator.GetNext()) {
- EncryptionHeaderValues candidate_value;
- candidate_value.rs = kDefaultRecordSizeBytes;
-
- if (!ParseEncryptionHeaderValuesImpl(value_iterator.value_begin(),
- value_iterator.value_end(),
- &candidate_value)) {
- return false;
- }
-
- candidate_values.push_back(candidate_value);
- }
-
- values->swap(candidate_values);
- return true;
-}
-
-bool ParseCryptoKeyHeader(const std::string& input,
- std::vector<CryptoKeyHeaderValues>* values) {
- DCHECK(values);
-
- std::vector<CryptoKeyHeaderValues> candidate_values;
-
- net::HttpUtil::ValuesIterator value_iterator(input.begin(), input.end(), ',');
- while (value_iterator.GetNext()) {
- CryptoKeyHeaderValues candidate_value;
- if (!ParseCryptoKeyHeaderValuesImpl(value_iterator.value_begin(),
- value_iterator.value_end(),
- &candidate_value)) {
- return false;
- }
-
- candidate_values.push_back(candidate_value);
- }
-
- values->swap(candidate_values);
- return true;
-}
-
} // namespace gcm

Powered by Google App Engine
This is Rietveld 408576698