From 8e0297663a27a8e4fd964dabce315837099c7787 Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Thu, 9 Jul 2026 12:41:33 -0700 Subject: [PATCH 1/3] feat(native-rust): add aws-esdk-cpp C++ shim crate Adds the aws-esdk-cpp crate: a C++ shim (cxx bridge) that exposes the native Rust ESDK to C++ callers. Includes the bridge definitions (src/lib.rs), generated header, CMake/Makefile build, example programs, and duvet requirement annotations tracing to the shim specifications. --- aws-esdk-cpp/Cargo.toml | 8 + aws-esdk-cpp/aws-esdk-cpp/.duvet/config.toml | 19 + .../esdk-shim/algorithm-suite-identifier.toml | 49 + .../shim/esdk-shim/cache-configuration.toml | 28 + .../shim/esdk-shim/commitment-policy.toml | 23 + .../esdk-shim/conformance-and-testing.toml | 27 + .../esdk-shim/create-dynamodb-client.toml | 23 + .../create-hierarchical-keyring.toml | 56 + .../spec/shim/esdk-shim/create-key-store.toml | 54 + .../shim/esdk-shim/create-kms-client.toml | 23 + .../spec/shim/esdk-shim/decrypt-inputs.toml | 41 + .../spec/shim/esdk-shim/decrypt-outputs.toml | 30 + .../spec/shim/esdk-shim/encrypt-inputs.toml | 59 + .../spec/shim/esdk-shim/encrypt-outputs.toml | 30 + .../shim/esdk-shim/encryption-context.toml | 32 + .../spec/shim/esdk-shim/frame-length.toml | 16 + .../shim/esdk-shim/kms-configuration.toml | 42 + .../spec/shim/esdk-shim/materials-source.toml | 23 + .../maximum-encrypted-data-keys.toml | 16 + .../spec/shim/esdk-shim/overview.toml | 23 + .../service-client-configuration.toml | 66 + .../spec/shim/shim/concurrency.toml | 14 + .../shim/shim/conformance-and-testing.toml | 25 + .../creating-and-releasing-resources.toml | 31 + .../spec/shim/shim/delegation.toml | 49 + .../spec/shim/shim/handles-and-lifetimes.toml | 25 + .../spec/shim/shim/operation-contracts.toml | 24 + .../spec/shim/shim/owned-interface.toml | 45 + .../spec/shim/shim/streaming.toml | 14 + .../spec/shim/shim/type-translation.toml | 52 + aws-esdk-cpp/aws-esdk-cpp/.duvet/snapshot.txt | 224 ++ aws-esdk-cpp/aws-esdk-cpp/.gitignore | 19 + aws-esdk-cpp/aws-esdk-cpp/CMakeLists.txt | 63 + aws-esdk-cpp/aws-esdk-cpp/Cargo.lock | 2835 +++++++++++++++++ aws-esdk-cpp/aws-esdk-cpp/Cargo.toml | 34 + aws-esdk-cpp/aws-esdk-cpp/Makefile | 53 + aws-esdk-cpp/aws-esdk-cpp/README.md | 19 + aws-esdk-cpp/aws-esdk-cpp/build.rs | 11 + aws-esdk-cpp/aws-esdk-cpp/doc_plan.md | 88 + .../include/aws/esdk/EncryptionSDK.h | 264 ++ aws-esdk-cpp/aws-esdk-cpp/main.cpp | 61 + aws-esdk-cpp/aws-esdk-cpp/main_idiomatic.cpp | 57 + aws-esdk-cpp/aws-esdk-cpp/spec | 1 + aws-esdk-cpp/aws-esdk-cpp/src/lib.rs | 920 ++++++ aws-esdk-cpp/aws-esdk-cpp/src/tests.rs | 658 ++++ aws-esdk-cpp/aws-esdk-cpp/test_esdk.cpp | 253 ++ aws-esdk-cpp/main_idiomatic.cpp | 57 + aws-esdk-cpp/src/lib.rs | 1 + 48 files changed, 6585 insertions(+) create mode 100644 aws-esdk-cpp/Cargo.toml create mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/config.toml create mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/algorithm-suite-identifier.toml create mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/cache-configuration.toml create mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/commitment-policy.toml create mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/conformance-and-testing.toml create mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/create-dynamodb-client.toml create mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/create-hierarchical-keyring.toml create mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/create-key-store.toml create mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/create-kms-client.toml create mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/decrypt-inputs.toml create mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/decrypt-outputs.toml create mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/encrypt-inputs.toml create mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/encrypt-outputs.toml create mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/encryption-context.toml create mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/frame-length.toml create mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/kms-configuration.toml create mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/materials-source.toml create mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/maximum-encrypted-data-keys.toml create mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/overview.toml create mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/service-client-configuration.toml create mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/concurrency.toml create mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/conformance-and-testing.toml create mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/creating-and-releasing-resources.toml create mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/delegation.toml create mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/handles-and-lifetimes.toml create mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/operation-contracts.toml create mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/owned-interface.toml create mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/streaming.toml create mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/type-translation.toml create mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/snapshot.txt create mode 100644 aws-esdk-cpp/aws-esdk-cpp/.gitignore create mode 100644 aws-esdk-cpp/aws-esdk-cpp/CMakeLists.txt create mode 100644 aws-esdk-cpp/aws-esdk-cpp/Cargo.lock create mode 100644 aws-esdk-cpp/aws-esdk-cpp/Cargo.toml create mode 100644 aws-esdk-cpp/aws-esdk-cpp/Makefile create mode 100644 aws-esdk-cpp/aws-esdk-cpp/README.md create mode 100644 aws-esdk-cpp/aws-esdk-cpp/build.rs create mode 100644 aws-esdk-cpp/aws-esdk-cpp/doc_plan.md create mode 100644 aws-esdk-cpp/aws-esdk-cpp/include/aws/esdk/EncryptionSDK.h create mode 100644 aws-esdk-cpp/aws-esdk-cpp/main.cpp create mode 100644 aws-esdk-cpp/aws-esdk-cpp/main_idiomatic.cpp create mode 120000 aws-esdk-cpp/aws-esdk-cpp/spec create mode 100644 aws-esdk-cpp/aws-esdk-cpp/src/lib.rs create mode 100644 aws-esdk-cpp/aws-esdk-cpp/src/tests.rs create mode 100644 aws-esdk-cpp/aws-esdk-cpp/test_esdk.cpp create mode 100644 aws-esdk-cpp/main_idiomatic.cpp create mode 100644 aws-esdk-cpp/src/lib.rs diff --git a/aws-esdk-cpp/Cargo.toml b/aws-esdk-cpp/Cargo.toml new file mode 100644 index 000000000..15a8be733 --- /dev/null +++ b/aws-esdk-cpp/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "aws-esdk-cpp-stub" +version = "0.0.0" +edition = "2024" +publish = false + +[lib] +path = "src/lib.rs" diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/config.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/config.toml new file mode 100644 index 000000000..6e50e17e7 --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/.duvet/config.toml @@ -0,0 +1,19 @@ +'$schema' = "https://awslabs.github.io/duvet/config/v0.4.0.json" + +[[source]] +pattern = "./src/**/*.rs" + +[[source]] +pattern = "./include/**/*.h" + +[[source]] +pattern = "./*.cpp" + +[[specification]] +source = "spec/shim/shim.md" + +[[specification]] +source = "spec/shim/esdk-shim.md" + +[report.snapshot] +enabled = true diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/algorithm-suite-identifier.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/algorithm-suite-identifier.toml new file mode 100644 index 000000000..70f872c11 --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/algorithm-suite-identifier.toml @@ -0,0 +1,49 @@ +target = "spec/shim/esdk-shim.md#algorithm-suite-identifier" + +# Algorithm suite identifier +# +# The target algorithm suite identifier is the two-byte algorithm suite ID defined +# by the ESDK message format. +# +# Converting to the core ESDK: +# +# - The shim MUST translate a target algorithm suite identifier to the core ESDK +# algorithm suite that has the same two-byte ID. +# - The shim MUST return an error when the target value is not one of the algorithm +# suite IDs defined by the core ESDK. +# +# Converting from the core ESDK: +# +# - The shim MUST translate a core ESDK algorithm suite to the target algorithm +# suite identifier that has the same two-byte ID. +# - The shim MUST return an error when the core ESDK produces an algorithm suite +# the shim does not define. + +[[spec]] +level = "MUST" +quote = ''' +- The shim MUST translate a target algorithm suite identifier to the core ESDK +algorithm suite that has the same two-byte ID. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The shim MUST return an error when the target value is not one of the algorithm +suite IDs defined by the core ESDK. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The shim MUST translate a core ESDK algorithm suite to the target algorithm +suite identifier that has the same two-byte ID. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The shim MUST return an error when the core ESDK produces an algorithm suite +the shim does not define. +''' + diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/cache-configuration.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/cache-configuration.toml new file mode 100644 index 000000000..2e2118558 --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/cache-configuration.toml @@ -0,0 +1,28 @@ +target = "spec/shim/esdk-shim.md#cache-configuration" + +# Cache configuration +# +# - The shim MUST translate a no-cache selection. +# - The shim MUST translate a multi-threaded cache selection. +# - The shim MUST return an error when the target cache type is not a supported +# value. + +[[spec]] +level = "MUST" +quote = ''' +- The shim MUST translate a no-cache selection. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The shim MUST translate a multi-threaded cache selection. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The shim MUST return an error when the target cache type is not a supported +value. +''' + diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/commitment-policy.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/commitment-policy.toml new file mode 100644 index 000000000..253a5b1b5 --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/commitment-policy.toml @@ -0,0 +1,23 @@ +target = "spec/shim/esdk-shim.md#commitment-policy" + +# Commitment policy +# +# - The shim MUST translate the target commitment policy to the core ESDK +# commitment policy of the same meaning. +# - The shim MUST return an error when the target commitment policy is not a supported +# value. + +[[spec]] +level = "MUST" +quote = ''' +- The shim MUST translate the target commitment policy to the core ESDK +commitment policy of the same meaning. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The shim MUST return an error when the target commitment policy is not a supported +value. +''' + diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/conformance-and-testing.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/conformance-and-testing.toml new file mode 100644 index 000000000..59d14f5b4 --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/conformance-and-testing.toml @@ -0,0 +1,27 @@ +target = "spec/shim/esdk-shim.md#conformance-and-testing" + +# Conformance and testing +# +# In addition to the [Shim Specification conformance requirements](./shim.md#conformance-and-testing): +# +# - The ESDK shim MUST be tested for the behavior it owns — translation, handle +# validation, error propagation, and lifetime safety — rather than by re-testing +# the core ESDK's cryptographic behavior. +# - The ESDK shim SHOULD demonstrate message interoperability with other ESDK +# implementations (for example via a shared test-vector suite). + +[[spec]] +level = "MUST" +quote = ''' +- The ESDK shim MUST be tested for the behavior it owns — translation, handle +validation, error propagation, and lifetime safety — rather than by re-testing +the core ESDK's cryptographic behavior. +''' + +[[spec]] +level = "SHOULD" +quote = ''' +- The ESDK shim SHOULD demonstrate message interoperability with other ESDK +implementations (for example via a shared test-vector suite). +''' + diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/create-dynamodb-client.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/create-dynamodb-client.toml new file mode 100644 index 000000000..a665a7189 --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/create-dynamodb-client.toml @@ -0,0 +1,23 @@ +target = "spec/shim/esdk-shim.md#create-dynamodb-client" + +# Create DynamoDB client +# +# - The shim MUST provide an operation that creates a DynamoDB service client +# backed by the core ESDK. +# - Creating a DynamoDB client MUST apply the target-supplied client configuration, +# as defined in [Service client configuration](#service-client-configuration). + +[[spec]] +level = "MUST" +quote = ''' +- The shim MUST provide an operation that creates a DynamoDB service client +backed by the core ESDK. +''' + +[[spec]] +level = "MUST" +quote = ''' +- Creating a DynamoDB client MUST apply the target-supplied client configuration, +as defined in [Service client configuration](#service-client-configuration). +''' + diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/create-hierarchical-keyring.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/create-hierarchical-keyring.toml new file mode 100644 index 000000000..763107d39 --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/create-hierarchical-keyring.toml @@ -0,0 +1,56 @@ +target = "spec/shim/esdk-shim.md#create-hierarchical-keyring" + +# Create hierarchical keyring +# +# - The shim MUST provide an operation that creates a hierarchical keyring backed +# by the core ESDK. +# - Creating a hierarchical keyring MUST require a key store handle, checked as +# defined in +# [Shim Specification: Handles and lifetimes](./shim.md#handles-and-lifetimes), +# and MUST provide it to the core ESDK. +# - Creating a hierarchical keyring MUST provide the target-supplied branch key id +# and time-to-live to the core ESDK. +# - Creating a hierarchical keyring MUST provide the target-supplied cache +# configuration to the core ESDK, converted as defined in +# [Cache configuration](#cache-configuration). +# - Creating a hierarchical keyring MUST provide the target-supplied partition id to +# the core ESDK when present; an unset value is omitted. + +[[spec]] +level = "MUST" +quote = ''' +- The shim MUST provide an operation that creates a hierarchical keyring backed +by the core ESDK. +''' + +[[spec]] +level = "MUST" +quote = ''' +- Creating a hierarchical keyring MUST require a key store handle, checked as +defined in +[Shim Specification: Handles and lifetimes](./shim.md#handles-and-lifetimes), +and MUST provide it to the core ESDK. +''' + +[[spec]] +level = "MUST" +quote = ''' +- Creating a hierarchical keyring MUST provide the target-supplied branch key id +and time-to-live to the core ESDK. +''' + +[[spec]] +level = "MUST" +quote = ''' +- Creating a hierarchical keyring MUST provide the target-supplied cache +configuration to the core ESDK, converted as defined in +[Cache configuration](#cache-configuration). +''' + +[[spec]] +level = "MUST" +quote = ''' +- Creating a hierarchical keyring MUST provide the target-supplied partition id to +the core ESDK when present; an unset value is omitted. +''' + diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/create-key-store.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/create-key-store.toml new file mode 100644 index 000000000..9b9698a27 --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/create-key-store.toml @@ -0,0 +1,54 @@ +target = "spec/shim/esdk-shim.md#create-key-store" + +# Create key store +# +# - The shim MUST provide an operation that creates a key store backed by the core +# ESDK. +# - Creating a key store MUST require a KMS client handle and a DynamoDB client +# handle, checked as defined in +# [Shim Specification: Handles and lifetimes](./shim.md#handles-and-lifetimes), +# and MUST provide both to the core ESDK. +# - Creating a key store MUST provide the target-supplied table name and logical key +# store name to the core ESDK. +# - Creating a key store MUST provide the target-supplied KMS configuration to the +# core ESDK, converted as defined in [KMS configuration](#kms-configuration). +# - Creating a key store MUST provide the target-supplied key store id and grant +# tokens to the core ESDK when present; an unset value is omitted. + +[[spec]] +level = "MUST" +quote = ''' +- The shim MUST provide an operation that creates a key store backed by the core +ESDK. +''' + +[[spec]] +level = "MUST" +quote = ''' +- Creating a key store MUST require a KMS client handle and a DynamoDB client +handle, checked as defined in +[Shim Specification: Handles and lifetimes](./shim.md#handles-and-lifetimes), +and MUST provide both to the core ESDK. +''' + +[[spec]] +level = "MUST" +quote = ''' +- Creating a key store MUST provide the target-supplied table name and logical key +store name to the core ESDK. +''' + +[[spec]] +level = "MUST" +quote = ''' +- Creating a key store MUST provide the target-supplied KMS configuration to the +core ESDK, converted as defined in [KMS configuration](#kms-configuration). +''' + +[[spec]] +level = "MUST" +quote = ''' +- Creating a key store MUST provide the target-supplied key store id and grant +tokens to the core ESDK when present; an unset value is omitted. +''' + diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/create-kms-client.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/create-kms-client.toml new file mode 100644 index 000000000..3052e0648 --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/create-kms-client.toml @@ -0,0 +1,23 @@ +target = "spec/shim/esdk-shim.md#create-kms-client" + +# Create KMS client +# +# - The shim MUST provide an operation that creates a KMS service client backed by +# the core ESDK. +# - Creating a KMS client MUST apply the target-supplied client configuration, as +# defined in [Service client configuration](#service-client-configuration). + +[[spec]] +level = "MUST" +quote = ''' +- The shim MUST provide an operation that creates a KMS service client backed by +the core ESDK. +''' + +[[spec]] +level = "MUST" +quote = ''' +- Creating a KMS client MUST apply the target-supplied client configuration, as +defined in [Service client configuration](#service-client-configuration). +''' + diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/decrypt-inputs.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/decrypt-inputs.toml new file mode 100644 index 000000000..759ca0dd4 --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/decrypt-inputs.toml @@ -0,0 +1,41 @@ +target = "spec/shim/esdk-shim.md#decrypt-inputs" + +# Decrypt inputs +# +# - `decrypt` MUST pass the target-supplied ciphertext to the core ESDK unmodified. +# - `decrypt` MUST provide the target-supplied encryption context to the core ESDK, +# converted as defined in [Encryption context](#encryption-context). +# - `decrypt` MUST provide the target-supplied commitment policy to the core ESDK, +# converted as defined in [Commitment policy](#commitment-policy). +# - `decrypt` MUST provide the target-supplied maximum-encrypted-data-keys value to +# the core ESDK, converted as defined in +# [Maximum encrypted data keys](#maximum-encrypted-data-keys). + +[[spec]] +level = "MUST" +quote = ''' +- `decrypt` MUST pass the target-supplied ciphertext to the core ESDK unmodified. +''' + +[[spec]] +level = "MUST" +quote = ''' +- `decrypt` MUST provide the target-supplied encryption context to the core ESDK, +converted as defined in [Encryption context](#encryption-context). +''' + +[[spec]] +level = "MUST" +quote = ''' +- `decrypt` MUST provide the target-supplied commitment policy to the core ESDK, +converted as defined in [Commitment policy](#commitment-policy). +''' + +[[spec]] +level = "MUST" +quote = ''' +- `decrypt` MUST provide the target-supplied maximum-encrypted-data-keys value to +the core ESDK, converted as defined in +[Maximum encrypted data keys](#maximum-encrypted-data-keys). +''' + diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/decrypt-outputs.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/decrypt-outputs.toml new file mode 100644 index 000000000..1f4daafe8 --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/decrypt-outputs.toml @@ -0,0 +1,30 @@ +target = "spec/shim/esdk-shim.md#decrypt-outputs" + +# Decrypt outputs +# +# - `decrypt` MUST return the core ESDK's plaintext unmodified. +# - `decrypt` MUST return the used algorithm suite, converted as defined in +# [Algorithm suite identifier](#algorithm-suite-identifier). +# - `decrypt` MUST return the result encryption context, converted as defined in +# [Encryption context](#encryption-context). + +[[spec]] +level = "MUST" +quote = ''' +- `decrypt` MUST return the core ESDK's plaintext unmodified. +''' + +[[spec]] +level = "MUST" +quote = ''' +- `decrypt` MUST return the used algorithm suite, converted as defined in +[Algorithm suite identifier](#algorithm-suite-identifier). +''' + +[[spec]] +level = "MUST" +quote = ''' +- `decrypt` MUST return the result encryption context, converted as defined in +[Encryption context](#encryption-context). +''' + diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/encrypt-inputs.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/encrypt-inputs.toml new file mode 100644 index 000000000..1c8303efd --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/encrypt-inputs.toml @@ -0,0 +1,59 @@ +target = "spec/shim/esdk-shim.md#encrypt-inputs" + +# Encrypt inputs +# +# - `encrypt` MUST pass the target-supplied plaintext to the core ESDK unmodified. +# - `encrypt` MUST provide the target-supplied encryption context to the core ESDK, +# converted as defined in [Encryption context](#encryption-context). +# - `encrypt` MUST provide the target-supplied algorithm suite to the core ESDK, +# converted as defined in [Algorithm suite identifier](#algorithm-suite-identifier). +# - `encrypt` MUST provide the target-supplied commitment policy to the core ESDK, +# converted as defined in [Commitment policy](#commitment-policy). +# - `encrypt` MUST provide the target-supplied frame length to the core ESDK, +# converted as defined in [Frame length](#frame-length). +# - `encrypt` MUST provide the target-supplied maximum-encrypted-data-keys value to +# the core ESDK, converted as defined in +# [Maximum encrypted data keys](#maximum-encrypted-data-keys). + +[[spec]] +level = "MUST" +quote = ''' +- `encrypt` MUST pass the target-supplied plaintext to the core ESDK unmodified. +''' + +[[spec]] +level = "MUST" +quote = ''' +- `encrypt` MUST provide the target-supplied encryption context to the core ESDK, +converted as defined in [Encryption context](#encryption-context). +''' + +[[spec]] +level = "MUST" +quote = ''' +- `encrypt` MUST provide the target-supplied algorithm suite to the core ESDK, +converted as defined in [Algorithm suite identifier](#algorithm-suite-identifier). +''' + +[[spec]] +level = "MUST" +quote = ''' +- `encrypt` MUST provide the target-supplied commitment policy to the core ESDK, +converted as defined in [Commitment policy](#commitment-policy). +''' + +[[spec]] +level = "MUST" +quote = ''' +- `encrypt` MUST provide the target-supplied frame length to the core ESDK, +converted as defined in [Frame length](#frame-length). +''' + +[[spec]] +level = "MUST" +quote = ''' +- `encrypt` MUST provide the target-supplied maximum-encrypted-data-keys value to +the core ESDK, converted as defined in +[Maximum encrypted data keys](#maximum-encrypted-data-keys). +''' + diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/encrypt-outputs.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/encrypt-outputs.toml new file mode 100644 index 000000000..69caa83c0 --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/encrypt-outputs.toml @@ -0,0 +1,30 @@ +target = "spec/shim/esdk-shim.md#encrypt-outputs" + +# Encrypt outputs +# +# - `encrypt` MUST return the core ESDK's ciphertext unmodified. +# - `encrypt` MUST return the used algorithm suite, converted as defined in +# [Algorithm suite identifier](#algorithm-suite-identifier). +# - `encrypt` MUST return the result encryption context, converted as defined in +# [Encryption context](#encryption-context). + +[[spec]] +level = "MUST" +quote = ''' +- `encrypt` MUST return the core ESDK's ciphertext unmodified. +''' + +[[spec]] +level = "MUST" +quote = ''' +- `encrypt` MUST return the used algorithm suite, converted as defined in +[Algorithm suite identifier](#algorithm-suite-identifier). +''' + +[[spec]] +level = "MUST" +quote = ''' +- `encrypt` MUST return the result encryption context, converted as defined in +[Encryption context](#encryption-context). +''' + diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/encryption-context.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/encryption-context.toml new file mode 100644 index 000000000..d54302bbf --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/encryption-context.toml @@ -0,0 +1,32 @@ +target = "spec/shim/esdk-shim.md#encryption-context" + +# Encryption context +# +# Converting to the core ESDK: +# +# - The shim MUST translate the target's encryption context, given as a list of +# key-value pairs, to the core ESDK's key-value map, preserving every pair and +# the exact key and value of each. +# +# Converting from the core ESDK: +# +# - The shim MUST translate the core ESDK's encryption context, given as a +# key-value map, to the target's list of key-value pairs, preserving every pair +# and the exact key and value of each. + +[[spec]] +level = "MUST" +quote = ''' +- The shim MUST translate the target's encryption context, given as a list of +key-value pairs, to the core ESDK's key-value map, preserving every pair and +the exact key and value of each. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The shim MUST translate the core ESDK's encryption context, given as a +key-value map, to the target's list of key-value pairs, preserving every pair +and the exact key and value of each. +''' + diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/frame-length.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/frame-length.toml new file mode 100644 index 000000000..2fd5eacee --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/frame-length.toml @@ -0,0 +1,16 @@ +target = "spec/shim/esdk-shim.md#frame-length" + +# Frame length +# +# - The shim MUST translate the target frame length using the core ESDK's frame +# length constructor, and MUST return an error when the core ESDK rejects the +# value. + +[[spec]] +level = "MUST" +quote = ''' +- The shim MUST translate the target frame length using the core ESDK's frame +length constructor, and MUST return an error when the core ESDK rejects the +value. +''' + diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/kms-configuration.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/kms-configuration.toml new file mode 100644 index 000000000..0facf7fa9 --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/kms-configuration.toml @@ -0,0 +1,42 @@ +target = "spec/shim/esdk-shim.md#kms-configuration" + +# KMS configuration +# +# - The shim MUST translate a KMS key ARN configuration. +# - The shim MUST translate a KMS multi-Region-key ARN configuration. +# - The shim MUST translate a discovery configuration. +# - The shim MUST translate a multi-Region-key discovery configuration. +# - The shim MUST return an error when the target KMS configuration type is not a +# supported value. + +[[spec]] +level = "MUST" +quote = ''' +- The shim MUST translate a KMS key ARN configuration. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The shim MUST translate a KMS multi-Region-key ARN configuration. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The shim MUST translate a discovery configuration. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The shim MUST translate a multi-Region-key discovery configuration. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The shim MUST return an error when the target KMS configuration type is not a +supported value. +''' + diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/materials-source.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/materials-source.toml new file mode 100644 index 000000000..abcd50fa8 --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/materials-source.toml @@ -0,0 +1,23 @@ +target = "spec/shim/esdk-shim.md#materials-source" + +# Materials source +# +# - Each of `encrypt` and `decrypt` MUST be supplied with exactly one materials +# source (see [Resources](#resources)). +# - The shim MUST return an error, and MUST NOT invoke the core ESDK, when no +# materials source is supplied. + +[[spec]] +level = "MUST" +quote = ''' +- Each of `encrypt` and `decrypt` MUST be supplied with exactly one materials +source (see [Resources](#resources)). +''' + +[[spec]] +level = "MUST" +quote = ''' +- The shim MUST return an error, and MUST NOT invoke the core ESDK, when no +materials source is supplied. +''' + diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/maximum-encrypted-data-keys.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/maximum-encrypted-data-keys.toml new file mode 100644 index 000000000..436ddeb7e --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/maximum-encrypted-data-keys.toml @@ -0,0 +1,16 @@ +target = "spec/shim/esdk-shim.md#maximum-encrypted-data-keys" + +# Maximum encrypted data keys +# +# - The target represents "no limit" as the value zero. The shim MUST translate zero +# to the core ESDK's "no limit" representation, and a positive value `n` to a +# limit of `n`. + +[[spec]] +level = "MUST" +quote = ''' +The shim MUST translate zero +to the core ESDK's "no limit" representation, and a positive value `n` to a +limit of `n`. +''' + diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/overview.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/overview.toml new file mode 100644 index 000000000..96b9cfcff --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/overview.toml @@ -0,0 +1,23 @@ +target = "spec/shim/esdk-shim.md#overview" + +# Overview +# +# This document specifies a **shim** whose **core library** is a compliant AWS +# Encryption SDK implementation (the **core ESDK**). An ESDK shim exposes the core +# ESDK to a consumer running in another language or runtime (the **target**). +# +# An ESDK shim MUST conform to the generic [Shim Specification](./shim.md). This +# document defines only the ESDK-specific detail that specification defers to a +# core-library-specific spec: the concrete [type translations](#type-translation), +# [resources](#resources), and [operations](#operation-contracts) an ESDK shim +# exposes. +# +# A shim is not an ESDK implementation. It delegates the message format, +# cryptography, key derivation, commitment, and signing to the core ESDK. + +[[spec]] +level = "MUST" +quote = ''' +An ESDK shim MUST conform to the generic [Shim Specification](./shim.md). +''' + diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/service-client-configuration.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/service-client-configuration.toml new file mode 100644 index 000000000..f875f002c --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/service-client-configuration.toml @@ -0,0 +1,66 @@ +target = "spec/shim/esdk-shim.md#service-client-configuration" + +# Service client configuration +# +# The shim configures each AWS service client it creates from a client +# configuration supplied by the target. Any value the target supplies is passed +# through to the service client; where the target omits a value, the shim may +# apply a default. +# +# - The shim MUST set a user-agent on each service client of the form +# `AwsEncryptionSdk-Shim---`, where +# `` is the target language, `` is the core +# ESDK's implementation language, and `` is the shim's published version. +# - The shim MUST preserve any user-agent already present in the loaded +# configuration, appending its own rather than replacing it. +# - If the target supplies a retry configuration, the shim MUST apply it to each +# service client. +# - If the target does not supply a retry configuration, the shim MAY apply a +# default retry configuration. +# - If the target supplies a region, the shim MUST apply it to each service client. +# - The shim SHOULD allow one client configuration to be applied to multiple +# service clients. + +[[spec]] +level = "MUST" +quote = ''' +- The shim MUST set a user-agent on each service client of the form +`AwsEncryptionSdk-Shim---`, where +`` is the target language, `` is the core +ESDK's implementation language, and `` is the shim's published version. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The shim MUST preserve any user-agent already present in the loaded +configuration, appending its own rather than replacing it. +''' + +[[spec]] +level = "MUST" +quote = ''' +- If the target supplies a retry configuration, the shim MUST apply it to each +service client. +''' + +[[spec]] +level = "MAY" +quote = ''' +- If the target does not supply a retry configuration, the shim MAY apply a +default retry configuration. +''' + +[[spec]] +level = "MUST" +quote = ''' +- If the target supplies a region, the shim MUST apply it to each service client. +''' + +[[spec]] +level = "SHOULD" +quote = ''' +- The shim SHOULD allow one client configuration to be applied to multiple +service clients. +''' + diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/concurrency.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/concurrency.toml new file mode 100644 index 000000000..9b5416aa1 --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/concurrency.toml @@ -0,0 +1,14 @@ +target = "spec/shim/shim.md#concurrency" + +# Concurrency +# +# If a core library resource or operation supports concurrent use from multiple threads, +# the shim library SHOULD support it as well. + +[[spec]] +level = "SHOULD" +quote = ''' +If a core library resource or operation supports concurrent use from multiple threads, +the shim library SHOULD support it as well. +''' + diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/conformance-and-testing.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/conformance-and-testing.toml new file mode 100644 index 000000000..c24d06513 --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/conformance-and-testing.toml @@ -0,0 +1,25 @@ +target = "spec/shim/shim.md#conformance-and-testing" + +# Conformance and testing +# +# - A shim MUST conform to this specification in addition to its core-library-specific +# shim specification. +# - The shim SHOULD be tested for the behavior it owns — translation, handle +# validation, error propagation, and lifetime safety — rather than by re-testing +# the core library's own behavior. + +[[spec]] +level = "MUST" +quote = ''' +- A shim MUST conform to this specification in addition to its core-library-specific +shim specification. +''' + +[[spec]] +level = "SHOULD" +quote = ''' +- The shim SHOULD be tested for the behavior it owns — translation, handle +validation, error propagation, and lifetime safety — rather than by re-testing +the core library's own behavior. +''' + diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/creating-and-releasing-resources.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/creating-and-releasing-resources.toml new file mode 100644 index 000000000..c1090b8c8 --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/creating-and-releasing-resources.toml @@ -0,0 +1,31 @@ +target = "spec/shim/shim.md#creating-and-releasing-resources" + +# Creating and releasing resources +# +# - For each resource kind, the shim MUST provide a means for the target to create an +# instance backed by the core library. +# - The shim MUST release the core-library resource backing an owned interface once +# the target no longer holds it. The shim MAY release it automatically when the +# owned interface is destroyed, or through an explicit target operation. + +[[spec]] +level = "MUST" +quote = ''' +- For each resource kind, the shim MUST provide a means for the target to create an +instance backed by the core library. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The shim MUST release the core-library resource backing an owned interface once +the target no longer holds it. +''' + +[[spec]] +level = "MAY" +quote = ''' +The shim MAY release it automatically when the +owned interface is destroyed, or through an explicit target operation. +''' + diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/delegation.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/delegation.toml new file mode 100644 index 000000000..416f4fa55 --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/delegation.toml @@ -0,0 +1,49 @@ +target = "spec/shim/shim.md#delegation" + +# Delegation +# +# The shim implements none of the core library's behavior of its own; it forwards +# each operation to the core library and lets the core library do the work and +# enforce validity. These requirements pin down that forwarding. +# +# - Each operation the shim exposes MUST produce its result by invoking the +# corresponding core-library operation. +# - The shim MUST NOT validate operation or resource-creation input values itself; +# it MUST translate each input and defer its validation to the core library. +# - When a core-library operation returns an error, the shim MUST return an error to +# the target and MUST NOT report the operation as successful. +# - An error the shim returns for a failed core-library operation SHOULD include +# context identifying which operation failed. +# +# Checking a target-supplied handle for presence before dereferencing it (see +# [Handles and lifetimes](#handles-and-lifetimes)) is a memory-safety measure, not +# input validation, and is not subject to the rule above. + +[[spec]] +level = "MUST" +quote = ''' +- Each operation the shim exposes MUST produce its result by invoking the +corresponding core-library operation. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The shim MUST NOT validate operation or resource-creation input values itself; +it MUST translate each input and defer its validation to the core library. +''' + +[[spec]] +level = "MUST" +quote = ''' +- When a core-library operation returns an error, the shim MUST return an error to +the target and MUST NOT report the operation as successful. +''' + +[[spec]] +level = "SHOULD" +quote = ''' +- An error the shim returns for a failed core-library operation SHOULD include +context identifying which operation failed. +''' + diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/handles-and-lifetimes.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/handles-and-lifetimes.toml new file mode 100644 index 000000000..7d09d3723 --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/handles-and-lifetimes.toml @@ -0,0 +1,25 @@ +target = "spec/shim/shim.md#handles-and-lifetimes" + +# Handles and lifetimes +# +# - Before dereferencing a target-supplied resource handle, the shim MUST check it +# and MUST return an error when a required handle is absent. +# - An owned interface that depends on another resource MUST retain ownership of +# that resource for its own lifetime, so that a handle passed across the boundary +# cannot outlive the resource it refers to. + +[[spec]] +level = "MUST" +quote = ''' +- Before dereferencing a target-supplied resource handle, the shim MUST check it +and MUST return an error when a required handle is absent. +''' + +[[spec]] +level = "MUST" +quote = ''' +- An owned interface that depends on another resource MUST retain ownership of +that resource for its own lifetime, so that a handle passed across the boundary +cannot outlive the resource it refers to. +''' + diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/operation-contracts.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/operation-contracts.toml new file mode 100644 index 000000000..9176e5360 --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/operation-contracts.toml @@ -0,0 +1,24 @@ +target = "spec/shim/shim.md#operation-contracts" + +# Operation contracts +# +# - For each operation the shim exposes, its core-library-specific shim +# specification defines which inputs are required, how each input is handled, +# and how each output field is handled. +# - Except where an input or output is passed through unmodified, each MUST be +# translated per [Type translation](#type-translation). +# - Each operation MUST invoke the core library per [Delegation](#delegation). + +[[spec]] +level = "MUST" +quote = ''' +- Except where an input or output is passed through unmodified, each MUST be +translated per [Type translation](#type-translation). +''' + +[[spec]] +level = "MUST" +quote = ''' +- Each operation MUST invoke the core library per [Delegation](#delegation). +''' + diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/owned-interface.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/owned-interface.toml new file mode 100644 index 000000000..45ffa01bf --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/owned-interface.toml @@ -0,0 +1,45 @@ +target = "spec/shim/shim.md#owned-interface" + +# Owned interface +# +# The owned interface is the public surface the target programs against. Its purpose +# is to decouple the target from the generator: because the target depends only on +# types the shim defines — never on generator-produced types — the binding +# generator can be changed or replaced without breaking target code. The following +# requirements keep that boundary intact. +# +# - The shim MUST define its own error type for its public surface. +# - For each core-library enumeration it exposes, the shim MUST define its own +# corresponding enumeration type. +# - Each public function the shim exposes MUST use only owned-interface types or +# standard-library types in its signature. +# - Each owned interface that represents a core-library resource MUST hold the +# generated handle privately and MUST NOT expose it in its public API. + +[[spec]] +level = "MUST" +quote = ''' +- The shim MUST define its own error type for its public surface. +''' + +[[spec]] +level = "MUST" +quote = ''' +- For each core-library enumeration it exposes, the shim MUST define its own +corresponding enumeration type. +''' + +[[spec]] +level = "MUST" +quote = ''' +- Each public function the shim exposes MUST use only owned-interface types or +standard-library types in its signature. +''' + +[[spec]] +level = "MUST" +quote = ''' +- Each owned interface that represents a core-library resource MUST hold the +generated handle privately and MUST NOT expose it in its public API. +''' + diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/streaming.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/streaming.toml new file mode 100644 index 000000000..76cff5daf --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/streaming.toml @@ -0,0 +1,14 @@ +target = "spec/shim/shim.md#streaming" + +# Streaming +# +# If a core library resource or operation supports [streamed](../client-apis/streaming.md) input/outputs, +# the shim library SHOULD support it as well. + +[[spec]] +level = "SHOULD" +quote = ''' +If a core library resource or operation supports [streamed](../client-apis/streaming.md) input/outputs, +the shim library SHOULD support it as well. +''' + diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/type-translation.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/type-translation.toml new file mode 100644 index 000000000..78ffa92eb --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/type-translation.toml @@ -0,0 +1,52 @@ +target = "spec/shim/shim.md#type-translation" + +# Type translation +# +# A shim converts each value between its target representation and the core +# library's representation. This generic specification does not enumerate concrete +# types; a core-library-specific shim specification defines a translation for +# each value it exposes. Every such translation MUST obey the following rules. +# +# - A translation MUST convert between the target representation and the core +# library representation, preserving meaning in both directions it supports. +# - A translation reports failure by returning an error; it MUST NOT panic, abort, +# or otherwise terminate the target process. +# - When the target supplies a value that has no corresponding core-library +# representation, the translation MUST return an error. +# - When the core library produces a value the shim does not define, the +# translation MUST return an error. + +[[spec]] +level = "MUST" +quote = ''' +Every such translation MUST obey the following rules. +''' + +[[spec]] +level = "MUST" +quote = ''' +- A translation MUST convert between the target representation and the core +library representation, preserving meaning in both directions it supports. +''' + +[[spec]] +level = "MUST" +quote = ''' +- A translation reports failure by returning an error; it MUST NOT panic, abort, +or otherwise terminate the target process. +''' + +[[spec]] +level = "MUST" +quote = ''' +- When the target supplies a value that has no corresponding core-library +representation, the translation MUST return an error. +''' + +[[spec]] +level = "MUST" +quote = ''' +- When the core library produces a value the shim does not define, the +translation MUST return an error. +''' + diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/snapshot.txt b/aws-esdk-cpp/aws-esdk-cpp/.duvet/snapshot.txt new file mode 100644 index 000000000..b26c8fad4 --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/.duvet/snapshot.txt @@ -0,0 +1,224 @@ +SPECIFICATION: [ESDK Shim Specification](spec/shim/esdk-shim.md) + SECTION: [Overview](#overview) + TEXT[!MUST,implication]: An ESDK shim MUST conform to the generic [Shim Specification](./shim.md). + + SECTION: [Algorithm suite identifier](#algorithm-suite-identifier) + TEXT[!MUST,implementation,test]: - The shim MUST translate a target algorithm suite identifier to the core ESDK + TEXT[!MUST,implementation,test]: algorithm suite that has the same two-byte ID. + TEXT[!MUST,implementation,test]: - The shim MUST return an error when the target value is not one of the algorithm + TEXT[!MUST,implementation,test]: suite IDs defined by the core ESDK. + TEXT[!MUST,implementation,test]: - The shim MUST translate a core ESDK algorithm suite to the target algorithm + TEXT[!MUST,implementation,test]: suite identifier that has the same two-byte ID. + TEXT[!MUST,implication]: - The shim MUST return an error when the core ESDK produces an algorithm suite + TEXT[!MUST,implication]: the shim does not define. + + SECTION: [Commitment policy](#commitment-policy) + TEXT[!MUST,implementation,test]: - The shim MUST translate the target commitment policy to the core ESDK + TEXT[!MUST,implementation,test]: commitment policy of the same meaning. + TEXT[!MUST,implementation,test]: - The shim MUST return an error when the target commitment policy is not a supported + TEXT[!MUST,implementation,test]: value. + + SECTION: [Encryption context](#encryption-context) + TEXT[!MUST,implementation,test]: - The shim MUST translate the target's encryption context, given as a list of + TEXT[!MUST,implementation,test]: key-value pairs, to the core ESDK's key-value map, preserving every pair and + TEXT[!MUST,implementation,test]: the exact key and value of each. + TEXT[!MUST,implementation,test]: - The shim MUST translate the core ESDK's encryption context, given as a + TEXT[!MUST,implementation,test]: key-value map, to the target's list of key-value pairs, preserving every pair + TEXT[!MUST,implementation,test]: and the exact key and value of each. + + SECTION: [Maximum encrypted data keys](#maximum-encrypted-data-keys) + TEXT[!MUST,implementation,test]: The shim MUST translate zero + TEXT[!MUST,implementation,test]: to the core ESDK's "no limit" representation, and a positive value `n` to a + TEXT[!MUST,implementation,test]: limit of `n`. + + SECTION: [Frame length](#frame-length) + TEXT[!MUST,implementation,test]: - The shim MUST translate the target frame length using the core ESDK's frame + TEXT[!MUST,implementation,test]: length constructor, and MUST return an error when the core ESDK rejects the + TEXT[!MUST,implementation,test]: value. + + SECTION: [KMS configuration](#kms-configuration) + TEXT[!MUST,implementation,test]: - The shim MUST translate a KMS key ARN configuration. + TEXT[!MUST,implementation,test]: - The shim MUST translate a KMS multi-Region-key ARN configuration. + TEXT[!MUST,implementation,test]: - The shim MUST translate a discovery configuration. + TEXT[!MUST,implementation,test]: - The shim MUST translate a multi-Region-key discovery configuration. + TEXT[!MUST,implementation,test]: - The shim MUST return an error when the target KMS configuration type is not a + TEXT[!MUST,implementation,test]: supported value. + + SECTION: [Cache configuration](#cache-configuration) + TEXT[!MUST,implementation,test]: - The shim MUST translate a no-cache selection. + TEXT[!MUST,implementation,test]: - The shim MUST translate a multi-threaded cache selection. + TEXT[!MUST,implementation,test]: - The shim MUST return an error when the target cache type is not a supported + TEXT[!MUST,implementation,test]: value. + + SECTION: [Service client configuration](#service-client-configuration) + TEXT[!MUST,implementation,test]: - The shim MUST set a user-agent on each service client of the form + TEXT[!MUST,implementation,test]: `AwsEncryptionSdk-Shim---`, where + TEXT[!MUST,implementation,test]: `` is the target language, `` is the core + TEXT[!MUST,implementation,test]: ESDK's implementation language, and `` is the shim's published version. + TEXT[!MUST,implementation,test]: - The shim MUST preserve any user-agent already present in the loaded + TEXT[!MUST,implementation,test]: configuration, appending its own rather than replacing it. + TEXT[!MUST,implementation,test]: - If the target supplies a retry configuration, the shim MUST apply it to each + TEXT[!MUST,implementation,test]: service client. + TEXT[!MAY,implementation,test]: - If the target does not supply a retry configuration, the shim MAY apply a + TEXT[!MAY,implementation,test]: default retry configuration. + TEXT[!MUST,implementation,test]: - If the target supplies a region, the shim MUST apply it to each service client. + TEXT[!SHOULD,implication]: - The shim SHOULD allow one client configuration to be applied to multiple + TEXT[!SHOULD,implication]: service clients. + + SECTION: [Materials source](#materials-source) + TEXT[!MUST,implication]: - Each of `encrypt` and `decrypt` MUST be supplied with exactly one materials + TEXT[!MUST,implication]: source (see [Resources](#resources)). + TEXT[!MUST,implementation,test]: - The shim MUST return an error, and MUST NOT invoke the core ESDK, when no + TEXT[!MUST,implementation,test]: materials source is supplied. + + SECTION: [Encrypt inputs](#encrypt-inputs) + TEXT[!MUST,implementation,test]: - `encrypt` MUST pass the target-supplied plaintext to the core ESDK unmodified. + TEXT[!MUST,implementation,test]: - `encrypt` MUST provide the target-supplied encryption context to the core ESDK, + TEXT[!MUST,implementation,test]: converted as defined in [Encryption context](#encryption-context). + TEXT[!MUST,implementation,test]: - `encrypt` MUST provide the target-supplied algorithm suite to the core ESDK, + TEXT[!MUST,implementation,test]: converted as defined in [Algorithm suite identifier](#algorithm-suite-identifier). + TEXT[!MUST,implementation]: - `encrypt` MUST provide the target-supplied commitment policy to the core ESDK, + TEXT[!MUST,implementation]: converted as defined in [Commitment policy](#commitment-policy). + TEXT[!MUST,implementation]: - `encrypt` MUST provide the target-supplied frame length to the core ESDK, + TEXT[!MUST,implementation]: converted as defined in [Frame length](#frame-length). + TEXT[!MUST,implementation]: - `encrypt` MUST provide the target-supplied maximum-encrypted-data-keys value to + TEXT[!MUST,implementation]: the core ESDK, converted as defined in + TEXT[!MUST,implementation]: [Maximum encrypted data keys](#maximum-encrypted-data-keys). + + SECTION: [Encrypt outputs](#encrypt-outputs) + TEXT[!MUST,implementation,test]: - `encrypt` MUST return the core ESDK's ciphertext unmodified. + TEXT[!MUST,implementation,test]: - `encrypt` MUST return the used algorithm suite, converted as defined in + TEXT[!MUST,implementation,test]: [Algorithm suite identifier](#algorithm-suite-identifier). + TEXT[!MUST,implementation,test]: - `encrypt` MUST return the result encryption context, converted as defined in + TEXT[!MUST,implementation,test]: [Encryption context](#encryption-context). + + SECTION: [Decrypt inputs](#decrypt-inputs) + TEXT[!MUST,implementation,test]: - `decrypt` MUST pass the target-supplied ciphertext to the core ESDK unmodified. + TEXT[!MUST,implementation,test]: - `decrypt` MUST provide the target-supplied encryption context to the core ESDK, + TEXT[!MUST,implementation,test]: converted as defined in [Encryption context](#encryption-context). + TEXT[!MUST,implementation]: - `decrypt` MUST provide the target-supplied commitment policy to the core ESDK, + TEXT[!MUST,implementation]: converted as defined in [Commitment policy](#commitment-policy). + TEXT[!MUST,implementation]: - `decrypt` MUST provide the target-supplied maximum-encrypted-data-keys value to + TEXT[!MUST,implementation]: the core ESDK, converted as defined in + TEXT[!MUST,implementation]: [Maximum encrypted data keys](#maximum-encrypted-data-keys). + + SECTION: [Decrypt outputs](#decrypt-outputs) + TEXT[!MUST,implementation,test]: - `decrypt` MUST return the core ESDK's plaintext unmodified. + TEXT[!MUST,implementation,test]: - `decrypt` MUST return the used algorithm suite, converted as defined in + TEXT[!MUST,implementation,test]: [Algorithm suite identifier](#algorithm-suite-identifier). + TEXT[!MUST,implementation,test]: - `decrypt` MUST return the result encryption context, converted as defined in + TEXT[!MUST,implementation,test]: [Encryption context](#encryption-context). + + SECTION: [Create KMS client](#create-kms-client) + TEXT[!MUST,implementation,test]: - The shim MUST provide an operation that creates a KMS service client backed by + TEXT[!MUST,implementation,test]: the core ESDK. + TEXT[!MUST,implementation,test]: - Creating a KMS client MUST apply the target-supplied client configuration, as + TEXT[!MUST,implementation,test]: defined in [Service client configuration](#service-client-configuration). + + SECTION: [Create DynamoDB client](#create-dynamodb-client) + TEXT[!MUST,implementation,test]: - The shim MUST provide an operation that creates a DynamoDB service client + TEXT[!MUST,implementation,test]: backed by the core ESDK. + TEXT[!MUST,implementation,test]: - Creating a DynamoDB client MUST apply the target-supplied client configuration, + TEXT[!MUST,implementation,test]: as defined in [Service client configuration](#service-client-configuration). + + SECTION: [Create key store](#create-key-store) + TEXT[!MUST,implementation,test]: - The shim MUST provide an operation that creates a key store backed by the core + TEXT[!MUST,implementation,test]: ESDK. + TEXT[!MUST,implementation,test]: - Creating a key store MUST require a KMS client handle and a DynamoDB client + TEXT[!MUST,implementation,test]: handle, checked as defined in + TEXT[!MUST,implementation,test]: [Shim Specification: Handles and lifetimes](./shim.md#handles-and-lifetimes), + TEXT[!MUST,implementation,test]: and MUST provide both to the core ESDK. + TEXT[!MUST,implementation,test]: - Creating a key store MUST provide the target-supplied table name and logical key + TEXT[!MUST,implementation,test]: store name to the core ESDK. + TEXT[!MUST,implementation,test]: - Creating a key store MUST provide the target-supplied KMS configuration to the + TEXT[!MUST,implementation,test]: core ESDK, converted as defined in [KMS configuration](#kms-configuration). + TEXT[!MUST,implementation,test]: - Creating a key store MUST provide the target-supplied key store id and grant + TEXT[!MUST,implementation,test]: tokens to the core ESDK when present; an unset value is omitted. + + SECTION: [Create hierarchical keyring](#create-hierarchical-keyring) + TEXT[!MUST,implementation,test]: - The shim MUST provide an operation that creates a hierarchical keyring backed + TEXT[!MUST,implementation,test]: by the core ESDK. + TEXT[!MUST,implementation,test]: - Creating a hierarchical keyring MUST require a key store handle, checked as + TEXT[!MUST,implementation,test]: defined in + TEXT[!MUST,implementation,test]: [Shim Specification: Handles and lifetimes](./shim.md#handles-and-lifetimes), + TEXT[!MUST,implementation,test]: and MUST provide it to the core ESDK. + TEXT[!MUST,implementation,test]: - Creating a hierarchical keyring MUST provide the target-supplied branch key id + TEXT[!MUST,implementation,test]: and time-to-live to the core ESDK. + TEXT[!MUST,implementation,test]: - Creating a hierarchical keyring MUST provide the target-supplied cache + TEXT[!MUST,implementation,test]: configuration to the core ESDK, converted as defined in + TEXT[!MUST,implementation,test]: [Cache configuration](#cache-configuration). + TEXT[!MUST,implementation,test]: - Creating a hierarchical keyring MUST provide the target-supplied partition id to + TEXT[!MUST,implementation,test]: the core ESDK when present; an unset value is omitted. + + SECTION: [Conformance and testing](#conformance-and-testing) + TEXT[!MUST,test]: - The ESDK shim MUST be tested for the behavior it owns — translation, handle + TEXT[!MUST,test]: validation, error propagation, and lifetime safety — rather than by re-testing + TEXT[!MUST,test]: the core ESDK's cryptographic behavior. + TEXT[!SHOULD,exception]: - The ESDK shim SHOULD demonstrate message interoperability with other ESDK + TEXT[!SHOULD,exception]: implementations (for example via a shared test-vector suite). + +SPECIFICATION: [Shim Specification](spec/shim/shim.md) + SECTION: [Owned interface](#owned-interface) + TEXT[!MUST,implication]: - The shim MUST define its own error type for its public surface. + TEXT[!MUST,implication]: - For each core-library enumeration it exposes, the shim MUST define its own + TEXT[!MUST,implication]: corresponding enumeration type. + TEXT[!MUST,implication]: - Each public function the shim exposes MUST use only owned-interface types or + TEXT[!MUST,implication]: standard-library types in its signature. + TEXT[!MUST,implication]: - Each owned interface that represents a core-library resource MUST hold the + TEXT[!MUST,implication]: generated handle privately and MUST NOT expose it in its public API. + + SECTION: [Type translation](#type-translation) + TEXT[!MUST,implication]: Every such translation MUST obey the following rules. + TEXT[!MUST,implication,test]: - A translation MUST convert between the target representation and the core + TEXT[!MUST,implication,test]: library representation, preserving meaning in both directions it supports. + TEXT[!MUST,test]: - A translation reports failure by returning an error; it MUST NOT panic, abort, + TEXT[!MUST,test]: or otherwise terminate the target process. + TEXT[!MUST,implication,test]: - When the target supplies a value that has no corresponding core-library + TEXT[!MUST,implication,test]: representation, the translation MUST return an error. + TEXT[!MUST,implication]: - When the core library produces a value the shim does not define, the + TEXT[!MUST,implication]: translation MUST return an error. + + SECTION: [Delegation](#delegation) + TEXT[!MUST,implication,test]: - Each operation the shim exposes MUST produce its result by invoking the + TEXT[!MUST,implication,test]: corresponding core-library operation. + TEXT[!MUST,implication]: - The shim MUST NOT validate operation or resource-creation input values itself; + TEXT[!MUST,implication]: it MUST translate each input and defer its validation to the core library. + TEXT[!MUST,implementation,test]: - When a core-library operation returns an error, the shim MUST return an error to + TEXT[!MUST,implementation,test]: the target and MUST NOT report the operation as successful. + TEXT[!SHOULD,implementation,test]: - An error the shim returns for a failed core-library operation SHOULD include + TEXT[!SHOULD,implementation,test]: context identifying which operation failed. + + SECTION: [Creating and releasing resources](#creating-and-releasing-resources) + TEXT[!MUST,implication]: - For each resource kind, the shim MUST provide a means for the target to create an + TEXT[!MUST,implication]: instance backed by the core library. + TEXT[!MUST,implication]: - The shim MUST release the core-library resource backing an owned interface once + TEXT[!MUST,implication]: the target no longer holds it. + TEXT[!MAY,implication]: The shim MAY release it automatically when the + TEXT[!MAY,implication]: owned interface is destroyed, or through an explicit target operation. + + SECTION: [Handles and lifetimes](#handles-and-lifetimes) + TEXT[!MUST,implementation,test]: - Before dereferencing a target-supplied resource handle, the shim MUST check it + TEXT[!MUST,implementation,test]: and MUST return an error when a required handle is absent. + TEXT[!MUST,test]: - An owned interface that depends on another resource MUST retain ownership of + TEXT[!MUST,test]: that resource for its own lifetime, so that a handle passed across the boundary + TEXT[!MUST,test]: cannot outlive the resource it refers to. + + SECTION: [Concurrency](#concurrency) + TEXT[!SHOULD,exception]: If a core library resource or operation supports concurrent use from multiple threads, + TEXT[!SHOULD,exception]: the shim library SHOULD support it as well. + + SECTION: [Streaming](#streaming) + TEXT[!SHOULD,exception]: If a core library resource or operation supports [streamed](../client-apis/streaming.md) input/outputs, + TEXT[!SHOULD,exception]: the shim library SHOULD support it as well. + + SECTION: [Operation contracts](#operation-contracts) + TEXT[!MUST,implication]: - Except where an input or output is passed through unmodified, each MUST be + TEXT[!MUST,implication]: translated per [Type translation](#type-translation). + TEXT[!MUST,implication]: - Each operation MUST invoke the core library per [Delegation](#delegation). + + SECTION: [Conformance and testing](#conformance-and-testing) + TEXT[!MUST,implication]: - A shim MUST conform to this specification in addition to its core-library-specific + TEXT[!MUST,implication]: shim specification. + TEXT[!SHOULD,test]: - The shim SHOULD be tested for the behavior it owns — translation, handle + TEXT[!SHOULD,test]: validation, error propagation, and lifetime safety — rather than by re-testing + TEXT[!SHOULD,test]: the core library's own behavior. diff --git a/aws-esdk-cpp/aws-esdk-cpp/.gitignore b/aws-esdk-cpp/aws-esdk-cpp/.gitignore new file mode 100644 index 000000000..f3728796b --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/.gitignore @@ -0,0 +1,19 @@ +# Cargo build output +/target/ + +# Compiled demo / test binaries (built via the Makefile) +/main +/main_release +/main_idiomatic +/test_esdk + +# Object files / archives +*.o +*.a + +# Agent tooling scratch / transcripts +.agent-reports/ + +# CMake build output +/build/ +/build-cmake/ diff --git a/aws-esdk-cpp/aws-esdk-cpp/CMakeLists.txt b/aws-esdk-cpp/aws-esdk-cpp/CMakeLists.txt new file mode 100644 index 000000000..4cb273e56 --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/CMakeLists.txt @@ -0,0 +1,63 @@ +# CMake integration for the AWS Encryption SDK C++ bindings (aws-esdk-cpp). +# +# Consumers do: +# add_subdirectory(aws-esdk-cpp) +# target_link_libraries(my_app PRIVATE AWS::esdk) +# #include +# +# This drives `cargo build` to produce the Rust staticlib and the cxx-generated +# C++ sources, then exposes them behind the AWS::esdk target. +cmake_minimum_required(VERSION 3.20) +project(aws_esdk_cpp LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(ESDK_ROOT ${CMAKE_CURRENT_SOURCE_DIR}) +set(ESDK_PROFILE debug) +set(ESDK_TARGET_DIR ${ESDK_ROOT}/target) + +# Build the Rust staticlib + cxx-generated sources before we reference them. +execute_process( + COMMAND cargo build + WORKING_DIRECTORY ${ESDK_ROOT} + RESULT_VARIABLE _esdk_cargo_result +) +if(NOT _esdk_cargo_result EQUAL 0) + message(FATAL_ERROR "cargo build failed (exit ${_esdk_cargo_result})") +endif() + +set(ESDK_STATICLIB ${ESDK_TARGET_DIR}/${ESDK_PROFILE}/libaws_esdk_cpp.a) +set(ESDK_BRIDGE_CC ${ESDK_TARGET_DIR}/cxxbridge/aws-esdk-cpp/src/lib.rs.cc) + +# The cxx runtime archive lives in a hashed build dir; locate it post-build. +file(GLOB_RECURSE _esdk_cxxbridge_rt + ${ESDK_TARGET_DIR}/${ESDK_PROFILE}/build/cxx-*/out/libcxxbridge1.a) +list(GET _esdk_cxxbridge_rt 0 ESDK_CXXBRIDGE_RT) + +# The public target: compiles the generated C++ bridge and links the Rust lib. +add_library(aws_esdk_cpp STATIC ${ESDK_BRIDGE_CC}) +target_include_directories(aws_esdk_cpp PUBLIC + ${ESDK_ROOT}/include + ${ESDK_TARGET_DIR}/cxxbridge +) +target_link_libraries(aws_esdk_cpp PUBLIC + ${ESDK_STATICLIB} + ${ESDK_CXXBRIDGE_RT} + pthread + ${CMAKE_DL_LIBS} +) +if(APPLE) + target_link_libraries(aws_esdk_cpp PUBLIC + "-framework Security" + "-framework CoreFoundation" + "-framework SystemConfiguration" + ) +endif() +add_library(AWS::esdk ALIAS aws_esdk_cpp) + +# Build the integration test only when this is the top-level project. +if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME) + add_executable(esdk_integration_test test_esdk.cpp) + target_link_libraries(esdk_integration_test PRIVATE AWS::esdk) +endif() diff --git a/aws-esdk-cpp/aws-esdk-cpp/Cargo.lock b/aws-esdk-cpp/aws-esdk-cpp/Cargo.lock new file mode 100644 index 000000000..5c037c89e --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/Cargo.lock @@ -0,0 +1,2835 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anstyle" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" + +[[package]] +name = "arc-swap" +version = "1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c049c0be4daef0b145cb3555416b3b8ef5b7888a38aea1a3a155801fe7b0810b" +dependencies = [ + "rustversion", +] + +[[package]] +name = "async-trait" +version = "0.1.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "aws-config" +version = "1.8.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e33f815b73a3899c03b380d543532e5865f230dce9678d108dc10732a8682275" +dependencies = [ + "aws-credential-types", + "aws-runtime", + "aws-sdk-sso", + "aws-sdk-ssooidc", + "aws-sdk-sts", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-schema", + "aws-smithy-types", + "aws-types", + "bytes", + "fastrand", + "hex", + "http 1.4.2", + "sha1", + "time", + "tokio", + "tracing", + "url", + "zeroize", +] + +[[package]] +name = "aws-credential-types" +version = "1.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f20799b373a1be121fe3005fba0c2090af9411573878f224df44b42727fcaf7" +dependencies = [ + "aws-smithy-async", + "aws-smithy-runtime-api", + "aws-smithy-types", + "zeroize", +] + +[[package]] +name = "aws-esdk" +version = "2.0.0" +dependencies = [ + "async-trait", + "aws-lc-rs", + "aws-mpl-native", + "aws-sdk-dynamodb", + "aws-sdk-kms", + "aws-smithy-types", + "tokio", + "zeroize", +] + +[[package]] +name = "aws-esdk-cpp" +version = "0.1.0" +dependencies = [ + "aws-config", + "aws-esdk", + "aws-mpl-native", + "aws-sdk-dynamodb", + "aws-sdk-kms", + "aws-smithy-types", + "cc", + "cxx", + "cxx-build", + "tokio", +] + +[[package]] +name = "aws-lc-rs" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4342d8937fc7e5dd9b1c60292261c0670c882a2cd1719cfc11b1af41731e32ad" +dependencies = [ + "aws-lc-sys 0.42.0", + "untrusted 0.7.1", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.37.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b092fe214090261288111db7a2b2c2118e5a7f30dc2569f1732c4069a6840549" +dependencies = [ + "cc", + "cmake", + "dunce", + "fs_extra", +] + +[[package]] +name = "aws-lc-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d9ceb1da931507a12f4fccea479dccd00da1943e1b4ae72d8e502d707361444" +dependencies = [ + "cc", + "cmake", + "dunce", + "fs_extra", + "pkg-config", +] + +[[package]] +name = "aws-mpl-legacy" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f04a638979445d746294e965c877b36c9eb037ce3291a43fd62b8f4a70f5813" +dependencies = [ + "aws-config", + "aws-lc-rs", + "aws-lc-sys 0.37.1", + "aws-sdk-dynamodb", + "aws-sdk-kms", + "aws-smithy-runtime-api", + "aws-smithy-types", + "chrono", + "cpu-time", + "dafny-runtime", + "dashmap", + "futures", + "pem", + "rand 0.9.4", + "timeout", + "tokio", + "uuid", +] + +[[package]] +name = "aws-mpl-native" +version = "0.2.0" +dependencies = [ + "async-trait", + "aws-mpl-legacy", + "aws-mpl-primitives", + "aws-sdk-dynamodb", + "aws-sdk-kms", + "zeroize", +] + +[[package]] +name = "aws-mpl-primitives" +version = "0.1.0" +dependencies = [ + "aws-lc-rs", +] + +[[package]] +name = "aws-runtime" +version = "1.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c9b9de216a988dd54b754a82a7660cfe14cee4f6782ae4524470972fa0ccb39" +dependencies = [ + "aws-credential-types", + "aws-sigv4", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "bytes-utils", + "fastrand", + "http 1.4.2", + "http-body 1.0.1", + "percent-encoding", + "pin-project-lite", + "tracing", + "uuid", +] + +[[package]] +name = "aws-sdk-dynamodb" +version = "1.116.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c937c55ae3030bec4431c0d9146e33d2b3e5f54bb47ed32597068200c56affc" +dependencies = [ + "arc-swap", + "aws-credential-types", + "aws-runtime", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-observability", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "fastrand", + "http 0.2.12", + "http 1.4.2", + "regex-lite", + "tracing", +] + +[[package]] +name = "aws-sdk-kms" +version = "1.111.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c62d6d9b9c60e08be622a6bfc98e483d75683795caaf9704886970aa07ed8529" +dependencies = [ + "arc-swap", + "aws-credential-types", + "aws-runtime", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-observability", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "fastrand", + "http 0.2.12", + "http 1.4.2", + "regex-lite", + "tracing", +] + +[[package]] +name = "aws-sdk-sso" +version = "1.102.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c82b3ac19f1431854f7ace3a7531674633e286bfdde21976893bfee36fd493b" +dependencies = [ + "arc-swap", + "aws-credential-types", + "aws-runtime", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-observability", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "fastrand", + "http 0.2.12", + "http 1.4.2", + "regex-lite", + "tracing", +] + +[[package]] +name = "aws-sdk-ssooidc" +version = "1.104.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "321000d2b4c5519ee573f73167f612efd7329322d9b26969ad1979f0427f1913" +dependencies = [ + "arc-swap", + "aws-credential-types", + "aws-runtime", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-observability", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "fastrand", + "http 0.2.12", + "http 1.4.2", + "regex-lite", + "tracing", +] + +[[package]] +name = "aws-sdk-sts" +version = "1.107.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d0d328ba962af23ecfa3c9f23b98d3d35e325fa218d7f13d17a6bf522f8a560" +dependencies = [ + "arc-swap", + "aws-credential-types", + "aws-runtime", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-observability", + "aws-smithy-query", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-smithy-xml", + "aws-types", + "fastrand", + "http 0.2.12", + "http 1.4.2", + "regex-lite", + "tracing", +] + +[[package]] +name = "aws-sigv4" +version = "1.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bae38512beae0ffee7010fc24e7a8a123c53efdfef42a61e80fda4882418dc71" +dependencies = [ + "aws-credential-types", + "aws-smithy-http", + "aws-smithy-runtime-api", + "aws-smithy-types", + "bytes", + "form_urlencoded", + "hex", + "hmac", + "http 0.2.12", + "http 1.4.2", + "percent-encoding", + "sha2", + "time", + "tracing", +] + +[[package]] +name = "aws-smithy-async" +version = "1.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ffcaf626bdda484571968400c326a244598634dc75fd451325a54ad1a59acfc" +dependencies = [ + "futures-util", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "aws-smithy-http" +version = "0.63.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba1ab2dc1c2c3749ead27180d333c42f11be8b0e934058fb4b2258ee8dbe5231" +dependencies = [ + "aws-smithy-runtime-api", + "aws-smithy-types", + "bytes", + "bytes-utils", + "futures-core", + "futures-util", + "http 1.4.2", + "http-body 1.0.1", + "http-body-util", + "percent-encoding", + "pin-project-lite", + "pin-utils", + "tracing", +] + +[[package]] +name = "aws-smithy-http-client" +version = "1.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c3ef8931ad1c98aa6a55b4256f847f3116090819844e0dd41ea682cac5dd2d3" +dependencies = [ + "aws-smithy-async", + "aws-smithy-runtime-api", + "aws-smithy-types", + "h2 0.3.27", + "h2 0.4.15", + "http 0.2.12", + "http 1.4.2", + "http-body 0.4.6", + "hyper 0.14.32", + "hyper 1.10.1", + "hyper-rustls 0.24.2", + "hyper-rustls 0.27.9", + "hyper-util", + "pin-project-lite", + "rustls 0.21.12", + "rustls 0.23.41", + "rustls-native-certs", + "rustls-pki-types", + "tokio", + "tokio-rustls 0.26.4", + "tower", + "tracing", +] + +[[package]] +name = "aws-smithy-json" +version = "0.62.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "701a947f4797e52a911e114a898667c746c39feea467bbd1abd7b3721f702ffa" +dependencies = [ + "aws-smithy-runtime-api", + "aws-smithy-schema", + "aws-smithy-types", +] + +[[package]] +name = "aws-smithy-observability" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06c2315d173edbf1920da8ba3a7189695827002e4c0fc961973ab1c54abca9c" +dependencies = [ + "aws-smithy-runtime-api", +] + +[[package]] +name = "aws-smithy-query" +version = "0.60.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a56d79744fb3edb5d722ef79d86081e121d3b9422cb209eb03aea6aa4f21ebd" +dependencies = [ + "aws-smithy-types", + "urlencoding", +] + +[[package]] +name = "aws-smithy-runtime" +version = "1.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e6f5caf6fea86f8c2206541ab5857cfcda9013426cdbe8fa0098b9e2d32182" +dependencies = [ + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-http-client", + "aws-smithy-observability", + "aws-smithy-runtime-api", + "aws-smithy-schema", + "aws-smithy-types", + "bytes", + "fastrand", + "http 0.2.12", + "http 1.4.2", + "http-body 0.4.6", + "http-body 1.0.1", + "http-body-util", + "pin-project-lite", + "pin-utils", + "tokio", + "tracing", +] + +[[package]] +name = "aws-smithy-runtime-api" +version = "1.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9db177daa6ba8afb9ee1aefcf548c907abcf52065e394ee11a92780057fe0e8c" +dependencies = [ + "aws-smithy-async", + "aws-smithy-runtime-api-macros", + "aws-smithy-types", + "bytes", + "http 0.2.12", + "http 1.4.2", + "pin-project-lite", + "tokio", + "tracing", + "zeroize", +] + +[[package]] +name = "aws-smithy-runtime-api-macros" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d7396fd9500589e62e460e987ecb671bad374934e55ec3b5f498cc7a8a8a7b7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "aws-smithy-schema" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7442cb268338f0eb8278140a107c046756aa01093d8ef5e99628d34ae09c94f5" +dependencies = [ + "aws-smithy-runtime-api", + "aws-smithy-types", + "http 1.4.2", +] + +[[package]] +name = "aws-smithy-types" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b42fcf341259d85ca10fac9a2f6448a8ec691c6955a18e45bc3b71a85fab85" +dependencies = [ + "base64-simd", + "bytes", + "bytes-utils", + "futures-core", + "http 0.2.12", + "http 1.4.2", + "http-body 0.4.6", + "http-body 1.0.1", + "http-body-util", + "itoa", + "num-integer", + "pin-project-lite", + "pin-utils", + "ryu", + "serde", + "time", + "tokio", + "tokio-util", +] + +[[package]] +name = "aws-smithy-xml" +version = "0.60.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce02add1aa3677d022f8adf81dcbe3046a95f17a1b1e8979c145cd21d3d22b3" +dependencies = [ + "xmlparser", +] + +[[package]] +name = "aws-types" +version = "1.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d16bf10b03a3c01e6b3b7d47cd964e873ffe9e7d4e80fad16bd4c077cb068531" +dependencies = [ + "aws-credential-types", + "aws-smithy-async", + "aws-smithy-runtime-api", + "aws-smithy-schema", + "aws-smithy-types", + "rustc_version", + "tracing", +] + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "base64-simd" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "339abbe78e73178762e23bea9dfd08e697eb3f3301cd4be981c0f78ba5859195" +dependencies = [ + "outref", + "vsimd", +] + +[[package]] +name = "bitflags" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" +dependencies = [ + "hybrid-array", +] + +[[package]] +name = "bumpalo" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "bytes" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae3f5d315924270530207e2a68396c3cc547f6dca3fbdca317cfb1a51edb593" + +[[package]] +name = "bytes-utils" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dafe3a8757b027e2be6e4e5601ed563c55989fcf1546e933c66c8eb3a058d35" +dependencies = [ + "bytes", + "either", +] + +[[package]] +name = "cc" +version = "1.2.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5d6cac793997bd970000024b2934968efe83b382de4fdcf4fcb46b6ee4ad996" +dependencies = [ + "find-msvc-tools", + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "chrono" +version = "0.4.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" +dependencies = [ + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-link", +] + +[[package]] +name = "clap" +version = "4.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51" +dependencies = [ + "clap_builder", +] + +[[package]] +name = "clap_builder" +version = "4.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" +dependencies = [ + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_lex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" + +[[package]] +name = "cmake" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" +dependencies = [ + "cc", +] + +[[package]] +name = "cmov" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c9ea0ac24bc397ab3c98583a3c9ba74fa56b09a4449bbe172b9b1ddb016027a" + +[[package]] +name = "codespan-reporting" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af491d569909a7e4dee0ad7db7f5341fef5c614d5b8ec8cf765732aba3cff681" +dependencies = [ + "serde", + "termcolor", + "unicode-width", +] + +[[package]] +name = "const-oid" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" + +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "cpu-time" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9e393a7668fe1fad3075085b86c781883000b4ede868f43627b34a87c8b7ded" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "cpufeatures" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +dependencies = [ + "libc", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17" + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "crypto-common" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" +dependencies = [ + "hybrid-array", +] + +[[package]] +name = "ctutils" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e" +dependencies = [ + "cmov", +] + +[[package]] +name = "cxx" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00424da159cc5adcb4eeea7e7b5cb1d96df41f5fa695ec596922181bdc36232a" +dependencies = [ + "cc", + "cxx-build", + "cxxbridge-cmd", + "cxxbridge-flags", + "cxxbridge-macro", + "foldhash", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43e05269dbed4dab7072ae0f04ef31799ad189d52ce2ac12710c2997b754f86a" +dependencies = [ + "cc", + "codespan-reporting", + "indexmap", + "proc-macro2", + "quote", + "scratch", + "syn", +] + +[[package]] +name = "cxxbridge-cmd" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2f017b07e0da7f425642339faff0edc9f0de6459a18180183d086d1f3381e89" +dependencies = [ + "clap", + "codespan-reporting", + "indexmap", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "293d267f43a5778bf3b89fff2a658f081166e7f152d9640e2ee3d917d065a5fc" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72dd233dc128223fe85d2afa5c617c79743c0f47fb495b69234b5da680d4986a" +dependencies = [ + "indexmap", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "dafny-runtime" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00ff59e5bdeafe83af48ddf5c7cb8ff233253aea4161f650e91c3bb0277c8a47" +dependencies = [ + "itertools", + "num", + "once_cell", +] + +[[package]] +name = "dashmap" +version = "6.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6361d5c062261c78a176addb82d4c821ae42bed6089de0e12603cd25de2059c" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "deranged" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "crypto-common 0.1.7", +] + +[[package]] +name = "digest" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" +dependencies = [ + "block-buffer 0.12.1", + "const-oid", + "crypto-common 0.2.2", + "ctutils", +] + +[[package]] +name = "displaydoc" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + +[[package]] +name = "either" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "fastrand" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" + +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + +[[package]] +name = "futures" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" + +[[package]] +name = "futures-executor" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" + +[[package]] +name = "futures-macro" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" + +[[package]] +name = "futures-task" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" + +[[package]] +name = "futures-util" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi 5.3.0", + "wasip2", +] + +[[package]] +name = "getrandom" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" +dependencies = [ + "cfg-if", + "libc", + "r-efi 6.0.0", +] + +[[package]] +name = "h2" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0beca50380b1fc32983fc1cb4587bfa4bb9e78fc259aad4a0032d2080309222d" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.12", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "h2" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cb093c84e8bd9b188d4c4a8cb6579fc016968d14c99882163cd3ff402a4f155" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http 1.4.2", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" +dependencies = [ + "digest 0.11.3", +] + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425" +dependencies = [ + "bytes", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http 0.2.12", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http 1.4.2", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http 1.4.2", + "http-body 1.0.1", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hybrid-array" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "818356c5132c1fede50f837ca96afbe78ff42413047f4abb886217845e1b6c8c" +dependencies = [ + "typenum", +] + +[[package]] +name = "hyper" +version = "0.14.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2 0.3.27", + "http 0.2.12", + "http-body 0.4.6", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.5.10", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "h2 0.4.15", + "http 1.4.2", + "http-body 1.0.1", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http 0.2.12", + "hyper 0.14.32", + "log", + "rustls 0.21.12", + "tokio", + "tokio-rustls 0.24.1", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" +dependencies = [ + "http 1.4.2", + "hyper 1.10.1", + "hyper-util", + "rustls 0.23.41", + "rustls-native-certs", + "tokio", + "tokio-rustls 0.26.4", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +dependencies = [ + "base64", + "bytes", + "futures-channel", + "futures-util", + "http 1.4.2", + "http-body 1.0.1", + "hyper 1.10.1", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2 0.6.4", + "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "icu_collections" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" +dependencies = [ + "displaydoc", + "potential_utf", + "utf8_iter", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" + +[[package]] +name = "icu_properties" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" +dependencies = [ + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" + +[[package]] +name = "icu_provider" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "indexmap" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +dependencies = [ + "equivalent", + "hashbrown 0.17.1", +] + +[[package]] +name = "ipnet" +version = "2.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" + +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "jobserver" +version = "0.1.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" +dependencies = [ + "getrandom 0.4.3", + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" +dependencies = [ + "cfg-if", + "futures-util", + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.186" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" + +[[package]] +name = "link-cplusplus" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f78c730aaa7d0b9336a299029ea49f9ee53b0ed06e9202e8cb7db9bae7b8c82" +dependencies = [ + "cc", +] + +[[package]] +name = "litemap" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" + +[[package]] +name = "memchr" +version = "2.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4" + +[[package]] +name = "mio" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.61.2", +] + +[[package]] +name = "num" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-conv" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c92800bd69a1eac91786bcfe9da64a897eb72911b8dc3095decbd07429e8048b" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "openssl-probe" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" + +[[package]] +name = "outref" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e" + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link", +] + +[[package]] +name = "pem" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be" +dependencies = [ + "base64", + "serde_core", +] + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" + +[[package]] +name = "potential_utf" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" +dependencies = [ + "zerovec", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + +[[package]] +name = "rand" +version = "0.3.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" +dependencies = [ + "libc", + "rand 0.4.6", +] + +[[package]] +name = "rand" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" +dependencies = [ + "fuchsia-cprng", + "libc", + "rand_core 0.3.1", + "rdrand", + "winapi", +] + +[[package]] +name = "rand" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" +dependencies = [ + "rand_chacha", + "rand_core 0.9.5", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.5", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", +] + +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", +] + +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex-lite" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab834c73d247e67f4fae452806d17d3c7501756d98c8808d7c9c7aa7d18f973" + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.17", + "libc", + "untrusted 0.9.0", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustls" +version = "0.21.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" +dependencies = [ + "log", + "ring", + "rustls-webpki 0.101.7", + "sct", +] + +[[package]] +name = "rustls" +version = "0.23.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b92b125634d9b795e7beca796cc790df15a7fb38323bf3196fda83292d06b1f" +dependencies = [ + "aws-lc-rs", + "once_cell", + "rustls-pki-types", + "rustls-webpki 0.103.13", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-native-certs" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dab5152771c58876a2146916e53e35057e1a4dfa2b9df0f0305b07f611fdea4d" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pki-types" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "764899a24af3980067ee14bc143654f297b22eaebfe3c7b6b211920a5a59b046" +dependencies = [ + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted 0.9.0", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" +dependencies = [ + "aws-lc-rs", + "ring", + "rustls-pki-types", + "untrusted 0.9.0", +] + +[[package]] +name = "rustversion" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" + +[[package]] +name = "ryu" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" + +[[package]] +name = "schannel" +version = "0.1.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "scratch" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d68f2ec51b097e4c1a75b681a8bec621909b5e91f15bb7b840c4f2f7b01148b2" + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted 0.9.0", +] + +[[package]] +name = "security-framework" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures 0.2.17", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "digest 0.11.3", +] + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + +[[package]] +name = "signal-hook-registry" +version = "1.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +dependencies = [ + "errno", + "libc", +] + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" + +[[package]] +name = "socket2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "socket2" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "2.0.118" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "time" +version = "0.3.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18dfaaeddcb932337b5e7866ee7d0ce9b76d2fd092997146f187ec09b4558a50" +dependencies = [ + "deranged", + "num-conv", + "powerfmt", + "serde_core", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" + +[[package]] +name = "time-macros" +version = "0.2.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c431b87111666e491a90baa837f914fb45cd5dc3c268591b0220ff5057f2085f" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "timeout" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "415e3859aca2dba2e8c60fd326c9f23596e980796974322ff391dad9d71a946f" +dependencies = [ + "rand 0.3.23", +] + +[[package]] +name = "tinystr" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tokio" +version = "1.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" +dependencies = [ + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2 0.6.4", + "tokio-macros", + "windows-sys 0.61.2", +] + +[[package]] +name = "tokio-macros" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls 0.21.12", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +dependencies = [ + "rustls 0.23.41", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "typenum" +version = "1.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "unicode-width" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "uuid" +version = "1.23.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf80a72845275afea99e7f2b434723d3bc7e38470fcd1c7ed39a599c73319a53" +dependencies = [ + "getrandom 0.4.3", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "vsimd" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasip2" +version = "1.0.4+wasi-0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + +[[package]] +name = "writeable" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" + +[[package]] +name = "xmlparser" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4" + +[[package]] +name = "yoke" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.8.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75726053136156d419e285b9b7eddaaea9e3fea6ce32eed44a89901f0bd98de1" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4714fd92cf900833d49538023a9b3915155210801d1c1169eba513b2addefd71" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zerofrom" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" + +[[package]] +name = "zerotrie" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/aws-esdk-cpp/aws-esdk-cpp/Cargo.toml b/aws-esdk-cpp/aws-esdk-cpp/Cargo.toml new file mode 100644 index 000000000..d17fe7bf2 --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name = "aws-esdk-cpp" +version = "0.1.0" +edition = "2024" +keywords = ["crypto", "cryptography", "security", "encryption", "c++"] +categories = ["cryptography", "external-ffi-bindings"] +license = "ISC AND (Apache-2.0 OR ISC)" +description = "C++ shim exposing the Rust implementation of the AWS Encryption SDK to C++ callers." +repository = "https://github.com/aws/aws-encryption-sdk" +authors = ["AWS-CryptoTools"] +documentation = "https://docs.rs/crate/aws-esdk-cpp" +readme = "README.md" + +[lib] +crate-type = ["staticlib", "cdylib"] + +[dependencies] +aws-config = "1.8.12" +aws-mpl-legacy = { package = "aws-mpl-native", path = "../../mpl" } +aws-sdk-dynamodb = "1.103.0" +aws-sdk-kms = "1.98.0" +aws-smithy-types = "1.3.6" +cxx = "1.0.194" +tokio = {version = "1.49.0", features = ["full"] } +aws-esdk = { path = "../../esdk" } + +[build-dependencies] +cxx-build = "1.0.194" +cc = "1.2.54" + +# This nested package is not part of the root workspace (the root member is the +# sibling stub crate). Declare it as its own workspace root so `cargo` builds it +# standalone; `mpl`/`esdk` are consumed as path dependencies above. +[workspace] diff --git a/aws-esdk-cpp/aws-esdk-cpp/Makefile b/aws-esdk-cpp/aws-esdk-cpp/Makefile new file mode 100644 index 000000000..154491d1b --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/Makefile @@ -0,0 +1,53 @@ +# Simple Makefile - all C++ bridge code is now compiled into the Rust static library + +main: main.cpp src/lib.rs target/debug/libaws_esdk_cpp.a + g++ main.cpp target/cxxbridge/aws-esdk-cpp/src/lib.rs.cc \ + $$(find target/debug/build -path "*/cxx-*/out/libcxxbridge1.a" | head -n1) \ + -Ltarget/debug -laws_esdk_cpp \ + -Itarget/cxxbridge \ + -lpthread -ldl \ + -std=c++11 \ + -o main + + +main_release: main.cpp src/lib.rs target/release/libaws_esdk_cpp.a + g++ main.cpp target/cxxbridge/aws-esdk-cpp/src/lib.rs.cc \ + $$(find target/release/build -path "*/cxx-*/out/libcxxbridge1.a" | head -n1) \ + -Ltarget/release -laws_esdk_cpp \ + -Itarget/cxxbridge \ + -lpthread -ldl \ + -std=c++11 \ + -o main_release + +clean: + rm -f main + +.PHONY: all clean duvet test clippy + +# Idiomatic-facade integration tests. Requires C++17 (aws_esdk.hpp uses +# std::string_view). Run ./test_esdk with ESDK_TEST_* env vars set (it skips +# cleanly if they are unset). +test_esdk: test_esdk.cpp include/aws/esdk/EncryptionSDK.h src/lib.rs target/debug/libaws_esdk_cpp.a + g++ test_esdk.cpp target/cxxbridge/aws-esdk-cpp/src/lib.rs.cc \ + $$(find target/debug/build -path "*/cxx-*/out/libcxxbridge1.a" | head -n1) \ + -Ltarget/debug -laws_esdk_cpp \ + -Itarget/cxxbridge -Iinclude \ + -lpthread -ldl \ + -std=c++17 \ + -o test_esdk + +clippy: + cargo clippy --tests --examples + +test: + cargo build + cargo build --release + make + ./main + make main_release + ./main_release + +duvet: + @test -e spec || ln -s ../../spec spec + rm -rf .duvet/reports .duvet/requirements + duvet report diff --git a/aws-esdk-cpp/aws-esdk-cpp/README.md b/aws-esdk-cpp/aws-esdk-cpp/README.md new file mode 100644 index 000000000..6bf96e504 --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/README.md @@ -0,0 +1,19 @@ +# aws-esdk-cpp + +A C++ shim over the Rust implementation of the AWS Encryption SDK. + +This crate exposes the Rust AWS Encryption SDK (`aws-esdk`) to C++ callers through +an idiomatic, generator-agnostic C++ API. Consumers program against +`Aws::Esdk::` types and `#include `; the underlying +Rust bindings (generated with `cxx`) are an implementation detail hidden behind +the facade. + +The shim's own behavioral contract — type translation, resource lifetimes, error +propagation, delegation to the core library — is specified in +[`spec/shim/shim.md`](spec/shim/shim.md) (generic) and +[`spec/shim/esdk-shim.md`](spec/shim/esdk-shim.md) (ESDK-specific), and tracked +with Duvet annotations in the source. + +## Status + +Work in progress. diff --git a/aws-esdk-cpp/aws-esdk-cpp/build.rs b/aws-esdk-cpp/aws-esdk-cpp/build.rs new file mode 100644 index 000000000..7f170b316 --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/build.rs @@ -0,0 +1,11 @@ +fn main() { + // Generate the cxx bridge code and compile it + cxx_build::bridge("src/lib.rs") + .flag_if_supported("-std=c++11") + .compile("cxxbridge-aws-mpl-cxx"); + + // Tell cargo to link the C++ standard library + println!("cargo:rustc-link-lib=c++"); + + println!("cargo:rerun-if-changed=src/lib.rs"); +} diff --git a/aws-esdk-cpp/aws-esdk-cpp/doc_plan.md b/aws-esdk-cpp/aws-esdk-cpp/doc_plan.md new file mode 100644 index 000000000..305f63ca7 --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/doc_plan.md @@ -0,0 +1,88 @@ +Redshift wants a performant C++ ESDK with hierarchical keyring support. At a high level we’ll deliver this by shipping a natively-written Rust ESDK and exposing it to C++ via bindings. This doc defines the scope of those deliverables. +Q1: What will we deliver for Redshift? +Andy previously decided this and we won’t backtrack since Option 1 is mostly implemented, but it’s worth stating the options again to understand how we got here. +1. C++ bindings to a native Rust ESDK that uses the Dafny-Rust MPL +Recommended and explored in this doc. +2. Option 1 but with a new Native Rust MPL +Not worth the effort. Most of the performance benefit from moving to native comes from eliminating conversions to/from Dafny shapes for large objects. The MPL handles orders of magnitude fewer bytes than the ESDK in typical operation, so moving it to native is less impactful. +3. Option 1 but with the existing Dafny Rust ESDK +Not performant. Early performance tests of a native Rust ESDK with the Dafny Rust MPL show: +• >4x speedup in wall-clock time for single-threaded encrypt/decrypt +o 50 MB payload, time dropped from 37 ms to 9 ms +• Memory overhead reduced from O(n) to O(1) relative to input size +o 50 MB payload, additional memory overhead dropped from 48 MB to 0.02 MB (not re-creating the entire input/output buffer as Dafny types) +4. Native C++ hierarchy keyring +We want to minimize the amount of C/C++ business logic we own moving forward; this would not help. +Q2: What is the long-term goal? +What did Andy leave behind +Andy left behind some partial Rust crates. For a full writeup, see the Appendix. Two relevant crates for this project are a native ESDK Rust crate and a C++ bindings crate. +More detail: +Native Rust ESDK +Implementation: Encrypt/decrypt are working and pass some interop testing. +Duvet: About 18% annotated, but all are implications (i.e. untested). +MPL: Uses a combination of the existing Dafny-Rust MPL and the native Rust MPL. (Native Rust MPL is only for type definitions – all methods are stubbed). We would refactor this to only use the Dafny-Rust MPL. +Tests: Implements most ESDK Dafny integ tests, passes some test vectors. +C++ Bindings +Implementation: Some Rust code re-defines shapes (ex. EncryptInput, AlgorithmSuiteId) and methods (ex. create_hierarchical_keyring(), encrypt()) that are exported to C++. The shapes exported to C++ are different than the Rust shapes; the exposed methods are responsible for converting from C++ shapes to Rust shapes and calling the Rust methods. A crate called `cxx-build` compiles this to C++ bindings. +Tests: None +Deliverables +We will deliver only the functionality required by Redshift. This means +1. An internal-Amazon native Rust ESDK that only supports hierarchy keyrings, and +2. C++ bindings for this native Rust ESDK. +This means not immediately delivering more fully-featured options: +• Support all MPL keyrings +o Redshift only needs HKeyring support. We can add others later. +• Release native Rust ESDK publicly +o Launching an “HKeyring-only” ESDK conflicts with the keyring support for the current public library. We should support all MPL keyrings before releasing this publicly, and we don’t need to do that now to deliver for Redshift. +o Probably dependent on post-Dafny strategy +o Public release requires docs, examples +Once we have demand for more keyrings or want to launch the native Rust ESDK publicly, we would start from this internal build. +Spec Compliance +The native Rust ESDK/C++ bindings will fully implement Duvet coverage for the ESDK spec, meaning files in either the data-format and client-apis folders. They do not need to implement coverage for any files for the MPL spec (the framework folder) since they are re-using the Dafny-Rust MPL components. +Duvet’ing the Rust code is straightforward, but I’ll need to figure out what Duvet’ing C++ bindings looks like in practice (out of scope for this doc). +As an aside, no ESDK implementation is actively Duvet’ed today; see the appendix. I won’t Duvet these other implementations for reasons described in the appendix. Not Duvet’ing other implementations increases the risk of implementation inconsistencies, but I suggest we accept this risk and mitigate it with testing. +Testing +Defining the testing bar for a native library isn’t straightforward because we don’t have a testing spec/test plan for the ESDK to follow. I’m not planning to create a testing spec for the ESDK for the same reasons as I’m not planning to Duvet existing ESDK implementations. +I’ll suggest bounding testing to the following: +• Unit tests +o Rust: ESDK implementation +o C++: Shim logic +• Integ tests +o Rust: Re-implement all Dafny ESDK integ tests (luckily, there aren’t a ton) scoped down/modified to test with HKeyring + These are all of the non-proof tests in the Dafny ESDK. By implementing this, the Rust ESDK would have “at least as many” integ tests as the Dafny ESDK, which sounds like a nice bar +o C++: Minimal happy-path smoke testing. ex. No need to re-implement all of the required EC CMM test cases +• ESDK encrypt/decrypt interop tests for HKeyring +o Both Rust and C++ (to test shim layer correctness) +o This should test the real HKeyring, not the fake HKeyring that the Dafny test vectors test +• Performance tests +o Ideally both Rust and C++ (to test shim layer overhead) +Development +Rust: Develop in a private Github repo (create a aws/aws-encryption-sdk-rust private repo). +• Testing is much easier if it’s in Github and not Brazil +• Why call it `aws/aws-encryption-sdk-rust`? I expect this project will evolve into the native ESDK rust we launch publicly. There’s a reasonable chance that product will live in the aws/aws-encryption-sdk-rust repo +o Even if the Native Builds work suggests putting this in a `aws/aws-encryption-sdk-rust`isn’t our repo organization approach moving forward, this aligns with our organization strategy today. We can migrate this repo along with our other repos once our organization strategy is defined. +• Can be imported into Brazil via a package we maintain + PRs to that package +C++: Develop in a private Github repo (create a aws/aws-encryption-sdk-cpp private repo) +• Why separate repo from ESDK Rust? It’s a different UX/language for customers, which seems like the right boundary for creating a new repo/product +• Can be imported into Brazil via a package we maintain + PRs to that package?? +• Tony wants them to own this +Alternatives: +• Develop in Brazil – testing is more complicated, harder to make public eventually +• Develop in some alternative repo – not sure which one, open to suggestions +Appendix +The spec compliance story for other languages is complicated. An ESDK spec exists, but no ESDK implementation is validated against the spec with Duvet today: +• Dafny: Some comments exist but Duvet does not run. All comments are in an old format and must be updated before Duvet can run. +• Java: No comments. +• Python: No comments. +• C: Some comments exist but Duvet does not run. All comments are in an old format and must be updated before Duvet can run. +• JavaScript: Comments for HKeyring implementation exist but Duvet does not run. +I’m not planning to Duvet any existing ESDK implementations. Achieving real spec alignment goes beyond simply adding annotations and enabling Duvet. It requires validating that code precisely implements the specification. Prior rushed batch spec updates led to missed nuances around UTF encoding (COE). Even if this alignment process were done carefully, it would probably find implementation inconsistencies that would need to be considered and addressed, delaying timelines (remembering FireEgg). Fully reconciling the spec and existing behavior is out of scope due to high cost and low near-term ROI. This requires a separate effort. + +Appendix +Andy left behind a lot of partial Rust crates: +• prim/ (aws-mpl-primitives) — Native Rust wrappers around aws-lc-rs. Covers AES-GCM encrypt/decrypt, HKDF (full, extract, expand), ECDSA sign/verify (including streaming DigestContext), ECDH, AES-KDF-CTR, HMAC, Digest, random bytes, constant-time compare, and a memory tracker. This maps to the full AwsCryptographyPrimitives Smithy model — all operations from the Smithy specs (aes, hkdf, signature, digest, random, ecdh) are covered. Nothing obviously missing. +• mpl/ (aws-mpl-rs) — Types and interfaces complete, implementations stubbed. All the core types are defined: EncryptionMaterials, DecryptionMaterials, EncryptedDataKey, Secret, AlgorithmSuite (all 11 ESDK + 2 DBE suites), CommitmentPolicy, EncryptionContext, Keyring and CryptographicMaterialsManager. Input/output structs for every keyring constructor exist (KMS strict, MRK, discovery, hierarchical, RSA, ECDH, raw AES, raw RSA, raw ECDH, multi-keyring). But every single function and method returns not_implemented(). So: the API surface is fully designed, but there's zero working keyring or CMM logic. You can't actually create any keyring from this crate. +• esdk/ (aws-esdk) – full encrypt/decrypt, including streaming support. +• aws-esdk-cpp/ — single lib.rs file exposing encrypt/decrypt, hierarchical keyring creation, keystore, KMS/DDB client lifecycle to C++ via the cxx crate. This can be used today to create and use a hierarchy keyring in C++. +• aws_structured_encryption/ — Partial rewrite, early stage. 9 source files covering encrypt/decrypt for structured data, canonization, header/footer serialization, crypto operations, path handling. Depends on the native MPL for types and the native Primitives for crypto. Compared to the full Dafny StructuredEncryption module, this has the core encrypt/decrypt path and the canonization logic, but it's missing the broader DB-ESDK integration (DynamoDB item encryptor, searchable encryption, beacons). It's the structured encryption core without the full DB-ESDK wrapper. + diff --git a/aws-esdk-cpp/aws-esdk-cpp/include/aws/esdk/EncryptionSDK.h b/aws-esdk-cpp/aws-esdk-cpp/include/aws/esdk/EncryptionSDK.h new file mode 100644 index 000000000..25f60ffb1 --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/include/aws/esdk/EncryptionSDK.h @@ -0,0 +1,264 @@ +// aws_esdk.hpp — idiomatic C++ facade over the cxx-generated bindings. +// +// Design goals (learnings from the binding-strategy review): +// * Stable, GENERATOR-AGNOSTIC public API: no cxx type (rust::*, the generated +// enums/structs) appears in any public signature. Swapping the binding +// backend later touches only this file's internals, not consumer code. +// * RAII + exceptions: cxx throws rust::Error on failure; we translate that +// into Aws::Esdk::EsdkException so callers never see a cxx type. +// * Memory safety at the handle seam: the bridge passes handles as raw +// `*const` pointers inside config structs, which can dangle if a C++ caller +// drops a client before it is used. Each wrapper here OWNS its dependencies +// via shared_ptr and declares them before the object that points at them, +// so a dependency can never be destroyed while something references it. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "rust/cxx.h" // rust::Error, rust::Box, rust::Vec, rust::Slice +#include "aws-esdk-cpp/src/lib.rs.h" // cxx-generated bindings (global namespace) + +namespace Aws { +namespace Esdk { + +// ---- File-wide owned-interface / lifetime invariants (see spec/shim/shim.md) - +//= spec/shim/shim.md#owned-interface +//= type=implication +//= reason=The facade defines its own Aws::Esdk:: enum for every core-library enumeration it exposes (AlgorithmSuiteId, CommitmentPolicy, CacheKind). +//# - For each core-library enumeration it exposes, the shim MUST define its own +//# corresponding enumeration type. +// +//= spec/shim/shim.md#owned-interface +//= type=implication +//= reason=Every public method signature uses only Aws::Esdk:: types and standard-library types; no generated or core-library type appears. +//# - Each public function the shim exposes MUST use only owned-interface types or +//# standard-library types in its signature. +// +//= spec/shim/shim.md#owned-interface +//= type=implication +//= reason=Every wrapper stores its generated handle in a private member and exposes it only through the internal ffi() accessor. +//# - Each owned interface that represents a core-library resource MUST hold the +//# generated handle privately and MUST NOT expose it in its public API. + +// ---- Public exception: hides cxx's rust::Error ------------------------------ +//= spec/shim/shim.md#owned-interface +//= type=implication +//= reason=EsdkException is the shim's own error type; detail::guard translates every cxx rust::Error into it, so no cxx or core-library error type appears on the public surface. +//# - The shim MUST define its own error type for its public surface. +class EsdkException : public std::runtime_error { +public: + explicit EsdkException(const std::string& msg) : std::runtime_error(msg) {} +}; + +// ---- Public enums: our own, so the generated enums never leak ---------------- +enum class AlgorithmSuiteId : std::uint16_t { + AesGcm128 = 0x0014, + AesGcm192 = 0x0046, + AesGcm256 = 0x0078, + AesGcm128Hkdf256 = 0x0114, + AesGcm192Hkdf256 = 0x0146, + AesGcm256Hkdf256 = 0x0178, + AesGcm128Hkdf256Ecdsa256 = 0x0214, + AesGcm192Hkdf384Ecdsa384 = 0x0346, + AesGcm256Hkdf384Ecdsa384 = 0x0378, + AesGcm256Hkdf512Commit = 0x0478, + AesGcm256Hkdf512CommitEcdsa384 = 0x0578, +}; + +enum class CommitmentPolicy : std::uint8_t { + ForbidEncryptAllowDecrypt = 0, + RequireEncryptAllowDecrypt = 1, + RequireEncryptRequireDecrypt = 2, +}; + +enum class CacheKind : std::uint8_t { None = 0, MultiThreaded = 1 }; + +namespace detail { + +// Run a cxx call, translating rust::Error -> EsdkException so no cxx exception +// type escapes this header. +template +inline auto guard(F&& f) -> decltype(f()) { + try { + return f(); + } catch (const ::rust::Error& e) { + throw EsdkException(e.what()); + } +} + +// Enum translation is the only code that knows the generated enum types exist. +// Values are kept identical to the generated enums, so casts are exact. +inline ::EsdkAlgorithmSuiteId to_ffi(AlgorithmSuiteId a) { + return static_cast<::EsdkAlgorithmSuiteId>(static_cast(a)); +} +inline ::EsdkCommitmentPolicy to_ffi(CommitmentPolicy p) { + return static_cast<::EsdkCommitmentPolicy>(static_cast(p)); +} +inline ::CacheType to_ffi(CacheKind c) { + return static_cast<::CacheType>(static_cast(c)); +} + +inline ::rust::Vec<::EncryptionContextItem> to_ec( + const std::map& ec) { + ::rust::Vec<::EncryptionContextItem> out; + for (const auto& kv : ec) { + ::EncryptionContextItem item; + item.key = ::rust::String(kv.first); + item.value = ::rust::String(kv.second); + out.push_back(std::move(item)); + } + return out; +} + +// Reverse translations, for values the core library returns to the target. +inline AlgorithmSuiteId alg_from_ffi(::EsdkAlgorithmSuiteId a) { + return static_cast(static_cast(a)); +} + +inline std::map from_ec( + const ::rust::Vec<::EncryptionContextItem>& ec) { + std::map out; + for (const auto& item : ec) { + out.emplace(std::string(item.key), std::string(item.value)); + } + return out; +} + +} // namespace detail + +// ---- Fluent client config ---------------------------------------------------- +class ClientConfig { + ::MplAwsClientConfig cfg_ = ::default_client_config(); +public: + ClientConfig& with_max_retry_attempts(std::uint32_t n) { cfg_.retry.max_attempts = n; return *this; } + ClientConfig& with_adaptive_retry(bool a) { cfg_.retry.mode_adaptive = a; return *this; } + ClientConfig& with_region(const std::string& r) { cfg_.region = ::rust::String(r); return *this; } + const ::MplAwsClientConfig& raw() const { return cfg_; } // internal; POD-ish, low leak risk +}; + +// ---- Handle wrappers: copyable (shared_ptr), so they can be owned as deps ----- +class KmsClient { + std::shared_ptr<::rust::Box<::MplKmsClient>> inner_; + const ::MplKmsClient* ffi() const { return &**inner_; } + friend class KeyStore; +public: + explicit KmsClient(const ClientConfig& cfg) + : inner_(std::make_shared<::rust::Box<::MplKmsClient>>( + detail::guard([&] { return ::create_kms_client(cfg.raw()); }))) {} +}; + +class DdbClient { + std::shared_ptr<::rust::Box<::MplDdbClient>> inner_; + const ::MplDdbClient* ffi() const { return &**inner_; } + friend class KeyStore; +public: + explicit DdbClient(const ClientConfig& cfg) + : inner_(std::make_shared<::rust::Box<::MplDdbClient>>( + detail::guard([&] { return ::create_ddb_client(cfg.raw()); }))) {} +}; + +class KeyStore { + // Declared before inner_ so they outlive it; shared_ptr keeps the Rust + // clients alive for as long as this KeyStore exists -> the raw pointers the + // bridge stores can never dangle. + KmsClient kms_; + DdbClient ddb_; + std::shared_ptr<::rust::Box<::KeyStore>> inner_; + const ::KeyStore* ffi() const { return &**inner_; } + friend class HierarchicalKeyring; +public: + KeyStore(const std::string& table_name, + const std::string& logical_key_store_name, + const std::string& kms_arn, + KmsClient kms, + DdbClient ddb) + : kms_(std::move(kms)), + ddb_(std::move(ddb)), + inner_(std::make_shared<::rust::Box<::KeyStore>>(detail::guard([&] { + ::KeyStoreConfig c = ::default_keystore_config(); + c.ddb_table_name = ::rust::String(table_name); + c.logical_key_store_name = ::rust::String(logical_key_store_name); + c.kms_configuration_type = ::KmsConfigurationType::KmsKeyArn; + c.kms_configuration_value = ::rust::String(kms_arn); + c.kms_client = kms_.ffi(); + c.ddb_client = ddb_.ffi(); + return ::create_keystore(c); + }))) {} +}; + +class HierarchicalKeyring { + KeyStore key_store_; // owns the keystore (and transitively its clients) + std::shared_ptr<::rust::Box<::Keyring>> inner_; + const ::Keyring* ffi() const { return &**inner_; } + friend class EncryptionSDK; +public: + HierarchicalKeyring(KeyStore key_store, + const std::string& branch_key_id, + std::uint32_t ttl_seconds, + std::uint32_t cache_capacity, + CacheKind cache = CacheKind::MultiThreaded) + : key_store_(std::move(key_store)), + inner_(std::make_shared<::rust::Box<::Keyring>>(detail::guard([&] { + ::HierarchicalKeyringInput in = ::default_hierarchical_keyring_input(); + in.branch_key_id = ::rust::String(branch_key_id); + in.key_store = key_store_.ffi(); + in.ttl = ttl_seconds; + in.cache = detail::to_ffi(cache); + in.multi_threaded_cache.entryCapacity = cache_capacity; + return ::create_hierarchical_keyring(in); + }))) {} +}; + +// ---- Decrypt result ---------------------------------------------------------- +// decrypt returns not just the plaintext but the encryption context and algorithm +// suite the core library reported, so the caller can inspect what was actually +// used and authenticated (for example, to make access-control decisions). +struct DecryptResult { + std::vector plaintext; + std::map encryption_context; + AlgorithmSuiteId algorithm_suite_id; +}; + +// ---- SDK facade -------------------------------------------------------------- +class EncryptionSDK { +public: + std::vector encrypt( + const std::vector& plaintext, + const HierarchicalKeyring& keyring, + AlgorithmSuiteId alg = AlgorithmSuiteId::AesGcm256Hkdf512CommitEcdsa384, + CommitmentPolicy policy = CommitmentPolicy::RequireEncryptRequireDecrypt, + const std::map& encryption_context = {}) { + // Start from the Rust-defined defaults, then override — so we never + // re-declare defaults in C++ and risk diverging from the Rust core. + ::EncryptInput in = ::default_encrypt_input(); + in.keyring = keyring.ffi(); + in.plaintext = ::rust::Slice(plaintext.data(), plaintext.size()); + in.algorithm_suite_id = detail::to_ffi(alg); + in.commitment_policy = detail::to_ffi(policy); + in.encryption_context = detail::to_ec(encryption_context); + ::EncryptOutput out = detail::guard([&] { return ::encrypt(in); }); + return std::vector(out.ciphertext.begin(), out.ciphertext.end()); + } + + DecryptResult decrypt( + const std::vector& ciphertext, + const HierarchicalKeyring& keyring) { + ::DecryptInput in = ::default_decrypt_input(); + in.keyring = keyring.ffi(); + in.ciphertext = ::rust::Slice(ciphertext.data(), ciphertext.size()); + ::DecryptOutput out = detail::guard([&] { return ::decrypt(in); }); + DecryptResult result; + result.plaintext = std::vector(out.plaintext.begin(), out.plaintext.end()); + result.encryption_context = detail::from_ec(out.encryption_context); + result.algorithm_suite_id = detail::alg_from_ffi(out.algorithm_suite_id); + return result; + } +}; + +} // namespace Esdk +} // namespace Aws diff --git a/aws-esdk-cpp/aws-esdk-cpp/main.cpp b/aws-esdk-cpp/aws-esdk-cpp/main.cpp new file mode 100644 index 000000000..31a78ea76 --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/main.cpp @@ -0,0 +1,61 @@ +#include +#include "aws-esdk-cpp/src/lib.rs.h" + +int main() +{ + try + { + auto client_config = default_client_config(); + client_config.retry.max_attempts = 5; + auto kms = create_kms_client(client_config); + auto ddb = create_ddb_client(client_config); + + auto keystore_config = default_keystore_config(); + keystore_config.ddb_client = &*ddb; + keystore_config.kms_client = &*kms; + keystore_config.ddb_table_name = "KeyStoreDdbTable"; + keystore_config.logical_key_store_name = "KeyStoreDdbTable"; + keystore_config.kms_configuration_value = "arn:aws:kms:us-west-2:370957321024:key/9d989aa2-2f9c-438c-a745-cc57d3ad0126"; + auto keystore = create_keystore(keystore_config); + + auto keyring_input = default_hierarchical_keyring_input(); + keyring_input.ttl = 4242; + keyring_input.multi_threaded_cache.entryCapacity = 42; + keyring_input.key_store = &*keystore; + keyring_input.branch_key_id = "3ce7656b-e166-40f3-8c9b-a920ce6596cd"; + auto keyring = create_hierarchical_keyring(keyring_input); + + auto encrypt_input = default_encrypt_input(); + encrypt_input.keyring = &*keyring; + const unsigned char data[] = "Hello World"; + encrypt_input.plaintext = rust::Slice(&data[0], sizeof(data)); + auto encrypt_output = encrypt(encrypt_input); + auto decrypt_input = default_decrypt_input(); + decrypt_input.keyring = &*keyring; + decrypt_input.ciphertext = rust::Slice(&encrypt_output.ciphertext[0], encrypt_output.ciphertext.size()); + auto decrypt_output = decrypt(decrypt_input); + if (encrypt_input.plaintext.size() != decrypt_output.plaintext.size()) + fprintf(stderr, "Decrypt size mismatch\n"); + if (memcmp(decrypt_output.plaintext.data(), encrypt_input.plaintext.data(), encrypt_input.plaintext.size())) + fprintf(stderr, "Decrypt data mismatch\n"); + + delete_keyring(std::move(keyring)); + delete_keystore(std::move(keystore)); + delete_kms_client(std::move(kms)); + delete_ddb_client(std::move(ddb)); + std::cout << "Success!\n"; + } + catch (const std::exception &e) + { + std::cout << "Error: " << e.what() << "\n"; + } + catch (const std::string &e) + { + std::cout << "Error String: " << e << "\n"; + } + catch (...) + { + std::cout << "Other Exception \n"; + } + return 0; +} diff --git a/aws-esdk-cpp/aws-esdk-cpp/main_idiomatic.cpp b/aws-esdk-cpp/aws-esdk-cpp/main_idiomatic.cpp new file mode 100644 index 000000000..3557b45bb --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/main_idiomatic.cpp @@ -0,0 +1,57 @@ +#include +#include +#include // Idiomatic C++ wrapper layer + +int main() { + try { + // Create AWS clients + auto client_config = Aws::Esdk::ClientConfig() + .with_max_retry_attempts(5); + + auto kms = Aws::Esdk::KmsClient(client_config); + auto ddb = Aws::Esdk::DdbClient(client_config); + + // Create keystore with constructor - all config in one place + auto keystore = Aws::Esdk::KeyStore( + "KeyStoreDdbTable", // table_name + "KeyStoreDdbTable", // logical_key_store_name + "arn:aws:kms:us-west-2:370957321024:key/9d989aa2-2f9c-438c-a745-cc57d3ad0126", // kms_arn + kms, + ddb + ); + + // Create hierarchical keyring with constructor + auto keyring = Aws::Esdk::HierarchicalKeyring( + keystore, + "3ce7656b-e166-40f3-8c9b-a920ce6596cd", // branch_key_id + 4242, // ttl_seconds + 42 // cache_capacity + ); + + // Create encryption SDK client + Aws::Esdk::EncryptionSDK sdk; + + // Encrypt with std::vector - idiomatic C++ + std::vector plaintext = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'}; + auto ciphertext = sdk.encrypt(plaintext, keyring); + + // Decrypt + auto decrypted = sdk.decrypt(ciphertext, keyring); + + // Validate results + if (plaintext != decrypted.plaintext) { + std::cerr << "Decryption failed: plaintext mismatch\n"; + return 1; + } + + std::cout << "Success! Encryption and decryption completed successfully.\n"; + + // Automatic cleanup via RAII - no manual delete calls needed! + + } catch (const std::exception &e) { + std::cerr << "Error: " << e.what() << "\n"; + return 1; + } + + return 0; +} diff --git a/aws-esdk-cpp/aws-esdk-cpp/spec b/aws-esdk-cpp/aws-esdk-cpp/spec new file mode 120000 index 000000000..409f03297 --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/spec @@ -0,0 +1 @@ +../../spec \ No newline at end of file diff --git a/aws-esdk-cpp/aws-esdk-cpp/src/lib.rs b/aws-esdk-cpp/aws-esdk-cpp/src/lib.rs new file mode 100644 index 000000000..0bff41e85 --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/src/lib.rs @@ -0,0 +1,920 @@ +//! # aws-esdk-cpp — a C++ shim over the Rust AWS Encryption SDK +//! +//! This crate is a shim that exposes the native Rust AWS Encryption SDK to C++ +//! callers. Its behavioral contract is specified in `spec/shim/shim.md` and +//! `spec/shim/esdk-shim.md`. +//! +//! ## Layering +//! +//! 1. This bridge (`#[cxx::bridge] mod ffi`) + the Rust glue below it. +//! 2. The cxx-generated bindings (`lib.rs.h` / `lib.rs.cc`). +//! 3. A hand-written idiomatic facade, `aws_esdk.hpp`, which is what consumers +//! use. `main.cpp` uses the raw generated bindings directly; +//! `main_idiomatic.cpp` uses the facade. + +#![allow(clippy::boxed_local, reason = "need to pass Box to destructors")] + +// ---- Crate-wide conformance (see spec/shim/shim.md and spec/shim/esdk-shim.md) ---- +// +// The generic Shim Specification requirements below are file-wide: they describe +// behavior that EVERY translation / operation / resource in this crate obeys, so +// they are recorded here once as implications rather than pinned to a single site. +//= spec/shim/esdk-shim.md#overview +//= type=implication +//= reason=This crate's annotations against shim.md are the evidence that the ESDK shim conforms to the generic Shim Specification. +//# An ESDK shim MUST conform to the generic [Shim Specification](./shim.md). +// +//= spec/shim/shim.md#conformance-and-testing +//= type=implication +//= reason=This crate carries annotations against both shim.md and esdk-shim.md, evidencing conformance to both. +//# - A shim MUST conform to this specification in addition to its core-library-specific +//# shim specification. +// +//= spec/shim/shim.md#type-translation +//= type=implication +//= reason=Every concrete translation in this crate returns a Result and follows the convert-or-error rules. +//# Every such translation MUST obey the following rules. +// +//= spec/shim/shim.md#type-translation +//= type=implication +//= reason=Every conversion function in this crate converts between the target and core-library representations in the direction(s) it supports. +//# - A translation MUST convert between the target representation and the core +//# library representation, preserving meaning in both directions it supports. +// +//= spec/shim/shim.md#type-translation +//= type=implication +//= reason=Every target-to-core conversion returns Err for a target value that has no core-library representation. +//# - When the target supplies a value that has no corresponding core-library +//# representation, the translation MUST return an error. +// +//= spec/shim/shim.md#type-translation +//= type=implication +//= reason=Every core-to-target conversion returns Err for a core-library value the shim does not define. +//# - When the core library produces a value the shim does not define, the +//# translation MUST return an error. +// +//= spec/shim/shim.md#delegation +//= type=implication +//= reason=No function in this crate validates operation or resource-creation inputs; each value is translated and passed to the core library, which performs all validation. +//# - The shim MUST NOT validate operation or resource-creation input values itself; +//# it MUST translate each input and defer its validation to the core library. +// +//= spec/shim/shim.md#delegation +//= type=implication +//= reason=Every operation in this crate produces its result by calling the corresponding aws_esdk core-library function. +//# - Each operation the shim exposes MUST produce its result by invoking the +//# corresponding core-library operation. +// +//= spec/shim/shim.md#operation-contracts +//= type=implication +//= reason=Every operation invokes the core library, satisfying Delegation. +//# - Each operation MUST invoke the core library per [Delegation](#delegation). +// +//= spec/shim/shim.md#operation-contracts +//= type=implication +//= reason=Every operation input/output is either passed through unmodified or converted by a Type-translation function. +//# - Except where an input or output is passed through unmodified, each MUST be +//# translated per [Type translation](#type-translation). +// +//= spec/shim/shim.md#creating-and-releasing-resources +//= type=implication +//= reason=Each resource kind has its own create_* function in the cxx bridge (keyring, key store, KMS client, DynamoDB client). +//# - For each resource kind, the shim MUST provide a means for the target to create an +//# instance backed by the core library. +// +//= spec/shim/shim.md#creating-and-releasing-resources +//= type=implication +//= reason=Each resource is a Box owned by the target; dropping the owned interface frees the backing core-library resource. +//# - The shim MUST release the core-library resource backing an owned interface once +//# the target no longer holds it. +// +//= spec/shim/shim.md#creating-and-releasing-resources +//= type=implication +//= reason=Dropping the Box at end of scope releases the resource automatically when the owned interface is destroyed. +//# The shim MAY release it automatically when the +//# owned interface is destroyed, or through an explicit target operation. +// +//= spec/shim/shim.md#concurrency +//= type=exception +//= reason=The shim adds no concurrency feature of its own and does not exercise concurrent use in this no-AWS crate; bridge entry points defer any threading behavior to the core library. +//# If a core library resource or operation supports concurrent use from multiple threads, +//# the shim library SHOULD support it as well. +// +//= spec/shim/shim.md#streaming +//= type=exception +//= reason=The owned interface exposes one-shot encrypt/decrypt (Vec in, Vec out); streamed input/output is not surfaced. +//# If a core library resource or operation supports [streamed](../client-apis/streaming.md) input/outputs, +//# the shim library SHOULD support it as well. +use aws_config::{AppName, Region, SdkConfig}; +use std::sync::LazyLock; + +static DAFNY_TOKIO_RUNTIME: LazyLock = LazyLock::new(|| { + // Building a multi-thread Tokio runtime only fails if the OS cannot spawn a + // thread or install the I/O/timer drivers — an environment failure with no + // meaningful library-level recovery. We surface it as a panic at first use + // rather than threading a `Result` through every bridge entry point. + tokio::runtime::Builder::new_multi_thread() + .enable_all() + .build() + .unwrap() +}); + +#[cxx::bridge] +mod ffi { + struct EncryptionContextItem { + key: String, + value: String, + } + enum EsdkAlgorithmSuiteId { + AlgAes128GcmIv12Tag16NoKdf = 0x0014, + AlgAes192GcmIv12Tag16NoKdf = 0x0046, + AlgAes256GcmIv12Tag16NoKdf = 0x0078, + AlgAes128GcmIv12Tag16HkdfSha256 = 0x0114, + AlgAes192GcmIv12Tag16HkdfSha256 = 0x0146, + AlgAes256GcmIv12Tag16HkdfSha256 = 0x0178, + AlgAes128GcmIv12Tag16HkdfSha256EcdsaP256 = 0x0214, + AlgAes192GcmIv12Tag16HkdfSha384EcdsaP384 = 0x0346, + AlgAes256GcmIv12Tag16HkdfSha384EcdsaP384 = 0x0378, + AlgAes256GcmHkdfSha512CommitKey = 0x0478, + AlgAes256GcmHkdfSha512CommitKeyEcdsaP384 = 0x0578, + } + + struct EncryptInput<'a> { + /// Algorithm Suite. See + pub algorithm_suite_id: EsdkAlgorithmSuiteId, + /// Key-Value pairs to associate with the encrypted data + pub encryption_context: Vec, + /// Bytes of plaintext data per frame. Default 4096. + pub frame_length: u32, + /// The source of cryptographic materials + pub keyring: *const Keyring, + /// data to be encrypted + pub plaintext: &'a [u8], + /// default is no limit + pub max_encrypted_data_keys: u32, + /// default is `EsdkCommitmentPolicy::RequireEncryptRequireDecrypt` + pub commitment_policy: EsdkCommitmentPolicy, + } + struct EncryptOutput { + /// Algorithm Suite. See + pub algorithm_suite_id: EsdkAlgorithmSuiteId, + /// data to be decrypted + pub ciphertext: Vec, + /// Key-Value pairs to associate with the encrypted data + pub encryption_context: Vec, + } + struct DecryptInput<'a> { + /// data to be decrypted + pub ciphertext: &'a [u8], + /// Key-Value pairs to associate with the encrypted data + pub encryption_context: Vec, + /// The source of cryptographic materials + pub keyring: *const Keyring, + /// default is no limit + pub max_encrypted_data_keys: u32, + /// default is `EsdkCommitmentPolicy::RequireEncryptRequireDecrypt` + pub commitment_policy: EsdkCommitmentPolicy, + } + struct DecryptOutput { + /// Algorithm Suite. See + pub algorithm_suite_id: EsdkAlgorithmSuiteId, + /// Key-Value pairs to associate with the encrypted data + pub encryption_context: Vec, + /// decrypted data + pub plaintext: Vec, + } + + enum EsdkCommitmentPolicy { + ForbidEncryptAllowDecrypt, + RequireEncryptAllowDecrypt, + RequireEncryptRequireDecrypt, + } + + struct RetryConfig { + mode_adaptive: bool, + max_attempts: u32, + initial_backoff_milli: u64, + max_backoff_milli: u64, + reconnect_all: bool, + use_static_exponential_base: bool, + } + + enum KmsConfigurationType { + KmsKeyArn, + KmsMrKeyArn, + Discovery, + MrDiscovery, + } + + enum CacheType { + NoCache, + MultiThreadedCache, + } + + struct MplAwsClientConfig { + env: bool, + region: String, + retry: RetryConfig, + } + + struct MultiThreadedCacheConfig { + entryCapacity: u32, + entryPruningTailSize: u32, + } + + struct KeyStoreConfig { + ddb_table_name: String, + kms_configuration_type: KmsConfigurationType, + kms_configuration_value: String, + logical_key_store_name: String, + id: String, + grant_tokens: Vec, + ddb_client: *const MplDdbClient, + kms_client: *const MplKmsClient, + } + + struct HierarchicalKeyringInput { + branch_key_id: String, + key_store: *const KeyStore, + ttl: u32, + cache: CacheType, + multi_threaded_cache: MultiThreadedCacheConfig, + partition_id: String, + } + + extern "Rust" { + type MplDdbClient; + fn create_ddb_client(value: &MplAwsClientConfig) -> Result>; + fn delete_ddb_client(client: Box) -> Result<()>; + + type KeyStore; + fn create_keystore(value: &KeyStoreConfig) -> Result>; + fn delete_keystore(client: Box) -> Result<()>; + + type Keyring; + fn create_hierarchical_keyring(value: &HierarchicalKeyringInput) -> Result>; + fn delete_keyring(client: Box) -> Result<()>; + + type MplKmsClient; + fn create_kms_client(value: &MplAwsClientConfig) -> Result>; + fn delete_kms_client(client: Box) -> Result<()>; + + fn encrypt(input: &EncryptInput) -> Result; + fn decrypt(input: &DecryptInput) -> Result; + + fn default_client_config() -> MplAwsClientConfig; + fn default_keystore_config() -> KeyStoreConfig; + fn default_hierarchical_keyring_input() -> HierarchicalKeyringInput; + fn default_encrypt_input() -> EncryptInput<'static>; + fn default_decrypt_input() -> DecryptInput<'static>; + } +} + +struct MplKmsClient { + client: aws_sdk_kms::Client, +} +struct MplDdbClient { + client: aws_sdk_dynamodb::Client, +} + +struct KeyStore { + client: aws_mpl_legacy::dafny::deps::aws_cryptography_keyStore::client::Client, +} + +struct Keyring { + client: aws_mpl_legacy::dafny::types::keyring::KeyringRef, +} + +//= spec/shim/esdk-shim.md#commitment-policy +//# - The shim MUST translate the target commitment policy to the core ESDK +//# commitment policy of the same meaning. +fn commitment_policy_target_to_core( + x: ffi::EsdkCommitmentPolicy, +) -> Result { + use aws_mpl_legacy::commitment::EsdkCommitmentPolicy as New; + use ffi::EsdkCommitmentPolicy as Old; + match x { + Old::ForbidEncryptAllowDecrypt => Ok(New::ForbidEncryptAllowDecrypt), + Old::RequireEncryptAllowDecrypt => Ok(New::RequireEncryptAllowDecrypt), + Old::RequireEncryptRequireDecrypt => Ok(New::RequireEncryptRequireDecrypt), + //= spec/shim/esdk-shim.md#commitment-policy + //# - The shim MUST return an error when the target commitment policy is not a supported + //# value. + _ => Err(format!("unrecognized EsdkCommitmentPolicy value: {}", x.repr)), + } +} + +fn default_encrypt_input() -> ffi::EncryptInput<'static> { + ffi::EncryptInput { + algorithm_suite_id: ffi::EsdkAlgorithmSuiteId::AlgAes256GcmHkdfSha512CommitKeyEcdsaP384, + encryption_context: Vec::default(), + frame_length: 4096, + keyring: std::ptr::null(), + plaintext: &[], + max_encrypted_data_keys: 0, + commitment_policy: ffi::EsdkCommitmentPolicy::RequireEncryptRequireDecrypt, + } +} + +fn default_decrypt_input() -> ffi::DecryptInput<'static> { + ffi::DecryptInput { + ciphertext: &[], + encryption_context: Vec::default(), + keyring: std::ptr::null(), + max_encrypted_data_keys: 0, + commitment_policy: ffi::EsdkCommitmentPolicy::RequireEncryptRequireDecrypt, + } +} + +fn default_hierarchical_keyring_input() -> ffi::HierarchicalKeyringInput { + ffi::HierarchicalKeyringInput { + branch_key_id: String::default(), + key_store: std::ptr::null(), + ttl: 300, + cache: ffi::CacheType::MultiThreadedCache, + multi_threaded_cache: ffi::MultiThreadedCacheConfig { + entryCapacity: 1000, + entryPruningTailSize: 1, + }, + partition_id: String::default(), + } +} + +fn default_keystore_config() -> ffi::KeyStoreConfig { + ffi::KeyStoreConfig { + ddb_table_name: String::default(), + kms_configuration_type: ffi::KmsConfigurationType::KmsKeyArn, + kms_configuration_value: String::default(), + logical_key_store_name: String::default(), + id: String::default(), + grant_tokens: Vec::default(), + ddb_client: std::ptr::null(), + kms_client: std::ptr::null(), + } +} + +fn default_client_config() -> ffi::MplAwsClientConfig { + ffi::MplAwsClientConfig { + env: true, + region: String::default(), + retry: default_retry_config(), + } +} + +fn default_retry_config() -> ffi::RetryConfig { + ffi::RetryConfig { + mode_adaptive: false, + max_attempts: 0, + initial_backoff_milli: 0, + max_backoff_milli: 0, + reconnect_all: false, + use_static_exponential_base: false, + } +} + +//= spec/shim/esdk-shim.md#algorithm-suite-identifier +//# - The shim MUST translate a target algorithm suite identifier to the core ESDK +//# algorithm suite that has the same two-byte ID. +fn alg_id_target_to_core( + e: ffi::EsdkAlgorithmSuiteId, +) -> Result { + use aws_mpl_legacy::suites::EsdkAlgorithmSuiteId as New; + use ffi::EsdkAlgorithmSuiteId as Old; + match e { + Old::AlgAes128GcmIv12Tag16NoKdf => Ok(New::AlgAes128GcmIv12Tag16NoKdf), + Old::AlgAes192GcmIv12Tag16NoKdf => Ok(New::AlgAes192GcmIv12Tag16NoKdf), + Old::AlgAes256GcmIv12Tag16NoKdf => Ok(New::AlgAes256GcmIv12Tag16NoKdf), + Old::AlgAes128GcmIv12Tag16HkdfSha256 => Ok(New::AlgAes128GcmIv12Tag16HkdfSha256), + Old::AlgAes192GcmIv12Tag16HkdfSha256 => Ok(New::AlgAes192GcmIv12Tag16HkdfSha256), + Old::AlgAes256GcmIv12Tag16HkdfSha256 => Ok(New::AlgAes256GcmIv12Tag16HkdfSha256), + Old::AlgAes128GcmIv12Tag16HkdfSha256EcdsaP256 => { + Ok(New::AlgAes128GcmIv12Tag16HkdfSha256EcdsaP256) + } + Old::AlgAes192GcmIv12Tag16HkdfSha384EcdsaP384 => { + Ok(New::AlgAes192GcmIv12Tag16HkdfSha384EcdsaP384) + } + Old::AlgAes256GcmIv12Tag16HkdfSha384EcdsaP384 => { + Ok(New::AlgAes256GcmIv12Tag16HkdfSha384EcdsaP384) + } + Old::AlgAes256GcmHkdfSha512CommitKey => Ok(New::AlgAes256GcmHkdfSha512CommitKey), + Old::AlgAes256GcmHkdfSha512CommitKeyEcdsaP384 => { + Ok(New::AlgAes256GcmHkdfSha512CommitKeyEcdsaP384) + } + //= spec/shim/esdk-shim.md#algorithm-suite-identifier + //# - The shim MUST return an error when the target value is not one of the algorithm + //# suite IDs defined by the core ESDK. + _ => Err(format!("unrecognized EsdkAlgorithmSuiteId value: {:#06x}", e.repr)), + } +} + +//= spec/shim/esdk-shim.md#algorithm-suite-identifier +//# - The shim MUST translate a core ESDK algorithm suite to the target algorithm +//# suite identifier that has the same two-byte ID. +fn alg_id_core_to_target( + e: aws_mpl_legacy::suites::EsdkAlgorithmSuiteId, +) -> Result { + use aws_mpl_legacy::suites::EsdkAlgorithmSuiteId as Old; + use ffi::EsdkAlgorithmSuiteId as New; + match e { + Old::AlgAes128GcmIv12Tag16NoKdf => Ok(New::AlgAes128GcmIv12Tag16NoKdf), + Old::AlgAes192GcmIv12Tag16NoKdf => Ok(New::AlgAes192GcmIv12Tag16NoKdf), + Old::AlgAes256GcmIv12Tag16NoKdf => Ok(New::AlgAes256GcmIv12Tag16NoKdf), + Old::AlgAes128GcmIv12Tag16HkdfSha256 => Ok(New::AlgAes128GcmIv12Tag16HkdfSha256), + Old::AlgAes192GcmIv12Tag16HkdfSha256 => Ok(New::AlgAes192GcmIv12Tag16HkdfSha256), + Old::AlgAes256GcmIv12Tag16HkdfSha256 => Ok(New::AlgAes256GcmIv12Tag16HkdfSha256), + Old::AlgAes128GcmIv12Tag16HkdfSha256EcdsaP256 => { + Ok(New::AlgAes128GcmIv12Tag16HkdfSha256EcdsaP256) + } + Old::AlgAes192GcmIv12Tag16HkdfSha384EcdsaP384 => { + Ok(New::AlgAes192GcmIv12Tag16HkdfSha384EcdsaP384) + } + Old::AlgAes256GcmIv12Tag16HkdfSha384EcdsaP384 => { + Ok(New::AlgAes256GcmIv12Tag16HkdfSha384EcdsaP384) + } + Old::AlgAes256GcmHkdfSha512CommitKey => Ok(New::AlgAes256GcmHkdfSha512CommitKey), + Old::AlgAes256GcmHkdfSha512CommitKeyEcdsaP384 => { + Ok(New::AlgAes256GcmHkdfSha512CommitKeyEcdsaP384) + } + //= spec/shim/esdk-shim.md#algorithm-suite-identifier + //= type=implication + //= reason=The core ESDK enum is exhaustive over its defined suites; a value it does not define cannot be constructed, so this defensive arm cannot be reached by a runtime test. + //# - The shim MUST return an error when the core ESDK produces an algorithm suite + //# the shim does not define. + _ => Err("core returned an algorithm suite id unknown to the C++ bindings".to_string()), + } +} + +//= spec/shim/esdk-shim.md#encryption-context +//# - The shim MUST translate the core ESDK's encryption context, given as a +//# key-value map, to the target's list of key-value pairs, preserving every pair +//# and the exact key and value of each. +fn encryption_context_core_to_target( + x: std::collections::HashMap, +) -> Vec { + x.into_iter() + .map(|(k, v)| ffi::EncryptionContextItem { key: k, value: v }) + .collect() +} + +//= spec/shim/esdk-shim.md#encryption-context +//# - The shim MUST translate the target's encryption context, given as a list of +//# key-value pairs, to the core ESDK's key-value map, preserving every pair and +//# the exact key and value of each. +fn encryption_context_target_to_core(x: &[ffi::EncryptionContextItem]) -> std::collections::HashMap { + x.iter().map(|x| (x.key.clone(), x.value.clone())).collect() +} + +//= spec/shim/esdk-shim.md#maximum-encrypted-data-keys +//# The shim MUST translate zero +//# to the core ESDK's "no limit" representation, and a positive value `n` to a +//# limit of `n`. +fn max_edks_target_to_core(n: u32) -> Option { + std::num::NonZeroUsize::new(usize::try_from(n).unwrap_or(usize::MAX)) +} + +//= spec/shim/esdk-shim.md#frame-length +//# - The shim MUST translate the target frame length using the core ESDK's frame +//# length constructor, and MUST return an error when the core ESDK rejects the +//# value. +fn make_frame_length(frame_length: u32) -> Result { + aws_esdk::FrameLength::new(frame_length).map_err(|e| format!("invalid frame_length: {:?}", e)) +} + +/// The user-agent this shim publishes: target language (C++), core language +/// (Rust), and the crate's published version. +fn shim_user_agent() -> String { + //= spec/shim/esdk-shim.md#service-client-configuration + //# - The shim MUST set a user-agent on each service client of the form + //# `AwsEncryptionSdk-Shim---`, where + //# `` is the target language, `` is the core + //# ESDK's implementation language, and `` is the shim's published version. + format!("AwsEncryptionSdk-Shim-C++-Rust-{}", env!("CARGO_PKG_VERSION")) +} + +/// Merge the shim's user-agent with any user-agent already present in the loaded +/// configuration. +fn merge_user_agent(current_app_name: &str, shim_ua: &str) -> String { + if current_app_name.is_empty() { + shim_ua.to_string() + } else { + //= spec/shim/esdk-shim.md#service-client-configuration + //# - The shim MUST preserve any user-agent already present in the loaded + //# configuration, appending its own rather than replacing it. + format!("{} {}", current_app_name, shim_ua) + } +} + +fn encrypt(input: &ffi::EncryptInput) -> Result { + //= spec/shim/esdk-shim.md#materials-source + //# - The shim MUST return an error, and MUST NOT invoke the core ESDK, when no + //# materials source is supplied. + if input.keyring.is_null() { + return Err("keyring is null in encrypt".to_string()); + } + + let mut core_input = aws_esdk::EncryptInput::with_legacy_keyring( + //= spec/shim/esdk-shim.md#encrypt-inputs + //# - `encrypt` MUST pass the target-supplied plaintext to the core ESDK unmodified. + input.plaintext, + //= spec/shim/esdk-shim.md#encrypt-inputs + //# - `encrypt` MUST provide the target-supplied encryption context to the core ESDK, + //# converted as defined in [Encryption context](#encryption-context). + encryption_context_target_to_core(&input.encryption_context), + //= spec/shim/esdk-shim.md#materials-source + //= type=implication + //= reason=EncryptInput carries exactly one materials-source field (keyring); the type admits no second source. + //# - Each of `encrypt` and `decrypt` MUST be supplied with exactly one materials + //# source (see [Resources](#resources)). + unsafe { (*input.keyring).client.clone() }, + ); + //= spec/shim/esdk-shim.md#encrypt-inputs + //# - `encrypt` MUST provide the target-supplied maximum-encrypted-data-keys value to + //# the core ESDK, converted as defined in + //# [Maximum encrypted data keys](#maximum-encrypted-data-keys). + core_input.max_encrypted_data_keys = max_edks_target_to_core(input.max_encrypted_data_keys); + //= spec/shim/esdk-shim.md#encrypt-inputs + //# - `encrypt` MUST provide the target-supplied frame length to the core ESDK, + //# converted as defined in [Frame length](#frame-length). + core_input.frame_length = make_frame_length(input.frame_length)?; + //= spec/shim/esdk-shim.md#encrypt-inputs + //# - `encrypt` MUST provide the target-supplied commitment policy to the core ESDK, + //# converted as defined in [Commitment policy](#commitment-policy). + core_input.commitment_policy = commitment_policy_target_to_core(input.commitment_policy)?; + //= spec/shim/esdk-shim.md#encrypt-inputs + //# - `encrypt` MUST provide the target-supplied algorithm suite to the core ESDK, + //# converted as defined in [Algorithm suite identifier](#algorithm-suite-identifier). + core_input.algorithm_suite_id = Some(alg_id_target_to_core(input.algorithm_suite_id)?); + let output = DAFNY_TOKIO_RUNTIME.block_on(aws_esdk::encrypt(&core_input)); + //= spec/shim/shim.md#delegation + //# - When a core-library operation returns an error, the shim MUST return an error to + //# the target and MUST NOT report the operation as successful. + // + //= spec/shim/shim.md#delegation + //# - An error the shim returns for a failed core-library operation SHOULD include + //# context identifying which operation failed. + let output = output.map_err(|e| format!("encrypt failed: {:?}", e))?; + Ok(ffi::EncryptOutput { + //= spec/shim/esdk-shim.md#encrypt-outputs + //# - `encrypt` MUST return the used algorithm suite, converted as defined in + //# [Algorithm suite identifier](#algorithm-suite-identifier). + algorithm_suite_id: alg_id_core_to_target(output.algorithm_suite_id)?, + //= spec/shim/esdk-shim.md#encrypt-outputs + //# - `encrypt` MUST return the core ESDK's ciphertext unmodified. + ciphertext: output.ciphertext, + //= spec/shim/esdk-shim.md#encrypt-outputs + //# - `encrypt` MUST return the result encryption context, converted as defined in + //# [Encryption context](#encryption-context). + encryption_context: encryption_context_core_to_target(output.encryption_context), + }) +} +fn decrypt(input: &ffi::DecryptInput) -> Result { + //= spec/shim/esdk-shim.md#materials-source + //# - The shim MUST return an error, and MUST NOT invoke the core ESDK, when no + //# materials source is supplied. + if input.keyring.is_null() { + return Err("keyring is null in decrypt".to_string()); + } + + let mut core_input = aws_esdk::DecryptInput::with_legacy_keyring( + //= spec/shim/esdk-shim.md#decrypt-inputs + //# - `decrypt` MUST pass the target-supplied ciphertext to the core ESDK unmodified. + input.ciphertext, + //= spec/shim/esdk-shim.md#decrypt-inputs + //# - `decrypt` MUST provide the target-supplied encryption context to the core ESDK, + //# converted as defined in [Encryption context](#encryption-context). + encryption_context_target_to_core(&input.encryption_context), + unsafe { (*input.keyring).client.clone() }, + ); + //= spec/shim/esdk-shim.md#decrypt-inputs + //# - `decrypt` MUST provide the target-supplied maximum-encrypted-data-keys value to + //# the core ESDK, converted as defined in + //# [Maximum encrypted data keys](#maximum-encrypted-data-keys). + core_input.max_encrypted_data_keys = max_edks_target_to_core(input.max_encrypted_data_keys); + //= spec/shim/esdk-shim.md#decrypt-inputs + //# - `decrypt` MUST provide the target-supplied commitment policy to the core ESDK, + //# converted as defined in [Commitment policy](#commitment-policy). + core_input.commitment_policy = commitment_policy_target_to_core(input.commitment_policy)?; + let output = DAFNY_TOKIO_RUNTIME.block_on(aws_esdk::decrypt(&core_input)); + let output = output.map_err(|e| format!("decrypt failed: {:?}", e))?; + Ok(ffi::DecryptOutput { + //= spec/shim/esdk-shim.md#decrypt-outputs + //# - `decrypt` MUST return the used algorithm suite, converted as defined in + //# [Algorithm suite identifier](#algorithm-suite-identifier). + algorithm_suite_id: alg_id_core_to_target(output.algorithm_suite_id)?, + //= spec/shim/esdk-shim.md#decrypt-outputs + //# - `decrypt` MUST return the core ESDK's plaintext unmodified. + plaintext: output.plaintext, + //= spec/shim/esdk-shim.md#decrypt-outputs + //# - `decrypt` MUST return the result encryption context, converted as defined in + //# [Encryption context](#encryption-context). + encryption_context: encryption_context_core_to_target(output.encryption_context), + }) +} + +//= spec/shim/esdk-shim.md#service-client-configuration +//# - If the target does not supply a retry configuration, the shim MAY apply a +//# default retry configuration. +fn make_retry_config(config: &ffi::RetryConfig) -> aws_config::retry::RetryConfig { + let mut out_config = if config.mode_adaptive { + aws_config::retry::RetryConfig::adaptive() + } else { + aws_config::retry::RetryConfig::standard() + }; + if config.max_attempts > 0 { + out_config = out_config.with_max_attempts(config.max_attempts); + } + if config.initial_backoff_milli > 0 { + out_config = out_config.with_initial_backoff(std::time::Duration::from_millis( + config.initial_backoff_milli, + )); + } + if config.max_backoff_milli > 0 { + out_config = + out_config.with_max_backoff(std::time::Duration::from_millis(config.max_backoff_milli)); + } + if config.reconnect_all { + out_config = out_config + .with_reconnect_mode(aws_sdk_kms::config::retry::ReconnectMode::ReuseAllConnections); + } + if config.use_static_exponential_base { + out_config = out_config.with_use_static_exponential_base(true); + } + out_config +} +fn delete_kms_client(_client: Box) -> Result<(), String> { + Ok(()) +} +fn delete_ddb_client(_client: Box) -> Result<(), String> { + Ok(()) +} +fn delete_keystore(_client: Box) -> Result<(), String> { + Ok(()) +} +fn delete_keyring(_client: Box) -> Result<(), String> { + Ok(()) +} + +fn make_cache_type( + config: &ffi::HierarchicalKeyringInput, +) -> Result { + match config.cache { + //= spec/shim/esdk-shim.md#cache-configuration + //# - The shim MUST translate a no-cache selection. + ffi::CacheType::NoCache => Ok(aws_mpl_legacy::dafny::types::CacheType::No( + aws_mpl_legacy::dafny::types::NoCache::builder() + .build() + .map_err(|e| format!("failed to build NoCache: {:?}", e))?, + )), + //= spec/shim/esdk-shim.md#cache-configuration + //# - The shim MUST translate a multi-threaded cache selection. + ffi::CacheType::MultiThreadedCache => { + let entry_capacity = i32::try_from(config.multi_threaded_cache.entryCapacity) + .map_err(|_| { + format!( + "entry_capacity {} exceeds the core ESDK's i32 limit", + config.multi_threaded_cache.entryCapacity + ) + })?; + let entry_pruning_tail_size = + i32::try_from(config.multi_threaded_cache.entryPruningTailSize).map_err(|_| { + format!( + "entry_pruning_tail_size {} exceeds the core ESDK's i32 limit", + config.multi_threaded_cache.entryPruningTailSize + ) + })?; + Ok(aws_mpl_legacy::dafny::types::CacheType::MultiThreaded( + aws_mpl_legacy::dafny::types::MultiThreadedCache::builder() + .entry_capacity(entry_capacity) + .entry_pruning_tail_size(entry_pruning_tail_size) + .build() + .map_err(|e| format!("failed to build MultiThreadedCache: {:?}", e))?, + )) + } + //= spec/shim/esdk-shim.md#cache-configuration + //# - The shim MUST return an error when the target cache type is not a supported + //# value. + _ => Err("Invalid CacheType in HierarchicalKeyringInput".to_string()), + } +} + +fn make_kms_config( + config: &ffi::KeyStoreConfig, +) -> Result { + match config.kms_configuration_type { + //= spec/shim/esdk-shim.md#kms-configuration + //# - The shim MUST translate a KMS key ARN configuration. + ffi::KmsConfigurationType::KmsKeyArn => Ok( + aws_mpl_legacy::dafny::deps::aws_cryptography_keyStore::types::KmsConfiguration::KmsKeyArn( + config.kms_configuration_value.clone(), + ), + ), + //= spec/shim/esdk-shim.md#kms-configuration + //# - The shim MUST translate a KMS multi-Region-key ARN configuration. + ffi::KmsConfigurationType::KmsMrKeyArn => Ok( + aws_mpl_legacy::dafny::deps::aws_cryptography_keyStore::types::KmsConfiguration::KmsMrKeyArn( + config.kms_configuration_value.clone(), + ), + ), + //= spec/shim/esdk-shim.md#kms-configuration + //# - The shim MUST translate a discovery configuration. + ffi::KmsConfigurationType::Discovery => Ok( + aws_mpl_legacy::dafny::deps::aws_cryptography_keyStore::types::KmsConfiguration::Discovery( + aws_mpl_legacy::dafny::deps::aws_cryptography_keyStore::types::Discovery::builder() + .build() + .map_err(|e| format!("failed to build Discovery: {:?}", e))?, + ), + ), + //= spec/shim/esdk-shim.md#kms-configuration + //# - The shim MUST translate a multi-Region-key discovery configuration. + ffi::KmsConfigurationType::MrDiscovery => Ok( + aws_mpl_legacy::dafny::deps::aws_cryptography_keyStore::types::KmsConfiguration::MrDiscovery( + aws_mpl_legacy::dafny::deps::aws_cryptography_keyStore::types::MrDiscovery::builder() + .build() + .map_err(|e| format!("failed to build MrDiscovery: {:?}", e))?, + ), + ), + //= spec/shim/esdk-shim.md#kms-configuration + //# - The shim MUST return an error when the target KMS configuration type is not a + //# supported value. + _ => Err("Invalid KmsConfigurationType".to_string()), + } +} + +//= spec/shim/esdk-shim.md#create-hierarchical-keyring +//# - The shim MUST provide an operation that creates a hierarchical keyring backed +//# by the core ESDK. +fn create_hierarchical_keyring( + input: &ffi::HierarchicalKeyringInput, +) -> Result, String> { + let mpl_config = aws_mpl_legacy::dafny::types::MaterialProvidersConfig::builder() + .build() + .map_err(|e| format!("failed to build MaterialProvidersConfig: {:?}", e))?; + let mpl = aws_mpl_legacy::dafny::Client::from_conf(mpl_config) + .map_err(|e| format!("failed to create MPL client: {:?}", e))?; + //= spec/shim/esdk-shim.md#create-hierarchical-keyring + //# - Creating a hierarchical keyring MUST provide the target-supplied cache + //# configuration to the core ESDK, converted as defined in + //# [Cache configuration](#cache-configuration). + // + //= spec/shim/esdk-shim.md#create-hierarchical-keyring + //# - Creating a hierarchical keyring MUST provide the target-supplied branch key id + //# and time-to-live to the core ESDK. + let mut builder = mpl + .create_aws_kms_hierarchical_keyring() + .cache(make_cache_type(input)?) + .branch_key_id(input.branch_key_id.clone()) + .ttl_seconds(input.ttl); + //= spec/shim/esdk-shim.md#create-hierarchical-keyring + //# - Creating a hierarchical keyring MUST require a key store handle, checked as + //# defined in + //# [Shim Specification: Handles and lifetimes](./shim.md#handles-and-lifetimes), + //# and MUST provide it to the core ESDK. + if input.key_store.is_null() { + return Err("key_store is null in create_hierarchical_keyring".to_string()); + } else { + builder = builder.key_store(unsafe { (*input.key_store).client.clone() }) + } + //= spec/shim/esdk-shim.md#create-hierarchical-keyring + //# - Creating a hierarchical keyring MUST provide the target-supplied partition id to + //# the core ESDK when present; an unset value is omitted. + // The "when present" branch is exercised by `round_trip_integration` (partition + // id set). The "unset ⇒ omitted" branch simply skips the builder call; the + // omission is a construction guarantee, not separately testable without AWS. + if !input.partition_id.is_empty() { + builder = builder.partition_id(input.partition_id.clone()); + } + + let keyring = DAFNY_TOKIO_RUNTIME + .block_on(builder.send()) + .map_err(|e| format!("failed to create hierarchical keyring: {:?}", e))?; + + let keyring = Keyring { client: keyring }; + Ok(Box::new(keyring)) +} + +//= spec/shim/esdk-shim.md#create-key-store +//# - The shim MUST provide an operation that creates a key store backed by the core +//# ESDK. +fn create_keystore(input: &ffi::KeyStoreConfig) -> Result, String> { + let mut builder = aws_mpl_legacy::dafny::deps::aws_cryptography_keyStore::types::key_store_config::KeyStoreConfig::builder(); + //= spec/shim/esdk-shim.md#create-key-store + //# - Creating a key store MUST require a KMS client handle and a DynamoDB client + //# handle, checked as defined in + //# [Shim Specification: Handles and lifetimes](./shim.md#handles-and-lifetimes), + //# and MUST provide both to the core ESDK. + // + //= spec/shim/shim.md#handles-and-lifetimes + //# - Before dereferencing a target-supplied resource handle, the shim MUST check it + //# and MUST return an error when a required handle is absent. + if input.kms_client.is_null() { + return Err("kms_client is null in create_keystore".to_string()); + } else { + builder = builder.kms_client(unsafe { (*input.kms_client).client.clone() }); + } + if input.ddb_client.is_null() { + return Err("ddb_client is null in create_keystore".to_string()); + } else { + builder = builder.ddb_client(unsafe { (*input.ddb_client).client.clone() }); + } + // Input values are translated and passed through; the core ESDK validates + // them (the shim does not short-circuit on empty/invalid values). + //= spec/shim/esdk-shim.md#create-key-store + //# - Creating a key store MUST provide the target-supplied table name and logical key + //# store name to the core ESDK. + builder = builder.ddb_table_name(input.ddb_table_name.clone()); + builder = builder.logical_key_store_name(input.logical_key_store_name.clone()); + //= spec/shim/esdk-shim.md#create-key-store + //# - Creating a key store MUST provide the target-supplied KMS configuration to the + //# core ESDK, converted as defined in [KMS configuration](#kms-configuration). + builder = builder.kms_configuration(make_kms_config(input)?); + //= spec/shim/esdk-shim.md#create-key-store + //# - Creating a key store MUST provide the target-supplied key store id and grant + //# tokens to the core ESDK when present; an unset value is omitted. + // The "when present" branch is exercised by `round_trip_integration` (id and + // grant tokens set). The "unset ⇒ omitted" branch simply skips the builder + // call, so whether the core received the value is only observable through a + // real key store; the omission is a construction guarantee, not separately + // testable without AWS. + if !input.id.is_empty() { + builder = builder.id(input.id.clone()); + } + if !input.grant_tokens.is_empty() { + builder = builder.grant_tokens(input.grant_tokens.clone()); + } + let config = builder + .build() + .map_err(|e| format!("failed to build KeyStoreConfig: {:?}", e))?; + + let store = aws_mpl_legacy::dafny::deps::aws_cryptography_keyStore::client::Client::from_conf(config) + .map_err(|e| format!("failed to create key store client: {:?}", e))?; + let store = KeyStore { client: store }; + Ok(Box::new(store)) +} + +//= spec/shim/esdk-shim.md#create-kms-client +//# - The shim MUST provide an operation that creates a KMS service client backed by +//# the core ESDK. +fn create_kms_client(input: &ffi::MplAwsClientConfig) -> Result, String> { + //= spec/shim/esdk-shim.md#create-kms-client + //# - Creating a KMS client MUST apply the target-supplied client configuration, as + //# defined in [Service client configuration](#service-client-configuration). + let sdk_config = create_sdk_config(input)?; + let client = aws_sdk_kms::Client::new(&sdk_config); + let client = MplKmsClient { client }; + Ok(Box::new(client)) +} + +//= spec/shim/esdk-shim.md#create-dynamodb-client +//# - The shim MUST provide an operation that creates a DynamoDB service client +//# backed by the core ESDK. +fn create_ddb_client(input: &ffi::MplAwsClientConfig) -> Result, String> { + //= spec/shim/esdk-shim.md#create-dynamodb-client + //# - Creating a DynamoDB client MUST apply the target-supplied client configuration, + //# as defined in [Service client configuration](#service-client-configuration). + let sdk_config = create_sdk_config(input)?; + let client = aws_sdk_dynamodb::Client::new(&sdk_config); + let client = MplDdbClient { client }; + Ok(Box::new(client)) +} + +//= spec/shim/esdk-shim.md#service-client-configuration +//= type=implication +//= reason=create_kms_client and create_ddb_client each build their SdkConfig from the same MplAwsClientConfig, so one configuration can be applied to multiple clients. +//# - The shim SHOULD allow one client configuration to be applied to multiple +//# service clients. +fn create_sdk_config(input: &ffi::MplAwsClientConfig) -> Result { + let shared_config = DAFNY_TOKIO_RUNTIME.block_on(aws_config::load_defaults( + aws_config::BehaviorVersion::latest(), + )); + + // Target (C++) and core (Rust) languages are fixed for this shim; the version + // is the crate version from Cargo.toml (i.e. the version this crate publishes). + let user_agent_string = shim_user_agent(); + let current_app_name = shared_config + .app_name() + .map(|app_name| app_name.to_string()) + .unwrap_or_default(); + let new_app_name = merge_user_agent(¤t_app_name, &user_agent_string); + let app_name = AppName::new(new_app_name).map_err(|e| format!("invalid app name: {:?}", e))?; + //= spec/shim/esdk-shim.md#service-client-configuration + //# - If the target supplies a retry configuration, the shim MUST apply it to each + //# service client. + let mut builder = shared_config + .to_builder() + .app_name(app_name) + .retry_config(make_retry_config(&input.retry)); + //= spec/shim/esdk-shim.md#service-client-configuration + //# - If the target supplies a region, the shim MUST apply it to each service client. + if !input.region.is_empty() { + builder = builder.region(Region::new(input.region.clone())); + } + Ok(builder.build()) +} + +//= spec/shim/esdk-shim.md#conformance-and-testing +//= type=exception +//= reason=Cross-implementation message interoperability is exercised by the shared ESDK test-vector suite maintained outside this shim crate, not within it. +//# - The ESDK shim SHOULD demonstrate message interoperability with other ESDK +//# implementations (for example via a shared test-vector suite). +#[cfg(test)] +mod tests; diff --git a/aws-esdk-cpp/aws-esdk-cpp/src/tests.rs b/aws-esdk-cpp/aws-esdk-cpp/src/tests.rs new file mode 100644 index 000000000..9e796c22e --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/src/tests.rs @@ -0,0 +1,658 @@ +//! Unit tests for the shim's pure conversion layer. +//! +//! These test the shim's OWN behavior (correct mapping + no target abort on +//! bad input), not ESDK crypto correctness. No AWS resources required. +//! +//! Declared from `lib.rs` as `#[cfg(test)] mod tests;`, so it is a child of the +//! crate root and reaches the crate-private conversion functions via `super::`. + +use super::*; +use ffi::EsdkAlgorithmSuiteId as F; +use ffi::EsdkCommitmentPolicy as P; + +// The complete set of algorithm-suite discriminants the shim supports. +// Mirrors the `ffi::EsdkAlgorithmSuiteId` enum in the bridge. +const ALG_REPRS: [u16; 11] = [ + 0x0014, 0x0046, 0x0078, 0x0114, 0x0146, 0x0178, 0x0214, 0x0346, 0x0378, 0x0478, 0x0578, +]; + +// alg_id_target_to_core: ffi enum -> core enum + +/// Exhaustiveness (ffi -> core): the set of values `alg_id_target_to_core` accepts must +/// be EXACTLY the known suite ids — no more, no fewer. Adding a suite id without +/// updating the conversion (or vice versa) fails this test. +//= spec/shim/shim.md#conformance-and-testing +//= type=test +//# - The shim SHOULD be tested for the behavior it owns — translation, handle +//# validation, error propagation, and lifetime safety — rather than by re-testing +//# the core library's own behavior. +// +//= spec/shim/esdk-shim.md#conformance-and-testing +//= type=test +//# - The ESDK shim MUST be tested for the behavior it owns — translation, handle +//# validation, error propagation, and lifetime safety — rather than by re-testing +//# the core ESDK's cryptographic behavior. +#[test] +fn alg_id_target_to_core_accepts_exactly_known_reprs() { + let mut accepted: Vec = (0..=u16::MAX) + .filter(|&n| alg_id_target_to_core(F { repr: n }).is_ok()) + .collect(); + accepted.sort_unstable(); + let mut expected = ALG_REPRS.to_vec(); + expected.sort_unstable(); + //= spec/shim/esdk-shim.md#algorithm-suite-identifier + //= type=test + //# - The shim MUST translate a target algorithm suite identifier to the core ESDK + //# algorithm suite that has the same two-byte ID. + assert_eq!(accepted, expected); +} + +/// Security property: NO value a C++ caller can supply may abort the target. +/// Sweeping the entire u16 domain proves `alg_id_target_to_core` returns Ok/Err for +/// every possible input and never panics. +//= spec/shim/shim.md#type-translation +//= type=test +//# - A translation reports failure by returning an error; it MUST NOT panic, +//# abort, or otherwise terminate the target process. +#[test] +fn alg_id_target_to_core_never_panics_over_full_range() { + for n in 0..=u16::MAX { + let _ = alg_id_target_to_core(F { repr: n }); + } +} + +/// An unknown suite id returns an error rather than panicking. +#[test] +fn alg_id_target_to_core_rejects_unknown() { + //= spec/shim/esdk-shim.md#algorithm-suite-identifier + //= type=test + //# - The shim MUST return an error when the target value is not one of the algorithm + //# suite IDs defined by the core ESDK. + // + //= spec/shim/shim.md#type-translation + //= type=test + //# - When the target supplies a value that has no corresponding core-library + //# representation, the translation MUST return an error. + let err = alg_id_target_to_core(F { repr: 0xFFFF }).unwrap_err(); + assert!(err.contains("unrecognized"), "unexpected error: {err}"); + assert!(alg_id_target_to_core(F { repr: 0x0000 }).is_err()); +} + +// alg_id_core_to_target: core enum -> ffi enum + +/// Every core variant maps to the expected ffi discriminant. +#[test] +fn alg_id_core_to_target_maps_every_core_variant() { + use aws_mpl_legacy::suites::EsdkAlgorithmSuiteId as C; + let pairs: [(C, u16); 11] = [ + (C::AlgAes128GcmIv12Tag16NoKdf, 0x0014), + (C::AlgAes192GcmIv12Tag16NoKdf, 0x0046), + (C::AlgAes256GcmIv12Tag16NoKdf, 0x0078), + (C::AlgAes128GcmIv12Tag16HkdfSha256, 0x0114), + (C::AlgAes192GcmIv12Tag16HkdfSha256, 0x0146), + (C::AlgAes256GcmIv12Tag16HkdfSha256, 0x0178), + (C::AlgAes128GcmIv12Tag16HkdfSha256EcdsaP256, 0x0214), + (C::AlgAes192GcmIv12Tag16HkdfSha384EcdsaP384, 0x0346), + (C::AlgAes256GcmIv12Tag16HkdfSha384EcdsaP384, 0x0378), + (C::AlgAes256GcmHkdfSha512CommitKey, 0x0478), + (C::AlgAes256GcmHkdfSha512CommitKeyEcdsaP384, 0x0578), + ]; + for (core, repr) in pairs { + //= spec/shim/esdk-shim.md#algorithm-suite-identifier + //= type=test + //# - The shim MUST translate a core ESDK algorithm suite to the target algorithm + //# suite identifier that has the same two-byte ID. + assert_eq!(alg_id_core_to_target(core).unwrap().repr, repr); + } +} + +/// Round-trip: every known ffi suite id survives ffi -> core -> ffi. +#[test] +fn alg_id_round_trips_through_both_conversions() { + for &n in &ALG_REPRS { + let core = alg_id_target_to_core(F { repr: n }).expect("known suite id converts"); + //= spec/shim/shim.md#type-translation + //= type=test + //= reason=The suite id survives ffi -> core -> ffi unchanged, proving the translation preserves meaning in both directions. + //# - A translation MUST convert between the target representation and the core + //# library representation, preserving meaning in both directions it supports. + let back = alg_id_core_to_target(core).expect("round-trips back"); + assert_eq!(back.repr, n); + } +} + +// commitment_policy_target_to_core: ffi enum -> core enum + +/// Exhaustiveness + correctness: each known repr maps to the core commitment +/// policy of the same meaning, and exactly the reprs {0,1,2} are accepted. +#[test] +fn commitment_policy_target_to_core_accepts_exactly_known_reprs() { + use aws_mpl_legacy::commitment::EsdkCommitmentPolicy as C; + let pairs: [(P, C); 3] = [ + (P::ForbidEncryptAllowDecrypt, C::ForbidEncryptAllowDecrypt), + (P::RequireEncryptAllowDecrypt, C::RequireEncryptAllowDecrypt), + (P::RequireEncryptRequireDecrypt, C::RequireEncryptRequireDecrypt), + ]; + for (target, expected_core) in pairs { + //= spec/shim/esdk-shim.md#commitment-policy + //= type=test + //# - The shim MUST translate the target commitment policy to the core ESDK + //# commitment policy of the same meaning. + assert_eq!( + commitment_policy_target_to_core(target).unwrap(), + expected_core + ); + } + + let accepted: Vec = (0..=u8::MAX) + .filter(|&n| commitment_policy_target_to_core(P { repr: n }).is_ok()) + .collect(); + //= spec/shim/esdk-shim.md#commitment-policy + //= type=test + //= reason=Sweeping 0..=u8::MAX, only 0,1,2 are accepted; every other value returns an error. + //# - The shim MUST return an error when the target commitment policy is not a supported + //# value. + assert_eq!(accepted, vec![0u8, 1, 2]); +} + +/// No commitment-policy value from C++ can abort the target. +#[test] +fn commitment_policy_target_to_core_never_panics_over_full_range() { + for n in 0..=u8::MAX { + let _ = commitment_policy_target_to_core(P { repr: n }); + } +} + +// encryption context: HashMap <-> Vec + +#[test] +fn encryption_context_round_trips() { + use std::collections::HashMap; + let mut m = HashMap::new(); + m.insert("k1".to_string(), "v1".to_string()); + m.insert("k2".to_string(), "v2".to_string()); + let list = encryption_context_core_to_target(m.clone()); + assert_eq!(list.len(), 2); + //= spec/shim/esdk-shim.md#encryption-context + //= type=test + //# - The shim MUST translate the target's encryption context, given as a list of + //# key-value pairs, to the core ESDK's key-value map, preserving every pair and + //# the exact key and value of each. + // + //= spec/shim/esdk-shim.md#encryption-context + //= type=test + //= reason=Round-trip map -> list -> map equals the original, proving the core-to-target conversion preserves every pair, key and value. + //# - The shim MUST translate the core ESDK's encryption context, given as a + //# key-value map, to the target's list of key-value pairs, preserving every pair + //# and the exact key and value of each. + assert_eq!(encryption_context_target_to_core(&list), m); +} + +#[test] +fn encryption_context_empty() { + // Regression: the empty map/list must translate to an empty result in both + // directions (no spurious pairs introduced), guarding the conversion helpers' + // edge case. + use std::collections::HashMap; + let empty: HashMap = HashMap::new(); + assert!(encryption_context_core_to_target(empty).is_empty()); + assert!(encryption_context_target_to_core(&[]).is_empty()); +} + +// Orchestration error paths (NO AWS resources required) +// These reach the null-checks / enum-validation in the create_*/encrypt/decrypt +// functions, which all return before any network call. They exercise the +// error-handling lines without credentials, so they run in ordinary CI. + +#[test] +fn encrypt_rejects_null_keyring() { + // default_encrypt_input() has a null keyring pointer. + //= spec/shim/esdk-shim.md#materials-source + //= type=test + //# - The shim MUST return an error, and MUST NOT invoke the core ESDK, when no + //# materials source is supplied. + let err = match encrypt(&default_encrypt_input()) { + Ok(_) => panic!("expected error"), + Err(e) => e, + }; + assert!(err.contains("keyring is null"), "unexpected error: {err}"); +} + +#[test] +fn decrypt_rejects_null_keyring() { + // Regression coverage for the symmetric decrypt null-check. The + // materials-source requirement is annotated once (on encrypt) to avoid a + // duplicate citation. + let err = match decrypt(&default_decrypt_input()) { + Ok(_) => panic!("expected error"), + Err(e) => e, + }; + assert!(err.contains("keyring is null"), "unexpected error: {err}"); +} + +#[test] +fn create_keystore_rejects_null_kms_client() { + // default config has null kms_client / ddb_client pointers. + let err = match create_keystore(&default_keystore_config()) { + Ok(_) => panic!("expected error"), + Err(e) => e, + }; + //= spec/shim/shim.md#handles-and-lifetimes + //= type=test + //# - Before dereferencing a target-supplied resource handle, the shim MUST check it + //# and MUST return an error when a required handle is absent. + // + //= spec/shim/esdk-shim.md#create-key-store + //= type=test + //# - Creating a key store MUST require a KMS client handle and a DynamoDB client + //# handle, checked as defined in + //# [Shim Specification: Handles and lifetimes](./shim.md#handles-and-lifetimes), + //# and MUST provide both to the core ESDK. + assert!(err.contains("kms_client is null"), "unexpected error: {err}"); +} + +#[test] +fn create_hierarchical_keyring_rejects_null_key_store() { + // default input has a null key_store pointer; the handle check fires before + // any network call. + //= spec/shim/esdk-shim.md#create-hierarchical-keyring + //= type=test + //# - Creating a hierarchical keyring MUST require a key store handle, checked as + //# defined in + //# [Shim Specification: Handles and lifetimes](./shim.md#handles-and-lifetimes), + //# and MUST provide it to the core ESDK. + let err = match create_hierarchical_keyring(&default_hierarchical_keyring_input()) { + Ok(_) => panic!("expected error"), + Err(e) => e, + }; + assert!(err.contains("key_store is null"), "unexpected error: {err}"); +} + +#[test] +fn make_kms_config_rejects_unknown_type() { + let mut cfg = default_keystore_config(); + cfg.kms_configuration_type = ffi::KmsConfigurationType { repr: 99 }; + //= spec/shim/esdk-shim.md#kms-configuration + //= type=test + //# - The shim MUST return an error when the target KMS configuration type is not a + //# supported value. + let err = make_kms_config(&cfg).unwrap_err(); + assert!(err.contains("Invalid KmsConfigurationType"), "unexpected error: {err}"); +} + +#[test] +fn make_kms_config_accepts_key_arn() { + // default type is KmsKeyArn -> exercises the happy arm (local, no AWS). + use aws_mpl_legacy::dafny::deps::aws_cryptography_keyStore::types::KmsConfiguration; + //= spec/shim/esdk-shim.md#kms-configuration + //= type=test + //# - The shim MUST translate a KMS key ARN configuration. + assert!(matches!( + make_kms_config(&default_keystore_config()).unwrap(), + KmsConfiguration::KmsKeyArn(_) + )); +} + +#[test] +fn make_kms_config_accepts_mr_key_arn() { + use aws_mpl_legacy::dafny::deps::aws_cryptography_keyStore::types::KmsConfiguration; + let mut cfg = default_keystore_config(); + cfg.kms_configuration_type = ffi::KmsConfigurationType::KmsMrKeyArn; + //= spec/shim/esdk-shim.md#kms-configuration + //= type=test + //# - The shim MUST translate a KMS multi-Region-key ARN configuration. + assert!(matches!( + make_kms_config(&cfg).unwrap(), + KmsConfiguration::KmsMrKeyArn(_) + )); +} + +#[test] +fn make_kms_config_accepts_discovery() { + use aws_mpl_legacy::dafny::deps::aws_cryptography_keyStore::types::KmsConfiguration; + let mut cfg = default_keystore_config(); + cfg.kms_configuration_type = ffi::KmsConfigurationType::Discovery; + //= spec/shim/esdk-shim.md#kms-configuration + //= type=test + //# - The shim MUST translate a discovery configuration. + assert!(matches!( + make_kms_config(&cfg).unwrap(), + KmsConfiguration::Discovery(_) + )); +} + +#[test] +fn make_kms_config_accepts_mr_discovery() { + use aws_mpl_legacy::dafny::deps::aws_cryptography_keyStore::types::KmsConfiguration; + let mut cfg = default_keystore_config(); + cfg.kms_configuration_type = ffi::KmsConfigurationType::MrDiscovery; + //= spec/shim/esdk-shim.md#kms-configuration + //= type=test + //# - The shim MUST translate a multi-Region-key discovery configuration. + assert!(matches!( + make_kms_config(&cfg).unwrap(), + KmsConfiguration::MrDiscovery(_) + )); +} + +#[test] +fn make_cache_type_rejects_unknown() { + let mut input = default_hierarchical_keyring_input(); + input.cache = ffi::CacheType { repr: 99 }; + //= spec/shim/esdk-shim.md#cache-configuration + //= type=test + //# - The shim MUST return an error when the target cache type is not a supported + //# value. + let err = make_cache_type(&input).unwrap_err(); + assert!(err.contains("Invalid CacheType"), "unexpected error: {err}"); +} + +#[test] +fn make_cache_type_builds_multi_threaded() { + // default cache is MultiThreaded -> exercises that arm (local, no AWS). + use aws_mpl_legacy::dafny::types::CacheType; + //= spec/shim/esdk-shim.md#cache-configuration + //= type=test + //# - The shim MUST translate a multi-threaded cache selection. + assert!(matches!( + make_cache_type(&default_hierarchical_keyring_input()).unwrap(), + CacheType::MultiThreaded(_) + )); +} + +#[test] +fn make_cache_type_builds_no_cache() { + use aws_mpl_legacy::dafny::types::CacheType; + let mut input = default_hierarchical_keyring_input(); + input.cache = ffi::CacheType::NoCache; + //= spec/shim/esdk-shim.md#cache-configuration + //= type=test + //# - The shim MUST translate a no-cache selection. + assert!(matches!( + make_cache_type(&input).unwrap(), + CacheType::No(_) + )); +} + +// Frame length + max-encrypted-data-keys translation (pure, no AWS) + +#[test] +fn make_frame_length_translates_and_rejects_zero() { + //= spec/shim/esdk-shim.md#frame-length + //= type=test + //# - The shim MUST translate the target frame length using the core ESDK's frame + //# length constructor, and MUST return an error when the core ESDK rejects the + //# value. + let err = make_frame_length(0).unwrap_err(); + assert!( + err.contains("invalid frame_length"), + "unexpected error: {err}" + ); + assert!(make_frame_length(4096).is_ok()); + assert!(make_frame_length(1).is_ok()); +} + +#[test] +fn max_edks_zero_is_no_limit_positive_is_limit() { + //= spec/shim/esdk-shim.md#maximum-encrypted-data-keys + //= type=test + //# The shim MUST translate zero + //# to the core ESDK's "no limit" representation, and a positive value `n` to a + //# limit of `n`. + assert_eq!(max_edks_target_to_core(0), None); + assert_eq!(max_edks_target_to_core(1), std::num::NonZeroUsize::new(1)); + assert_eq!(max_edks_target_to_core(42), std::num::NonZeroUsize::new(42)); +} + +// Service client user-agent + retry translation (pure, no AWS) + +#[test] +fn user_agent_form_and_append() { + // Empty existing app-name -> the shim's own user-agent, in the required form. + //= spec/shim/esdk-shim.md#service-client-configuration + //= type=test + //# - The shim MUST set a user-agent on each service client of the form + //# `AwsEncryptionSdk-Shim---`, where + //# `` is the target language, `` is the core + //# ESDK's implementation language, and `` is the shim's published version. + let ua = shim_user_agent(); + assert_eq!(merge_user_agent("", &ua), ua); + assert!(ua.starts_with("AwsEncryptionSdk-Shim-C++-Rust-")); + + // Existing app-name is preserved and the shim's UA appended, not replaced. + //= spec/shim/esdk-shim.md#service-client-configuration + //= type=test + //# - The shim MUST preserve any user-agent already present in the loaded + //# configuration, appending its own rather than replacing it. + let merged = merge_user_agent("existing-agent/1.0", &ua); + assert!(merged.starts_with("existing-agent/1.0"), "must preserve existing: {merged}"); + assert!(merged.contains(&ua), "must append shim UA: {merged}"); +} + +#[test] +fn make_retry_config_applies_a_default() { + // With no explicit values the shim still produces a (default) retry config. + //= spec/shim/esdk-shim.md#service-client-configuration + //= type=test + //= reason=make_retry_config always returns a standard/adaptive RetryConfig even when the target supplies no values. + //# - If the target does not supply a retry configuration, the shim MAY apply a + //# default retry configuration. + let cfg = default_retry_config(); + let _ = make_retry_config(&cfg); + // With an explicit max_attempts the translation carries it through. + let mut with_attempts = default_retry_config(); + with_attempts.max_attempts = 5; + assert_eq!(make_retry_config(&with_attempts).max_attempts(), 5); +} + +// Service client SdkConfig assembly (builds config, no credentials used) + +#[test] +fn create_sdk_config_applies_region_retry_and_user_agent() { + let mut cfg = default_client_config(); + cfg.region = "us-west-2".to_string(); + cfg.retry.max_attempts = 7; + let sdk = create_sdk_config(&cfg).expect("build sdk config"); + + let region: Option<&str> = sdk.region().map(|r| r.as_ref()); + //= spec/shim/esdk-shim.md#service-client-configuration + //= type=test + //# - If the target supplies a region, the shim MUST apply it to each service client. + assert_eq!(region, Some("us-west-2")); + + //= spec/shim/esdk-shim.md#service-client-configuration + //= type=test + //# - If the target supplies a retry configuration, the shim MUST apply it to each + //# service client. + assert_eq!(sdk.retry_config().map(|r| r.max_attempts()), Some(7)); + + let app_name: &str = sdk.app_name().expect("app name is set").as_ref(); + // Regression: the assembled SdkConfig carries the shim's user-agent; the + // user-agent form/append requirements are annotated in user_agent_form_and_append. + assert!(app_name.contains("AwsEncryptionSdk-Shim-C++-Rust-")); +} + +// Full round-trip integration test (REQUIRES real AWS resources) +// Skips cleanly when the ESDK_TEST_* env vars are unset, so it never fails +// credential-less CI. Run under `cargo llvm-cov` in a creds-enabled job to +// cover the create_*/encrypt/decrypt success paths. + +fn test_env(name: &str) -> Option { + std::env::var(name).ok().filter(|s| !s.is_empty()) +} + +#[test] +fn round_trip_integration() { + let (kms_arn, table, logical, branch) = match ( + test_env("ESDK_TEST_KMS_KEY_ARN"), + test_env("ESDK_TEST_DDB_TABLE"), + test_env("ESDK_TEST_LOGICAL_KEYSTORE"), + test_env("ESDK_TEST_BRANCH_KEY_ID"), + ) { + (Some(a), Some(b), Some(c), Some(d)) => (a, b, c, d), + _ => { + eprintln!( + "SKIP round_trip_integration: set ESDK_TEST_KMS_KEY_ARN, \ + ESDK_TEST_DDB_TABLE, ESDK_TEST_LOGICAL_KEYSTORE, ESDK_TEST_BRANCH_KEY_ID" + ); + return; + } + }; + + let mut client_cfg = default_client_config(); + client_cfg.region = test_env("ESDK_TEST_REGION").unwrap_or_default(); + + //= spec/shim/esdk-shim.md#create-kms-client + //= type=test + //# - The shim MUST provide an operation that creates a KMS service client backed by + //# the core ESDK. + // + //= spec/shim/esdk-shim.md#create-kms-client + //= type=test + //# - Creating a KMS client MUST apply the target-supplied client configuration, as + //# defined in [Service client configuration](#service-client-configuration). + let kms = create_kms_client(&client_cfg).expect("create kms client"); + + //= spec/shim/esdk-shim.md#create-dynamodb-client + //= type=test + //# - The shim MUST provide an operation that creates a DynamoDB service client + //# backed by the core ESDK. + // + //= spec/shim/esdk-shim.md#create-dynamodb-client + //= type=test + //# - Creating a DynamoDB client MUST apply the target-supplied client configuration, + //# as defined in [Service client configuration](#service-client-configuration). + let ddb = create_ddb_client(&client_cfg).expect("create ddb client"); + + let mut ks_cfg = default_keystore_config(); + //= spec/shim/esdk-shim.md#create-key-store + //= type=test + //# - Creating a key store MUST provide the target-supplied table name and logical key + //# store name to the core ESDK. + ks_cfg.ddb_table_name = table; + ks_cfg.logical_key_store_name = logical; + //= spec/shim/esdk-shim.md#create-key-store + //= type=test + //# - Creating a key store MUST provide the target-supplied KMS configuration to the + //# core ESDK, converted as defined in [KMS configuration](#kms-configuration). + ks_cfg.kms_configuration_type = ffi::KmsConfigurationType::KmsKeyArn; + ks_cfg.kms_configuration_value = kms_arn; + ks_cfg.kms_client = &*kms as *const MplKmsClient; + ks_cfg.ddb_client = &*ddb as *const MplDdbClient; + //= spec/shim/esdk-shim.md#create-key-store + //= type=test + //# - Creating a key store MUST provide the target-supplied key store id and grant + //# tokens to the core ESDK when present; an unset value is omitted. + ks_cfg.id = "shim-integration-test".to_string(); + ks_cfg.grant_tokens = vec!["grant-token-example".to_string()]; + //= spec/shim/esdk-shim.md#create-key-store + //= type=test + //# - The shim MUST provide an operation that creates a key store backed by the core + //# ESDK. + let keystore = create_keystore(&ks_cfg).expect("create keystore"); + + let mut kr_in = default_hierarchical_keyring_input(); + //= spec/shim/esdk-shim.md#create-hierarchical-keyring + //= type=test + //# - Creating a hierarchical keyring MUST provide the target-supplied branch key id + //# and time-to-live to the core ESDK. + kr_in.branch_key_id = branch; + kr_in.key_store = &*keystore as *const KeyStore; + //= spec/shim/esdk-shim.md#create-hierarchical-keyring + //= type=test + //# - Creating a hierarchical keyring MUST provide the target-supplied cache + //# configuration to the core ESDK, converted as defined in + //# [Cache configuration](#cache-configuration). + kr_in.cache = ffi::CacheType::MultiThreadedCache; + //= spec/shim/esdk-shim.md#create-hierarchical-keyring + //= type=test + //# - Creating a hierarchical keyring MUST provide the target-supplied partition id to + //# the core ESDK when present; an unset value is omitted. + kr_in.partition_id = "shim-partition".to_string(); + //= spec/shim/esdk-shim.md#create-hierarchical-keyring + //= type=test + //# - The shim MUST provide an operation that creates a hierarchical keyring backed + //# by the core ESDK. + let keyring = create_hierarchical_keyring(&kr_in).expect("create keyring"); + + let plaintext = b"Hello from the Rust integration test".to_vec(); + let mut ec = std::collections::HashMap::new(); + ec.insert("purpose".to_string(), "integration-test".to_string()); + + let mut enc_in = default_encrypt_input(); + enc_in.keyring = &*keyring as *const Keyring; + enc_in.plaintext = plaintext.as_slice(); + enc_in.encryption_context = ec + .iter() + .map(|(k, v)| ffi::EncryptionContextItem { key: k.clone(), value: v.clone() }) + .collect(); + enc_in.algorithm_suite_id = ffi::EsdkAlgorithmSuiteId::AlgAes256GcmHkdfSha512CommitKeyEcdsaP384; + // commitment policy, frame length, and max-EDKs are forwarded plumbing + // (plain source-side `implementation`); values here equal the ESDK defaults, so + // asserting on them would not falsify the forwarding — no `type=test` here. + enc_in.commitment_policy = ffi::EsdkCommitmentPolicy::RequireEncryptRequireDecrypt; + enc_in.frame_length = 4096; + enc_in.max_encrypted_data_keys = 3; + + let enc_out = encrypt(&enc_in).expect("encrypt"); + // Ciphertext differs from plaintext (encryption happened); the "unmodified" + // guarantee is proven below by the successful decrypt back to `plaintext`. + assert_ne!(enc_out.ciphertext, plaintext); + //= spec/shim/esdk-shim.md#encrypt-outputs + //= type=test + //# - `encrypt` MUST return the used algorithm suite, converted as defined in + //# [Algorithm suite identifier](#algorithm-suite-identifier). + // + //= spec/shim/esdk-shim.md#encrypt-inputs + //= type=test + //= reason=The returned used-suite equals the suite set on the input, proving the target-supplied algorithm suite reached the core ESDK. + //# - `encrypt` MUST provide the target-supplied algorithm suite to the core ESDK, + //# converted as defined in [Algorithm suite identifier](#algorithm-suite-identifier). + assert_eq!(enc_out.algorithm_suite_id.repr, enc_in.algorithm_suite_id.repr); + //= spec/shim/esdk-shim.md#encrypt-outputs + //= type=test + //# - `encrypt` MUST return the result encryption context, converted as defined in + //# [Encryption context](#encryption-context). + // + //= spec/shim/esdk-shim.md#encrypt-inputs + //= type=test + //= reason=The result encryption context contains the target-supplied pair, proving the encryption context reached the core ESDK. + //# - `encrypt` MUST provide the target-supplied encryption context to the core ESDK, + //# converted as defined in [Encryption context](#encryption-context). + assert_eq!( + encryption_context_target_to_core(&enc_out.encryption_context).get("purpose"), + Some(&"integration-test".to_string()) + ); + + let mut dec_in = default_decrypt_input(); + dec_in.keyring = &*keyring as *const Keyring; + dec_in.ciphertext = enc_out.ciphertext.as_slice(); + // commitment policy and max-EDKs are forwarded plumbing (plain source-side + // `implementation`); values here equal the ESDK defaults, so asserting on + // them would not falsify the forwarding — no `type=test` here. + dec_in.commitment_policy = ffi::EsdkCommitmentPolicy::RequireEncryptRequireDecrypt; + dec_in.max_encrypted_data_keys = 3; + //= spec/shim/esdk-shim.md#decrypt-inputs + //= type=test + //= reason=decrypt supplies the same encryption-context pair used at encrypt time; a successful round-trip proves it was provided to the core ESDK. + //# - `decrypt` MUST provide the target-supplied encryption context to the core ESDK, + //# converted as defined in [Encryption context](#encryption-context). + dec_in.encryption_context = ec + .iter() + .map(|(k, v)| ffi::EncryptionContextItem { key: k.clone(), value: v.clone() }) + .collect(); + + let dec_out = decrypt(&dec_in).expect("decrypt"); + // Round-trip fidelity — plaintext/ciphertext passed and returned unmodified, + // and the core operation actually invoked — is proven end-to-end through the + // C++ facade in test_esdk.cpp (see the `type=test` citations there). + assert_eq!(dec_out.plaintext, plaintext); + // The decrypt-output fields (used suite, result encryption context) are now + // surfaced by the C++ facade's DecryptResult and asserted there (test_esdk.cpp); + // these bridge-level checks remain but carry no duvet citation. + assert_eq!(dec_out.algorithm_suite_id.repr, enc_in.algorithm_suite_id.repr); + assert_eq!( + encryption_context_target_to_core(&dec_out.encryption_context).get("purpose"), + Some(&"integration-test".to_string()) + ); +} diff --git a/aws-esdk-cpp/aws-esdk-cpp/test_esdk.cpp b/aws-esdk-cpp/aws-esdk-cpp/test_esdk.cpp new file mode 100644 index 000000000..4e4a5eeae --- /dev/null +++ b/aws-esdk-cpp/aws-esdk-cpp/test_esdk.cpp @@ -0,0 +1,253 @@ +// test_esdk.cpp — integration tests for the idiomatic C++ facade (aws_esdk.hpp). +// +// These test the SHIM's own behavior through the public C++ API: +// * encrypt/decrypt round-trip fidelity, +// * encryption-context handling, +// * failures surface as Aws::Esdk::EsdkException (not a crash), +// * tampered ciphertext is rejected, +// * handle lifetime safety (a keyring keeps its clients/keystore alive even +// after the local wrappers go out of scope). +// +// They exercise the real crypto path, so they need real AWS resources. Provide +// them via environment variables; if any required var is unset the suite prints +// SKIP and exits 0 (so it never fails credential-less CI): +// +// ESDK_TEST_KMS_KEY_ARN KMS key ARN backing the key store +// ESDK_TEST_DDB_TABLE DynamoDB table name of the key store +// ESDK_TEST_LOGICAL_KEYSTORE logical key store name +// ESDK_TEST_BRANCH_KEY_ID branch key id provisioned in the key store +// ESDK_TEST_REGION (optional) AWS region, e.g. us-west-2 +// +// Build: see the `test_esdk` target in the Makefile (requires -std=c++17). + +#include +#include +#include +#include +#include + +#include + +// ---- Tiny assertion harness (no external test framework dependency) --------- +static int g_tests = 0; +static int g_failures = 0; + +#define CHECK(cond) \ + do { \ + ++g_tests; \ + if (!(cond)) { \ + ++g_failures; \ + std::cerr << "FAIL: " << #cond << " (" << __FILE__ << ":" \ + << __LINE__ << ")\n"; \ + } \ + } while (0) + +#define CHECK_THROWS_ESDK(expr) \ + do { \ + ++g_tests; \ + bool threw = false; \ + try { \ + expr; \ + } catch (const Aws::Esdk::EsdkException&) { \ + threw = true; \ + } catch (...) { \ + } \ + if (!threw) { \ + ++g_failures; \ + std::cerr << "FAIL: expected EsdkException from " << #expr << "\n"; \ + } \ + } while (0) + +namespace { + +struct TestConfig { + std::string kms_key_arn; + std::string ddb_table; + std::string logical_keystore; + std::string branch_key_id; + std::string region; +}; + +std::vector to_bytes(const std::string& s) { + return std::vector(s.begin(), s.end()); +} + +// Build a keyring. Deliberately constructs the clients/keystore as locals and +// moves them in, so the returned keyring is the sole owner — used by the +// lifetime test to prove the wrappers keep their dependencies alive. +Aws::Esdk::HierarchicalKeyring make_keyring(const TestConfig& cfg) { + auto client_config = Aws::Esdk::ClientConfig().with_max_retry_attempts(3); + if (!cfg.region.empty()) { + client_config.with_region(cfg.region); + } + Aws::Esdk::KmsClient kms(client_config); + Aws::Esdk::DdbClient ddb(client_config); + Aws::Esdk::KeyStore keystore(cfg.ddb_table, cfg.logical_keystore, + cfg.kms_key_arn, kms, ddb); + return Aws::Esdk::HierarchicalKeyring(std::move(keystore), cfg.branch_key_id, + /*ttl_seconds*/ 600, /*cache_capacity*/ 100); +} + +void test_round_trip(const TestConfig& cfg) { + auto keyring = make_keyring(cfg); + Aws::Esdk::EncryptionSDK sdk; + auto plaintext = to_bytes("Hello World"); + auto ciphertext = sdk.encrypt(plaintext, keyring); + CHECK(ciphertext != plaintext); + + //= spec/shim/shim.md#delegation + //= type=test + //= reason=Encrypting then decrypting back to the plaintext through the C++ facade proves the shim invoked the core library's encrypt and decrypt operations. + //# - Each operation the shim exposes MUST produce its result by invoking the + //# corresponding core-library operation. + // + //= spec/shim/esdk-shim.md#encrypt-inputs + //= type=test + //= reason=Round-tripping back to the original plaintext proves encrypt passed the target plaintext to the core library unmodified. + //# - `encrypt` MUST pass the target-supplied plaintext to the core ESDK unmodified. + // + //= spec/shim/esdk-shim.md#encrypt-outputs + //= type=test + //= reason=Decrypting the returned ciphertext back to the original plaintext proves encrypt returned the core library's ciphertext unmodified. + //# - `encrypt` MUST return the core ESDK's ciphertext unmodified. + // + //= spec/shim/esdk-shim.md#decrypt-inputs + //= type=test + //= reason=Decrypting this exact ciphertext back to the original plaintext proves it reached the core library unmodified; any modification would fail authentication. + //# - `decrypt` MUST pass the target-supplied ciphertext to the core ESDK unmodified. + // + //= spec/shim/esdk-shim.md#decrypt-outputs + //= type=test + //= reason=The recovered plaintext equals the original, proving decrypt returned the core library's plaintext unmodified. + //# - `decrypt` MUST return the core ESDK's plaintext unmodified. + auto decrypted = sdk.decrypt(ciphertext, keyring); + CHECK(decrypted.plaintext == plaintext); +} + +void test_round_trip_with_encryption_context(const TestConfig& cfg) { + auto keyring = make_keyring(cfg); + Aws::Esdk::EncryptionSDK sdk; + auto plaintext = to_bytes("context matters"); + std::map ec = {{"purpose", "test"}, {"origin", "cxx"}}; + auto ciphertext = sdk.encrypt(plaintext, keyring, + Aws::Esdk::AlgorithmSuiteId::AesGcm256Hkdf512CommitEcdsa384, + Aws::Esdk::CommitmentPolicy::RequireEncryptRequireDecrypt, ec); + auto decrypted = sdk.decrypt(ciphertext, keyring); + CHECK(decrypted.plaintext == plaintext); + + //= spec/shim/esdk-shim.md#decrypt-outputs + //= type=test + //= reason=The decrypt result exposes the encryption context the core library returned; it contains every pair supplied at encrypt time. + //# - `decrypt` MUST return the result encryption context, converted as defined in + //# [Encryption context](#encryption-context). + for (const auto& kv : ec) { + CHECK(decrypted.encryption_context.count(kv.first) == 1); + CHECK(decrypted.encryption_context[kv.first] == kv.second); + } + + //= spec/shim/esdk-shim.md#decrypt-outputs + //= type=test + //= reason=The decrypt result exposes the algorithm suite the core library used; it equals the suite selected at encrypt time. + //# - `decrypt` MUST return the used algorithm suite, converted as defined in + //# [Algorithm suite identifier](#algorithm-suite-identifier). + CHECK(decrypted.algorithm_suite_id == + Aws::Esdk::AlgorithmSuiteId::AesGcm256Hkdf512CommitEcdsa384); +} + +void test_decrypt_garbage_throws(const TestConfig& cfg) { + auto keyring = make_keyring(cfg); + Aws::Esdk::EncryptionSDK sdk; + auto garbage = to_bytes("this is not a valid ESDK message"); + // A failure must surface as an exception, never a crash/abort. + //= spec/shim/shim.md#delegation + //= type=test + //# - When a core-library operation returns an error, the shim MUST return an error to + //# the target and MUST NOT report the operation as successful. + CHECK_THROWS_ESDK(sdk.decrypt(garbage, keyring)); + + // The surfaced error identifies which operation failed (SHOULD context): + // EsdkException carries the core error string, which is prefixed "decrypt failed". + std::string msg; + try { + sdk.decrypt(garbage, keyring); + } catch (const Aws::Esdk::EsdkException& e) { + msg = e.what(); + } + //= spec/shim/shim.md#delegation + //= type=test + //# - An error the shim returns for a failed core-library operation SHOULD include + //# context identifying which operation failed. + CHECK(msg.find("decrypt") != std::string::npos); +} + +void test_tampered_ciphertext_throws(const TestConfig& cfg) { + auto keyring = make_keyring(cfg); + Aws::Esdk::EncryptionSDK sdk; + auto ciphertext = sdk.encrypt(to_bytes("tamper me"), keyring); + CHECK(!ciphertext.empty()); + ciphertext[ciphertext.size() / 2] ^= 0xFF; // flip a byte in the body + CHECK_THROWS_ESDK(sdk.decrypt(ciphertext, keyring)); +} + +// #3: the keyring is built inside make_keyring(); all local KmsClient/DdbClient/ +// KeyStore wrappers are destroyed when it returns. If the facade did NOT keep +// them alive, the raw pointers the bridge stored would dangle and this would +// crash. Succeeding proves the shared_ptr ownership works. +void test_lifetime_safety(const TestConfig& cfg) { + Aws::Esdk::HierarchicalKeyring keyring = make_keyring(cfg); + Aws::Esdk::EncryptionSDK sdk; + auto plaintext = to_bytes("outlives its dependencies"); + //= spec/shim/shim.md#handles-and-lifetimes + //= type=test + //= reason=make_keyring builds the KmsClient/DdbClient/KeyStore as locals and returns only the keyring; a successful encrypt+decrypt after those locals are destroyed proves the keyring retained ownership of its dependencies, so a handle could not outlive the resource it refers to. + //# - An owned interface that depends on another resource MUST retain ownership of + //# that resource for its own lifetime, so that a handle passed across the boundary + //# cannot outlive the resource it refers to. + auto ciphertext = sdk.encrypt(plaintext, keyring); + auto decrypted = sdk.decrypt(ciphertext, keyring); + CHECK(decrypted.plaintext == plaintext); +} + +const char* env_or_null(const char* name) { + const char* v = std::getenv(name); + return (v && *v) ? v : nullptr; +} + +} // namespace + +int main() { + const char* kms = env_or_null("ESDK_TEST_KMS_KEY_ARN"); + const char* ddb = env_or_null("ESDK_TEST_DDB_TABLE"); + const char* logical = env_or_null("ESDK_TEST_LOGICAL_KEYSTORE"); + const char* branch = env_or_null("ESDK_TEST_BRANCH_KEY_ID"); + const char* region = env_or_null("ESDK_TEST_REGION"); + + if (!kms || !ddb || !logical || !branch) { + std::cout << "SKIP: set ESDK_TEST_KMS_KEY_ARN, ESDK_TEST_DDB_TABLE, " + "ESDK_TEST_LOGICAL_KEYSTORE, and ESDK_TEST_BRANCH_KEY_ID " + "to run the C++ integration tests.\n"; + return 0; + } + + TestConfig cfg{kms, ddb, logical, branch, region ? region : ""}; + + // Each test builds its own keyring so a failure in one does not cascade. + try { + test_round_trip(cfg); + test_round_trip_with_encryption_context(cfg); + test_decrypt_garbage_throws(cfg); + test_tampered_ciphertext_throws(cfg); + test_lifetime_safety(cfg); + } catch (const std::exception& e) { + std::cerr << "FATAL: unexpected exception aborted the suite: " << e.what() << "\n"; + return 2; + } + + std::cout << (g_tests - g_failures) << "/" << g_tests << " checks passed\n"; + if (g_failures > 0) { + std::cerr << g_failures << " check(s) FAILED\n"; + return 1; + } + std::cout << "All C++ integration tests passed.\n"; + return 0; +} diff --git a/aws-esdk-cpp/main_idiomatic.cpp b/aws-esdk-cpp/main_idiomatic.cpp new file mode 100644 index 000000000..9ddcb318f --- /dev/null +++ b/aws-esdk-cpp/main_idiomatic.cpp @@ -0,0 +1,57 @@ +#include +#include +#include "aws_esdk.hpp" // Idiomatic C++ wrapper layer + +int main() { + try { + // Create AWS clients + auto client_config = aws_esdk::ClientConfig() + .with_max_retry_attempts(5); + + auto kms = aws_esdk::KmsClient(client_config); + auto ddb = aws_esdk::DdbClient(client_config); + + // Create keystore with constructor - all config in one place + auto keystore = aws_esdk::KeyStore( + "KeyStoreDdbTable", // table_name + "KeyStoreDdbTable", // logical_key_store_name + "arn:aws:kms:us-west-2:370957321024:key/9d989aa2-2f9c-438c-a745-cc57d3ad0126", // kms_arn + kms, + ddb + ); + + // Create hierarchical keyring with constructor + auto keyring = aws_esdk::HierarchicalKeyring( + keystore, + "3ce7656b-e166-40f3-8c9b-a920ce6596cd", // branch_key_id + 4242, // ttl_seconds + 42 // cache_capacity + ); + + // Create encryption SDK client + aws_esdk::EncryptionSDK sdk; + + // Encrypt with std::vector - idiomatic C++ + std::vector plaintext = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'}; + auto ciphertext = sdk.encrypt(plaintext, keyring); + + // Decrypt + auto decrypted = sdk.decrypt(ciphertext, keyring); + + // Validate results + if (plaintext != decrypted) { + std::cerr << "Decryption failed: plaintext mismatch\n"; + return 1; + } + + std::cout << "Success! Encryption and decryption completed successfully.\n"; + + // Automatic cleanup via RAII - no manual delete calls needed! + + } catch (const std::exception &e) { + std::cerr << "Error: " << e.what() << "\n"; + return 1; + } + + return 0; +} diff --git a/aws-esdk-cpp/src/lib.rs b/aws-esdk-cpp/src/lib.rs new file mode 100644 index 000000000..8ca453f83 --- /dev/null +++ b/aws-esdk-cpp/src/lib.rs @@ -0,0 +1 @@ +// Stub lib for aws-esdk-cpp-stub — tooling workaround, see aws-esdk-cpp/Cargo.toml. From 562f51275f2a55eca925140576bc091cdac8235d Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Thu, 9 Jul 2026 13:02:26 -0700 Subject: [PATCH 2/3] chore(native-rust): tidy aws-esdk-cpp crate for review - gitignore generated duvet output (.duvet/requirements/, snapshot.txt, reports/) and Cargo.lock; untrack the previously committed copies - remove doc_plan.md and main.cpp - move main_idiomatic.cpp to examples/basic_hierarchical_keyring_example.cpp - update Makefile: build the relocated example instead of main.cpp --- .../esdk-shim/algorithm-suite-identifier.toml | 49 - .../shim/esdk-shim/cache-configuration.toml | 28 - .../shim/esdk-shim/commitment-policy.toml | 23 - .../esdk-shim/conformance-and-testing.toml | 27 - .../esdk-shim/create-dynamodb-client.toml | 23 - .../create-hierarchical-keyring.toml | 56 - .../spec/shim/esdk-shim/create-key-store.toml | 54 - .../shim/esdk-shim/create-kms-client.toml | 23 - .../spec/shim/esdk-shim/decrypt-inputs.toml | 41 - .../spec/shim/esdk-shim/decrypt-outputs.toml | 30 - .../spec/shim/esdk-shim/encrypt-inputs.toml | 59 - .../spec/shim/esdk-shim/encrypt-outputs.toml | 30 - .../shim/esdk-shim/encryption-context.toml | 32 - .../spec/shim/esdk-shim/frame-length.toml | 16 - .../shim/esdk-shim/kms-configuration.toml | 42 - .../spec/shim/esdk-shim/materials-source.toml | 23 - .../maximum-encrypted-data-keys.toml | 16 - .../spec/shim/esdk-shim/overview.toml | 23 - .../service-client-configuration.toml | 66 - .../spec/shim/shim/concurrency.toml | 14 - .../shim/shim/conformance-and-testing.toml | 25 - .../creating-and-releasing-resources.toml | 31 - .../spec/shim/shim/delegation.toml | 49 - .../spec/shim/shim/handles-and-lifetimes.toml | 25 - .../spec/shim/shim/operation-contracts.toml | 24 - .../spec/shim/shim/owned-interface.toml | 45 - .../spec/shim/shim/streaming.toml | 14 - .../spec/shim/shim/type-translation.toml | 52 - aws-esdk-cpp/aws-esdk-cpp/.duvet/snapshot.txt | 224 -- aws-esdk-cpp/aws-esdk-cpp/.gitignore | 10 +- aws-esdk-cpp/aws-esdk-cpp/Cargo.lock | 2835 ----------------- aws-esdk-cpp/aws-esdk-cpp/Makefile | 42 +- aws-esdk-cpp/aws-esdk-cpp/doc_plan.md | 88 - .../basic_hierarchical_keyring_example.cpp} | 0 aws-esdk-cpp/aws-esdk-cpp/main.cpp | 61 - 35 files changed, 23 insertions(+), 4177 deletions(-) delete mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/algorithm-suite-identifier.toml delete mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/cache-configuration.toml delete mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/commitment-policy.toml delete mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/conformance-and-testing.toml delete mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/create-dynamodb-client.toml delete mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/create-hierarchical-keyring.toml delete mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/create-key-store.toml delete mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/create-kms-client.toml delete mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/decrypt-inputs.toml delete mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/decrypt-outputs.toml delete mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/encrypt-inputs.toml delete mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/encrypt-outputs.toml delete mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/encryption-context.toml delete mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/frame-length.toml delete mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/kms-configuration.toml delete mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/materials-source.toml delete mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/maximum-encrypted-data-keys.toml delete mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/overview.toml delete mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/service-client-configuration.toml delete mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/concurrency.toml delete mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/conformance-and-testing.toml delete mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/creating-and-releasing-resources.toml delete mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/delegation.toml delete mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/handles-and-lifetimes.toml delete mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/operation-contracts.toml delete mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/owned-interface.toml delete mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/streaming.toml delete mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/type-translation.toml delete mode 100644 aws-esdk-cpp/aws-esdk-cpp/.duvet/snapshot.txt delete mode 100644 aws-esdk-cpp/aws-esdk-cpp/Cargo.lock delete mode 100644 aws-esdk-cpp/aws-esdk-cpp/doc_plan.md rename aws-esdk-cpp/aws-esdk-cpp/{main_idiomatic.cpp => examples/basic_hierarchical_keyring_example.cpp} (100%) delete mode 100644 aws-esdk-cpp/aws-esdk-cpp/main.cpp diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/algorithm-suite-identifier.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/algorithm-suite-identifier.toml deleted file mode 100644 index 70f872c11..000000000 --- a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/algorithm-suite-identifier.toml +++ /dev/null @@ -1,49 +0,0 @@ -target = "spec/shim/esdk-shim.md#algorithm-suite-identifier" - -# Algorithm suite identifier -# -# The target algorithm suite identifier is the two-byte algorithm suite ID defined -# by the ESDK message format. -# -# Converting to the core ESDK: -# -# - The shim MUST translate a target algorithm suite identifier to the core ESDK -# algorithm suite that has the same two-byte ID. -# - The shim MUST return an error when the target value is not one of the algorithm -# suite IDs defined by the core ESDK. -# -# Converting from the core ESDK: -# -# - The shim MUST translate a core ESDK algorithm suite to the target algorithm -# suite identifier that has the same two-byte ID. -# - The shim MUST return an error when the core ESDK produces an algorithm suite -# the shim does not define. - -[[spec]] -level = "MUST" -quote = ''' -- The shim MUST translate a target algorithm suite identifier to the core ESDK -algorithm suite that has the same two-byte ID. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The shim MUST return an error when the target value is not one of the algorithm -suite IDs defined by the core ESDK. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The shim MUST translate a core ESDK algorithm suite to the target algorithm -suite identifier that has the same two-byte ID. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The shim MUST return an error when the core ESDK produces an algorithm suite -the shim does not define. -''' - diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/cache-configuration.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/cache-configuration.toml deleted file mode 100644 index 2e2118558..000000000 --- a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/cache-configuration.toml +++ /dev/null @@ -1,28 +0,0 @@ -target = "spec/shim/esdk-shim.md#cache-configuration" - -# Cache configuration -# -# - The shim MUST translate a no-cache selection. -# - The shim MUST translate a multi-threaded cache selection. -# - The shim MUST return an error when the target cache type is not a supported -# value. - -[[spec]] -level = "MUST" -quote = ''' -- The shim MUST translate a no-cache selection. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The shim MUST translate a multi-threaded cache selection. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The shim MUST return an error when the target cache type is not a supported -value. -''' - diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/commitment-policy.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/commitment-policy.toml deleted file mode 100644 index 253a5b1b5..000000000 --- a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/commitment-policy.toml +++ /dev/null @@ -1,23 +0,0 @@ -target = "spec/shim/esdk-shim.md#commitment-policy" - -# Commitment policy -# -# - The shim MUST translate the target commitment policy to the core ESDK -# commitment policy of the same meaning. -# - The shim MUST return an error when the target commitment policy is not a supported -# value. - -[[spec]] -level = "MUST" -quote = ''' -- The shim MUST translate the target commitment policy to the core ESDK -commitment policy of the same meaning. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The shim MUST return an error when the target commitment policy is not a supported -value. -''' - diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/conformance-and-testing.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/conformance-and-testing.toml deleted file mode 100644 index 59d14f5b4..000000000 --- a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/conformance-and-testing.toml +++ /dev/null @@ -1,27 +0,0 @@ -target = "spec/shim/esdk-shim.md#conformance-and-testing" - -# Conformance and testing -# -# In addition to the [Shim Specification conformance requirements](./shim.md#conformance-and-testing): -# -# - The ESDK shim MUST be tested for the behavior it owns — translation, handle -# validation, error propagation, and lifetime safety — rather than by re-testing -# the core ESDK's cryptographic behavior. -# - The ESDK shim SHOULD demonstrate message interoperability with other ESDK -# implementations (for example via a shared test-vector suite). - -[[spec]] -level = "MUST" -quote = ''' -- The ESDK shim MUST be tested for the behavior it owns — translation, handle -validation, error propagation, and lifetime safety — rather than by re-testing -the core ESDK's cryptographic behavior. -''' - -[[spec]] -level = "SHOULD" -quote = ''' -- The ESDK shim SHOULD demonstrate message interoperability with other ESDK -implementations (for example via a shared test-vector suite). -''' - diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/create-dynamodb-client.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/create-dynamodb-client.toml deleted file mode 100644 index a665a7189..000000000 --- a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/create-dynamodb-client.toml +++ /dev/null @@ -1,23 +0,0 @@ -target = "spec/shim/esdk-shim.md#create-dynamodb-client" - -# Create DynamoDB client -# -# - The shim MUST provide an operation that creates a DynamoDB service client -# backed by the core ESDK. -# - Creating a DynamoDB client MUST apply the target-supplied client configuration, -# as defined in [Service client configuration](#service-client-configuration). - -[[spec]] -level = "MUST" -quote = ''' -- The shim MUST provide an operation that creates a DynamoDB service client -backed by the core ESDK. -''' - -[[spec]] -level = "MUST" -quote = ''' -- Creating a DynamoDB client MUST apply the target-supplied client configuration, -as defined in [Service client configuration](#service-client-configuration). -''' - diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/create-hierarchical-keyring.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/create-hierarchical-keyring.toml deleted file mode 100644 index 763107d39..000000000 --- a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/create-hierarchical-keyring.toml +++ /dev/null @@ -1,56 +0,0 @@ -target = "spec/shim/esdk-shim.md#create-hierarchical-keyring" - -# Create hierarchical keyring -# -# - The shim MUST provide an operation that creates a hierarchical keyring backed -# by the core ESDK. -# - Creating a hierarchical keyring MUST require a key store handle, checked as -# defined in -# [Shim Specification: Handles and lifetimes](./shim.md#handles-and-lifetimes), -# and MUST provide it to the core ESDK. -# - Creating a hierarchical keyring MUST provide the target-supplied branch key id -# and time-to-live to the core ESDK. -# - Creating a hierarchical keyring MUST provide the target-supplied cache -# configuration to the core ESDK, converted as defined in -# [Cache configuration](#cache-configuration). -# - Creating a hierarchical keyring MUST provide the target-supplied partition id to -# the core ESDK when present; an unset value is omitted. - -[[spec]] -level = "MUST" -quote = ''' -- The shim MUST provide an operation that creates a hierarchical keyring backed -by the core ESDK. -''' - -[[spec]] -level = "MUST" -quote = ''' -- Creating a hierarchical keyring MUST require a key store handle, checked as -defined in -[Shim Specification: Handles and lifetimes](./shim.md#handles-and-lifetimes), -and MUST provide it to the core ESDK. -''' - -[[spec]] -level = "MUST" -quote = ''' -- Creating a hierarchical keyring MUST provide the target-supplied branch key id -and time-to-live to the core ESDK. -''' - -[[spec]] -level = "MUST" -quote = ''' -- Creating a hierarchical keyring MUST provide the target-supplied cache -configuration to the core ESDK, converted as defined in -[Cache configuration](#cache-configuration). -''' - -[[spec]] -level = "MUST" -quote = ''' -- Creating a hierarchical keyring MUST provide the target-supplied partition id to -the core ESDK when present; an unset value is omitted. -''' - diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/create-key-store.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/create-key-store.toml deleted file mode 100644 index 9b9698a27..000000000 --- a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/create-key-store.toml +++ /dev/null @@ -1,54 +0,0 @@ -target = "spec/shim/esdk-shim.md#create-key-store" - -# Create key store -# -# - The shim MUST provide an operation that creates a key store backed by the core -# ESDK. -# - Creating a key store MUST require a KMS client handle and a DynamoDB client -# handle, checked as defined in -# [Shim Specification: Handles and lifetimes](./shim.md#handles-and-lifetimes), -# and MUST provide both to the core ESDK. -# - Creating a key store MUST provide the target-supplied table name and logical key -# store name to the core ESDK. -# - Creating a key store MUST provide the target-supplied KMS configuration to the -# core ESDK, converted as defined in [KMS configuration](#kms-configuration). -# - Creating a key store MUST provide the target-supplied key store id and grant -# tokens to the core ESDK when present; an unset value is omitted. - -[[spec]] -level = "MUST" -quote = ''' -- The shim MUST provide an operation that creates a key store backed by the core -ESDK. -''' - -[[spec]] -level = "MUST" -quote = ''' -- Creating a key store MUST require a KMS client handle and a DynamoDB client -handle, checked as defined in -[Shim Specification: Handles and lifetimes](./shim.md#handles-and-lifetimes), -and MUST provide both to the core ESDK. -''' - -[[spec]] -level = "MUST" -quote = ''' -- Creating a key store MUST provide the target-supplied table name and logical key -store name to the core ESDK. -''' - -[[spec]] -level = "MUST" -quote = ''' -- Creating a key store MUST provide the target-supplied KMS configuration to the -core ESDK, converted as defined in [KMS configuration](#kms-configuration). -''' - -[[spec]] -level = "MUST" -quote = ''' -- Creating a key store MUST provide the target-supplied key store id and grant -tokens to the core ESDK when present; an unset value is omitted. -''' - diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/create-kms-client.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/create-kms-client.toml deleted file mode 100644 index 3052e0648..000000000 --- a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/create-kms-client.toml +++ /dev/null @@ -1,23 +0,0 @@ -target = "spec/shim/esdk-shim.md#create-kms-client" - -# Create KMS client -# -# - The shim MUST provide an operation that creates a KMS service client backed by -# the core ESDK. -# - Creating a KMS client MUST apply the target-supplied client configuration, as -# defined in [Service client configuration](#service-client-configuration). - -[[spec]] -level = "MUST" -quote = ''' -- The shim MUST provide an operation that creates a KMS service client backed by -the core ESDK. -''' - -[[spec]] -level = "MUST" -quote = ''' -- Creating a KMS client MUST apply the target-supplied client configuration, as -defined in [Service client configuration](#service-client-configuration). -''' - diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/decrypt-inputs.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/decrypt-inputs.toml deleted file mode 100644 index 759ca0dd4..000000000 --- a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/decrypt-inputs.toml +++ /dev/null @@ -1,41 +0,0 @@ -target = "spec/shim/esdk-shim.md#decrypt-inputs" - -# Decrypt inputs -# -# - `decrypt` MUST pass the target-supplied ciphertext to the core ESDK unmodified. -# - `decrypt` MUST provide the target-supplied encryption context to the core ESDK, -# converted as defined in [Encryption context](#encryption-context). -# - `decrypt` MUST provide the target-supplied commitment policy to the core ESDK, -# converted as defined in [Commitment policy](#commitment-policy). -# - `decrypt` MUST provide the target-supplied maximum-encrypted-data-keys value to -# the core ESDK, converted as defined in -# [Maximum encrypted data keys](#maximum-encrypted-data-keys). - -[[spec]] -level = "MUST" -quote = ''' -- `decrypt` MUST pass the target-supplied ciphertext to the core ESDK unmodified. -''' - -[[spec]] -level = "MUST" -quote = ''' -- `decrypt` MUST provide the target-supplied encryption context to the core ESDK, -converted as defined in [Encryption context](#encryption-context). -''' - -[[spec]] -level = "MUST" -quote = ''' -- `decrypt` MUST provide the target-supplied commitment policy to the core ESDK, -converted as defined in [Commitment policy](#commitment-policy). -''' - -[[spec]] -level = "MUST" -quote = ''' -- `decrypt` MUST provide the target-supplied maximum-encrypted-data-keys value to -the core ESDK, converted as defined in -[Maximum encrypted data keys](#maximum-encrypted-data-keys). -''' - diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/decrypt-outputs.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/decrypt-outputs.toml deleted file mode 100644 index 1f4daafe8..000000000 --- a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/decrypt-outputs.toml +++ /dev/null @@ -1,30 +0,0 @@ -target = "spec/shim/esdk-shim.md#decrypt-outputs" - -# Decrypt outputs -# -# - `decrypt` MUST return the core ESDK's plaintext unmodified. -# - `decrypt` MUST return the used algorithm suite, converted as defined in -# [Algorithm suite identifier](#algorithm-suite-identifier). -# - `decrypt` MUST return the result encryption context, converted as defined in -# [Encryption context](#encryption-context). - -[[spec]] -level = "MUST" -quote = ''' -- `decrypt` MUST return the core ESDK's plaintext unmodified. -''' - -[[spec]] -level = "MUST" -quote = ''' -- `decrypt` MUST return the used algorithm suite, converted as defined in -[Algorithm suite identifier](#algorithm-suite-identifier). -''' - -[[spec]] -level = "MUST" -quote = ''' -- `decrypt` MUST return the result encryption context, converted as defined in -[Encryption context](#encryption-context). -''' - diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/encrypt-inputs.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/encrypt-inputs.toml deleted file mode 100644 index 1c8303efd..000000000 --- a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/encrypt-inputs.toml +++ /dev/null @@ -1,59 +0,0 @@ -target = "spec/shim/esdk-shim.md#encrypt-inputs" - -# Encrypt inputs -# -# - `encrypt` MUST pass the target-supplied plaintext to the core ESDK unmodified. -# - `encrypt` MUST provide the target-supplied encryption context to the core ESDK, -# converted as defined in [Encryption context](#encryption-context). -# - `encrypt` MUST provide the target-supplied algorithm suite to the core ESDK, -# converted as defined in [Algorithm suite identifier](#algorithm-suite-identifier). -# - `encrypt` MUST provide the target-supplied commitment policy to the core ESDK, -# converted as defined in [Commitment policy](#commitment-policy). -# - `encrypt` MUST provide the target-supplied frame length to the core ESDK, -# converted as defined in [Frame length](#frame-length). -# - `encrypt` MUST provide the target-supplied maximum-encrypted-data-keys value to -# the core ESDK, converted as defined in -# [Maximum encrypted data keys](#maximum-encrypted-data-keys). - -[[spec]] -level = "MUST" -quote = ''' -- `encrypt` MUST pass the target-supplied plaintext to the core ESDK unmodified. -''' - -[[spec]] -level = "MUST" -quote = ''' -- `encrypt` MUST provide the target-supplied encryption context to the core ESDK, -converted as defined in [Encryption context](#encryption-context). -''' - -[[spec]] -level = "MUST" -quote = ''' -- `encrypt` MUST provide the target-supplied algorithm suite to the core ESDK, -converted as defined in [Algorithm suite identifier](#algorithm-suite-identifier). -''' - -[[spec]] -level = "MUST" -quote = ''' -- `encrypt` MUST provide the target-supplied commitment policy to the core ESDK, -converted as defined in [Commitment policy](#commitment-policy). -''' - -[[spec]] -level = "MUST" -quote = ''' -- `encrypt` MUST provide the target-supplied frame length to the core ESDK, -converted as defined in [Frame length](#frame-length). -''' - -[[spec]] -level = "MUST" -quote = ''' -- `encrypt` MUST provide the target-supplied maximum-encrypted-data-keys value to -the core ESDK, converted as defined in -[Maximum encrypted data keys](#maximum-encrypted-data-keys). -''' - diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/encrypt-outputs.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/encrypt-outputs.toml deleted file mode 100644 index 69caa83c0..000000000 --- a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/encrypt-outputs.toml +++ /dev/null @@ -1,30 +0,0 @@ -target = "spec/shim/esdk-shim.md#encrypt-outputs" - -# Encrypt outputs -# -# - `encrypt` MUST return the core ESDK's ciphertext unmodified. -# - `encrypt` MUST return the used algorithm suite, converted as defined in -# [Algorithm suite identifier](#algorithm-suite-identifier). -# - `encrypt` MUST return the result encryption context, converted as defined in -# [Encryption context](#encryption-context). - -[[spec]] -level = "MUST" -quote = ''' -- `encrypt` MUST return the core ESDK's ciphertext unmodified. -''' - -[[spec]] -level = "MUST" -quote = ''' -- `encrypt` MUST return the used algorithm suite, converted as defined in -[Algorithm suite identifier](#algorithm-suite-identifier). -''' - -[[spec]] -level = "MUST" -quote = ''' -- `encrypt` MUST return the result encryption context, converted as defined in -[Encryption context](#encryption-context). -''' - diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/encryption-context.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/encryption-context.toml deleted file mode 100644 index d54302bbf..000000000 --- a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/encryption-context.toml +++ /dev/null @@ -1,32 +0,0 @@ -target = "spec/shim/esdk-shim.md#encryption-context" - -# Encryption context -# -# Converting to the core ESDK: -# -# - The shim MUST translate the target's encryption context, given as a list of -# key-value pairs, to the core ESDK's key-value map, preserving every pair and -# the exact key and value of each. -# -# Converting from the core ESDK: -# -# - The shim MUST translate the core ESDK's encryption context, given as a -# key-value map, to the target's list of key-value pairs, preserving every pair -# and the exact key and value of each. - -[[spec]] -level = "MUST" -quote = ''' -- The shim MUST translate the target's encryption context, given as a list of -key-value pairs, to the core ESDK's key-value map, preserving every pair and -the exact key and value of each. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The shim MUST translate the core ESDK's encryption context, given as a -key-value map, to the target's list of key-value pairs, preserving every pair -and the exact key and value of each. -''' - diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/frame-length.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/frame-length.toml deleted file mode 100644 index 2fd5eacee..000000000 --- a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/frame-length.toml +++ /dev/null @@ -1,16 +0,0 @@ -target = "spec/shim/esdk-shim.md#frame-length" - -# Frame length -# -# - The shim MUST translate the target frame length using the core ESDK's frame -# length constructor, and MUST return an error when the core ESDK rejects the -# value. - -[[spec]] -level = "MUST" -quote = ''' -- The shim MUST translate the target frame length using the core ESDK's frame -length constructor, and MUST return an error when the core ESDK rejects the -value. -''' - diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/kms-configuration.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/kms-configuration.toml deleted file mode 100644 index 0facf7fa9..000000000 --- a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/kms-configuration.toml +++ /dev/null @@ -1,42 +0,0 @@ -target = "spec/shim/esdk-shim.md#kms-configuration" - -# KMS configuration -# -# - The shim MUST translate a KMS key ARN configuration. -# - The shim MUST translate a KMS multi-Region-key ARN configuration. -# - The shim MUST translate a discovery configuration. -# - The shim MUST translate a multi-Region-key discovery configuration. -# - The shim MUST return an error when the target KMS configuration type is not a -# supported value. - -[[spec]] -level = "MUST" -quote = ''' -- The shim MUST translate a KMS key ARN configuration. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The shim MUST translate a KMS multi-Region-key ARN configuration. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The shim MUST translate a discovery configuration. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The shim MUST translate a multi-Region-key discovery configuration. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The shim MUST return an error when the target KMS configuration type is not a -supported value. -''' - diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/materials-source.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/materials-source.toml deleted file mode 100644 index abcd50fa8..000000000 --- a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/materials-source.toml +++ /dev/null @@ -1,23 +0,0 @@ -target = "spec/shim/esdk-shim.md#materials-source" - -# Materials source -# -# - Each of `encrypt` and `decrypt` MUST be supplied with exactly one materials -# source (see [Resources](#resources)). -# - The shim MUST return an error, and MUST NOT invoke the core ESDK, when no -# materials source is supplied. - -[[spec]] -level = "MUST" -quote = ''' -- Each of `encrypt` and `decrypt` MUST be supplied with exactly one materials -source (see [Resources](#resources)). -''' - -[[spec]] -level = "MUST" -quote = ''' -- The shim MUST return an error, and MUST NOT invoke the core ESDK, when no -materials source is supplied. -''' - diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/maximum-encrypted-data-keys.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/maximum-encrypted-data-keys.toml deleted file mode 100644 index 436ddeb7e..000000000 --- a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/maximum-encrypted-data-keys.toml +++ /dev/null @@ -1,16 +0,0 @@ -target = "spec/shim/esdk-shim.md#maximum-encrypted-data-keys" - -# Maximum encrypted data keys -# -# - The target represents "no limit" as the value zero. The shim MUST translate zero -# to the core ESDK's "no limit" representation, and a positive value `n` to a -# limit of `n`. - -[[spec]] -level = "MUST" -quote = ''' -The shim MUST translate zero -to the core ESDK's "no limit" representation, and a positive value `n` to a -limit of `n`. -''' - diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/overview.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/overview.toml deleted file mode 100644 index 96b9cfcff..000000000 --- a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/overview.toml +++ /dev/null @@ -1,23 +0,0 @@ -target = "spec/shim/esdk-shim.md#overview" - -# Overview -# -# This document specifies a **shim** whose **core library** is a compliant AWS -# Encryption SDK implementation (the **core ESDK**). An ESDK shim exposes the core -# ESDK to a consumer running in another language or runtime (the **target**). -# -# An ESDK shim MUST conform to the generic [Shim Specification](./shim.md). This -# document defines only the ESDK-specific detail that specification defers to a -# core-library-specific spec: the concrete [type translations](#type-translation), -# [resources](#resources), and [operations](#operation-contracts) an ESDK shim -# exposes. -# -# A shim is not an ESDK implementation. It delegates the message format, -# cryptography, key derivation, commitment, and signing to the core ESDK. - -[[spec]] -level = "MUST" -quote = ''' -An ESDK shim MUST conform to the generic [Shim Specification](./shim.md). -''' - diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/service-client-configuration.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/service-client-configuration.toml deleted file mode 100644 index f875f002c..000000000 --- a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/esdk-shim/service-client-configuration.toml +++ /dev/null @@ -1,66 +0,0 @@ -target = "spec/shim/esdk-shim.md#service-client-configuration" - -# Service client configuration -# -# The shim configures each AWS service client it creates from a client -# configuration supplied by the target. Any value the target supplies is passed -# through to the service client; where the target omits a value, the shim may -# apply a default. -# -# - The shim MUST set a user-agent on each service client of the form -# `AwsEncryptionSdk-Shim---`, where -# `` is the target language, `` is the core -# ESDK's implementation language, and `` is the shim's published version. -# - The shim MUST preserve any user-agent already present in the loaded -# configuration, appending its own rather than replacing it. -# - If the target supplies a retry configuration, the shim MUST apply it to each -# service client. -# - If the target does not supply a retry configuration, the shim MAY apply a -# default retry configuration. -# - If the target supplies a region, the shim MUST apply it to each service client. -# - The shim SHOULD allow one client configuration to be applied to multiple -# service clients. - -[[spec]] -level = "MUST" -quote = ''' -- The shim MUST set a user-agent on each service client of the form -`AwsEncryptionSdk-Shim---`, where -`` is the target language, `` is the core -ESDK's implementation language, and `` is the shim's published version. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The shim MUST preserve any user-agent already present in the loaded -configuration, appending its own rather than replacing it. -''' - -[[spec]] -level = "MUST" -quote = ''' -- If the target supplies a retry configuration, the shim MUST apply it to each -service client. -''' - -[[spec]] -level = "MAY" -quote = ''' -- If the target does not supply a retry configuration, the shim MAY apply a -default retry configuration. -''' - -[[spec]] -level = "MUST" -quote = ''' -- If the target supplies a region, the shim MUST apply it to each service client. -''' - -[[spec]] -level = "SHOULD" -quote = ''' -- The shim SHOULD allow one client configuration to be applied to multiple -service clients. -''' - diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/concurrency.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/concurrency.toml deleted file mode 100644 index 9b5416aa1..000000000 --- a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/concurrency.toml +++ /dev/null @@ -1,14 +0,0 @@ -target = "spec/shim/shim.md#concurrency" - -# Concurrency -# -# If a core library resource or operation supports concurrent use from multiple threads, -# the shim library SHOULD support it as well. - -[[spec]] -level = "SHOULD" -quote = ''' -If a core library resource or operation supports concurrent use from multiple threads, -the shim library SHOULD support it as well. -''' - diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/conformance-and-testing.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/conformance-and-testing.toml deleted file mode 100644 index c24d06513..000000000 --- a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/conformance-and-testing.toml +++ /dev/null @@ -1,25 +0,0 @@ -target = "spec/shim/shim.md#conformance-and-testing" - -# Conformance and testing -# -# - A shim MUST conform to this specification in addition to its core-library-specific -# shim specification. -# - The shim SHOULD be tested for the behavior it owns — translation, handle -# validation, error propagation, and lifetime safety — rather than by re-testing -# the core library's own behavior. - -[[spec]] -level = "MUST" -quote = ''' -- A shim MUST conform to this specification in addition to its core-library-specific -shim specification. -''' - -[[spec]] -level = "SHOULD" -quote = ''' -- The shim SHOULD be tested for the behavior it owns — translation, handle -validation, error propagation, and lifetime safety — rather than by re-testing -the core library's own behavior. -''' - diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/creating-and-releasing-resources.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/creating-and-releasing-resources.toml deleted file mode 100644 index c1090b8c8..000000000 --- a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/creating-and-releasing-resources.toml +++ /dev/null @@ -1,31 +0,0 @@ -target = "spec/shim/shim.md#creating-and-releasing-resources" - -# Creating and releasing resources -# -# - For each resource kind, the shim MUST provide a means for the target to create an -# instance backed by the core library. -# - The shim MUST release the core-library resource backing an owned interface once -# the target no longer holds it. The shim MAY release it automatically when the -# owned interface is destroyed, or through an explicit target operation. - -[[spec]] -level = "MUST" -quote = ''' -- For each resource kind, the shim MUST provide a means for the target to create an -instance backed by the core library. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The shim MUST release the core-library resource backing an owned interface once -the target no longer holds it. -''' - -[[spec]] -level = "MAY" -quote = ''' -The shim MAY release it automatically when the -owned interface is destroyed, or through an explicit target operation. -''' - diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/delegation.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/delegation.toml deleted file mode 100644 index 416f4fa55..000000000 --- a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/delegation.toml +++ /dev/null @@ -1,49 +0,0 @@ -target = "spec/shim/shim.md#delegation" - -# Delegation -# -# The shim implements none of the core library's behavior of its own; it forwards -# each operation to the core library and lets the core library do the work and -# enforce validity. These requirements pin down that forwarding. -# -# - Each operation the shim exposes MUST produce its result by invoking the -# corresponding core-library operation. -# - The shim MUST NOT validate operation or resource-creation input values itself; -# it MUST translate each input and defer its validation to the core library. -# - When a core-library operation returns an error, the shim MUST return an error to -# the target and MUST NOT report the operation as successful. -# - An error the shim returns for a failed core-library operation SHOULD include -# context identifying which operation failed. -# -# Checking a target-supplied handle for presence before dereferencing it (see -# [Handles and lifetimes](#handles-and-lifetimes)) is a memory-safety measure, not -# input validation, and is not subject to the rule above. - -[[spec]] -level = "MUST" -quote = ''' -- Each operation the shim exposes MUST produce its result by invoking the -corresponding core-library operation. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The shim MUST NOT validate operation or resource-creation input values itself; -it MUST translate each input and defer its validation to the core library. -''' - -[[spec]] -level = "MUST" -quote = ''' -- When a core-library operation returns an error, the shim MUST return an error to -the target and MUST NOT report the operation as successful. -''' - -[[spec]] -level = "SHOULD" -quote = ''' -- An error the shim returns for a failed core-library operation SHOULD include -context identifying which operation failed. -''' - diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/handles-and-lifetimes.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/handles-and-lifetimes.toml deleted file mode 100644 index 7d09d3723..000000000 --- a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/handles-and-lifetimes.toml +++ /dev/null @@ -1,25 +0,0 @@ -target = "spec/shim/shim.md#handles-and-lifetimes" - -# Handles and lifetimes -# -# - Before dereferencing a target-supplied resource handle, the shim MUST check it -# and MUST return an error when a required handle is absent. -# - An owned interface that depends on another resource MUST retain ownership of -# that resource for its own lifetime, so that a handle passed across the boundary -# cannot outlive the resource it refers to. - -[[spec]] -level = "MUST" -quote = ''' -- Before dereferencing a target-supplied resource handle, the shim MUST check it -and MUST return an error when a required handle is absent. -''' - -[[spec]] -level = "MUST" -quote = ''' -- An owned interface that depends on another resource MUST retain ownership of -that resource for its own lifetime, so that a handle passed across the boundary -cannot outlive the resource it refers to. -''' - diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/operation-contracts.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/operation-contracts.toml deleted file mode 100644 index 9176e5360..000000000 --- a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/operation-contracts.toml +++ /dev/null @@ -1,24 +0,0 @@ -target = "spec/shim/shim.md#operation-contracts" - -# Operation contracts -# -# - For each operation the shim exposes, its core-library-specific shim -# specification defines which inputs are required, how each input is handled, -# and how each output field is handled. -# - Except where an input or output is passed through unmodified, each MUST be -# translated per [Type translation](#type-translation). -# - Each operation MUST invoke the core library per [Delegation](#delegation). - -[[spec]] -level = "MUST" -quote = ''' -- Except where an input or output is passed through unmodified, each MUST be -translated per [Type translation](#type-translation). -''' - -[[spec]] -level = "MUST" -quote = ''' -- Each operation MUST invoke the core library per [Delegation](#delegation). -''' - diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/owned-interface.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/owned-interface.toml deleted file mode 100644 index 45ffa01bf..000000000 --- a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/owned-interface.toml +++ /dev/null @@ -1,45 +0,0 @@ -target = "spec/shim/shim.md#owned-interface" - -# Owned interface -# -# The owned interface is the public surface the target programs against. Its purpose -# is to decouple the target from the generator: because the target depends only on -# types the shim defines — never on generator-produced types — the binding -# generator can be changed or replaced without breaking target code. The following -# requirements keep that boundary intact. -# -# - The shim MUST define its own error type for its public surface. -# - For each core-library enumeration it exposes, the shim MUST define its own -# corresponding enumeration type. -# - Each public function the shim exposes MUST use only owned-interface types or -# standard-library types in its signature. -# - Each owned interface that represents a core-library resource MUST hold the -# generated handle privately and MUST NOT expose it in its public API. - -[[spec]] -level = "MUST" -quote = ''' -- The shim MUST define its own error type for its public surface. -''' - -[[spec]] -level = "MUST" -quote = ''' -- For each core-library enumeration it exposes, the shim MUST define its own -corresponding enumeration type. -''' - -[[spec]] -level = "MUST" -quote = ''' -- Each public function the shim exposes MUST use only owned-interface types or -standard-library types in its signature. -''' - -[[spec]] -level = "MUST" -quote = ''' -- Each owned interface that represents a core-library resource MUST hold the -generated handle privately and MUST NOT expose it in its public API. -''' - diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/streaming.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/streaming.toml deleted file mode 100644 index 76cff5daf..000000000 --- a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/streaming.toml +++ /dev/null @@ -1,14 +0,0 @@ -target = "spec/shim/shim.md#streaming" - -# Streaming -# -# If a core library resource or operation supports [streamed](../client-apis/streaming.md) input/outputs, -# the shim library SHOULD support it as well. - -[[spec]] -level = "SHOULD" -quote = ''' -If a core library resource or operation supports [streamed](../client-apis/streaming.md) input/outputs, -the shim library SHOULD support it as well. -''' - diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/type-translation.toml b/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/type-translation.toml deleted file mode 100644 index 78ffa92eb..000000000 --- a/aws-esdk-cpp/aws-esdk-cpp/.duvet/requirements/spec/shim/shim/type-translation.toml +++ /dev/null @@ -1,52 +0,0 @@ -target = "spec/shim/shim.md#type-translation" - -# Type translation -# -# A shim converts each value between its target representation and the core -# library's representation. This generic specification does not enumerate concrete -# types; a core-library-specific shim specification defines a translation for -# each value it exposes. Every such translation MUST obey the following rules. -# -# - A translation MUST convert between the target representation and the core -# library representation, preserving meaning in both directions it supports. -# - A translation reports failure by returning an error; it MUST NOT panic, abort, -# or otherwise terminate the target process. -# - When the target supplies a value that has no corresponding core-library -# representation, the translation MUST return an error. -# - When the core library produces a value the shim does not define, the -# translation MUST return an error. - -[[spec]] -level = "MUST" -quote = ''' -Every such translation MUST obey the following rules. -''' - -[[spec]] -level = "MUST" -quote = ''' -- A translation MUST convert between the target representation and the core -library representation, preserving meaning in both directions it supports. -''' - -[[spec]] -level = "MUST" -quote = ''' -- A translation reports failure by returning an error; it MUST NOT panic, abort, -or otherwise terminate the target process. -''' - -[[spec]] -level = "MUST" -quote = ''' -- When the target supplies a value that has no corresponding core-library -representation, the translation MUST return an error. -''' - -[[spec]] -level = "MUST" -quote = ''' -- When the core library produces a value the shim does not define, the -translation MUST return an error. -''' - diff --git a/aws-esdk-cpp/aws-esdk-cpp/.duvet/snapshot.txt b/aws-esdk-cpp/aws-esdk-cpp/.duvet/snapshot.txt deleted file mode 100644 index b26c8fad4..000000000 --- a/aws-esdk-cpp/aws-esdk-cpp/.duvet/snapshot.txt +++ /dev/null @@ -1,224 +0,0 @@ -SPECIFICATION: [ESDK Shim Specification](spec/shim/esdk-shim.md) - SECTION: [Overview](#overview) - TEXT[!MUST,implication]: An ESDK shim MUST conform to the generic [Shim Specification](./shim.md). - - SECTION: [Algorithm suite identifier](#algorithm-suite-identifier) - TEXT[!MUST,implementation,test]: - The shim MUST translate a target algorithm suite identifier to the core ESDK - TEXT[!MUST,implementation,test]: algorithm suite that has the same two-byte ID. - TEXT[!MUST,implementation,test]: - The shim MUST return an error when the target value is not one of the algorithm - TEXT[!MUST,implementation,test]: suite IDs defined by the core ESDK. - TEXT[!MUST,implementation,test]: - The shim MUST translate a core ESDK algorithm suite to the target algorithm - TEXT[!MUST,implementation,test]: suite identifier that has the same two-byte ID. - TEXT[!MUST,implication]: - The shim MUST return an error when the core ESDK produces an algorithm suite - TEXT[!MUST,implication]: the shim does not define. - - SECTION: [Commitment policy](#commitment-policy) - TEXT[!MUST,implementation,test]: - The shim MUST translate the target commitment policy to the core ESDK - TEXT[!MUST,implementation,test]: commitment policy of the same meaning. - TEXT[!MUST,implementation,test]: - The shim MUST return an error when the target commitment policy is not a supported - TEXT[!MUST,implementation,test]: value. - - SECTION: [Encryption context](#encryption-context) - TEXT[!MUST,implementation,test]: - The shim MUST translate the target's encryption context, given as a list of - TEXT[!MUST,implementation,test]: key-value pairs, to the core ESDK's key-value map, preserving every pair and - TEXT[!MUST,implementation,test]: the exact key and value of each. - TEXT[!MUST,implementation,test]: - The shim MUST translate the core ESDK's encryption context, given as a - TEXT[!MUST,implementation,test]: key-value map, to the target's list of key-value pairs, preserving every pair - TEXT[!MUST,implementation,test]: and the exact key and value of each. - - SECTION: [Maximum encrypted data keys](#maximum-encrypted-data-keys) - TEXT[!MUST,implementation,test]: The shim MUST translate zero - TEXT[!MUST,implementation,test]: to the core ESDK's "no limit" representation, and a positive value `n` to a - TEXT[!MUST,implementation,test]: limit of `n`. - - SECTION: [Frame length](#frame-length) - TEXT[!MUST,implementation,test]: - The shim MUST translate the target frame length using the core ESDK's frame - TEXT[!MUST,implementation,test]: length constructor, and MUST return an error when the core ESDK rejects the - TEXT[!MUST,implementation,test]: value. - - SECTION: [KMS configuration](#kms-configuration) - TEXT[!MUST,implementation,test]: - The shim MUST translate a KMS key ARN configuration. - TEXT[!MUST,implementation,test]: - The shim MUST translate a KMS multi-Region-key ARN configuration. - TEXT[!MUST,implementation,test]: - The shim MUST translate a discovery configuration. - TEXT[!MUST,implementation,test]: - The shim MUST translate a multi-Region-key discovery configuration. - TEXT[!MUST,implementation,test]: - The shim MUST return an error when the target KMS configuration type is not a - TEXT[!MUST,implementation,test]: supported value. - - SECTION: [Cache configuration](#cache-configuration) - TEXT[!MUST,implementation,test]: - The shim MUST translate a no-cache selection. - TEXT[!MUST,implementation,test]: - The shim MUST translate a multi-threaded cache selection. - TEXT[!MUST,implementation,test]: - The shim MUST return an error when the target cache type is not a supported - TEXT[!MUST,implementation,test]: value. - - SECTION: [Service client configuration](#service-client-configuration) - TEXT[!MUST,implementation,test]: - The shim MUST set a user-agent on each service client of the form - TEXT[!MUST,implementation,test]: `AwsEncryptionSdk-Shim---`, where - TEXT[!MUST,implementation,test]: `` is the target language, `` is the core - TEXT[!MUST,implementation,test]: ESDK's implementation language, and `` is the shim's published version. - TEXT[!MUST,implementation,test]: - The shim MUST preserve any user-agent already present in the loaded - TEXT[!MUST,implementation,test]: configuration, appending its own rather than replacing it. - TEXT[!MUST,implementation,test]: - If the target supplies a retry configuration, the shim MUST apply it to each - TEXT[!MUST,implementation,test]: service client. - TEXT[!MAY,implementation,test]: - If the target does not supply a retry configuration, the shim MAY apply a - TEXT[!MAY,implementation,test]: default retry configuration. - TEXT[!MUST,implementation,test]: - If the target supplies a region, the shim MUST apply it to each service client. - TEXT[!SHOULD,implication]: - The shim SHOULD allow one client configuration to be applied to multiple - TEXT[!SHOULD,implication]: service clients. - - SECTION: [Materials source](#materials-source) - TEXT[!MUST,implication]: - Each of `encrypt` and `decrypt` MUST be supplied with exactly one materials - TEXT[!MUST,implication]: source (see [Resources](#resources)). - TEXT[!MUST,implementation,test]: - The shim MUST return an error, and MUST NOT invoke the core ESDK, when no - TEXT[!MUST,implementation,test]: materials source is supplied. - - SECTION: [Encrypt inputs](#encrypt-inputs) - TEXT[!MUST,implementation,test]: - `encrypt` MUST pass the target-supplied plaintext to the core ESDK unmodified. - TEXT[!MUST,implementation,test]: - `encrypt` MUST provide the target-supplied encryption context to the core ESDK, - TEXT[!MUST,implementation,test]: converted as defined in [Encryption context](#encryption-context). - TEXT[!MUST,implementation,test]: - `encrypt` MUST provide the target-supplied algorithm suite to the core ESDK, - TEXT[!MUST,implementation,test]: converted as defined in [Algorithm suite identifier](#algorithm-suite-identifier). - TEXT[!MUST,implementation]: - `encrypt` MUST provide the target-supplied commitment policy to the core ESDK, - TEXT[!MUST,implementation]: converted as defined in [Commitment policy](#commitment-policy). - TEXT[!MUST,implementation]: - `encrypt` MUST provide the target-supplied frame length to the core ESDK, - TEXT[!MUST,implementation]: converted as defined in [Frame length](#frame-length). - TEXT[!MUST,implementation]: - `encrypt` MUST provide the target-supplied maximum-encrypted-data-keys value to - TEXT[!MUST,implementation]: the core ESDK, converted as defined in - TEXT[!MUST,implementation]: [Maximum encrypted data keys](#maximum-encrypted-data-keys). - - SECTION: [Encrypt outputs](#encrypt-outputs) - TEXT[!MUST,implementation,test]: - `encrypt` MUST return the core ESDK's ciphertext unmodified. - TEXT[!MUST,implementation,test]: - `encrypt` MUST return the used algorithm suite, converted as defined in - TEXT[!MUST,implementation,test]: [Algorithm suite identifier](#algorithm-suite-identifier). - TEXT[!MUST,implementation,test]: - `encrypt` MUST return the result encryption context, converted as defined in - TEXT[!MUST,implementation,test]: [Encryption context](#encryption-context). - - SECTION: [Decrypt inputs](#decrypt-inputs) - TEXT[!MUST,implementation,test]: - `decrypt` MUST pass the target-supplied ciphertext to the core ESDK unmodified. - TEXT[!MUST,implementation,test]: - `decrypt` MUST provide the target-supplied encryption context to the core ESDK, - TEXT[!MUST,implementation,test]: converted as defined in [Encryption context](#encryption-context). - TEXT[!MUST,implementation]: - `decrypt` MUST provide the target-supplied commitment policy to the core ESDK, - TEXT[!MUST,implementation]: converted as defined in [Commitment policy](#commitment-policy). - TEXT[!MUST,implementation]: - `decrypt` MUST provide the target-supplied maximum-encrypted-data-keys value to - TEXT[!MUST,implementation]: the core ESDK, converted as defined in - TEXT[!MUST,implementation]: [Maximum encrypted data keys](#maximum-encrypted-data-keys). - - SECTION: [Decrypt outputs](#decrypt-outputs) - TEXT[!MUST,implementation,test]: - `decrypt` MUST return the core ESDK's plaintext unmodified. - TEXT[!MUST,implementation,test]: - `decrypt` MUST return the used algorithm suite, converted as defined in - TEXT[!MUST,implementation,test]: [Algorithm suite identifier](#algorithm-suite-identifier). - TEXT[!MUST,implementation,test]: - `decrypt` MUST return the result encryption context, converted as defined in - TEXT[!MUST,implementation,test]: [Encryption context](#encryption-context). - - SECTION: [Create KMS client](#create-kms-client) - TEXT[!MUST,implementation,test]: - The shim MUST provide an operation that creates a KMS service client backed by - TEXT[!MUST,implementation,test]: the core ESDK. - TEXT[!MUST,implementation,test]: - Creating a KMS client MUST apply the target-supplied client configuration, as - TEXT[!MUST,implementation,test]: defined in [Service client configuration](#service-client-configuration). - - SECTION: [Create DynamoDB client](#create-dynamodb-client) - TEXT[!MUST,implementation,test]: - The shim MUST provide an operation that creates a DynamoDB service client - TEXT[!MUST,implementation,test]: backed by the core ESDK. - TEXT[!MUST,implementation,test]: - Creating a DynamoDB client MUST apply the target-supplied client configuration, - TEXT[!MUST,implementation,test]: as defined in [Service client configuration](#service-client-configuration). - - SECTION: [Create key store](#create-key-store) - TEXT[!MUST,implementation,test]: - The shim MUST provide an operation that creates a key store backed by the core - TEXT[!MUST,implementation,test]: ESDK. - TEXT[!MUST,implementation,test]: - Creating a key store MUST require a KMS client handle and a DynamoDB client - TEXT[!MUST,implementation,test]: handle, checked as defined in - TEXT[!MUST,implementation,test]: [Shim Specification: Handles and lifetimes](./shim.md#handles-and-lifetimes), - TEXT[!MUST,implementation,test]: and MUST provide both to the core ESDK. - TEXT[!MUST,implementation,test]: - Creating a key store MUST provide the target-supplied table name and logical key - TEXT[!MUST,implementation,test]: store name to the core ESDK. - TEXT[!MUST,implementation,test]: - Creating a key store MUST provide the target-supplied KMS configuration to the - TEXT[!MUST,implementation,test]: core ESDK, converted as defined in [KMS configuration](#kms-configuration). - TEXT[!MUST,implementation,test]: - Creating a key store MUST provide the target-supplied key store id and grant - TEXT[!MUST,implementation,test]: tokens to the core ESDK when present; an unset value is omitted. - - SECTION: [Create hierarchical keyring](#create-hierarchical-keyring) - TEXT[!MUST,implementation,test]: - The shim MUST provide an operation that creates a hierarchical keyring backed - TEXT[!MUST,implementation,test]: by the core ESDK. - TEXT[!MUST,implementation,test]: - Creating a hierarchical keyring MUST require a key store handle, checked as - TEXT[!MUST,implementation,test]: defined in - TEXT[!MUST,implementation,test]: [Shim Specification: Handles and lifetimes](./shim.md#handles-and-lifetimes), - TEXT[!MUST,implementation,test]: and MUST provide it to the core ESDK. - TEXT[!MUST,implementation,test]: - Creating a hierarchical keyring MUST provide the target-supplied branch key id - TEXT[!MUST,implementation,test]: and time-to-live to the core ESDK. - TEXT[!MUST,implementation,test]: - Creating a hierarchical keyring MUST provide the target-supplied cache - TEXT[!MUST,implementation,test]: configuration to the core ESDK, converted as defined in - TEXT[!MUST,implementation,test]: [Cache configuration](#cache-configuration). - TEXT[!MUST,implementation,test]: - Creating a hierarchical keyring MUST provide the target-supplied partition id to - TEXT[!MUST,implementation,test]: the core ESDK when present; an unset value is omitted. - - SECTION: [Conformance and testing](#conformance-and-testing) - TEXT[!MUST,test]: - The ESDK shim MUST be tested for the behavior it owns — translation, handle - TEXT[!MUST,test]: validation, error propagation, and lifetime safety — rather than by re-testing - TEXT[!MUST,test]: the core ESDK's cryptographic behavior. - TEXT[!SHOULD,exception]: - The ESDK shim SHOULD demonstrate message interoperability with other ESDK - TEXT[!SHOULD,exception]: implementations (for example via a shared test-vector suite). - -SPECIFICATION: [Shim Specification](spec/shim/shim.md) - SECTION: [Owned interface](#owned-interface) - TEXT[!MUST,implication]: - The shim MUST define its own error type for its public surface. - TEXT[!MUST,implication]: - For each core-library enumeration it exposes, the shim MUST define its own - TEXT[!MUST,implication]: corresponding enumeration type. - TEXT[!MUST,implication]: - Each public function the shim exposes MUST use only owned-interface types or - TEXT[!MUST,implication]: standard-library types in its signature. - TEXT[!MUST,implication]: - Each owned interface that represents a core-library resource MUST hold the - TEXT[!MUST,implication]: generated handle privately and MUST NOT expose it in its public API. - - SECTION: [Type translation](#type-translation) - TEXT[!MUST,implication]: Every such translation MUST obey the following rules. - TEXT[!MUST,implication,test]: - A translation MUST convert between the target representation and the core - TEXT[!MUST,implication,test]: library representation, preserving meaning in both directions it supports. - TEXT[!MUST,test]: - A translation reports failure by returning an error; it MUST NOT panic, abort, - TEXT[!MUST,test]: or otherwise terminate the target process. - TEXT[!MUST,implication,test]: - When the target supplies a value that has no corresponding core-library - TEXT[!MUST,implication,test]: representation, the translation MUST return an error. - TEXT[!MUST,implication]: - When the core library produces a value the shim does not define, the - TEXT[!MUST,implication]: translation MUST return an error. - - SECTION: [Delegation](#delegation) - TEXT[!MUST,implication,test]: - Each operation the shim exposes MUST produce its result by invoking the - TEXT[!MUST,implication,test]: corresponding core-library operation. - TEXT[!MUST,implication]: - The shim MUST NOT validate operation or resource-creation input values itself; - TEXT[!MUST,implication]: it MUST translate each input and defer its validation to the core library. - TEXT[!MUST,implementation,test]: - When a core-library operation returns an error, the shim MUST return an error to - TEXT[!MUST,implementation,test]: the target and MUST NOT report the operation as successful. - TEXT[!SHOULD,implementation,test]: - An error the shim returns for a failed core-library operation SHOULD include - TEXT[!SHOULD,implementation,test]: context identifying which operation failed. - - SECTION: [Creating and releasing resources](#creating-and-releasing-resources) - TEXT[!MUST,implication]: - For each resource kind, the shim MUST provide a means for the target to create an - TEXT[!MUST,implication]: instance backed by the core library. - TEXT[!MUST,implication]: - The shim MUST release the core-library resource backing an owned interface once - TEXT[!MUST,implication]: the target no longer holds it. - TEXT[!MAY,implication]: The shim MAY release it automatically when the - TEXT[!MAY,implication]: owned interface is destroyed, or through an explicit target operation. - - SECTION: [Handles and lifetimes](#handles-and-lifetimes) - TEXT[!MUST,implementation,test]: - Before dereferencing a target-supplied resource handle, the shim MUST check it - TEXT[!MUST,implementation,test]: and MUST return an error when a required handle is absent. - TEXT[!MUST,test]: - An owned interface that depends on another resource MUST retain ownership of - TEXT[!MUST,test]: that resource for its own lifetime, so that a handle passed across the boundary - TEXT[!MUST,test]: cannot outlive the resource it refers to. - - SECTION: [Concurrency](#concurrency) - TEXT[!SHOULD,exception]: If a core library resource or operation supports concurrent use from multiple threads, - TEXT[!SHOULD,exception]: the shim library SHOULD support it as well. - - SECTION: [Streaming](#streaming) - TEXT[!SHOULD,exception]: If a core library resource or operation supports [streamed](../client-apis/streaming.md) input/outputs, - TEXT[!SHOULD,exception]: the shim library SHOULD support it as well. - - SECTION: [Operation contracts](#operation-contracts) - TEXT[!MUST,implication]: - Except where an input or output is passed through unmodified, each MUST be - TEXT[!MUST,implication]: translated per [Type translation](#type-translation). - TEXT[!MUST,implication]: - Each operation MUST invoke the core library per [Delegation](#delegation). - - SECTION: [Conformance and testing](#conformance-and-testing) - TEXT[!MUST,implication]: - A shim MUST conform to this specification in addition to its core-library-specific - TEXT[!MUST,implication]: shim specification. - TEXT[!SHOULD,test]: - The shim SHOULD be tested for the behavior it owns — translation, handle - TEXT[!SHOULD,test]: validation, error propagation, and lifetime safety — rather than by re-testing - TEXT[!SHOULD,test]: the core library's own behavior. diff --git a/aws-esdk-cpp/aws-esdk-cpp/.gitignore b/aws-esdk-cpp/aws-esdk-cpp/.gitignore index f3728796b..11db1487d 100644 --- a/aws-esdk-cpp/aws-esdk-cpp/.gitignore +++ b/aws-esdk-cpp/aws-esdk-cpp/.gitignore @@ -1,10 +1,9 @@ # Cargo build output /target/ +Cargo.lock # Compiled demo / test binaries (built via the Makefile) -/main -/main_release -/main_idiomatic +/basic_hierarchical_keyring_example /test_esdk # Object files / archives @@ -17,3 +16,8 @@ # CMake build output /build/ /build-cmake/ + +# Duvet: generated requirement extraction, snapshot, and reports +.duvet/requirements/ +.duvet/snapshot.txt +.duvet/reports/ diff --git a/aws-esdk-cpp/aws-esdk-cpp/Cargo.lock b/aws-esdk-cpp/aws-esdk-cpp/Cargo.lock deleted file mode 100644 index 5c037c89e..000000000 --- a/aws-esdk-cpp/aws-esdk-cpp/Cargo.lock +++ /dev/null @@ -1,2835 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] -name = "anstyle" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" - -[[package]] -name = "arc-swap" -version = "1.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c049c0be4daef0b145cb3555416b3b8ef5b7888a38aea1a3a155801fe7b0810b" -dependencies = [ - "rustversion", -] - -[[package]] -name = "async-trait" -version = "0.1.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "atomic-waker" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" - -[[package]] -name = "autocfg" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" - -[[package]] -name = "aws-config" -version = "1.8.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33f815b73a3899c03b380d543532e5865f230dce9678d108dc10732a8682275" -dependencies = [ - "aws-credential-types", - "aws-runtime", - "aws-sdk-sso", - "aws-sdk-ssooidc", - "aws-sdk-sts", - "aws-smithy-async", - "aws-smithy-http", - "aws-smithy-json", - "aws-smithy-runtime", - "aws-smithy-runtime-api", - "aws-smithy-schema", - "aws-smithy-types", - "aws-types", - "bytes", - "fastrand", - "hex", - "http 1.4.2", - "sha1", - "time", - "tokio", - "tracing", - "url", - "zeroize", -] - -[[package]] -name = "aws-credential-types" -version = "1.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f20799b373a1be121fe3005fba0c2090af9411573878f224df44b42727fcaf7" -dependencies = [ - "aws-smithy-async", - "aws-smithy-runtime-api", - "aws-smithy-types", - "zeroize", -] - -[[package]] -name = "aws-esdk" -version = "2.0.0" -dependencies = [ - "async-trait", - "aws-lc-rs", - "aws-mpl-native", - "aws-sdk-dynamodb", - "aws-sdk-kms", - "aws-smithy-types", - "tokio", - "zeroize", -] - -[[package]] -name = "aws-esdk-cpp" -version = "0.1.0" -dependencies = [ - "aws-config", - "aws-esdk", - "aws-mpl-native", - "aws-sdk-dynamodb", - "aws-sdk-kms", - "aws-smithy-types", - "cc", - "cxx", - "cxx-build", - "tokio", -] - -[[package]] -name = "aws-lc-rs" -version = "1.17.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4342d8937fc7e5dd9b1c60292261c0670c882a2cd1719cfc11b1af41731e32ad" -dependencies = [ - "aws-lc-sys 0.42.0", - "untrusted 0.7.1", - "zeroize", -] - -[[package]] -name = "aws-lc-sys" -version = "0.37.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b092fe214090261288111db7a2b2c2118e5a7f30dc2569f1732c4069a6840549" -dependencies = [ - "cc", - "cmake", - "dunce", - "fs_extra", -] - -[[package]] -name = "aws-lc-sys" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d9ceb1da931507a12f4fccea479dccd00da1943e1b4ae72d8e502d707361444" -dependencies = [ - "cc", - "cmake", - "dunce", - "fs_extra", - "pkg-config", -] - -[[package]] -name = "aws-mpl-legacy" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f04a638979445d746294e965c877b36c9eb037ce3291a43fd62b8f4a70f5813" -dependencies = [ - "aws-config", - "aws-lc-rs", - "aws-lc-sys 0.37.1", - "aws-sdk-dynamodb", - "aws-sdk-kms", - "aws-smithy-runtime-api", - "aws-smithy-types", - "chrono", - "cpu-time", - "dafny-runtime", - "dashmap", - "futures", - "pem", - "rand 0.9.4", - "timeout", - "tokio", - "uuid", -] - -[[package]] -name = "aws-mpl-native" -version = "0.2.0" -dependencies = [ - "async-trait", - "aws-mpl-legacy", - "aws-mpl-primitives", - "aws-sdk-dynamodb", - "aws-sdk-kms", - "zeroize", -] - -[[package]] -name = "aws-mpl-primitives" -version = "0.1.0" -dependencies = [ - "aws-lc-rs", -] - -[[package]] -name = "aws-runtime" -version = "1.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c9b9de216a988dd54b754a82a7660cfe14cee4f6782ae4524470972fa0ccb39" -dependencies = [ - "aws-credential-types", - "aws-sigv4", - "aws-smithy-async", - "aws-smithy-http", - "aws-smithy-runtime", - "aws-smithy-runtime-api", - "aws-smithy-types", - "aws-types", - "bytes", - "bytes-utils", - "fastrand", - "http 1.4.2", - "http-body 1.0.1", - "percent-encoding", - "pin-project-lite", - "tracing", - "uuid", -] - -[[package]] -name = "aws-sdk-dynamodb" -version = "1.116.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c937c55ae3030bec4431c0d9146e33d2b3e5f54bb47ed32597068200c56affc" -dependencies = [ - "arc-swap", - "aws-credential-types", - "aws-runtime", - "aws-smithy-async", - "aws-smithy-http", - "aws-smithy-json", - "aws-smithy-observability", - "aws-smithy-runtime", - "aws-smithy-runtime-api", - "aws-smithy-types", - "aws-types", - "bytes", - "fastrand", - "http 0.2.12", - "http 1.4.2", - "regex-lite", - "tracing", -] - -[[package]] -name = "aws-sdk-kms" -version = "1.111.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62d6d9b9c60e08be622a6bfc98e483d75683795caaf9704886970aa07ed8529" -dependencies = [ - "arc-swap", - "aws-credential-types", - "aws-runtime", - "aws-smithy-async", - "aws-smithy-http", - "aws-smithy-json", - "aws-smithy-observability", - "aws-smithy-runtime", - "aws-smithy-runtime-api", - "aws-smithy-types", - "aws-types", - "bytes", - "fastrand", - "http 0.2.12", - "http 1.4.2", - "regex-lite", - "tracing", -] - -[[package]] -name = "aws-sdk-sso" -version = "1.102.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c82b3ac19f1431854f7ace3a7531674633e286bfdde21976893bfee36fd493b" -dependencies = [ - "arc-swap", - "aws-credential-types", - "aws-runtime", - "aws-smithy-async", - "aws-smithy-http", - "aws-smithy-json", - "aws-smithy-observability", - "aws-smithy-runtime", - "aws-smithy-runtime-api", - "aws-smithy-types", - "aws-types", - "bytes", - "fastrand", - "http 0.2.12", - "http 1.4.2", - "regex-lite", - "tracing", -] - -[[package]] -name = "aws-sdk-ssooidc" -version = "1.104.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "321000d2b4c5519ee573f73167f612efd7329322d9b26969ad1979f0427f1913" -dependencies = [ - "arc-swap", - "aws-credential-types", - "aws-runtime", - "aws-smithy-async", - "aws-smithy-http", - "aws-smithy-json", - "aws-smithy-observability", - "aws-smithy-runtime", - "aws-smithy-runtime-api", - "aws-smithy-types", - "aws-types", - "bytes", - "fastrand", - "http 0.2.12", - "http 1.4.2", - "regex-lite", - "tracing", -] - -[[package]] -name = "aws-sdk-sts" -version = "1.107.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d0d328ba962af23ecfa3c9f23b98d3d35e325fa218d7f13d17a6bf522f8a560" -dependencies = [ - "arc-swap", - "aws-credential-types", - "aws-runtime", - "aws-smithy-async", - "aws-smithy-http", - "aws-smithy-json", - "aws-smithy-observability", - "aws-smithy-query", - "aws-smithy-runtime", - "aws-smithy-runtime-api", - "aws-smithy-types", - "aws-smithy-xml", - "aws-types", - "fastrand", - "http 0.2.12", - "http 1.4.2", - "regex-lite", - "tracing", -] - -[[package]] -name = "aws-sigv4" -version = "1.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bae38512beae0ffee7010fc24e7a8a123c53efdfef42a61e80fda4882418dc71" -dependencies = [ - "aws-credential-types", - "aws-smithy-http", - "aws-smithy-runtime-api", - "aws-smithy-types", - "bytes", - "form_urlencoded", - "hex", - "hmac", - "http 0.2.12", - "http 1.4.2", - "percent-encoding", - "sha2", - "time", - "tracing", -] - -[[package]] -name = "aws-smithy-async" -version = "1.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffcaf626bdda484571968400c326a244598634dc75fd451325a54ad1a59acfc" -dependencies = [ - "futures-util", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "aws-smithy-http" -version = "0.63.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba1ab2dc1c2c3749ead27180d333c42f11be8b0e934058fb4b2258ee8dbe5231" -dependencies = [ - "aws-smithy-runtime-api", - "aws-smithy-types", - "bytes", - "bytes-utils", - "futures-core", - "futures-util", - "http 1.4.2", - "http-body 1.0.1", - "http-body-util", - "percent-encoding", - "pin-project-lite", - "pin-utils", - "tracing", -] - -[[package]] -name = "aws-smithy-http-client" -version = "1.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c3ef8931ad1c98aa6a55b4256f847f3116090819844e0dd41ea682cac5dd2d3" -dependencies = [ - "aws-smithy-async", - "aws-smithy-runtime-api", - "aws-smithy-types", - "h2 0.3.27", - "h2 0.4.15", - "http 0.2.12", - "http 1.4.2", - "http-body 0.4.6", - "hyper 0.14.32", - "hyper 1.10.1", - "hyper-rustls 0.24.2", - "hyper-rustls 0.27.9", - "hyper-util", - "pin-project-lite", - "rustls 0.21.12", - "rustls 0.23.41", - "rustls-native-certs", - "rustls-pki-types", - "tokio", - "tokio-rustls 0.26.4", - "tower", - "tracing", -] - -[[package]] -name = "aws-smithy-json" -version = "0.62.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "701a947f4797e52a911e114a898667c746c39feea467bbd1abd7b3721f702ffa" -dependencies = [ - "aws-smithy-runtime-api", - "aws-smithy-schema", - "aws-smithy-types", -] - -[[package]] -name = "aws-smithy-observability" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06c2315d173edbf1920da8ba3a7189695827002e4c0fc961973ab1c54abca9c" -dependencies = [ - "aws-smithy-runtime-api", -] - -[[package]] -name = "aws-smithy-query" -version = "0.60.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a56d79744fb3edb5d722ef79d86081e121d3b9422cb209eb03aea6aa4f21ebd" -dependencies = [ - "aws-smithy-types", - "urlencoding", -] - -[[package]] -name = "aws-smithy-runtime" -version = "1.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e6f5caf6fea86f8c2206541ab5857cfcda9013426cdbe8fa0098b9e2d32182" -dependencies = [ - "aws-smithy-async", - "aws-smithy-http", - "aws-smithy-http-client", - "aws-smithy-observability", - "aws-smithy-runtime-api", - "aws-smithy-schema", - "aws-smithy-types", - "bytes", - "fastrand", - "http 0.2.12", - "http 1.4.2", - "http-body 0.4.6", - "http-body 1.0.1", - "http-body-util", - "pin-project-lite", - "pin-utils", - "tokio", - "tracing", -] - -[[package]] -name = "aws-smithy-runtime-api" -version = "1.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9db177daa6ba8afb9ee1aefcf548c907abcf52065e394ee11a92780057fe0e8c" -dependencies = [ - "aws-smithy-async", - "aws-smithy-runtime-api-macros", - "aws-smithy-types", - "bytes", - "http 0.2.12", - "http 1.4.2", - "pin-project-lite", - "tokio", - "tracing", - "zeroize", -] - -[[package]] -name = "aws-smithy-runtime-api-macros" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d7396fd9500589e62e460e987ecb671bad374934e55ec3b5f498cc7a8a8a7b7" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "aws-smithy-schema" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7442cb268338f0eb8278140a107c046756aa01093d8ef5e99628d34ae09c94f5" -dependencies = [ - "aws-smithy-runtime-api", - "aws-smithy-types", - "http 1.4.2", -] - -[[package]] -name = "aws-smithy-types" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b42fcf341259d85ca10fac9a2f6448a8ec691c6955a18e45bc3b71a85fab85" -dependencies = [ - "base64-simd", - "bytes", - "bytes-utils", - "futures-core", - "http 0.2.12", - "http 1.4.2", - "http-body 0.4.6", - "http-body 1.0.1", - "http-body-util", - "itoa", - "num-integer", - "pin-project-lite", - "pin-utils", - "ryu", - "serde", - "time", - "tokio", - "tokio-util", -] - -[[package]] -name = "aws-smithy-xml" -version = "0.60.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ce02add1aa3677d022f8adf81dcbe3046a95f17a1b1e8979c145cd21d3d22b3" -dependencies = [ - "xmlparser", -] - -[[package]] -name = "aws-types" -version = "1.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16bf10b03a3c01e6b3b7d47cd964e873ffe9e7d4e80fad16bd4c077cb068531" -dependencies = [ - "aws-credential-types", - "aws-smithy-async", - "aws-smithy-runtime-api", - "aws-smithy-schema", - "aws-smithy-types", - "rustc_version", - "tracing", -] - -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - -[[package]] -name = "base64-simd" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "339abbe78e73178762e23bea9dfd08e697eb3f3301cd4be981c0f78ba5859195" -dependencies = [ - "outref", - "vsimd", -] - -[[package]] -name = "bitflags" -version = "2.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "block-buffer" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" -dependencies = [ - "hybrid-array", -] - -[[package]] -name = "bumpalo" -version = "3.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" - -[[package]] -name = "bytes" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae3f5d315924270530207e2a68396c3cc547f6dca3fbdca317cfb1a51edb593" - -[[package]] -name = "bytes-utils" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dafe3a8757b027e2be6e4e5601ed563c55989fcf1546e933c66c8eb3a058d35" -dependencies = [ - "bytes", - "either", -] - -[[package]] -name = "cc" -version = "1.2.66" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5d6cac793997bd970000024b2934968efe83b382de4fdcf4fcb46b6ee4ad996" -dependencies = [ - "find-msvc-tools", - "jobserver", - "libc", - "shlex", -] - -[[package]] -name = "cfg-if" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" - -[[package]] -name = "chrono" -version = "0.4.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" -dependencies = [ - "iana-time-zone", - "js-sys", - "num-traits", - "wasm-bindgen", - "windows-link", -] - -[[package]] -name = "clap" -version = "4.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51" -dependencies = [ - "clap_builder", -] - -[[package]] -name = "clap_builder" -version = "4.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" -dependencies = [ - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_lex" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" - -[[package]] -name = "cmake" -version = "0.1.58" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" -dependencies = [ - "cc", -] - -[[package]] -name = "cmov" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c9ea0ac24bc397ab3c98583a3c9ba74fa56b09a4449bbe172b9b1ddb016027a" - -[[package]] -name = "codespan-reporting" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af491d569909a7e4dee0ad7db7f5341fef5c614d5b8ec8cf765732aba3cff681" -dependencies = [ - "serde", - "termcolor", - "unicode-width", -] - -[[package]] -name = "const-oid" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" - -[[package]] -name = "core-foundation" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "cpu-time" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9e393a7668fe1fad3075085b86c781883000b4ede868f43627b34a87c8b7ded" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "cpufeatures" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] - -[[package]] -name = "cpufeatures" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" -dependencies = [ - "libc", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17" - -[[package]] -name = "crypto-common" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "crypto-common" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" -dependencies = [ - "hybrid-array", -] - -[[package]] -name = "ctutils" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e" -dependencies = [ - "cmov", -] - -[[package]] -name = "cxx" -version = "1.0.197" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00424da159cc5adcb4eeea7e7b5cb1d96df41f5fa695ec596922181bdc36232a" -dependencies = [ - "cc", - "cxx-build", - "cxxbridge-cmd", - "cxxbridge-flags", - "cxxbridge-macro", - "foldhash", - "link-cplusplus", -] - -[[package]] -name = "cxx-build" -version = "1.0.197" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43e05269dbed4dab7072ae0f04ef31799ad189d52ce2ac12710c2997b754f86a" -dependencies = [ - "cc", - "codespan-reporting", - "indexmap", - "proc-macro2", - "quote", - "scratch", - "syn", -] - -[[package]] -name = "cxxbridge-cmd" -version = "1.0.197" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2f017b07e0da7f425642339faff0edc9f0de6459a18180183d086d1f3381e89" -dependencies = [ - "clap", - "codespan-reporting", - "indexmap", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "cxxbridge-flags" -version = "1.0.197" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "293d267f43a5778bf3b89fff2a658f081166e7f152d9640e2ee3d917d065a5fc" - -[[package]] -name = "cxxbridge-macro" -version = "1.0.197" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72dd233dc128223fe85d2afa5c617c79743c0f47fb495b69234b5da680d4986a" -dependencies = [ - "indexmap", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "dafny-runtime" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00ff59e5bdeafe83af48ddf5c7cb8ff233253aea4161f650e91c3bb0277c8a47" -dependencies = [ - "itertools", - "num", - "once_cell", -] - -[[package]] -name = "dashmap" -version = "6.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6361d5c062261c78a176addb82d4c821ae42bed6089de0e12603cd25de2059c" -dependencies = [ - "cfg-if", - "crossbeam-utils", - "hashbrown 0.14.5", - "lock_api", - "once_cell", - "parking_lot_core", -] - -[[package]] -name = "deranged" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer 0.10.4", - "crypto-common 0.1.7", -] - -[[package]] -name = "digest" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" -dependencies = [ - "block-buffer 0.12.1", - "const-oid", - "crypto-common 0.2.2", - "ctutils", -] - -[[package]] -name = "displaydoc" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "dunce" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" - -[[package]] -name = "either" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" - -[[package]] -name = "equivalent" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - -[[package]] -name = "errno" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" -dependencies = [ - "libc", - "windows-sys 0.61.2", -] - -[[package]] -name = "fastrand" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" - -[[package]] -name = "find-msvc-tools" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foldhash" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" - -[[package]] -name = "form_urlencoded" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "fs_extra" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" - -[[package]] -name = "fuchsia-cprng" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" - -[[package]] -name = "futures" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" - -[[package]] -name = "futures-executor" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" - -[[package]] -name = "futures-macro" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "futures-sink" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" - -[[package]] -name = "futures-task" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" - -[[package]] -name = "futures-util" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "slab", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "getrandom" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" -dependencies = [ - "cfg-if", - "libc", - "r-efi 5.3.0", - "wasip2", -] - -[[package]] -name = "getrandom" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" -dependencies = [ - "cfg-if", - "libc", - "r-efi 6.0.0", -] - -[[package]] -name = "h2" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0beca50380b1fc32983fc1cb4587bfa4bb9e78fc259aad4a0032d2080309222d" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http 0.2.12", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "h2" -version = "0.4.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cb093c84e8bd9b188d4c4a8cb6579fc016968d14c99882163cd3ff402a4f155" -dependencies = [ - "atomic-waker", - "bytes", - "fnv", - "futures-core", - "futures-sink", - "http 1.4.2", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" - -[[package]] -name = "hashbrown" -version = "0.17.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hmac" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" -dependencies = [ - "digest 0.11.3", -] - -[[package]] -name = "http" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425" -dependencies = [ - "bytes", - "itoa", -] - -[[package]] -name = "http-body" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" -dependencies = [ - "bytes", - "http 0.2.12", - "pin-project-lite", -] - -[[package]] -name = "http-body" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" -dependencies = [ - "bytes", - "http 1.4.2", -] - -[[package]] -name = "http-body-util" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" -dependencies = [ - "bytes", - "futures-core", - "http 1.4.2", - "http-body 1.0.1", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" - -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - -[[package]] -name = "hybrid-array" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "818356c5132c1fede50f837ca96afbe78ff42413047f4abb886217845e1b6c8c" -dependencies = [ - "typenum", -] - -[[package]] -name = "hyper" -version = "0.14.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2 0.3.27", - "http 0.2.12", - "http-body 0.4.6", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2 0.5.10", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498" -dependencies = [ - "atomic-waker", - "bytes", - "futures-channel", - "futures-core", - "h2 0.4.15", - "http 1.4.2", - "http-body 1.0.1", - "httparse", - "itoa", - "pin-project-lite", - "smallvec", - "tokio", - "want", -] - -[[package]] -name = "hyper-rustls" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" -dependencies = [ - "futures-util", - "http 0.2.12", - "hyper 0.14.32", - "log", - "rustls 0.21.12", - "tokio", - "tokio-rustls 0.24.1", -] - -[[package]] -name = "hyper-rustls" -version = "0.27.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" -dependencies = [ - "http 1.4.2", - "hyper 1.10.1", - "hyper-util", - "rustls 0.23.41", - "rustls-native-certs", - "tokio", - "tokio-rustls 0.26.4", - "tower-service", -] - -[[package]] -name = "hyper-util" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" -dependencies = [ - "base64", - "bytes", - "futures-channel", - "futures-util", - "http 1.4.2", - "http-body 1.0.1", - "hyper 1.10.1", - "ipnet", - "libc", - "percent-encoding", - "pin-project-lite", - "socket2 0.6.4", - "tokio", - "tower-service", - "tracing", -] - -[[package]] -name = "iana-time-zone" -version = "0.1.65" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "log", - "wasm-bindgen", - "windows-core", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - -[[package]] -name = "icu_collections" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" -dependencies = [ - "displaydoc", - "potential_utf", - "utf8_iter", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_locale_core" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" -dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", -] - -[[package]] -name = "icu_normalizer" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" -dependencies = [ - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "zerovec", -] - -[[package]] -name = "icu_normalizer_data" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" - -[[package]] -name = "icu_properties" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" -dependencies = [ - "icu_collections", - "icu_locale_core", - "icu_properties_data", - "icu_provider", - "zerotrie", - "zerovec", -] - -[[package]] -name = "icu_properties_data" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" - -[[package]] -name = "icu_provider" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" -dependencies = [ - "displaydoc", - "icu_locale_core", - "writeable", - "yoke", - "zerofrom", - "zerotrie", - "zerovec", -] - -[[package]] -name = "idna" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" -dependencies = [ - "idna_adapter", - "smallvec", - "utf8_iter", -] - -[[package]] -name = "idna_adapter" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" -dependencies = [ - "icu_normalizer", - "icu_properties", -] - -[[package]] -name = "indexmap" -version = "2.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" -dependencies = [ - "equivalent", - "hashbrown 0.17.1", -] - -[[package]] -name = "ipnet" -version = "2.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" - -[[package]] -name = "itertools" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" - -[[package]] -name = "jobserver" -version = "0.1.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" -dependencies = [ - "getrandom 0.4.3", - "libc", -] - -[[package]] -name = "js-sys" -version = "0.3.103" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" -dependencies = [ - "cfg-if", - "futures-util", - "wasm-bindgen", -] - -[[package]] -name = "libc" -version = "0.2.186" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" - -[[package]] -name = "link-cplusplus" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f78c730aaa7d0b9336a299029ea49f9ee53b0ed06e9202e8cb7db9bae7b8c82" -dependencies = [ - "cc", -] - -[[package]] -name = "litemap" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" - -[[package]] -name = "lock_api" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" -dependencies = [ - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" - -[[package]] -name = "memchr" -version = "2.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4" - -[[package]] -name = "mio" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda" -dependencies = [ - "libc", - "wasi", - "windows-sys 0.61.2", -] - -[[package]] -name = "num" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" -dependencies = [ - "num-bigint", - "num-complex", - "num-integer", - "num-iter", - "num-rational", - "num-traits", -] - -[[package]] -name = "num-bigint" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367" -dependencies = [ - "num-integer", - "num-traits", -] - -[[package]] -name = "num-complex" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-conv" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-iter" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c92800bd69a1eac91786bcfe9da64a897eb72911b8dc3095decbd07429e8048b" -dependencies = [ - "num-integer", - "num-traits", -] - -[[package]] -name = "num-rational" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" -dependencies = [ - "num-bigint", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "once_cell" -version = "1.21.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" - -[[package]] -name = "openssl-probe" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" - -[[package]] -name = "outref" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e" - -[[package]] -name = "parking_lot" -version = "0.12.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-link", -] - -[[package]] -name = "pem" -version = "3.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be" -dependencies = [ - "base64", - "serde_core", -] - -[[package]] -name = "percent-encoding" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" - -[[package]] -name = "pin-project-lite" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkg-config" -version = "0.3.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" - -[[package]] -name = "potential_utf" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" -dependencies = [ - "zerovec", -] - -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - -[[package]] -name = "ppv-lite86" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "proc-macro2" -version = "1.0.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "r-efi" -version = "5.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" - -[[package]] -name = "r-efi" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" - -[[package]] -name = "rand" -version = "0.3.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" -dependencies = [ - "libc", - "rand 0.4.6", -] - -[[package]] -name = "rand" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" -dependencies = [ - "fuchsia-cprng", - "libc", - "rand_core 0.3.1", - "rdrand", - "winapi", -] - -[[package]] -name = "rand" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" -dependencies = [ - "rand_chacha", - "rand_core 0.9.5", -] - -[[package]] -name = "rand_chacha" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" -dependencies = [ - "ppv-lite86", - "rand_core 0.9.5", -] - -[[package]] -name = "rand_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -dependencies = [ - "rand_core 0.4.2", -] - -[[package]] -name = "rand_core" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" - -[[package]] -name = "rand_core" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" -dependencies = [ - "getrandom 0.3.4", -] - -[[package]] -name = "rdrand" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "redox_syscall" -version = "0.5.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" -dependencies = [ - "bitflags", -] - -[[package]] -name = "regex-lite" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cab834c73d247e67f4fae452806d17d3c7501756d98c8808d7c9c7aa7d18f973" - -[[package]] -name = "ring" -version = "0.17.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" -dependencies = [ - "cc", - "cfg-if", - "getrandom 0.2.17", - "libc", - "untrusted 0.9.0", - "windows-sys 0.52.0", -] - -[[package]] -name = "rustc_version" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" -dependencies = [ - "semver", -] - -[[package]] -name = "rustls" -version = "0.21.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" -dependencies = [ - "log", - "ring", - "rustls-webpki 0.101.7", - "sct", -] - -[[package]] -name = "rustls" -version = "0.23.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b92b125634d9b795e7beca796cc790df15a7fb38323bf3196fda83292d06b1f" -dependencies = [ - "aws-lc-rs", - "once_cell", - "rustls-pki-types", - "rustls-webpki 0.103.13", - "subtle", - "zeroize", -] - -[[package]] -name = "rustls-native-certs" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dab5152771c58876a2146916e53e35057e1a4dfa2b9df0f0305b07f611fdea4d" -dependencies = [ - "openssl-probe", - "rustls-pki-types", - "schannel", - "security-framework", -] - -[[package]] -name = "rustls-pki-types" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "764899a24af3980067ee14bc143654f297b22eaebfe3c7b6b211920a5a59b046" -dependencies = [ - "zeroize", -] - -[[package]] -name = "rustls-webpki" -version = "0.101.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" -dependencies = [ - "ring", - "untrusted 0.9.0", -] - -[[package]] -name = "rustls-webpki" -version = "0.103.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" -dependencies = [ - "aws-lc-rs", - "ring", - "rustls-pki-types", - "untrusted 0.9.0", -] - -[[package]] -name = "rustversion" -version = "1.0.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" - -[[package]] -name = "ryu" -version = "1.0.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" - -[[package]] -name = "schannel" -version = "0.1.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" -dependencies = [ - "windows-sys 0.61.2", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "scratch" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d68f2ec51b097e4c1a75b681a8bec621909b5e91f15bb7b840c4f2f7b01148b2" - -[[package]] -name = "sct" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" -dependencies = [ - "ring", - "untrusted 0.9.0", -] - -[[package]] -name = "security-framework" -version = "3.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" -dependencies = [ - "bitflags", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "semver" -version = "1.0.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" - -[[package]] -name = "serde" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" -dependencies = [ - "serde_core", - "serde_derive", -] - -[[package]] -name = "serde_core" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "sha1" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" -dependencies = [ - "cfg-if", - "cpufeatures 0.2.17", - "digest 0.10.7", -] - -[[package]] -name = "sha2" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" -dependencies = [ - "cfg-if", - "cpufeatures 0.3.0", - "digest 0.11.3", -] - -[[package]] -name = "shlex" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" - -[[package]] -name = "signal-hook-registry" -version = "1.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" -dependencies = [ - "errno", - "libc", -] - -[[package]] -name = "slab" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" - -[[package]] -name = "smallvec" -version = "1.15.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" - -[[package]] -name = "socket2" -version = "0.5.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "socket2" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51" -dependencies = [ - "libc", - "windows-sys 0.61.2", -] - -[[package]] -name = "stable_deref_trait" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" - -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - -[[package]] -name = "subtle" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" - -[[package]] -name = "syn" -version = "2.0.118" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "synstructure" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "termcolor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "time" -version = "0.3.53" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18dfaaeddcb932337b5e7866ee7d0ce9b76d2fd092997146f187ec09b4558a50" -dependencies = [ - "deranged", - "num-conv", - "powerfmt", - "serde_core", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" - -[[package]] -name = "time-macros" -version = "0.2.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c431b87111666e491a90baa837f914fb45cd5dc3c268591b0220ff5057f2085f" -dependencies = [ - "num-conv", - "time-core", -] - -[[package]] -name = "timeout" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "415e3859aca2dba2e8c60fd326c9f23596e980796974322ff391dad9d71a946f" -dependencies = [ - "rand 0.3.23", -] - -[[package]] -name = "tinystr" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" -dependencies = [ - "displaydoc", - "zerovec", -] - -[[package]] -name = "tokio" -version = "1.52.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" -dependencies = [ - "bytes", - "libc", - "mio", - "parking_lot", - "pin-project-lite", - "signal-hook-registry", - "socket2 0.6.4", - "tokio-macros", - "windows-sys 0.61.2", -] - -[[package]] -name = "tokio-macros" -version = "2.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tokio-rustls" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" -dependencies = [ - "rustls 0.21.12", - "tokio", -] - -[[package]] -name = "tokio-rustls" -version = "0.26.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" -dependencies = [ - "rustls 0.23.41", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tower" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" -dependencies = [ - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-layer" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" - -[[package]] -name = "tower-service" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" - -[[package]] -name = "tracing" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" -dependencies = [ - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tracing-core" -version = "0.1.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" -dependencies = [ - "once_cell", -] - -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - -[[package]] -name = "typenum" -version = "1.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" - -[[package]] -name = "unicode-ident" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" - -[[package]] -name = "unicode-width" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" - -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - -[[package]] -name = "url" -version = "2.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", - "serde", -] - -[[package]] -name = "urlencoding" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" - -[[package]] -name = "utf8_iter" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" - -[[package]] -name = "uuid" -version = "1.23.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf80a72845275afea99e7f2b434723d3bc7e38470fcd1c7ed39a599c73319a53" -dependencies = [ - "getrandom 0.4.3", - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "vsimd" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" - -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - -[[package]] -name = "wasi" -version = "0.11.1+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" - -[[package]] -name = "wasip2" -version = "1.0.4+wasi-0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" -dependencies = [ - "wit-bindgen", -] - -[[package]] -name = "wasm-bindgen" -version = "0.2.126" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" -dependencies = [ - "cfg-if", - "once_cell", - "rustversion", - "wasm-bindgen-macro", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.126" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.126" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" -dependencies = [ - "bumpalo", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.126" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" -dependencies = [ - "windows-sys 0.61.2", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-core" -version = "0.62.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" -dependencies = [ - "windows-implement", - "windows-interface", - "windows-link", - "windows-result", - "windows-strings", -] - -[[package]] -name = "windows-implement" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "windows-interface" -version = "0.59.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "windows-link" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" - -[[package]] -name = "windows-result" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-strings" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-sys" -version = "0.61.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "wit-bindgen" -version = "0.57.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" - -[[package]] -name = "writeable" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" - -[[package]] -name = "xmlparser" -version = "0.13.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4" - -[[package]] -name = "yoke" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" -dependencies = [ - "stable_deref_trait", - "yoke-derive", - "zerofrom", -] - -[[package]] -name = "yoke-derive" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "zerocopy" -version = "0.8.53" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75726053136156d419e285b9b7eddaaea9e3fea6ce32eed44a89901f0bd98de1" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.53" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4714fd92cf900833d49538023a9b3915155210801d1c1169eba513b2addefd71" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "zerofrom" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" -dependencies = [ - "zerofrom-derive", -] - -[[package]] -name = "zerofrom-derive" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "zeroize" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" - -[[package]] -name = "zerotrie" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", -] - -[[package]] -name = "zerovec" -version = "0.11.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" -dependencies = [ - "yoke", - "zerofrom", - "zerovec-derive", -] - -[[package]] -name = "zerovec-derive" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] diff --git a/aws-esdk-cpp/aws-esdk-cpp/Makefile b/aws-esdk-cpp/aws-esdk-cpp/Makefile index 154491d1b..c2c45bcdc 100644 --- a/aws-esdk-cpp/aws-esdk-cpp/Makefile +++ b/aws-esdk-cpp/aws-esdk-cpp/Makefile @@ -1,30 +1,17 @@ -# Simple Makefile - all C++ bridge code is now compiled into the Rust static library +# Simple Makefile - all C++ bridge code is compiled into the Rust static library. -main: main.cpp src/lib.rs target/debug/libaws_esdk_cpp.a - g++ main.cpp target/cxxbridge/aws-esdk-cpp/src/lib.rs.cc \ +# Idiomatic example. Requires C++17 (the idiomatic header uses std::string_view). +# Needs live AWS resources / ESDK_TEST_* env vars to run; builds without them. +example: examples/basic_hierarchical_keyring_example.cpp include/aws/esdk/EncryptionSDK.h src/lib.rs target/debug/libaws_esdk_cpp.a + g++ examples/basic_hierarchical_keyring_example.cpp target/cxxbridge/aws-esdk-cpp/src/lib.rs.cc \ $$(find target/debug/build -path "*/cxx-*/out/libcxxbridge1.a" | head -n1) \ -Ltarget/debug -laws_esdk_cpp \ - -Itarget/cxxbridge \ - -lpthread -ldl \ - -std=c++11 \ - -o main - - -main_release: main.cpp src/lib.rs target/release/libaws_esdk_cpp.a - g++ main.cpp target/cxxbridge/aws-esdk-cpp/src/lib.rs.cc \ - $$(find target/release/build -path "*/cxx-*/out/libcxxbridge1.a" | head -n1) \ - -Ltarget/release -laws_esdk_cpp \ - -Itarget/cxxbridge \ + -Itarget/cxxbridge -Iinclude \ -lpthread -ldl \ - -std=c++11 \ - -o main_release - -clean: - rm -f main - -.PHONY: all clean duvet test clippy + -std=c++17 \ + -o basic_hierarchical_keyring_example -# Idiomatic-facade integration tests. Requires C++17 (aws_esdk.hpp uses +# Idiomatic-facade integration tests. Requires C++17 (the idiomatic header uses # std::string_view). Run ./test_esdk with ESDK_TEST_* env vars set (it skips # cleanly if they are unset). test_esdk: test_esdk.cpp include/aws/esdk/EncryptionSDK.h src/lib.rs target/debug/libaws_esdk_cpp.a @@ -36,18 +23,21 @@ test_esdk: test_esdk.cpp include/aws/esdk/EncryptionSDK.h src/lib.rs target/debu -std=c++17 \ -o test_esdk +clean: + rm -f basic_hierarchical_keyring_example test_esdk + clippy: cargo clippy --tests --examples test: cargo build cargo build --release - make - ./main - make main_release - ./main_release + make example + make test_esdk duvet: @test -e spec || ln -s ../../spec spec rm -rf .duvet/reports .duvet/requirements duvet report + +.PHONY: all clean duvet test clippy diff --git a/aws-esdk-cpp/aws-esdk-cpp/doc_plan.md b/aws-esdk-cpp/aws-esdk-cpp/doc_plan.md deleted file mode 100644 index 305f63ca7..000000000 --- a/aws-esdk-cpp/aws-esdk-cpp/doc_plan.md +++ /dev/null @@ -1,88 +0,0 @@ -Redshift wants a performant C++ ESDK with hierarchical keyring support. At a high level we’ll deliver this by shipping a natively-written Rust ESDK and exposing it to C++ via bindings. This doc defines the scope of those deliverables. -Q1: What will we deliver for Redshift? -Andy previously decided this and we won’t backtrack since Option 1 is mostly implemented, but it’s worth stating the options again to understand how we got here. -1. C++ bindings to a native Rust ESDK that uses the Dafny-Rust MPL -Recommended and explored in this doc. -2. Option 1 but with a new Native Rust MPL -Not worth the effort. Most of the performance benefit from moving to native comes from eliminating conversions to/from Dafny shapes for large objects. The MPL handles orders of magnitude fewer bytes than the ESDK in typical operation, so moving it to native is less impactful. -3. Option 1 but with the existing Dafny Rust ESDK -Not performant. Early performance tests of a native Rust ESDK with the Dafny Rust MPL show: -• >4x speedup in wall-clock time for single-threaded encrypt/decrypt -o 50 MB payload, time dropped from 37 ms to 9 ms -• Memory overhead reduced from O(n) to O(1) relative to input size -o 50 MB payload, additional memory overhead dropped from 48 MB to 0.02 MB (not re-creating the entire input/output buffer as Dafny types) -4. Native C++ hierarchy keyring -We want to minimize the amount of C/C++ business logic we own moving forward; this would not help. -Q2: What is the long-term goal? -What did Andy leave behind -Andy left behind some partial Rust crates. For a full writeup, see the Appendix. Two relevant crates for this project are a native ESDK Rust crate and a C++ bindings crate. -More detail: -Native Rust ESDK -Implementation: Encrypt/decrypt are working and pass some interop testing. -Duvet: About 18% annotated, but all are implications (i.e. untested). -MPL: Uses a combination of the existing Dafny-Rust MPL and the native Rust MPL. (Native Rust MPL is only for type definitions – all methods are stubbed). We would refactor this to only use the Dafny-Rust MPL. -Tests: Implements most ESDK Dafny integ tests, passes some test vectors. -C++ Bindings -Implementation: Some Rust code re-defines shapes (ex. EncryptInput, AlgorithmSuiteId) and methods (ex. create_hierarchical_keyring(), encrypt()) that are exported to C++. The shapes exported to C++ are different than the Rust shapes; the exposed methods are responsible for converting from C++ shapes to Rust shapes and calling the Rust methods. A crate called `cxx-build` compiles this to C++ bindings. -Tests: None -Deliverables -We will deliver only the functionality required by Redshift. This means -1. An internal-Amazon native Rust ESDK that only supports hierarchy keyrings, and -2. C++ bindings for this native Rust ESDK. -This means not immediately delivering more fully-featured options: -• Support all MPL keyrings -o Redshift only needs HKeyring support. We can add others later. -• Release native Rust ESDK publicly -o Launching an “HKeyring-only” ESDK conflicts with the keyring support for the current public library. We should support all MPL keyrings before releasing this publicly, and we don’t need to do that now to deliver for Redshift. -o Probably dependent on post-Dafny strategy -o Public release requires docs, examples -Once we have demand for more keyrings or want to launch the native Rust ESDK publicly, we would start from this internal build. -Spec Compliance -The native Rust ESDK/C++ bindings will fully implement Duvet coverage for the ESDK spec, meaning files in either the data-format and client-apis folders. They do not need to implement coverage for any files for the MPL spec (the framework folder) since they are re-using the Dafny-Rust MPL components. -Duvet’ing the Rust code is straightforward, but I’ll need to figure out what Duvet’ing C++ bindings looks like in practice (out of scope for this doc). -As an aside, no ESDK implementation is actively Duvet’ed today; see the appendix. I won’t Duvet these other implementations for reasons described in the appendix. Not Duvet’ing other implementations increases the risk of implementation inconsistencies, but I suggest we accept this risk and mitigate it with testing. -Testing -Defining the testing bar for a native library isn’t straightforward because we don’t have a testing spec/test plan for the ESDK to follow. I’m not planning to create a testing spec for the ESDK for the same reasons as I’m not planning to Duvet existing ESDK implementations. -I’ll suggest bounding testing to the following: -• Unit tests -o Rust: ESDK implementation -o C++: Shim logic -• Integ tests -o Rust: Re-implement all Dafny ESDK integ tests (luckily, there aren’t a ton) scoped down/modified to test with HKeyring - These are all of the non-proof tests in the Dafny ESDK. By implementing this, the Rust ESDK would have “at least as many” integ tests as the Dafny ESDK, which sounds like a nice bar -o C++: Minimal happy-path smoke testing. ex. No need to re-implement all of the required EC CMM test cases -• ESDK encrypt/decrypt interop tests for HKeyring -o Both Rust and C++ (to test shim layer correctness) -o This should test the real HKeyring, not the fake HKeyring that the Dafny test vectors test -• Performance tests -o Ideally both Rust and C++ (to test shim layer overhead) -Development -Rust: Develop in a private Github repo (create a aws/aws-encryption-sdk-rust private repo). -• Testing is much easier if it’s in Github and not Brazil -• Why call it `aws/aws-encryption-sdk-rust`? I expect this project will evolve into the native ESDK rust we launch publicly. There’s a reasonable chance that product will live in the aws/aws-encryption-sdk-rust repo -o Even if the Native Builds work suggests putting this in a `aws/aws-encryption-sdk-rust`isn’t our repo organization approach moving forward, this aligns with our organization strategy today. We can migrate this repo along with our other repos once our organization strategy is defined. -• Can be imported into Brazil via a package we maintain + PRs to that package -C++: Develop in a private Github repo (create a aws/aws-encryption-sdk-cpp private repo) -• Why separate repo from ESDK Rust? It’s a different UX/language for customers, which seems like the right boundary for creating a new repo/product -• Can be imported into Brazil via a package we maintain + PRs to that package?? -• Tony wants them to own this -Alternatives: -• Develop in Brazil – testing is more complicated, harder to make public eventually -• Develop in some alternative repo – not sure which one, open to suggestions -Appendix -The spec compliance story for other languages is complicated. An ESDK spec exists, but no ESDK implementation is validated against the spec with Duvet today: -• Dafny: Some comments exist but Duvet does not run. All comments are in an old format and must be updated before Duvet can run. -• Java: No comments. -• Python: No comments. -• C: Some comments exist but Duvet does not run. All comments are in an old format and must be updated before Duvet can run. -• JavaScript: Comments for HKeyring implementation exist but Duvet does not run. -I’m not planning to Duvet any existing ESDK implementations. Achieving real spec alignment goes beyond simply adding annotations and enabling Duvet. It requires validating that code precisely implements the specification. Prior rushed batch spec updates led to missed nuances around UTF encoding (COE). Even if this alignment process were done carefully, it would probably find implementation inconsistencies that would need to be considered and addressed, delaying timelines (remembering FireEgg). Fully reconciling the spec and existing behavior is out of scope due to high cost and low near-term ROI. This requires a separate effort. - -Appendix -Andy left behind a lot of partial Rust crates: -• prim/ (aws-mpl-primitives) — Native Rust wrappers around aws-lc-rs. Covers AES-GCM encrypt/decrypt, HKDF (full, extract, expand), ECDSA sign/verify (including streaming DigestContext), ECDH, AES-KDF-CTR, HMAC, Digest, random bytes, constant-time compare, and a memory tracker. This maps to the full AwsCryptographyPrimitives Smithy model — all operations from the Smithy specs (aes, hkdf, signature, digest, random, ecdh) are covered. Nothing obviously missing. -• mpl/ (aws-mpl-rs) — Types and interfaces complete, implementations stubbed. All the core types are defined: EncryptionMaterials, DecryptionMaterials, EncryptedDataKey, Secret, AlgorithmSuite (all 11 ESDK + 2 DBE suites), CommitmentPolicy, EncryptionContext, Keyring and CryptographicMaterialsManager. Input/output structs for every keyring constructor exist (KMS strict, MRK, discovery, hierarchical, RSA, ECDH, raw AES, raw RSA, raw ECDH, multi-keyring). But every single function and method returns not_implemented(). So: the API surface is fully designed, but there's zero working keyring or CMM logic. You can't actually create any keyring from this crate. -• esdk/ (aws-esdk) – full encrypt/decrypt, including streaming support. -• aws-esdk-cpp/ — single lib.rs file exposing encrypt/decrypt, hierarchical keyring creation, keystore, KMS/DDB client lifecycle to C++ via the cxx crate. This can be used today to create and use a hierarchy keyring in C++. -• aws_structured_encryption/ — Partial rewrite, early stage. 9 source files covering encrypt/decrypt for structured data, canonization, header/footer serialization, crypto operations, path handling. Depends on the native MPL for types and the native Primitives for crypto. Compared to the full Dafny StructuredEncryption module, this has the core encrypt/decrypt path and the canonization logic, but it's missing the broader DB-ESDK integration (DynamoDB item encryptor, searchable encryption, beacons). It's the structured encryption core without the full DB-ESDK wrapper. - diff --git a/aws-esdk-cpp/aws-esdk-cpp/main_idiomatic.cpp b/aws-esdk-cpp/aws-esdk-cpp/examples/basic_hierarchical_keyring_example.cpp similarity index 100% rename from aws-esdk-cpp/aws-esdk-cpp/main_idiomatic.cpp rename to aws-esdk-cpp/aws-esdk-cpp/examples/basic_hierarchical_keyring_example.cpp diff --git a/aws-esdk-cpp/aws-esdk-cpp/main.cpp b/aws-esdk-cpp/aws-esdk-cpp/main.cpp deleted file mode 100644 index 31a78ea76..000000000 --- a/aws-esdk-cpp/aws-esdk-cpp/main.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include -#include "aws-esdk-cpp/src/lib.rs.h" - -int main() -{ - try - { - auto client_config = default_client_config(); - client_config.retry.max_attempts = 5; - auto kms = create_kms_client(client_config); - auto ddb = create_ddb_client(client_config); - - auto keystore_config = default_keystore_config(); - keystore_config.ddb_client = &*ddb; - keystore_config.kms_client = &*kms; - keystore_config.ddb_table_name = "KeyStoreDdbTable"; - keystore_config.logical_key_store_name = "KeyStoreDdbTable"; - keystore_config.kms_configuration_value = "arn:aws:kms:us-west-2:370957321024:key/9d989aa2-2f9c-438c-a745-cc57d3ad0126"; - auto keystore = create_keystore(keystore_config); - - auto keyring_input = default_hierarchical_keyring_input(); - keyring_input.ttl = 4242; - keyring_input.multi_threaded_cache.entryCapacity = 42; - keyring_input.key_store = &*keystore; - keyring_input.branch_key_id = "3ce7656b-e166-40f3-8c9b-a920ce6596cd"; - auto keyring = create_hierarchical_keyring(keyring_input); - - auto encrypt_input = default_encrypt_input(); - encrypt_input.keyring = &*keyring; - const unsigned char data[] = "Hello World"; - encrypt_input.plaintext = rust::Slice(&data[0], sizeof(data)); - auto encrypt_output = encrypt(encrypt_input); - auto decrypt_input = default_decrypt_input(); - decrypt_input.keyring = &*keyring; - decrypt_input.ciphertext = rust::Slice(&encrypt_output.ciphertext[0], encrypt_output.ciphertext.size()); - auto decrypt_output = decrypt(decrypt_input); - if (encrypt_input.plaintext.size() != decrypt_output.plaintext.size()) - fprintf(stderr, "Decrypt size mismatch\n"); - if (memcmp(decrypt_output.plaintext.data(), encrypt_input.plaintext.data(), encrypt_input.plaintext.size())) - fprintf(stderr, "Decrypt data mismatch\n"); - - delete_keyring(std::move(keyring)); - delete_keystore(std::move(keystore)); - delete_kms_client(std::move(kms)); - delete_ddb_client(std::move(ddb)); - std::cout << "Success!\n"; - } - catch (const std::exception &e) - { - std::cout << "Error: " << e.what() << "\n"; - } - catch (const std::string &e) - { - std::cout << "Error String: " << e << "\n"; - } - catch (...) - { - std::cout << "Other Exception \n"; - } - return 0; -} From bb4bb6d2974b8440764869c57eddc5c938c33639 Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Thu, 9 Jul 2026 13:28:57 -0700 Subject: [PATCH 3/3] chore(native-rust): remove stale outer main_idiomatic.cpp This duplicate referenced the old aws_esdk.hpp header (since renamed to include/aws/esdk/EncryptionSDK.h) and the old aws_esdk:: namespace. --- aws-esdk-cpp/main_idiomatic.cpp | 57 --------------------------------- 1 file changed, 57 deletions(-) delete mode 100644 aws-esdk-cpp/main_idiomatic.cpp diff --git a/aws-esdk-cpp/main_idiomatic.cpp b/aws-esdk-cpp/main_idiomatic.cpp deleted file mode 100644 index 9ddcb318f..000000000 --- a/aws-esdk-cpp/main_idiomatic.cpp +++ /dev/null @@ -1,57 +0,0 @@ -#include -#include -#include "aws_esdk.hpp" // Idiomatic C++ wrapper layer - -int main() { - try { - // Create AWS clients - auto client_config = aws_esdk::ClientConfig() - .with_max_retry_attempts(5); - - auto kms = aws_esdk::KmsClient(client_config); - auto ddb = aws_esdk::DdbClient(client_config); - - // Create keystore with constructor - all config in one place - auto keystore = aws_esdk::KeyStore( - "KeyStoreDdbTable", // table_name - "KeyStoreDdbTable", // logical_key_store_name - "arn:aws:kms:us-west-2:370957321024:key/9d989aa2-2f9c-438c-a745-cc57d3ad0126", // kms_arn - kms, - ddb - ); - - // Create hierarchical keyring with constructor - auto keyring = aws_esdk::HierarchicalKeyring( - keystore, - "3ce7656b-e166-40f3-8c9b-a920ce6596cd", // branch_key_id - 4242, // ttl_seconds - 42 // cache_capacity - ); - - // Create encryption SDK client - aws_esdk::EncryptionSDK sdk; - - // Encrypt with std::vector - idiomatic C++ - std::vector plaintext = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'}; - auto ciphertext = sdk.encrypt(plaintext, keyring); - - // Decrypt - auto decrypted = sdk.decrypt(ciphertext, keyring); - - // Validate results - if (plaintext != decrypted) { - std::cerr << "Decryption failed: plaintext mismatch\n"; - return 1; - } - - std::cout << "Success! Encryption and decryption completed successfully.\n"; - - // Automatic cleanup via RAII - no manual delete calls needed! - - } catch (const std::exception &e) { - std::cerr << "Error: " << e.what() << "\n"; - return 1; - } - - return 0; -}