From f5b30613b968f1a822d8cad4fe767fce97d2963d Mon Sep 17 00:00:00 2001 From: David Tanner Date: Wed, 25 Oct 2023 10:15:35 -0600 Subject: [PATCH] feat: add Uint8 array as hmac type --- src/index.ts | 2 +- src/lib/aesCredstash.ts | 13 +++++++++++-- src/types.ts | 2 +- test/unit/lib/aesCredstash.test.ts | 10 +++++++++- 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/index.ts b/src/index.ts index a2fbdc5..5960980 100755 --- a/src/index.ts +++ b/src/index.ts @@ -187,7 +187,7 @@ export class CredStash { const results = []; for (const secret of Items) { const result = await this.deleteSecret( - { name: opts.name, version: secret.version }, + { ...opts, version: secret.version }, ); results.push(result); } diff --git a/src/lib/aesCredstash.ts b/src/lib/aesCredstash.ts index 5d0be5e..732f33d 100644 --- a/src/lib/aesCredstash.ts +++ b/src/lib/aesCredstash.ts @@ -84,6 +84,10 @@ export const sealAesCtrLegacy = async ( }; }; +const getHmacAsString = (hmac: string | Uint8Array): string => ( + typeof hmac === 'string' ? hmac : Buffer.from(hmac).toString('utf-8') +); + /** * Decrypts secrets stored by `seal_aes_ctr_legacy`. * Assumes that the plaintext is unicode (non-binary). @@ -95,6 +99,11 @@ export const openAesCtrLegacy = async ( const key = await keyService.decrypt(record.key); const digestMethod = record.digest || DEFAULT_DIGEST; const ciphertext = Buffer.from(record.contents, 'base64'); - const hmac = (record.hmac as { value: string }).value ?? record.hmac as string; - return openAesCtr(key, LEGACY_NONCE, ciphertext, hmac, digestMethod, record.name); + let rawHmac: string | Uint8Array; + if (typeof record.hmac === 'object' && !(record.hmac instanceof Uint8Array)) { + rawHmac = record.hmac.value; + } else { + rawHmac = record.hmac; + } + return openAesCtr(key, LEGACY_NONCE, ciphertext, getHmacAsString(rawHmac), digestMethod, record.name); }; diff --git a/src/types.ts b/src/types.ts index 7560bb7..84e022c 100644 --- a/src/types.ts +++ b/src/types.ts @@ -7,7 +7,7 @@ export interface SecretRecord { version: string; digest?: string; contents: string; - hmac: string | { value: string; }; + hmac: string | Uint8Array | { value: string | Uint8Array; }; } export type KMSOpts = ConstructorParameters[0]; diff --git a/test/unit/lib/aesCredstash.test.ts b/test/unit/lib/aesCredstash.test.ts index e72098e..ed454df 100644 --- a/test/unit/lib/aesCredstash.test.ts +++ b/test/unit/lib/aesCredstash.test.ts @@ -40,9 +40,17 @@ test.each([ if (digest) { record.hmac = item[`hmac${digest}`]; } + const hmac = record.hmac as string; + const uintArray = new TextEncoder().encode(hmac); await expect(openAesCtrLegacy(keyService, record)).resolves.toBe(item.plainText); - record.hmac = { value: record.hmac as string }; + record.hmac = uintArray; + await expect(openAesCtrLegacy(keyService, record)).resolves.toBe(item.plainText); + + record.hmac = { value: hmac }; + await expect(openAesCtrLegacy(keyService, record)).resolves.toBe(item.plainText); + + record.hmac = { value: uintArray }; await expect(openAesCtrLegacy(keyService, record)).resolves.toBe(item.plainText); });