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 |