OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/child/webcrypto/algorithm_dispatch.h" | 5 #include "content/child/webcrypto/algorithm_dispatch.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "content/child/webcrypto/algorithm_implementation.h" | 8 #include "content/child/webcrypto/algorithm_implementation.h" |
9 #include "content/child/webcrypto/algorithm_registry.h" | 9 #include "content/child/webcrypto/algorithm_registry.h" |
10 #include "content/child/webcrypto/crypto_data.h" | 10 #include "content/child/webcrypto/crypto_data.h" |
11 #include "content/child/webcrypto/platform_crypto.h" | 11 #include "content/child/webcrypto/platform_crypto.h" |
12 #include "content/child/webcrypto/status.h" | 12 #include "content/child/webcrypto/status.h" |
13 #include "content/child/webcrypto/webcrypto_util.h" | 13 #include "content/child/webcrypto/webcrypto_util.h" |
14 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" | 14 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" |
15 | 15 |
16 namespace content { | 16 namespace content { |
17 | 17 |
18 namespace webcrypto { | 18 namespace webcrypto { |
19 | 19 |
20 namespace { | 20 namespace { |
21 | 21 |
22 Status DecryptDontCheckKeyUsage(const blink::WebCryptoAlgorithm& algorithm, | 22 Status DecryptDontCheckKeyUsage(const blink::WebCryptoAlgorithm& algorithm, |
23 const blink::WebCryptoKey& key, | 23 const blink::WebCryptoKey& key, |
24 const CryptoData& data, | 24 const CryptoData& data, |
25 std::vector<uint8>* buffer) { | 25 std::vector<uint8_t>* buffer) { |
26 if (algorithm.id() != key.algorithm().id()) | 26 if (algorithm.id() != key.algorithm().id()) |
27 return Status::ErrorUnexpected(); | 27 return Status::ErrorUnexpected(); |
28 | 28 |
29 const AlgorithmImplementation* impl = NULL; | 29 const AlgorithmImplementation* impl = NULL; |
30 Status status = GetAlgorithmImplementation(algorithm.id(), &impl); | 30 Status status = GetAlgorithmImplementation(algorithm.id(), &impl); |
31 if (status.IsError()) | 31 if (status.IsError()) |
32 return status; | 32 return status; |
33 | 33 |
34 return impl->Decrypt(algorithm, key, data, buffer); | 34 return impl->Decrypt(algorithm, key, data, buffer); |
35 } | 35 } |
36 | 36 |
37 Status EncryptDontCheckUsage(const blink::WebCryptoAlgorithm& algorithm, | 37 Status EncryptDontCheckUsage(const blink::WebCryptoAlgorithm& algorithm, |
38 const blink::WebCryptoKey& key, | 38 const blink::WebCryptoKey& key, |
39 const CryptoData& data, | 39 const CryptoData& data, |
40 std::vector<uint8>* buffer) { | 40 std::vector<uint8_t>* buffer) { |
41 if (algorithm.id() != key.algorithm().id()) | 41 if (algorithm.id() != key.algorithm().id()) |
42 return Status::ErrorUnexpected(); | 42 return Status::ErrorUnexpected(); |
43 | 43 |
44 const AlgorithmImplementation* impl = NULL; | 44 const AlgorithmImplementation* impl = NULL; |
45 Status status = GetAlgorithmImplementation(algorithm.id(), &impl); | 45 Status status = GetAlgorithmImplementation(algorithm.id(), &impl); |
46 if (status.IsError()) | 46 if (status.IsError()) |
47 return status; | 47 return status; |
48 | 48 |
49 return impl->Encrypt(algorithm, key, data, buffer); | 49 return impl->Encrypt(algorithm, key, data, buffer); |
50 } | 50 } |
51 | 51 |
52 Status ExportKeyDontCheckExtractability(blink::WebCryptoKeyFormat format, | 52 Status ExportKeyDontCheckExtractability(blink::WebCryptoKeyFormat format, |
53 const blink::WebCryptoKey& key, | 53 const blink::WebCryptoKey& key, |
54 std::vector<uint8>* buffer) { | 54 std::vector<uint8_t>* buffer) { |
55 const AlgorithmImplementation* impl = NULL; | 55 const AlgorithmImplementation* impl = NULL; |
56 Status status = GetAlgorithmImplementation(key.algorithm().id(), &impl); | 56 Status status = GetAlgorithmImplementation(key.algorithm().id(), &impl); |
57 if (status.IsError()) | 57 if (status.IsError()) |
58 return status; | 58 return status; |
59 | 59 |
60 switch (format) { | 60 switch (format) { |
61 case blink::WebCryptoKeyFormatRaw: | 61 case blink::WebCryptoKeyFormatRaw: |
62 return impl->ExportKeyRaw(key, buffer); | 62 return impl->ExportKeyRaw(key, buffer); |
63 case blink::WebCryptoKeyFormatSpki: | 63 case blink::WebCryptoKeyFormatSpki: |
64 return impl->ExportKeySpki(key, buffer); | 64 return impl->ExportKeySpki(key, buffer); |
65 case blink::WebCryptoKeyFormatPkcs8: | 65 case blink::WebCryptoKeyFormatPkcs8: |
66 return impl->ExportKeyPkcs8(key, buffer); | 66 return impl->ExportKeyPkcs8(key, buffer); |
67 case blink::WebCryptoKeyFormatJwk: | 67 case blink::WebCryptoKeyFormatJwk: |
68 return impl->ExportKeyJwk(key, buffer); | 68 return impl->ExportKeyJwk(key, buffer); |
69 default: | 69 default: |
70 return Status::ErrorUnsupported(); | 70 return Status::ErrorUnsupported(); |
71 } | 71 } |
72 } | 72 } |
73 | 73 |
74 } // namespace | 74 } // namespace |
75 | 75 |
76 Status Encrypt(const blink::WebCryptoAlgorithm& algorithm, | 76 Status Encrypt(const blink::WebCryptoAlgorithm& algorithm, |
77 const blink::WebCryptoKey& key, | 77 const blink::WebCryptoKey& key, |
78 const CryptoData& data, | 78 const CryptoData& data, |
79 std::vector<uint8>* buffer) { | 79 std::vector<uint8_t>* buffer) { |
80 if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageEncrypt)) | 80 if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageEncrypt)) |
81 return Status::ErrorUnexpected(); | 81 return Status::ErrorUnexpected(); |
82 return EncryptDontCheckUsage(algorithm, key, data, buffer); | 82 return EncryptDontCheckUsage(algorithm, key, data, buffer); |
83 } | 83 } |
84 | 84 |
85 Status Decrypt(const blink::WebCryptoAlgorithm& algorithm, | 85 Status Decrypt(const blink::WebCryptoAlgorithm& algorithm, |
86 const blink::WebCryptoKey& key, | 86 const blink::WebCryptoKey& key, |
87 const CryptoData& data, | 87 const CryptoData& data, |
88 std::vector<uint8>* buffer) { | 88 std::vector<uint8_t>* buffer) { |
89 if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageDecrypt)) | 89 if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageDecrypt)) |
90 return Status::ErrorUnexpected(); | 90 return Status::ErrorUnexpected(); |
91 return DecryptDontCheckKeyUsage(algorithm, key, data, buffer); | 91 return DecryptDontCheckKeyUsage(algorithm, key, data, buffer); |
92 } | 92 } |
93 | 93 |
94 Status Digest(const blink::WebCryptoAlgorithm& algorithm, | 94 Status Digest(const blink::WebCryptoAlgorithm& algorithm, |
95 const CryptoData& data, | 95 const CryptoData& data, |
96 std::vector<uint8>* buffer) { | 96 std::vector<uint8_t>* buffer) { |
97 const AlgorithmImplementation* impl = NULL; | 97 const AlgorithmImplementation* impl = NULL; |
98 Status status = GetAlgorithmImplementation(algorithm.id(), &impl); | 98 Status status = GetAlgorithmImplementation(algorithm.id(), &impl); |
99 if (status.IsError()) | 99 if (status.IsError()) |
100 return status; | 100 return status; |
101 | 101 |
102 return impl->Digest(algorithm, data, buffer); | 102 return impl->Digest(algorithm, data, buffer); |
103 } | 103 } |
104 | 104 |
105 Status GenerateSecretKey(const blink::WebCryptoAlgorithm& algorithm, | 105 Status GenerateSecretKey(const blink::WebCryptoAlgorithm& algorithm, |
106 bool extractable, | 106 bool extractable, |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 case blink::WebCryptoKeyFormatJwk: | 172 case blink::WebCryptoKeyFormatJwk: |
173 return impl->ImportKeyJwk( | 173 return impl->ImportKeyJwk( |
174 key_data, algorithm, extractable, usage_mask, key); | 174 key_data, algorithm, extractable, usage_mask, key); |
175 default: | 175 default: |
176 return Status::ErrorUnsupported(); | 176 return Status::ErrorUnsupported(); |
177 } | 177 } |
178 } | 178 } |
179 | 179 |
180 Status ExportKey(blink::WebCryptoKeyFormat format, | 180 Status ExportKey(blink::WebCryptoKeyFormat format, |
181 const blink::WebCryptoKey& key, | 181 const blink::WebCryptoKey& key, |
182 std::vector<uint8>* buffer) { | 182 std::vector<uint8_t>* buffer) { |
183 if (!key.extractable()) | 183 if (!key.extractable()) |
184 return Status::ErrorKeyNotExtractable(); | 184 return Status::ErrorKeyNotExtractable(); |
185 return ExportKeyDontCheckExtractability(format, key, buffer); | 185 return ExportKeyDontCheckExtractability(format, key, buffer); |
186 } | 186 } |
187 | 187 |
188 Status Sign(const blink::WebCryptoAlgorithm& algorithm, | 188 Status Sign(const blink::WebCryptoAlgorithm& algorithm, |
189 const blink::WebCryptoKey& key, | 189 const blink::WebCryptoKey& key, |
190 const CryptoData& data, | 190 const CryptoData& data, |
191 std::vector<uint8>* buffer) { | 191 std::vector<uint8_t>* buffer) { |
192 if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageSign)) | 192 if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageSign)) |
193 return Status::ErrorUnexpected(); | 193 return Status::ErrorUnexpected(); |
194 if (algorithm.id() != key.algorithm().id()) | 194 if (algorithm.id() != key.algorithm().id()) |
195 return Status::ErrorUnexpected(); | 195 return Status::ErrorUnexpected(); |
196 | 196 |
197 const AlgorithmImplementation* impl = NULL; | 197 const AlgorithmImplementation* impl = NULL; |
198 Status status = GetAlgorithmImplementation(algorithm.id(), &impl); | 198 Status status = GetAlgorithmImplementation(algorithm.id(), &impl); |
199 if (status.IsError()) | 199 if (status.IsError()) |
200 return status; | 200 return status; |
201 | 201 |
(...skipping 24 matching lines...) Expand all Loading... |
226 if (status.IsError()) | 226 if (status.IsError()) |
227 return status; | 227 return status; |
228 | 228 |
229 return impl->Verify(algorithm, key, signature, data, signature_match); | 229 return impl->Verify(algorithm, key, signature, data, signature_match); |
230 } | 230 } |
231 | 231 |
232 Status WrapKey(blink::WebCryptoKeyFormat format, | 232 Status WrapKey(blink::WebCryptoKeyFormat format, |
233 const blink::WebCryptoKey& key_to_wrap, | 233 const blink::WebCryptoKey& key_to_wrap, |
234 const blink::WebCryptoKey& wrapping_key, | 234 const blink::WebCryptoKey& wrapping_key, |
235 const blink::WebCryptoAlgorithm& wrapping_algorithm, | 235 const blink::WebCryptoAlgorithm& wrapping_algorithm, |
236 std::vector<uint8>* buffer) { | 236 std::vector<uint8_t>* buffer) { |
237 if (!KeyUsageAllows(wrapping_key, blink::WebCryptoKeyUsageWrapKey)) | 237 if (!KeyUsageAllows(wrapping_key, blink::WebCryptoKeyUsageWrapKey)) |
238 return Status::ErrorUnexpected(); | 238 return Status::ErrorUnexpected(); |
239 | 239 |
240 std::vector<uint8> exported_data; | 240 std::vector<uint8_t> exported_data; |
241 Status status = ExportKey(format, key_to_wrap, &exported_data); | 241 Status status = ExportKey(format, key_to_wrap, &exported_data); |
242 if (status.IsError()) | 242 if (status.IsError()) |
243 return status; | 243 return status; |
244 return EncryptDontCheckUsage( | 244 return EncryptDontCheckUsage( |
245 wrapping_algorithm, wrapping_key, CryptoData(exported_data), buffer); | 245 wrapping_algorithm, wrapping_key, CryptoData(exported_data), buffer); |
246 } | 246 } |
247 | 247 |
248 Status UnwrapKey(blink::WebCryptoKeyFormat format, | 248 Status UnwrapKey(blink::WebCryptoKeyFormat format, |
249 const CryptoData& wrapped_key_data, | 249 const CryptoData& wrapped_key_data, |
250 const blink::WebCryptoKey& wrapping_key, | 250 const blink::WebCryptoKey& wrapping_key, |
(...skipping 10 matching lines...) Expand all Loading... |
261 // Fail fast if the import is doomed to fail. | 261 // Fail fast if the import is doomed to fail. |
262 const AlgorithmImplementation* import_impl = NULL; | 262 const AlgorithmImplementation* import_impl = NULL; |
263 Status status = GetAlgorithmImplementation(algorithm.id(), &import_impl); | 263 Status status = GetAlgorithmImplementation(algorithm.id(), &import_impl); |
264 if (status.IsError()) | 264 if (status.IsError()) |
265 return status; | 265 return status; |
266 | 266 |
267 status = import_impl->VerifyKeyUsagesBeforeImportKey(format, usage_mask); | 267 status = import_impl->VerifyKeyUsagesBeforeImportKey(format, usage_mask); |
268 if (status.IsError()) | 268 if (status.IsError()) |
269 return status; | 269 return status; |
270 | 270 |
271 std::vector<uint8> buffer; | 271 std::vector<uint8_t> buffer; |
272 status = DecryptDontCheckKeyUsage( | 272 status = DecryptDontCheckKeyUsage( |
273 wrapping_algorithm, wrapping_key, wrapped_key_data, &buffer); | 273 wrapping_algorithm, wrapping_key, wrapped_key_data, &buffer); |
274 if (status.IsError()) | 274 if (status.IsError()) |
275 return status; | 275 return status; |
276 | 276 |
277 // NOTE that returning the details of ImportKey() failures may leak | 277 // NOTE that returning the details of ImportKey() failures may leak |
278 // information about the plaintext of the encrypted key (for instance the JWK | 278 // information about the plaintext of the encrypted key (for instance the JWK |
279 // key_ops). As long as the ImportKey error messages don't describe actual | 279 // key_ops). As long as the ImportKey error messages don't describe actual |
280 // key bytes however this should be OK. For more discussion see | 280 // key bytes however this should be OK. For more discussion see |
281 // http://crubg.com/372040 | 281 // http://crubg.com/372040 |
282 return ImportKey( | 282 return ImportKey( |
283 format, CryptoData(buffer), algorithm, extractable, usage_mask, key); | 283 format, CryptoData(buffer), algorithm, extractable, usage_mask, key); |
284 } | 284 } |
285 | 285 |
286 scoped_ptr<blink::WebCryptoDigestor> CreateDigestor( | 286 scoped_ptr<blink::WebCryptoDigestor> CreateDigestor( |
287 blink::WebCryptoAlgorithmId algorithm) { | 287 blink::WebCryptoAlgorithmId algorithm) { |
288 PlatformInit(); | 288 PlatformInit(); |
289 return CreatePlatformDigestor(algorithm); | 289 return CreatePlatformDigestor(algorithm); |
290 } | 290 } |
291 | 291 |
292 } // namespace webcrypto | 292 } // namespace webcrypto |
293 | 293 |
294 } // namespace content | 294 } // namespace content |
OLD | NEW |