| 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/shared_crypto.h" | 5 #include "content/child/webcrypto/shared_crypto.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "content/child/webcrypto/crypto_data.h" | 8 #include "content/child/webcrypto/crypto_data.h" |
| 9 #include "content/child/webcrypto/jwk.h" | 9 #include "content/child/webcrypto/jwk.h" |
| 10 #include "content/child/webcrypto/platform_crypto.h" | 10 #include "content/child/webcrypto/platform_crypto.h" |
| 11 #include "content/child/webcrypto/status.h" | 11 #include "content/child/webcrypto/status.h" |
| 12 #include "content/child/webcrypto/webcrypto_util.h" | 12 #include "content/child/webcrypto/webcrypto_util.h" |
| 13 #include "crypto/secure_util.h" | 13 #include "crypto/secure_util.h" |
| 14 #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h" | 14 #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h" |
| 15 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" | 15 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" |
| 16 #include "third_party/WebKit/public/platform/WebCryptoKey.h" | 16 #include "third_party/WebKit/public/platform/WebCryptoKey.h" |
| 17 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" | 17 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" |
| 18 | 18 |
| 19 namespace content { | 19 namespace content { |
| 20 | 20 |
| 21 namespace webcrypto { | 21 namespace webcrypto { |
| 22 | 22 |
| 23 // ------------ | |
| 24 // Threading: | |
| 25 // ------------ | |
| 26 // | |
| 27 // All functions in this file are called from the webcrypto worker pool except | |
| 28 // for: | |
| 29 // | |
| 30 // * SerializeKeyForClone() | |
| 31 // * DeserializeKeyForClone() | |
| 32 // * ImportKey() // TODO(eroman): Change this. | |
| 33 | |
| 34 namespace { | 23 namespace { |
| 35 | 24 |
| 36 // TODO(eroman): Move this helper to WebCryptoKey. | 25 // TODO(eroman): Move this helper to WebCryptoKey. |
| 37 bool KeyUsageAllows(const blink::WebCryptoKey& key, | 26 bool KeyUsageAllows(const blink::WebCryptoKey& key, |
| 38 const blink::WebCryptoKeyUsage usage) { | 27 const blink::WebCryptoKeyUsage usage) { |
| 39 return ((key.usages() & usage) != 0); | 28 return ((key.usages() & usage) != 0); |
| 40 } | 29 } |
| 41 | 30 |
| 42 bool IsValidAesKeyLengthBits(unsigned int length_bits) { | 31 bool IsValidAesKeyLengthBits(unsigned int length_bits) { |
| 43 return length_bits == 128 || length_bits == 192 || length_bits == 256; | 32 return length_bits == 128 || length_bits == 192 || length_bits == 256; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 70 return Status::ErrorUnexpectedKeyType(); | 59 return Status::ErrorUnexpectedKeyType(); |
| 71 return Status::Success(); | 60 return Status::Success(); |
| 72 } | 61 } |
| 73 | 62 |
| 74 const size_t kAesBlockSizeBytes = 16; | 63 const size_t kAesBlockSizeBytes = 16; |
| 75 | 64 |
| 76 Status EncryptDecryptAesCbc(EncryptOrDecrypt mode, | 65 Status EncryptDecryptAesCbc(EncryptOrDecrypt mode, |
| 77 const blink::WebCryptoAlgorithm& algorithm, | 66 const blink::WebCryptoAlgorithm& algorithm, |
| 78 const blink::WebCryptoKey& key, | 67 const blink::WebCryptoKey& key, |
| 79 const CryptoData& data, | 68 const CryptoData& data, |
| 80 std::vector<uint8>* buffer) { | 69 blink::WebArrayBuffer* buffer) { |
| 81 platform::SymKey* sym_key; | 70 platform::SymKey* sym_key; |
| 82 Status status = ToPlatformSymKey(key, &sym_key); | 71 Status status = ToPlatformSymKey(key, &sym_key); |
| 83 if (status.IsError()) | 72 if (status.IsError()) |
| 84 return status; | 73 return status; |
| 85 | 74 |
| 86 const blink::WebCryptoAesCbcParams* params = algorithm.aesCbcParams(); | 75 const blink::WebCryptoAesCbcParams* params = algorithm.aesCbcParams(); |
| 87 if (!params) | 76 if (!params) |
| 88 return Status::ErrorUnexpected(); | 77 return Status::ErrorUnexpected(); |
| 89 | 78 |
| 90 CryptoData iv(params->iv().data(), params->iv().size()); | 79 CryptoData iv(params->iv().data(), params->iv().size()); |
| 91 if (iv.byte_length() != kAesBlockSizeBytes) | 80 if (iv.byte_length() != kAesBlockSizeBytes) |
| 92 return Status::ErrorIncorrectSizeAesCbcIv(); | 81 return Status::ErrorIncorrectSizeAesCbcIv(); |
| 93 | 82 |
| 94 return platform::EncryptDecryptAesCbc(mode, sym_key, data, iv, buffer); | 83 return platform::EncryptDecryptAesCbc(mode, sym_key, data, iv, buffer); |
| 95 } | 84 } |
| 96 | 85 |
| 97 Status EncryptDecryptAesGcm(EncryptOrDecrypt mode, | 86 Status EncryptDecryptAesGcm(EncryptOrDecrypt mode, |
| 98 const blink::WebCryptoAlgorithm& algorithm, | 87 const blink::WebCryptoAlgorithm& algorithm, |
| 99 const blink::WebCryptoKey& key, | 88 const blink::WebCryptoKey& key, |
| 100 const CryptoData& data, | 89 const CryptoData& data, |
| 101 std::vector<uint8>* buffer) { | 90 blink::WebArrayBuffer* buffer) { |
| 102 platform::SymKey* sym_key; | 91 platform::SymKey* sym_key; |
| 103 Status status = ToPlatformSymKey(key, &sym_key); | 92 Status status = ToPlatformSymKey(key, &sym_key); |
| 104 if (status.IsError()) | 93 if (status.IsError()) |
| 105 return status; | 94 return status; |
| 106 | 95 |
| 107 const blink::WebCryptoAesGcmParams* params = algorithm.aesGcmParams(); | 96 const blink::WebCryptoAesGcmParams* params = algorithm.aesGcmParams(); |
| 108 if (!params) | 97 if (!params) |
| 109 return Status::ErrorUnexpected(); | 98 return Status::ErrorUnexpected(); |
| 110 | 99 |
| 111 unsigned int tag_length_bits = 128; | 100 unsigned int tag_length_bits = 128; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 123 data, | 112 data, |
| 124 CryptoData(params->iv()), | 113 CryptoData(params->iv()), |
| 125 CryptoData(params->optionalAdditionalData()), | 114 CryptoData(params->optionalAdditionalData()), |
| 126 tag_length_bits, | 115 tag_length_bits, |
| 127 buffer); | 116 buffer); |
| 128 } | 117 } |
| 129 | 118 |
| 130 Status EncryptRsaEsPkcs1v1_5(const blink::WebCryptoAlgorithm& algorithm, | 119 Status EncryptRsaEsPkcs1v1_5(const blink::WebCryptoAlgorithm& algorithm, |
| 131 const blink::WebCryptoKey& key, | 120 const blink::WebCryptoKey& key, |
| 132 const CryptoData& data, | 121 const CryptoData& data, |
| 133 std::vector<uint8>* buffer) { | 122 blink::WebArrayBuffer* buffer) { |
| 134 platform::PublicKey* public_key; | 123 platform::PublicKey* public_key; |
| 135 Status status = ToPlatformPublicKey(key, &public_key); | 124 Status status = ToPlatformPublicKey(key, &public_key); |
| 136 if (status.IsError()) | 125 if (status.IsError()) |
| 137 return status; | 126 return status; |
| 138 | 127 |
| 139 // RSAES encryption does not support empty input | 128 // RSAES encryption does not support empty input |
| 140 if (!data.byte_length()) | 129 if (!data.byte_length()) |
| 141 return Status::ErrorDataTooSmall(); | 130 return Status::ErrorDataTooSmall(); |
| 142 | 131 |
| 143 return platform::EncryptRsaEsPkcs1v1_5(public_key, data, buffer); | 132 return platform::EncryptRsaEsPkcs1v1_5(public_key, data, buffer); |
| 144 } | 133 } |
| 145 | 134 |
| 146 Status DecryptRsaEsPkcs1v1_5(const blink::WebCryptoAlgorithm& algorithm, | 135 Status DecryptRsaEsPkcs1v1_5(const blink::WebCryptoAlgorithm& algorithm, |
| 147 const blink::WebCryptoKey& key, | 136 const blink::WebCryptoKey& key, |
| 148 const CryptoData& data, | 137 const CryptoData& data, |
| 149 std::vector<uint8>* buffer) { | 138 blink::WebArrayBuffer* buffer) { |
| 150 platform::PrivateKey* private_key; | 139 platform::PrivateKey* private_key; |
| 151 Status status = ToPlatformPrivateKey(key, &private_key); | 140 Status status = ToPlatformPrivateKey(key, &private_key); |
| 152 if (status.IsError()) | 141 if (status.IsError()) |
| 153 return status; | 142 return status; |
| 154 | 143 |
| 155 // RSAES decryption does not support empty input | 144 // RSAES decryption does not support empty input |
| 156 if (!data.byte_length()) | 145 if (!data.byte_length()) |
| 157 return Status::ErrorDataTooSmall(); | 146 return Status::ErrorDataTooSmall(); |
| 158 | 147 |
| 159 return platform::DecryptRsaEsPkcs1v1_5(private_key, data, buffer); | 148 return platform::DecryptRsaEsPkcs1v1_5(private_key, data, buffer); |
| 160 } | 149 } |
| 161 | 150 |
| 162 Status SignHmac(const blink::WebCryptoAlgorithm& algorithm, | 151 Status SignHmac(const blink::WebCryptoAlgorithm& algorithm, |
| 163 const blink::WebCryptoKey& key, | 152 const blink::WebCryptoKey& key, |
| 164 const CryptoData& data, | 153 const CryptoData& data, |
| 165 std::vector<uint8>* buffer) { | 154 blink::WebArrayBuffer* buffer) { |
| 166 platform::SymKey* sym_key; | 155 platform::SymKey* sym_key; |
| 167 Status status = ToPlatformSymKey(key, &sym_key); | 156 Status status = ToPlatformSymKey(key, &sym_key); |
| 168 if (status.IsError()) | 157 if (status.IsError()) |
| 169 return status; | 158 return status; |
| 170 | 159 |
| 171 return platform::SignHmac( | 160 return platform::SignHmac( |
| 172 sym_key, key.algorithm().hmacParams()->hash(), data, buffer); | 161 sym_key, key.algorithm().hmacParams()->hash(), data, buffer); |
| 173 } | 162 } |
| 174 | 163 |
| 175 Status VerifyHmac(const blink::WebCryptoAlgorithm& algorithm, | 164 Status VerifyHmac(const blink::WebCryptoAlgorithm& algorithm, |
| 176 const blink::WebCryptoKey& key, | 165 const blink::WebCryptoKey& key, |
| 177 const CryptoData& signature, | 166 const CryptoData& signature, |
| 178 const CryptoData& data, | 167 const CryptoData& data, |
| 179 bool* signature_match) { | 168 bool* signature_match) { |
| 180 std::vector<uint8> result; | 169 blink::WebArrayBuffer result; |
| 181 Status status = SignHmac(algorithm, key, data, &result); | 170 Status status = SignHmac(algorithm, key, data, &result); |
| 182 if (status.IsError()) | 171 if (status.IsError()) |
| 183 return status; | 172 return status; |
| 184 | 173 |
| 185 // Do not allow verification of truncated MACs. | 174 // Do not allow verification of truncated MACs. |
| 186 *signature_match = | 175 *signature_match = |
| 187 result.size() == signature.byte_length() && | 176 result.byteLength() == signature.byte_length() && |
| 188 crypto::SecureMemEqual( | 177 crypto::SecureMemEqual( |
| 189 Uint8VectorStart(result), signature.bytes(), signature.byte_length()); | 178 result.data(), signature.bytes(), signature.byte_length()); |
| 190 | 179 |
| 191 return Status::Success(); | 180 return Status::Success(); |
| 192 } | 181 } |
| 193 | 182 |
| 194 Status SignRsaSsaPkcs1v1_5(const blink::WebCryptoAlgorithm& algorithm, | 183 Status SignRsaSsaPkcs1v1_5(const blink::WebCryptoAlgorithm& algorithm, |
| 195 const blink::WebCryptoKey& key, | 184 const blink::WebCryptoKey& key, |
| 196 const CryptoData& data, | 185 const CryptoData& data, |
| 197 std::vector<uint8>* buffer) { | 186 blink::WebArrayBuffer* buffer) { |
| 198 platform::PrivateKey* private_key; | 187 platform::PrivateKey* private_key; |
| 199 Status status = ToPlatformPrivateKey(key, &private_key); | 188 Status status = ToPlatformPrivateKey(key, &private_key); |
| 200 if (status.IsError()) | 189 if (status.IsError()) |
| 201 return status; | 190 return status; |
| 202 | 191 |
| 203 return platform::SignRsaSsaPkcs1v1_5( | 192 return platform::SignRsaSsaPkcs1v1_5( |
| 204 private_key, key.algorithm().rsaHashedParams()->hash(), data, buffer); | 193 private_key, key.algorithm().rsaHashedParams()->hash(), data, buffer); |
| 205 } | 194 } |
| 206 | 195 |
| 207 Status VerifyRsaSsaPkcs1v1_5(const blink::WebCryptoAlgorithm& algorithm, | 196 Status VerifyRsaSsaPkcs1v1_5(const blink::WebCryptoAlgorithm& algorithm, |
| 208 const blink::WebCryptoKey& key, | 197 const blink::WebCryptoKey& key, |
| 209 const CryptoData& signature, | 198 const CryptoData& signature, |
| 210 const CryptoData& data, | 199 const CryptoData& data, |
| 211 bool* signature_match) { | 200 bool* signature_match) { |
| 212 platform::PublicKey* public_key; | 201 platform::PublicKey* public_key; |
| 213 Status status = ToPlatformPublicKey(key, &public_key); | 202 Status status = ToPlatformPublicKey(key, &public_key); |
| 214 if (status.IsError()) | 203 if (status.IsError()) |
| 215 return status; | 204 return status; |
| 216 | 205 |
| 217 return platform::VerifyRsaSsaPkcs1v1_5( | 206 return platform::VerifyRsaSsaPkcs1v1_5( |
| 218 public_key, | 207 public_key, |
| 219 key.algorithm().rsaHashedParams()->hash(), | 208 key.algorithm().rsaHashedParams()->hash(), |
| 220 signature, | 209 signature, |
| 221 data, | 210 data, |
| 222 signature_match); | 211 signature_match); |
| 223 } | 212 } |
| 224 | 213 |
| 225 // Note that this function may be called from the target Blink thread. | |
| 226 Status ImportKeyRaw(const CryptoData& key_data, | 214 Status ImportKeyRaw(const CryptoData& key_data, |
| 227 const blink::WebCryptoAlgorithm& algorithm, | 215 const blink::WebCryptoAlgorithm& algorithm, |
| 228 bool extractable, | 216 bool extractable, |
| 229 blink::WebCryptoKeyUsageMask usage_mask, | 217 blink::WebCryptoKeyUsageMask usage_mask, |
| 230 blink::WebCryptoKey* key) { | 218 blink::WebCryptoKey* key) { |
| 231 switch (algorithm.id()) { | 219 switch (algorithm.id()) { |
| 232 case blink::WebCryptoAlgorithmIdAesCtr: | 220 case blink::WebCryptoAlgorithmIdAesCtr: |
| 233 case blink::WebCryptoAlgorithmIdAesCbc: | 221 case blink::WebCryptoAlgorithmIdAesCbc: |
| 234 case blink::WebCryptoAlgorithmIdAesGcm: | 222 case blink::WebCryptoAlgorithmIdAesGcm: |
| 235 case blink::WebCryptoAlgorithmIdAesKw: | 223 case blink::WebCryptoAlgorithmIdAesKw: |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 return blink::WebCryptoAlgorithm::createNull(); | 266 return blink::WebCryptoAlgorithm::createNull(); |
| 279 } | 267 } |
| 280 | 268 |
| 281 // There is some duplicated information in the serialized format used by | 269 // There is some duplicated information in the serialized format used by |
| 282 // structured clone (since the KeyAlgorithm is serialized separately from the | 270 // structured clone (since the KeyAlgorithm is serialized separately from the |
| 283 // key data). Use this extra information to further validate what was | 271 // key data). Use this extra information to further validate what was |
| 284 // deserialized from the key data. | 272 // deserialized from the key data. |
| 285 // | 273 // |
| 286 // A failure here implies either a bug in the code, or that the serialized data | 274 // A failure here implies either a bug in the code, or that the serialized data |
| 287 // was corrupted. | 275 // was corrupted. |
| 288 bool ValidateDeserializedKey(const blink::WebCryptoKey& key, | 276 Status ValidateDeserializedKey(const blink::WebCryptoKey& key, |
| 289 const blink::WebCryptoKeyAlgorithm& algorithm, | 277 const blink::WebCryptoKeyAlgorithm& algorithm, |
| 290 blink::WebCryptoKeyType type) { | 278 blink::WebCryptoKeyType type) { |
| 291 if (algorithm.id() != key.algorithm().id()) | 279 if (algorithm.id() != key.algorithm().id()) |
| 292 return false; | 280 return Status::ErrorUnexpected(); |
| 293 | 281 |
| 294 if (key.type() != type) | 282 if (key.type() != type) |
| 295 return false; | 283 return Status::ErrorUnexpected(); |
| 296 | 284 |
| 297 switch (algorithm.paramsType()) { | 285 switch (algorithm.paramsType()) { |
| 298 case blink::WebCryptoKeyAlgorithmParamsTypeAes: | 286 case blink::WebCryptoKeyAlgorithmParamsTypeAes: |
| 299 if (algorithm.aesParams()->lengthBits() != | 287 if (algorithm.aesParams()->lengthBits() != |
| 300 key.algorithm().aesParams()->lengthBits()) | 288 key.algorithm().aesParams()->lengthBits()) |
| 301 return false; | 289 return Status::ErrorUnexpected(); |
| 302 break; | 290 break; |
| 303 case blink::WebCryptoKeyAlgorithmParamsTypeRsa: | 291 case blink::WebCryptoKeyAlgorithmParamsTypeRsa: |
| 304 case blink::WebCryptoKeyAlgorithmParamsTypeRsaHashed: | 292 case blink::WebCryptoKeyAlgorithmParamsTypeRsaHashed: |
| 305 if (algorithm.rsaParams()->modulusLengthBits() != | 293 if (algorithm.rsaParams()->modulusLengthBits() != |
| 306 key.algorithm().rsaParams()->modulusLengthBits()) | 294 key.algorithm().rsaParams()->modulusLengthBits()) |
| 307 return false; | 295 return Status::ErrorUnexpected(); |
| 308 if (algorithm.rsaParams()->publicExponent().size() != | 296 if (algorithm.rsaParams()->publicExponent().size() != |
| 309 key.algorithm().rsaParams()->publicExponent().size()) | 297 key.algorithm().rsaParams()->publicExponent().size()) |
| 310 return false; | 298 return Status::ErrorUnexpected(); |
| 311 if (memcmp(algorithm.rsaParams()->publicExponent().data(), | 299 if (memcmp(algorithm.rsaParams()->publicExponent().data(), |
| 312 key.algorithm().rsaParams()->publicExponent().data(), | 300 key.algorithm().rsaParams()->publicExponent().data(), |
| 313 key.algorithm().rsaParams()->publicExponent().size()) != 0) | 301 key.algorithm().rsaParams()->publicExponent().size()) != 0) |
| 314 return false; | 302 return Status::ErrorUnexpected(); |
| 315 break; | 303 break; |
| 316 case blink::WebCryptoKeyAlgorithmParamsTypeNone: | 304 case blink::WebCryptoKeyAlgorithmParamsTypeNone: |
| 317 case blink::WebCryptoKeyAlgorithmParamsTypeHmac: | 305 case blink::WebCryptoKeyAlgorithmParamsTypeHmac: |
| 318 break; | 306 break; |
| 319 } | 307 } |
| 320 | 308 |
| 321 return true; | 309 return Status::Success(); |
| 322 } | 310 } |
| 323 | 311 |
| 324 // Validates the size of data input to AES-KW. AES-KW requires the input data | 312 // Validates the size of data input to AES-KW. AES-KW requires the input data |
| 325 // size to be at least 24 bytes and a multiple of 8 bytes. | 313 // size to be at least 24 bytes and a multiple of 8 bytes. |
| 326 Status CheckAesKwInputSize(const CryptoData& aeskw_input_data) { | 314 Status CheckAesKwInputSize(const CryptoData& aeskw_input_data) { |
| 327 if (aeskw_input_data.byte_length() < 24) | 315 if (aeskw_input_data.byte_length() < 24) |
| 328 return Status::ErrorDataTooSmall(); | 316 return Status::ErrorDataTooSmall(); |
| 329 if (aeskw_input_data.byte_length() % 8) | 317 if (aeskw_input_data.byte_length() % 8) |
| 330 return Status::ErrorInvalidAesKwDataLength(); | 318 return Status::ErrorInvalidAesKwDataLength(); |
| 331 return Status::Success(); | 319 return Status::Success(); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 371 key); | 359 key); |
| 372 } | 360 } |
| 373 default: | 361 default: |
| 374 return Status::ErrorUnsupported(); | 362 return Status::ErrorUnsupported(); |
| 375 } | 363 } |
| 376 } | 364 } |
| 377 | 365 |
| 378 Status WrapKeyRaw(const blink::WebCryptoKey& wrapping_key, | 366 Status WrapKeyRaw(const blink::WebCryptoKey& wrapping_key, |
| 379 const blink::WebCryptoKey& key_to_wrap, | 367 const blink::WebCryptoKey& key_to_wrap, |
| 380 const blink::WebCryptoAlgorithm& wrapping_algorithm, | 368 const blink::WebCryptoAlgorithm& wrapping_algorithm, |
| 381 std::vector<uint8>* buffer) { | 369 blink::WebArrayBuffer* buffer) { |
| 382 // A raw key is always a symmetric key. | 370 // A raw key is always a symmetric key. |
| 383 platform::SymKey* platform_key; | 371 platform::SymKey* platform_key; |
| 384 Status status = ToPlatformSymKey(key_to_wrap, &platform_key); | 372 Status status = ToPlatformSymKey(key_to_wrap, &platform_key); |
| 385 if (status.IsError()) | 373 if (status.IsError()) |
| 386 return status; | 374 return status; |
| 387 | 375 |
| 388 // TODO(padolph): Handle other wrapping algorithms | 376 // TODO(padolph): Handle other wrapping algorithms |
| 389 switch (wrapping_algorithm.id()) { | 377 switch (wrapping_algorithm.id()) { |
| 390 case blink::WebCryptoAlgorithmIdAesKw: { | 378 case blink::WebCryptoAlgorithmIdAesKw: { |
| 391 platform::SymKey* platform_wrapping_key; | 379 platform::SymKey* platform_wrapping_key; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 404 platform_wrapping_key, platform_key, buffer); | 392 platform_wrapping_key, platform_key, buffer); |
| 405 } | 393 } |
| 406 default: | 394 default: |
| 407 return Status::ErrorUnsupported(); | 395 return Status::ErrorUnsupported(); |
| 408 } | 396 } |
| 409 } | 397 } |
| 410 | 398 |
| 411 Status DecryptAesKw(const blink::WebCryptoAlgorithm& algorithm, | 399 Status DecryptAesKw(const blink::WebCryptoAlgorithm& algorithm, |
| 412 const blink::WebCryptoKey& key, | 400 const blink::WebCryptoKey& key, |
| 413 const CryptoData& data, | 401 const CryptoData& data, |
| 414 std::vector<uint8>* buffer) { | 402 blink::WebArrayBuffer* buffer) { |
| 415 platform::SymKey* sym_key; | 403 platform::SymKey* sym_key; |
| 416 Status status = ToPlatformSymKey(key, &sym_key); | 404 Status status = ToPlatformSymKey(key, &sym_key); |
| 417 if (status.IsError()) | 405 if (status.IsError()) |
| 418 return status; | 406 return status; |
| 419 status = CheckAesKwInputSize(data); | 407 status = CheckAesKwInputSize(data); |
| 420 if (status.IsError()) | 408 if (status.IsError()) |
| 421 return status; | 409 return status; |
| 422 return platform::DecryptAesKw(sym_key, data, buffer); | 410 return platform::DecryptAesKw(sym_key, data, buffer); |
| 423 } | 411 } |
| 424 | 412 |
| 425 Status DecryptDontCheckKeyUsage(const blink::WebCryptoAlgorithm& algorithm, | 413 Status DecryptDontCheckKeyUsage(const blink::WebCryptoAlgorithm& algorithm, |
| 426 const blink::WebCryptoKey& key, | 414 const blink::WebCryptoKey& key, |
| 427 const CryptoData& data, | 415 const CryptoData& data, |
| 428 std::vector<uint8>* buffer) { | 416 blink::WebArrayBuffer* buffer) { |
| 429 if (algorithm.id() != key.algorithm().id()) | 417 if (algorithm.id() != key.algorithm().id()) |
| 430 return Status::ErrorUnexpected(); | 418 return Status::ErrorUnexpected(); |
| 431 switch (algorithm.id()) { | 419 switch (algorithm.id()) { |
| 432 case blink::WebCryptoAlgorithmIdAesCbc: | 420 case blink::WebCryptoAlgorithmIdAesCbc: |
| 433 return EncryptDecryptAesCbc(DECRYPT, algorithm, key, data, buffer); | 421 return EncryptDecryptAesCbc(DECRYPT, algorithm, key, data, buffer); |
| 434 case blink::WebCryptoAlgorithmIdAesGcm: | 422 case blink::WebCryptoAlgorithmIdAesGcm: |
| 435 return EncryptDecryptAesGcm(DECRYPT, algorithm, key, data, buffer); | 423 return EncryptDecryptAesGcm(DECRYPT, algorithm, key, data, buffer); |
| 436 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: | 424 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: |
| 437 return DecryptRsaEsPkcs1v1_5(algorithm, key, data, buffer); | 425 return DecryptRsaEsPkcs1v1_5(algorithm, key, data, buffer); |
| 438 case blink::WebCryptoAlgorithmIdAesKw: | 426 case blink::WebCryptoAlgorithmIdAesKw: |
| 439 return DecryptAesKw(algorithm, key, data, buffer); | 427 return DecryptAesKw(algorithm, key, data, buffer); |
| 440 default: | 428 default: |
| 441 return Status::ErrorUnsupported(); | 429 return Status::ErrorUnsupported(); |
| 442 } | 430 } |
| 443 } | 431 } |
| 444 | 432 |
| 445 Status EncryptDontCheckUsage(const blink::WebCryptoAlgorithm& algorithm, | 433 Status EncryptDontCheckUsage(const blink::WebCryptoAlgorithm& algorithm, |
| 446 const blink::WebCryptoKey& key, | 434 const blink::WebCryptoKey& key, |
| 447 const CryptoData& data, | 435 const CryptoData& data, |
| 448 std::vector<uint8>* buffer) { | 436 blink::WebArrayBuffer* buffer) { |
| 449 if (algorithm.id() != key.algorithm().id()) | 437 if (algorithm.id() != key.algorithm().id()) |
| 450 return Status::ErrorUnexpected(); | 438 return Status::ErrorUnexpected(); |
| 451 switch (algorithm.id()) { | 439 switch (algorithm.id()) { |
| 452 case blink::WebCryptoAlgorithmIdAesCbc: | 440 case blink::WebCryptoAlgorithmIdAesCbc: |
| 453 return EncryptDecryptAesCbc(ENCRYPT, algorithm, key, data, buffer); | 441 return EncryptDecryptAesCbc(ENCRYPT, algorithm, key, data, buffer); |
| 454 case blink::WebCryptoAlgorithmIdAesGcm: | 442 case blink::WebCryptoAlgorithmIdAesGcm: |
| 455 return EncryptDecryptAesGcm(ENCRYPT, algorithm, key, data, buffer); | 443 return EncryptDecryptAesGcm(ENCRYPT, algorithm, key, data, buffer); |
| 456 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: | 444 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: |
| 457 return EncryptRsaEsPkcs1v1_5(algorithm, key, data, buffer); | 445 return EncryptRsaEsPkcs1v1_5(algorithm, key, data, buffer); |
| 458 default: | 446 default: |
| 459 return Status::ErrorUnsupported(); | 447 return Status::ErrorUnsupported(); |
| 460 } | 448 } |
| 461 } | 449 } |
| 462 | 450 |
| 463 Status UnwrapKeyDecryptAndImport( | 451 Status UnwrapKeyDecryptAndImport( |
| 464 blink::WebCryptoKeyFormat format, | 452 blink::WebCryptoKeyFormat format, |
| 465 const CryptoData& wrapped_key_data, | 453 const CryptoData& wrapped_key_data, |
| 466 const blink::WebCryptoKey& wrapping_key, | 454 const blink::WebCryptoKey& wrapping_key, |
| 467 const blink::WebCryptoAlgorithm& wrapping_algorithm, | 455 const blink::WebCryptoAlgorithm& wrapping_algorithm, |
| 468 const blink::WebCryptoAlgorithm& algorithm, | 456 const blink::WebCryptoAlgorithm& algorithm, |
| 469 bool extractable, | 457 bool extractable, |
| 470 blink::WebCryptoKeyUsageMask usage_mask, | 458 blink::WebCryptoKeyUsageMask usage_mask, |
| 471 blink::WebCryptoKey* key) { | 459 blink::WebCryptoKey* key) { |
| 472 std::vector<uint8> buffer; | 460 blink::WebArrayBuffer buffer; |
| 473 Status status = DecryptDontCheckKeyUsage( | 461 Status status = DecryptDontCheckKeyUsage( |
| 474 wrapping_algorithm, wrapping_key, wrapped_key_data, &buffer); | 462 wrapping_algorithm, wrapping_key, wrapped_key_data, &buffer); |
| 475 if (status.IsError()) | 463 if (status.IsError()) |
| 476 return status; | 464 return status; |
| 477 status = ImportKey( | 465 status = ImportKey( |
| 478 format, CryptoData(buffer), algorithm, extractable, usage_mask, key); | 466 format, CryptoData(buffer), algorithm, extractable, usage_mask, key); |
| 479 // NOTE! Returning the details of any ImportKey() failure here would leak | 467 // NOTE! Returning the details of any ImportKey() failure here would leak |
| 480 // information about the plaintext internals of the encrypted key. Instead, | 468 // information about the plaintext internals of the encrypted key. Instead, |
| 481 // collapse any error into the generic Status::OperationError(). | 469 // collapse any error into the generic Status::OperationError(). |
| 482 return status.IsError() ? Status::OperationError() : Status::Success(); | 470 return status.IsError() ? Status::OperationError() : Status::Success(); |
| 483 } | 471 } |
| 484 | 472 |
| 485 Status WrapKeyExportAndEncrypt( | 473 Status WrapKeyExportAndEncrypt( |
| 486 blink::WebCryptoKeyFormat format, | 474 blink::WebCryptoKeyFormat format, |
| 487 const blink::WebCryptoKey& wrapping_key, | 475 const blink::WebCryptoKey& wrapping_key, |
| 488 const blink::WebCryptoKey& key_to_wrap, | 476 const blink::WebCryptoKey& key_to_wrap, |
| 489 const blink::WebCryptoAlgorithm& wrapping_algorithm, | 477 const blink::WebCryptoAlgorithm& wrapping_algorithm, |
| 490 std::vector<uint8>* buffer) { | 478 blink::WebArrayBuffer* buffer) { |
| 491 std::vector<uint8> exported_data; | 479 blink::WebArrayBuffer exported_data; |
| 492 Status status = ExportKey(format, key_to_wrap, &exported_data); | 480 Status status = ExportKey(format, key_to_wrap, &exported_data); |
| 493 if (status.IsError()) | 481 if (status.IsError()) |
| 494 return status; | 482 return status; |
| 495 return EncryptDontCheckUsage( | 483 return EncryptDontCheckUsage( |
| 496 wrapping_algorithm, wrapping_key, CryptoData(exported_data), buffer); | 484 wrapping_algorithm, wrapping_key, CryptoData(exported_data), buffer); |
| 497 } | 485 } |
| 498 | 486 |
| 499 // Returns the internal block size for SHA-* | 487 // Returns the internal block size for SHA-* |
| 500 unsigned int ShaBlockSizeBytes(blink::WebCryptoAlgorithmId hash_id) { | 488 unsigned int ShaBlockSizeBytes(blink::WebCryptoAlgorithmId hash_id) { |
| 501 switch (hash_id) { | 489 switch (hash_id) { |
| 502 case blink::WebCryptoAlgorithmIdSha1: | 490 case blink::WebCryptoAlgorithmIdSha1: |
| 503 case blink::WebCryptoAlgorithmIdSha256: | 491 case blink::WebCryptoAlgorithmIdSha256: |
| 504 return 64; | 492 return 64; |
| 505 case blink::WebCryptoAlgorithmIdSha384: | 493 case blink::WebCryptoAlgorithmIdSha384: |
| 506 case blink::WebCryptoAlgorithmIdSha512: | 494 case blink::WebCryptoAlgorithmIdSha512: |
| 507 return 128; | 495 return 128; |
| 508 default: | 496 default: |
| 509 NOTREACHED(); | 497 NOTREACHED(); |
| 510 return 0; | 498 return 0; |
| 511 } | 499 } |
| 512 } | 500 } |
| 513 | 501 |
| 514 } // namespace | 502 } // namespace |
| 515 | 503 |
| 516 void Init() { platform::Init(); } | 504 void Init() { platform::Init(); } |
| 517 | 505 |
| 518 Status Encrypt(const blink::WebCryptoAlgorithm& algorithm, | 506 Status Encrypt(const blink::WebCryptoAlgorithm& algorithm, |
| 519 const blink::WebCryptoKey& key, | 507 const blink::WebCryptoKey& key, |
| 520 const CryptoData& data, | 508 const CryptoData& data, |
| 521 std::vector<uint8>* buffer) { | 509 blink::WebArrayBuffer* buffer) { |
| 522 if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageEncrypt)) | 510 if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageEncrypt)) |
| 523 return Status::ErrorUnexpected(); | 511 return Status::ErrorUnexpected(); |
| 524 return EncryptDontCheckUsage(algorithm, key, data, buffer); | 512 return EncryptDontCheckUsage(algorithm, key, data, buffer); |
| 525 } | 513 } |
| 526 | 514 |
| 527 Status Decrypt(const blink::WebCryptoAlgorithm& algorithm, | 515 Status Decrypt(const blink::WebCryptoAlgorithm& algorithm, |
| 528 const blink::WebCryptoKey& key, | 516 const blink::WebCryptoKey& key, |
| 529 const CryptoData& data, | 517 const CryptoData& data, |
| 530 std::vector<uint8>* buffer) { | 518 blink::WebArrayBuffer* buffer) { |
| 531 if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageDecrypt)) | 519 if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageDecrypt)) |
| 532 return Status::ErrorUnexpected(); | 520 return Status::ErrorUnexpected(); |
| 533 return DecryptDontCheckKeyUsage(algorithm, key, data, buffer); | 521 return DecryptDontCheckKeyUsage(algorithm, key, data, buffer); |
| 534 } | 522 } |
| 535 | 523 |
| 536 Status Digest(const blink::WebCryptoAlgorithm& algorithm, | 524 Status Digest(const blink::WebCryptoAlgorithm& algorithm, |
| 537 const CryptoData& data, | 525 const CryptoData& data, |
| 538 std::vector<uint8>* buffer) { | 526 blink::WebArrayBuffer* buffer) { |
| 539 switch (algorithm.id()) { | 527 switch (algorithm.id()) { |
| 540 case blink::WebCryptoAlgorithmIdSha1: | 528 case blink::WebCryptoAlgorithmIdSha1: |
| 541 case blink::WebCryptoAlgorithmIdSha256: | 529 case blink::WebCryptoAlgorithmIdSha256: |
| 542 case blink::WebCryptoAlgorithmIdSha384: | 530 case blink::WebCryptoAlgorithmIdSha384: |
| 543 case blink::WebCryptoAlgorithmIdSha512: | 531 case blink::WebCryptoAlgorithmIdSha512: |
| 544 return platform::DigestSha(algorithm.id(), data, buffer); | 532 return platform::DigestSha(algorithm.id(), data, buffer); |
| 545 default: | 533 default: |
| 546 return Status::ErrorUnsupported(); | 534 return Status::ErrorUnsupported(); |
| 547 } | 535 } |
| 548 } | 536 } |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 631 publicExponent, | 619 publicExponent, |
| 632 hash_or_null, | 620 hash_or_null, |
| 633 public_key, | 621 public_key, |
| 634 private_key); | 622 private_key); |
| 635 } | 623 } |
| 636 default: | 624 default: |
| 637 return Status::ErrorUnsupported(); | 625 return Status::ErrorUnsupported(); |
| 638 } | 626 } |
| 639 } | 627 } |
| 640 | 628 |
| 641 // Note that this function may be called from the target Blink thread. | |
| 642 Status ImportKey(blink::WebCryptoKeyFormat format, | 629 Status ImportKey(blink::WebCryptoKeyFormat format, |
| 643 const CryptoData& key_data, | 630 const CryptoData& key_data, |
| 644 const blink::WebCryptoAlgorithm& algorithm, | 631 const blink::WebCryptoAlgorithm& algorithm, |
| 645 bool extractable, | 632 bool extractable, |
| 646 blink::WebCryptoKeyUsageMask usage_mask, | 633 blink::WebCryptoKeyUsageMask usage_mask, |
| 647 blink::WebCryptoKey* key) { | 634 blink::WebCryptoKey* key) { |
| 648 switch (format) { | 635 switch (format) { |
| 649 case blink::WebCryptoKeyFormatRaw: | 636 case blink::WebCryptoKeyFormatRaw: |
| 650 return ImportKeyRaw(key_data, algorithm, extractable, usage_mask, key); | 637 return ImportKeyRaw(key_data, algorithm, extractable, usage_mask, key); |
| 651 case blink::WebCryptoKeyFormatSpki: | 638 case blink::WebCryptoKeyFormatSpki: |
| 652 return platform::ImportKeySpki( | 639 return platform::ImportKeySpki( |
| 653 algorithm, key_data, extractable, usage_mask, key); | 640 algorithm, key_data, extractable, usage_mask, key); |
| 654 case blink::WebCryptoKeyFormatPkcs8: | 641 case blink::WebCryptoKeyFormatPkcs8: |
| 655 return platform::ImportKeyPkcs8( | 642 return platform::ImportKeyPkcs8( |
| 656 algorithm, key_data, extractable, usage_mask, key); | 643 algorithm, key_data, extractable, usage_mask, key); |
| 657 case blink::WebCryptoKeyFormatJwk: | 644 case blink::WebCryptoKeyFormatJwk: |
| 658 return ImportKeyJwk(key_data, algorithm, extractable, usage_mask, key); | 645 return ImportKeyJwk(key_data, algorithm, extractable, usage_mask, key); |
| 659 default: | 646 default: |
| 660 return Status::ErrorUnsupported(); | 647 return Status::ErrorUnsupported(); |
| 661 } | 648 } |
| 662 } | 649 } |
| 663 | 650 |
| 664 // TODO(eroman): Move this to anonymous namespace. | 651 // TODO(eroman): Move this to anonymous namespace. |
| 665 Status ExportKeyDontCheckExtractability(blink::WebCryptoKeyFormat format, | 652 Status ExportKeyDontCheckExtractability(blink::WebCryptoKeyFormat format, |
| 666 const blink::WebCryptoKey& key, | 653 const blink::WebCryptoKey& key, |
| 667 std::vector<uint8>* buffer) { | 654 blink::WebArrayBuffer* buffer) { |
| 668 switch (format) { | 655 switch (format) { |
| 669 case blink::WebCryptoKeyFormatRaw: { | 656 case blink::WebCryptoKeyFormatRaw: { |
| 670 platform::SymKey* sym_key; | 657 platform::SymKey* sym_key; |
| 671 Status status = ToPlatformSymKey(key, &sym_key); | 658 Status status = ToPlatformSymKey(key, &sym_key); |
| 672 if (status.IsError()) | 659 if (status.IsError()) |
| 673 return status; | 660 return status; |
| 674 return platform::ExportKeyRaw(sym_key, buffer); | 661 return platform::ExportKeyRaw(sym_key, buffer); |
| 675 } | 662 } |
| 676 case blink::WebCryptoKeyFormatSpki: { | 663 case blink::WebCryptoKeyFormatSpki: { |
| 677 platform::PublicKey* public_key; | 664 platform::PublicKey* public_key; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 689 } | 676 } |
| 690 case blink::WebCryptoKeyFormatJwk: | 677 case blink::WebCryptoKeyFormatJwk: |
| 691 return ExportKeyJwk(key, buffer); | 678 return ExportKeyJwk(key, buffer); |
| 692 default: | 679 default: |
| 693 return Status::ErrorUnsupported(); | 680 return Status::ErrorUnsupported(); |
| 694 } | 681 } |
| 695 } | 682 } |
| 696 | 683 |
| 697 Status ExportKey(blink::WebCryptoKeyFormat format, | 684 Status ExportKey(blink::WebCryptoKeyFormat format, |
| 698 const blink::WebCryptoKey& key, | 685 const blink::WebCryptoKey& key, |
| 699 std::vector<uint8>* buffer) { | 686 blink::WebArrayBuffer* buffer) { |
| 700 if (!key.extractable()) | 687 if (!key.extractable()) |
| 701 return Status::ErrorKeyNotExtractable(); | 688 return Status::ErrorKeyNotExtractable(); |
| 702 return ExportKeyDontCheckExtractability(format, key, buffer); | 689 return ExportKeyDontCheckExtractability(format, key, buffer); |
| 703 } | 690 } |
| 704 | 691 |
| 705 Status Sign(const blink::WebCryptoAlgorithm& algorithm, | 692 Status Sign(const blink::WebCryptoAlgorithm& algorithm, |
| 706 const blink::WebCryptoKey& key, | 693 const blink::WebCryptoKey& key, |
| 707 const CryptoData& data, | 694 const CryptoData& data, |
| 708 std::vector<uint8>* buffer) { | 695 blink::WebArrayBuffer* buffer) { |
| 709 if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageSign)) | 696 if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageSign)) |
| 710 return Status::ErrorUnexpected(); | 697 return Status::ErrorUnexpected(); |
| 711 if (algorithm.id() != key.algorithm().id()) | 698 if (algorithm.id() != key.algorithm().id()) |
| 712 return Status::ErrorUnexpected(); | 699 return Status::ErrorUnexpected(); |
| 713 | 700 |
| 714 switch (algorithm.id()) { | 701 switch (algorithm.id()) { |
| 715 case blink::WebCryptoAlgorithmIdHmac: | 702 case blink::WebCryptoAlgorithmIdHmac: |
| 716 return SignHmac(algorithm, key, data, buffer); | 703 return SignHmac(algorithm, key, data, buffer); |
| 717 case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: | 704 case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: |
| 718 return SignRsaSsaPkcs1v1_5(algorithm, key, data, buffer); | 705 return SignRsaSsaPkcs1v1_5(algorithm, key, data, buffer); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 747 algorithm, key, signature, data, signature_match); | 734 algorithm, key, signature, data, signature_match); |
| 748 default: | 735 default: |
| 749 return Status::ErrorUnsupported(); | 736 return Status::ErrorUnsupported(); |
| 750 } | 737 } |
| 751 } | 738 } |
| 752 | 739 |
| 753 Status WrapKey(blink::WebCryptoKeyFormat format, | 740 Status WrapKey(blink::WebCryptoKeyFormat format, |
| 754 const blink::WebCryptoKey& wrapping_key, | 741 const blink::WebCryptoKey& wrapping_key, |
| 755 const blink::WebCryptoKey& key_to_wrap, | 742 const blink::WebCryptoKey& key_to_wrap, |
| 756 const blink::WebCryptoAlgorithm& wrapping_algorithm, | 743 const blink::WebCryptoAlgorithm& wrapping_algorithm, |
| 757 std::vector<uint8>* buffer) { | 744 blink::WebArrayBuffer* buffer) { |
| 758 if (!KeyUsageAllows(wrapping_key, blink::WebCryptoKeyUsageWrapKey)) | 745 if (!KeyUsageAllows(wrapping_key, blink::WebCryptoKeyUsageWrapKey)) |
| 759 return Status::ErrorUnexpected(); | 746 return Status::ErrorUnexpected(); |
| 760 if (wrapping_algorithm.id() != wrapping_key.algorithm().id()) | 747 if (wrapping_algorithm.id() != wrapping_key.algorithm().id()) |
| 761 return Status::ErrorUnexpected(); | 748 return Status::ErrorUnexpected(); |
| 762 | 749 |
| 763 switch (format) { | 750 switch (format) { |
| 764 case blink::WebCryptoKeyFormatRaw: | 751 case blink::WebCryptoKeyFormatRaw: |
| 765 return WrapKeyRaw(wrapping_key, key_to_wrap, wrapping_algorithm, buffer); | 752 return WrapKeyRaw(wrapping_key, key_to_wrap, wrapping_algorithm, buffer); |
| 766 case blink::WebCryptoKeyFormatJwk: | 753 case blink::WebCryptoKeyFormatJwk: |
| 767 return WrapKeyExportAndEncrypt( | 754 return WrapKeyExportAndEncrypt( |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 808 key); | 795 key); |
| 809 case blink::WebCryptoKeyFormatSpki: | 796 case blink::WebCryptoKeyFormatSpki: |
| 810 case blink::WebCryptoKeyFormatPkcs8: | 797 case blink::WebCryptoKeyFormatPkcs8: |
| 811 return Status::ErrorUnsupported(); // TODO(padolph) | 798 return Status::ErrorUnsupported(); // TODO(padolph) |
| 812 default: | 799 default: |
| 813 NOTREACHED(); | 800 NOTREACHED(); |
| 814 return Status::ErrorUnsupported(); | 801 return Status::ErrorUnsupported(); |
| 815 } | 802 } |
| 816 } | 803 } |
| 817 | 804 |
| 818 // Note that this function is called from the target Blink thread. | 805 Status SerializeKeyForClone(const blink::WebCryptoKey& key, |
| 819 bool SerializeKeyForClone(const blink::WebCryptoKey& key, | 806 blink::WebVector<unsigned char>* data) { |
| 820 blink::WebVector<uint8>* key_data) { | 807 blink::WebArrayBuffer buffer; |
| 821 return static_cast<webcrypto::platform::Key*>(key.handle()) | 808 Status status = ExportKeyDontCheckExtractability( |
| 822 ->ThreadSafeSerializeForClone(key_data); | 809 GetCloneFormatForKeyType(key.type()), key, &buffer); |
| 810 if (status.IsError()) |
| 811 return status; |
| 812 data->assign( |
| 813 reinterpret_cast<unsigned char*>(buffer.data()), buffer.byteLength()); |
| 814 return Status::Success(); |
| 823 } | 815 } |
| 824 | 816 |
| 825 // Note that this function is called from the target Blink thread. | 817 Status DeserializeKeyForClone(const blink::WebCryptoKeyAlgorithm& algorithm, |
| 826 bool DeserializeKeyForClone(const blink::WebCryptoKeyAlgorithm& algorithm, | 818 blink::WebCryptoKeyType type, |
| 827 blink::WebCryptoKeyType type, | 819 bool extractable, |
| 828 bool extractable, | 820 blink::WebCryptoKeyUsageMask usage_mask, |
| 829 blink::WebCryptoKeyUsageMask usage_mask, | 821 const CryptoData& key_data, |
| 830 const CryptoData& key_data, | 822 blink::WebCryptoKey* key) { |
| 831 blink::WebCryptoKey* key) { | |
| 832 // TODO(eroman): This should not call into the platform crypto layer. | |
| 833 // Otherwise it runs the risk of stalling while the NSS/OpenSSL global locks | |
| 834 // are held. | |
| 835 // | |
| 836 // An alternate approach is to defer the key import until the key is used. | |
| 837 // However this means that any deserialization errors would have to be | |
| 838 // surfaced as WebCrypto errors, leading to slightly different behaviors. For | |
| 839 // instance you could clone a key which fails to be deserialized. | |
| 840 Status status = ImportKey(GetCloneFormatForKeyType(type), | 823 Status status = ImportKey(GetCloneFormatForKeyType(type), |
| 841 key_data, | 824 key_data, |
| 842 KeyAlgorithmToImportAlgorithm(algorithm), | 825 KeyAlgorithmToImportAlgorithm(algorithm), |
| 843 extractable, | 826 extractable, |
| 844 usage_mask, | 827 usage_mask, |
| 845 key); | 828 key); |
| 846 if (status.IsError()) | 829 if (status.IsError()) |
| 847 return false; | 830 return status; |
| 831 |
| 848 return ValidateDeserializedKey(*key, algorithm, type); | 832 return ValidateDeserializedKey(*key, algorithm, type); |
| 849 } | 833 } |
| 850 | 834 |
| 851 } // namespace webcrypto | 835 } // namespace webcrypto |
| 852 | 836 |
| 853 } // namespace content | 837 } // namespace content |
| OLD | NEW |