awslabs / aws-sdk-rust

AWS SDK for the Rust Programming Language
https://awslabs.github.io/aws-sdk-rust/
Apache License 2.0
3.01k stars 248 forks source link

[request]: AWS KMS client with Nitro Enclaves #74

Open tomtau opened 3 years ago

tomtau commented 3 years ago

Community Note

Tell us about your request What do you want us to build?

Support for AWS KMS client with Nitro Enclaves. Currently, this is possibly in the AWS Nitro Enclaves C SDK (aws_nitro_enclaves_kms_client_new): https://github.com/aws/aws-nitro-enclaves-sdk-c/blob/main/include/aws/nitro_enclaves/kms.h

It'd be good to have a plain Rust version in the AWS Rust SDK.

Tell us about the problem you're trying to solve. What are you trying to do, and why is it hard? What outcome are you trying to achieve, ultimately, and why is it hard/impossible to do right now? What is the impact of not having this problem solved? The more details you can provide, the better we'll be able to understand and solve the problem.

Trying to call AWS KMS API with additional attestation payload produced in AWS Nitro Enclaves. Right now, the AWS KMS API requests need to be send via vsock, because Nitro Enclaves don't allow other forms of I/O. Building the AWS NE C SDK is rather complex: https://github.com/aws/aws-nitro-enclaves-sdk-c#dependencies (in comparison to plain Rust projects)

Are you currently working around this issue? How are you currently solving this problem?

Using the C SDK: https://github.com/aws/aws-nitro-enclaves-sdk-c and this wrapper crate: https://crates.io/crates/aws-ne-sys

Additional context Anything else we should know? Original issue: https://github.com/rusoto/rusoto/issues/1858

Attachments If you think you might have additional information that you'd like to include via an attachment, please do - we'll take a look. (Remember to remove any personally-identifiable information.)

rcoh commented 3 years ago

Thanks for your request!

I think if this is supported it will probably be via a high-level-library rather than via something in-SDK. We'll keep this in mind.

tomtau commented 3 years ago

Thanks for your request!

I think if this is supported it will probably be via a high-level-library rather than via something in-SDK. We'll keep this in mind.

@rcoh thanks -- I think it's not necessary to have the full flow as in AWS NE C SDK. For AWS Rust SDK, it'd be two changes:

  1. add the missing optional aws_recipient fields to the AWS KMS requests: https://github.com/aws/aws-nitro-enclaves-sdk-c/blob/main/include/aws/nitro_enclaves/kms.h#L60 -- the content for that field can be provided by a high-level-library;
  2. allow contacting AWS KMS API over vsock instead of TCP.
rcoh commented 3 years ago
  1. I need to research

  2. May be achievable today by providing your own connection with Client::from_conf_conn(..) and using the HttpService interface to implement it with vsock instead of with TCP

ChrisGreenaway commented 2 years ago

Note that it's not just the request that changes - but also the response - as it uses CiphertextForRecipient rather than Plaintext as documented here: https://github.com/aws/aws-nitro-enclaves-sdk-c/blob/main/docs/kms-apis/Decrypt.md

tomtau commented 2 years ago

Yes, that will happen if one specifies Recipient in the request.

cheungpat commented 2 years ago

I tried to add the Nitro Enclave-specific parameters (Recipient, CiphertextForRecipient) to the KMS SDK and it seems to work:

models json: https://github.com/cheungpat/smithy-rs/commit/fde3a43a65adec77484e5b9ad1dd6fe13ed63fc1 updated sdk: https://github.com/cheungpat/aws-sdk-rust/commit/7c2030782bfddd76e7cfca5b12be680eda63de87

I assume I couldn’t just make a pull request on the models json files because it appears the models are sync'ed from elsewhere. Correct me if I am wrong.

As for the vsock connection, we opted not to include the SDK in the enclave, but to built it in the server program that runs outside of the enclave. In my application there is an existing RPC connection between the two, so we send the attestation document via the connection and have the outside program sends the API calls on the enclave’s behalf. This is better too because I can make use of the credentials available to the EC2 instance, rather than passing those into the enclave.

Hope this helps others who are doing similar things.

tomtau commented 2 years ago

As for the vsock connection, we opted not to include the SDK in the enclave, but to built it in the server program that runs outside of the enclave. In my application there is an existing RPC connection between the two, so we send the attestation document via the connection and have the outside program sends the API calls on the enclave’s behalf. This is better too because I can make use of the credentials available to the EC2 instance, rather than passing those into the enclave.

That's ok for the decryption requests (given it specified Recipient and only the enclave app can read CiphertextForRecipient). For other types of requests, it depends on a particular application, but some applications may need a TLS session directly between their enclave app and KMS, so that the (untrusted) EC2 instance host system can't intercept them.

4tXJ7f commented 1 year ago

It looks like some of the missing

I tried to add the Nitro Enclave-specific parameters (Recipient, CiphertextForRecipient) to the KMS SDK and it seems to work:

models json: cheungpat/smithy-rs@fde3a43 updated sdk: cheungpat@7c20307

[...]

Hope this helps others who are doing similar things.

It looks like the official JSON files have been updated to include the missing parameters: https://github.com/awslabs/smithy-rs/commit/41774b8405de4bb8c7741075aee4e7397b2493a8#diff-461b87548326b2be524a1591353b42744f63b2b12268f365ef890fc4c5fdf8a0