| 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 "components/webcrypto/algorithms/rsa.h" | 5 #include "components/webcrypto/algorithms/rsa.h" |
| 6 | 6 |
| 7 #include <openssl/evp.h> | 7 #include <openssl/evp.h> |
| 8 #include <utility> |
| 8 | 9 |
| 9 #include "base/logging.h" | 10 #include "base/logging.h" |
| 10 #include "components/webcrypto/algorithms/asymmetric_key_util.h" | 11 #include "components/webcrypto/algorithms/asymmetric_key_util.h" |
| 11 #include "components/webcrypto/algorithms/util.h" | 12 #include "components/webcrypto/algorithms/util.h" |
| 12 #include "components/webcrypto/blink_key_handle.h" | 13 #include "components/webcrypto/blink_key_handle.h" |
| 13 #include "components/webcrypto/crypto_data.h" | 14 #include "components/webcrypto/crypto_data.h" |
| 14 #include "components/webcrypto/generate_key_result.h" | 15 #include "components/webcrypto/generate_key_result.h" |
| 15 #include "components/webcrypto/jwk.h" | 16 #include "components/webcrypto/jwk.h" |
| 16 #include "components/webcrypto/status.h" | 17 #include "components/webcrypto/status.h" |
| 17 #include "crypto/openssl_util.h" | 18 #include "crypto/openssl_util.h" |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 const blink::WebCryptoAlgorithm& hash, | 141 const blink::WebCryptoAlgorithm& hash, |
| 141 bool extractable, | 142 bool extractable, |
| 142 blink::WebCryptoKeyUsageMask usages, | 143 blink::WebCryptoKeyUsageMask usages, |
| 143 blink::WebCryptoKey* key) { | 144 blink::WebCryptoKey* key) { |
| 144 blink::WebCryptoKeyAlgorithm key_algorithm; | 145 blink::WebCryptoKeyAlgorithm key_algorithm; |
| 145 Status status = CreateRsaHashedKeyAlgorithm( | 146 Status status = CreateRsaHashedKeyAlgorithm( |
| 146 rsa_algorithm_id, hash.id(), private_key.get(), &key_algorithm); | 147 rsa_algorithm_id, hash.id(), private_key.get(), &key_algorithm); |
| 147 if (status.IsError()) | 148 if (status.IsError()) |
| 148 return status; | 149 return status; |
| 149 | 150 |
| 150 return CreateWebCryptoPrivateKey(private_key.Pass(), key_algorithm, | 151 return CreateWebCryptoPrivateKey(std::move(private_key), key_algorithm, |
| 151 extractable, usages, key); | 152 extractable, usages, key); |
| 152 } | 153 } |
| 153 | 154 |
| 154 // Creates a WebCryptoKey that wraps |public_key|. | 155 // Creates a WebCryptoKey that wraps |public_key|. |
| 155 Status CreateWebCryptoRsaPublicKey( | 156 Status CreateWebCryptoRsaPublicKey( |
| 156 crypto::ScopedEVP_PKEY public_key, | 157 crypto::ScopedEVP_PKEY public_key, |
| 157 const blink::WebCryptoAlgorithmId rsa_algorithm_id, | 158 const blink::WebCryptoAlgorithmId rsa_algorithm_id, |
| 158 const blink::WebCryptoAlgorithm& hash, | 159 const blink::WebCryptoAlgorithm& hash, |
| 159 bool extractable, | 160 bool extractable, |
| 160 blink::WebCryptoKeyUsageMask usages, | 161 blink::WebCryptoKeyUsageMask usages, |
| 161 blink::WebCryptoKey* key) { | 162 blink::WebCryptoKey* key) { |
| 162 blink::WebCryptoKeyAlgorithm key_algorithm; | 163 blink::WebCryptoKeyAlgorithm key_algorithm; |
| 163 Status status = CreateRsaHashedKeyAlgorithm(rsa_algorithm_id, hash.id(), | 164 Status status = CreateRsaHashedKeyAlgorithm(rsa_algorithm_id, hash.id(), |
| 164 public_key.get(), &key_algorithm); | 165 public_key.get(), &key_algorithm); |
| 165 if (status.IsError()) | 166 if (status.IsError()) |
| 166 return status; | 167 return status; |
| 167 | 168 |
| 168 return CreateWebCryptoPublicKey(public_key.Pass(), key_algorithm, extractable, | 169 return CreateWebCryptoPublicKey(std::move(public_key), key_algorithm, |
| 169 usages, key); | 170 extractable, usages, key); |
| 170 } | 171 } |
| 171 | 172 |
| 172 Status ImportRsaPrivateKey(const blink::WebCryptoAlgorithm& algorithm, | 173 Status ImportRsaPrivateKey(const blink::WebCryptoAlgorithm& algorithm, |
| 173 bool extractable, | 174 bool extractable, |
| 174 blink::WebCryptoKeyUsageMask usages, | 175 blink::WebCryptoKeyUsageMask usages, |
| 175 const JwkRsaInfo& params, | 176 const JwkRsaInfo& params, |
| 176 blink::WebCryptoKey* key) { | 177 blink::WebCryptoKey* key) { |
| 177 crypto::ScopedRSA rsa(RSA_new()); | 178 crypto::ScopedRSA rsa(RSA_new()); |
| 178 | 179 |
| 179 rsa->n = CreateBIGNUM(params.n); | 180 rsa->n = CreateBIGNUM(params.n); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 192 | 193 |
| 193 // TODO(eroman): This should be a DataError. | 194 // TODO(eroman): This should be a DataError. |
| 194 if (!RSA_check_key(rsa.get())) | 195 if (!RSA_check_key(rsa.get())) |
| 195 return Status::OperationError(); | 196 return Status::OperationError(); |
| 196 | 197 |
| 197 // Create a corresponding EVP_PKEY. | 198 // Create a corresponding EVP_PKEY. |
| 198 crypto::ScopedEVP_PKEY pkey(EVP_PKEY_new()); | 199 crypto::ScopedEVP_PKEY pkey(EVP_PKEY_new()); |
| 199 if (!pkey || !EVP_PKEY_set1_RSA(pkey.get(), rsa.get())) | 200 if (!pkey || !EVP_PKEY_set1_RSA(pkey.get(), rsa.get())) |
| 200 return Status::OperationError(); | 201 return Status::OperationError(); |
| 201 | 202 |
| 202 return CreateWebCryptoRsaPrivateKey(pkey.Pass(), algorithm.id(), | 203 return CreateWebCryptoRsaPrivateKey(std::move(pkey), algorithm.id(), |
| 203 algorithm.rsaHashedImportParams()->hash(), | 204 algorithm.rsaHashedImportParams()->hash(), |
| 204 extractable, usages, key); | 205 extractable, usages, key); |
| 205 } | 206 } |
| 206 | 207 |
| 207 Status ImportRsaPublicKey(const blink::WebCryptoAlgorithm& algorithm, | 208 Status ImportRsaPublicKey(const blink::WebCryptoAlgorithm& algorithm, |
| 208 bool extractable, | 209 bool extractable, |
| 209 blink::WebCryptoKeyUsageMask usages, | 210 blink::WebCryptoKeyUsageMask usages, |
| 210 const CryptoData& n, | 211 const CryptoData& n, |
| 211 const CryptoData& e, | 212 const CryptoData& e, |
| 212 blink::WebCryptoKey* key) { | 213 blink::WebCryptoKey* key) { |
| 213 crypto::ScopedRSA rsa(RSA_new()); | 214 crypto::ScopedRSA rsa(RSA_new()); |
| 214 | 215 |
| 215 rsa->n = BN_bin2bn(n.bytes(), n.byte_length(), NULL); | 216 rsa->n = BN_bin2bn(n.bytes(), n.byte_length(), NULL); |
| 216 rsa->e = BN_bin2bn(e.bytes(), e.byte_length(), NULL); | 217 rsa->e = BN_bin2bn(e.bytes(), e.byte_length(), NULL); |
| 217 | 218 |
| 218 if (!rsa->n || !rsa->e) | 219 if (!rsa->n || !rsa->e) |
| 219 return Status::OperationError(); | 220 return Status::OperationError(); |
| 220 | 221 |
| 221 // Create a corresponding EVP_PKEY. | 222 // Create a corresponding EVP_PKEY. |
| 222 crypto::ScopedEVP_PKEY pkey(EVP_PKEY_new()); | 223 crypto::ScopedEVP_PKEY pkey(EVP_PKEY_new()); |
| 223 if (!pkey || !EVP_PKEY_set1_RSA(pkey.get(), rsa.get())) | 224 if (!pkey || !EVP_PKEY_set1_RSA(pkey.get(), rsa.get())) |
| 224 return Status::OperationError(); | 225 return Status::OperationError(); |
| 225 | 226 |
| 226 return CreateWebCryptoRsaPublicKey(pkey.Pass(), algorithm.id(), | 227 return CreateWebCryptoRsaPublicKey(std::move(pkey), algorithm.id(), |
| 227 algorithm.rsaHashedImportParams()->hash(), | 228 algorithm.rsaHashedImportParams()->hash(), |
| 228 extractable, usages, key); | 229 extractable, usages, key); |
| 229 } | 230 } |
| 230 | 231 |
| 231 // Converts a BIGNUM to a big endian byte array. | 232 // Converts a BIGNUM to a big endian byte array. |
| 232 std::vector<uint8_t> BIGNUMToVector(const BIGNUM* n) { | 233 std::vector<uint8_t> BIGNUMToVector(const BIGNUM* n) { |
| 233 std::vector<uint8_t> v(BN_num_bytes(n)); | 234 std::vector<uint8_t> v(BN_num_bytes(n)); |
| 234 BN_bn2bin(n, v.data()); | 235 BN_bn2bin(n, v.data()); |
| 235 return v; | 236 return v; |
| 236 } | 237 } |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 if (!public_pkey || | 314 if (!public_pkey || |
| 314 !EVP_PKEY_set1_RSA(public_pkey.get(), rsa_public_key.get())) { | 315 !EVP_PKEY_set1_RSA(public_pkey.get(), rsa_public_key.get())) { |
| 315 return Status::OperationError(); | 316 return Status::OperationError(); |
| 316 } | 317 } |
| 317 | 318 |
| 318 blink::WebCryptoKey public_key; | 319 blink::WebCryptoKey public_key; |
| 319 blink::WebCryptoKey private_key; | 320 blink::WebCryptoKey private_key; |
| 320 | 321 |
| 321 // Note that extractable is unconditionally set to true. This is because per | 322 // Note that extractable is unconditionally set to true. This is because per |
| 322 // the WebCrypto spec generated public keys are always extractable. | 323 // the WebCrypto spec generated public keys are always extractable. |
| 323 status = CreateWebCryptoRsaPublicKey(public_pkey.Pass(), algorithm.id(), | 324 status = CreateWebCryptoRsaPublicKey(std::move(public_pkey), algorithm.id(), |
| 324 params->hash(), true, public_usages, | 325 params->hash(), true, public_usages, |
| 325 &public_key); | 326 &public_key); |
| 326 if (status.IsError()) | 327 if (status.IsError()) |
| 327 return status; | 328 return status; |
| 328 | 329 |
| 329 status = CreateWebCryptoRsaPrivateKey(private_pkey.Pass(), algorithm.id(), | 330 status = CreateWebCryptoRsaPrivateKey(std::move(private_pkey), algorithm.id(), |
| 330 params->hash(), extractable, | 331 params->hash(), extractable, |
| 331 private_usages, &private_key); | 332 private_usages, &private_key); |
| 332 if (status.IsError()) | 333 if (status.IsError()) |
| 333 return status; | 334 return status; |
| 334 | 335 |
| 335 result->AssignKeyPair(public_key, private_key); | 336 result->AssignKeyPair(public_key, private_key); |
| 336 return Status::Success(); | 337 return Status::Success(); |
| 337 } | 338 } |
| 338 | 339 |
| 339 Status RsaHashedAlgorithm::VerifyKeyUsagesBeforeImportKey( | 340 Status RsaHashedAlgorithm::VerifyKeyUsagesBeforeImportKey( |
| (...skipping 18 matching lines...) Expand all Loading... |
| 358 // Verify the parameters of the key. | 359 // Verify the parameters of the key. |
| 359 crypto::ScopedRSA rsa(EVP_PKEY_get1_RSA(private_key.get())); | 360 crypto::ScopedRSA rsa(EVP_PKEY_get1_RSA(private_key.get())); |
| 360 if (!rsa.get()) | 361 if (!rsa.get()) |
| 361 return Status::ErrorUnexpected(); | 362 return Status::ErrorUnexpected(); |
| 362 if (!RSA_check_key(rsa.get())) | 363 if (!RSA_check_key(rsa.get())) |
| 363 return Status::DataError(); | 364 return Status::DataError(); |
| 364 | 365 |
| 365 // TODO(eroman): Validate the algorithm OID against the webcrypto provided | 366 // TODO(eroman): Validate the algorithm OID against the webcrypto provided |
| 366 // hash. http://crbug.com/389400 | 367 // hash. http://crbug.com/389400 |
| 367 | 368 |
| 368 return CreateWebCryptoRsaPrivateKey(private_key.Pass(), algorithm.id(), | 369 return CreateWebCryptoRsaPrivateKey(std::move(private_key), algorithm.id(), |
| 369 algorithm.rsaHashedImportParams()->hash(), | 370 algorithm.rsaHashedImportParams()->hash(), |
| 370 extractable, usages, key); | 371 extractable, usages, key); |
| 371 } | 372 } |
| 372 | 373 |
| 373 Status RsaHashedAlgorithm::ImportKeySpki( | 374 Status RsaHashedAlgorithm::ImportKeySpki( |
| 374 const CryptoData& key_data, | 375 const CryptoData& key_data, |
| 375 const blink::WebCryptoAlgorithm& algorithm, | 376 const blink::WebCryptoAlgorithm& algorithm, |
| 376 bool extractable, | 377 bool extractable, |
| 377 blink::WebCryptoKeyUsageMask usages, | 378 blink::WebCryptoKeyUsageMask usages, |
| 378 blink::WebCryptoKey* key) const { | 379 blink::WebCryptoKey* key) const { |
| 379 crypto::ScopedEVP_PKEY public_key; | 380 crypto::ScopedEVP_PKEY public_key; |
| 380 Status status = | 381 Status status = |
| 381 ImportUnverifiedPkeyFromSpki(key_data, EVP_PKEY_RSA, &public_key); | 382 ImportUnverifiedPkeyFromSpki(key_data, EVP_PKEY_RSA, &public_key); |
| 382 if (status.IsError()) | 383 if (status.IsError()) |
| 383 return status; | 384 return status; |
| 384 | 385 |
| 385 // TODO(eroman): Validate the algorithm OID against the webcrypto provided | 386 // TODO(eroman): Validate the algorithm OID against the webcrypto provided |
| 386 // hash. http://crbug.com/389400 | 387 // hash. http://crbug.com/389400 |
| 387 | 388 |
| 388 return CreateWebCryptoRsaPublicKey(public_key.Pass(), algorithm.id(), | 389 return CreateWebCryptoRsaPublicKey(std::move(public_key), algorithm.id(), |
| 389 algorithm.rsaHashedImportParams()->hash(), | 390 algorithm.rsaHashedImportParams()->hash(), |
| 390 extractable, usages, key); | 391 extractable, usages, key); |
| 391 } | 392 } |
| 392 | 393 |
| 393 Status RsaHashedAlgorithm::ImportKeyJwk( | 394 Status RsaHashedAlgorithm::ImportKeyJwk( |
| 394 const CryptoData& key_data, | 395 const CryptoData& key_data, |
| 395 const blink::WebCryptoAlgorithm& algorithm, | 396 const blink::WebCryptoAlgorithm& algorithm, |
| 396 bool extractable, | 397 bool extractable, |
| 397 blink::WebCryptoKeyUsageMask usages, | 398 blink::WebCryptoKeyUsageMask usages, |
| 398 blink::WebCryptoKey* key) const { | 399 blink::WebCryptoKey* key) const { |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 540 memcmp(algorithm.rsaHashedParams()->publicExponent().data(), | 541 memcmp(algorithm.rsaHashedParams()->publicExponent().data(), |
| 541 key->algorithm().rsaHashedParams()->publicExponent().data(), | 542 key->algorithm().rsaHashedParams()->publicExponent().data(), |
| 542 key->algorithm().rsaHashedParams()->publicExponent().size())) { | 543 key->algorithm().rsaHashedParams()->publicExponent().size())) { |
| 543 return Status::ErrorUnexpected(); | 544 return Status::ErrorUnexpected(); |
| 544 } | 545 } |
| 545 | 546 |
| 546 return Status::Success(); | 547 return Status::Success(); |
| 547 } | 548 } |
| 548 | 549 |
| 549 } // namespace webcrypto | 550 } // namespace webcrypto |
| OLD | NEW |