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;
@@ -752,7 +754,7 @@ void CipherBase::SetAAD(const FunctionCallbackInfo<Value>& args) {
752
754
CipherBase::UpdateResult CipherBase::Update (
753
755
const char * data,
754
756
size_t len,
755
- AllocatedBuffer * out) {
757
+ std::unique_ptr<BackingStore> * out) {
756
758
if (!ctx_ || len > INT_MAX)
757
759
return kErrorState ;
758
760
MarkPopErrorOnReturn mark_pop_error_on_return;
@@ -779,15 +781,22 @@ CipherBase::UpdateResult CipherBase::Update(
779
781
return kErrorState ;
780
782
}
781
783
782
- *out = AllocatedBuffer::AllocateManaged (env (), buf_len);
784
+ {
785
+ NoArrayBufferZeroFillScope no_zero_fill_scope (env ()->isolate_data ());
786
+ *out = ArrayBuffer::NewBackingStore (env ()->isolate (), buf_len);
787
+ }
788
+
783
789
int r = EVP_CipherUpdate (ctx_.get (),
784
- reinterpret_cast <unsigned char *>(out-> data ()),
790
+ static_cast <unsigned char *>((* out)-> Data ()),
785
791
&buf_len,
786
792
reinterpret_cast <const unsigned char *>(data),
787
793
len);
788
794
789
- CHECK_LE (static_cast <size_t >(buf_len), out->size ());
790
- out->Resize (buf_len);
795
+ CHECK_LE (static_cast <size_t >(buf_len), (*out)->ByteLength ());
796
+ if (buf_len == 0 )
797
+ *out = ArrayBuffer::NewBackingStore (env ()->isolate (), 0 );
798
+ else
799
+ *out = BackingStore::Reallocate (env ()->isolate (), std::move (*out), buf_len);
791
800
792
801
// When in CCM mode, EVP_CipherUpdate will fail if the authentication tag is
793
802
// invalid. In that case, remember the error and throw in final().
@@ -802,7 +811,7 @@ void CipherBase::Update(const FunctionCallbackInfo<Value>& args) {
802
811
Decode<CipherBase>(args, [](CipherBase* cipher,
803
812
const FunctionCallbackInfo<Value>& args,
804
813
const char * data, size_t size) {
805
- AllocatedBuffer out;
814
+ std::unique_ptr<BackingStore> out;
806
815
Environment* env = Environment::GetCurrent (args);
807
816
808
817
if (UNLIKELY (size > INT_MAX))
@@ -818,8 +827,9 @@ void CipherBase::Update(const FunctionCallbackInfo<Value>& args) {
818
827
return ;
819
828
}
820
829
821
- CHECK (out.data () != nullptr || out.size () == 0 );
822
- args.GetReturnValue ().Set (out.ToBuffer ().FromMaybe (Local<Value>()));
830
+ Local<ArrayBuffer> ab = ArrayBuffer::New (env->isolate (), std::move (out));
831
+ args.GetReturnValue ().Set (
832
+ Buffer::New (env, ab, 0 , ab->ByteLength ()).FromMaybe (Local<Value>()));
823
833
});
824
834
}
825
835
@@ -838,36 +848,40 @@ void CipherBase::SetAutoPadding(const FunctionCallbackInfo<Value>& args) {
838
848
args.GetReturnValue ().Set (b); // Possibly report invalid state failure
839
849
}
840
850
841
- bool CipherBase::Final (AllocatedBuffer * out) {
851
+ bool CipherBase::Final (std::unique_ptr<BackingStore> * out) {
842
852
if (!ctx_)
843
853
return false ;
844
854
845
855
const int mode = EVP_CIPHER_CTX_mode (ctx_.get ());
846
856
847
- *out = AllocatedBuffer::AllocateManaged (
848
- env (),
849
- static_cast <size_t >(EVP_CIPHER_CTX_block_size (ctx_.get ())));
857
+ {
858
+ NoArrayBufferZeroFillScope no_zero_fill_scope (env ()->isolate_data ());
859
+ *out = ArrayBuffer::NewBackingStore (env ()->isolate (),
860
+ static_cast <size_t >(EVP_CIPHER_CTX_block_size (ctx_.get ())));
861
+ }
850
862
851
- if (kind_ == kDecipher && IsSupportedAuthenticatedMode (ctx_.get ())) {
863
+ if (kind_ == kDecipher && IsSupportedAuthenticatedMode (ctx_.get ()))
852
864
MaybePassAuthTagToOpenSSL ();
853
- }
854
865
855
866
// In CCM mode, final() only checks whether authentication failed in update().
856
867
// EVP_CipherFinal_ex must not be called and will fail.
857
868
bool ok;
858
869
if (kind_ == kDecipher && mode == EVP_CIPH_CCM_MODE) {
859
870
ok = !pending_auth_failed_;
860
- *out = AllocatedBuffer::AllocateManaged (env (), 0 ); // Empty buffer.
871
+ *out = ArrayBuffer::NewBackingStore (env ()-> isolate () , 0 );
861
872
} else {
862
- int out_len = out-> size ();
873
+ int out_len = (* out)-> ByteLength ();
863
874
ok = EVP_CipherFinal_ex (ctx_.get (),
864
- reinterpret_cast <unsigned char *>(out-> data ()),
875
+ static_cast <unsigned char *>((* out)-> Data ()),
865
876
&out_len) == 1 ;
866
877
867
- if (out_len >= 0 )
868
- out->Resize (out_len);
869
- else
870
- *out = AllocatedBuffer (); // *out will not be used.
878
+ CHECK_LE (static_cast <size_t >(out_len), (*out)->ByteLength ());
879
+ if (out_len > 0 ) {
880
+ *out =
881
+ BackingStore::Reallocate (env ()->isolate (), std::move (*out), out_len);
882
+ } else {
883
+ *out = ArrayBuffer::NewBackingStore (env ()->isolate (), 0 );
884
+ }
871
885
872
886
if (ok && kind_ == kCipher && IsAuthenticatedMode ()) {
873
887
// In GCM mode, the authentication tag length can be specified in advance,
@@ -896,7 +910,7 @@ void CipherBase::Final(const FunctionCallbackInfo<Value>& args) {
896
910
if (cipher->ctx_ == nullptr )
897
911
return THROW_ERR_CRYPTO_INVALID_STATE (env);
898
912
899
- AllocatedBuffer out;
913
+ std::unique_ptr<BackingStore> out;
900
914
901
915
// Check IsAuthenticatedMode() first, Final() destroys the EVP_CIPHER_CTX.
902
916
const bool is_auth_mode = cipher->IsAuthenticatedMode ();
@@ -910,7 +924,9 @@ void CipherBase::Final(const FunctionCallbackInfo<Value>& args) {
910
924
return ThrowCryptoError (env, ERR_get_error (), msg);
911
925
}
912
926
913
- args.GetReturnValue ().Set (out.ToBuffer ().FromMaybe (Local<Value>()));
927
+ Local<ArrayBuffer> ab = ArrayBuffer::New (env->isolate (), std::move (out));
928
+ args.GetReturnValue ().Set (
929
+ Buffer::New (env, ab, 0 , ab->ByteLength ()).FromMaybe (Local<Value>()));
914
930
}
915
931
916
932
template <PublicKeyCipher::Operation operation,
@@ -923,7 +939,7 @@ bool PublicKeyCipher::Cipher(
923
939
const EVP_MD* digest,
924
940
const ArrayBufferOrViewContents<unsigned char >& oaep_label,
925
941
const ArrayBufferOrViewContents<unsigned char >& data,
926
- AllocatedBuffer * out) {
942
+ std::unique_ptr<BackingStore> * out) {
927
943
EVPKeyCtxPointer ctx (EVP_PKEY_CTX_new (pkey.get (), nullptr ));
928
944
if (!ctx)
929
945
return false ;
@@ -959,18 +975,26 @@ bool PublicKeyCipher::Cipher(
959
975
return false ;
960
976
}
961
977
962
- *out = AllocatedBuffer::AllocateManaged (env, out_len);
978
+ {
979
+ NoArrayBufferZeroFillScope no_zero_fill_scope (env->isolate_data ());
980
+ *out = ArrayBuffer::NewBackingStore (env->isolate (), out_len);
981
+ }
963
982
964
983
if (EVP_PKEY_cipher (
965
984
ctx.get (),
966
- reinterpret_cast <unsigned char *>(out-> data ()),
985
+ static_cast <unsigned char *>((* out)-> Data ()),
967
986
&out_len,
968
987
data.data (),
969
988
data.size ()) <= 0 ) {
970
989
return false ;
971
990
}
972
991
973
- out->Resize (out_len);
992
+ CHECK_LE (out_len, (*out)->ByteLength ());
993
+ if (out_len > 0 )
994
+ *out = BackingStore::Reallocate (env->isolate (), std::move (*out), out_len);
995
+ else
996
+ *out = ArrayBuffer::NewBackingStore (env->isolate (), 0 );
997
+
974
998
return true ;
975
999
}
976
1000
@@ -1009,15 +1033,15 @@ void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
1009
1033
return THROW_ERR_OUT_OF_RANGE (env, " oaep_label is too big" );
1010
1034
}
1011
1035
1012
- AllocatedBuffer out;
1036
+ std::unique_ptr<BackingStore> out;
1013
1037
if (!Cipher<operation, EVP_PKEY_cipher_init, EVP_PKEY_cipher>(
1014
1038
env, pkey, padding, digest, oaep_label, buf, &out)) {
1015
1039
return ThrowCryptoError (env, ERR_get_error ());
1016
1040
}
1017
1041
1018
- Local<Value> result ;
1019
- if (out. ToBuffer ().ToLocal (&result))
1020
- args. GetReturnValue (). Set (result );
1042
+ Local<ArrayBuffer> ab = ArrayBuffer::New (env-> isolate (), std::move (out)) ;
1043
+ args. GetReturnValue ().Set (
1044
+ Buffer::New (env, ab, 0 , ab-> ByteLength ()). FromMaybe (Local<Value>()) );
1021
1045
}
1022
1046
1023
1047
} // namespace crypto
0 commit comments