Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(149)

Side by Side Diff: components/webcrypto/algorithms/ec.cc

Issue 2162303002: [webcrypto] Add support for import/export of "raw" formatted EC keys. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@usage_order
Patch Set: address feedback Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « components/webcrypto/algorithms/ec.h ('k') | components/webcrypto/ec_import_key_raw_fuzzer.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/ec.h" 5 #include "components/webcrypto/algorithms/ec.h"
6 6
7 #include <openssl/ec.h> 7 #include <openssl/ec.h>
8 #include <openssl/ec_key.h> 8 #include <openssl/ec_key.h>
9 #include <openssl/evp.h> 9 #include <openssl/evp.h>
10 #include <stddef.h> 10 #include <stddef.h>
11 #include <utility> 11 #include <utility>
12 12
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/macros.h" 14 #include "base/macros.h"
15 #include "components/webcrypto/algorithms/asymmetric_key_util.h" 15 #include "components/webcrypto/algorithms/asymmetric_key_util.h"
16 #include "components/webcrypto/algorithms/util.h" 16 #include "components/webcrypto/algorithms/util.h"
17 #include "components/webcrypto/blink_key_handle.h" 17 #include "components/webcrypto/blink_key_handle.h"
18 #include "components/webcrypto/crypto_data.h" 18 #include "components/webcrypto/crypto_data.h"
19 #include "components/webcrypto/generate_key_result.h" 19 #include "components/webcrypto/generate_key_result.h"
20 #include "components/webcrypto/jwk.h" 20 #include "components/webcrypto/jwk.h"
21 #include "components/webcrypto/status.h" 21 #include "components/webcrypto/status.h"
22 #include "crypto/auto_cbb.h"
22 #include "crypto/openssl_util.h" 23 #include "crypto/openssl_util.h"
23 #include "crypto/scoped_openssl_types.h" 24 #include "crypto/scoped_openssl_types.h"
24 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" 25 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
25 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" 26 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
26 27
27 namespace webcrypto { 28 namespace webcrypto {
28 29
29 namespace { 30 namespace {
30 31
31 // Maps a blink::WebCryptoNamedCurve to the corresponding NID used by 32 // Maps a blink::WebCryptoNamedCurve to the corresponding NID used by
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 return Status::Success(); 291 return Status::Success();
291 } 292 }
292 293
293 Status EcAlgorithm::ImportKey(blink::WebCryptoKeyFormat format, 294 Status EcAlgorithm::ImportKey(blink::WebCryptoKeyFormat format,
294 const CryptoData& key_data, 295 const CryptoData& key_data,
295 const blink::WebCryptoAlgorithm& algorithm, 296 const blink::WebCryptoAlgorithm& algorithm,
296 bool extractable, 297 bool extractable,
297 blink::WebCryptoKeyUsageMask usages, 298 blink::WebCryptoKeyUsageMask usages,
298 blink::WebCryptoKey* key) const { 299 blink::WebCryptoKey* key) const {
299 switch (format) { 300 switch (format) {
301 case blink::WebCryptoKeyFormatRaw:
302 return ImportKeyRaw(key_data, algorithm, extractable, usages, key);
300 case blink::WebCryptoKeyFormatPkcs8: 303 case blink::WebCryptoKeyFormatPkcs8:
301 return ImportKeyPkcs8(key_data, algorithm, extractable, usages, key); 304 return ImportKeyPkcs8(key_data, algorithm, extractable, usages, key);
302 case blink::WebCryptoKeyFormatSpki: 305 case blink::WebCryptoKeyFormatSpki:
303 return ImportKeySpki(key_data, algorithm, extractable, usages, key); 306 return ImportKeySpki(key_data, algorithm, extractable, usages, key);
304 case blink::WebCryptoKeyFormatJwk: 307 case blink::WebCryptoKeyFormatJwk:
305 return ImportKeyJwk(key_data, algorithm, extractable, usages, key); 308 return ImportKeyJwk(key_data, algorithm, extractable, usages, key);
306 default: 309 default:
307 return Status::ErrorUnsupportedImportKeyFormat(); 310 return Status::ErrorUnsupportedImportKeyFormat();
308 } 311 }
309 } 312 }
310 313
311 Status EcAlgorithm::ExportKey(blink::WebCryptoKeyFormat format, 314 Status EcAlgorithm::ExportKey(blink::WebCryptoKeyFormat format,
312 const blink::WebCryptoKey& key, 315 const blink::WebCryptoKey& key,
313 std::vector<uint8_t>* buffer) const { 316 std::vector<uint8_t>* buffer) const {
314 switch (format) { 317 switch (format) {
318 case blink::WebCryptoKeyFormatRaw:
319 return ExportKeyRaw(key, buffer);
315 case blink::WebCryptoKeyFormatPkcs8: 320 case blink::WebCryptoKeyFormatPkcs8:
316 return ExportKeyPkcs8(key, buffer); 321 return ExportKeyPkcs8(key, buffer);
317 case blink::WebCryptoKeyFormatSpki: 322 case blink::WebCryptoKeyFormatSpki:
318 return ExportKeySpki(key, buffer); 323 return ExportKeySpki(key, buffer);
319 case blink::WebCryptoKeyFormatJwk: 324 case blink::WebCryptoKeyFormatJwk:
320 return ExportKeyJwk(key, buffer); 325 return ExportKeyJwk(key, buffer);
321 default: 326 default:
322 return Status::ErrorUnsupportedExportKeyFormat(); 327 return Status::ErrorUnsupportedExportKeyFormat();
323 } 328 }
324 } 329 }
325 330
331 Status EcAlgorithm::ImportKeyRaw(const CryptoData& key_data,
332 const blink::WebCryptoAlgorithm& algorithm,
333 bool extractable,
334 blink::WebCryptoKeyUsageMask usages,
335 blink::WebCryptoKey* key) const {
336 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
337
338 Status status = CheckKeyCreationUsages(all_public_key_usages_, usages);
339 if (status.IsError())
340 return status;
341
342 const blink::WebCryptoEcKeyImportParams* params =
343 algorithm.ecKeyImportParams();
344
345 // Create an EC_KEY.
346 crypto::ScopedEC_KEY ec;
347 status = CreateEC_KEY(params->namedCurve(), &ec);
348 if (status.IsError())
349 return status;
350
351 crypto::ScopedEC_POINT point(EC_POINT_new(EC_KEY_get0_group(ec.get())));
352 if (!point.get())
353 return Status::OperationError();
354
355 // Convert the "raw" input from X9.62 format to an EC_POINT.
356 if (!EC_POINT_oct2point(EC_KEY_get0_group(ec.get()), point.get(),
357 key_data.bytes(), key_data.byte_length(), nullptr)) {
358 return Status::DataError();
359 }
360
361 // Copy the point (public key) into the EC_KEY.
362 if (!EC_KEY_set_public_key(ec.get(), point.get()))
363 return Status::OperationError();
364
365 // Verify the key.
366 if (!EC_KEY_check_key(ec.get()))
367 return Status::ErrorEcKeyInvalid();
368
369 // Wrap the EC_KEY into an EVP_PKEY.
370 crypto::ScopedEVP_PKEY pkey(EVP_PKEY_new());
371 if (!pkey || !EVP_PKEY_set1_EC_KEY(pkey.get(), ec.get()))
372 return Status::OperationError();
373
374 blink::WebCryptoKeyAlgorithm key_algorithm =
375 blink::WebCryptoKeyAlgorithm::createEc(algorithm.id(),
376 params->namedCurve());
377
378 // Wrap the EVP_PKEY into a WebCryptoKey
379 return CreateWebCryptoPublicKey(std::move(pkey), key_algorithm, extractable,
380 usages, key);
381 }
382
326 Status EcAlgorithm::ImportKeyPkcs8(const CryptoData& key_data, 383 Status EcAlgorithm::ImportKeyPkcs8(const CryptoData& key_data,
327 const blink::WebCryptoAlgorithm& algorithm, 384 const blink::WebCryptoAlgorithm& algorithm,
328 bool extractable, 385 bool extractable,
329 blink::WebCryptoKeyUsageMask usages, 386 blink::WebCryptoKeyUsageMask usages,
330 blink::WebCryptoKey* key) const { 387 blink::WebCryptoKey* key) const {
331 Status status = CheckKeyCreationUsages(all_private_key_usages_, usages); 388 Status status = CheckKeyCreationUsages(all_private_key_usages_, usages);
332 if (status.IsError()) 389 if (status.IsError())
333 return status; 390 return status;
334 391
335 crypto::ScopedEVP_PKEY private_key; 392 crypto::ScopedEVP_PKEY private_key;
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 537
481 // Wrap the EVP_PKEY into a WebCryptoKey 538 // Wrap the EVP_PKEY into a WebCryptoKey
482 if (is_private_key) { 539 if (is_private_key) {
483 return CreateWebCryptoPrivateKey(std::move(pkey), key_algorithm, 540 return CreateWebCryptoPrivateKey(std::move(pkey), key_algorithm,
484 extractable, usages, key); 541 extractable, usages, key);
485 } 542 }
486 return CreateWebCryptoPublicKey(std::move(pkey), key_algorithm, extractable, 543 return CreateWebCryptoPublicKey(std::move(pkey), key_algorithm, extractable,
487 usages, key); 544 usages, key);
488 } 545 }
489 546
547 Status EcAlgorithm::ExportKeyRaw(const blink::WebCryptoKey& key,
548 std::vector<uint8_t>* buffer) const {
549 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
550
551 if (key.type() != blink::WebCryptoKeyTypePublic)
552 return Status::ErrorUnexpectedKeyType();
553
554 EVP_PKEY* pkey = GetEVP_PKEY(key);
555
556 EC_KEY* ec = EVP_PKEY_get0_EC_KEY(pkey);
557 if (!ec)
558 return Status::ErrorUnexpected();
559
560 // Serialize the public key as an uncompressed point in X9.62 form.
561 uint8_t* raw;
562 size_t raw_len;
563 crypto::AutoCBB cbb;
564 if (!CBB_init(cbb.get(), 0) ||
565 !EC_POINT_point2cbb(cbb.get(), EC_KEY_get0_group(ec),
566 EC_KEY_get0_public_key(ec),
567 POINT_CONVERSION_UNCOMPRESSED, nullptr) ||
568 !CBB_finish(cbb.get(), &raw, &raw_len)) {
569 return Status::OperationError();
570 }
571 buffer->assign(raw, raw + raw_len);
572 OPENSSL_free(raw);
573
574 return Status::Success();
575 }
576
490 Status EcAlgorithm::ExportKeyPkcs8(const blink::WebCryptoKey& key, 577 Status EcAlgorithm::ExportKeyPkcs8(const blink::WebCryptoKey& key,
491 std::vector<uint8_t>* buffer) const { 578 std::vector<uint8_t>* buffer) const {
492 if (key.type() != blink::WebCryptoKeyTypePrivate) 579 if (key.type() != blink::WebCryptoKeyTypePrivate)
493 return Status::ErrorUnexpectedKeyType(); 580 return Status::ErrorUnexpectedKeyType();
494 // This relies on the fact that PKCS8 formatted data was already 581 // This relies on the fact that PKCS8 formatted data was already
495 // associated with the key during its creation (used by 582 // associated with the key during its creation (used by
496 // structured clone). 583 // structured clone).
497 *buffer = GetSerializedKeyData(key); 584 *buffer = GetSerializedKeyData(key);
498 return Status::Success(); 585 return Status::Success();
499 } 586 }
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 687
601 if (algorithm.ecParams()->namedCurve() != 688 if (algorithm.ecParams()->namedCurve() !=
602 key->algorithm().ecParams()->namedCurve()) { 689 key->algorithm().ecParams()->namedCurve()) {
603 return Status::ErrorUnexpected(); 690 return Status::ErrorUnexpected();
604 } 691 }
605 692
606 return Status::Success(); 693 return Status::Success();
607 } 694 }
608 695
609 } // namespace webcrypto 696 } // namespace webcrypto
OLDNEW
« no previous file with comments | « components/webcrypto/algorithms/ec.h ('k') | components/webcrypto/ec_import_key_raw_fuzzer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698