Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Missing errors in raw keyrings #320

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 25 additions & 4 deletions modules/raw-keyring/src/raw_keyring_decorators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
KeyringTrace,
KeyringTraceFlag,
EncryptedDataKey,
needs,
} from '@aws-crypto/material-management'

export interface RawKeyRing<S extends SupportedAlgorithmSuites> {
Expand Down Expand Up @@ -54,17 +55,37 @@ export function _onDecrypt<
/* Check for early return (Postcondition): If there are not EncryptedDataKeys for this keyring, do nothing. */
if (!edks.length) return material

const cmkErrors: Error[] = []

for (const edk of edks) {
try {
return await this._unwrapKey(material, edk)
} catch (e) {
// there should be some debug here? or wrap?
// Failures decrypt should not short-circuit the process
// If the caller does not have access they may have access
// through another Keyring.
/* Failures onDecrypt should not short-circuit the process
* If the caller does not have access they may have access
* through another Keyring.
*/
cmkErrors.push(e)
}
}

/* Postcondition: An EDK must provide a valid data key or _unwrapKey must not have raised any errors.
* If I have a data key,
* decrypt errors can be ignored.
* However, if I was unable to decrypt a data key AND I have errors,
* these errors should bubble up.
* Otherwise, the only error customers will see is that
* the material does not have an unencrypted data key.
* So I return a concatenated Error message
*/
needs(
material.hasValidKey() || (!material.hasValidKey() && !cmkErrors.length),
cmkErrors.reduce(
(m, e, i) => `${m} Error #${i + 1} \n ${e.stack} \n`,
`Unable to decrypt data key ${this.keyName} ${this.keyNamespace}.\n `
)
)

return material
}
}
Expand Down
8 changes: 5 additions & 3 deletions modules/raw-keyring/test/raw_keyring_decorators.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ describe('_onDecrypt', () => {
expect(filterCalled).to.equal(1)
})

it('errors in _unwrapKey should not cause _onDecrypt to throw.', async () => {
it('Postcondition: An EDK must provide a valid data key or _unwrapKey must not have raised any errors.', async () => {
const suite = new NodeAlgorithmSuite(
AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16
)
Expand Down Expand Up @@ -258,8 +258,10 @@ describe('_onDecrypt', () => {
_filter,
} as any

const test = await testKeyring._onDecrypt(material, [edk])
expect(test.hasValidKey()).to.equal(false)
await expect(testKeyring._onDecrypt(material, [edk])).to.rejectedWith(
Error,
'Unable to decrypt data key'
)
expect(unwrapCalled).to.equal(1)
expect(filterCalled).to.equal(1)
})
Expand Down