diff --git a/all-examples/php/v2/.gitignore b/all-examples/php/v2/.gitignore new file mode 100644 index 00000000..07108589 --- /dev/null +++ b/all-examples/php/v2/.gitignore @@ -0,0 +1,4 @@ +vendor/* +cookies.txt +server.pid +composer.lock \ No newline at end of file diff --git a/all-examples/php/v2/Makefile b/all-examples/php/v2/Makefile new file mode 100644 index 00000000..0747d7b8 --- /dev/null +++ b/all-examples/php/v2/Makefile @@ -0,0 +1,71 @@ +# Makefile for S3 Encryption Client PHP v2 Example + +# Default target +.PHONY: all install clean run help + +# Variables +SCRIPT = main.php + +# Default arguments for running the example +# Override these when calling make run +BUCKET_NAME ?= avp-21638 +OBJECT_KEY ?= s3ec-php-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 Composer +install: + @echo "Installing PHP dependencies..." + @composer install --no-dev --optimize-autoloader + @echo "Dependencies installed successfully!" + +# Clean composer artifacts +clean: + @echo "Cleaning composer artifacts..." + @rm -rf vendor/ + @rm -f composer.lock + @echo "Clean completed!" + +# Run the example with default arguments +run: install + @echo "Running S3 Encryption Client v2 PHP example..." + @echo "Bucket: $(BUCKET_NAME)" + @echo "Object Key: $(OBJECT_KEY)" + @echo "KMS Key ID: $(KMS_KEY_ID)" + @echo "Region: $(AWS_REGION)" + @echo "" + @php $(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 + @php $(SCRIPT) $(BUCKET_NAME) $(OBJECT_KEY) $(KMS_KEY_ID) $(AWS_REGION) + +# Show help +help: + @echo "S3 Encryption Client PHP v2 Example Makefile" + @echo "" + @echo "Available targets:" + @echo " install - Install PHP dependencies using Composer" + @echo " run - Install dependencies and run the example with default parameters" + @echo " run-custom - Install dependencies and run with custom parameters" + @echo " clean - Remove composer artifacts (vendor/, composer.lock)" + @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 " - PHP 7.4+ installed on the system" + @echo " - Composer installed (https://getcomposer.org/)" + @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 PHP SDK (included in local-php-sdk)" diff --git a/all-examples/php/v2/composer.json b/all-examples/php/v2/composer.json new file mode 100644 index 00000000..914bf900 --- /dev/null +++ b/all-examples/php/v2/composer.json @@ -0,0 +1,33 @@ +{ + "name": "aws/s3ec-php-v2-example", + "description": "PHP v2 example for Amazon S3 Encryption Client", + "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", + "ramsey/uuid": "^4.9" + }, + "autoload": { + "psr-4": { + "AWS\\S3EC\\Example\\": "src/" + } + }, + "config": { + "optimize-autoloader": true, + "platform": { + "php": "8.1" + } + }, + "minimum-stability": "dev", + "prefer-stable": true +} diff --git a/all-examples/php/v2/local-php-sdk b/all-examples/php/v2/local-php-sdk new file mode 120000 index 00000000..04ad0cf7 --- /dev/null +++ b/all-examples/php/v2/local-php-sdk @@ -0,0 +1 @@ +../../../test-server/php-v2-transition-server/local-php-sdk \ No newline at end of file diff --git a/all-examples/php/v2/main.php b/all-examples/php/v2/main.php new file mode 100755 index 00000000..df2fdd32 --- /dev/null +++ b/all-examples/php/v2/main.php @@ -0,0 +1,161 @@ +#!/usr/bin/env php + \n"; + echo "Example: {$GLOBALS['argv'][0]} avp-21638 s3ec-php-v2 arn:aws:kms:us-east-2:648638458147:key/a47079da-17e4-45a5-b82e-2bac101cad01 us-east-2\n"; + exit(1); + } + + $bucketName = $GLOBALS['argv'][1]; + $objectKey = $GLOBALS['argv'][2]; + $kmsKeyId = $GLOBALS['argv'][3]; + $region = $GLOBALS['argv'][4]; + + echo "=== S3 Encryption Client v2 Example (PHP) ===\n"; + echo "Bucket: {$bucketName}\n"; + echo "Object Key: {$objectKey}\n"; + echo "KMS Key ID: {$kmsKeyId}\n"; + echo "Region: {$region}\n"; + echo "\n"; + + try { + // Test data for encryption + $testData = "Hello, World! This is a test message for S3 encryption client v2 in PHP."; + echo "Original data: {$testData}\n"; + echo "Data length: " . strlen($testData) . " bytes\n"; + echo "\n"; + + echo "--- Initialize S3 Encryption Client v2 ---\n"; + + // Create regular S3 client + $s3Client = new S3Client([ + 'region' => $region, + 'version' => 'latest' + ]); + + // Create KMS client + $kmsClient = new KmsClient([ + 'region' => $region, + 'version' => 'latest' + ]); + + // Create S3 Encryption Client v2 + $encryptionClient = new S3EncryptionClientV2($s3Client); + $materialsProvider = new KmsMaterialsProviderV2($kmsClient, $kmsKeyId); + + echo "Successfully initialized S3 Encryption Client v2\n"; + echo "--- Encrypt and Upload Object to S3 ---\n"; + + // Add encryption context + $encryptionContext = [ + 'purpose' => 'example', + 'version' => 'v2', + 'language' => 'php' + ]; + + $cipherOptions = [ + 'Cipher' => 'gcm', + 'KeySize' => 256, + ]; + + // Upload encrypted object using S3 Encryption Client + $putResponse = $encryptionClient->putObject([ + 'Bucket' => $bucketName, + 'Key' => $objectKey, + 'Body' => $testData, + '@MaterialsProvider' => $materialsProvider, + '@KmsEncryptionContext' => $encryptionContext, + '@CipherOptions' => $cipherOptions, + ]); + + echo "Successfully uploaded encrypted object to S3!\n"; + echo " Bucket: {$bucketName}\n"; + echo " Key: {$objectKey}\n"; + echo " Encryption Context: " . json_encode($encryptionContext) . "\n"; + echo "\n"; + + echo "--- Download and Decrypt Object from S3 ---\n"; + + // Download and decrypt object using S3 Encryption Client + $getResponse = $encryptionClient->getObject([ + 'Bucket' => $bucketName, + 'Key' => $objectKey, + '@KmsEncryptionContext' => $encryptionContext, + '@MaterialsProvider' => $materialsProvider, + '@CommitmentPolicy' => 'FORBID_ENCRYPT_ALLOW_DECRYPT', + '@SecurityProfile' => 'V2' + ]); + + // Read the decrypted data + $decryptedData = (string) $getResponse['Body']; + + echo "Successfully downloaded and decrypted object from S3!\n"; + echo " Object size: " . strlen($decryptedData) . " bytes\n"; + echo " Decrypted data: {$decryptedData}\n"; + echo "\n"; + + echo "--- Verify Roundtrip Success ---\n"; + + // Verify the roundtrip was successful + if ($decryptedData === $testData) { + echo "SUCCESS: Roundtrip encryption/decryption completed successfully!\n"; + echo " Original data matches decrypted data\n"; + echo " Data integrity verified\n"; + } else { + echo "ERROR: Roundtrip failed - data mismatch\n"; + echo " Original: {$testData}\n"; + echo " Decrypted: {$decryptedData}\n"; + exit(1); + } + + // Optionally Delete the Object + // echo "--- Cleanup ---\n"; + // Clean up the test object using regular S3 client + // $s3Client->deleteObject([ + // 'Bucket' => $bucketName, + // 'Key' => $objectKey + // ]); + // echo "Test object deleted from S3\n"; + + echo "\n"; + echo "=== Example completed successfully! ===\n"; + + } catch (AwsException $e) { + $errorCode = $e->getAwsErrorCode(); + $errorMessage = $e->getMessage(); + + if (strpos($errorCode, 'NoSuchBucket') !== false) { + echo "Error: S3 bucket '{$bucketName}' does not exist or is not accessible\n"; + echo " {$errorMessage}\n"; + } elseif (strpos($errorCode, 'NotFoundException') !== false) { + echo "Error: KMS key '{$kmsKeyId}' not found or not accessible\n"; + echo " {$errorMessage}\n"; + } elseif (strpos($errorMessage, 'encryption') !== false) { + echo "S3 Encryption Error: {$errorMessage}\n"; + } else { + echo "AWS Service Error: {$errorMessage}\n"; + echo " Error Code: {$errorCode}\n"; + } + exit(1); + } catch (Exception $e) { + echo "Unexpected error: {$e->getMessage()}\n"; + echo " File: {$e->getFile()}:{$e->getLine()}\n"; + exit(1); + } +} + +// Run the main function if this script is executed directly +if (php_sapi_name() === 'cli' && isset($GLOBALS['argv']) && basename($GLOBALS['argv'][0]) === basename(__FILE__)) { + main(); +} diff --git a/all-examples/php/v3/.gitignore b/all-examples/php/v3/.gitignore new file mode 100644 index 00000000..07108589 --- /dev/null +++ b/all-examples/php/v3/.gitignore @@ -0,0 +1,4 @@ +vendor/* +cookies.txt +server.pid +composer.lock \ No newline at end of file diff --git a/all-examples/php/v3/Makefile b/all-examples/php/v3/Makefile new file mode 100644 index 00000000..328a901a --- /dev/null +++ b/all-examples/php/v3/Makefile @@ -0,0 +1,71 @@ +# Makefile for S3 Encryption Client PHP v3 Example + +# Default target +.PHONY: all install clean run help + +# Variables +SCRIPT = main.php + +# Default arguments for running the example +# Override these when calling make run +BUCKET_NAME ?= avp-21638 +OBJECT_KEY ?= s3ec-php-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 Composer +install: + @echo "Installing PHP dependencies..." + @composer install --no-dev --optimize-autoloader + @echo "Dependencies installed successfully!" + +# Clean composer artifacts +clean: + @echo "Cleaning composer artifacts..." + @rm -rf vendor/ + @rm -f composer.lock + @echo "Clean completed!" + +# Run the example with default arguments +run: install + @echo "Running S3 Encryption Client v3 PHP example..." + @echo "Bucket: $(BUCKET_NAME)" + @echo "Object Key: $(OBJECT_KEY)" + @echo "KMS Key ID: $(KMS_KEY_ID)" + @echo "Region: $(AWS_REGION)" + @echo "" + @php $(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 + @php $(SCRIPT) $(BUCKET_NAME) $(OBJECT_KEY) $(KMS_KEY_ID) $(AWS_REGION) + +# Show help +help: + @echo "S3 Encryption Client PHP v3 Example Makefile" + @echo "" + @echo "Available targets:" + @echo " install - Install PHP dependencies using Composer" + @echo " run - Install dependencies and run the example with default parameters" + @echo " run-custom - Install dependencies and run with custom parameters" + @echo " clean - Remove composer artifacts (vendor/, composer.lock)" + @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 " - PHP 7.4+ installed on the system" + @echo " - Composer installed (https://getcomposer.org/)" + @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 PHP SDK (included in local-php-sdk)" diff --git a/all-examples/php/v3/composer.json b/all-examples/php/v3/composer.json new file mode 100644 index 00000000..2ad2469a --- /dev/null +++ b/all-examples/php/v3/composer.json @@ -0,0 +1,33 @@ +{ + "name": "aws/s3ec-php-v3-example", + "description": "PHP v3 example for Amazon S3 Encryption Client", + "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", + "ramsey/uuid": "^4.9" + }, + "autoload": { + "psr-4": { + "AWS\\S3EC\\Example\\": "src/" + } + }, + "config": { + "optimize-autoloader": true, + "platform": { + "php": "8.1" + } + }, + "minimum-stability": "dev", + "prefer-stable": true +} diff --git a/all-examples/php/v3/local-php-sdk b/all-examples/php/v3/local-php-sdk new file mode 120000 index 00000000..3b9b4cd7 --- /dev/null +++ b/all-examples/php/v3/local-php-sdk @@ -0,0 +1 @@ +../../../test-server/php-v3-server/local-php-sdk \ No newline at end of file diff --git a/all-examples/php/v3/main.php b/all-examples/php/v3/main.php new file mode 100755 index 00000000..e22519c3 --- /dev/null +++ b/all-examples/php/v3/main.php @@ -0,0 +1,163 @@ +#!/usr/bin/env php + \n"; + echo "Example: {$GLOBALS['argv'][0]} avp-21638 s3ec-php-v3 arn:aws:kms:us-east-2:648638458147:key/a47079da-17e4-45a5-b82e-2bac101cad01 us-east-2\n"; + exit(1); + } + + $bucketName = $GLOBALS['argv'][1]; + $objectKey = $GLOBALS['argv'][2]; + $kmsKeyId = $GLOBALS['argv'][3]; + $region = $GLOBALS['argv'][4]; + + echo "=== S3 Encryption Client v3 Example (PHP) ===\n"; + echo "Bucket: {$bucketName}\n"; + echo "Object Key: {$objectKey}\n"; + echo "KMS Key ID: {$kmsKeyId}\n"; + echo "Region: {$region}\n"; + echo "\n"; + + try { + // Test data for encryption + $testData = "Hello, World! This is a test message for S3 encryption client v3 in PHP."; + echo "Original data: {$testData}\n"; + echo "Data length: " . strlen($testData) . " bytes\n"; + echo "\n"; + + echo "--- Initialize S3 Encryption Client v3 ---\n"; + + // Create regular S3 client + $s3Client = new S3Client([ + 'region' => $region, + 'version' => 'latest' + ]); + + // Create KMS client + $kmsClient = new KmsClient([ + 'region' => $region, + 'version' => 'latest' + ]); + + // Create S3 Encryption Client v3 + // Create S3 Encryption Client v2 + $encryptionClient = new S3EncryptionClientV3($s3Client); + $materialsProvider = new KmsMaterialsProviderV3($kmsClient, $kmsKeyId); + + echo "Successfully initialized S3 Encryption Client v3\n"; + echo "--- Encrypt and Upload Object to S3 ---\n"; + + // Add encryption context + $encryptionContext = [ + 'purpose' => 'example', + 'version' => 'v3', + 'language' => 'php' + ]; + + $cipherOptions = [ + 'Cipher' => 'gcm', + 'KeySize' => 256, + ]; + + // Upload encrypted object using S3 Encryption Client + $putResponse = $encryptionClient->putObject([ + 'Bucket' => $bucketName, + 'Key' => $objectKey, + 'Body' => $testData, + '@MaterialsProvider' => $materialsProvider, + '@KmsEncryptionContext' => $encryptionContext, + '@CommitmentPolicy' => "REQUIRE_ENCRYPT_REQUIRE_DECRYPT", + '@CipherOptions' => $cipherOptions, + ]); + + echo "Successfully uploaded encrypted object to S3!\n"; + echo " Bucket: {$bucketName}\n"; + echo " Key: {$objectKey}\n"; + echo " Encryption Context: " . json_encode($encryptionContext) . "\n"; + echo "\n"; + + echo "--- Download and Decrypt Object from S3 ---\n"; + + // Download and decrypt object using S3 Encryption Client + $getResponse = $encryptionClient->getObject([ + 'Bucket' => $bucketName, + 'Key' => $objectKey, + '@KmsEncryptionContext' => $encryptionContext, + '@MaterialsProvider' => $materialsProvider, + '@CommitmentPolicy' => "REQUIRE_ENCRYPT_REQUIRE_DECRYPT", + '@SecurityProfile' => 'V3' + ]); + + // Read the decrypted data + $decryptedData = (string) $getResponse['Body']; + + echo "Successfully downloaded and decrypted object from S3!\n"; + echo " Object size: " . strlen($decryptedData) . " bytes\n"; + echo " Decrypted data: {$decryptedData}\n"; + echo "\n"; + + echo "--- Verify Roundtrip Success ---\n"; + + // Verify the roundtrip was successful + if ($decryptedData === $testData) { + echo "SUCCESS: Roundtrip encryption/decryption completed successfully!\n"; + echo " Original data matches decrypted data\n"; + echo " Data integrity verified\n"; + } else { + echo "ERROR: Roundtrip failed - data mismatch\n"; + echo " Original: {$testData}\n"; + echo " Decrypted: {$decryptedData}\n"; + exit(1); + } + + // Optionally Delete the Object + // echo "--- Cleanup ---\n"; + // Clean up the test object using regular S3 client + // $s3Client->deleteObject([ + // 'Bucket' => $bucketName, + // 'Key' => $objectKey + // ]); + // echo "Test object deleted from S3\n"; + + echo "\n"; + echo "=== Example completed successfully! ===\n"; + + } catch (AwsException $e) { + $errorCode = $e->getAwsErrorCode(); + $errorMessage = $e->getMessage(); + + if (strpos($errorCode, 'NoSuchBucket') !== false) { + echo "Error: S3 bucket '{$bucketName}' does not exist or is not accessible\n"; + echo " {$errorMessage}\n"; + } elseif (strpos($errorCode, 'NotFoundException') !== false) { + echo "Error: KMS key '{$kmsKeyId}' not found or not accessible\n"; + echo " {$errorMessage}\n"; + } elseif (strpos($errorMessage, 'encryption') !== false) { + echo "S3 Encryption Error: {$errorMessage}\n"; + } else { + echo "AWS Service Error: {$errorMessage}\n"; + echo " Error Code: {$errorCode}\n"; + } + exit(1); + } catch (Exception $e) { + echo "Unexpected error: {$e->getMessage()}\n"; + echo " File: {$e->getFile()}:{$e->getLine()}\n"; + exit(1); + } +} + +// Run the main function if this script is executed directly +if (php_sapi_name() === 'cli' && isset($GLOBALS['argv']) && basename($GLOBALS['argv'][0]) === basename(__FILE__)) { + main(); +} diff --git a/test-server/php-v2-transition-server/local-php-sdk b/test-server/php-v2-transition-server/local-php-sdk deleted file mode 160000 index 35a52086..00000000 --- a/test-server/php-v2-transition-server/local-php-sdk +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 35a52086c5ccf7f5e62e3c17e210923e129c823b diff --git a/test-server/php-v2-transition-server/local-php-sdk b/test-server/php-v2-transition-server/local-php-sdk new file mode 120000 index 00000000..4610ddb9 --- /dev/null +++ b/test-server/php-v2-transition-server/local-php-sdk @@ -0,0 +1 @@ +../php-v3-server/local-php-sdk \ No newline at end of file diff --git a/test-server/php-v3-server/local-php-sdk b/test-server/php-v3-server/local-php-sdk index 35a52086..2cb0cda2 160000 --- a/test-server/php-v3-server/local-php-sdk +++ b/test-server/php-v3-server/local-php-sdk @@ -1 +1 @@ -Subproject commit 35a52086c5ccf7f5e62e3c17e210923e129c823b +Subproject commit 2cb0cda27812fae3f16e719df4b22b5c08526148