diff --git a/.github/workflows/daily_ci.yml b/.github/workflows/daily_ci.yml index 1b7aea9481..e8b3961c06 100644 --- a/.github/workflows/daily_ci.yml +++ b/.github/workflows/daily_ci.yml @@ -43,6 +43,12 @@ jobs: uses: ./.github/workflows/library_net_tests.yml with: dafny: ${{needs.getVersion.outputs.version}} + daily-ci-rust: + needs: getVersion + if: github.event_name != 'schedule' || github.repository_owner == 'aws' + uses: ./.github/workflows/library_rust_tests.yml + with: + dafny: ${{needs.getVersion.outputs.version}} daily-ci-python: needs: getVersion if: github.event_name != 'schedule' || github.repository_owner == 'aws' diff --git a/.github/workflows/library_dafny_verification.yml b/.github/workflows/library_dafny_verification.yml index 235f289797..bab1bcde80 100644 --- a/.github/workflows/library_dafny_verification.yml +++ b/.github/workflows/library_dafny_verification.yml @@ -53,7 +53,7 @@ jobs: dafny-version: ${{ inputs.dafny }} # dafny-reportgenerator requires next6 - # but only 7.0 is installed on macos-12-large + # but only 7.0 is installed on macos-13-large - name: Setup .NET Core SDK '6.0.x' uses: actions/setup-dotnet@v3 with: diff --git a/.github/workflows/library_interop_tests.yml b/.github/workflows/library_interop_tests.yml index 5ea08760da..c4b3986d8f 100644 --- a/.github/workflows/library_interop_tests.yml +++ b/.github/workflows/library_interop_tests.yml @@ -23,9 +23,9 @@ jobs: # https://taskei.amazon.dev/tasks/CrypTool-5283 # windows-latest, ubuntu-latest, - macos-12, + macos-13, ] - language: [java, net, python] + language: [java, net, python, rust] # https://taskei.amazon.dev/tasks/CrypTool-5284 dotnet-version: ["6.0.x"] runs-on: ${{ matrix.os }} @@ -37,11 +37,19 @@ jobs: run: | git config --global core.longpaths true + # Test Vectors need to call KMS + - name: Configure AWS Credentials for Tests + uses: aws-actions/configure-aws-credentials@v2 + with: + aws-region: us-west-2 + role-to-assume: arn:aws:iam::370957321024:role/GitHub-CI-MPL-Dafny-Role-us-west-2 + role-session-name: InterOpTests + - uses: actions/checkout@v3 # Not all submodules are needed. # We manually pull the submodule we DO need. - run: git submodule update --init libraries - - run: git submodule update --init smithy-dafny + - run: git submodule update --init --recursive smithy-dafny # Set up runtimes - name: Setup .NET Core SDK ${{ matrix.dotnet-version }} @@ -50,8 +58,9 @@ jobs: with: dotnet-version: ${{ matrix.dotnet-version }} + # Setup Java in Rust is needed for running polymorph - name: Setup Java 17 - if: matrix.language == 'java' + if: matrix.language == 'java' || matrix.language == 'rust' uses: actions/setup-java@v3 with: distribution: "corretto" @@ -67,8 +76,32 @@ jobs: pip install --upgrade tox pip install poetry + - name: Setup Rust Toolchain for GitHub CI + if: matrix.language == 'rust' + uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 + with: + components: rustfmt + # TODO - uncomment this after Rust formatter works + # - name: Rustfmt Check + # uses: actions-rust-lang/rustfmt@v1 + + # TODO: Remove this after the formatting in Rust starts working + - name: smithy-dafny Rust hacks + if: matrix.language == 'rust' + shell: bash + run: | + if [ "$RUNNER_OS" == "macOS" ]; then + sed -i '' 's|rustfmt --edition 2021 runtimes/rust/src/implementation_from_dafny.rs|#&|' smithy-dafny/SmithyDafnyMakefile.mk + else + sed -i 's|rustfmt --edition 2021 runtimes/rust/src/implementation_from_dafny.rs|#&|' smithy-dafny/SmithyDafnyMakefile.mk + fi + + - name: Setup NASM for Windows in Rust (aws-lc-sys) + if: matrix.language == 'rust' && matrix.os == 'windows-latest' + uses: ilammy/setup-nasm@v1 + - name: Setup Dafny - uses: dafny-lang/setup-dafny-action@v1.6.1 + uses: dafny-lang/setup-dafny-action@v1.7.0 with: dafny-version: ${{ inputs.dafny }} @@ -108,20 +141,32 @@ jobs: CORES=$(node -e 'console.log(os.cpus().length)') make transpile_python + - name: Install Smithy-Dafny codegen dependencies + if: matrix.language == 'rust' + uses: ./.github/actions/install_smithy_dafny_codegen_dependencies + + # TODO: Remove this after checking in Rust polymorph code + - name: Run make polymorph_rust + if: matrix.language == 'rust' + shell: bash + working-directory: ./${{ matrix.library }} + run: | + make polymorph_rust + + - name: Build ${{ matrix.library }} implementation in Rust + if: matrix.language == 'rust' + shell: bash + working-directory: ./${{ matrix.library }} + run: | + CORES=$(node -e 'console.log(os.cpus().length)') + make transpile_rust TRANSPILE_TESTS_IN_RUST=1 CORES=$CORES + - name: Setup gradle if: matrix.language == 'java' uses: gradle/gradle-build-action@v2 with: gradle-version: 7.2 - # Test Vectors need to call KMS - - name: Configure AWS Credentials for Tests - uses: aws-actions/configure-aws-credentials@v2 - with: - aws-region: us-west-2 - role-to-assume: arn:aws:iam::370957321024:role/GitHub-CI-MPL-Dafny-Role-us-west-2 - role-session-name: InterOpTests - - name: Create Manifests working-directory: ./${{ matrix.library }} run: make test_generate_vectors_${{ matrix.language }} @@ -145,10 +190,10 @@ jobs: # TODO just test on mac and ubuntu for now # windows-latest, ubuntu-latest, - macos-12, + macos-13, ] - encrypting_language: [java, net, python] - decrypting_language: [java, net, python] + encrypting_language: [java, net, python, rust] + decrypting_language: [java, net, python, rust] dotnet-version: ["6.0.x"] runs-on: ${{ matrix.os }} permissions: @@ -158,6 +203,7 @@ jobs: - name: Support longpaths on Git checkout run: | git config --global core.longpaths true + # KMS and MPL tests need to use credentials which can call KMS - name: Configure AWS Credentials for Tests uses: aws-actions/configure-aws-credentials@v2 @@ -170,7 +216,7 @@ jobs: # Not all submodules are needed. # We manually pull the submodule we DO need. - run: git submodule update --init libraries - - run: git submodule update --init smithy-dafny + - run: git submodule update --init --recursive smithy-dafny # Set up runtimes - name: Setup .NET Core SDK ${{ matrix.dotnet-version }} @@ -179,8 +225,9 @@ jobs: with: dotnet-version: ${{ matrix.dotnet-version }} + # Setup Java in Rust is needed for running polymorph - name: Setup Java 17 - if: matrix.decrypting_language == 'java' + if: matrix.decrypting_language == 'java' || matrix.decrypting_language == 'rust' uses: actions/setup-java@v3 with: distribution: "corretto" @@ -196,6 +243,30 @@ jobs: pip install --upgrade tox pip install poetry + - name: Setup Rust Toolchain for GitHub CI + if: matrix.decrypting_language == 'rust' + uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 + with: + components: rustfmt + # TODO - uncomment this after Rust formatter works + # - name: Rustfmt Check + # uses: actions-rust-lang/rustfmt@v1 + + # TODO: Remove this after the formatting in Rust starts working + - name: smithy-dafny Rust hacks + if: matrix.decrypting_language == 'rust' + shell: bash + run: | + if [ "$RUNNER_OS" == "macOS" ]; then + sed -i '' 's|rustfmt --edition 2021 runtimes/rust/src/implementation_from_dafny.rs|#&|' smithy-dafny/SmithyDafnyMakefile.mk + else + sed -i 's|rustfmt --edition 2021 runtimes/rust/src/implementation_from_dafny.rs|#&|' smithy-dafny/SmithyDafnyMakefile.mk + fi + + - name: Setup NASM for Windows in Rust (aws-lc-sys) + if: matrix.decrypting_language == 'rust' && matrix.os == 'windows-latest' + uses: ilammy/setup-nasm@v1 + - name: Setup Dafny uses: dafny-lang/setup-dafny-action@v1.6.1 with: @@ -237,6 +308,26 @@ jobs: CORES=$(node -e 'console.log(os.cpus().length)') make transpile_python + - name: Install Smithy-Dafny codegen dependencies + if: matrix.decrypting_language == 'rust' + uses: ./.github/actions/install_smithy_dafny_codegen_dependencies + + # TODO: Remove this after checking in Rust polymorph code + - name: Run make polymorph_rust + if: matrix.decrypting_language == 'rust' + shell: bash + working-directory: ./${{ matrix.library }} + run: | + make polymorph_rust + + - name: Build ${{ matrix.library }} implementation in Rust + if: matrix.decrypting_language == 'rust' + shell: bash + working-directory: ./${{ matrix.library }} + run: | + CORES=$(node -e 'console.log(os.cpus().length)') + make transpile_rust TRANSPILE_TESTS_IN_RUST=1 CORES=$CORES + - name: Download Encrypt Manifest Artifact uses: actions/download-artifact@v4 with: diff --git a/.github/workflows/library_java_tests.yml b/.github/workflows/library_java_tests.yml index 7248665828..353cf88493 100644 --- a/.github/workflows/library_java_tests.yml +++ b/.github/workflows/library_java_tests.yml @@ -32,7 +32,7 @@ jobs: # TODO just test on mac for now # windows-latest, ubuntu-latest, - macos-12, + macos-13, ] runs-on: ${{ matrix.os }} permissions: diff --git a/.github/workflows/library_net_tests.yml b/.github/workflows/library_net_tests.yml index f8d92fa4b4..2a0957b871 100644 --- a/.github/workflows/library_net_tests.yml +++ b/.github/workflows/library_net_tests.yml @@ -29,7 +29,7 @@ jobs: TestVectorsAwsCryptographicMaterialProviders, ] dotnet-version: ["6.0.x"] - os: [windows-latest, ubuntu-latest, macos-12] + os: [windows-latest, ubuntu-latest, macos-13] runs-on: ${{ matrix.os }} defaults: run: diff --git a/.github/workflows/library_python_tests.yml b/.github/workflows/library_python_tests.yml index d862576bdf..8a09597384 100644 --- a/.github/workflows/library_python_tests.yml +++ b/.github/workflows/library_python_tests.yml @@ -28,7 +28,7 @@ jobs: AwsCryptographicMaterialProviders, TestVectorsAwsCryptographicMaterialProviders, ] - python-version: ["3.11"] + python-version: ["3.11", "3.13"] os: [ # TODO fix Dafny-generated tests on Windows; # the sys.path workaround for generated Dafny doesn't work on Windows. @@ -36,7 +36,7 @@ jobs: # Windows source code is tested downstream (ex. ESDK-Python CI). # windows-latest, ubuntu-latest, - macos-12, + macos-13, ] runs-on: ${{ matrix.os }} defaults: diff --git a/.github/workflows/library_rust_tests.yml b/.github/workflows/library_rust_tests.yml new file mode 100644 index 0000000000..130f5e7666 --- /dev/null +++ b/.github/workflows/library_rust_tests.yml @@ -0,0 +1,112 @@ +# This workflow performs tests in Rust. +name: Library Rust tests + +on: + workflow_call: + inputs: + dafny: + description: "The Dafny version to run" + required: true + type: string + regenerate-code: + description: "Regenerate code using smithy-dafny" + required: false + default: false + type: boolean + +jobs: + testRust: + strategy: + fail-fast: false + matrix: + library: + [ + StandardLibrary, + ComAmazonawsDynamodb, + ComAmazonawsKms, + AwsCryptographyPrimitives, + AwsCryptographicMaterialProviders, + TestVectorsAwsCryptographicMaterialProviders, + ] + # removed windows-latest because somehow it can't build aws-lc in CI + os: [ubuntu-latest, macos-13] + runs-on: ${{ matrix.os }} + permissions: + id-token: write + contents: read + env: + RUST_MIN_STACK: 104857600 + steps: + - name: Support longpaths on Git checkout + run: | + git config --global core.longpaths true + - uses: actions/checkout@v3 + - name: Init Submodules + shell: bash + run: | + git submodule update --init libraries + git submodule update --init --recursive smithy-dafny + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v2 + with: + aws-region: us-west-2 + role-to-assume: arn:aws:iam::370957321024:role/GitHub-CI-MPL-Dafny-Role-us-west-2 + role-session-name: RustTests + + - name: Setup Rust Toolchain for GitHub CI + uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 + with: + components: rustfmt + # TODO - uncomment this after Rust formatter works + # - name: Rustfmt Check + # uses: actions-rust-lang/rustfmt@v1 + + # TODO: Use setup-dafny-actions with correct version when Dafny releases 4.8.2 + - name: Setup Dafny + uses: dafny-lang/setup-dafny-action@v1.7.0 + with: + dafny-version: 4.9.0 + + # TODO: Remove this after the formatting in Rust starts working + - name: smithy-dafny Rust hacks + shell: bash + run: | + if [ "$RUNNER_OS" == "macOS" ]; then + sed -i '' 's|rustfmt --edition 2021 runtimes/rust/src/implementation_from_dafny.rs|#&|' smithy-dafny/SmithyDafnyMakefile.mk + else + sed -i 's|rustfmt --edition 2021 runtimes/rust/src/implementation_from_dafny.rs|#&|' smithy-dafny/SmithyDafnyMakefile.mk + fi + + - name: Setup Java 17 for codegen + uses: actions/setup-java@v3 + with: + distribution: "corretto" + java-version: "17" + + - name: Setup NASM for Windows (aws-lc-sys) + if: matrix.os == 'windows-latest' + uses: ilammy/setup-nasm@v1 + + - name: Install Smithy-Dafny codegen dependencies + uses: ./.github/actions/install_smithy_dafny_codegen_dependencies + + - name: Run make polymorph_rust + shell: bash + working-directory: ./${{ matrix.library }} + run: | + make polymorph_rust + + - name: Compile ${{ matrix.library }} implementation + shell: bash + working-directory: ./${{ matrix.library }} + run: | + # This works because `node` is installed by default on GHA runners + CORES=$(node -e 'console.log(os.cpus().length)') + make transpile_rust TRANSPILE_TESTS_IN_RUST=1 CORES=$CORES + + - name: Test ${{ matrix.library }} Rust + shell: bash + working-directory: ./${{ matrix.library }} + run: | + make test_rust diff --git a/.github/workflows/manual.yml b/.github/workflows/manual.yml index 872df87481..11dac1ac3c 100644 --- a/.github/workflows/manual.yml +++ b/.github/workflows/manual.yml @@ -37,6 +37,11 @@ jobs: with: dafny: ${{ inputs.dafny }} regenerate-code: ${{ inputs.regenerate-code }} + manual-ci-rust: + uses: ./.github/workflows/library_rust_tests.yml + with: + dafny: ${{ inputs.dafny }} + regenerate-code: ${{ inputs.regenerate-code }} manual-ci-python: uses: ./.github/workflows/library_python_tests.yml with: diff --git a/.github/workflows/nightly_dafny.yml b/.github/workflows/nightly_dafny.yml index 8d7f7ab5bb..82050f369e 100644 --- a/.github/workflows/nightly_dafny.yml +++ b/.github/workflows/nightly_dafny.yml @@ -41,6 +41,12 @@ jobs: with: dafny: "nightly-latest" regenerate-code: true + dafny-nightly-rust: + if: github.event_name != 'schedule' || github.repository_owner == 'aws' + uses: ./.github/workflows/library_rust_tests.yml + with: + dafny: "nightly-latest" + regenerate-code: true dafny-nightly-python: needs: getVersion if: github.event_name != 'schedule' || github.repository_owner == 'aws' diff --git a/.github/workflows/pull.yml b/.github/workflows/pull.yml index 5756acd1d2..8b14194b99 100644 --- a/.github/workflows/pull.yml +++ b/.github/workflows/pull.yml @@ -34,6 +34,11 @@ jobs: uses: ./.github/workflows/library_net_tests.yml with: dafny: ${{needs.getVersion.outputs.version}} + pr-ci-rust: + needs: getVersion + uses: ./.github/workflows/library_rust_tests.yml + with: + dafny: ${{needs.getVersion.outputs.version}} pr-ci-python: needs: getVersion uses: ./.github/workflows/library_python_tests.yml diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 18f45b044e..afe067b32d 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -36,6 +36,11 @@ jobs: uses: ./.github/workflows/library_net_tests.yml with: dafny: ${{needs.getVersion.outputs.version}} + push-ci-rust: + needs: getVersion + uses: ./.github/workflows/library_rust_tests.yml + with: + dafny: ${{needs.getVersion.outputs.version}} push-ci-python: needs: getVersion uses: ./.github/workflows/library_python_tests.yml diff --git a/.github/workflows/sem_ver.yml b/.github/workflows/sem_ver.yml index 58fc64cc05..51f5ce2d76 100644 --- a/.github/workflows/sem_ver.yml +++ b/.github/workflows/sem_ver.yml @@ -6,7 +6,7 @@ on: jobs: semantic-release: - runs-on: macos-12 + runs-on: macos-13 permissions: id-token: write contents: read diff --git a/.github/workflows/semantic_release.yml b/.github/workflows/semantic_release.yml index 72e0bdb746..97f6a8f399 100644 --- a/.github/workflows/semantic_release.yml +++ b/.github/workflows/semantic_release.yml @@ -15,7 +15,7 @@ jobs: # privileged operation, so we must make sure this list of users is a subset of the users labeled as maintainers of # https://github.com/orgs/aws/teams/aws-crypto-tools if: contains('["seebees","texastony","ShubhamChaturvedi7","lucasmcdonald3","josecorella","imabhichow","rishav-karanjit","antonf-amzn","kessplas","RitvikKapila","ajewellamz"]', github.actor) - runs-on: macos-12 + runs-on: macos-13 permissions: id-token: write contents: write diff --git a/.gitignore b/.gitignore index 12d93feaab..8dc5091d95 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,7 @@ build/* test/**/Output/* /package-lock.json -/node_modules +node_modules *.log # Python docs build Artifacts diff --git a/.prettierignore b/.prettierignore index 9fe68598b1..b59346bd86 100644 --- a/.prettierignore +++ b/.prettierignore @@ -6,6 +6,7 @@ libraries */runtimes/java/build/* */runtimes/net/obj/* */runtimes/net/bin/* +*/runtimes/rust/target/* # Dafny generated java */runtimes/java/src/*/dafny-generated/* diff --git a/AwsCryptographicMaterialProviders/Makefile b/AwsCryptographicMaterialProviders/Makefile index 9242af331d..ab65f66c34 100644 --- a/AwsCryptographicMaterialProviders/Makefile +++ b/AwsCryptographicMaterialProviders/Makefile @@ -13,6 +13,28 @@ PROJECT_SERVICES := \ SERVICE_NAMESPACE_AwsCryptographicMaterialProviders=aws.cryptography.materialProviders SERVICE_NAMESPACE_AwsCryptographyKeyStore=aws.cryptography.keyStore +MAIN_SERVICE_FOR_RUST := AwsCryptographicMaterialProviders + +RUST_OTHER_FILES := \ + runtimes/rust/src/aes_gcm.rs \ + runtimes/rust/src/aes_kdf_ctr.rs \ + runtimes/rust/src/ddb.rs \ + runtimes/rust/src/concurrent_call.rs \ + runtimes/rust/src/dafny_libraries.rs \ + runtimes/rust/src/digest.rs \ + runtimes/rust/src/ecdh.rs \ + runtimes/rust/src/ecdsa.rs \ + runtimes/rust/src/hmac.rs \ + runtimes/rust/src/kms.rs \ + runtimes/rust/src/local_cmc.rs \ + runtimes/rust/src/random.rs \ + runtimes/rust/src/rsa.rs \ + runtimes/rust/src/sets.rs \ + runtimes/rust/src/software_externs.rs \ + runtimes/rust/src/storm_tracker.rs \ + runtimes/rust/src/time.rs \ + runtimes/rust/src/uuid.rs + MAX_RESOURCE_COUNT=90000000 # Order is important # In java they MUST be built diff --git a/AwsCryptographicMaterialProviders/codebuild/release-python/prod-release.yml b/AwsCryptographicMaterialProviders/codebuild/release-python/prod-release.yml index f9774dd073..3184f2cfde 100644 --- a/AwsCryptographicMaterialProviders/codebuild/release-python/prod-release.yml +++ b/AwsCryptographicMaterialProviders/codebuild/release-python/prod-release.yml @@ -28,6 +28,15 @@ phases: - git fetch --tags - git checkout $COMMIT_ID - FOUND_VERSION=$(sed -n 's/version = "\(.*\)"/\1/p' AwsCryptographicMaterialProviders/runtimes/python/pyproject.toml) + # Assert we are not releasing "aws-cryptographic-material-providers==10.0.0" to prod PyPI. + # A bad release has already been uploaded under this name/version to prod PyPI. + # This release has been deleted. + # Prod PyPI does not allow re-uploading a release under the same name/version. + - | + if expr ${FOUND_VERSION} == "10.0.0"; then + echo "Cannot release version 10.0.0" + exit 1; + fi - | if expr ${FOUND_VERSION} != ${VERSION}; then echo "pyproject.toml version (${FOUND_VERSION}) does not match expected version (${VERSION}), stopping" diff --git a/AwsCryptographicMaterialProviders/codebuild/release-python/test-release.yml b/AwsCryptographicMaterialProviders/codebuild/release-python/test-release.yml index 38517065a0..d672c0f3e8 100644 --- a/AwsCryptographicMaterialProviders/codebuild/release-python/test-release.yml +++ b/AwsCryptographicMaterialProviders/codebuild/release-python/test-release.yml @@ -28,6 +28,16 @@ phases: - git fetch --tags - git checkout $COMMIT_ID - FOUND_VERSION=$(sed -n 's/version = "\(.*\)"/\1/p' AwsCryptographicMaterialProviders/runtimes/python/pyproject.toml) + # Assert we are not releasing "aws-cryptographic-material-providers==10.0.0" to prod PyPI. + # A bad release has already been uploaded under this name/version to prod PyPI. + # This release has been deleted. + # Prod PyPI does not allow re-uploading a release under the same name/version. + # (We do not need this assertion for other libraries in the MPL; this only applies to "aws-cryptographic-material-providers==10.0.0".) + - | + if expr ${FOUND_VERSION} == "10.0.0"; then + echo "Cannot release version 10.0.0" + exit 1; + fi - | if expr ${FOUND_VERSION} != ${VERSION}; then echo "pyproject.toml version (${FOUND_VERSION}) does not match expected version (${VERSION}), stopping" diff --git a/AwsCryptographicMaterialProviders/codebuild/release-python/validate.yml b/AwsCryptographicMaterialProviders/codebuild/release-python/validate.yml index d701b5e330..a727dbb8d6 100644 --- a/AwsCryptographicMaterialProviders/codebuild/release-python/validate.yml +++ b/AwsCryptographicMaterialProviders/codebuild/release-python/validate.yml @@ -25,6 +25,9 @@ phases: - export PATH="$PWD/dafny:$PATH" # Switch back to the main directory - cd aws-cryptographic-material-providers-library + # Check out tests for release commit + - git fetch --tags + - git checkout $COMMIT_ID # Install test dependencies - pyenv install --skip-existing 3.11 - pyenv local 3.11 @@ -35,7 +38,7 @@ phases: # The actual test code must be from local, since we don't publish tests. - pip install aws-cryptographic-material-providers==$VERSION # Install ESDK-Python, override its requirements to force use of the just-published MPL version - - git clone -b mpl-reviewed https://github.com/aws/aws-encryption-sdk-python.git + - git clone -b master https://github.com/aws/aws-encryption-sdk-python.git - cd aws-encryption-sdk-python - sed -i "s/aws-cryptographic-material-providers.*/aws-cryptographic-material-providers==$VERSION/" requirements_mpl.txt - cd .. diff --git a/AwsCryptographicMaterialProviders/dafny/AwsCryptographicMaterialProviders/Model/AwsCryptographyMaterialProvidersTypes.dfy b/AwsCryptographicMaterialProviders/dafny/AwsCryptographicMaterialProviders/Model/AwsCryptographyMaterialProvidersTypes.dfy index 0790e276f9..a32d3987ff 100644 --- a/AwsCryptographicMaterialProviders/dafny/AwsCryptographicMaterialProviders/Model/AwsCryptographyMaterialProvidersTypes.dfy +++ b/AwsCryptographicMaterialProviders/dafny/AwsCryptographicMaterialProviders/Model/AwsCryptographyMaterialProvidersTypes.dfy @@ -1713,7 +1713,9 @@ module {:extern "software.amazon.cryptography.materialproviders.internaldafny.ty | CollectionOfErrors(list: seq, nameonly message: string) // The Opaque error, used for native, extern, wrapped or unknown errors | Opaque(obj: object) - type OpaqueError = e: Error | e.Opaque? witness * + // A better Opaque, with a visible string representation. + | OpaqueWithText(obj: object, objMessage : string) + type OpaqueError = e: Error | e.Opaque? || e.OpaqueWithText? witness * // This dummy subset type is included to make sure Dafny // always generates a _ExternBase___default.java class. type DummySubsetType = x: int | IsDummySubsetType(x) witness 1 diff --git a/AwsCryptographicMaterialProviders/dafny/AwsCryptographyKeyStore/Model/AwsCryptographyKeyStoreTypes.dfy b/AwsCryptographicMaterialProviders/dafny/AwsCryptographyKeyStore/Model/AwsCryptographyKeyStoreTypes.dfy index b16e75d070..a371045798 100644 --- a/AwsCryptographicMaterialProviders/dafny/AwsCryptographyKeyStore/Model/AwsCryptographyKeyStoreTypes.dfy +++ b/AwsCryptographicMaterialProviders/dafny/AwsCryptographyKeyStore/Model/AwsCryptographyKeyStoreTypes.dfy @@ -283,7 +283,9 @@ module {:extern "software.amazon.cryptography.keystore.internaldafny.types" } Aw | CollectionOfErrors(list: seq, nameonly message: string) // The Opaque error, used for native, extern, wrapped or unknown errors | Opaque(obj: object) - type OpaqueError = e: Error | e.Opaque? witness * + // A better Opaque, with a visible string representation. + | OpaqueWithText(obj: object, objMessage : string) + type OpaqueError = e: Error | e.Opaque? || e.OpaqueWithText? witness * // This dummy subset type is included to make sure Dafny // always generates a _ExternBase___default.java class. type DummySubsetType = x: int | IsDummySubsetType(x) witness 1 diff --git a/AwsCryptographicMaterialProviders/dafny/AwsCryptographyKeyStore/test/TestGetKeys.dfy b/AwsCryptographicMaterialProviders/dafny/AwsCryptographyKeyStore/test/TestGetKeys.dfy index 23cda9e28a..7efc428c44 100644 --- a/AwsCryptographicMaterialProviders/dafny/AwsCryptographyKeyStore/test/TestGetKeys.dfy +++ b/AwsCryptographicMaterialProviders/dafny/AwsCryptographyKeyStore/test/TestGetKeys.dfy @@ -182,7 +182,7 @@ module TestGetKeys { Types.GetActiveBranchKeyInput(branchKeyIdentifier := WestBranchKey)); expect badResult.Failure?; expect badResult.error.ComAmazonawsKms?; - expect badResult.error.ComAmazonawsKms.Opaque?; + expect badResult.error.ComAmazonawsKms.OpaqueWithText?; // it's an opaque error, so I can't test its contents } diff --git a/AwsCryptographicMaterialProviders/project.properties b/AwsCryptographicMaterialProviders/project.properties index f5e8cdf0b4..55d988fe1b 100644 --- a/AwsCryptographicMaterialProviders/project.properties +++ b/AwsCryptographicMaterialProviders/project.properties @@ -1,4 +1,4 @@ # This file stores the top level dafny version information. # All elements of the project need to agree on this version. -dafnyVersion=4.8.1 -dafnyRuntimeJavaVersion=4.8.1 +dafnyVersion=4.9.0 +dafnyRuntimeJavaVersion=4.9.0 diff --git a/AwsCryptographicMaterialProviders/runtimes/java/build.gradle.kts b/AwsCryptographicMaterialProviders/runtimes/java/build.gradle.kts index 8b48714086..4391add8e1 100644 --- a/AwsCryptographicMaterialProviders/runtimes/java/build.gradle.kts +++ b/AwsCryptographicMaterialProviders/runtimes/java/build.gradle.kts @@ -18,7 +18,7 @@ var props = Properties().apply { var dafnyVersion = props.getProperty("dafnyVersion") group = "software.amazon.cryptography" -version = "1.7.3-SNAPSHOT" +version = "1.7.4-SNAPSHOT" description = "AWS Cryptographic Material Providers Library" java { diff --git a/AwsCryptographicMaterialProviders/runtimes/java/src/main/java/software/amazon/cryptography/internaldafny/StormTrackingCMC/StormTrackingCMC.java b/AwsCryptographicMaterialProviders/runtimes/java/src/main/java/software/amazon/cryptography/internaldafny/StormTrackingCMC/StormTrackingCMC.java index df5cfb803a..19154ce584 100644 --- a/AwsCryptographicMaterialProviders/runtimes/java/src/main/java/software/amazon/cryptography/internaldafny/StormTrackingCMC/StormTrackingCMC.java +++ b/AwsCryptographicMaterialProviders/runtimes/java/src/main/java/software/amazon/cryptography/internaldafny/StormTrackingCMC/StormTrackingCMC.java @@ -109,7 +109,13 @@ > GetCacheEntry_k( } else { try { Thread.sleep(wrapped.sleepMilli); - } catch (Exception e) {} + } catch (Exception e) { + return CreateGetCacheEntryFailure( + software.amazon.cryptography.materialproviders.internaldafny.types.Error.create_Opaque( + e + ) + ); + } } } } diff --git a/AwsCryptographicMaterialProviders/runtimes/java/src/main/java/software/amazon/cryptography/keystore/types/__default.java b/AwsCryptographicMaterialProviders/runtimes/java/src/main/java/software/amazon/cryptography/keystore/types/__default.java index 35abb02657..3c8bbba4cf 100644 --- a/AwsCryptographicMaterialProviders/runtimes/java/src/main/java/software/amazon/cryptography/keystore/types/__default.java +++ b/AwsCryptographicMaterialProviders/runtimes/java/src/main/java/software/amazon/cryptography/keystore/types/__default.java @@ -1,4 +1,4 @@ package software.amazon.cryptography.keystore.internaldafny.types; public class __default - extends software.amazon.cryptography.keystore.internaldafny._ExternBase___default {} + extends software.amazon.cryptography.keystore.internaldafny.types._ExternBase___default {} diff --git a/AwsCryptographicMaterialProviders/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/keystore/ToDafny.java b/AwsCryptographicMaterialProviders/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/keystore/ToDafny.java index 9a949c1490..0788d384fc 100644 --- a/AwsCryptographicMaterialProviders/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/keystore/ToDafny.java +++ b/AwsCryptographicMaterialProviders/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/keystore/ToDafny.java @@ -41,6 +41,7 @@ import software.amazon.cryptography.keystore.model.CollectionOfErrors; import software.amazon.cryptography.keystore.model.KeyStoreException; import software.amazon.cryptography.keystore.model.OpaqueError; +import software.amazon.cryptography.keystore.model.OpaqueWithTextError; import software.amazon.cryptography.services.dynamodb.internaldafny.types.IDynamoDBClient; import software.amazon.cryptography.services.kms.internaldafny.types.IKMSClient; @@ -53,6 +54,9 @@ public static Error Error(RuntimeException nativeValue) { if (nativeValue instanceof OpaqueError) { return ToDafny.Error((OpaqueError) nativeValue); } + if (nativeValue instanceof OpaqueWithTextError) { + return ToDafny.Error((OpaqueWithTextError) nativeValue); + } if (nativeValue instanceof CollectionOfErrors) { return ToDafny.Error((CollectionOfErrors) nativeValue); } @@ -63,6 +67,13 @@ public static Error Error(OpaqueError nativeValue) { return Error.create_Opaque(nativeValue.obj()); } + public static Error Error(OpaqueWithTextError nativeValue) { + return Error.create_OpaqueWithText( + nativeValue.obj(), + dafny.DafnySequence.asString(nativeValue.objMessage()) + ); + } + public static Error Error(CollectionOfErrors nativeValue) { DafnySequence list = software.amazon.smithy.dafny.conversion.ToDafny.Aggregate.GenericToSequence( diff --git a/AwsCryptographicMaterialProviders/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/keystore/ToNative.java b/AwsCryptographicMaterialProviders/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/keystore/ToNative.java index e2ac0de8fc..2171f5406b 100644 --- a/AwsCryptographicMaterialProviders/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/keystore/ToNative.java +++ b/AwsCryptographicMaterialProviders/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/keystore/ToNative.java @@ -16,6 +16,7 @@ import software.amazon.cryptography.keystore.internaldafny.types.Error_CollectionOfErrors; import software.amazon.cryptography.keystore.internaldafny.types.Error_KeyStoreException; import software.amazon.cryptography.keystore.internaldafny.types.Error_Opaque; +import software.amazon.cryptography.keystore.internaldafny.types.Error_OpaqueWithText; import software.amazon.cryptography.keystore.internaldafny.types.IKeyStoreClient; import software.amazon.cryptography.keystore.model.BeaconKeyMaterials; import software.amazon.cryptography.keystore.model.BranchKeyMaterials; @@ -37,6 +38,7 @@ import software.amazon.cryptography.keystore.model.KeyStoreException; import software.amazon.cryptography.keystore.model.MRDiscovery; import software.amazon.cryptography.keystore.model.OpaqueError; +import software.amazon.cryptography.keystore.model.OpaqueWithTextError; import software.amazon.cryptography.keystore.model.VersionKeyInput; import software.amazon.cryptography.keystore.model.VersionKeyOutput; @@ -48,6 +50,17 @@ public static OpaqueError Error(Error_Opaque dafnyValue) { return nativeBuilder.build(); } + public static OpaqueWithTextError Error(Error_OpaqueWithText dafnyValue) { + OpaqueWithTextError.Builder nativeBuilder = OpaqueWithTextError.builder(); + nativeBuilder.obj(dafnyValue.dtor_obj()); + nativeBuilder.objMessage( + software.amazon.smithy.dafny.conversion.ToNative.Simple.String( + dafnyValue.dtor_objMessage() + ) + ); + return nativeBuilder.build(); + } + public static CollectionOfErrors Error(Error_CollectionOfErrors dafnyValue) { CollectionOfErrors.Builder nativeBuilder = CollectionOfErrors.builder(); nativeBuilder.list( @@ -81,6 +94,9 @@ public static RuntimeException Error(Error dafnyValue) { if (dafnyValue.is_Opaque()) { return ToNative.Error((Error_Opaque) dafnyValue); } + if (dafnyValue.is_OpaqueWithText()) { + return ToNative.Error((Error_OpaqueWithText) dafnyValue); + } if (dafnyValue.is_CollectionOfErrors()) { return ToNative.Error((Error_CollectionOfErrors) dafnyValue); } diff --git a/AwsCryptographicMaterialProviders/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/keystore/model/OpaqueWithTextError.java b/AwsCryptographicMaterialProviders/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/keystore/model/OpaqueWithTextError.java new file mode 100644 index 0000000000..3c4bd3aa27 --- /dev/null +++ b/AwsCryptographicMaterialProviders/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/keystore/model/OpaqueWithTextError.java @@ -0,0 +1,180 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// Do not modify this file. This file is machine generated, and any changes to it will be overwritten. +package software.amazon.cryptography.keystore.model; + +public class OpaqueWithTextError extends RuntimeException { + + /** + * The unexpected object encountered. It MIGHT BE an Exception, but that is not guaranteed. + */ + private final Object obj; + + /** + * The text equivalent of obj. + */ + private final String objMessage; + + protected OpaqueWithTextError(BuilderImpl builder) { + super(messageFromBuilder(builder), builder.cause()); + this.obj = builder.obj(); + this.objMessage = builder.objMessage(); + } + + private static String messageFromBuilder(Builder builder) { + if (builder.message() != null) { + return builder.message(); + } + if (builder.cause() != null) { + return builder.cause().getMessage(); + } + return null; + } + + /** + * See {@link Throwable#getMessage()}. + */ + public String message() { + return this.getMessage(); + } + + /** + * See {@link Throwable#getCause()}. + */ + public Throwable cause() { + return this.getCause(); + } + + /** + * @return The unexpected object encountered. It MIGHT BE an Exception, but that is not guaranteed. + */ + public Object obj() { + return this.obj; + } + + /** + * @return The text equivalent of obj. + */ + public String objMessage() { + return this.objMessage; + } + + public Builder toBuilder() { + return new BuilderImpl(this); + } + + public static Builder builder() { + return new BuilderImpl(); + } + + public interface Builder { + /** + * @param message The detailed message. The detail message is saved for later retrieval by the {@link #getMessage()} method. + */ + Builder message(String message); + + /** + * @return The detailed message. The detail message is saved for later retrieval by the {@link #getMessage()} method. + */ + String message(); + + /** + * @param cause The cause (which is saved for later retrieval by the {@link #getCause()} method). (A {@code null} value is permitted, and indicates that the cause is nonexistent or unknown.) + */ + Builder cause(Throwable cause); + + /** + * @return The cause (which is saved for later retrieval by the {@link #getCause()} method). (A {@code null} value is permitted, and indicates that the cause is nonexistent or unknown.) + */ + Throwable cause(); + + /** + * @param obj The unexpected object encountered. It MIGHT BE an Exception, but that is not guaranteed. + */ + Builder obj(Object obj); + + /** + * @return The unexpected object encountered. It MIGHT BE an Exception, but that is not guaranteed. + */ + Object obj(); + + /** + * @param objMessage The text equivalent of obj. + */ + Builder objMessage(String objMessage); + + /** + * @return The text equivalent of obj. + */ + String objMessage(); + + OpaqueWithTextError build(); + } + + static class BuilderImpl implements Builder { + + protected String message; + + protected Throwable cause; + + protected Object obj; + + protected String objMessage; + + protected BuilderImpl() {} + + protected BuilderImpl(OpaqueWithTextError model) { + this.cause = model.getCause(); + this.message = model.getMessage(); + this.obj = model.obj(); + this.objMessage = model.objMessage(); + } + + public Builder message(String message) { + this.message = message; + return this; + } + + public String message() { + return this.message; + } + + public Builder cause(Throwable cause) { + this.cause = cause; + return this; + } + + public Throwable cause() { + return this.cause; + } + + public Builder obj(Object obj) { + this.obj = obj; + return this; + } + + public Object obj() { + return this.obj; + } + + public Builder objMessage(String objMessage) { + this.objMessage = objMessage; + return this; + } + + public String objMessage() { + return this.objMessage; + } + + public OpaqueWithTextError build() { + if ( + this.obj != null && this.cause == null && this.obj instanceof Throwable + ) { + this.cause = (Throwable) this.obj; + } else if (this.obj == null && this.cause != null) { + this.obj = this.cause; + } + return new OpaqueWithTextError(this); + } + } +} diff --git a/AwsCryptographicMaterialProviders/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/materialproviders/ToDafny.java b/AwsCryptographicMaterialProviders/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/materialproviders/ToDafny.java index d2efbf5117..469094c39d 100644 --- a/AwsCryptographicMaterialProviders/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/materialproviders/ToDafny.java +++ b/AwsCryptographicMaterialProviders/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/materialproviders/ToDafny.java @@ -126,6 +126,7 @@ import software.amazon.cryptography.materialproviders.model.InvalidEncryptionMaterials; import software.amazon.cryptography.materialproviders.model.InvalidEncryptionMaterialsTransition; import software.amazon.cryptography.materialproviders.model.OpaqueError; +import software.amazon.cryptography.materialproviders.model.OpaqueWithTextError; import software.amazon.cryptography.primitives.internaldafny.types.DigestAlgorithm; import software.amazon.cryptography.primitives.internaldafny.types.ECDHCurveSpec; import software.amazon.cryptography.primitives.internaldafny.types.ECDSASignatureAlgorithm; @@ -170,6 +171,9 @@ public static Error Error(RuntimeException nativeValue) { if (nativeValue instanceof OpaqueError) { return ToDafny.Error((OpaqueError) nativeValue); } + if (nativeValue instanceof OpaqueWithTextError) { + return ToDafny.Error((OpaqueWithTextError) nativeValue); + } if (nativeValue instanceof CollectionOfErrors) { return ToDafny.Error((CollectionOfErrors) nativeValue); } @@ -180,6 +184,13 @@ public static Error Error(OpaqueError nativeValue) { return Error.create_Opaque(nativeValue.obj()); } + public static Error Error(OpaqueWithTextError nativeValue) { + return Error.create_OpaqueWithText( + nativeValue.obj(), + dafny.DafnySequence.asString(nativeValue.objMessage()) + ); + } + public static Error Error(CollectionOfErrors nativeValue) { DafnySequence list = software.amazon.smithy.dafny.conversion.ToDafny.Aggregate.GenericToSequence( diff --git a/AwsCryptographicMaterialProviders/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/materialproviders/ToNative.java b/AwsCryptographicMaterialProviders/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/materialproviders/ToNative.java index 9bd2cbf7cd..50092ec55f 100644 --- a/AwsCryptographicMaterialProviders/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/materialproviders/ToNative.java +++ b/AwsCryptographicMaterialProviders/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/materialproviders/ToNative.java @@ -27,6 +27,7 @@ import software.amazon.cryptography.materialproviders.internaldafny.types.Error_InvalidEncryptionMaterials; import software.amazon.cryptography.materialproviders.internaldafny.types.Error_InvalidEncryptionMaterialsTransition; import software.amazon.cryptography.materialproviders.internaldafny.types.Error_Opaque; +import software.amazon.cryptography.materialproviders.internaldafny.types.Error_OpaqueWithText; import software.amazon.cryptography.materialproviders.internaldafny.types.IAwsCryptographicMaterialProvidersClient; import software.amazon.cryptography.materialproviders.model.AesWrappingAlg; import software.amazon.cryptography.materialproviders.model.AlgorithmSuiteId; @@ -107,6 +108,7 @@ import software.amazon.cryptography.materialproviders.model.OnEncryptInput; import software.amazon.cryptography.materialproviders.model.OnEncryptOutput; import software.amazon.cryptography.materialproviders.model.OpaqueError; +import software.amazon.cryptography.materialproviders.model.OpaqueWithTextError; import software.amazon.cryptography.materialproviders.model.PaddingScheme; import software.amazon.cryptography.materialproviders.model.PublicKeyDiscoveryInput; import software.amazon.cryptography.materialproviders.model.PutCacheEntryInput; @@ -131,6 +133,17 @@ public static OpaqueError Error(Error_Opaque dafnyValue) { return nativeBuilder.build(); } + public static OpaqueWithTextError Error(Error_OpaqueWithText dafnyValue) { + OpaqueWithTextError.Builder nativeBuilder = OpaqueWithTextError.builder(); + nativeBuilder.obj(dafnyValue.dtor_obj()); + nativeBuilder.objMessage( + software.amazon.smithy.dafny.conversion.ToNative.Simple.String( + dafnyValue.dtor_objMessage() + ) + ); + return nativeBuilder.build(); + } + public static CollectionOfErrors Error(Error_CollectionOfErrors dafnyValue) { CollectionOfErrors.Builder nativeBuilder = CollectionOfErrors.builder(); nativeBuilder.list( @@ -315,6 +328,9 @@ public static RuntimeException Error(Error dafnyValue) { if (dafnyValue.is_Opaque()) { return ToNative.Error((Error_Opaque) dafnyValue); } + if (dafnyValue.is_OpaqueWithText()) { + return ToNative.Error((Error_OpaqueWithText) dafnyValue); + } if (dafnyValue.is_CollectionOfErrors()) { return ToNative.Error((Error_CollectionOfErrors) dafnyValue); } diff --git a/AwsCryptographicMaterialProviders/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/materialproviders/model/OpaqueWithTextError.java b/AwsCryptographicMaterialProviders/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/materialproviders/model/OpaqueWithTextError.java new file mode 100644 index 0000000000..53ba43a7bc --- /dev/null +++ b/AwsCryptographicMaterialProviders/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/materialproviders/model/OpaqueWithTextError.java @@ -0,0 +1,180 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// Do not modify this file. This file is machine generated, and any changes to it will be overwritten. +package software.amazon.cryptography.materialproviders.model; + +public class OpaqueWithTextError extends RuntimeException { + + /** + * The unexpected object encountered. It MIGHT BE an Exception, but that is not guaranteed. + */ + private final Object obj; + + /** + * The text equivalent of obj. + */ + private final String objMessage; + + protected OpaqueWithTextError(BuilderImpl builder) { + super(messageFromBuilder(builder), builder.cause()); + this.obj = builder.obj(); + this.objMessage = builder.objMessage(); + } + + private static String messageFromBuilder(Builder builder) { + if (builder.message() != null) { + return builder.message(); + } + if (builder.cause() != null) { + return builder.cause().getMessage(); + } + return null; + } + + /** + * See {@link Throwable#getMessage()}. + */ + public String message() { + return this.getMessage(); + } + + /** + * See {@link Throwable#getCause()}. + */ + public Throwable cause() { + return this.getCause(); + } + + /** + * @return The unexpected object encountered. It MIGHT BE an Exception, but that is not guaranteed. + */ + public Object obj() { + return this.obj; + } + + /** + * @return The text equivalent of obj. + */ + public String objMessage() { + return this.objMessage; + } + + public Builder toBuilder() { + return new BuilderImpl(this); + } + + public static Builder builder() { + return new BuilderImpl(); + } + + public interface Builder { + /** + * @param message The detailed message. The detail message is saved for later retrieval by the {@link #getMessage()} method. + */ + Builder message(String message); + + /** + * @return The detailed message. The detail message is saved for later retrieval by the {@link #getMessage()} method. + */ + String message(); + + /** + * @param cause The cause (which is saved for later retrieval by the {@link #getCause()} method). (A {@code null} value is permitted, and indicates that the cause is nonexistent or unknown.) + */ + Builder cause(Throwable cause); + + /** + * @return The cause (which is saved for later retrieval by the {@link #getCause()} method). (A {@code null} value is permitted, and indicates that the cause is nonexistent or unknown.) + */ + Throwable cause(); + + /** + * @param obj The unexpected object encountered. It MIGHT BE an Exception, but that is not guaranteed. + */ + Builder obj(Object obj); + + /** + * @return The unexpected object encountered. It MIGHT BE an Exception, but that is not guaranteed. + */ + Object obj(); + + /** + * @param objMessage The text equivalent of obj. + */ + Builder objMessage(String objMessage); + + /** + * @return The text equivalent of obj. + */ + String objMessage(); + + OpaqueWithTextError build(); + } + + static class BuilderImpl implements Builder { + + protected String message; + + protected Throwable cause; + + protected Object obj; + + protected String objMessage; + + protected BuilderImpl() {} + + protected BuilderImpl(OpaqueWithTextError model) { + this.cause = model.getCause(); + this.message = model.getMessage(); + this.obj = model.obj(); + this.objMessage = model.objMessage(); + } + + public Builder message(String message) { + this.message = message; + return this; + } + + public String message() { + return this.message; + } + + public Builder cause(Throwable cause) { + this.cause = cause; + return this; + } + + public Throwable cause() { + return this.cause; + } + + public Builder obj(Object obj) { + this.obj = obj; + return this; + } + + public Object obj() { + return this.obj; + } + + public Builder objMessage(String objMessage) { + this.objMessage = objMessage; + return this; + } + + public String objMessage() { + return this.objMessage; + } + + public OpaqueWithTextError build() { + if ( + this.obj != null && this.cause == null && this.obj instanceof Throwable + ) { + this.cause = (Throwable) this.obj; + } else if (this.obj == null && this.cause != null) { + this.obj = this.cause; + } + return new OpaqueWithTextError(this); + } + } +} diff --git a/AwsCryptographicMaterialProviders/runtimes/net/AssemblyInfo.cs b/AwsCryptographicMaterialProviders/runtimes/net/AssemblyInfo.cs index 15197e1db2..ccf03cd039 100644 --- a/AwsCryptographicMaterialProviders/runtimes/net/AssemblyInfo.cs +++ b/AwsCryptographicMaterialProviders/runtimes/net/AssemblyInfo.cs @@ -3,4 +3,4 @@ [assembly: AssemblyTitle("AWS.Cryptography.MaterialProviders")] // This should be kept in sync with the version number in MPL.csproj -[assembly: AssemblyVersion("1.7.3")] +[assembly: AssemblyVersion("1.7.4")] diff --git a/AwsCryptographicMaterialProviders/runtimes/net/Generated/AwsCryptographicMaterialProviders/OpaqueWithTextError.cs b/AwsCryptographicMaterialProviders/runtimes/net/Generated/AwsCryptographicMaterialProviders/OpaqueWithTextError.cs new file mode 100644 index 0000000000..55fff5741f --- /dev/null +++ b/AwsCryptographicMaterialProviders/runtimes/net/Generated/AwsCryptographicMaterialProviders/OpaqueWithTextError.cs @@ -0,0 +1,17 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// Do not modify this file. This file is machine generated, and any changes to it will be overwritten. +using System; +using AWS.Cryptography.MaterialProviders; +namespace AWS.Cryptography.MaterialProviders +{ + public class OpaqueWithTextError : Exception + { + public readonly object obj; + public readonly string objMessage; + public OpaqueWithTextError(Exception ex) : base("OpaqueError:", ex) { this.obj = ex; this.objMessage = obj.ToString(); } + public OpaqueWithTextError() : base("Unknown Unexpected Error") { } + public OpaqueWithTextError(object obj, string objMessage) : base(obj is Exception ? "OpaqueWithTextError:" : "Opaque obj is not an Exception.", obj as Exception) { this.obj = obj; this.objMessage = objMessage; } + } + +} diff --git a/AwsCryptographicMaterialProviders/runtimes/net/Generated/AwsCryptographicMaterialProviders/TypeConversion.cs b/AwsCryptographicMaterialProviders/runtimes/net/Generated/AwsCryptographicMaterialProviders/TypeConversion.cs index 56aef9ec66..315ad15e7e 100644 --- a/AwsCryptographicMaterialProviders/runtimes/net/Generated/AwsCryptographicMaterialProviders/TypeConversion.cs +++ b/AwsCryptographicMaterialProviders/runtimes/net/Generated/AwsCryptographicMaterialProviders/TypeConversion.cs @@ -3935,6 +3935,8 @@ public static System.Exception FromDafny_CommonError(software.amazon.cryptograph new string(dafnyVal.dtor_message.Elements)); case software.amazon.cryptography.materialproviders.internaldafny.types.Error_Opaque dafnyVal: return new OpaqueError(dafnyVal._obj); + case software.amazon.cryptography.materialproviders.internaldafny.types.Error_OpaqueWithText dafnyVal: + return new OpaqueWithTextError(dafnyVal._obj, dafnyVal._obj.ToString()); default: // The switch MUST be complete for _IError, so `value` MUST NOT be an _IError. (How did you get here?) return new OpaqueError(); diff --git a/AwsCryptographicMaterialProviders/runtimes/net/Generated/AwsCryptographyKeyStore/OpaqueWithTextError.cs b/AwsCryptographicMaterialProviders/runtimes/net/Generated/AwsCryptographyKeyStore/OpaqueWithTextError.cs new file mode 100644 index 0000000000..30923009fc --- /dev/null +++ b/AwsCryptographicMaterialProviders/runtimes/net/Generated/AwsCryptographyKeyStore/OpaqueWithTextError.cs @@ -0,0 +1,17 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// Do not modify this file. This file is machine generated, and any changes to it will be overwritten. +using System; +using AWS.Cryptography.KeyStore; +namespace AWS.Cryptography.KeyStore +{ + public class OpaqueWithTextError : Exception + { + public readonly object obj; + public readonly string objMessage; + public OpaqueWithTextError(Exception ex) : base("OpaqueError:", ex) { this.obj = ex; this.objMessage = obj.ToString(); } + public OpaqueWithTextError() : base("Unknown Unexpected Error") { } + public OpaqueWithTextError(object obj, string objMessage) : base(obj is Exception ? "OpaqueWithTextError:" : "Opaque obj is not an Exception.", obj as Exception) { this.obj = obj; this.objMessage = objMessage; } + } + +} diff --git a/AwsCryptographicMaterialProviders/runtimes/net/Generated/AwsCryptographyKeyStore/TypeConversion.cs b/AwsCryptographicMaterialProviders/runtimes/net/Generated/AwsCryptographyKeyStore/TypeConversion.cs index 832e525e5d..9c9b351d5e 100644 --- a/AwsCryptographicMaterialProviders/runtimes/net/Generated/AwsCryptographyKeyStore/TypeConversion.cs +++ b/AwsCryptographicMaterialProviders/runtimes/net/Generated/AwsCryptographyKeyStore/TypeConversion.cs @@ -750,6 +750,8 @@ public static System.Exception FromDafny_CommonError(software.amazon.cryptograph new string(dafnyVal.dtor_message.Elements)); case software.amazon.cryptography.keystore.internaldafny.types.Error_Opaque dafnyVal: return new OpaqueError(dafnyVal._obj); + case software.amazon.cryptography.keystore.internaldafny.types.Error_OpaqueWithText dafnyVal: + return new OpaqueWithTextError(dafnyVal._obj, dafnyVal._obj.ToString()); default: // The switch MUST be complete for _IError, so `value` MUST NOT be an _IError. (How did you get here?) return new OpaqueError(); diff --git a/AwsCryptographicMaterialProviders/runtimes/net/MPL.csproj b/AwsCryptographicMaterialProviders/runtimes/net/MPL.csproj index 742a033873..e7bf80d1f8 100644 --- a/AwsCryptographicMaterialProviders/runtimes/net/MPL.csproj +++ b/AwsCryptographicMaterialProviders/runtimes/net/MPL.csproj @@ -5,7 +5,7 @@ false true - 1.7.3 + 1.7.4 AWS.Cryptography.MaterialProviders AWS.Cryptography.MaterialProviders diff --git a/AwsCryptographicMaterialProviders/runtimes/python/pyproject.toml b/AwsCryptographicMaterialProviders/runtimes/python/pyproject.toml index bf752163bd..127b5f2685 100644 --- a/AwsCryptographicMaterialProviders/runtimes/python/pyproject.toml +++ b/AwsCryptographicMaterialProviders/runtimes/python/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "aws-cryptographic-material-providers" -version = "1.7.3" +version = "1.7.4" description = "AWS Cryptographic Material Providers Library for Python" authors = ["AWS Crypto Tools "] packages = [ diff --git a/AwsCryptographicMaterialProviders/runtimes/python/src/aws_cryptographic_material_providers/internaldafny/extern/StormTrackingCMC.py b/AwsCryptographicMaterialProviders/runtimes/python/src/aws_cryptographic_material_providers/internaldafny/extern/StormTrackingCMC.py index 5164cebde3..032187eb52 100644 --- a/AwsCryptographicMaterialProviders/runtimes/python/src/aws_cryptographic_material_providers/internaldafny/extern/StormTrackingCMC.py +++ b/AwsCryptographicMaterialProviders/runtimes/python/src/aws_cryptographic_material_providers/internaldafny/extern/StormTrackingCMC.py @@ -12,14 +12,18 @@ def __init__(self, wrapped): def PutCacheEntry(self, input): self.lock.Lock__() - val = self.wrapped.PutCacheEntry(input) - self.lock.Unlock() + try: + val = self.wrapped.PutCacheEntry(input) + finally: + self.lock.Unlock() return val def UpdateUsageMetadata(self, input): self.lock.Lock__() - val = self.wrapped.UpdateUsageMetadata(input) - self.lock.Unlock() + try: + val = self.wrapped.UpdateUsageMetadata(input) + finally: + self.lock.Unlock() return val # NOT locked, as some sleeping might be involved @@ -28,27 +32,35 @@ def GetCacheEntry(self, input): def DeleteCacheEntry(self, input): self.lock.Lock__() - val = self.wrapped.DeleteCacheEntry(input) - self.lock.Unlock() + try: + val = self.wrapped.DeleteCacheEntry(input) + finally: + self.lock.Unlock() return val def PutCacheEntry_k(self, input): self.lock.Lock__() - val = self.wrapped.PutCacheEntry(input) - self.lock.Unlock() + try: + val = self.wrapped.PutCacheEntry(input) + finally: + self.lock.Unlock() return val def UpdateUsageMetadata_k(self, input): self.lock.Lock__() - val = self.wrapped.UpdateUsageMetadata(input) - self.lock.Unlock() + try: + val = self.wrapped.UpdateUsageMetadata(input) + finally: + self.lock.Unlock() return val # This is the synchronization for GetCacheEntry and GetCacheEntry_k def GetFromCacheInner(self, input): self.lock.Lock__() - val = self.wrapped.GetFromCache(input) - self.lock.Unlock() + try: + val = self.wrapped.GetFromCache(input) + finally: + self.lock.Unlock() return val # NOT locked, because we sleep. Calls GetFromCache which IS synchronized. @@ -73,8 +85,10 @@ def GetCacheEntry_k(self, input): def DeleteCacheEntry_k(self, input): self.lock.Lock__() - val = self.wrapped.DeleteCacheEntry(input) - self.lock.Unlock() + try: + val = self.wrapped.DeleteCacheEntry(input) + finally: + self.lock.Unlock() return val def __str__(self): diff --git a/AwsCryptographicMaterialProviders/runtimes/python/src/aws_cryptographic_material_providers/internaldafny/extern/SynchronizedLocalCMC.py b/AwsCryptographicMaterialProviders/runtimes/python/src/aws_cryptographic_material_providers/internaldafny/extern/SynchronizedLocalCMC.py index 122b54c844..2f08cd81cf 100644 --- a/AwsCryptographicMaterialProviders/runtimes/python/src/aws_cryptographic_material_providers/internaldafny/extern/SynchronizedLocalCMC.py +++ b/AwsCryptographicMaterialProviders/runtimes/python/src/aws_cryptographic_material_providers/internaldafny/extern/SynchronizedLocalCMC.py @@ -12,56 +12,74 @@ def __init__(self, wrapped): def PutCacheEntry(self, input): self.lock.Lock__() - val = self.wrapped.PutCacheEntry(input) - self.lock.Unlock() + try: + val = self.wrapped.PutCacheEntry(input) + finally: + self.lock.Unlock() return val def UpdateUsageMetadata(self, input): self.lock.Lock__() - val = self.wrapped.UpdateUsageMetadata(input) - self.lock.Unlock() + try: + val = self.wrapped.UpdateUsageMetadata(input) + finally: + self.lock.Unlock() return val def GetCacheEntry(self, input): self.lock.Lock__() - val = self.wrapped.GetCacheEntry(input) - self.lock.Unlock() + try: + val = self.wrapped.GetCacheEntry(input) + finally: + self.lock.Unlock() return val def DeleteCacheEntry(self, input): self.lock.Lock__() - val = self.wrapped.DeleteCacheEntry(input) - self.lock.Unlock() + try: + val = self.wrapped.DeleteCacheEntry(input) + finally: + self.lock.Unlock() return val def PutCacheEntry_k(self, input): self.lock.Lock__() - val = self.wrapped.PutCacheEntry(input) - self.lock.Unlock() + try: + val = self.wrapped.PutCacheEntry(input) + finally: + self.lock.Unlock() return val def UpdateUsageMetadata_k(self, input): self.lock.Lock__() - val = self.wrapped.UpdateUsageMetadata(input) - self.lock.Unlock() + try: + val = self.wrapped.UpdateUsageMetadata(input) + finally: + self.lock.Unlock() return val def GetFromCacheInner(self, input): self.lock.Lock__() - val = self.wrapped.GetFromCache(input) - self.lock.Unlock() + try: + val = self.wrapped.GetFromCache(input) + finally: + self.lock.Unlock() return val def GetCacheEntry_k(self, input): self.lock.Lock__() - val = self.wrapped.GetCacheEntry(input) - self.lock.Unlock() + try: + val = self.wrapped.GetCacheEntry(input) + finally: + self.lock.Unlock() return val def DeleteCacheEntry_k(self, input): self.lock.Lock__() - val = self.wrapped.DeleteCacheEntry(input) - self.lock.Unlock() + try: + val = self.wrapped.DeleteCacheEntry(input) + finally: + self.lock.Unlock() return val def __str__(self): diff --git a/AwsCryptographicMaterialProviders/runtimes/python/src/aws_cryptographic_material_providers/smithygenerated/aws_cryptography_keystore/deserialize.py b/AwsCryptographicMaterialProviders/runtimes/python/src/aws_cryptographic_material_providers/smithygenerated/aws_cryptography_keystore/deserialize.py index 213c9a6d92..874cead290 100644 --- a/AwsCryptographicMaterialProviders/runtimes/python/src/aws_cryptographic_material_providers/smithygenerated/aws_cryptography_keystore/deserialize.py +++ b/AwsCryptographicMaterialProviders/runtimes/python/src/aws_cryptographic_material_providers/smithygenerated/aws_cryptography_keystore/deserialize.py @@ -103,6 +103,8 @@ def _deserialize_get_beacon_key(input: DafnyResponse, config: Config): def _deserialize_error(error: Error) -> ServiceError: if error.is_Opaque: return OpaqueError(obj=error.obj) + elif error.is_OpaqueWithText: + return OpaqueErrorWithText(obj=error.obj, obj_message=error.objMessage) elif error.is_CollectionOfErrors: return CollectionOfErrors( message=_dafny.string_of(error.message), diff --git a/AwsCryptographicMaterialProviders/runtimes/python/src/aws_cryptographic_material_providers/smithygenerated/aws_cryptography_keystore/errors.py b/AwsCryptographicMaterialProviders/runtimes/python/src/aws_cryptographic_material_providers/smithygenerated/aws_cryptography_keystore/errors.py index 134fbbba15..1826a7ef93 100644 --- a/AwsCryptographicMaterialProviders/runtimes/python/src/aws_cryptographic_material_providers/smithygenerated/aws_cryptography_keystore/errors.py +++ b/AwsCryptographicMaterialProviders/runtimes/python/src/aws_cryptographic_material_providers/smithygenerated/aws_cryptography_keystore/errors.py @@ -198,6 +198,64 @@ def __eq__(self, other: Any) -> bool: return all(getattr(self, a) == getattr(other, a) for a in attributes) +class OpaqueWithTextError(ApiError[Literal["OpaqueWithTextError"]]): + code: Literal["OpaqueWithTextError"] = "OpaqueWithTextError" + obj: Any # As an OpaqueWithTextError, type of obj is unknown + obj_message: str # obj_message is a message representing the details of obj + + def __init__(self, *, obj, obj_message): + super().__init__("") + self.obj = obj + self.obj_message = obj_message + + def as_dict(self) -> Dict[str, Any]: + """Converts the OpaqueWithTextError to a dictionary. + + The dictionary uses the modeled shape names rather than the + parameter names as keys to be mostly compatible with boto3. + """ + return { + "message": self.message, + "code": self.code, + "obj": self.obj, + "obj_message": self.obj_message, + } + + @staticmethod + def from_dict(d: Dict[str, Any]) -> "OpaqueWithTextError": + """Creates a OpaqueWithTextError from a dictionary. + + The dictionary is expected to use the modeled shape names rather + than the parameter names as keys to be mostly compatible with + boto3. + """ + kwargs: Dict[str, Any] = { + "message": d["message"], + "obj": d["obj"], + "obj_message": d["obj_message"], + } + + return OpaqueWithTextError(**kwargs) + + def __repr__(self) -> str: + result = "OpaqueWithTextError(" + result += f"message={self.message}," + if self.message is not None: + result += f"message={repr(self.message)}" + result += f"obj={self.obj}" + result += f"obj_message={self.obj_message}" + result += ")" + return result + + def __eq__(self, other: Any) -> bool: + if not isinstance(other, OpaqueWithTextError): + return False + if not (self.obj == other.obj): + return False + attributes: list[str] = ["message", "message"] + return all(getattr(self, a) == getattr(other, a) for a in attributes) + + def _smithy_error_to_dafny_error(e: ServiceError): """Converts the provided native Smithy-modeled error into the corresponding Dafny error.""" @@ -232,6 +290,11 @@ def _smithy_error_to_dafny_error(e: ServiceError): obj=e.obj ) + if isinstance(e, OpaqueWithTextError): + return aws_cryptographic_material_providers.internaldafny.generated.AwsCryptographyKeyStoreTypes.Error_OpaqueWithText( + obj=e.obj, objMessage=e.obj_message + ) + else: return aws_cryptographic_material_providers.internaldafny.generated.AwsCryptographyKeyStoreTypes.Error_Opaque( obj=e diff --git a/AwsCryptographicMaterialProviders/runtimes/python/src/aws_cryptographic_material_providers/smithygenerated/aws_cryptography_materialproviders/deserialize.py b/AwsCryptographicMaterialProviders/runtimes/python/src/aws_cryptographic_material_providers/smithygenerated/aws_cryptography_materialproviders/deserialize.py index d3cbc61851..eca1565bfa 100644 --- a/AwsCryptographicMaterialProviders/runtimes/python/src/aws_cryptographic_material_providers/smithygenerated/aws_cryptography_materialproviders/deserialize.py +++ b/AwsCryptographicMaterialProviders/runtimes/python/src/aws_cryptographic_material_providers/smithygenerated/aws_cryptography_materialproviders/deserialize.py @@ -320,6 +320,8 @@ def _deserialize_validate_commitment_policy_on_decrypt( def _deserialize_error(error: Error) -> ServiceError: if error.is_Opaque: return OpaqueError(obj=error.obj) + elif error.is_OpaqueWithText: + return OpaqueErrorWithText(obj=error.obj, obj_message=error.objMessage) elif error.is_CollectionOfErrors: return CollectionOfErrors( message=_dafny.string_of(error.message), diff --git a/AwsCryptographicMaterialProviders/runtimes/python/src/aws_cryptographic_material_providers/smithygenerated/aws_cryptography_materialproviders/errors.py b/AwsCryptographicMaterialProviders/runtimes/python/src/aws_cryptographic_material_providers/smithygenerated/aws_cryptography_materialproviders/errors.py index 2b6ca2e952..77c63d0b96 100644 --- a/AwsCryptographicMaterialProviders/runtimes/python/src/aws_cryptographic_material_providers/smithygenerated/aws_cryptography_materialproviders/errors.py +++ b/AwsCryptographicMaterialProviders/runtimes/python/src/aws_cryptographic_material_providers/smithygenerated/aws_cryptography_materialproviders/errors.py @@ -697,6 +697,64 @@ def __eq__(self, other: Any) -> bool: return all(getattr(self, a) == getattr(other, a) for a in attributes) +class OpaqueWithTextError(ApiError[Literal["OpaqueWithTextError"]]): + code: Literal["OpaqueWithTextError"] = "OpaqueWithTextError" + obj: Any # As an OpaqueWithTextError, type of obj is unknown + obj_message: str # obj_message is a message representing the details of obj + + def __init__(self, *, obj, obj_message): + super().__init__("") + self.obj = obj + self.obj_message = obj_message + + def as_dict(self) -> Dict[str, Any]: + """Converts the OpaqueWithTextError to a dictionary. + + The dictionary uses the modeled shape names rather than the + parameter names as keys to be mostly compatible with boto3. + """ + return { + "message": self.message, + "code": self.code, + "obj": self.obj, + "obj_message": self.obj_message, + } + + @staticmethod + def from_dict(d: Dict[str, Any]) -> "OpaqueWithTextError": + """Creates a OpaqueWithTextError from a dictionary. + + The dictionary is expected to use the modeled shape names rather + than the parameter names as keys to be mostly compatible with + boto3. + """ + kwargs: Dict[str, Any] = { + "message": d["message"], + "obj": d["obj"], + "obj_message": d["obj_message"], + } + + return OpaqueWithTextError(**kwargs) + + def __repr__(self) -> str: + result = "OpaqueWithTextError(" + result += f"message={self.message}," + if self.message is not None: + result += f"message={repr(self.message)}" + result += f"obj={self.obj}" + result += f"obj_message={self.obj_message}" + result += ")" + return result + + def __eq__(self, other: Any) -> bool: + if not isinstance(other, OpaqueWithTextError): + return False + if not (self.obj == other.obj): + return False + attributes: list[str] = ["message", "message"] + return all(getattr(self, a) == getattr(other, a) for a in attributes) + + def _smithy_error_to_dafny_error(e: ServiceError): """Converts the provided native Smithy-modeled error into the corresponding Dafny error.""" @@ -813,6 +871,11 @@ def _smithy_error_to_dafny_error(e: ServiceError): obj=e.obj ) + if isinstance(e, OpaqueWithTextError): + return aws_cryptographic_material_providers.internaldafny.generated.AwsCryptographyMaterialProvidersTypes.Error_OpaqueWithText( + obj=e.obj, objMessage=e.obj_message + ) + else: return aws_cryptographic_material_providers.internaldafny.generated.AwsCryptographyMaterialProvidersTypes.Error_Opaque( obj=e diff --git a/AwsCryptographicMaterialProviders/runtimes/python/tox.ini b/AwsCryptographicMaterialProviders/runtimes/python/tox.ini index b81a4c9544..9af0a3ef73 100644 --- a/AwsCryptographicMaterialProviders/runtimes/python/tox.ini +++ b/AwsCryptographicMaterialProviders/runtimes/python/tox.ini @@ -1,7 +1,7 @@ [tox] isolated_build = True envlist = - py{311,312}-{dafnytests} + py{311,312,313}-{dafnytests} docs [testenv:base-command] diff --git a/AwsCryptographicMaterialProviders/runtimes/rust/.gitignore b/AwsCryptographicMaterialProviders/runtimes/rust/.gitignore new file mode 100644 index 0000000000..2c0c6bcb17 --- /dev/null +++ b/AwsCryptographicMaterialProviders/runtimes/rust/.gitignore @@ -0,0 +1,17 @@ +Cargo.lock +src/client.rs +src/client +src/conversions.rs +src/conversions +src/deps.rs +src/deps +src/error.rs +src/error +src/implementation_from_dafny.rs +src/operation.rs +src/operation +src/standard_library_conversions.rs +src/standard_library_externs.rs +src/types.rs +src/types +target diff --git a/AwsCryptographicMaterialProviders/runtimes/rust/Cargo.toml b/AwsCryptographicMaterialProviders/runtimes/rust/Cargo.toml new file mode 100644 index 0000000000..5f330ee4f7 --- /dev/null +++ b/AwsCryptographicMaterialProviders/runtimes/rust/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "aws-mpl-rs" +version = "0.1.0" +edition = "2021" +rust-version = "1.80.0" +keywords = ["crypto", "cryptography", "security", "encryption", "client-side", "clientside"] +license = "ISC AND (Apache-2.0 OR ISC)" +description = "aws-mpl-rs is a low level library for implementing client side encryption." +authors = ["AWS-CryptoTools"] +documentation = "https://docs.rs/crate/aws-mpl-rs" +readme = "README.md" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +aws-config = "1.5.8" +aws-lc-rs = "1.10.0" +aws-lc-sys = "0.22.0" +aws-sdk-dynamodb = "1.50.0" +aws-sdk-kms = "1.47.0" +aws-smithy-runtime-api = {version = "1.7.2", features = ["client"] } +aws-smithy-types = "1.2.8" +chrono = "0.4.38" +cpu-time = "1.0.0" +dafny_runtime = { path = "../../../smithy-dafny/TestModels/dafny-dependencies/dafny_runtime_rust"} +dashmap = "6.1.0" +pem = "3.0.4" +tokio = {version = "1.41.0", features = ["full"] } +uuid = { version = "1.11.0", features = ["v4"] } diff --git a/AwsCryptographicMaterialProviders/runtimes/rust/src/aes_gcm.rs b/AwsCryptographicMaterialProviders/runtimes/rust/src/aes_gcm.rs new file mode 100644 index 0000000000..21bf9230f8 --- /dev/null +++ b/AwsCryptographicMaterialProviders/runtimes/rust/src/aes_gcm.rs @@ -0,0 +1,255 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +#![deny(warnings, unconditional_panic)] +#![deny(nonstandard_style)] +#![deny(clippy::all)] + +use crate::software::amazon::cryptography::primitives::internaldafny::types::AESEncryptOutput; +use crate::software::amazon::cryptography::primitives::internaldafny::types::Error as DafnyError; +use crate::software::amazon::cryptography::primitives::internaldafny::types::AES_GCM; +use crate::*; +use aws_lc_rs::aead::{Aad, LessSafeKey, Nonce, UnboundKey}; +use std::rc::Rc; + +struct DoAESEncryptOutput { + cipher_text: Vec, + auth_tag: Vec, +} + +fn error(s: &str) -> Rc { + Rc::new(DafnyError::AwsCryptographicPrimitivesError { + message: + dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(s), + }) +} + +fn enc_result(s: &str) -> Rc<_Wrappers_Compile::Result, Rc>> { + Rc::new(_Wrappers_Compile::Result::Failure { error: error(s) }) +} + +fn dec_result( + s: &str, +) -> Rc<_Wrappers_Compile::Result<::dafny_runtime::Sequence, Rc>> { + Rc::new(_Wrappers_Compile::Result::Failure { error: error(s) }) +} + +#[allow(non_snake_case)] +pub mod AESEncryption { + pub use crate::software::amazon::cryptography::primitives::internaldafny::types::*; +} +impl AES_GCM { + fn get_alg(&self) -> Result<&'static aws_lc_rs::aead::Algorithm, String> { + if *self.tagLength() != 16i32 { + Err(format!( + "Tag length of {} not supported in Rust. Tag length must be 16.", + self.tagLength() + )) + } else if *self.ivLength() != 12i32 { + Err(format!( + "IV length of {} not supported in Rust. IV length must be 12.", + self.ivLength() + )) + } else if *self.keyLength() == 32i32 { + Ok(&aws_lc_rs::aead::AES_256_GCM) + } else if *self.keyLength() == 16i32 { + Ok(&aws_lc_rs::aead::AES_128_GCM) + } else { + Err(format!( + "Key length of {} not supported in Rust. Key length must be 16 or 32.", + self.keyLength() + )) + } + } + + fn do_aes_encrypt( + &self, + iv: &[u8], + key: &[u8], + msg: &[u8], + aad: &[u8], + ) -> Result { + let alg = self.get_alg()?; + let mut in_out_buffer = Vec::from(msg); + let key = UnboundKey::new(alg, key).map_err(|e| format!("new {:?}", e))?; + let nonce = Nonce::assume_unique_for_key(iv.try_into().unwrap()); + let key = LessSafeKey::new(key); + let aad = Aad::from(aad); + let tag = key + .seal_in_place_separate_tag(nonce, aad, &mut in_out_buffer) + .map_err(|e| format!("Seal {:?}", e))?; + Ok(DoAESEncryptOutput { + cipher_text: in_out_buffer, + auth_tag: Vec::from(tag.as_ref()), + }) + } + + fn do_aes_decrypt( + &self, + key: &[u8], + cipher_text: &[u8], + auth_tag: &[u8], + iv: &[u8], + aad: &[u8], + ) -> Result, String> { + let alg = self.get_alg()?; + let mut out_buffer = Vec::from(cipher_text); + let key = UnboundKey::new(alg, key).map_err(|e| format!("new {:?}", e))?; + let nonce = Nonce::assume_unique_for_key(iv.try_into().unwrap()); + let key = LessSafeKey::new(key); + let aad = Aad::from(aad); + key.open_separate_gather(nonce, aad, cipher_text, auth_tag, &mut out_buffer) + .map_err(|e| format!("gather {:?}", e))?; + Ok(out_buffer) + } + + #[allow(non_snake_case)] + pub fn AESEncryptExtern( + &self, + iv: &::dafny_runtime::Sequence, + key: &::dafny_runtime::Sequence, + msg: &::dafny_runtime::Sequence, + aad: &::dafny_runtime::Sequence, + ) -> Rc<_Wrappers_Compile::Result, Rc>> { + let iv: Vec = iv.iter().collect(); + let key: Vec = key.iter().collect(); + let msg: Vec = msg.iter().collect(); + let aad: Vec = aad.iter().collect(); + + if *self.keyLength() as usize != key.len() { + let msg = format!( + "AESEncrypt : algorithm key length was {} but actual key length was {}.", + self.keyLength(), + key.len() + ); + return enc_result(&msg); + } + if *self.ivLength() as usize != iv.len() { + let msg = format!( + "AESEncrypt : algorithm nonce length was {} but actual nonce length was {}.", + self.ivLength(), + iv.len() + ); + return enc_result(&msg); + } + + match self.do_aes_encrypt(&iv, &key, &msg, &aad) { + Ok(x) => Rc::new(_Wrappers_Compile::Result::Success { + value: Rc::new(AESEncryptOutput::AESEncryptOutput { + cipherText: x.cipher_text.iter().cloned().collect(), + authTag: x.auth_tag.iter().cloned().collect(), + }), + }), + Err(e) => { + let msg = format!("AES Encrypt : {}", e); + enc_result(&msg) + } + } + } + + #[allow(non_snake_case)] + pub fn AESDecryptExtern( + &self, + key: &::dafny_runtime::Sequence, + cipher_text: &::dafny_runtime::Sequence, + auth_tag: &::dafny_runtime::Sequence, + iv: &::dafny_runtime::Sequence, + aad: &::dafny_runtime::Sequence, + ) -> Rc<_Wrappers_Compile::Result<::dafny_runtime::Sequence, Rc>> { + let key: Vec = key.iter().collect(); + let cipher_text: Vec = cipher_text.iter().collect(); + let auth_tag: Vec = auth_tag.iter().collect(); + let iv: Vec = iv.iter().collect(); + let aad: Vec = aad.iter().collect(); + + if *self.keyLength() as usize != key.len() { + let msg = format!( + "AESEncrypt : algorithm key length was {} but actual key length was {}.", + self.keyLength(), + key.len() + ); + return dec_result(&msg); + } + + if *self.ivLength() as usize != iv.len() { + let msg = format!( + "AESEncrypt : algorithm nonce length was {} but actual nonce length was {}.", + self.ivLength(), + iv.len() + ); + return dec_result(&msg); + } + + if *self.tagLength() as usize != auth_tag.len() { + let msg = format!( + "AESEncrypt : algorithm auth tag length was {} but actual auth tag length was {}.", + self.tagLength(), + auth_tag.len() + ); + return dec_result(&msg); + } + + match self.do_aes_decrypt(&key, &cipher_text, &auth_tag, &iv, &aad) { + Ok(x) => Rc::new(_Wrappers_Compile::Result::Success { + value: x.iter().cloned().collect(), + }), + Err(e) => { + let msg = format!("AES Decrypt : {}", e); + dec_result(&msg) + } + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn test_generate() { + let iv: ::dafny_runtime::Sequence = [1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] + .iter() + .cloned() + .collect(); + let key: ::dafny_runtime::Sequence = [ + 2u8, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, + ] + .iter() + .cloned() + .collect(); + let msg: ::dafny_runtime::Sequence = [2u8, 4, 6, 8, 10, 12].iter().cloned().collect(); + let aad: ::dafny_runtime::Sequence = + [3u8, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17] + .iter() + .cloned() + .collect(); + + let alg = AES_GCM::AES_GCM { + keyLength: 32, + tagLength: 16, + ivLength: 12, + }; + let cipher = match &*alg.AESEncryptExtern(&iv, &key, &msg, &aad) { + _Wrappers_Compile::Result::Success { value } => value.clone(), + _Wrappers_Compile::Result::Failure { error } => { + panic!("AESEncryptExtern Failed : {:?}", error); + } + }; + + let (cipher_text, auth_tag) = match &*cipher { + AESEncryptOutput::AESEncryptOutput { + cipherText, + authTag, + } => (cipherText, authTag), + }; + + let output = match &*alg.AESDecryptExtern(&key, &cipher_text, &auth_tag, &iv, &aad) { + _Wrappers_Compile::Result::Success { value } => value.clone(), + _Wrappers_Compile::Result::Failure { error } => { + panic!("AESEncryptExtern Failed : {:?}", error); + } + }; + + assert_eq!(output, msg); + } +} diff --git a/AwsCryptographicMaterialProviders/runtimes/rust/src/aes_kdf_ctr.rs b/AwsCryptographicMaterialProviders/runtimes/rust/src/aes_kdf_ctr.rs new file mode 100644 index 0000000000..f5b996ba33 --- /dev/null +++ b/AwsCryptographicMaterialProviders/runtimes/rust/src/aes_kdf_ctr.rs @@ -0,0 +1,77 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +#![deny(warnings, unconditional_panic)] +#![deny(nonstandard_style)] +#![deny(clippy::all)] +#![allow(dead_code)] + +#[allow(non_snake_case)] +pub mod AesKdfCtr { + use crate::software::amazon::cryptography::primitives::internaldafny::types::Error as DafnyError; + use crate::*; + use aws_lc_rs::cipher::{EncryptingKey, EncryptionContext, UnboundCipherKey, AES_256}; + use dafny_runtime::Sequence; + use std::rc::Rc; + + #[allow(non_camel_case_types)] + // pub struct _default {} + + fn error(s: &str) -> Rc { + Rc::new(DafnyError::AwsCryptographicPrimitivesError { + message: + dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(s), + }) + } + + fn as_array(nonce: &[u8]) -> &[u8; aws_lc_rs::iv::IV_LEN_128_BIT] { + nonce.try_into().unwrap() + } + + fn ctr_stream(nonce: &[u8], key: &[u8], length: u32) -> Result, String> { + if nonce.len() != aws_lc_rs::iv::IV_LEN_128_BIT { + return Err(format!( + "Nonce length of {} not supported in AesKdfCtrStream. Nonce length must be {}.", + nonce.len(), + aws_lc_rs::iv::IV_LEN_128_BIT + )); + } + + let mut in_out_buffer = vec![0; length as usize]; + + let key = UnboundCipherKey::new(&AES_256, key).map_err(|e| format!("new {:?}", e))?; + let encrypting_key = EncryptingKey::ctr(key).map_err(|e| format!("new {:?}", e))?; + let nonce = aws_lc_rs::iv::FixedLength::<16>::from(as_array(nonce)); + let context = EncryptionContext::Iv128(nonce); + encrypting_key + .less_safe_encrypt(&mut in_out_buffer, context) + .map_err(|e| format!("new {:?}", e))?; + Ok(in_out_buffer) + } + + impl crate::AesKdfCtr::_default { + #[allow(non_snake_case)] + pub fn AesKdfCtrStream( + nonce: &Sequence, + key: &Sequence, + length: u32, + ) -> Rc< + _Wrappers_Compile::Result< + Sequence, + Rc, + >, + > { + let nonce: Vec = nonce.iter().collect(); + let key: Vec = key.iter().collect(); + match ctr_stream(&nonce, &key, length) { + Ok(x) => Rc::new(_Wrappers_Compile::Result::Success { + value: x.iter().cloned().collect(), + }), + Err(e) => { + let msg = format!("Aes Kdf Ctr : {}", e); + Rc::new(_Wrappers_Compile::Result::Failure { error: error(&msg) }) + } + } + } + } +} diff --git a/AwsCryptographicMaterialProviders/runtimes/rust/src/concurrent_call.rs b/AwsCryptographicMaterialProviders/runtimes/rust/src/concurrent_call.rs new file mode 100644 index 0000000000..6bafd0c6a3 --- /dev/null +++ b/AwsCryptographicMaterialProviders/runtimes/rust/src/concurrent_call.rs @@ -0,0 +1,61 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +#![deny(warnings, unconditional_panic)] +#![deny(nonstandard_style)] +#![deny(clippy::all)] +#![allow(dead_code)] + +#[allow(non_snake_case)] +pub mod ConcurrentCall { + + fn de_const( + p: *const dafny_runtime::Object<(dyn Callee + 'static)>, + ) -> *mut dafny_runtime::Object<(dyn Callee + 'static)> { + p as _ + } + + pub struct FakeCallee { + callee: *const dafny_runtime::Object<(dyn Callee + 'static)>, + } + impl FakeCallee { + fn new(callee: &dafny_runtime::Object<(dyn Callee + 'static)>) -> Self { + Self { + callee: std::ptr::from_ref(callee), + } + } + fn call(&self, x: u32, y: u32) { + let mptr = de_const(self.callee); + let value: &mut dafny_runtime::Object<(dyn Callee + 'static)> = unsafe { &mut *mptr }; + value.as_mut().call(x, y); + } + } + unsafe impl Send for FakeCallee {} + + #[allow(nonstandard_style)] + pub struct _default {} + use crate::ConcurrentCall::Callee; + impl _default { + pub fn ConcurrentCall( + callee: &dafny_runtime::Object<(dyn Callee + 'static)>, + serial_iters: u32, + concurrent_iters: u32, + ) { + let mut children = vec![]; + + for i in 0..concurrent_iters { + // Spin up another thread + let fake = FakeCallee::new(callee); + children.push(std::thread::spawn(move || { + for j in 0..serial_iters { + fake.call(j, i); + } + })); + } + + for child in children { + let _ = child.join(); + } + } + } +} diff --git a/AwsCryptographicMaterialProviders/runtimes/rust/src/dafny_libraries.rs b/AwsCryptographicMaterialProviders/runtimes/rust/src/dafny_libraries.rs new file mode 100644 index 0000000000..de16d5af73 --- /dev/null +++ b/AwsCryptographicMaterialProviders/runtimes/rust/src/dafny_libraries.rs @@ -0,0 +1,159 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +#![deny(warnings, unconditional_panic)] +#![deny(nonstandard_style)] +#![deny(clippy::all)] + +#[allow(non_snake_case)] +pub mod DafnyLibraries { + use dashmap::DashMap; + use std::collections::HashMap; + use std::collections::HashSet; + + pub struct MutableMap { + map: DashMap, + } + + impl MutableMap { + pub fn _allocate_object() -> ::dafny_runtime::Object { + ::dafny_runtime::Object::new(MutableMap { + map: DashMap::new(), + }) + } + } + + impl + crate::DafnyLibraries::MutableMapTrait for MutableMap + { + fn content(&self) -> ::dafny_runtime::Map { + let mut new_map = HashMap::new(); + for entry in self.map.iter() { + new_map.insert(entry.key().clone(), entry.value().clone()); + } + dafny_runtime::Map::from_hashmap_owned(new_map) + } + fn Put(&self, k: &K, v: &V) { + self.map.insert(k.clone(), v.clone()); + } + fn Keys(&self) -> ::dafny_runtime::Set { + let mut new_set = HashSet::new(); + for entry in self.map.iter() { + new_set.insert(entry.key().clone()); + } + dafny_runtime::Set::from_hashset_owned(new_set) + } + fn HasKey(&self, k: &K) -> bool { + self.map.contains_key(k) + } + fn Values(&self) -> ::dafny_runtime::Set { + let mut new_set = HashSet::new(); + for entry in self.map.iter() { + new_set.insert(entry.value().clone()); + } + dafny_runtime::Set::from_hashset_owned(new_set) + } + fn Items(&self) -> ::dafny_runtime::Set<(K, V)> { + let mut new_set = HashSet::new(); + for entry in self.map.iter() { + new_set.insert((entry.key().clone(), entry.value().clone())); + } + dafny_runtime::Set::from_hashset_owned(new_set) + } + fn Select(&self, k: &K) -> V { + self.map.get(k).unwrap().clone() + } + fn Remove(&self, k: &K) { + self.map.remove(k); + } + fn Size(&self) -> ::dafny_runtime::DafnyInt { + self.map.len().into() + } + } + + pub mod FileIO { + use std::fs::File; + use std::io::Read; + use std::io::Write; + use std::path::Path; + + pub fn INTERNAL_ReadBytesFromFile( + file: &::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>, + ) -> ( + bool, + ::dafny_runtime::Sequence, + ::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>, + ) { + let file_name = dafny_runtime::dafny_runtime_conversions::unicode_chars_false::dafny_string_to_string(file); + let path = Path::new(&file_name); + + let mut file = match File::open(path) { + Err(why) => { + let err_msg = format!("couldn't open {} for reading from {}: {}", path.display(), curr_dir(), why); + let err_msg = dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(&err_msg); + return (true, dafny_runtime::Sequence::default(), err_msg); + } + Ok(file) => file, + }; + + let mut result = Vec::new(); + match file.read_to_end(&mut result) { + Err(why) => { + let err_msg = format!("couldn't read from {}: {}", path.display(), why); + let err_msg = dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(&err_msg); + (true, dafny_runtime::Sequence::default(), err_msg) + } + Ok(_) => ( + false, + dafny_runtime::Sequence::from_array_owned(result), + dafny_runtime::Sequence::default(), + ), + } + } + + fn curr_dir() -> String + { + let path = std::env::current_dir(); + match path { + Ok(path) => format!("{}", path.display()), + Err(_) => "unknown".to_string(), + } + } + + pub fn INTERNAL_WriteBytesToFile( + path: &::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>, + bytes: &::dafny_runtime::Sequence, + ) -> ( + bool, + ::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>, + ) { + let file_name = dafny_runtime::dafny_runtime_conversions::unicode_chars_false::dafny_string_to_string(path); + let path = Path::new(&file_name); + + let maybe_file = std::fs::OpenOptions::new() + .write(true) + .create(true) + .truncate(true) + .open(path); + let mut file = match maybe_file { + Err(why) => { + let err_msg = format!("couldn't open {} for writing from {}: {}", path.display(), curr_dir(), why); + let err_msg = dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(&err_msg); + return (true, err_msg); + } + Ok(file) => file, + }; + + let bytes = bytes.to_array(); + match file.write_all(&bytes) { + Err(why) => { + let err_msg = + format!("couldn't write all bytes to {}: {}", path.display(), why); + let err_msg = dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(&err_msg); + (true, err_msg) + } + Ok(_) => (false, dafny_runtime::Sequence::default()), + } + } + } +} diff --git a/AwsCryptographicMaterialProviders/runtimes/rust/src/ddb.rs b/AwsCryptographicMaterialProviders/runtimes/rust/src/ddb.rs new file mode 100644 index 0000000000..2032916b58 --- /dev/null +++ b/AwsCryptographicMaterialProviders/runtimes/rust/src/ddb.rs @@ -0,0 +1,75 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +#![deny(warnings, unconditional_panic)] +#![deny(nonstandard_style)] +#![deny(clippy::all)] + +use aws_config::Region; +use std::sync::LazyLock; + +static DAFNY_TOKIO_RUNTIME: LazyLock = LazyLock::new(|| { + tokio::runtime::Builder::new_multi_thread() + .enable_all() + .build() + .unwrap() +}); + +#[allow(non_snake_case)] +impl crate::r#software::amazon::cryptography::services::dynamodb::internaldafny::_default { + pub fn DDBClientForRegion(region: &::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>) -> ::std::rc::Rc< + crate::r#_Wrappers_Compile::Result< + ::dafny_runtime::Object, + ::std::rc::Rc + > + >{ + let region = + dafny_runtime::dafny_runtime_conversions::unicode_chars_false::dafny_string_to_string( + region, + ); + let shared_config = match tokio::runtime::Handle::try_current() { + Ok(curr) => tokio::task::block_in_place(|| { + curr.block_on(async { + aws_config::load_defaults(aws_config::BehaviorVersion::v2024_03_28()).await + }) + }), + Err(_) => DAFNY_TOKIO_RUNTIME.block_on(aws_config::load_defaults( + aws_config::BehaviorVersion::v2024_03_28(), + )), + }; + let shared_config = shared_config + .to_builder() + .region(Region::new(region)) + .build(); + let inner = aws_sdk_dynamodb::Client::new(&shared_config); + let client = crate::deps::com_amazonaws_dynamodb::client::Client { inner }; + let dafny_client = ::dafny_runtime::upcast_object()(::dafny_runtime::object::new(client)); + std::rc::Rc::new(crate::r#_Wrappers_Compile::Result::Success { + value: dafny_client, + }) + } + + pub fn DynamoDBClient() -> ::std::rc::Rc< + crate::r#_Wrappers_Compile::Result< + ::dafny_runtime::Object, + ::std::rc::Rc + > + >{ + let shared_config = match tokio::runtime::Handle::try_current() { + Ok(curr) => tokio::task::block_in_place(|| { + curr.block_on(async { + aws_config::load_defaults(aws_config::BehaviorVersion::v2024_03_28()).await + }) + }), + Err(_) => DAFNY_TOKIO_RUNTIME.block_on(aws_config::load_defaults( + aws_config::BehaviorVersion::v2024_03_28(), + )), + }; + let inner = aws_sdk_dynamodb::Client::new(&shared_config); + let client = crate::deps::com_amazonaws_dynamodb::client::Client { inner }; + let dafny_client = ::dafny_runtime::upcast_object()(::dafny_runtime::object::new(client)); + std::rc::Rc::new(crate::r#_Wrappers_Compile::Result::Success { + value: dafny_client, + }) + } +} diff --git a/AwsCryptographicMaterialProviders/runtimes/rust/src/digest.rs b/AwsCryptographicMaterialProviders/runtimes/rust/src/digest.rs new file mode 100644 index 0000000000..f3a01ce677 --- /dev/null +++ b/AwsCryptographicMaterialProviders/runtimes/rust/src/digest.rs @@ -0,0 +1,34 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +#![deny(warnings, unconditional_panic)] +#![deny(nonstandard_style)] +#![deny(clippy::all)] + +use crate::*; +use aws_lc_rs::digest; +use software::amazon::cryptography::primitives::internaldafny::types::DigestAlgorithm; + +impl crate::ExternDigest::_default { + #[allow(non_snake_case)] + pub fn Digest( + digest_algorithm: &::std::rc::Rc, + message: &::dafny_runtime::Sequence, + ) -> ::std::rc::Rc< + _Wrappers_Compile::Result< + ::dafny_runtime::Sequence, + ::std::rc::Rc, + >, + > { + let algorithm = match **digest_algorithm { + DigestAlgorithm::SHA_512 {} => &digest::SHA512, + DigestAlgorithm::SHA_384 {} => &digest::SHA384, + DigestAlgorithm::SHA_256 {} => &digest::SHA256, + }; + let message_vec: Vec = message.iter().collect(); + let result = digest::digest(algorithm, &message_vec); + ::std::rc::Rc::new(_Wrappers_Compile::Result::Success { + value: result.as_ref().iter().cloned().collect(), + }) + } +} diff --git a/AwsCryptographicMaterialProviders/runtimes/rust/src/ecdh.rs b/AwsCryptographicMaterialProviders/runtimes/rust/src/ecdh.rs new file mode 100644 index 0000000000..15e1795054 --- /dev/null +++ b/AwsCryptographicMaterialProviders/runtimes/rust/src/ecdh.rs @@ -0,0 +1,513 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +#![deny(warnings, unconditional_panic)] +#![deny(nonstandard_style)] +#![deny(clippy::all)] +#![allow(dead_code)] + +#[allow(non_snake_case)] +pub mod ECDH { + use crate::software::amazon::cryptography::primitives::internaldafny::types::Error as DafnyError; + use std::rc::Rc; + + fn error(s: &str) -> Rc { + Rc::new(DafnyError::AwsCryptographicPrimitivesError { + message: + dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(s), + }) + } + + pub mod ECCUtils { + use crate::software::amazon::cryptography::primitives::internaldafny::types::ECDHCurveSpec; + use crate::software::amazon::cryptography::primitives::internaldafny::types::Error as DafnyError; + use crate::*; + use aws_lc_sys; + use std::rc::Rc; + + fn get_nid(x: &ECDHCurveSpec) -> i32 { + match x { + ECDHCurveSpec::ECC_NIST_P256 {} => aws_lc_sys::NID_X9_62_prime256v1, + ECDHCurveSpec::ECC_NIST_P384 {} => aws_lc_sys::NID_secp384r1, + ECDHCurveSpec::ECC_NIST_P521 {} => aws_lc_sys::NID_secp521r1, + ECDHCurveSpec::SM2 {} => panic!("No SM2 in Rust"), + } + } + // NID_secp224r1 (NIST P-224), + // NID_secp256k1 (SEC/ANSI P-256 K1) + + pub(crate) fn get_alg(x: &ECDHCurveSpec) -> &'static aws_lc_rs::agreement::Algorithm { + match x { + ECDHCurveSpec::ECC_NIST_P256 {} => &aws_lc_rs::agreement::ECDH_P256, + ECDHCurveSpec::ECC_NIST_P384 {} => &aws_lc_rs::agreement::ECDH_P384, + ECDHCurveSpec::ECC_NIST_P521 {} => &aws_lc_rs::agreement::ECDH_P521, + ECDHCurveSpec::SM2 {} => panic!("No SM2 in Rust"), + } + } + + use aws_lc_sys::CBB_finish; + use aws_lc_sys::CBB_init; + use aws_lc_sys::EC_GROUP_get_curve_name; + use aws_lc_sys::EC_GROUP_new_by_curve_name; + use aws_lc_sys::EC_KEY_get0_group; + use aws_lc_sys::EC_KEY_get0_public_key; + use aws_lc_sys::EC_KEY_new_by_curve_name; + use aws_lc_sys::EC_KEY_set_public_key; + use aws_lc_sys::EC_POINT_free; + use aws_lc_sys::EC_POINT_new; + use aws_lc_sys::EC_POINT_oct2point; + use aws_lc_sys::EC_POINT_point2oct; + use aws_lc_sys::EVP_PKEY_assign_EC_KEY; + use aws_lc_sys::EVP_PKEY_free; + use aws_lc_sys::EVP_PKEY_get0_EC_KEY; + use aws_lc_sys::EVP_PKEY_new; + use aws_lc_sys::EVP_PKEY_size; + use aws_lc_sys::EVP_marshal_public_key; + use aws_lc_sys::EVP_parse_public_key; + use aws_lc_sys::OPENSSL_free; + use aws_lc_sys::CBB; + use aws_lc_sys::CBS; + use aws_lc_sys::EVP_PKEY_EC; + use std::ptr::null_mut; + + const ELEM_MAX_BITS: usize = 521; + const ELEM_MAX_BYTES: usize = (ELEM_MAX_BITS + 7) / 8; + const PUBLIC_KEY_MAX_LEN: usize = 1 + (2 * ELEM_MAX_BYTES); + + pub(crate) fn X509_to_X962( + public_key: &[u8], + compress: bool, + nid: Option, + ) -> Result, String> { + let mut cbs = CBS { + data: public_key.as_ptr(), + len: public_key.len(), + }; + + let evp_pkey = unsafe { EVP_parse_public_key(&mut cbs) }; + if evp_pkey.is_null() { + return Err("Invalid X509 Public Key.".to_string()); + } + let ec_key = unsafe { EVP_PKEY_get0_EC_KEY(evp_pkey) }; + + let ec_group = unsafe { EC_KEY_get0_group(ec_key) }; + if ec_group.is_null() { + return Err("Error in EC_KEY_get0_group in X509_to_X962.".to_string()); + } + if nid.is_some() && nid.unwrap() != unsafe { EC_GROUP_get_curve_name(ec_group) } { + return Err("Curve type mismatch in X509_to_X962.".to_string()); + } + let ec_point = unsafe { EC_KEY_get0_public_key(ec_key) }; + if ec_point.is_null() { + return Err("Error in EC_KEY_get0_public_key in X509_to_X962.".to_string()); + } + + let comp = if compress { + aws_lc_sys::point_conversion_form_t::POINT_CONVERSION_COMPRESSED + } else { + aws_lc_sys::point_conversion_form_t::POINT_CONVERSION_UNCOMPRESSED + }; + + let mut out_buf = [0u8; PUBLIC_KEY_MAX_LEN]; + let new_size = unsafe { + EC_POINT_point2oct( + ec_group, + ec_point, + comp, + out_buf.as_mut_ptr(), + PUBLIC_KEY_MAX_LEN, + null_mut(), + ) + }; + unsafe { EVP_PKEY_free(evp_pkey) }; + Ok(out_buf[..new_size].to_vec()) + } + + pub(crate) fn X962_to_X509( + public_key: &[u8], + alg: &ECDHCurveSpec, + ) -> Result, String> { + let ec_group = unsafe { EC_GROUP_new_by_curve_name(get_nid(alg)) }; + let ec_point = unsafe { EC_POINT_new(ec_group) }; + + if 1 != unsafe { + EC_POINT_oct2point( + ec_group, + ec_point, + public_key.as_ptr(), + public_key.len(), + null_mut(), + ) + } { + return Err("Error in EC_POINT_oct2point.".to_string()); + } + + let ec_key = unsafe { EC_KEY_new_by_curve_name(get_nid(alg)) }; + if 1 != unsafe { EC_KEY_set_public_key(ec_key, ec_point) } { + return Err("Error in EC_KEY_set_public_key.".to_string()); + } + + let evp_pkey = unsafe { EVP_PKEY_new() }; + if 1 != unsafe { EVP_PKEY_assign_EC_KEY(evp_pkey, ec_key) } { + return Err("Error in EVP_PKEY_assign_EC_KEY.".to_string()); + } + + let key_size_bytes: usize = unsafe { EVP_PKEY_size(evp_pkey) }.try_into().unwrap(); + let mut cbb: CBB = Default::default(); + unsafe { CBB_init(&mut cbb as *mut CBB, key_size_bytes * 5) }; + + if 1 != unsafe { EVP_marshal_public_key(&mut cbb, evp_pkey) } { + return Err("Error in EVP_marshal_public_key in GetPublicKey.".to_string()); + }; + + let mut out_data = null_mut::(); + let mut out_len: usize = 0; + + if 1 != unsafe { CBB_finish(&mut cbb, &mut out_data, &mut out_len) } { + return Err("Error in CBB_finish in GetPublicKey.".to_string()); + }; + let slice = unsafe { std::slice::from_raw_parts(out_data, out_len) }; + let slice = slice.to_vec(); + + unsafe { OPENSSL_free(out_data as *mut ::std::os::raw::c_void) }; + unsafe { EVP_PKEY_free(evp_pkey) }; + unsafe { EC_POINT_free(ec_point) }; + Ok(slice) + } + + fn inner_get_public_key( + key_bytes: &[u8], + expected_curve_nid: i32, + ) -> Result, String> { + let mut out = null_mut(); + let evp_pkey = unsafe { + aws_lc_sys::d2i_PrivateKey( + EVP_PKEY_EC, + &mut out, + &mut key_bytes.as_ptr(), + key_bytes + .len() + .try_into() + .map_err(|_| "Key too long".to_string())?, + ) + }; + if evp_pkey.is_null() { + return Err("Error in d2i_PrivateKey in GetPublicKey.".to_string()); + } + + let ec_key = unsafe { EVP_PKEY_get0_EC_KEY(evp_pkey) }; + if ec_key.is_null() { + return Err("Error in EVP_PKEY_get0_EC_KEY in GetPublicKey.".to_string()); + } + let ec_group = unsafe { EC_KEY_get0_group(ec_key) }; + if ec_group.is_null() { + return Err("Error in EC_KEY_get0_group in GetPublicKey.".to_string()); + } + let key_nid = unsafe { EC_GROUP_get_curve_name(ec_group) }; + + if key_nid != expected_curve_nid { + return Err("Wrong Algorithm".to_string()); + } + + let key_size_bytes: usize = unsafe { EVP_PKEY_size(evp_pkey) }.try_into().unwrap(); + let mut cbb: CBB = Default::default(); + unsafe { CBB_init(&mut cbb as *mut CBB, key_size_bytes * 5) }; + + if 1 != unsafe { EVP_marshal_public_key(&mut cbb, evp_pkey) } { + return Err("Error in EVP_marshal_public_key in GetPublicKey.".to_string()); + }; + + let mut out_data = null_mut::(); + let mut out_len: usize = 0; + + if 1 != unsafe { CBB_finish(&mut cbb, &mut out_data, &mut out_len) } { + return Err("Error in CBB_finish in GetPublicKey.".to_string()); + }; + let slice = unsafe { std::slice::from_raw_parts(out_data, out_len) }; + let slice = slice.to_vec(); + + unsafe { OPENSSL_free(out_data as *mut ::std::os::raw::c_void) }; + unsafe { EVP_PKEY_free(evp_pkey) }; + Ok(slice) + } + fn get_public_key(alg: &ECDHCurveSpec, pem: &[u8]) -> Result, String> { + let pem = std::str::from_utf8(pem).map_err(|e| format!("{:?}", e))?; + let private_key = pem::parse(pem).map_err(|e| format!("{:?}", e))?; + inner_get_public_key(private_key.contents(), get_nid(alg)) + } + + fn get_out_of_bounds(curve: &ECDHCurveSpec) -> Vec { + match curve { + ECDHCurveSpec::ECC_NIST_P256 {} => vec![ + 48, 89, 48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 8, 42, 134, 72, 206, 61, + 3, 1, 7, 3, 66, 0, 4, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, + ], + ECDHCurveSpec::ECC_NIST_P384 {} => vec![ + 48, 118, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 34, 3, + 98, 0, 4, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, + ], + ECDHCurveSpec::ECC_NIST_P521 {} => vec![ + 48, 129, 155, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, + 35, 3, 129, 134, 0, 4, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, + ], + ECDHCurveSpec::SM2 {} => vec![], + } + } + pub fn GetOutOfBoundsPublicKey( + curve_algorithm: &Rc, + ) -> Rc<_Wrappers_Compile::Result<::dafny_runtime::Sequence, Rc>> { + let result = get_out_of_bounds(curve_algorithm); + Rc::new(_Wrappers_Compile::Result::Success { + value: result.iter().cloned().collect(), + }) + } + + fn get_infinity(curve: &ECDHCurveSpec) -> Vec { + match curve { + ECDHCurveSpec::ECC_NIST_P256 {} => vec![ + 48, 25, 48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 8, 42, 134, 72, 206, 61, + 3, 1, 7, 3, 2, 0, 0, + ], + ECDHCurveSpec::ECC_NIST_P384 {} => vec![ + 48, 22, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 34, 3, + 2, 0, 0, + ], + ECDHCurveSpec::ECC_NIST_P521 {} => vec![ + 48, 22, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 35, 3, + 2, 0, 0, + ], + ECDHCurveSpec::SM2 {} => vec![], + } + } + + pub fn GetInfinityPublicKey( + curve_algorithm: &Rc, + ) -> Rc<_Wrappers_Compile::Result<::dafny_runtime::Sequence, Rc>> { + let result = get_infinity(curve_algorithm); + Rc::new(_Wrappers_Compile::Result::Success { + value: result.iter().cloned().collect(), + }) + } + pub fn GetPublicKey( + curve_algorithm: &Rc, + private_key: &Rc, + ) -> Rc<_Wrappers_Compile::Result<::dafny_runtime::Sequence, Rc>> { + let private_key: Vec = private_key.pem().iter().collect(); + match get_public_key(curve_algorithm, &private_key) { + Ok(x) => Rc::new(_Wrappers_Compile::Result::Success { + value: x.iter().cloned().collect(), + }), + Err(e) => { + let msg = format!("ECDH Get Public Key : {}", e); + Rc::new(_Wrappers_Compile::Result::Failure { + error: super::error(&msg), + }) + } + } + } + + // for the moment, it's valid if we can use it to generate a shared secret + fn valid_public_key(alg: &ECDHCurveSpec, public_key: &[u8]) -> Result<(), String> { + X509_to_X962(public_key, false, Some(get_nid(alg)))?; + Ok(()) + } + + pub fn ValidatePublicKey( + curve_algorithm: &Rc, + public_key: &::dafny_runtime::Sequence, + ) -> Rc<_Wrappers_Compile::Result>> { + let public_key: Vec = public_key.iter().collect(); + match valid_public_key(curve_algorithm, &public_key) { + Ok(_) => Rc::new(_Wrappers_Compile::Result::Success { value: true }), + Err(e) => Rc::new(_Wrappers_Compile::Result::Failure { + error: super::error(&e), + }), + } + } + + pub fn CompressPublicKey( + public_key: &::dafny_runtime::Sequence, + _curve_algorithm: &Rc, + ) -> Rc<_Wrappers_Compile::Result<::dafny_runtime::Sequence, Rc>> { + let public_key: Vec = public_key.iter().collect(); + match X509_to_X962(&public_key, true, None) { + Ok(v) => Rc::new(_Wrappers_Compile::Result::Success { + value: v.iter().cloned().collect(), + }), + Err(e) => { + let msg = format!("ECDH Compress Public Key {}", e); + Rc::new(_Wrappers_Compile::Result::Failure { + error: super::error(&msg), + }) + } + } + } + + pub fn DecompressPublicKey( + public_key: &::dafny_runtime::Sequence, + curve_algorithm: &Rc, + ) -> Rc<_Wrappers_Compile::Result<::dafny_runtime::Sequence, Rc>> { + let public_key: Vec = public_key.iter().collect(); + match X962_to_X509(&public_key, curve_algorithm) { + Ok(v) => Rc::new(_Wrappers_Compile::Result::Success { + value: v.iter().cloned().collect(), + }), + Err(e) => { + let msg = format!("ECDH Decompress Public Key {}", e); + Rc::new(_Wrappers_Compile::Result::Failure { + error: super::error(&msg), + }) + } + } + } + + pub fn ParsePublicKey( + publicKey: &::dafny_runtime::Sequence, + ) -> Rc<_Wrappers_Compile::Result<::dafny_runtime::Sequence, Rc>> { + let public_key: Vec = publicKey.iter().collect(); + match X509_to_X962(&public_key, false, None) { + Ok(_) => Rc::new(_Wrappers_Compile::Result::Success { + value: publicKey.clone(), + }), + Err(e) => Rc::new(_Wrappers_Compile::Result::Failure { + error: super::error(&e), + }), + } + } + } + pub mod DeriveSharedSecret { + use crate::software::amazon::cryptography::primitives::internaldafny::types::ECDHCurveSpec; + use crate::software::amazon::cryptography::primitives::internaldafny::types::Error as DafnyError; + use crate::*; + use std::rc::Rc; + + pub fn agree( + curve_algorithm: &ECDHCurveSpec, + private_key_pem: &[u8], + public_key_der: &[u8], + ) -> Result, String> { + let pem = std::str::from_utf8(private_key_pem).map_err(|e| format!("{:?}", e))?; + let private_key = pem::parse(pem).map_err(|e| format!("{:?}", e))?; + let private_key = aws_lc_rs::agreement::PrivateKey::from_private_key_der( + super::ECCUtils::get_alg(curve_algorithm), + private_key.contents(), + ) + .map_err(|e| format!("{:?}", e))?; + let public_key = super::ECCUtils::X509_to_X962(public_key_der, false, None)?; + let public_key = aws_lc_rs::agreement::UnparsedPublicKey::new( + super::ECCUtils::get_alg(curve_algorithm), + &public_key, + ); + let shared: Vec = + aws_lc_rs::agreement::agree(&private_key, &public_key, "foo", |x| Ok(x.to_vec())) + .map_err(|_e| "Failure in aws_lc_rs::agreement::agree.".to_string())?; + Ok(shared) + } + pub fn CalculateSharedSecret( + curve_algorithm: &Rc, + private_key: &Rc, + public_key: &Rc, + ) -> Rc<_Wrappers_Compile::Result<::dafny_runtime::Sequence, Rc>> { + let private_key: Vec = private_key.pem().iter().collect(); + let public_key: Vec = public_key.der().iter().collect(); + match agree(curve_algorithm, &private_key, &public_key) { + Ok(v) => Rc::new(_Wrappers_Compile::Result::Success { + value: v.iter().cloned().collect(), + }), + Err(e) => { + let msg = format!("ECDH Calculate Shared Secret : {}", e); + Rc::new(_Wrappers_Compile::Result::Failure { + error: super::error(&msg), + }) + } + } + } + } + pub mod KeyGeneration { + use crate::software::amazon::cryptography::primitives::internaldafny::types::ECDHCurveSpec; + use crate::software::amazon::cryptography::primitives::internaldafny::types::Error as DafnyError; + use crate::*; + use aws_lc_rs::encoding::AsDer; + use aws_lc_rs::encoding::EcPrivateKeyRfc5915Der; + use std::rc::Rc; + + fn ecdsa_key_gen(alg: &ECDHCurveSpec) -> Result<(Vec, Vec), String> { + let private_key = + aws_lc_rs::agreement::PrivateKey::generate(super::ECCUtils::get_alg(alg)) + .map_err(|e| format!("{:?}", e))?; + + let public_key = private_key + .compute_public_key() + .map_err(|e| format!("{:?}", e))?; + + let public_key: Vec = super::ECCUtils::X962_to_X509(public_key.as_ref(), alg)?; + + let private_key_der = AsDer::::as_der(&private_key) + .map_err(|e| format!("{:?}", e))?; + let private_key = pem::Pem::new("PRIVATE KEY", private_key_der.as_ref()); + let private_key = pem::encode(&private_key); + let private_key: Vec = private_key.into_bytes(); + + Ok((public_key, private_key)) + } + + pub fn GenerateKeyPair( + s: &Rc, + ) -> Rc<_Wrappers_Compile::Result, Rc>> { + match ecdsa_key_gen(s) { + Ok(x) => Rc::new(_Wrappers_Compile::Result::Success { + value: Rc::new(crate::ECDH::EccKeyPair::EccKeyPair { + publicKey: x.0.iter().cloned().collect(), + privateKey: x.1.iter().cloned().collect(), + }), + }), + Err(e) => { + let msg = format!("ECDH Generate Key Pair : {}", e); + Rc::new(_Wrappers_Compile::Result::Failure { + error: super::error(&msg), + }) + } + } + } + } + #[cfg(test)] + mod tests { + use super::*; + use crate::software::amazon::cryptography::primitives::internaldafny::types::ECDHCurveSpec; + use crate::*; + use std::rc::Rc; + + #[test] + fn test_generate() { + let alg = Rc::new(ECDHCurveSpec::ECC_NIST_P256 {}); + + let pair: crate::ECDH::EccKeyPair = match &*KeyGeneration::GenerateKeyPair(&alg) { + _Wrappers_Compile::Result::Success { value } => (**value).clone(), + _Wrappers_Compile::Result::Failure { error } => panic!("{:?}", error), + }; + + match &*ECCUtils::ValidatePublicKey(&alg, pair.publicKey()) { + _Wrappers_Compile::Result::Success { .. } => {} + _Wrappers_Compile::Result::Failure { error } => panic!("{:?}", error), + }; + } + } +} diff --git a/AwsCryptographicMaterialProviders/runtimes/rust/src/ecdsa.rs b/AwsCryptographicMaterialProviders/runtimes/rust/src/ecdsa.rs new file mode 100644 index 0000000000..ae4a51b7b0 --- /dev/null +++ b/AwsCryptographicMaterialProviders/runtimes/rust/src/ecdsa.rs @@ -0,0 +1,282 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +#![deny(warnings, unconditional_panic)] +#![deny(nonstandard_style)] +#![deny(clippy::all)] + +#[allow(non_snake_case)] +pub mod Signature { + pub mod ECDSA { + use crate::software::amazon::cryptography::primitives::internaldafny::types::ECDSASignatureAlgorithm; + use crate::software::amazon::cryptography::primitives::internaldafny::types::Error as DafnyError; + use crate::*; + use aws_lc_rs::encoding::AsDer; + use aws_lc_rs::rand::SystemRandom; + use aws_lc_rs::signature::EcdsaKeyPair; + use aws_lc_rs::signature::EcdsaSigningAlgorithm; + use aws_lc_rs::signature::EcdsaVerificationAlgorithm; + use aws_lc_rs::signature::KeyPair; + use aws_lc_rs::signature::UnparsedPublicKey; + use std::rc::Rc; + + fn error(s: &str) -> Rc { + Rc::new(DafnyError::AwsCryptographicPrimitivesError { + message: + dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(s), + }) + } + + fn get_alg(x: &ECDSASignatureAlgorithm) -> &'static EcdsaSigningAlgorithm { + match x { + ECDSASignatureAlgorithm::ECDSA_P256 {} => { + // &aws_lc_rs::signature::ECDSA_P256_SHA256_FIXED_SIGNING + &aws_lc_rs::signature::ECDSA_P256_SHA256_ASN1_SIGNING + } + ECDSASignatureAlgorithm::ECDSA_P384 {} => { + // &aws_lc_rs::signature::ECDSA_P384_SHA384_FIXED_SIGNING + &aws_lc_rs::signature::ECDSA_P384_SHA384_ASN1_SIGNING + } + } + } + + fn get_ver_alg(x: &ECDSASignatureAlgorithm) -> &'static EcdsaVerificationAlgorithm { + match x { + ECDSASignatureAlgorithm::ECDSA_P256 {} => { + // &aws_lc_rs::signature::ECDSA_P256_SHA256_FIXED + &aws_lc_rs::signature::ECDSA_P256_SHA256_ASN1 + } + ECDSASignatureAlgorithm::ECDSA_P384 {} => { + // &aws_lc_rs::signature::ECDSA_P384_SHA384_FIXED + &aws_lc_rs::signature::ECDSA_P384_SHA384_ASN1 + } + } + } + + fn get_nid(x: &ECDSASignatureAlgorithm) -> i32 { + match x { + ECDSASignatureAlgorithm::ECDSA_P256 {} => aws_lc_sys::NID_X9_62_prime256v1, + ECDSASignatureAlgorithm::ECDSA_P384 {} => aws_lc_sys::NID_secp384r1, + } + } + + const ELEM_MAX_BITS: usize = 521; + const ELEM_MAX_BYTES: usize = (ELEM_MAX_BITS + 7) / 8; + const PUBLIC_KEY_MAX_LEN: usize = 1 + (2 * ELEM_MAX_BYTES); + + pub(crate) fn sec1_compress( + data: &[u8], + alg: &ECDSASignatureAlgorithm, + ) -> Result, String> { + sec1_convert( + data, + get_nid(alg), + aws_lc_sys::point_conversion_form_t::POINT_CONVERSION_COMPRESSED, + ) + } + + pub(crate) fn sec1_convert( + data: &[u8], + nid: i32, + form: aws_lc_sys::point_conversion_form_t, + ) -> Result, String> { + use aws_lc_sys::EC_GROUP_new_by_curve_name; + use aws_lc_sys::EC_POINT_free; + use aws_lc_sys::EC_POINT_new; + use aws_lc_sys::EC_POINT_oct2point; + use aws_lc_sys::EC_POINT_point2oct; + use std::ptr::null_mut; + + // no need to free ec_group + let ec_group = unsafe { EC_GROUP_new_by_curve_name(nid) }; + if ec_group.is_null() { + return Err("EC_GROUP_new_by_curve_name returned failure.".to_string()); + } + + let ec_point = unsafe { EC_POINT_new(ec_group) }; + if ec_point.is_null() { + return Err("EC_POINT_new returned failure.".to_string()); + } + let mut out_buf = [0u8; PUBLIC_KEY_MAX_LEN]; + + let ret = unsafe { + EC_POINT_oct2point(ec_group, ec_point, data.as_ptr(), data.len(), null_mut()) + }; + if ret == 0 { + return Err("EC_POINT_oct2point returned failure.".to_string()); + } + let new_size: usize = unsafe { + EC_POINT_point2oct( + ec_group, + ec_point, + form, + out_buf.as_mut_ptr(), + PUBLIC_KEY_MAX_LEN, + null_mut(), + ) + }; + unsafe { EC_POINT_free(ec_point) }; + Ok(out_buf[..new_size].to_vec()) + } + + fn ecdsa_key_gen(alg: &ECDSASignatureAlgorithm) -> Result<(Vec, Vec), String> { + let pair = EcdsaKeyPair::generate(get_alg(alg)).map_err(|e| format!("{:?}", e))?; + + let public_key: Vec = sec1_compress(pair.public_key().as_ref(), alg)?; + let private_key: Vec = pair.private_key().as_der().unwrap().as_ref().to_vec(); + Ok((public_key, private_key)) + } + + pub fn ExternKeyGen( + alg: &Rc, + ) -> Rc<_Wrappers_Compile::Result, Rc>> + { + match ecdsa_key_gen(alg) { + Ok(x) => Rc::new(_Wrappers_Compile::Result::Success { + value: Rc::new(Signature::SignatureKeyPair::SignatureKeyPair { + verificationKey: x.0.iter().cloned().collect(), + signingKey: x.1.iter().cloned().collect(), + }), + }), + Err(e) => { + let msg = format!("ECDSA Key Gen : {}", e); + Rc::new(_Wrappers_Compile::Result::Failure { error: error(&msg) }) + } + } + } + + fn ecdsa_sign_inner( + alg: &ECDSASignatureAlgorithm, + key: &[u8], + msg: &[u8], + ) -> Result, String> { + let private_key = EcdsaKeyPair::from_private_key_der(get_alg(alg), key) + .map_err(|e| format!("{:?}", e))?; + let rng = SystemRandom::new(); + let sig = private_key + .sign(&rng, msg) + .map_err(|e| format!("{:?}", e))?; + Ok(sig.as_ref().to_vec()) + } + fn ecdsa_sign( + alg: &ECDSASignatureAlgorithm, + key: &[u8], + msg: &[u8], + ) -> Result, String> { + // This loop can in theory run forever, but the chances of that are negligible. + // We may want to consider failing, after some number of loops, if we can do so in a way consistent with other ESDKs. + loop { + let result = ecdsa_sign_inner(alg, key, msg)?; + if (get_alg(alg) == &aws_lc_rs::signature::ECDSA_P384_SHA384_ASN1_SIGNING + && result.len() == 103) + || (get_alg(alg) == &aws_lc_rs::signature::ECDSA_P256_SHA256_ASN1_SIGNING + && result.len() == 71) + { + return Ok(result); + } + } + } + + pub fn Sign( + alg: &Rc, + key: &::dafny_runtime::Sequence, + msg: &::dafny_runtime::Sequence, + ) -> Rc<_Wrappers_Compile::Result<::dafny_runtime::Sequence, Rc>> { + let key: Vec = key.iter().collect(); + let msg: Vec = msg.iter().collect(); + match ecdsa_sign(alg, &key, &msg) { + Ok(x) => Rc::new(_Wrappers_Compile::Result::Success { + value: x.iter().cloned().collect(), + }), + Err(e) => { + let msg = format!("ECDSA Sign : {}", e); + Rc::new(_Wrappers_Compile::Result::Failure { error: error(&msg) }) + } + } + } + + fn ecdsa_verify( + alg: &ECDSASignatureAlgorithm, + key: &[u8], + msg: &[u8], + sig: &[u8], + ) -> Result { + let public_key = UnparsedPublicKey::new(get_ver_alg(alg), key); + match public_key.verify(msg, sig) { + Ok(_) => Ok(true), + Err(_) => Ok(false), + } + } + + pub fn Verify( + alg: &Rc, + key: &::dafny_runtime::Sequence, + msg: &::dafny_runtime::Sequence, + sig: &::dafny_runtime::Sequence, + ) -> Rc<_Wrappers_Compile::Result>> { + let key: Vec = key.iter().collect(); + let msg: Vec = msg.iter().collect(); + let sig: Vec = sig.iter().collect(); + match ecdsa_verify(alg, &key, &msg, &sig) { + Ok(x) => Rc::new(_Wrappers_Compile::Result::Success { value: x }), + Err(e) => { + let msg = format!("ECDSA Verify : {}", e); + Rc::new(_Wrappers_Compile::Result::Failure { error: error(&msg) }) + } + } + } + #[cfg(test)] + mod tests { + use super::*; + use std::rc::Rc; + + #[test] + fn test_generate() { + let alg = Rc::new(ECDSASignatureAlgorithm::ECDSA_P384 {}); + let key_pair = match &*ExternKeyGen(&alg) { + _Wrappers_Compile::Result::Success { value } => value.clone(), + _Wrappers_Compile::Result::Failure { error } => { + panic!("ExternKeyGen Failed : {:?}", error); + } + }; + + let (s_key, v_key) = match &*key_pair { + Signature::SignatureKeyPair::SignatureKeyPair { + signingKey, + verificationKey, + } => (signingKey, verificationKey), + }; + + let message: ::dafny_runtime::Sequence = + [1u8, 2, 3, 4, 5].iter().cloned().collect(); + + let sig = match &*Sign(&alg, &s_key, &message) { + _Wrappers_Compile::Result::Success { value } => value.clone(), + _Wrappers_Compile::Result::Failure { error } => { + panic!("Sign Failed : {:?}", error); + } + }; + + let ver: bool = match &*Verify(&alg, &v_key, &message, &sig) { + _Wrappers_Compile::Result::Success { value } => value.clone(), + _Wrappers_Compile::Result::Failure { error } => { + panic!("Verify Failed : {:?}", error); + } + }; + assert!(ver); + + let mut sig_vec: Vec = sig.iter().collect(); + sig_vec[0] = 42; + let sig2: ::dafny_runtime::Sequence = sig_vec.iter().cloned().collect(); + assert!(sig != sig2); + let ver2: bool = match &*Verify(&alg, &v_key, &message, &sig2) { + _Wrappers_Compile::Result::Success { value } => value.clone(), + _Wrappers_Compile::Result::Failure { error } => { + panic!("Verify Failed : {:?}", error); + } + }; + assert!(!ver2); + } + } + } +} diff --git a/AwsCryptographicMaterialProviders/runtimes/rust/src/hmac.rs b/AwsCryptographicMaterialProviders/runtimes/rust/src/hmac.rs new file mode 100644 index 0000000000..a336060f50 --- /dev/null +++ b/AwsCryptographicMaterialProviders/runtimes/rust/src/hmac.rs @@ -0,0 +1,123 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +#![deny(warnings, unconditional_panic)] +#![deny(nonstandard_style)] +#![deny(clippy::all)] + +use crate::software::amazon::cryptography::primitives::internaldafny::types::DigestAlgorithm; +use crate::*; +use aws_lc_rs::hmac; + +fn convert_algorithm(input: &DigestAlgorithm) -> hmac::Algorithm { + match input { + DigestAlgorithm::SHA_512 {} => hmac::HMAC_SHA512, + DigestAlgorithm::SHA_384 {} => hmac::HMAC_SHA384, + DigestAlgorithm::SHA_256 {} => hmac::HMAC_SHA256, + } +} + +// Let's implement HMAC::_default::Digest +impl crate::HMAC::_default { + #[allow(non_snake_case)] + pub fn Digest( + input: &::std::rc::Rc< + crate::software::amazon::cryptography::primitives::internaldafny::types::HMacInput, + >, + ) -> ::std::rc::Rc< + _Wrappers_Compile::Result< + ::dafny_runtime::Sequence, + ::std::rc::Rc, + >, + > { + let key_vec: Vec = input.key().iter().collect(); + let the_key = hmac::Key::new(convert_algorithm(input.digestAlgorithm()), &key_vec); + let message_vec: Vec = input.message().iter().collect(); + let result = hmac::sign(&the_key, &message_vec); + ::std::rc::Rc::new(_Wrappers_Compile::Result::Success { + value: result.as_ref().iter().cloned().collect(), + }) + } +} + +#[allow(non_snake_case)] +pub mod HMAC { + use crate::*; + use aws_lc_rs::hmac; + use std::cell::RefCell; + #[allow(non_camel_case_types)] + pub struct _default {} + + #[derive(Debug)] + pub struct HMacInner { + context: Option, + key: Option, + } + pub struct HMac { + algorithm: hmac::Algorithm, + inner: RefCell, + } + + impl dafny_runtime::UpcastObject for HMac { + dafny_runtime::UpcastObjectFn!(dyn std::any::Any); + } + + impl HMac { + pub fn Init(&self, salt: &::dafny_runtime::Sequence) { + let salt: Vec = salt.iter().collect(); + self.inner.borrow_mut().key = Some(hmac::Key::new(self.algorithm, &salt)); + let context = Some(hmac::Context::with_key( + self.inner.borrow().key.as_ref().unwrap(), + )); + self.inner.borrow_mut().context = context; + } + pub fn re_init(&self) { + let context = Some(hmac::Context::with_key( + self.inner.borrow().key.as_ref().unwrap(), + )); + self.inner.borrow_mut().context = context; + } + pub fn Build( + input: &::std::rc::Rc< + software::amazon::cryptography::primitives::internaldafny::types::DigestAlgorithm, + >, + ) -> ::std::rc::Rc< + _Wrappers_Compile::Result< + ::dafny_runtime::Object, + ::std::rc::Rc< + software::amazon::cryptography::primitives::internaldafny::types::Error, + >, + >, + > { + let inner = dafny_runtime::Object::new(Self { + algorithm: super::convert_algorithm(input), + inner: RefCell::new(HMacInner { + context: None, + key: None, + }), + }); + + ::std::rc::Rc::new(_Wrappers_Compile::Result::Success { value: inner }) + } + pub fn BlockUpdate(&self, block: &::dafny_runtime::Sequence) { + let part: Vec = block.iter().collect(); + self.inner + .borrow_mut() + .context + .as_mut() + .unwrap() + .update(&part); + } + pub fn GetResult(&self) -> ::dafny_runtime::Sequence { + let is_empty = self.inner.borrow().context.is_none(); + if is_empty { + return [].iter().cloned().collect(); + } + let tag = self.inner.borrow_mut().context.take().unwrap().sign(); + // other languages allow you to call BlockUpdate after GetResult + // so we re-initialize to mimic that behavior + self.re_init(); + tag.as_ref().iter().cloned().collect() + } + } +} diff --git a/AwsCryptographicMaterialProviders/runtimes/rust/src/impl_add.rs b/AwsCryptographicMaterialProviders/runtimes/rust/src/impl_add.rs new file mode 100644 index 0000000000..bcc9a32e7b --- /dev/null +++ b/AwsCryptographicMaterialProviders/runtimes/rust/src/impl_add.rs @@ -0,0 +1,4 @@ +pub use crate::deps::aws_cryptography_keyStore; +pub use crate::deps::aws_cryptography_primitives; +pub use crate::deps::com_amazonaws_dynamodb; +pub use crate::deps::com_amazonaws_kms; diff --git a/AwsCryptographicMaterialProviders/runtimes/rust/src/kms.rs b/AwsCryptographicMaterialProviders/runtimes/rust/src/kms.rs new file mode 100644 index 0000000000..571a3b3faf --- /dev/null +++ b/AwsCryptographicMaterialProviders/runtimes/rust/src/kms.rs @@ -0,0 +1,88 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +#![deny(warnings, unconditional_panic)] +#![deny(nonstandard_style)] +#![deny(clippy::all)] + +use aws_config::Region; +use std::sync::LazyLock; + +static DAFNY_TOKIO_RUNTIME: LazyLock = LazyLock::new(|| { + tokio::runtime::Builder::new_multi_thread() + .enable_all() + .build() + .unwrap() +}); + +impl crate::r#software::amazon::cryptography::services::kms::internaldafny::_default { + #[allow(non_snake_case)] + pub fn KMSClientForRegion(region: &::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>) -> ::std::rc::Rc, ::std::rc::Rc>>{ + let region = + dafny_runtime::dafny_runtime_conversions::unicode_chars_false::dafny_string_to_string( + region, + ); + + let shared_config = match tokio::runtime::Handle::try_current() { + Ok(curr) => tokio::task::block_in_place(|| { + curr.block_on(async { + aws_config::load_defaults(aws_config::BehaviorVersion::v2024_03_28()).await + }) + }), + Err(_) => DAFNY_TOKIO_RUNTIME.block_on(aws_config::load_defaults( + aws_config::BehaviorVersion::v2024_03_28(), + )), + }; + + let shared_config = shared_config + .to_builder() + .region(Region::new(region)) + .build(); + let inner = aws_sdk_kms::Client::new(&shared_config); + let client = crate::deps::com_amazonaws_kms::client::Client { inner }; + let dafny_client = ::dafny_runtime::upcast_object()(::dafny_runtime::object::new(client)); + std::rc::Rc::new(crate::r#_Wrappers_Compile::Result::Success { + value: dafny_client, + }) + } + + #[allow(non_snake_case)] + pub fn KMSClient() -> ::std::rc::Rc, ::std::rc::Rc>>{ + let shared_config = match tokio::runtime::Handle::try_current() { + Ok(curr) => tokio::task::block_in_place(|| { + curr.block_on(async { + aws_config::load_defaults(aws_config::BehaviorVersion::v2024_03_28()).await + }) + }), + Err(_) => DAFNY_TOKIO_RUNTIME.block_on(aws_config::load_defaults( + aws_config::BehaviorVersion::v2024_03_28(), + )), + }; + + let inner = aws_sdk_kms::Client::new(&shared_config); + let client = crate::deps::com_amazonaws_kms::client::Client { inner }; + let dafny_client = ::dafny_runtime::upcast_object()(::dafny_runtime::object::new(client)); + std::rc::Rc::new(crate::r#_Wrappers_Compile::Result::Success { + value: dafny_client, + }) + } + + #[allow(non_snake_case)] + pub fn RegionMatch( + kmsClient: &::dafny_runtime::Object, + region: &::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>, + ) -> ::std::rc::Rc> { + let region = + dafny_runtime::dafny_runtime_conversions::unicode_chars_false::dafny_string_to_string( + region, + ); + let any = dafny_runtime::cast_any_object!(kmsClient); + let client = + dafny_runtime::cast_object!(any, crate::deps::com_amazonaws_kms::client::Client); + let flag = match client.as_ref().inner.config().region() { + Some(r) => r.as_ref() == region, + None => false, + }; + ::std::rc::Rc::new(crate::r#_Wrappers_Compile::Option::Some { value: flag }) + } +} diff --git a/AwsCryptographicMaterialProviders/runtimes/rust/src/lib.rs b/AwsCryptographicMaterialProviders/runtimes/rust/src/lib.rs new file mode 100644 index 0000000000..2727355c88 --- /dev/null +++ b/AwsCryptographicMaterialProviders/runtimes/rust/src/lib.rs @@ -0,0 +1,60 @@ +#![allow( + deprecated, + non_upper_case_globals, + unused, + non_snake_case, + non_camel_case_types +)] + +pub mod client; +pub mod conversions; +pub mod deps; +pub mod error; +pub mod operation; +pub mod types; + +pub(crate) mod standard_library_conversions; +pub(crate) mod standard_library_externs; +pub use client::Client; + +pub use crate::deps::aws_cryptography_primitives; +pub use crate::deps::aws_cryptography_keyStore; +pub use crate::deps::com_amazonaws_dynamodb; +pub use crate::deps::com_amazonaws_kms; + +pub(crate) mod implementation_from_dafny; + +pub mod aes_gcm; +pub mod aes_kdf_ctr; +pub mod concurrent_call; +pub mod dafny_libraries; +pub mod ddb; +pub mod digest; +pub mod ecdh; +pub mod ecdsa; +pub mod hmac; +pub mod kms; +pub mod local_cmc; +pub mod random; +pub mod rsa; +pub mod sets; +pub mod software_externs; +pub mod storm_tracker; +pub mod time; +pub mod uuid; + +pub(crate) use crate::implementation_from_dafny::r#_Wrappers_Compile; +pub(crate) use crate::implementation_from_dafny::software; +pub(crate) use crate::implementation_from_dafny::AesKdfCtr; +pub(crate) use crate::implementation_from_dafny::ConcurrentCall; +pub(crate) use crate::implementation_from_dafny::DafnyLibraries; +pub(crate) use crate::implementation_from_dafny::ExternDigest; +pub(crate) use crate::implementation_from_dafny::ExternRandom; +pub(crate) use crate::implementation_from_dafny::Signature; +pub(crate) use crate::implementation_from_dafny::Time; +pub(crate) use crate::implementation_from_dafny::ECDH; +pub(crate) use crate::implementation_from_dafny::HMAC; +pub(crate) use crate::implementation_from_dafny::UTF8; +pub(crate) use crate::implementation_from_dafny::UUID; +pub(crate) use crate::implementation_from_dafny::_StormTracker_Compile; +pub(crate) use crate::implementation_from_dafny::_LocalCMC_Compile; diff --git a/AwsCryptographicMaterialProviders/runtimes/rust/src/local_cmc.rs b/AwsCryptographicMaterialProviders/runtimes/rust/src/local_cmc.rs new file mode 100644 index 0000000000..c12c67f4f0 --- /dev/null +++ b/AwsCryptographicMaterialProviders/runtimes/rust/src/local_cmc.rs @@ -0,0 +1,53 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +#![deny(warnings, unconditional_panic)] +#![deny(nonstandard_style)] +#![deny(clippy::all)] + +#[allow(non_snake_case)] +pub mod internal_SynchronizedLocalCMC { + use crate::*; + use std::sync::Mutex; + + pub struct SynchronizedLocalCMC { + wrapped: Mutex<::dafny_runtime::Object<_LocalCMC_Compile::LocalCMC>>, + } + + impl SynchronizedLocalCMC { + pub fn _allocate_object( + cmc: ::dafny_runtime::Object<_LocalCMC_Compile::LocalCMC>, + ) -> ::dafny_runtime::Object { + ::dafny_runtime::Object::new(SynchronizedLocalCMC { + wrapped: Mutex::new(cmc), + }) + } + } + + impl ::dafny_runtime::UpcastObject for SynchronizedLocalCMC { + ::dafny_runtime::UpcastObjectFn!(dyn ::std::any::Any); + } + + impl ::dafny_runtime::UpcastObject + for SynchronizedLocalCMC { + ::dafny_runtime::UpcastObjectFn!(dyn software::amazon::cryptography::materialproviders::internaldafny::types::ICryptographicMaterialsCache); + } + + impl software::amazon::cryptography::materialproviders::internaldafny::types::ICryptographicMaterialsCache for SynchronizedLocalCMC { + fn r#_PutCacheEntry_k(&self, input: &std::rc::Rc) -> std::rc::Rc>> { + self.wrapped.lock().unwrap().as_mut()._PutCacheEntry_k(input) + } + + fn r#_UpdateUsageMetadata_k(&self, input: &std::rc::Rc) -> std::rc::Rc>> { + self.wrapped.lock().unwrap().as_mut()._UpdateUsageMetadata_k(input) + } + + fn r#_GetCacheEntry_k(&self, input: &std::rc::Rc) -> std::rc::Rc, std::rc::Rc>> { + self.wrapped.lock().unwrap().as_mut()._GetCacheEntry_k(input) + } + + fn r#_DeleteCacheEntry_k(&self, input: &std::rc::Rc) -> std::rc::Rc>> { + self.wrapped.lock().unwrap().as_mut()._DeleteCacheEntry_k(input) + } + } +} diff --git a/AwsCryptographicMaterialProviders/runtimes/rust/src/random.rs b/AwsCryptographicMaterialProviders/runtimes/rust/src/random.rs new file mode 100644 index 0000000000..437a22c692 --- /dev/null +++ b/AwsCryptographicMaterialProviders/runtimes/rust/src/random.rs @@ -0,0 +1,38 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +#![deny(warnings, unconditional_panic)] +#![deny(nonstandard_style)] +#![deny(clippy::all)] + +use crate::*; +use aws_lc_rs::rand; + +impl crate::ExternRandom::_default { + #[allow(non_snake_case)] + pub fn GenerateBytes( + num_bytes: i32, + ) -> ::std::rc::Rc< + _Wrappers_Compile::Result< + ::dafny_runtime::Sequence, + ::std::rc::Rc, + >, + > { + let mut rand_bytes: Vec = vec![0; num_bytes as usize]; + match rand::fill(&mut rand_bytes) { + Ok(_) => { + ::std::rc::Rc::new( + _Wrappers_Compile::Result::Success{value : + dafny_runtime::dafny_runtime_conversions::vec_to_dafny_sequence(&rand_bytes, |x| *x) + } + ) + } + Err(_) => { + std::rc::Rc::new(_Wrappers_Compile::Result::Failure{ error : std::rc::Rc::new( + software::amazon::cryptography::primitives::internaldafny::types::Error::AwsCryptographicPrimitivesError{ + message : dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string("Error generating random bytes.") + })}) + } + } + } +} diff --git a/AwsCryptographicMaterialProviders/runtimes/rust/src/rsa.rs b/AwsCryptographicMaterialProviders/runtimes/rust/src/rsa.rs new file mode 100644 index 0000000000..9bb76d9cc4 --- /dev/null +++ b/AwsCryptographicMaterialProviders/runtimes/rust/src/rsa.rs @@ -0,0 +1,256 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +#![deny(warnings, unconditional_panic)] +#![deny(nonstandard_style)] +#![deny(clippy::all)] + +// Extern methods with a foreign module name +#[allow(non_snake_case)] +pub mod RSAEncryption { + pub mod RSA { + use crate::_Wrappers_Compile as Wrappers; + use crate::software::amazon::cryptography::primitives::internaldafny::types::RSAPaddingMode; + use crate::*; + use ::std::rc::Rc; + use aws_lc_rs::encoding::{AsDer, Pkcs8V1Der, PublicKeyX509Der}; + + use aws_lc_rs::rsa::KeySize; + use aws_lc_rs::rsa::OaepAlgorithm; + use aws_lc_rs::rsa::OaepPrivateDecryptingKey; + use aws_lc_rs::rsa::OaepPublicEncryptingKey; + use aws_lc_rs::rsa::Pkcs1PrivateDecryptingKey; + use aws_lc_rs::rsa::Pkcs1PublicEncryptingKey; + use aws_lc_rs::rsa::PrivateDecryptingKey; + use aws_lc_rs::rsa::PublicEncryptingKey; + use pem; + use software::amazon::cryptography::primitives::internaldafny::types::Error as DafnyError; + + pub fn key_size_from_length(length: i32) -> KeySize { + match length { + 2048 => KeySize::Rsa2048, + 3072 => KeySize::Rsa3072, + 4096 => KeySize::Rsa4096, + 8192 => KeySize::Rsa8192, + _ => panic!("Bad length for GenerateKeyPair"), + } + } + + fn error(s: &str) -> Rc { + Rc::new(DafnyError::AwsCryptographicPrimitivesError { + message: + dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(s), + }) + } + + fn generate_key_pair(length_bits: i32) -> Result<(Vec, Vec), String> { + // Generate an RSA key. + let private_key = PrivateDecryptingKey::generate(key_size_from_length(length_bits)) + .map_err(|e| format!("{:?}", e))?; + + // Serialize the RSA private key to DER encoded PKCS#8 format for later usage. + let private_key_der = + AsDer::::as_der(&private_key).map_err(|e| format!("{:?}", e))?; + + // Retrieve the RSA public key + let public_key = private_key.public_key(); + + // Serialize the RSA public key to DER encoded X.509 SubjectPublicKeyInfo for later usage. + let public_key_der = + AsDer::::as_der(&public_key).map_err(|e| format!("{:?}", e))?; + + let public_key = pem::Pem::new("RSA PUBLIC KEY", public_key_der.as_ref()); + let public_key = pem::encode(&public_key); + let private_key = pem::Pem::new("RSA PRIVATE KEY", private_key_der.as_ref()); + let private_key = pem::encode(&private_key); + + Ok((public_key.into(), private_key.into())) + } + #[allow(non_snake_case)] + pub fn GenerateKeyPairExtern( + length_bits: i32, + ) -> (::dafny_runtime::Sequence, ::dafny_runtime::Sequence) { + match generate_key_pair(length_bits) { + Ok(x) => (x.0.iter().cloned().collect(), x.1.iter().cloned().collect()), + Err(e) => { + panic!("Unexpected error generating RSA Key Pair{}", e); + } + } + } + + fn get_alg_for_padding(mode: &RSAPaddingMode) -> Result<&'static OaepAlgorithm, String> { + match mode { + RSAPaddingMode::PKCS1 {} => { + Err("No support for RSA with PKCS1 in Rust.".to_string()) + } + RSAPaddingMode::OAEP_SHA1 {} => Ok(&aws_lc_rs::rsa::OAEP_SHA1_MGF1SHA1), + RSAPaddingMode::OAEP_SHA256 {} => Ok(&aws_lc_rs::rsa::OAEP_SHA256_MGF1SHA256), + RSAPaddingMode::OAEP_SHA384 {} => Ok(&aws_lc_rs::rsa::OAEP_SHA384_MGF1SHA384), + RSAPaddingMode::OAEP_SHA512 {} => Ok(&aws_lc_rs::rsa::OAEP_SHA512_MGF1SHA512), + } + } + + fn get_modulus(public_key: &[u8]) -> Result { + let public_key = std::str::from_utf8(public_key).map_err(|e| format!("{:?}", e))?; + let public_key = pem::parse(public_key).map_err(|e| format!("{:?}", e))?; + let public_key = PublicEncryptingKey::from_der(public_key.contents()) + .map_err(|e| format!("{:?}", e))?; + Ok(public_key.key_size_bits() as u32) + } + + #[allow(non_snake_case)] + pub fn GetRSAKeyModulusLengthExtern( + public_key: &::dafny_runtime::Sequence, + ) -> Rc>> { + let public_key: Vec = public_key.iter().collect(); + match get_modulus(&public_key) { + Ok(v) => Rc::new(Wrappers::Result::Success { value: v }), + Err(e) => Rc::new(Wrappers::Result::Failure { error: error(&e) }), + } + } + + fn decrypt_extern( + mode: &RSAPaddingMode, + private_key: &[u8], + cipher_text: &[u8], + ) -> Result, String> { + let private_key = + std::str::from_utf8(private_key).map_err(|e| format!("from_utf8 : {:?}", e))?; + let private_key = + pem::parse(private_key).map_err(|e| format!("pem::parse : {:?}", e))?; + if mode == &(RSAPaddingMode::PKCS1 {}) { + return decrypt_pkcs1(private_key.contents(), cipher_text); + } + let mode = get_alg_for_padding(mode)?; + + let private_key = PrivateDecryptingKey::from_pkcs8(private_key.contents()) + .map_err(|e| format!("from_pkcs8 : {:?}", e))?; + let private_key = + OaepPrivateDecryptingKey::new(private_key).map_err(|e| format!("new : {:?}", e))?; + let mut message: Vec = vec![0; cipher_text.len()]; + let message = private_key + .decrypt(mode, cipher_text, &mut message, None) + .map_err(|e| format!("decrypt {:?}", e))?; + Ok(message.to_vec()) + } + + #[allow(non_snake_case)] + pub fn DecryptExtern( + mode: &RSAPaddingMode, + private_key: &::dafny_runtime::Sequence, + cipher_text: &::dafny_runtime::Sequence, + ) -> Rc, Rc>> { + let private_key: Vec = private_key.iter().collect(); + let cipher_text: Vec = cipher_text.iter().collect(); + match decrypt_extern(mode, &private_key, &cipher_text) { + Ok(x) => Rc::new(Wrappers::Result::Success { + value: x.iter().cloned().collect(), + }), + Err(e) => { + let msg = format!("RSA Decrypt : {}", e); + Rc::new(Wrappers::Result::Failure { error: error(&msg) }) + } + } + } + + fn encrypt_extern( + mode: &RSAPaddingMode, + public_key: &[u8], + message: &[u8], + ) -> Result, String> { + let public_key = std::str::from_utf8(public_key).map_err(|e| format!("{:?}", e))?; + let public_key = pem::parse(public_key).map_err(|e| format!("{:?}", e))?; + if mode == &(RSAPaddingMode::PKCS1 {}) { + return encrypt_pkcs1(public_key.contents(), message); + } + let mode = get_alg_for_padding(mode)?; + + let public_key = PublicEncryptingKey::from_der(public_key.contents()) + .map_err(|e| format!("{:?}", e))?; + let public_key = + OaepPublicEncryptingKey::new(public_key).map_err(|e| format!("{:?}", e))?; + let mut ciphertext: Vec = vec![0; message.len() + public_key.key_size_bytes()]; + let cipher_text = public_key + .encrypt(mode, message, &mut ciphertext, None) + .map_err(|e| format!("{:?}", e))?; + Ok(cipher_text.to_vec()) + } + + #[allow(non_snake_case)] + pub fn EncryptExtern( + mode: &RSAPaddingMode, + public_key: &::dafny_runtime::Sequence, + message: &::dafny_runtime::Sequence, + ) -> Rc, Rc>> { + let public_key: Vec = public_key.iter().collect(); + let message: Vec = message.iter().collect(); + match encrypt_extern(mode, &public_key, &message) { + Ok(x) => Rc::new(Wrappers::Result::Success { + value: x.iter().cloned().collect(), + }), + Err(e) => { + let msg = format!("RSA Encrypt : {}", e); + Rc::new(Wrappers::Result::Failure { error: error(&msg) }) + } + } + } + + pub fn encrypt_pkcs1(public_key: &[u8], plain_text: &[u8]) -> Result, String> { + let public_key = + PublicEncryptingKey::from_der(public_key).map_err(|e| format!("{:?}", e))?; + let public_key = + Pkcs1PublicEncryptingKey::new(public_key).map_err(|e| format!("{:?}", e))?; + let mut ciphertext: Vec = vec![0; plain_text.len() + public_key.key_size_bytes()]; + let cipher_text = public_key + .encrypt(plain_text, &mut ciphertext) + .map_err(|e| format!("{:?}", e))?; + Ok(cipher_text.to_vec()) + } + + pub fn decrypt_pkcs1(private_key: &[u8], cipher_text: &[u8]) -> Result, String> { + let private_key = PrivateDecryptingKey::from_pkcs8(private_key) + .map_err(|e| format!("from_pkcs8 : {:?}", e))?; + let private_key = Pkcs1PrivateDecryptingKey::new(private_key) + .map_err(|e| format!("new : {:?}", e))?; + let mut message: Vec = vec![0; cipher_text.len()]; + let message = private_key + .decrypt(cipher_text, &mut message) + .map_err(|e| format!("decrypt {:?}", e))?; + Ok(message.to_vec()) + } + + #[cfg(test)] + mod tests { + use super::*; + #[test] + fn test_generate() { + let (public_key, private_key) = GenerateKeyPairExtern(2048); + + let modulus: u32 = match &*GetRSAKeyModulusLengthExtern(&public_key) { + Wrappers::Result::Success { value } => *value, + Wrappers::Result::Failure { error } => panic!("{:?}", error), + }; + assert_eq!(modulus, 2048); + + let mode = RSAPaddingMode::OAEP_SHA256 {}; + + let plain_text: ::dafny_runtime::Sequence = + [1u8, 2, 3, 4, 5].iter().cloned().collect(); + + let cipher: ::dafny_runtime::Sequence = + match &*EncryptExtern(&mode, &public_key, &plain_text) { + Wrappers::Result::Success { value } => value.clone(), + Wrappers::Result::Failure { error } => panic!("{:?}", error), + }; + + let message: ::dafny_runtime::Sequence = + match &*DecryptExtern(&mode, &private_key, &cipher) { + Wrappers::Result::Success { value } => value.clone(), + Wrappers::Result::Failure { error } => panic!("{:?}", error), + }; + + assert_eq!(plain_text, message); + } + } + } +} diff --git a/AwsCryptographicMaterialProviders/runtimes/rust/src/sets.rs b/AwsCryptographicMaterialProviders/runtimes/rust/src/sets.rs new file mode 100644 index 0000000000..755615ddb7 --- /dev/null +++ b/AwsCryptographicMaterialProviders/runtimes/rust/src/sets.rs @@ -0,0 +1,63 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +#![deny(warnings, unconditional_panic)] +#![deny(nonstandard_style)] +#![deny(clippy::all)] + +#[allow(non_snake_case)] +#[allow(clippy::type_complexity)] +pub mod SortedSets { + use std::cmp::Ordering; + + #[allow(non_camel_case_types)] + pub struct _default {} + impl _default { + pub fn SetToSequence( + elems: &::dafny_runtime::Set, + ) -> ::dafny_runtime::Sequence { + elems.iter().cloned().collect() + } + + pub fn SetToOrderedSequence( + elems: &::dafny_runtime::Set<::dafny_runtime::Sequence>, + less: &::std::rc::Rc bool>, + ) -> ::dafny_runtime::Sequence<::dafny_runtime::Sequence> { + let mut vec = elems.iter().cloned().collect::>(); + vec.sort_by(|a, b| Self::order(a, b, less)); + dafny_runtime::dafny_runtime_conversions::vec_to_dafny_sequence(&vec, |x| x.clone()) + } + + pub fn SetToOrderedSequence2( + elems: &::dafny_runtime::Set<::dafny_runtime::Sequence>, + less: &::std::rc::Rc bool>, + ) -> ::dafny_runtime::Sequence<::dafny_runtime::Sequence> { + Self::SetToOrderedSequence(elems, less) + } + + fn order( + x: &::dafny_runtime::Sequence, + y: &::dafny_runtime::Sequence, + less: &::std::rc::Rc bool>, + ) -> Ordering { + let mut iter1 = x.iter(); + let mut iter2 = y.iter(); + + loop { + match (iter1.next(), iter2.next()) { + (Some(lhs), Some(rhs)) => { + if less(&lhs, &rhs) { + return Ordering::Less; + } + if less(&rhs, &lhs) { + return Ordering::Greater; + } + } + (Some(_), None) => return Ordering::Greater, + (None, Some(_)) => return Ordering::Less, + (None, None) => return Ordering::Equal, + } + } + } + } +} diff --git a/AwsCryptographicMaterialProviders/runtimes/rust/src/software_externs.rs b/AwsCryptographicMaterialProviders/runtimes/rust/src/software_externs.rs new file mode 100644 index 0000000000..5ff57e57f4 --- /dev/null +++ b/AwsCryptographicMaterialProviders/runtimes/rust/src/software_externs.rs @@ -0,0 +1,22 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +#![deny(warnings, unconditional_panic)] +#![deny(nonstandard_style)] +#![deny(clippy::all)] +#![allow(non_snake_case)] + +pub mod software { + pub mod amazon { + pub mod cryptography { + pub mod internaldafny { + pub mod StormTrackingCMC { + pub use crate::storm_tracker::internal_StormTrackingCMC::*; + } + pub mod SynchronizedLocalCMC { + pub use crate::local_cmc::internal_SynchronizedLocalCMC::*; + } + } + } + } +} diff --git a/AwsCryptographicMaterialProviders/runtimes/rust/src/storm_tracker.rs b/AwsCryptographicMaterialProviders/runtimes/rust/src/storm_tracker.rs new file mode 100644 index 0000000000..abb4024bbb --- /dev/null +++ b/AwsCryptographicMaterialProviders/runtimes/rust/src/storm_tracker.rs @@ -0,0 +1,80 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +#![deny(warnings, unconditional_panic)] +#![deny(nonstandard_style)] +#![deny(clippy::all)] + +#[allow(non_snake_case)] +pub mod internal_StormTrackingCMC { + use crate::_StormTracker_Compile::CacheState::*; + use crate::*; + use std::sync::Mutex; + use std::time::Duration; + + pub struct StormTrackingCMC { + wrapped: Mutex<::dafny_runtime::Object<_StormTracker_Compile::StormTracker>>, + } + impl StormTrackingCMC { + pub fn _allocate_object( + cmc: ::dafny_runtime::Object<_StormTracker_Compile::StormTracker>, + ) -> ::dafny_runtime::Object { + ::dafny_runtime::Object::new(StormTrackingCMC { + wrapped: Mutex::new(cmc), + }) + } + } + + impl ::dafny_runtime::UpcastObject for StormTrackingCMC { + ::dafny_runtime::UpcastObjectFn!(dyn ::std::any::Any); + } + + impl ::dafny_runtime::UpcastObject + for StormTrackingCMC { + ::dafny_runtime::UpcastObjectFn!(dyn software::amazon::cryptography::materialproviders::internaldafny::types::ICryptographicMaterialsCache); +} + + impl crate::software::amazon::cryptography::materialproviders::internaldafny::types::ICryptographicMaterialsCache for StormTrackingCMC { + fn r#_PutCacheEntry_k(&self, input: &std::rc::Rc) + -> std::rc::Rc>> + { + self.wrapped.lock().unwrap().as_mut().PutCacheEntry(input) + } + + fn r#_UpdateUsageMetadata_k(&self, input: &std::rc::Rc) + -> std::rc::Rc>> + { + self.wrapped.lock().unwrap().as_mut().UpdateUsageMetadata(input) + } + + fn r#_GetCacheEntry_k(&self, input: &std::rc::Rc) + -> std::rc::Rc, std::rc::Rc>> + { + loop { + let result = self.wrapped.lock().unwrap().as_mut().GetFromCache(input); + match &*result { + crate::_Wrappers_Compile::Result::Failure{error} => {return std::rc::Rc::new(crate::_Wrappers_Compile::Result::Failure{error : error.clone()});} + crate::_Wrappers_Compile::Result::Success{value} => { + match &**value { + Full { data } => { return std::rc::Rc::new(crate::_Wrappers_Compile::Result::Success{value : data.clone()}); } + EmptyFetch {} => { + return std::rc::Rc::new(crate::_Wrappers_Compile::Result::Failure{error : + std::rc::Rc::new(crate::software::amazon::cryptography::materialproviders::internaldafny::types::Error::EntryDoesNotExist { message: + dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string( + "Entry does not exist" + ) + }, + )}); + } + EmptyWait {} => { std::thread::sleep(Duration::from_micros(50)); } + } + } + } + } + } + + fn r#_DeleteCacheEntry_k(&self, input: &std::rc::Rc) -> std::rc::Rc>> { + self.wrapped.lock().unwrap().as_mut().DeleteCacheEntry(input) + } + } +} diff --git a/AwsCryptographicMaterialProviders/runtimes/rust/src/time.rs b/AwsCryptographicMaterialProviders/runtimes/rust/src/time.rs new file mode 100644 index 0000000000..cb170033fd --- /dev/null +++ b/AwsCryptographicMaterialProviders/runtimes/rust/src/time.rs @@ -0,0 +1,44 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +#![deny(warnings, unconditional_panic)] +#![deny(nonstandard_style)] +#![deny(clippy::all)] + +use crate::*; +use std::time::SystemTime; + +impl crate::Time::_default { + #[allow(non_snake_case)] + pub fn CurrentRelativeTime() -> i64 { + match SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) { + Ok(n) => n.as_secs() as i64, + Err(_) => 0, + } + } + + #[allow(non_snake_case)] + #[allow(dead_code)] + pub fn CurrentRelativeTimeMilli() -> i64 { + match SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) { + Ok(n) => n.as_millis() as i64, + Err(_) => 0, + } + } + + #[allow(non_snake_case)] + pub fn GetCurrentTimeStamp() -> ::std::rc::Rc< + _Wrappers_Compile::Result< + ::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>, + ::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>, + >, + > { + let now_utc = chrono::Utc::now(); + let formatted = format!("{}", now_utc.format("%Y-%m-%dT%H:%M:%S%.6fZ")); + ::std::rc::Rc::new( + _Wrappers_Compile::Result::Success{value : + dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(&formatted) + } + ) + } +} diff --git a/AwsCryptographicMaterialProviders/runtimes/rust/src/timer.rs b/AwsCryptographicMaterialProviders/runtimes/rust/src/timer.rs new file mode 100644 index 0000000000..811dee8651 --- /dev/null +++ b/AwsCryptographicMaterialProviders/runtimes/rust/src/timer.rs @@ -0,0 +1,66 @@ +pub struct ResourceTracker { + count : usize, + total : usize, + time : std::time::SystemTime, + cpu : cpu_time::ProcessTime, +} + +impl ResourceTracker { + pub fn new() -> Self { + Self { + count : get_counter(), + total : get_total(), + time : std::time::SystemTime::now(), + cpu : cpu_time::ProcessTime::now(), + } + } + pub fn report(&self) { + let time = self.time.elapsed().unwrap().as_secs_f64(); + let cpu = self.cpu.elapsed().as_secs_f64(); + println!("Allocation Count : {}, Total : {}, CPU Time : {}, Clock Time : {}", + get_counter()-self.count, get_total()-self.total, cpu, time); + } +} + +static mut COUNTER: usize = 0; +static mut TOTAL: usize = 0; + +fn add_to_counter(inc: usize) { + // SAFETY: There are no other threads which could be accessing `COUNTER`. + unsafe { + COUNTER += 1; + TOTAL += inc; + } +} + +fn get_counter() -> usize { + // SAFETY: There are no other threads which could be accessing `COUNTER`. + unsafe { + COUNTER + } +} + +fn get_total() -> usize { + // SAFETY: There are no other threads which could be accessing `COUNTER`. + unsafe { + TOTAL + } +} + +use std::alloc::{GlobalAlloc, System, Layout}; + +struct MyAllocator; + +unsafe impl GlobalAlloc for MyAllocator { + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + add_to_counter(layout.size()); + System.alloc(layout) + } + + unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { + System.dealloc(ptr, layout) + } +} + +#[global_allocator] +static GLOBAL: MyAllocator = MyAllocator; diff --git a/AwsCryptographicMaterialProviders/runtimes/rust/src/uuid.rs b/AwsCryptographicMaterialProviders/runtimes/rust/src/uuid.rs new file mode 100644 index 0000000000..700b2b1d21 --- /dev/null +++ b/AwsCryptographicMaterialProviders/runtimes/rust/src/uuid.rs @@ -0,0 +1,76 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +#![deny(warnings, unconditional_panic)] +#![deny(nonstandard_style)] +#![deny(clippy::all)] + +use crate::*; +use ::uuid::Uuid; + +impl crate::UUID::_default { + #[allow(non_snake_case)] + pub fn ToByteArray( + bytes: &::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>, + ) -> ::std::rc::Rc< + _Wrappers_Compile::Result< + ::dafny_runtime::Sequence, + ::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>, + >, + > { + let my_str = + dafny_runtime::dafny_runtime_conversions::unicode_chars_false::dafny_string_to_string( + bytes, + ); + match Uuid::parse_str(&my_str) { + Ok(u) => { + let b = u.as_bytes(); + std::rc::Rc::new(_Wrappers_Compile::Result::Success { value : + b.iter().cloned().collect() + }) + } + Err(e) => { + std::rc::Rc::new(_Wrappers_Compile::Result::Failure{ error : + dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string( + &format!("{my_str} is not a valid UUID ({e}).")) + }) + } + } + } + + #[allow(non_snake_case)] + pub fn FromByteArray( + bytes: &::dafny_runtime::Sequence, + ) -> ::std::rc::Rc< + _Wrappers_Compile::Result< + ::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>, + ::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>, + >, + > { + let vec: Vec = bytes.iter().collect(); + if vec.len() != 16 { + return std::rc::Rc::new(_Wrappers_Compile::Result::Failure{ error : + dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string("Not 16 bytes of input to FromByteArray.") + }); + } + let bytes: ::uuid::Bytes = vec[..16].try_into().unwrap(); + let uuid = Uuid::from_bytes_ref(&bytes); + let my_str = uuid.to_string(); + std::rc::Rc::new(_Wrappers_Compile::Result::Success { value : + dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(&my_str) + }) + } + + #[allow(non_snake_case)] + pub fn GenerateUUID() -> ::std::rc::Rc< + _Wrappers_Compile::Result< + ::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>, + ::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>, + >, + > { + let my_str = Uuid::new_v4().to_string(); + std::rc::Rc::new(_Wrappers_Compile::Result::Success { value : + dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(&my_str) + }) + } +} diff --git a/AwsCryptographyPrimitives/Makefile b/AwsCryptographyPrimitives/Makefile index 57b7da9504..0dc0f3eff1 100644 --- a/AwsCryptographyPrimitives/Makefile +++ b/AwsCryptographyPrimitives/Makefile @@ -9,6 +9,23 @@ include ../SharedMakefileV2.mk PROJECT_SERVICES := \ AwsCryptographyPrimitives +MAIN_SERVICE_FOR_RUST := AwsCryptographyPrimitives + +RUST_OTHER_FILES := \ + runtimes/rust/src/aes_gcm.rs \ + runtimes/rust/src/aes_kdf_ctr.rs \ + runtimes/rust/src/concurrent_call.rs \ + runtimes/rust/src/dafny_libraries.rs \ + runtimes/rust/src/digest.rs \ + runtimes/rust/src/ecdh.rs \ + runtimes/rust/src/ecdsa.rs \ + runtimes/rust/src/hmac.rs \ + runtimes/rust/src/random.rs \ + runtimes/rust/src/rsa.rs \ + runtimes/rust/src/sets.rs \ + runtimes/rust/src/time.rs \ + runtimes/rust/src/uuid.rs + SERVICE_NAMESPACE_AwsCryptographyPrimitives=aws.cryptography.primitives MAX_RESOURCE_COUNT=10000000 diff --git a/AwsCryptographyPrimitives/Model/AwsCryptographyPrimitivesTypes.dfy b/AwsCryptographyPrimitives/Model/AwsCryptographyPrimitivesTypes.dfy index 485871afc5..7714244df6 100644 --- a/AwsCryptographyPrimitives/Model/AwsCryptographyPrimitivesTypes.dfy +++ b/AwsCryptographyPrimitives/Model/AwsCryptographyPrimitivesTypes.dfy @@ -690,7 +690,9 @@ module {:extern "software.amazon.cryptography.primitives.internaldafny.types" } | CollectionOfErrors(list: seq, nameonly message: string) // The Opaque error, used for native, extern, wrapped or unknown errors | Opaque(obj: object) - type OpaqueError = e: Error | e.Opaque? witness * + // A better Opaque, with a visible string representation. + | OpaqueWithText(obj: object, objMessage : string) + type OpaqueError = e: Error | e.Opaque? || e.OpaqueWithText? witness * // This dummy subset type is included to make sure Dafny // always generates a _ExternBase___default.java class. type DummySubsetType = x: int | IsDummySubsetType(x) witness 1 diff --git a/AwsCryptographyPrimitives/codebuild/release-python/validate.yml b/AwsCryptographyPrimitives/codebuild/release-python/validate.yml index 5b7b902db9..0f70c76e07 100644 --- a/AwsCryptographyPrimitives/codebuild/release-python/validate.yml +++ b/AwsCryptographyPrimitives/codebuild/release-python/validate.yml @@ -20,6 +20,9 @@ phases: - export PATH="$PWD/dafny:$PATH" # Switch back to the main directory - cd aws-cryptographic-material-providers-library + # Check out tests for release commit + - git fetch --tags + - git checkout $COMMIT_ID # Install test dependencies - pyenv install --skip-existing 3.11 - pyenv local 3.11 diff --git a/AwsCryptographyPrimitives/project.properties b/AwsCryptographyPrimitives/project.properties index f5e8cdf0b4..55d988fe1b 100644 --- a/AwsCryptographyPrimitives/project.properties +++ b/AwsCryptographyPrimitives/project.properties @@ -1,4 +1,4 @@ # This file stores the top level dafny version information. # All elements of the project need to agree on this version. -dafnyVersion=4.8.1 -dafnyRuntimeJavaVersion=4.8.1 +dafnyVersion=4.9.0 +dafnyRuntimeJavaVersion=4.9.0 diff --git a/AwsCryptographyPrimitives/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/primitives/ToDafny.java b/AwsCryptographyPrimitives/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/primitives/ToDafny.java index 3ba9bace3e..06ef1d008e 100644 --- a/AwsCryptographyPrimitives/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/primitives/ToDafny.java +++ b/AwsCryptographyPrimitives/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/primitives/ToDafny.java @@ -67,6 +67,7 @@ import software.amazon.cryptography.primitives.model.AwsCryptographicPrimitivesError; import software.amazon.cryptography.primitives.model.CollectionOfErrors; import software.amazon.cryptography.primitives.model.OpaqueError; +import software.amazon.cryptography.primitives.model.OpaqueWithTextError; public class ToDafny { @@ -77,6 +78,9 @@ public static Error Error(RuntimeException nativeValue) { if (nativeValue instanceof OpaqueError) { return ToDafny.Error((OpaqueError) nativeValue); } + if (nativeValue instanceof OpaqueWithTextError) { + return ToDafny.Error((OpaqueWithTextError) nativeValue); + } if (nativeValue instanceof CollectionOfErrors) { return ToDafny.Error((CollectionOfErrors) nativeValue); } @@ -87,6 +91,13 @@ public static Error Error(OpaqueError nativeValue) { return Error.create_Opaque(nativeValue.obj()); } + public static Error Error(OpaqueWithTextError nativeValue) { + return Error.create_OpaqueWithText( + nativeValue.obj(), + dafny.DafnySequence.asString(nativeValue.objMessage()) + ); + } + public static Error Error(CollectionOfErrors nativeValue) { DafnySequence list = software.amazon.smithy.dafny.conversion.ToDafny.Aggregate.GenericToSequence( diff --git a/AwsCryptographyPrimitives/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/primitives/ToNative.java b/AwsCryptographyPrimitives/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/primitives/ToNative.java index 94bd292dfc..f2bec62913 100644 --- a/AwsCryptographyPrimitives/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/primitives/ToNative.java +++ b/AwsCryptographyPrimitives/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/primitives/ToNative.java @@ -15,6 +15,7 @@ import software.amazon.cryptography.primitives.internaldafny.types.Error_AwsCryptographicPrimitivesError; import software.amazon.cryptography.primitives.internaldafny.types.Error_CollectionOfErrors; import software.amazon.cryptography.primitives.internaldafny.types.Error_Opaque; +import software.amazon.cryptography.primitives.internaldafny.types.Error_OpaqueWithText; import software.amazon.cryptography.primitives.internaldafny.types.IAwsCryptographicPrimitivesClient; import software.amazon.cryptography.primitives.model.AESDecryptInput; import software.amazon.cryptography.primitives.model.AESEncryptInput; @@ -56,6 +57,7 @@ import software.amazon.cryptography.primitives.model.HkdfInput; import software.amazon.cryptography.primitives.model.KdfCtrInput; import software.amazon.cryptography.primitives.model.OpaqueError; +import software.amazon.cryptography.primitives.model.OpaqueWithTextError; import software.amazon.cryptography.primitives.model.ParsePublicKeyInput; import software.amazon.cryptography.primitives.model.ParsePublicKeyOutput; import software.amazon.cryptography.primitives.model.RSADecryptInput; @@ -74,6 +76,17 @@ public static OpaqueError Error(Error_Opaque dafnyValue) { return nativeBuilder.build(); } + public static OpaqueWithTextError Error(Error_OpaqueWithText dafnyValue) { + OpaqueWithTextError.Builder nativeBuilder = OpaqueWithTextError.builder(); + nativeBuilder.obj(dafnyValue.dtor_obj()); + nativeBuilder.objMessage( + software.amazon.smithy.dafny.conversion.ToNative.Simple.String( + dafnyValue.dtor_objMessage() + ) + ); + return nativeBuilder.build(); + } + public static CollectionOfErrors Error(Error_CollectionOfErrors dafnyValue) { CollectionOfErrors.Builder nativeBuilder = CollectionOfErrors.builder(); nativeBuilder.list( @@ -110,6 +123,9 @@ public static RuntimeException Error(Error dafnyValue) { if (dafnyValue.is_Opaque()) { return ToNative.Error((Error_Opaque) dafnyValue); } + if (dafnyValue.is_OpaqueWithText()) { + return ToNative.Error((Error_OpaqueWithText) dafnyValue); + } if (dafnyValue.is_CollectionOfErrors()) { return ToNative.Error((Error_CollectionOfErrors) dafnyValue); } diff --git a/AwsCryptographyPrimitives/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/primitives/model/OpaqueWithTextError.java b/AwsCryptographyPrimitives/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/primitives/model/OpaqueWithTextError.java new file mode 100644 index 0000000000..60d0de43fd --- /dev/null +++ b/AwsCryptographyPrimitives/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/primitives/model/OpaqueWithTextError.java @@ -0,0 +1,180 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// Do not modify this file. This file is machine generated, and any changes to it will be overwritten. +package software.amazon.cryptography.primitives.model; + +public class OpaqueWithTextError extends RuntimeException { + + /** + * The unexpected object encountered. It MIGHT BE an Exception, but that is not guaranteed. + */ + private final Object obj; + + /** + * The text equivalent of obj. + */ + private final String objMessage; + + protected OpaqueWithTextError(BuilderImpl builder) { + super(messageFromBuilder(builder), builder.cause()); + this.obj = builder.obj(); + this.objMessage = builder.objMessage(); + } + + private static String messageFromBuilder(Builder builder) { + if (builder.message() != null) { + return builder.message(); + } + if (builder.cause() != null) { + return builder.cause().getMessage(); + } + return null; + } + + /** + * See {@link Throwable#getMessage()}. + */ + public String message() { + return this.getMessage(); + } + + /** + * See {@link Throwable#getCause()}. + */ + public Throwable cause() { + return this.getCause(); + } + + /** + * @return The unexpected object encountered. It MIGHT BE an Exception, but that is not guaranteed. + */ + public Object obj() { + return this.obj; + } + + /** + * @return The text equivalent of obj. + */ + public String objMessage() { + return this.objMessage; + } + + public Builder toBuilder() { + return new BuilderImpl(this); + } + + public static Builder builder() { + return new BuilderImpl(); + } + + public interface Builder { + /** + * @param message The detailed message. The detail message is saved for later retrieval by the {@link #getMessage()} method. + */ + Builder message(String message); + + /** + * @return The detailed message. The detail message is saved for later retrieval by the {@link #getMessage()} method. + */ + String message(); + + /** + * @param cause The cause (which is saved for later retrieval by the {@link #getCause()} method). (A {@code null} value is permitted, and indicates that the cause is nonexistent or unknown.) + */ + Builder cause(Throwable cause); + + /** + * @return The cause (which is saved for later retrieval by the {@link #getCause()} method). (A {@code null} value is permitted, and indicates that the cause is nonexistent or unknown.) + */ + Throwable cause(); + + /** + * @param obj The unexpected object encountered. It MIGHT BE an Exception, but that is not guaranteed. + */ + Builder obj(Object obj); + + /** + * @return The unexpected object encountered. It MIGHT BE an Exception, but that is not guaranteed. + */ + Object obj(); + + /** + * @param objMessage The text equivalent of obj. + */ + Builder objMessage(String objMessage); + + /** + * @return The text equivalent of obj. + */ + String objMessage(); + + OpaqueWithTextError build(); + } + + static class BuilderImpl implements Builder { + + protected String message; + + protected Throwable cause; + + protected Object obj; + + protected String objMessage; + + protected BuilderImpl() {} + + protected BuilderImpl(OpaqueWithTextError model) { + this.cause = model.getCause(); + this.message = model.getMessage(); + this.obj = model.obj(); + this.objMessage = model.objMessage(); + } + + public Builder message(String message) { + this.message = message; + return this; + } + + public String message() { + return this.message; + } + + public Builder cause(Throwable cause) { + this.cause = cause; + return this; + } + + public Throwable cause() { + return this.cause; + } + + public Builder obj(Object obj) { + this.obj = obj; + return this; + } + + public Object obj() { + return this.obj; + } + + public Builder objMessage(String objMessage) { + this.objMessage = objMessage; + return this; + } + + public String objMessage() { + return this.objMessage; + } + + public OpaqueWithTextError build() { + if ( + this.obj != null && this.cause == null && this.obj instanceof Throwable + ) { + this.cause = (Throwable) this.obj; + } else if (this.obj == null && this.cause != null) { + this.obj = this.cause; + } + return new OpaqueWithTextError(this); + } + } +} diff --git a/AwsCryptographyPrimitives/runtimes/net/AssemblyInfo.cs b/AwsCryptographyPrimitives/runtimes/net/AssemblyInfo.cs index b36ccec998..2a1309d59f 100644 --- a/AwsCryptographyPrimitives/runtimes/net/AssemblyInfo.cs +++ b/AwsCryptographyPrimitives/runtimes/net/AssemblyInfo.cs @@ -3,4 +3,4 @@ [assembly: AssemblyTitle("AWS.Cryptography.Internal.AwsCryptographyPrimitives")] // This should be kept in sync with the version number in Crypto.csproj -[assembly: AssemblyVersion("1.7.3")] +[assembly: AssemblyVersion("1.7.4")] diff --git a/AwsCryptographyPrimitives/runtimes/net/Crypto.csproj b/AwsCryptographyPrimitives/runtimes/net/Crypto.csproj index 0e1adcabda..68d1893955 100644 --- a/AwsCryptographyPrimitives/runtimes/net/Crypto.csproj +++ b/AwsCryptographyPrimitives/runtimes/net/Crypto.csproj @@ -5,7 +5,7 @@ false true - 1.7.3 + 1.7.4 AWS.Cryptography.Internal.AwsCryptographyPrimitives AWS.Cryptography.Internal.AwsCryptographyPrimitives diff --git a/AwsCryptographyPrimitives/runtimes/net/Generated/OpaqueWithTextError.cs b/AwsCryptographyPrimitives/runtimes/net/Generated/OpaqueWithTextError.cs new file mode 100644 index 0000000000..8451beb571 --- /dev/null +++ b/AwsCryptographyPrimitives/runtimes/net/Generated/OpaqueWithTextError.cs @@ -0,0 +1,17 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// Do not modify this file. This file is machine generated, and any changes to it will be overwritten. +using System; +using AWS.Cryptography.Primitives; +namespace AWS.Cryptography.Primitives +{ + public class OpaqueWithTextError : Exception + { + public readonly object obj; + public readonly string objMessage; + public OpaqueWithTextError(Exception ex) : base("OpaqueError:", ex) { this.obj = ex; this.objMessage = obj.ToString(); } + public OpaqueWithTextError() : base("Unknown Unexpected Error") { } + public OpaqueWithTextError(object obj, string objMessage) : base(obj is Exception ? "OpaqueWithTextError:" : "Opaque obj is not an Exception.", obj as Exception) { this.obj = obj; this.objMessage = objMessage; } + } + +} diff --git a/AwsCryptographyPrimitives/runtimes/net/Generated/TypeConversion.cs b/AwsCryptographyPrimitives/runtimes/net/Generated/TypeConversion.cs index 93391f9049..83071c6b61 100644 --- a/AwsCryptographyPrimitives/runtimes/net/Generated/TypeConversion.cs +++ b/AwsCryptographyPrimitives/runtimes/net/Generated/TypeConversion.cs @@ -1608,6 +1608,8 @@ public static System.Exception FromDafny_CommonError(software.amazon.cryptograph new string(dafnyVal.dtor_message.Elements)); case software.amazon.cryptography.primitives.internaldafny.types.Error_Opaque dafnyVal: return new OpaqueError(dafnyVal._obj); + case software.amazon.cryptography.primitives.internaldafny.types.Error_OpaqueWithText dafnyVal: + return new OpaqueWithTextError(dafnyVal._obj, dafnyVal._obj.ToString()); default: // The switch MUST be complete for _IError, so `value` MUST NOT be an _IError. (How did you get here?) return new OpaqueError(); diff --git a/AwsCryptographyPrimitives/runtimes/python/pyproject.toml b/AwsCryptographyPrimitives/runtimes/python/pyproject.toml index d2bc3da0e6..581e26a8c6 100644 --- a/AwsCryptographyPrimitives/runtimes/python/pyproject.toml +++ b/AwsCryptographyPrimitives/runtimes/python/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "aws-cryptography-internal-primitives" -version = "1.7.3" +version = "1.7.4" description = "" authors = ["AWS Crypto Tools "] packages = [ diff --git a/AwsCryptographyPrimitives/runtimes/python/src/aws_cryptography_primitives/internaldafny/generated/dafny_src-py.dtr b/AwsCryptographyPrimitives/runtimes/python/src/aws_cryptography_primitives/internaldafny/generated/dafny_src-py.dtr index 14d0303faa..603c44587c 100644 --- a/AwsCryptographyPrimitives/runtimes/python/src/aws_cryptography_primitives/internaldafny/generated/dafny_src-py.dtr +++ b/AwsCryptographyPrimitives/runtimes/python/src/aws_cryptography_primitives/internaldafny/generated/dafny_src-py.dtr @@ -1,5 +1,5 @@ file_format_version = "1.0" -dafny_version = "4.8.1.0" +dafny_version = "4.8.0.0" [options_by_module.AwsCryptographyPrimitivesTypes] legacy-module-names = false python-module-name = "aws_cryptography_primitives.internaldafny.generated" diff --git a/AwsCryptographyPrimitives/runtimes/python/src/aws_cryptography_primitives/smithygenerated/aws_cryptography_primitives/deserialize.py b/AwsCryptographyPrimitives/runtimes/python/src/aws_cryptography_primitives/smithygenerated/aws_cryptography_primitives/deserialize.py index 2556ced3a4..743c02a04e 100644 --- a/AwsCryptographyPrimitives/runtimes/python/src/aws_cryptography_primitives/smithygenerated/aws_cryptography_primitives/deserialize.py +++ b/AwsCryptographyPrimitives/runtimes/python/src/aws_cryptography_primitives/smithygenerated/aws_cryptography_primitives/deserialize.py @@ -252,6 +252,8 @@ def _deserialize_parse_public_key(input: DafnyResponse, config: Config): def _deserialize_error(error: Error) -> ServiceError: if error.is_Opaque: return OpaqueError(obj=error.obj) + elif error.is_OpaqueWithText: + return OpaqueErrorWithText(obj=error.obj, obj_message=error.objMessage) elif error.is_CollectionOfErrors: return CollectionOfErrors( message=_dafny.string_of(error.message), diff --git a/AwsCryptographyPrimitives/runtimes/python/src/aws_cryptography_primitives/smithygenerated/aws_cryptography_primitives/errors.py b/AwsCryptographyPrimitives/runtimes/python/src/aws_cryptography_primitives/smithygenerated/aws_cryptography_primitives/errors.py index 59b8ea5608..b9a1d39ec2 100644 --- a/AwsCryptographyPrimitives/runtimes/python/src/aws_cryptography_primitives/smithygenerated/aws_cryptography_primitives/errors.py +++ b/AwsCryptographyPrimitives/runtimes/python/src/aws_cryptography_primitives/smithygenerated/aws_cryptography_primitives/errors.py @@ -188,6 +188,64 @@ def __eq__(self, other: Any) -> bool: return all(getattr(self, a) == getattr(other, a) for a in attributes) +class OpaqueWithTextError(ApiError[Literal["OpaqueWithTextError"]]): + code: Literal["OpaqueWithTextError"] = "OpaqueWithTextError" + obj: Any # As an OpaqueWithTextError, type of obj is unknown + obj_message: str # obj_message is a message representing the details of obj + + def __init__(self, *, obj, obj_message): + super().__init__("") + self.obj = obj + self.obj_message = obj_message + + def as_dict(self) -> Dict[str, Any]: + """Converts the OpaqueWithTextError to a dictionary. + + The dictionary uses the modeled shape names rather than the + parameter names as keys to be mostly compatible with boto3. + """ + return { + "message": self.message, + "code": self.code, + "obj": self.obj, + "obj_message": self.obj_message, + } + + @staticmethod + def from_dict(d: Dict[str, Any]) -> "OpaqueWithTextError": + """Creates a OpaqueWithTextError from a dictionary. + + The dictionary is expected to use the modeled shape names rather + than the parameter names as keys to be mostly compatible with + boto3. + """ + kwargs: Dict[str, Any] = { + "message": d["message"], + "obj": d["obj"], + "obj_message": d["obj_message"], + } + + return OpaqueWithTextError(**kwargs) + + def __repr__(self) -> str: + result = "OpaqueWithTextError(" + result += f"message={self.message}," + if self.message is not None: + result += f"message={repr(self.message)}" + result += f"obj={self.obj}" + result += f"obj_message={self.obj_message}" + result += ")" + return result + + def __eq__(self, other: Any) -> bool: + if not isinstance(other, OpaqueWithTextError): + return False + if not (self.obj == other.obj): + return False + attributes: list[str] = ["message", "message"] + return all(getattr(self, a) == getattr(other, a) for a in attributes) + + def _smithy_error_to_dafny_error(e: ServiceError): """Converts the provided native Smithy-modeled error into the corresponding Dafny error.""" @@ -212,6 +270,11 @@ def _smithy_error_to_dafny_error(e: ServiceError): obj=e.obj ) + if isinstance(e, OpaqueWithTextError): + return aws_cryptography_primitives.internaldafny.generated.AwsCryptographyPrimitivesTypes.Error_OpaqueWithText( + obj=e.obj, objMessage=e.obj_message + ) + else: return aws_cryptography_primitives.internaldafny.generated.AwsCryptographyPrimitivesTypes.Error_Opaque( obj=e diff --git a/AwsCryptographyPrimitives/runtimes/python/tox.ini b/AwsCryptographyPrimitives/runtimes/python/tox.ini index 929b2ed447..6b649d5eb7 100644 --- a/AwsCryptographyPrimitives/runtimes/python/tox.ini +++ b/AwsCryptographyPrimitives/runtimes/python/tox.ini @@ -1,7 +1,7 @@ [tox] isolated_build = True envlist = - py{311,312}-{dafnytests,functional} + py{311,312,313}-{dafnytests,functional} [testenv:base-command] commands = poetry run pytest -l {posargs} diff --git a/AwsCryptographyPrimitives/runtimes/rust/.gitignore b/AwsCryptographyPrimitives/runtimes/rust/.gitignore new file mode 100644 index 0000000000..fabab0a10f --- /dev/null +++ b/AwsCryptographyPrimitives/runtimes/rust/.gitignore @@ -0,0 +1,16 @@ +Cargo.lock +src/client.rs +src/client +src/conversions.rs +src/conversions +src/ddb.rs +src/deps.rs +src/error.rs +src/error +src/implementation_from_dafny.rs +src/operation.rs +src/operation +src/standard_library_conversions.rs +src/standard_library_externs.rs +src/types.rs +src/types diff --git a/AwsCryptographyPrimitives/runtimes/rust/Cargo.toml b/AwsCryptographyPrimitives/runtimes/rust/Cargo.toml new file mode 100644 index 0000000000..f554c5665b --- /dev/null +++ b/AwsCryptographyPrimitives/runtimes/rust/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "aws-mpl-primitives" +version = "0.1.0" +edition = "2021" +rust-version = "1.80.0" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +aws-config = "1.5.10" +aws-lc-rs = "1.10.0" +aws-lc-sys = "0.22.0" +aws-smithy-runtime-api = "1.7.3" +aws-smithy-types = "1.2.9" +chrono = "0.4.38" +dafny_runtime = { path = "../../../smithy-dafny/TestModels/dafny-dependencies/dafny_runtime_rust"} +dashmap = "6.1.0" +pem = "3.0.4" +tokio = {version = "1.41.1", features = ["full"] } +uuid = { version = "1.11.0", features = ["v4"] } diff --git a/AwsCryptographyPrimitives/runtimes/rust/copy_externs.sh b/AwsCryptographyPrimitives/runtimes/rust/copy_externs.sh new file mode 100755 index 0000000000..69e761affa --- /dev/null +++ b/AwsCryptographyPrimitives/runtimes/rust/copy_externs.sh @@ -0,0 +1,19 @@ +#!/bin/bash -eu + +cd $( dirname ${BASH_SOURCE[0]} ) + +SRC=../../../AwsCryptographicMaterialProviders/runtimes/rust/src/ + +cp $SRC/aes_gcm.rs src +cp $SRC/aes_kdf_ctr.rs src +cp $SRC/concurrent_call.rs src +cp $SRC/dafny_libraries.rs src +cp $SRC/digest.rs src +cp $SRC/ecdh.rs src +cp $SRC/ecdsa.rs src +cp $SRC/hmac.rs src +cp $SRC/random.rs src +cp $SRC/rsa.rs src +cp $SRC/sets.rs src +cp $SRC/time.rs src +cp $SRC/uuid.rs src diff --git a/AwsCryptographyPrimitives/runtimes/rust/src/lib.rs b/AwsCryptographyPrimitives/runtimes/rust/src/lib.rs new file mode 100644 index 0000000000..9d18ccf31d --- /dev/null +++ b/AwsCryptographyPrimitives/runtimes/rust/src/lib.rs @@ -0,0 +1,47 @@ +#![allow( + deprecated, + non_upper_case_globals, + unused, + non_snake_case, + non_camel_case_types +)] + +pub mod client; +pub mod conversions; +pub mod error; +pub mod operation; +pub mod types; + +pub(crate) mod standard_library_conversions; +pub(crate) mod standard_library_externs; +pub use client::Client; + +pub(crate) mod implementation_from_dafny; + +pub mod aes_gcm; +pub mod aes_kdf_ctr; +pub mod concurrent_call; +pub mod dafny_libraries; +pub mod digest; +pub mod ecdh; +pub mod ecdsa; +pub mod hmac; +pub mod random; +pub mod rsa; +pub mod sets; +pub mod time; +pub mod uuid; + +pub(crate) use crate::implementation_from_dafny::r#_Wrappers_Compile; +pub(crate) use crate::implementation_from_dafny::software; +pub(crate) use crate::implementation_from_dafny::AesKdfCtr; +pub(crate) use crate::implementation_from_dafny::ConcurrentCall; +pub(crate) use crate::implementation_from_dafny::DafnyLibraries; +pub(crate) use crate::implementation_from_dafny::ExternDigest; +pub(crate) use crate::implementation_from_dafny::ExternRandom; +pub(crate) use crate::implementation_from_dafny::Signature; +pub(crate) use crate::implementation_from_dafny::Time; +pub(crate) use crate::implementation_from_dafny::ECDH; +pub(crate) use crate::implementation_from_dafny::HMAC; +pub(crate) use crate::implementation_from_dafny::UTF8; +pub(crate) use crate::implementation_from_dafny::UUID; diff --git a/AwsCryptographyPrimitives/src/RSAEncryption.dfy b/AwsCryptographyPrimitives/src/RSAEncryption.dfy index e2d08684b6..c5b7f36060 100644 --- a/AwsCryptographyPrimitives/src/RSAEncryption.dfy +++ b/AwsCryptographyPrimitives/src/RSAEncryption.dfy @@ -3,7 +3,7 @@ include "../Model/AwsCryptographyPrimitivesTypes.dfy" -module RSAEncryption { +module {:extern "RSAEncryption"} RSAEncryption { import opened Wrappers import opened UInt = StandardLibrary.UInt import Types = AwsCryptographyPrimitivesTypes @@ -39,21 +39,21 @@ module RSAEncryption { output := EncryptExtern(input.padding, input.publicKey, input.plaintext); } - method {:extern "GenerateKeyPairExtern"} GenerateKeyPairExtern(lengthBits: Types.RSAModulusLengthBitsToGenerate) + method {:extern "RSAEncryption.RSA", "GenerateKeyPairExtern"} GenerateKeyPairExtern(lengthBits: Types.RSAModulusLengthBitsToGenerate) returns (publicKey: seq, privateKey: seq) ensures |publicKey| > 0 ensures |privateKey| > 0 - function method {:extern "GetRSAKeyModulusLengthExtern"} GetRSAKeyModulusLengthExtern(publicKey: seq) + function method {:extern "RSAEncryption.RSA", "GetRSAKeyModulusLengthExtern"} GetRSAKeyModulusLengthExtern(publicKey: seq) : (length: Result) - method {:extern "DecryptExtern"} DecryptExtern(padding: Types.RSAPaddingMode, privateKey: seq, + method {:extern "RSAEncryption.RSA", "DecryptExtern"} DecryptExtern(padding: Types.RSAPaddingMode, privateKey: seq, cipherText: seq) returns (res: Result, Types.Error>) requires |privateKey| > 0 requires |cipherText| > 0 - method {:extern "EncryptExtern"} EncryptExtern(padding: Types.RSAPaddingMode, publicKey: seq, + method {:extern "RSAEncryption.RSA", "EncryptExtern"} EncryptExtern(padding: Types.RSAPaddingMode, publicKey: seq, plaintextData: seq) returns (res: Result, Types.Error>) requires |publicKey| > 0 diff --git a/CHANGELOG.md b/CHANGELOG.md index 1edd6d31fc..599ce2c791 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +# [1.7.4](https://github.com/aws/aws-cryptographic-material-providers-library/compare/v1.7.3...v1.7.4) (2024-11-06) + +This release is available in the following languages: + +- Python + +### Bug Fixes + +- **Python:** Support Python 3.13 ([#953](https://github.com/aws/aws-cryptographic-material-providers-library/issues/953)) ([000baed](https://github.com/aws/aws-cryptographic-material-providers-library/commit/000baedfab341670952449837541c88ea5cf1dba)) + ## [1.7.3](https://github.com/aws/aws-cryptographic-material-providers-library/compare/v1.7.2...v1.7.3) (2024-10-31) This release is available in the following languages: diff --git a/ComAmazonawsDynamodb/Makefile b/ComAmazonawsDynamodb/Makefile index 4ce44741f4..39c6770806 100644 --- a/ComAmazonawsDynamodb/Makefile +++ b/ComAmazonawsDynamodb/Makefile @@ -10,6 +10,16 @@ include ../SharedMakefileV2.mk PROJECT_SERVICES := \ ComAmazonawsDynamodb \ +MAIN_SERVICE_FOR_RUST := ComAmazonawsDynamodb + +RUST_OTHER_FILES := \ + runtimes/rust/src/concurrent_call.rs \ + runtimes/rust/src/dafny_libraries.rs \ + runtimes/rust/src/ddb.rs \ + runtimes/rust/src/sets.rs \ + runtimes/rust/src/time.rs \ + runtimes/rust/src/uuid.rs + SERVICE_NAMESPACE_ComAmazonawsDynamodb=com.amazonaws.dynamodb MAX_RESOURCE_COUNT=10000000 AWS_SDK_CMD := --aws-sdk diff --git a/ComAmazonawsDynamodb/Model/ComAmazonawsDynamodbTypes.dfy b/ComAmazonawsDynamodb/Model/ComAmazonawsDynamodbTypes.dfy index 8c808cfd6d..8dd9372b23 100644 --- a/ComAmazonawsDynamodb/Model/ComAmazonawsDynamodbTypes.dfy +++ b/ComAmazonawsDynamodb/Model/ComAmazonawsDynamodbTypes.dfy @@ -2904,7 +2904,9 @@ module {:extern "software.amazon.cryptography.services.dynamodb.internaldafny.ty // The Opaque error, used for native, extern, wrapped or unknown errors | Opaque(obj: object) - type OpaqueError = e: Error | e.Opaque? witness * + // A better Opaque, with a visible string representation. + | OpaqueWithText(obj: object, objMessage : string) + type OpaqueError = e: Error | e.Opaque? || e.OpaqueWithText? witness * // This dummy subset type is included to make sure Dafny // always generates a _ExternBase___default.java class. type DummySubsetType = x: int | IsDummySubsetType(x) witness 1 diff --git a/ComAmazonawsDynamodb/Model/dynamodb/model.json b/ComAmazonawsDynamodb/Model/dynamodb/model.json index d550ce8a60..4957a48d76 100644 --- a/ComAmazonawsDynamodb/Model/dynamodb/model.json +++ b/ComAmazonawsDynamodb/Model/dynamodb/model.json @@ -798,7 +798,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#BatchExecuteStatementOutput": { @@ -818,7 +817,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#BatchGetItem": { @@ -928,8 +926,7 @@ } }, "traits": { - "smithy.api#documentation": "

Represents the input of a BatchGetItem operation.

", - "smithy.api#input": {} + "smithy.api#documentation": "

Represents the input of a BatchGetItem operation.

" } }, "com.amazonaws.dynamodb#BatchGetItemOutput": { @@ -955,8 +952,7 @@ } }, "traits": { - "smithy.api#documentation": "

Represents the output of a BatchGetItem operation.

", - "smithy.api#output": {} + "smithy.api#documentation": "

Represents the output of a BatchGetItem operation.

" } }, "com.amazonaws.dynamodb#BatchGetRequestMap": { @@ -1241,8 +1237,7 @@ } }, "traits": { - "smithy.api#documentation": "

Represents the input of a BatchWriteItem operation.

", - "smithy.api#input": {} + "smithy.api#documentation": "

Represents the input of a BatchWriteItem operation.

" } }, "com.amazonaws.dynamodb#BatchWriteItemOutput": { @@ -1268,8 +1263,7 @@ } }, "traits": { - "smithy.api#documentation": "

Represents the output of a BatchWriteItem operation.

", - "smithy.api#output": {} + "smithy.api#documentation": "

Represents the output of a BatchWriteItem operation.

" } }, "com.amazonaws.dynamodb#BatchWriteItemRequestMap": { @@ -1901,7 +1895,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#CreateBackupOutput": { @@ -1915,7 +1908,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#CreateGlobalSecondaryIndexAction": { @@ -2010,7 +2002,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#CreateGlobalTableOutput": { @@ -2024,7 +2015,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#CreateReplicaAction": { @@ -2208,8 +2198,7 @@ } }, "traits": { - "smithy.api#documentation": "

Represents the input of a CreateTable operation.

", - "smithy.api#input": {} + "smithy.api#documentation": "

Represents the input of a CreateTable operation.

" } }, "com.amazonaws.dynamodb#CreateTableOutput": { @@ -2223,8 +2212,7 @@ } }, "traits": { - "smithy.api#documentation": "

Represents the output of a CreateTable operation.

", - "smithy.api#output": {} + "smithy.api#documentation": "

Represents the output of a CreateTable operation.

" } }, "com.amazonaws.dynamodb#CsvDelimiter": { @@ -2372,7 +2360,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#DeleteBackupOutput": { @@ -2386,7 +2373,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#DeleteGlobalSecondaryIndexAction": { @@ -2532,8 +2518,7 @@ } }, "traits": { - "smithy.api#documentation": "

Represents the input of a DeleteItem operation.

", - "smithy.api#input": {} + "smithy.api#documentation": "

Represents the input of a DeleteItem operation.

" } }, "com.amazonaws.dynamodb#DeleteItemOutput": { @@ -2559,8 +2544,7 @@ } }, "traits": { - "smithy.api#documentation": "

Represents the output of a DeleteItem operation.

", - "smithy.api#output": {} + "smithy.api#documentation": "

Represents the output of a DeleteItem operation.

" } }, "com.amazonaws.dynamodb#DeleteReplicaAction": { @@ -2661,7 +2645,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#DeleteResourcePolicyOutput": { @@ -2675,7 +2658,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#DeleteTable": { @@ -2744,8 +2726,7 @@ } }, "traits": { - "smithy.api#documentation": "

Represents the input of a DeleteTable operation.

", - "smithy.api#input": {} + "smithy.api#documentation": "

Represents the input of a DeleteTable operation.

" } }, "com.amazonaws.dynamodb#DeleteTableOutput": { @@ -2759,8 +2740,7 @@ } }, "traits": { - "smithy.api#documentation": "

Represents the output of a DeleteTable operation.

", - "smithy.api#output": {} + "smithy.api#documentation": "

Represents the output of a DeleteTable operation.

" } }, "com.amazonaws.dynamodb#DeletionProtectionEnabled": { @@ -2804,7 +2784,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#DescribeBackupOutput": { @@ -2818,7 +2797,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#DescribeContinuousBackups": { @@ -2859,7 +2837,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#DescribeContinuousBackupsOutput": { @@ -2873,7 +2850,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#DescribeContributorInsights": { @@ -2914,7 +2890,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#DescribeContributorInsightsOutput": { @@ -2958,7 +2933,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#DescribeEndpoints": { @@ -2977,7 +2951,6 @@ "type": "structure", "members": {}, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#DescribeEndpointsResponse": { @@ -2992,7 +2965,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#DescribeExport": { @@ -3030,7 +3002,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#DescribeExportOutput": { @@ -3044,7 +3015,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#DescribeGlobalTable": { @@ -3085,7 +3055,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#DescribeGlobalTableOutput": { @@ -3099,7 +3068,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#DescribeGlobalTableSettings": { @@ -3140,7 +3108,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#DescribeGlobalTableSettingsOutput": { @@ -3160,7 +3127,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#DescribeImport": { @@ -3192,7 +3158,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#DescribeImportOutput": { @@ -3207,7 +3172,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#DescribeKinesisStreamingDestination": { @@ -3248,7 +3212,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#DescribeKinesisStreamingDestinationOutput": { @@ -3268,7 +3231,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#DescribeLimits": { @@ -3310,8 +3272,7 @@ "type": "structure", "members": {}, "traits": { - "smithy.api#documentation": "

Represents the input of a DescribeLimits operation. Has no\n content.

", - "smithy.api#input": {} + "smithy.api#documentation": "

Represents the input of a DescribeLimits operation. Has no\n content.

" } }, "com.amazonaws.dynamodb#DescribeLimitsOutput": { @@ -3343,8 +3304,7 @@ } }, "traits": { - "smithy.api#documentation": "

Represents the output of a DescribeLimits operation.

", - "smithy.api#output": {} + "smithy.api#documentation": "

Represents the output of a DescribeLimits operation.

" } }, "com.amazonaws.dynamodb#DescribeTable": { @@ -3419,8 +3379,7 @@ } }, "traits": { - "smithy.api#documentation": "

Represents the input of a DescribeTable operation.

", - "smithy.api#input": {} + "smithy.api#documentation": "

Represents the input of a DescribeTable operation.

" } }, "com.amazonaws.dynamodb#DescribeTableOutput": { @@ -3434,8 +3393,7 @@ } }, "traits": { - "smithy.api#documentation": "

Represents the output of a DescribeTable operation.

", - "smithy.api#output": {} + "smithy.api#documentation": "

Represents the output of a DescribeTable operation.

" } }, "com.amazonaws.dynamodb#DescribeTableReplicaAutoScaling": { @@ -3470,7 +3428,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#DescribeTableReplicaAutoScalingOutput": { @@ -3484,7 +3441,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#DescribeTimeToLive": { @@ -3525,7 +3481,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#DescribeTimeToLiveOutput": { @@ -3539,7 +3494,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#DestinationStatus": { @@ -5079,7 +5033,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#ExecuteStatementOutput": { @@ -5108,7 +5061,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#ExecuteTransaction": { @@ -5171,7 +5123,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#ExecuteTransactionOutput": { @@ -5191,7 +5142,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#ExpectedAttributeMap": { @@ -5595,7 +5545,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#ExportTableToPointInTimeOutput": { @@ -5609,7 +5558,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#ExportTime": { @@ -5853,8 +5801,7 @@ } }, "traits": { - "smithy.api#documentation": "

Represents the input of a GetItem operation.

", - "smithy.api#input": {} + "smithy.api#documentation": "

Represents the input of a GetItem operation.

" } }, "com.amazonaws.dynamodb#GetItemOutput": { @@ -5874,8 +5821,7 @@ } }, "traits": { - "smithy.api#documentation": "

Represents the output of a GetItem operation.

", - "smithy.api#output": {} + "smithy.api#documentation": "

Represents the output of a GetItem operation.

" } }, "com.amazonaws.dynamodb#GetResourcePolicy": { @@ -5919,7 +5865,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#GetResourcePolicyOutput": { @@ -5939,7 +5884,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#GlobalSecondaryIndex": { @@ -6674,7 +6618,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#ImportTableOutput": { @@ -6689,7 +6632,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#ImportedItemCount": { @@ -7432,7 +7374,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#ListBackupsOutput": { @@ -7452,7 +7393,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#ListContributorInsights": { @@ -7504,7 +7444,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#ListContributorInsightsLimit": { @@ -7533,7 +7472,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#ListExports": { @@ -7584,7 +7522,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#ListExportsMaxLimit": { @@ -7613,7 +7550,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#ListGlobalTables": { @@ -7662,7 +7598,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#ListGlobalTablesOutput": { @@ -7682,7 +7617,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#ListImports": { @@ -7730,7 +7664,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#ListImportsMaxLimit": { @@ -7759,7 +7692,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#ListTables": { @@ -7817,8 +7749,7 @@ } }, "traits": { - "smithy.api#documentation": "

Represents the input of a ListTables operation.

", - "smithy.api#input": {} + "smithy.api#documentation": "

Represents the input of a ListTables operation.

" } }, "com.amazonaws.dynamodb#ListTablesInputLimit": { @@ -7847,8 +7778,7 @@ } }, "traits": { - "smithy.api#documentation": "

Represents the output of a ListTables operation.

", - "smithy.api#output": {} + "smithy.api#documentation": "

Represents the output of a ListTables operation.

" } }, "com.amazonaws.dynamodb#ListTagsOfResource": { @@ -7895,7 +7825,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#ListTagsOfResourceOutput": { @@ -7915,7 +7844,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#LocalSecondaryIndex": { @@ -8640,8 +8568,7 @@ } }, "traits": { - "smithy.api#documentation": "

Represents the input of a PutItem operation.

", - "smithy.api#input": {} + "smithy.api#documentation": "

Represents the input of a PutItem operation.

" } }, "com.amazonaws.dynamodb#PutItemInputAttributeMap": { @@ -8676,8 +8603,7 @@ } }, "traits": { - "smithy.api#documentation": "

Represents the output of a PutItem operation.

", - "smithy.api#output": {} + "smithy.api#documentation": "

Represents the output of a PutItem operation.

" } }, "com.amazonaws.dynamodb#PutRequest": { @@ -8763,7 +8689,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#PutResourcePolicyOutput": { @@ -8777,7 +8702,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#Query": { @@ -8952,8 +8876,7 @@ } }, "traits": { - "smithy.api#documentation": "

Represents the input of a Query operation.

", - "smithy.api#input": {} + "smithy.api#documentation": "

Represents the input of a Query operation.

" } }, "com.amazonaws.dynamodb#QueryOutput": { @@ -8993,8 +8916,7 @@ } }, "traits": { - "smithy.api#documentation": "

Represents the output of a Query operation.

", - "smithy.api#output": {} + "smithy.api#documentation": "

Represents the output of a Query operation.

" } }, "com.amazonaws.dynamodb#RegionName": { @@ -9817,7 +9739,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#RestoreTableFromBackupOutput": { @@ -9831,7 +9752,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#RestoreTableToPointInTime": { @@ -9944,7 +9864,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#RestoreTableToPointInTimeOutput": { @@ -9958,7 +9877,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#ReturnConsumedCapacity": { @@ -10451,8 +10369,7 @@ } }, "traits": { - "smithy.api#documentation": "

Represents the input of a Scan operation.

", - "smithy.api#input": {} + "smithy.api#documentation": "

Represents the input of a Scan operation.

" } }, "com.amazonaws.dynamodb#ScanOutput": { @@ -10492,8 +10409,7 @@ } }, "traits": { - "smithy.api#documentation": "

Represents the output of a Scan operation.

", - "smithy.api#output": {} + "smithy.api#documentation": "

Represents the output of a Scan operation.

" } }, "com.amazonaws.dynamodb#ScanSegment": { @@ -11210,7 +11126,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#TagValueString": { @@ -11391,7 +11306,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#TransactGetItemsOutput": { @@ -11411,7 +11325,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#TransactWriteItem": { @@ -11527,7 +11440,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#TransactWriteItemsOutput": { @@ -11547,7 +11459,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#TransactionCanceledException": { @@ -11643,7 +11554,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#Update": { @@ -11747,7 +11657,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#UpdateContinuousBackupsOutput": { @@ -11761,7 +11670,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#UpdateContributorInsights": { @@ -11809,7 +11717,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#UpdateContributorInsightsOutput": { @@ -11835,7 +11742,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#UpdateExpression": { @@ -11922,7 +11828,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#UpdateGlobalTableOutput": { @@ -11936,7 +11841,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#UpdateGlobalTableSettings": { @@ -12019,7 +11923,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#UpdateGlobalTableSettingsOutput": { @@ -12039,7 +11942,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#UpdateItem": { @@ -12206,8 +12108,7 @@ } }, "traits": { - "smithy.api#documentation": "

Represents the input of an UpdateItem operation.

", - "smithy.api#input": {} + "smithy.api#documentation": "

Represents the input of an UpdateItem operation.

" } }, "com.amazonaws.dynamodb#UpdateItemOutput": { @@ -12233,8 +12134,7 @@ } }, "traits": { - "smithy.api#documentation": "

Represents the output of an UpdateItem operation.

", - "smithy.api#output": {} + "smithy.api#documentation": "

Represents the output of an UpdateItem operation.

" } }, "com.amazonaws.dynamodb#UpdateKinesisStreamingConfiguration": { @@ -12308,7 +12208,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#UpdateKinesisStreamingDestinationOutput": { @@ -12340,7 +12239,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#UpdateReplicationGroupMemberAction": { @@ -12492,8 +12390,7 @@ } }, "traits": { - "smithy.api#documentation": "

Represents the input of an UpdateTable operation.

", - "smithy.api#input": {} + "smithy.api#documentation": "

Represents the input of an UpdateTable operation.

" } }, "com.amazonaws.dynamodb#UpdateTableOutput": { @@ -12507,8 +12404,7 @@ } }, "traits": { - "smithy.api#documentation": "

Represents the output of an UpdateTable operation.

", - "smithy.api#output": {} + "smithy.api#documentation": "

Represents the output of an UpdateTable operation.

" } }, "com.amazonaws.dynamodb#UpdateTableReplicaAutoScaling": { @@ -12564,7 +12460,6 @@ } }, "traits": { - "smithy.api#input": {} } }, "com.amazonaws.dynamodb#UpdateTableReplicaAutoScalingOutput": { @@ -12578,7 +12473,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#UpdateTimeToLive": { @@ -12632,8 +12526,7 @@ } }, "traits": { - "smithy.api#documentation": "

Represents the input of an UpdateTimeToLive operation.

", - "smithy.api#input": {} + "smithy.api#documentation": "

Represents the input of an UpdateTimeToLive operation.

" } }, "com.amazonaws.dynamodb#UpdateTimeToLiveOutput": { @@ -12647,7 +12540,6 @@ } }, "traits": { - "smithy.api#output": {} } }, "com.amazonaws.dynamodb#WriteRequest": { diff --git a/ComAmazonawsDynamodb/codebuild/release-python/prod-release.yml b/ComAmazonawsDynamodb/codebuild/release-python/prod-release.yml index def04e70d9..d3691897c5 100644 --- a/ComAmazonawsDynamodb/codebuild/release-python/prod-release.yml +++ b/ComAmazonawsDynamodb/codebuild/release-python/prod-release.yml @@ -52,12 +52,12 @@ phases: batch: fast-fail: true build-graph: - - identifier: release_to_staging + - identifier: release_to_prod env: image: aws/codebuild/standard:7.0 - - identifier: validate_staging_release + - identifier: validate_prod_release depend-on: - - release_to_staging + - release_to_prod buildspec: ComAmazonawsDynamodb/codebuild/release-python/validate.yml env: variables: diff --git a/ComAmazonawsDynamodb/codebuild/release-python/validate.yml b/ComAmazonawsDynamodb/codebuild/release-python/validate.yml index 8605dff531..7982f6a2f8 100644 --- a/ComAmazonawsDynamodb/codebuild/release-python/validate.yml +++ b/ComAmazonawsDynamodb/codebuild/release-python/validate.yml @@ -20,6 +20,9 @@ phases: - export PATH="$PWD/dafny:$PATH" # Switch back to the main directory - cd aws-cryptographic-material-providers-library + # Check out tests for release commit + - git fetch --tags + - git checkout $COMMIT_ID # Install test dependencies - pyenv install --skip-existing 3.11 - pyenv local 3.11 diff --git a/ComAmazonawsDynamodb/codegen-patches/java/dafny-4.2.0.patch b/ComAmazonawsDynamodb/codegen-patches/java/dafny-4.2.0.patch deleted file mode 100644 index c601737aea..0000000000 --- a/ComAmazonawsDynamodb/codegen-patches/java/dafny-4.2.0.patch +++ /dev/null @@ -1,131 +0,0 @@ -diff --git b/ComAmazonawsDynamodb/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/services/dynamodb/internaldafny/ToNative.java a/ComAmazonawsDynamodb/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/services/dynamodb/internaldafny/ToNative.java -index c30e7cdf..3964b7cb 100644 ---- b/ComAmazonawsDynamodb/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/services/dynamodb/internaldafny/ToNative.java -+++ a/ComAmazonawsDynamodb/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/services/dynamodb/internaldafny/ToNative.java -@@ -8040,6 +8040,126 @@ public class ToNative { - return builder.build(); - } - -+ // BEGIN MANUAL EDIT -+ public static RuntimeException Error( -+ software.amazon.cryptography.services.dynamodb.internaldafny.types.Error dafnyValue -+ ) { -+ if (dafnyValue.is_BackupInUseException()) { -+ return ToNative.Error((Error_BackupInUseException) dafnyValue); -+ } -+ if (dafnyValue.is_BackupNotFoundException()) { -+ return ToNative.Error((Error_BackupNotFoundException) dafnyValue); -+ } -+ if (dafnyValue.is_ConditionalCheckFailedException()) { -+ return ToNative.Error((Error_ConditionalCheckFailedException) dafnyValue); -+ } -+ if (dafnyValue.is_ContinuousBackupsUnavailableException()) { -+ return ToNative.Error( -+ (Error_ContinuousBackupsUnavailableException) dafnyValue -+ ); -+ } -+ if (dafnyValue.is_DuplicateItemException()) { -+ return ToNative.Error((Error_DuplicateItemException) dafnyValue); -+ } -+ if (dafnyValue.is_ExportConflictException()) { -+ return ToNative.Error((Error_ExportConflictException) dafnyValue); -+ } -+ if (dafnyValue.is_ExportNotFoundException()) { -+ return ToNative.Error((Error_ExportNotFoundException) dafnyValue); -+ } -+ if (dafnyValue.is_GlobalTableAlreadyExistsException()) { -+ return ToNative.Error( -+ (Error_GlobalTableAlreadyExistsException) dafnyValue -+ ); -+ } -+ if (dafnyValue.is_GlobalTableNotFoundException()) { -+ return ToNative.Error((Error_GlobalTableNotFoundException) dafnyValue); -+ } -+ if (dafnyValue.is_IdempotentParameterMismatchException()) { -+ return ToNative.Error( -+ (Error_IdempotentParameterMismatchException) dafnyValue -+ ); -+ } -+ if (dafnyValue.is_ImportConflictException()) { -+ return ToNative.Error((Error_ImportConflictException) dafnyValue); -+ } -+ if (dafnyValue.is_ImportNotFoundException()) { -+ return ToNative.Error((Error_ImportNotFoundException) dafnyValue); -+ } -+ if (dafnyValue.is_IndexNotFoundException()) { -+ return ToNative.Error((Error_IndexNotFoundException) dafnyValue); -+ } -+ if (dafnyValue.is_InternalServerError()) { -+ return ToNative.Error((Error_InternalServerError) dafnyValue); -+ } -+ if (dafnyValue.is_InvalidExportTimeException()) { -+ return ToNative.Error((Error_InvalidExportTimeException) dafnyValue); -+ } -+ if (dafnyValue.is_InvalidRestoreTimeException()) { -+ return ToNative.Error((Error_InvalidRestoreTimeException) dafnyValue); -+ } -+ if (dafnyValue.is_ItemCollectionSizeLimitExceededException()) { -+ return ToNative.Error( -+ (Error_ItemCollectionSizeLimitExceededException) dafnyValue -+ ); -+ } -+ if (dafnyValue.is_LimitExceededException()) { -+ return ToNative.Error((Error_LimitExceededException) dafnyValue); -+ } -+ if (dafnyValue.is_PointInTimeRecoveryUnavailableException()) { -+ return ToNative.Error( -+ (Error_PointInTimeRecoveryUnavailableException) dafnyValue -+ ); -+ } -+ if (dafnyValue.is_ProvisionedThroughputExceededException()) { -+ return ToNative.Error( -+ (Error_ProvisionedThroughputExceededException) dafnyValue -+ ); -+ } -+ if (dafnyValue.is_ReplicaAlreadyExistsException()) { -+ return ToNative.Error((Error_ReplicaAlreadyExistsException) dafnyValue); -+ } -+ if (dafnyValue.is_ReplicaNotFoundException()) { -+ return ToNative.Error((Error_ReplicaNotFoundException) dafnyValue); -+ } -+ if (dafnyValue.is_RequestLimitExceeded()) { -+ return ToNative.Error((Error_RequestLimitExceeded) dafnyValue); -+ } -+ if (dafnyValue.is_ResourceInUseException()) { -+ return ToNative.Error((Error_ResourceInUseException) dafnyValue); -+ } -+ if (dafnyValue.is_ResourceNotFoundException()) { -+ return ToNative.Error((Error_ResourceNotFoundException) dafnyValue); -+ } -+ if (dafnyValue.is_TableAlreadyExistsException()) { -+ return ToNative.Error((Error_TableAlreadyExistsException) dafnyValue); -+ } -+ if (dafnyValue.is_TableInUseException()) { -+ return ToNative.Error((Error_TableInUseException) dafnyValue); -+ } -+ if (dafnyValue.is_TableNotFoundException()) { -+ return ToNative.Error((Error_TableNotFoundException) dafnyValue); -+ } -+ if (dafnyValue.is_TransactionCanceledException()) { -+ return ToNative.Error((Error_TransactionCanceledException) dafnyValue); -+ } -+ if (dafnyValue.is_TransactionConflictException()) { -+ return ToNative.Error((Error_TransactionConflictException) dafnyValue); -+ } -+ if (dafnyValue.is_TransactionInProgressException()) { -+ return ToNative.Error((Error_TransactionInProgressException) dafnyValue); -+ } -+ if (dafnyValue.is_Opaque()) { -+ return ToNative.Error((Error_Opaque) dafnyValue); -+ } -+ // TODO This should indicate a codegen bug -+ return new IllegalStateException( -+ String.format("Unknown error thrown while calling DDB. %s", dafnyValue) -+ ); -+ } -+ -+ // END MANUAL EDIT -+ - public static DynamoDbClient DynamoDB_20120810(IDynamoDBClient dafnyValue) { - return ((Shim) dafnyValue).impl(); - } diff --git a/ComAmazonawsDynamodb/codegen-patches/java/dafny-4.8.0.patch b/ComAmazonawsDynamodb/codegen-patches/java/dafny-4.8.0.patch new file mode 100644 index 0000000000..193233bc7f --- /dev/null +++ b/ComAmazonawsDynamodb/codegen-patches/java/dafny-4.8.0.patch @@ -0,0 +1,14 @@ +diff --git b/ComAmazonawsDynamodb/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/services/dynamodb/internaldafny/ToNative.java a/ComAmazonawsDynamodb/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/services/dynamodb/internaldafny/ToNative.java +index 5c6364b2..7feacebc 100644 +--- b/ComAmazonawsDynamodb/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/services/dynamodb/internaldafny/ToNative.java ++++ a/ComAmazonawsDynamodb/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/services/dynamodb/internaldafny/ToNative.java +@@ -8670,9 +8670,6 @@ public class ToNative { + if (dafnyValue.is_InternalServerError()) { + return ToNative.Error((Error_InternalServerError) dafnyValue); + } +- if (dafnyValue.is_InvalidEndpointException()) { +- return ToNative.Error((Error_InvalidEndpointException) dafnyValue); +- } + if (dafnyValue.is_InvalidExportTimeException()) { + return ToNative.Error((Error_InvalidExportTimeException) dafnyValue); + } diff --git a/ComAmazonawsDynamodb/project.properties b/ComAmazonawsDynamodb/project.properties index f5e8cdf0b4..55d988fe1b 100644 --- a/ComAmazonawsDynamodb/project.properties +++ b/ComAmazonawsDynamodb/project.properties @@ -1,4 +1,4 @@ # This file stores the top level dafny version information. # All elements of the project need to agree on this version. -dafnyVersion=4.8.1 -dafnyRuntimeJavaVersion=4.8.1 +dafnyVersion=4.9.0 +dafnyRuntimeJavaVersion=4.9.0 diff --git a/ComAmazonawsDynamodb/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/services/dynamodb/internaldafny/ToDafny.java b/ComAmazonawsDynamodb/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/services/dynamodb/internaldafny/ToDafny.java index f6e1352aa7..abc8e618c9 100644 --- a/ComAmazonawsDynamodb/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/services/dynamodb/internaldafny/ToDafny.java +++ b/ComAmazonawsDynamodb/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/services/dynamodb/internaldafny/ToDafny.java @@ -13425,7 +13425,10 @@ public static Error Error(DynamoDbException nativeValue) { // An un-modeled Service Error is different from a Java Heap Exhaustion error. // In the future, Smithy-Dafny MAY allow for this distinction. // Which would allow Dafny developers to treat the two differently. - return Error.create_Opaque(nativeValue); + return Error.create_OpaqueWithText( + nativeValue, + dafny.DafnySequence.asString(nativeValue.getMessage()) + ); } public static Error Error(Exception nativeValue) { @@ -13434,7 +13437,10 @@ public static Error Error(Exception nativeValue) { // An un-modeled Service Error is different from a Java Heap Exhaustion error. // In the future, Smithy-Dafny MAY allow for this distinction. // Which would allow Dafny developers to treat the two differently. - return Error.create_Opaque(nativeValue); + return Error.create_OpaqueWithText( + nativeValue, + dafny.DafnySequence.asString(nativeValue.getMessage()) + ); } public static IDynamoDBClient DynamoDB_20120810(DynamoDbClient nativeValue) { diff --git a/ComAmazonawsDynamodb/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/services/dynamodb/internaldafny/ToNative.java b/ComAmazonawsDynamodb/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/services/dynamodb/internaldafny/ToNative.java index 89b16d3aa8..2e0d19e7bf 100644 --- a/ComAmazonawsDynamodb/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/services/dynamodb/internaldafny/ToNative.java +++ b/ComAmazonawsDynamodb/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/services/dynamodb/internaldafny/ToNative.java @@ -8,10 +8,10 @@ import java.lang.Byte; import java.lang.Character; import java.lang.Double; -import java.lang.Exception; import java.lang.IllegalStateException; import java.lang.RuntimeException; import java.lang.String; +import java.lang.Throwable; import java.util.List; import java.util.Map; import software.amazon.awssdk.core.SdkBytes; @@ -354,6 +354,7 @@ import software.amazon.cryptography.services.dynamodb.internaldafny.types.DisableKinesisStreamingDestinationOutput; import software.amazon.cryptography.services.dynamodb.internaldafny.types.EnableKinesisStreamingDestinationInput; import software.amazon.cryptography.services.dynamodb.internaldafny.types.EnableKinesisStreamingDestinationOutput; +import software.amazon.cryptography.services.dynamodb.internaldafny.types.Error; import software.amazon.cryptography.services.dynamodb.internaldafny.types.Error_BackupInUseException; import software.amazon.cryptography.services.dynamodb.internaldafny.types.Error_BackupNotFoundException; import software.amazon.cryptography.services.dynamodb.internaldafny.types.Error_ConditionalCheckFailedException; @@ -368,11 +369,13 @@ import software.amazon.cryptography.services.dynamodb.internaldafny.types.Error_ImportNotFoundException; import software.amazon.cryptography.services.dynamodb.internaldafny.types.Error_IndexNotFoundException; import software.amazon.cryptography.services.dynamodb.internaldafny.types.Error_InternalServerError; +import software.amazon.cryptography.services.dynamodb.internaldafny.types.Error_InvalidEndpointException; import software.amazon.cryptography.services.dynamodb.internaldafny.types.Error_InvalidExportTimeException; import software.amazon.cryptography.services.dynamodb.internaldafny.types.Error_InvalidRestoreTimeException; import software.amazon.cryptography.services.dynamodb.internaldafny.types.Error_ItemCollectionSizeLimitExceededException; import software.amazon.cryptography.services.dynamodb.internaldafny.types.Error_LimitExceededException; import software.amazon.cryptography.services.dynamodb.internaldafny.types.Error_Opaque; +import software.amazon.cryptography.services.dynamodb.internaldafny.types.Error_OpaqueWithText; import software.amazon.cryptography.services.dynamodb.internaldafny.types.Error_PointInTimeRecoveryUnavailableException; import software.amazon.cryptography.services.dynamodb.internaldafny.types.Error_PolicyNotFoundException; import software.amazon.cryptography.services.dynamodb.internaldafny.types.Error_ProvisionedThroughputExceededException; @@ -8596,10 +8599,63 @@ public static TransactionInProgressException Error( return builder.build(); } - // BEGIN MANUAL EDIT - public static RuntimeException Error( - software.amazon.cryptography.services.dynamodb.internaldafny.types.Error dafnyValue - ) { + public static DynamoDbClient DynamoDB_20120810(IDynamoDBClient dafnyValue) { + return ((Shim) dafnyValue).impl(); + } + + public static RuntimeException Error(Error_Opaque dafnyValue) { + // While the first two cases are logically identical, + // there is a semantic distinction. + // An un-modeled Service Error is different from a Java Heap Exhaustion error. + // In the future, Smithy-Dafny MAY allow for this distinction. + // Which would allow Dafny developers to treat the two differently. + if (dafnyValue.dtor_obj() instanceof DynamoDbException) { + return (DynamoDbException) dafnyValue.dtor_obj(); + } else if (dafnyValue.dtor_obj() instanceof RuntimeException) { + return (RuntimeException) dafnyValue.dtor_obj(); + } else if (dafnyValue.dtor_obj() instanceof Throwable) { + return new RuntimeException( + String.format( + "Unknown error thrown while calling Amazon DynamoDB. %s", + (Throwable) dafnyValue.dtor_obj() + ) + ); + } + return new IllegalStateException( + String.format( + "Unknown error thrown while calling Amazon DynamoDB. %s", + dafnyValue + ) + ); + } + + public static RuntimeException Error(Error_OpaqueWithText dafnyValue) { + // While the first two cases are logically identical, + // there is a semantic distinction. + // An un-modeled Service Error is different from a Java Heap Exhaustion error. + // In the future, Smithy-Dafny MAY allow for this distinction. + // Which would allow Dafny developers to treat the two differently. + if (dafnyValue.dtor_obj() instanceof DynamoDbException) { + return (DynamoDbException) dafnyValue.dtor_obj(); + } else if (dafnyValue.dtor_obj() instanceof RuntimeException) { + return (RuntimeException) dafnyValue.dtor_obj(); + } else if (dafnyValue.dtor_obj() instanceof Throwable) { + return new RuntimeException( + String.format( + "Unknown error thrown while calling Amazon DynamoDB. %s", + (Throwable) dafnyValue.dtor_obj() + ) + ); + } + return new IllegalStateException( + String.format( + "Unknown error thrown while calling Amazon DynamoDB. %s", + dafnyValue + ) + ); + } + + public static RuntimeException Error(Error dafnyValue) { if (dafnyValue.is_BackupInUseException()) { return ToNative.Error((Error_BackupInUseException) dafnyValue); } @@ -8667,6 +8723,9 @@ public static RuntimeException Error( (Error_PointInTimeRecoveryUnavailableException) dafnyValue ); } + if (dafnyValue.is_PolicyNotFoundException()) { + return ToNative.Error((Error_PolicyNotFoundException) dafnyValue); + } if (dafnyValue.is_ProvisionedThroughputExceededException()) { return ToNative.Error( (Error_ProvisionedThroughputExceededException) dafnyValue @@ -8708,32 +8767,13 @@ public static RuntimeException Error( if (dafnyValue.is_Opaque()) { return ToNative.Error((Error_Opaque) dafnyValue); } - // TODO This should indicate a codegen bug - return new IllegalStateException( - String.format("Unknown error thrown while calling DDB. %s", dafnyValue) - ); - } - - // END MANUAL EDIT - - public static DynamoDbClient DynamoDB_20120810(IDynamoDBClient dafnyValue) { - return ((Shim) dafnyValue).impl(); - } - - public static RuntimeException Error(Error_Opaque dafnyValue) { - // While the first two cases are logically identical, - // there is a semantic distinction. - // An un-modeled Service Error is different from a Java Heap Exhaustion error. - // In the future, Smithy-Dafny MAY allow for this distinction. - // Which would allow Dafny developers to treat the two differently. - if (dafnyValue.dtor_obj() instanceof DynamoDbException) { - return (DynamoDbException) dafnyValue.dtor_obj(); - } else if (dafnyValue.dtor_obj() instanceof Exception) { - return (RuntimeException) dafnyValue.dtor_obj(); + if (dafnyValue.is_OpaqueWithText()) { + return ToNative.Error((Error_OpaqueWithText) dafnyValue); } + // TODO This should indicate a codegen bug; every error Should have been taken care of. return new IllegalStateException( String.format( - "Unknown error thrown while calling Amazon DynamoDB. %s", + "Unknown error thrown while calling service. %s", dafnyValue ) ); diff --git a/ComAmazonawsDynamodb/runtimes/net/AssemblyInfo.cs b/ComAmazonawsDynamodb/runtimes/net/AssemblyInfo.cs index 5ccbbb03c6..c2720d914f 100644 --- a/ComAmazonawsDynamodb/runtimes/net/AssemblyInfo.cs +++ b/ComAmazonawsDynamodb/runtimes/net/AssemblyInfo.cs @@ -3,4 +3,4 @@ [assembly: AssemblyTitle("AWS.Cryptography.Internal.ComAmazonawsDynamodb")] // This should be kept in sync with the version number in ComAmazonawsDynamodb.csproj -[assembly: AssemblyVersion("1.7.3")] +[assembly: AssemblyVersion("1.7.4")] diff --git a/ComAmazonawsDynamodb/runtimes/net/ComAmazonawsDynamodb.csproj b/ComAmazonawsDynamodb/runtimes/net/ComAmazonawsDynamodb.csproj index 5a29f690d0..232a51c4d5 100644 --- a/ComAmazonawsDynamodb/runtimes/net/ComAmazonawsDynamodb.csproj +++ b/ComAmazonawsDynamodb/runtimes/net/ComAmazonawsDynamodb.csproj @@ -4,9 +4,9 @@ Library false true - - 1.7.3 - + + 1.7.4 + AWS.Cryptography.Internal.ComAmazonawsDynamodb AWS.Cryptography.Internal.ComAmazonawsDynamodb ComAmazonawsDynmodb diff --git a/ComAmazonawsDynamodb/runtimes/net/Generated/TypeConversion.cs b/ComAmazonawsDynamodb/runtimes/net/Generated/TypeConversion.cs index 3ba9829a49..b133fcd495 100644 --- a/ComAmazonawsDynamodb/runtimes/net/Generated/TypeConversion.cs +++ b/ComAmazonawsDynamodb/runtimes/net/Generated/TypeConversion.cs @@ -13135,7 +13135,7 @@ public static System.Exception FromDafny_CommonError(software.amazon.cryptograph return FromDafny_N3_com__N9_amazonaws__N8_dynamodb__S28_TransactionConflictException(dafnyVal); case software.amazon.cryptography.services.dynamodb.internaldafny.types.Error_TransactionInProgressException dafnyVal: return FromDafny_N3_com__N9_amazonaws__N8_dynamodb__S30_TransactionInProgressException(dafnyVal); - case software.amazon.cryptography.services.dynamodb.internaldafny.types.Error_Opaque dafnyVal: + case software.amazon.cryptography.services.dynamodb.internaldafny.types.Error_OpaqueWithText dafnyVal: return new SystemException(dafnyVal._obj.ToString()); default: // The switch MUST be complete for _IError, so `value` MUST NOT be an _IError. (How did you get here?) @@ -13244,7 +13244,7 @@ public static software.amazon.cryptography.services.dynamodb.internaldafny.types return TypeConversion.ToDafny_N3_com__N9_amazonaws__N8_dynamodb__S30_TransactionInProgressException(e); default: - return new software.amazon.cryptography.services.dynamodb.internaldafny.types.Error_Opaque(value); + return new software.amazon.cryptography.services.dynamodb.internaldafny.types.Error_OpaqueWithText(value, Dafny.Sequence.FromString(value.ToString())); } } diff --git a/ComAmazonawsDynamodb/runtimes/python/pyproject.toml b/ComAmazonawsDynamodb/runtimes/python/pyproject.toml index 910034fe60..147bd0ff0a 100644 --- a/ComAmazonawsDynamodb/runtimes/python/pyproject.toml +++ b/ComAmazonawsDynamodb/runtimes/python/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "aws-cryptography-internal-dynamodb" -version = "1.7.3" +version = "1.7.4" description = "" authors = ["AWS Crypto Tools "] packages = [ diff --git a/ComAmazonawsDynamodb/runtimes/python/src/aws_cryptography_internal_dynamodb/internaldafny/generated/dafny_src-py.dtr b/ComAmazonawsDynamodb/runtimes/python/src/aws_cryptography_internal_dynamodb/internaldafny/generated/dafny_src-py.dtr index 5666725005..c512ff4c02 100644 --- a/ComAmazonawsDynamodb/runtimes/python/src/aws_cryptography_internal_dynamodb/internaldafny/generated/dafny_src-py.dtr +++ b/ComAmazonawsDynamodb/runtimes/python/src/aws_cryptography_internal_dynamodb/internaldafny/generated/dafny_src-py.dtr @@ -1,5 +1,5 @@ file_format_version = "1.0" -dafny_version = "4.8.1.0" +dafny_version = "4.8.0.0" [options_by_module.ComAmazonawsDynamodbTypes] legacy-module-names = false python-module-name = "aws_cryptography_internal_dynamodb.internaldafny.generated" diff --git a/ComAmazonawsDynamodb/runtimes/python/src/aws_cryptography_internal_dynamodb/smithygenerated/com_amazonaws_dynamodb/shim.py b/ComAmazonawsDynamodb/runtimes/python/src/aws_cryptography_internal_dynamodb/smithygenerated/com_amazonaws_dynamodb/shim.py index defd47c9f0..9f62a2697b 100644 --- a/ComAmazonawsDynamodb/runtimes/python/src/aws_cryptography_internal_dynamodb/smithygenerated/com_amazonaws_dynamodb/shim.py +++ b/ComAmazonawsDynamodb/runtimes/python/src/aws_cryptography_internal_dynamodb/smithygenerated/com_amazonaws_dynamodb/shim.py @@ -2,6 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 # Do not modify this file. This file is machine generated, and any changes to it will be overwritten. +import _dafny from aws_cryptography_internal_dynamodb.internaldafny.generated.ComAmazonawsDynamodbTypes import ( BatchExecuteStatementInput_BatchExecuteStatementInput as DafnyBatchExecuteStatementInput, BatchExecuteStatementOutput_BatchExecuteStatementOutput as DafnyBatchExecuteStatementOutput, @@ -296,8 +297,16 @@ def _sdk_error_to_dafny_error(e: ClientError): e.response ) - return aws_cryptography_internal_dynamodb.internaldafny.generated.ComAmazonawsDynamodbTypes.Error_Opaque( - obj=e + return aws_cryptography_internal_dynamodb.internaldafny.generated.ComAmazonawsDynamodbTypes.Error_OpaqueWithText( + obj=e, + objMessage=_dafny.Seq( + "".join( + [ + chr(int.from_bytes(pair, "big")) + for pair in zip(*[iter(repr(e).encode("utf-16-be"))] * 2) + ] + ) + ), ) diff --git a/ComAmazonawsDynamodb/runtimes/python/tox.ini b/ComAmazonawsDynamodb/runtimes/python/tox.ini index 5e6bbcb9db..09b5ee384f 100644 --- a/ComAmazonawsDynamodb/runtimes/python/tox.ini +++ b/ComAmazonawsDynamodb/runtimes/python/tox.ini @@ -1,7 +1,7 @@ [tox] isolated_build = True envlist = - py{311,312}-{dafnytests} + py{311,312,313}-{dafnytests} [testenv:base-command] commands = poetry run pytest -l {posargs} diff --git a/ComAmazonawsDynamodb/runtimes/rust/.gitignore b/ComAmazonawsDynamodb/runtimes/rust/.gitignore new file mode 100644 index 0000000000..f51a898e77 --- /dev/null +++ b/ComAmazonawsDynamodb/runtimes/rust/.gitignore @@ -0,0 +1,15 @@ +Cargo.lock +src/client.rs +src/concurrent_call.rs +src/conversions.rs +src/conversions +src/dafny_libraries.rs +src/deps.rs +src/implementation_from_dafny.rs +src/sets.rs +src/standard_library_conversions.rs +src/standard_library_externs.rs +src/time.rs +src/types.rs +src/types +src/uuid.rs diff --git a/ComAmazonawsDynamodb/runtimes/rust/Cargo.toml b/ComAmazonawsDynamodb/runtimes/rust/Cargo.toml new file mode 100644 index 0000000000..0531c245b0 --- /dev/null +++ b/ComAmazonawsDynamodb/runtimes/rust/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "aws-mpl-ddb" +version = "0.1.0" +edition = "2021" +rust-version = "1.80.0" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +aws-config = "1.5.10" +aws-sdk-dynamodb = "1.53.0" +aws-smithy-runtime-api = "1.7.3" +aws-smithy-types = "1.2.9" +chrono = "0.4.38" +dafny_runtime = { path = "../../../smithy-dafny/TestModels/dafny-dependencies/dafny_runtime_rust"} +dashmap = "6.1.0" +tokio = {version = "1.41.1", features = ["full"] } +uuid = { version = "1.11.0", features = ["v4"] } diff --git a/ComAmazonawsDynamodb/runtimes/rust/copy_externs.sh b/ComAmazonawsDynamodb/runtimes/rust/copy_externs.sh new file mode 100755 index 0000000000..d79a0acf28 --- /dev/null +++ b/ComAmazonawsDynamodb/runtimes/rust/copy_externs.sh @@ -0,0 +1,12 @@ +#!/bin/bash -eu + +cd $( dirname ${BASH_SOURCE[0]} ) + +SRC=../../../AwsCryptographicMaterialProviders/runtimes/rust/src/ + +cp $SRC/concurrent_call.rs src +cp $SRC/dafny_libraries.rs src +# ddb is different, because of ::deps:: +cp $SRC/sets.rs src +cp $SRC/time.rs src +cp $SRC/uuid.rs src diff --git a/ComAmazonawsDynamodb/runtimes/rust/src/ddb.rs b/ComAmazonawsDynamodb/runtimes/rust/src/ddb.rs new file mode 100644 index 0000000000..f2f942a0a8 --- /dev/null +++ b/ComAmazonawsDynamodb/runtimes/rust/src/ddb.rs @@ -0,0 +1,75 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +#![deny(warnings, unconditional_panic)] +#![deny(nonstandard_style)] +#![deny(clippy::all)] + +use aws_config::Region; +use std::sync::LazyLock; + +static DAFNY_TOKIO_RUNTIME: LazyLock = LazyLock::new(|| { + tokio::runtime::Builder::new_multi_thread() + .enable_all() + .build() + .unwrap() +}); + +#[allow(non_snake_case)] +impl crate::r#software::amazon::cryptography::services::dynamodb::internaldafny::_default { + pub fn DDBClientForRegion(region: &::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>) -> ::std::rc::Rc< + crate::r#_Wrappers_Compile::Result< + ::dafny_runtime::Object, + ::std::rc::Rc + > + >{ + let region = + dafny_runtime::dafny_runtime_conversions::unicode_chars_false::dafny_string_to_string( + region, + ); + let shared_config = match tokio::runtime::Handle::try_current() { + Ok(curr) => tokio::task::block_in_place(|| { + curr.block_on(async { + aws_config::load_defaults(aws_config::BehaviorVersion::v2024_03_28()).await + }) + }), + Err(_) => DAFNY_TOKIO_RUNTIME.block_on(aws_config::load_defaults( + aws_config::BehaviorVersion::v2024_03_28(), + )), + }; + let shared_config = shared_config + .to_builder() + .region(Region::new(region)) + .build(); + let inner = aws_sdk_dynamodb::Client::new(&shared_config); + let client = crate::client::Client { inner }; + let dafny_client = ::dafny_runtime::upcast_object()(::dafny_runtime::object::new(client)); + std::rc::Rc::new(crate::r#_Wrappers_Compile::Result::Success { + value: dafny_client, + }) + } + + pub fn DynamoDBClient() -> ::std::rc::Rc< + crate::r#_Wrappers_Compile::Result< + ::dafny_runtime::Object, + ::std::rc::Rc + > + >{ + let shared_config = match tokio::runtime::Handle::try_current() { + Ok(curr) => tokio::task::block_in_place(|| { + curr.block_on(async { + aws_config::load_defaults(aws_config::BehaviorVersion::v2024_03_28()).await + }) + }), + Err(_) => DAFNY_TOKIO_RUNTIME.block_on(aws_config::load_defaults( + aws_config::BehaviorVersion::v2024_03_28(), + )), + }; + let inner = aws_sdk_dynamodb::Client::new(&shared_config); + let client = crate::client::Client { inner }; + let dafny_client = ::dafny_runtime::upcast_object()(::dafny_runtime::object::new(client)); + std::rc::Rc::new(crate::r#_Wrappers_Compile::Result::Success { + value: dafny_client, + }) + } +} diff --git a/ComAmazonawsDynamodb/runtimes/rust/src/lib.rs b/ComAmazonawsDynamodb/runtimes/rust/src/lib.rs new file mode 100644 index 0000000000..f0642d3016 --- /dev/null +++ b/ComAmazonawsDynamodb/runtimes/rust/src/lib.rs @@ -0,0 +1,28 @@ +#![allow(deprecated, non_upper_case_globals, unused, non_snake_case, non_camel_case_types)] + + +pub mod client; +pub mod conversions; +pub mod types; + +pub(crate) mod standard_library_externs; +pub(crate) mod standard_library_conversions; +pub use client::Client; + +pub(crate) mod implementation_from_dafny; +pub(crate) use crate::implementation_from_dafny::r#_Wrappers_Compile; + +pub(crate) mod dafny_libraries; +pub(crate) mod ddb; +pub(crate) mod sets; +pub(crate) mod time; +pub(crate) mod uuid; +pub(crate) use crate::implementation_from_dafny::UTF8; +pub(crate) mod concurrent_call; +//pub(crate) mod dafny_libraries; + +pub(crate) use crate::implementation_from_dafny::DafnyLibraries; +pub(crate) use crate::implementation_from_dafny::ConcurrentCall; +pub(crate) use crate::implementation_from_dafny::Time; +pub(crate) use crate::implementation_from_dafny::UUID; +pub(crate) use crate::implementation_from_dafny::software; diff --git a/ComAmazonawsKms/Makefile b/ComAmazonawsKms/Makefile index 708d197bd6..67021e08df 100644 --- a/ComAmazonawsKms/Makefile +++ b/ComAmazonawsKms/Makefile @@ -9,6 +9,16 @@ include ../SharedMakefileV2.mk PROJECT_SERVICES := \ ComAmazonawsKms \ +MAIN_SERVICE_FOR_RUST := ComAmazonawsKms + +RUST_OTHER_FILES := \ + runtimes/rust/src/concurrent_call.rs \ + runtimes/rust/src/dafny_libraries.rs \ + runtimes/rust/src/kms.rs \ + runtimes/rust/src/sets.rs \ + runtimes/rust/src/time.rs \ + runtimes/rust/src/uuid.rs + SERVICE_NAMESPACE_ComAmazonawsKms=com.amazonaws.kms MAX_RESOURCE_COUNT=10000000 AWS_SDK_CMD := --aws-sdk diff --git a/ComAmazonawsKms/Model/ComAmazonawsKmsTypes.dfy b/ComAmazonawsKms/Model/ComAmazonawsKmsTypes.dfy index 54f8f6bdec..ff5520a289 100644 --- a/ComAmazonawsKms/Model/ComAmazonawsKmsTypes.dfy +++ b/ComAmazonawsKms/Model/ComAmazonawsKmsTypes.dfy @@ -1977,7 +1977,9 @@ module {:extern "software.amazon.cryptography.services.kms.internaldafny.types" // The Opaque error, used for native, extern, wrapped or unknown errors | Opaque(obj: object) - type OpaqueError = e: Error | e.Opaque? witness * + // A better Opaque, with a visible string representation. + | OpaqueWithText(obj: object, objMessage : string) + type OpaqueError = e: Error | e.Opaque? || e.OpaqueWithText? witness * // This dummy subset type is included to make sure Dafny // always generates a _ExternBase___default.java class. type DummySubsetType = x: int | IsDummySubsetType(x) witness 1 diff --git a/ComAmazonawsKms/codebuild/release-python/validate.yml b/ComAmazonawsKms/codebuild/release-python/validate.yml index 6650845536..eacc086638 100644 --- a/ComAmazonawsKms/codebuild/release-python/validate.yml +++ b/ComAmazonawsKms/codebuild/release-python/validate.yml @@ -20,6 +20,9 @@ phases: - export PATH="$PWD/dafny:$PATH" # Switch back to the main directory - cd aws-cryptographic-material-providers-library + # Check out tests for release commit + - git fetch --tags + - git checkout $COMMIT_ID # Install test dependencies - pyenv install --skip-existing 3.11 - pyenv local 3.11 diff --git a/ComAmazonawsKms/codegen-patches/java/dafny-4.8.0.patch b/ComAmazonawsKms/codegen-patches/java/dafny-4.8.0.patch index 1c2310cd74..90ef7642d3 100644 --- a/ComAmazonawsKms/codegen-patches/java/dafny-4.8.0.patch +++ b/ComAmazonawsKms/codegen-patches/java/dafny-4.8.0.patch @@ -4494,7 +4494,7 @@ index 5e894e4e..9d02d333 100644 return new Error_XksProxyVpcEndpointServiceInvalidConfigurationException( message ); -@@ -5641,14 +4617,11 @@ public class ToDafny { +@@ -5641,13 +4617,10 @@ public class ToDafny { message = Objects.nonNull(nativeValue.getMessage()) ? Option.create_Some( @@ -4509,227 +4509,3 @@ index 5e894e4e..9d02d333 100644 + : Option.create_None(); return new Error_XksProxyVpcEndpointServiceNotFoundException(message); } - -@@ -5676,7 +4649,9 @@ public class ToDafny { - { - return AlgorithmSpec.create_RSA__AES__KEY__WRAP__SHA__256(); - } -- case SM2PKE: -+ // BEGIN MANUAL EDIT -+ case SM2_PKE: -+ // END MANUAL EDIT - { - return AlgorithmSpec.create_SM2PKE(); - } -@@ -6483,7 +5458,9 @@ public class ToDafny { - { - return SigningAlgorithmSpec.create_ECDSA__SHA__512(); - } -- case SM2DSA: -+ // BEGIN MANUAL EDIT -+ case SM2_DSA: -+ // END MANUAL EDIT - { - return SigningAlgorithmSpec.create_SM2DSA(); - } -diff --git a/ComAmazonawsKms/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/services/kms/internaldafny/ToNative.java b/ComAmazonawsKms/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/services/kms/internaldafny/ToNative.java -index e8eddd3c..399865e7 100644 ---- a/ComAmazonawsKms/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/services/kms/internaldafny/ToNative.java -+++ b/ComAmazonawsKms/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/services/kms/internaldafny/ToNative.java -@@ -4542,6 +4542,196 @@ public class ToNative { - return builder.build(); - } - -+ // BEGIN MANUAL EDIT -+ public static RuntimeException Error( -+ software.amazon.cryptography.services.kms.internaldafny.types.Error dafnyValue -+ ) { -+ if (dafnyValue.is_AlreadyExistsException()) { -+ return ToNative.Error((Error_AlreadyExistsException) dafnyValue); -+ } -+ if (dafnyValue.is_CloudHsmClusterInUseException()) { -+ return ToNative.Error((Error_CloudHsmClusterInUseException) dafnyValue); -+ } -+ if (dafnyValue.is_CloudHsmClusterInvalidConfigurationException()) { -+ return ToNative.Error( -+ (Error_CloudHsmClusterInvalidConfigurationException) dafnyValue -+ ); -+ } -+ if (dafnyValue.is_CloudHsmClusterNotActiveException()) { -+ return ToNative.Error( -+ (Error_CloudHsmClusterNotActiveException) dafnyValue -+ ); -+ } -+ if (dafnyValue.is_CloudHsmClusterNotFoundException()) { -+ return ToNative.Error( -+ (Error_CloudHsmClusterNotFoundException) dafnyValue -+ ); -+ } -+ if (dafnyValue.is_CloudHsmClusterNotRelatedException()) { -+ return ToNative.Error( -+ (Error_CloudHsmClusterNotRelatedException) dafnyValue -+ ); -+ } -+ if (dafnyValue.is_ConflictException()) { -+ return ToNative.Error((Error_ConflictException) dafnyValue); -+ } -+ if (dafnyValue.is_CustomKeyStoreHasCMKsException()) { -+ return ToNative.Error((Error_CustomKeyStoreHasCMKsException) dafnyValue); -+ } -+ if (dafnyValue.is_CustomKeyStoreInvalidStateException()) { -+ return ToNative.Error( -+ (Error_CustomKeyStoreInvalidStateException) dafnyValue -+ ); -+ } -+ if (dafnyValue.is_CustomKeyStoreNameInUseException()) { -+ return ToNative.Error( -+ (Error_CustomKeyStoreNameInUseException) dafnyValue -+ ); -+ } -+ if (dafnyValue.is_CustomKeyStoreNotFoundException()) { -+ return ToNative.Error((Error_CustomKeyStoreNotFoundException) dafnyValue); -+ } -+ if (dafnyValue.is_DependencyTimeoutException()) { -+ return ToNative.Error((Error_DependencyTimeoutException) dafnyValue); -+ } -+ if (dafnyValue.is_DisabledException()) { -+ return ToNative.Error((Error_DisabledException) dafnyValue); -+ } -+ if (dafnyValue.is_DryRunOperationException()) { -+ return ToNative.Error((Error_DryRunOperationException) dafnyValue); -+ } -+ if (dafnyValue.is_ExpiredImportTokenException()) { -+ return ToNative.Error((Error_ExpiredImportTokenException) dafnyValue); -+ } -+ if (dafnyValue.is_IncorrectKeyException()) { -+ return ToNative.Error((Error_IncorrectKeyException) dafnyValue); -+ } -+ if (dafnyValue.is_IncorrectKeyMaterialException()) { -+ return ToNative.Error((Error_IncorrectKeyMaterialException) dafnyValue); -+ } -+ if (dafnyValue.is_IncorrectTrustAnchorException()) { -+ return ToNative.Error((Error_IncorrectTrustAnchorException) dafnyValue); -+ } -+ if (dafnyValue.is_InvalidAliasNameException()) { -+ return ToNative.Error((Error_InvalidAliasNameException) dafnyValue); -+ } -+ if (dafnyValue.is_InvalidArnException()) { -+ return ToNative.Error((Error_InvalidArnException) dafnyValue); -+ } -+ if (dafnyValue.is_InvalidCiphertextException()) { -+ return ToNative.Error((Error_InvalidCiphertextException) dafnyValue); -+ } -+ if (dafnyValue.is_InvalidGrantIdException()) { -+ return ToNative.Error((Error_InvalidGrantIdException) dafnyValue); -+ } -+ if (dafnyValue.is_InvalidGrantTokenException()) { -+ return ToNative.Error((Error_InvalidGrantTokenException) dafnyValue); -+ } -+ if (dafnyValue.is_InvalidImportTokenException()) { -+ return ToNative.Error((Error_InvalidImportTokenException) dafnyValue); -+ } -+ if (dafnyValue.is_InvalidKeyUsageException()) { -+ return ToNative.Error((Error_InvalidKeyUsageException) dafnyValue); -+ } -+ if (dafnyValue.is_InvalidMarkerException()) { -+ return ToNative.Error((Error_InvalidMarkerException) dafnyValue); -+ } -+ if (dafnyValue.is_KeyUnavailableException()) { -+ return ToNative.Error((Error_KeyUnavailableException) dafnyValue); -+ } -+ if (dafnyValue.is_KMSInternalException()) { -+ return ToNative.Error((Error_KMSInternalException) dafnyValue); -+ } -+ if (dafnyValue.is_KMSInvalidMacException()) { -+ return ToNative.Error((Error_KMSInvalidMacException) dafnyValue); -+ } -+ if (dafnyValue.is_KMSInvalidSignatureException()) { -+ return ToNative.Error((Error_KMSInvalidSignatureException) dafnyValue); -+ } -+ if (dafnyValue.is_KMSInvalidStateException()) { -+ return ToNative.Error((Error_KMSInvalidStateException) dafnyValue); -+ } -+ if (dafnyValue.is_LimitExceededException()) { -+ return ToNative.Error((Error_LimitExceededException) dafnyValue); -+ } -+ if (dafnyValue.is_MalformedPolicyDocumentException()) { -+ return ToNative.Error( -+ (Error_MalformedPolicyDocumentException) dafnyValue -+ ); -+ } -+ if (dafnyValue.is_NotFoundException()) { -+ return ToNative.Error((Error_NotFoundException) dafnyValue); -+ } -+ if (dafnyValue.is_TagException()) { -+ return ToNative.Error((Error_TagException) dafnyValue); -+ } -+ if (dafnyValue.is_UnsupportedOperationException()) { -+ return ToNative.Error((Error_UnsupportedOperationException) dafnyValue); -+ } -+ if (dafnyValue.is_XksKeyAlreadyInUseException()) { -+ return ToNative.Error((Error_XksKeyAlreadyInUseException) dafnyValue); -+ } -+ if (dafnyValue.is_XksKeyInvalidConfigurationException()) { -+ return ToNative.Error( -+ (Error_XksKeyInvalidConfigurationException) dafnyValue -+ ); -+ } -+ if (dafnyValue.is_XksKeyNotFoundException()) { -+ return ToNative.Error((Error_XksKeyNotFoundException) dafnyValue); -+ } -+ if (dafnyValue.is_XksProxyIncorrectAuthenticationCredentialException()) { -+ return ToNative.Error( -+ (Error_XksProxyIncorrectAuthenticationCredentialException) dafnyValue -+ ); -+ } -+ if (dafnyValue.is_XksProxyInvalidConfigurationException()) { -+ return ToNative.Error( -+ (Error_XksProxyInvalidConfigurationException) dafnyValue -+ ); -+ } -+ if (dafnyValue.is_XksProxyInvalidResponseException()) { -+ return ToNative.Error( -+ (Error_XksProxyInvalidResponseException) dafnyValue -+ ); -+ } -+ if (dafnyValue.is_XksProxyUriEndpointInUseException()) { -+ return ToNative.Error( -+ (Error_XksProxyUriEndpointInUseException) dafnyValue -+ ); -+ } -+ if (dafnyValue.is_XksProxyUriInUseException()) { -+ return ToNative.Error((Error_XksProxyUriInUseException) dafnyValue); -+ } -+ if (dafnyValue.is_XksProxyUriUnreachableException()) { -+ return ToNative.Error((Error_XksProxyUriUnreachableException) dafnyValue); -+ } -+ if (dafnyValue.is_XksProxyVpcEndpointServiceInUseException()) { -+ return ToNative.Error( -+ (Error_XksProxyVpcEndpointServiceInUseException) dafnyValue -+ ); -+ } -+ if ( -+ dafnyValue.is_XksProxyVpcEndpointServiceInvalidConfigurationException() -+ ) { -+ return ToNative.Error( -+ (Error_XksProxyVpcEndpointServiceInvalidConfigurationException) dafnyValue -+ ); -+ } -+ if (dafnyValue.is_XksProxyVpcEndpointServiceNotFoundException()) { -+ return ToNative.Error( -+ (Error_XksProxyVpcEndpointServiceNotFoundException) dafnyValue -+ ); -+ } -+ if (dafnyValue.is_Opaque()) { -+ return ToNative.Error((Error_Opaque) dafnyValue); -+ } -+ // TODO This should indicate a codegen bug; every error Should have been taken care of. -+ return new IllegalStateException( -+ String.format("Unknown error thrown while calling KMS. %s", dafnyValue) -+ ); -+ } -+ -+ // END MANUAL EDIT - public static KmsClient TrentService(IKMSClient dafnyValue) { - return ((Shim) dafnyValue).impl(); - } diff --git a/ComAmazonawsKms/project.properties b/ComAmazonawsKms/project.properties index f5e8cdf0b4..55d988fe1b 100644 --- a/ComAmazonawsKms/project.properties +++ b/ComAmazonawsKms/project.properties @@ -1,4 +1,4 @@ # This file stores the top level dafny version information. # All elements of the project need to agree on this version. -dafnyVersion=4.8.1 -dafnyRuntimeJavaVersion=4.8.1 +dafnyVersion=4.9.0 +dafnyRuntimeJavaVersion=4.9.0 diff --git a/ComAmazonawsKms/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/services/kms/internaldafny/ToDafny.java b/ComAmazonawsKms/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/services/kms/internaldafny/ToDafny.java index d8dc6c8f0a..3a7a97f73f 100644 --- a/ComAmazonawsKms/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/services/kms/internaldafny/ToDafny.java +++ b/ComAmazonawsKms/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/services/kms/internaldafny/ToDafny.java @@ -4645,9 +4645,7 @@ public static AlgorithmSpec AlgorithmSpec( { return AlgorithmSpec.create_RSA__AES__KEY__WRAP__SHA__256(); } - // BEGIN MANUAL EDIT case SM2_PKE: - // END MANUAL EDIT { return AlgorithmSpec.create_SM2PKE(); } @@ -5454,9 +5452,7 @@ public static SigningAlgorithmSpec SigningAlgorithmSpec( { return SigningAlgorithmSpec.create_ECDSA__SHA__512(); } - // BEGIN MANUAL EDIT case SM2_DSA: - // END MANUAL EDIT { return SigningAlgorithmSpec.create_SM2DSA(); } @@ -5731,7 +5727,10 @@ public static Error Error(KmsException nativeValue) { // An un-modeled Service Error is different from a Java Heap Exhaustion error. // In the future, Smithy-Dafny MAY allow for this distinction. // Which would allow Dafny developers to treat the two differently. - return Error.create_Opaque(nativeValue); + return Error.create_OpaqueWithText( + nativeValue, + dafny.DafnySequence.asString(nativeValue.getMessage()) + ); } public static Error Error(Exception nativeValue) { @@ -5740,7 +5739,10 @@ public static Error Error(Exception nativeValue) { // An un-modeled Service Error is different from a Java Heap Exhaustion error. // In the future, Smithy-Dafny MAY allow for this distinction. // Which would allow Dafny developers to treat the two differently. - return Error.create_Opaque(nativeValue); + return Error.create_OpaqueWithText( + nativeValue, + dafny.DafnySequence.asString(nativeValue.getMessage()) + ); } public static IKMSClient TrentService(KmsClient nativeValue) { diff --git a/ComAmazonawsKms/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/services/kms/internaldafny/ToNative.java b/ComAmazonawsKms/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/services/kms/internaldafny/ToNative.java index 399865e769..b4266fe789 100644 --- a/ComAmazonawsKms/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/services/kms/internaldafny/ToNative.java +++ b/ComAmazonawsKms/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/services/kms/internaldafny/ToNative.java @@ -6,10 +6,10 @@ import dafny.DafnyMap; import dafny.DafnySequence; import java.lang.Character; -import java.lang.Exception; import java.lang.IllegalStateException; import java.lang.RuntimeException; import java.lang.String; +import java.lang.Throwable; import java.util.List; import java.util.Map; import software.amazon.awssdk.core.SdkBytes; @@ -190,6 +190,7 @@ import software.amazon.awssdk.services.kms.model.XksProxyVpcEndpointServiceInUseException; import software.amazon.awssdk.services.kms.model.XksProxyVpcEndpointServiceInvalidConfigurationException; import software.amazon.awssdk.services.kms.model.XksProxyVpcEndpointServiceNotFoundException; +import software.amazon.cryptography.services.kms.internaldafny.types.Error; import software.amazon.cryptography.services.kms.internaldafny.types.Error_AlreadyExistsException; import software.amazon.cryptography.services.kms.internaldafny.types.Error_CloudHsmClusterInUseException; import software.amazon.cryptography.services.kms.internaldafny.types.Error_CloudHsmClusterInvalidConfigurationException; @@ -225,6 +226,7 @@ import software.amazon.cryptography.services.kms.internaldafny.types.Error_MalformedPolicyDocumentException; import software.amazon.cryptography.services.kms.internaldafny.types.Error_NotFoundException; import software.amazon.cryptography.services.kms.internaldafny.types.Error_Opaque; +import software.amazon.cryptography.services.kms.internaldafny.types.Error_OpaqueWithText; import software.amazon.cryptography.services.kms.internaldafny.types.Error_TagException; import software.amazon.cryptography.services.kms.internaldafny.types.Error_UnsupportedOperationException; import software.amazon.cryptography.services.kms.internaldafny.types.Error_XksKeyAlreadyInUseException; @@ -4542,10 +4544,63 @@ public static XksProxyVpcEndpointServiceNotFoundException Error( return builder.build(); } - // BEGIN MANUAL EDIT - public static RuntimeException Error( - software.amazon.cryptography.services.kms.internaldafny.types.Error dafnyValue - ) { + public static KmsClient TrentService(IKMSClient dafnyValue) { + return ((Shim) dafnyValue).impl(); + } + + public static RuntimeException Error(Error_Opaque dafnyValue) { + // While the first two cases are logically identical, + // there is a semantic distinction. + // An un-modeled Service Error is different from a Java Heap Exhaustion error. + // In the future, Smithy-Dafny MAY allow for this distinction. + // Which would allow Dafny developers to treat the two differently. + if (dafnyValue.dtor_obj() instanceof KmsException) { + return (KmsException) dafnyValue.dtor_obj(); + } else if (dafnyValue.dtor_obj() instanceof RuntimeException) { + return (RuntimeException) dafnyValue.dtor_obj(); + } else if (dafnyValue.dtor_obj() instanceof Throwable) { + return new RuntimeException( + String.format( + "Unknown error thrown while calling AWS Key Management Service. %s", + (Throwable) dafnyValue.dtor_obj() + ) + ); + } + return new IllegalStateException( + String.format( + "Unknown error thrown while calling AWS Key Management Service. %s", + dafnyValue + ) + ); + } + + public static RuntimeException Error(Error_OpaqueWithText dafnyValue) { + // While the first two cases are logically identical, + // there is a semantic distinction. + // An un-modeled Service Error is different from a Java Heap Exhaustion error. + // In the future, Smithy-Dafny MAY allow for this distinction. + // Which would allow Dafny developers to treat the two differently. + if (dafnyValue.dtor_obj() instanceof KmsException) { + return (KmsException) dafnyValue.dtor_obj(); + } else if (dafnyValue.dtor_obj() instanceof RuntimeException) { + return (RuntimeException) dafnyValue.dtor_obj(); + } else if (dafnyValue.dtor_obj() instanceof Throwable) { + return new RuntimeException( + String.format( + "Unknown error thrown while calling AWS Key Management Service. %s", + (Throwable) dafnyValue.dtor_obj() + ) + ); + } + return new IllegalStateException( + String.format( + "Unknown error thrown while calling AWS Key Management Service. %s", + dafnyValue + ) + ); + } + + public static RuntimeException Error(Error dafnyValue) { if (dafnyValue.is_AlreadyExistsException()) { return ToNative.Error((Error_AlreadyExistsException) dafnyValue); } @@ -4725,31 +4780,13 @@ public static RuntimeException Error( if (dafnyValue.is_Opaque()) { return ToNative.Error((Error_Opaque) dafnyValue); } - // TODO This should indicate a codegen bug; every error Should have been taken care of. - return new IllegalStateException( - String.format("Unknown error thrown while calling KMS. %s", dafnyValue) - ); - } - - // END MANUAL EDIT - public static KmsClient TrentService(IKMSClient dafnyValue) { - return ((Shim) dafnyValue).impl(); - } - - public static RuntimeException Error(Error_Opaque dafnyValue) { - // While the first two cases are logically identical, - // there is a semantic distinction. - // An un-modeled Service Error is different from a Java Heap Exhaustion error. - // In the future, Smithy-Dafny MAY allow for this distinction. - // Which would allow Dafny developers to treat the two differently. - if (dafnyValue.dtor_obj() instanceof KmsException) { - return (KmsException) dafnyValue.dtor_obj(); - } else if (dafnyValue.dtor_obj() instanceof Exception) { - return (RuntimeException) dafnyValue.dtor_obj(); + if (dafnyValue.is_OpaqueWithText()) { + return ToNative.Error((Error_OpaqueWithText) dafnyValue); } + // TODO This should indicate a codegen bug; every error Should have been taken care of. return new IllegalStateException( String.format( - "Unknown error thrown while calling AWS Key Management Service. %s", + "Unknown error thrown while calling service. %s", dafnyValue ) ); diff --git a/ComAmazonawsKms/runtimes/net/AWS-KMS.csproj b/ComAmazonawsKms/runtimes/net/AWS-KMS.csproj index 272427445f..04229ca62c 100644 --- a/ComAmazonawsKms/runtimes/net/AWS-KMS.csproj +++ b/ComAmazonawsKms/runtimes/net/AWS-KMS.csproj @@ -5,7 +5,7 @@ false true - 1.7.3 + 1.7.4 AWS.Cryptography.Internal.ComAmazonawsKms AWS.Cryptography.Internal.ComAmazonawsKms diff --git a/ComAmazonawsKms/runtimes/net/AssemblyInfo.cs b/ComAmazonawsKms/runtimes/net/AssemblyInfo.cs index 3c8fbda6bf..f4bdb1974e 100644 --- a/ComAmazonawsKms/runtimes/net/AssemblyInfo.cs +++ b/ComAmazonawsKms/runtimes/net/AssemblyInfo.cs @@ -3,4 +3,4 @@ [assembly: AssemblyTitle("AWS.Cryptography.Internal.ComAmazonawsKms")] // This should be kept in sync with the version number in AWS-KMS.csproj -[assembly: AssemblyVersion("1.7.3")] +[assembly: AssemblyVersion("1.7.4")] diff --git a/ComAmazonawsKms/runtimes/net/Generated/TypeConversion.cs b/ComAmazonawsKms/runtimes/net/Generated/TypeConversion.cs index 46aff0c762..0752a1dbbc 100644 --- a/ComAmazonawsKms/runtimes/net/Generated/TypeConversion.cs +++ b/ComAmazonawsKms/runtimes/net/Generated/TypeConversion.cs @@ -6681,7 +6681,7 @@ public static System.Exception FromDafny_CommonError(software.amazon.cryptograph return FromDafny_N3_com__N9_amazonaws__N3_kms__S55_XksProxyVpcEndpointServiceInvalidConfigurationException(dafnyVal); case software.amazon.cryptography.services.kms.internaldafny.types.Error_XksProxyVpcEndpointServiceNotFoundException dafnyVal: return FromDafny_N3_com__N9_amazonaws__N3_kms__S43_XksProxyVpcEndpointServiceNotFoundException(dafnyVal); - case software.amazon.cryptography.services.kms.internaldafny.types.Error_Opaque dafnyVal: + case software.amazon.cryptography.services.kms.internaldafny.types.Error_OpaqueWithText dafnyVal: return new SystemException(dafnyVal._obj.ToString()); default: // The switch MUST be complete for _IError, so `value` MUST NOT be an _IError. (How did you get here?) @@ -6837,7 +6837,7 @@ public static software.amazon.cryptography.services.kms.internaldafny.types._IEr return TypeConversion.ToDafny_N3_com__N9_amazonaws__N3_kms__S43_XksProxyVpcEndpointServiceNotFoundException(e); default: - return new software.amazon.cryptography.services.kms.internaldafny.types.Error_Opaque(value); + return new software.amazon.cryptography.services.kms.internaldafny.types.Error_OpaqueWithText(value, Dafny.Sequence.FromString(value.ToString())); } } diff --git a/ComAmazonawsKms/runtimes/python/pyproject.toml b/ComAmazonawsKms/runtimes/python/pyproject.toml index 40f0caae8d..9a64fe940b 100644 --- a/ComAmazonawsKms/runtimes/python/pyproject.toml +++ b/ComAmazonawsKms/runtimes/python/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "aws-cryptography-internal-kms" -version = "1.7.3" +version = "1.7.4" description = "" authors = ["AWS Crypto Tools "] packages = [ diff --git a/ComAmazonawsKms/runtimes/python/src/aws_cryptography_internal_kms/internaldafny/generated/dafny_src-py.dtr b/ComAmazonawsKms/runtimes/python/src/aws_cryptography_internal_kms/internaldafny/generated/dafny_src-py.dtr index ccf35f9a12..17f4d6fd5f 100644 --- a/ComAmazonawsKms/runtimes/python/src/aws_cryptography_internal_kms/internaldafny/generated/dafny_src-py.dtr +++ b/ComAmazonawsKms/runtimes/python/src/aws_cryptography_internal_kms/internaldafny/generated/dafny_src-py.dtr @@ -1,5 +1,5 @@ file_format_version = "1.0" -dafny_version = "4.8.1.0" +dafny_version = "4.8.0.0" [options_by_module.ComAmazonawsKmsTypes] legacy-module-names = false python-module-name = "aws_cryptography_internal_kms.internaldafny.generated" diff --git a/ComAmazonawsKms/runtimes/python/src/aws_cryptography_internal_kms/smithygenerated/com_amazonaws_kms/shim.py b/ComAmazonawsKms/runtimes/python/src/aws_cryptography_internal_kms/smithygenerated/com_amazonaws_kms/shim.py index 8bf832b482..79a83136c0 100644 --- a/ComAmazonawsKms/runtimes/python/src/aws_cryptography_internal_kms/smithygenerated/com_amazonaws_kms/shim.py +++ b/ComAmazonawsKms/runtimes/python/src/aws_cryptography_internal_kms/smithygenerated/com_amazonaws_kms/shim.py @@ -2,6 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 # Do not modify this file. This file is machine generated, and any changes to it will be overwritten. +import _dafny from aws_cryptography_internal_kms.internaldafny.generated.ComAmazonawsKmsTypes import ( CancelKeyDeletionRequest_CancelKeyDeletionRequest as DafnyCancelKeyDeletionRequest, CancelKeyDeletionResponse_CancelKeyDeletionResponse as DafnyCancelKeyDeletionResponse, @@ -354,8 +355,16 @@ def _sdk_error_to_dafny_error(e: ClientError): e.response ) - return aws_cryptography_internal_kms.internaldafny.generated.ComAmazonawsKmsTypes.Error_Opaque( - obj=e + return aws_cryptography_internal_kms.internaldafny.generated.ComAmazonawsKmsTypes.Error_OpaqueWithText( + obj=e, + objMessage=_dafny.Seq( + "".join( + [ + chr(int.from_bytes(pair, "big")) + for pair in zip(*[iter(repr(e).encode("utf-16-be"))] * 2) + ] + ) + ), ) diff --git a/ComAmazonawsKms/runtimes/python/tox.ini b/ComAmazonawsKms/runtimes/python/tox.ini index 5e6bbcb9db..09b5ee384f 100644 --- a/ComAmazonawsKms/runtimes/python/tox.ini +++ b/ComAmazonawsKms/runtimes/python/tox.ini @@ -1,7 +1,7 @@ [tox] isolated_build = True envlist = - py{311,312}-{dafnytests} + py{311,312,313}-{dafnytests} [testenv:base-command] commands = poetry run pytest -l {posargs} diff --git a/ComAmazonawsKms/runtimes/rust/.gitignore b/ComAmazonawsKms/runtimes/rust/.gitignore new file mode 100644 index 0000000000..89f58a7521 --- /dev/null +++ b/ComAmazonawsKms/runtimes/rust/.gitignore @@ -0,0 +1,10 @@ +Cargo.lock +src/client.rs +src/conversions.rs +src/conversions +src/deps.rs +src/implementation_from_dafny.rs +src/standard_library_conversions.rs +src/standard_library_externs.rs +src/types.rs +src/types diff --git a/ComAmazonawsKms/runtimes/rust/Cargo.toml b/ComAmazonawsKms/runtimes/rust/Cargo.toml new file mode 100644 index 0000000000..c6ee650346 --- /dev/null +++ b/ComAmazonawsKms/runtimes/rust/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "aws-mpl-kms" +version = "0.1.0" +edition = "2021" +rust-version = "1.80.0" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +aws-config = "1.5.10" +aws-sdk-kms = "1.50.0" +aws-smithy-runtime-api = "1.7.3" +aws-smithy-types = "1.2.9" +chrono = "0.4.38" +dafny_runtime = { path = "../../../smithy-dafny/TestModels/dafny-dependencies/dafny_runtime_rust"} +dashmap = "6.1.0" +tokio = {version = "1.41.1", features = ["full"] } +uuid = { version = "1.11.0", features = ["v4"] } diff --git a/ComAmazonawsKms/runtimes/rust/copy_externs.sh b/ComAmazonawsKms/runtimes/rust/copy_externs.sh new file mode 100755 index 0000000000..176465e88c --- /dev/null +++ b/ComAmazonawsKms/runtimes/rust/copy_externs.sh @@ -0,0 +1,12 @@ +#!/bin/bash -eu + +cd $( dirname ${BASH_SOURCE[0]} ) + +SRC=../../../AwsCryptographicMaterialProviders/runtimes/rust/src/ + +cp $SRC/concurrent_call.rs src +cp $SRC/dafny_libraries.rs src +# kms is different, because of ::deps:: +cp $SRC/sets.rs src +cp $SRC/time.rs src +cp $SRC/uuid.rs src diff --git a/ComAmazonawsKms/runtimes/rust/src/kms.rs b/ComAmazonawsKms/runtimes/rust/src/kms.rs new file mode 100644 index 0000000000..97abe65c46 --- /dev/null +++ b/ComAmazonawsKms/runtimes/rust/src/kms.rs @@ -0,0 +1,88 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +#![deny(warnings, unconditional_panic)] +#![deny(nonstandard_style)] +#![deny(clippy::all)] + +use aws_config::Region; +use std::sync::LazyLock; + +static DAFNY_TOKIO_RUNTIME: LazyLock = LazyLock::new(|| { + tokio::runtime::Builder::new_multi_thread() + .enable_all() + .build() + .unwrap() +}); + +impl crate::r#software::amazon::cryptography::services::kms::internaldafny::_default { + #[allow(non_snake_case)] + pub fn KMSClientForRegion(region: &::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>) -> ::std::rc::Rc, ::std::rc::Rc>>{ + let region = + dafny_runtime::dafny_runtime_conversions::unicode_chars_false::dafny_string_to_string( + region, + ); + + let shared_config = match tokio::runtime::Handle::try_current() { + Ok(curr) => tokio::task::block_in_place(|| { + curr.block_on(async { + aws_config::load_defaults(aws_config::BehaviorVersion::v2024_03_28()).await + }) + }), + Err(_) => DAFNY_TOKIO_RUNTIME.block_on(aws_config::load_defaults( + aws_config::BehaviorVersion::v2024_03_28(), + )), + }; + + let shared_config = shared_config + .to_builder() + .region(Region::new(region)) + .build(); + let inner = aws_sdk_kms::Client::new(&shared_config); + let client = crate::client::Client { inner }; + let dafny_client = ::dafny_runtime::upcast_object()(::dafny_runtime::object::new(client)); + std::rc::Rc::new(crate::r#_Wrappers_Compile::Result::Success { + value: dafny_client, + }) + } + + #[allow(non_snake_case)] + pub fn KMSClient() -> ::std::rc::Rc, ::std::rc::Rc>>{ + let shared_config = match tokio::runtime::Handle::try_current() { + Ok(curr) => tokio::task::block_in_place(|| { + curr.block_on(async { + aws_config::load_defaults(aws_config::BehaviorVersion::v2024_03_28()).await + }) + }), + Err(_) => DAFNY_TOKIO_RUNTIME.block_on(aws_config::load_defaults( + aws_config::BehaviorVersion::v2024_03_28(), + )), + }; + + let inner = aws_sdk_kms::Client::new(&shared_config); + let client = crate::client::Client { inner }; + let dafny_client = ::dafny_runtime::upcast_object()(::dafny_runtime::object::new(client)); + std::rc::Rc::new(crate::r#_Wrappers_Compile::Result::Success { + value: dafny_client, + }) + } + + #[allow(non_snake_case)] + pub fn RegionMatch( + kmsClient: &::dafny_runtime::Object, + region: &::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>, + ) -> ::std::rc::Rc> { + let region = + dafny_runtime::dafny_runtime_conversions::unicode_chars_false::dafny_string_to_string( + region, + ); + let any = dafny_runtime::cast_any_object!(kmsClient); + let client = + dafny_runtime::cast_object!(any, crate::client::Client); + let flag = match client.as_ref().inner.config().region() { + Some(r) => r.as_ref() == region, + None => false, + }; + ::std::rc::Rc::new(crate::r#_Wrappers_Compile::Option::Some { value: flag }) + } +} diff --git a/ComAmazonawsKms/runtimes/rust/src/lib.rs b/ComAmazonawsKms/runtimes/rust/src/lib.rs new file mode 100644 index 0000000000..8ecbe0a596 --- /dev/null +++ b/ComAmazonawsKms/runtimes/rust/src/lib.rs @@ -0,0 +1,28 @@ +#![allow(deprecated, non_upper_case_globals, unused, non_snake_case, non_camel_case_types)] + + +pub mod client; +pub mod conversions; +pub mod types; + +pub(crate) mod standard_library_externs; +pub(crate) mod standard_library_conversions; +pub use client::Client; + +pub(crate) mod implementation_from_dafny; +pub(crate) use crate::implementation_from_dafny::r#_Wrappers_Compile; + +pub(crate) mod dafny_libraries; +pub(crate) mod kms; +pub(crate) mod sets; +pub(crate) mod time; +pub(crate) mod uuid; +pub(crate) use crate::implementation_from_dafny::UTF8; +pub(crate) mod concurrent_call; +//pub(crate) mod dafny_libraries; + +pub(crate) use crate::implementation_from_dafny::DafnyLibraries; +pub(crate) use crate::implementation_from_dafny::ConcurrentCall; +pub(crate) use crate::implementation_from_dafny::Time; +pub(crate) use crate::implementation_from_dafny::UUID; +pub(crate) use crate::implementation_from_dafny::software; diff --git a/ComAmazonawsKms/test/TestComAmazonawsKms.dfy b/ComAmazonawsKms/test/TestComAmazonawsKms.dfy index 3cbd71aa31..e07ec47655 100644 --- a/ComAmazonawsKms/test/TestComAmazonawsKms.dfy +++ b/ComAmazonawsKms/test/TestComAmazonawsKms.dfy @@ -118,9 +118,9 @@ module TestComAmazonawsKms { var ret := client.GenerateDataKeyWithoutPlaintext(failingInput); expect ret.Failure?; var err: Kms.Types.Error := ret.error; - expect err.Opaque?; + expect err.OpaqueWithText?; match err { - case Opaque(obj) => expect true; + case OpaqueWithText(obj, objMessage) => expect true; case _ => expect false, "Failing KMS Key MUST cause an OpaqueError that can later be unwrapped to a proper but generic KMS Exception."; } } diff --git a/StandardLibrary/Makefile b/StandardLibrary/Makefile index d70b70093c..27f618e4d4 100644 --- a/StandardLibrary/Makefile +++ b/StandardLibrary/Makefile @@ -21,3 +21,12 @@ GO_MODULE_NAME="github.com/dafny-lang/DafnyStandardLibGo" # Python PYTHON_MODULE_NAME=smithy_dafny_standard_library + +RUST_OTHER_FILES := \ + runtimes/rust/src/concurrent_call.rs \ + runtimes/rust/src/sets.rs \ + runtimes/rust/src/time.rs \ + runtimes/rust/src/uuid.rs + +polymorph_rust: + @echo no polymorph needed for StandardLibrary diff --git a/StandardLibrary/codebuild/release-python/validate.yml b/StandardLibrary/codebuild/release-python/validate.yml index 3170b2dc1c..7eed7fb463 100644 --- a/StandardLibrary/codebuild/release-python/validate.yml +++ b/StandardLibrary/codebuild/release-python/validate.yml @@ -20,6 +20,9 @@ phases: - export PATH="$PWD/dafny:$PATH" # Switch back to the main directory - cd aws-cryptographic-material-providers-library + # Check out tests for release commit + - git fetch --tags + - git checkout $COMMIT_ID # Install test dependencies - pyenv install --skip-existing 3.11 - pyenv local 3.11 diff --git a/StandardLibrary/runtimes/java/src/main/java/DafnyLibraries/MutableMap.java b/StandardLibrary/runtimes/java/src/main/java/DafnyLibraries/MutableMap.java index b9f2f1316f..3b5607e291 100644 --- a/StandardLibrary/runtimes/java/src/main/java/DafnyLibraries/MutableMap.java +++ b/StandardLibrary/runtimes/java/src/main/java/DafnyLibraries/MutableMap.java @@ -8,8 +8,7 @@ import java.util.Map; import java.util.concurrent.*; -public class MutableMap - extends DafnyLibraries._ExternBase_MutableMap { +public class MutableMap implements DafnyLibraries.MutableMapTrait { private ConcurrentHashMap m; @@ -17,7 +16,6 @@ public MutableMap( dafny.TypeDescriptor _td_K, dafny.TypeDescriptor _td_V ) { - super(_td_K, _td_V); m = new ConcurrentHashMap(); } @@ -69,4 +67,4 @@ public void Remove(K k) { public BigInteger Size() { return BigInteger.valueOf(m.size()); } -} +} \ No newline at end of file diff --git a/StandardLibrary/runtimes/net/AssemblyInfo.cs b/StandardLibrary/runtimes/net/AssemblyInfo.cs index 1263336ed0..1e9e39450b 100644 --- a/StandardLibrary/runtimes/net/AssemblyInfo.cs +++ b/StandardLibrary/runtimes/net/AssemblyInfo.cs @@ -3,4 +3,4 @@ [assembly: AssemblyTitle("AWS.Cryptography.Internal.StandardLibrary")] // This should be kept in sync with the version number in STD.csproj -[assembly: AssemblyVersion("1.7.3")] +[assembly: AssemblyVersion("1.7.4")] diff --git a/StandardLibrary/runtimes/net/STD.csproj b/StandardLibrary/runtimes/net/STD.csproj index a141f4ca1e..13a3d9180f 100644 --- a/StandardLibrary/runtimes/net/STD.csproj +++ b/StandardLibrary/runtimes/net/STD.csproj @@ -5,7 +5,7 @@ false true - 1.7.3 + 1.7.4 AWS.Cryptography.Internal.StandardLibrary AWS.Cryptography.Internal.StandardLibrary diff --git a/StandardLibrary/runtimes/python/pyproject.toml b/StandardLibrary/runtimes/python/pyproject.toml index e4234ec4be..68efe8759f 100644 --- a/StandardLibrary/runtimes/python/pyproject.toml +++ b/StandardLibrary/runtimes/python/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "aws-cryptography-internal-standard-library" -version = "1.7.3" +version = "1.7.4" description = "" authors = ["AWS Crypto Tools "] packages = [ diff --git a/StandardLibrary/runtimes/python/src/smithy_dafny_standard_library/internaldafny/extern/UTF8.py b/StandardLibrary/runtimes/python/src/smithy_dafny_standard_library/internaldafny/extern/UTF8.py index e0ed1d3921..0c34e42d39 100644 --- a/StandardLibrary/runtimes/python/src/smithy_dafny_standard_library/internaldafny/extern/UTF8.py +++ b/StandardLibrary/runtimes/python/src/smithy_dafny_standard_library/internaldafny/extern/UTF8.py @@ -20,18 +20,9 @@ However, if a Unicode-escaped character is outside the BMP, Python internally represents it as a Unicode-escaped character using surrogate pairs. -ex. -"\uD808\uDC00" == 'ð’€€' --> ord('ð’€€') == 73728 --> 73728 > 65535 --> outside BMP -Since "\uD808\uDC00" is outside the BMP, Python internally represents it as "\uD808\uDC00": - -``` ->>> s = "\uD808\uDC00" ->>> s -'\ud808\udc00' -``` Dafny expects its strings to be UTF-16 code units. -However, the `.decode()` method with 'surrogatepass' leaves '\ud808\udc00' as 'ð’€€', +However, the `.decode()` method with 'surrogatepass' leaves surrogates pairs as their Unicode representations, which, if passed directly to Dafny, will be interpreted as a single UTF-32 code unit, instead of the desired two UTF-16 code units. diff --git a/StandardLibrary/runtimes/python/src/smithy_dafny_standard_library/internaldafny/generated/dafny_src-py.dtr b/StandardLibrary/runtimes/python/src/smithy_dafny_standard_library/internaldafny/generated/dafny_src-py.dtr index 45c157e6f9..710d07681c 100644 --- a/StandardLibrary/runtimes/python/src/smithy_dafny_standard_library/internaldafny/generated/dafny_src-py.dtr +++ b/StandardLibrary/runtimes/python/src/smithy_dafny_standard_library/internaldafny/generated/dafny_src-py.dtr @@ -1,5 +1,5 @@ file_format_version = "1.0" -dafny_version = "4.8.1.0" +dafny_version = "4.8.0.0" [options_by_module.Wrappers] legacy-module-names = false python-module-name = "smithy_dafny_standard_library.internaldafny.generated" diff --git a/StandardLibrary/runtimes/python/tox.ini b/StandardLibrary/runtimes/python/tox.ini index 5e6bbcb9db..09b5ee384f 100644 --- a/StandardLibrary/runtimes/python/tox.ini +++ b/StandardLibrary/runtimes/python/tox.ini @@ -1,7 +1,7 @@ [tox] isolated_build = True envlist = - py{311,312}-{dafnytests} + py{311,312,313}-{dafnytests} [testenv:base-command] commands = poetry run pytest -l {posargs} diff --git a/StandardLibrary/runtimes/rust/.gitignore b/StandardLibrary/runtimes/rust/.gitignore new file mode 100644 index 0000000000..f691b92211 --- /dev/null +++ b/StandardLibrary/runtimes/rust/.gitignore @@ -0,0 +1,7 @@ +Cargo.lock +src/concurrent_call.rs +src/implementation_from_dafny.rs +src/sets.rs +src/time.rs +src/uuid.rs +target diff --git a/StandardLibrary/runtimes/rust/Cargo.toml b/StandardLibrary/runtimes/rust/Cargo.toml new file mode 100644 index 0000000000..4e2380d2a8 --- /dev/null +++ b/StandardLibrary/runtimes/rust/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "aws-mpl-stdlib" +version = "0.1.0" +edition = "2021" +rust-version = "1.80.0" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +chrono = "0.4.38" +dafny_runtime = { path = "../../../smithy-dafny/TestModels/dafny-dependencies/dafny_runtime_rust"} +dashmap = "6.1.0" +uuid = { version = "1.11.0", features = ["v4"] } diff --git a/StandardLibrary/runtimes/rust/copy_externs.sh b/StandardLibrary/runtimes/rust/copy_externs.sh new file mode 100755 index 0000000000..eb901a4aa4 --- /dev/null +++ b/StandardLibrary/runtimes/rust/copy_externs.sh @@ -0,0 +1,10 @@ +#!/bin/bash -eu + +cd $( dirname ${BASH_SOURCE[0]} ) + +SRC=../../../AwsCryptographicMaterialProviders/runtimes/rust/src/ + +cp $SRC/concurrent_call.rs src +cp $SRC/sets.rs src +cp $SRC/time.rs src +cp $SRC/uuid.rs src diff --git a/StandardLibrary/runtimes/rust/src/lib.rs b/StandardLibrary/runtimes/rust/src/lib.rs new file mode 100644 index 0000000000..b19ab9a648 --- /dev/null +++ b/StandardLibrary/runtimes/rust/src/lib.rs @@ -0,0 +1,17 @@ +#![allow(deprecated, non_upper_case_globals, unused, non_snake_case, non_camel_case_types)] + +pub(crate) mod standard_library_externs; + +pub(crate) mod implementation_from_dafny; +pub(crate) use crate::implementation_from_dafny::r#_Wrappers_Compile; + +pub(crate) mod sets; +pub(crate) mod time; +pub(crate) mod uuid; +pub(crate) use crate::implementation_from_dafny::UTF8; +pub(crate) mod concurrent_call; +//pub(crate) mod dafny_libraries; + +pub(crate) use crate::implementation_from_dafny::ConcurrentCall; +pub(crate) use crate::implementation_from_dafny::Time; +pub(crate) use crate::implementation_from_dafny::UUID; diff --git a/StandardLibrary/runtimes/rust/src/standard_library_externs.rs b/StandardLibrary/runtimes/rust/src/standard_library_externs.rs new file mode 100644 index 0000000000..f5f0f35fbd --- /dev/null +++ b/StandardLibrary/runtimes/rust/src/standard_library_externs.rs @@ -0,0 +1,80 @@ +// Annotation to ignore the case of this module +use crate::r#_Wrappers_Compile; +use crate::implementation_from_dafny::UTF8; + +impl crate::implementation_from_dafny::UTF8::_default { + pub fn Encode( + s: &::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>, + ) -> ::std::rc::Rc< + r#_Wrappers_Compile::Result< + UTF8::ValidUTF8Bytes, + ::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>, + >, + > { + let v = s.to_array(); + let mut _accumulator: Vec = vec![]; + // Use of .encode_utf8 method. + let mut surrogate: Option = None; + for c in v.iter() { + let s = if let Some(s) = surrogate { + String::from_utf16(&[s, c.0]) + } else { + String::from_utf16(&[c.0]) + }; + surrogate = None; + match s { + Ok(value) => { + _accumulator.extend(value.as_bytes()); + continue; + } + Err(e) => { + if 0xD800 <= c.0 && c.0 <= 0xDFFF { + surrogate = Some(c.0); + continue; + } + return ::std::rc::Rc::new(r#_Wrappers_Compile::Result::>::Failure { + error: ::dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string( + &e.to_string()) + }); + } + } + } + if let Some(s) = surrogate { + return ::std::rc::Rc::new(r#_Wrappers_Compile::Result::>::Failure { + error: ::dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string( + &format!("Surrogate pair missing: 0x{:04x}", s)) + }); + } + ::std::rc::Rc::new(r#_Wrappers_Compile::Result::< + UTF8::ValidUTF8Bytes, + ::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>, + >::Success { + value: ::dafny_runtime::Sequence::from_array_owned(_accumulator), + }) + } + pub fn Decode( + b: &::dafny_runtime::Sequence, + ) -> ::std::rc::Rc< + r#_Wrappers_Compile::Result< + ::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>, + ::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>, + >, + > { + let b = String::from_utf8(b.to_array().as_ref().clone()); + match b { + Ok(s) => { + ::std::rc::Rc::new(r#_Wrappers_Compile::Result::<::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>, + ::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>>::Success { + value: ::dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(&s) + }) + }, + Err(e) => { + return ::std::rc::Rc::new(r#_Wrappers_Compile::Result::<::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>, + ::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>>::Failure { + error: ::dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string( + &e.to_string()) + }) + } + } + } +} diff --git a/StandardLibrary/src/Sequence.dfy b/StandardLibrary/src/Sequence.dfy new file mode 100644 index 0000000000..2f87dd3095 --- /dev/null +++ b/StandardLibrary/src/Sequence.dfy @@ -0,0 +1,42 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +include "UInt.dfy" + +module StandardLibrary.Sequence { + // export provides SequenceEqual, StandardLibrary + import opened UInt + + predicate method SequenceEqualNat(seq1: seq, seq2: seq, start1: nat, start2: nat, size: nat) : (ret : bool) + requires start1 + size <= |seq1| + requires start2 + size <= |seq2| + ensures ret ==> seq1[start1..start1 + size] == seq2[start2..start2 + size] + { + if |seq1| > UINT64_MAX_LIMIT || |seq2| > UINT64_MAX_LIMIT then + // This line of code will never be executed, but is included for correctness + seq1[start1..start1 + size] == seq2[start2..start2 + size] + else + SequenceEqual(seq1, seq2, start1 as uint64, start2 as uint64, size as uint64) + } + + predicate SequenceEqual(seq1: seq64, seq2: seq64, start1: uint64, start2: uint64, size: uint64) : (ret : bool) + requires start1 as nat + size as nat <= |seq1| + requires start2 as nat + size as nat <= |seq2| + ensures ret <==> seq1[start1..start1 + size] == seq2[start2..start2 + size] + { + seq1[start1..start1 + size] == seq2[start2..start2 + size] + } by method { + var j := start2 as uint64; + for i := start1 as uint64 to (start1 + size) as uint64 + invariant j == i - start1 + start2 + invariant forall k : uint64 | start1 <= k < i :: seq1[k] == seq2[k - start1 + start2] + { + if seq1[i] != seq2[j] { + return false; + } + j := j + 1; + } + return true; + } + +} diff --git a/StandardLibrary/src/String.dfy b/StandardLibrary/src/String.dfy index f7a384d0a1..2c34ec5322 100644 --- a/StandardLibrary/src/String.dfy +++ b/StandardLibrary/src/String.dfy @@ -1,8 +1,13 @@ // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 +include "../../libraries/src/Wrappers.dfy" +include "Sequence.dfy" module StandardLibrary.String { - export provides Int2String, Base10Int2String + import Wrappers + import opened UInt + import opened Sequence + export provides Int2String, Base10Int2String, HasSubString, Wrappers, UInt const Base10: seq := ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'] @@ -48,4 +53,37 @@ module StandardLibrary.String { { Int2String(n, Base10) } + + /* Returns the index of a substring or None, if the substring is not in the string */ + method HasSubString(haystack: string, needle: string) + returns (o: Wrappers.Option) + + ensures o.Some? ==> + && o.value <= |haystack| - |needle| && haystack[o.value..(o.value + |needle|)] == needle + && (forall i | 0 <= i < o.value :: haystack[i..][..|needle|] != needle) + + ensures |haystack| < |needle| || |haystack| > (UINT64_MAX_LIMIT-1) ==> o.None? + + ensures o.None? && |needle| <= |haystack| && |haystack| <= (UINT64_MAX_LIMIT-1) ==> + (forall i | 0 <= i <= (|haystack|-|needle|) :: haystack[i..][..|needle|] != needle) + { + if |haystack| < |needle| { + return Wrappers.None; + } + + // `-1` is needed because of how `limit` is calculated below + expect |haystack| <= (UINT64_MAX_LIMIT-1); + + var size : uint64 := |needle| as uint64; + var limit: uint64 := |haystack| as uint64 - size + 1; + + for index := 0 to limit + invariant forall i | 0 <= i < index :: haystack[i..][..size] != needle + { + if SequenceEqual(seq1 := haystack, seq2 := needle, start1 := index, start2 := 0, size := size) { + return Wrappers.Some(index as nat); + } + } + return Wrappers.None; + } } diff --git a/StandardLibrary/src/UInt.dfy b/StandardLibrary/src/UInt.dfy index 7bd825eb70..2f9daf0621 100644 --- a/StandardLibrary/src/UInt.dfy +++ b/StandardLibrary/src/UInt.dfy @@ -16,6 +16,7 @@ module StandardLibrary.UInt { const UINT64_LIMIT := BoundedInts.UINT64_MAX as int + 1 const INT32_MAX_LIMIT := BoundedInts.INT32_MAX as int const INT64_MAX_LIMIT := BoundedInts.INT64_MAX as int + const UINT64_MAX_LIMIT := BoundedInts.UINT64_MAX as int predicate method UInt8Less(a: uint8, b: uint8) { a < b } diff --git a/StandardLibrary/test/TestString.dfy b/StandardLibrary/test/TestString.dfy new file mode 100644 index 0000000000..8833c31984 --- /dev/null +++ b/StandardLibrary/test/TestString.dfy @@ -0,0 +1,35 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +include "../src/StandardLibrary.dfy" +include "../src/String.dfy" +include "../../libraries/src/Wrappers.dfy" + +module TestStrings { + import StandardLibrary.String + import opened Wrappers + + method {:test} TestHasSubStringPositive() + { + var actual := String.HasSubString("Koda is a Dog.", "Koda"); + expect actual == Some(0), "'Koda' is in 'Koda is a Dog.' at index 0, but HasSubString does not think so"; + actual := String.HasSubString("Koda is a Dog.", "Koda is a Dog."); + expect actual == Some(0), "'Koda is a Dog.' is in 'Koda is a Dog.' at index 0, but HasSubString does not think so"; + actual := String.HasSubString("Koda is a Dog.", "Dog."); + expect actual == Some(10), "'Dog.' is in 'Koda is a Dog.' at index 10, but HasSubString does not think so"; + actual := String.HasSubString("Koda is a Dog.", "."); + expect actual == Some(13), "'.' is in 'Koda is a Dog.' at index 13, but HasSubString does not think so"; + actual := String.HasSubString("Koda is a Dog.", ""); + expect actual == Some(0), "The empty string is in 'Koda is a Dog.' at index 0, but HasSubString does not think so"; + } + + method {:test} TestHasSubStringNegative() + { + var actual := String.HasSubString("Robbie is a Dog.", "Koda"); + expect actual == None, "'Robbie is a Dog.' does not contain Koda"; + actual := String.HasSubString("\t", " "); + expect actual == None, "A tab is not a space"; + actual := String.HasSubString("large", "larger"); + expect actual == None, "Needle larger than haystack"; + } +} diff --git a/TestVectorsAwsCryptographicMaterialProviders/Makefile b/TestVectorsAwsCryptographicMaterialProviders/Makefile index 6d8415410d..e253651b3e 100644 --- a/TestVectorsAwsCryptographicMaterialProviders/Makefile +++ b/TestVectorsAwsCryptographicMaterialProviders/Makefile @@ -11,6 +11,29 @@ PROJECT_SERVICES := \ KeyVectors \ TestVectorsAwsCryptographicMaterialProviders \ +MAIN_SERVICE_FOR_RUST := TestVectorsAwsCryptographicMaterialProviders + +RUST_OTHER_FILES := \ + runtimes/rust/src/aes_gcm.rs \ + runtimes/rust/src/aes_kdf_ctr.rs \ + runtimes/rust/src/concurrent_call.rs \ + runtimes/rust/src/dafny_libraries.rs \ + runtimes/rust/src/ddb.rs \ + runtimes/rust/src/digest.rs \ + runtimes/rust/src/ecdh.rs \ + runtimes/rust/src/ecdsa.rs \ + runtimes/rust/src/hmac.rs \ + runtimes/rust/src/kms.rs \ + runtimes/rust/src/local_cmc.rs \ + runtimes/rust/src/random.rs \ + runtimes/rust/src/rsa.rs \ + runtimes/rust/src/sets.rs \ + runtimes/rust/src/software_externs.rs \ + runtimes/rust/src/storm_tracker.rs \ + runtimes/rust/src/time.rs \ + runtimes/rust/src/test_vec_dir.rs \ + runtimes/rust/src/uuid.rs + SMITHY_MODEL_ROOT := $(PROJECT_ROOT)/AwsCryptographicMaterialProviders/dafny/AwsCryptographicMaterialProviders/Model OUTPUT_LOCAL_SERVICE_TestVectorsAwsCryptographicMaterialProviders := --local-service-test @@ -72,6 +95,38 @@ WRAPPED_INDEX_FILE_PATH=dafny/TestVectorsAwsCryptographicMaterialProviders/src/L WRAPPED_INDEX_FILE_WITH_EXTERN_STRING="module {:extern \"software.amazon.cryptography.materialproviders.internaldafny.wrapped\" } WrappedMaterialProviders refines WrappedAbstractAwsCryptographyMaterialProvidersService" WRAPPED_INDEX_FILE_WITHOUT_EXTERN_STRING="module WrappedMaterialProviders refines WrappedAbstractAwsCryptographyMaterialProvidersService" +# Rust SED Hacks +IMPLEMENTATION_FROM_DAFNY_TV_RUST_FILE=runtimes/rust/src/implementation_from_dafny.rs +IMPLEMENTATION_FROM_DAFNY_TV_RUST_MPL_MAIN="WrappedMaterialProvidersMain::_default::Main();" +IMPLEMENTATION_FROM_DAFNY_TV_RUST_ESDK_MAIN= \ + "let args: Vec = std::env::args().collect();\ + let dafny_strings = args.iter().map(|x| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(\&x)).collect::>();\ + let dafny_args = dafny_runtime::Sequence::from_array_owned(dafny_strings);\ + r\#_WrappedMaterialProvidersMain_Compile::_default::Main(\&dafny_args);" + +# TODO: Remove after wrapped client issue is fixed in Rust +REMOVE_WRAPPED_CLIENT_AFTER_POLYMORPH_RUST_PRIMITIVES=runtimes/rust/src/deps/aws_cryptography_primitives.rs +REMOVE_WRAPPED_CLIENT_AFTER_POLYMORPH_RUST_KEYSTORE=runtimes/rust/src/deps/aws_cryptography_keyStore.rs +REMOVE_WRAPPED_CLIENT_AFTER_POLYMORPH_RUST_FROM_1 = "\#\[cfg(feature = \"wrapped-client\")\]" +REMOVE_WRAPPED_CLIENT_AFTER_POLYMORPH_RUST_FROM_2 := 'pub mod wrapped;' +REMOVE_WRAPPED_CLIENT_AFTER_POLYMORPH_RUST_TO_1 := '\/\/ removed wrapped-client feature using sed;' +REMOVE_WRAPPED_CLIENT_AFTER_POLYMORPH_RUST_TO_2 := '\/\/ removed wrapped module using sed;' + +transpile_implementation_rust: _replace_main_method_name_rust + +# TODO: Remove after wrapped client issue is fixed in Rust +_polymorph_rust: _remove_wrapped_client_rust + +_replace_main_method_name_rust: + $(MAKE) _sed_file SED_FILE_PATH=$(IMPLEMENTATION_FROM_DAFNY_TV_RUST_FILE) SED_BEFORE_STRING=$(IMPLEMENTATION_FROM_DAFNY_TV_RUST_MPL_MAIN) SED_AFTER_STRING=$(IMPLEMENTATION_FROM_DAFNY_TV_RUST_ESDK_MAIN) + +# TODO: Remove after wrapped client issue is fixed in Rust +_remove_wrapped_client_rust: + $(MAKE) _sed_file SED_FILE_PATH=$(REMOVE_WRAPPED_CLIENT_AFTER_POLYMORPH_RUST_PRIMITIVES) SED_BEFORE_STRING=$(REMOVE_WRAPPED_CLIENT_AFTER_POLYMORPH_RUST_FROM_1) SED_AFTER_STRING=$(REMOVE_WRAPPED_CLIENT_AFTER_POLYMORPH_RUST_TO_1) + $(MAKE) _sed_file SED_FILE_PATH=$(REMOVE_WRAPPED_CLIENT_AFTER_POLYMORPH_RUST_PRIMITIVES) SED_BEFORE_STRING=$(REMOVE_WRAPPED_CLIENT_AFTER_POLYMORPH_RUST_FROM_2) SED_AFTER_STRING=$(REMOVE_WRAPPED_CLIENT_AFTER_POLYMORPH_RUST_TO_2) + $(MAKE) _sed_file SED_FILE_PATH=$(REMOVE_WRAPPED_CLIENT_AFTER_POLYMORPH_RUST_KEYSTORE) SED_BEFORE_STRING=$(REMOVE_WRAPPED_CLIENT_AFTER_POLYMORPH_RUST_FROM_1) SED_AFTER_STRING=$(REMOVE_WRAPPED_CLIENT_AFTER_POLYMORPH_RUST_TO_1) + $(MAKE) _sed_file SED_FILE_PATH=$(REMOVE_WRAPPED_CLIENT_AFTER_POLYMORPH_RUST_KEYSTORE) SED_BEFORE_STRING=$(REMOVE_WRAPPED_CLIENT_AFTER_POLYMORPH_RUST_FROM_2) SED_AFTER_STRING=$(REMOVE_WRAPPED_CLIENT_AFTER_POLYMORPH_RUST_TO_2) + # Python # smithy.api namespace is a workaround for having a wrapped localService shim in a different Python package, @@ -122,6 +177,12 @@ test_generate_vectors_python: python3 -m tox -c runtimes/python --verbose -e cli -- encrypt-manifest --encrypt-manifest-output runtimes/python cp dafny/TestVectorsAwsCryptographicMaterialProviders/test/keys.json runtimes/python +test_generate_vectors_rust: + cd runtimes/rust && \ + cargo run --bin test-vectors --features="wrapped-client" --release -- encrypt-manifest --encrypt-manifest-output . && \ + cd ../../ + cp dafny/TestVectorsAwsCryptographicMaterialProviders/test/keys.json runtimes/rust/ + test_encrypt_vectors_java: gradle -p runtimes/java run --args="encrypt --manifest-path . --decrypt-manifest-path ." @@ -135,6 +196,11 @@ test_encrypt_vectors_python: rm -rf runtimes/python/.tox python3 -m tox -c runtimes/python --verbose -e cli -- encrypt --manifest-path runtimes/python --decrypt-manifest-path runtimes/python +test_encrypt_vectors_rust: + cd runtimes/rust && \ + cargo run --bin test-vectors --features="wrapped-client" --release -- encrypt --manifest-path . --decrypt-manifest-path . && \ + cd ../../ + test_decrypt_encrypt_vectors_java: gradle -p runtimes/java run --args="decrypt --manifest-path ." @@ -147,3 +213,8 @@ test_decrypt_encrypt_vectors_net: test_decrypt_encrypt_vectors_python: rm -rf runtimes/python/.tox python3 -m tox -c runtimes/python --verbose -e cli -- decrypt --manifest-path runtimes/python + +test_decrypt_encrypt_vectors_rust: + cd runtimes/rust && \ + cargo run --bin test-vectors --features="wrapped-client" --release -- decrypt --manifest-path . && \ + cd ../../ diff --git a/TestVectorsAwsCryptographicMaterialProviders/dafny/KeyVectors/Model/AwsCryptographyMaterialProvidersTestVectorKeysTypes.dfy b/TestVectorsAwsCryptographicMaterialProviders/dafny/KeyVectors/Model/AwsCryptographyMaterialProvidersTestVectorKeysTypes.dfy index bc931fdbc9..201cf7476b 100644 --- a/TestVectorsAwsCryptographicMaterialProviders/dafny/KeyVectors/Model/AwsCryptographyMaterialProvidersTestVectorKeysTypes.dfy +++ b/TestVectorsAwsCryptographicMaterialProviders/dafny/KeyVectors/Model/AwsCryptographyMaterialProvidersTestVectorKeysTypes.dfy @@ -261,7 +261,16 @@ module {:extern "software.amazon.cryptography.materialproviderstestvectorkeys.in | CollectionOfErrors(list: seq, nameonly message: string) // The Opaque error, used for native, extern, wrapped or unknown errors | Opaque(obj: object) - type OpaqueError = e: Error | e.Opaque? witness * + // A better Opaque, with a visible string representation. + | OpaqueWithText(obj: object, objMessage : string) + type OpaqueError = e: Error | e.Opaque? || e.OpaqueWithText? witness * + // This dummy subset type is included to make sure Dafny + // always generates a _ExternBase___default.java class. + type DummySubsetType = x: int | IsDummySubsetType(x) witness 1 + predicate method IsDummySubsetType(x: int) { + 0 < x + } + } abstract module AbstractAwsCryptographyMaterialProvidersTestVectorKeysService { diff --git a/TestVectorsAwsCryptographicMaterialProviders/dafny/TestVectorsAwsCryptographicMaterialProviders/.gitignore b/TestVectorsAwsCryptographicMaterialProviders/dafny/TestVectorsAwsCryptographicMaterialProviders/.gitignore new file mode 100644 index 0000000000..c1dfac9502 --- /dev/null +++ b/TestVectorsAwsCryptographicMaterialProviders/dafny/TestVectorsAwsCryptographicMaterialProviders/.gitignore @@ -0,0 +1,3 @@ +keys.json +manifest.json +test/manifest.json diff --git a/TestVectorsAwsCryptographicMaterialProviders/dafny/TestVectorsAwsCryptographicMaterialProviders/src/VectorsComposition/AllAlgorithmSuites.dfy b/TestVectorsAwsCryptographicMaterialProviders/dafny/TestVectorsAwsCryptographicMaterialProviders/src/VectorsComposition/AllAlgorithmSuites.dfy index 7484dd010f..a089a94113 100644 --- a/TestVectorsAwsCryptographicMaterialProviders/dafny/TestVectorsAwsCryptographicMaterialProviders/src/VectorsComposition/AllAlgorithmSuites.dfy +++ b/TestVectorsAwsCryptographicMaterialProviders/dafny/TestVectorsAwsCryptographicMaterialProviders/src/VectorsComposition/AllAlgorithmSuites.dfy @@ -21,15 +21,35 @@ module {:options "-functionSyntax:4"} AllAlgorithmSuites { Types.CommitmentPolicy.DBE(Types.DBECommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT) } - const ESDKAlgorithmSuites := set id: Types.ESDKAlgorithmSuiteId :: AlgorithmSuites.GetESDKSuite(id) + // TODO: Add aes-192 after aws-lc-rs adds support + // To add AES192 tests, uncomment next line and remove the current value of ESDKAlgorithmSuites + // const ESDKAlgorithmSuites := set id: Types.ESDKAlgorithmSuiteId :: AlgorithmSuites.GetESDKSuite(id) + const ESDKAlgorithmSuites := set id: Types.ESDKAlgorithmSuiteId | + id != Types.ALG_AES_192_GCM_IV12_TAG16_NO_KDF && + id != Types.ALG_AES_192_GCM_IV12_TAG16_HKDF_SHA256 && + id != Types.ALG_AES_192_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384 :: + AlgorithmSuites.GetESDKSuite(id) const DBEAlgorithmSuites := set id: Types.DBEAlgorithmSuiteId :: AlgorithmSuites.GetDBESuite(id) const AllAlgorithmSuites := ESDKAlgorithmSuites + DBEAlgorithmSuites - lemma AllAlgorithmSuitesIsComplete(id: Types.AlgorithmSuiteId) + // TODO: Add aes-192 after aws-lc-rs adds support + // To add AES192 tests, comment out AllAlgorithmSuitesIsCompleteExceptAES192 + // and uncomment AllAlgorithmSuitesIsComplete + lemma AllAlgorithmSuitesIsCompleteExceptAES192(id: Types.AlgorithmSuiteId) + requires match id + case ESDK(e) => + e != Types.ALG_AES_192_GCM_IV12_TAG16_NO_KDF && + e != Types.ALG_AES_192_GCM_IV12_TAG16_HKDF_SHA256 && + e != Types.ALG_AES_192_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384 + case DBE(_) => true ensures AlgorithmSuites.GetSuite(id) in AllAlgorithmSuites {} + // lemma AllAlgorithmSuitesIsComplete(id: Types.AlgorithmSuiteId) + // ensures AlgorithmSuites.GetSuite(id) in AllAlgorithmSuites + // {} + function ToHex(algorithmSuite: Types.AlgorithmSuiteInfo) : string { diff --git a/TestVectorsAwsCryptographicMaterialProviders/dafny/TestVectorsAwsCryptographicMaterialProviders/src/VectorsComposition/AllRawAES.dfy b/TestVectorsAwsCryptographicMaterialProviders/dafny/TestVectorsAwsCryptographicMaterialProviders/src/VectorsComposition/AllRawAES.dfy index d527522deb..4079583f97 100644 --- a/TestVectorsAwsCryptographicMaterialProviders/dafny/TestVectorsAwsCryptographicMaterialProviders/src/VectorsComposition/AllRawAES.dfy +++ b/TestVectorsAwsCryptographicMaterialProviders/dafny/TestVectorsAwsCryptographicMaterialProviders/src/VectorsComposition/AllRawAES.dfy @@ -10,7 +10,10 @@ module {:options "-functionSyntax:4"} AllRawAES { import KeyVectorsTypes = AwsCryptographyMaterialProvidersTestVectorKeysTypes // These are all the PositiveKeyDescription for the RawAESKeyring - const aesPersistentKeyNames := [ "aes-128", "aes-192", "aes-256"] + + // TODO: Add aes-192 after aws-lc-rs adds support + // const aesPersistentKeyNames := [ "aes-128", "aes-192", "aes-256"] + const aesPersistentKeyNames := [ "aes-128", "aes-256"] const KeyDescriptions := set key <- aesPersistentKeyNames diff --git a/TestVectorsAwsCryptographicMaterialProviders/project.properties b/TestVectorsAwsCryptographicMaterialProviders/project.properties index 02e193a7d6..55d988fe1b 100644 --- a/TestVectorsAwsCryptographicMaterialProviders/project.properties +++ b/TestVectorsAwsCryptographicMaterialProviders/project.properties @@ -1,4 +1,4 @@ # This file stores the top level dafny version information. # All elements of the project need to agree on this version. -dafnyVersion=4.8.0 -dafnyRuntimeJavaVersion=4.8.0 +dafnyVersion=4.9.0 +dafnyRuntimeJavaVersion=4.9.0 diff --git a/TestVectorsAwsCryptographicMaterialProviders/runtimes/java/build.gradle.kts b/TestVectorsAwsCryptographicMaterialProviders/runtimes/java/build.gradle.kts index 890d61edea..e161e17f55 100644 --- a/TestVectorsAwsCryptographicMaterialProviders/runtimes/java/build.gradle.kts +++ b/TestVectorsAwsCryptographicMaterialProviders/runtimes/java/build.gradle.kts @@ -20,7 +20,7 @@ var props = Properties().apply { var dafnyVersion = props.getProperty("dafnyVersion") group = "software.amazon.cryptography" -version = "1.7.3-SNAPSHOT" +version = "1.7.4-SNAPSHOT" description = "TestAwsCryptographicMaterialProviders" java { @@ -68,7 +68,7 @@ repositories { dependencies { implementation("org.dafny:DafnyRuntime:${dafnyVersion}") implementation("software.amazon.smithy.dafny:conversion:0.1.1") - implementation("software.amazon.cryptography:aws-cryptographic-material-providers:1.7.3-SNAPSHOT") + implementation("software.amazon.cryptography:aws-cryptographic-material-providers:1.7.4-SNAPSHOT") implementation(platform("software.amazon.awssdk:bom:2.25.1")) implementation("software.amazon.awssdk:dynamodb") implementation("software.amazon.awssdk:dynamodb-enhanced") diff --git a/TestVectorsAwsCryptographicMaterialProviders/runtimes/java/src/main/java/software/amazon/cryptography/materialproviderstestvectorkeys/internaldafny/types/__default.java b/TestVectorsAwsCryptographicMaterialProviders/runtimes/java/src/main/java/software/amazon/cryptography/materialproviderstestvectorkeys/internaldafny/types/__default.java new file mode 100644 index 0000000000..92a8f3b0c9 --- /dev/null +++ b/TestVectorsAwsCryptographicMaterialProviders/runtimes/java/src/main/java/software/amazon/cryptography/materialproviderstestvectorkeys/internaldafny/types/__default.java @@ -0,0 +1,3 @@ +package software.amazon.cryptography.materialproviderstestvectorkeys.internaldafny.types; + +public class __default extends _ExternBase___default {} diff --git a/TestVectorsAwsCryptographicMaterialProviders/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/materialproviderstestvectorkeys/ToDafny.java b/TestVectorsAwsCryptographicMaterialProviders/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/materialproviderstestvectorkeys/ToDafny.java index 429283097e..3b3651b232 100644 --- a/TestVectorsAwsCryptographicMaterialProviders/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/materialproviderstestvectorkeys/ToDafny.java +++ b/TestVectorsAwsCryptographicMaterialProviders/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/materialproviderstestvectorkeys/ToDafny.java @@ -40,6 +40,7 @@ import software.amazon.cryptography.materialproviderstestvectorkeys.model.CollectionOfErrors; import software.amazon.cryptography.materialproviderstestvectorkeys.model.KeyVectorException; import software.amazon.cryptography.materialproviderstestvectorkeys.model.OpaqueError; +import software.amazon.cryptography.materialproviderstestvectorkeys.model.OpaqueWithTextError; import software.amazon.cryptography.services.kms.internaldafny.types.EncryptionAlgorithmSpec; public class ToDafny { @@ -51,6 +52,9 @@ public static Error Error(RuntimeException nativeValue) { if (nativeValue instanceof OpaqueError) { return ToDafny.Error((OpaqueError) nativeValue); } + if (nativeValue instanceof OpaqueWithTextError) { + return ToDafny.Error((OpaqueWithTextError) nativeValue); + } if (nativeValue instanceof CollectionOfErrors) { return ToDafny.Error((CollectionOfErrors) nativeValue); } @@ -61,6 +65,13 @@ public static Error Error(OpaqueError nativeValue) { return Error.create_Opaque(nativeValue.obj()); } + public static Error Error(OpaqueWithTextError nativeValue) { + return Error.create_OpaqueWithText( + nativeValue.obj(), + dafny.DafnySequence.asString(nativeValue.objMessage()) + ); + } + public static Error Error(CollectionOfErrors nativeValue) { DafnySequence list = software.amazon.smithy.dafny.conversion.ToDafny.Aggregate.GenericToSequence( diff --git a/TestVectorsAwsCryptographicMaterialProviders/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/materialproviderstestvectorkeys/ToNative.java b/TestVectorsAwsCryptographicMaterialProviders/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/materialproviderstestvectorkeys/ToNative.java index 60a3424647..f322900ea9 100644 --- a/TestVectorsAwsCryptographicMaterialProviders/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/materialproviderstestvectorkeys/ToNative.java +++ b/TestVectorsAwsCryptographicMaterialProviders/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/materialproviderstestvectorkeys/ToNative.java @@ -11,6 +11,7 @@ import software.amazon.cryptography.materialproviderstestvectorkeys.internaldafny.types.Error_CollectionOfErrors; import software.amazon.cryptography.materialproviderstestvectorkeys.internaldafny.types.Error_KeyVectorException; import software.amazon.cryptography.materialproviderstestvectorkeys.internaldafny.types.Error_Opaque; +import software.amazon.cryptography.materialproviderstestvectorkeys.internaldafny.types.Error_OpaqueWithText; import software.amazon.cryptography.materialproviderstestvectorkeys.internaldafny.types.IKeyVectorsClient; import software.amazon.cryptography.materialproviderstestvectorkeys.model.CmmOperation; import software.amazon.cryptography.materialproviderstestvectorkeys.model.CollectionOfErrors; @@ -27,6 +28,7 @@ import software.amazon.cryptography.materialproviderstestvectorkeys.model.KmsRsaKeyring; import software.amazon.cryptography.materialproviderstestvectorkeys.model.MultiKeyring; import software.amazon.cryptography.materialproviderstestvectorkeys.model.OpaqueError; +import software.amazon.cryptography.materialproviderstestvectorkeys.model.OpaqueWithTextError; import software.amazon.cryptography.materialproviderstestvectorkeys.model.RawAES; import software.amazon.cryptography.materialproviderstestvectorkeys.model.RawEcdh; import software.amazon.cryptography.materialproviderstestvectorkeys.model.RawRSA; @@ -45,6 +47,17 @@ public static OpaqueError Error(Error_Opaque dafnyValue) { return nativeBuilder.build(); } + public static OpaqueWithTextError Error(Error_OpaqueWithText dafnyValue) { + OpaqueWithTextError.Builder nativeBuilder = OpaqueWithTextError.builder(); + nativeBuilder.obj(dafnyValue.dtor_obj()); + nativeBuilder.objMessage( + software.amazon.smithy.dafny.conversion.ToNative.Simple.String( + dafnyValue.dtor_objMessage() + ) + ); + return nativeBuilder.build(); + } + public static CollectionOfErrors Error(Error_CollectionOfErrors dafnyValue) { CollectionOfErrors.Builder nativeBuilder = CollectionOfErrors.builder(); nativeBuilder.list( @@ -78,6 +91,9 @@ public static RuntimeException Error(Error dafnyValue) { if (dafnyValue.is_Opaque()) { return ToNative.Error((Error_Opaque) dafnyValue); } + if (dafnyValue.is_OpaqueWithText()) { + return ToNative.Error((Error_OpaqueWithText) dafnyValue); + } if (dafnyValue.is_CollectionOfErrors()) { return ToNative.Error((Error_CollectionOfErrors) dafnyValue); } diff --git a/TestVectorsAwsCryptographicMaterialProviders/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/materialproviderstestvectorkeys/model/OpaqueWithTextError.java b/TestVectorsAwsCryptographicMaterialProviders/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/materialproviderstestvectorkeys/model/OpaqueWithTextError.java new file mode 100644 index 0000000000..5997b10b02 --- /dev/null +++ b/TestVectorsAwsCryptographicMaterialProviders/runtimes/java/src/main/smithy-generated/software/amazon/cryptography/materialproviderstestvectorkeys/model/OpaqueWithTextError.java @@ -0,0 +1,180 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// Do not modify this file. This file is machine generated, and any changes to it will be overwritten. +package software.amazon.cryptography.materialproviderstestvectorkeys.model; + +public class OpaqueWithTextError extends RuntimeException { + + /** + * The unexpected object encountered. It MIGHT BE an Exception, but that is not guaranteed. + */ + private final Object obj; + + /** + * The text equivalent of obj. + */ + private final String objMessage; + + protected OpaqueWithTextError(BuilderImpl builder) { + super(messageFromBuilder(builder), builder.cause()); + this.obj = builder.obj(); + this.objMessage = builder.objMessage(); + } + + private static String messageFromBuilder(Builder builder) { + if (builder.message() != null) { + return builder.message(); + } + if (builder.cause() != null) { + return builder.cause().getMessage(); + } + return null; + } + + /** + * See {@link Throwable#getMessage()}. + */ + public String message() { + return this.getMessage(); + } + + /** + * See {@link Throwable#getCause()}. + */ + public Throwable cause() { + return this.getCause(); + } + + /** + * @return The unexpected object encountered. It MIGHT BE an Exception, but that is not guaranteed. + */ + public Object obj() { + return this.obj; + } + + /** + * @return The text equivalent of obj. + */ + public String objMessage() { + return this.objMessage; + } + + public Builder toBuilder() { + return new BuilderImpl(this); + } + + public static Builder builder() { + return new BuilderImpl(); + } + + public interface Builder { + /** + * @param message The detailed message. The detail message is saved for later retrieval by the {@link #getMessage()} method. + */ + Builder message(String message); + + /** + * @return The detailed message. The detail message is saved for later retrieval by the {@link #getMessage()} method. + */ + String message(); + + /** + * @param cause The cause (which is saved for later retrieval by the {@link #getCause()} method). (A {@code null} value is permitted, and indicates that the cause is nonexistent or unknown.) + */ + Builder cause(Throwable cause); + + /** + * @return The cause (which is saved for later retrieval by the {@link #getCause()} method). (A {@code null} value is permitted, and indicates that the cause is nonexistent or unknown.) + */ + Throwable cause(); + + /** + * @param obj The unexpected object encountered. It MIGHT BE an Exception, but that is not guaranteed. + */ + Builder obj(Object obj); + + /** + * @return The unexpected object encountered. It MIGHT BE an Exception, but that is not guaranteed. + */ + Object obj(); + + /** + * @param objMessage The text equivalent of obj. + */ + Builder objMessage(String objMessage); + + /** + * @return The text equivalent of obj. + */ + String objMessage(); + + OpaqueWithTextError build(); + } + + static class BuilderImpl implements Builder { + + protected String message; + + protected Throwable cause; + + protected Object obj; + + protected String objMessage; + + protected BuilderImpl() {} + + protected BuilderImpl(OpaqueWithTextError model) { + this.cause = model.getCause(); + this.message = model.getMessage(); + this.obj = model.obj(); + this.objMessage = model.objMessage(); + } + + public Builder message(String message) { + this.message = message; + return this; + } + + public String message() { + return this.message; + } + + public Builder cause(Throwable cause) { + this.cause = cause; + return this; + } + + public Throwable cause() { + return this.cause; + } + + public Builder obj(Object obj) { + this.obj = obj; + return this; + } + + public Object obj() { + return this.obj; + } + + public Builder objMessage(String objMessage) { + this.objMessage = objMessage; + return this; + } + + public String objMessage() { + return this.objMessage; + } + + public OpaqueWithTextError build() { + if ( + this.obj != null && this.cause == null && this.obj instanceof Throwable + ) { + this.cause = (Throwable) this.obj; + } else if (this.obj == null && this.cause != null) { + this.obj = this.cause; + } + return new OpaqueWithTextError(this); + } + } +} diff --git a/TestVectorsAwsCryptographicMaterialProviders/runtimes/net/Generated/KeyVectors/OpaqueWithTextError.cs b/TestVectorsAwsCryptographicMaterialProviders/runtimes/net/Generated/KeyVectors/OpaqueWithTextError.cs new file mode 100644 index 0000000000..be8759d845 --- /dev/null +++ b/TestVectorsAwsCryptographicMaterialProviders/runtimes/net/Generated/KeyVectors/OpaqueWithTextError.cs @@ -0,0 +1,17 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// Do not modify this file. This file is machine generated, and any changes to it will be overwritten. +using System; +using AWS.Cryptography.MaterialProvidersTestVectorKeys; +namespace AWS.Cryptography.MaterialProvidersTestVectorKeys +{ + public class OpaqueWithTextError : Exception + { + public readonly object obj; + public readonly string objMessage; + public OpaqueWithTextError(Exception ex) : base("OpaqueError:", ex) { this.obj = ex; this.objMessage = obj.ToString(); } + public OpaqueWithTextError() : base("Unknown Unexpected Error") { } + public OpaqueWithTextError(object obj, string objMessage) : base(obj is Exception ? "OpaqueWithTextError:" : "Opaque obj is not an Exception.", obj as Exception) { this.obj = obj; this.objMessage = objMessage; } + } + +} diff --git a/TestVectorsAwsCryptographicMaterialProviders/runtimes/net/Generated/KeyVectors/TypeConversion.cs b/TestVectorsAwsCryptographicMaterialProviders/runtimes/net/Generated/KeyVectors/TypeConversion.cs index 6e78de744f..d37b12d1ee 100644 --- a/TestVectorsAwsCryptographicMaterialProviders/runtimes/net/Generated/KeyVectors/TypeConversion.cs +++ b/TestVectorsAwsCryptographicMaterialProviders/runtimes/net/Generated/KeyVectors/TypeConversion.cs @@ -995,6 +995,8 @@ public static System.Exception FromDafny_CommonError(software.amazon.cryptograph new string(dafnyVal.dtor_message.Elements)); case software.amazon.cryptography.materialproviderstestvectorkeys.internaldafny.types.Error_Opaque dafnyVal: return new OpaqueError(dafnyVal._obj); + case software.amazon.cryptography.materialproviderstestvectorkeys.internaldafny.types.Error_OpaqueWithText dafnyVal: + return new OpaqueWithTextError(dafnyVal._obj, dafnyVal._obj.ToString()); default: // The switch MUST be complete for _IError, so `value` MUST NOT be an _IError. (How did you get here?) return new OpaqueError(); diff --git a/TestVectorsAwsCryptographicMaterialProviders/runtimes/net/Generated/TestVectorsAwsCryptographicMaterialProviders/TypeConversion.cs b/TestVectorsAwsCryptographicMaterialProviders/runtimes/net/Generated/TestVectorsAwsCryptographicMaterialProviders/TypeConversion.cs index e477a78825..0fa25a68ca 100644 --- a/TestVectorsAwsCryptographicMaterialProviders/runtimes/net/Generated/TestVectorsAwsCryptographicMaterialProviders/TypeConversion.cs +++ b/TestVectorsAwsCryptographicMaterialProviders/runtimes/net/Generated/TestVectorsAwsCryptographicMaterialProviders/TypeConversion.cs @@ -3898,6 +3898,8 @@ public static System.Exception FromDafny_CommonError(software.amazon.cryptograph new string(dafnyVal.dtor_message.Elements)); case software.amazon.cryptography.materialproviders.internaldafny.types.Error_Opaque dafnyVal: return new OpaqueError(dafnyVal._obj); + case software.amazon.cryptography.materialproviders.internaldafny.types.Error_OpaqueWithText dafnyVal: + return new OpaqueWithTextError(dafnyVal._obj, dafnyVal._obj.ToString()); default: // The switch MUST be complete for _IError, so `value` MUST NOT be an _IError. (How did you get here?) return new OpaqueError(); diff --git a/TestVectorsAwsCryptographicMaterialProviders/runtimes/python/src/aws_cryptography_materialproviders_test_vectors/internaldafny/generated/dafny_src-py.dtr b/TestVectorsAwsCryptographicMaterialProviders/runtimes/python/src/aws_cryptography_materialproviders_test_vectors/internaldafny/generated/dafny_src-py.dtr index 9834541b50..b59cf4040a 100644 --- a/TestVectorsAwsCryptographicMaterialProviders/runtimes/python/src/aws_cryptography_materialproviders_test_vectors/internaldafny/generated/dafny_src-py.dtr +++ b/TestVectorsAwsCryptographicMaterialProviders/runtimes/python/src/aws_cryptography_materialproviders_test_vectors/internaldafny/generated/dafny_src-py.dtr @@ -1,5 +1,5 @@ file_format_version = "1.0" -dafny_version = "4.8.1.0" +dafny_version = "4.8.0.0" [options_by_module.MplManifestOptions] legacy-module-names = false python-module-name = "aws_cryptography_materialproviders_test_vectors.internaldafny.generated" diff --git a/TestVectorsAwsCryptographicMaterialProviders/runtimes/python/src/aws_cryptography_materialproviders_test_vectors/smithygenerated/aws_cryptography_materialproviderstestvectorkeys/deserialize.py b/TestVectorsAwsCryptographicMaterialProviders/runtimes/python/src/aws_cryptography_materialproviders_test_vectors/smithygenerated/aws_cryptography_materialproviderstestvectorkeys/deserialize.py index 42b5a9f6d8..57535e2980 100644 --- a/TestVectorsAwsCryptographicMaterialProviders/runtimes/python/src/aws_cryptography_materialproviders_test_vectors/smithygenerated/aws_cryptography_materialproviderstestvectorkeys/deserialize.py +++ b/TestVectorsAwsCryptographicMaterialProviders/runtimes/python/src/aws_cryptography_materialproviders_test_vectors/smithygenerated/aws_cryptography_materialproviderstestvectorkeys/deserialize.py @@ -70,6 +70,8 @@ def _deserialize_serialize_key_description(input: DafnyResponse, config: Config) def _deserialize_error(error: Error) -> ServiceError: if error.is_Opaque: return OpaqueError(obj=error.obj) + elif error.is_OpaqueWithText: + return OpaqueErrorWithText(obj=error.obj, obj_message=error.objMessage) elif error.is_CollectionOfErrors: return CollectionOfErrors( message=_dafny.string_of(error.message), diff --git a/TestVectorsAwsCryptographicMaterialProviders/runtimes/python/src/aws_cryptography_materialproviders_test_vectors/smithygenerated/aws_cryptography_materialproviderstestvectorkeys/errors.py b/TestVectorsAwsCryptographicMaterialProviders/runtimes/python/src/aws_cryptography_materialproviders_test_vectors/smithygenerated/aws_cryptography_materialproviderstestvectorkeys/errors.py index d06847e71e..1dcd143df6 100644 --- a/TestVectorsAwsCryptographicMaterialProviders/runtimes/python/src/aws_cryptography_materialproviders_test_vectors/smithygenerated/aws_cryptography_materialproviderstestvectorkeys/errors.py +++ b/TestVectorsAwsCryptographicMaterialProviders/runtimes/python/src/aws_cryptography_materialproviders_test_vectors/smithygenerated/aws_cryptography_materialproviderstestvectorkeys/errors.py @@ -184,6 +184,64 @@ def __eq__(self, other: Any) -> bool: return all(getattr(self, a) == getattr(other, a) for a in attributes) +class OpaqueWithTextError(ApiError[Literal["OpaqueWithTextError"]]): + code: Literal["OpaqueWithTextError"] = "OpaqueWithTextError" + obj: Any # As an OpaqueWithTextError, type of obj is unknown + obj_message: str # obj_message is a message representing the details of obj + + def __init__(self, *, obj, obj_message): + super().__init__("") + self.obj = obj + self.obj_message = obj_message + + def as_dict(self) -> Dict[str, Any]: + """Converts the OpaqueWithTextError to a dictionary. + + The dictionary uses the modeled shape names rather than the + parameter names as keys to be mostly compatible with boto3. + """ + return { + "message": self.message, + "code": self.code, + "obj": self.obj, + "obj_message": self.obj_message, + } + + @staticmethod + def from_dict(d: Dict[str, Any]) -> "OpaqueWithTextError": + """Creates a OpaqueWithTextError from a dictionary. + + The dictionary is expected to use the modeled shape names rather + than the parameter names as keys to be mostly compatible with + boto3. + """ + kwargs: Dict[str, Any] = { + "message": d["message"], + "obj": d["obj"], + "obj_message": d["obj_message"], + } + + return OpaqueWithTextError(**kwargs) + + def __repr__(self) -> str: + result = "OpaqueWithTextError(" + result += f"message={self.message}," + if self.message is not None: + result += f"message={repr(self.message)}" + result += f"obj={self.obj}" + result += f"obj_message={self.obj_message}" + result += ")" + return result + + def __eq__(self, other: Any) -> bool: + if not isinstance(other, OpaqueWithTextError): + return False + if not (self.obj == other.obj): + return False + attributes: list[str] = ["message", "message"] + return all(getattr(self, a) == getattr(other, a) for a in attributes) + + def _smithy_error_to_dafny_error(e: ServiceError): """Converts the provided native Smithy-modeled error into the corresponding Dafny error.""" @@ -208,6 +266,11 @@ def _smithy_error_to_dafny_error(e: ServiceError): obj=e.obj ) + if isinstance(e, OpaqueWithTextError): + return aws_cryptography_materialproviders_test_vectors.internaldafny.generated.AwsCryptographyMaterialProvidersTestVectorKeysTypes.Error_OpaqueWithText( + obj=e.obj, objMessage=e.obj_message + ) + else: return aws_cryptography_materialproviders_test_vectors.internaldafny.generated.AwsCryptographyMaterialProvidersTestVectorKeysTypes.Error_Opaque( obj=e diff --git a/TestVectorsAwsCryptographicMaterialProviders/runtimes/python/test/internaldafny/generated/dafny_test-py.dtr b/TestVectorsAwsCryptographicMaterialProviders/runtimes/python/test/internaldafny/generated/dafny_test-py.dtr index 8f383e665a..daf2aeba5c 100644 --- a/TestVectorsAwsCryptographicMaterialProviders/runtimes/python/test/internaldafny/generated/dafny_test-py.dtr +++ b/TestVectorsAwsCryptographicMaterialProviders/runtimes/python/test/internaldafny/generated/dafny_test-py.dtr @@ -1,4 +1,4 @@ file_format_version = "1.0" -dafny_version = "4.8.1.0" +dafny_version = "4.8.0.0" [options_by_module.TestWrappedMaterialProvidersMain] legacy-module-names = false diff --git a/TestVectorsAwsCryptographicMaterialProviders/runtimes/python/tox.ini b/TestVectorsAwsCryptographicMaterialProviders/runtimes/python/tox.ini index b3761f5c7d..330522cdb2 100644 --- a/TestVectorsAwsCryptographicMaterialProviders/runtimes/python/tox.ini +++ b/TestVectorsAwsCryptographicMaterialProviders/runtimes/python/tox.ini @@ -1,7 +1,7 @@ [tox] isolated_build = True envlist = - py{311,312}-{dafnytests,cli} + py{311,312,313}-{dafnytests,cli} [testenv:dafnytests] skip_install = true diff --git a/TestVectorsAwsCryptographicMaterialProviders/runtimes/rust/.gitignore b/TestVectorsAwsCryptographicMaterialProviders/runtimes/rust/.gitignore new file mode 100644 index 0000000000..7f68976c1a --- /dev/null +++ b/TestVectorsAwsCryptographicMaterialProviders/runtimes/rust/.gitignore @@ -0,0 +1,40 @@ +target +src/wrapped +src/wrapped.rs +src/uuid.rs +src/types +src/types.rs +src/timer.rs +src/time.rs +src/storm_tracker.rs +src/standard_library_externs.rs +src/standard_library_conversions.rs +src/software_externs.rs +src/sets.rs +src/rsa.rs +src/random.rs +src/operation +src/operation.rs +src/local_cmc.rs +src/kms.rs +src/implementation_from_dafny.rs +src/hmac.rs +src/error +src/error.rs +src/ecdsa.rs +src/ecdh.rs +src/digest.rs +src/deps +src/deps.rs +src/ddb.rs +src/dafny_libraries.rs +src/conversions +src/conversions.rs +src/concurrent_call.rs +src/client +src/client.rs +src/aes_kdf_ctr.rs +src/aes_gcm.rs +Cargo.lock + +/*.json diff --git a/TestVectorsAwsCryptographicMaterialProviders/runtimes/rust/Cargo.toml b/TestVectorsAwsCryptographicMaterialProviders/runtimes/rust/Cargo.toml new file mode 100644 index 0000000000..d71a3bbe3f --- /dev/null +++ b/TestVectorsAwsCryptographicMaterialProviders/runtimes/rust/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "aws-mpl-test-vectors" +version = "0.1.0" +edition = "2021" +rust-version = "1.80.0" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[features] +wrapped-client = [] + +[dependencies] +aws-config = "1.5.8" +aws-lc-rs = "1.10.0" +aws-lc-sys = "0.22.0" +aws-sdk-dynamodb = "1.50.0" +aws-sdk-kms = "1.47.0" +aws-smithy-runtime-api = {version = "1.7.2", features = ["client"] } +aws-smithy-types = "1.2.8" +chrono = "0.4.38" +cpu-time = "1.0.0" +dafny_runtime = { path = "../../../smithy-dafny/TestModels/dafny-dependencies/dafny_runtime_rust"} +dashmap = "6.1.0" +pem = "3.0.4" +tokio = {version = "1.41.0", features = ["full"] } +uuid = { version = "1.11.0", features = ["v4"] } + +[dev-dependencies] +aws-mpl-test-vectors = { path = ".", features = ["wrapped-client"] } + +[[bin]] +name = "test-vectors" +path = "src/main.rs" \ No newline at end of file diff --git a/TestVectorsAwsCryptographicMaterialProviders/runtimes/rust/copy_externs.sh b/TestVectorsAwsCryptographicMaterialProviders/runtimes/rust/copy_externs.sh new file mode 100755 index 0000000000..d8b1fc7a4f --- /dev/null +++ b/TestVectorsAwsCryptographicMaterialProviders/runtimes/rust/copy_externs.sh @@ -0,0 +1,24 @@ +#!/bin/bash -eu + +cd $( dirname ${BASH_SOURCE[0]} ) + +SRC=../../../AwsCryptographicMaterialProviders/runtimes/rust/src/ + +cp $SRC/aes_gcm.rs src +cp $SRC/aes_kdf_ctr.rs src +cp $SRC/concurrent_call.rs src +cp $SRC/dafny_libraries.rs src +cp $SRC/ddb.rs src +cp $SRC/digest.rs src +cp $SRC/ecdh.rs src +cp $SRC/ecdsa.rs src +cp $SRC/hmac.rs src +cp $SRC/kms.rs src +cp $SRC/local_cmc.rs src +cp $SRC/random.rs src +cp $SRC/rsa.rs src +cp $SRC/sets.rs src +cp $SRC/software_externs.rs src +cp $SRC/storm_tracker.rs src +cp $SRC/time.rs src +cp $SRC/uuid.rs src diff --git a/TestVectorsAwsCryptographicMaterialProviders/runtimes/rust/src/main.rs b/TestVectorsAwsCryptographicMaterialProviders/runtimes/rust/src/main.rs new file mode 100644 index 0000000000..94333fe6c0 --- /dev/null +++ b/TestVectorsAwsCryptographicMaterialProviders/runtimes/rust/src/main.rs @@ -0,0 +1,71 @@ +#![allow( + deprecated, + non_upper_case_globals, + unused, + non_snake_case, + non_camel_case_types, + unexpected_cfgs +)] + +pub mod client; +pub mod conversions; +pub mod deps; +pub mod error; +pub mod operation; +pub mod types; +pub mod wrapped; + +pub(crate) mod standard_library_conversions; +pub(crate) mod standard_library_externs; +pub use client::Client; + +pub use crate::deps::aws_cryptography_primitives; +pub use crate::deps::aws_cryptography_keyStore; +pub use crate::deps::com_amazonaws_dynamodb; +pub use crate::deps::com_amazonaws_kms; + +pub(crate) mod implementation_from_dafny; + +pub mod aes_gcm; +pub mod aes_kdf_ctr; +pub mod concurrent_call; +pub mod dafny_libraries; +pub mod ddb; +pub mod digest; +pub mod ecdh; +pub mod ecdsa; +pub mod hmac; +pub mod kms; +pub mod local_cmc; +pub mod random; +pub mod rsa; +pub mod sets; +pub mod software_externs; +pub mod storm_tracker; +pub mod test_vec_dir; +pub mod time; +pub mod uuid; + +pub(crate) use crate::implementation_from_dafny::r#_Wrappers_Compile; +pub(crate) use crate::implementation_from_dafny::software; +pub(crate) use crate::implementation_from_dafny::AesKdfCtr; +pub(crate) use crate::implementation_from_dafny::ConcurrentCall; +pub(crate) use crate::implementation_from_dafny::DafnyLibraries; +pub(crate) use crate::implementation_from_dafny::ExternDigest; +pub(crate) use crate::implementation_from_dafny::ExternRandom; +pub(crate) use crate::implementation_from_dafny::Signature; +pub(crate) use crate::implementation_from_dafny::Time; +pub(crate) use crate::implementation_from_dafny::ECDH; +pub(crate) use crate::implementation_from_dafny::HMAC; +pub(crate) use crate::implementation_from_dafny::UTF8; +pub(crate) use crate::implementation_from_dafny::UUID; +pub(crate) use crate::implementation_from_dafny::_StormTracker_Compile; +pub(crate) use crate::implementation_from_dafny::_LocalCMC_Compile; +pub(crate) use crate::implementation_from_dafny::_TestWrappedMaterialProvidersMain_Compile; + +fn main() { + let args: Vec = std::env::args().collect(); + let dafny_strings = args.iter().map(|x| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(&x)).collect::>(); + let dafny_args = dafny_runtime::Sequence::from_array_owned(dafny_strings); + crate::implementation_from_dafny::r#_WrappedMaterialProvidersMain_Compile::_default::Main(&dafny_args); +} \ No newline at end of file diff --git a/TestVectorsAwsCryptographicMaterialProviders/runtimes/rust/src/test_vec_dir.rs b/TestVectorsAwsCryptographicMaterialProviders/runtimes/rust/src/test_vec_dir.rs new file mode 100644 index 0000000000..198e02a2ee --- /dev/null +++ b/TestVectorsAwsCryptographicMaterialProviders/runtimes/rust/src/test_vec_dir.rs @@ -0,0 +1,17 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +#![deny(warnings, unconditional_panic)] +#![deny(nonstandard_style)] +#![deny(clippy::all)] + +use dafny_runtime::Sequence; +use dafny_runtime::dafny_runtime_conversions::DafnyCharUTF16; + +impl crate::_TestWrappedMaterialProvidersMain_Compile::_default { + #[allow(non_snake_case)] + pub fn GetTestVectorExecutionDirectory() -> Sequence + { + dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string("../../") + } +} diff --git a/libraries b/libraries index 9ed496a338..7af1ae1b99 160000 --- a/libraries +++ b/libraries @@ -1 +1 @@ -Subproject commit 9ed496a338e32a3f70226cee0c2e5b230a3c9435 +Subproject commit 7af1ae1b99aa893616db42c0ddeb5af6827b1524 diff --git a/project.properties b/project.properties index 391a641821..bdc86a0f67 100644 --- a/project.properties +++ b/project.properties @@ -5,6 +5,6 @@ # export `export `cat ./aws-cryptographic-material-providers-library-dafny/project.properties` # The Java project include this file as a Gradle properties # And the Dotnet projects include and parse this file. -dafnyVersion=4.8.0 -dafnyVerifyVersion=4.8.0 -mplVersion=1.7.3-SNAPSHOT +dafnyVersion=4.9.0 +dafnyVerifyVersion=4.9.0 +mplVersion=1.7.4-SNAPSHOT diff --git a/smithy-dafny b/smithy-dafny index 782f314bb5..25bdd91759 160000 --- a/smithy-dafny +++ b/smithy-dafny @@ -1 +1 @@ -Subproject commit 782f314bb5ce3277a308361d38929b204a357ba1 +Subproject commit 25bdd9175994285c83cf35e0c88e5536a3843728