| OLD | NEW | 
|---|
|  | (Empty) | 
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. |  | 
| 2 // Use of this source code is governed by a BSD-style license that can be |  | 
| 3 // found in the LICENSE file. |  | 
| 4 |  | 
| 5 #include "base/stl_util.h" |  | 
| 6 #include "components/webcrypto/algorithm_implementation.h" |  | 
| 7 #include "components/webcrypto/crypto_data.h" |  | 
| 8 #include "components/webcrypto/openssl/key_openssl.h" |  | 
| 9 #include "components/webcrypto/openssl/util_openssl.h" |  | 
| 10 #include "components/webcrypto/status.h" |  | 
| 11 #include "components/webcrypto/webcrypto_util.h" |  | 
| 12 #include "crypto/openssl_util.h" |  | 
| 13 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" |  | 
| 14 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" |  | 
| 15 |  | 
| 16 namespace webcrypto { |  | 
| 17 |  | 
| 18 namespace { |  | 
| 19 |  | 
| 20 const blink::WebCryptoKeyUsageMask kAllKeyUsages = |  | 
| 21     blink::WebCryptoKeyUsageDeriveKey | blink::WebCryptoKeyUsageDeriveBits; |  | 
| 22 |  | 
| 23 class Pbkdf2Implementation : public AlgorithmImplementation { |  | 
| 24  public: |  | 
| 25   Pbkdf2Implementation() {} |  | 
| 26 |  | 
| 27   Status VerifyKeyUsagesBeforeImportKey( |  | 
| 28       blink::WebCryptoKeyFormat format, |  | 
| 29       blink::WebCryptoKeyUsageMask usages) const override { |  | 
| 30     switch (format) { |  | 
| 31       case blink::WebCryptoKeyFormatRaw: |  | 
| 32         return CheckKeyCreationUsages(kAllKeyUsages, usages, false); |  | 
| 33       default: |  | 
| 34         return Status::ErrorUnsupportedImportKeyFormat(); |  | 
| 35     } |  | 
| 36   } |  | 
| 37 |  | 
| 38   Status ImportKeyRaw(const CryptoData& key_data, |  | 
| 39                       const blink::WebCryptoAlgorithm& algorithm, |  | 
| 40                       bool extractable, |  | 
| 41                       blink::WebCryptoKeyUsageMask usages, |  | 
| 42                       blink::WebCryptoKey* key) const override { |  | 
| 43     const blink::WebCryptoKeyAlgorithm key_algorithm = |  | 
| 44         blink::WebCryptoKeyAlgorithm::createWithoutParams( |  | 
| 45             blink::WebCryptoAlgorithmIdPbkdf2); |  | 
| 46 |  | 
| 47     return CreateWebCryptoSecretKey(key_data, key_algorithm, extractable, |  | 
| 48                                     usages, key); |  | 
| 49   } |  | 
| 50 |  | 
| 51   Status DeriveBits(const blink::WebCryptoAlgorithm& algorithm, |  | 
| 52                     const blink::WebCryptoKey& base_key, |  | 
| 53                     bool has_optional_length_bits, |  | 
| 54                     unsigned int optional_length_bits, |  | 
| 55                     std::vector<uint8_t>* derived_bytes) const override { |  | 
| 56     crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); |  | 
| 57 |  | 
| 58     if (!has_optional_length_bits) |  | 
| 59       return Status::ErrorPbkdf2DeriveBitsLengthNotSpecified(); |  | 
| 60 |  | 
| 61     if (optional_length_bits % 8) |  | 
| 62       return Status::ErrorPbkdf2InvalidLength(); |  | 
| 63 |  | 
| 64     const blink::WebCryptoPbkdf2Params* params = algorithm.pbkdf2Params(); |  | 
| 65 |  | 
| 66     const blink::WebCryptoAlgorithm& hash = params->hash(); |  | 
| 67     const EVP_MD* digest_algorithm = GetDigest(hash.id()); |  | 
| 68     if (!digest_algorithm) |  | 
| 69       return Status::ErrorUnsupported(); |  | 
| 70 |  | 
| 71     unsigned int keylen_bytes = optional_length_bits / 8; |  | 
| 72     derived_bytes->resize(keylen_bytes); |  | 
| 73 |  | 
| 74     const std::vector<uint8_t>& password = |  | 
| 75         SymKeyOpenSsl::Cast(base_key)->raw_key_data(); |  | 
| 76 |  | 
| 77     if (!PKCS5_PBKDF2_HMAC( |  | 
| 78             reinterpret_cast<const char*>(vector_as_array(&password)), |  | 
| 79             password.size(), params->salt().data(), params->salt().size(), |  | 
| 80             params->iterations(), digest_algorithm, keylen_bytes, |  | 
| 81             vector_as_array(derived_bytes))) { |  | 
| 82       return Status::OperationError(); |  | 
| 83     } |  | 
| 84     return Status::Success(); |  | 
| 85   } |  | 
| 86 |  | 
| 87   Status SerializeKeyForClone( |  | 
| 88       const blink::WebCryptoKey& key, |  | 
| 89       blink::WebVector<uint8_t>* key_data) const override { |  | 
| 90     key_data->assign(SymKeyOpenSsl::Cast(key)->serialized_key_data()); |  | 
| 91     return Status::Success(); |  | 
| 92   } |  | 
| 93 |  | 
| 94   Status DeserializeKeyForClone(const blink::WebCryptoKeyAlgorithm& algorithm, |  | 
| 95                                 blink::WebCryptoKeyType type, |  | 
| 96                                 bool extractable, |  | 
| 97                                 blink::WebCryptoKeyUsageMask usages, |  | 
| 98                                 const CryptoData& key_data, |  | 
| 99                                 blink::WebCryptoKey* key) const override { |  | 
| 100     return CreateWebCryptoSecretKey(key_data, algorithm, extractable, usages, |  | 
| 101                                     key); |  | 
| 102   } |  | 
| 103 |  | 
| 104   Status GetKeyLength(const blink::WebCryptoAlgorithm& key_length_algorithm, |  | 
| 105                       bool* has_length_bits, |  | 
| 106                       unsigned int* length_bits) const override { |  | 
| 107     *has_length_bits = false; |  | 
| 108     return Status::Success(); |  | 
| 109   } |  | 
| 110 }; |  | 
| 111 |  | 
| 112 }  // namespace |  | 
| 113 |  | 
| 114 AlgorithmImplementation* CreatePlatformPbkdf2Implementation() { |  | 
| 115   return new Pbkdf2Implementation; |  | 
| 116 } |  | 
| 117 |  | 
| 118 }  // namespace webcrypto |  | 
| OLD | NEW | 
|---|