Skip to content

aws-samples/custom-attestation-multi-party-crypto-wallet-with-aws-nitro-enclave

Advanced Attestation and multi-party crypto wallets with AWS Nitro Enclaves

Architecture

AWS Deployment

SSS Application

External Dependencies

  • viproxy: TCP/IP via vsock proxy.
  • nitriding-daemon: HTTPS service that terminates incoming HTTPS connections, responds to attestation requests, and forwards all /app* HTTP requests to the sss app HTTP listener.
  • gvproxy: Proxy component that manages outbound and inbound TCP to vsock connections.
  • nitrite: Go(lang) based binary to parse and verify AWS Nitro Enclave attestations.

Deploying the solution with AWS CDK

Deploying the solution with the AWS CDK The AWS CDK is an open-source framework for defining and provisioning cloud application resources. It uses common programming languages such as JavaScript, C#, and Python. The AWS CDK command line interface (CLI) allows you to interact with CDK applications. It provides features like synthesizing AWS CloudFormation templates, confirming the security changes, and deploying applications.

This section shows how to prepare the environment for running CDK and the sample code. For this walkthrough, you must have the following prerequisites:

When working with Python, it’s good practice to use venv to create project-specific virtual environments. The use of venv also reflects AWS CDK standard behavior. You can find out more in the workshop Activating the virtualenv.

  1. Install the CDK and test the CDK CLI:

    npm install -g aws-cdk && cdk --version
  2. Download the code from the GitHub repo and switch in the new directory:

    git clone https://github.com/aws-samples/aws-nitro-enclave-blockchain-wallet.git && cd aws-nitro-enclave-blockchain-wallet
  3. Install the dependencies using the Python package manager:

    pip install -r requirements.txt
  4. Specify the AWS region and account for your deployment:

    export CDK_DEPLOY_REGION=us-east-1
    export CDK_DEPLOY_ACCOUNT=$(aws sts get-caller-identity | jq -r '.Account')
  5. Specify which public IP should be used to interact with the application:

    export C9_PUBLIC_IP="$(curl https://checkip.amazonaws.com)"
  6. Trigger the vsock proxy build:

    ./scripts/build_vsock_proxy.sh
  7. Change into the application/attestation/third-party folder and install the following dependencies:

    • nitriding-daemon
    git clone https://github.com/brave/nitriding-daemon.git
    cd nitriding-daemon
    make nitriding
    cd ..
    • nitride
    git clone https://github.com/hf/nitrite.git
    cd nitrite
    go build -o nitrite ./cmd/nitrite
    cd ..
    • gvisor
    git clone --depth 1 --branch v0.7.4 https://github.com/containers/gvisor-tap-vsock.git
    cd gvisor-tap-vsock
    CGO_ENABLED=0 GOARCH=amd64 GOOS=linux go build -ldflags '-extldflags "-static"' -o bin/gvproxy-linux-amd64 ./cmd/gvproxy
    cd ..
  8. Deploy the example code with the CDK CLI:

    cdk deploy devNitroWalletSSS -O nitrowallet_output.json

KMS Key Policy

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Enable decrypt from enclave",
      "Effect": "Allow",
      "Principal": {
        "AWS": "<devNitroWalletEth.EC2InstanceRoleARN>"
      },
      "Action": "kms:Decrypt",
      "Resource": "*",
      "Condition": {
        "StringEqualsIgnoreCase": {
          "kms:RecipientAttestation:ImageSha384": "<PCR0_VALUE_FROM_EIF_BUILD>"
        }
      }
    },
    {
      "Sid": "Enable encrypt from enclave",
      "Effect": "Allow",
      "Principal": {
          "AWS": "<devNitroWalletEth.EC2InstanceRoleARN>"
      },
      "Action": "kms:Encrypt",
      "Resource": "*"
      },
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "<KMS_ADMINISTRATOR_ROLE_ARN>"
      },
      "Action": [
        "kms:Create*",
        "kms:Describe*",
        "kms:Enable*",
        "kms:List*",
        "kms:Put*",
        "kms:Update*",
        "kms:Revoke*",
        "kms:Disable*",
        "kms:Get*",
        "kms:Delete*",
        "kms:ScheduleKeyDeletion",
        "kms:CancelKeyDeletion",
        "kms:GenerateDataKey",
        "kms:TagResource",
        "kms:UntagResource"
      ],
      "Resource": "*"
    }
  ]
}

To leverage the provided generate_key_policy.sh script, a CDK output file needs to be provided. This file can be created by running the following command:

cdk deploy devNitroWalletEth -O output.json

After the output.json file has been created, the following command can be used to create the KMS key policy:

./scripts/generate_key_policy.sh ./output.json

If the debug mode has been turned on by appending --debug-mode to the enclaves start sequence, the enclaves PCR0 value in the AWS KMS key policy needs to be updated to 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, otherwise AWS KMS will return error code 400.

Requests

All subsequent requests require the endpoint variable to point to the NLB public DNS address:

export endpoint="<NLB public load balancer DNS>" 

All requests initiated by the enclave touching AWS service require a set of valid AWS credentials. The credentials are being pulled using the imds proxy flow as shown in the following diagram:

Get Attestation Doc Flow

Get Attestation Doc

curl -k https://${endpoint}/enclave/attestation?nonce=ffffffffffffffffffffffffffffffffffffffff

Get Attestation Doc Flow

Create New Key Shard

export recovery_public_key_b64=""
curl -k --header "Content-Type: application/json" \
  --request POST \
  --data '{"recovery_public_key_b64":"'"$recovery_public_key_b64"'"}' \
  "https://${endpoint}/app/sss/key"| jq '.'

Key Shard Generation Flow

Get Signature

export key_shard_b64=""
export pub_key=""
export tx_hash=""
curl -k --header "Content-Type: application/json" \
  --request POST \
  --data '{"key_shard_b64":"'"${key_shard_b64}"'","pub_key":"'"${pub_key}"'","tx_hash":"'"${tx_hash}"'"}' \
  "https://${endpoint}/app/sss/signature" | jq '.'

Signature Creation Flow

Cleaning up

Once you have completed the deployment and tested the application, clean up the environment to avoid incurring extra cost. This command removes all resources in this stack provisioned by the CDK:

cdk destroy

Security

See CONTRIBUTING for more information.

License

This library is licensed under the MIT-0 License. See the LICENSE file.