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

Side by Side Diff: components/gcm_driver/crypto/encryption_header_parsers.cc

Issue 1244803002: Add parsers for the Encryption and Encryption-Key HTTP headers. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rewrite Created 5 years, 3 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 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 #include "components/gcm_driver/crypto/encryption_header_parsers.h"
6
7 #include "base/base64.h"
8 #include "base/strings/string_number_conversions.h"
9 #include "base/strings/string_piece.h"
10 #include "base/strings/string_util.h"
11 #include "net/http/http_util.h"
12
13 namespace gcm {
14
15 namespace {
16
17 const int64_t kDefaultRecordSize = 4096;
whywhat 2015/09/14 14:57:43 Is this size in bytes? Kb?
Peter Beverloo 2015/09/15 19:41:11 Done. Also clarified the origin of this value.
18
19 bool Base64DecodeURLSafe(const base::StringPiece& input, std::string* output) {
whywhat 2015/09/14 14:57:43 perhaps a comment what you mean by safe here? You
Peter Beverloo 2015/09/15 19:41:11 Renamed to the more appropriate Base64URLDecode.
20 size_t padded_size = (input.size() + 3) - (input.size() + 3) % 4;
whywhat 2015/09/14 14:57:43 Does it have to be an arithmetic expression? I had
Peter Beverloo 2015/09/15 19:41:11 Hah. I adopted your suggestion. This is not perfor
21
22 // Add padding to |input|.
23 std::string padded_input(input.begin(), input.end());
24 padded_input.resize(padded_size, '=');
25
26 // Convert to standard base64 alphabet.
27 base::ReplaceChars(padded_input, "-", "+", &padded_input);
28 base::ReplaceChars(padded_input, "_", "/", &padded_input);
29
30 return base::Base64Decode(padded_input, output);
31 }
32
33 bool ValueToDecodedString(std::string::const_iterator begin,
whywhat 2015/09/14 14:57:43 can you pass iterators by reference (perhaps only
Peter Beverloo 2015/09/15 19:41:11 Done.
34 std::string::const_iterator end,
35 std::string* salt) {
36 const base::StringPiece value(begin, end);
37 if (value.empty())
whywhat 2015/09/14 14:57:43 you could check if begin == end before constructin
Peter Beverloo 2015/09/15 19:41:11 Construction of the StringPiece should be inline,
38 return false;
39
40 return Base64DecodeURLSafe(value, salt);
41 }
42
43 bool RecordSizeToInt(std::string::const_iterator begin,
whywhat 2015/09/14 14:57:43 Read this a "record (verb) a size to an int". Mayb
Peter Beverloo 2015/09/15 19:41:11 As discussed offline - I understand you concern bu
44 std::string::const_iterator end,
45 int64_t* rs) {
46 const base::StringPiece value(begin, end);
47 if (value.empty())
48 return false;
49
50 if (!base::StringToInt64(value, rs))
51 return false;
52
53 // The record size MUST be greater than 1.
54 return *rs > 1;
whywhat 2015/09/14 14:57:43 this has a possible unintended effect of changing
Peter Beverloo 2015/09/15 19:41:11 Ack, that's why we use temps in the public :)
55 }
56
57 bool ParseEncryptionHeaderImpl(const std::string& input,
58 std::string* keyid,
59 std::string* salt,
60 int64_t* rs) {
61 net::HttpUtil::NameValuePairsIterator name_value_pairs(
62 input.begin(), input.end(), ';',
63 net::HttpUtil::NameValuePairsIterator::VALUES_NOT_OPTIONAL);
64
65 while (name_value_pairs.GetNext()) {
66 const base::StringPiece name =
whywhat 2015/09/14 14:57:43 can't you do: const base::StringPiece name(n_v_p.
Peter Beverloo 2015/09/15 19:41:11 Done.
67 base::StringPiece(name_value_pairs.name_begin(),
68 name_value_pairs.name_end());
69
70 if (base::LowerCaseEqualsASCII(name, "keyid")) {
whywhat 2015/09/14 14:57:43 give names to the magic constants? you only reuse
Peter Beverloo 2015/09/15 19:41:11 As you say, the gain is minimal while this is much
71 keyid->assign(name_value_pairs.value_begin(),
72 name_value_pairs.value_end());
73 } else if (base::LowerCaseEqualsASCII(name, "salt")) {
74 if (!ValueToDecodedString(name_value_pairs.value_begin(),
75 name_value_pairs.value_end(), salt)) {
76 return false;
77 }
78 } else if (base::LowerCaseEqualsASCII(name, "rs")) {
79 if (!RecordSizeToInt(name_value_pairs.value_begin(),
80 name_value_pairs.value_end(), rs)) {
81 return false;
82 }
83 } else {
84 // Silently ignore unknown directives for forward compatibility.
85 }
86 }
87
88 return name_value_pairs.valid();
89 }
90
91 bool ParseEncryptionKeyHeaderImpl(const std::string& input,
92 std::string* keyid,
93 std::string* key,
94 std::string* dh) {
95 net::HttpUtil::NameValuePairsIterator name_value_pairs(
96 input.begin(), input.end(), ';',
97 net::HttpUtil::NameValuePairsIterator::VALUES_NOT_OPTIONAL);
98
99 while (name_value_pairs.GetNext()) {
100 const base::StringPiece name =
101 base::StringPiece(name_value_pairs.name_begin(),
102 name_value_pairs.name_end());
103
104 if (base::LowerCaseEqualsASCII(name, "keyid")) {
105 keyid->assign(name_value_pairs.value_begin(),
106 name_value_pairs.value_end());
107 } else if (base::LowerCaseEqualsASCII(name, "key")) {
108 if (!ValueToDecodedString(name_value_pairs.value_begin(),
109 name_value_pairs.value_end(), key)) {
110 return false;
111 }
112 } else if (base::LowerCaseEqualsASCII(name, "dh")) {
113 if (!ValueToDecodedString(name_value_pairs.value_begin(),
114 name_value_pairs.value_end(), dh)) {
115 return false;
116 }
117 } else {
118 // Silently ignore unknown directives for forward compatibility.
119 }
120 }
121
122 return name_value_pairs.valid();
123 }
124
125 } // namespace
126
127 // "Encryption" ":"
128 // [ "keyid" "=" string ]
129 // [ ";" "salt" "=" base64url ]
130 // [ ";" "rs" "=" octet-count ]
131 bool ParseEncryptionHeader(const std::string& input,
132 std::string* keyid,
133 std::string* salt,
134 int64_t* rs) {
135 std::string candidate_keyid;
136 std::string candidate_salt;
137 int64_t candidate_rs = kDefaultRecordSize;
138
139 if (!ParseEncryptionHeaderImpl(input, &candidate_keyid, &candidate_salt,
140 &candidate_rs)) {
141 return false;
142 }
143
144 keyid->swap(candidate_keyid);
145 salt->swap(candidate_salt);
146 *rs = candidate_rs;
147 return true;
148 }
149
150 // "Encryption-Key" ":"
151 // [ "keyid" "=" string ]
152 // [ ";" "key" "=" base64url ]
153 // [ ";" "dh" "=" base64url ]
154 bool ParseEncryptionKeyHeader(const std::string& input,
155 std::string* keyid,
156 std::string* key,
157 std::string* dh) {
158 std::string candidate_keyid;
159 std::string candidate_key;
160 std::string candidate_dh;
161
162 if (!ParseEncryptionKeyHeaderImpl(input, &candidate_keyid, &candidate_key,
163 &candidate_dh)) {
164 return false;
165 }
166
167 keyid->swap(candidate_keyid);
168 key->swap(candidate_key);
169 dh->swap(candidate_dh);
170 return true;
171 }
172
173 } // namespace gcm
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698