| 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 |