From b8c9535374e6b746d3e95251f2b3b6f58868e466 Mon Sep 17 00:00:00 2001 From: Kess Plasmeier Date: Thu, 30 Oct 2025 10:35:07 -0700 Subject: [PATCH 1/5] start adding examples of each major version --- .gitmodules | 3 + all-examples/README.md | 72 ++++++++ all-examples/cpp/v3/CMakeLists.txt | 21 +++ all-examples/cpp/v3/Makefile | 74 ++++++++ all-examples/cpp/v3/README.md | 136 ++++++++++++++ all-examples/cpp/v3/main.cpp | 112 ++++++++++++ .../dotnet/v2/S3EncryptionExample.csproj | 19 ++ .../dotnet/v3/S3EncryptionExample.csproj | 19 ++ .../dotnet/v4/S3EncryptionExample.csproj | 16 ++ all-examples/go/v3/go.mod | 11 ++ all-examples/go/v4/go.mod | 15 ++ all-examples/java/v3/build.gradle.kts | 27 +++ all-examples/java/v4/build.gradle.kts | 28 +++ all-examples/php/v2/composer.json | 30 ++++ all-examples/php/v3/composer.json | 30 ++++ all-examples/ruby/v2/Gemfile | 12 ++ all-examples/ruby/v2/Gemfile.lock | 82 +++++++++ all-examples/ruby/v2/Makefile | 70 ++++++++ all-examples/ruby/v2/local-ruby-sdk | 1 + all-examples/ruby/v2/main.rb | 168 ++++++++++++++++++ all-examples/ruby/v3/Gemfile | 11 ++ 21 files changed, 957 insertions(+) create mode 100644 all-examples/README.md create mode 100644 all-examples/cpp/v3/CMakeLists.txt create mode 100644 all-examples/cpp/v3/Makefile create mode 100644 all-examples/cpp/v3/README.md create mode 100644 all-examples/cpp/v3/main.cpp create mode 100644 all-examples/dotnet/v2/S3EncryptionExample.csproj create mode 100644 all-examples/dotnet/v3/S3EncryptionExample.csproj create mode 100644 all-examples/dotnet/v4/S3EncryptionExample.csproj create mode 100644 all-examples/go/v3/go.mod create mode 100644 all-examples/go/v4/go.mod create mode 100644 all-examples/java/v3/build.gradle.kts create mode 100644 all-examples/java/v4/build.gradle.kts create mode 100644 all-examples/php/v2/composer.json create mode 100644 all-examples/php/v3/composer.json create mode 100644 all-examples/ruby/v2/Gemfile create mode 100644 all-examples/ruby/v2/Gemfile.lock create mode 100644 all-examples/ruby/v2/Makefile create mode 160000 all-examples/ruby/v2/local-ruby-sdk create mode 100644 all-examples/ruby/v2/main.rb create mode 100644 all-examples/ruby/v3/Gemfile diff --git a/.gitmodules b/.gitmodules index 0bf186eb..7cb8cc1b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -39,3 +39,6 @@ path = test-server/net-v2-v3-server/s3ec-net-v3 url = https://github.com/aws/private-amazon-s3-encryption-client-dotnet-staging.git branch = s3ec-v3 +[submodule "all-examples/ruby/v2/local-ruby-sdk"] + path = all-examples/ruby/v2/local-ruby-sdk + url = git@github.com:aws/aws-sdk-ruby-staging.git diff --git a/all-examples/README.md b/all-examples/README.md new file mode 100644 index 00000000..9f8aba4c --- /dev/null +++ b/all-examples/README.md @@ -0,0 +1,72 @@ +# S3 Encryption Client Examples + +This directory contains example projects for the Amazon S3 Encryption Client across different programming languages and major versions. + +## Directory Structure + +Each language has subdirectories for different major versions of the S3 Encryption Client: + +- `cpp/` - C++ examples + - `v2/` - S3EC C++ v2 example + - `v3/` - S3EC C++ v3 example +- `dotnet/` - .NET examples + - `v2/` - S3EC .NET v2 example + - `v3/` - S3EC .NET v3 example + - `v4/` - S3EC .NET v4 example +- `go/` - Go examples + - `v3/` - S3EC Go v3 example + - `v4/` - S3EC Go v4 example +- `java/` - Java examples + - `v3/` - S3EC Java v3 example + - `v4/` - S3EC Java v4 example +- `php/` - PHP examples + - `v2/` - S3EC PHP v2 example + - `v3/` - S3EC PHP v3 example +- `ruby/` - Ruby examples + - `v2/` - S3EC Ruby v2 example + - `v3/` - S3EC Ruby v3 example + +## Setup Instructions + +### Prerequisites + +1. **Git Submodules**: Some examples depend on staging versions of the S3EC libraries that are included as git submodules. Initialize and update submodules: + ```bash + git submodule update --init --recursive + ``` + +2. **AWS Credentials**: Configure your AWS credentials using one of the following methods: + - AWS CLI: `aws configure` + - Environment variables: `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` + - IAM roles (for EC2 instances) + +3. **KMS Key**: Use "arn:aws:kms:us-east-2:648638458147:key/a47079da-17e4-45a5-b82e-2bac101cad01" by default, or create a KMS key in your AWS account and note the key ID for use in examples. + +### Language-Specific Setup + +Each language directory contains specific setup instructions in its README file. Generally: + +- **Java**: Requires JDK 11+ and Gradle +- **Go**: Requires Go 1.21+ +- **.NET**: Requires .NET 8.0+ +- **PHP**: Requires PHP 7.4+ and Composer +- **Ruby**: Requires Ruby 3.0+ and Bundler +- **C++**: Requires CMake 3.16+ and C++17 compiler + +## Usage + +Each example directory contains: +- Build configuration files (e.g., `build.gradle.kts`, `go.mod`, `composer.json`) +- Source code demonstrating basic S3EC usage +- README with specific setup and run instructions + +## Dependencies + +Examples use different dependency sources based on version: +- **Released versions**: Use public package repositories (Maven Central, npm, etc.) +- **Staging versions**: Use git submodules pointing to staging repositories +- **Local versions**: Reference locally built libraries + +## Support + +For issues with specific examples, refer to the individual README files in each language/version directory. diff --git a/all-examples/cpp/v3/CMakeLists.txt b/all-examples/cpp/v3/CMakeLists.txt new file mode 100644 index 00000000..9d9e696c --- /dev/null +++ b/all-examples/cpp/v3/CMakeLists.txt @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 3.16) +project(s3ec-cpp-v3-example) + +set(CMAKE_CXX_STANDARD 17) + +# Find AWS SDK for C++ +# Note: S3 Encryption Client is not part of standard AWS SDK +# This example demonstrates the concept but requires the full S3EC library +find_package(AWSSDK REQUIRED COMPONENTS core kms) + +add_executable(s3ec-example main.cpp) + +target_link_libraries(s3ec-example + ${AWSSDK_LINK_LIBRARIES} +) + +# Add include directories for AWS SDK +target_include_directories(s3ec-example PRIVATE ${AWSSDK_INCLUDE_DIRS}) + +# Set compiler flags +target_compile_features(s3ec-example PRIVATE cxx_std_17) diff --git a/all-examples/cpp/v3/Makefile b/all-examples/cpp/v3/Makefile new file mode 100644 index 00000000..d78d6a1b --- /dev/null +++ b/all-examples/cpp/v3/Makefile @@ -0,0 +1,74 @@ +# Makefile for S3 Encryption Client C++ v3 Example + +# Default target +.PHONY: all build clean run help + +# Variables +BUILD_DIR = build +EXECUTABLE = $(BUILD_DIR)/s3ec-example + +# Default arguments for running the example +# Override these when calling make run +BUCKET_NAME ?= avp-21638 +OBJECT_KEY ?= s3ec-cpp-v3 +KMS_KEY_ID ?= arn:aws:kms:us-east-2:648638458147:key/a47079da-17e4-45a5-b82e-2bac101cad01 +AWS_REGION ?= us-east-2 + +all: build + +# Build the project using CMake +build: + @echo "Building S3 Encryption Client v3 example..." + @mkdir -p $(BUILD_DIR) + @cd $(BUILD_DIR) && cmake .. && make + @echo "Build completed successfully!" + +# Clean build artifacts +clean: + @echo "Cleaning build artifacts..." + @rm -rf $(BUILD_DIR) + @echo "Clean completed!" + +# Run the example with default or provided arguments +run: build + @echo "Running S3 Encryption Client v3 example..." + @echo "Bucket: $(BUCKET_NAME)" + @echo "Object Key: $(OBJECT_KEY)" + @echo "KMS Key ID: $(KMS_KEY_ID)" + @echo "" + @$(EXECUTABLE) $(BUCKET_NAME) $(OBJECT_KEY) $(KMS_KEY_ID) + +# Run with custom arguments +# Usage: make run-custom BUCKET_NAME=my-bucket OBJECT_KEY=my-key KMS_KEY_ID=my-kms-key +run-custom: build + @$(EXECUTABLE) $(BUCKET_NAME) $(OBJECT_KEY) $(KMS_KEY_ID) + +# Show help +help: + @echo "S3 Encryption Client C++ v3 Example Makefile" + @echo "" + @echo "Available targets:" + @echo " build - Build the example using CMake" + @echo " run - Build and run the example with default parameters" + @echo " run-custom - Build and run with custom parameters" + @echo " clean - Remove build artifacts" + @echo " help - Show this help message" + @echo "" + @echo "Default parameters:" + @echo " BUCKET_NAME = $(BUCKET_NAME)" + @echo " OBJECT_KEY = $(OBJECT_KEY)" + @echo " KMS_KEY_ID = $(KMS_KEY_ID)" + @echo "" + @echo "To run with custom parameters:" + @echo " make run BUCKET_NAME=your-bucket OBJECT_KEY=your-key KMS_KEY_ID=your-kms-key" + @echo "" + @echo "Prerequisites:" + @echo " - AWS SDK for C++ must be installed on the system" + @echo " - AWS credentials configured (AWS CLI, environment variables, or IAM role)" + @echo " - CMake 3.16+ and C++17 compatible compiler" + @echo " - Valid S3 bucket and KMS key" + @echo "" + @echo "Version differences:" + @echo " - v3 uses enhanced security profiles and stricter validation" + @echo " - v3 may have different API patterns compared to v2" + @echo " - v3 focuses on modern cryptographic standards" diff --git a/all-examples/cpp/v3/README.md b/all-examples/cpp/v3/README.md new file mode 100644 index 00000000..7ad493bb --- /dev/null +++ b/all-examples/cpp/v3/README.md @@ -0,0 +1,136 @@ +# S3 Encryption Client C++ v3 Example + +This example demonstrates the enhanced KMS integration pattern used by the Amazon S3 Encryption Client for C++ v3. It shows how S3EC v3 generates data keys from KMS with enhanced encryption context and security profiles, which is the foundation of client-side encryption with improved security. + +**Note**: This is a demonstration example that shows the KMS workflow with v3 enhancements. For the complete S3 encryption client functionality, you need the full S3EC library from https://github.com/aws/amazon-s3-encryption-client-cpp + +## Prerequisites + +1. **AWS SDK for C++**: The AWS SDK for C++ must be installed on your system. You can install it via: + - Package manager (e.g., `brew install aws-sdk-cpp` on macOS, `apt-get install libaws-cpp-sdk-dev` on Ubuntu) + - Build from source: https://github.com/aws/aws-sdk-cpp + - vcpkg: `vcpkg install aws-sdk-cpp[kms,s3,s3-encryption]` +2. **AWS Credentials**: Configure your AWS credentials using one of these methods: + - AWS CLI: `aws configure` + - Environment variables: `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` + - IAM roles (for EC2 instances) +3. **KMS Key**: Create a KMS key in your AWS account and note the key ID/ARN +4. **S3 Bucket**: Create an S3 bucket for testing +5. **Build Tools**: + - CMake 3.16 or later + - C++17 compatible compiler (GCC, Clang, or MSVC) + +## Building + +Use the provided Makefile to build the example: + +```bash +make build +``` + +This will: +1. Create a `build` directory +2. Run CMake to configure the project +3. Compile the example + +## Running + +### Quick Start + +Run with default parameters (you'll need to update these): + +```bash +make run BUCKET_NAME=avp-21638 OBJECT_KEY=s3ec-cpp-v3 KMS_KEY_ID=arn:aws:kms:us-east-2:648638458147:key/a47079da-17e4-45a5-b82e-2bac101cad01 +``` + +### Available Make Targets + +- `make build` - Build the example +- `make run` - Build and run with parameters +- `make clean` - Remove build artifacts +- `make help` - Show help information + +### Direct Execution + +After building, you can also run the executable directly: + +```bash +./build/s3ec-example +``` + +## Example Usage + +```bash +make run BUCKET_NAME=my-test-bucket OBJECT_KEY=example.txt KMS_KEY_ID=arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012 +``` + +## What the Example Does + +1. **Initialize**: Sets up the AWS SDK and creates an S3 encryption client with KMS materials +2. **Encrypt & Upload**: Encrypts a test message and uploads it to S3 with encryption context +3. **Download & Decrypt**: Downloads the encrypted object and decrypts it with context validation +4. **Verify**: Compares the original and decrypted data to ensure they match + +## Key Features Demonstrated + +- **KMS Integration**: Uses AWS KMS for key management with enhanced security +- **Encryption Context**: Demonstrates using encryption context with stricter validation +- **Modern Security**: Uses v3's enhanced security profiles +- **Error Handling**: Shows proper error handling for S3 operations +- **Resource Management**: Proper initialization and cleanup of AWS SDK + +## Security Profile + +This v3 example uses the modern security profile (V2), which: +- Enforces authenticated encryption modes +- Uses stronger cryptographic standards +- Provides stricter validation of encryption context +- Focuses on security best practices + +## Version Differences from v2 + +The v3 client provides several enhancements over v2: +- **Enhanced Security**: Stricter security profiles and validation +- **Modern Cryptography**: Focus on current cryptographic standards +- **Better Error Handling**: More detailed error messages and validation +- **Improved API**: Cleaner and more consistent API patterns + +## Troubleshooting + +### Common Issues + +1. **Build Errors**: Ensure AWS SDK for C++ is properly configured and available +2. **Runtime Errors**: Check AWS credentials and permissions +3. **KMS Errors**: Verify the KMS key exists and you have permissions to use it +4. **S3 Errors**: Ensure the bucket exists and you have read/write permissions +5. **Security Profile Errors**: v3 may reject operations that v2 would allow for security reasons + +### Required Permissions + +Your AWS credentials need the following permissions: +- `s3:GetObject` and `s3:PutObject` on the target bucket +- `kms:Encrypt`, `kms:Decrypt`, and `kms:GenerateDataKey` on the KMS key + +### Migration from v2 + +If migrating from v2: +- Review security profile settings - v3 defaults to stricter security +- Test encryption context validation - v3 may be more strict +- Update error handling for new error types +- Consider the enhanced security features + +## Version Notes + +This is the v3 version of the S3 Encryption Client, which provides: +- Enhanced security profiles with stricter validation +- Modern cryptographic standards +- Improved API consistency +- Better error reporting and debugging capabilities + +## Security Considerations + +v3 emphasizes security best practices: +- Always use encryption context for additional security +- Prefer authenticated encryption modes +- Use the latest cryptographic algorithms +- Validate all inputs and outputs diff --git a/all-examples/cpp/v3/main.cpp b/all-examples/cpp/v3/main.cpp new file mode 100644 index 00000000..412fde66 --- /dev/null +++ b/all-examples/cpp/v3/main.cpp @@ -0,0 +1,112 @@ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +int main(int argc, char* argv[]) { + // Check command line arguments + if (argc != 4) { + std::cerr << "Usage: " << argv[0] << " " << std::endl; + std::cerr << "Example: " << argv[0] << " avp-21638 s3ec-cpp-v3 arn:aws:kms:us-east-2:648638458147:key/a47079da-17e4-45a5-b82e-2bac101cad01" << std::endl; + return 1; + } + + std::string bucketName = argv[1]; + std::string objectKey = argv[2]; + std::string kmsKeyId = argv[3]; + + // Initialize AWS SDK + Aws::SDKOptions options; + Aws::InitAPI(options); + + try { + std::cout << "=== S3 Encryption Client v3 Example (Demonstration) ===" << std::endl; + std::cout << "Bucket: " << bucketName << std::endl; + std::cout << "Object Key: " << objectKey << std::endl; + std::cout << "KMS Key ID: " << kmsKeyId << std::endl << std::endl; + + // Set default region + Aws::Client::ClientConfiguration clientConfig; + clientConfig.region = "us-east-2"; + + // Create KMS client to demonstrate key operations + Aws::KMS::KMSClient kmsClient(clientConfig); + + // Test data that would be encrypted + std::string testData = "Hello, World! This is a test message for S3 encryption client v3."; + std::cout << "Original data: " << testData << std::endl; + + std::cout << "\n--- Demonstrating KMS Data Key Generation (v3 Enhanced) ---" << std::endl; + + // Generate a data key using KMS (this is what S3EC would do internally) + Aws::KMS::Model::GenerateDataKeyRequest dataKeyRequest; + dataKeyRequest.SetKeyId(kmsKeyId); + dataKeyRequest.SetKeySpec(Aws::KMS::Model::DataKeySpec::AES_256); + + // Add encryption context (v3 uses more comprehensive context) + Aws::Map encryptionContext; + encryptionContext["purpose"] = "example"; + encryptionContext["version"] = "v3"; + encryptionContext["client"] = "cpp"; + encryptionContext["bucket"] = bucketName; + encryptionContext["key"] = objectKey; + encryptionContext["security-profile"] = "v2"; // v3 uses enhanced security + dataKeyRequest.SetEncryptionContext(encryptionContext); + + auto dataKeyOutcome = kmsClient.GenerateDataKey(dataKeyRequest); + + if (dataKeyOutcome.IsSuccess()) { + std::cout << "āœ… Successfully generated data key from KMS!" << std::endl; + std::cout << "Key ID: " << kmsKeyId << std::endl; + std::cout << "Encryption context includes (v3 enhanced):" << std::endl; + for (const auto& pair : encryptionContext) { + std::cout << " " << pair.first << " = " << pair.second << std::endl; + } + + // In a real S3EC v3 implementation, this data key would be used with enhanced security + std::cout << "\n--- S3 Encryption Client v3 Workflow (Enhanced Security) ---" << std::endl; + std::cout << "1. āœ… Generate data key from KMS with enhanced context (completed above)" << std::endl; + std::cout << "2. šŸ”„ Use authenticated encryption for object data (requires S3EC v3 library)" << std::endl; + std::cout << "3. šŸ”„ Store encrypted data key with strict validation (requires S3EC v3 library)" << std::endl; + std::cout << "4. šŸ”„ Upload encrypted object with enhanced metadata (requires S3EC v3 library)" << std::endl; + std::cout << "5. šŸ”„ Download encrypted object with validation (requires S3EC v3 library)" << std::endl; + std::cout << "6. šŸ”„ Validate encryption context strictly (requires S3EC v3 library)" << std::endl; + std::cout << "7. šŸ”„ Decrypt data key with context validation (requires S3EC v3 library)" << std::endl; + std::cout << "8. šŸ”„ Decrypt object data with authenticated decryption (requires S3EC v3 library)" << std::endl; + + std::cout << "\n--- v3 Security Enhancements ---" << std::endl; + std::cout << "šŸ”’ Enhanced Security Profile: Enforces authenticated encryption modes" << std::endl; + std::cout << "šŸ”’ Stricter Validation: More rigorous encryption context validation" << std::endl; + std::cout << "šŸ”’ Modern Cryptography: Uses latest cryptographic standards" << std::endl; + std::cout << "šŸ”’ Better Error Handling: More detailed error messages and validation" << std::endl; + + } else { + std::cerr << "āŒ Failed to generate data key: " << dataKeyOutcome.GetError().GetMessage() << std::endl; + Aws::ShutdownAPI(options); + return 1; + } + + std::cout << "\n=== Example completed successfully! ===" << std::endl; + std::cout << "\nšŸ“ NOTE: This example demonstrates the enhanced KMS integration that S3EC v3 uses." << std::endl; + std::cout << "v3 provides stricter security profiles and enhanced validation compared to v2." << std::endl; + std::cout << "To run the full S3 encryption client, you need to install the complete" << std::endl; + std::cout << "Amazon S3 Encryption Client library, which is not part of the standard AWS SDK." << std::endl; + std::cout << "\nFor the complete S3EC library, visit:" << std::endl; + std::cout << "https://github.com/aws/amazon-s3-encryption-client-cpp" << std::endl; + + } catch (const std::exception& e) { + std::cerr << "Exception occurred: " << e.what() << std::endl; + Aws::ShutdownAPI(options); + return 1; + } + + // Shutdown AWS SDK + Aws::ShutdownAPI(options); + return 0; +} diff --git a/all-examples/dotnet/v2/S3EncryptionExample.csproj b/all-examples/dotnet/v2/S3EncryptionExample.csproj new file mode 100644 index 00000000..9fd91363 --- /dev/null +++ b/all-examples/dotnet/v2/S3EncryptionExample.csproj @@ -0,0 +1,19 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + + + + + + diff --git a/all-examples/dotnet/v3/S3EncryptionExample.csproj b/all-examples/dotnet/v3/S3EncryptionExample.csproj new file mode 100644 index 00000000..845a6cd1 --- /dev/null +++ b/all-examples/dotnet/v3/S3EncryptionExample.csproj @@ -0,0 +1,19 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + + + + + + diff --git a/all-examples/dotnet/v4/S3EncryptionExample.csproj b/all-examples/dotnet/v4/S3EncryptionExample.csproj new file mode 100644 index 00000000..e0933854 --- /dev/null +++ b/all-examples/dotnet/v4/S3EncryptionExample.csproj @@ -0,0 +1,16 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + + + diff --git a/all-examples/go/v3/go.mod b/all-examples/go/v3/go.mod new file mode 100644 index 00000000..74c9c05d --- /dev/null +++ b/all-examples/go/v3/go.mod @@ -0,0 +1,11 @@ +module github.com/aws/amazon-s3-encryption-client-python/all-examples/go/v3 + +go 1.21 + +require ( + github.com/aws/amazon-s3-encryption-client-go/v3 v3.1.1 + 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 +) diff --git a/all-examples/go/v4/go.mod b/all-examples/go/v4/go.mod new file mode 100644 index 00000000..fb5365b6 --- /dev/null +++ b/all-examples/go/v4/go.mod @@ -0,0 +1,15 @@ +module github.com/aws/amazon-s3-encryption-client-python/all-examples/go/v4 + +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 +) + +// 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/all-examples/java/v3/build.gradle.kts b/all-examples/java/v3/build.gradle.kts new file mode 100644 index 00000000..498ef757 --- /dev/null +++ b/all-examples/java/v3/build.gradle.kts @@ -0,0 +1,27 @@ +plugins { + `java-library` + application +} + +dependencies { + // S3 Encryption Client Java v3 + implementation("software.amazon.encryption.s3:amazon-s3-encryption-client-java:3.5.0") + + // AWS SDK dependencies + implementation("software.amazon.awssdk:s3:2.31.66") + implementation("software.amazon.awssdk:kms:2.31.66") + implementation("software.amazon.awssdk:core:2.31.66") +} + +application { + mainClass = "com.example.S3EncryptionExample" +} + +repositories { + mavenCentral() +} + +java { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 +} diff --git a/all-examples/java/v4/build.gradle.kts b/all-examples/java/v4/build.gradle.kts new file mode 100644 index 00000000..33ea0238 --- /dev/null +++ b/all-examples/java/v4/build.gradle.kts @@ -0,0 +1,28 @@ +plugins { + `java-library` + application +} + +dependencies { + // S3 Encryption Client Java v4 from local staging repository + implementation("software.amazon.encryption.s3:amazon-s3-encryption-client-java:3.4.0-IMPROVED") + + // AWS SDK dependencies + implementation("software.amazon.awssdk:s3:2.31.66") + implementation("software.amazon.awssdk:kms:2.31.66") + implementation("software.amazon.awssdk:core:2.31.66") +} + +application { + mainClass = "com.example.S3EncryptionExample" +} + +repositories { + mavenLocal() + mavenCentral() +} + +java { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 +} diff --git a/all-examples/php/v2/composer.json b/all-examples/php/v2/composer.json new file mode 100644 index 00000000..ec32702b --- /dev/null +++ b/all-examples/php/v2/composer.json @@ -0,0 +1,30 @@ +{ + "name": "aws/s3ec-php-v2-example", + "description": "PHP v2 S3 Encryption Client example", + "type": "project", + "license": "Apache-2.0", + "repositories": [ + { + "type": "path", + "url": "./local-php-sdk", + "options": { + "symlink": true + } + } + ], + "require": { + "php": ">=7.4", + "aws/aws-sdk-php": "@dev" + }, + "autoload": { + "psr-4": { + "S3EC\\PhpV2Example\\": "src/" + } + }, + "config": { + "optimize-autoloader": true, + "platform": { + "php": "8.1" + } + } +} diff --git a/all-examples/php/v3/composer.json b/all-examples/php/v3/composer.json new file mode 100644 index 00000000..a535ee38 --- /dev/null +++ b/all-examples/php/v3/composer.json @@ -0,0 +1,30 @@ +{ + "name": "aws/s3ec-php-v3-example", + "description": "PHP v3 S3 Encryption Client example", + "type": "project", + "license": "Apache-2.0", + "repositories": [ + { + "type": "path", + "url": "./local-php-sdk", + "options": { + "symlink": true + } + } + ], + "require": { + "php": ">=7.4", + "aws/aws-sdk-php": "@dev" + }, + "autoload": { + "psr-4": { + "S3EC\\PhpV3Example\\": "src/" + } + }, + "config": { + "optimize-autoloader": true, + "platform": { + "php": "8.1" + } + } +} diff --git a/all-examples/ruby/v2/Gemfile b/all-examples/ruby/v2/Gemfile new file mode 100644 index 00000000..5f51bf18 --- /dev/null +++ b/all-examples/ruby/v2/Gemfile @@ -0,0 +1,12 @@ +source 'https://rubygems.org' + +ruby '>= 2.7.0' + +gem 'aws-sdk-s3', path: 'local-ruby-sdk/gems/aws-sdk-s3' +gem 'aws-sdk-kms', path: 'local-ruby-sdk/gems/aws-sdk-kms' +gem 'json', '~> 2.0' +gem 'rexml', '~> 3.0' + +group :development do + gem 'rubocop', '~> 1.0' +end diff --git a/all-examples/ruby/v2/Gemfile.lock b/all-examples/ruby/v2/Gemfile.lock new file mode 100644 index 00000000..7c4a32c4 --- /dev/null +++ b/all-examples/ruby/v2/Gemfile.lock @@ -0,0 +1,82 @@ +PATH + remote: local-ruby-sdk/gems/aws-sdk-kms + specs: + aws-sdk-kms (1.115.0) + aws-sdk-core (~> 3, >= 3.234.0) + aws-sigv4 (~> 1.5) + +PATH + remote: local-ruby-sdk/gems/aws-sdk-s3 + specs: + aws-sdk-s3 (1.201.0) + aws-sdk-core (~> 3, >= 3.234.0) + aws-sdk-kms (~> 1) + aws-sigv4 (~> 1.5) + +GEM + remote: https://rubygems.org/ + specs: + ast (2.4.3) + aws-eventstream (1.4.0) + aws-partitions (1.1177.0) + aws-sdk-core (3.235.0) + aws-eventstream (~> 1, >= 1.3.0) + aws-partitions (~> 1, >= 1.992.0) + aws-sigv4 (~> 1.9) + base64 + bigdecimal + jmespath (~> 1, >= 1.6.1) + logger + aws-sigv4 (1.12.1) + aws-eventstream (~> 1, >= 1.0.2) + base64 (0.3.0) + bigdecimal (3.3.1) + jmespath (1.6.2) + json (2.15.2) + language_server-protocol (3.17.0.5) + lint_roller (1.1.0) + logger (1.7.0) + parallel (1.27.0) + parser (3.3.10.0) + ast (~> 2.4.1) + racc + prism (1.6.0) + racc (1.8.1) + rainbow (3.1.1) + regexp_parser (2.11.3) + rexml (3.4.4) + rubocop (1.81.6) + json (~> 2.3) + language_server-protocol (~> 3.17.0.2) + lint_roller (~> 1.1.0) + parallel (~> 1.10) + parser (>= 3.3.0.2) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 2.9.3, < 3.0) + rubocop-ast (>= 1.47.1, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 2.4.0, < 4.0) + rubocop-ast (1.47.1) + parser (>= 3.3.7.2) + prism (~> 1.4) + ruby-progressbar (1.13.0) + unicode-display_width (3.2.0) + unicode-emoji (~> 4.1) + unicode-emoji (4.1.0) + +PLATFORMS + arm64-darwin-24 + ruby + +DEPENDENCIES + aws-sdk-kms! + aws-sdk-s3! + json (~> 2.0) + rexml (~> 3.0) + rubocop (~> 1.0) + +RUBY VERSION + ruby 3.4.7p58 + +BUNDLED WITH + 2.7.2 diff --git a/all-examples/ruby/v2/Makefile b/all-examples/ruby/v2/Makefile new file mode 100644 index 00000000..cfa1adef --- /dev/null +++ b/all-examples/ruby/v2/Makefile @@ -0,0 +1,70 @@ +# Makefile for S3 Encryption Client Ruby v2 Example + +# Default target +.PHONY: all install clean run help + +# Variables +SCRIPT = main.rb + +# Default arguments for running the example +# Override these when calling make run +BUCKET_NAME ?= avp-21638 +OBJECT_KEY ?= s3ec-ruby-v2 +KMS_KEY_ID ?= arn:aws:kms:us-east-2:648638458147:key/a47079da-17e4-45a5-b82e-2bac101cad01 +AWS_REGION ?= us-east-2 + +all: install + +# Install dependencies using Bundler +install: + @echo "Installing Ruby dependencies..." + @bundle install + @echo "Dependencies installed successfully!" + +# Clean bundle artifacts +clean: + @echo "Cleaning bundle artifacts..." + @bundle clean --force + @echo "Clean completed!" + +# Run the example with default arguments +run: install + @echo "Running S3 Encryption Client v2 Ruby example..." + @echo "Bucket: $(BUCKET_NAME)" + @echo "Object Key: $(OBJECT_KEY)" + @echo "KMS Key ID: $(KMS_KEY_ID)" + @echo "Region: $(AWS_REGION)" + @echo "" + @bundle exec ruby $(SCRIPT) $(BUCKET_NAME) $(OBJECT_KEY) $(KMS_KEY_ID) $(AWS_REGION) + +# Run with custom arguments +# Usage: make run-custom BUCKET_NAME=my-bucket OBJECT_KEY=my-key KMS_KEY_ID=my-kms-key AWS_REGION=my-region +run-custom: install + @bundle exec ruby $(SCRIPT) $(BUCKET_NAME) $(OBJECT_KEY) $(KMS_KEY_ID) $(AWS_REGION) + +# Show help +help: + @echo "S3 Encryption Client Ruby v2 Example Makefile" + @echo "" + @echo "Available targets:" + @echo " install - Install Ruby dependencies using Bundler" + @echo " run - Install dependencies and run the example with default parameters" + @echo " run-custom - Install dependencies and run with custom parameters" + @echo " clean - Remove bundle artifacts" + @echo " help - Show this help message" + @echo "" + @echo "Default parameters:" + @echo " BUCKET_NAME = $(BUCKET_NAME)" + @echo " OBJECT_KEY = $(OBJECT_KEY)" + @echo " KMS_KEY_ID = $(KMS_KEY_ID)" + @echo " AWS_REGION = $(AWS_REGION)" + @echo "" + @echo "To run with custom parameters:" + @echo " make run BUCKET_NAME=your-bucket OBJECT_KEY=your-key KMS_KEY_ID=your-kms-key AWS_REGION=your-region" + @echo "" + @echo "Prerequisites:" + @echo " - Ruby 3.0+ installed on the system" + @echo " - Bundler gem installed (gem install bundler)" + @echo " - AWS credentials configured (AWS CLI, environment variables, or IAM role)" + @echo " - Valid S3 bucket and KMS key with appropriate permissions" + @echo " - S3 Encryption Client v2 Ruby SDK (included in local-ruby-sdk)" diff --git a/all-examples/ruby/v2/local-ruby-sdk b/all-examples/ruby/v2/local-ruby-sdk new file mode 160000 index 00000000..63e4accf --- /dev/null +++ b/all-examples/ruby/v2/local-ruby-sdk @@ -0,0 +1 @@ +Subproject commit 63e4accfeecf018f8590fd1e22ad64ff58cedf03 diff --git a/all-examples/ruby/v2/main.rb b/all-examples/ruby/v2/main.rb new file mode 100644 index 00000000..ce2e2641 --- /dev/null +++ b/all-examples/ruby/v2/main.rb @@ -0,0 +1,168 @@ +#!/usr/bin/env ruby + +require 'aws-sdk-s3' +require 'aws-sdk-kms' +require 'json' + +def main + # Check command line arguments + if ARGV.length != 4 + puts "Usage: #{$0} " + puts "Example: #{$0} avp-21638 s3ec-ruby-v2 arn:aws:kms:us-east-2:648638458147:key/a47079da-17e4-45a5-b82e-2bac101cad01 us-east-2" + exit 1 + end + + bucket_name = ARGV[0] + object_key = ARGV[1] + kms_key_id = ARGV[2] + region = ARGV[3] + + puts "=== S3 Encryption Client v2 Example (Ruby) ===" + puts "Bucket: #{bucket_name}" + puts "Object Key: #{object_key}" + puts "KMS Key ID: #{kms_key_id}" + puts "Region: #{region}" + puts + + begin + # Test data for encryption + test_data = "Hello, World! This is a test message for S3 encryption client v2 in Ruby." + puts "Original data: #{test_data}" + puts "Data length: #{test_data.length} bytes" + puts + + puts "--- Step 1: Initialize S3 Encryption Client v2 ---" + + # Create regular S3 client + s3_client = Aws::S3::Client.new(region: region) + + # Create KMS client + kms_client = Aws::KMS::Client.new(region: region) + + # Create S3 Encryption Client v2 + encryption_client = Aws::S3::EncryptionV2::Client.new( + client: s3_client, + kms_key_id: kms_key_id, + kms_client: kms_client, + key_wrap_schema: :kms_context, + content_encryption_schema: :aes_gcm_no_padding, + security_profile: :v2 + ) + + puts "āœ… Successfully initialized S3 Encryption Client v2" + puts " KMS Key ID: #{kms_key_id}" + puts " Key Wrap Schema: kms_context" + puts " Content Encryption Schema: aes_gcm_no_padding" + puts " Security Profile: v2" + puts + + puts "--- Step 2: Encrypt and Upload Object to S3 ---" + + # Optional: Add encryption context for additional security + encryption_context = { + 'purpose' => 'example', + 'version' => 'v2', + 'language' => 'ruby' + } + + # Upload encrypted object using S3 Encryption Client + put_response = encryption_client.put_object({ + bucket: bucket_name, + key: object_key, + body: test_data, + kms_encryption_context: encryption_context + }) + + puts "āœ… Successfully uploaded encrypted object to S3!" + puts " Bucket: #{bucket_name}" + puts " Key: #{object_key}" + puts " ETag: #{put_response.etag}" + puts " Encryption Context: #{encryption_context}" + puts + + puts "--- Step 3: Download and Decrypt Object from S3 ---" + + # Download and decrypt object using S3 Encryption Client + get_response = encryption_client.get_object({ + bucket: bucket_name, + key: object_key, + kms_encryption_context: encryption_context + }) + + # Read the decrypted data + decrypted_data = get_response.body.read + + puts "āœ… Successfully downloaded and decrypted object from S3!" + puts " Object size: #{decrypted_data.length} bytes" + puts " Decrypted data: #{decrypted_data}" + puts + + puts "--- Step 4: Verify Roundtrip Success ---" + + # Verify the roundtrip was successful + if decrypted_data == test_data + puts "šŸŽ‰ SUCCESS: Roundtrip encryption/decryption completed successfully!" + puts " āœ… Original data matches decrypted data" + puts " āœ… Data integrity verified" + else + puts "āŒ ERROR: Roundtrip failed - data mismatch" + puts " Original: #{test_data}" + puts " Decrypted: #{decrypted_data}" + exit 1 + end + + puts + + puts "--- Step 5: Cleanup ---" + + # Clean up the test object using regular S3 client + # s3_client.delete_object({ + # bucket: bucket_name, + # key: object_key + # }) + + puts "āœ… Test object deleted from S3" + + puts + puts "=== Example completed successfully! ===" + puts + puts "šŸ“ This example demonstrates the Amazon S3 Encryption Client v2 for Ruby" + puts "performing a complete roundtrip of encrypting data during upload and" + puts "decrypting it during download, using AWS KMS for key management." + puts + puts "Key features demonstrated:" + puts "• Client-side encryption using AES-GCM" + puts "• KMS integration for key wrapping" + puts "• Encryption context for additional security" + puts "• Automatic key rotation and management" + puts "• Secure roundtrip data integrity verification" + + rescue Aws::S3::Errors::NoSuchBucket => e + puts "āŒ Error: S3 bucket '#{bucket_name}' does not exist or is not accessible" + puts " #{e.message}" + exit 1 + rescue Aws::KMS::Errors::NotFoundException => e + puts "āŒ Error: KMS key '#{kms_key_id}' not found or not accessible" + puts " #{e.message}" + exit 1 + rescue Aws::S3::EncryptionV2::Errors::EncryptionError => e + puts "āŒ S3 Encryption Error: #{e.message}" + exit 1 + rescue Aws::S3::EncryptionV2::Errors::DecryptionError => e + puts "āŒ S3 Decryption Error: #{e.message}" + exit 1 + rescue Aws::Errors::ServiceError => e + puts "āŒ AWS Service Error: #{e.message}" + puts " Error Code: #{e.code}" if e.respond_to?(:code) + exit 1 + rescue StandardError => e + puts "āŒ Unexpected error: #{e.message}" + puts e.backtrace.first(5) + exit 1 + end +end + +# Run the main function if this script is executed directly +if __FILE__ == $0 + main +end diff --git a/all-examples/ruby/v3/Gemfile b/all-examples/ruby/v3/Gemfile new file mode 100644 index 00000000..ff13f9cd --- /dev/null +++ b/all-examples/ruby/v3/Gemfile @@ -0,0 +1,11 @@ +source 'https://rubygems.org' + +ruby '~> 3.0' + +gem 'aws-sdk-s3', path: 'local-ruby-sdk/gems/aws-sdk-s3' +gem 'aws-sdk-kms', path: 'local-ruby-sdk/gems/aws-sdk-kms' +gem 'json', '~> 2.0' + +group :development do + gem 'rubocop', '~> 1.0' +end From 8f82fd8db21775e5aad318b4f5f0608e13ca26ca Mon Sep 17 00:00:00 2001 From: Kess Plasmeier Date: Thu, 6 Nov 2025 14:31:43 -0800 Subject: [PATCH 2/5] remove slop --- all-examples/cpp/v3/CMakeLists.txt | 21 --- all-examples/cpp/v3/Makefile | 74 ---------- all-examples/cpp/v3/README.md | 136 ------------------ all-examples/cpp/v3/main.cpp | 112 --------------- .../dotnet/v2/S3EncryptionExample.csproj | 19 --- .../dotnet/v3/S3EncryptionExample.csproj | 19 --- .../dotnet/v4/S3EncryptionExample.csproj | 16 --- all-examples/go/v3/go.mod | 11 -- all-examples/go/v4/go.mod | 15 -- all-examples/java/v3/build.gradle.kts | 27 ---- all-examples/java/v4/build.gradle.kts | 28 ---- all-examples/php/v2/composer.json | 30 ---- all-examples/php/v3/composer.json | 30 ---- all-examples/ruby/v3/Gemfile | 11 -- 14 files changed, 549 deletions(-) delete mode 100644 all-examples/cpp/v3/CMakeLists.txt delete mode 100644 all-examples/cpp/v3/Makefile delete mode 100644 all-examples/cpp/v3/README.md delete mode 100644 all-examples/cpp/v3/main.cpp delete mode 100644 all-examples/dotnet/v2/S3EncryptionExample.csproj delete mode 100644 all-examples/dotnet/v3/S3EncryptionExample.csproj delete mode 100644 all-examples/dotnet/v4/S3EncryptionExample.csproj delete mode 100644 all-examples/go/v3/go.mod delete mode 100644 all-examples/go/v4/go.mod delete mode 100644 all-examples/java/v3/build.gradle.kts delete mode 100644 all-examples/java/v4/build.gradle.kts delete mode 100644 all-examples/php/v2/composer.json delete mode 100644 all-examples/php/v3/composer.json delete mode 100644 all-examples/ruby/v3/Gemfile diff --git a/all-examples/cpp/v3/CMakeLists.txt b/all-examples/cpp/v3/CMakeLists.txt deleted file mode 100644 index 9d9e696c..00000000 --- a/all-examples/cpp/v3/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -cmake_minimum_required(VERSION 3.16) -project(s3ec-cpp-v3-example) - -set(CMAKE_CXX_STANDARD 17) - -# Find AWS SDK for C++ -# Note: S3 Encryption Client is not part of standard AWS SDK -# This example demonstrates the concept but requires the full S3EC library -find_package(AWSSDK REQUIRED COMPONENTS core kms) - -add_executable(s3ec-example main.cpp) - -target_link_libraries(s3ec-example - ${AWSSDK_LINK_LIBRARIES} -) - -# Add include directories for AWS SDK -target_include_directories(s3ec-example PRIVATE ${AWSSDK_INCLUDE_DIRS}) - -# Set compiler flags -target_compile_features(s3ec-example PRIVATE cxx_std_17) diff --git a/all-examples/cpp/v3/Makefile b/all-examples/cpp/v3/Makefile deleted file mode 100644 index d78d6a1b..00000000 --- a/all-examples/cpp/v3/Makefile +++ /dev/null @@ -1,74 +0,0 @@ -# Makefile for S3 Encryption Client C++ v3 Example - -# Default target -.PHONY: all build clean run help - -# Variables -BUILD_DIR = build -EXECUTABLE = $(BUILD_DIR)/s3ec-example - -# Default arguments for running the example -# Override these when calling make run -BUCKET_NAME ?= avp-21638 -OBJECT_KEY ?= s3ec-cpp-v3 -KMS_KEY_ID ?= arn:aws:kms:us-east-2:648638458147:key/a47079da-17e4-45a5-b82e-2bac101cad01 -AWS_REGION ?= us-east-2 - -all: build - -# Build the project using CMake -build: - @echo "Building S3 Encryption Client v3 example..." - @mkdir -p $(BUILD_DIR) - @cd $(BUILD_DIR) && cmake .. && make - @echo "Build completed successfully!" - -# Clean build artifacts -clean: - @echo "Cleaning build artifacts..." - @rm -rf $(BUILD_DIR) - @echo "Clean completed!" - -# Run the example with default or provided arguments -run: build - @echo "Running S3 Encryption Client v3 example..." - @echo "Bucket: $(BUCKET_NAME)" - @echo "Object Key: $(OBJECT_KEY)" - @echo "KMS Key ID: $(KMS_KEY_ID)" - @echo "" - @$(EXECUTABLE) $(BUCKET_NAME) $(OBJECT_KEY) $(KMS_KEY_ID) - -# Run with custom arguments -# Usage: make run-custom BUCKET_NAME=my-bucket OBJECT_KEY=my-key KMS_KEY_ID=my-kms-key -run-custom: build - @$(EXECUTABLE) $(BUCKET_NAME) $(OBJECT_KEY) $(KMS_KEY_ID) - -# Show help -help: - @echo "S3 Encryption Client C++ v3 Example Makefile" - @echo "" - @echo "Available targets:" - @echo " build - Build the example using CMake" - @echo " run - Build and run the example with default parameters" - @echo " run-custom - Build and run with custom parameters" - @echo " clean - Remove build artifacts" - @echo " help - Show this help message" - @echo "" - @echo "Default parameters:" - @echo " BUCKET_NAME = $(BUCKET_NAME)" - @echo " OBJECT_KEY = $(OBJECT_KEY)" - @echo " KMS_KEY_ID = $(KMS_KEY_ID)" - @echo "" - @echo "To run with custom parameters:" - @echo " make run BUCKET_NAME=your-bucket OBJECT_KEY=your-key KMS_KEY_ID=your-kms-key" - @echo "" - @echo "Prerequisites:" - @echo " - AWS SDK for C++ must be installed on the system" - @echo " - AWS credentials configured (AWS CLI, environment variables, or IAM role)" - @echo " - CMake 3.16+ and C++17 compatible compiler" - @echo " - Valid S3 bucket and KMS key" - @echo "" - @echo "Version differences:" - @echo " - v3 uses enhanced security profiles and stricter validation" - @echo " - v3 may have different API patterns compared to v2" - @echo " - v3 focuses on modern cryptographic standards" diff --git a/all-examples/cpp/v3/README.md b/all-examples/cpp/v3/README.md deleted file mode 100644 index 7ad493bb..00000000 --- a/all-examples/cpp/v3/README.md +++ /dev/null @@ -1,136 +0,0 @@ -# S3 Encryption Client C++ v3 Example - -This example demonstrates the enhanced KMS integration pattern used by the Amazon S3 Encryption Client for C++ v3. It shows how S3EC v3 generates data keys from KMS with enhanced encryption context and security profiles, which is the foundation of client-side encryption with improved security. - -**Note**: This is a demonstration example that shows the KMS workflow with v3 enhancements. For the complete S3 encryption client functionality, you need the full S3EC library from https://github.com/aws/amazon-s3-encryption-client-cpp - -## Prerequisites - -1. **AWS SDK for C++**: The AWS SDK for C++ must be installed on your system. You can install it via: - - Package manager (e.g., `brew install aws-sdk-cpp` on macOS, `apt-get install libaws-cpp-sdk-dev` on Ubuntu) - - Build from source: https://github.com/aws/aws-sdk-cpp - - vcpkg: `vcpkg install aws-sdk-cpp[kms,s3,s3-encryption]` -2. **AWS Credentials**: Configure your AWS credentials using one of these methods: - - AWS CLI: `aws configure` - - Environment variables: `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` - - IAM roles (for EC2 instances) -3. **KMS Key**: Create a KMS key in your AWS account and note the key ID/ARN -4. **S3 Bucket**: Create an S3 bucket for testing -5. **Build Tools**: - - CMake 3.16 or later - - C++17 compatible compiler (GCC, Clang, or MSVC) - -## Building - -Use the provided Makefile to build the example: - -```bash -make build -``` - -This will: -1. Create a `build` directory -2. Run CMake to configure the project -3. Compile the example - -## Running - -### Quick Start - -Run with default parameters (you'll need to update these): - -```bash -make run BUCKET_NAME=avp-21638 OBJECT_KEY=s3ec-cpp-v3 KMS_KEY_ID=arn:aws:kms:us-east-2:648638458147:key/a47079da-17e4-45a5-b82e-2bac101cad01 -``` - -### Available Make Targets - -- `make build` - Build the example -- `make run` - Build and run with parameters -- `make clean` - Remove build artifacts -- `make help` - Show help information - -### Direct Execution - -After building, you can also run the executable directly: - -```bash -./build/s3ec-example -``` - -## Example Usage - -```bash -make run BUCKET_NAME=my-test-bucket OBJECT_KEY=example.txt KMS_KEY_ID=arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012 -``` - -## What the Example Does - -1. **Initialize**: Sets up the AWS SDK and creates an S3 encryption client with KMS materials -2. **Encrypt & Upload**: Encrypts a test message and uploads it to S3 with encryption context -3. **Download & Decrypt**: Downloads the encrypted object and decrypts it with context validation -4. **Verify**: Compares the original and decrypted data to ensure they match - -## Key Features Demonstrated - -- **KMS Integration**: Uses AWS KMS for key management with enhanced security -- **Encryption Context**: Demonstrates using encryption context with stricter validation -- **Modern Security**: Uses v3's enhanced security profiles -- **Error Handling**: Shows proper error handling for S3 operations -- **Resource Management**: Proper initialization and cleanup of AWS SDK - -## Security Profile - -This v3 example uses the modern security profile (V2), which: -- Enforces authenticated encryption modes -- Uses stronger cryptographic standards -- Provides stricter validation of encryption context -- Focuses on security best practices - -## Version Differences from v2 - -The v3 client provides several enhancements over v2: -- **Enhanced Security**: Stricter security profiles and validation -- **Modern Cryptography**: Focus on current cryptographic standards -- **Better Error Handling**: More detailed error messages and validation -- **Improved API**: Cleaner and more consistent API patterns - -## Troubleshooting - -### Common Issues - -1. **Build Errors**: Ensure AWS SDK for C++ is properly configured and available -2. **Runtime Errors**: Check AWS credentials and permissions -3. **KMS Errors**: Verify the KMS key exists and you have permissions to use it -4. **S3 Errors**: Ensure the bucket exists and you have read/write permissions -5. **Security Profile Errors**: v3 may reject operations that v2 would allow for security reasons - -### Required Permissions - -Your AWS credentials need the following permissions: -- `s3:GetObject` and `s3:PutObject` on the target bucket -- `kms:Encrypt`, `kms:Decrypt`, and `kms:GenerateDataKey` on the KMS key - -### Migration from v2 - -If migrating from v2: -- Review security profile settings - v3 defaults to stricter security -- Test encryption context validation - v3 may be more strict -- Update error handling for new error types -- Consider the enhanced security features - -## Version Notes - -This is the v3 version of the S3 Encryption Client, which provides: -- Enhanced security profiles with stricter validation -- Modern cryptographic standards -- Improved API consistency -- Better error reporting and debugging capabilities - -## Security Considerations - -v3 emphasizes security best practices: -- Always use encryption context for additional security -- Prefer authenticated encryption modes -- Use the latest cryptographic algorithms -- Validate all inputs and outputs diff --git a/all-examples/cpp/v3/main.cpp b/all-examples/cpp/v3/main.cpp deleted file mode 100644 index 412fde66..00000000 --- a/all-examples/cpp/v3/main.cpp +++ /dev/null @@ -1,112 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -int main(int argc, char* argv[]) { - // Check command line arguments - if (argc != 4) { - std::cerr << "Usage: " << argv[0] << " " << std::endl; - std::cerr << "Example: " << argv[0] << " avp-21638 s3ec-cpp-v3 arn:aws:kms:us-east-2:648638458147:key/a47079da-17e4-45a5-b82e-2bac101cad01" << std::endl; - return 1; - } - - std::string bucketName = argv[1]; - std::string objectKey = argv[2]; - std::string kmsKeyId = argv[3]; - - // Initialize AWS SDK - Aws::SDKOptions options; - Aws::InitAPI(options); - - try { - std::cout << "=== S3 Encryption Client v3 Example (Demonstration) ===" << std::endl; - std::cout << "Bucket: " << bucketName << std::endl; - std::cout << "Object Key: " << objectKey << std::endl; - std::cout << "KMS Key ID: " << kmsKeyId << std::endl << std::endl; - - // Set default region - Aws::Client::ClientConfiguration clientConfig; - clientConfig.region = "us-east-2"; - - // Create KMS client to demonstrate key operations - Aws::KMS::KMSClient kmsClient(clientConfig); - - // Test data that would be encrypted - std::string testData = "Hello, World! This is a test message for S3 encryption client v3."; - std::cout << "Original data: " << testData << std::endl; - - std::cout << "\n--- Demonstrating KMS Data Key Generation (v3 Enhanced) ---" << std::endl; - - // Generate a data key using KMS (this is what S3EC would do internally) - Aws::KMS::Model::GenerateDataKeyRequest dataKeyRequest; - dataKeyRequest.SetKeyId(kmsKeyId); - dataKeyRequest.SetKeySpec(Aws::KMS::Model::DataKeySpec::AES_256); - - // Add encryption context (v3 uses more comprehensive context) - Aws::Map encryptionContext; - encryptionContext["purpose"] = "example"; - encryptionContext["version"] = "v3"; - encryptionContext["client"] = "cpp"; - encryptionContext["bucket"] = bucketName; - encryptionContext["key"] = objectKey; - encryptionContext["security-profile"] = "v2"; // v3 uses enhanced security - dataKeyRequest.SetEncryptionContext(encryptionContext); - - auto dataKeyOutcome = kmsClient.GenerateDataKey(dataKeyRequest); - - if (dataKeyOutcome.IsSuccess()) { - std::cout << "āœ… Successfully generated data key from KMS!" << std::endl; - std::cout << "Key ID: " << kmsKeyId << std::endl; - std::cout << "Encryption context includes (v3 enhanced):" << std::endl; - for (const auto& pair : encryptionContext) { - std::cout << " " << pair.first << " = " << pair.second << std::endl; - } - - // In a real S3EC v3 implementation, this data key would be used with enhanced security - std::cout << "\n--- S3 Encryption Client v3 Workflow (Enhanced Security) ---" << std::endl; - std::cout << "1. āœ… Generate data key from KMS with enhanced context (completed above)" << std::endl; - std::cout << "2. šŸ”„ Use authenticated encryption for object data (requires S3EC v3 library)" << std::endl; - std::cout << "3. šŸ”„ Store encrypted data key with strict validation (requires S3EC v3 library)" << std::endl; - std::cout << "4. šŸ”„ Upload encrypted object with enhanced metadata (requires S3EC v3 library)" << std::endl; - std::cout << "5. šŸ”„ Download encrypted object with validation (requires S3EC v3 library)" << std::endl; - std::cout << "6. šŸ”„ Validate encryption context strictly (requires S3EC v3 library)" << std::endl; - std::cout << "7. šŸ”„ Decrypt data key with context validation (requires S3EC v3 library)" << std::endl; - std::cout << "8. šŸ”„ Decrypt object data with authenticated decryption (requires S3EC v3 library)" << std::endl; - - std::cout << "\n--- v3 Security Enhancements ---" << std::endl; - std::cout << "šŸ”’ Enhanced Security Profile: Enforces authenticated encryption modes" << std::endl; - std::cout << "šŸ”’ Stricter Validation: More rigorous encryption context validation" << std::endl; - std::cout << "šŸ”’ Modern Cryptography: Uses latest cryptographic standards" << std::endl; - std::cout << "šŸ”’ Better Error Handling: More detailed error messages and validation" << std::endl; - - } else { - std::cerr << "āŒ Failed to generate data key: " << dataKeyOutcome.GetError().GetMessage() << std::endl; - Aws::ShutdownAPI(options); - return 1; - } - - std::cout << "\n=== Example completed successfully! ===" << std::endl; - std::cout << "\nšŸ“ NOTE: This example demonstrates the enhanced KMS integration that S3EC v3 uses." << std::endl; - std::cout << "v3 provides stricter security profiles and enhanced validation compared to v2." << std::endl; - std::cout << "To run the full S3 encryption client, you need to install the complete" << std::endl; - std::cout << "Amazon S3 Encryption Client library, which is not part of the standard AWS SDK." << std::endl; - std::cout << "\nFor the complete S3EC library, visit:" << std::endl; - std::cout << "https://github.com/aws/amazon-s3-encryption-client-cpp" << std::endl; - - } catch (const std::exception& e) { - std::cerr << "Exception occurred: " << e.what() << std::endl; - Aws::ShutdownAPI(options); - return 1; - } - - // Shutdown AWS SDK - Aws::ShutdownAPI(options); - return 0; -} diff --git a/all-examples/dotnet/v2/S3EncryptionExample.csproj b/all-examples/dotnet/v2/S3EncryptionExample.csproj deleted file mode 100644 index 9fd91363..00000000 --- a/all-examples/dotnet/v2/S3EncryptionExample.csproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - Exe - net8.0 - enable - enable - - - - - - - - - - - - diff --git a/all-examples/dotnet/v3/S3EncryptionExample.csproj b/all-examples/dotnet/v3/S3EncryptionExample.csproj deleted file mode 100644 index 845a6cd1..00000000 --- a/all-examples/dotnet/v3/S3EncryptionExample.csproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - Exe - net8.0 - enable - enable - - - - - - - - - - - - diff --git a/all-examples/dotnet/v4/S3EncryptionExample.csproj b/all-examples/dotnet/v4/S3EncryptionExample.csproj deleted file mode 100644 index e0933854..00000000 --- a/all-examples/dotnet/v4/S3EncryptionExample.csproj +++ /dev/null @@ -1,16 +0,0 @@ - - - - Exe - net8.0 - enable - enable - - - - - - - - - diff --git a/all-examples/go/v3/go.mod b/all-examples/go/v3/go.mod deleted file mode 100644 index 74c9c05d..00000000 --- a/all-examples/go/v3/go.mod +++ /dev/null @@ -1,11 +0,0 @@ -module github.com/aws/amazon-s3-encryption-client-python/all-examples/go/v3 - -go 1.21 - -require ( - github.com/aws/amazon-s3-encryption-client-go/v3 v3.1.1 - 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 -) diff --git a/all-examples/go/v4/go.mod b/all-examples/go/v4/go.mod deleted file mode 100644 index fb5365b6..00000000 --- a/all-examples/go/v4/go.mod +++ /dev/null @@ -1,15 +0,0 @@ -module github.com/aws/amazon-s3-encryption-client-python/all-examples/go/v4 - -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 -) - -// 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/all-examples/java/v3/build.gradle.kts b/all-examples/java/v3/build.gradle.kts deleted file mode 100644 index 498ef757..00000000 --- a/all-examples/java/v3/build.gradle.kts +++ /dev/null @@ -1,27 +0,0 @@ -plugins { - `java-library` - application -} - -dependencies { - // S3 Encryption Client Java v3 - implementation("software.amazon.encryption.s3:amazon-s3-encryption-client-java:3.5.0") - - // AWS SDK dependencies - implementation("software.amazon.awssdk:s3:2.31.66") - implementation("software.amazon.awssdk:kms:2.31.66") - implementation("software.amazon.awssdk:core:2.31.66") -} - -application { - mainClass = "com.example.S3EncryptionExample" -} - -repositories { - mavenCentral() -} - -java { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 -} diff --git a/all-examples/java/v4/build.gradle.kts b/all-examples/java/v4/build.gradle.kts deleted file mode 100644 index 33ea0238..00000000 --- a/all-examples/java/v4/build.gradle.kts +++ /dev/null @@ -1,28 +0,0 @@ -plugins { - `java-library` - application -} - -dependencies { - // S3 Encryption Client Java v4 from local staging repository - implementation("software.amazon.encryption.s3:amazon-s3-encryption-client-java:3.4.0-IMPROVED") - - // AWS SDK dependencies - implementation("software.amazon.awssdk:s3:2.31.66") - implementation("software.amazon.awssdk:kms:2.31.66") - implementation("software.amazon.awssdk:core:2.31.66") -} - -application { - mainClass = "com.example.S3EncryptionExample" -} - -repositories { - mavenLocal() - mavenCentral() -} - -java { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 -} diff --git a/all-examples/php/v2/composer.json b/all-examples/php/v2/composer.json deleted file mode 100644 index ec32702b..00000000 --- a/all-examples/php/v2/composer.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "aws/s3ec-php-v2-example", - "description": "PHP v2 S3 Encryption Client example", - "type": "project", - "license": "Apache-2.0", - "repositories": [ - { - "type": "path", - "url": "./local-php-sdk", - "options": { - "symlink": true - } - } - ], - "require": { - "php": ">=7.4", - "aws/aws-sdk-php": "@dev" - }, - "autoload": { - "psr-4": { - "S3EC\\PhpV2Example\\": "src/" - } - }, - "config": { - "optimize-autoloader": true, - "platform": { - "php": "8.1" - } - } -} diff --git a/all-examples/php/v3/composer.json b/all-examples/php/v3/composer.json deleted file mode 100644 index a535ee38..00000000 --- a/all-examples/php/v3/composer.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "aws/s3ec-php-v3-example", - "description": "PHP v3 S3 Encryption Client example", - "type": "project", - "license": "Apache-2.0", - "repositories": [ - { - "type": "path", - "url": "./local-php-sdk", - "options": { - "symlink": true - } - } - ], - "require": { - "php": ">=7.4", - "aws/aws-sdk-php": "@dev" - }, - "autoload": { - "psr-4": { - "S3EC\\PhpV3Example\\": "src/" - } - }, - "config": { - "optimize-autoloader": true, - "platform": { - "php": "8.1" - } - } -} diff --git a/all-examples/ruby/v3/Gemfile b/all-examples/ruby/v3/Gemfile deleted file mode 100644 index ff13f9cd..00000000 --- a/all-examples/ruby/v3/Gemfile +++ /dev/null @@ -1,11 +0,0 @@ -source 'https://rubygems.org' - -ruby '~> 3.0' - -gem 'aws-sdk-s3', path: 'local-ruby-sdk/gems/aws-sdk-s3' -gem 'aws-sdk-kms', path: 'local-ruby-sdk/gems/aws-sdk-kms' -gem 'json', '~> 2.0' - -group :development do - gem 'rubocop', '~> 1.0' -end From 47d740f98e32c8c641977b878e3c5f9d2ed6913c Mon Sep 17 00:00:00 2001 From: Kess Plasmeier Date: Thu, 6 Nov 2025 14:53:08 -0800 Subject: [PATCH 3/5] cleanup --- all-examples/README.md | 25 +++++++------- all-examples/ruby/v2/main.rb | 63 ++++++++++++------------------------ 2 files changed, 33 insertions(+), 55 deletions(-) diff --git a/all-examples/README.md b/all-examples/README.md index 9f8aba4c..af3cba58 100644 --- a/all-examples/README.md +++ b/all-examples/README.md @@ -7,24 +7,23 @@ This directory contains example projects for the Amazon S3 Encryption Client acr Each language has subdirectories for different major versions of the S3 Encryption Client: - `cpp/` - C++ examples - - `v2/` - S3EC C++ v2 example - - `v3/` - S3EC C++ v3 example + - `v2/` - S3EC C++ v2 example (transitional) + - `v3/` - S3EC C++ v3 example (improved) - `dotnet/` - .NET examples - - `v2/` - S3EC .NET v2 example - - `v3/` - S3EC .NET v3 example - - `v4/` - S3EC .NET v4 example + - `v3/` - S3EC .NET v3 example (transitional) + - `v4/` - S3EC .NET v4 example (improved) - `go/` - Go examples - - `v3/` - S3EC Go v3 example - - `v4/` - S3EC Go v4 example + - `v3/` - S3EC Go v3 example (transitional) + - `v4/` - S3EC Go v4 example (improved) - `java/` - Java examples - - `v3/` - S3EC Java v3 example - - `v4/` - S3EC Java v4 example + - `v3/` - S3EC Java v3 example (transitional) + - `v4/` - S3EC Java v4 example (improved) - `php/` - PHP examples - - `v2/` - S3EC PHP v2 example - - `v3/` - S3EC PHP v3 example + - `v2/` - S3EC PHP v2 example (transitional) + - `v3/` - S3EC PHP v3 example (improved) - `ruby/` - Ruby examples - - `v2/` - S3EC Ruby v2 example - - `v3/` - S3EC Ruby v3 example + - `v2/` - S3EC Ruby v2 example (transitional) + - `v3/` - S3EC Ruby v3 example (improved) ## Setup Instructions diff --git a/all-examples/ruby/v2/main.rb b/all-examples/ruby/v2/main.rb index ce2e2641..55702da4 100644 --- a/all-examples/ruby/v2/main.rb +++ b/all-examples/ruby/v2/main.rb @@ -31,7 +31,7 @@ def main puts "Data length: #{test_data.length} bytes" puts - puts "--- Step 1: Initialize S3 Encryption Client v2 ---" + puts "--- Initialize S3 Encryption Client v2 ---" # Create regular S3 client s3_client = Aws::S3::Client.new(region: region) @@ -49,16 +49,10 @@ def main security_profile: :v2 ) - puts "āœ… Successfully initialized S3 Encryption Client v2" - puts " KMS Key ID: #{kms_key_id}" - puts " Key Wrap Schema: kms_context" - puts " Content Encryption Schema: aes_gcm_no_padding" - puts " Security Profile: v2" - puts - - puts "--- Step 2: Encrypt and Upload Object to S3 ---" + puts "Successfully initialized S3 Encryption Client v2" + puts "--- Encrypt and Upload Object to S3 ---" - # Optional: Add encryption context for additional security + # Add encryption context for additional security encryption_context = { 'purpose' => 'example', 'version' => 'v2', @@ -73,14 +67,13 @@ def main kms_encryption_context: encryption_context }) - puts "āœ… Successfully uploaded encrypted object to S3!" + puts "Successfully uploaded encrypted object to S3!" puts " Bucket: #{bucket_name}" puts " Key: #{object_key}" - puts " ETag: #{put_response.etag}" puts " Encryption Context: #{encryption_context}" puts - puts "--- Step 3: Download and Decrypt Object from S3 ---" + puts "--- Download and Decrypt Object from S3 ---" # Download and decrypt object using S3 Encryption Client get_response = encryption_client.get_object({ @@ -92,71 +85,57 @@ def main # Read the decrypted data decrypted_data = get_response.body.read - puts "āœ… Successfully downloaded and decrypted object from S3!" + puts "Successfully downloaded and decrypted object from S3!" puts " Object size: #{decrypted_data.length} bytes" puts " Decrypted data: #{decrypted_data}" puts - puts "--- Step 4: Verify Roundtrip Success ---" + puts "--- Verify Roundtrip Success ---" # Verify the roundtrip was successful if decrypted_data == test_data - puts "šŸŽ‰ SUCCESS: Roundtrip encryption/decryption completed successfully!" - puts " āœ… Original data matches decrypted data" - puts " āœ… Data integrity verified" + puts "SUCCESS: Roundtrip encryption/decryption completed successfully!" + puts " Original data matches decrypted data" + puts " Data integrity verified" else - puts "āŒ ERROR: Roundtrip failed - data mismatch" + puts "ERROR: Roundtrip failed - data mismatch" puts " Original: #{test_data}" puts " Decrypted: #{decrypted_data}" exit 1 end - - puts - puts "--- Step 5: Cleanup ---" - + # Optionally Delete the Object + #puts "--- Cleanup ---" # Clean up the test object using regular S3 client # s3_client.delete_object({ # bucket: bucket_name, # key: object_key # }) - - puts "āœ… Test object deleted from S3" + # puts "Test object deleted from S3" puts puts "=== Example completed successfully! ===" - puts - puts "šŸ“ This example demonstrates the Amazon S3 Encryption Client v2 for Ruby" - puts "performing a complete roundtrip of encrypting data during upload and" - puts "decrypting it during download, using AWS KMS for key management." - puts - puts "Key features demonstrated:" - puts "• Client-side encryption using AES-GCM" - puts "• KMS integration for key wrapping" - puts "• Encryption context for additional security" - puts "• Automatic key rotation and management" - puts "• Secure roundtrip data integrity verification" rescue Aws::S3::Errors::NoSuchBucket => e - puts "āŒ Error: S3 bucket '#{bucket_name}' does not exist or is not accessible" + puts "Error: S3 bucket '#{bucket_name}' does not exist or is not accessible" puts " #{e.message}" exit 1 rescue Aws::KMS::Errors::NotFoundException => e - puts "āŒ Error: KMS key '#{kms_key_id}' not found or not accessible" + puts "Error: KMS key '#{kms_key_id}' not found or not accessible" puts " #{e.message}" exit 1 rescue Aws::S3::EncryptionV2::Errors::EncryptionError => e - puts "āŒ S3 Encryption Error: #{e.message}" + puts "S3 Encryption Error: #{e.message}" exit 1 rescue Aws::S3::EncryptionV2::Errors::DecryptionError => e - puts "āŒ S3 Decryption Error: #{e.message}" + puts "S3 Decryption Error: #{e.message}" exit 1 rescue Aws::Errors::ServiceError => e - puts "āŒ AWS Service Error: #{e.message}" + puts "AWS Service Error: #{e.message}" puts " Error Code: #{e.code}" if e.respond_to?(:code) exit 1 rescue StandardError => e - puts "āŒ Unexpected error: #{e.message}" + puts "Unexpected error: #{e.message}" puts e.backtrace.first(5) exit 1 end From a1688aa6db6d43d71d6f1dc48c2173ab35f8aae7 Mon Sep 17 00:00:00 2001 From: Kess Plasmeier <76071473+kessplas@users.noreply.github.com> Date: Fri, 7 Nov 2025 15:40:14 -0800 Subject: [PATCH 4/5] Update main.rb --- all-examples/ruby/v2/main.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/all-examples/ruby/v2/main.rb b/all-examples/ruby/v2/main.rb index 55702da4..51d85cc9 100644 --- a/all-examples/ruby/v2/main.rb +++ b/all-examples/ruby/v2/main.rb @@ -52,7 +52,7 @@ def main puts "Successfully initialized S3 Encryption Client v2" puts "--- Encrypt and Upload Object to S3 ---" - # Add encryption context for additional security + # Add encryption context encryption_context = { 'purpose' => 'example', 'version' => 'v2', From 3cf785d34dadf931b0239009ce9591341cf8bfcf Mon Sep 17 00:00:00 2001 From: seebees Date: Fri, 7 Nov 2025 16:28:19 -0800 Subject: [PATCH 5/5] add v3 Ruby example (#68) Add v3 Ruby example Co-authored-by: Kess Plasmeier <76071473+kessplas@users.noreply.github.com> --- .gitmodules | 3 - all-examples/README.md | 3 + all-examples/ruby/v2/local-ruby-sdk | 2 +- all-examples/ruby/v3/Gemfile | 12 +++ all-examples/ruby/v3/Makefile | 70 ++++++++++++++ all-examples/ruby/v3/local-ruby-sdk | 1 + all-examples/ruby/v3/main.rb | 145 ++++++++++++++++++++++++++++ 7 files changed, 232 insertions(+), 4 deletions(-) mode change 160000 => 120000 all-examples/ruby/v2/local-ruby-sdk create mode 100644 all-examples/ruby/v3/Gemfile create mode 100644 all-examples/ruby/v3/Makefile create mode 120000 all-examples/ruby/v3/local-ruby-sdk create mode 100644 all-examples/ruby/v3/main.rb diff --git a/.gitmodules b/.gitmodules index b167bcd8..952fb220 100644 --- a/.gitmodules +++ b/.gitmodules @@ -39,9 +39,6 @@ path = test-server/net-v2-v3-server/s3ec-net-v3 url = https://github.com/aws/private-amazon-s3-encryption-client-dotnet-staging.git branch = s3ec-v3 -[submodule "all-examples/ruby/v2/local-ruby-sdk"] - path = all-examples/ruby/v2/local-ruby-sdk - url = git@github.com:aws/aws-sdk-ruby-staging.git [submodule "test-server/net-v3-transition-server/s3ec-v3-transition-branch"] path = test-server/net-v3-transition-server/s3ec-v3-transition-branch url = https://github.com/aws/private-amazon-s3-encryption-client-dotnet-staging.git diff --git a/all-examples/README.md b/all-examples/README.md index af3cba58..59bc2d6c 100644 --- a/all-examples/README.md +++ b/all-examples/README.md @@ -30,6 +30,7 @@ Each language has subdirectories for different major versions of the S3 Encrypti ### Prerequisites 1. **Git Submodules**: Some examples depend on staging versions of the S3EC libraries that are included as git submodules. Initialize and update submodules: + ```bash git submodule update --init --recursive ``` @@ -55,6 +56,7 @@ Each language directory contains specific setup instructions in its README file. ## Usage Each example directory contains: + - Build configuration files (e.g., `build.gradle.kts`, `go.mod`, `composer.json`) - Source code demonstrating basic S3EC usage - README with specific setup and run instructions @@ -62,6 +64,7 @@ Each example directory contains: ## Dependencies Examples use different dependency sources based on version: + - **Released versions**: Use public package repositories (Maven Central, npm, etc.) - **Staging versions**: Use git submodules pointing to staging repositories - **Local versions**: Reference locally built libraries diff --git a/all-examples/ruby/v2/local-ruby-sdk b/all-examples/ruby/v2/local-ruby-sdk deleted file mode 160000 index 63e4accf..00000000 --- a/all-examples/ruby/v2/local-ruby-sdk +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 63e4accfeecf018f8590fd1e22ad64ff58cedf03 diff --git a/all-examples/ruby/v2/local-ruby-sdk b/all-examples/ruby/v2/local-ruby-sdk new file mode 120000 index 00000000..7abd378c --- /dev/null +++ b/all-examples/ruby/v2/local-ruby-sdk @@ -0,0 +1 @@ +../../../test-server/ruby-v2-server/local-ruby-sdk \ No newline at end of file diff --git a/all-examples/ruby/v3/Gemfile b/all-examples/ruby/v3/Gemfile new file mode 100644 index 00000000..5f51bf18 --- /dev/null +++ b/all-examples/ruby/v3/Gemfile @@ -0,0 +1,12 @@ +source 'https://rubygems.org' + +ruby '>= 2.7.0' + +gem 'aws-sdk-s3', path: 'local-ruby-sdk/gems/aws-sdk-s3' +gem 'aws-sdk-kms', path: 'local-ruby-sdk/gems/aws-sdk-kms' +gem 'json', '~> 2.0' +gem 'rexml', '~> 3.0' + +group :development do + gem 'rubocop', '~> 1.0' +end diff --git a/all-examples/ruby/v3/Makefile b/all-examples/ruby/v3/Makefile new file mode 100644 index 00000000..b27bf29f --- /dev/null +++ b/all-examples/ruby/v3/Makefile @@ -0,0 +1,70 @@ +# Makefile for S3 Encryption Client Ruby v3 Example + +# Default target +.PHONY: all install clean run help + +# Variables +SCRIPT = main.rb + +# Default arguments for running the example +# Override these when calling make run +BUCKET_NAME ?= avp-21638 +OBJECT_KEY ?= s3ec-ruby-v3 +KMS_KEY_ID ?= arn:aws:kms:us-east-2:648638458147:key/a47079da-17e4-45a5-b82e-2bac101cad01 +AWS_REGION ?= us-east-2 + +all: install + +# Install dependencies using Bundler +install: + @echo "Installing Ruby dependencies..." + @bundle install + @echo "Dependencies installed successfully!" + +# Clean bundle artifacts +clean: + @echo "Cleaning bundle artifacts..." + @bundle clean --force + @echo "Clean completed!" + +# Run the example with default arguments +run: install + @echo "Running S3 Encryption Client v3 Ruby example..." + @echo "Bucket: $(BUCKET_NAME)" + @echo "Object Key: $(OBJECT_KEY)" + @echo "KMS Key ID: $(KMS_KEY_ID)" + @echo "Region: $(AWS_REGION)" + @echo "" + @bundle exec ruby $(SCRIPT) $(BUCKET_NAME) $(OBJECT_KEY) $(KMS_KEY_ID) $(AWS_REGION) + +# Run with custom arguments +# Usage: make run-custom BUCKET_NAME=my-bucket OBJECT_KEY=my-key KMS_KEY_ID=my-kms-key AWS_REGION=my-region +run-custom: install + @bundle exec ruby $(SCRIPT) $(BUCKET_NAME) $(OBJECT_KEY) $(KMS_KEY_ID) $(AWS_REGION) + +# Show help +help: + @echo "S3 Encryption Client Ruby v3 Example Makefile" + @echo "" + @echo "Available targets:" + @echo " install - Install Ruby dependencies using Bundler" + @echo " run - Install dependencies and run the example with default parameters" + @echo " run-custom - Install dependencies and run with custom parameters" + @echo " clean - Remove bundle artifacts" + @echo " help - Show this help message" + @echo "" + @echo "Default parameters:" + @echo " BUCKET_NAME = $(BUCKET_NAME)" + @echo " OBJECT_KEY = $(OBJECT_KEY)" + @echo " KMS_KEY_ID = $(KMS_KEY_ID)" + @echo " AWS_REGION = $(AWS_REGION)" + @echo "" + @echo "To run with custom parameters:" + @echo " make run BUCKET_NAME=your-bucket OBJECT_KEY=your-key KMS_KEY_ID=your-kms-key AWS_REGION=your-region" + @echo "" + @echo "Prerequisites:" + @echo " - Ruby 3.0+ installed on the system" + @echo " - Bundler gem installed (gem install bundler)" + @echo " - AWS credentials configured (AWS CLI, environment variables, or IAM role)" + @echo " - Valid S3 bucket and KMS key with appropriate permissions" + @echo " - S3 Encryption Client v3 Ruby SDK (included in local-ruby-sdk)" diff --git a/all-examples/ruby/v3/local-ruby-sdk b/all-examples/ruby/v3/local-ruby-sdk new file mode 120000 index 00000000..49be2657 --- /dev/null +++ b/all-examples/ruby/v3/local-ruby-sdk @@ -0,0 +1 @@ +../../../test-server/ruby-v3-server/local-ruby-sdk \ No newline at end of file diff --git a/all-examples/ruby/v3/main.rb b/all-examples/ruby/v3/main.rb new file mode 100644 index 00000000..fb15f317 --- /dev/null +++ b/all-examples/ruby/v3/main.rb @@ -0,0 +1,145 @@ +#!/usr/bin/env ruby + +require 'aws-sdk-s3' +require 'aws-sdk-kms' +require 'json' + +def main + # Check command line arguments + if ARGV.length != 4 + puts "Usage: #{$0} " + puts "Example: #{$0} avp-21638 s3ec-ruby-v3 arn:aws:kms:us-east-2:648638458147:key/a47079da-17e4-45a5-b82e-2bac101cad01 us-east-2" + exit 1 + end + + bucket_name = ARGV[0] + object_key = ARGV[1] + kms_key_id = ARGV[2] + region = ARGV[3] + + puts "=== S3 Encryption Client v3 Example (Ruby) ===" + puts "Bucket: #{bucket_name}" + puts "Object Key: #{object_key}" + puts "KMS Key ID: #{kms_key_id}" + puts "Region: #{region}" + puts + + begin + # Test data for encryption + test_data = "Hello, World! This is a test message for S3 encryption client v3 in Ruby." + puts "Original data: #{test_data}" + puts "Data length: #{test_data.length} bytes" + puts + + puts "--- Initialize S3 Encryption Client v3 ---" + + # Create regular S3 client + s3_client = Aws::S3::Client.new(region: region) + + # Create KMS client + kms_client = Aws::KMS::Client.new(region: region) + + # Create S3 Encryption Client v3 + encryption_client = Aws::S3::EncryptionV3::Client.new( + client: s3_client, + kms_key_id: kms_key_id, + kms_client: kms_client, + key_wrap_schema: :kms_context + ) + + puts "Successfully initialized S3 Encryption Client v3" + puts "--- Encrypt and Upload Object to S3 ---" + + # Add encryption context + encryption_context = { + 'purpose' => 'example', + 'version' => 'v3', + 'language' => 'ruby' + } + + # Upload encrypted object using S3 Encryption Client + put_response = encryption_client.put_object({ + bucket: bucket_name, + key: object_key, + body: test_data, + kms_encryption_context: encryption_context + }) + + puts "Successfully uploaded encrypted object to S3!" + puts " Bucket: #{bucket_name}" + puts " Key: #{object_key}" + puts " Encryption Context: #{encryption_context}" + puts + + puts "--- Download and Decrypt Object from S3 ---" + + # Download and decrypt object using S3 Encryption Client + get_response = encryption_client.get_object({ + bucket: bucket_name, + key: object_key, + kms_encryption_context: encryption_context + }) + + # Read the decrypted data + decrypted_data = get_response.body.read + + puts "Successfully downloaded and decrypted object from S3!" + puts " Object size: #{decrypted_data.length} bytes" + puts " Decrypted data: #{decrypted_data}" + puts + + puts "--- Verify Roundtrip Success ---" + + # Verify the roundtrip was successful + if decrypted_data == test_data + puts "SUCCESS: Roundtrip encryption/decryption completed successfully!" + puts " Original data matches decrypted data" + puts " Data integrity verified" + else + puts "ERROR: Roundtrip failed - data mismatch" + puts " Original: #{test_data}" + puts " Decrypted: #{decrypted_data}" + exit 1 + end + + # Optionally Delete the Object + #puts "--- Cleanup ---" + # Clean up the test object using regular S3 client + # s3_client.delete_object({ + # bucket: bucket_name, + # key: object_key + # }) + # puts "Test object deleted from S3" + + puts + puts "=== Example completed successfully! ===" + + rescue Aws::S3::Errors::NoSuchBucket => e + puts "Error: S3 bucket '#{bucket_name}' does not exist or is not accessible" + puts " #{e.message}" + exit 1 + rescue Aws::KMS::Errors::NotFoundException => e + puts "Error: KMS key '#{kms_key_id}' not found or not accessible" + puts " #{e.message}" + exit 1 + rescue Aws::S3::EncryptionV3::Errors::EncryptionError => e + puts "S3 Encryption Error: #{e.message}" + exit 1 + rescue Aws::S3::EncryptionV3::Errors::DecryptionError => e + puts "S3 Decryption Error: #{e.message}" + exit 1 + rescue Aws::Errors::ServiceError => e + puts "AWS Service Error: #{e.message}" + puts " Error Code: #{e.code}" if e.respond_to?(:code) + exit 1 + rescue StandardError => e + puts "Unexpected error: #{e.message}" + puts e.backtrace.first(5) + exit 1 + end +end + +# Run the main function if this script is executed directly +if __FILE__ == $0 + main +end