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