@@ -539,62 +539,68 @@ WebCryptoKeyExportStatus DHKeyExportTraits::DoExport(
539
539
}
540
540
541
541
namespace {
542
- AllocatedBuffer StatelessDiffieHellman (
543
- Environment* env,
544
- ManagedEVPPKey our_key,
545
- ManagedEVPPKey their_key) {
546
- size_t out_size;
547
-
548
- EVPKeyCtxPointer ctx (EVP_PKEY_CTX_new (our_key.get (), nullptr ));
542
+ Maybe<bool > CreateStatelessDiffieHellmanContext (
543
+ const ManagedEVPPKey& our_key,
544
+ const ManagedEVPPKey& their_key,
545
+ char ** buf,
546
+ size_t * out_size) {
547
+ const EVPKeyCtxPointer ctx (EVP_PKEY_CTX_new (our_key.get (), nullptr ));
549
548
if (!ctx ||
550
549
EVP_PKEY_derive_init (ctx.get ()) <= 0 ||
551
550
EVP_PKEY_derive_set_peer (ctx.get (), their_key.get ()) <= 0 ||
552
- EVP_PKEY_derive (ctx.get (), nullptr , & out_size) <= 0 )
553
- return AllocatedBuffer ();
551
+ EVP_PKEY_derive (ctx.get (), nullptr , out_size) <= 0 )
552
+ return Nothing< bool > ();
554
553
555
- AllocatedBuffer result = AllocatedBuffer::AllocateManaged (env, out_size);
556
- CHECK_NOT_NULL (result.data ());
554
+ *buf = MallocOpenSSL<char >(*out_size);
555
+ size_t remainder_size = *out_size;
556
+ if (EVP_PKEY_derive (ctx.get (),
557
+ reinterpret_cast <unsigned char *>(*buf),
558
+ &remainder_size) <= 0 )
559
+ return Nothing<bool >();
557
560
558
- unsigned char * data = reinterpret_cast <unsigned char *>(result.data ());
559
- if (EVP_PKEY_derive (ctx.get (), data, &out_size) <= 0 )
560
- return AllocatedBuffer ();
561
+ ZeroPadDiffieHellmanSecret (remainder_size, *buf, *out_size);
561
562
562
- ZeroPadDiffieHellmanSecret (out_size, &result);
563
- return result;
563
+ return Just (true );
564
564
}
565
565
566
- // The version of StatelessDiffieHellman that returns an AllocatedBuffer
567
- // is not threadsafe because of the AllocatedBuffer allocation of a
568
- // v8::BackingStore (it'll cause much crashing if we call it from a
569
- // libuv worker thread). This version allocates a ByteSource instead,
570
- // which we can convert into a v8::BackingStore later.
571
- // TODO(@jasnell): Eliminate the code duplication between these two
572
- // versions of the function.
573
- ByteSource StatelessDiffieHellmanThreadsafe (
566
+ Local<Value> StatelessDiffieHellman (
574
567
Environment* env,
575
- ManagedEVPPKey our_key,
576
- ManagedEVPPKey their_key) {
568
+ const ManagedEVPPKey& our_key,
569
+ const ManagedEVPPKey& their_key) {
570
+ char * buf = nullptr ;
577
571
size_t out_size;
578
-
579
- EVPKeyCtxPointer ctx (EVP_PKEY_CTX_new (our_key.get (), nullptr ));
580
- if (!ctx ||
581
- EVP_PKEY_derive_init (ctx.get ()) <= 0 ||
582
- EVP_PKEY_derive_set_peer (ctx.get (), their_key.get ()) <= 0 ||
583
- EVP_PKEY_derive (ctx.get (), nullptr , &out_size) <= 0 )
584
- return ByteSource ();
585
-
586
- char * buf = MallocOpenSSL<char >(out_size);
587
- ByteSource out = ByteSource::Allocated (buf, out_size);
588
-
589
- if (EVP_PKEY_derive (
590
- ctx.get (),
591
- reinterpret_cast <unsigned char *>(buf),
592
- &out_size) <= 0 ) {
572
+ if (CreateStatelessDiffieHellmanContext (our_key,
573
+ their_key,
574
+ &buf,
575
+ &out_size).IsNothing ())
576
+ return Local<Value>();
577
+
578
+ return Buffer::New (env,
579
+ buf,
580
+ out_size,
581
+ [](char * data, void * hint) {
582
+ OPENSSL_free (data);
583
+ },
584
+ nullptr ).FromMaybe (Local<Object>());
585
+ }
586
+
587
+ // The version of StatelessDiffieHellman that returns a Buffer
588
+ // is not threadsafe because of the allocation of a v8::BackingStore
589
+ // (it'll cause much crashing if we call it from a libuv worker
590
+ // thread). This version allocates a ByteSource instead, which we can
591
+ // convert into a v8::BackingStore later.
592
+ ByteSource StatelessDiffieHellmanThreadsafe (
593
+ const ManagedEVPPKey& our_key,
594
+ const ManagedEVPPKey& their_key) {
595
+ char * buf = nullptr ;
596
+ size_t out_size;
597
+ if (CreateStatelessDiffieHellmanContext (our_key,
598
+ their_key,
599
+ &buf,
600
+ &out_size).IsNothing ())
593
601
return ByteSource ();
594
- }
595
602
596
- ZeroPadDiffieHellmanSecret (out_size, buf, out.size ());
597
- return out;
603
+ return ByteSource::Allocated (buf, out_size);
598
604
}
599
605
} // namespace
600
606
@@ -612,11 +618,11 @@ void DiffieHellman::Stateless(const FunctionCallbackInfo<Value>& args) {
612
618
ManagedEVPPKey our_key = our_key_object->Data ()->GetAsymmetricKey ();
613
619
ManagedEVPPKey their_key = their_key_object->Data ()->GetAsymmetricKey ();
614
620
615
- AllocatedBuffer out = StatelessDiffieHellman (env, our_key, their_key);
616
- if (out.size ( ) == 0 )
621
+ Local<Value> out = StatelessDiffieHellman (env, our_key, their_key);
622
+ if (out.IsEmpty () || Buffer::Length (out ) == 0 )
617
623
return ThrowCryptoError (env, ERR_get_error (), " diffieHellman failed" );
618
624
619
- args.GetReturnValue ().Set (out. ToBuffer (). FromMaybe (Local<Value>()) );
625
+ args.GetReturnValue ().Set (out);
620
626
}
621
627
622
628
Maybe<bool > DHBitsTraits::AdditionalConfig (
@@ -661,7 +667,6 @@ bool DHBitsTraits::DeriveBits(
661
667
const DHBitsConfig& params,
662
668
ByteSource* out) {
663
669
*out = StatelessDiffieHellmanThreadsafe (
664
- env,
665
670
params.private_key ->GetAsymmetricKey (),
666
671
params.public_key ->GetAsymmetricKey ());
667
672
return true ;
0 commit comments