OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/renderer/webcrypto/webcrypto_util.h" | 5 #include "content/renderer/webcrypto/webcrypto_util.h" |
6 | 6 |
7 #include "base/base64.h" | 7 #include "base/base64.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/strings/stringprintf.h" | |
9 #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h" | 10 #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h" |
10 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" | 11 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" |
11 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" | 12 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" |
12 | 13 |
13 namespace content { | 14 namespace content { |
14 | 15 |
15 namespace webcrypto { | 16 namespace webcrypto { |
16 | 17 |
17 bool Status::IsError() const { return type_ == TYPE_ERROR; } | 18 bool Status::IsError() const { return type_ == TYPE_ERROR; } |
18 | 19 |
(...skipping 21 matching lines...) Expand all Loading... | |
40 const std::string& expected_type) { | 41 const std::string& expected_type) { |
41 return Status("The JWK property \"" + property + "\" must be a " + | 42 return Status("The JWK property \"" + property + "\" must be a " + |
42 expected_type); | 43 expected_type); |
43 } | 44 } |
44 | 45 |
45 Status Status::ErrorJwkBase64Decode(const std::string& property) { | 46 Status Status::ErrorJwkBase64Decode(const std::string& property) { |
46 return Status("The JWK property \"" + property + | 47 return Status("The JWK property \"" + property + |
47 "\" could not be base64 decoded"); | 48 "\" could not be base64 decoded"); |
48 } | 49 } |
49 | 50 |
50 Status Status::ErrorJwkExtractableInconsistent() { | 51 Status Status::ErrorJwkExtInconsistent() { |
51 return Status( | 52 return Status( |
52 "The \"extractable\" property of the JWK dictionary is " | 53 "The \"ext\" property of the JWK dictionary is inconsistent what that " |
53 "inconsistent what that specified by the Web Crypto call"); | 54 "specified by the Web Crypto call"); |
54 } | 55 } |
55 | 56 |
56 Status Status::ErrorJwkUnrecognizedAlgorithm() { | 57 Status Status::ErrorJwkUnrecognizedAlgorithm() { |
57 return Status("The JWK \"alg\" property was not recognized"); | 58 return Status("The JWK \"alg\" property was not recognized"); |
58 } | 59 } |
59 | 60 |
60 Status Status::ErrorJwkAlgorithmInconsistent() { | 61 Status Status::ErrorJwkAlgorithmInconsistent() { |
61 return Status( | 62 return Status( |
62 "The JWK \"alg\" property was inconsistent with that specified " | 63 "The JWK \"alg\" property was inconsistent with that specified " |
63 "by the Web Crypto call"); | 64 "by the Web Crypto call"); |
64 } | 65 } |
65 | 66 |
66 Status Status::ErrorJwkAlgorithmMissing() { | 67 Status Status::ErrorJwkAlgorithmMissing() { |
67 return Status( | 68 return Status( |
68 "The JWK optional \"alg\" property is missing or not a string, " | 69 "The JWK optional \"alg\" property is missing or not a string, " |
69 "and one wasn't specified by the Web Crypto call"); | 70 "and one wasn't specified by the Web Crypto call"); |
70 } | 71 } |
71 | 72 |
72 Status Status::ErrorJwkUnrecognizedUsage() { | 73 Status Status::ErrorJwkUnrecognizedUse() { |
73 return Status("The JWK \"use\" property could not be parsed"); | 74 return Status("The JWK \"use\" property could not be parsed"); |
74 } | 75 } |
75 | 76 |
76 Status Status::ErrorJwkUsageInconsistent() { | 77 Status Status::ErrorJwkUnrecognizedKeyop() { |
78 return Status("The JWK \"key_ops\" property could not be parsed"); | |
79 } | |
80 | |
81 Status Status::ErrorJwkUseInconsistent() { | |
77 return Status( | 82 return Status( |
78 "The JWK \"use\" property was inconsistent with that specified " | 83 "The JWK \"use\" property was inconsistent with that specified " |
79 "by the Web Crypto call. The JWK usage must be a superset of " | 84 "by the Web Crypto call. The JWK usage must be a superset of " |
80 "those requested"); | 85 "those requested"); |
81 } | 86 } |
82 | 87 |
88 Status Status::ErrorJwkKeyopsInconsistent() { | |
89 return Status( | |
90 "The JWK \"key_ops\" property was inconsistent with that " | |
91 "specified by the Web Crypto call. The JWK usage must be a " | |
92 "superset of those requested"); | |
93 } | |
94 | |
95 Status Status::ErrorJwkUseAndKeyopsInconsistent() { | |
96 return Status( | |
97 "The JWK \"use\" and \"key_ops\" properties were both found " | |
98 "but are inconsistent with each other."); | |
99 } | |
100 | |
83 Status Status::ErrorJwkRsaPrivateKeyUnsupported() { | 101 Status Status::ErrorJwkRsaPrivateKeyUnsupported() { |
84 return Status( | 102 return Status( |
85 "JWK RSA key contained \"d\" property: Private key import is " | 103 "JWK RSA key contained \"d\" property: Private key import is " |
86 "not yet supported"); | 104 "not yet supported"); |
87 } | 105 } |
88 | 106 |
89 Status Status::ErrorJwkUnrecognizedKty() { | 107 Status Status::ErrorJwkUnrecognizedKty() { |
90 return Status("The JWK \"kty\" property was unrecognized"); | 108 return Status("The JWK \"kty\" property was unrecognized"); |
91 } | 109 } |
92 | 110 |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
212 // transformation including adding padding if required, and then call a base64 | 230 // transformation including adding padding if required, and then call a base64 |
213 // decoder. | 231 // decoder. |
214 bool Base64DecodeUrlSafe(const std::string& input, std::string* output) { | 232 bool Base64DecodeUrlSafe(const std::string& input, std::string* output) { |
215 std::string base64EncodedText(input); | 233 std::string base64EncodedText(input); |
216 std::replace(base64EncodedText.begin(), base64EncodedText.end(), '-', '+'); | 234 std::replace(base64EncodedText.begin(), base64EncodedText.end(), '-', '+'); |
217 std::replace(base64EncodedText.begin(), base64EncodedText.end(), '_', '/'); | 235 std::replace(base64EncodedText.begin(), base64EncodedText.end(), '_', '/'); |
218 base64EncodedText.append((4 - base64EncodedText.size() % 4) % 4, '='); | 236 base64EncodedText.append((4 - base64EncodedText.size() % 4) % 4, '='); |
219 return base::Base64Decode(base64EncodedText, output); | 237 return base::Base64Decode(base64EncodedText, output); |
220 } | 238 } |
221 | 239 |
240 // Produces an unpadded 'base64url' encoding of the input data, using the | |
241 // inverse of the process above. | |
242 void Base64EncodeUrlSafe(const base::StringPiece& input, std::string* output) { | |
eroman
2014/03/07 19:33:06
[optional] Since no error can be returned, you mig
padolph
2014/03/09 22:06:36
Done.
| |
243 base::Base64Encode(input, output); | |
244 std::replace(output->begin(), output->end(), '+', '-'); | |
245 std::replace(output->begin(), output->end(), '/', '_'); | |
246 output->erase(std::remove(output->begin(), output->end(), '='), | |
247 output->end()); | |
248 } | |
249 | |
250 struct JwkToWebCryptoUsage { | |
251 const char* const jwk_key_op; | |
252 const blink::WebCryptoKeyUsage webcrypto_usage; | |
253 }; | |
254 | |
255 const JwkToWebCryptoUsage kJwkWebCryptoUsageMap[] = { | |
256 {"encrypt", blink::WebCryptoKeyUsageEncrypt}, | |
257 {"decrypt", blink::WebCryptoKeyUsageDecrypt}, | |
258 {"deriveKey", blink::WebCryptoKeyUsageDeriveKey}, | |
259 // TODO(padolph): Add 'deriveBits' once supported by Blink. | |
260 {"sign", blink::WebCryptoKeyUsageSign}, | |
261 {"unwrapKey", blink::WebCryptoKeyUsageUnwrapKey}, | |
262 {"verify", blink::WebCryptoKeyUsageVerify}, | |
263 {"wrapKey", blink::WebCryptoKeyUsageWrapKey}}; | |
264 | |
265 // Composes a Web Crypto usage mask from an array of JWK key_ops values. | |
266 Status GetWebCryptoUsagesFromJwkKeyOps( | |
267 base::ListValue* jwk_key_ops_value, | |
eroman
2014/03/07 19:33:06
can this parameter be "const"?
padolph
2014/03/09 22:06:36
Yes. Done.
| |
268 blink::WebCryptoKeyUsageMask* usage_mask) { | |
269 *usage_mask = 0; | |
270 for (size_t i = 0; i < jwk_key_ops_value->GetSize(); ++i) { | |
eroman
2014/03/07 19:33:06
nit: ++i to match other code in webcrypto
padolph
2014/03/09 22:06:36
I don't understand the comment. The code already h
eroman
2014/03/10 21:55:34
My mistake, please disregard!
| |
271 std::string key_op; | |
272 if (!jwk_key_ops_value->GetString(i, &key_op)) | |
eroman
2014/03/07 19:33:06
Please add a curly brace around this (because of l
padolph
2014/03/09 22:06:36
Done.
| |
273 return Status::ErrorJwkPropertyWrongType( | |
274 base::StringPrintf("key_ops[%d]", static_cast<int>(i)), "string"); | |
275 size_t j; | |
276 const size_t map_size = ARRAYSIZE_UNSAFE(kJwkWebCryptoUsageMap); | |
eroman
2014/03/07 19:33:06
Is the UNSAFE variant needed here or does it work
padolph
2014/03/09 22:06:36
Done.
| |
277 for (j = 0; j < map_size; ++j) { | |
eroman
2014/03/07 19:33:06
I have been burned by mixups on "i" vs "j" in the
padolph
2014/03/09 22:06:36
Done.
| |
278 if (key_op == kJwkWebCryptoUsageMap[j].jwk_key_op) { | |
279 *usage_mask |= kJwkWebCryptoUsageMap[j].webcrypto_usage; | |
280 break; | |
281 } | |
282 } | |
283 if (j == map_size) | |
284 return Status::ErrorJwkUnrecognizedKeyop(); | |
285 } | |
286 return Status::Success(); | |
287 } | |
288 | |
289 // Composes a JWK key_ops List from a Web Crypto usage mask. | |
290 void GetJwkKeyOpsFromWebCryptoUsages(blink::WebCryptoKeyUsageMask usage_mask, | |
eroman
2014/03/07 19:33:06
I would call this "Fill" rather than "Get".
Or al
padolph
2014/03/09 22:06:36
Done.
| |
291 base::ListValue* jwk_key_ops) { | |
292 jwk_key_ops->Clear(); | |
293 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kJwkWebCryptoUsageMap); ++i) { | |
294 if (usage_mask & kJwkWebCryptoUsageMap[i].webcrypto_usage) | |
295 jwk_key_ops->AppendString(kJwkWebCryptoUsageMap[i].jwk_key_op); | |
296 } | |
297 } | |
298 | |
222 bool IsHashAlgorithm(blink::WebCryptoAlgorithmId alg_id) { | 299 bool IsHashAlgorithm(blink::WebCryptoAlgorithmId alg_id) { |
223 return alg_id == blink::WebCryptoAlgorithmIdSha1 || | 300 return alg_id == blink::WebCryptoAlgorithmIdSha1 || |
224 alg_id == blink::WebCryptoAlgorithmIdSha224 || | 301 alg_id == blink::WebCryptoAlgorithmIdSha224 || |
225 alg_id == blink::WebCryptoAlgorithmIdSha256 || | 302 alg_id == blink::WebCryptoAlgorithmIdSha256 || |
226 alg_id == blink::WebCryptoAlgorithmIdSha384 || | 303 alg_id == blink::WebCryptoAlgorithmIdSha384 || |
227 alg_id == blink::WebCryptoAlgorithmIdSha512; | 304 alg_id == blink::WebCryptoAlgorithmIdSha512; |
228 } | 305 } |
229 | 306 |
230 blink::WebCryptoAlgorithm GetInnerHashAlgorithm( | 307 blink::WebCryptoAlgorithm GetInnerHashAlgorithm( |
231 const blink::WebCryptoAlgorithm& algorithm) { | 308 const blink::WebCryptoAlgorithm& algorithm) { |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
311 new blink::WebCryptoAesKeyAlgorithmParams(keylen_bytes * 8)); | 388 new blink::WebCryptoAesKeyAlgorithmParams(keylen_bytes * 8)); |
312 return true; | 389 return true; |
313 default: | 390 default: |
314 return false; | 391 return false; |
315 } | 392 } |
316 } | 393 } |
317 | 394 |
318 } // namespace webcrypto | 395 } // namespace webcrypto |
319 | 396 |
320 } // namespace content | 397 } // namespace content |
OLD | NEW |