From a68c29adfdc2a710f7857ec0ced1bf24b316818a Mon Sep 17 00:00:00 2001 From: Andy Jewell Date: Tue, 11 Nov 2025 13:47:13 -0500 Subject: [PATCH 1/3] c++ example --- all-examples/cpp/CMakeLists.txt | 23 ++++ all-examples/cpp/Makefile | 60 +++++++++++ all-examples/cpp/README.md | 15 +++ all-examples/cpp/main.cpp | 181 ++++++++++++++++++++++++++++++++ 4 files changed, 279 insertions(+) create mode 100644 all-examples/cpp/CMakeLists.txt create mode 100644 all-examples/cpp/Makefile create mode 100644 all-examples/cpp/README.md create mode 100644 all-examples/cpp/main.cpp diff --git a/all-examples/cpp/CMakeLists.txt b/all-examples/cpp/CMakeLists.txt new file mode 100644 index 00000000..906951b8 --- /dev/null +++ b/all-examples/cpp/CMakeLists.txt @@ -0,0 +1,23 @@ +cmake_minimum_required(VERSION 3.16) +project(s3ec-test) + +set(CMAKE_CXX_STANDARD 14) + +# Configure AWS SDK build options +set(BUILD_ONLY "kms;s3;s3-encryption" CACHE STRING "Build only KMS, S3, and S3-encryption components") +set(ENABLE_TESTING OFF CACHE BOOL "Disable testing") +set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build static libraries") + +# Add AWS SDK as subdirectory +add_subdirectory(aws-sdk-cpp) + +find_package(PkgConfig REQUIRED) + +add_executable(s3ec-test main.cpp) + +target_link_libraries(s3ec-test + aws-cpp-sdk-core + aws-cpp-sdk-kms + aws-cpp-sdk-s3 + aws-cpp-sdk-s3-encryption +) diff --git a/all-examples/cpp/Makefile b/all-examples/cpp/Makefile new file mode 100644 index 00000000..64550528 --- /dev/null +++ b/all-examples/cpp/Makefile @@ -0,0 +1,60 @@ +# Makefile for S3 Encryption Client C++ Example + +.PHONY: all install clean run help + +# Default arguments for running the example +# Override these when calling make run +VERSION ?= V3 +BUCKET_NAME ?= avp-21638 +OBJECT_KEY ?= s3ec-cpp-test +KMS_KEY_ID ?= arn:aws:kms:us-east-2:648638458147:key/a47079da-17e4-45a5-b82e-2bac101cad01 +AWS_REGION ?= us-east-2 + +all: run + +install: build/s3ec-test + +aws-sdk-cpp: + git clone --recurse-submodules -b fire-egg-dev https://github.com/awslabs/aws-sdk-cpp-staging.git aws-sdk-cpp + +build/s3ec-test: aws-sdk-cpp + mkdir -p build && cd build && cmake .. && make + +clean: + rm -rf build + +# Run the example with default arguments +run: build/s3ec-test + @echo "Running S3 Encryption Client C++ example..." + @echo "Version: $(VERSION)" + @echo "Bucket: $(BUCKET_NAME)" + @echo "Object Key: $(OBJECT_KEY)" + @echo "KMS Key ID: $(KMS_KEY_ID)" + @echo "Region: $(AWS_REGION)" + @echo "" + ./build/s3ec-test $(VERSION) $(BUCKET_NAME) $(OBJECT_KEY) $(KMS_KEY_ID) $(AWS_REGION) + +# Show help +help: + @echo "S3 Encryption Client C++ Example Makefile" + @echo "" + @echo "Available targets:" + @echo " install - Install Go dependencies using Go modules" + @echo " run - Install dependencies and run the example" + @echo " clean - Remove C++ artifacts" + @echo " help - Show this help message" + @echo "" + @echo "Default parameters:" + @echo " VERSION = $(VERSION) (must be V2 or V3)" + @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 VERSION=your-version BUCKET_NAME=your-bucket OBJECT_KEY=your-key KMS_KEY_ID=your-kms-key AWS_REGION=your-region" + @echo "" + @echo "Prerequisites:" + @echo " - Read access to https://github.com/awslabs/aws-sdk-cpp-staging.git" + @echo " - AWS credentials configured (AWS CLI, environment variables, or IAM role)" + @echo " - Valid S3 bucket and KMS key with appropriate permissions" diff --git a/all-examples/cpp/README.md b/all-examples/cpp/README.md new file mode 100644 index 00000000..8875fb07 --- /dev/null +++ b/all-examples/cpp/README.md @@ -0,0 +1,15 @@ +# C++ S3 Encryption Test + +Minimal C++ use of S3 Encryption + +## Build + +```bash +make install +``` + +## Run + +```bash +make run +``` diff --git a/all-examples/cpp/main.cpp b/all-examples/cpp/main.cpp new file mode 100644 index 00000000..db8627d7 --- /dev/null +++ b/all-examples/cpp/main.cpp @@ -0,0 +1,181 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +using namespace Aws::S3Encryption; +using Aws::S3Encryption::Materials::KMSWithContextEncryptionMaterials; + +static Aws::Map get_encryption_context(const char * version) +{ + return { + {"purpose", "example"}, + {"version", version}, + {"language", "c++"} + }; +} + +static int test_v3(const char *bucket, const char *object, const char *kms_key_id, const char *region) +{ + Aws::Client::ClientConfiguration s3ClientConfig; + s3ClientConfig.region = region; + + auto materials = std::make_shared(kms_key_id, s3ClientConfig); + CryptoConfigurationV3 config(materials); + // config.AllowLegacy(); + // config.SetStorageMethod(StorageMethod::INSTRUCTION_FILE); + // config.SetCommitmentPolicy(CommitmentPolicy::FORBID_ENCRYPT_ALLOW_DECRYPT); + + + auto client = std::make_shared(config, s3ClientConfig); + + auto encryption_context = get_encryption_context("V3"); + + Aws::S3::Model::PutObjectRequest put_request; + put_request.SetBucket(bucket); + put_request.SetKey(object); + + auto data = std::string("This is the sample content."); + + auto stream = std::make_shared(data); + put_request.SetBody(stream); + + auto put_outcome = client->PutObject(put_request, encryption_context); + if (put_outcome.IsSuccess()) + { + fprintf(stderr, "PutObject V3 Successful.\n"); + } + else + { + fprintf(stderr, "PutObject V3 Failed : %s\n", put_outcome.GetError().GetMessage().c_str()); + return 1; + } + + Aws::S3::Model::GetObjectRequest get_request; + get_request.SetBucket(bucket); + get_request.SetKey(object); + auto get_outcome = client->GetObject(get_request, encryption_context); + if (get_outcome.IsSuccess()) + { + fprintf(stderr, "GetObject V3 Successful.\n"); + Aws::StringStream response_stream; + response_stream << get_outcome.GetResult().GetBody().rdbuf(); + if (response_stream.str() != data) + { + fprintf(stderr, "GetObject V3 returned the wrong data.\n"); + return 1; + } + } + else + { + fprintf(stderr, "GetObject V3 Failed : %s\n", put_outcome.GetError().GetMessage().c_str()); + return 1; + } + return 0; +} + +static int test_v2(const char *bucket, const char *object, const char *kms_key_id, const char *region) +{ + Aws::Client::ClientConfiguration s3ClientConfig; + s3ClientConfig.region = region; + + auto materials = std::make_shared(kms_key_id, s3ClientConfig); + CryptoConfigurationV2 config(materials); + // config.SetSecurityProfile(SecurityProfile::V2_AND_LEGACY); + // config.SetStorageMethod(StorageMethod::INSTRUCTION_FILE); + + + auto client = std::make_shared(config, s3ClientConfig); + + auto encryption_context = get_encryption_context("V2"); + + Aws::S3::Model::PutObjectRequest put_request; + put_request.SetBucket(bucket); + put_request.SetKey(object); + + auto data = std::string("This is the sample content."); + + auto stream = std::make_shared(data); + put_request.SetBody(stream); + + auto put_outcome = client->PutObject(put_request, encryption_context); + if (put_outcome.IsSuccess()) + { + fprintf(stderr, "PutObject V2 Successful.\n"); + } + else + { + fprintf(stderr, "PutObject V2 Failed : %s\n", put_outcome.GetError().GetMessage().c_str()); + return 1; + } + + Aws::S3::Model::GetObjectRequest get_request; + get_request.SetBucket(bucket); + get_request.SetKey(object); + auto get_outcome = client->GetObject(get_request, encryption_context); + if (get_outcome.IsSuccess()) + { + fprintf(stderr, "GetObject V2 Successful.\n"); + Aws::StringStream response_stream; + response_stream << get_outcome.GetResult().GetBody().rdbuf(); + if (response_stream.str() != data) + { + fprintf(stderr, "GetObject V2 returned the wrong data.\n"); + return 1; + } + } + else + { + fprintf(stderr, "GetObject V2 Failed : %s\n", put_outcome.GetError().GetMessage().c_str()); + return 1; + } + return 0; +} + +int main(int argc, char **argv) +{ + if (argc != 6) + { + fprintf(stderr, "USAGE : s3ec-test version bucket object key_id region"); + return 1; + } + + auto version_str = argv[1]; + auto bucket = argv[2]; + auto object = argv[3]; + auto kms_key_id = argv[4]; + auto region = argv[5]; + + bool is_v3; + if (strcasecmp(version_str, "v3") == 0) + { + is_v3 = true; + } + else if (strcasecmp(version_str, "v2") == 0) + { + is_v3 = false; + } + else + { + fprintf(stderr, "Version was <%s> must be V2 or V3\n", version_str); + return 1; + } + + Aws::SDKOptions options; + Aws::InitAPI(options); + + if (is_v3) + test_v3(bucket, object, kms_key_id, region); + else + test_v2(bucket, object, kms_key_id, region); + + Aws::ShutdownAPI(options); +} From a9230a8c4bae057c2705240db03fa91504b15dd2 Mon Sep 17 00:00:00 2001 From: Andy Jewell Date: Tue, 11 Nov 2025 13:49:42 -0500 Subject: [PATCH 2/3] m --- .github/workflows/examples.yml | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index 30e47a06..cecb6989 100644 --- a/.github/workflows/examples.yml +++ b/.github/workflows/examples.yml @@ -17,23 +17,14 @@ jobs: submodules: true token: ${{ secrets.PAT_FOR_PRIVATE_RUBY }} - - name: Checkout CPP code for cpp-v2-transition + - name: Checkout CPP code cpp-examples uses: actions/checkout@v5 with: submodules: recursive token: ${{ secrets.PAT_FOR_CPP }} repository: awslabs/aws-sdk-cpp-staging ref: fire-egg-dev - path: test-server/cpp-v2-transition-server/aws-sdk-cpp/ - - - name: Checkout CPP code cpp-v3 - uses: actions/checkout@v5 - with: - submodules: recursive - token: ${{ secrets.PAT_FOR_CPP }} - repository: awslabs/aws-sdk-cpp-staging - ref: fire-egg-dev - path: test-server/cpp-v3-server/aws-sdk-cpp/ + path: all-examples/cpp/aws-sdk-cpp/ - name: Checkout .NET V2 code uses: actions/checkout@v5 From 8e4ec153c5f868c374aa0af880bf68f1b177ee3a Mon Sep 17 00:00:00 2001 From: Andy Jewell Date: Tue, 11 Nov 2025 14:41:52 -0500 Subject: [PATCH 3/3] m --- all-examples/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/all-examples/Makefile b/all-examples/Makefile index 7dac8ce6..eeb0949b 100644 --- a/all-examples/Makefile +++ b/all-examples/Makefile @@ -5,7 +5,7 @@ .PHONY: all install clean run help list-examples # Find all directories with Makefiles -EXAMPLE_DIRS := $(shell find . -name Makefile -not -path "./Makefile" | xargs dirname | sed 's|^\./||' | $(if $(FILTER),grep -E "$$(echo '$(FILTER)' | sed 's/,/|/g')",cat) | sort) +EXAMPLE_DIRS := $(shell find . -name Makefile -not -path "./Makefile" -not -path "./cpp/aws-sdk-cpp/**" -not -path "./cpp/build/**" | xargs dirname | sed 's|^\./||' | $(if $(FILTER),grep -E "$$(echo '$(FILTER)' | sed 's/,/|/g')",cat) | sort) all: install