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