@@ -3462,42 +3462,22 @@ bool CipherBase::IsAuthenticatedMode() const {
3462
3462
}
3463
3463
3464
3464
3465
- bool CipherBase::GetAuthTag (char ** out, unsigned int * out_len) const {
3466
- // only callable after Final and if encrypting.
3467
- if (initialised_ || kind_ != kCipher || !auth_tag_)
3468
- return false ;
3469
- *out_len = auth_tag_len_;
3470
- *out = node::Malloc (auth_tag_len_);
3471
- memcpy (*out, auth_tag_, auth_tag_len_);
3472
- return true ;
3473
- }
3474
-
3475
-
3476
3465
void CipherBase::GetAuthTag (const FunctionCallbackInfo<Value>& args) {
3477
3466
Environment* env = Environment::GetCurrent (args);
3478
3467
CipherBase* cipher;
3479
3468
ASSIGN_OR_RETURN_UNWRAP (&cipher, args.Holder ());
3480
3469
3481
- char * out = nullptr ;
3482
- unsigned int out_len = 0 ;
3483
-
3484
- if (cipher->GetAuthTag (&out, &out_len)) {
3485
- Local<Object> buf = Buffer::New (env, out, out_len).ToLocalChecked ();
3486
- args.GetReturnValue ().Set (buf);
3487
- } else {
3488
- env->ThrowError (" Attempting to get auth tag in unsupported state" );
3470
+ // Only callable after Final and if encrypting.
3471
+ if (cipher->initialised_ ||
3472
+ cipher->kind_ != kCipher ||
3473
+ cipher->auth_tag_len_ == 0 ) {
3474
+ return env->ThrowError (" Attempting to get auth tag in unsupported state" );
3489
3475
}
3490
- }
3491
-
3492
3476
3493
- bool CipherBase::SetAuthTag (const char * data, unsigned int len) {
3494
- if (!initialised_ || !IsAuthenticatedMode () || kind_ != kDecipher )
3495
- return false ;
3496
- delete[] auth_tag_;
3497
- auth_tag_len_ = len;
3498
- auth_tag_ = new char [len];
3499
- memcpy (auth_tag_, data, len);
3500
- return true ;
3477
+ Local<Object> buf =
3478
+ Buffer::Copy (env, cipher->auth_tag_ , cipher->auth_tag_len_ )
3479
+ .ToLocalChecked ();
3480
+ args.GetReturnValue ().Set (buf);
3501
3481
}
3502
3482
3503
3483
@@ -3509,8 +3489,20 @@ void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
3509
3489
CipherBase* cipher;
3510
3490
ASSIGN_OR_RETURN_UNWRAP (&cipher, args.Holder ());
3511
3491
3512
- if (!cipher->SetAuthTag (Buffer::Data (args[0 ]), Buffer::Length (args[0 ])))
3513
- env->ThrowError (" Attempting to set auth tag in unsupported state" );
3492
+ if (!cipher->initialised_ ||
3493
+ !cipher->IsAuthenticatedMode () ||
3494
+ cipher->kind_ != kDecipher ) {
3495
+ return env->ThrowError (" Attempting to set auth tag in unsupported state" );
3496
+ }
3497
+
3498
+ // FIXME(bnoordhuis) Throw when buffer length is not a valid tag size.
3499
+ // Note: we don't use std::max() here to work around a header conflict.
3500
+ cipher->auth_tag_len_ = Buffer::Length (args[0 ]);
3501
+ if (cipher->auth_tag_len_ > sizeof (cipher->auth_tag_ ))
3502
+ cipher->auth_tag_len_ = sizeof (cipher->auth_tag_ );
3503
+
3504
+ memset (cipher->auth_tag_ , 0 , sizeof (cipher->auth_tag_ ));
3505
+ memcpy (cipher->auth_tag_ , Buffer::Data (args[0 ]), cipher->auth_tag_len_ );
3514
3506
}
3515
3507
3516
3508
@@ -3550,13 +3542,12 @@ bool CipherBase::Update(const char* data,
3550
3542
return 0 ;
3551
3543
3552
3544
// on first update:
3553
- if (kind_ == kDecipher && IsAuthenticatedMode () && auth_tag_ != nullptr ) {
3545
+ if (kind_ == kDecipher && IsAuthenticatedMode () && auth_tag_len_ > 0 ) {
3554
3546
EVP_CIPHER_CTX_ctrl (&ctx_,
3555
3547
EVP_CTRL_GCM_SET_TAG,
3556
3548
auth_tag_len_,
3557
3549
reinterpret_cast <unsigned char *>(auth_tag_));
3558
- delete[] auth_tag_;
3559
- auth_tag_ = nullptr ;
3550
+ auth_tag_len_ = 0 ;
3560
3551
}
3561
3552
3562
3553
*out_len = len + EVP_CIPHER_CTX_block_size (&ctx_);
@@ -3634,18 +3625,11 @@ bool CipherBase::Final(unsigned char** out, int *out_len) {
3634
3625
static_cast <size_t >(EVP_CIPHER_CTX_block_size (&ctx_)));
3635
3626
int r = EVP_CipherFinal_ex (&ctx_, *out, out_len);
3636
3627
3637
- if (r && kind_ == kCipher ) {
3638
- delete[] auth_tag_;
3639
- auth_tag_ = nullptr ;
3640
- if (IsAuthenticatedMode ()) {
3641
- auth_tag_len_ = EVP_GCM_TLS_TAG_LEN; // use default tag length
3642
- auth_tag_ = new char [auth_tag_len_];
3643
- memset (auth_tag_, 0 , auth_tag_len_);
3644
- EVP_CIPHER_CTX_ctrl (&ctx_,
3645
- EVP_CTRL_GCM_GET_TAG,
3646
- auth_tag_len_,
3647
- reinterpret_cast <unsigned char *>(auth_tag_));
3648
- }
3628
+ if (r == 1 && kind_ == kCipher && IsAuthenticatedMode ()) {
3629
+ auth_tag_len_ = sizeof (auth_tag_);
3630
+ r = EVP_CIPHER_CTX_ctrl (&ctx_, EVP_CTRL_GCM_GET_TAG, auth_tag_len_,
3631
+ reinterpret_cast <unsigned char *>(auth_tag_));
3632
+ CHECK_EQ (r, 1 );
3649
3633
}
3650
3634
3651
3635
EVP_CIPHER_CTX_cleanup (&ctx_);
0 commit comments