Closed shanecurran closed 3 years ago
@shanecurran - Thank you for your post. I am trying to understand the issue here. You are trying to call the kms Decrypt api here with the Recipient
parameter ? Can't you specify the AttestationDocument inside EncryptionContext
.
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/kms.html#KMS.Client.decrypt
https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#encrypt_context
AWS KMS allows you to use attestation document values in conditions keys to grant access to specific cryptographic operations. I found this documentation which might helps: https://docs.aws.amazon.com/kms/latest/developerguide/policy-conditions.html#conditions-kms https://docs.aws.amazon.com/kms/latest/developerguide/policy-conditions.html#conditions-nitro-enclaves
Let me know if i misunderstood anything here.
Thanks for the response @swetashre. In the current structure of the KMS + Nitro Enclaves flow, the Recipient
parameter is actually a separate field in the JSON body that gets sent to KMS on Decrypt
, GenerateRandom
and GenerateDataKey
. It is not a field in the EncryptionContext
, presumably because it is also supported by asymmetric CMKs.
KMS supports a (currently) undocumented flow whereby the resulting plaintext/random value gets RSAES_OAEP_PKCS1 encrypted using the Nitro Enclave public key from the AttestationDocument
as the receiver. KMS generates a response which is PKCS#7/CMS + Base64 encoded, and included in the CiphertextForRecipient
response field.
I can't find this functionality documented anywhere in the official AWS docs, which has been a source of confusion for me as I only managed to find out the request structure by reading a third-party blog. We use the functionality in production and can confirm that it works as intended.
Thanks for the information @shanecurran. I've contacted the KMS team to find out more.
0550741557
I heard back with from a Nitro Enclaves engineer. The documentation for this feature is here, and is complete with respect to what can be done by customers with the Recipient
field, which is used internally as a "private API" to enable users of the Nitro Enclave SDK to gain access to encrypted data:
https://docs.aws.amazon.com/enclaves/latest/user/kms.html
Full description of this from the team:
The Nitro Enclaves SDK includes the Recipient field on KMS calls for the purpose of re-encrypting a ciphertext previously encrypted by the customer under an AWS KMS customer managed to be encrypted under a public key that corresponds to a private key that is 100% managed by the EC2 service in the Nitro Enclave. Therefore, it's not possible for a customer to use the Recipient field on KMS calls and insert their own arbitrary content in the request (e.g. a public key to be used for re-encryption, or an attestation document signed by some private key the customer provides). The mental model here is that the Recipient field for KMS can only be used by the the Nitro Enclave SDK and it's "hard coded" to use values that are controlled by AWS.
If there is something missing from the documentation such that this is unclear, let us know and I will relay that to the team.
Greetings! It looks like this issue hasn’t been active in longer than a week. We encourage you to check if this is still an issue in the latest release. Because it has been longer than a week since the last update on this, and in the absence of more information, we will be closing this issue soon. If you find that this is still a problem, please feel free to provide a comment or add an upvote to prevent automatic closure, or if the issue is already closed, please feel free to open a new one.
I noticed this issue was closed due to inactivity, but this is still a feature that I think many users can benefit from. The definitions included in botocore
are used to generate code for other languages libraries. For instance, Rusoto, the de-facto Rust AWS library, generates lots of its code from botocore
. So to use Rusoto with these features, we have to fork botocore
and Rusoto
. Up-streaming our changes would be fantastic.
I understand if there is hesitancy to expose this feature to end users, but not exposing it forces people to reverse engineer the APIs based on the Nitro C SDK, and various blog posts like the one linked above. In addition, the documentation on Nitro is currently lacking. There is value in adding these docs just to elucidate how Nitro works internally.
@kdaily - so are you saying that all access to the KMS API that uses attestation has to go via the C API? What if I want an implementation native to the programming language so as to avoid an FFI call to C and the complexity of deploying C libs?
Wouldn't it be possible to generate the attestation (via interacting with the NSM device) and then attach that to a REST KMS API call using the Recipient
key? So, for example, I could use https://github.com/donkersgoed/aws-nsm-interface to get the attestation via native Python and then send a KMS REST call with that attestation - except that isn't currently possible using botocore
because it doesn't expose the Recipient
key.
Unless that's possible, then it pushes those who want native code (i.e. in their programming language) to make those KMS calls by hand - i.e. not using the botocore
API.
@sphw gave the example of Rusoto - and there's a clear argument with that for wanting to avoid the C API. Rust is aimed at safety - unlike C. Avoiding C completely allows a security focus - critical for those wanting to use nitro enclaves.,
The repo that contains the C API documents the REST API with Recipient
directly: see "Request Syntax" in https://github.com/aws/aws-nitro-enclaves-sdk-c/blob/main/docs/kms-apis/Decrypt.md
Describe the bug AWS Nitro Enclaves includes an attestation flow which is closely linked with KMS, whereby the response of a KMS Decrypt, GenerateRandom or GenerateDataKey encrypt the response data with a public key included in the Attestation Document. The flow is described here.
Expected behavior There is no official documentation for this particular flow and I have had to rely on unofficial sources, such as this blog post to find out what the payload structure is. No AWS SDKs currently support the additional
Recipient
parameter and I have had to resort to building my own signing scheme to call the KMS endpoints directly over HTTP.Example structure