From 8626d226946e0c9561d28713b1e86d118c468122 Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Tue, 16 Sep 2025 11:31:31 -0700 Subject: [PATCH 01/22] Squashed 'hard-submodules/amazon-s3-encryption-client-go/' content from commit abc858c git-subtree-dir: hard-submodules/amazon-s3-encryption-client-go git-subtree-split: abc858cbea07fc1e754c701450c5016d6a08e04d --- CODE_OF_CONDUCT.md | 4 ++ CONTRIBUTING.md | 59 +++++++++++++++ LICENSE | 175 +++++++++++++++++++++++++++++++++++++++++++++ NOTICE | 1 + README.md | 17 +++++ 5 files changed, 256 insertions(+) create mode 100644 CODE_OF_CONDUCT.md create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE create mode 100644 NOTICE create mode 100644 README.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..5b627cfa --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,4 @@ +## Code of Conduct +This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). +For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact +opensource-codeofconduct@amazon.com with any additional questions or comments. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..c4b6a1c5 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,59 @@ +# Contributing Guidelines + +Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional +documentation, we greatly value feedback and contributions from our community. + +Please read through this document before submitting any issues or pull requests to ensure we have all the necessary +information to effectively respond to your bug report or contribution. + + +## Reporting Bugs/Feature Requests + +We welcome you to use the GitHub issue tracker to report bugs or suggest features. + +When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already +reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: + +* A reproducible test case or series of steps +* The version of our code being used +* Any modifications you've made relevant to the bug +* Anything unusual about your environment or deployment + + +## Contributing via Pull Requests +Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: + +1. You are working against the latest source on the *main* branch. +2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. +3. You open an issue to discuss any significant work - we would hate for your time to be wasted. + +To send us a pull request, please: + +1. Fork the repository. +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. +3. Ensure local tests pass. +4. Commit to your fork using clear commit messages. +5. Send us a pull request, answering any default questions in the pull request interface. +6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. + +GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and +[creating a pull request](https://help.github.com/articles/creating-a-pull-request/). + + +## Finding contributions to work on +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' issues is a great place to start. + + +## Code of Conduct +This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). +For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact +opensource-codeofconduct@amazon.com with any additional questions or comments. + + +## Security issue notifications +If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. + + +## Licensing + +See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..67db8588 --- /dev/null +++ b/LICENSE @@ -0,0 +1,175 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. diff --git a/NOTICE b/NOTICE new file mode 100644 index 00000000..616fc588 --- /dev/null +++ b/NOTICE @@ -0,0 +1 @@ +Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. diff --git a/README.md b/README.md new file mode 100644 index 00000000..847260ca --- /dev/null +++ b/README.md @@ -0,0 +1,17 @@ +## My Project + +TODO: Fill this README out! + +Be sure to: + +* Change the title in this README +* Edit your repository description on GitHub + +## Security + +See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information. + +## License + +This project is licensed under the Apache-2.0 License. + From 6efb5fda5a2f26550692c6dfc35b7f2f0f9de43c Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Wed, 17 Sep 2025 09:29:55 -0700 Subject: [PATCH 02/22] m --- .../amazon-s3-encryption-client-go/README.md | 210 +++++++++++++++++- test-server/Makefile | 24 +- .../amazon/encryption/s3/RoundTripTests.java | 2 + 3 files changed, 224 insertions(+), 12 deletions(-) diff --git a/hard-submodules/amazon-s3-encryption-client-go/README.md b/hard-submodules/amazon-s3-encryption-client-go/README.md index 847260ca..5bc75d78 100644 --- a/hard-submodules/amazon-s3-encryption-client-go/README.md +++ b/hard-submodules/amazon-s3-encryption-client-go/README.md @@ -1,11 +1,210 @@ -## My Project +# Amazon S3 Encryption Client for Go V4 -TODO: Fill this README out! +[![Go Build status](https://github.com/aws/amazon-s3-encryption-client-go/actions/workflows/go-test.yml/badge.svg?branch=main)](https://github.com/aws/amazon-s3-encryption-client-go/actions/workflows/go-test.yml) [![Apache V2 License](https://img.shields.io/badge/license-Apache%20V2-blue.svg)](https://github.com/aws/amazon-s3-encryption-client-go/blob/main/LICENSE) -Be sure to: +This library provides an S3 client that supports client-side encryption. +`amazon-s3-encryption-client-go` is the v4 of the Amazon S3 Encryption Client for the Go programming language. -* Change the title in this README -* Edit your repository description on GitHub +The v4 encryption client requires a minimum version of `Go 1.20`. + +Check out the [release notes](https://github.com/aws/amazon-s3-encryption-client-go/blob/main/CHANGELOG.md) for information about the latest bug +fixes, updates, and features added to the encryption client. + +Jump To: +* [Getting Started](#getting-started) +* [Migration](#migration) + +## Maintenance and support for SDK major versions + +For information about maintenance and support for SDK major versions and their underlying dependencies, see the +following in the AWS SDKs and Tools Shared Configuration and Credentials Reference Guide: + +* [AWS SDKs and Tools Maintenance Policy](https://docs.aws.amazon.com/credref/latest/refdocs/maint-policy.html) +* [AWS SDKs and Tools Version Support Matrix](https://docs.aws.amazon.com/credref/latest/refdocs/version-support-matrix.html) + +### Go version support policy + +The v4 Encryption Client follows the upstream [release policy](https://go.dev/doc/devel/release#policy) +with an additional six months of support for the most recently deprecated +language version. + +**AWS reserves the right to drop support for unsupported Go versions earlier to +address critical security issues.** + +## Getting started +To get started working with the S3 Encryption Client set up your project for Go modules, and retrieve the client's dependencies with `go get`. +This example shows how you can use the v4 encryption client to make a `PutItem` request using a KmsKeyring. + +###### Initialize Project +```sh +$ mkdir ~/encryptionclient +$ cd ~/encryptionclient +$ go mod init encryptionclient +``` +###### Add SDK Dependencies +```sh +$ go get github.com/aws/amazon-s3-encryption-client-go/v4 +``` + +###### Write Code +In your preferred editor add the following content to `main.go` + +```go +package main + +import ( + "context" + "log" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/service/kms" + "github.com/aws/aws-sdk-go-v2/service/s3" + + // Import the materials and client package + "github.com/aws/amazon-s3-encryption-client-go/v4/client" + "github.com/aws/amazon-s3-encryption-client-go/v4/materials" +) + +func main() { + ctx := context.Background() + // Using the SDK's default configuration, loading additional config + // and credentials values from the environment variables, shared + // credentials, and shared configuration files + cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion("us-west-2")) + if err != nil { + log.Fatalf("unable to load SDK config, %v", err) + } + key := "testObjectWithNewEncryptionClient" + plaintext := "This is a test.\n" + + s3Client := s3.NewFromConfig(cfg) + kmsClient := kms.NewFromConfig(cfg) + + // Create the keyring and &CMM-long; (&CMM-short;) + cmm, err := materials.NewCryptographicMaterialsManager(materials.NewKmsKeyring(kmsClient, kmsKeyArn, func(options *materials.KeyringOptions) { + options.EnableLegacyWrappingAlgorithms = false + })) + if err != nil { + log.Fatalf("error while creating new CMM") + } + + s3EncryptionClient, err := client.New(s3Client, cmm) + + _, err = s3EncryptionClient.PutObject(ctx, &s3Client.PutObjectInput{ + Bucket: aws.String(bucket), + Key: aws.String(key), + Body: bytes.NewReader([]byte(plaintext)), + }) + if err != nil { + log.Fatalf("error calling putObject: %v", err) + } +} +``` + +## Migration + +This version of the library supports reading encrypted objects from previous versions. +It also supports writing objects with non-legacy algorithms. +The list of legacy modes and operations will be provided below. + +### Examples +#### V2 KMS to V3 + +The following example demonstrates how to migrate a version v2 application that uses +the `NewKMSContextKeyGenerator` kms-key provider with a material +description and `AESGCMContentCipherBuilderV2` content cipher to +version v3 of the S3 Encryption Client for Go. + +```go +func KmsContextV2toV3GCMExample() error { + bucket := LoadBucket() + kmsKeyAlias := LoadAwsKmsAlias() + + objectKey := "my-object-key" + region := "us-west-2" + plaintext := "This is an example.\n" + + // Create an S3EC Go v2 encryption client + // using the KMS client from AWS SDK for Go v1 + sessKms, err := sessionV1.NewSession(&awsV1.Config{ + Region: aws.String(region), + }) + + kmsSvc := kmsV1.New(sessKms) + handler := s3cryptoV2.NewKMSContextKeyGenerator(kmsSvc, kmsKeyAlias, s3cryptoV2.MaterialDescription{}) + builder := s3cryptoV2.AESGCMContentCipherBuilderV2(handler) + encClient, err := s3cryptoV2.NewEncryptionClientV2(sessKms, builder) + if err != nil { + log.Fatalf("error creating new v2 client: %v", err) + } + + // Encrypt using KMS+Context and AES-GCM content cipher + _, err = encClient.PutObject(s3V1.PutObjectInput{ + Bucket: aws.String(bucket), + Key: aws.String(objectKey), + Body: bytes.NewReader([]byte(plaintext)), + }) + if err != nil { + log.Fatalf("error calling putObject: %v", err) + } + fmt.Printf("successfully uploaded file to %s/%s\n", bucket, key) + + // Create an S3EC Go v3 client + // using the KMS client from AWS SDK for Go v2 + ctx := context.Background() + cfg, err := config.LoadDefaultConfig(ctx, + config.WithRegion(region), + ) + + kmsV2 := kms.NewFromConfig(cfg) + cmm, err := materials.NewCryptographicMaterialsManager(materials.NewKmsKeyring(kmsV2, kmsKeyAlias)) + if err != nil { + t.Fatalf("error while creating new CMM") + } + + s3V2 := s3.NewFromConfig(cfg) + s3ecV3, err := client.New(s3V2, cmm) + + result, err := s3ecV3.GetObject(ctx, s3.GetObjectInput{ + Bucket: aws.String(bucket), + Key: aws.String(objectKey), + }) + if err != nil { + t.Fatalf("error while decrypting: %v", err) + } +``` + +#### Enable legacy decryption modes +The `enableLegacyUnauthenticatedModes` flag enables the S3 Encryption Client to decrypt +encrypted objects with a fully supported or legacy encryption algorithm. +Version V3 of the S3 Encryption Client uses one of the fully supported wrapping algorithms and the +wrapping key you specify to encrypt and decrypt the data keys. The +`enableLegacyWrappingAlgorithms` flag enables the S3 Encryption Client to decrypt +encrypted data keys with a fully supported or legacy wrapping algorithm. + +```go +cmm, err := materials.NewCryptographicMaterialsManager(materials.NewKmsKeyring(kmsClient, kmsKeyArn, func(options *materials.KeyringOptions) { + options.EnableLegacyWrappingAlgorithms = true + }) + + if err != nil { + t.Fatalf("error while creating new CMM") + } + + client, err := client.New(s3Client, cmm, func(clientOptions *client.EncryptionClientOptions) { + clientOptions.EnableLegacyUnauthenticatedModes = true + }) + + if err != nil { + // handle error + } +``` + +### Legacy Algorithms and Modes +#### Content Encryption +* AES/CBC +#### Key Wrap Encryption +* KMS (without context) ## Security @@ -14,4 +213,3 @@ See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more inform ## License This project is licensed under the Apache-2.0 License. - diff --git a/test-server/Makefile b/test-server/Makefile index 4831d68d..56030aef 100644 --- a/test-server/Makefile +++ b/test-server/Makefile @@ -9,7 +9,7 @@ all: start-servers run-tests ci: start-servers run-tests stop-servers -# Start Python server in background +# Start Python V3 server in background start-python-v3-server: @echo "Starting Python V3 server..." cd python-v3-server && \ @@ -22,9 +22,9 @@ start-python-v3-server: AWS_SESSION_TOKEN="$$AWS_SESSION_TOKEN" \ AWS_REGION="us-west-2" \ .venv/bin/python src/main.py & echo $$! > ../python-v3-server.pid - @echo "Python server starting..." + @echo "Python V3 server starting..." -# Start Java server in background +# Start Java V3 server in background start-java-v3-server: @echo "Starting Java V3 server..." cd java-v3-server && \ @@ -33,9 +33,9 @@ start-java-v3-server: AWS_SESSION_TOKEN="$$AWS_SESSION_TOKEN" \ AWS_REGION="us-west-2" \ ./gradlew --build-cache --parallel run & echo $$! > ../java-v3-server.pid - @echo "Java server starting..." + @echo "Java V3 server starting..." -# Start Go server in background +# Start Go V3 server in background start-go-v3-server: @echo "Starting Go V3 server..." cd go-v3-server && \ @@ -45,7 +45,19 @@ start-go-v3-server: AWS_SESSION_TOKEN="$$AWS_SESSION_TOKEN" \ AWS_REGION="us-west-2" \ go run . & echo $$! > ../go-v3-server.pid - @echo "Go server starting..." + @echo "Go V3 server starting..." + +# Start Go V4 server in background +start-go-v4-server: + @echo "Starting Go V4 server..." + cd go-v4-server && \ + go mod tidy && \ + AWS_ACCESS_KEY_ID="$$AWS_ACCESS_KEY_ID" \ + AWS_SECRET_ACCESS_KEY="$$AWS_SECRET_ACCESS_KEY" \ + AWS_SESSION_TOKEN="$$AWS_SESSION_TOKEN" \ + AWS_REGION="us-west-2" \ + go run . & echo $$! > ../go-v4-server.pid + @echo "Go V4 server starting..." # Start all servers in parallel start-servers: diff --git a/test-server/java-tests/src/it/java/software/amazon/encryption/s3/RoundTripTests.java b/test-server/java-tests/src/it/java/software/amazon/encryption/s3/RoundTripTests.java index 535e4d8d..64a04a59 100644 --- a/test-server/java-tests/src/it/java/software/amazon/encryption/s3/RoundTripTests.java +++ b/test-server/java-tests/src/it/java/software/amazon/encryption/s3/RoundTripTests.java @@ -68,11 +68,13 @@ public class RoundTripTests { serverList.add(new LanguageServerTarget("Java-V3", "8080")); serverList.add(new LanguageServerTarget("Python-V3", "8081")); serverList.add(new LanguageServerTarget("Go-V3", "8082")); + serverList.add(new LanguageServerTarget("Go-V4", "8089")); serverMap = new HashMap<>(14); serverMap.put("Java-V3", new LanguageServerTarget("Java-V3", "8080")); serverMap.put("Python-V3", new LanguageServerTarget("Python-V3", "8081")); serverMap.put("Go-V3", new LanguageServerTarget("Go-V3", "8082")); + serverMap.put("Go-V4", new LanguageServerTarget("Go-V4", "8089")); } // These S3EC implementations do not validate encryption context provided to getObject (i.e. on decrypt). From 476ef861fe497bdc1275147de61623c6bb9cb48f Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Wed, 17 Sep 2025 14:18:50 -0700 Subject: [PATCH 03/22] m --- .../amazon/encryption/s3/RoundTripTests.java | 129 +++++++++++++++++- test-server/model/client.smithy | 9 +- 2 files changed, 132 insertions(+), 6 deletions(-) diff --git a/test-server/java-tests/src/it/java/software/amazon/encryption/s3/RoundTripTests.java b/test-server/java-tests/src/it/java/software/amazon/encryption/s3/RoundTripTests.java index 211269d7..45dfc388 100644 --- a/test-server/java-tests/src/it/java/software/amazon/encryption/s3/RoundTripTests.java +++ b/test-server/java-tests/src/it/java/software/amazon/encryption/s3/RoundTripTests.java @@ -13,11 +13,7 @@ import java.net.URI; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; +import java.util.*; import java.util.stream.Stream; import com.amazonaws.services.s3.model.KMSEncryptionMaterials; @@ -62,6 +58,41 @@ public class RoundTripTests { private static final String BUCKET = System.getenv("TEST_SERVER_S3_BUCKET") != null ? System.getenv("TEST_SERVER_S3_BUCKET") : "s3ec-test-server-github-bucket"; + // Strings for naming each version + // Each language can have up to 3 versions: + // vN-Current: Currently released version. Does not support setting commitment policy. + // vN-Transition: Proposed patch/feature release version with a new client class. + // Supports setting commitment policy; no default policy; MUST be explicitly configured on constructor. + // vN+1: Proposed breaking release version. + // Supports setting commitment policy; defaults to `RequireEncryptRequireDecrypt`. + + private static final String JAVA_V3_CURRENT = "Java-V3-Current"; + private static final String JAVA_V3_TRANSITION = "Java-V3-Transition"; + private static final String JAVA_V4 = "Java-V4"; + + // No Python S3EC versions are released. Only test V3 as the "vN+1" version. + private static final String PYTHON_V3 = "Python-V3"; + + private static final String GO_V3_CURRENT = "Go-V3-Current"; + private static final String GO_V3_TRANSITION = "Go-V3-Transition"; + private static final String GO_V4 = "Go-V4"; + + private static final String NET_V2_CURRENT = "Net-V2-Current"; + private static final String NET_V2_TRANSITION = "Net-V2-Transition"; + private static final String NET_V3 = "Net-V3"; + + private static final String CPP_V2_CURRENT = "Cpp-V2-Current"; + private static final String CPP_V2_TRANSITION = "Cpp-V2-Transition"; + private static final String CPP_V3 = "Cpp-V3"; + + private static final String RUBY_V2_CURRENT = "Ruby-V2-Current"; + private static final String RUBY_V2_TRANSITION = "Ruby-V2-Transition"; + private static final String RUBY_V3 = "Ruby-V3"; + + private static final String PHP_V2_CURRENT = "PHP-V2-Current"; + private static final String PHP_V2_TRANSITION = "PHP-V2-Transition"; + private static final String PHP_V3 = "PHP-V3"; + static { serverList = new ArrayList<>(2); serverList.add(new LanguageServerTarget("Java", "8080")); @@ -72,6 +103,44 @@ public class RoundTripTests { serverMap.put("Python", new LanguageServerTarget("Python", "8081")); } + // These S3EC implementations do not validate encryption context provided to getObject (i.e. on decrypt). + // If the encryption context provided to getObject does not match the encryption context on the stored object, + // these implementations will not raise an error as expected. + // For now, skip tests that expect encryption context validation on decrypt. + private static final Set ENCRYPTION_CONTEXT_ON_DECRYPT_UNSUPPORTED = + Set.of("Go-V3"); + + private static final Set CURRENT_VERSIONS = + Set.of( + JAVA_V3_CURRENT, + GO_V3_CURRENT, + NET_V2_CURRENT, + CPP_V2_CURRENT, + RUBY_V2_CURRENT, + PHP_V2_CURRENT + ); + + private static final Set TRANSITION_VERSIONS = + Set.of( + JAVA_V3_TRANSITION, + GO_V3_TRANSITION, + NET_V2_TRANSITION, + CPP_V2_TRANSITION, + RUBY_V2_TRANSITION, + PHP_V2_TRANSITION + ); + + private static final Set IMPROVED_VERSIONS = + Set.of( + JAVA_V4, + PYTHON_V3, + GO_V4, + NET_V3, + CPP_V3, + RUBY_V3, + PHP_V3 + ); + static public class LanguageServerTarget { public String getLanguageName() { return languageName; @@ -433,4 +502,54 @@ public void kmsV1LegacyFailsWhenLegacyDisabled(String language) { } } + // Exhaustive test 1 + @ParameterizedTest(name = "{displayName} for Encrypt: {0}, Decrypt: {1}") + @MethodSource("crossLanguageClients") + public void GIVEN_EncryptWithKeyCommitment_WHEN_DecryptWithCurrentVersion_THEN_Fail(LanguageServerTarget encLang, LanguageServerTarget decLang) { + // Given: encrypt language is either an improved version or a transition version + if (!IMPROVED_VERSIONS.contains(encLang.getLanguageName()) || !TRANSITION_VERSIONS.contains(encLang.getLanguageName())) { + return; + } + + // Given: decrypt language is a current version + if (!CURRENT_VERSIONS.contains(decLang.getLanguageName())) { + return; + } + + S3ECTestServerClient encClient = testServerClientFor(encLang); + final String objectKey = "encrypt-kc-decrypt-current-test-key-" + encLang; + final String input = "simple-test-input"; + KeyMaterial kmsKeyArn = KeyMaterial.builder() + .kmsKeyId(KMS_KEY_ARN) + .build(); + CreateClientOutput encClientOutput = encClient.createClient(CreateClientInput.builder() + .config(S3ECConfig.builder() + .keyMaterial(kmsKeyArn).build()) + .build()); + String encS3ECId = encClientOutput.getClientId(); + encClient.putObject(PutObjectInput.builder() + .clientID(encS3ECId) + .key(objectKey) + .bucket(BUCKET) + .body(ByteBuffer.wrap(input.getBytes(StandardCharsets.UTF_8))) + .build()); + S3ECTestServerClient decClient = testServerClientFor(decLang); + CreateClientOutput decClientOutput = decClient.createClient(CreateClientInput.builder() + .config(S3ECConfig.builder() + .keyMaterial(kmsKeyArn).build()) + .build()); + String decS3ECId = decClientOutput.getClientId(); + GetObjectOutput output = decClient.getObject(GetObjectInput.builder() + .clientID(decS3ECId) + .bucket(BUCKET) + .key(objectKey) + .build()); + + if (!input.equals(StandardCharsets.UTF_8.decode(output.getBody()).toString())) { + fail(String.format("Encryption in %s failed to decrpyt in %s!", encLang, decLang)); + } + + + } + } diff --git a/test-server/model/client.smithy b/test-server/model/client.smithy index 4de56b5b..1069934f 100644 --- a/test-server/model/client.smithy +++ b/test-server/model/client.smithy @@ -28,10 +28,17 @@ structure KeyMaterial { kmsKeyId: String } +enum CommitmentPolicy { + REQUIRE_ENCRYPT_REQUIRE_DECRYPT, + REQUIRE_ENCRYPT_ALLOW_DECRYPT, + ALLOW_ENCRYPT_ALLOW_DECRYPT +} + structure S3ECConfig { enableLegacyUnauthenticatedModes: Boolean = false, enableDelayedAuthenticationMode: Boolean = false, enableLegacyWrappingAlgorithms: Boolean = false, setBufferSize: Long, - keyMaterial: KeyMaterial + keyMaterial: KeyMaterial, + commitmentPolicy: CommitmentPolicy } From 7a556ed4771a2ec4bbe7f2418dfa0a19e8ae2a92 Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Mon, 22 Sep 2025 10:59:40 -0700 Subject: [PATCH 04/22] m --- .gitmodules | 3 +++ test-server/go-v4-server/local-go-s3ec | 1 + 2 files changed, 4 insertions(+) create mode 160000 test-server/go-v4-server/local-go-s3ec diff --git a/.gitmodules b/.gitmodules index b2b112a0..bb6e6e65 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "test-server/ruby-v3-server/local-ruby-sdk"] path = test-server/ruby-v3-server/local-ruby-sdk url = git@github.com:aws/aws-sdk-ruby-staging.git +[submodule "test-server/go-v4-server/local-go-s3ec"] + path = test-server/go-v4-server/local-go-s3ec + url = git@github.com:aws/private-amazon-s3-encryption-client-go-staging.git diff --git a/test-server/go-v4-server/local-go-s3ec b/test-server/go-v4-server/local-go-s3ec new file mode 160000 index 00000000..87b83dbc --- /dev/null +++ b/test-server/go-v4-server/local-go-s3ec @@ -0,0 +1 @@ +Subproject commit 87b83dbcceca1f2678e52747fad2c253334c0c5d From 4f194a706a2d277bf692af286304e70ec83afc96 Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Mon, 22 Sep 2025 11:08:33 -0700 Subject: [PATCH 05/22] m --- .../CODE_OF_CONDUCT.md | 4 - .../CONTRIBUTING.md | 59 --- .../amazon-s3-encryption-client-go/LICENSE | 175 --------- .../amazon-s3-encryption-client-go/NOTICE | 1 - .../amazon-s3-encryption-client-go/README.md | 215 ----------- test-server/go-v4-server/Makefile | 25 ++ test-server/go-v4-server/README.md | 32 ++ test-server/go-v4-server/go.mod | 33 ++ test-server/go-v4-server/go.sum | 45 +++ test-server/go-v4-server/main.go | 350 ++++++++++++++++++ test-server/go-v4-server/server.pid | 1 + 11 files changed, 486 insertions(+), 454 deletions(-) delete mode 100644 hard-submodules/amazon-s3-encryption-client-go/CODE_OF_CONDUCT.md delete mode 100644 hard-submodules/amazon-s3-encryption-client-go/CONTRIBUTING.md delete mode 100644 hard-submodules/amazon-s3-encryption-client-go/LICENSE delete mode 100644 hard-submodules/amazon-s3-encryption-client-go/NOTICE delete mode 100644 hard-submodules/amazon-s3-encryption-client-go/README.md create mode 100644 test-server/go-v4-server/Makefile create mode 100644 test-server/go-v4-server/README.md create mode 100644 test-server/go-v4-server/go.mod create mode 100644 test-server/go-v4-server/go.sum create mode 100644 test-server/go-v4-server/main.go create mode 100644 test-server/go-v4-server/server.pid diff --git a/hard-submodules/amazon-s3-encryption-client-go/CODE_OF_CONDUCT.md b/hard-submodules/amazon-s3-encryption-client-go/CODE_OF_CONDUCT.md deleted file mode 100644 index 5b627cfa..00000000 --- a/hard-submodules/amazon-s3-encryption-client-go/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,4 +0,0 @@ -## Code of Conduct -This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). -For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact -opensource-codeofconduct@amazon.com with any additional questions or comments. diff --git a/hard-submodules/amazon-s3-encryption-client-go/CONTRIBUTING.md b/hard-submodules/amazon-s3-encryption-client-go/CONTRIBUTING.md deleted file mode 100644 index c4b6a1c5..00000000 --- a/hard-submodules/amazon-s3-encryption-client-go/CONTRIBUTING.md +++ /dev/null @@ -1,59 +0,0 @@ -# Contributing Guidelines - -Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional -documentation, we greatly value feedback and contributions from our community. - -Please read through this document before submitting any issues or pull requests to ensure we have all the necessary -information to effectively respond to your bug report or contribution. - - -## Reporting Bugs/Feature Requests - -We welcome you to use the GitHub issue tracker to report bugs or suggest features. - -When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already -reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: - -* A reproducible test case or series of steps -* The version of our code being used -* Any modifications you've made relevant to the bug -* Anything unusual about your environment or deployment - - -## Contributing via Pull Requests -Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: - -1. You are working against the latest source on the *main* branch. -2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. -3. You open an issue to discuss any significant work - we would hate for your time to be wasted. - -To send us a pull request, please: - -1. Fork the repository. -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. -3. Ensure local tests pass. -4. Commit to your fork using clear commit messages. -5. Send us a pull request, answering any default questions in the pull request interface. -6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. - -GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and -[creating a pull request](https://help.github.com/articles/creating-a-pull-request/). - - -## Finding contributions to work on -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' issues is a great place to start. - - -## Code of Conduct -This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). -For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact -opensource-codeofconduct@amazon.com with any additional questions or comments. - - -## Security issue notifications -If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. - - -## Licensing - -See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. diff --git a/hard-submodules/amazon-s3-encryption-client-go/LICENSE b/hard-submodules/amazon-s3-encryption-client-go/LICENSE deleted file mode 100644 index 67db8588..00000000 --- a/hard-submodules/amazon-s3-encryption-client-go/LICENSE +++ /dev/null @@ -1,175 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. diff --git a/hard-submodules/amazon-s3-encryption-client-go/NOTICE b/hard-submodules/amazon-s3-encryption-client-go/NOTICE deleted file mode 100644 index 616fc588..00000000 --- a/hard-submodules/amazon-s3-encryption-client-go/NOTICE +++ /dev/null @@ -1 +0,0 @@ -Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. diff --git a/hard-submodules/amazon-s3-encryption-client-go/README.md b/hard-submodules/amazon-s3-encryption-client-go/README.md deleted file mode 100644 index 5bc75d78..00000000 --- a/hard-submodules/amazon-s3-encryption-client-go/README.md +++ /dev/null @@ -1,215 +0,0 @@ -# Amazon S3 Encryption Client for Go V4 - -[![Go Build status](https://github.com/aws/amazon-s3-encryption-client-go/actions/workflows/go-test.yml/badge.svg?branch=main)](https://github.com/aws/amazon-s3-encryption-client-go/actions/workflows/go-test.yml) [![Apache V2 License](https://img.shields.io/badge/license-Apache%20V2-blue.svg)](https://github.com/aws/amazon-s3-encryption-client-go/blob/main/LICENSE) - -This library provides an S3 client that supports client-side encryption. -`amazon-s3-encryption-client-go` is the v4 of the Amazon S3 Encryption Client for the Go programming language. - -The v4 encryption client requires a minimum version of `Go 1.20`. - -Check out the [release notes](https://github.com/aws/amazon-s3-encryption-client-go/blob/main/CHANGELOG.md) for information about the latest bug -fixes, updates, and features added to the encryption client. - -Jump To: -* [Getting Started](#getting-started) -* [Migration](#migration) - -## Maintenance and support for SDK major versions - -For information about maintenance and support for SDK major versions and their underlying dependencies, see the -following in the AWS SDKs and Tools Shared Configuration and Credentials Reference Guide: - -* [AWS SDKs and Tools Maintenance Policy](https://docs.aws.amazon.com/credref/latest/refdocs/maint-policy.html) -* [AWS SDKs and Tools Version Support Matrix](https://docs.aws.amazon.com/credref/latest/refdocs/version-support-matrix.html) - -### Go version support policy - -The v4 Encryption Client follows the upstream [release policy](https://go.dev/doc/devel/release#policy) -with an additional six months of support for the most recently deprecated -language version. - -**AWS reserves the right to drop support for unsupported Go versions earlier to -address critical security issues.** - -## Getting started -To get started working with the S3 Encryption Client set up your project for Go modules, and retrieve the client's dependencies with `go get`. -This example shows how you can use the v4 encryption client to make a `PutItem` request using a KmsKeyring. - -###### Initialize Project -```sh -$ mkdir ~/encryptionclient -$ cd ~/encryptionclient -$ go mod init encryptionclient -``` -###### Add SDK Dependencies -```sh -$ go get github.com/aws/amazon-s3-encryption-client-go/v4 -``` - -###### Write Code -In your preferred editor add the following content to `main.go` - -```go -package main - -import ( - "context" - "log" - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/config" - "github.com/aws/aws-sdk-go-v2/service/kms" - "github.com/aws/aws-sdk-go-v2/service/s3" - - // Import the materials and client package - "github.com/aws/amazon-s3-encryption-client-go/v4/client" - "github.com/aws/amazon-s3-encryption-client-go/v4/materials" -) - -func main() { - ctx := context.Background() - // Using the SDK's default configuration, loading additional config - // and credentials values from the environment variables, shared - // credentials, and shared configuration files - cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion("us-west-2")) - if err != nil { - log.Fatalf("unable to load SDK config, %v", err) - } - key := "testObjectWithNewEncryptionClient" - plaintext := "This is a test.\n" - - s3Client := s3.NewFromConfig(cfg) - kmsClient := kms.NewFromConfig(cfg) - - // Create the keyring and &CMM-long; (&CMM-short;) - cmm, err := materials.NewCryptographicMaterialsManager(materials.NewKmsKeyring(kmsClient, kmsKeyArn, func(options *materials.KeyringOptions) { - options.EnableLegacyWrappingAlgorithms = false - })) - if err != nil { - log.Fatalf("error while creating new CMM") - } - - s3EncryptionClient, err := client.New(s3Client, cmm) - - _, err = s3EncryptionClient.PutObject(ctx, &s3Client.PutObjectInput{ - Bucket: aws.String(bucket), - Key: aws.String(key), - Body: bytes.NewReader([]byte(plaintext)), - }) - if err != nil { - log.Fatalf("error calling putObject: %v", err) - } -} -``` - -## Migration - -This version of the library supports reading encrypted objects from previous versions. -It also supports writing objects with non-legacy algorithms. -The list of legacy modes and operations will be provided below. - -### Examples -#### V2 KMS to V3 - -The following example demonstrates how to migrate a version v2 application that uses -the `NewKMSContextKeyGenerator` kms-key provider with a material -description and `AESGCMContentCipherBuilderV2` content cipher to -version v3 of the S3 Encryption Client for Go. - -```go -func KmsContextV2toV3GCMExample() error { - bucket := LoadBucket() - kmsKeyAlias := LoadAwsKmsAlias() - - objectKey := "my-object-key" - region := "us-west-2" - plaintext := "This is an example.\n" - - // Create an S3EC Go v2 encryption client - // using the KMS client from AWS SDK for Go v1 - sessKms, err := sessionV1.NewSession(&awsV1.Config{ - Region: aws.String(region), - }) - - kmsSvc := kmsV1.New(sessKms) - handler := s3cryptoV2.NewKMSContextKeyGenerator(kmsSvc, kmsKeyAlias, s3cryptoV2.MaterialDescription{}) - builder := s3cryptoV2.AESGCMContentCipherBuilderV2(handler) - encClient, err := s3cryptoV2.NewEncryptionClientV2(sessKms, builder) - if err != nil { - log.Fatalf("error creating new v2 client: %v", err) - } - - // Encrypt using KMS+Context and AES-GCM content cipher - _, err = encClient.PutObject(s3V1.PutObjectInput{ - Bucket: aws.String(bucket), - Key: aws.String(objectKey), - Body: bytes.NewReader([]byte(plaintext)), - }) - if err != nil { - log.Fatalf("error calling putObject: %v", err) - } - fmt.Printf("successfully uploaded file to %s/%s\n", bucket, key) - - // Create an S3EC Go v3 client - // using the KMS client from AWS SDK for Go v2 - ctx := context.Background() - cfg, err := config.LoadDefaultConfig(ctx, - config.WithRegion(region), - ) - - kmsV2 := kms.NewFromConfig(cfg) - cmm, err := materials.NewCryptographicMaterialsManager(materials.NewKmsKeyring(kmsV2, kmsKeyAlias)) - if err != nil { - t.Fatalf("error while creating new CMM") - } - - s3V2 := s3.NewFromConfig(cfg) - s3ecV3, err := client.New(s3V2, cmm) - - result, err := s3ecV3.GetObject(ctx, s3.GetObjectInput{ - Bucket: aws.String(bucket), - Key: aws.String(objectKey), - }) - if err != nil { - t.Fatalf("error while decrypting: %v", err) - } -``` - -#### Enable legacy decryption modes -The `enableLegacyUnauthenticatedModes` flag enables the S3 Encryption Client to decrypt -encrypted objects with a fully supported or legacy encryption algorithm. -Version V3 of the S3 Encryption Client uses one of the fully supported wrapping algorithms and the -wrapping key you specify to encrypt and decrypt the data keys. The -`enableLegacyWrappingAlgorithms` flag enables the S3 Encryption Client to decrypt -encrypted data keys with a fully supported or legacy wrapping algorithm. - -```go -cmm, err := materials.NewCryptographicMaterialsManager(materials.NewKmsKeyring(kmsClient, kmsKeyArn, func(options *materials.KeyringOptions) { - options.EnableLegacyWrappingAlgorithms = true - }) - - if err != nil { - t.Fatalf("error while creating new CMM") - } - - client, err := client.New(s3Client, cmm, func(clientOptions *client.EncryptionClientOptions) { - clientOptions.EnableLegacyUnauthenticatedModes = true - }) - - if err != nil { - // handle error - } -``` - -### Legacy Algorithms and Modes -#### Content Encryption -* AES/CBC -#### Key Wrap Encryption -* KMS (without context) - -## Security - -See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information. - -## License - -This project is licensed under the Apache-2.0 License. diff --git a/test-server/go-v4-server/Makefile b/test-server/go-v4-server/Makefile new file mode 100644 index 00000000..a8a2553d --- /dev/null +++ b/test-server/go-v4-server/Makefile @@ -0,0 +1,25 @@ +# Makefile for S3 Encryption Client Testing + +.PHONY: start-server stop-server wait-for-server + +PID_FILE := server.pid +PORT := 8089 + +start-server: + @echo "Starting Go V4 server..." + go mod tidy + AWS_ACCESS_KEY_ID="$$AWS_ACCESS_KEY_ID" \ + AWS_SECRET_ACCESS_KEY="$$AWS_SECRET_ACCESS_KEY" \ + AWS_SESSION_TOKEN="$$AWS_SESSION_TOKEN" \ + AWS_REGION="us-west-2" \ + go run . & echo $$! > $(PID_FILE) + @echo "Go V4 server starting..." + +stop-server: + @if [ -f $(PID_FILE) ]; then \ + kill $$(cat $(PID_FILE)) 2>/dev/null || true; \ + rm $(PID_FILE); \ + fi + +wait-for-server: + $(MAKE) -C .. wait-for-port PORT=$(PORT) diff --git a/test-server/go-v4-server/README.md b/test-server/go-v4-server/README.md new file mode 100644 index 00000000..6b153bfc --- /dev/null +++ b/test-server/go-v4-server/README.md @@ -0,0 +1,32 @@ +# S3EC Go V3 Test Server + +This is the Go implementation of the S3ECTestServer framework for S3EC Go V3. It provides a server implementation for testing Go S3 Encryption Client V3 functionality. + +## Overview + +The S3EC Go test server implements the S3ECTestServer service defined in the shared Smithy model. It provides endpoints for: + +- Creating S3 Encryption Clients +- Putting objects with encryption +- Getting and decrypting objects + +## Architecture + +The server is built using: + +- **HTTP Framework**: Gorilla Mux for routing +- **AWS SDK**: AWS SDK for Go v2 for S3 and KMS operations +- **Concurrency**: Thread-safe client caching with sync.RWMutex +- **Error Handling**: Smithy-compliant error responses + +## Usage + +To run the server: + +```console +go run . +``` + +This will start the server running on port `8082`. + +The server is used as part of the testing framework to verify cross-language compatibility of the S3 Encryption Client implementations. diff --git a/test-server/go-v4-server/go.mod b/test-server/go-v4-server/go.mod new file mode 100644 index 00000000..8fac0047 --- /dev/null +++ b/test-server/go-v4-server/go.mod @@ -0,0 +1,33 @@ +module github.com/aws/amazon-s3-encryption-client-python/test-server/go-server + +go 1.21 + +require ( + github.com/aws/amazon-s3-encryption-client-go/v4 v4.0.0 + github.com/aws/aws-sdk-go-v2 v1.24.0 + github.com/aws/aws-sdk-go-v2/config v1.26.1 + github.com/aws/aws-sdk-go-v2/service/kms v1.27.4 + github.com/aws/aws-sdk-go-v2/service/s3 v1.47.5 + github.com/google/uuid v1.5.0 + github.com/gorilla/mux v1.8.1 +) + +require ( + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.16.12 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.9 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.2.9 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.2.9 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.16.9 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.18.5 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.26.5 // indirect + github.com/aws/smithy-go v1.19.0 // indirect +) + +replace github.com/aws/amazon-s3-encryption-client-go/v4 => ./local-go-s3ec/v4 diff --git a/test-server/go-v4-server/go.sum b/test-server/go-v4-server/go.sum new file mode 100644 index 00000000..1bb969a3 --- /dev/null +++ b/test-server/go-v4-server/go.sum @@ -0,0 +1,45 @@ + +github.com/aws/aws-sdk-go-v2 v1.24.0 h1:890+mqQ+hTpNuw0gGP6/4akolQkSToDJgHfQE7AwGuk= +github.com/aws/aws-sdk-go-v2 v1.24.0/go.mod h1:LNh45Br1YAkEKaAqvmE1m8FUx6a5b/V0oAKV7of29b4= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4 h1:OCs21ST2LrepDfD3lwlQiOqIGp6JiEUqG84GzTDoyJs= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4/go.mod h1:usURWEKSNNAcAZuzRn/9ZYPT8aZQkR7xcCtunK/LkJo= +github.com/aws/aws-sdk-go-v2/config v1.26.1 h1:z6DqMxclFGL3Zfo+4Q0rLnAZ6yVkzCRxhRMsiRQnD1o= +github.com/aws/aws-sdk-go-v2/config v1.26.1/go.mod h1:ZB+CuKHRbb5v5F0oJtGdhFTelmrxd4iWO1lf0rQwSAg= +github.com/aws/aws-sdk-go-v2/credentials v1.16.12 h1:v/WgB8NxprNvr5inKIiVVrXPuuTegM+K8nncFkr1usU= +github.com/aws/aws-sdk-go-v2/credentials v1.16.12/go.mod h1:X21k0FjEJe+/pauud82HYiQbEr9jRKY3kXEIQ4hXeTQ= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10 h1:w98BT5w+ao1/r5sUuiH6JkVzjowOKeOJRHERyy1vh58= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10/go.mod h1:K2WGI7vUvkIv1HoNbfBA1bvIZ+9kL3YVmWxeKuLQsiw= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9 h1:v+HbZaCGmOwnTTVS86Fleq0vPzOd7tnJGbFhP0stNLs= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9/go.mod h1:Xjqy+Nyj7VDLBtCMkQYOw1QYfAEZCVLrfI0ezve8wd4= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.9 h1:N94sVhRACtXyVcjXxrwK1SKFIJrA9pOJ5yu2eSHnmls= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.9/go.mod h1:hqamLz7g1/4EJP+GH5NBhcUMLjW+gKLQabgyz6/7WAU= +github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 h1:GrSw8s0Gs/5zZ0SX+gX4zQjRnRsMJDJ2sLur1gRBhEM= +github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2/go.mod h1:6fQQgfuGmw8Al/3M2IgIllycxV7ZW7WCdVSqfBeUiCY= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.2.9 h1:ugD6qzjYtB7zM5PN/ZIeaAIyefPaD82G8+SJopgvUpw= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.2.9/go.mod h1:YD0aYBWCrPENpHolhKw2XDlTIWae2GKXT1T4o6N6hiM= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 h1:/b31bi3YVNlkzkBrm9LfpaKoaYZUxIAj4sHfOTmLfqw= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4/go.mod h1:2aGXHFmbInwgP9ZfpmdIfOELL79zhdNYNmReK8qDfdQ= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.2.9 h1:/90OR2XbSYfXucBMJ4U14wrjlfleq/0SB6dZDPncgmo= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.2.9/go.mod h1:dN/Of9/fNZet7UrQQ6kTDo/VSwKPIq94vjlU16bRARc= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9 h1:Nf2sHxjMJR8CSImIVCONRi4g0Su3J+TSTbS7G0pUeMU= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9/go.mod h1:idky4TER38YIjr2cADF1/ugFMKvZV7p//pVeV5LZbF0= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.16.9 h1:iEAeF6YC3l4FzlJPP9H3Ko1TXpdjdqWffxXjp8SY6uk= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.16.9/go.mod h1:kjsXoK23q9Z/tLBrckZLLyvjhZoS+AGrzqzUfEClvMM= +github.com/aws/aws-sdk-go-v2/service/kms v1.27.4 h1:c75pHGBV3h6WOsIjbJhLyOnlCPXzap45nbiP2Z5jk5M= +github.com/aws/aws-sdk-go-v2/service/kms v1.27.4/go.mod h1:D9FVDkZjkZnnFHymJ3fPVz0zOUlNSd0xcIIVmmrAac8= +github.com/aws/aws-sdk-go-v2/service/s3 v1.47.5 h1:Keso8lIOS+IzI2MkPZyK6G0LYcK3My2LQ+T5bxghEAY= +github.com/aws/aws-sdk-go-v2/service/s3 v1.47.5/go.mod h1:vADO6Jn+Rq4nDtfwNjhgR84qkZwiC6FqCaXdw/kYwjA= +github.com/aws/aws-sdk-go-v2/service/sso v1.18.5 h1:ldSFWz9tEHAwHNmjx2Cvy1MjP5/L9kNoR0skc6wyOOM= +github.com/aws/aws-sdk-go-v2/service/sso v1.18.5/go.mod h1:CaFfXLYL376jgbP7VKC96uFcU8Rlavak0UlAwk1Dlhc= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5 h1:2k9KmFawS63euAkY4/ixVNsYYwrwnd5fIvgEKkfZFNM= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5/go.mod h1:W+nd4wWDVkSUIox9bacmkBP5NMFQeTJ/xqNabpzSR38= +github.com/aws/aws-sdk-go-v2/service/sts v1.26.5 h1:5UYvv8JUvllZsRnfrcMQ+hJ9jNICmcgKPAO1CER25Wg= +github.com/aws/aws-sdk-go-v2/service/sts v1.26.5/go.mod h1:XX5gh4CB7wAs4KhcF46G6C8a2i7eupU19dcAAE+EydU= +github.com/aws/smithy-go v1.19.0 h1:KWFKQV80DpP3vJrrA9sVAHQ5gc2z8i4EzrLhLlWXcBM= +github.com/aws/smithy-go v1.19.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= +github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= +github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= diff --git a/test-server/go-v4-server/main.go b/test-server/go-v4-server/main.go new file mode 100644 index 00000000..47fbd9b7 --- /dev/null +++ b/test-server/go-v4-server/main.go @@ -0,0 +1,350 @@ +package main + +import ( + "context" + "encoding/json" + "fmt" + "io" + "log" + "net/http" + "strings" + + "github.com/aws/amazon-s3-encryption-client-go/v4/client" + "github.com/aws/amazon-s3-encryption-client-go/v4/materials" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/service/kms" + "github.com/aws/aws-sdk-go-v2/service/s3" + "github.com/google/uuid" + "github.com/gorilla/mux" +) + +// Server represents the Go test server +type Server struct { + clientCache map[string]*client.S3EncryptionClientV4 + kmsClient *kms.Client +} + +// CreateClientInput represents the input for creating a client +type CreateClientInput struct { + Config S3ECConfig `json:"config"` +} + +// CreateClientOutput represents the output for creating a client +type CreateClientOutput struct { + ClientID string `json:"clientId"` +} + +// S3ECConfig represents the S3 encryption client configuration +type S3ECConfig struct { + EnableLegacyUnauthenticatedModes bool `json:"enableLegacyUnauthenticatedModes"` + EnableDelayedAuthenticationMode bool `json:"enableDelayedAuthenticationMode"` + EnableLegacyWrappingAlgorithms bool `json:"enableLegacyWrappingAlgorithms"` + SetBufferSize int64 `json:"setBufferSize"` + KeyMaterial KeyMaterial `json:"keyMaterial"` +} + +// KeyMaterial represents the key material for encryption +type KeyMaterial struct { + RSAKey []byte `json:"rsaKey"` + AESKey []byte `json:"aesKey"` + KMSKeyID string `json:"kmsKeyId"` +} + +// PutObjectOutput represents the output for put object operation +type PutObjectOutput struct { + Bucket string `json:"bucket"` + Key string `json:"key"` + Metadata []string `json:"metadata"` +} + +// ErrorResponse represents an error response +type ErrorResponse struct { + Type string `json:"__type"` + Message string `json:"message"` +} + +// NewServer creates a new server instance +func NewServer() (*Server, error) { + cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRegion("us-west-2")) + if err != nil { + return nil, fmt.Errorf("failed to load AWS config: %w", err) + } + + return &Server{ + clientCache: make(map[string]*client.S3EncryptionClientV4), + kmsClient: kms.NewFromConfig(cfg), + }, nil +} + +// createGenericServerError creates a generic server error response +func (s *Server) createGenericServerError(w http.ResponseWriter, message string, statusCode int) { + // Echo error to console + log.Printf("[Go V4] GenericServerError: %s (Status: %d)", message, statusCode) + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(statusCode) + json.NewEncoder(w).Encode(ErrorResponse{ + Type: "software.amazon.encryption.s3#GenericServerError", + Message: message, + }) +} + +// createS3EncryptionClientError creates an S3 encryption client error response +func (s *Server) createS3EncryptionClientError(w http.ResponseWriter, message string, statusCode int) { + // Echo error to console + log.Printf("[Go V4] S3EncryptionClientError: %s (Status: %d)", message, statusCode) + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(statusCode) + json.NewEncoder(w).Encode(ErrorResponse{ + Type: "software.amazon.encryption.s3#S3EncryptionClientError", + Message: message, + }) +} + +// metadataStringToMap converts metadata string to map +func metadataStringToMap(mdString string) (map[string]string, error) { + md := make(map[string]string) + if mdString == "" { + return md, nil + } + + mdList := strings.Split(mdString, ",") + for _, entry := range mdList { + // Split on "]:[" to separate key and value + parts := strings.Split(entry, "]:[") + if len(parts) == 2 { + // Remove remaining brackets from start and end + key := parts[0][1:] // Remove first character + value := parts[1][:len(parts[1])-1] // Remove last character + md[key] = value + } else { + return nil, fmt.Errorf("malformed metadata list entry: %s", entry) + } + } + return md, nil +} + +// createClient handles POST /client +func (s *Server) createClient(w http.ResponseWriter, r *http.Request) { + // Read body + body, err := io.ReadAll(r.Body) + if err != nil { + s.createGenericServerError(w, "Failed to read request body", http.StatusBadRequest) + return + } + + var input CreateClientInput + if err := json.Unmarshal(body, &input); err != nil { + s.createGenericServerError(w, "Invalid JSON in request body", http.StatusBadRequest) + return + } + + cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRegion("us-west-2")) + if err != nil { + s.createS3EncryptionClientError(w, fmt.Sprintf("Failed to load AWS config: %v", err), http.StatusInternalServerError) + return + } + + // Create KMS keyring + kmsClient := kms.NewFromConfig(cfg) + keyring := materials.NewKmsKeyring(kmsClient, input.Config.KeyMaterial.KMSKeyID, func(options *materials.KeyringOptions) { + options.EnableLegacyWrappingAlgorithms = input.Config.EnableLegacyWrappingAlgorithms + }) + cmm, err := materials.NewCryptographicMaterialsManager(keyring) + + if err != nil { + s.createS3EncryptionClientError(w, fmt.Sprintf("Failed to create CMM: %v", err), http.StatusInternalServerError) + return + } + + // Create S3 encryption client + var s3EncryptionClient *client.S3EncryptionClientV4 + s3PlaintextClient := s3.NewFromConfig(cfg) + s3EncryptionClient, err = client.New(s3PlaintextClient, cmm) + + if err != nil { + s.createS3EncryptionClientError(w, fmt.Sprintf("Failed to create S3EC: %v", err), http.StatusInternalServerError) + return + } + + // Generate client ID + clientID := uuid.New().String() + + // Store client in cache + s.clientCache[clientID] = s3EncryptionClient + + // Return response + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(CreateClientOutput{ + ClientID: clientID, + }) +} + +// putObject handles PUT /object/{bucket}/{key} +func (s *Server) putObject(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + bucket := vars["bucket"] + key := vars["key"] + + clientID := r.Header.Get("ClientID") + if clientID == "" { + s.createGenericServerError(w, "ClientID header is required", http.StatusBadRequest) + return + } + + // Get client from cache + client, exists := s.clientCache[clientID] + + if !exists { + s.createGenericServerError(w, fmt.Sprintf("No client found for ClientID: %s", clientID), http.StatusNotFound) + return + } + + // Read body + body, err := io.ReadAll(r.Body) + if err != nil { + s.createGenericServerError(w, "Failed to read request body", http.StatusBadRequest) + return + } + + // Get metadata from header + metadataHeader := r.Header.Get("Content-Metadata") + encCtx, err := metadataStringToMap(metadataHeader) + + // Create context with encryption context + ctx := context.Background() + encryptionContext := context.WithValue(ctx, "EncryptionContext", encCtx) + if err != nil { + s.createS3EncryptionClientError(w, fmt.Sprintf("Failed to parse metadata: %v", err), http.StatusBadRequest) + return + } + + // Create put object input + putInput := &s3.PutObjectInput{ + Bucket: aws.String(bucket), + Key: aws.String(key), + Body: strings.NewReader(string(body)), + } + + // Add metadata if present + if len(encCtx) > 0 { + putInput.Metadata = encCtx + } + + // Make the put object request using the encryption client + _, err = client.PutObject(encryptionContext, putInput) + if err != nil { + s.createS3EncryptionClientError(w, fmt.Sprintf("Failed to put object: %v", err), http.StatusInternalServerError) + return + } + + log.Printf("[Go V4] PutObject SUCCESS: Bucket=%s, Key=%s", bucket, key) + + // Return response + w.Header().Set("Content-Type", "application/json") + response := PutObjectOutput{ + Bucket: bucket, + Key: key, + Metadata: []string{}, // Return empty metadata list as per the model + } + json.NewEncoder(w).Encode(response) +} + +// getObject handles GET /object/{bucket}/{key} +func (s *Server) getObject(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + bucket := vars["bucket"] + key := vars["key"] + + clientID := r.Header.Get("ClientID") + if clientID == "" { + s.createGenericServerError(w, "ClientID header is required", http.StatusBadRequest) + return + } + + // Get client from cache + client, exists := s.clientCache[clientID] + + if !exists { + s.createGenericServerError(w, fmt.Sprintf("No client found for ClientID: %s", clientID), http.StatusNotFound) + return + } + + // Get metadata from header + metadataHeader := r.Header.Get("Content-Metadata") + encCtx, err := metadataStringToMap(metadataHeader) + + ctx := context.Background() + encryptionContext := context.WithValue(ctx, "EncryptionContext", encCtx) + if err != nil { + s.createS3EncryptionClientError(w, fmt.Sprintf("Failed to parse metadata: %v", err), http.StatusBadRequest) + return + } + + // Create get object input + getInput := &s3.GetObjectInput{ + Bucket: aws.String(bucket), + Key: aws.String(key), + } + + // Make the get object request using the encryption client + result, err := client.GetObject(encryptionContext, getInput) + if err != nil { + errMsg := err.Error() + // Shim the S3EC error message to the error message expected by the test server. + // We don't want to change the S3EC error message but the test server expects a specific error message; + // This is the appropriate place to rewrite the error message. + if strings.Contains(errMsg, "to decrypt x-amz-cek-alg value `kms` you must enable legacyWrappingAlgorithms on the keyring") { + s.createS3EncryptionClientError(w, "Enable legacy wrapping algorithms to use legacy key wrapping algorithm: kms", http.StatusInternalServerError) + return + } + + s.createS3EncryptionClientError(w, fmt.Sprintf("Failed to get object: %v", err), http.StatusInternalServerError) + return + } + defer result.Body.Close() + + // Read the body + body, err := io.ReadAll(result.Body) + if err != nil { + s.createS3EncryptionClientError(w, fmt.Sprintf("Failed to read object body: %v", err), http.StatusInternalServerError) + return + } + + // Convert metadata to string format + var metadataList []string + if result.Metadata != nil { + for k, v := range result.Metadata { + metadataList = append(metadataList, fmt.Sprintf("%s=%s", k, v)) + } + } + + metadataStr := strings.Join(metadataList, ",") + + log.Printf("[Go V4] GetObject SUCCESS: Bucket=%s, Key=%s", bucket, key) + + // Set response headers + w.Header().Set("Content-Metadata", metadataStr) + + // Return the body as response + w.Write(body) +} + +func main() { + server, err := NewServer() + if err != nil { + log.Fatalf("[Go V4] Failed to create Go V4 server: %v", err) + } + + r := mux.NewRouter() + + // Register routes + r.HandleFunc("/client", server.createClient).Methods("POST") + r.HandleFunc("/object/{bucket}/{key}", server.putObject).Methods("PUT") + r.HandleFunc("/object/{bucket}/{key}", server.getObject).Methods("GET") + + fmt.Println("[Go V4] Starting Go V4 server on :8089...") + log.Fatal(http.ListenAndServe(":8089", r)) +} diff --git a/test-server/go-v4-server/server.pid b/test-server/go-v4-server/server.pid new file mode 100644 index 00000000..67f5e17a --- /dev/null +++ b/test-server/go-v4-server/server.pid @@ -0,0 +1 @@ +48049 From 8860a56af6e39d59795db0a69ec4fe1319575e55 Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Mon, 22 Sep 2025 11:11:41 -0700 Subject: [PATCH 06/22] m --- test-server/go-v4-server/README.md | 15 ++------- test-server/go-v4-server/go.mod | 2 ++ test-server/go-v4-server/server.pid | 1 - .../amazon/encryption/s3/RoundTripTests.java | 31 ------------------- test-server/model/client.smithy | 9 +----- 5 files changed, 6 insertions(+), 52 deletions(-) delete mode 100644 test-server/go-v4-server/server.pid diff --git a/test-server/go-v4-server/README.md b/test-server/go-v4-server/README.md index 6b153bfc..d97a37bf 100644 --- a/test-server/go-v4-server/README.md +++ b/test-server/go-v4-server/README.md @@ -1,6 +1,6 @@ -# S3EC Go V3 Test Server +# S3EC Go V4 Test Server -This is the Go implementation of the S3ECTestServer framework for S3EC Go V3. It provides a server implementation for testing Go S3 Encryption Client V3 functionality. +This is the Go implementation of the S3ECTestServer framework for S3EC Go V4. It provides a server implementation for testing Go S3 Encryption Client V4 functionality. ## Overview @@ -10,15 +10,6 @@ The S3EC Go test server implements the S3ECTestServer service defined in the sha - Putting objects with encryption - Getting and decrypting objects -## Architecture - -The server is built using: - -- **HTTP Framework**: Gorilla Mux for routing -- **AWS SDK**: AWS SDK for Go v2 for S3 and KMS operations -- **Concurrency**: Thread-safe client caching with sync.RWMutex -- **Error Handling**: Smithy-compliant error responses - ## Usage To run the server: @@ -27,6 +18,6 @@ To run the server: go run . ``` -This will start the server running on port `8082`. +This will start the server running on port `8089`. The server is used as part of the testing framework to verify cross-language compatibility of the S3 Encryption Client implementations. diff --git a/test-server/go-v4-server/go.mod b/test-server/go-v4-server/go.mod index 8fac0047..4ab1895c 100644 --- a/test-server/go-v4-server/go.mod +++ b/test-server/go-v4-server/go.mod @@ -30,4 +30,6 @@ require ( github.com/aws/smithy-go v1.19.0 // indirect ) +// S3EC Go V4 is not released to pkg.go.dev as of writing. +// It is included as a submodule and referenced locally. replace github.com/aws/amazon-s3-encryption-client-go/v4 => ./local-go-s3ec/v4 diff --git a/test-server/go-v4-server/server.pid b/test-server/go-v4-server/server.pid deleted file mode 100644 index 67f5e17a..00000000 --- a/test-server/go-v4-server/server.pid +++ /dev/null @@ -1 +0,0 @@ -48049 diff --git a/test-server/java-tests/src/it/java/software/amazon/encryption/s3/RoundTripTests.java b/test-server/java-tests/src/it/java/software/amazon/encryption/s3/RoundTripTests.java index 8db5cbcb..cd67f2e0 100644 --- a/test-server/java-tests/src/it/java/software/amazon/encryption/s3/RoundTripTests.java +++ b/test-server/java-tests/src/it/java/software/amazon/encryption/s3/RoundTripTests.java @@ -133,37 +133,6 @@ private static Map filterServers(Map ENCRYPTION_CONTEXT_ON_ENCRYPT_UNSUPPORTED = Set.of(NET_V2, NET_V3); - private static final Set CURRENT_VERSIONS = - Set.of( - JAVA_V3_CURRENT, - GO_V3_CURRENT, - NET_V2_CURRENT, - CPP_V2_CURRENT, - RUBY_V2_CURRENT, - PHP_V2_CURRENT - ); - - private static final Set TRANSITION_VERSIONS = - Set.of( - JAVA_V3_TRANSITION, - GO_V3_TRANSITION, - NET_V2_TRANSITION, - CPP_V2_TRANSITION, - RUBY_V2_TRANSITION, - PHP_V2_TRANSITION - ); - - private static final Set IMPROVED_VERSIONS = - Set.of( - JAVA_V4, - PYTHON_V3, - GO_V4, - NET_V3, - CPP_V3, - RUBY_V3, - PHP_V3 - ); - static public class LanguageServerTarget { public String getLanguageName() { return languageName; diff --git a/test-server/model/client.smithy b/test-server/model/client.smithy index 1069934f..4de56b5b 100644 --- a/test-server/model/client.smithy +++ b/test-server/model/client.smithy @@ -28,17 +28,10 @@ structure KeyMaterial { kmsKeyId: String } -enum CommitmentPolicy { - REQUIRE_ENCRYPT_REQUIRE_DECRYPT, - REQUIRE_ENCRYPT_ALLOW_DECRYPT, - ALLOW_ENCRYPT_ALLOW_DECRYPT -} - structure S3ECConfig { enableLegacyUnauthenticatedModes: Boolean = false, enableDelayedAuthenticationMode: Boolean = false, enableLegacyWrappingAlgorithms: Boolean = false, setBufferSize: Long, - keyMaterial: KeyMaterial, - commitmentPolicy: CommitmentPolicy + keyMaterial: KeyMaterial } From 6fc8d09f031333ffa484254710bc2d3675e72b4b Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Mon, 22 Sep 2025 12:53:25 -0700 Subject: [PATCH 07/22] m --- .github/workflows/test.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 49b125ef..fe19814e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -22,6 +22,8 @@ jobs: uses: actions/checkout@v4 with: submodules: true + # ryanemer owns this PAT. + # Ping him to extend this PAT's permissions to access a new private repo. token: ${{ secrets.PAT_FOR_PRIVATE_RUBY }} - name: Set up Python From bb7c9ae5f9b4d85464067aecf936812de6456b37 Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Mon, 22 Sep 2025 13:24:22 -0700 Subject: [PATCH 08/22] m --- .github/workflows/test.yml | 5 +++-- .../java/software/amazon/encryption/s3/RoundTripTests.java | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fe19814e..390f003d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -22,8 +22,9 @@ jobs: uses: actions/checkout@v4 with: submodules: true - # ryanemer owns this PAT. - # Ping him to extend this PAT's permissions to access a new private repo. + # This is Ryan Emery's (seebees) PAT. + # To grant this workflow access to a new private repo, + # ask Ryan to edit this PAT's permissions to add access to a new private repo. token: ${{ secrets.PAT_FOR_PRIVATE_RUBY }} - name: Set up Python diff --git a/test-server/java-tests/src/it/java/software/amazon/encryption/s3/RoundTripTests.java b/test-server/java-tests/src/it/java/software/amazon/encryption/s3/RoundTripTests.java index cd67f2e0..8ae4f449 100644 --- a/test-server/java-tests/src/it/java/software/amazon/encryption/s3/RoundTripTests.java +++ b/test-server/java-tests/src/it/java/software/amazon/encryption/s3/RoundTripTests.java @@ -60,6 +60,7 @@ public class RoundTripTests { private static final String JAVA_V3 = "Java-V3"; private static final String PYTHON_V3 = "Python-V3"; private static final String GO_V3 = "Go-V3"; + private static final String GO_V3 = "Go-V4"; private static final String CPP_V2 = "CPP-V2"; private static final String NET_V2 = "NET-V2"; private static final String NET_V3 = "NET-V3"; @@ -85,6 +86,7 @@ public class RoundTripTests { servers.put(NET_V3, new LanguageServerTarget(NET_V3, "8084")); servers.put(CPP_V2, new LanguageServerTarget(CPP_V2, "8085")); servers.put(PHP_V2, new LanguageServerTarget(PHP_V2, "8087")); + servers.put(GO_V3, new LanguageServerTarget(GO_V4, "8089")); servers.put(PHP_V3, new LanguageServerTarget(PHP_V3, "8093")); servers.put(RUBY_V2, new LanguageServerTarget(RUBY_V2, "8086")); servers.put(RUBY_V3, new LanguageServerTarget(RUBY_V3, "8092")); From 2752ce0d68889e411ff6dddd2298fdb5cce7eedc Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Mon, 22 Sep 2025 13:45:23 -0700 Subject: [PATCH 09/22] m --- .../it/java/software/amazon/encryption/s3/RoundTripTests.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-server/java-tests/src/it/java/software/amazon/encryption/s3/RoundTripTests.java b/test-server/java-tests/src/it/java/software/amazon/encryption/s3/RoundTripTests.java index 8ae4f449..c8060aa7 100644 --- a/test-server/java-tests/src/it/java/software/amazon/encryption/s3/RoundTripTests.java +++ b/test-server/java-tests/src/it/java/software/amazon/encryption/s3/RoundTripTests.java @@ -60,7 +60,7 @@ public class RoundTripTests { private static final String JAVA_V3 = "Java-V3"; private static final String PYTHON_V3 = "Python-V3"; private static final String GO_V3 = "Go-V3"; - private static final String GO_V3 = "Go-V4"; + private static final String GO_V4 = "Go-V4"; private static final String CPP_V2 = "CPP-V2"; private static final String NET_V2 = "NET-V2"; private static final String NET_V3 = "NET-V3"; From fedd82ae20f0637264f8fcd6ff464ce9f4bdfe07 Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Tue, 23 Sep 2025 09:02:38 -0700 Subject: [PATCH 10/22] m --- .../it/java/software/amazon/encryption/s3/RoundTripTests.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-server/java-tests/src/it/java/software/amazon/encryption/s3/RoundTripTests.java b/test-server/java-tests/src/it/java/software/amazon/encryption/s3/RoundTripTests.java index c8060aa7..8b0ea5e6 100644 --- a/test-server/java-tests/src/it/java/software/amazon/encryption/s3/RoundTripTests.java +++ b/test-server/java-tests/src/it/java/software/amazon/encryption/s3/RoundTripTests.java @@ -86,7 +86,7 @@ public class RoundTripTests { servers.put(NET_V3, new LanguageServerTarget(NET_V3, "8084")); servers.put(CPP_V2, new LanguageServerTarget(CPP_V2, "8085")); servers.put(PHP_V2, new LanguageServerTarget(PHP_V2, "8087")); - servers.put(GO_V3, new LanguageServerTarget(GO_V4, "8089")); + servers.put(GO_V4, new LanguageServerTarget(GO_V4, "8089")); servers.put(PHP_V3, new LanguageServerTarget(PHP_V3, "8093")); servers.put(RUBY_V2, new LanguageServerTarget(RUBY_V2, "8086")); servers.put(RUBY_V3, new LanguageServerTarget(RUBY_V3, "8092")); From d49545f94531dd76e65155dc83941c011f66ad36 Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Wed, 24 Sep 2025 13:01:37 -0700 Subject: [PATCH 11/22] bump --- test-server/go-v4-server/local-go-s3ec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-server/go-v4-server/local-go-s3ec b/test-server/go-v4-server/local-go-s3ec index 87b83dbc..4223bd14 160000 --- a/test-server/go-v4-server/local-go-s3ec +++ b/test-server/go-v4-server/local-go-s3ec @@ -1 +1 @@ -Subproject commit 87b83dbcceca1f2678e52747fad2c253334c0c5d +Subproject commit 4223bd142c51ecf7f94c432c891f7a9b99a730a7 From 1827c03e26d041f4374911359795b5b9ebc8ae09 Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Wed, 24 Sep 2025 14:54:58 -0700 Subject: [PATCH 12/22] m --- test-server/go-v4-server/local-go-s3ec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-server/go-v4-server/local-go-s3ec b/test-server/go-v4-server/local-go-s3ec index 4223bd14..4e8ff419 160000 --- a/test-server/go-v4-server/local-go-s3ec +++ b/test-server/go-v4-server/local-go-s3ec @@ -1 +1 @@ -Subproject commit 4223bd142c51ecf7f94c432c891f7a9b99a730a7 +Subproject commit 4e8ff4196b86ff7a21461f586932f322af49310f From 27a95c266ade793e61595003b9d49382c911d0a8 Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Thu, 25 Sep 2025 09:57:43 -0700 Subject: [PATCH 13/22] m --- test-server/go-v4-server/main.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/test-server/go-v4-server/main.go b/test-server/go-v4-server/main.go index 47fbd9b7..a9a18d4e 100644 --- a/test-server/go-v4-server/main.go +++ b/test-server/go-v4-server/main.go @@ -234,7 +234,7 @@ func (s *Server) putObject(w http.ResponseWriter, r *http.Request) { } // Make the put object request using the encryption client - _, err = client.PutObject(encryptionContext, putInput) + result, err = client.PutObject(encryptionContext, putInput) if err != nil { s.createS3EncryptionClientError(w, fmt.Sprintf("Failed to put object: %v", err), http.StatusInternalServerError) return @@ -242,12 +242,20 @@ func (s *Server) putObject(w http.ResponseWriter, r *http.Request) { log.Printf("[Go V4] PutObject SUCCESS: Bucket=%s, Key=%s", bucket, key) + // Return an empty metadata list if result.Metadata is nil, not a list, or empty. + Metadata: func() []string { + if result.Metadata == nil || len(result.Metadata) == 0 { + return []string{} + } + return result.Metadata + }(), + // Return response w.Header().Set("Content-Type", "application/json") response := PutObjectOutput{ Bucket: bucket, Key: key, - Metadata: []string{}, // Return empty metadata list as per the model + Metadata: Metadata, } json.NewEncoder(w).Encode(response) } From a153963e64789182000dccbb00539b83dde4aabb Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Thu, 25 Sep 2025 14:34:25 -0700 Subject: [PATCH 14/22] m --- test-server/go-v4-server/main.go | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/test-server/go-v4-server/main.go b/test-server/go-v4-server/main.go index a9a18d4e..d22659eb 100644 --- a/test-server/go-v4-server/main.go +++ b/test-server/go-v4-server/main.go @@ -242,22 +242,20 @@ func (s *Server) putObject(w http.ResponseWriter, r *http.Request) { log.Printf("[Go V4] PutObject SUCCESS: Bucket=%s, Key=%s", bucket, key) - // Return an empty metadata list if result.Metadata is nil, not a list, or empty. - Metadata: func() []string { - if result.Metadata == nil || len(result.Metadata) == 0 { - return []string{} - } - return result.Metadata - }(), + // Empty metadata list if result.Metadata is nil or empty + md := result.Metadata + if md == nil { + md = []string{} + } // Return response w.Header().Set("Content-Type", "application/json") - response := PutObjectOutput{ + resp := PutObjectOutput{ Bucket: bucket, Key: key, - Metadata: Metadata, + Metadata: md, } - json.NewEncoder(w).Encode(response) + json.NewEncoder(w).Encode(resp) } // getObject handles GET /object/{bucket}/{key} From 7ceff2431533ec6822599995335af94a1d6b6f00 Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Fri, 26 Sep 2025 08:17:49 -0700 Subject: [PATCH 15/22] m --- test-server/go-v4-server/main.go | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/test-server/go-v4-server/main.go b/test-server/go-v4-server/main.go index d22659eb..1e3ef3ab 100644 --- a/test-server/go-v4-server/main.go +++ b/test-server/go-v4-server/main.go @@ -242,18 +242,12 @@ func (s *Server) putObject(w http.ResponseWriter, r *http.Request) { log.Printf("[Go V4] PutObject SUCCESS: Bucket=%s, Key=%s", bucket, key) - // Empty metadata list if result.Metadata is nil or empty - md := result.Metadata - if md == nil { - md = []string{} - } - // Return response w.Header().Set("Content-Type", "application/json") resp := PutObjectOutput{ Bucket: bucket, Key: key, - Metadata: md, + Metadata: []string{}, // TODO: pass metadata back in response } json.NewEncoder(w).Encode(resp) } From d9c8e66b8c035c0964470cdb6333c4801e400a60 Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Fri, 26 Sep 2025 09:23:13 -0700 Subject: [PATCH 16/22] m --- .../src/it/java/software/amazon/encryption/s3/TestUtils.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test-server/java-tests/src/it/java/software/amazon/encryption/s3/TestUtils.java b/test-server/java-tests/src/it/java/software/amazon/encryption/s3/TestUtils.java index 2e78d9e5..c348293d 100644 --- a/test-server/java-tests/src/it/java/software/amazon/encryption/s3/TestUtils.java +++ b/test-server/java-tests/src/it/java/software/amazon/encryption/s3/TestUtils.java @@ -34,6 +34,7 @@ public class TestUtils { public static final String JAVA_V3 = "Java-V3"; public static final String PYTHON_V3 = "Python-V3"; public static final String GO_V3 = "Go-V3"; + public static final String GO_V4 = "Go-V4"; public static final String CPP_V2 = "CPP-V2"; public static final String NET_V2 = "NET-V2"; public static final String NET_V3 = "NET-V3"; @@ -67,6 +68,7 @@ public class TestUtils { servers.put(NET_V3, new LanguageServerTarget(NET_V3, "8084")); servers.put(CPP_V2, new LanguageServerTarget(CPP_V2, "8085")); servers.put(PHP_V2, new LanguageServerTarget(PHP_V2, "8087")); + servers.put(GO_V4, new LanguageServerTarget(GO_V3, "8089")); servers.put(PHP_V3, new LanguageServerTarget(PHP_V3, "8093")); servers.put(RUBY_V2, new LanguageServerTarget(RUBY_V2, "8086")); servers.put(RUBY_V3, new LanguageServerTarget(RUBY_V3, "8092")); From 6924ddfc7c0fcc8e95b353e5d338157a6cf60723 Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Fri, 26 Sep 2025 13:01:53 -0700 Subject: [PATCH 17/22] m --- .gitmodules | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitmodules b/.gitmodules index e0bf53a1..f168410b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,9 +4,6 @@ [submodule "test-server/ruby-v3-server/local-ruby-sdk"] path = test-server/ruby-v3-server/local-ruby-sdk url = git@github.com:aws/aws-sdk-ruby-staging.git -[submodule "test-server/go-v4-server/local-go-s3ec"] - path = test-server/go-v4-server/local-go-s3ec - url = git@github.com:aws/private-amazon-s3-encryption-client-go-staging.git [submodule "test-server/php-v2-server/local-php-sdk"] path = test-server/php-v2-server/local-php-sdk url = git@github.com:aws/private-aws-sdk-php-staging.git @@ -15,3 +12,6 @@ path = test-server/php-v3-server/local-php-sdk url = git@github.com:aws/private-aws-sdk-php-staging.git branch = s3ec/improved +[submodule "test-server/go-v4-server/local-go-s3ec"] + path = test-server/go-v4-server/local-go-s3ec + url = https://github.com/aws/private-amazon-s3-encryption-client-go-staging From cf68cf4a0ffb6492b8b0297e798f4f39a1405dae Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Fri, 26 Sep 2025 14:33:16 -0700 Subject: [PATCH 18/22] m --- .github/workflows/test.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 390f003d..e64d4519 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -108,3 +108,9 @@ jobs: TEST_SERVER_S3_BUCKET: ${{ vars.TEST_SERVER_S3_BUCKET }} TEST_SERVER_KMS_KEY_ARN: ${{ vars.TEST_SERVER_KMS_KEY_ARN }} GRADLE_OPTS: "-Dorg.gradle.daemon=true -Dorg.gradle.parallel=true -Dorg.gradle.caching=true" + + - name: Upload results + uses: actions/upload-artifact@v4 + with: + name: results + path: test-server/java-tests/build/reports/tests/integ From a768bcf818a1dc2c3a5e6c48fde80e3ce3a73228 Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Mon, 29 Sep 2025 09:27:23 -0700 Subject: [PATCH 19/22] m --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e64d4519..76c4bbcc 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -110,6 +110,7 @@ jobs: GRADLE_OPTS: "-Dorg.gradle.daemon=true -Dorg.gradle.parallel=true -Dorg.gradle.caching=true" - name: Upload results + if: always() uses: actions/upload-artifact@v4 with: name: results From cc855cf8b12c1cd0462441eb04dca8d45236dd30 Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Mon, 29 Sep 2025 09:58:16 -0700 Subject: [PATCH 20/22] m --- test-server/go-v4-server/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-server/go-v4-server/main.go b/test-server/go-v4-server/main.go index 1e3ef3ab..75871d5f 100644 --- a/test-server/go-v4-server/main.go +++ b/test-server/go-v4-server/main.go @@ -234,7 +234,7 @@ func (s *Server) putObject(w http.ResponseWriter, r *http.Request) { } // Make the put object request using the encryption client - result, err = client.PutObject(encryptionContext, putInput) + _, err = client.PutObject(encryptionContext, putInput) if err != nil { s.createS3EncryptionClientError(w, fmt.Sprintf("Failed to put object: %v", err), http.StatusInternalServerError) return From 504e2ce7d33b3d4422ff160d8109dd9cd75cd658 Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Thu, 2 Oct 2025 12:02:35 -0700 Subject: [PATCH 21/22] m --- test-server/go-v4-server/local-go-s3ec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-server/go-v4-server/local-go-s3ec b/test-server/go-v4-server/local-go-s3ec index 4e8ff419..4c6578db 160000 --- a/test-server/go-v4-server/local-go-s3ec +++ b/test-server/go-v4-server/local-go-s3ec @@ -1 +1 @@ -Subproject commit 4e8ff4196b86ff7a21461f586932f322af49310f +Subproject commit 4c6578db98536d0c892eab4109cd70a320594aba From 983fe174bfec8b926c6bae9fe367526040c6dbc5 Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Thu, 2 Oct 2025 13:12:52 -0700 Subject: [PATCH 22/22] m --- test-server/go-v4-server/local-go-s3ec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-server/go-v4-server/local-go-s3ec b/test-server/go-v4-server/local-go-s3ec index 4c6578db..cbb8bc60 160000 --- a/test-server/go-v4-server/local-go-s3ec +++ b/test-server/go-v4-server/local-go-s3ec @@ -1 +1 @@ -Subproject commit 4c6578db98536d0c892eab4109cd70a320594aba +Subproject commit cbb8bc608754ae52f8063987d0570a7c5a927fa0