Skip to content

fix: KeyringTraceFlag requirements and data key caching #210

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

Merged
merged 2 commits into from
Sep 19, 2019

Conversation

seebees
Copy link
Contributor

@seebees seebees commented Sep 16, 2019

cloneMaterial incorectly required WRAPPING_KEY_GENERATED_DATA_KEY.
in the case of DecryptionMaterials, this should never be the case.
When I wrote the tests, I did not take this case into consideration
and simply set the generate and decrypt flags on the same keyringTrace.

The organization of the traces has also changed.
There is now a single trace for each “operation”.
This mean that a trace will exists for the set operation
as well as the encrypted data key.
This lets me require only valid trace flags for each operation.
I simplified the cloneMaterial function to rely on the set methods
setUnencryptedDataKey and addEncryptedDataKey
to deny invalid fields.
I also, organize the KeyringTraceFlags to determin which flags are valid.

The KMS Keyring needed to be updated
to make sure that the trace contains the WRAPPING_KEY_SIGNED_ENC_CTX
flag.

Tests are updated, and added.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

Check any applicable:

  • Were any files moved? Moving files changes their URL, which breaks all hyperlinks to the files.

cloneMaterial incorectly required WRAPPING_KEY_GENERATED_DATA_KEY.
in the case of DecryptionMaterials, this should never be the case.
When I wrote the tests, I did not take this case into consideration
and simply set the generate and decrypt flags on the same keyringTrace.

The organization of the traces has also changed.
There is now a single trace for each “operation”.
This mean that a trace will exists for the set operation
as well as the encrypted data key.
This lets me require only valid trace flags for each operation.
I simplified the cloneMaterial function to rely on the set methods
`setUnencryptedDataKey` and `addEncryptedDataKey`
to deny invalid fields.
I also, organize the KeyringTraceFlags to determin which flags are valid.

The KMS Keyring needed to be updated
to make sure that the trace contains the WRAPPING_KEY_SIGNED_ENC_CTX
flag.

Tests are updated, and added.
@seebees seebees requested a review from a team September 16, 2019 16:34
expect(material.keyringTrace).to.have.lengthOf(2)
const [traceGenerate, traceEncrypt] = material.keyringTrace
expect(material.keyringTrace).to.have.lengthOf(3)
const [traceGenerate, traceEncrypt1, traceEncrypt2] = material.keyringTrace
expect(traceGenerate.keyNamespace).to.equal('aws-kms')
expect(traceGenerate.keyName).to.equal(generatorKeyId)
expect(traceGenerate.flags & KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY).to.equal(KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY)
expect(traceGenerate.flags & KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY).to.equal(KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do WRAPPING_KEY_ENCRYPTED_DATA_KEY and WRAPPING_KEY_SIGNED_ENC_CTX exist on the generate trace? Should they if the wrapping key hasn't been used to encrypt yet?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the KMS case. On generate, the encrypted data key is also returned....
It is just so that people can see the relationship between
the generate trace and the encrypt trace.

source.encryptedDataKeys.forEach(edk => {
const encryptedDataKeys = source.encryptedDataKeys
/* Precondition: For each encrypted data key, there must be a trace. */
needs(encryptedDataKeys.length === traces.length, 'KeyringTrace length does not match encrypted data keys.')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is this true if there is a separate trace for generate?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const [generate, ...others] = traces

If you see above :)


ENCRYPT_FLAGS = WRAPPING_KEY_ENCRYPTED_DATA_KEY | WRAPPING_KEY_SIGNED_ENC_CTX, // eslint-disable-line no-unused-vars

SET_FLAGS = WRAPPING_KEY_GENERATED_DATA_KEY | WRAPPING_KEY_DECRYPTED_DATA_KEY, // eslint-disable-line no-unused-vars
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After going over the PR a couple times the inclusion of WRAPPING_KEY_DECRYPTED_DATA_KEY here finally makes sense, but is initially very confusing. When I think of the decrypt flag I think of the decrypt operation. The fact that the output was of that set in the materials is something that seems less salient. I'm not sure if there is another way to name this/organize these fields that is more intuitive. 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also am thinking about it. That is why I called it SET because the function setUnencryptedDataKey

* it must be valid for the type of material.
* It is invalid to claim that EncryptionMaterial were decrypted.
*/
const deniedSetFlags = (KeyringTraceFlag.SET_FLAGS ^ setFlag) | (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Going back to the SET_FLAG naming, it feels weird to organize the SET_FLAGS but then also have this logic here say "if you're encrypting actually we only care about the generate flag and if you're decrypting we only care about the decrypt flag". If this function requires this logic anyway, why try to reason in terms of SET_FLAGS at all and instead just think in terms of the generate and decrypt flags?

@seebees
Copy link
Contributor Author

seebees commented Sep 18, 2019

This PR deals with KeyringTraces.
While, this PR makes the assignment of the proper traces safer,
it complicates keyring traces generally.
If/when additional traces are added the code will get even more complicated.

Ideally the general interface would be improved.
When #210 is addressed, these ideas should be considered.

@seebees seebees merged commit 7dfa1ae into aws:master Sep 19, 2019
@seebees seebees deleted the clone-decrypt-materials branch September 19, 2019 17:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants