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_impl.h" | 5 #include "content/renderer/webcrypto/webcrypto_impl.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 #include <openssl/aes.h> | 8 #include <openssl/aes.h> |
9 #include <openssl/evp.h> | 9 #include <openssl/evp.h> |
10 #include <openssl/hmac.h> | 10 #include <openssl/hmac.h> |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 | 114 |
115 unsigned char* const buffer_data = | 115 unsigned char* const buffer_data = |
116 reinterpret_cast<unsigned char*>(buffer->data()); | 116 reinterpret_cast<unsigned char*>(buffer->data()); |
117 | 117 |
118 int output_len = 0; | 118 int output_len = 0; |
119 if (!EVP_CipherUpdate( | 119 if (!EVP_CipherUpdate( |
120 context.get(), buffer_data, &output_len, data, data_size)) | 120 context.get(), buffer_data, &output_len, data, data_size)) |
121 return Status::Error(); | 121 return Status::Error(); |
122 int final_output_chunk_len = 0; | 122 int final_output_chunk_len = 0; |
123 if (!EVP_CipherFinal_ex( | 123 if (!EVP_CipherFinal_ex( |
124 context.get(), buffer_data + output_len, &final_output_chunk_len)) | 124 context.get(), buffer_data + output_len, &final_output_chunk_len)) { |
125 return Status::Error(); | 125 return Status::Error(); |
| 126 } |
126 | 127 |
127 const unsigned final_output_len = | 128 const unsigned final_output_len = |
128 static_cast<unsigned>(output_len) + | 129 static_cast<unsigned>(output_len) + |
129 static_cast<unsigned>(final_output_chunk_len); | 130 static_cast<unsigned>(final_output_chunk_len); |
130 DCHECK_LE(final_output_len, output_max_len); | 131 DCHECK_LE(final_output_len, output_max_len); |
131 | 132 |
132 webcrypto::ShrinkBuffer(buffer, final_output_len); | 133 webcrypto::ShrinkBuffer(buffer, final_output_len); |
133 | 134 |
134 return Status::Success(); | 135 return Status::Success(); |
135 } | 136 } |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 case blink::WebCryptoAlgorithmIdSha512: | 213 case blink::WebCryptoAlgorithmIdSha512: |
213 digest_algorithm = EVP_sha512(); | 214 digest_algorithm = EVP_sha512(); |
214 break; | 215 break; |
215 default: | 216 default: |
216 // Not a digest algorithm. | 217 // Not a digest algorithm. |
217 return Status::ErrorUnsupported(); | 218 return Status::ErrorUnsupported(); |
218 } | 219 } |
219 | 220 |
220 crypto::ScopedOpenSSL<EVP_MD_CTX, EVP_MD_CTX_destroy> digest_context( | 221 crypto::ScopedOpenSSL<EVP_MD_CTX, EVP_MD_CTX_destroy> digest_context( |
221 EVP_MD_CTX_create()); | 222 EVP_MD_CTX_create()); |
222 if (!digest_context.get()) { | 223 if (!digest_context.get()) |
223 return Status::Error(); | 224 return Status::Error(); |
224 } | |
225 | 225 |
226 if (!EVP_DigestInit_ex(digest_context.get(), digest_algorithm, NULL) || | 226 if (!EVP_DigestInit_ex(digest_context.get(), digest_algorithm, NULL) || |
227 !EVP_DigestUpdate(digest_context.get(), data, data_size)) { | 227 !EVP_DigestUpdate(digest_context.get(), data, data_size)) { |
228 return Status::Error(); | 228 return Status::Error(); |
229 } | 229 } |
230 | 230 |
231 const int hash_expected_size = EVP_MD_CTX_size(digest_context.get()); | 231 const int hash_expected_size = EVP_MD_CTX_size(digest_context.get()); |
232 if (hash_expected_size <= 0) { | 232 if (hash_expected_size <= 0) { |
233 return Status::ErrorUnexpected(); | 233 return Status::ErrorUnexpected(); |
234 } | 234 } |
(...skipping 22 matching lines...) Expand all Loading... |
257 unsigned keylen_bytes = 0; | 257 unsigned keylen_bytes = 0; |
258 blink::WebCryptoKeyType key_type; | 258 blink::WebCryptoKeyType key_type; |
259 switch (algorithm.id()) { | 259 switch (algorithm.id()) { |
260 case blink::WebCryptoAlgorithmIdAesCbc: { | 260 case blink::WebCryptoAlgorithmIdAesCbc: { |
261 const blink::WebCryptoAesKeyGenParams* params = | 261 const blink::WebCryptoAesKeyGenParams* params = |
262 algorithm.aesKeyGenParams(); | 262 algorithm.aesKeyGenParams(); |
263 DCHECK(params); | 263 DCHECK(params); |
264 if (params->lengthBits() % 8) | 264 if (params->lengthBits() % 8) |
265 return Status::ErrorGenerateKeyLength(); | 265 return Status::ErrorGenerateKeyLength(); |
266 keylen_bytes = params->lengthBits() / 8; | 266 keylen_bytes = params->lengthBits() / 8; |
267 if (!GetAESCipherByKeyLength(keylen_bytes)) { | 267 if (!GetAESCipherByKeyLength(keylen_bytes)) |
268 return Status::Error(); | 268 return Status::Error(); |
269 } | |
270 key_type = blink::WebCryptoKeyTypeSecret; | 269 key_type = blink::WebCryptoKeyTypeSecret; |
271 break; | 270 break; |
272 } | 271 } |
273 case blink::WebCryptoAlgorithmIdHmac: { | 272 case blink::WebCryptoAlgorithmIdHmac: { |
274 const blink::WebCryptoHmacKeyParams* params = algorithm.hmacKeyParams(); | 273 const blink::WebCryptoHmacKeyParams* params = algorithm.hmacKeyParams(); |
275 DCHECK(params); | 274 DCHECK(params); |
276 if (params->hasLengthBytes()) { | 275 if (params->hasLengthBytes()) |
277 keylen_bytes = params->optionalLengthBytes(); | 276 keylen_bytes = params->optionalLengthBytes(); |
278 } else { | 277 else |
279 keylen_bytes = webcrypto::ShaBlockSizeBytes(params->hash().id()); | 278 keylen_bytes = webcrypto::ShaBlockSizeBytes(params->hash().id()); |
280 } | |
281 key_type = blink::WebCryptoKeyTypeSecret; | 279 key_type = blink::WebCryptoKeyTypeSecret; |
282 break; | 280 break; |
283 } | 281 } |
284 | 282 |
285 default: { return Status::ErrorUnsupported(); } | 283 default: { return Status::ErrorUnsupported(); } |
286 } | 284 } |
287 | 285 |
288 if (keylen_bytes == 0) { | 286 if (keylen_bytes == 0) |
289 return Status::ErrorGenerateKeyLength(); | 287 return Status::ErrorGenerateKeyLength(); |
290 } | |
291 | 288 |
292 crypto::OpenSSLErrStackTracer(FROM_HERE); | 289 crypto::OpenSSLErrStackTracer(FROM_HERE); |
293 | 290 |
294 std::vector<unsigned char> random_bytes(keylen_bytes, 0); | 291 std::vector<unsigned char> random_bytes(keylen_bytes, 0); |
295 if (!(RAND_bytes(&random_bytes[0], keylen_bytes))) { | 292 if (!(RAND_bytes(&random_bytes[0], keylen_bytes))) |
296 return Status::Error(); | 293 return Status::Error(); |
297 } | |
298 | 294 |
299 *key = blink::WebCryptoKey::create( | 295 *key = blink::WebCryptoKey::create( |
300 new SymKeyHandle(&random_bytes[0], random_bytes.size()), | 296 new SymKeyHandle(&random_bytes[0], random_bytes.size()), |
301 key_type, extractable, algorithm, usage_mask); | 297 key_type, extractable, algorithm, usage_mask); |
302 | 298 |
303 return Status::Success(); | 299 return Status::Success(); |
304 } | 300 } |
305 | 301 |
306 Status WebCryptoImpl::GenerateKeyPairInternal( | 302 Status WebCryptoImpl::GenerateKeyPairInternal( |
307 const blink::WebCryptoAlgorithm& algorithm, | 303 const blink::WebCryptoAlgorithm& algorithm, |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
479 const blink::WebCryptoKey& key, | 475 const blink::WebCryptoKey& key, |
480 const unsigned char* signature, | 476 const unsigned char* signature, |
481 unsigned signature_size, | 477 unsigned signature_size, |
482 const unsigned char* data, | 478 const unsigned char* data, |
483 unsigned data_size, | 479 unsigned data_size, |
484 bool* signature_match) { | 480 bool* signature_match) { |
485 switch (algorithm.id()) { | 481 switch (algorithm.id()) { |
486 case blink::WebCryptoAlgorithmIdHmac: { | 482 case blink::WebCryptoAlgorithmIdHmac: { |
487 blink::WebArrayBuffer result; | 483 blink::WebArrayBuffer result; |
488 Status status = SignInternal(algorithm, key, data, data_size, &result); | 484 Status status = SignInternal(algorithm, key, data, data_size, &result); |
489 if (status.IsError()) { | 485 if (status.IsError()) |
490 return status; | 486 return status; |
491 } | |
492 | 487 |
493 // Handling of truncated signatures is underspecified in the WebCrypto | 488 // Handling of truncated signatures is underspecified in the WebCrypto |
494 // spec, so here we fail verification if a truncated signature is being | 489 // spec, so here we fail verification if a truncated signature is being |
495 // verified. | 490 // verified. |
496 // See https://www.w3.org/Bugs/Public/show_bug.cgi?id=23097 | 491 // See https://www.w3.org/Bugs/Public/show_bug.cgi?id=23097 |
497 *signature_match = | 492 *signature_match = |
498 result.byteLength() == signature_size && | 493 result.byteLength() == signature_size && |
499 crypto::SecureMemEqual(result.data(), signature, signature_size); | 494 crypto::SecureMemEqual(result.data(), signature, signature_size); |
500 | 495 |
501 break; | 496 break; |
(...skipping 12 matching lines...) Expand all Loading... |
514 const blink::WebCryptoAlgorithm& algorithm, | 509 const blink::WebCryptoAlgorithm& algorithm, |
515 bool extractable, | 510 bool extractable, |
516 blink::WebCryptoKeyUsageMask usage_mask, | 511 blink::WebCryptoKeyUsageMask usage_mask, |
517 blink::WebCryptoKey* key) { | 512 blink::WebCryptoKey* key) { |
518 // TODO(padolph): Placeholder for OpenSSL implementation. | 513 // TODO(padolph): Placeholder for OpenSSL implementation. |
519 // Issue http://crbug.com/267888. | 514 // Issue http://crbug.com/267888. |
520 return Status::ErrorUnsupported(); | 515 return Status::ErrorUnsupported(); |
521 } | 516 } |
522 | 517 |
523 } // namespace content | 518 } // namespace content |
OLD | NEW |