You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							184 lines
						
					
					
						
							6.9 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							184 lines
						
					
					
						
							6.9 KiB
						
					
					
				
								package sse_test
							 | 
						|
								
							 | 
						|
								import (
							 | 
						|
									"bytes"
							 | 
						|
									"context"
							 | 
						|
									"io"
							 | 
						|
									"testing"
							 | 
						|
									"time"
							 | 
						|
								
							 | 
						|
									"github.com/aws/aws-sdk-go-v2/aws"
							 | 
						|
									"github.com/aws/aws-sdk-go-v2/service/s3"
							 | 
						|
									"github.com/aws/aws-sdk-go-v2/service/s3/types"
							 | 
						|
									"github.com/stretchr/testify/assert"
							 | 
						|
									"github.com/stretchr/testify/require"
							 | 
						|
								)
							 | 
						|
								
							 | 
						|
								// TestSSEKMSOpenBaoIntegration tests SSE-KMS with real OpenBao KMS provider
							 | 
						|
								// This test verifies that SeaweedFS can successfully encrypt and decrypt data
							 | 
						|
								// using actual KMS operations through OpenBao, not just mock key IDs
							 | 
						|
								func TestSSEKMSOpenBaoIntegration(t *testing.T) {
							 | 
						|
									ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
							 | 
						|
									defer cancel()
							 | 
						|
								
							 | 
						|
									client, err := createS3Client(ctx, defaultConfig)
							 | 
						|
									require.NoError(t, err, "Failed to create S3 client")
							 | 
						|
								
							 | 
						|
									bucketName, err := createTestBucket(ctx, client, defaultConfig.BucketPrefix+"sse-kms-openbao-")
							 | 
						|
									require.NoError(t, err, "Failed to create test bucket")
							 | 
						|
									defer cleanupTestBucket(ctx, client, bucketName)
							 | 
						|
								
							 | 
						|
									t.Run("Basic SSE-KMS with OpenBao", func(t *testing.T) {
							 | 
						|
										testData := []byte("Hello, SSE-KMS with OpenBao integration!")
							 | 
						|
										objectKey := "test-openbao-kms-object"
							 | 
						|
										kmsKeyID := "test-key-123" // This key should exist in OpenBao
							 | 
						|
								
							 | 
						|
										// Upload object with SSE-KMS
							 | 
						|
										putResp, err := client.PutObject(ctx, &s3.PutObjectInput{
							 | 
						|
											Bucket:               aws.String(bucketName),
							 | 
						|
											Key:                  aws.String(objectKey),
							 | 
						|
											Body:                 bytes.NewReader(testData),
							 | 
						|
											ServerSideEncryption: types.ServerSideEncryptionAwsKms,
							 | 
						|
											SSEKMSKeyId:          aws.String(kmsKeyID),
							 | 
						|
										})
							 | 
						|
										require.NoError(t, err, "Failed to upload SSE-KMS object with OpenBao")
							 | 
						|
										assert.NotEmpty(t, aws.ToString(putResp.ETag), "ETag should be present")
							 | 
						|
								
							 | 
						|
										// Retrieve and verify object
							 | 
						|
										getResp, err := client.GetObject(ctx, &s3.GetObjectInput{
							 | 
						|
											Bucket: aws.String(bucketName),
							 | 
						|
											Key:    aws.String(objectKey),
							 | 
						|
										})
							 | 
						|
										require.NoError(t, err, "Failed to retrieve SSE-KMS object")
							 | 
						|
										defer getResp.Body.Close()
							 | 
						|
								
							 | 
						|
										// Verify content matches (this proves encryption/decryption worked)
							 | 
						|
										retrievedData, err := io.ReadAll(getResp.Body)
							 | 
						|
										require.NoError(t, err, "Failed to read retrieved data")
							 | 
						|
										assert.Equal(t, testData, retrievedData, "Decrypted data should match original")
							 | 
						|
								
							 | 
						|
										// Verify SSE-KMS headers are present
							 | 
						|
										assert.Equal(t, types.ServerSideEncryptionAwsKms, getResp.ServerSideEncryption, "Should indicate KMS encryption")
							 | 
						|
										assert.Equal(t, kmsKeyID, aws.ToString(getResp.SSEKMSKeyId), "Should return the KMS key ID used")
							 | 
						|
									})
							 | 
						|
								
							 | 
						|
									t.Run("Multiple KMS Keys with OpenBao", func(t *testing.T) {
							 | 
						|
										testCases := []struct {
							 | 
						|
											keyID     string
							 | 
						|
											data      string
							 | 
						|
											objectKey string
							 | 
						|
										}{
							 | 
						|
											{"test-key-123", "Data encrypted with test-key-123", "object-key-123"},
							 | 
						|
											{"seaweedfs-test-key", "Data encrypted with seaweedfs-test-key", "object-seaweedfs-key"},
							 | 
						|
											{"high-security-key", "Data encrypted with high-security-key", "object-security-key"},
							 | 
						|
										}
							 | 
						|
								
							 | 
						|
										for _, tc := range testCases {
							 | 
						|
											t.Run("Key_"+tc.keyID, func(t *testing.T) {
							 | 
						|
												testData := []byte(tc.data)
							 | 
						|
								
							 | 
						|
												// Upload with specific KMS key
							 | 
						|
												_, err := client.PutObject(ctx, &s3.PutObjectInput{
							 | 
						|
													Bucket:               aws.String(bucketName),
							 | 
						|
													Key:                  aws.String(tc.objectKey),
							 | 
						|
													Body:                 bytes.NewReader(testData),
							 | 
						|
													ServerSideEncryption: types.ServerSideEncryptionAwsKms,
							 | 
						|
													SSEKMSKeyId:          aws.String(tc.keyID),
							 | 
						|
												})
							 | 
						|
												require.NoError(t, err, "Failed to upload with KMS key %s", tc.keyID)
							 | 
						|
								
							 | 
						|
												// Retrieve and verify
							 | 
						|
												getResp, err := client.GetObject(ctx, &s3.GetObjectInput{
							 | 
						|
													Bucket: aws.String(bucketName),
							 | 
						|
													Key:    aws.String(tc.objectKey),
							 | 
						|
												})
							 | 
						|
												require.NoError(t, err, "Failed to retrieve object encrypted with key %s", tc.keyID)
							 | 
						|
												defer getResp.Body.Close()
							 | 
						|
								
							 | 
						|
												retrievedData, err := io.ReadAll(getResp.Body)
							 | 
						|
												require.NoError(t, err, "Failed to read data for key %s", tc.keyID)
							 | 
						|
								
							 | 
						|
												// Verify data integrity (proves real encryption/decryption occurred)
							 | 
						|
												assert.Equal(t, testData, retrievedData, "Data should match for key %s", tc.keyID)
							 | 
						|
												assert.Equal(t, tc.keyID, aws.ToString(getResp.SSEKMSKeyId), "Should return correct key ID")
							 | 
						|
											})
							 | 
						|
										}
							 | 
						|
									})
							 | 
						|
								
							 | 
						|
									t.Run("Large Data with OpenBao KMS", func(t *testing.T) {
							 | 
						|
										// Test with larger data to ensure chunked encryption works
							 | 
						|
										testData := generateTestData(64 * 1024) // 64KB
							 | 
						|
										objectKey := "large-openbao-kms-object"
							 | 
						|
										kmsKeyID := "performance-key"
							 | 
						|
								
							 | 
						|
										// Upload large object with SSE-KMS
							 | 
						|
										_, err := client.PutObject(ctx, &s3.PutObjectInput{
							 | 
						|
											Bucket:               aws.String(bucketName),
							 | 
						|
											Key:                  aws.String(objectKey),
							 | 
						|
											Body:                 bytes.NewReader(testData),
							 | 
						|
											ServerSideEncryption: types.ServerSideEncryptionAwsKms,
							 | 
						|
											SSEKMSKeyId:          aws.String(kmsKeyID),
							 | 
						|
										})
							 | 
						|
										require.NoError(t, err, "Failed to upload large SSE-KMS object")
							 | 
						|
								
							 | 
						|
										// Retrieve and verify large object
							 | 
						|
										getResp, err := client.GetObject(ctx, &s3.GetObjectInput{
							 | 
						|
											Bucket: aws.String(bucketName),
							 | 
						|
											Key:    aws.String(objectKey),
							 | 
						|
										})
							 | 
						|
										require.NoError(t, err, "Failed to retrieve large SSE-KMS object")
							 | 
						|
										defer getResp.Body.Close()
							 | 
						|
								
							 | 
						|
										retrievedData, err := io.ReadAll(getResp.Body)
							 | 
						|
										require.NoError(t, err, "Failed to read large data")
							 | 
						|
								
							 | 
						|
										// Use MD5 comparison for large data
							 | 
						|
										assertDataEqual(t, testData, retrievedData, "Large encrypted data should match original")
							 | 
						|
										assert.Equal(t, kmsKeyID, aws.ToString(getResp.SSEKMSKeyId), "Should return performance key ID")
							 | 
						|
									})
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								// TestSSEKMSOpenBaoAvailability checks if OpenBao KMS is available for testing
							 | 
						|
								// This test can be run separately to verify the KMS setup
							 | 
						|
								func TestSSEKMSOpenBaoAvailability(t *testing.T) {
							 | 
						|
									ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
							 | 
						|
									defer cancel()
							 | 
						|
								
							 | 
						|
									client, err := createS3Client(ctx, defaultConfig)
							 | 
						|
									require.NoError(t, err, "Failed to create S3 client")
							 | 
						|
								
							 | 
						|
									bucketName, err := createTestBucket(ctx, client, defaultConfig.BucketPrefix+"sse-kms-availability-")
							 | 
						|
									require.NoError(t, err, "Failed to create test bucket")
							 | 
						|
									defer cleanupTestBucket(ctx, client, bucketName)
							 | 
						|
								
							 | 
						|
									// Try a simple KMS operation to verify availability
							 | 
						|
									testData := []byte("KMS availability test")
							 | 
						|
									objectKey := "kms-availability-test"
							 | 
						|
									kmsKeyID := "test-key-123"
							 | 
						|
								
							 | 
						|
									// This should succeed if KMS is properly configured
							 | 
						|
									_, err = client.PutObject(ctx, &s3.PutObjectInput{
							 | 
						|
										Bucket:               aws.String(bucketName),
							 | 
						|
										Key:                  aws.String(objectKey),
							 | 
						|
										Body:                 bytes.NewReader(testData),
							 | 
						|
										ServerSideEncryption: types.ServerSideEncryptionAwsKms,
							 | 
						|
										SSEKMSKeyId:          aws.String(kmsKeyID),
							 | 
						|
									})
							 | 
						|
								
							 | 
						|
									if err != nil {
							 | 
						|
										t.Skipf("OpenBao KMS not available for testing: %v", err)
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									t.Logf("OpenBao KMS is available and working")
							 | 
						|
								
							 | 
						|
									// Verify we can retrieve the object
							 | 
						|
									getResp, err := client.GetObject(ctx, &s3.GetObjectInput{
							 | 
						|
										Bucket: aws.String(bucketName),
							 | 
						|
										Key:    aws.String(objectKey),
							 | 
						|
									})
							 | 
						|
									require.NoError(t, err, "Failed to retrieve KMS test object")
							 | 
						|
									defer getResp.Body.Close()
							 | 
						|
								
							 | 
						|
									assert.Equal(t, types.ServerSideEncryptionAwsKms, getResp.ServerSideEncryption)
							 | 
						|
									t.Logf("KMS encryption/decryption working correctly")
							 | 
						|
								}
							 |