├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ └── aws-encryption-sdk-issue.md ├── PULL_REQUEST_TEMPLATE.md ├── dependabot.yml └── workflows │ ├── ci.yml │ └── repo-sync.yml ├── .gitignore ├── .gitmodules ├── .releaserc ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── NOTICE.txt ├── README-JML.md ├── README.md ├── SUPPORT_POLICY.rst ├── VERSIONING.rst ├── cfn ├── Public-ESDK-Java-CI.yml ├── ci_cd.yml ├── code_artifact.yml └── code_build_parameter_map.json ├── codebuild ├── ci │ ├── net-vectors-ci.yml │ ├── release-ci.yml │ ├── settings.xml │ ├── static-analysis.yml │ ├── validate-ci.yml │ ├── vectors-ci-mkp.yml │ ├── vectors-ci.yml │ └── vectors-generator.yml └── release │ ├── artifact-hunt.yml │ ├── javadoc.yml │ ├── release-prod.yml │ ├── release-staging.yml │ ├── release.yml │ ├── settings.xml │ ├── upload_artifacts.yml │ ├── validate-prod.yml │ ├── validate-staging.yml │ └── version.yml ├── look_4_version.sh ├── pom.xml ├── src ├── examples │ └── java │ │ └── com │ │ └── amazonaws │ │ └── crypto │ │ └── examples │ │ ├── keyrings │ │ ├── AwsKmsRsaKeyringExample.java │ │ ├── BasicEncryptionKeyringExample.java │ │ ├── CustomizeSDKClient.java │ │ ├── DiscoveryDecryptionKeyringExample.java │ │ ├── DiscoveryMultiRegionDecryptionKeyringExample.java │ │ ├── EscrowedEncryptKeyringExample.java │ │ ├── FileStreamingKeyringExample.java │ │ ├── MultiKeyringExample.java │ │ ├── MultipleCmkEncryptKeyringExample.java │ │ ├── RawAesKeyringExample.java │ │ ├── RawRsaKeyringExample.java │ │ ├── RequiredEncryptionContextCMMExample.java │ │ ├── SetCommitmentPolicyKeyringExample.java │ │ ├── SetEncryptionAlgorithmKeyringExample.java │ │ ├── StreamingWithRequiredEncryptionContextCMMExample.java │ │ └── hierarchical │ │ │ ├── AwsKmsHierarchicalKeyringExample.java │ │ │ ├── CreateBranchKeyId.java │ │ │ ├── ExampleBranchKeyIdSupplier.java │ │ │ ├── SharedCacheAcrossHierarchicalKeyringsExample.java │ │ │ └── VersionBranchKeyId.java │ │ └── v2 │ │ ├── BasicEncryptionExample.java │ │ ├── BasicMultiRegionKeyEncryptionExample.java │ │ ├── CustomCMMExample.java │ │ ├── DiscoveryDecryptionExample.java │ │ ├── DiscoveryMultiRegionDecryptionExample.java │ │ ├── EscrowedEncryptExample.java │ │ ├── FileStreamingExample.java │ │ ├── MultipleCmkEncryptExample.java │ │ ├── RestrictRegionExample.java │ │ ├── SetCommitmentPolicyExample.java │ │ ├── SetEncryptionAlgorithmExample.java │ │ └── SimpleDataKeyCachingExample.java ├── main │ ├── java │ │ └── com │ │ │ └── amazonaws │ │ │ └── encryptionsdk │ │ │ ├── AwsCrypto.java │ │ │ ├── CMMHandler.java │ │ │ ├── CommitmentPolicy.java │ │ │ ├── CryptoAlgorithm.java │ │ │ ├── CryptoInputStream.java │ │ │ ├── CryptoMaterialsManager.java │ │ │ ├── CryptoOutputStream.java │ │ │ ├── CryptoResult.java │ │ │ ├── DataKey.java │ │ │ ├── DefaultCryptoMaterialsManager.java │ │ │ ├── EncryptedDataKey.java │ │ │ ├── MasterKey.java │ │ │ ├── MasterKeyProvider.java │ │ │ ├── MasterKeyRequest.java │ │ │ ├── ParsedCiphertext.java │ │ │ ├── caching │ │ │ ├── CachingCryptoMaterialsManager.java │ │ │ ├── CryptoMaterialsCache.java │ │ │ ├── LocalCryptoMaterialsCache.java │ │ │ ├── MsClock.java │ │ │ └── NullCryptoMaterialsCache.java │ │ │ ├── exception │ │ │ ├── AwsCryptoException.java │ │ │ ├── BadCiphertextException.java │ │ │ ├── CannotUnwrapDataKeyException.java │ │ │ ├── NoSuchMasterKeyException.java │ │ │ ├── ParseException.java │ │ │ ├── UnsupportedProviderException.java │ │ │ └── package-info.java │ │ │ ├── internal │ │ │ ├── AesGcmJceKeyCipher.java │ │ │ ├── AwsKmsCmkArnInfo.java │ │ │ ├── BlockDecryptionHandler.java │ │ │ ├── BlockEncryptionHandler.java │ │ │ ├── CipherHandler.java │ │ │ ├── CommittedKey.java │ │ │ ├── Constants.java │ │ │ ├── CryptoHandler.java │ │ │ ├── DecryptionHandler.java │ │ │ ├── EncryptionContextSerializer.java │ │ │ ├── EncryptionHandler.java │ │ │ ├── FrameDecryptionHandler.java │ │ │ ├── FrameEncryptionHandler.java │ │ │ ├── HmacKeyDerivationFunction.java │ │ │ ├── JceKeyCipher.java │ │ │ ├── LazyMessageCryptoHandler.java │ │ │ ├── MessageCryptoHandler.java │ │ │ ├── PrimitivesParser.java │ │ │ ├── ProcessingSummary.java │ │ │ ├── RsaJceKeyCipher.java │ │ │ ├── SignaturePolicy.java │ │ │ ├── TrailingSignatureAlgorithm.java │ │ │ ├── Utils.java │ │ │ ├── VersionInfo.java │ │ │ └── package-info.java │ │ │ ├── jce │ │ │ ├── JceMasterKey.java │ │ │ ├── KeyStoreProvider.java │ │ │ └── package-info.java │ │ │ ├── kms │ │ │ ├── AwsKmsMrkAwareMasterKey.java │ │ │ ├── AwsKmsMrkAwareMasterKeyProvider.java │ │ │ ├── DiscoveryFilter.java │ │ │ ├── KmsMasterKey.java │ │ │ ├── KmsMasterKeyProvider.java │ │ │ ├── KmsMethods.java │ │ │ └── package-info.java │ │ │ ├── kmssdkv2 │ │ │ ├── AwsKmsMrkAwareMasterKey.java │ │ │ ├── AwsKmsMrkAwareMasterKeyProvider.java │ │ │ ├── KmsMasterKey.java │ │ │ ├── KmsMasterKeyProvider.java │ │ │ ├── RegionalClientSupplier.java │ │ │ ├── RequestClientCacher.java │ │ │ └── package-info.java │ │ │ ├── model │ │ │ ├── CipherBlockHeaders.java │ │ │ ├── CipherFrameHeaders.java │ │ │ ├── CiphertextFooters.java │ │ │ ├── CiphertextHeaders.java │ │ │ ├── CiphertextType.java │ │ │ ├── ContentType.java │ │ │ ├── DecryptionMaterials.java │ │ │ ├── DecryptionMaterialsHandler.java │ │ │ ├── DecryptionMaterialsRequest.java │ │ │ ├── EncryptionCompletionListener.java │ │ │ ├── EncryptionMaterials.java │ │ │ ├── EncryptionMaterialsHandler.java │ │ │ ├── EncryptionMaterialsRequest.java │ │ │ ├── KeyBlob.java │ │ │ └── package-info.java │ │ │ ├── multi │ │ │ ├── MultipleProviderFactory.java │ │ │ └── package-info.java │ │ │ └── package-info.java │ └── resources │ │ └── project.properties └── test │ ├── java │ └── com │ │ └── amazonaws │ │ ├── crypto │ │ └── examples │ │ │ ├── keyrings │ │ │ ├── AwsKmsHierarchicalKeyringExampleTest.java │ │ │ ├── AwsKmsRsaKeyringExampleTest.java │ │ │ ├── BasicEncryptionKeyringExampleTest.java │ │ │ ├── CustomizeSDKClientTest.java │ │ │ ├── DiscoveryDecryptionKeyringExampleTest.java │ │ │ ├── DiscoveryMultiRegionDecryptionKeyringExampleTest.java │ │ │ ├── MultiKeyringExampleTest.java │ │ │ ├── MultipleCmkEncryptKeyringExampleTest.java │ │ │ ├── RawAesKeyringExampleTest.java │ │ │ ├── RawRsaKeyringExampleTest.java │ │ │ ├── RequiredEncryptionContextCMMExampleTest.java │ │ │ ├── SetCommitmentPolicyKeyringExampleTest.java │ │ │ ├── SetEncryptionAlgorithmKeyringExampleTest.java │ │ │ ├── SharedCacheAcrossHierarchicalKeyringsExampleTest.java │ │ │ └── StreamingWithRequiredEncryptionContextCMMExampleTest.java │ │ │ └── v2 │ │ │ ├── BasicEncryptionExampleTest.java │ │ │ ├── BasicMultiRegionKeyEncryptionExampleTest.java │ │ │ ├── CustomCMMExampleTest.java │ │ │ ├── DiscoveryDecryptionExampleTest.java │ │ │ ├── DiscoveryMultiRegionDecryptionExampleTest.java │ │ │ ├── MultipleCmkEncryptExampleTest.java │ │ │ ├── RestrictRegionExampleTest.java │ │ │ ├── SetCommitmentPolicyExampleTest.java │ │ │ ├── SetEncryptionAlgorithmExampleTest.java │ │ │ ├── SimpleDataKeyCachingExampleTest.java │ │ │ └── V2DefaultCryptoMaterialsManager.java │ │ └── encryptionsdk │ │ ├── AllTestsSuite.java │ │ ├── AwsCryptoIntegrationTest.java │ │ ├── AwsCryptoTest.java │ │ ├── CMMHandlerTest.java │ │ ├── CommitmentKATRunner.java │ │ ├── CryptoAlgorithmTest.java │ │ ├── CryptoInputStreamTest.java │ │ ├── CryptoOutputStreamTest.java │ │ ├── DecryptionMethod.java │ │ ├── DefaultCryptoMaterialsManagerTest.java │ │ ├── EncryptionContextCMMTest.java │ │ ├── FastTestsOnlySuite.java │ │ ├── Fixtures.java │ │ ├── IntegrationTestSuite.java │ │ ├── ParsedCiphertextTest.java │ │ ├── RecordingMaterialsManager.java │ │ ├── SlowTestCategory.java │ │ ├── TestUtils.java │ │ ├── TestVectorGenerator.java │ │ ├── TestVectorRunner.java │ │ ├── XCompatDecryptTest.java │ │ ├── caching │ │ ├── CacheIdentifierTests.java │ │ ├── CacheTestFixtures.java │ │ ├── CachingCryptoMaterialsManagerTest.java │ │ ├── LocalCryptoMaterialsCacheTest.java │ │ ├── LocalCryptoMaterialsCacheThreadStormTest.java │ │ └── NullCryptoMaterialsCacheTest.java │ │ ├── internal │ │ ├── AwsKmsCmkArnInfoTest.java │ │ ├── BlockDecryptionHandlerTest.java │ │ ├── BlockEncryptionHandlerTest.java │ │ ├── CipherHandlerTest.java │ │ ├── CommittedKeyTest.java │ │ ├── DecryptionHandlerTest.java │ │ ├── EncContextSerializerTest.java │ │ ├── EncryptionHandlerTest.java │ │ ├── FrameDecryptionHandlerTest.java │ │ ├── FrameEncryptionHandlerTest.java │ │ ├── FrameEncryptionHandlerVeryLongTest.java │ │ ├── HmacKeyDerivationFunctionTest.java │ │ ├── PrimitivesParserTest.java │ │ ├── RandomBytesGenerator.java │ │ ├── StaticMasterKey.java │ │ ├── TestIOUtils.java │ │ ├── TrailingSignatureAlgorithmTest.java │ │ ├── UtilsTest.java │ │ └── VersionInfoTest.java │ │ ├── jce │ │ ├── JceMasterKeyTest.java │ │ └── KeyStoreProviderTest.java │ │ ├── kms │ │ ├── AwsKmsMrkAwareMasterKeyProviderTest.java │ │ ├── AwsKmsMrkAwareMasterKeyTest.java │ │ ├── DiscoveryFilterTest.java │ │ ├── KMSProviderBuilderIntegrationTests.java │ │ ├── KMSProviderBuilderMockTests.java │ │ ├── KMSTestFixtures.java │ │ ├── KmsMasterKeyProviderTest.java │ │ ├── KmsMasterKeyTest.java │ │ ├── MaxEncryptedDataKeysIntegrationTest.java │ │ ├── MockKMSClient.java │ │ └── XCompatKmsDecryptTest.java │ │ ├── kmssdkv2 │ │ ├── AwsKmsMrkAwareMasterKeyProviderTest.java │ │ ├── AwsKmsMrkAwareMasterKeyTest.java │ │ ├── KMSProviderBuilderIntegrationTests.java │ │ ├── KMSProviderBuilderMockTests.java │ │ ├── KmsMasterKeyProviderTest.java │ │ ├── KmsMasterKeyTest.java │ │ ├── MaxEncryptedDataKeysIntegrationTest.java │ │ ├── MockKmsClient.java │ │ ├── ProxyCredentialsProvider.java │ │ ├── ProxyKmsClient.java │ │ └── XCompatKmsDecryptTest.java │ │ ├── model │ │ ├── ByteFormatCheckValues.java │ │ ├── CipherBlockHeadersTest.java │ │ ├── CipherFrameHeadersTest.java │ │ ├── CiphertextHeadersTest.java │ │ ├── DecryptionMaterialsRequestTest.java │ │ ├── DecryptionMaterialsTest.java │ │ ├── EncryptionMaterialsRequestTest.java │ │ └── KeyBlobTest.java │ │ └── multi │ │ └── MultipleMasterKeyTest.java │ └── resources │ ├── commitment-test-vectors.json │ └── keys.json └── util ├── duvet-report.sh └── test-conditions.sh /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Each line is a file pattern followed by one or more owners. 2 | # https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners 3 | 4 | # Default code owner for everything is our aws-crypto-tools group 5 | * @aws/aws-crypto-tools 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/aws-encryption-sdk-issue.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: AWS Encryption SDK Issue 3 | about: AWS Encryption SDK Issue 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ### Security issue notifications 11 | 12 | If you discover a potential security issue in the AWS Encryption SDK we ask that you notify AWS Security via our [vulnerability reporting page](https://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public GitHub issue. 13 | 14 | ### Problem: 15 | 16 | A short description of what the problem is and why we need to fix it. Add reproduction steps if necessary. 17 | 18 | ### Solution: 19 | 20 | A description of the possible solution in terms of Encryption SDK architecture. 21 | 22 | ### Out of scope: 23 | 24 | Is there anything the solution will intentionally NOT address? 25 | 26 | [//]: # (NOTE: If you believe this might be a security issue, please email aws-security@amazon.com instead of creating a GitHub issue. For more details, see the AWS Vulnerability Reporting Guide: https://aws.amazon.com/security/vulnerability-reporting/ ) 27 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | *Issue #, if available:* 2 | 3 | *Description of changes:* 4 | 5 | 6 | By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license. 7 | 8 | # Check any applicable: 9 | - [ ] Were any files moved? Moving files changes their URL, which breaks all hyperlinks to the files. 10 | 11 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "maven" 4 | directory: "/" 5 | schedule: 6 | interval: "daily" 7 | - package-ecosystem: "github-actions" 8 | directory: "/" 9 | schedule: 10 | interval: "daily" 11 | -------------------------------------------------------------------------------- /.github/workflows/repo-sync.yml: -------------------------------------------------------------------------------- 1 | name: Repo Sync 2 | 3 | on: 4 | workflow_dispatch: # allows triggering this manually through the Actions UI 5 | 6 | jobs: 7 | repo-sync: 8 | name: Repo Sync 9 | environment: repo-sync 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v3 13 | - uses: repo-sync/github-sync@v2 14 | name: Sync repo to branch 15 | with: 16 | source_repo: ${{ secrets.SOURCE_REPO }} 17 | source_branch: master 18 | destination_branch: ${{ secrets.INTERMEDIATE_BRANCH }} 19 | github_token: ${{ secrets.GITHUB_TOKEN }} 20 | - uses: repo-sync/pull-request@v2 21 | name: Create pull request 22 | with: 23 | source_branch: ${{ secrets.INTERMEDIATE_BRANCH }} 24 | destination_branch: master 25 | github_token: ${{ secrets.GITHUB_TOKEN }} 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | eclipse-bin/ 2 | target/ 3 | .settings/ 4 | .project 5 | .classpath 6 | /bin/ 7 | .idea/ 8 | *.iml 9 | /.history 10 | /.DS_Store 11 | /specification_compliance_report.html 12 | .DS_Store 13 | 14 | ## semantic-release 15 | package-lock.json 16 | package.json 17 | node_modules/ 18 | pom.xml.versionsBackup 19 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "src/test/resources/aws-encryption-sdk-test-vectors"] 2 | path = src/test/resources/aws-encryption-sdk-test-vectors 3 | url = https://github.com/awslabs/aws-encryption-sdk-test-vectors.git 4 | [submodule "aws-encryption-sdk-specification"] 5 | path = aws-encryption-sdk-specification 6 | url = https://github.com/awslabs/aws-encryption-sdk-specification.git 7 | [submodule "submodules/MaterialProviders"] 8 | path = submodules/MaterialProviders 9 | url = https://github.com/aws/aws-cryptographic-material-providers-library.git 10 | -------------------------------------------------------------------------------- /.releaserc: -------------------------------------------------------------------------------- 1 | ## Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | ## SPDX-License-Identifier: Apache-2.0 3 | { 4 | "branches": ["master"], 5 | "plugins": [ 6 | ["@semantic-release/commit-analyzer", { 7 | "preset": "conventionalcommits", 8 | "parserOpts": { 9 | "noteKeywords": ["BREAKING CHANGE", "BREAKING CHANGES"] 10 | }, 11 | "presetConfig": { 12 | "types": [ 13 | {"type": "feat", "section": "Features"}, 14 | {"type": "fix", "section": "Fixes"}, 15 | {"type": "chore", "section": "Maintenance"}, 16 | {"type": "docs", "section": "Maintenance"}, 17 | {"type": "revert", "section": "Fixes"}, 18 | {"type": "style", "hidden": true}, 19 | {"type": "refactor", "hidden": true}, 20 | {"type": "perf", "hidden": true}, 21 | {"type": "test", "hidden": true} 22 | ] 23 | }, 24 | "releaseRules": [ 25 | {"type": "docs", "release": "patch"}, 26 | {"type": "revert", "release": "patch"}, 27 | {"type": "chore", "release": "patch"} 28 | ] 29 | }], 30 | ["@semantic-release/release-notes-generator", { 31 | "preset": "conventionalcommits", 32 | "parserOpts": { 33 | "noteKeywords": ["BREAKING CHANGE", "BREAKING CHANGES"] 34 | }, 35 | "presetConfig": { 36 | "types": [ 37 | {"type": "feat", "section": "Features"}, 38 | {"type": "fix", "section": "Fixes"}, 39 | {"type": "chore", "section": "Maintenance"}, 40 | {"type": "docs", "section": "Maintenance"}, 41 | {"type": "revert", "section": "Fixes"}, 42 | {"type": "style", "hidden": true}, 43 | {"type": "refactor", "hidden": true}, 44 | {"type": "perf", "hidden": true}, 45 | {"type": "test", "hidden": true} 46 | ] 47 | } 48 | }], 49 | ["@semantic-release/changelog", { 50 | "changelogFile": "./CHANGELOG.md", 51 | "changelogTitle": "# Changelog" 52 | }], 53 | ["@semantic-release/exec", { 54 | "prepareCmd": "mvn versions:set -DnewVersion=${nextRelease.version} \ 55 | -DautoVersionSubmodules=true && find README.md -type f \ 56 | -exec sed -i 's/.*<\\/version>/${nextRelease.version}<\\/version>/g' {} \\;" 57 | }], 58 | ["@semantic-release/git", { 59 | "assets": ["./CHANGELOG.md", "./pom.xml", "./README.md"], 60 | "message": "AWS Encryption SDK ${nextRelease.version} Release -- ${new Date().toISOString().slice(0, 10)} \n\n${nextRelease.notes}" 61 | }], 62 | ], 63 | "repositoryUrl": "https://github.com/aws/aws-encryption-sdk-java", 64 | } 65 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional 4 | documentation, we greatly value feedback and contributions from our community. 5 | 6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 7 | information to effectively respond to your bug report or contribution. 8 | 9 | ## Security issue notifications 10 | If you discover a potential security issue in this project, notify AWS/Amazon Security by using our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public GitHub issue. 11 | 12 | ## Reporting Bugs/Feature Requests 13 | 14 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 15 | 16 | When filing an issue, please check [existing open](https://github.com/aws/aws-encryption-sdk-java/issues), or [recently closed](https://github.com/aws/aws-encryption-sdk-java/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aclosed%20), issues to make sure somebody else hasn't already 17 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 18 | 19 | * A reproducible test case or series of steps 20 | * The version of our code being used 21 | * Any modifications you've made relevant to the bug 22 | * Anything unusual about your environment or deployment 23 | 24 | 25 | ## Contributing via Pull Requests 26 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 27 | 28 | 1. You are working against the latest source on the *master* branch. 29 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 30 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 31 | 32 | To send us a pull request, please: 33 | 34 | 1. Fork the repository. 35 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 36 | 3. Ensure local tests pass. 37 | 4. Commit to your fork using clear commit messages. 38 | 5. Send us a pull request, answering any default questions in the pull request interface. 39 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 40 | 41 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 42 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 43 | 44 | 45 | ## Finding contributions to work on 46 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any ['help wanted'](https://github.com/aws/aws-encryption-sdk-java/labels/help%20wanted) issues is a great place to start. 47 | 48 | 49 | ## Code of Conduct 50 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 51 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 52 | opensource-codeofconduct@amazon.com with any additional questions or comments. 53 | 54 | 55 | ## Licensing 56 | 57 | See the [LICENSE](https://github.com/aws/aws-encryption-sdk-java/blob/master/LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. 58 | 59 | We may ask you to sign a [Contributor License Agreement (CLA)](http://en.wikipedia.org/wiki/Contributor_License_Agreement) for larger changes. 60 | -------------------------------------------------------------------------------- /NOTICE.txt: -------------------------------------------------------------------------------- 1 | AWS Encryption SDK 2 | Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | THIRD PARTY COMPONENTS 5 | ********************** 6 | This software includes third party software subject to the following copyrights: 7 | 8 | -Cryptographic functions from Bouncy Castle Crypto APIs for Java - Copyright 9 | 2000-2013 The Legion of the Bouncy Castle 10 | 11 | The licenses for these third party components are included in LICENSE.txt 12 | -------------------------------------------------------------------------------- /SUPPORT_POLICY.rst: -------------------------------------------------------------------------------- 1 | Overview 2 | ======== 3 | This page describes the support policy for the AWS Encryption SDK. We regularly provide the AWS Encryption SDK with updates that may contain support for new or updated APIs, new features, enhancements, bug fixes, security patches, or documentation updates. Updates may also address changes with dependencies, language runtimes, and operating systems. 4 | 5 | We recommend users to stay up-to-date with Encryption SDK releases to keep up with the latest features, security updates, and underlying dependencies. Continued use of an unsupported SDK version is not recommended and is done at the user’s discretion 6 | 7 | 8 | Major Version Lifecycle 9 | ======================== 10 | The AWS Encryption SDK follows the same major version lifecycle as the AWS SDK. For details on this lifecycle, see `AWS SDKs and Tools Maintenance Policy`_. 11 | 12 | Version Support Matrix 13 | ====================== 14 | This table describes the current support status of each major version of the AWS Encryption SDK for Java. It also shows the next status each major version will transition to, and the date at which that transition will happen. 15 | 16 | .. list-table:: 17 | :widths: 30 50 50 50 18 | :header-rows: 1 19 | 20 | * - Major version 21 | - Current status 22 | - Next status 23 | - Next status date 24 | * - 1.x 25 | - End of Support 26 | - 27 | - 28 | * - 2.x 29 | - Generally Available 30 | - Maintenance Mode 31 | - 2024 32 | * - 3.x 33 | - Generally Available 34 | - 35 | - 36 | 37 | .. _AWS SDKs and Tools Maintenance Policy: https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle 38 | -------------------------------------------------------------------------------- /VERSIONING.rst: -------------------------------------------------------------------------------- 1 | ***************** 2 | Versioning Policy 3 | ***************** 4 | 5 | We use a three-part X.Y.Z (Major.Minor.Patch) versioning definition, as follows: 6 | 7 | * **X (Major)** version changes are significant and expected to break backwards compatibility. 8 | * **Y (Minor)** version changes are moderate changes. These include: 9 | 10 | * Significant non-breaking feature additions. 11 | * Any change to the version of a dependency. 12 | * Possible backwards-incompatible changes. These changes will be noted and explained in detail in the release notes. 13 | 14 | * **Z (Patch)** version changes are small changes. These changes will not break backwards compatibility. 15 | 16 | * Z releases will also include warning of upcoming breaking changes, whenever possible. 17 | 18 | What this means for you 19 | ======================= 20 | 21 | We recommend running the most recent version. Here are our suggestions for managing updates: 22 | 23 | * X changes will require some effort to incorporate. 24 | * Y changes will not require significant effort to incorporate. 25 | 26 | * If you have good unit and integration tests, these changes are generally safe to pick up automatically. 27 | 28 | * Z changes will not require any changes to your code. Z changes are intended to be picked up automatically. 29 | 30 | * Good unit and integration tests are always recommended. 31 | -------------------------------------------------------------------------------- /cfn/Public-ESDK-Java-CI.yml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: "2010-09-09" 2 | Description: "DDB Table and IAM Managed Policies/Role for AWS KMS Hierarchical Keyring Testing" 3 | 4 | Parameters: 5 | TableName: 6 | Type: String 7 | Description: Test Table Name 8 | Default: HierarchicalKeyringTestTable 9 | KeyStoreTable: 10 | Type: String 11 | Description: Key Store Test Table Name 12 | Default: KeyStoreTestTable 13 | ProjectName: 14 | Type: String 15 | Description: A prefix that will be applied to any names 16 | Default: Public-ESDK-Java 17 | GitHubRepo: 18 | Type: String 19 | Description: GitHub Repo that invokes CI 20 | Default: aws/aws-encryption-sdk-java 21 | 22 | Resources: 23 | GitHubCIRole: 24 | Type: 'AWS::IAM::Role' 25 | Properties: 26 | RoleName: !Sub "GitHub-CI-${ProjectName}-Role-${AWS::Region}" 27 | Description: "Access DDB, KMS, Resources for CI from GitHub" 28 | ManagedPolicyArns: 29 | - "arn:aws:iam::370957321024:policy/ESDK-Dafny-DDB-ReadWriteDelete-us-west-2" 30 | - "arn:aws:iam::370957321024:policy/Hierarchical-GitHub-KMS-Key-Policy" 31 | - "arn:aws:iam::370957321024:policy/KMS-Public-CMK-EncryptDecrypt-Key-Access" 32 | - "arn:aws:iam::370957321024:policy/RSA-GitHub-KMS-Key-Policy" 33 | AssumeRolePolicyDocument: !Sub | 34 | { 35 | "Version": "2012-10-17", 36 | "Statement": [ 37 | { 38 | "Effect": "Allow", 39 | "Principal": { "Federated": "arn:aws:iam::${AWS::AccountId}:oidc-provider/token.actions.githubusercontent.com" }, 40 | "Action": "sts:AssumeRoleWithWebIdentity", 41 | "Condition": { 42 | "StringEquals": { 43 | "token.actions.githubusercontent.com:aud": "sts.amazonaws.com" 44 | }, 45 | "StringLike": { 46 | "token.actions.githubusercontent.com:sub": "repo:${GitHubRepo}:*" 47 | } 48 | } 49 | }, 50 | { 51 | "Effect": "Allow", 52 | "Principal": { 53 | "AWS": "*" 54 | }, 55 | "Action": "sts:AssumeRole", 56 | "Condition": { 57 | "StringEquals": { 58 | "aws:PrincipalArn": [ 59 | "arn:aws:iam::587316601012:role/service-role/codebuild-AWS-ESDK-Java-service-role-ci", 60 | "arn:aws:iam::587316601012:role/service-role/codebuild-AWS-ESDK-Java-service-role-release", 61 | "arn:aws:iam::${AWS::AccountId}:role/ToolsDevelopment" 62 | ] 63 | } 64 | } 65 | } 66 | ] 67 | } 68 | -------------------------------------------------------------------------------- /cfn/code_artifact.yml: -------------------------------------------------------------------------------- 1 | # Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | # SPDX-License-Identifier: Apache-2.0 3 | AWSTemplateFormatVersion: 2010-09-09 4 | Description: "Template for CodeArtifact repositories. Creates Domain if CreateDomainFlag is True" 5 | Parameters: 6 | DomainName: 7 | Type: String 8 | Description: The name of the CodeArtifact Domain 9 | Default: crypto-tools-internal 10 | RepositoryName: 11 | Type: String 12 | Description: Base Name for the Repositories 13 | Default: esdk-java 14 | CreateDomainFlag: 15 | Type: String 16 | Description: Attempt to create Domain or not 17 | Default: False 18 | AllowedValues: 19 | - True 20 | - False 21 | 22 | Conditions: 23 | CreateDomain: !Equals 24 | - !Ref CreateDomainFlag 25 | - True 26 | 27 | Resources: 28 | Domain: 29 | Type: AWS::CodeArtifact::Domain 30 | Condition: CreateDomain 31 | Properties: 32 | DomainName: !Ref DomainName 33 | 34 | CIRepo: 35 | Type: AWS::CodeArtifact::Repository 36 | Properties: 37 | DomainName: !Ref DomainName 38 | RepositoryName: !Sub "${RepositoryName}-ci" 39 | 40 | StagingRepo: 41 | Type: AWS::CodeArtifact::Repository 42 | Properties: 43 | DomainName: !Ref DomainName 44 | RepositoryName: !Sub "${RepositoryName}-staging" 45 | -------------------------------------------------------------------------------- /cfn/code_build_parameter_map.json: -------------------------------------------------------------------------------- 1 | { 2 | "NumberOfBuildsInBatch": 50, 3 | "ProjectDescription": "CD for Java ESDK", 4 | "ProjectName": "java-esdk", 5 | "SourceLocation": "https://github.com/aws/aws-encryption-sdk-java.git" 6 | } 7 | -------------------------------------------------------------------------------- /codebuild/ci/net-vectors-ci.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | # Runs Only the ESDK-NET v4.0.1 Decryption Vectors, testing Required EC CMM 3 | phases: 4 | install: 5 | runtime-versions: 6 | java: $JAVA_ENV_VERSION 7 | commands: 8 | - git submodule update --init submodules/MaterialProviders 9 | # Get Dafny 10 | - curl https://github.com/dafny-lang/dafny/releases/download/v4.8.0/dafny-4.8.0-x64-ubuntu-20.04.zip -L -o dafny.zip 11 | - unzip -qq dafny.zip && rm dafny.zip 12 | - export PATH="$PWD/dafny:$PATH" 13 | # Get Gradle 7.6 14 | - curl https://services.gradle.org/distributions/gradle-7.6-all.zip -L -o gradle.zip 15 | - unzip -qq gradle.zip && rm gradle.zip 16 | - export PATH="$PWD/gradle-7.6/bin:$PATH" 17 | pre_build: 18 | commands: 19 | # Assume Role to access non-prod resources 20 | - TMP_ROLE=$(aws sts assume-role --role-arn "arn:aws:iam::370957321024:role/GitHub-CI-Public-ESDK-Java-Role-us-west-2" --role-session-name "CB-TestVectorResources") 21 | - export TMP_ROLE 22 | - export AWS_ACCESS_KEY_ID=$(echo "${TMP_ROLE}" | jq -r '.Credentials.AccessKeyId') 23 | - export AWS_SECRET_ACCESS_KEY=$(echo "${TMP_ROLE}" | jq -r '.Credentials.SecretAccessKey') 24 | - export AWS_SESSION_TOKEN=$(echo "${TMP_ROLE}" | jq -r '.Credentials.SessionToken') 25 | - aws sts get-caller-identity 26 | 27 | # Build and deploy TestVectors to maven local 28 | - cd submodules/MaterialProviders/TestVectorsAwsCryptographicMaterialProviders/ 29 | - make build_java && make mvn_local_deploy 30 | - cd $CODEBUILD_SRC_DIR 31 | 32 | # Fetch ESDK .NET v4.0.1 Test Vectors 33 | - VECTOR_ZIP=$CODEBUILD_SRC_DIR/v4-Net-4.0.1.zip 34 | - VECTORS_URL=https://github.com/aws/aws-encryption-sdk-dafny/raw/mainline/AwsEncryptionSDK/runtimes/net/TestVectorsNative/TestVectors/resources/v4-Net-4.0.1.zip 35 | - curl -s --output $VECTOR_ZIP --location $VECTORS_URL 36 | build: 37 | commands: 38 | # NOTE: We need to pass the absolute path of the vectors 39 | - mvn -B -ntp install -Dgpg.skip=true -Djacoco.skip=true "-Dtest=TestVectorRunner" "-DtestVectorZip=file://$VECTOR_ZIP" 40 | -------------------------------------------------------------------------------- /codebuild/ci/settings.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | codeartifact 8 | aws 9 | ${codeartifact.token} 10 | 11 | 12 | 13 | 14 | 15 | codeartifact 16 | 17 | 18 | codeartifact 19 | codeartifact 20 | ${codeartifact.url} 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /codebuild/ci/static-analysis.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | 3 | phases: 4 | install: 5 | runtime-versions: 6 | nodejs: 12 7 | java: corretto11 8 | build: 9 | commands: 10 | - mvn -T 4 -ntp com.coveo:fmt-maven-plugin:check 11 | - ./util/test-conditions.sh 12 | -------------------------------------------------------------------------------- /codebuild/ci/validate-ci.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | 3 | env: 4 | variables: 5 | REGION: us-east-1 6 | DOMAIN: crypto-tools-internal 7 | REPOSITORY: java-esdk-ci 8 | parameter-store: 9 | ACCOUNT: /CodeBuild/AccountId 10 | 11 | phases: 12 | install: 13 | commands: 14 | - pip install awscli 15 | runtime-versions: 16 | java: $JAVA_ENV_VERSION 17 | pre_build: 18 | commands: 19 | - VERSION_HASH="$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)-$CODEBUILD_RESOLVED_SOURCE_VERSION-$GITHUB_EVENT_NAME" 20 | - export SETTINGS_FILE=$(pwd)/codebuild/ci/settings.xml 21 | - git clone https://github.com/aws-samples/busy-engineers-document-bucket.git 22 | - cd busy-engineers-document-bucket/exercises/java/encryption-context-complete 23 | - export CODEARTIFACT_TOKEN=$(aws codeartifact get-authorization-token --domain $DOMAIN --domain-owner $ACCOUNT --query authorizationToken --output text --region ${REGION}) 24 | - export CODEARTIFACT_REPO_URL=https://${DOMAIN}-${ACCOUNT}.d.codeartifact.${REGION}.amazonaws.com/maven/${REPOSITORY} 25 | build: 26 | commands: 27 | - | 28 | mvn verify \ 29 | -Pcodeartifact \ 30 | -Dcheckstyle.skip \ 31 | -Desdk.version=$VERSION_HASH \ 32 | -Dmaven.compiler.target=$JAVA_NUMERIC_VERSION \ 33 | -Dmaven.compiler.source=$JAVA_NUMERIC_VERSION \ 34 | -Dcodeartifact.token=$CODEARTIFACT_TOKEN \ 35 | -Dcodeartifact.url=$CODEARTIFACT_REPO_URL \ 36 | --no-transfer-progress \ 37 | -T 4 \ 38 | -s $SETTINGS_FILE 39 | -------------------------------------------------------------------------------- /codebuild/ci/vectors-ci-mkp.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | # Runs "Golden Manifest" against legacy Master Key Providers 3 | phases: 4 | install: 5 | runtime-versions: 6 | java: $JAVA_ENV_VERSION 7 | commands: 8 | - git submodule update --init submodules/MaterialProviders 9 | # Get Dafny 10 | - curl https://github.com/dafny-lang/dafny/releases/download/v4.8.0/dafny-4.8.0-x64-ubuntu-20.04.zip -L -o dafny.zip 11 | - unzip -qq dafny.zip && rm dafny.zip 12 | - export PATH="$PWD/dafny:$PATH" 13 | # Get Gradle 7.6 14 | - curl https://services.gradle.org/distributions/gradle-7.6-all.zip -L -o gradle.zip 15 | - unzip -qq gradle.zip && rm gradle.zip 16 | - export PATH="$PWD/gradle-7.6/bin:$PATH" 17 | pre_build: 18 | commands: 19 | # Assume Role to access non-prod resources 20 | - TMP_ROLE=$(aws sts assume-role --role-arn "arn:aws:iam::370957321024:role/GitHub-CI-Public-ESDK-Java-Role-us-west-2" --role-session-name "CB-TestVectorResources") 21 | - export TMP_ROLE 22 | - export AWS_ACCESS_KEY_ID=$(echo "${TMP_ROLE}" | jq -r '.Credentials.AccessKeyId') 23 | - export AWS_SECRET_ACCESS_KEY=$(echo "${TMP_ROLE}" | jq -r '.Credentials.SecretAccessKey') 24 | - export AWS_SESSION_TOKEN=$(echo "${TMP_ROLE}" | jq -r '.Credentials.SessionToken') 25 | - aws sts get-caller-identity 26 | 27 | # Build and deploy TestVectors to maven local 28 | - cd submodules/MaterialProviders/TestVectorsAwsCryptographicMaterialProviders/ 29 | - make build_java && make mvn_local_deploy 30 | - cd $CODEBUILD_SRC_DIR 31 | build: 32 | commands: 33 | # Enable masterKey to run Test Vectors against MasterKeyProvider 34 | # NOTE: We need to pass the absolute path of the vectors 35 | - mvn -B -ntp install -Dgpg.skip=true -Djacoco.skip=true "-Dtest=TestVectorRunner" "-Dmasterkey=true" "-DtestVectorZip=file://$CODEBUILD_SRC_DIR/src/test/resources/aws-encryption-sdk-test-vectors/vectors/awses-decrypt/python-2.3.0.zip" 36 | -------------------------------------------------------------------------------- /codebuild/ci/vectors-ci.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | # Runs "Golden Manifest" against Keyrings 3 | phases: 4 | install: 5 | runtime-versions: 6 | java: $JAVA_ENV_VERSION 7 | commands: 8 | - git submodule update --init submodules/MaterialProviders 9 | # Get Dafny 10 | - curl https://github.com/dafny-lang/dafny/releases/download/v4.8.0/dafny-4.8.0-x64-ubuntu-20.04.zip -L -o dafny.zip 11 | - unzip -qq dafny.zip && rm dafny.zip 12 | - export PATH="$PWD/dafny:$PATH" 13 | # Get Gradle 7.6 14 | - curl https://services.gradle.org/distributions/gradle-7.6-all.zip -L -o gradle.zip 15 | - unzip -qq gradle.zip && rm gradle.zip 16 | - export PATH="$PWD/gradle-7.6/bin:$PATH" 17 | pre_build: 18 | commands: 19 | # Assume Role to access non-prod resources 20 | - TMP_ROLE=$(aws sts assume-role --role-arn "arn:aws:iam::370957321024:role/GitHub-CI-Public-ESDK-Java-Role-us-west-2" --role-session-name "CB-TestVectorResources") 21 | - export TMP_ROLE 22 | - export AWS_ACCESS_KEY_ID=$(echo "${TMP_ROLE}" | jq -r '.Credentials.AccessKeyId') 23 | - export AWS_SECRET_ACCESS_KEY=$(echo "${TMP_ROLE}" | jq -r '.Credentials.SecretAccessKey') 24 | - export AWS_SESSION_TOKEN=$(echo "${TMP_ROLE}" | jq -r '.Credentials.SessionToken') 25 | - aws sts get-caller-identity 26 | 27 | # Build and deploy TestVectors to maven local 28 | - cd submodules/MaterialProviders/TestVectorsAwsCryptographicMaterialProviders/ 29 | - make build_java && make mvn_local_deploy 30 | - cd $CODEBUILD_SRC_DIR 31 | build: 32 | commands: 33 | # NOTE: We need to pass the absolute path of the vectors 34 | - mvn install -T 8 -Dgpg.skip=true -ntp "-DtestVectorZip=file://$CODEBUILD_SRC_DIR/src/test/resources/aws-encryption-sdk-test-vectors/vectors/awses-decrypt/python-2.3.0.zip" 35 | -------------------------------------------------------------------------------- /codebuild/ci/vectors-generator.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | 3 | phases: 4 | install: 5 | runtime-versions: 6 | java: $JAVA_ENV_VERSION 7 | commands: 8 | - n 16 9 | # Install the Javascript ESDK run test vectors 10 | - npm install -g @aws-crypto/integration-node 11 | 12 | - git submodule update --init submodules/MaterialProviders 13 | # Get Dafny 14 | - curl https://github.com/dafny-lang/dafny/releases/download/v4.8.0/dafny-4.8.0-x64-ubuntu-20.04.zip -L -o dafny.zip 15 | - unzip -qq dafny.zip && rm dafny.zip 16 | - export PATH="$PWD/dafny:$PATH" 17 | # Get Gradle 7.6 18 | - curl https://services.gradle.org/distributions/gradle-7.6-all.zip -L -o gradle.zip 19 | - unzip -qq gradle.zip && rm gradle.zip 20 | - export PATH="$PWD/gradle-7.6/bin:$PATH" 21 | pre_build: 22 | commands: 23 | # Assume Role to access non-prod resources 24 | - TMP_ROLE=$(aws sts assume-role --role-arn "arn:aws:iam::370957321024:role/GitHub-CI-Public-ESDK-Java-Role-us-west-2" --role-session-name "CB-TestVectorResources") 25 | - export TMP_ROLE 26 | - export AWS_ACCESS_KEY_ID=$(echo "${TMP_ROLE}" | jq -r '.Credentials.AccessKeyId') 27 | - export AWS_SECRET_ACCESS_KEY=$(echo "${TMP_ROLE}" | jq -r '.Credentials.SecretAccessKey') 28 | - export AWS_SESSION_TOKEN=$(echo "${TMP_ROLE}" | jq -r '.Credentials.SessionToken') 29 | - aws sts get-caller-identity 30 | 31 | # Build and deploy TestVectors to maven local 32 | - cd submodules/MaterialProviders/TestVectorsAwsCryptographicMaterialProviders/ 33 | - make build_java && make mvn_local_deploy 34 | - cd $CODEBUILD_SRC_DIR 35 | build: 36 | commands: 37 | - export VECTORS_ZIP="$CODEBUILD_SRC_DIR/generated_vectors.zip" 38 | # Generate test vectors by encrypting with Keyrings 39 | # Ignore Testing coverage requirement by skipping jacoco 40 | - mvn -B -ntp install -Dgpg.skip=true -Djacoco.skip=true "-Dtest=TestVectorGenerator" "-DzipFilePath=$VECTORS_ZIP" "-DkeysManifest=$CODEBUILD_SRC_DIR/src/test/resources/keys.json" 41 | # Decrypt generated vectors with Javascript ESDK 42 | - integration-node decrypt -v $VECTORS_ZIP 43 | 44 | - rm $VECTORS_ZIP 45 | # Generate test vectors by encrypting with MasterKeys 46 | - mvn -B -ntp install -Dgpg.skip=true -Djacoco.skip=true -Dmasterkey=true "-Dtest=TestVectorGenerator" "-DzipFilePath=$VECTORS_ZIP" "-DkeysManifest=$CODEBUILD_SRC_DIR/src/test/resources/keys.json" 47 | # Decrypt generated vectors with Javascript ESDK 48 | - integration-node decrypt -v $VECTORS_ZIP 49 | -------------------------------------------------------------------------------- /codebuild/release/artifact-hunt.yml: -------------------------------------------------------------------------------- 1 | ## Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | ## SPDX-License-Identifier: Apache-2.0 3 | 4 | version: 0.2 5 | 6 | env: 7 | variables: 8 | BRANCH: "master" 9 | 10 | phases: 11 | install: 12 | runtime-versions: 13 | java: corretto11 14 | pre_build: 15 | commands: 16 | - git checkout $BRANCH 17 | - export VERSION=$(grep version pom.xml | head -n 1 | sed -n 's/[ \t]*\(.*\)<\/version>/\1/p') 18 | build: 19 | commands: 20 | - ./look_4_version.sh $VERSION 21 | -------------------------------------------------------------------------------- /codebuild/release/javadoc.yml: -------------------------------------------------------------------------------- 1 | ## Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | ## SPDX-License-Identifier: Apache-2.0 3 | 4 | version: 0.2 5 | 6 | env: 7 | variables: 8 | BRANCH: "master" 9 | GH_PAGES: "gh-pages" 10 | git-credential-helper: yes 11 | 12 | phases: 13 | pre_build: 14 | commands: 15 | - git config --global user.name "aws-crypto-tools-ci-bot" 16 | - git config --global user.email "no-reply@noemail.local" 17 | - git checkout $BRANCH 18 | build: 19 | commands: 20 | - mvn javadoc:javadoc 21 | - cp -r ./target/site/apidocs /tmp 22 | - git checkout $GH_PAGES 23 | - cp -r /tmp/apidocs/* . 24 | - git add . 25 | - 'git commit -m "docs: updating javadocs"' 26 | - git push -u origin $GH_PAGES -------------------------------------------------------------------------------- /codebuild/release/release-prod.yml: -------------------------------------------------------------------------------- 1 | ## Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | ## SPDX-License-Identifier: Apache-2.0 3 | 4 | version: 0.2 5 | 6 | env: 7 | variables: 8 | BRANCH: "master" 9 | secrets-manager: 10 | GPG_KEY: Maven-GPG-Keys-Release-Credentials:Keyname 11 | GPG_PASS: Maven-GPG-Keys-Release-Credentials:Passphrase 12 | SONA_USERNAME: Sonatype-Central-Portal:Username 13 | SONA_PASSWORD: Sonatype-Central-Portal:Password 14 | 15 | phases: 16 | install: 17 | runtime-versions: 18 | java: corretto11 19 | commands: 20 | - git submodule update --init submodules/MaterialProviders 21 | # Get Dafny 22 | - curl https://github.com/dafny-lang/dafny/releases/download/v4.8.0/dafny-4.8.0-x64-ubuntu-20.04.zip -L -o dafny.zip 23 | - unzip -qq dafny.zip && rm dafny.zip 24 | - export PATH="$PWD/dafny:$PATH" 25 | # Get Gradle 7.6 26 | - curl https://services.gradle.org/distributions/gradle-7.6-all.zip -L -o gradle.zip 27 | - unzip -qq gradle.zip && rm gradle.zip 28 | - export PATH="$PWD/gradle-7.6/bin:$PATH" 29 | pre_build: 30 | commands: 31 | - git checkout $BRANCH 32 | - export SETTINGS_FILE=$(pwd)/codebuild/release/settings.xml 33 | - aws secretsmanager get-secret-value --region us-west-2 --secret-id Maven-GPG-Keys-Release --query SecretBinary --output text | base64 -d > ~/mvn_gpg.tgz 34 | - tar -xvf ~/mvn_gpg.tgz -C ~ 35 | # Build and deploy TestVectors to maven local 36 | - cd submodules/MaterialProviders/TestVectorsAwsCryptographicMaterialProviders/ 37 | - make build_java && make mvn_local_deploy 38 | - cd $CODEBUILD_SRC_DIR 39 | build: 40 | commands: 41 | # Assume Role to access non-prod resources 42 | - TMP_ROLE=$(aws sts assume-role --role-arn "arn:aws:iam::370957321024:role/GitHub-CI-Public-ESDK-Java-Role-us-west-2" --role-session-name "CB-TestVectorResources") 43 | - export TMP_ROLE 44 | - export AWS_ACCESS_KEY_ID=$(echo "${TMP_ROLE}" | jq -r '.Credentials.AccessKeyId') 45 | - export AWS_SECRET_ACCESS_KEY=$(echo "${TMP_ROLE}" | jq -r '.Credentials.SecretAccessKey') 46 | - export AWS_SESSION_TOKEN=$(echo "${TMP_ROLE}" | jq -r '.Credentials.SessionToken') 47 | - aws sts get-caller-identity 48 | - | 49 | mvn deploy \ 50 | -Ppublishing \ 51 | -Pfast-tests-only \ 52 | -DperformRelease \ 53 | -Dgpg.homedir="$HOME/mvn_gpg" \ 54 | -DautoReleaseAfterClose=true \ 55 | -Dgpg.keyname="$GPG_KEY" \ 56 | -Dgpg.passphrase="$GPG_PASS" \ 57 | -Dsonatype.username="$SONA_USERNAME" \ 58 | -Dsonatype.password="$SONA_PASSWORD" \ 59 | --no-transfer-progress \ 60 | -s $SETTINGS_FILE 61 | -------------------------------------------------------------------------------- /codebuild/release/release-staging.yml: -------------------------------------------------------------------------------- 1 | ## Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | ## SPDX-License-Identifier: Apache-2.0 3 | 4 | version: 0.2 5 | 6 | env: 7 | variables: 8 | REGION: us-east-1 9 | DOMAIN: crypto-tools-internal 10 | REPOSITORY: java-esdk-staging 11 | parameter-store: 12 | ACCOUNT: /CodeBuild/AccountId 13 | secrets-manager: 14 | GPG_KEY: Maven-GPG-Keys-Release-Credentials:Keyname 15 | GPG_PASS: Maven-GPG-Keys-Release-Credentials:Passphrase 16 | 17 | phases: 18 | install: 19 | runtime-versions: 20 | java: corretto11 21 | commands: 22 | - git submodule update --init submodules/MaterialProviders 23 | # Get Dafny 24 | - curl https://github.com/dafny-lang/dafny/releases/download/v4.8.0/dafny-4.8.0-x64-ubuntu-20.04.zip -L -o dafny.zip 25 | - unzip -qq dafny.zip && rm dafny.zip 26 | - export PATH="$PWD/dafny:$PATH" 27 | # Get Gradle 7.6 28 | - curl https://services.gradle.org/distributions/gradle-7.6-all.zip -L -o gradle.zip 29 | - unzip -qq gradle.zip && rm gradle.zip 30 | - export PATH="$PWD/gradle-7.6/bin:$PATH" 31 | pre_build: 32 | commands: 33 | - export SETTINGS_FILE=$(pwd)/codebuild/release/settings.xml 34 | - export CODEARTIFACT_TOKEN=$(aws codeartifact get-authorization-token --domain $DOMAIN --domain-owner $ACCOUNT --query authorizationToken --output text --region ${REGION}) 35 | - export CODEARTIFACT_REPO_URL=https://${DOMAIN}-${ACCOUNT}.d.codeartifact.${REGION}.amazonaws.com/maven/${REPOSITORY} 36 | - aws secretsmanager get-secret-value --region us-west-2 --secret-id Maven-GPG-Keys-Release --query SecretBinary --output text | base64 -d > ~/mvn_gpg.tgz 37 | - tar -xvf ~/mvn_gpg.tgz -C ~ 38 | # Build and deploy TestVectors to maven local 39 | - cd submodules/MaterialProviders/TestVectorsAwsCryptographicMaterialProviders/ 40 | - make build_java && make mvn_local_deploy 41 | - cd $CODEBUILD_SRC_DIR 42 | build: 43 | commands: 44 | # Assume Role to access non-prod resources 45 | - TMP_ROLE=$(aws sts assume-role --role-arn "arn:aws:iam::370957321024:role/GitHub-CI-Public-ESDK-Java-Role-us-west-2" --role-session-name "CB-TestVectorResources") 46 | - export TMP_ROLE 47 | - export AWS_ACCESS_KEY_ID=$(echo "${TMP_ROLE}" | jq -r '.Credentials.AccessKeyId') 48 | - export AWS_SECRET_ACCESS_KEY=$(echo "${TMP_ROLE}" | jq -r '.Credentials.SecretAccessKey') 49 | - export AWS_SESSION_TOKEN=$(echo "${TMP_ROLE}" | jq -r '.Credentials.SessionToken') 50 | - aws sts get-caller-identity 51 | 52 | - VERSION_HASH="$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)-$CODEBUILD_RESOLVED_SOURCE_VERSION" 53 | # See https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-env-vars.html 54 | - echo "Setting version in POM to $VERSION_HASH" 55 | - mvn versions:set -DnewVersion="$VERSION_HASH" --no-transfer-progress 56 | - echo "Version is now $(grep version pom.xml | head -n 1 | sed -n 's/[ \t]*\(.*\)<\/version>/\1/p')" 57 | - | 58 | mvn deploy \ 59 | -PpublishingCodeArtifact \ 60 | -Pfast-tests-only \ 61 | -DperformRelease \ 62 | -Dgpg.homedir="$HOME/mvn_gpg" \ 63 | -DautoReleaseAfterClose=true \ 64 | -Dgpg.keyname="$GPG_KEY" \ 65 | -Dgpg.passphrase="$GPG_PASS" \ 66 | -Dcodeartifact.token=$CODEARTIFACT_TOKEN \ 67 | -DaltDeploymentRepository=codeartifact::default::$CODEARTIFACT_REPO_URL \ 68 | --no-transfer-progress \ 69 | -s $SETTINGS_FILE 70 | -------------------------------------------------------------------------------- /codebuild/release/settings.xml: -------------------------------------------------------------------------------- 1 | 5 | 9 | 10 | 11 | codeartifact 12 | aws 13 | ${codeartifact.token} 14 | 15 | 16 | central 17 | ${sonatype.username} 18 | ${sonatype.password} 19 | 20 | 21 | 22 | 23 | 24 | codeartifact 25 | 26 | 27 | codeartifact 28 | codeartifact 29 | ${codeartifact.url} 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /codebuild/release/upload_artifacts.yml: -------------------------------------------------------------------------------- 1 | ## Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | ## SPDX-License-Identifier: Apache-2.0 3 | 4 | version: 0.2 5 | 6 | env: 7 | variables: 8 | BRANCH: "master" 9 | git-credential-helper: yes 10 | secrets-manager: 11 | GH_TOKEN: Github/aws-crypto-tools-ci-bot:ESDK Release Token 12 | 13 | phases: 14 | pre_build: 15 | commands: 16 | # get new project version 17 | - git checkout $BRANCH 18 | - export VERSION=$(grep version pom.xml | head -n 1 | sed -n 's/[ \t]*\(.*\)<\/version>/\1/p') 19 | - git config --global user.name "aws-crypto-tools-ci-bot" 20 | - git config --global user.email "no-reply@noemail.local" 21 | - echo $GH_TOKEN > token.txt 22 | - export GH_TOKEN= 23 | # install gh cli in order to upload artifacts 24 | - curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | gpg --dearmor -o /usr/share/keyrings/githubcli-archive-keyring.gpg 25 | - echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null 26 | - apt -y update 27 | - apt -y install gh 28 | build: 29 | commands: 30 | - gh version 31 | - gh auth login --with-token < token.txt 32 | - gh auth status 33 | - | 34 | mvn org.apache.maven.plugins:maven-dependency-plugin:3.1.2:get \ 35 | -DrepoUrl=https://aws.oss.sonatype.org \ 36 | -Dartifact=com.amazonaws:aws-encryption-sdk-java:${VERSION}:jar 37 | - | 38 | mvn org.apache.maven.plugins:maven-dependency-plugin:3.1.2:get \ 39 | -DrepoUrl=https://aws.oss.sonatype.org \ 40 | -Dartifact=com.amazonaws:aws-encryption-sdk-java:${VERSION}:jar:sources 41 | - | 42 | mvn org.apache.maven.plugins:maven-dependency-plugin:3.1.2:get \ 43 | -DrepoUrl=https://aws.oss.sonatype.org \ 44 | -Dartifact=com.amazonaws:aws-encryption-sdk-java:${VERSION}:jar:javadoc 45 | - gh release create v${VERSION} ~/.m2/repository/com/amazonaws/aws-encryption-sdk-java/${VERSION}/*.jar -d -F CHANGELOG.md -t "AWS Encryption SDK ${VERSION} Release -- $(date +'%Y-%m-%d')" 46 | -------------------------------------------------------------------------------- /codebuild/release/validate-prod.yml: -------------------------------------------------------------------------------- 1 | ## Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | ## SPDX-License-Identifier: Apache-2.0 3 | 4 | version: 0.2 5 | 6 | env: 7 | variables: 8 | BRANCH: "master" 9 | 10 | phases: 11 | install: 12 | runtime-versions: 13 | java: $JAVA_ENV_VERSION 14 | pre_build: 15 | commands: 16 | - git checkout $BRANCH 17 | - export VERSION=$(grep version pom.xml | head -n 1 | sed -n 's/[ \t]*\(.*\)<\/version>/\1/p') 18 | - git clone https://github.com/aws-samples/busy-engineers-document-bucket.git 19 | - cd busy-engineers-document-bucket/exercises/java/encryption-context-complete 20 | build: 21 | commands: 22 | - | 23 | mvn verify \ 24 | -Dcheckstyle.skip \ 25 | -Desdk.version=$VERSION \ 26 | -Dmaven.compiler.target=$JAVA_NUMERIC_VERSION \ 27 | -Dmaven.compiler.source=$JAVA_NUMERIC_VERSION \ 28 | --no-transfer-progress 29 | -------------------------------------------------------------------------------- /codebuild/release/validate-staging.yml: -------------------------------------------------------------------------------- 1 | ## Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | ## SPDX-License-Identifier: Apache-2.0 3 | 4 | version: 0.2 5 | 6 | env: 7 | variables: 8 | REGION: us-east-1 9 | DOMAIN: crypto-tools-internal 10 | REPOSITORY: java-esdk-staging 11 | parameter-store: 12 | ACCOUNT: /CodeBuild/AccountId 13 | 14 | phases: 15 | install: 16 | commands: 17 | - pip install awscli 18 | runtime-versions: 19 | java: $JAVA_ENV_VERSION 20 | pre_build: 21 | commands: 22 | - VERSION_HASH="$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)-$CODEBUILD_RESOLVED_SOURCE_VERSION" 23 | - export SETTINGS_FILE=$(pwd)/codebuild/release/settings.xml 24 | - git clone https://github.com/aws-samples/busy-engineers-document-bucket.git 25 | - cd busy-engineers-document-bucket/exercises/java/encryption-context-complete 26 | - export CODEARTIFACT_TOKEN=$(aws codeartifact get-authorization-token --domain $DOMAIN --domain-owner $ACCOUNT --query authorizationToken --output text --region ${REGION}) 27 | - export CODEARTIFACT_REPO_URL=https://${DOMAIN}-${ACCOUNT}.d.codeartifact.${REGION}.amazonaws.com/maven/${REPOSITORY} 28 | build: 29 | commands: 30 | - | 31 | mvn verify \ 32 | -Pcodeartifact \ 33 | -Dcheckstyle.skip \ 34 | -Desdk.version=$VERSION_HASH \ 35 | -Dmaven.compiler.target=$JAVA_NUMERIC_VERSION \ 36 | -Dmaven.compiler.source=$JAVA_NUMERIC_VERSION \ 37 | -Dcodeartifact.token=$CODEARTIFACT_TOKEN \ 38 | -Dcodeartifact.url=$CODEARTIFACT_REPO_URL \ 39 | --no-transfer-progress \ 40 | -T 4 \ 41 | -s $SETTINGS_FILE 42 | 43 | -------------------------------------------------------------------------------- /codebuild/release/version.yml: -------------------------------------------------------------------------------- 1 | ## Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | ## SPDX-License-Identifier: Apache-2.0 3 | 4 | version: 0.2 5 | 6 | env: 7 | variables: 8 | NODE_OPTIONS: "--max-old-space-size=4096" 9 | BRANCH: "master" 10 | git-credential-helper: "yes" 11 | 12 | phases: 13 | install: 14 | commands: 15 | - n 20 16 | - node -v 17 | - npm install --save-dev semantic-release 18 | - npm install @semantic-release/changelog -d 19 | - npm install @semantic-release/exec -d 20 | - npm install @semantic-release/git -d 21 | - npm install conventional-changelog-conventionalcommits -d 22 | - npm install --save conventional-changelog 23 | pre_build: 24 | commands: 25 | - git config --global user.name "aws-crypto-tools-ci-bot" 26 | - git config --global user.email "no-reply@noemail.local" 27 | - git checkout $BRANCH 28 | build: 29 | commands: 30 | - npx semantic-release --branches $BRANCH --no-ci 31 | -------------------------------------------------------------------------------- /look_4_version.sh: -------------------------------------------------------------------------------- 1 | ## Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | ## SPDX-License-Identifier: Apache-2.0 3 | 4 | #!bin/bash 5 | 6 | VERSION=$1 7 | COUNTER=0 8 | STATUS=1 9 | 10 | echo "Looking for version $VERSION" 11 | 12 | while [ $STATUS -ne 0 ]; do 13 | mvn org.apache.maven.plugins:maven-dependency-plugin:3.0.1:get \ 14 | -Dartifact=com.amazonaws:aws-encryption-sdk-java:$VERSION:jar -U 15 | 16 | STATUS=$? 17 | if [ $STATUS -eq 0 ]; then 18 | echo "Found version $VERSION in Maven Central :)" 19 | break 20 | fi 21 | 22 | if [ $((COUNTER+=1)) -eq 15 ]; then 23 | echo "It has been an awfully long time, you should check Maven Central for issues" 24 | exit 1 25 | fi 26 | 27 | echo "Could not find version $VERSION. Trying again." 28 | sleep 60 29 | done 30 | -------------------------------------------------------------------------------- /src/examples/java/com/amazonaws/crypto/examples/keyrings/BasicEncryptionKeyringExample.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.crypto.examples.keyrings; 5 | 6 | import com.amazonaws.encryptionsdk.AwsCrypto; 7 | import com.amazonaws.encryptionsdk.CommitmentPolicy; 8 | import com.amazonaws.encryptionsdk.CryptoResult; 9 | import software.amazon.cryptography.materialproviders.IKeyring; 10 | import software.amazon.cryptography.materialproviders.MaterialProviders; 11 | import software.amazon.cryptography.materialproviders.model.CreateAwsKmsMultiKeyringInput; 12 | import software.amazon.cryptography.materialproviders.model.MaterialProvidersConfig; 13 | 14 | import java.nio.charset.StandardCharsets; 15 | import java.util.Arrays; 16 | import java.util.Collections; 17 | import java.util.Map; 18 | 19 | /** 20 | * Encrypts and then decrypts data using an AWS KMS Keyring. 21 | * 22 | *

Arguments: 23 | * 24 | *

    25 | *
  1. Key ARN: For help finding the Amazon Resource Name (ARN) of your AWS KMS customer master 26 | * key (CMK), see 'Viewing Keys' at 27 | * http://docs.aws.amazon.com/kms/latest/developerguide/viewing-keys.html 28 | *
29 | */ 30 | public class BasicEncryptionKeyringExample { 31 | 32 | private static final byte[] EXAMPLE_DATA = "Hello World".getBytes(StandardCharsets.UTF_8); 33 | 34 | public static void main(final String[] args) { 35 | final String keyArn = args[0]; 36 | 37 | encryptAndDecryptWithKeyring(keyArn); 38 | } 39 | 40 | public static void encryptAndDecryptWithKeyring(final String keyArn) { 41 | // 1. Instantiate the SDK 42 | // This builds the AwsCrypto client with the RequireEncryptRequireDecrypt commitment policy, 43 | // which enforces that this client only encrypts using committing algorithm suites and enforces 44 | // that this client will only decrypt encrypted messages that were created with a committing 45 | // algorithm suite. 46 | // This is the default commitment policy if you build the client with 47 | // `AwsCrypto.builder().build()` 48 | // or `AwsCrypto.standard()`. 49 | final AwsCrypto crypto = 50 | AwsCrypto.builder() 51 | .withCommitmentPolicy(CommitmentPolicy.RequireEncryptRequireDecrypt) 52 | .build(); 53 | 54 | // 2. Create the AWS KMS keyring. 55 | // We create a multi keyring, as this interface creates the KMS client for us automatically. 56 | final MaterialProviders materialProviders = 57 | MaterialProviders.builder() 58 | .MaterialProvidersConfig(MaterialProvidersConfig.builder().build()) 59 | .build(); 60 | final CreateAwsKmsMultiKeyringInput keyringInput = 61 | CreateAwsKmsMultiKeyringInput.builder().generator(keyArn).build(); 62 | final IKeyring kmsKeyring = materialProviders.CreateAwsKmsMultiKeyring(keyringInput); 63 | 64 | // 3. Create an encryption context 65 | // Most encrypted data should have an associated encryption context 66 | // to protect integrity. This sample uses placeholder values. 67 | // For more information see: 68 | // blogs.aws.amazon.com/security/post/Tx2LZ6WBJJANTNW/How-to-Protect-the-Integrity-of-Your-Encrypted-Data-by-Using-AWS-Key-Management 69 | final Map encryptionContext = 70 | Collections.singletonMap("ExampleContextKey", "ExampleContextValue"); 71 | 72 | // 4. Encrypt the data 73 | final CryptoResult encryptResult = 74 | crypto.encryptData(kmsKeyring, EXAMPLE_DATA, encryptionContext); 75 | final byte[] ciphertext = encryptResult.getResult(); 76 | 77 | // 5. Decrypt the data 78 | final CryptoResult decryptResult = 79 | crypto.decryptData( 80 | kmsKeyring, 81 | ciphertext, 82 | // Verify that the encryption context in the result contains the 83 | // encryption context supplied to the encryptData method 84 | encryptionContext); 85 | 86 | // 6. Verify that the decrypted plaintext matches the original plaintext 87 | assert Arrays.equals(decryptResult.getResult(), EXAMPLE_DATA); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/examples/java/com/amazonaws/crypto/examples/keyrings/hierarchical/CreateBranchKeyId.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.crypto.examples.keyrings.hierarchical; 5 | 6 | import static com.amazonaws.encryptionsdk.kms.KMSTestFixtures.TEST_KEYSTORE_KMS_KEY_ID; 7 | import static com.amazonaws.encryptionsdk.kms.KMSTestFixtures.TEST_KEYSTORE_NAME; 8 | import static com.amazonaws.encryptionsdk.kms.KMSTestFixtures.TEST_LOGICAL_KEYSTORE_NAME; 9 | 10 | import software.amazon.awssdk.services.dynamodb.DynamoDbClient; 11 | import software.amazon.awssdk.services.kms.KmsClient; 12 | import software.amazon.cryptography.keystore.KeyStore; 13 | import software.amazon.cryptography.keystore.model.CreateKeyInput; 14 | import software.amazon.cryptography.keystore.model.CreateKeyOutput; 15 | import software.amazon.cryptography.keystore.model.KMSConfiguration; 16 | import software.amazon.cryptography.keystore.model.KeyStoreConfig; 17 | 18 | public class CreateBranchKeyId { 19 | public static String createBranchKeyId() { 20 | // Create an AWS KMS Configuration to use with your KeyStore. 21 | // The KMS Configuration MUST have the right access to the resources in the KeyStore. 22 | final KMSConfiguration kmsConfig = 23 | KMSConfiguration.builder().kmsKeyArn(TEST_KEYSTORE_KMS_KEY_ID).build(); 24 | 25 | // Configure your KeyStore resource. 26 | // This SHOULD be the same configuration that you used 27 | // to initially create and populate your KeyStore. 28 | final KeyStoreConfig keystoreConfig = 29 | KeyStoreConfig.builder() 30 | .ddbClient(DynamoDbClient.create()) 31 | .ddbTableName(TEST_KEYSTORE_NAME) 32 | .logicalKeyStoreName(TEST_LOGICAL_KEYSTORE_NAME) 33 | .kmsClient(KmsClient.create()) 34 | .kmsConfiguration(kmsConfig) 35 | .build(); 36 | 37 | // Create a KeyStore 38 | final KeyStore keystore = KeyStore.builder().KeyStoreConfig(keystoreConfig).build(); 39 | 40 | // Create a branch key identifier with the AWS KMS Key configured in the KeyStore Configuration. 41 | final CreateKeyOutput branchKeyId = keystore.CreateKey(CreateKeyInput.builder().build()); 42 | 43 | return branchKeyId.branchKeyIdentifier(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/examples/java/com/amazonaws/crypto/examples/keyrings/hierarchical/ExampleBranchKeyIdSupplier.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.crypto.examples.keyrings.hierarchical; 5 | 6 | import software.amazon.cryptography.materialproviders.IBranchKeyIdSupplier; 7 | import software.amazon.cryptography.materialproviders.model.GetBranchKeyIdInput; 8 | import software.amazon.cryptography.materialproviders.model.GetBranchKeyIdOutput; 9 | 10 | import java.util.Map; 11 | 12 | // Use the encryption contexts to define friendly names for each branch key 13 | public class ExampleBranchKeyIdSupplier implements IBranchKeyIdSupplier { 14 | private static String branchKeyIdForTenantA; 15 | private static String branchKeyIdForTenantB; 16 | 17 | public ExampleBranchKeyIdSupplier(String tenant1Id, String tenant2Id) { 18 | this.branchKeyIdForTenantA = tenant1Id; 19 | this.branchKeyIdForTenantB = tenant2Id; 20 | } 21 | 22 | @Override 23 | public GetBranchKeyIdOutput GetBranchKeyId(GetBranchKeyIdInput input) { 24 | 25 | Map encryptionContext = input.encryptionContext(); 26 | 27 | if (!encryptionContext.containsKey("tenant")) { 28 | throw new IllegalArgumentException( 29 | "EncryptionContext invalid, does not contain expected tenant key value pair."); 30 | } 31 | 32 | String tenantKeyId = encryptionContext.get("tenant"); 33 | String branchKeyId; 34 | 35 | if (tenantKeyId.equals("TenantA")) { 36 | branchKeyId = branchKeyIdForTenantA; 37 | } else if (tenantKeyId.equals("TenantB")) { 38 | branchKeyId = branchKeyIdForTenantB; 39 | } else { 40 | throw new IllegalArgumentException("Item does not contain valid tenant ID"); 41 | } 42 | return GetBranchKeyIdOutput.builder().branchKeyId(branchKeyId).build(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/examples/java/com/amazonaws/crypto/examples/keyrings/hierarchical/VersionBranchKeyId.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.crypto.examples.keyrings.hierarchical; 5 | 6 | import static com.amazonaws.encryptionsdk.kms.KMSTestFixtures.TEST_KEYSTORE_KMS_KEY_ID; 7 | import static com.amazonaws.encryptionsdk.kms.KMSTestFixtures.TEST_KEYSTORE_NAME; 8 | import static com.amazonaws.encryptionsdk.kms.KMSTestFixtures.TEST_LOGICAL_KEYSTORE_NAME; 9 | 10 | import software.amazon.awssdk.services.dynamodb.DynamoDbClient; 11 | import software.amazon.awssdk.services.kms.KmsClient; 12 | import software.amazon.cryptography.keystore.KeyStore; 13 | import software.amazon.cryptography.keystore.model.KMSConfiguration; 14 | import software.amazon.cryptography.keystore.model.KeyStoreConfig; 15 | import software.amazon.cryptography.keystore.model.VersionKeyInput; 16 | 17 | public class VersionBranchKeyId { 18 | public static void versionBranchKeyId(String branchKeyId) { 19 | // Create an AWS KMS Configuration to use with your KeyStore. 20 | // The KMS Configuration MUST have the right access to the resources in the KeyStore. 21 | final KMSConfiguration kmsConfig = 22 | KMSConfiguration.builder().kmsKeyArn(TEST_KEYSTORE_KMS_KEY_ID).build(); 23 | 24 | // Configure your KeyStore resource. 25 | // This SHOULD be the same configuration that you used 26 | // to initially create and populate your KeyStore. 27 | final KeyStoreConfig keystoreConfig = 28 | KeyStoreConfig.builder() 29 | .ddbClient(DynamoDbClient.create()) 30 | .ddbTableName(TEST_KEYSTORE_NAME) 31 | .logicalKeyStoreName(TEST_LOGICAL_KEYSTORE_NAME) 32 | .kmsClient(KmsClient.create()) 33 | .kmsConfiguration(kmsConfig) 34 | .build(); 35 | 36 | // Create a KeyStore 37 | final KeyStore keystore = KeyStore.builder().KeyStoreConfig(keystoreConfig).build(); 38 | 39 | // To version a branch key you MUST have access to kms:ReEncrypt* and 40 | // kms:GenerateDataKeyWithoutPlaintext 41 | keystore.VersionKey(VersionKeyInput.builder().branchKeyIdentifier(branchKeyId).build()); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/examples/java/com/amazonaws/crypto/examples/v2/SimpleDataKeyCachingExample.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.crypto.examples.v2; 5 | 6 | import java.nio.charset.StandardCharsets; 7 | import java.util.Collections; 8 | import java.util.Map; 9 | import java.util.concurrent.TimeUnit; 10 | 11 | import com.amazonaws.encryptionsdk.AwsCrypto; 12 | import com.amazonaws.encryptionsdk.CryptoMaterialsManager; 13 | import com.amazonaws.encryptionsdk.MasterKeyProvider; 14 | import com.amazonaws.encryptionsdk.caching.CachingCryptoMaterialsManager; 15 | import com.amazonaws.encryptionsdk.caching.CryptoMaterialsCache; 16 | import com.amazonaws.encryptionsdk.caching.LocalCryptoMaterialsCache; 17 | import com.amazonaws.encryptionsdk.kmssdkv2.KmsMasterKey; 18 | import com.amazonaws.encryptionsdk.kmssdkv2.KmsMasterKeyProvider; 19 | 20 | /** 21 | *

22 | * Encrypts a string using an AWS KMS customer master key (CMK) and data key caching 23 | * 24 | *

25 | * Arguments: 26 | *

    27 | *
  1. KMS CMK ARN: To find the Amazon Resource Name of your AWS KMS customer master key (CMK), 28 | * see 'Viewing Keys' at http://docs.aws.amazon.com/kms/latest/developerguide/viewing-keys.html 29 | *
  2. Max entry age: Maximum time (in seconds) that a cached entry can be used 30 | *
  3. Cache capacity: Maximum number of entries in the cache 31 | *
32 | */ 33 | public class SimpleDataKeyCachingExample { 34 | /* 35 | * Security thresholds 36 | * Max entry age is required. 37 | * Max messages (and max bytes) per data key are optional 38 | */ 39 | private static final int MAX_ENTRY_MSGS = 100; 40 | 41 | public static byte[] encryptWithCaching(String kmsCmkArn, int maxEntryAge, int cacheCapacity) { 42 | // Plaintext data to be encrypted 43 | byte[] myData = "My plaintext data".getBytes(StandardCharsets.UTF_8); 44 | 45 | // Encryption context 46 | // Most encrypted data should have an associated encryption context 47 | // to protect integrity. This sample uses placeholder values. 48 | // For more information see: 49 | // blogs.aws.amazon.com/security/post/Tx2LZ6WBJJANTNW/How-to-Protect-the-Integrity-of-Your-Encrypted-Data-by-Using-AWS-Key-Management 50 | final Map encryptionContext = Collections.singletonMap("purpose", "test"); 51 | 52 | // Create a master key provider 53 | MasterKeyProvider keyProvider = KmsMasterKeyProvider.builder().buildStrict(kmsCmkArn); 54 | 55 | // Create a cache 56 | CryptoMaterialsCache cache = new LocalCryptoMaterialsCache(cacheCapacity); 57 | 58 | // Create a caching CMM 59 | CryptoMaterialsManager cachingCmm = 60 | CachingCryptoMaterialsManager.newBuilder().withMasterKeyProvider(keyProvider) 61 | .withCache(cache) 62 | .withMaxAge(maxEntryAge, TimeUnit.SECONDS) 63 | .withMessageUseLimit(MAX_ENTRY_MSGS) 64 | .build(); 65 | 66 | // When the call to encryptData specifies a caching CMM, 67 | // the encryption operation uses the data key cache 68 | final AwsCrypto encryptionSdk = AwsCrypto.standard(); 69 | return encryptionSdk.encryptData(cachingCmm, myData, encryptionContext).getResult(); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/CommitmentPolicy.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.encryptionsdk; 5 | 6 | import software.amazon.cryptography.materialproviders.model.ESDKCommitmentPolicy; 7 | 8 | /** 9 | * Governs how a AwsCrypto behaves during configuration, encryption, and decryption, with respect to 10 | * key commitment. 11 | */ 12 | public enum CommitmentPolicy { 13 | /** 14 | * On encrypty, algorithm suite must NOT support key commitment; On decrypt, if a key commitment 15 | * is present on the ciphertext, then the key commitment must be valid. Key commitment will NOT be 16 | * included in ciphertext on encrypt. 17 | */ 18 | ForbidEncryptAllowDecrypt(ESDKCommitmentPolicy.FORBID_ENCRYPT_ALLOW_DECRYPT), 19 | /** 20 | * On encrypt, algorithm suite must support key commitment; On decrypt, if a key commitment is 21 | * present on the ciphertext, then the key commitment must be valid. Key commitment will be 22 | * included in ciphertext on encrypt. 23 | */ 24 | RequireEncryptAllowDecrypt(ESDKCommitmentPolicy.REQUIRE_ENCRYPT_ALLOW_DECRYPT), 25 | /** 26 | * Algorithm suite must support key commitment. Key commitment will be included in ciphertext on 27 | * encrypt. Valid key commitment must be present in ciphertext on decrypt. 28 | */ 29 | RequireEncryptRequireDecrypt(ESDKCommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT); 30 | 31 | private final software.amazon.cryptography.materialproviders.model.CommitmentPolicy 32 | mplCommitmentPolicy; 33 | 34 | CommitmentPolicy(ESDKCommitmentPolicy esdkCommitmentPolicy) { 35 | this.mplCommitmentPolicy = 36 | software.amazon.cryptography.materialproviders.model.CommitmentPolicy.builder() 37 | .ESDK(esdkCommitmentPolicy) 38 | .build(); 39 | } 40 | 41 | public software.amazon.cryptography.materialproviders.model.CommitmentPolicy 42 | getMplCommitmentPolicy() { 43 | return mplCommitmentPolicy; 44 | } 45 | 46 | /** Validates that an algorithm meets the Policy's On encrypt key commitment. */ 47 | public boolean algorithmAllowedForEncrypt(CryptoAlgorithm algorithm) { 48 | switch (this) { 49 | case ForbidEncryptAllowDecrypt: 50 | return !algorithm.isCommitting(); 51 | case RequireEncryptAllowDecrypt: 52 | case RequireEncryptRequireDecrypt: 53 | return algorithm.isCommitting(); 54 | default: 55 | throw new UnsupportedOperationException( 56 | "Support for commitment policy " + this + " not yet built."); 57 | } 58 | } 59 | 60 | /** Validates that an algorithm meets the Policy's On decrypt key commitment. */ 61 | public boolean algorithmAllowedForDecrypt(CryptoAlgorithm algorithm) { 62 | switch (this) { 63 | case ForbidEncryptAllowDecrypt: 64 | case RequireEncryptAllowDecrypt: 65 | return true; 66 | case RequireEncryptRequireDecrypt: 67 | return algorithm.isCommitting(); 68 | default: 69 | throw new UnsupportedOperationException( 70 | "Support for commitment policy " + this + " not yet built."); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/CryptoMaterialsManager.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.encryptionsdk; 2 | 3 | import com.amazonaws.encryptionsdk.model.DecryptionMaterials; 4 | import com.amazonaws.encryptionsdk.model.DecryptionMaterialsRequest; 5 | import com.amazonaws.encryptionsdk.model.EncryptionMaterials; 6 | import com.amazonaws.encryptionsdk.model.EncryptionMaterialsRequest; 7 | 8 | /** 9 | * The crypto materials manager is responsible for preparing the cryptographic materials needed to 10 | * process a request - notably, preparing the cleartext data key and (if applicable) trailing 11 | * signature keys on both encrypt and decrypt. 12 | */ 13 | public interface CryptoMaterialsManager { 14 | /** 15 | * Prepares materials for an encrypt request. The resulting materials result must have a cleartext 16 | * data key and (if applicable for the crypto algorithm in use) a trailing signature key. 17 | * 18 | *

The encryption context returned may be different from the one passed in the materials 19 | * request, and will be serialized (in cleartext) within the encrypted message. 20 | * 21 | * @see EncryptionMaterials 22 | * @see EncryptionMaterialsRequest 23 | * @param request 24 | * @return 25 | */ 26 | EncryptionMaterials getMaterialsForEncrypt(EncryptionMaterialsRequest request); 27 | 28 | DecryptionMaterials decryptMaterials(DecryptionMaterialsRequest request); 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/CryptoResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except 5 | * in compliance with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | package com.amazonaws.encryptionsdk; 15 | 16 | import com.amazonaws.encryptionsdk.model.CiphertextHeaders; 17 | import java.util.ArrayList; 18 | import java.util.Collections; 19 | import java.util.List; 20 | import java.util.Map; 21 | 22 | /** 23 | * Represents the result of an operation by {@link AwsCrypto}. It not only captures the {@code 24 | * result} of the operation but also additional metadata such as the {@code encryptionContext}, 25 | * {@code algorithm}, {@link MasterKey}(s), and any other information captured in the {@link 26 | * CiphertextHeaders}. 27 | * 28 | * @param the type of the underlying {@code result} 29 | * @param the type of the {@link MasterKey}s used in production of this result 30 | */ 31 | public class CryptoResult> { 32 | private final T result_; 33 | private final List masterKeys_; 34 | private final Map encryptionContext_; 35 | private final CiphertextHeaders headers_; 36 | 37 | /** Note, does not make a defensive copy of any of the data. */ 38 | CryptoResult( 39 | final T result, 40 | final List masterKeys, 41 | final CiphertextHeaders headers, 42 | Map encryptionContext) { 43 | result_ = result; 44 | masterKeys_ = Collections.unmodifiableList(masterKeys); 45 | headers_ = headers; 46 | encryptionContext_ = encryptionContext; 47 | } 48 | 49 | /** 50 | * The actual result of the cryptographic operation. This is not a defensive copy and callers 51 | * should not modify it. 52 | */ 53 | public T getResult() { 54 | return result_; 55 | } 56 | 57 | /** 58 | * Returns all relevant {@link MasterKey}s. In the case of encryption, returns all {@code 59 | * MasterKey}s used to protect the ciphertext. In the case of decryption, returns just the {@code 60 | * MasterKey} used to decrypt the ciphertext. 61 | */ 62 | public List getMasterKeys() { 63 | return masterKeys_; 64 | } 65 | 66 | /** Convenience method for retrieving the keyIds in the results from {@link #getMasterKeys()}. */ 67 | public List getMasterKeyIds() { 68 | final List result = new ArrayList<>(masterKeys_.size()); 69 | for (final MasterKey mk : masterKeys_) { 70 | result.add(mk.getKeyId()); 71 | } 72 | return result; 73 | } 74 | 75 | public Map getEncryptionContext() { 76 | return encryptionContext_; 77 | } 78 | 79 | /** Convenience method equivalent to {@link #getHeaders()}.{@code getCryptoAlgoId()}. */ 80 | public CryptoAlgorithm getCryptoAlgorithm() { 81 | return headers_.getCryptoAlgoId(); 82 | } 83 | 84 | public CiphertextHeaders getHeaders() { 85 | return headers_; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/DataKey.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except 5 | * in compliance with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | package com.amazonaws.encryptionsdk; 15 | 16 | import javax.crypto.SecretKey; 17 | 18 | /** 19 | * Represents both the cleartext and encrypted bytes of a data key. 20 | * 21 | * @param the type of {@link MasterKey} used to protect this {@code DataKey}. 22 | */ 23 | public class DataKey> implements EncryptedDataKey { 24 | private final byte[] providerInformation_; 25 | private final byte[] encryptedDataKey_; 26 | private final SecretKey key_; 27 | private final M masterKey_; 28 | 29 | public DataKey( 30 | final SecretKey key, 31 | final byte[] encryptedDataKey, 32 | final byte[] providerInformation, 33 | final M masterKey) { 34 | super(); 35 | key_ = key; 36 | encryptedDataKey_ = encryptedDataKey.clone(); 37 | providerInformation_ = providerInformation.clone(); 38 | masterKey_ = masterKey; 39 | } 40 | 41 | /** Returns the cleartext bytes of the data key. */ 42 | public SecretKey getKey() { 43 | return key_; 44 | } 45 | 46 | @Override 47 | public String getProviderId() { 48 | return masterKey_.getProviderId(); 49 | } 50 | 51 | @Override 52 | public byte[] getProviderInformation() { 53 | return providerInformation_.clone(); 54 | } 55 | 56 | @Override 57 | public byte[] getEncryptedDataKey() { 58 | return encryptedDataKey_.clone(); 59 | } 60 | 61 | /** Returns the {@link MasterKey} used to encrypt this {@link DataKey}. */ 62 | public M getMasterKey() { 63 | return masterKey_; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/ParsedCiphertext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except 5 | * in compliance with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | package com.amazonaws.encryptionsdk; 15 | 16 | import com.amazonaws.encryptionsdk.exception.BadCiphertextException; 17 | import com.amazonaws.encryptionsdk.internal.Utils; 18 | import com.amazonaws.encryptionsdk.model.CiphertextHeaders; 19 | import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; 20 | 21 | /** 22 | * Exposes header information of ciphertexts to make it easier to inspect the algorithm, keys, and 23 | * encryption context prior to decryption. 24 | * 25 | *

Please note that the class does not make defensive copies. 26 | */ 27 | public class ParsedCiphertext extends CiphertextHeaders { 28 | private final byte[] ciphertext_; 29 | private final int offset_; 30 | 31 | /** 32 | * Parses {@code ciphertext}. Please note that this does not make a defensive copy of 33 | * {@code ciphertext} and that any changes made to the backing array will be reflected here as 34 | * well. 35 | * 36 | * @param ciphertext The ciphertext to parse 37 | * @param maxEncryptedDataKeys The maximum number of encrypted data keys to parse. Zero indicates 38 | * no maximum. 39 | */ 40 | public ParsedCiphertext(final byte[] ciphertext, final int maxEncryptedDataKeys) { 41 | ciphertext_ = Utils.assertNonNull(ciphertext, "ciphertext"); 42 | offset_ = deserialize(ciphertext_, 0, maxEncryptedDataKeys); 43 | if (!this.isComplete()) { 44 | throw new BadCiphertextException("Incomplete ciphertext."); 45 | } 46 | } 47 | 48 | /** 49 | * Parses {@code ciphertext} without enforcing a max EDK count. Please note that this does 50 | * not make a defensive copy of {@code ciphertext} and that any changes made to the 51 | * backing array will be reflected here as well. 52 | */ 53 | public ParsedCiphertext(final byte[] ciphertext) { 54 | this(ciphertext, CiphertextHeaders.NO_MAX_ENCRYPTED_DATA_KEYS); 55 | } 56 | 57 | /** 58 | * Returns the raw ciphertext backing this object. This is not a defensive copy and so 59 | * must not be modified by callers. 60 | */ 61 | @SuppressFBWarnings("EI_EXPOSE_REP") 62 | public byte[] getCiphertext() { 63 | return ciphertext_; 64 | } 65 | 66 | /** The offset at which the first non-header byte in {@code ciphertext} is located. */ 67 | public int getOffset() { 68 | return offset_; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/caching/MsClock.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.encryptionsdk.caching; 2 | 3 | interface MsClock { 4 | MsClock WALLCLOCK = System::currentTimeMillis; 5 | 6 | public long timestamp(); 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/caching/NullCryptoMaterialsCache.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.encryptionsdk.caching; 2 | 3 | import com.amazonaws.encryptionsdk.model.DecryptionMaterials; 4 | import com.amazonaws.encryptionsdk.model.EncryptionMaterials; 5 | 6 | /** A {@link CryptoMaterialsCache} that doesn't actually cache anything. */ 7 | public class NullCryptoMaterialsCache implements CryptoMaterialsCache { 8 | @Override 9 | public EncryptCacheEntry getEntryForEncrypt(byte[] cacheId, final UsageStats usageIncrement) { 10 | return null; 11 | } 12 | 13 | @Override 14 | public EncryptCacheEntry putEntryForEncrypt( 15 | byte[] cacheId, 16 | EncryptionMaterials encryptionMaterials, 17 | CacheHint hint, 18 | UsageStats initialUsage) { 19 | return new EncryptCacheEntry() { 20 | private final long creationTime = System.currentTimeMillis(); 21 | 22 | @Override 23 | public synchronized UsageStats getUsageStats() { 24 | return initialUsage; 25 | } 26 | 27 | @Override 28 | public long getEntryCreationTime() { 29 | return creationTime; 30 | } 31 | 32 | @Override 33 | public EncryptionMaterials getResult() { 34 | return encryptionMaterials; 35 | } 36 | }; 37 | } 38 | 39 | @Override 40 | public DecryptCacheEntry getEntryForDecrypt(byte[] cacheId) { 41 | return null; 42 | } 43 | 44 | @Override 45 | public void putEntryForDecrypt( 46 | byte[] cacheId, DecryptionMaterials decryptionMaterials, CacheHint hint) { 47 | // no-op 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/exception/AwsCryptoException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except 5 | * in compliance with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | package com.amazonaws.encryptionsdk.exception; 15 | 16 | /** This is the parent class of the runtime exceptions thrown by the AWS Encryption SDK. */ 17 | // @ non_null_by_default 18 | public class AwsCryptoException extends RuntimeException { 19 | private static final long serialVersionUID = -1L; 20 | 21 | // @ public normal_behavior 22 | // @ ensures standardThrowable(); 23 | // @ pure 24 | public AwsCryptoException() { 25 | super(); 26 | } 27 | 28 | // @ public normal_behavior 29 | // @ ensures standardThrowable(message); 30 | // @ pure 31 | public AwsCryptoException(final String message) { 32 | super(message); 33 | } 34 | 35 | // @ public normal_behavior 36 | // @ ensures standardThrowable(cause); 37 | // @ pure 38 | public AwsCryptoException(final Throwable cause) { 39 | super(cause); 40 | } 41 | 42 | // @ public normal_behavior 43 | // @ ensures standardThrowable(message,cause); 44 | // @ pure 45 | public AwsCryptoException(final String message, final Throwable cause) { 46 | super(message, cause); 47 | } 48 | 49 | // @ public normal_behavior 50 | // @ ensures standardThrowable(message,cause); 51 | // @ pure // TODO 52 | public AwsCryptoException( 53 | final String message, 54 | final Throwable cause, 55 | final boolean enableSuppression, 56 | final boolean writableStackTrace) { 57 | super(message, cause, enableSuppression, writableStackTrace); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/exception/BadCiphertextException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except 5 | * in compliance with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | package com.amazonaws.encryptionsdk.exception; 15 | 16 | /** 17 | * This exception is thrown when the values found in a ciphertext message are invalid or corrupt. 18 | */ 19 | // @ non_null_by_default 20 | public class BadCiphertextException extends AwsCryptoException { 21 | private static final long serialVersionUID = -1L; 22 | 23 | /*@ public normal_behavior 24 | @ ensures standardThrowable(); 25 | @*/ 26 | // @ pure 27 | public BadCiphertextException() { 28 | super(); 29 | } 30 | 31 | /*@ public normal_behavior 32 | @ ensures standardThrowable(message); 33 | @*/ 34 | // @ pure 35 | public BadCiphertextException(final String message) { 36 | super(message); 37 | } 38 | 39 | /*@ public normal_behavior 40 | @ ensures standardThrowable(cause); 41 | @*/ 42 | // @ pure 43 | public BadCiphertextException(final Throwable cause) { 44 | super(cause); 45 | } 46 | 47 | /*@ public normal_behavior 48 | @ ensures standardThrowable(message,cause); 49 | @*/ 50 | // @ pure 51 | public BadCiphertextException(final String message, final Throwable cause) { 52 | super(message, cause); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/exception/CannotUnwrapDataKeyException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except 5 | * in compliance with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | package com.amazonaws.encryptionsdk.exception; 15 | 16 | import com.amazonaws.encryptionsdk.DataKey; 17 | 18 | /** This exception is thrown when there are no {@link DataKey}s which can be decrypted. */ 19 | // @ non_null_by_default 20 | public class CannotUnwrapDataKeyException extends AwsCryptoException { 21 | private static final long serialVersionUID = -1L; 22 | 23 | /*@ public normal_behavior 24 | @ ensures standardThrowable(); 25 | @*/ 26 | // @ pure 27 | public CannotUnwrapDataKeyException() { 28 | super(); 29 | } 30 | 31 | /*@ public normal_behavior 32 | @ ensures standardThrowable(message); 33 | @*/ 34 | // @ pure 35 | public CannotUnwrapDataKeyException(final String message) { 36 | super(message); 37 | } 38 | 39 | /*@ public normal_behavior 40 | @ ensures standardThrowable(cause); 41 | @*/ 42 | // @ pure 43 | public CannotUnwrapDataKeyException(final Throwable cause) { 44 | super(cause); 45 | } 46 | 47 | /*@ public normal_behavior 48 | @ ensures standardThrowable(message,cause); 49 | @*/ 50 | // @ pure 51 | public CannotUnwrapDataKeyException(final String message, final Throwable cause) { 52 | super(message, cause); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/exception/NoSuchMasterKeyException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except 5 | * in compliance with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | package com.amazonaws.encryptionsdk.exception; 15 | 16 | import com.amazonaws.encryptionsdk.MasterKey; 17 | 18 | /** 19 | * This exception is thrown when the SDK attempts to use a {@link MasterKey} which either doesn't 20 | * exist or to which it doesn't have access. 21 | */ 22 | // @ non_null_by_default 23 | public class NoSuchMasterKeyException extends AwsCryptoException { 24 | private static final long serialVersionUID = -1L; 25 | 26 | /*@ public normal_behavior 27 | @ ensures standardThrowable(); 28 | @*/ 29 | // @ pure 30 | public NoSuchMasterKeyException() {} 31 | 32 | /*@ public normal_behavior 33 | @ ensures standardThrowable(message); 34 | @*/ 35 | // @ pure 36 | public NoSuchMasterKeyException(final String message) { 37 | super(message); 38 | } 39 | 40 | /*@ public normal_behavior 41 | @ ensures standardThrowable(cause); 42 | @*/ 43 | // @ pure 44 | public NoSuchMasterKeyException(final Throwable cause) { 45 | super(cause); 46 | } 47 | 48 | /*@ public normal_behavior 49 | @ ensures standardThrowable(message,cause); 50 | @*/ 51 | // @ pure 52 | public NoSuchMasterKeyException(final String message, final Throwable cause) { 53 | super(message, cause); 54 | } 55 | 56 | /*@ public normal_behavior 57 | @ ensures standardThrowable(message,cause); 58 | @*/ 59 | // @ pure // TODO 60 | public NoSuchMasterKeyException( 61 | final String message, 62 | final Throwable cause, 63 | final boolean enableSuppression, 64 | final boolean writableStackTrace) { 65 | super(message, cause, enableSuppression, writableStackTrace); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/exception/ParseException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except 5 | * in compliance with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | package com.amazonaws.encryptionsdk.exception; 15 | 16 | /** 17 | * This exception is thrown when there are not enough bytes to parse a primitive, a specified number 18 | * of bytes, or the bytes does not properly represent the desired object. 19 | */ 20 | // @ non_null_by_default 21 | public class ParseException extends AwsCryptoException { 22 | private static final long serialVersionUID = -1L; 23 | 24 | /** Constructs a new exception with no detail message. */ 25 | /*@ public normal_behavior 26 | @ ensures standardThrowable(); 27 | @*/ 28 | // @ pure 29 | public ParseException() { 30 | super(); 31 | } 32 | 33 | /** 34 | * Constructs a new exception with the specified detail message. 35 | * 36 | * @param message the detail message. 37 | */ 38 | /*@ public normal_behavior 39 | @ ensures standardThrowable(message); 40 | @*/ 41 | // @ pure 42 | public ParseException(final String message) { 43 | super(message); 44 | } 45 | 46 | /** 47 | * Constructs a new exception with the specified cause and a detail message of (cause==null ? 48 | * null : cause.toString()) (which typically contains the class and detail message of 49 | * cause). 50 | * 51 | * @param cause the cause (which is saved for later retrieval by the {@link Throwable#getCause()} 52 | * method). (A null value is permitted, and indicates that the cause is nonexistent 53 | * or unknown.) 54 | */ 55 | /*@ public normal_behavior 56 | @ ensures standardThrowable(cause); 57 | @*/ 58 | // @ pure 59 | public ParseException(final Throwable cause) { 60 | super(cause); 61 | } 62 | 63 | /** 64 | * Constructs a new exception with the specified detail message and cause. 65 | * 66 | *

Note that the detail message associated with cause is not automatically incorporated in this 67 | * exception's detail message. 68 | * 69 | * @param message the detail message (which is saved for later retrieval by the {@link 70 | * Throwable#getMessage()} method). 71 | * @param cause the cause (which is saved for later retrieval by the {@link Throwable#getCause()} 72 | * method). (A null value is permitted, and indicates that the cause is nonexistent 73 | * or unknown.) 74 | */ 75 | /*@ public normal_behavior 76 | @ ensures standardThrowable(message,cause); 77 | @*/ 78 | // @ pure 79 | public ParseException(final String message, final Throwable cause) { 80 | super(message, cause); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/exception/UnsupportedProviderException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except 5 | * in compliance with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | package com.amazonaws.encryptionsdk.exception; 15 | 16 | import com.amazonaws.encryptionsdk.MasterKeyProvider; 17 | 18 | /** 19 | * This exception is thrown when there are no {@link MasterKeyProvider}s which which support the 20 | * requested {@code provider} value. 21 | */ 22 | // @ non_null_by_default 23 | public class UnsupportedProviderException extends AwsCryptoException { 24 | private static final long serialVersionUID = -1L; 25 | 26 | /*@ public normal_behavior 27 | @ ensures standardThrowable(); 28 | @*/ 29 | // @ pure 30 | public UnsupportedProviderException() {} 31 | 32 | /*@ public normal_behavior 33 | @ ensures standardThrowable(message); 34 | @*/ 35 | // @ pure 36 | public UnsupportedProviderException(final String message) { 37 | super(message); 38 | } 39 | 40 | /*@ public normal_behavior 41 | @ ensures standardThrowable(cause); 42 | @*/ 43 | // @ pure 44 | public UnsupportedProviderException(final Throwable cause) { 45 | super(cause); 46 | } 47 | 48 | /*@ public normal_behavior 49 | @ ensures standardThrowable(message,cause); 50 | @*/ 51 | // @ pure 52 | public UnsupportedProviderException(final String message, final Throwable cause) { 53 | super(message, cause); 54 | } 55 | 56 | /*@ public normal_behavior 57 | @ ensures standardThrowable(message,cause); 58 | @*/ 59 | // @ pure // TODO 60 | public UnsupportedProviderException( 61 | final String message, 62 | final Throwable cause, 63 | final boolean enableSuppression, 64 | final boolean writableStackTrace) { 65 | super(message, cause, enableSuppression, writableStackTrace); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/exception/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except 5 | * in compliance with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | /** Contains the various exceptions which may be thrown by the AWS Encryption SDK. */ 15 | package com.amazonaws.encryptionsdk.exception; 16 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/internal/AesGcmJceKeyCipher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except 5 | * in compliance with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | package com.amazonaws.encryptionsdk.internal; 15 | 16 | import java.nio.ByteBuffer; 17 | import java.security.GeneralSecurityException; 18 | import java.security.InvalidKeyException; 19 | import java.security.Key; 20 | import java.util.Map; 21 | import javax.crypto.Cipher; 22 | import javax.crypto.SecretKey; 23 | import javax.crypto.spec.GCMParameterSpec; 24 | 25 | /** A JceKeyCipher based on the Advanced Encryption Standard in Galois/Counter Mode. */ 26 | class AesGcmJceKeyCipher extends JceKeyCipher { 27 | private static final int NONCE_LENGTH = 12; 28 | private static final int TAG_LENGTH = 128; 29 | private static final String TRANSFORMATION = "AES/GCM/NoPadding"; 30 | private static final int SPEC_LENGTH = Integer.BYTES + Integer.BYTES + NONCE_LENGTH; 31 | 32 | AesGcmJceKeyCipher(SecretKey key) { 33 | super(key, key); 34 | } 35 | 36 | private static byte[] specToBytes(final GCMParameterSpec spec) { 37 | final byte[] nonce = spec.getIV(); 38 | final byte[] result = new byte[SPEC_LENGTH]; 39 | final ByteBuffer buffer = ByteBuffer.wrap(result); 40 | buffer.putInt(spec.getTLen()); 41 | buffer.putInt(nonce.length); 42 | buffer.put(nonce); 43 | return result; 44 | } 45 | 46 | private static GCMParameterSpec bytesToSpec(final byte[] data, final int offset) 47 | throws InvalidKeyException { 48 | if (data.length - offset != SPEC_LENGTH) { 49 | throw new InvalidKeyException("Algorithm specification was an invalid data size"); 50 | } 51 | 52 | final ByteBuffer buffer = ByteBuffer.wrap(data, offset, SPEC_LENGTH); 53 | final int tagLen = buffer.getInt(); 54 | final int nonceLen = buffer.getInt(); 55 | 56 | if (tagLen != TAG_LENGTH) { 57 | throw new InvalidKeyException( 58 | String.format("Authentication tag length must be %s", TAG_LENGTH)); 59 | } 60 | 61 | if (nonceLen != NONCE_LENGTH) { 62 | throw new InvalidKeyException( 63 | String.format("Initialization vector (IV) length must be %s", NONCE_LENGTH)); 64 | } 65 | 66 | final byte[] nonce = new byte[nonceLen]; 67 | buffer.get(nonce); 68 | 69 | return new GCMParameterSpec(tagLen, nonce); 70 | } 71 | 72 | @Override 73 | WrappingData buildWrappingCipher(final Key key, final Map encryptionContext) 74 | throws GeneralSecurityException { 75 | final byte[] nonce = new byte[NONCE_LENGTH]; 76 | Utils.getSecureRandom().nextBytes(nonce); 77 | final GCMParameterSpec spec = new GCMParameterSpec(TAG_LENGTH, nonce); 78 | final Cipher cipher = Cipher.getInstance(TRANSFORMATION); 79 | cipher.init(Cipher.ENCRYPT_MODE, key, spec); 80 | final byte[] aad = EncryptionContextSerializer.serialize(encryptionContext); 81 | cipher.updateAAD(aad); 82 | return new WrappingData(cipher, specToBytes(spec)); 83 | } 84 | 85 | @Override 86 | Cipher buildUnwrappingCipher( 87 | final Key key, 88 | final byte[] extraInfo, 89 | final int offset, 90 | final Map encryptionContext) 91 | throws GeneralSecurityException { 92 | final GCMParameterSpec spec = bytesToSpec(extraInfo, offset); 93 | final Cipher cipher = Cipher.getInstance(TRANSFORMATION); 94 | cipher.init(Cipher.DECRYPT_MODE, key, spec); 95 | final byte[] aad = EncryptionContextSerializer.serialize(encryptionContext); 96 | cipher.updateAAD(aad); 97 | return cipher; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/internal/Constants.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except 5 | * in compliance with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | package com.amazonaws.encryptionsdk.internal; 15 | 16 | import com.amazonaws.encryptionsdk.CryptoAlgorithm; 17 | 18 | public final class Constants { 19 | /** 20 | * Default length of the message identifier used to uniquely identify every ciphertext created by 21 | * this library. 22 | * 23 | * @deprecated This value may change based on {@link CryptoAlgorithm#getMessageIdLength()} 24 | */ 25 | @Deprecated public static final int MESSAGE_ID_LEN = 16; 26 | 27 | private Constants() { 28 | // Prevent instantiation 29 | } 30 | 31 | /** Marker for identifying the final frame. */ 32 | public static final int ENDFRAME_SEQUENCE_NUMBER = ~0; // is 0xFFFFFFFF 33 | 34 | /** 35 | * The identifier for non-final frames in the framing content type. This value is used as part of 36 | * the additional authenticated data (AAD) when encryption of content in a frame. 37 | */ 38 | public static final String FRAME_STRING_ID = "AWSKMSEncryptionClient Frame"; 39 | 40 | /** 41 | * The identifier for the final frame in the framing content type. This value is used as part of 42 | * the additional authenticated data (AAD) when encryption of content in a frame. 43 | */ 44 | public static final String FINAL_FRAME_STRING_ID = "AWSKMSEncryptionClient Final Frame"; 45 | 46 | /** 47 | * The identifier for the single block content type. This value is used as part of the additional 48 | * authenticated data (AAD) when encryption of content in a single block. 49 | */ 50 | public static final String SINGLE_BLOCK_STRING_ID = "AWSKMSEncryptionClient Single Block"; 51 | 52 | /** Maximum length of the content that can be encrypted in GCM mode. */ 53 | public static final long GCM_MAX_CONTENT_LEN = (1L << 36) - 32; 54 | 55 | public static final int MAX_NONCE_LENGTH = (1 << 8) - 1; 56 | 57 | /** Maximum value of an unsigned short. */ 58 | public static final int UNSIGNED_SHORT_MAX_VAL = (1 << 16) - 1; 59 | 60 | public static final long MAX_FRAME_NUMBER = (1L << 32) - 1; 61 | 62 | public static final String EC_PUBLIC_KEY_FIELD = "aws-crypto-public-key"; 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/internal/LazyMessageCryptoHandler.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.encryptionsdk.internal; 2 | 3 | import com.amazonaws.encryptionsdk.MasterKey; 4 | import com.amazonaws.encryptionsdk.model.CiphertextHeaders; 5 | import java.util.List; 6 | import java.util.Map; 7 | import java.util.function.Function; 8 | import javax.annotation.concurrent.NotThreadSafe; 9 | 10 | /** 11 | * A {@link MessageCryptoHandler} that delegates to another MessageCryptoHandler, which is created 12 | * at the last possible moment. Typically, this is used in order to defer the creation of the data 13 | * key (and associated request to the {@link com.amazonaws.encryptionsdk.CryptoMaterialsManager} 14 | * until the max message size is known. 15 | */ 16 | @NotThreadSafe 17 | public class LazyMessageCryptoHandler implements MessageCryptoHandler { 18 | private Function delegateFactory; 19 | private MessageCryptoHandler delegate; 20 | private long maxInputSize = -1; 21 | 22 | public static final class LateBoundInfo { 23 | private final long maxInputSize; 24 | 25 | private LateBoundInfo(long maxInputSize) { 26 | this.maxInputSize = maxInputSize; 27 | } 28 | 29 | public long getMaxInputSize() { 30 | return maxInputSize; 31 | } 32 | } 33 | 34 | public LazyMessageCryptoHandler(Function delegateFactory) { 35 | this.delegateFactory = delegateFactory; 36 | this.delegate = null; 37 | } 38 | 39 | private MessageCryptoHandler getDelegate() { 40 | if (delegate == null) { 41 | delegate = delegateFactory.apply(new LateBoundInfo(maxInputSize)); 42 | if (maxInputSize != -1) { 43 | delegate.setMaxInputLength(maxInputSize); 44 | } 45 | 46 | // Release references to the delegate factory, now that we're done with it. 47 | delegateFactory = null; 48 | } 49 | 50 | return delegate; 51 | } 52 | 53 | @Override 54 | public void setMaxInputLength(long size) { 55 | if (size < 0) { 56 | throw new IllegalArgumentException("Max input size must be non-negative"); 57 | } 58 | 59 | if (delegate == null) { 60 | if (maxInputSize == -1 || maxInputSize > size) { 61 | maxInputSize = size; 62 | } 63 | } else { 64 | delegate.setMaxInputLength(size); 65 | } 66 | } 67 | 68 | @Override 69 | public boolean isComplete() { 70 | // If we haven't generated the delegate, we're definitely not done yet. 71 | return delegate != null && delegate.isComplete(); 72 | } 73 | 74 | /* Operations which autovivify the delegate */ 75 | 76 | @Override 77 | public Map getEncryptionContext() { 78 | return getDelegate().getEncryptionContext(); 79 | } 80 | 81 | @Override 82 | public CiphertextHeaders getHeaders() { 83 | return getDelegate().getHeaders(); 84 | } 85 | 86 | @Override 87 | public ProcessingSummary processBytes(byte[] in, int inOff, int inLen, byte[] out, int outOff) { 88 | return getDelegate().processBytes(in, inOff, inLen, out, outOff); 89 | } 90 | 91 | @Override 92 | public List> getMasterKeys() { 93 | return getDelegate().getMasterKeys(); 94 | } 95 | 96 | @Override 97 | public int doFinal(byte[] out, int outOff) { 98 | return getDelegate().doFinal(out, outOff); 99 | } 100 | 101 | @Override 102 | public int estimateOutputSize(int inLen) { 103 | return getDelegate().estimateOutputSize(inLen); 104 | } 105 | 106 | @Override 107 | public int estimatePartialOutputSize(int inLen) { 108 | return getDelegate().estimatePartialOutputSize(inLen); 109 | } 110 | 111 | @Override 112 | public int estimateFinalOutputSize() { 113 | return getDelegate().estimateFinalOutputSize(); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/internal/MessageCryptoHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except 5 | * in compliance with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | package com.amazonaws.encryptionsdk.internal; 15 | 16 | import com.amazonaws.encryptionsdk.MasterKey; 17 | import com.amazonaws.encryptionsdk.model.CiphertextHeaders; 18 | import java.util.List; 19 | import java.util.Map; 20 | 21 | public interface MessageCryptoHandler extends CryptoHandler { 22 | /** 23 | * Informs this handler of an upper bound on the input data size. The handler will throw an 24 | * exception if this bound is exceeded, and may use it to perform performance optimizations as 25 | * well. 26 | * 27 | *

If this method is called multiple times, the smallest bound will be used. 28 | * 29 | * @param size An upper bound on the input data size. 30 | */ 31 | void setMaxInputLength(long size); 32 | 33 | /** 34 | * Return the encryption context used in the generation of the data key used for the encryption of 35 | * content. 36 | * 37 | *

During decryption, this value should be obtained by parsing the ciphertext headers that 38 | * encodes this value. 39 | * 40 | * @return the key-value map containing the encryption context. 41 | */ 42 | Map getEncryptionContext(); 43 | 44 | CiphertextHeaders getHeaders(); 45 | 46 | /** 47 | * All used {@link MasterKey}s. For encryption flows, these are all the {@link 48 | * MasterKey}s used to protect the data. In the decryption flow, it is the single {@link 49 | * MasterKey} actually used to decrypt the data. 50 | */ 51 | List> getMasterKeys(); 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/internal/ProcessingSummary.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except 5 | * in compliance with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | package com.amazonaws.encryptionsdk.internal; 15 | 16 | public class ProcessingSummary { 17 | public static final ProcessingSummary ZERO = new ProcessingSummary(0, 0); 18 | 19 | private final int bytesWritten; 20 | private final int bytesProcessed; 21 | 22 | public ProcessingSummary(final int bytesWritten, final int bytesProcessed) { 23 | this.bytesWritten = bytesWritten; 24 | this.bytesProcessed = bytesProcessed; 25 | } 26 | 27 | public int getBytesProcessed() { 28 | return bytesProcessed; 29 | } 30 | 31 | public int getBytesWritten() { 32 | return bytesWritten; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/internal/SignaturePolicy.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.encryptionsdk.internal; 2 | 3 | import com.amazonaws.encryptionsdk.CryptoAlgorithm; 4 | 5 | public enum SignaturePolicy { 6 | AllowEncryptAllowDecrypt { 7 | @Override 8 | public boolean algorithmAllowedForDecrypt(CryptoAlgorithm algorithm) { 9 | return true; 10 | } 11 | }, 12 | AllowEncryptForbidDecrypt { 13 | @Override 14 | public boolean algorithmAllowedForDecrypt(CryptoAlgorithm algorithm) { 15 | return algorithm.getTrailingSignatureLength() == 0; 16 | } 17 | }; 18 | 19 | public abstract boolean algorithmAllowedForDecrypt(CryptoAlgorithm algorithm); 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/internal/VersionInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except 5 | * in compliance with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | package com.amazonaws.encryptionsdk.internal; 15 | 16 | import java.io.IOException; 17 | import java.net.URL; 18 | import java.util.Enumeration; 19 | import java.util.Properties; 20 | 21 | /** This class specifies the versioning system for the AWS KMS encryption client. */ 22 | public class VersionInfo { 23 | public static final String USER_AGENT_PREFIX = "AwsCrypto/"; 24 | public static final String UNKNOWN_VERSION = "unknown"; 25 | /* 26 | * Loads the version of the library 27 | */ 28 | public static String loadUserAgent() { 29 | return USER_AGENT_PREFIX + versionNumber(); 30 | } 31 | 32 | /** 33 | * This returns the API name compatible with the AWS SDK v2 34 | * 35 | * @return the name of the library with a tag indicating intended for AWS SDK v2 36 | */ 37 | public static String apiName() { 38 | return USER_AGENT_PREFIX.substring(0, USER_AGENT_PREFIX.length() - 1); 39 | } 40 | 41 | /* 42 | * String representation of the library version e.g. 2.3.3 43 | */ 44 | public static String versionNumber() { 45 | try { 46 | final Properties properties = new Properties(); 47 | final ClassLoader loader = VersionInfo.class.getClassLoader(); 48 | // Other JARs on the classpath may also define project.properties 49 | // Enumerate through and find the one for the ESDK 50 | Enumeration urls = loader.getResources("project.properties"); 51 | if (urls == null) { 52 | return UNKNOWN_VERSION; 53 | } 54 | while (urls.hasMoreElements()) { 55 | URL thisURL = urls.nextElement(); 56 | if (thisURL.getPath().contains("aws-encryption-sdk-java")) { 57 | properties.load(thisURL.openStream()); 58 | break; 59 | } 60 | } 61 | String maybeVersion = properties.getProperty("esdkVersion"); 62 | if (maybeVersion == null) { 63 | // This should never happen in practice, 64 | // but is included for robustness. 65 | return UNKNOWN_VERSION; 66 | } else { 67 | return maybeVersion; 68 | } 69 | } catch (final IOException ex) { 70 | return UNKNOWN_VERSION; 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except 5 | * in compliance with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | /** 15 | * Contains the internal classes that handle the cryptographic defined by the message formats and 16 | * algorithms. The package also includes auxiliary classes that implement serialization of 17 | * encryption context, parser for deserializing bytes into primitives, and generation of random 18 | * bytes. 19 | * 20 | *

No classes in this package are intended for public consumption. They may be changed at any 21 | * time without concern for API compatibility. 22 | * 23 | *

    24 | *
  • the CryptoHandler interface that defines the contract for the methods that must be 25 | * implemented by classes that perform encryption and decryption in this library. 26 | *
  • the EncryptionHandler and DecryptionHandler classes handle the creation and parsing of the 27 | * ciphertext headers as described in the message format. These two classes delegate the 28 | * actual encryption and decryption of content to the Block and Frame handlers. 29 | *
  • the BlockEncryptionHandler and BlockDecryptionHandler classes handle the encryption and 30 | * decryption of content stored as a single-block as described in the message format. 31 | *
  • the FrameEncryptionHandler and FrameDecryptionHandler classes handle the encryption and 32 | * decryption of content stored as frames as described in the message format. 33 | *
  • the CipherHandler that provides methods to cryptographically transform bytes using a block 34 | * cipher. Currently, it only uses AES-GCM block cipher. 35 | *
  • the EncContextSerializer provides methods to serialize a map containing the encryption 36 | * context into bytes, and deserialize bytes into a map containing the encryption context. 37 | *
  • the PrimitivesParser provides methods to parse primitive types from bytes. These methods 38 | * are used by deserialization code. 39 | *
  • the ContentAadGenerator provides methods to generate the Additional Authenticated Data 40 | * (AAD) used in encrypting the content. 41 | *
  • the Constants class that contains the constants and default values used in the library. 42 | *
43 | */ 44 | package com.amazonaws.encryptionsdk.internal; 45 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/jce/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except 5 | * in compliance with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | /** 15 | * Contains logic necessary to create {@link com.amazonaws.encryptionsdk.MasterKey}s with raw 16 | * cryptographic keys, {@link java.security.Key}s, or {@link java.security.KeyStore}. 17 | */ 18 | package com.amazonaws.encryptionsdk.jce; 19 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/kms/DiscoveryFilter.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.encryptionsdk.kms; 5 | 6 | import java.util.Arrays; 7 | import java.util.Collection; 8 | import java.util.Collections; 9 | import java.util.HashSet; 10 | 11 | /** 12 | * This class stores the configuration for filtering AWS KMS CMK ARNs by AWS account ID and 13 | * partition. 14 | * 15 | *

The filter allows a KMS CMK if its partition matches {@code partition} and its accountId is 16 | * included in {@code accountIds}. 17 | */ 18 | public final class DiscoveryFilter { 19 | private final String partition_; 20 | private final Collection accountIds_; 21 | 22 | public DiscoveryFilter(String partition, String... accountIds) { 23 | this(partition, Arrays.asList(accountIds)); 24 | } 25 | 26 | public DiscoveryFilter(String partition, Collection accountIds) { 27 | if (partition == null || partition.isEmpty()) { 28 | throw new IllegalArgumentException( 29 | "Discovery filter cannot be configured without " + "a partition."); 30 | } else if (accountIds == null || accountIds.isEmpty()) { 31 | throw new IllegalArgumentException( 32 | "Discovery filter cannot be configured without " + "account IDs."); 33 | } else if (accountIds.contains(null) || accountIds.contains("")) { 34 | throw new IllegalArgumentException( 35 | "Discovery filter cannot be configured with " + "null or empty account IDs."); 36 | } 37 | 38 | partition_ = partition; 39 | accountIds_ = new HashSet(accountIds); 40 | } 41 | 42 | public String getPartition() { 43 | return partition_; 44 | } 45 | 46 | public Collection getAccountIds() { 47 | return Collections.unmodifiableSet(new HashSet<>(accountIds_)); 48 | } 49 | 50 | public boolean allowsPartitionAndAccount(String partition, String accountId) { 51 | return (partition_.equals(partition) && accountIds_.contains(accountId)); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/kms/KmsMethods.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except 5 | * in compliance with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | package com.amazonaws.encryptionsdk.kms; 15 | 16 | import java.util.List; 17 | 18 | /** Methods common to all classes which interact with KMS. */ 19 | public interface KmsMethods { 20 | /** Sets the {@code grantTokens} which should be submitted to KMS when calling it. */ 21 | public void setGrantTokens(List grantTokens); 22 | 23 | /** Returns the grantTokens which this object sends to KMS when calling it. */ 24 | public List getGrantTokens(); 25 | 26 | /** Adds {@code grantToken} to the list of grantTokens sent to KMS when this class calls it. */ 27 | public void addGrantToken(String grantToken); 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/kms/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except 5 | * in compliance with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | /** 15 | * Contains logic necessary to create {@link com.amazonaws.encryptionsdk.MasterKey}s backed by AWS 16 | * KMS keys. 17 | */ 18 | package com.amazonaws.encryptionsdk.kms; 19 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/kmssdkv2/RegionalClientSupplier.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.encryptionsdk.kmssdkv2; 2 | 3 | import software.amazon.awssdk.regions.Region; 4 | import software.amazon.awssdk.services.kms.KmsClient; 5 | 6 | @FunctionalInterface 7 | public interface RegionalClientSupplier { 8 | /** 9 | * Supplies an {@link KmsClient} instance to use for a given {@link Region}. The {@link 10 | * KmsMasterKeyProvider} will not cache the result of this function. 11 | * 12 | *

Note: The AWS Encryption SDK for Java does not support the {@code KmsAsyncClient} interface. 13 | * 14 | * @param region The region to get a client for 15 | * @return The client to use, or null if this region cannot or should not be used. 16 | */ 17 | KmsClient getClient(Region region); 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/kmssdkv2/RequestClientCacher.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.encryptionsdk.kmssdkv2; 2 | 3 | import java.util.concurrent.ConcurrentHashMap; 4 | import software.amazon.awssdk.awscore.exception.AwsServiceException; 5 | import software.amazon.awssdk.core.interceptor.Context; 6 | import software.amazon.awssdk.core.interceptor.ExecutionAttributes; 7 | import software.amazon.awssdk.core.interceptor.ExecutionInterceptor; 8 | import software.amazon.awssdk.regions.Region; 9 | import software.amazon.awssdk.services.kms.KmsClient; 10 | 11 | class RequestClientCacher implements ExecutionInterceptor { 12 | private final ConcurrentHashMap cache_; 13 | private final Region region_; 14 | private KmsClient client_; 15 | 16 | volatile boolean ranBefore_ = false; 17 | 18 | RequestClientCacher(final ConcurrentHashMap cache, final Region region) { 19 | this.region_ = region; 20 | this.cache_ = cache; 21 | } 22 | 23 | public KmsClient setClient(final KmsClient client) { 24 | client_ = client; 25 | return client; 26 | } 27 | 28 | @Override 29 | public void afterExecution( 30 | Context.AfterExecution context, ExecutionAttributes executionAttributes) { 31 | if (ranBefore_) { 32 | return; 33 | } 34 | ranBefore_ = true; 35 | 36 | cache_.putIfAbsent(region_, client_); 37 | } 38 | 39 | @Override 40 | public void onExecutionFailure( 41 | Context.FailedExecution context, ExecutionAttributes executionAttributes) { 42 | if (ranBefore_) { 43 | return; 44 | } 45 | 46 | if (!(context.exception() instanceof AwsServiceException)) { 47 | return; 48 | } 49 | 50 | ranBefore_ = true; 51 | cache_.putIfAbsent(region_, client_); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/kmssdkv2/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except 5 | * in compliance with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | /** 15 | * Contains logic necessary to create {@link com.amazonaws.encryptionsdk.MasterKey}s backed by AWS 16 | * KMS keys. 17 | */ 18 | package com.amazonaws.encryptionsdk.kmssdkv2; 19 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/model/CiphertextType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except 5 | * in compliance with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | package com.amazonaws.encryptionsdk.model; 15 | 16 | import java.util.EnumSet; 17 | import java.util.HashMap; 18 | import java.util.Map; 19 | 20 | /** 21 | * This enum describes the supported types of ciphertext in this library. 22 | * 23 | *

Format: CiphertextType(byte value representing the type) 24 | */ 25 | public enum CiphertextType { 26 | CUSTOMER_AUTHENTICATED_ENCRYPTED_DATA(128); 27 | 28 | private final byte value_; 29 | 30 | /** 31 | * Create a mapping between the CiphertextType object and its byte value. This is a static method 32 | * so the map is created when the class is loaded. This enables fast lookups of the CiphertextType 33 | * given a value. 34 | */ 35 | private static final Map ID_MAPPING = new HashMap<>(); 36 | 37 | static { 38 | for (final CiphertextType s : EnumSet.allOf(CiphertextType.class)) { 39 | ID_MAPPING.put(s.value_, s); 40 | } 41 | } 42 | 43 | private CiphertextType(final int value) { 44 | /* 45 | * Java reads literals as integers. So we cast the integer value to byte 46 | * here to avoid doing this in the enum definitions above. 47 | */ 48 | value_ = (byte) value; 49 | } 50 | 51 | /** 52 | * Return the value used to encode this ciphertext type object in the ciphertext. 53 | * 54 | * @return the byte value used to encode this ciphertext type. 55 | */ 56 | public byte getValue() { 57 | return value_; 58 | } 59 | 60 | /** 61 | * Deserialize the provided byte value by returning the CiphertextType object representing the 62 | * byte value. 63 | * 64 | * @param value the byte representing the value of the CiphertextType object. 65 | * @return the CiphertextType object representing the byte value. 66 | */ 67 | public static CiphertextType deserialize(final byte value) { 68 | final Byte valueByte = Byte.valueOf(value); 69 | final CiphertextType result = ID_MAPPING.get(valueByte); 70 | return result; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/model/ContentType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except 5 | * in compliance with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | package com.amazonaws.encryptionsdk.model; 15 | 16 | import java.util.EnumSet; 17 | import java.util.HashMap; 18 | import java.util.Map; 19 | 20 | /** 21 | * This enum describes the supported types for storing the encrypted content in the message format. 22 | * There are two types current currently supported: single block and frames. 23 | * 24 | *

The single block format stores the encrypted content in a single block wrapped with headers 25 | * containing the nonce, MAC tag, and the content length. 26 | * 27 | *

The frame format partitions the encrypted content in multiple frames of a specified frame 28 | * length. Each frame is wrapped by an header containing the frame sequence number, nonce, and the 29 | * MAC tag. 30 | * 31 | *

Format: ContentType(byte value representing the type) 32 | */ 33 | public enum ContentType { 34 | SINGLEBLOCK(1), 35 | FRAME(2); 36 | 37 | private final byte value_; 38 | 39 | /** 40 | * Create a mapping between the ContentType object and its byte value. This is a static method so 41 | * the map is created when the class is loaded. This enables fast lookups of the ContentType given 42 | * a value. 43 | */ 44 | private static final Map ID_MAPPING = new HashMap(); 45 | 46 | static { 47 | for (final ContentType s : EnumSet.allOf(ContentType.class)) { 48 | ID_MAPPING.put(s.value_, s); 49 | } 50 | } 51 | 52 | private ContentType(final int value) { 53 | /* 54 | * Java reads literals as integers. So we cast the integer value to byte 55 | * here to avoid doing this in the enum definitions above. 56 | */ 57 | value_ = (byte) value; 58 | } 59 | 60 | /** 61 | * Return the value used to encode this content type object in the ciphertext. 62 | * 63 | * @return the byte value used to encode this content type. 64 | */ 65 | public byte getValue() { 66 | return value_; 67 | } 68 | 69 | /** 70 | * Deserialize the provided byte value by returning the ContentType object representing the byte 71 | * value. 72 | * 73 | * @param value the byte representing the value of the ContentType object. 74 | * @return the ContentType object representing the byte value. 75 | */ 76 | public static ContentType deserialize(final byte value) { 77 | final Byte valueByte = Byte.valueOf(value); 78 | final ContentType result = ID_MAPPING.get(valueByte); 79 | return result; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/model/DecryptionMaterials.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.encryptionsdk.model; 2 | 3 | import com.amazonaws.encryptionsdk.DataKey; 4 | import java.security.PublicKey; 5 | import java.util.Collections; 6 | import java.util.Map; 7 | 8 | public final class DecryptionMaterials { 9 | private final DataKey dataKey; 10 | private final PublicKey trailingSignatureKey; 11 | private final Map encryptionContext; 12 | 13 | private DecryptionMaterials(Builder b) { 14 | dataKey = b.getDataKey(); 15 | trailingSignatureKey = b.getTrailingSignatureKey(); 16 | if (b.getEncryptionContext() != null) { 17 | encryptionContext = b.getEncryptionContext(); 18 | } else { 19 | encryptionContext = Collections.emptyMap(); 20 | } 21 | } 22 | 23 | public DataKey getDataKey() { 24 | return dataKey; 25 | } 26 | 27 | public PublicKey getTrailingSignatureKey() { 28 | return trailingSignatureKey; 29 | } 30 | 31 | public Map getEncryptionContext() { 32 | return encryptionContext; 33 | } 34 | 35 | public static Builder newBuilder() { 36 | return new Builder(); 37 | } 38 | 39 | public Builder toBuilder() { 40 | return new Builder(this); 41 | } 42 | 43 | public static final class Builder { 44 | private DataKey dataKey; 45 | private PublicKey trailingSignatureKey; 46 | private Map encryptionContext; 47 | 48 | private Builder(DecryptionMaterials result) { 49 | this.dataKey = result.getDataKey(); 50 | this.trailingSignatureKey = result.getTrailingSignatureKey(); 51 | this.encryptionContext = result.getEncryptionContext(); 52 | } 53 | 54 | private Builder() {} 55 | 56 | public DataKey getDataKey() { 57 | return dataKey; 58 | } 59 | 60 | public Builder setDataKey(DataKey dataKey) { 61 | this.dataKey = dataKey; 62 | return this; 63 | } 64 | 65 | public PublicKey getTrailingSignatureKey() { 66 | return trailingSignatureKey; 67 | } 68 | 69 | public Builder setTrailingSignatureKey(PublicKey trailingSignatureKey) { 70 | this.trailingSignatureKey = trailingSignatureKey; 71 | return this; 72 | } 73 | 74 | public Map getEncryptionContext() { 75 | return encryptionContext; 76 | } 77 | 78 | public Builder setEncryptionContext(Map encryptionContext) { 79 | this.encryptionContext = encryptionContext; 80 | return this; 81 | } 82 | 83 | public DecryptionMaterials build() { 84 | return new DecryptionMaterials(this); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/model/DecryptionMaterialsHandler.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.encryptionsdk.model; 2 | 3 | import com.amazonaws.encryptionsdk.CryptoAlgorithm; 4 | import com.amazonaws.encryptionsdk.DataKey; 5 | import com.amazonaws.encryptionsdk.internal.TrailingSignatureAlgorithm; 6 | import java.security.PublicKey; 7 | import java.util.Collections; 8 | import java.util.List; 9 | import java.util.Map; 10 | import javax.crypto.SecretKey; 11 | import javax.crypto.spec.SecretKeySpec; 12 | 13 | /** 14 | * Handler to abstract the differences between the original {@link DecryptionMaterials} and the 15 | * MPL's {@link software.amazon.cryptography.materialproviders.model.DecryptionMaterials}. 16 | */ 17 | public class DecryptionMaterialsHandler { 18 | private DecryptionMaterials materials; 19 | private software.amazon.cryptography.materialproviders.model.DecryptionMaterials mplMaterials; 20 | 21 | public DecryptionMaterialsHandler(DecryptionMaterials materials) { 22 | this.materials = materials; 23 | this.mplMaterials = null; 24 | } 25 | 26 | public DecryptionMaterialsHandler( 27 | software.amazon.cryptography.materialproviders.model.DecryptionMaterials mplMaterials) { 28 | this.mplMaterials = mplMaterials; 29 | this.materials = null; 30 | } 31 | 32 | public DataKey getDataKey() { 33 | if (materials != null) { 34 | return materials.getDataKey(); 35 | } else { 36 | byte[] cacheDataKey = mplMaterials.plaintextDataKey().array(); 37 | SecretKey key = 38 | new SecretKeySpec( 39 | cacheDataKey, 40 | 0, 41 | cacheDataKey.length, 42 | CryptoAlgorithm.valueOf(mplMaterials.algorithmSuite().id().ESDK().name()) 43 | .getDataKeyAlgo()); 44 | return new DataKey<>(key, new byte[0], new byte[0], null); 45 | } 46 | } 47 | 48 | public PublicKey getTrailingSignatureKey() { 49 | if (materials != null) { 50 | return materials.getTrailingSignatureKey(); 51 | } else { 52 | if (mplMaterials.verificationKey() == null) { 53 | return null; 54 | } 55 | // Converts ByteBuffer to ECPublicKey using the AlgorithmSuiteInfo 56 | return TrailingSignatureAlgorithm.forCryptoAlgorithm(mplMaterials.algorithmSuite()) 57 | .decompressPublicKey(mplMaterials.verificationKey().array()); 58 | } 59 | } 60 | 61 | public Map getEncryptionContext() { 62 | if (materials != null) { 63 | return materials.getEncryptionContext(); 64 | } else { 65 | return mplMaterials.encryptionContext(); 66 | } 67 | } 68 | 69 | public List getRequiredEncryptionContextKeys() { 70 | if (materials != null) { 71 | return Collections.emptyList(); 72 | } else { 73 | return mplMaterials.requiredEncryptionContextKeys(); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/model/DecryptionMaterialsRequest.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.encryptionsdk.model; 2 | 3 | import com.amazonaws.encryptionsdk.CryptoAlgorithm; 4 | import java.util.ArrayList; 5 | import java.util.Collections; 6 | import java.util.HashMap; 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | public final class DecryptionMaterialsRequest { 11 | private final CryptoAlgorithm algorithm; 12 | private final Map encryptionContext; 13 | private final Map reproducedEncryptionContext; 14 | private final List encryptedDataKeys; 15 | 16 | private DecryptionMaterialsRequest(Builder b) { 17 | this.algorithm = b.getAlgorithm(); 18 | this.encryptionContext = b.getEncryptionContext(); 19 | this.reproducedEncryptionContext = b.getReproducedEncryptionContext(); 20 | this.encryptedDataKeys = b.getEncryptedDataKeys(); 21 | } 22 | 23 | public CryptoAlgorithm getAlgorithm() { 24 | return algorithm; 25 | } 26 | 27 | public Map getEncryptionContext() { 28 | return encryptionContext; 29 | } 30 | 31 | public Map getReproducedEncryptionContext() { 32 | return reproducedEncryptionContext; 33 | } 34 | 35 | public List getEncryptedDataKeys() { 36 | return encryptedDataKeys; 37 | } 38 | 39 | public static Builder newBuilder() { 40 | return new Builder(); 41 | } 42 | 43 | public Builder toBuilder() { 44 | return new Builder(this); 45 | } 46 | 47 | public static DecryptionMaterialsRequest fromCiphertextHeaders(CiphertextHeaders headers) { 48 | return newBuilder() 49 | .setAlgorithm(headers.getCryptoAlgoId()) 50 | .setEncryptionContext(headers.getEncryptionContextMap()) 51 | .setEncryptedDataKeys(headers.getEncryptedKeyBlobs()) 52 | .build(); 53 | } 54 | 55 | public static final class Builder { 56 | private CryptoAlgorithm algorithm; 57 | private Map encryptionContext; 58 | private Map reproducedEncryptionContext; 59 | private List encryptedDataKeys; 60 | 61 | private Builder(DecryptionMaterialsRequest request) { 62 | this.algorithm = request.getAlgorithm(); 63 | this.encryptionContext = request.getEncryptionContext(); 64 | this.reproducedEncryptionContext = request.getReproducedEncryptionContext(); 65 | this.encryptedDataKeys = request.getEncryptedDataKeys(); 66 | } 67 | 68 | private Builder() {} 69 | 70 | public DecryptionMaterialsRequest build() { 71 | return new DecryptionMaterialsRequest(this); 72 | } 73 | 74 | public CryptoAlgorithm getAlgorithm() { 75 | return algorithm; 76 | } 77 | 78 | public Builder setAlgorithm(CryptoAlgorithm algorithm) { 79 | this.algorithm = algorithm; 80 | return this; 81 | } 82 | 83 | public Map getEncryptionContext() { 84 | return encryptionContext; 85 | } 86 | 87 | public Builder setEncryptionContext(Map encryptionContext) { 88 | this.encryptionContext = Collections.unmodifiableMap(new HashMap<>(encryptionContext)); 89 | return this; 90 | } 91 | 92 | public Map getReproducedEncryptionContext() { 93 | return reproducedEncryptionContext; 94 | } 95 | 96 | public Builder setReproducedEncryptionContext(Map reproducedEncryptionContext) { 97 | this.reproducedEncryptionContext = 98 | Collections.unmodifiableMap(new HashMap<>(reproducedEncryptionContext)); 99 | return this; 100 | } 101 | 102 | public List getEncryptedDataKeys() { 103 | return encryptedDataKeys; 104 | } 105 | 106 | public Builder setEncryptedDataKeys(List encryptedDataKeys) { 107 | this.encryptedDataKeys = Collections.unmodifiableList(new ArrayList<>(encryptedDataKeys)); 108 | return this; 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/model/EncryptionCompletionListener.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.encryptionsdk.model; 2 | 3 | @FunctionalInterface 4 | public interface EncryptionCompletionListener { 5 | /** 6 | * Invoked upon encryption completion; MaterialsManagers that need to know the size of the 7 | * plaintext (e.g. to enforce caching policies) can make use of this. 8 | * 9 | * @param plaintextBytes Total number of plaintext bytes encrypted 10 | */ 11 | void onEncryptDone(long plaintextBytes); 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/model/EncryptionMaterialsHandler.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.encryptionsdk.model; 2 | 3 | import com.amazonaws.encryptionsdk.CryptoAlgorithm; 4 | import com.amazonaws.encryptionsdk.MasterKey; 5 | import com.amazonaws.encryptionsdk.internal.TrailingSignatureAlgorithm; 6 | import java.security.PrivateKey; 7 | import java.util.ArrayList; 8 | import java.util.Collections; 9 | import java.util.List; 10 | import java.util.Map; 11 | import javax.crypto.SecretKey; 12 | import javax.crypto.spec.SecretKeySpec; 13 | import software.amazon.cryptography.materialproviders.model.EncryptedDataKey; 14 | 15 | /** 16 | * Handler to abstract the differences between the original {@link EncryptionMaterials} and the 17 | * MPL's {@link software.amazon.cryptography.materialproviders.model.EncryptionMaterials}. 18 | */ 19 | public class EncryptionMaterialsHandler { 20 | EncryptionMaterials materials; 21 | software.amazon.cryptography.materialproviders.model.EncryptionMaterials mplMaterials; 22 | 23 | public EncryptionMaterialsHandler(EncryptionMaterials materials) { 24 | this.materials = materials; 25 | } 26 | 27 | public EncryptionMaterialsHandler( 28 | software.amazon.cryptography.materialproviders.model.EncryptionMaterials mplMaterials) { 29 | this.mplMaterials = mplMaterials; 30 | } 31 | 32 | public CryptoAlgorithm getAlgorithm() { 33 | if (materials != null) { 34 | return materials.getAlgorithm(); 35 | } else { 36 | return CryptoAlgorithm.valueOf(mplMaterials.algorithmSuite().id().ESDK().name()); 37 | } 38 | } 39 | 40 | public Map getEncryptionContext() { 41 | if (materials != null) { 42 | return materials.getEncryptionContext(); 43 | } else { 44 | return mplMaterials.encryptionContext(); 45 | } 46 | } 47 | 48 | public List getEncryptedDataKeys() { 49 | if (materials != null) { 50 | return materials.getEncryptedDataKeys(); 51 | } else { 52 | List edks = mplMaterials.encryptedDataKeys(); 53 | List keyBlobs = new ArrayList<>(edks.size()); 54 | for (EncryptedDataKey edk : edks) { 55 | keyBlobs.add( 56 | new KeyBlob( 57 | edk.keyProviderId(), edk.keyProviderInfo().array(), edk.ciphertext().array())); 58 | } 59 | return keyBlobs; 60 | } 61 | } 62 | 63 | public SecretKey getCleartextDataKey() { 64 | if (materials != null) { 65 | return materials.getCleartextDataKey(); 66 | } else { 67 | byte[] cacheDataKey = mplMaterials.plaintextDataKey().array(); 68 | CryptoAlgorithm cryptoAlgorithm = 69 | CryptoAlgorithm.valueOf(mplMaterials.algorithmSuite().id().ESDK().name()); 70 | return new SecretKeySpec( 71 | cacheDataKey, 0, cacheDataKey.length, cryptoAlgorithm.getDataKeyAlgo()); 72 | } 73 | } 74 | 75 | public PrivateKey getTrailingSignatureKey() { 76 | if (materials != null) { 77 | return materials.getTrailingSignatureKey(); 78 | } else { 79 | if (mplMaterials.signingKey() == null) { 80 | return null; 81 | } 82 | // Converts ByteBuffer to ECPrivateKey using the AlgorithmSuiteInfo 83 | return TrailingSignatureAlgorithm.forCryptoAlgorithm(mplMaterials.algorithmSuite()) 84 | .privateKeyFromByteBuffer(mplMaterials.signingKey()); 85 | } 86 | } 87 | 88 | public List getRequiredEncryptionContextKeys() { 89 | if (materials != null) { 90 | return Collections.emptyList(); 91 | } else { 92 | return mplMaterials.requiredEncryptionContextKeys(); 93 | } 94 | } 95 | 96 | public List getMasterKeys() { 97 | if (materials != null) { 98 | return materials.getMasterKeys(); 99 | } else { 100 | // Return Empty List 101 | return Collections.emptyList(); 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/model/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except 5 | * in compliance with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | /** 15 | * Contains the classes that implement the defined message format for storing the encrypted content 16 | * and the data key. 17 | * 18 | *

    19 | *
  • the CiphertextHeaders class implements the format for the headers that wrap the 20 | * (single-block/framed) encrypted content. The data key is stored in this header. 21 | *
  • the CipherBlockHeaders class implements the format for the headers that wrap the encrypted 22 | * content stored as a single-block. 23 | *
  • the CipherFrameHeader class implements the format for the headers that wrap the encrypted 24 | * content stored in frames. 25 | *
  • the KeyBlob class implements the format for storing the encrypted data key along with the 26 | * headers that identify the key provider. 27 | *
28 | */ 29 | package com.amazonaws.encryptionsdk.model; 30 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/multi/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except 5 | * in compliance with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | /** 15 | * Contains logic necessary to create {@link com.amazonaws.encryptionsdk.MasterKeyProvider}s which 16 | * are backed by multiple {@code MasterKeyProviders}. 17 | */ 18 | package com.amazonaws.encryptionsdk.multi; 19 | -------------------------------------------------------------------------------- /src/main/java/com/amazonaws/encryptionsdk/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except 5 | * in compliance with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | /** 15 | * Contains {@link com.amazonaws.encryptionsdk.AwsCrypto}, the primary entry-point to the Aws 16 | * Encryption SDK. 17 | */ 18 | package com.amazonaws.encryptionsdk; 19 | -------------------------------------------------------------------------------- /src/main/resources/project.properties: -------------------------------------------------------------------------------- 1 | esdkVersion=${project.version} 2 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/crypto/examples/keyrings/AwsKmsHierarchicalKeyringExampleTest.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.crypto.examples.keyrings; 5 | 6 | import com.amazonaws.crypto.examples.keyrings.hierarchical.AwsKmsHierarchicalKeyringExample; 7 | import com.amazonaws.encryptionsdk.kms.KMSTestFixtures; 8 | import org.junit.Test; 9 | 10 | public class AwsKmsHierarchicalKeyringExampleTest { 11 | @Test 12 | public void testEncryptAndDecrypt() { 13 | AwsKmsHierarchicalKeyringExample.encryptAndDecryptWithKeyring( 14 | KMSTestFixtures.TEST_KEYSTORE_NAME, 15 | KMSTestFixtures.TEST_LOGICAL_KEYSTORE_NAME, 16 | KMSTestFixtures.TEST_KEYSTORE_KMS_KEY_ID); 17 | } 18 | 19 | @Test 20 | public void testEncryptAndDecryptWithKeyringThreadSafe() { 21 | AwsKmsHierarchicalKeyringExample.encryptAndDecryptWithKeyringThreadSafe( 22 | KMSTestFixtures.TEST_KEYSTORE_NAME, 23 | KMSTestFixtures.TEST_LOGICAL_KEYSTORE_NAME, 24 | KMSTestFixtures.TEST_KEYSTORE_KMS_KEY_ID); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/crypto/examples/keyrings/AwsKmsRsaKeyringExampleTest.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.crypto.examples.keyrings; 5 | 6 | import com.amazonaws.encryptionsdk.kms.KMSTestFixtures; 7 | import org.junit.Test; 8 | 9 | public class AwsKmsRsaKeyringExampleTest { 10 | 11 | @Test 12 | public void testEncryptAndDecrypt() { 13 | AwsKmsRsaKeyringExample.encryptAndDecryptWithKeyring(KMSTestFixtures.US_WEST_2_KMS_RSA_KEY_ID); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/crypto/examples/keyrings/BasicEncryptionKeyringExampleTest.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.crypto.examples.keyrings; 5 | 6 | import com.amazonaws.encryptionsdk.kms.KMSTestFixtures; 7 | import org.junit.Test; 8 | 9 | public class BasicEncryptionKeyringExampleTest { 10 | 11 | @Test 12 | public void testEncryptAndDecrypt() { 13 | BasicEncryptionKeyringExample.encryptAndDecryptWithKeyring(KMSTestFixtures.TEST_KEY_IDS[0]); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/crypto/examples/keyrings/CustomizeSDKClientTest.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.crypto.examples.keyrings; 2 | 3 | import com.amazonaws.encryptionsdk.kms.KMSTestFixtures; 4 | import org.junit.Test; 5 | 6 | public class CustomizeSDKClientTest { 7 | @Test 8 | public void testEncryptAndDecrypt() { 9 | BasicEncryptionKeyringExample.encryptAndDecryptWithKeyring(KMSTestFixtures.TEST_KEY_IDS[0]); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/crypto/examples/keyrings/DiscoveryDecryptionKeyringExampleTest.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.crypto.examples.keyrings; 5 | 6 | import com.amazonaws.encryptionsdk.kms.KMSTestFixtures; 7 | import org.junit.Test; 8 | 9 | public class DiscoveryDecryptionKeyringExampleTest { 10 | 11 | @Test 12 | public void testEncryptAndDecrypt() { 13 | DiscoveryDecryptionKeyringExample.encryptAndDecryptWithKeyring( 14 | KMSTestFixtures.TEST_KEY_IDS[0], 15 | KMSTestFixtures.PARTITION, 16 | KMSTestFixtures.ACCOUNT_ID, 17 | KMSTestFixtures.US_WEST_2); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/crypto/examples/keyrings/DiscoveryMultiRegionDecryptionKeyringExampleTest.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.crypto.examples.keyrings; 5 | 6 | import com.amazonaws.encryptionsdk.kms.KMSTestFixtures; 7 | import org.junit.Test; 8 | 9 | public class DiscoveryMultiRegionDecryptionKeyringExampleTest { 10 | 11 | @Test 12 | public void testEncryptAndDecrypt() { 13 | DiscoveryMultiRegionDecryptionKeyringExample.encryptAndDecryptWithKeyring( 14 | KMSTestFixtures.US_EAST_1_MULTI_REGION_KEY_ID, 15 | KMSTestFixtures.PARTITION, 16 | KMSTestFixtures.ACCOUNT_ID, 17 | KMSTestFixtures.US_WEST_2); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/crypto/examples/keyrings/MultiKeyringExampleTest.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.crypto.examples.keyrings; 2 | 3 | import com.amazonaws.encryptionsdk.kms.KMSTestFixtures; 4 | import java.nio.ByteBuffer; 5 | import org.junit.Test; 6 | 7 | public class MultiKeyringExampleTest { 8 | @Test 9 | public void testEncryptAndDecrypt() { 10 | // Generate a new AES key 11 | ByteBuffer aesKeyBytes = MultiKeyringExample.generateAesKeyBytes(); 12 | 13 | MultiKeyringExample.encryptAndDecryptWithKeyring(KMSTestFixtures.TEST_KEY_IDS[0], aesKeyBytes); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/crypto/examples/keyrings/MultipleCmkEncryptKeyringExampleTest.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.crypto.examples.keyrings; 5 | 6 | import com.amazonaws.encryptionsdk.kms.KMSTestFixtures; 7 | import org.junit.Test; 8 | 9 | public class MultipleCmkEncryptKeyringExampleTest { 10 | 11 | @Test 12 | public void testEncryptAndDecrypt() { 13 | MultipleCmkEncryptKeyringExample.encryptAndDecryptWithKeyring( 14 | KMSTestFixtures.TEST_KEY_IDS[0], KMSTestFixtures.TEST_KEY_IDS[1]); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/crypto/examples/keyrings/RawAesKeyringExampleTest.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.crypto.examples.keyrings; 5 | 6 | import java.nio.ByteBuffer; 7 | import org.junit.Test; 8 | 9 | public class RawAesKeyringExampleTest { 10 | @Test 11 | public void testRawAesKeyringExample() { 12 | // Generate a new AES key 13 | ByteBuffer aesKeyBytes = RawAesKeyringExample.generateAesKeyBytes(); 14 | 15 | RawAesKeyringExample.encryptAndDecryptWithKeyring(aesKeyBytes); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/crypto/examples/keyrings/RawRsaKeyringExampleTest.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.crypto.examples.keyrings; 5 | 6 | import java.nio.ByteBuffer; 7 | import java.security.KeyPair; 8 | import org.junit.Test; 9 | 10 | public class RawRsaKeyringExampleTest { 11 | @Test 12 | public void testRawAesKeyringExample() { 13 | KeyPair keyPair = RawRsaKeyringExample.generateKeyPair(); 14 | ByteBuffer publicKeyBytes = RawRsaKeyringExample.getPEMPublicKey(keyPair.getPublic()); 15 | ByteBuffer privateKeyBytes = RawRsaKeyringExample.getPEMPrivateKey(keyPair.getPrivate()); 16 | 17 | RawRsaKeyringExample.encryptAndDecryptWithKeyring(publicKeyBytes, privateKeyBytes); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/crypto/examples/keyrings/RequiredEncryptionContextCMMExampleTest.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.crypto.examples.keyrings; 5 | 6 | import com.amazonaws.encryptionsdk.kms.KMSTestFixtures; 7 | import org.junit.Test; 8 | 9 | public class RequiredEncryptionContextCMMExampleTest { 10 | 11 | @Test 12 | public void testEncryptAndDecrypt() { 13 | RequiredEncryptionContextCMMExample.encryptAndDecryptWithKeyring( 14 | KMSTestFixtures.US_WEST_2_KEY_ID); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/crypto/examples/keyrings/SetCommitmentPolicyKeyringExampleTest.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.crypto.examples.keyrings; 5 | 6 | import com.amazonaws.encryptionsdk.kms.KMSTestFixtures; 7 | import org.junit.Test; 8 | 9 | public class SetCommitmentPolicyKeyringExampleTest { 10 | 11 | @Test 12 | public void testEncryptAndDecryptKeyrings() { 13 | SetCommitmentPolicyKeyringExample.encryptAndDecryptWithKeyrings( 14 | KMSTestFixtures.TEST_KEY_IDS[0]); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/crypto/examples/keyrings/SetEncryptionAlgorithmKeyringExampleTest.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.crypto.examples.keyrings; 5 | 6 | import com.amazonaws.encryptionsdk.kms.KMSTestFixtures; 7 | import org.junit.Test; 8 | 9 | public class SetEncryptionAlgorithmKeyringExampleTest { 10 | 11 | @Test 12 | public void testEncryptAndDecrypt() { 13 | SetEncryptionAlgorithmKeyringExample.encryptAndDecryptWithKeyring( 14 | KMSTestFixtures.TEST_KEY_IDS[0]); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/crypto/examples/keyrings/SharedCacheAcrossHierarchicalKeyringsExampleTest.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.crypto.examples.keyrings; 5 | 6 | import com.amazonaws.crypto.examples.keyrings.hierarchical.SharedCacheAcrossHierarchicalKeyringsExample; 7 | import com.amazonaws.encryptionsdk.kms.KMSTestFixtures; 8 | import org.junit.Test; 9 | 10 | public class SharedCacheAcrossHierarchicalKeyringsExampleTest { 11 | @Test 12 | public void testEncryptAndDecrypt() { 13 | SharedCacheAcrossHierarchicalKeyringsExample.encryptAndDecryptWithKeyring( 14 | KMSTestFixtures.TEST_KEYSTORE_NAME, 15 | KMSTestFixtures.TEST_LOGICAL_KEYSTORE_NAME, 16 | KMSTestFixtures.HIERARCHY_KEYRING_PARTITION_ID, 17 | KMSTestFixtures.TEST_KEYSTORE_KMS_KEY_ID); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/crypto/examples/keyrings/StreamingWithRequiredEncryptionContextCMMExampleTest.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.crypto.examples.keyrings; 5 | 6 | import com.amazonaws.encryptionsdk.kms.KMSTestFixtures; 7 | import java.io.File; 8 | import java.io.IOException; 9 | import java.nio.charset.StandardCharsets; 10 | import java.nio.file.Files; 11 | import java.nio.file.Paths; 12 | import java.security.SecureRandom; 13 | import org.junit.Test; 14 | 15 | public class StreamingWithRequiredEncryptionContextCMMExampleTest { 16 | 17 | @Test 18 | public void testEncryptAndDecrypt() throws IOException { 19 | // Create a temporary file for testing the example 20 | final String srcFile = "RandomFile.txt"; 21 | final File file = new File(srcFile); 22 | file.createNewFile(); 23 | String randomMessage = generateRandomMessage(1024); 24 | 25 | writeToFile(srcFile, randomMessage); 26 | 27 | StreamingWithRequiredEncryptionContextCMMExample.encryptAndDecryptWithKeyring( 28 | srcFile, KMSTestFixtures.US_WEST_2_KEY_ID); 29 | } 30 | 31 | private static String generateRandomMessage(int length) { 32 | String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 33 | StringBuilder randomMessage = new StringBuilder(); 34 | 35 | SecureRandom random = new SecureRandom(); 36 | for (int i = 0; i < length; i++) { 37 | int randomIndex = random.nextInt(characters.length()); 38 | randomMessage.append(characters.charAt(randomIndex)); 39 | } 40 | 41 | return randomMessage.toString(); 42 | } 43 | 44 | private static void writeToFile(String srcFile, String content) throws IOException { 45 | Files.write(Paths.get(srcFile), content.getBytes(StandardCharsets.UTF_8)); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/crypto/examples/v2/BasicEncryptionExampleTest.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.crypto.examples.v2; 5 | 6 | import com.amazonaws.encryptionsdk.kms.KMSTestFixtures; 7 | import org.junit.Test; 8 | 9 | public class BasicEncryptionExampleTest { 10 | 11 | @Test 12 | public void testEncryptAndDecrypt() { 13 | BasicEncryptionExample.encryptAndDecrypt(KMSTestFixtures.TEST_KEY_IDS[0]); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/crypto/examples/v2/BasicMultiRegionKeyEncryptionExampleTest.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.crypto.examples.v2; 5 | 6 | import com.amazonaws.encryptionsdk.kms.KMSTestFixtures; 7 | import org.junit.Test; 8 | 9 | public class BasicMultiRegionKeyEncryptionExampleTest { 10 | 11 | @Test 12 | public void testEncryptAndDecrypt() { 13 | BasicMultiRegionKeyEncryptionExample.encryptAndDecrypt( 14 | KMSTestFixtures.US_EAST_1_MULTI_REGION_KEY_ID, 15 | KMSTestFixtures.US_WEST_2_MULTI_REGION_KEY_ID); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/crypto/examples/v2/CustomCMMExampleTest.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.crypto.examples.v2; 5 | 6 | import com.amazonaws.encryptionsdk.CryptoMaterialsManager; 7 | import com.amazonaws.encryptionsdk.kms.KMSTestFixtures; 8 | import com.amazonaws.encryptionsdk.kms.KmsMasterKeyProvider; 9 | import org.junit.Test; 10 | 11 | public class CustomCMMExampleTest { 12 | 13 | @Test 14 | public void testCustomCMMExample() { 15 | CryptoMaterialsManager cmm = 16 | new CustomCMMExample.SigningSuiteOnlyCMM( 17 | KmsMasterKeyProvider.builder().buildStrict(KMSTestFixtures.US_WEST_2_KEY_ID)); 18 | CustomCMMExample.encryptAndDecryptWithCMM(cmm); 19 | } 20 | 21 | @Test 22 | public void testV2Cmm() { 23 | V2DefaultCryptoMaterialsManager cmm = 24 | new V2DefaultCryptoMaterialsManager( 25 | KmsMasterKeyProvider.builder().buildStrict(KMSTestFixtures.US_WEST_2_KEY_ID)); 26 | CustomCMMExample.encryptAndDecryptWithCMM(cmm); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/crypto/examples/v2/DiscoveryDecryptionExampleTest.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.crypto.examples.v2; 5 | 6 | import com.amazonaws.encryptionsdk.kms.KMSTestFixtures; 7 | import org.junit.Test; 8 | 9 | public class DiscoveryDecryptionExampleTest { 10 | 11 | @Test 12 | public void testEncryptAndDecrypt() { 13 | DiscoveryDecryptionExample.encryptAndDecrypt( 14 | KMSTestFixtures.TEST_KEY_IDS[0], KMSTestFixtures.PARTITION, KMSTestFixtures.ACCOUNT_ID); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/crypto/examples/v2/DiscoveryMultiRegionDecryptionExampleTest.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.crypto.examples.v2; 5 | 6 | import com.amazonaws.encryptionsdk.kms.KMSTestFixtures; 7 | import org.junit.Test; 8 | import software.amazon.awssdk.regions.Region; 9 | 10 | public class DiscoveryMultiRegionDecryptionExampleTest { 11 | 12 | @Test 13 | public void testEncryptAndDecrypt() { 14 | DiscoveryMultiRegionDecryptionExample.encryptAndDecrypt( 15 | KMSTestFixtures.US_EAST_1_MULTI_REGION_KEY_ID, 16 | KMSTestFixtures.PARTITION, 17 | KMSTestFixtures.ACCOUNT_ID, 18 | Region.US_WEST_2); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/crypto/examples/v2/MultipleCmkEncryptExampleTest.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.crypto.examples.v2; 5 | 6 | import com.amazonaws.encryptionsdk.kms.KMSTestFixtures; 7 | import org.junit.Test; 8 | 9 | public class MultipleCmkEncryptExampleTest { 10 | 11 | @Test 12 | public void testEncryptAndDecrypt() { 13 | MultipleCmkEncryptExample.encryptAndDecrypt( 14 | KMSTestFixtures.TEST_KEY_IDS[0], KMSTestFixtures.TEST_KEY_IDS[1]); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/crypto/examples/v2/RestrictRegionExampleTest.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.crypto.examples.v2; 5 | 6 | import com.amazonaws.encryptionsdk.kms.KMSTestFixtures; 7 | import org.junit.Test; 8 | import software.amazon.awssdk.regions.Region; 9 | 10 | public class RestrictRegionExampleTest { 11 | 12 | @Test 13 | public void testEncryptAndDecrypt() { 14 | RestrictRegionExample.encryptAndDecrypt( 15 | KMSTestFixtures.US_WEST_2_KEY_ID, 16 | KMSTestFixtures.PARTITION, 17 | KMSTestFixtures.ACCOUNT_ID, 18 | Region.US_WEST_2); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/crypto/examples/v2/SetCommitmentPolicyExampleTest.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.crypto.examples.v2; 5 | 6 | import com.amazonaws.encryptionsdk.kms.KMSTestFixtures; 7 | import org.junit.Test; 8 | 9 | public class SetCommitmentPolicyExampleTest { 10 | 11 | @Test 12 | public void testEncryptAndDecrypt() { 13 | SetCommitmentPolicyExample.encryptAndDecrypt(KMSTestFixtures.TEST_KEY_IDS[0]); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/crypto/examples/v2/SetEncryptionAlgorithmExampleTest.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.crypto.examples.v2; 5 | 6 | import com.amazonaws.encryptionsdk.kms.KMSTestFixtures; 7 | import org.junit.Test; 8 | 9 | public class SetEncryptionAlgorithmExampleTest { 10 | 11 | @Test 12 | public void testEncryptAndDecrypt() { 13 | SetEncryptionAlgorithmExample.encryptAndDecrypt(KMSTestFixtures.TEST_KEY_IDS[0]); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/crypto/examples/v2/SimpleDataKeyCachingExampleTest.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.crypto.examples.v2; 5 | 6 | import static org.junit.Assert.assertArrayEquals; 7 | import static org.junit.Assert.assertEquals; 8 | import static org.junit.Assert.assertNotNull; 9 | 10 | import com.amazonaws.encryptionsdk.ParsedCiphertext; 11 | import com.amazonaws.encryptionsdk.kms.KMSTestFixtures; 12 | import org.junit.Test; 13 | 14 | public class SimpleDataKeyCachingExampleTest { 15 | private static final int MAX_ENTRY_AGE = 100; 16 | private static final int CACHE_CAPACITY = 1000; 17 | 18 | @Test 19 | public void testEncryptWithCaching() { 20 | final byte[] result = 21 | SimpleDataKeyCachingExample.encryptWithCaching( 22 | KMSTestFixtures.TEST_KEY_IDS[0], MAX_ENTRY_AGE, CACHE_CAPACITY); 23 | assertNotNull(result); 24 | final ParsedCiphertext parsedResult = new ParsedCiphertext(result); 25 | assertEquals(1, parsedResult.getEncryptedKeyBlobs().size()); 26 | assertArrayEquals( 27 | KMSTestFixtures.TEST_KEY_IDS[0].getBytes(), 28 | parsedResult.getEncryptedKeyBlobs().get(0).getProviderInformation()); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/encryptionsdk/FastTestsOnlySuite.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.encryptionsdk; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | import org.junit.ClassRule; 5 | import org.junit.experimental.categories.Categories; 6 | import org.junit.rules.TestRule; 7 | import org.junit.rules.Timeout; 8 | import org.junit.runner.Description; 9 | import org.junit.runner.RunWith; 10 | import org.junit.runner.Runner; 11 | import org.junit.runners.Suite; 12 | import org.junit.runners.model.InitializationError; 13 | import org.junit.runners.model.RunnerBuilder; 14 | import org.junit.runners.model.Statement; 15 | 16 | /** 17 | * This test suite is intended to assist in rapid development; it filters out some of the slower, 18 | * more exhaustive tests in the overall test suite to allow for a rapid edit-test cycle. 19 | */ 20 | @RunWith(FastTestsOnlySuite.CustomRunner.class) 21 | @Suite.SuiteClasses({AllTestsSuite.class}) 22 | @Categories.ExcludeCategory(SlowTestCategory.class) 23 | public class FastTestsOnlySuite { 24 | private static InheritableThreadLocal IS_FAST_TEST_SUITE_ACTIVE = 25 | new InheritableThreadLocal() { 26 | @Override 27 | protected Boolean initialValue() { 28 | return false; 29 | } 30 | }; 31 | 32 | // This method is used to adjust DataProviders to provide a smaller subset of their test cases 33 | // when the fast tests 34 | // are selected 35 | public static boolean isFastTestSuiteActive() { 36 | return IS_FAST_TEST_SUITE_ACTIVE.get(); 37 | } 38 | 39 | // Require that this fast suite completes relatively quickly. If you're seeing this timeout get 40 | // hit, it's time to 41 | // pare down tests some more. As a general rule of thumb, we should avoid any single test taking 42 | // more than 10s, and 43 | // try to keep the number of such slow tests to a minimum. 44 | @ClassRule public static Timeout timeout = new Timeout(2, TimeUnit.MINUTES); 45 | 46 | @ClassRule public static EnableFastSuite enableFastSuite = new EnableFastSuite(); 47 | 48 | // TestRules run over the execution of tests, but not over the generation of parameterized test 49 | // data... 50 | private static class EnableFastSuite implements TestRule { 51 | @Override 52 | public Statement apply(Statement base, Description description) { 53 | return new Statement() { 54 | @Override 55 | public void evaluate() throws Throwable { 56 | Boolean oldValue = IS_FAST_TEST_SUITE_ACTIVE.get(); 57 | 58 | try { 59 | IS_FAST_TEST_SUITE_ACTIVE.set(true); 60 | base.evaluate(); 61 | } finally { 62 | IS_FAST_TEST_SUITE_ACTIVE.set(oldValue); 63 | } 64 | } 65 | }; 66 | } 67 | } 68 | 69 | // ... so we also need a custom TestRunner that will pass the flag on to the parameterized test 70 | // data generators. 71 | public static class CustomRunner extends Categories { 72 | public CustomRunner(Class klass, RunnerBuilder builder) throws InitializationError { 73 | super( 74 | klass, 75 | new RunnerBuilder() { 76 | @Override 77 | public Runner runnerForClass(Class testClass) throws Throwable { 78 | Boolean oldValue = IS_FAST_TEST_SUITE_ACTIVE.get(); 79 | 80 | try { 81 | IS_FAST_TEST_SUITE_ACTIVE.set(true); 82 | Runner r = builder.runnerForClass(testClass); 83 | return r; 84 | } finally { 85 | IS_FAST_TEST_SUITE_ACTIVE.set(oldValue); 86 | } 87 | } 88 | }); 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/encryptionsdk/Fixtures.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.encryptionsdk; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | import java.util.stream.Collectors; 8 | import java.util.stream.Stream; 9 | 10 | public class Fixtures { 11 | public enum Variation { 12 | Empty, 13 | A, 14 | B, 15 | AB, 16 | BA, 17 | C, 18 | CE 19 | } 20 | 21 | public static Map generateEncryptionContext(Variation v) { 22 | Map encryptionContext = new HashMap<>(); 23 | 24 | switch (v) { 25 | case A: 26 | encryptionContext.put("keyA", "valA"); 27 | break; 28 | case B: 29 | encryptionContext.put("keyB", "valB"); 30 | break; 31 | case AB: 32 | case BA: 33 | encryptionContext.put("keyA", "valA"); 34 | encryptionContext.put("keyB", "valB"); 35 | break; 36 | case C: 37 | encryptionContext.put("keyC", "valC"); 38 | break; 39 | case CE: 40 | encryptionContext.put("keyC", "valC"); 41 | encryptionContext.put("keyD", "valD"); 42 | break; 43 | } 44 | 45 | return encryptionContext; 46 | } 47 | 48 | public static Map generateMismatchedEncryptionContext(Variation v) { 49 | Map encryptionContext = new HashMap<>(); 50 | 51 | switch (v) { 52 | case A: 53 | encryptionContext.put("keyA", "valB"); 54 | break; 55 | case B: 56 | encryptionContext.put("keyB", "valA"); 57 | break; 58 | case AB: 59 | case BA: 60 | encryptionContext.put("keyA", "valC"); 61 | encryptionContext.put("keyB", "valD"); 62 | break; 63 | case C: 64 | encryptionContext.put("keyC", "valA"); 65 | break; 66 | case CE: 67 | encryptionContext.put("keyC", "valA"); 68 | encryptionContext.put("keyD", "valB"); 69 | break; 70 | } 71 | 72 | return encryptionContext; 73 | } 74 | 75 | public static List generateEncryptionContextKeys(Variation v) { 76 | return Stream.of("keyA", "keyB", "keyC", "keyD") 77 | .filter( 78 | key -> { 79 | if (v == Variation.Empty) { 80 | return false; 81 | } 82 | if (v == Variation.A && !key.equals("keyA")) { 83 | return false; 84 | } 85 | if (v == Variation.B && !key.equals("keyB")) { 86 | return false; 87 | } 88 | if (v == Variation.AB && (!key.equals("keyA") && !key.equals("keyB"))) { 89 | return false; 90 | } 91 | if (v == Variation.BA && (!key.equals("keyB") && !key.equals("keyA"))) { 92 | return false; 93 | } 94 | if (v == Variation.C && !key.equals("keyC")) { 95 | return false; 96 | } 97 | if (v == Variation.CE && (!key.equals("keyC") && !key.equals("keyD"))) { 98 | return false; 99 | } 100 | return true; 101 | }) 102 | .collect(Collectors.toList()); 103 | } 104 | 105 | public static Map getReservedEncryptionContextMap() { 106 | Map encryptionContext = new HashMap<>(); 107 | encryptionContext.put("aws-crypto-public-key", "not a real public key"); 108 | return encryptionContext; 109 | } 110 | 111 | public static List getReservedEncryptionContextKey() { 112 | List ecKeys = new ArrayList(); 113 | ecKeys.add("aws-crypto-public-key"); 114 | return ecKeys; 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/encryptionsdk/IntegrationTestSuite.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.encryptionsdk; 2 | 3 | import com.amazonaws.encryptionsdk.kms.KMSProviderBuilderIntegrationTests; 4 | import com.amazonaws.encryptionsdk.kms.MaxEncryptedDataKeysIntegrationTest; 5 | import com.amazonaws.encryptionsdk.kms.XCompatKmsDecryptTest; 6 | import org.junit.runner.RunWith; 7 | import org.junit.runners.Suite; 8 | 9 | @RunWith(Suite.class) 10 | @Suite.SuiteClasses({ 11 | XCompatKmsDecryptTest.class, 12 | KMSProviderBuilderIntegrationTests.class, 13 | MaxEncryptedDataKeysIntegrationTest.class, 14 | com.amazonaws.encryptionsdk.kms.KMSProviderBuilderIntegrationTests.class, 15 | com.amazonaws.encryptionsdk.kms.MaxEncryptedDataKeysIntegrationTest.class, 16 | com.amazonaws.encryptionsdk.kms.XCompatKmsDecryptTest.class 17 | }) 18 | public class IntegrationTestSuite {} 19 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/encryptionsdk/RecordingMaterialsManager.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.encryptionsdk; 5 | 6 | import com.amazonaws.encryptionsdk.model.DecryptionMaterials; 7 | import com.amazonaws.encryptionsdk.model.DecryptionMaterialsRequest; 8 | import com.amazonaws.encryptionsdk.model.EncryptionMaterials; 9 | import com.amazonaws.encryptionsdk.model.EncryptionMaterialsRequest; 10 | import java.util.Collections; 11 | 12 | public class RecordingMaterialsManager implements CryptoMaterialsManager { 13 | private final CryptoMaterialsManager delegate; 14 | private final CommitmentPolicy commitmentPolicy = TestUtils.DEFAULT_TEST_COMMITMENT_POLICY; 15 | 16 | public boolean didDecrypt = false; 17 | 18 | public RecordingMaterialsManager(CryptoMaterialsManager delegate) { 19 | this.delegate = delegate; 20 | } 21 | 22 | public RecordingMaterialsManager(MasterKeyProvider delegate) { 23 | this.delegate = new DefaultCryptoMaterialsManager(delegate); 24 | } 25 | 26 | @Override 27 | public EncryptionMaterials getMaterialsForEncrypt(EncryptionMaterialsRequest request) { 28 | request = request.toBuilder().setContext(Collections.singletonMap("foo", "bar")).build(); 29 | 30 | EncryptionMaterials result = delegate.getMaterialsForEncrypt(request); 31 | 32 | return result; 33 | } 34 | 35 | @Override 36 | public DecryptionMaterials decryptMaterials(DecryptionMaterialsRequest request) { 37 | didDecrypt = true; 38 | return delegate.decryptMaterials(request); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/encryptionsdk/SlowTestCategory.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.encryptionsdk; 2 | 3 | /** 4 | * JUnit category marking tests to be excluded from the FastTestsOnlySuite. Usage: 5 | * @Category(SlowTestCategory.class) 6 | * @Test 7 | * public void mySlowTest() { 8 | * // encrypt a couple terabytes of test data 9 | * } 10 | * 11 | */ 12 | public interface SlowTestCategory {} 13 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/encryptionsdk/caching/CacheTestFixtures.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.encryptionsdk.caching; 2 | 3 | import com.amazonaws.encryptionsdk.CommitmentPolicy; 4 | import com.amazonaws.encryptionsdk.DataKey; 5 | import com.amazonaws.encryptionsdk.DefaultCryptoMaterialsManager; 6 | import com.amazonaws.encryptionsdk.MasterKey; 7 | import com.amazonaws.encryptionsdk.TestUtils; 8 | import com.amazonaws.encryptionsdk.jce.JceMasterKey; 9 | import com.amazonaws.encryptionsdk.model.DecryptionMaterials; 10 | import com.amazonaws.encryptionsdk.model.DecryptionMaterialsRequest; 11 | import com.amazonaws.encryptionsdk.model.EncryptionMaterials; 12 | import com.amazonaws.encryptionsdk.model.EncryptionMaterialsRequest; 13 | import java.util.Collections; 14 | import javax.crypto.SecretKey; 15 | import javax.crypto.spec.SecretKeySpec; 16 | 17 | public class CacheTestFixtures { 18 | private static final CommitmentPolicy commitmentPolicy = TestUtils.DEFAULT_TEST_COMMITMENT_POLICY; 19 | 20 | private static final MasterKey FIXED_KEY = 21 | JceMasterKey.getInstance( 22 | new SecretKeySpec(TestUtils.insecureRandomBytes(16), "AES"), 23 | "prov", 24 | "keyid", 25 | "AES/GCM/NoPadding"); 26 | 27 | public static EncryptionMaterialsRequest createMaterialsRequest(int index) { 28 | return EncryptionMaterialsRequest.newBuilder() 29 | .setContext(Collections.singletonMap("index", Integer.toString(index))) 30 | .setCommitmentPolicy(commitmentPolicy) 31 | .build(); 32 | } 33 | 34 | public static EncryptionMaterials createMaterialsResult(EncryptionMaterialsRequest request) { 35 | return new DefaultCryptoMaterialsManager(FIXED_KEY) 36 | .getMaterialsForEncrypt(request).toBuilder().setCleartextDataKey(new SentinelKey()).build(); 37 | } 38 | 39 | public static DecryptionMaterialsRequest createDecryptRequest(int index) { 40 | EncryptionMaterialsRequest mreq = createMaterialsRequest(index); 41 | EncryptionMaterials mres = createMaterialsResult(mreq); 42 | 43 | return createDecryptRequest(mres); 44 | } 45 | 46 | public static DecryptionMaterialsRequest createDecryptRequest(EncryptionMaterials mres) { 47 | return DecryptionMaterialsRequest.newBuilder() 48 | .setAlgorithm(mres.getAlgorithm()) 49 | .setEncryptionContext(mres.getEncryptionContext()) 50 | .setEncryptedDataKeys(mres.getEncryptedDataKeys()) 51 | .build(); 52 | } 53 | 54 | public static DecryptionMaterials createDecryptResult(DecryptionMaterialsRequest request) { 55 | DecryptionMaterials realResult = 56 | new DefaultCryptoMaterialsManager(FIXED_KEY).decryptMaterials(request); 57 | return realResult.toBuilder() 58 | .setDataKey( 59 | new DataKey( 60 | new SentinelKey(), 61 | realResult.getDataKey().getEncryptedDataKey(), 62 | realResult.getDataKey().getProviderInformation(), 63 | realResult.getDataKey().getMasterKey())) 64 | .build(); 65 | } 66 | 67 | static EncryptionMaterials createMaterialsResult() { 68 | return createMaterialsResult(createMaterialsRequest(0)); 69 | } 70 | 71 | // These SentinelKeys let us detect when a particular DecryptionMaterials or EncryptionMaterials 72 | // is being used, without 73 | // being concerned about matching all of the fields - we can just use object identity. 74 | public static class SentinelKey implements SecretKey { 75 | @Override 76 | public String getAlgorithm() { 77 | return "AES"; 78 | } 79 | 80 | @Override 81 | public String getFormat() { 82 | return "RAW"; 83 | } 84 | 85 | @Override 86 | public byte[] getEncoded() { 87 | return null; 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/encryptionsdk/caching/NullCryptoMaterialsCacheTest.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.encryptionsdk.caching; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertFalse; 5 | import static org.junit.Assert.assertNull; 6 | 7 | import com.amazonaws.encryptionsdk.model.DecryptionMaterials; 8 | import com.amazonaws.encryptionsdk.model.DecryptionMaterialsRequest; 9 | import com.amazonaws.encryptionsdk.model.EncryptionMaterials; 10 | import com.amazonaws.encryptionsdk.model.EncryptionMaterialsRequest; 11 | import org.junit.Test; 12 | 13 | public class NullCryptoMaterialsCacheTest { 14 | @Test 15 | public void testEncryptPath() { 16 | NullCryptoMaterialsCache cache = new NullCryptoMaterialsCache(); 17 | 18 | EncryptionMaterialsRequest req = CacheTestFixtures.createMaterialsRequest(1); 19 | EncryptionMaterials result = CacheTestFixtures.createMaterialsResult(req); 20 | 21 | CryptoMaterialsCache.UsageStats stats = new CryptoMaterialsCache.UsageStats(123, 456); 22 | CryptoMaterialsCache.EncryptCacheEntry entry = 23 | cache.putEntryForEncrypt(new byte[1], result, () -> Long.MAX_VALUE, stats); 24 | assertEquals(result, entry.getResult()); 25 | assertFalse(entry.getEntryCreationTime() > System.currentTimeMillis()); 26 | assertEquals(stats, entry.getUsageStats()); 27 | ; 28 | 29 | // the entry should not be in the "cache" 30 | byte[] cacheId = new byte[1]; 31 | assertNull(cache.getEntryForEncrypt(cacheId, CryptoMaterialsCache.UsageStats.ZERO)); 32 | 33 | entry.invalidate(); // shouldn't throw 34 | } 35 | 36 | @Test 37 | public void testDecryptPath() { 38 | NullCryptoMaterialsCache cache = new NullCryptoMaterialsCache(); 39 | 40 | DecryptionMaterialsRequest request = CacheTestFixtures.createDecryptRequest(1); 41 | DecryptionMaterials result = CacheTestFixtures.createDecryptResult(request); 42 | 43 | assertNull(cache.getEntryForDecrypt(new byte[1])); 44 | cache.putEntryForDecrypt(new byte[1], result, () -> Long.MAX_VALUE); 45 | assertNull(cache.getEntryForDecrypt(new byte[1])); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/encryptionsdk/internal/FrameEncryptionHandlerVeryLongTest.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.encryptionsdk.internal; 2 | 3 | import static org.junit.Assert.fail; 4 | 5 | import com.amazonaws.encryptionsdk.CryptoAlgorithm; 6 | import com.amazonaws.encryptionsdk.model.CipherFrameHeaders; 7 | import java.nio.ByteBuffer; 8 | import java.nio.ByteOrder; 9 | import java.util.Arrays; 10 | import javax.crypto.spec.SecretKeySpec; 11 | import org.bouncycastle.util.encoders.Hex; 12 | import org.junit.Test; 13 | 14 | /* 15 | * This test exhaustively encrypts a 2^32 frame message, which takes approximately 2-3 hours on my hardware. Because of 16 | * this long test time, this test is not run as part of the normal suites. 17 | */ 18 | public class FrameEncryptionHandlerVeryLongTest { 19 | @Test 20 | public void exhaustiveIVCheck() throws Exception { 21 | CryptoAlgorithm algorithm = CryptoAlgorithm.ALG_AES_128_GCM_IV12_TAG16_NO_KDF; 22 | FrameEncryptionHandler frameEncryptionHandler_ = 23 | new FrameEncryptionHandler( 24 | new SecretKeySpec(new byte[16], "AES"), 12, algorithm, new byte[16], 1); 25 | 26 | byte[] buf = new byte[1024]; 27 | 28 | ByteBuffer expectedNonce = ByteBuffer.allocate(12); 29 | long lastIndex = 1; // starting index for the test 30 | long lastTS = System.nanoTime(); 31 | for (long i = lastIndex; i <= Constants.MAX_FRAME_NUMBER; i++) { 32 | Utils.clear(expectedNonce); 33 | expectedNonce.order(ByteOrder.BIG_ENDIAN); 34 | expectedNonce.putInt(0); 35 | expectedNonce.putLong(i); 36 | 37 | if (i != Constants.MAX_FRAME_NUMBER) { 38 | frameEncryptionHandler_.processBytes(buf, 0, 1, buf, 0); 39 | } else { 40 | frameEncryptionHandler_.doFinal(buf, 0); 41 | } 42 | 43 | CipherFrameHeaders headers = new CipherFrameHeaders(); 44 | headers.setNonceLength(algorithm.getNonceLen()); 45 | headers.deserialize(buf, 0); 46 | 47 | byte[] nonce = headers.getNonce(); 48 | byte[] expectedArray = expectedNonce.array(); 49 | if (!Arrays.equals(nonce, expectedArray)) { 50 | fail( 51 | String.format( 52 | "Index %08x bytes %s != %s", 53 | i, new String(Hex.encode(nonce)), new String(Hex.encode(expectedArray)))); 54 | } 55 | 56 | if ((i & 0xFFFFF) == 0) { 57 | // Print progress messages, since this test takes a _very_ long time to run. 58 | System.out.print( 59 | String.format( 60 | "%05.2f%% complete", 100 * (double) i / (double) Constants.MAX_FRAME_NUMBER)); 61 | long newTS = System.nanoTime(); 62 | System.out.println( 63 | String.format( 64 | " at a rate of %f/sec\n", (i - lastIndex) / ((newTS - lastTS) / 1_000_000_000.0))); 65 | lastTS = newTS; 66 | lastIndex = i; 67 | } 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/encryptionsdk/internal/PrimitivesParserTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except 5 | * in compliance with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | package com.amazonaws.encryptionsdk.internal; 15 | 16 | import static org.junit.Assert.assertEquals; 17 | 18 | import java.io.ByteArrayOutputStream; 19 | import java.io.DataOutputStream; 20 | import java.io.IOException; 21 | import org.junit.Test; 22 | 23 | public class PrimitivesParserTest { 24 | 25 | @Test 26 | public void testParseLong() throws IOException { 27 | final long[] tests = 28 | new long[] { 29 | Long.MIN_VALUE, Long.MAX_VALUE, -1, 0, 1, Long.MIN_VALUE + 1, Long.MAX_VALUE - 1 30 | }; 31 | for (long x : tests) { 32 | try (final ByteArrayOutputStream baos = new ByteArrayOutputStream(); 33 | final DataOutputStream dos = new DataOutputStream(baos)) { 34 | dos.writeLong(x); 35 | dos.close(); 36 | assertEquals(x, PrimitivesParser.parseLong(baos.toByteArray(), 0)); 37 | } 38 | } 39 | } 40 | 41 | @Test 42 | public void testParseInt() throws IOException { 43 | final int[] tests = 44 | new int[] { 45 | Integer.MIN_VALUE, 46 | Integer.MAX_VALUE, 47 | -1, 48 | 0, 49 | 1, 50 | Integer.MIN_VALUE + 1, 51 | Integer.MAX_VALUE - 1 52 | }; 53 | for (int x : tests) { 54 | try (final ByteArrayOutputStream baos = new ByteArrayOutputStream(); 55 | final DataOutputStream dos = new DataOutputStream(baos)) { 56 | dos.writeInt(x); 57 | dos.close(); 58 | assertEquals(x, PrimitivesParser.parseInt(baos.toByteArray(), 0)); 59 | } 60 | } 61 | } 62 | 63 | @Test 64 | public void testParseShort() throws IOException { 65 | for (int x = Short.MIN_VALUE; x < Short.MAX_VALUE; x++) { 66 | try (final ByteArrayOutputStream baos = new ByteArrayOutputStream(); 67 | final DataOutputStream dos = new DataOutputStream(baos)) { 68 | dos.writeShort(x); 69 | dos.close(); 70 | assertEquals((short) x, PrimitivesParser.parseShort(baos.toByteArray(), 0)); 71 | } 72 | } 73 | } 74 | 75 | @Test 76 | public void testParseUnsignedShort() throws IOException { 77 | for (int x = 0; x < Constants.UNSIGNED_SHORT_MAX_VAL; x++) { 78 | try (final ByteArrayOutputStream baos = new ByteArrayOutputStream(); 79 | final DataOutputStream dos = new DataOutputStream(baos)) { 80 | PrimitivesParser.writeUnsignedShort(dos, x); 81 | assertEquals(x, PrimitivesParser.parseUnsignedShort(baos.toByteArray(), 0)); 82 | } 83 | } 84 | } 85 | 86 | @Test 87 | public void testParseByte() throws IOException { 88 | for (int x = Byte.MIN_VALUE; x < Byte.MAX_VALUE; x++) { 89 | try (final ByteArrayOutputStream baos = new ByteArrayOutputStream(); 90 | final DataOutputStream dos = new DataOutputStream(baos)) { 91 | dos.writeByte(x); 92 | dos.close(); 93 | assertEquals((byte) x, PrimitivesParser.parseByte(baos.toByteArray(), 0)); 94 | } 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/encryptionsdk/internal/RandomBytesGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except 5 | * in compliance with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | package com.amazonaws.encryptionsdk.internal; 15 | 16 | import java.security.SecureRandom; 17 | 18 | public class RandomBytesGenerator { 19 | private static final SecureRandom RND = new SecureRandom(); 20 | 21 | /* Some Providers (such as the FIPS certified Bouncy Castle) enforce a 22 | * maximum number of bytes that may be requested from SecureRandom. If 23 | * the requested len is larger than this value, the Secure Random will 24 | * be called multiple times to achieve the requested total length. */ 25 | private static final int MAX_BYTES = 1 << 15; 26 | 27 | /** 28 | * Generates a byte array of random data of the given length. 29 | * 30 | * @param len The length of the byte array. 31 | * @return The byte array. 32 | */ 33 | public static byte[] generate(final int len) { 34 | final byte[] result = new byte[len]; 35 | int bytesGenerated = 0; 36 | 37 | while (bytesGenerated < len) { 38 | final int requestSize = Math.min(MAX_BYTES, len - bytesGenerated); 39 | final byte[] request = new byte[requestSize]; 40 | RND.nextBytes(request); 41 | System.arraycopy(request, 0, result, bytesGenerated, requestSize); 42 | bytesGenerated += requestSize; 43 | } 44 | 45 | return result; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/encryptionsdk/internal/VersionInfoTest.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.encryptionsdk.internal; 5 | 6 | import static org.junit.Assert.assertTrue; 7 | 8 | import org.junit.Test; 9 | 10 | public class VersionInfoTest { 11 | 12 | @Test 13 | public void basic_use() { 14 | final String userAgent = VersionInfo.loadUserAgent(); 15 | assertTrue(userAgent.startsWith(VersionInfo.USER_AGENT_PREFIX)); 16 | assertTrue(!userAgent.equals(VersionInfo.USER_AGENT_PREFIX + VersionInfo.UNKNOWN_VERSION)); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/encryptionsdk/jce/JceMasterKeyTest.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.encryptionsdk.jce; 2 | 3 | import java.security.KeyPair; 4 | import java.security.KeyPairGenerator; 5 | import java.security.NoSuchAlgorithmException; 6 | import java.security.PrivateKey; 7 | import java.security.PublicKey; 8 | import javax.crypto.SecretKey; 9 | import javax.crypto.spec.SecretKeySpec; 10 | import org.junit.Test; 11 | 12 | public class JceMasterKeyTest { 13 | 14 | private static final SecretKey SECRET_KEY = new SecretKeySpec(new byte[1], "AES"); 15 | private static final PrivateKey PRIVATE_KEY; 16 | private static final PublicKey PUBLIC_KEY; 17 | 18 | static { 19 | try { 20 | KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); 21 | KeyPair keyPair = keyPairGenerator.generateKeyPair(); 22 | PUBLIC_KEY = keyPair.getPublic(); 23 | PRIVATE_KEY = keyPair.getPrivate(); 24 | } catch (NoSuchAlgorithmException e) { 25 | throw new RuntimeException(e); 26 | } 27 | } 28 | 29 | private JceMasterKey jceGetInstance(final String algorithmName) { 30 | return JceMasterKey.getInstance(SECRET_KEY, "mockProvider", "mockKey", algorithmName); 31 | } 32 | 33 | private JceMasterKey jceGetInstanceAsymmetric(final String algorithmName) { 34 | return JceMasterKey.getInstance( 35 | PUBLIC_KEY, PRIVATE_KEY, "mockProvider", "mockKey", algorithmName); 36 | } 37 | 38 | @Test(expected = IllegalArgumentException.class) 39 | public void testGetInstanceInvalidWrappingAlgorithm() { 40 | jceGetInstance("blatently/unsupported/algorithm"); 41 | } 42 | 43 | @Test(expected = UnsupportedOperationException.class) 44 | public void testGetInstanceAsymmetricInvalidWrappingAlgorithm() { 45 | jceGetInstanceAsymmetric("rsa/ec/unsupportedAlgorithm"); 46 | } 47 | 48 | /** 49 | * Calls JceMasterKey.getInstance with differently cased wrappingAlgorithm names. Passes if no 50 | * Exception is thrown. Relies on passing an invalid algorithm name to result in an Exception. 51 | */ 52 | @Test 53 | public void testGetInstanceAllLowercase() { 54 | jceGetInstance("aes/gcm/nopadding"); 55 | } 56 | 57 | @Test 58 | public void testGetInstanceMixedCasing() { 59 | jceGetInstance("AES/GCm/NOpadding"); 60 | } 61 | 62 | @Test 63 | public void testGetInstanceAsymmetricAllLowercase() { 64 | jceGetInstanceAsymmetric("rsa/ecb/oaepwithsha-256andmgf1padding"); 65 | } 66 | 67 | @Test 68 | public void testGetInstanceAsymmetricMixedCasing() { 69 | jceGetInstanceAsymmetric("RSA/ECB/OAepwithsha-256andmgf1padding"); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/encryptionsdk/kms/DiscoveryFilterTest.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.encryptionsdk.kms; 5 | 6 | import static com.amazonaws.encryptionsdk.TestUtils.assertThrows; 7 | import static org.junit.Assert.assertNotNull; 8 | 9 | import java.util.Arrays; 10 | import java.util.Collections; 11 | import java.util.List; 12 | import org.junit.Test; 13 | 14 | public class DiscoveryFilterTest { 15 | @Test 16 | public void testValidConstruct() throws Exception { 17 | DiscoveryFilter filter = new DiscoveryFilter("partition", Arrays.asList("accountId")); 18 | assertNotNull(filter); 19 | 20 | DiscoveryFilter filter2 = new DiscoveryFilter("partition", "accountId1", "accountId2"); 21 | assertNotNull(filter2); 22 | } 23 | 24 | @Test 25 | public void testConstructWithEmptyPartition() throws Exception { 26 | assertThrows( 27 | IllegalArgumentException.class, () -> new DiscoveryFilter("", Arrays.asList("accountId"))); 28 | assertThrows(IllegalArgumentException.class, () -> new DiscoveryFilter("", "accountId")); 29 | } 30 | 31 | @Test 32 | public void testConstructWithNullPartition() throws Exception { 33 | assertThrows( 34 | IllegalArgumentException.class, 35 | () -> new DiscoveryFilter(null, Arrays.asList("accountId"))); 36 | assertThrows(IllegalArgumentException.class, () -> new DiscoveryFilter(null, "accountId")); 37 | } 38 | 39 | @Test 40 | public void testConstructWithEmptyIds() throws Exception { 41 | assertThrows( 42 | IllegalArgumentException.class, () -> new DiscoveryFilter("aws", Collections.emptyList())); 43 | } 44 | 45 | @Test 46 | public void testConstructWithNullIds() throws Exception { 47 | assertThrows( 48 | IllegalArgumentException.class, () -> new DiscoveryFilter("aws", (List) null)); 49 | } 50 | 51 | @Test 52 | public void testConstructWithIdsContainingEmptyId() throws Exception { 53 | assertThrows( 54 | IllegalArgumentException.class, 55 | () -> new DiscoveryFilter("aws", Arrays.asList("accountId", ""))); 56 | assertThrows(IllegalArgumentException.class, () -> new DiscoveryFilter("aws", "accountId", "")); 57 | } 58 | 59 | @Test 60 | public void testConstructWithIdsContainingNullId() throws Exception { 61 | assertThrows( 62 | IllegalArgumentException.class, 63 | () -> new DiscoveryFilter("aws", Arrays.asList("accountId", null))); 64 | assertThrows( 65 | IllegalArgumentException.class, () -> new DiscoveryFilter("aws", "accountId", null)); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/encryptionsdk/kms/KMSTestFixtures.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.encryptionsdk.kms; 5 | 6 | public final class KMSTestFixtures { 7 | private KMSTestFixtures() { 8 | throw new UnsupportedOperationException( 9 | "This class exists to hold static constants and cannot be instantiated."); 10 | } 11 | 12 | /** 13 | * These special test keys have been configured to allow Encrypt, Decrypt, and GenerateDataKey 14 | * operations from any AWS principal and should be used when adding new KMS tests. 15 | * 16 | *

This should go without saying, but never use these keys for production purposes (as anyone 17 | * in the world can decrypt data encrypted using them). 18 | */ 19 | public static final String US_WEST_2_KEY_ID = 20 | "arn:aws:kms:us-west-2:658956600833:key/b3537ef1-d8dc-4780-9f5a-55776cbb2f7f"; 21 | 22 | public static final String EU_CENTRAL_1_KEY_ID = 23 | "arn:aws:kms:eu-central-1:658956600833:key/75414c93-5285-4b57-99c9-30c1cf0a22c2"; 24 | public static final String US_EAST_1_MULTI_REGION_KEY_ID = 25 | "arn:aws:kms:us-east-1:658956600833:key/mrk-80bd8ecdcd4342aebd84b7dc9da498a7"; 26 | public static final String US_WEST_2_MULTI_REGION_KEY_ID = 27 | "arn:aws:kms:us-west-2:658956600833:key/mrk-80bd8ecdcd4342aebd84b7dc9da498a7"; 28 | public static final String US_WEST_2_KMS_RSA_KEY_ID = 29 | "arn:aws:kms:us-west-2:370957321024:key/mrk-63d386cb70614ea59b32ad65c9315297"; 30 | 31 | public static final String ACCOUNT_ID = "658956600833"; 32 | public static final String PARTITION = "aws"; 33 | public static final String US_WEST_2 = "us-west-2"; 34 | 35 | public static final String[] TEST_KEY_IDS = new String[] {US_WEST_2_KEY_ID, EU_CENTRAL_1_KEY_ID}; 36 | public static final String TEST_KEYSTORE_NAME = "KeyStoreDdbTable"; 37 | public static final String TEST_LOGICAL_KEYSTORE_NAME = "KeyStoreDdbTable"; 38 | public static final String TEST_KEYSTORE_KMS_KEY_ID = 39 | "arn:aws:kms:us-west-2:370957321024:key/9d989aa2-2f9c-438c-a745-cc57d3ad0126"; 40 | 41 | public static final String HIERARCHY_KEYRING_PARTITION_ID = 42 | "91c1b6a2-6fc3-4539-ad5e-938d597ed730"; 43 | } 44 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/encryptionsdk/kms/MaxEncryptedDataKeysIntegrationTest.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.encryptionsdk.kms; 5 | 6 | import static org.junit.Assert.assertArrayEquals; 7 | import static org.mockito.Mockito.any; 8 | import static org.mockito.Mockito.never; 9 | import static org.mockito.Mockito.spy; 10 | import static org.mockito.Mockito.verify; 11 | 12 | import com.amazonaws.encryptionsdk.AwsCrypto; 13 | import com.amazonaws.encryptionsdk.TestUtils; 14 | import com.amazonaws.encryptionsdk.exception.AwsCryptoException; 15 | import com.amazonaws.services.kms.AWSKMS; 16 | import com.amazonaws.services.kms.AWSKMSClientBuilder; 17 | import java.util.ArrayList; 18 | import java.util.List; 19 | import org.junit.Before; 20 | import org.junit.Test; 21 | 22 | public class MaxEncryptedDataKeysIntegrationTest { 23 | private static final byte[] PLAINTEXT = {1, 2, 3, 4}; 24 | private static final int MAX_EDKS = 3; 25 | 26 | private AWSKMS testClient_; 27 | private KmsMasterKeyProvider.RegionalClientSupplier testClientSupplier_; 28 | private AwsCrypto testCryptoClient_; 29 | 30 | @Before 31 | public void setup() { 32 | testClient_ = spy(AWSKMSClientBuilder.standard().withRegion("us-west-2").build()); 33 | testClientSupplier_ = 34 | regionName -> { 35 | if (regionName.equals("us-west-2")) { 36 | return testClient_; 37 | } 38 | throw new AwsCryptoException( 39 | "test supplier only configured for us-west-2 and eu-central-1"); 40 | }; 41 | testCryptoClient_ = AwsCrypto.standard().toBuilder().withMaxEncryptedDataKeys(MAX_EDKS).build(); 42 | } 43 | 44 | private KmsMasterKeyProvider providerWithEdks(int numKeys) { 45 | List keyIds = new ArrayList<>(numKeys); 46 | for (int i = 0; i < numKeys; i++) { 47 | keyIds.add(KMSTestFixtures.US_WEST_2_KEY_ID); 48 | } 49 | return KmsMasterKeyProvider.builder() 50 | .withCustomClientFactory(testClientSupplier_) 51 | .buildStrict(keyIds); 52 | } 53 | 54 | @Test 55 | public void encryptDecryptWithLessThanMaxEdks() { 56 | KmsMasterKeyProvider provider = providerWithEdks(MAX_EDKS - 1); 57 | byte[] ciphertext = testCryptoClient_.encryptData(provider, PLAINTEXT).getResult(); 58 | byte[] decrypted = testCryptoClient_.decryptData(provider, ciphertext).getResult(); 59 | assertArrayEquals(decrypted, PLAINTEXT); 60 | } 61 | 62 | @Test 63 | public void encryptDecryptWithMaxEdks() { 64 | KmsMasterKeyProvider provider = providerWithEdks(MAX_EDKS); 65 | byte[] ciphertext = testCryptoClient_.encryptData(provider, PLAINTEXT).getResult(); 66 | byte[] decrypted = testCryptoClient_.decryptData(provider, ciphertext).getResult(); 67 | assertArrayEquals(decrypted, PLAINTEXT); 68 | } 69 | 70 | @Test 71 | public void noEncryptWithMoreThanMaxEdks() { 72 | KmsMasterKeyProvider provider = providerWithEdks(MAX_EDKS + 1); 73 | TestUtils.assertThrows( 74 | AwsCryptoException.class, 75 | "Encrypted data keys exceed maxEncryptedDataKeys", 76 | () -> testCryptoClient_.encryptData(provider, PLAINTEXT)); 77 | } 78 | 79 | @Test 80 | public void noDecryptWithMoreThanMaxEdks() { 81 | KmsMasterKeyProvider provider = providerWithEdks(MAX_EDKS + 1); 82 | byte[] ciphertext = AwsCrypto.standard().encryptData(provider, PLAINTEXT).getResult(); 83 | TestUtils.assertThrows( 84 | AwsCryptoException.class, 85 | "Ciphertext encrypted data keys exceed maxEncryptedDataKeys", 86 | () -> testCryptoClient_.decryptData(provider, ciphertext)); 87 | verify(testClient_, never()).decrypt(any()); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/encryptionsdk/kmssdkv2/MaxEncryptedDataKeysIntegrationTest.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.encryptionsdk.kmssdkv2; 5 | 6 | import static org.junit.Assert.assertArrayEquals; 7 | import static org.mockito.Mockito.*; 8 | 9 | import com.amazonaws.encryptionsdk.AwsCrypto; 10 | import com.amazonaws.encryptionsdk.TestUtils; 11 | import com.amazonaws.encryptionsdk.exception.AwsCryptoException; 12 | import com.amazonaws.encryptionsdk.kms.KMSTestFixtures; 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | import org.junit.Before; 16 | import org.junit.Test; 17 | import software.amazon.awssdk.regions.Region; 18 | import software.amazon.awssdk.services.kms.KmsClient; 19 | import software.amazon.awssdk.services.kms.model.DecryptRequest; 20 | 21 | public class MaxEncryptedDataKeysIntegrationTest { 22 | private static final byte[] PLAINTEXT = {1, 2, 3, 4}; 23 | private static final int MAX_EDKS = 3; 24 | 25 | private KmsClient testClient_; 26 | private RegionalClientSupplier testClientSupplier_; 27 | private AwsCrypto testCryptoClient_; 28 | 29 | @Before 30 | public void setup() { 31 | testClient_ = spy(new ProxyKmsClient(KmsClient.builder().region(Region.US_WEST_2).build())); 32 | testClientSupplier_ = 33 | region -> { 34 | if (region == Region.US_WEST_2) { 35 | return testClient_; 36 | } 37 | throw new AwsCryptoException( 38 | "test supplier only configured for us-west-2 and eu-central-1"); 39 | }; 40 | testCryptoClient_ = AwsCrypto.standard().toBuilder().withMaxEncryptedDataKeys(MAX_EDKS).build(); 41 | } 42 | 43 | private KmsMasterKeyProvider providerWithEdks(int numKeys) { 44 | List keyIds = new ArrayList<>(numKeys); 45 | for (int i = 0; i < numKeys; i++) { 46 | keyIds.add(KMSTestFixtures.US_WEST_2_KEY_ID); 47 | } 48 | return KmsMasterKeyProvider.builder() 49 | .customRegionalClientSupplier(testClientSupplier_) 50 | .buildStrict(keyIds); 51 | } 52 | 53 | @Test 54 | public void encryptDecryptWithLessThanMaxEdks() { 55 | KmsMasterKeyProvider provider = providerWithEdks(MAX_EDKS - 1); 56 | byte[] ciphertext = testCryptoClient_.encryptData(provider, PLAINTEXT).getResult(); 57 | byte[] decrypted = testCryptoClient_.decryptData(provider, ciphertext).getResult(); 58 | assertArrayEquals(decrypted, PLAINTEXT); 59 | } 60 | 61 | @Test 62 | public void encryptDecryptWithMaxEdks() { 63 | KmsMasterKeyProvider provider = providerWithEdks(MAX_EDKS); 64 | byte[] ciphertext = testCryptoClient_.encryptData(provider, PLAINTEXT).getResult(); 65 | byte[] decrypted = testCryptoClient_.decryptData(provider, ciphertext).getResult(); 66 | assertArrayEquals(decrypted, PLAINTEXT); 67 | } 68 | 69 | @Test 70 | public void noEncryptWithMoreThanMaxEdks() { 71 | KmsMasterKeyProvider provider = providerWithEdks(MAX_EDKS + 1); 72 | TestUtils.assertThrows( 73 | AwsCryptoException.class, 74 | "Encrypted data keys exceed maxEncryptedDataKeys", 75 | () -> testCryptoClient_.encryptData(provider, PLAINTEXT)); 76 | } 77 | 78 | @Test 79 | public void noDecryptWithMoreThanMaxEdks() { 80 | KmsMasterKeyProvider provider = providerWithEdks(MAX_EDKS + 1); 81 | byte[] ciphertext = AwsCrypto.standard().encryptData(provider, PLAINTEXT).getResult(); 82 | TestUtils.assertThrows( 83 | AwsCryptoException.class, 84 | "Ciphertext encrypted data keys exceed maxEncryptedDataKeys", 85 | () -> testCryptoClient_.decryptData(provider, ciphertext)); 86 | verify(testClient_, never()).decrypt((DecryptRequest) any()); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/encryptionsdk/kmssdkv2/ProxyCredentialsProvider.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.encryptionsdk.kmssdkv2; 2 | 3 | import software.amazon.awssdk.auth.credentials.AwsCredentials; 4 | import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; 5 | 6 | class ProxyCredentialsProvider implements AwsCredentialsProvider { 7 | private final AwsCredentialsProvider proxiedProvider_; 8 | 9 | ProxyCredentialsProvider(AwsCredentialsProvider credentialsProvider) { 10 | proxiedProvider_ = credentialsProvider; 11 | } 12 | 13 | @Override 14 | public AwsCredentials resolveCredentials() { 15 | return proxiedProvider_.resolveCredentials(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/encryptionsdk/kmssdkv2/ProxyKmsClient.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.encryptionsdk.kmssdkv2; 2 | 3 | import software.amazon.awssdk.awscore.exception.AwsServiceException; 4 | import software.amazon.awssdk.core.exception.SdkClientException; 5 | import software.amazon.awssdk.services.kms.KmsClient; 6 | import software.amazon.awssdk.services.kms.model.DecryptRequest; 7 | import software.amazon.awssdk.services.kms.model.DecryptResponse; 8 | import software.amazon.awssdk.services.kms.model.DependencyTimeoutException; 9 | import software.amazon.awssdk.services.kms.model.DisabledException; 10 | import software.amazon.awssdk.services.kms.model.EncryptRequest; 11 | import software.amazon.awssdk.services.kms.model.EncryptResponse; 12 | import software.amazon.awssdk.services.kms.model.GenerateDataKeyRequest; 13 | import software.amazon.awssdk.services.kms.model.GenerateDataKeyResponse; 14 | import software.amazon.awssdk.services.kms.model.IncorrectKeyException; 15 | import software.amazon.awssdk.services.kms.model.InvalidCiphertextException; 16 | import software.amazon.awssdk.services.kms.model.InvalidGrantTokenException; 17 | import software.amazon.awssdk.services.kms.model.InvalidKeyUsageException; 18 | import software.amazon.awssdk.services.kms.model.KeyUnavailableException; 19 | import software.amazon.awssdk.services.kms.model.KmsException; 20 | import software.amazon.awssdk.services.kms.model.KmsInternalException; 21 | import software.amazon.awssdk.services.kms.model.KmsInvalidStateException; 22 | import software.amazon.awssdk.services.kms.model.NotFoundException; 23 | 24 | /** This wraps KmsClient since the default implementation is final. */ 25 | class ProxyKmsClient implements KmsClient { 26 | private final KmsClient proxiedClient_; 27 | 28 | ProxyKmsClient(KmsClient kmsClient) { 29 | proxiedClient_ = kmsClient; 30 | } 31 | 32 | @Override 33 | public String serviceName() { 34 | return proxiedClient_.serviceName(); 35 | } 36 | 37 | @Override 38 | public void close() { 39 | proxiedClient_.close(); 40 | } 41 | 42 | @Override 43 | public DecryptResponse decrypt(DecryptRequest decryptRequest) 44 | throws NotFoundException, DisabledException, InvalidCiphertextException, 45 | KeyUnavailableException, IncorrectKeyException, InvalidKeyUsageException, 46 | DependencyTimeoutException, InvalidGrantTokenException, KmsInternalException, 47 | KmsInvalidStateException, AwsServiceException, SdkClientException, KmsException { 48 | return proxiedClient_.decrypt(decryptRequest); 49 | } 50 | 51 | @Override 52 | public EncryptResponse encrypt(EncryptRequest encryptRequest) 53 | throws NotFoundException, DisabledException, KeyUnavailableException, 54 | DependencyTimeoutException, InvalidKeyUsageException, InvalidGrantTokenException, 55 | KmsInternalException, KmsInvalidStateException, AwsServiceException, SdkClientException, 56 | KmsException { 57 | return proxiedClient_.encrypt(encryptRequest); 58 | } 59 | 60 | @Override 61 | public GenerateDataKeyResponse generateDataKey(GenerateDataKeyRequest generateDataKeyRequest) 62 | throws NotFoundException, DisabledException, KeyUnavailableException, 63 | DependencyTimeoutException, InvalidKeyUsageException, InvalidGrantTokenException, 64 | KmsInternalException, KmsInvalidStateException, AwsServiceException, SdkClientException, 65 | KmsException { 66 | return proxiedClient_.generateDataKey(generateDataKeyRequest); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/encryptionsdk/kmssdkv2/XCompatKmsDecryptTest.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.encryptionsdk.kmssdkv2; 5 | 6 | import static org.junit.Assert.assertArrayEquals; 7 | 8 | import com.amazonaws.encryptionsdk.AwsCrypto; 9 | import com.amazonaws.encryptionsdk.CryptoResult; 10 | import com.fasterxml.jackson.core.type.TypeReference; 11 | import com.fasterxml.jackson.databind.ObjectMapper; 12 | import java.io.File; 13 | import java.nio.file.Files; 14 | import java.nio.file.Paths; 15 | import java.util.*; 16 | import org.apache.commons.lang3.StringUtils; 17 | import org.junit.Test; 18 | import org.junit.runner.RunWith; 19 | import org.junit.runners.Parameterized; 20 | import org.junit.runners.Parameterized.Parameters; 21 | 22 | @RunWith(Parameterized.class) 23 | public class XCompatKmsDecryptTest { 24 | private final String plaintextFileName; 25 | private final String ciphertextFileName; 26 | private final String kmsKeyId; 27 | 28 | public XCompatKmsDecryptTest( 29 | String plaintextFileName, String ciphertextFileName, String kmsKeyId) { 30 | this.plaintextFileName = plaintextFileName; 31 | this.ciphertextFileName = ciphertextFileName; 32 | this.kmsKeyId = kmsKeyId; 33 | } 34 | 35 | @Parameters(name = "{index}: testDecryptFromFile({0}, {1}, {2})") 36 | public static Collection data() throws Exception { 37 | String baseDirName; 38 | baseDirName = System.getProperty("staticCompatibilityResourcesDir"); 39 | if (baseDirName == null) { 40 | baseDirName = 41 | XCompatKmsDecryptTest.class.getProtectionDomain().getCodeSource().getLocation().getPath() 42 | + "aws_encryption_sdk_resources"; 43 | } 44 | 45 | List testCases_ = new ArrayList<>(); 46 | 47 | String ciphertextManifestName = 48 | StringUtils.join( 49 | new String[] {baseDirName, "manifests", "ciphertext.manifest"}, File.separator); 50 | File ciphertextManifestFile = new File(ciphertextManifestName); 51 | 52 | if (!ciphertextManifestFile.exists()) { 53 | return Collections.emptyList(); 54 | } 55 | 56 | ObjectMapper ciphertextManifestMapper = new ObjectMapper(); 57 | Map ciphertextManifest = 58 | ciphertextManifestMapper.readValue( 59 | ciphertextManifestFile, new TypeReference>() {}); 60 | 61 | List> testCases = 62 | (List>) ciphertextManifest.get("test_cases"); 63 | for (Map testCase : testCases) { 64 | Map plaintext = (Map) testCase.get("plaintext"); 65 | Map ciphertext = (Map) testCase.get("ciphertext"); 66 | 67 | List> masterKeys = 68 | (List>) testCase.get("master_keys"); 69 | for (Map masterKey : masterKeys) { 70 | String providerId = (String) masterKey.get("provider_id"); 71 | if (providerId.equals("aws-kms") && (boolean) masterKey.get("decryptable")) { 72 | testCases_.add( 73 | new Object[] { 74 | baseDirName + File.separator + plaintext.get("filename"), 75 | baseDirName + File.separator + ciphertext.get("filename"), 76 | (String) masterKey.get("key_id") 77 | }); 78 | break; 79 | } 80 | } 81 | } 82 | return testCases_; 83 | } 84 | 85 | @Test 86 | public void testDecryptFromFile() throws Exception { 87 | AwsCrypto crypto = AwsCrypto.standard(); 88 | final KmsMasterKeyProvider masterKeyProvider = 89 | KmsMasterKeyProvider.builder().buildStrict(kmsKeyId); 90 | byte[] ciphertextBytes = Files.readAllBytes(Paths.get(ciphertextFileName)); 91 | byte[] plaintextBytes = Files.readAllBytes(Paths.get(plaintextFileName)); 92 | final CryptoResult decryptResult = 93 | crypto.decryptData(masterKeyProvider, ciphertextBytes); 94 | assertArrayEquals(plaintextBytes, decryptResult.getResult()); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/encryptionsdk/model/ByteFormatCheckValues.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except 5 | * in compliance with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | package com.amazonaws.encryptionsdk.model; 15 | 16 | import com.amazonaws.encryptionsdk.internal.Utils; 17 | 18 | public class ByteFormatCheckValues { 19 | private static final String base64MessageId_ = "NQ/NXvg4mMN5zm5JFZHUWw=="; 20 | private static final String base64PlaintextKey_ = "N9vW5Ox5xh4BrUgeaL2gXg=="; 21 | private static final String base64EncryptedKey_ = "Zg5VUzPfgD0/H92Fx7h0ew=="; 22 | 23 | private static final String base64Nonce_ = "3rktZhNbwrZBSaqt"; 24 | private static final String base64Tag_ = "cBPLjSEz0fsWDToxTqMvfQ=="; 25 | 26 | private static final String base64CiphertextHeaderHash_ = 27 | "bCScP4wa25l9TLQZ4KLv7xqVCg9AN58lB1FHrl2yVes="; 28 | private static final String base64BlockHeaderHash_ = 29 | "7q8fULz95XaJqrksEuzDoVpSYih54QbPC1+v833s/5Y="; 30 | private static final String base64FrameHeaderHash_ = 31 | "tB/UmW+/hLJU5i2D9Or8guXrn8lP0uCiUaP1KkdyKGs="; 32 | private static final String base64FinalFrameHeaderHash_ = 33 | "/b2fVFOxvnaM5vXDMGyyFPNTWMjuU/c/48qeH3uTHj0="; 34 | 35 | public static byte[] getMessageId() { 36 | return Utils.decodeBase64String(base64MessageId_); 37 | } 38 | 39 | public static byte[] getEncryptedKey() { 40 | return Utils.decodeBase64String(base64EncryptedKey_); 41 | } 42 | 43 | public static byte[] getPlaintextKey() { 44 | return Utils.decodeBase64String(base64PlaintextKey_); 45 | } 46 | 47 | public static byte[] getCiphertextHeaderHash() { 48 | return Utils.decodeBase64String(base64CiphertextHeaderHash_); 49 | } 50 | 51 | public static byte[] getCipherBlockHeaderHash() { 52 | return Utils.decodeBase64String(base64BlockHeaderHash_); 53 | } 54 | 55 | public static byte[] getCipherFrameHeaderHash() { 56 | return Utils.decodeBase64String(base64FrameHeaderHash_); 57 | } 58 | 59 | public static byte[] getCipherFinalFrameHeaderHash() { 60 | return Utils.decodeBase64String(base64FinalFrameHeaderHash_); 61 | } 62 | 63 | public static byte[] getNonce() { 64 | return Utils.decodeBase64String(base64Nonce_); 65 | } 66 | 67 | public static byte[] getTag() { 68 | return Utils.decodeBase64String(base64Tag_); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/encryptionsdk/model/DecryptionMaterialsRequestTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except 5 | * in compliance with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 | * specific language governing permissions and limitations under the License. 12 | */ 13 | 14 | package com.amazonaws.encryptionsdk.model; 15 | 16 | import static org.junit.Assert.assertEquals; 17 | 18 | import com.amazonaws.encryptionsdk.CryptoAlgorithm; 19 | import java.util.ArrayList; 20 | import java.util.HashMap; 21 | import java.util.List; 22 | import java.util.Map; 23 | import org.junit.Test; 24 | 25 | public class DecryptionMaterialsRequestTest { 26 | @Test 27 | public void build() { 28 | CryptoAlgorithm alg = CryptoAlgorithm.ALG_AES_256_GCM_IV12_TAG16_HKDF_SHA256; 29 | Map encryptionContext = new HashMap(1); 30 | encryptionContext.put("DMR", "DecryptionMaterialsRequest Test"); 31 | List kbs = new ArrayList(); 32 | 33 | DecryptionMaterialsRequest request0 = 34 | DecryptionMaterialsRequest.newBuilder() 35 | .setAlgorithm(alg) 36 | .setEncryptionContext(encryptionContext) 37 | .setEncryptedDataKeys(kbs) 38 | .build(); 39 | 40 | DecryptionMaterialsRequest request1 = request0.toBuilder().build(); 41 | 42 | assertEquals(request0.getAlgorithm(), request1.getAlgorithm()); 43 | assertEquals(request0.getEncryptionContext().size(), request1.getEncryptionContext().size()); 44 | assertEquals(request0.getEncryptedDataKeys().size(), request1.getEncryptedDataKeys().size()); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/encryptionsdk/model/DecryptionMaterialsTest.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.encryptionsdk.model; 5 | 6 | import static org.junit.Assert.assertEquals; 7 | import static org.mockito.Mockito.mock; 8 | 9 | import java.util.Collections; 10 | import java.util.Map; 11 | import org.junit.Test; 12 | 13 | public class DecryptionMaterialsTest { 14 | 15 | @Test 16 | public void GIVEN_builder_with_unset_EC_WHEN_constructor_THEN_object_EC_is_empty_map() { 17 | // Given: DecryptionMaterials.Builder with unset encryption context 18 | DecryptionMaterials.Builder builder = DecryptionMaterials.newBuilder(); 19 | 20 | // When: constructor 21 | DecryptionMaterials decryptionMaterials = builder.build(); 22 | 23 | // Then: constructor assigns an empty map to DecryptionMaterials objects 24 | assertEquals(Collections.emptyMap(), decryptionMaterials.getEncryptionContext()); 25 | } 26 | 27 | @Test 28 | public void GIVEN_builder_with_EC_WHEN_constructor_THEN_object_EC_is_builder_EC() { 29 | // Given: DecryptionMaterials.Builder with any encryption context map set 30 | Map anyEncryptionContext = mock(Map.class); 31 | DecryptionMaterials.Builder builder = DecryptionMaterials.newBuilder(); 32 | builder.setEncryptionContext(anyEncryptionContext); 33 | 34 | // When: constructor 35 | DecryptionMaterials decryptionMaterials = builder.build(); 36 | 37 | // Then: constructor assigns that encryption context map to DecryptionMaterials objects 38 | assertEquals(anyEncryptionContext, decryptionMaterials.getEncryptionContext()); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/test/java/com/amazonaws/encryptionsdk/model/EncryptionMaterialsRequestTest.java: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package com.amazonaws.encryptionsdk.model; 5 | 6 | import static org.junit.Assert.assertEquals; 7 | import static org.junit.Assert.assertNotNull; 8 | 9 | import com.amazonaws.encryptionsdk.CommitmentPolicy; 10 | import org.junit.Test; 11 | 12 | public class EncryptionMaterialsRequestTest { 13 | 14 | @Test(expected = IllegalArgumentException.class) 15 | public void testConstructWithNullCommitmentPolicy() { 16 | EncryptionMaterialsRequest.newBuilder().setCommitmentPolicy(null).build(); 17 | } 18 | 19 | @Test(expected = IllegalArgumentException.class) 20 | public void testConstructWithoutCommitmentPolicy() { 21 | EncryptionMaterialsRequest.newBuilder().build(); 22 | } 23 | 24 | @Test 25 | public void testConstructWithCommitmentPolicy() { 26 | EncryptionMaterialsRequest req = 27 | EncryptionMaterialsRequest.newBuilder() 28 | .setCommitmentPolicy(CommitmentPolicy.ForbidEncryptAllowDecrypt) 29 | .build(); 30 | assertNotNull(req); 31 | assertEquals(CommitmentPolicy.ForbidEncryptAllowDecrypt, req.getCommitmentPolicy()); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /util/duvet-report.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | ./aws-encryption-sdk-specification/util/report.js \ 7 | 'src/main/**/*.java' \ 8 | 'src/test/**/*.java' \ 9 | 'compliance_exceptions/*.java' 10 | -------------------------------------------------------------------------------- /util/test-conditions.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | ./aws-encryption-sdk-specification/util/test_conditions \ 7 | -s '-r src/main/ --include *.java' \ 8 | -t '-r src/test/ --include *.java' \ 9 | -s 'compliance_exceptions/*.java' 10 | --------------------------------------------------------------------------------