Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions all-examples/go/v3/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Makefile for S3 Encryption Client Go v3 Example

# Default target
.PHONY: all install clean run help

# Variables
SCRIPT = main.go

# Default arguments for running the example
# Override these when calling make run
BUCKET_NAME ?= avp-21638
OBJECT_KEY ?= s3ec-go-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 Go modules
install:
@echo "Installing Go dependencies..."
@go mod tidy
@echo "Dependencies installed successfully!"

# Clean Go artifacts
clean:
@echo "Cleaning Go artifacts..."
@go clean
@echo "Clean completed!"

# Run the example with default arguments
run: install
@echo "Running S3 Encryption Client v3 Go example..."
@echo "Bucket: $(BUCKET_NAME)"
@echo "Object Key: $(OBJECT_KEY)"
@echo "KMS Key ID: $(KMS_KEY_ID)"
@echo "Region: $(AWS_REGION)"
@echo ""
@go run $(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
@go run $(SCRIPT) $(BUCKET_NAME) $(OBJECT_KEY) $(KMS_KEY_ID) $(AWS_REGION)

# Show help
help:
@echo "S3 Encryption Client Go v3 Example Makefile"
@echo ""
@echo "Available targets:"
@echo " install - Install Go dependencies using Go modules"
@echo " run - Install dependencies and run the example with default parameters"
@echo " run-custom - Install dependencies and run with custom parameters"
@echo " clean - Remove Go 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 " - Go 1.24+ installed on the system"
@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 Go SDK (included in local-go-s3ec)"
55 changes: 55 additions & 0 deletions all-examples/go/v3/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# S3 Encryption Client Go v3 Example

This example demonstrates how to use the Amazon S3 Encryption Client v3 for Go to perform client-side encryption and decryption of objects.

## Prerequisites

1. **Go**: Requires Go 1.24 or later
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**: You'll need a KMS key ID or ARN. You can use the default example key: `arn:aws:kms:us-east-2:648638458147:key/a47079da-17e4-45a5-b82e-2bac101cad01`
4. **S3 Bucket**: An existing S3 bucket where you have read/write permissions

## Setup

1. Initialize submodules and download dependencies:
```bash
make install
```

Or manually:
```bash
go mod tidy
```

**Note**: This example uses a local submodule for the S3EC Go v3 library via the `replace` directive in `go.mod`.

## Usage

### Using Make (Recommended)

Run the example with default parameters:
```bash
make run
```

Run with custom parameters:
```bash
make run BUCKET_NAME=my-bucket OBJECT_KEY=my-key KMS_KEY_ID=my-kms-key AWS_REGION=my-region
```

### Manual Usage

Run the example with the following command:

```bash
go run main.go <bucket-name> <object-key> <kms-key-id> <region>
```

### Example:

```bash
go run main.go my-test-bucket s3ec-go-v3-test arn:aws:kms:us-east-2:648638458147:key/a47079da-17e4-45a5-b82e-2bac101cad01 us-east-2
```
32 changes: 32 additions & 0 deletions all-examples/go/v3/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
module github.com/aws/amazon-s3-encryption-client-python/all-examples/go/v3

go 1.24

require (
github.com/aws/amazon-s3-encryption-client-go/v3 v3.1.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
)

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
)

// S3EC Go V3 uses a local submodule for development
replace github.com/aws/amazon-s3-encryption-client-go/v3 => ./local-go-s3ec/v3
40 changes: 40 additions & 0 deletions all-examples/go/v3/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
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=
1 change: 1 addition & 0 deletions all-examples/go/v3/local-go-s3ec
171 changes: 171 additions & 0 deletions all-examples/go/v3/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
package main

import (
"context"
"fmt"
"io"
"os"
"strings"

"github.com/aws/amazon-s3-encryption-client-go/v3/client"
"github.com/aws/amazon-s3-encryption-client-go/v3/commitment"
"github.com/aws/amazon-s3-encryption-client-go/v3/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"
)

func main() {
// Check command line arguments
if len(os.Args) != 5 {
fmt.Printf("Usage: %s <bucket-name> <object-key> <kms-key-id> <region>\n", os.Args[0])
fmt.Printf("Example: %s avp-21638 s3ec-go-v3 arn:aws:kms:us-east-2:648638458147:key/a47079da-17e4-45a5-b82e-2bac101cad01 us-east-2\n", os.Args[0])
os.Exit(1)
}

bucketName := os.Args[1]
objectKey := os.Args[2]
kmsKeyID := os.Args[3]
region := os.Args[4]

fmt.Println("=== S3 Encryption Client v3 Example (Go) ===")
fmt.Printf("Bucket: %s\n", bucketName)
fmt.Printf("Object Key: %s\n", objectKey)
fmt.Printf("KMS Key ID: %s\n", kmsKeyID)
fmt.Printf("Region: %s\n", region)
fmt.Println()

// Test data for encryption
testData := "Hello, World! This is a test message for S3 encryption client v3 in Go."
fmt.Printf("Original data: %s\n", testData)
fmt.Printf("Data length: %d bytes\n", len(testData))
fmt.Println()

fmt.Println("--- Initialize S3 Encryption Client v3 ---")

// Create regular S3 client
cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRegion(region))
if err != nil {
fmt.Printf("Error loading AWS config: %v\n", err)
os.Exit(1)
}
s3Client := s3.NewFromConfig(cfg)

// Create KMS client
kmsClient := kms.NewFromConfig(cfg)

// Create KMS keyring
keyring := materials.NewKmsKeyring(kmsClient, kmsKeyID)

// Create Cryptographic Materials Manager
cmm, err := materials.NewCryptographicMaterialsManager(keyring)
if err != nil {
fmt.Printf("Error creating CMM: %v\n", err)
os.Exit(1)
}

// Create S3 Encryption Client v3
encryptionClient, err := client.New(s3Client, cmm, func(options *client.EncryptionClientOptions) {
options.CommitmentPolicy = commitment.FORBID_ENCRYPT_ALLOW_DECRYPT
})
if err != nil {
fmt.Printf("Error creating S3 Encryption Client: %v\n", err)
os.Exit(1)
}

fmt.Println("Successfully initialized S3 Encryption Client v3")
fmt.Println("--- Encrypt and Upload Object to S3 ---")

// Add encryption context
encryptionContext := map[string]string{
"purpose": "example",
"version": "v3",
"language": "go",
}

// Create context with encryption context
ctx := context.WithValue(context.Background(), "EncryptionContext", encryptionContext)

// Upload encrypted object using S3 Encryption Client
putInput := &s3.PutObjectInput{
Bucket: aws.String(bucketName),
Key: aws.String(objectKey),
Body: strings.NewReader(testData),
}

_, err = encryptionClient.PutObject(ctx, putInput)
if err != nil {
if strings.Contains(err.Error(), "NoSuchBucket") {
fmt.Printf("Error: S3 bucket '%s' does not exist or is not accessible\n", bucketName)
} else if strings.Contains(err.Error(), "NotFoundException") {
fmt.Printf("Error: KMS key '%s' not found or not accessible\n", kmsKeyID)
} else {
fmt.Printf("Error uploading encrypted object: %v\n", err)
}
os.Exit(1)
}

fmt.Println("Successfully uploaded encrypted object to S3!")
fmt.Printf(" Bucket: %s\n", bucketName)
fmt.Printf(" Key: %s\n", objectKey)
fmt.Printf(" Encryption Context: %v\n", encryptionContext)
fmt.Println()

fmt.Println("--- Download and Decrypt Object from S3 ---")

// Download and decrypt object using S3 Encryption Client
getInput := &s3.GetObjectInput{
Bucket: aws.String(bucketName),
Key: aws.String(objectKey),
}

getResponse, err := encryptionClient.GetObject(ctx, getInput)
if err != nil {
fmt.Printf("Error downloading and decrypting object: %v\n", err)
os.Exit(1)
}
defer getResponse.Body.Close()

// Read the decrypted data
decryptedData, err := io.ReadAll(getResponse.Body)
if err != nil {
fmt.Printf("Error reading decrypted data: %v\n", err)
os.Exit(1)
}

fmt.Println("Successfully downloaded and decrypted object from S3!")
fmt.Printf(" Object size: %d bytes\n", len(decryptedData))
fmt.Printf(" Decrypted data: %s\n", string(decryptedData))
fmt.Println()

fmt.Println("--- Verify Roundtrip Success ---")

// Verify the roundtrip was successful
if string(decryptedData) == testData {
fmt.Println("SUCCESS: Roundtrip encryption/decryption completed successfully!")
fmt.Println(" Original data matches decrypted data")
fmt.Println(" Data integrity verified")
} else {
fmt.Println("ERROR: Roundtrip failed - data mismatch")
fmt.Printf(" Original: %s\n", testData)
fmt.Printf(" Decrypted: %s\n", string(decryptedData))
os.Exit(1)
}

// Optionally Delete the Object
//fmt.Println("--- Cleanup ---")
// Clean up the test object using regular S3 client
// _, err = s3Client.DeleteObject(context.TODO(), &s3.DeleteObjectInput{
// Bucket: aws.String(bucketName),
// Key: aws.String(objectKey),
// })
// if err != nil {
// fmt.Printf("Error deleting test object: %v\n", err)
// } else {
// fmt.Println("Test object deleted from S3")
// }

fmt.Println()
fmt.Println("=== Example completed successfully! ===")
}
Loading