12
12
namespace node {
13
13
14
14
using v8::Array;
15
+ using v8::ArrayBuffer;
16
+ using v8::BackingStore;
15
17
using v8::FunctionCallbackInfo;
16
18
using v8::FunctionTemplate;
17
19
using v8::HandleScope;
@@ -720,7 +722,7 @@ void CipherBase::SetAAD(const FunctionCallbackInfo<Value>& args) {
720
722
CipherBase::UpdateResult CipherBase::Update (
721
723
const char * data,
722
724
size_t len,
723
- AllocatedBuffer * out) {
725
+ std::unique_ptr<BackingStore> * out) {
724
726
if (!ctx_ || len > INT_MAX)
725
727
return kErrorState ;
726
728
MarkPopErrorOnReturn mark_pop_error_on_return;
@@ -747,15 +749,22 @@ CipherBase::UpdateResult CipherBase::Update(
747
749
return kErrorState ;
748
750
}
749
751
750
- *out = AllocatedBuffer::AllocateManaged (env (), buf_len);
752
+ {
753
+ NoArrayBufferZeroFillScope no_zero_fill_scope (env ()->isolate_data ());
754
+ *out = ArrayBuffer::NewBackingStore (env ()->isolate (), buf_len);
755
+ }
756
+
751
757
int r = EVP_CipherUpdate (ctx_.get (),
752
- reinterpret_cast <unsigned char *>(out-> data ()),
758
+ static_cast <unsigned char *>((* out)-> Data ()),
753
759
&buf_len,
754
760
reinterpret_cast <const unsigned char *>(data),
755
761
len);
756
762
757
- CHECK_LE (static_cast <size_t >(buf_len), out->size ());
758
- out->Resize (buf_len);
763
+ CHECK_LE (static_cast <size_t >(buf_len), (*out)->ByteLength ());
764
+ if (buf_len == 0 )
765
+ *out = ArrayBuffer::NewBackingStore (env ()->isolate (), 0 );
766
+ else
767
+ *out = BackingStore::Reallocate (env ()->isolate (), std::move (*out), buf_len);
759
768
760
769
// When in CCM mode, EVP_CipherUpdate will fail if the authentication tag is
761
770
// invalid. In that case, remember the error and throw in final().
@@ -770,7 +779,7 @@ void CipherBase::Update(const FunctionCallbackInfo<Value>& args) {
770
779
Decode<CipherBase>(args, [](CipherBase* cipher,
771
780
const FunctionCallbackInfo<Value>& args,
772
781
const char * data, size_t size) {
773
- AllocatedBuffer out;
782
+ std::unique_ptr<BackingStore> out;
774
783
Environment* env = Environment::GetCurrent (args);
775
784
776
785
if (UNLIKELY (size > INT_MAX))
@@ -786,8 +795,9 @@ void CipherBase::Update(const FunctionCallbackInfo<Value>& args) {
786
795
return ;
787
796
}
788
797
789
- CHECK (out.data () != nullptr || out.size () == 0 );
790
- args.GetReturnValue ().Set (out.ToBuffer ().FromMaybe (Local<Value>()));
798
+ Local<ArrayBuffer> ab = ArrayBuffer::New (env->isolate (), std::move (out));
799
+ args.GetReturnValue ().Set (
800
+ Buffer::New (env, ab, 0 , ab->ByteLength ()).FromMaybe (Local<Value>()));
791
801
});
792
802
}
793
803
@@ -806,36 +816,40 @@ void CipherBase::SetAutoPadding(const FunctionCallbackInfo<Value>& args) {
806
816
args.GetReturnValue ().Set (b); // Possibly report invalid state failure
807
817
}
808
818
809
- bool CipherBase::Final (AllocatedBuffer * out) {
819
+ bool CipherBase::Final (std::unique_ptr<BackingStore> * out) {
810
820
if (!ctx_)
811
821
return false ;
812
822
813
823
const int mode = EVP_CIPHER_CTX_mode (ctx_.get ());
814
824
815
- *out = AllocatedBuffer::AllocateManaged (
816
- env (),
817
- static_cast <size_t >(EVP_CIPHER_CTX_block_size (ctx_.get ())));
825
+ {
826
+ NoArrayBufferZeroFillScope no_zero_fill_scope (env ()->isolate_data ());
827
+ *out = ArrayBuffer::NewBackingStore (env ()->isolate (),
828
+ static_cast <size_t >(EVP_CIPHER_CTX_block_size (ctx_.get ())));
829
+ }
818
830
819
- if (kind_ == kDecipher && IsSupportedAuthenticatedMode (ctx_.get ())) {
831
+ if (kind_ == kDecipher && IsSupportedAuthenticatedMode (ctx_.get ()))
820
832
MaybePassAuthTagToOpenSSL ();
821
- }
822
833
823
834
// In CCM mode, final() only checks whether authentication failed in update().
824
835
// EVP_CipherFinal_ex must not be called and will fail.
825
836
bool ok;
826
837
if (kind_ == kDecipher && mode == EVP_CIPH_CCM_MODE) {
827
838
ok = !pending_auth_failed_;
828
- *out = AllocatedBuffer::AllocateManaged (env (), 0 ); // Empty buffer.
839
+ *out = ArrayBuffer::NewBackingStore (env ()-> isolate () , 0 );
829
840
} else {
830
- int out_len = out-> size ();
841
+ int out_len = (* out)-> ByteLength ();
831
842
ok = EVP_CipherFinal_ex (ctx_.get (),
832
- reinterpret_cast <unsigned char *>(out-> data ()),
843
+ static_cast <unsigned char *>((* out)-> Data ()),
833
844
&out_len) == 1 ;
834
845
835
- if (out_len >= 0 )
836
- out->Resize (out_len);
837
- else
838
- *out = AllocatedBuffer (); // *out will not be used.
846
+ CHECK_LE (static_cast <size_t >(out_len), (*out)->ByteLength ());
847
+ if (out_len > 0 ) {
848
+ *out =
849
+ BackingStore::Reallocate (env ()->isolate (), std::move (*out), out_len);
850
+ } else {
851
+ *out = ArrayBuffer::NewBackingStore (env ()->isolate (), 0 );
852
+ }
839
853
840
854
if (ok && kind_ == kCipher && IsAuthenticatedMode ()) {
841
855
// In GCM mode, the authentication tag length can be specified in advance,
@@ -864,7 +878,7 @@ void CipherBase::Final(const FunctionCallbackInfo<Value>& args) {
864
878
if (cipher->ctx_ == nullptr )
865
879
return THROW_ERR_CRYPTO_INVALID_STATE (env);
866
880
867
- AllocatedBuffer out;
881
+ std::unique_ptr<BackingStore> out;
868
882
869
883
// Check IsAuthenticatedMode() first, Final() destroys the EVP_CIPHER_CTX.
870
884
const bool is_auth_mode = cipher->IsAuthenticatedMode ();
@@ -878,7 +892,9 @@ void CipherBase::Final(const FunctionCallbackInfo<Value>& args) {
878
892
return ThrowCryptoError (env, ERR_get_error (), msg);
879
893
}
880
894
881
- args.GetReturnValue ().Set (out.ToBuffer ().FromMaybe (Local<Value>()));
895
+ Local<ArrayBuffer> ab = ArrayBuffer::New (env->isolate (), std::move (out));
896
+ args.GetReturnValue ().Set (
897
+ Buffer::New (env, ab, 0 , ab->ByteLength ()).FromMaybe (Local<Value>()));
882
898
}
883
899
884
900
template <PublicKeyCipher::Operation operation,
@@ -891,7 +907,7 @@ bool PublicKeyCipher::Cipher(
891
907
const EVP_MD* digest,
892
908
const ArrayBufferOrViewContents<unsigned char >& oaep_label,
893
909
const ArrayBufferOrViewContents<unsigned char >& data,
894
- AllocatedBuffer * out) {
910
+ std::unique_ptr<BackingStore> * out) {
895
911
EVPKeyCtxPointer ctx (EVP_PKEY_CTX_new (pkey.get (), nullptr ));
896
912
if (!ctx)
897
913
return false ;
@@ -927,18 +943,26 @@ bool PublicKeyCipher::Cipher(
927
943
return false ;
928
944
}
929
945
930
- *out = AllocatedBuffer::AllocateManaged (env, out_len);
946
+ {
947
+ NoArrayBufferZeroFillScope no_zero_fill_scope (env->isolate_data ());
948
+ *out = ArrayBuffer::NewBackingStore (env->isolate (), out_len);
949
+ }
931
950
932
951
if (EVP_PKEY_cipher (
933
952
ctx.get (),
934
- reinterpret_cast <unsigned char *>(out-> data ()),
953
+ static_cast <unsigned char *>((* out)-> Data ()),
935
954
&out_len,
936
955
data.data (),
937
956
data.size ()) <= 0 ) {
938
957
return false ;
939
958
}
940
959
941
- out->Resize (out_len);
960
+ CHECK_LE (out_len, (*out)->ByteLength ());
961
+ if (out_len > 0 )
962
+ *out = BackingStore::Reallocate (env->isolate (), std::move (*out), out_len);
963
+ else
964
+ *out = ArrayBuffer::NewBackingStore (env->isolate (), 0 );
965
+
942
966
return true ;
943
967
}
944
968
@@ -977,15 +1001,15 @@ void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
977
1001
return THROW_ERR_OUT_OF_RANGE (env, " oaep_label is too big" );
978
1002
}
979
1003
980
- AllocatedBuffer out;
1004
+ std::unique_ptr<BackingStore> out;
981
1005
if (!Cipher<operation, EVP_PKEY_cipher_init, EVP_PKEY_cipher>(
982
1006
env, pkey, padding, digest, oaep_label, buf, &out)) {
983
1007
return ThrowCryptoError (env, ERR_get_error ());
984
1008
}
985
1009
986
- Local<Value> result ;
987
- if (out. ToBuffer ().ToLocal (&result))
988
- args. GetReturnValue (). Set (result );
1010
+ Local<ArrayBuffer> ab = ArrayBuffer::New (env-> isolate (), std::move (out)) ;
1011
+ args. GetReturnValue ().Set (
1012
+ Buffer::New (env, ab, 0 , ab-> ByteLength ()). FromMaybe (Local<Value>()) );
989
1013
}
990
1014
991
1015
} // namespace crypto
0 commit comments