@@ -3462,42 +3462,22 @@ bool CipherBase::IsAuthenticatedMode() const {
34623462}
34633463
34643464
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-
34763465void CipherBase::GetAuthTag (const FunctionCallbackInfo<Value>& args) {
34773466 Environment* env = Environment::GetCurrent (args);
34783467 CipherBase* cipher;
34793468 ASSIGN_OR_RETURN_UNWRAP (&cipher, args.Holder ());
34803469
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" );
34893475 }
3490- }
3491-
34923476
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);
35013481}
35023482
35033483
@@ -3509,8 +3489,20 @@ void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
35093489 CipherBase* cipher;
35103490 ASSIGN_OR_RETURN_UNWRAP (&cipher, args.Holder ());
35113491
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_ );
35143506}
35153507
35163508
@@ -3550,13 +3542,12 @@ bool CipherBase::Update(const char* data,
35503542 return 0 ;
35513543
35523544 // on first update:
3553- if (kind_ == kDecipher && IsAuthenticatedMode () && auth_tag_ != nullptr ) {
3545+ if (kind_ == kDecipher && IsAuthenticatedMode () && auth_tag_len_ > 0 ) {
35543546 EVP_CIPHER_CTX_ctrl (&ctx_,
35553547 EVP_CTRL_GCM_SET_TAG,
35563548 auth_tag_len_,
35573549 reinterpret_cast <unsigned char *>(auth_tag_));
3558- delete[] auth_tag_;
3559- auth_tag_ = nullptr ;
3550+ auth_tag_len_ = 0 ;
35603551 }
35613552
35623553 *out_len = len + EVP_CIPHER_CTX_block_size (&ctx_);
@@ -3634,18 +3625,11 @@ bool CipherBase::Final(unsigned char** out, int *out_len) {
36343625 static_cast <size_t >(EVP_CIPHER_CTX_block_size (&ctx_)));
36353626 int r = EVP_CipherFinal_ex (&ctx_, *out, out_len);
36363627
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 );
36493633 }
36503634
36513635 EVP_CIPHER_CTX_cleanup (&ctx_);
0 commit comments