From c0cfcd46aac6e570ca2be0426f9d817eb4b2b506 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Tue, 28 Oct 2025 17:23:52 -0700 Subject: [PATCH 01/28] net v4 improved --- .../net-v4-improved-server/.duvet/.gitignore | 3 + .../net-v4-improved-server/.duvet/config.toml | 21 ++++ test-server/net-v4-improved-server/.gitignore | 44 ++++++++ .../Controllers/ClientController.cs | 100 +++++++++++++++++ .../Controllers/ObjectController.cs | 105 ++++++++++++++++++ test-server/net-v4-improved-server/Makefile | 34 ++++++ .../Models/ClientRequest.cs | 30 +++++ .../Models/ClientResponse.cs | 8 ++ .../Models/ErrorModels.cs | 17 +++ .../NetV4ImprovedServer.csproj | 27 +++++ test-server/net-v4-improved-server/Program.cs | 17 +++ test-server/net-v4-improved-server/README.md | 66 +++++++++++ .../Services/ClientCacheService.cs | 28 +++++ .../net-v4-improved-server-backup.sln | 24 ++++ 14 files changed, 524 insertions(+) create mode 100644 test-server/net-v4-improved-server/.duvet/.gitignore create mode 100644 test-server/net-v4-improved-server/.duvet/config.toml create mode 100644 test-server/net-v4-improved-server/.gitignore create mode 100644 test-server/net-v4-improved-server/Controllers/ClientController.cs create mode 100644 test-server/net-v4-improved-server/Controllers/ObjectController.cs create mode 100644 test-server/net-v4-improved-server/Makefile create mode 100644 test-server/net-v4-improved-server/Models/ClientRequest.cs create mode 100644 test-server/net-v4-improved-server/Models/ClientResponse.cs create mode 100644 test-server/net-v4-improved-server/Models/ErrorModels.cs create mode 100644 test-server/net-v4-improved-server/NetV4ImprovedServer.csproj create mode 100644 test-server/net-v4-improved-server/Program.cs create mode 100644 test-server/net-v4-improved-server/README.md create mode 100644 test-server/net-v4-improved-server/Services/ClientCacheService.cs create mode 100644 test-server/net-v4-improved-server/net-v4-improved-server-backup.sln diff --git a/test-server/net-v4-improved-server/.duvet/.gitignore b/test-server/net-v4-improved-server/.duvet/.gitignore new file mode 100644 index 00000000..93956e36 --- /dev/null +++ b/test-server/net-v4-improved-server/.duvet/.gitignore @@ -0,0 +1,3 @@ +reports/ +requirements/ +specification/ \ No newline at end of file diff --git a/test-server/net-v4-improved-server/.duvet/config.toml b/test-server/net-v4-improved-server/.duvet/config.toml new file mode 100644 index 00000000..04d2e812 --- /dev/null +++ b/test-server/net-v4-improved-server/.duvet/config.toml @@ -0,0 +1,21 @@ +'$schema' = "https://awslabs.github.io/duvet/config/v0.4.0.json" + +[[source]] +pattern = "**/*.cs" + +# Include required specifications here +[[specification]] +source = "../specification/s3-encryption/data-format/content-metadata.md" +[[specification]] +source = "../specification/s3-encryption/data-format/metadata-strategy.md" +[[specification]] +source = "../specification/s3-encryption/encryption.md" +[[specification]] +source = "../specification/s3-encryption/key-derivation.md" + +[report.html] +enabled = true + +# Enable snapshots to prevent requirement coverage regressions +[report.snapshot] +enabled = false diff --git a/test-server/net-v4-improved-server/.gitignore b/test-server/net-v4-improved-server/.gitignore new file mode 100644 index 00000000..4c20cbc8 --- /dev/null +++ b/test-server/net-v4-improved-server/.gitignore @@ -0,0 +1,44 @@ +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# NuGet Packages +*.nupkg +*.snupkg +packages/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# VS Code +.vscode/ + +# macOS +.DS_Store + +# Temporary files +*.tmp +*.temp diff --git a/test-server/net-v4-improved-server/Controllers/ClientController.cs b/test-server/net-v4-improved-server/Controllers/ClientController.cs new file mode 100644 index 00000000..f65176c7 --- /dev/null +++ b/test-server/net-v4-improved-server/Controllers/ClientController.cs @@ -0,0 +1,100 @@ +using System.Text.Json; +using Amazon.Extensions.S3.Encryption; +using Amazon.Extensions.S3.Encryption.Primitives; +using Microsoft.AspNetCore.Mvc; +using NetV4ImprovedServer.Models; +using NetV4ImprovedServer.Services; + +namespace NetV4ImprovedServer.Controllers; + +[ApiController] +[Route("[controller]")] +public class ClientController(IClientCacheService clientCacheService, ILogger logger) : ControllerBase +{ + [HttpPost] + public IActionResult CreateClient([FromBody] ClientRequest request) + { + // Return 501 for not implemented features by the server + if (request.Config.EnableDelayedAuthenticationMode) + return StatusCode(501, new GenericServerError { Message = "EnableDelayedAuthenticationMode not supported" }); + if (request.Config.SetBufferSize.HasValue) + return StatusCode(501, new GenericServerError { Message = "SetBufferSize not supported" }); + if (request.Config.KeyMaterial.RsaKey != null) + return StatusCode(501, new GenericServerError { Message = "RsaKey not supported" }); + if (request.Config.KeyMaterial.AesKey != null) + return StatusCode(501, new GenericServerError { Message = "AesKey not supported" }); + + var kmsKeyId = request.Config.KeyMaterial.KmsKeyId; + var enableLegacyUnauthenticatedModes = request.Config.EnableLegacyUnauthenticatedModes; + var enableLegacyWrappingAlgorithms = request.Config.EnableLegacyWrappingAlgorithms; + + try + { + // Parse CommitmentPolicy enum + CommitmentPolicy? commitmentPolicy = null; + if (!string.IsNullOrEmpty(request.Config.CommitmentPolicy)) + { + commitmentPolicy = request.Config.CommitmentPolicy switch + { + "FORBID_ENCRYPT_ALLOW_DECRYPT" => CommitmentPolicy.ForbidEncryptAllowDecrypt, + "REQUIRE_ENCRYPT_ALLOW_DECRYPT" => CommitmentPolicy.RequireEncryptAllowDecrypt, + "REQUIRE_ENCRYPT_REQUIRE_DECRYPT" => CommitmentPolicy.RequireEncryptRequireDecrypt, + _ => throw new ArgumentException($"Unsupported CommitmentPolicy: {request.Config.CommitmentPolicy}") + }; + } + + ContentEncryptionAlgorithm contextEncAlg = ContentEncryptionAlgorithm.AesGcmWithCommitment; + if (commitmentPolicy != null && commitmentPolicy.Value == CommitmentPolicy.ForbidEncryptAllowDecrypt) + { + contextEncAlg = ContentEncryptionAlgorithm.AesGcm; + } + + // The POST request does not contain encryption context. + // However, encryption context is a required field when using KMS. + // So, we are passing empty dictionary. + var encryptionContext = new Dictionary(); + var encryptionMaterial = new EncryptionMaterialsV4(kmsKeyId, KmsType.KmsContext, encryptionContext); + logger.LogInformation( + "Created EncryptionMaterialsV4: KMS={KmsKeyId}", + kmsKeyId); + // SecurityProfile V4AndLegacy can decrypt from legacy S3EC and AESGCM but V4 cannot + var enableLegacyMode = enableLegacyUnauthenticatedModes || enableLegacyWrappingAlgorithms; + var securityProfile = enableLegacyMode ? SecurityProfile.V4AndLegacy : SecurityProfile.V4; + + // TODO: We could do this too. + // if (commitmentPolicy.Value == CommitmentPolicy.ForbidEncryptAllowDecrypt) + // { + // logger.LogInformation("CommitmentPolicy is set to FORBID_ENCRYPT_ALLOW_DECRYPT. " + + // "Forcing to Create AmazonS3CryptoConfigurationV4 with security profile: V4AndLegacy,"); + // securityProfile = SecurityProfile.V4AndLegacy; + // } + logger.LogInformation("Created AmazonS3CryptoConfigurationV4 with security profile: {securityProfile}," + + "commitmentPolicy: {commitmentPolicy}, encryptionAlgorithm: {encryptionAlgorithm}", securityProfile.ToString(), commitmentPolicy.Value, contextEncAlg); + + var configuration = new AmazonS3CryptoConfigurationV4(securityProfile, commitmentPolicy.Value, contextEncAlg); + + // Create S3 encryption client + var encryptionClient = new AmazonS3EncryptionClientV4(configuration, encryptionMaterial); + // Add to cache and return client ID + var clientId = clientCacheService.AddClient(encryptionClient); + var response = new ClientResponse { ClientId = clientId }; + + logger.LogInformation("Created S3EC client with ID: {clientId}", clientId); + + return new ContentResult + { + Content = JsonSerializer.Serialize(response), + ContentType = "application/json", + StatusCode = 200 + }; + } + catch (Exception ex) + { + logger.LogError(ex, "Failed to create S3EC client"); + return StatusCode(500, new S3EncryptionClientError + { + Message = $"Failed to create client: {ex.Message}" + }); + } + } +} \ No newline at end of file diff --git a/test-server/net-v4-improved-server/Controllers/ObjectController.cs b/test-server/net-v4-improved-server/Controllers/ObjectController.cs new file mode 100644 index 00000000..0a1b2ee8 --- /dev/null +++ b/test-server/net-v4-improved-server/Controllers/ObjectController.cs @@ -0,0 +1,105 @@ +using System.Text.Json; +using Amazon.S3.Model; +using Microsoft.AspNetCore.Mvc; +using NetV4ImprovedServer.Models; +using NetV4ImprovedServer.Services; + +namespace NetV4ImprovedServer.Controllers; + +[ApiController] +[Route("[controller]")] +public class ObjectController(IClientCacheService clientCacheService, ILogger logger) : ControllerBase +{ + [HttpPut("{bucket}/{key}")] + public async Task PutObject(string bucket, string key) + { + logger.LogInformation("Starting PutObject"); + var clientId = Request.Headers["clientId"].FirstOrDefault(); + if (string.IsNullOrEmpty(clientId)) + return BadRequest(new GenericServerError { Message = "ClientID header is required" }); + + var client = clientCacheService.GetClient(clientId); + if (client == null) + return NotFound(new GenericServerError { Message = $"No client found for ClientID: {clientId}" }); + + try + { + // Read raw body data + using var memoryStream = new MemoryStream(); + // Request is the HTTP request this method is currently handling + await Request.Body.CopyToAsync(memoryStream); + var bodyBytes = memoryStream.ToArray(); + + // Create put request + var putRequest = new PutObjectRequest + { + BucketName = bucket, + Key = key, + InputStream = new MemoryStream(bodyBytes) + }; + + await client.PutObjectAsync(putRequest); + + var response = new { bucket, key }; + + logger.LogInformation( + "Put object succeeded for bucket={bucket}, key={key} and clientId = {clientId}", + bucket, key, clientId); + return new ContentResult + { + Content = JsonSerializer.Serialize(response), + ContentType = "application/json", + StatusCode = 200 + }; + } + catch (Exception ex) + { + logger.LogError(ex, "Failed to put object from S3 for bucket={bucket}, key={key}", bucket, key); + return StatusCode(500, new S3EncryptionClientError { Message = $"Failed to put object: {ex.Message}" }); + } + } + + [HttpGet("{bucket}/{key}")] + public async Task GetObject(string bucket, string key) + { + logger.LogInformation("Starting GetObject"); + var clientId = Request.Headers["clientId"].FirstOrDefault(); + if (string.IsNullOrEmpty(clientId)) + return BadRequest(new GenericServerError { Message = "ClientID header is required" }); + + var client = clientCacheService.GetClient(clientId); + if (client == null) + return NotFound(new GenericServerError { Message = $"No client found for ClientID: {clientId}" }); + + try + { + var getRequest = new GetObjectRequest + { + BucketName = bucket, + Key = key + }; + var response = await client.GetObjectAsync(getRequest); + logger.LogInformation("Got object from S3 for bucket={bucket}, key={key}", bucket, key); + // Read response body + using var memoryStream = new MemoryStream(); + await response.ResponseStream.CopyToAsync(memoryStream); + var bodyBytes = memoryStream.ToArray(); + + // Convert metadata to content-metadata header format + var metadataList = response.Metadata.Keys + .Select(metaDataKey => $"{metaDataKey}={response.Metadata[metaDataKey]}") + .ToList(); + var metadataStr = string.Join(",", metadataList); + + // Set response headers + Response.Headers["Content-Metadata"] = metadataStr; + + return File(bodyBytes, "application/octet-stream"); + } + catch (Exception ex) + { + logger.LogError(ex, "Failed to get object from S3 for bucket={bucket}, key={key}", bucket, key); + return StatusCode(500, new S3EncryptionClientError { Message = ex.Message }); + } + } +} \ No newline at end of file diff --git a/test-server/net-v4-improved-server/Makefile b/test-server/net-v4-improved-server/Makefile new file mode 100644 index 00000000..67bf9691 --- /dev/null +++ b/test-server/net-v4-improved-server/Makefile @@ -0,0 +1,34 @@ +# Makefile for S3 Encryption Client .NET Testing + +.PHONY: start-server stop-server wait-for-server + +PID_FILE_NET_V3_TRANSITION := net-v3-transition-server.pid +PORT_NET_V3_TRANSITION := 8100 + +start-server: + $(MAKE) start-net-v3-transition-server + +stop-server: + @if [ -f $(PID_FILE_NET_V3_TRANSITION) ]; then \ + kill $$(cat $(PID_FILE_NET_V3_TRANSITION)) 2>/dev/null || true; \ + rm $(PID_FILE_NET_V3_TRANSITION); \ + fi + +# Start .NET V3 transition server in background +start-net-v3-transition-server: + @echo "Starting .NET V3 server..." + AWS_ACCESS_KEY_ID="$$AWS_ACCESS_KEY_ID" \ + AWS_SECRET_ACCESS_KEY="$$AWS_SECRET_ACCESS_KEY" \ + AWS_SESSION_TOKEN="$$AWS_SESSION_TOKEN" \ + AWS_REGION="us-west-2" \ + dotnet run > net-v3-transition-server.log 2>&1 & echo $$! > net-v3-transition-server.pid + @echo ".NET V3 server starting..." + +wait-for-server: + $(MAKE) -C .. wait-for-port PORT=$(PORT_NET_V3_TRANSITION) + +duvet: + duvet report + +view-report-mac: + open .duvet/reports/report.html diff --git a/test-server/net-v4-improved-server/Models/ClientRequest.cs b/test-server/net-v4-improved-server/Models/ClientRequest.cs new file mode 100644 index 00000000..97567d3d --- /dev/null +++ b/test-server/net-v4-improved-server/Models/ClientRequest.cs @@ -0,0 +1,30 @@ +using System.ComponentModel.DataAnnotations; + +namespace NetV4ImprovedServer.Models; + +public class ClientRequest +{ + [Required] + public ClientConfig Config { get; set; } = new(); +} + +public class ClientConfig +{ + public bool EnableLegacyUnauthenticatedModes { get; set; } = false; + public bool EnableLegacyWrappingAlgorithms { get; set; } = false; + public bool EnableDelayedAuthenticationMode { get; set; } = false; + public long? SetBufferSize { get; set; } + public string? CommitmentPolicy { get; set; } + public string? EncryptionAlgorithm { get; set; } + [Required] + public KeyMaterial KeyMaterial { get; set; } = new(); +} + +public class KeyMaterial +{ + public byte[]? RsaKey { get; set; } + public byte[]? AesKey { get; set; } + + [Required] + public string KmsKeyId { get; set; } = string.Empty; +} \ No newline at end of file diff --git a/test-server/net-v4-improved-server/Models/ClientResponse.cs b/test-server/net-v4-improved-server/Models/ClientResponse.cs new file mode 100644 index 00000000..313253c2 --- /dev/null +++ b/test-server/net-v4-improved-server/Models/ClientResponse.cs @@ -0,0 +1,8 @@ +using System.Text.Json.Serialization; + +namespace NetV4ImprovedServer.Models; + +public class ClientResponse +{ + [JsonPropertyName("clientId")] public string ClientId { get; set; } = string.Empty; +} \ No newline at end of file diff --git a/test-server/net-v4-improved-server/Models/ErrorModels.cs b/test-server/net-v4-improved-server/Models/ErrorModels.cs new file mode 100644 index 00000000..6bdc0454 --- /dev/null +++ b/test-server/net-v4-improved-server/Models/ErrorModels.cs @@ -0,0 +1,17 @@ +using System.Text.Json.Serialization; + +namespace NetV4ImprovedServer.Models; + +public class GenericServerError +{ + [JsonPropertyName("__type")] + public string Type { get; set; } = "software.amazon.encryption.s3#GenericServerError"; + public string Message { get; set; } = string.Empty; +} + +public class S3EncryptionClientError +{ + [JsonPropertyName("__type")] + public string Type { get; set; } = "software.amazon.encryption.s3#S3EncryptionClientError"; + public string Message { get; set; } = string.Empty; +} diff --git a/test-server/net-v4-improved-server/NetV4ImprovedServer.csproj b/test-server/net-v4-improved-server/NetV4ImprovedServer.csproj new file mode 100644 index 00000000..a6016a98 --- /dev/null +++ b/test-server/net-v4-improved-server/NetV4ImprovedServer.csproj @@ -0,0 +1,27 @@ + + + + net8.0 + enable + enable + false + + + + false + + + + + + + + + + + + + + + + diff --git a/test-server/net-v4-improved-server/Program.cs b/test-server/net-v4-improved-server/Program.cs new file mode 100644 index 00000000..cffa4947 --- /dev/null +++ b/test-server/net-v4-improved-server/Program.cs @@ -0,0 +1,17 @@ +using NetV4ImprovedServer.Services; + +var builder = WebApplication.CreateBuilder(args); + +builder.Services.AddControllers(); +builder.Services.AddSingleton(); + +const int port = 8090; + +builder.WebHost.UseUrls($"http://localhost:{port}"); + +var app = builder.Build(); + +app.MapControllers(); + +Console.WriteLine($"Starting server on port {port}"); +app.Run(); diff --git a/test-server/net-v4-improved-server/README.md b/test-server/net-v4-improved-server/README.md new file mode 100644 index 00000000..a78b65c0 --- /dev/null +++ b/test-server/net-v4-improved-server/README.md @@ -0,0 +1,66 @@ +# Net-V2-V3-Server + +A .NET test server for Amazon S3 encryption client .NET v4. + +## Project Structure + +``` +net-v2-v3-server/ +├── Controllers/ # API controllers +├── Models/ # Data models +├── Services/ # Business logic services +├── Program.cs # Application entry point +├── NetV2V3Server.csproj # Project file +└── README.md # This file +``` + +## Running the Server + +For S3 Encryption Client v4 (runs on port 8090): + +```bash +dotnet run +``` + +## API Endpoints + +### Client Management + +- `POST /Client` - Create a new S3 encryption client + +### Object Operations + +- `PUT /{bucket}/{key}` - Upload an encrypted object to S3 +- `GET /{bucket}/{key}` - Download and decrypt an object from S3 + +All object operations require a `clientId` header to specify which client to use. + +## Example Usage + +### Create a Client + +```bash +curl -i -X POST \ + -H "Content-Type: application/json" \ + -H "User-Agent: smithy-java/0.0.3 ua/2.1 os/macos#15.5 lang/java#23.0.2" \ + -d '{"config":{"enableLegacyUnauthenticatedModes":true,"enableLegacyWrappingAlgorithms":true,"keyMaterial":{"kmsKeyId":"arn:aws:kms:us-west-2:370957321024:alias/S3EC-Test-Server-Github-KMS-Key"}, "encryptionContext": {"abc": "b"}}}' \ + http://localhost:8083/client +``` + +### Upload an Object + +```bash +curl -X PUT \ + -H "clientid: 7978763a-a02b-4dea-a5d4-78ef11d13d12" \ + -H "content-type: application/octet-stream" \ + -d "simple-test-input-net" \ + http://localhost:8083/object/s3ec-test-server-github-bucket/cross-lang-test-key-kms-ec-dotnet +``` + +### Download an Object + +```bash +curl -X GET \ + -H "clientid: 7978763a-a02b-4dea-a5d4-78ef11d13d12" \ + http://localhost:8083/object/s3ec-test-server-github-bucket/cross-lang-test-key-kms-ec-dotnet +``` diff --git a/test-server/net-v4-improved-server/Services/ClientCacheService.cs b/test-server/net-v4-improved-server/Services/ClientCacheService.cs new file mode 100644 index 00000000..2f232445 --- /dev/null +++ b/test-server/net-v4-improved-server/Services/ClientCacheService.cs @@ -0,0 +1,28 @@ +using Amazon.Extensions.S3.Encryption; +using System.Collections.Concurrent; + +namespace NetV4ImprovedServer.Services; + +public interface IClientCacheService +{ + string AddClient(AmazonS3EncryptionClientV4 client); + AmazonS3EncryptionClientV4? GetClient(string clientId); +} + +public class ClientCacheService : IClientCacheService +{ + private readonly ConcurrentDictionary _clients = new(); + + public string AddClient(AmazonS3EncryptionClientV4 client) + { + var clientId = Guid.NewGuid().ToString(); + _clients[clientId] = client; + return clientId; + } + + public AmazonS3EncryptionClientV4? GetClient(string clientId) + { + _clients.TryGetValue(clientId, out var client); + return client; + } +} diff --git a/test-server/net-v4-improved-server/net-v4-improved-server-backup.sln b/test-server/net-v4-improved-server/net-v4-improved-server-backup.sln new file mode 100644 index 00000000..cb5d8ec2 --- /dev/null +++ b/test-server/net-v4-improved-server/net-v4-improved-server-backup.sln @@ -0,0 +1,24 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.2.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetV4ImprovedServer", "NetV4ImprovedServer.csproj", "{FBC090B5-1767-DD4D-6787-29AFFC1D4283}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {FBC090B5-1767-DD4D-6787-29AFFC1D4283}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FBC090B5-1767-DD4D-6787-29AFFC1D4283}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FBC090B5-1767-DD4D-6787-29AFFC1D4283}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FBC090B5-1767-DD4D-6787-29AFFC1D4283}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {0BAED2B8-7156-4D5F-B83E-88D585A1F437} + EndGlobalSection +EndGlobal From 7a4ce1a22d12e5305fc0aff321d6707150281b03 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Tue, 28 Oct 2025 17:29:20 -0700 Subject: [PATCH 02/28] rm redundant sln --- .../net-v4-improved-server-backup.sln | 24 ------------------- 1 file changed, 24 deletions(-) delete mode 100644 test-server/net-v4-improved-server/net-v4-improved-server-backup.sln diff --git a/test-server/net-v4-improved-server/net-v4-improved-server-backup.sln b/test-server/net-v4-improved-server/net-v4-improved-server-backup.sln deleted file mode 100644 index cb5d8ec2..00000000 --- a/test-server/net-v4-improved-server/net-v4-improved-server-backup.sln +++ /dev/null @@ -1,24 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.5.2.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetV4ImprovedServer", "NetV4ImprovedServer.csproj", "{FBC090B5-1767-DD4D-6787-29AFFC1D4283}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {FBC090B5-1767-DD4D-6787-29AFFC1D4283}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FBC090B5-1767-DD4D-6787-29AFFC1D4283}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FBC090B5-1767-DD4D-6787-29AFFC1D4283}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FBC090B5-1767-DD4D-6787-29AFFC1D4283}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {0BAED2B8-7156-4D5F-B83E-88D585A1F437} - EndGlobalSection -EndGlobal From 32bfe1b6986dfe01d04da0156025c5e52ff56b50 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Tue, 28 Oct 2025 17:43:10 -0700 Subject: [PATCH 03/28] Deleted wrong dir --- .../net-v4-improved-server/.duvet/.gitignore | 3 - .../net-v4-improved-server/.duvet/config.toml | 21 ---- test-server/net-v4-improved-server/.gitignore | 44 -------- .../Controllers/ClientController.cs | 100 ----------------- .../Controllers/ObjectController.cs | 105 ------------------ test-server/net-v4-improved-server/Makefile | 34 ------ .../Models/ClientRequest.cs | 30 ----- .../Models/ClientResponse.cs | 8 -- .../Models/ErrorModels.cs | 17 --- .../NetV4ImprovedServer.csproj | 27 ----- test-server/net-v4-improved-server/Program.cs | 17 --- test-server/net-v4-improved-server/README.md | 66 ----------- .../Services/ClientCacheService.cs | 28 ----- 13 files changed, 500 deletions(-) delete mode 100644 test-server/net-v4-improved-server/.duvet/.gitignore delete mode 100644 test-server/net-v4-improved-server/.duvet/config.toml delete mode 100644 test-server/net-v4-improved-server/.gitignore delete mode 100644 test-server/net-v4-improved-server/Controllers/ClientController.cs delete mode 100644 test-server/net-v4-improved-server/Controllers/ObjectController.cs delete mode 100644 test-server/net-v4-improved-server/Makefile delete mode 100644 test-server/net-v4-improved-server/Models/ClientRequest.cs delete mode 100644 test-server/net-v4-improved-server/Models/ClientResponse.cs delete mode 100644 test-server/net-v4-improved-server/Models/ErrorModels.cs delete mode 100644 test-server/net-v4-improved-server/NetV4ImprovedServer.csproj delete mode 100644 test-server/net-v4-improved-server/Program.cs delete mode 100644 test-server/net-v4-improved-server/README.md delete mode 100644 test-server/net-v4-improved-server/Services/ClientCacheService.cs diff --git a/test-server/net-v4-improved-server/.duvet/.gitignore b/test-server/net-v4-improved-server/.duvet/.gitignore deleted file mode 100644 index 93956e36..00000000 --- a/test-server/net-v4-improved-server/.duvet/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -reports/ -requirements/ -specification/ \ No newline at end of file diff --git a/test-server/net-v4-improved-server/.duvet/config.toml b/test-server/net-v4-improved-server/.duvet/config.toml deleted file mode 100644 index 04d2e812..00000000 --- a/test-server/net-v4-improved-server/.duvet/config.toml +++ /dev/null @@ -1,21 +0,0 @@ -'$schema' = "https://awslabs.github.io/duvet/config/v0.4.0.json" - -[[source]] -pattern = "**/*.cs" - -# Include required specifications here -[[specification]] -source = "../specification/s3-encryption/data-format/content-metadata.md" -[[specification]] -source = "../specification/s3-encryption/data-format/metadata-strategy.md" -[[specification]] -source = "../specification/s3-encryption/encryption.md" -[[specification]] -source = "../specification/s3-encryption/key-derivation.md" - -[report.html] -enabled = true - -# Enable snapshots to prevent requirement coverage regressions -[report.snapshot] -enabled = false diff --git a/test-server/net-v4-improved-server/.gitignore b/test-server/net-v4-improved-server/.gitignore deleted file mode 100644 index 4c20cbc8..00000000 --- a/test-server/net-v4-improved-server/.gitignore +++ /dev/null @@ -1,44 +0,0 @@ -# Build results -[Dd]ebug/ -[Dd]ebugPublic/ -[Rr]elease/ -[Rr]eleases/ -x64/ -x86/ -[Ww][Ii][Nn]32/ -[Aa][Rr][Mm]/ -[Aa][Rr][Mm]64/ -bld/ -[Bb]in/ -[Oo]bj/ -[Ll]og/ -[Ll]ogs/ - -# Visual Studio 2015/2017 cache/options directory -.vs/ - -# User-specific files -*.rsuser -*.suo -*.user -*.userosscache -*.sln.docstates - -# NuGet Packages -*.nupkg -*.snupkg -packages/ - -# JetBrains Rider -.idea/ -*.sln.iml - -# VS Code -.vscode/ - -# macOS -.DS_Store - -# Temporary files -*.tmp -*.temp diff --git a/test-server/net-v4-improved-server/Controllers/ClientController.cs b/test-server/net-v4-improved-server/Controllers/ClientController.cs deleted file mode 100644 index f65176c7..00000000 --- a/test-server/net-v4-improved-server/Controllers/ClientController.cs +++ /dev/null @@ -1,100 +0,0 @@ -using System.Text.Json; -using Amazon.Extensions.S3.Encryption; -using Amazon.Extensions.S3.Encryption.Primitives; -using Microsoft.AspNetCore.Mvc; -using NetV4ImprovedServer.Models; -using NetV4ImprovedServer.Services; - -namespace NetV4ImprovedServer.Controllers; - -[ApiController] -[Route("[controller]")] -public class ClientController(IClientCacheService clientCacheService, ILogger logger) : ControllerBase -{ - [HttpPost] - public IActionResult CreateClient([FromBody] ClientRequest request) - { - // Return 501 for not implemented features by the server - if (request.Config.EnableDelayedAuthenticationMode) - return StatusCode(501, new GenericServerError { Message = "EnableDelayedAuthenticationMode not supported" }); - if (request.Config.SetBufferSize.HasValue) - return StatusCode(501, new GenericServerError { Message = "SetBufferSize not supported" }); - if (request.Config.KeyMaterial.RsaKey != null) - return StatusCode(501, new GenericServerError { Message = "RsaKey not supported" }); - if (request.Config.KeyMaterial.AesKey != null) - return StatusCode(501, new GenericServerError { Message = "AesKey not supported" }); - - var kmsKeyId = request.Config.KeyMaterial.KmsKeyId; - var enableLegacyUnauthenticatedModes = request.Config.EnableLegacyUnauthenticatedModes; - var enableLegacyWrappingAlgorithms = request.Config.EnableLegacyWrappingAlgorithms; - - try - { - // Parse CommitmentPolicy enum - CommitmentPolicy? commitmentPolicy = null; - if (!string.IsNullOrEmpty(request.Config.CommitmentPolicy)) - { - commitmentPolicy = request.Config.CommitmentPolicy switch - { - "FORBID_ENCRYPT_ALLOW_DECRYPT" => CommitmentPolicy.ForbidEncryptAllowDecrypt, - "REQUIRE_ENCRYPT_ALLOW_DECRYPT" => CommitmentPolicy.RequireEncryptAllowDecrypt, - "REQUIRE_ENCRYPT_REQUIRE_DECRYPT" => CommitmentPolicy.RequireEncryptRequireDecrypt, - _ => throw new ArgumentException($"Unsupported CommitmentPolicy: {request.Config.CommitmentPolicy}") - }; - } - - ContentEncryptionAlgorithm contextEncAlg = ContentEncryptionAlgorithm.AesGcmWithCommitment; - if (commitmentPolicy != null && commitmentPolicy.Value == CommitmentPolicy.ForbidEncryptAllowDecrypt) - { - contextEncAlg = ContentEncryptionAlgorithm.AesGcm; - } - - // The POST request does not contain encryption context. - // However, encryption context is a required field when using KMS. - // So, we are passing empty dictionary. - var encryptionContext = new Dictionary(); - var encryptionMaterial = new EncryptionMaterialsV4(kmsKeyId, KmsType.KmsContext, encryptionContext); - logger.LogInformation( - "Created EncryptionMaterialsV4: KMS={KmsKeyId}", - kmsKeyId); - // SecurityProfile V4AndLegacy can decrypt from legacy S3EC and AESGCM but V4 cannot - var enableLegacyMode = enableLegacyUnauthenticatedModes || enableLegacyWrappingAlgorithms; - var securityProfile = enableLegacyMode ? SecurityProfile.V4AndLegacy : SecurityProfile.V4; - - // TODO: We could do this too. - // if (commitmentPolicy.Value == CommitmentPolicy.ForbidEncryptAllowDecrypt) - // { - // logger.LogInformation("CommitmentPolicy is set to FORBID_ENCRYPT_ALLOW_DECRYPT. " + - // "Forcing to Create AmazonS3CryptoConfigurationV4 with security profile: V4AndLegacy,"); - // securityProfile = SecurityProfile.V4AndLegacy; - // } - logger.LogInformation("Created AmazonS3CryptoConfigurationV4 with security profile: {securityProfile}," + - "commitmentPolicy: {commitmentPolicy}, encryptionAlgorithm: {encryptionAlgorithm}", securityProfile.ToString(), commitmentPolicy.Value, contextEncAlg); - - var configuration = new AmazonS3CryptoConfigurationV4(securityProfile, commitmentPolicy.Value, contextEncAlg); - - // Create S3 encryption client - var encryptionClient = new AmazonS3EncryptionClientV4(configuration, encryptionMaterial); - // Add to cache and return client ID - var clientId = clientCacheService.AddClient(encryptionClient); - var response = new ClientResponse { ClientId = clientId }; - - logger.LogInformation("Created S3EC client with ID: {clientId}", clientId); - - return new ContentResult - { - Content = JsonSerializer.Serialize(response), - ContentType = "application/json", - StatusCode = 200 - }; - } - catch (Exception ex) - { - logger.LogError(ex, "Failed to create S3EC client"); - return StatusCode(500, new S3EncryptionClientError - { - Message = $"Failed to create client: {ex.Message}" - }); - } - } -} \ No newline at end of file diff --git a/test-server/net-v4-improved-server/Controllers/ObjectController.cs b/test-server/net-v4-improved-server/Controllers/ObjectController.cs deleted file mode 100644 index 0a1b2ee8..00000000 --- a/test-server/net-v4-improved-server/Controllers/ObjectController.cs +++ /dev/null @@ -1,105 +0,0 @@ -using System.Text.Json; -using Amazon.S3.Model; -using Microsoft.AspNetCore.Mvc; -using NetV4ImprovedServer.Models; -using NetV4ImprovedServer.Services; - -namespace NetV4ImprovedServer.Controllers; - -[ApiController] -[Route("[controller]")] -public class ObjectController(IClientCacheService clientCacheService, ILogger logger) : ControllerBase -{ - [HttpPut("{bucket}/{key}")] - public async Task PutObject(string bucket, string key) - { - logger.LogInformation("Starting PutObject"); - var clientId = Request.Headers["clientId"].FirstOrDefault(); - if (string.IsNullOrEmpty(clientId)) - return BadRequest(new GenericServerError { Message = "ClientID header is required" }); - - var client = clientCacheService.GetClient(clientId); - if (client == null) - return NotFound(new GenericServerError { Message = $"No client found for ClientID: {clientId}" }); - - try - { - // Read raw body data - using var memoryStream = new MemoryStream(); - // Request is the HTTP request this method is currently handling - await Request.Body.CopyToAsync(memoryStream); - var bodyBytes = memoryStream.ToArray(); - - // Create put request - var putRequest = new PutObjectRequest - { - BucketName = bucket, - Key = key, - InputStream = new MemoryStream(bodyBytes) - }; - - await client.PutObjectAsync(putRequest); - - var response = new { bucket, key }; - - logger.LogInformation( - "Put object succeeded for bucket={bucket}, key={key} and clientId = {clientId}", - bucket, key, clientId); - return new ContentResult - { - Content = JsonSerializer.Serialize(response), - ContentType = "application/json", - StatusCode = 200 - }; - } - catch (Exception ex) - { - logger.LogError(ex, "Failed to put object from S3 for bucket={bucket}, key={key}", bucket, key); - return StatusCode(500, new S3EncryptionClientError { Message = $"Failed to put object: {ex.Message}" }); - } - } - - [HttpGet("{bucket}/{key}")] - public async Task GetObject(string bucket, string key) - { - logger.LogInformation("Starting GetObject"); - var clientId = Request.Headers["clientId"].FirstOrDefault(); - if (string.IsNullOrEmpty(clientId)) - return BadRequest(new GenericServerError { Message = "ClientID header is required" }); - - var client = clientCacheService.GetClient(clientId); - if (client == null) - return NotFound(new GenericServerError { Message = $"No client found for ClientID: {clientId}" }); - - try - { - var getRequest = new GetObjectRequest - { - BucketName = bucket, - Key = key - }; - var response = await client.GetObjectAsync(getRequest); - logger.LogInformation("Got object from S3 for bucket={bucket}, key={key}", bucket, key); - // Read response body - using var memoryStream = new MemoryStream(); - await response.ResponseStream.CopyToAsync(memoryStream); - var bodyBytes = memoryStream.ToArray(); - - // Convert metadata to content-metadata header format - var metadataList = response.Metadata.Keys - .Select(metaDataKey => $"{metaDataKey}={response.Metadata[metaDataKey]}") - .ToList(); - var metadataStr = string.Join(",", metadataList); - - // Set response headers - Response.Headers["Content-Metadata"] = metadataStr; - - return File(bodyBytes, "application/octet-stream"); - } - catch (Exception ex) - { - logger.LogError(ex, "Failed to get object from S3 for bucket={bucket}, key={key}", bucket, key); - return StatusCode(500, new S3EncryptionClientError { Message = ex.Message }); - } - } -} \ No newline at end of file diff --git a/test-server/net-v4-improved-server/Makefile b/test-server/net-v4-improved-server/Makefile deleted file mode 100644 index 67bf9691..00000000 --- a/test-server/net-v4-improved-server/Makefile +++ /dev/null @@ -1,34 +0,0 @@ -# Makefile for S3 Encryption Client .NET Testing - -.PHONY: start-server stop-server wait-for-server - -PID_FILE_NET_V3_TRANSITION := net-v3-transition-server.pid -PORT_NET_V3_TRANSITION := 8100 - -start-server: - $(MAKE) start-net-v3-transition-server - -stop-server: - @if [ -f $(PID_FILE_NET_V3_TRANSITION) ]; then \ - kill $$(cat $(PID_FILE_NET_V3_TRANSITION)) 2>/dev/null || true; \ - rm $(PID_FILE_NET_V3_TRANSITION); \ - fi - -# Start .NET V3 transition server in background -start-net-v3-transition-server: - @echo "Starting .NET V3 server..." - AWS_ACCESS_KEY_ID="$$AWS_ACCESS_KEY_ID" \ - AWS_SECRET_ACCESS_KEY="$$AWS_SECRET_ACCESS_KEY" \ - AWS_SESSION_TOKEN="$$AWS_SESSION_TOKEN" \ - AWS_REGION="us-west-2" \ - dotnet run > net-v3-transition-server.log 2>&1 & echo $$! > net-v3-transition-server.pid - @echo ".NET V3 server starting..." - -wait-for-server: - $(MAKE) -C .. wait-for-port PORT=$(PORT_NET_V3_TRANSITION) - -duvet: - duvet report - -view-report-mac: - open .duvet/reports/report.html diff --git a/test-server/net-v4-improved-server/Models/ClientRequest.cs b/test-server/net-v4-improved-server/Models/ClientRequest.cs deleted file mode 100644 index 97567d3d..00000000 --- a/test-server/net-v4-improved-server/Models/ClientRequest.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace NetV4ImprovedServer.Models; - -public class ClientRequest -{ - [Required] - public ClientConfig Config { get; set; } = new(); -} - -public class ClientConfig -{ - public bool EnableLegacyUnauthenticatedModes { get; set; } = false; - public bool EnableLegacyWrappingAlgorithms { get; set; } = false; - public bool EnableDelayedAuthenticationMode { get; set; } = false; - public long? SetBufferSize { get; set; } - public string? CommitmentPolicy { get; set; } - public string? EncryptionAlgorithm { get; set; } - [Required] - public KeyMaterial KeyMaterial { get; set; } = new(); -} - -public class KeyMaterial -{ - public byte[]? RsaKey { get; set; } - public byte[]? AesKey { get; set; } - - [Required] - public string KmsKeyId { get; set; } = string.Empty; -} \ No newline at end of file diff --git a/test-server/net-v4-improved-server/Models/ClientResponse.cs b/test-server/net-v4-improved-server/Models/ClientResponse.cs deleted file mode 100644 index 313253c2..00000000 --- a/test-server/net-v4-improved-server/Models/ClientResponse.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System.Text.Json.Serialization; - -namespace NetV4ImprovedServer.Models; - -public class ClientResponse -{ - [JsonPropertyName("clientId")] public string ClientId { get; set; } = string.Empty; -} \ No newline at end of file diff --git a/test-server/net-v4-improved-server/Models/ErrorModels.cs b/test-server/net-v4-improved-server/Models/ErrorModels.cs deleted file mode 100644 index 6bdc0454..00000000 --- a/test-server/net-v4-improved-server/Models/ErrorModels.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Text.Json.Serialization; - -namespace NetV4ImprovedServer.Models; - -public class GenericServerError -{ - [JsonPropertyName("__type")] - public string Type { get; set; } = "software.amazon.encryption.s3#GenericServerError"; - public string Message { get; set; } = string.Empty; -} - -public class S3EncryptionClientError -{ - [JsonPropertyName("__type")] - public string Type { get; set; } = "software.amazon.encryption.s3#S3EncryptionClientError"; - public string Message { get; set; } = string.Empty; -} diff --git a/test-server/net-v4-improved-server/NetV4ImprovedServer.csproj b/test-server/net-v4-improved-server/NetV4ImprovedServer.csproj deleted file mode 100644 index a6016a98..00000000 --- a/test-server/net-v4-improved-server/NetV4ImprovedServer.csproj +++ /dev/null @@ -1,27 +0,0 @@ - - - - net8.0 - enable - enable - false - - - - false - - - - - - - - - - - - - - - - diff --git a/test-server/net-v4-improved-server/Program.cs b/test-server/net-v4-improved-server/Program.cs deleted file mode 100644 index cffa4947..00000000 --- a/test-server/net-v4-improved-server/Program.cs +++ /dev/null @@ -1,17 +0,0 @@ -using NetV4ImprovedServer.Services; - -var builder = WebApplication.CreateBuilder(args); - -builder.Services.AddControllers(); -builder.Services.AddSingleton(); - -const int port = 8090; - -builder.WebHost.UseUrls($"http://localhost:{port}"); - -var app = builder.Build(); - -app.MapControllers(); - -Console.WriteLine($"Starting server on port {port}"); -app.Run(); diff --git a/test-server/net-v4-improved-server/README.md b/test-server/net-v4-improved-server/README.md deleted file mode 100644 index a78b65c0..00000000 --- a/test-server/net-v4-improved-server/README.md +++ /dev/null @@ -1,66 +0,0 @@ -# Net-V2-V3-Server - -A .NET test server for Amazon S3 encryption client .NET v4. - -## Project Structure - -``` -net-v2-v3-server/ -├── Controllers/ # API controllers -├── Models/ # Data models -├── Services/ # Business logic services -├── Program.cs # Application entry point -├── NetV2V3Server.csproj # Project file -└── README.md # This file -``` - -## Running the Server - -For S3 Encryption Client v4 (runs on port 8090): - -```bash -dotnet run -``` - -## API Endpoints - -### Client Management - -- `POST /Client` - Create a new S3 encryption client - -### Object Operations - -- `PUT /{bucket}/{key}` - Upload an encrypted object to S3 -- `GET /{bucket}/{key}` - Download and decrypt an object from S3 - -All object operations require a `clientId` header to specify which client to use. - -## Example Usage - -### Create a Client - -```bash -curl -i -X POST \ - -H "Content-Type: application/json" \ - -H "User-Agent: smithy-java/0.0.3 ua/2.1 os/macos#15.5 lang/java#23.0.2" \ - -d '{"config":{"enableLegacyUnauthenticatedModes":true,"enableLegacyWrappingAlgorithms":true,"keyMaterial":{"kmsKeyId":"arn:aws:kms:us-west-2:370957321024:alias/S3EC-Test-Server-Github-KMS-Key"}, "encryptionContext": {"abc": "b"}}}' \ - http://localhost:8083/client -``` - -### Upload an Object - -```bash -curl -X PUT \ - -H "clientid: 7978763a-a02b-4dea-a5d4-78ef11d13d12" \ - -H "content-type: application/octet-stream" \ - -d "simple-test-input-net" \ - http://localhost:8083/object/s3ec-test-server-github-bucket/cross-lang-test-key-kms-ec-dotnet -``` - -### Download an Object - -```bash -curl -X GET \ - -H "clientid: 7978763a-a02b-4dea-a5d4-78ef11d13d12" \ - http://localhost:8083/object/s3ec-test-server-github-bucket/cross-lang-test-key-kms-ec-dotnet -``` diff --git a/test-server/net-v4-improved-server/Services/ClientCacheService.cs b/test-server/net-v4-improved-server/Services/ClientCacheService.cs deleted file mode 100644 index 2f232445..00000000 --- a/test-server/net-v4-improved-server/Services/ClientCacheService.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Amazon.Extensions.S3.Encryption; -using System.Collections.Concurrent; - -namespace NetV4ImprovedServer.Services; - -public interface IClientCacheService -{ - string AddClient(AmazonS3EncryptionClientV4 client); - AmazonS3EncryptionClientV4? GetClient(string clientId); -} - -public class ClientCacheService : IClientCacheService -{ - private readonly ConcurrentDictionary _clients = new(); - - public string AddClient(AmazonS3EncryptionClientV4 client) - { - var clientId = Guid.NewGuid().ToString(); - _clients[clientId] = client; - return clientId; - } - - public AmazonS3EncryptionClientV4? GetClient(string clientId) - { - _clients.TryGetValue(clientId, out var client); - return client; - } -} From 7067ef999d3a7bc332369c8294a5c5cc12d522e0 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Tue, 28 Oct 2025 17:55:58 -0700 Subject: [PATCH 04/28] v4 server --- .gitmodules | 4 + .../Controllers/ClientController.cs | 72 ++++++++++++ .../Controllers/ObjectController.cs | 105 ++++++++++++++++++ test-server/net-v4-server/Makefile | 61 ++++++++++ .../net-v4-server/Models/ClientRequest.cs | 28 +++++ .../net-v4-server/Models/ClientResponse.cs | 8 ++ .../net-v4-server/Models/ErrorModels.cs | 17 +++ test-server/net-v4-server/NetV4Server.csproj | 28 +++++ test-server/net-v4-server/Program.cs | 17 +++ test-server/net-v4-server/README.md | 72 ++++++++++++ .../Services/ClientCacheService.cs | 28 +++++ .../net-v4-server/s3ec-net-v4-improved | 1 + 12 files changed, 441 insertions(+) create mode 100644 test-server/net-v4-server/Controllers/ClientController.cs create mode 100644 test-server/net-v4-server/Controllers/ObjectController.cs create mode 100644 test-server/net-v4-server/Makefile create mode 100644 test-server/net-v4-server/Models/ClientRequest.cs create mode 100644 test-server/net-v4-server/Models/ClientResponse.cs create mode 100644 test-server/net-v4-server/Models/ErrorModels.cs create mode 100644 test-server/net-v4-server/NetV4Server.csproj create mode 100644 test-server/net-v4-server/Program.cs create mode 100644 test-server/net-v4-server/README.md create mode 100644 test-server/net-v4-server/Services/ClientCacheService.cs create mode 160000 test-server/net-v4-server/s3ec-net-v4-improved diff --git a/.gitmodules b/.gitmodules index 0bf186eb..a399d866 100644 --- a/.gitmodules +++ b/.gitmodules @@ -39,3 +39,7 @@ 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 "test-server/net-v4-server/s3ec-net-v4-improved"] + path = test-server/net-v4-server/s3ec-net-v4-improved + url = https://github.com/aws/private-amazon-s3-encryption-client-dotnet-staging.git + branch = s3ec-v4-WIP diff --git a/test-server/net-v4-server/Controllers/ClientController.cs b/test-server/net-v4-server/Controllers/ClientController.cs new file mode 100644 index 00000000..f437c695 --- /dev/null +++ b/test-server/net-v4-server/Controllers/ClientController.cs @@ -0,0 +1,72 @@ +using System.Text.Json; +using Amazon.Extensions.S3.Encryption; +using Amazon.Extensions.S3.Encryption.Primitives; +using Microsoft.AspNetCore.Mvc; +using NetV4Server.Models; +using NetV4Server.Services; + +namespace NetV4Server.Controllers; + +[ApiController] +[Route("[controller]")] +public class ClientController(IClientCacheService clientCacheService, ILogger logger) : ControllerBase +{ + [HttpPost] + public IActionResult CreateClient([FromBody] ClientRequest request) + { + // Return 501 for not implemented features by the server + if (request.Config.EnableDelayedAuthenticationMode) + return StatusCode(501, new GenericServerError { Message = "EnableDelayedAuthenticationMode not supported" }); + if (request.Config.SetBufferSize.HasValue) + return StatusCode(501, new GenericServerError { Message = "SetBufferSize not supported" }); + if (request.Config.KeyMaterial.RsaKey != null) + return StatusCode(501, new GenericServerError { Message = "RsaKey not supported" }); + if (request.Config.KeyMaterial.AesKey != null) + return StatusCode(501, new GenericServerError { Message = "AesKey not supported" }); + + var kmsKeyId = request.Config.KeyMaterial.KmsKeyId; + var enableLegacyUnauthenticatedModes = request.Config.EnableLegacyUnauthenticatedModes; + var enableLegacyWrappingAlgorithms = request.Config.EnableLegacyWrappingAlgorithms; + + try + { + // The POST request does not contain encryption context. + // However, encryption context is a required field when using KMS. + // So, we are passing empty dictionary. + var encryptionContext = new Dictionary(); + var encryptionMaterial = new EncryptionMaterialsV2(kmsKeyId, KmsType.KmsContext, encryptionContext); + logger.LogInformation( + "Created EncryptionMaterialsV2: KMS={KmsKeyId}", + kmsKeyId); + // SecurityProfile V2AndLegacy can decrypt from legacy S3EC but V2 cannot + var enableLegacyMode = enableLegacyUnauthenticatedModes || enableLegacyWrappingAlgorithms; + var securityProfile = enableLegacyMode ? SecurityProfile.V2AndLegacy : SecurityProfile.V2; + + logger.LogInformation("Created securityProfile= {securityProfile}", securityProfile.ToString()); + + var configuration = new AmazonS3CryptoConfigurationV2(securityProfile); + // Create S3 encryption client + var encryptionClient = new AmazonS3EncryptionClientV2(configuration, encryptionMaterial); + // Add to cache and return client ID + var clientId = clientCacheService.AddClient(encryptionClient); + var response = new ClientResponse { ClientId = clientId }; + + logger.LogInformation("Created S3EC client with ID: {clientId}", clientId); + + return new ContentResult + { + Content = JsonSerializer.Serialize(response), + ContentType = "application/json", + StatusCode = 200 + }; + } + catch (Exception ex) + { + logger.LogError(ex, "Failed to create S3EC client"); + return StatusCode(500, new S3EncryptionClientError + { + Message = $"Failed to create client: {ex.Message}" + }); + } + } +} \ No newline at end of file diff --git a/test-server/net-v4-server/Controllers/ObjectController.cs b/test-server/net-v4-server/Controllers/ObjectController.cs new file mode 100644 index 00000000..e4b9f022 --- /dev/null +++ b/test-server/net-v4-server/Controllers/ObjectController.cs @@ -0,0 +1,105 @@ +using System.Text.Json; +using Amazon.S3.Model; +using Microsoft.AspNetCore.Mvc; +using NetV4Server.Models; +using NetV4Server.Services; + +namespace NetV4Server.Controllers; + +[ApiController] +[Route("[controller]")] +public class ObjectController(IClientCacheService clientCacheService, ILogger logger) : ControllerBase +{ + [HttpPut("{bucket}/{key}")] + public async Task PutObject(string bucket, string key) + { + logger.LogInformation("Starting PutObject"); + var clientId = Request.Headers["clientId"].FirstOrDefault(); + if (string.IsNullOrEmpty(clientId)) + return BadRequest(new GenericServerError { Message = "ClientID header is required" }); + + var client = clientCacheService.GetClient(clientId); + if (client == null) + return NotFound(new GenericServerError { Message = $"No client found for ClientID: {clientId}" }); + + try + { + // Read raw body data + using var memoryStream = new MemoryStream(); + // Request is the HTTP request this method is currently handling + await Request.Body.CopyToAsync(memoryStream); + var bodyBytes = memoryStream.ToArray(); + + // Create put request + var putRequest = new PutObjectRequest + { + BucketName = bucket, + Key = key, + InputStream = new MemoryStream(bodyBytes) + }; + + await client.PutObjectAsync(putRequest); + + var response = new { bucket, key }; + + logger.LogInformation( + "Put object succeeded for bucket={bucket}, key={key} and clientId = {clientId}", + bucket, key, clientId); + return new ContentResult + { + Content = JsonSerializer.Serialize(response), + ContentType = "application/json", + StatusCode = 200 + }; + } + catch (Exception ex) + { + logger.LogError(ex, "Failed to put object from S3 for bucket={bucket}, key={key}", bucket, key); + return StatusCode(500, new S3EncryptionClientError { Message = $"Failed to put object: {ex.Message}" }); + } + } + + [HttpGet("{bucket}/{key}")] + public async Task GetObject(string bucket, string key) + { + logger.LogInformation("Starting GetObject"); + var clientId = Request.Headers["clientId"].FirstOrDefault(); + if (string.IsNullOrEmpty(clientId)) + return BadRequest(new GenericServerError { Message = "ClientID header is required" }); + + var client = clientCacheService.GetClient(clientId); + if (client == null) + return NotFound(new GenericServerError { Message = $"No client found for ClientID: {clientId}" }); + + try + { + var getRequest = new GetObjectRequest + { + BucketName = bucket, + Key = key + }; + var response = await client.GetObjectAsync(getRequest); + logger.LogInformation("Got object from S3 for bucket={bucket}, key={key}", bucket, key); + // Read response body + using var memoryStream = new MemoryStream(); + await response.ResponseStream.CopyToAsync(memoryStream); + var bodyBytes = memoryStream.ToArray(); + + // Convert metadata to content-metadata header format + var metadataList = response.Metadata.Keys + .Select(metaDataKey => $"{metaDataKey}={response.Metadata[metaDataKey]}") + .ToList(); + var metadataStr = string.Join(",", metadataList); + + // Set response headers + Response.Headers["Content-Metadata"] = metadataStr; + + return File(bodyBytes, "application/octet-stream"); + } + catch (Exception ex) + { + logger.LogError(ex, "Failed to get object from S3 for bucket={bucket}, key={key}", bucket, key); + return StatusCode(500, new S3EncryptionClientError { Message = ex.Message }); + } + } +} \ No newline at end of file diff --git a/test-server/net-v4-server/Makefile b/test-server/net-v4-server/Makefile new file mode 100644 index 00000000..a16ff57e --- /dev/null +++ b/test-server/net-v4-server/Makefile @@ -0,0 +1,61 @@ +# Makefile for S3 Encryption Client .NET Testing + +.PHONY: start-server stop-server wait-for-server + +PID_FILE_NET_V2 := net-v2-server.pid +PID_FILE_NET_V3 := net-v3-server.pid +PORT_NET_V2 := 8083 +PORT_NET_V3 := 8084 + +start-server: + $(MAKE) start-net-v2-server; \ + $(MAKE) start-net-v3-server; + +stop-server: + @if [ -f $(PID_FILE_NET_V2) ]; then \ + kill $$(cat $(PID_FILE_NET_V2)) 2>/dev/null || true; \ + rm $(PID_FILE_NET_V2); \ + fi + @if [ -f $(PID_FILE_NET_V3) ]; then \ + kill $$(cat $(PID_FILE_NET_V3)) 2>/dev/null || true; \ + rm $(PID_FILE_NET_V3); \ + fi + +# Start .NET V2 server in background +# This builds first into bin/v2 and runs through dll +# to avoid simultaneous dotnet run conflict +start-net-v2-server: + @echo "Starting .NET V2 server..." + AWS_ACCESS_KEY_ID="$$AWS_ACCESS_KEY_ID" \ + AWS_SECRET_ACCESS_KEY="$$AWS_SECRET_ACCESS_KEY" \ + AWS_SESSION_TOKEN="$$AWS_SESSION_TOKEN" \ + AWS_REGION="us-west-2" \ + rm -rf obj/v2 bin/v2 && \ + dotnet build -p:S3EncryptionVersion=v2 -o bin/v2 -p:BaseIntermediateOutputPath=obj/v2/ && \ + dotnet bin/v2/NetV2V3Server.dll > net-v2-server.log 2>&1 & echo $$! > net-v2-server.pid + @echo ".NET V2 server starting..." + + +# Start .NET V3 server in background +# This builds first into bin/v3 and runs through dll +# to avoid simultaneous dotnet run conflict +start-net-v3-server: + @echo "Starting .NET V3 server..." + AWS_ACCESS_KEY_ID="$$AWS_ACCESS_KEY_ID" \ + AWS_SECRET_ACCESS_KEY="$$AWS_SECRET_ACCESS_KEY" \ + AWS_SESSION_TOKEN="$$AWS_SESSION_TOKEN" \ + AWS_REGION="us-west-2" \ + rm -rf obj/v3 bin/v3 && \ + dotnet build -p:S3EncryptionVersion=v3 -o bin/v3 -p:BaseIntermediateOutputPath=obj/v3/ && \ + dotnet bin/v3/NetV2V3Server.dll > net-v3-server.log 2>&1 & echo $$! > net-v3-server.pid + @echo ".NET V3 server starting..." + +wait-for-server: + $(MAKE) -C .. wait-for-port PORT=$(PORT_NET_V2) \ + $(MAKE) -C .. wait-for-port PORT=$(PORT_NET_V3) + +duvet: + duvet report + +view-report-mac: + open .duvet/reports/report.html diff --git a/test-server/net-v4-server/Models/ClientRequest.cs b/test-server/net-v4-server/Models/ClientRequest.cs new file mode 100644 index 00000000..c425ca8c --- /dev/null +++ b/test-server/net-v4-server/Models/ClientRequest.cs @@ -0,0 +1,28 @@ +using System.ComponentModel.DataAnnotations; + +namespace NetV4Server.Models; + +public class ClientRequest +{ + [Required] + public ClientConfig Config { get; set; } = new(); +} + +public class ClientConfig +{ + public bool EnableLegacyUnauthenticatedModes { get; set; } = false; + public bool EnableLegacyWrappingAlgorithms { get; set; } = false; + public bool EnableDelayedAuthenticationMode { get; set; } = false; + public long? SetBufferSize { get; set; } + [Required] + public KeyMaterial KeyMaterial { get; set; } = new(); +} + +public class KeyMaterial +{ + public byte[]? RsaKey { get; set; } + public byte[]? AesKey { get; set; } + + [Required] + public string KmsKeyId { get; set; } = string.Empty; +} \ No newline at end of file diff --git a/test-server/net-v4-server/Models/ClientResponse.cs b/test-server/net-v4-server/Models/ClientResponse.cs new file mode 100644 index 00000000..b4dbb494 --- /dev/null +++ b/test-server/net-v4-server/Models/ClientResponse.cs @@ -0,0 +1,8 @@ +using System.Text.Json.Serialization; + +namespace NetV4Server.Models; + +public class ClientResponse +{ + [JsonPropertyName("clientId")] public string ClientId { get; set; } = string.Empty; +} \ No newline at end of file diff --git a/test-server/net-v4-server/Models/ErrorModels.cs b/test-server/net-v4-server/Models/ErrorModels.cs new file mode 100644 index 00000000..e4b818e3 --- /dev/null +++ b/test-server/net-v4-server/Models/ErrorModels.cs @@ -0,0 +1,17 @@ +using System.Text.Json.Serialization; + +namespace NetV4Server.Models; + +public class GenericServerError +{ + [JsonPropertyName("__type")] + public string Type { get; set; } = "software.amazon.encryption.s3#GenericServerError"; + public string Message { get; set; } = string.Empty; +} + +public class S3EncryptionClientError +{ + [JsonPropertyName("__type")] + public string Type { get; set; } = "software.amazon.encryption.s3#S3EncryptionClientError"; + public string Message { get; set; } = string.Empty; +} diff --git a/test-server/net-v4-server/NetV4Server.csproj b/test-server/net-v4-server/NetV4Server.csproj new file mode 100644 index 00000000..28ddba06 --- /dev/null +++ b/test-server/net-v4-server/NetV4Server.csproj @@ -0,0 +1,28 @@ + + + + net8.0 + enable + enable + false + NetV2V3Server + + + + false + + + + + + + + + + + + + + + + diff --git a/test-server/net-v4-server/Program.cs b/test-server/net-v4-server/Program.cs new file mode 100644 index 00000000..23cf79d9 --- /dev/null +++ b/test-server/net-v4-server/Program.cs @@ -0,0 +1,17 @@ +using NetV4Server.Services; + +var builder = WebApplication.CreateBuilder(args); + +builder.Services.AddControllers(); +builder.Services.AddSingleton(); + +const int port = 8090; + +builder.WebHost.UseUrls($"http://localhost:{port}"); + +var app = builder.Build(); + +app.MapControllers(); + +Console.WriteLine($"Starting server on port {port}"); +app.Run(); diff --git a/test-server/net-v4-server/README.md b/test-server/net-v4-server/README.md new file mode 100644 index 00000000..9463d8b5 --- /dev/null +++ b/test-server/net-v4-server/README.md @@ -0,0 +1,72 @@ +# Net-V2-V3-Server + +A .NET test server for Amazon S3 encryption client .NET v2 and v3. + +## Project Structure + +``` +net-v2-v3-server/ +├── Controllers/ # API controllers +├── Models/ # Data models +├── Services/ # Business logic services +├── Program.cs # Application entry point +├── NetV2V3Server.csproj # Project file +└── README.md # This file +``` + +## Running the Server + +For S3 Encryption Client v2 (runs on port 8083): + +```bash +dotnet run -p:S3EncryptionVersion=v2 +``` + +For S3 Encryption Client v3 (runs on port 8084): + +```bash +dotnet run -p:S3EncryptionVersion=v3 +``` + +## API Endpoints + +### Client Management + +- `POST /Client` - Create a new S3 encryption client + +### Object Operations + +- `PUT /{bucket}/{key}` - Upload an encrypted object to S3 +- `GET /{bucket}/{key}` - Download and decrypt an object from S3 + +All object operations require a `clientId` header to specify which client to use. + +## Example Usage + +### Create a Client + +```bash +curl -i -X POST \ + -H "Content-Type: application/json" \ + -H "User-Agent: smithy-java/0.0.3 ua/2.1 os/macos#15.5 lang/java#23.0.2" \ + -d '{"config":{"enableLegacyUnauthenticatedModes":true,"enableLegacyWrappingAlgorithms":true,"keyMaterial":{"kmsKeyId":"arn:aws:kms:us-west-2:370957321024:alias/S3EC-Test-Server-Github-KMS-Key"}, "encryptionContext": {"abc": "b"}}}' \ + http://localhost:8083/client +``` + +### Upload an Object + +```bash +curl -X PUT \ + -H "clientid: 7978763a-a02b-4dea-a5d4-78ef11d13d12" \ + -H "content-type: application/octet-stream" \ + -d "simple-test-input-net" \ + http://localhost:8083/object/s3ec-test-server-github-bucket/cross-lang-test-key-kms-ec-dotnet +``` + +### Download an Object + +```bash +curl -X GET \ + -H "clientid: 7978763a-a02b-4dea-a5d4-78ef11d13d12" \ + http://localhost:8083/object/s3ec-test-server-github-bucket/cross-lang-test-key-kms-ec-dotnet +``` diff --git a/test-server/net-v4-server/Services/ClientCacheService.cs b/test-server/net-v4-server/Services/ClientCacheService.cs new file mode 100644 index 00000000..e1183274 --- /dev/null +++ b/test-server/net-v4-server/Services/ClientCacheService.cs @@ -0,0 +1,28 @@ +using Amazon.Extensions.S3.Encryption; +using System.Collections.Concurrent; + +namespace NetV4Server.Services; + +public interface IClientCacheService +{ + string AddClient(AmazonS3EncryptionClientV2 client); + AmazonS3EncryptionClientV2? GetClient(string clientId); +} + +public class ClientCacheService : IClientCacheService +{ + private readonly ConcurrentDictionary _clients = new(); + + public string AddClient(AmazonS3EncryptionClientV2 client) + { + var clientId = Guid.NewGuid().ToString(); + _clients[clientId] = client; + return clientId; + } + + public AmazonS3EncryptionClientV2? GetClient(string clientId) + { + _clients.TryGetValue(clientId, out var client); + return client; + } +} diff --git a/test-server/net-v4-server/s3ec-net-v4-improved b/test-server/net-v4-server/s3ec-net-v4-improved new file mode 160000 index 00000000..61ff05d3 --- /dev/null +++ b/test-server/net-v4-server/s3ec-net-v4-improved @@ -0,0 +1 @@ +Subproject commit 61ff05d3e78463be9f7ca16827f9a72b67c0dd26 From d707266c9f809382ae4c5210419f245bd5faa9ad Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Tue, 28 Oct 2025 17:59:58 -0700 Subject: [PATCH 05/28] auto commit --- test-server/net-v4-server/Makefile | 51 ++++++++---------------------- 1 file changed, 13 insertions(+), 38 deletions(-) diff --git a/test-server/net-v4-server/Makefile b/test-server/net-v4-server/Makefile index a16ff57e..e667971d 100644 --- a/test-server/net-v4-server/Makefile +++ b/test-server/net-v4-server/Makefile @@ -2,57 +2,32 @@ .PHONY: start-server stop-server wait-for-server -PID_FILE_NET_V2 := net-v2-server.pid -PID_FILE_NET_V3 := net-v3-server.pid -PORT_NET_V2 := 8083 -PORT_NET_V3 := 8084 +PID_FILE_NET_V4 := net-V4-server.pid +PORT_NET_V4 := 8090 start-server: - $(MAKE) start-net-v2-server; \ - $(MAKE) start-net-v3-server; + $(MAKE) start-net-V4-server; stop-server: - @if [ -f $(PID_FILE_NET_V2) ]; then \ - kill $$(cat $(PID_FILE_NET_V2)) 2>/dev/null || true; \ - rm $(PID_FILE_NET_V2); \ + @if [ -f $(PID_FILE_NET_V4) ]; then \ + kill $$(cat $(PID_FILE_NET_V4)) 2>/dev/null || true; \ + rm $(PID_FILE_NET_V4); \ fi - @if [ -f $(PID_FILE_NET_V3) ]; then \ - kill $$(cat $(PID_FILE_NET_V3)) 2>/dev/null || true; \ - rm $(PID_FILE_NET_V3); \ - fi - -# Start .NET V2 server in background -# This builds first into bin/v2 and runs through dll -# to avoid simultaneous dotnet run conflict -start-net-v2-server: - @echo "Starting .NET V2 server..." - AWS_ACCESS_KEY_ID="$$AWS_ACCESS_KEY_ID" \ - AWS_SECRET_ACCESS_KEY="$$AWS_SECRET_ACCESS_KEY" \ - AWS_SESSION_TOKEN="$$AWS_SESSION_TOKEN" \ - AWS_REGION="us-west-2" \ - rm -rf obj/v2 bin/v2 && \ - dotnet build -p:S3EncryptionVersion=v2 -o bin/v2 -p:BaseIntermediateOutputPath=obj/v2/ && \ - dotnet bin/v2/NetV2V3Server.dll > net-v2-server.log 2>&1 & echo $$! > net-v2-server.pid - @echo ".NET V2 server starting..." - -# Start .NET V3 server in background -# This builds first into bin/v3 and runs through dll +# Start .NET V4 server in background +# This builds first into bin/V4 and runs through dll # to avoid simultaneous dotnet run conflict -start-net-v3-server: - @echo "Starting .NET V3 server..." +start-net-V4-server: + @echo "Starting .NET V4 server..." AWS_ACCESS_KEY_ID="$$AWS_ACCESS_KEY_ID" \ AWS_SECRET_ACCESS_KEY="$$AWS_SECRET_ACCESS_KEY" \ AWS_SESSION_TOKEN="$$AWS_SESSION_TOKEN" \ AWS_REGION="us-west-2" \ - rm -rf obj/v3 bin/v3 && \ - dotnet build -p:S3EncryptionVersion=v3 -o bin/v3 -p:BaseIntermediateOutputPath=obj/v3/ && \ - dotnet bin/v3/NetV2V3Server.dll > net-v3-server.log 2>&1 & echo $$! > net-v3-server.pid - @echo ".NET V3 server starting..." + dotnet run > net-v3-transition-server.log 2>&1 & echo $$! > net-v3-transition-server.pid + @echo ".NET V4 server starting..." wait-for-server: - $(MAKE) -C .. wait-for-port PORT=$(PORT_NET_V2) \ - $(MAKE) -C .. wait-for-port PORT=$(PORT_NET_V3) + $(MAKE) -C .. wait-for-port PORT=$(PORT_NET_V4) duvet: duvet report From 874e5b7be88bb63e10c5ad801c17263921e340e9 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Tue, 28 Oct 2025 18:08:44 -0700 Subject: [PATCH 06/28] auto commit --- .../Controllers/ClientController.cs | 43 ++++++++++++++++--- .../net-v4-server/Models/ClientRequest.cs | 20 +++++++++ .../Services/ClientCacheService.cs | 10 ++--- 3 files changed, 62 insertions(+), 11 deletions(-) diff --git a/test-server/net-v4-server/Controllers/ClientController.cs b/test-server/net-v4-server/Controllers/ClientController.cs index f437c695..26668300 100644 --- a/test-server/net-v4-server/Controllers/ClientController.cs +++ b/test-server/net-v4-server/Controllers/ClientController.cs @@ -34,19 +34,29 @@ public IActionResult CreateClient([FromBody] ClientRequest request) // However, encryption context is a required field when using KMS. // So, we are passing empty dictionary. var encryptionContext = new Dictionary(); - var encryptionMaterial = new EncryptionMaterialsV2(kmsKeyId, KmsType.KmsContext, encryptionContext); + var encryptionMaterial = new EncryptionMaterialsV4(kmsKeyId, KmsType.KmsContext, encryptionContext); logger.LogInformation( - "Created EncryptionMaterialsV2: KMS={KmsKeyId}", + "Created EncryptionMaterialsV4: KMS={KmsKeyId}", kmsKeyId); - // SecurityProfile V2AndLegacy can decrypt from legacy S3EC but V2 cannot + // SecurityProfile V4AndLegacy can decrypt from legacy S3EC but V4 cannot var enableLegacyMode = enableLegacyUnauthenticatedModes || enableLegacyWrappingAlgorithms; - var securityProfile = enableLegacyMode ? SecurityProfile.V2AndLegacy : SecurityProfile.V2; + var securityProfile = enableLegacyMode ? SecurityProfile.V4AndLegacy : SecurityProfile.V4; logger.LogInformation("Created securityProfile= {securityProfile}", securityProfile.ToString()); + + // Map request enums to SDK enums + var commitmentPolicy = MapCommitmentPolicy(request.Config.CommitmentPolicy); - var configuration = new AmazonS3CryptoConfigurationV2(securityProfile); + // Currently, tests does not send EncryptionAlgorithm + // var encryptionAlgorithm = MapEncryptionAlgorithm(request.Config.EncryptionAlgorithm); + var encryptionAlgorithm = commitmentPolicy == Amazon.Extensions.S3.Encryption.CommitmentPolicy.ForbidEncryptAllowDecrypt ? ContentEncryptionAlgorithm.AesGcm : ContentEncryptionAlgorithm.AesGcmWithCommitment; + logger.LogInformation("Created commitmentPolicy= {commitmentPolicy}", commitmentPolicy); + logger.LogInformation("Created encryptionAlgorithm= {encryptionAlgorithm}", encryptionAlgorithm); + + var configuration = new AmazonS3CryptoConfigurationV4(securityProfile, commitmentPolicy, encryptionAlgorithm); + // Create S3 encryption client - var encryptionClient = new AmazonS3EncryptionClientV2(configuration, encryptionMaterial); + var encryptionClient = new AmazonS3EncryptionClientV4(configuration, encryptionMaterial); // Add to cache and return client ID var clientId = clientCacheService.AddClient(encryptionClient); var response = new ClientResponse { ClientId = clientId }; @@ -69,4 +79,25 @@ public IActionResult CreateClient([FromBody] ClientRequest request) }); } } + + private static Amazon.Extensions.S3.Encryption.CommitmentPolicy MapCommitmentPolicy(Models.CommitmentPolicy? policy) + { + return policy switch + { + Models.CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT => Amazon.Extensions.S3.Encryption.CommitmentPolicy.RequireEncryptRequireDecrypt, + Models.CommitmentPolicy.REQUIRE_ENCRYPT_ALLOW_DECRYPT => Amazon.Extensions.S3.Encryption.CommitmentPolicy.RequireEncryptAllowDecrypt, + Models.CommitmentPolicy.FORBID_ENCRYPT_ALLOW_DECRYPT => Amazon.Extensions.S3.Encryption.CommitmentPolicy.ForbidEncryptAllowDecrypt, + _ => Amazon.Extensions.S3.Encryption.CommitmentPolicy.ForbidEncryptAllowDecrypt + }; + } + + private static ContentEncryptionAlgorithm MapEncryptionAlgorithm(Models.EncryptionAlgorithm? algorithm) + { + return algorithm switch + { + Models.EncryptionAlgorithm.ALG_AES_256_GCM_IV12_TAG16_NO_KDF => ContentEncryptionAlgorithm.AesGcm, + Models.EncryptionAlgorithm.ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY => ContentEncryptionAlgorithm.AesGcmWithCommitment, + _ => ContentEncryptionAlgorithm.AesGcm + }; + } } \ No newline at end of file diff --git a/test-server/net-v4-server/Models/ClientRequest.cs b/test-server/net-v4-server/Models/ClientRequest.cs index c425ca8c..28bddd95 100644 --- a/test-server/net-v4-server/Models/ClientRequest.cs +++ b/test-server/net-v4-server/Models/ClientRequest.cs @@ -1,4 +1,5 @@ using System.ComponentModel.DataAnnotations; +using System.Text.Json.Serialization; namespace NetV4Server.Models; @@ -16,6 +17,10 @@ public class ClientConfig public long? SetBufferSize { get; set; } [Required] public KeyMaterial KeyMaterial { get; set; } = new(); + [JsonPropertyName("commitmentPolicy")] + public CommitmentPolicy? CommitmentPolicy { get; set; } + [JsonPropertyName("encryptionAlgorithm")] + public EncryptionAlgorithm? EncryptionAlgorithm { get; set; } } public class KeyMaterial @@ -25,4 +30,19 @@ public class KeyMaterial [Required] public string KmsKeyId { get; set; } = string.Empty; +} + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum CommitmentPolicy +{ + REQUIRE_ENCRYPT_REQUIRE_DECRYPT, + REQUIRE_ENCRYPT_ALLOW_DECRYPT, + FORBID_ENCRYPT_ALLOW_DECRYPT +} + +public enum EncryptionAlgorithm +{ + ALG_AES_256_CBC_IV16_NO_KDF, + ALG_AES_256_GCM_IV12_TAG16_NO_KDF, + ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY } \ No newline at end of file diff --git a/test-server/net-v4-server/Services/ClientCacheService.cs b/test-server/net-v4-server/Services/ClientCacheService.cs index e1183274..55764152 100644 --- a/test-server/net-v4-server/Services/ClientCacheService.cs +++ b/test-server/net-v4-server/Services/ClientCacheService.cs @@ -5,22 +5,22 @@ namespace NetV4Server.Services; public interface IClientCacheService { - string AddClient(AmazonS3EncryptionClientV2 client); - AmazonS3EncryptionClientV2? GetClient(string clientId); + string AddClient(AmazonS3EncryptionClientV4 client); + AmazonS3EncryptionClientV4? GetClient(string clientId); } public class ClientCacheService : IClientCacheService { - private readonly ConcurrentDictionary _clients = new(); + private readonly ConcurrentDictionary _clients = new(); - public string AddClient(AmazonS3EncryptionClientV2 client) + public string AddClient(AmazonS3EncryptionClientV4 client) { var clientId = Guid.NewGuid().ToString(); _clients[clientId] = client; return clientId; } - public AmazonS3EncryptionClientV2? GetClient(string clientId) + public AmazonS3EncryptionClientV4? GetClient(string clientId) { _clients.TryGetValue(clientId, out var client); return client; From d9d7b41b9c73235a78020ad579d232abe07789fb Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Tue, 28 Oct 2025 18:15:23 -0700 Subject: [PATCH 07/28] auto commit --- .github/workflows/test.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8c8a9616..7bcfb2e9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -54,6 +54,15 @@ jobs: ref: s3ec-v3 path: test-server/net-v2-v3-server/s3ec-net-v3 + - name: Checkout .NET V4 (Improved) code + uses: actions/checkout@v5 + with: + token: ${{ secrets.PAT_FOR_DOTNET }} + repository: aws/private-amazon-s3-encryption-client-dotnet-staging + # This is the branch for S3EC .NET V4 (improved) + ref: s3ec-v4-WIP + path: test-server/net-v4-server/s3ec-net-v4-improved + - name: Set up Python uses: actions/setup-python@v5 with: From 2bf1d6b7866aa0effbbb7b754fbac92d82ba5f01 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Tue, 28 Oct 2025 21:57:33 -0700 Subject: [PATCH 08/28] auto commit --- test-server/net-v4-server/.gitignore | 44 ++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 test-server/net-v4-server/.gitignore diff --git a/test-server/net-v4-server/.gitignore b/test-server/net-v4-server/.gitignore new file mode 100644 index 00000000..4c20cbc8 --- /dev/null +++ b/test-server/net-v4-server/.gitignore @@ -0,0 +1,44 @@ +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# NuGet Packages +*.nupkg +*.snupkg +packages/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# VS Code +.vscode/ + +# macOS +.DS_Store + +# Temporary files +*.tmp +*.temp From 7f31a7415f21e750a02c8a656f3960ca427b9223 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Tue, 28 Oct 2025 22:08:06 -0700 Subject: [PATCH 09/28] auto commit --- .../amazon/encryption/s3/RoundTripTests.java | 2 +- .../amazon/encryption/s3/TestUtils.java | 28 +++++++++++-------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/test-server/java-tests/src/it/java/software/amazon/encryption/s3/RoundTripTests.java b/test-server/java-tests/src/it/java/software/amazon/encryption/s3/RoundTripTests.java index e8dc4bae..d4b19482 100644 --- a/test-server/java-tests/src/it/java/software/amazon/encryption/s3/RoundTripTests.java +++ b/test-server/java-tests/src/it/java/software/amazon/encryption/s3/RoundTripTests.java @@ -402,7 +402,7 @@ public void kmsV1LegacyFailsWhenLegacyDisabled(TestUtils.LanguageServerTarget la .build()); fail("Expected Exception"); } catch (S3EncryptionClientError e) { - if (language.getLanguageName().equals(NET_V3) || language.getLanguageName().equals(NET_V2_CURRENT) + if (language.getLanguageName().equals(NET_V3_CURRENT) || language.getLanguageName().equals(NET_V2_CURRENT) || language.getLanguageName().equals(NET_V4) || language.getLanguageName().equals(CPP_V2_CURRENT) || language.getLanguageName().equals(CPP_V2_TRANSITION) || language.getLanguageName().equals(CPP_V3)) { assertTrue(e.getMessage().contains( "The requested object is encrypted with V1 encryption schemas that have been disabled by client configuration" diff --git a/test-server/java-tests/src/it/java/software/amazon/encryption/s3/TestUtils.java b/test-server/java-tests/src/it/java/software/amazon/encryption/s3/TestUtils.java index a79d5bc2..4709c2f2 100644 --- a/test-server/java-tests/src/it/java/software/amazon/encryption/s3/TestUtils.java +++ b/test-server/java-tests/src/it/java/software/amazon/encryption/s3/TestUtils.java @@ -68,8 +68,10 @@ public class TestUtils { public static final String GO_V4 = "Go-V4"; public static final String NET_V2_CURRENT = "NET-V2-Current"; + public static final String NET_V3_CURRENT = "NET-V3-Current"; public static final String NET_V2_TRANSITION = "NET-V2-Transition"; - public static final String NET_V3 = "NET-V3"; + public static final String NET_V3_TRANSITION = "NET-V3-Transition"; + public static final String NET_V4 = "NET-V4"; public static final String CPP_V2_CURRENT = "CPP-V2-Current"; public static final String CPP_V2_TRANSITION = "CPP-V2-Transition"; @@ -92,17 +94,18 @@ public class TestUtils { // Sets of unsupported features by language public static final Set ENCRYPTION_CONTEXT_ON_DECRYPT_UNSUPPORTED = - Set.of(GO_V3_CURRENT, PHP_V2_CURRENT, PHP_V2_TRANSITION, PHP_V3, NET_V2_CURRENT, NET_V3); + Set.of(GO_V3_CURRENT, PHP_V2_CURRENT, PHP_V2_TRANSITION, PHP_V3, NET_V2_CURRENT, NET_V3_CURRENT, NET_V3_TRANSITION, NET_V4); public static final Set ENCRYPTION_CONTEXT_ON_ENCRYPT_UNSUPPORTED = - Set.of(NET_V2_CURRENT, NET_V3); + Set.of(NET_V2_CURRENT, NET_V3_CURRENT, NET_V3_TRANSITION, NET_V4); public static final Set CURRENT_VERSIONS = Set.of( JAVA_V3_CURRENT, GO_V3_CURRENT, NET_V2_CURRENT, - // CPP_V2_CURRENT, + NET_V3_CURRENT, + CPP_V2_CURRENT, RUBY_V2_CURRENT, PHP_V2_CURRENT ); @@ -112,7 +115,8 @@ public class TestUtils { // JAVA_V3_TRANSITION, // GO_V3_TRANSITION, // NET_V2_TRANSITION, - // CPP_V2_TRANSITION, + // NET_V3_TRANSITION, + CPP_V2_TRANSITION, // PHP_V2_TRANSITION, RUBY_V2_TRANSITION ); @@ -121,8 +125,8 @@ public class TestUtils { Set.of( // JAVA_V4, // PYTHON_V3, - // GO_V4, - // NET_V3, + GO_V4, + // NET_V4, // CPP_V3, // PHP_V3, RUBY_V3 @@ -136,21 +140,23 @@ public class TestUtils { servers.put(PYTHON_V3, new LanguageServerTarget(PYTHON_V3, "8081")); servers.put(GO_V3_CURRENT, new LanguageServerTarget(GO_V3_CURRENT, "8082")); servers.put(NET_V2_CURRENT, new LanguageServerTarget(NET_V2_CURRENT, "8083")); - servers.put(NET_V3, new LanguageServerTarget(NET_V3, "8084")); - // servers.put(CPP_V2_CURRENT, new LanguageServerTarget(CPP_V2_CURRENT, "8085")); + servers.put(NET_V3_CURRENT, new LanguageServerTarget(NET_V3_CURRENT, "8084")); + servers.put(CPP_V2_CURRENT, new LanguageServerTarget(CPP_V2_CURRENT, "8085")); // servers.put(RUBY_V2_CURRENT, new LanguageServerTarget(RUBY_V2_CURRENT, "8086")); servers.put(PHP_V2_CURRENT, new LanguageServerTarget(PHP_V2_CURRENT, "8087")); + servers.put(JAVA_V4, new LanguageServerTarget(JAVA_V4, "8088")); servers.put(GO_V4, new LanguageServerTarget(GO_V4, "8089")); + servers.put(NET_V4, new LanguageServerTarget(NET_V4, "8090")); servers.put(RUBY_V3, new LanguageServerTarget(RUBY_V3, "8092")); servers.put(PHP_V3, new LanguageServerTarget(PHP_V3, "8093")); // TODO: Create and add transition servers servers.put(JAVA_V3_TRANSITION, new LanguageServerTarget(JAVA_V3_TRANSITION, "8094")); // servers.put(GO_V3_TRANSITION, new LanguageServerTarget(GO_V3_TRANSITION, "8095")); // servers.put(NET_V2_TRANSITION, new LanguageServerTarget(NET_V2_TRANSITION, "8096")); - // servers.put(CPP_V2_TRANSITION, new LanguageServerTarget(CPP_V2_TRANSITION, "8097")); + servers.put(CPP_V2_TRANSITION, new LanguageServerTarget(CPP_V2_TRANSITION, "8097")); servers.put(RUBY_V2_TRANSITION, new LanguageServerTarget(RUBY_V2_TRANSITION, "8098")); servers.put(PHP_V2_TRANSITION, new LanguageServerTarget(PHP_V2_TRANSITION, "8099")); - servers.put(JAVA_V4, new LanguageServerTarget(JAVA_V4, "8090")); + // servers.put(NET_V3_TRANSITION, new LanguageServerTarget(NET_V3_TRANSITION, "8100")); serverMap = filterServers(servers); } From 58b09e72050b499f8689407a849e1603d1f0b128 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Tue, 28 Oct 2025 23:04:12 -0700 Subject: [PATCH 10/28] auto commit --- test-server/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-server/Makefile b/test-server/Makefile index cd667505..b5f5f4ef 100644 --- a/test-server/Makefile +++ b/test-server/Makefile @@ -6,7 +6,7 @@ all: start-all-servers run-tests # CI target for GitHub Actions -ci: start-all-servers run-tests stop-servers +ci: start-servers run-tests stop-servers SERVER_DIRS := $(shell find . -maxdepth 1 -type d -name '*-server' | sed 's|^\./||' | $(if $(FILTER),grep -E "$$(echo '$(FILTER)' | sed 's/,/|/g')",cat) | sort) # SERVER_DIRS := cpp-v3-server From f93212f1da07af1c6c2cffcdcfb18e2a42558996 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Tue, 28 Oct 2025 23:29:04 -0700 Subject: [PATCH 11/28] auto commit --- test-server/java-v4-server/Makefile | 2 +- test-server/java-v4-server/README.md | 2 +- .../java/software/amazon/encryption/s3/S3ECJavaTestServer.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test-server/java-v4-server/Makefile b/test-server/java-v4-server/Makefile index 922499f7..40805d1e 100644 --- a/test-server/java-v4-server/Makefile +++ b/test-server/java-v4-server/Makefile @@ -3,7 +3,7 @@ .PHONY: start-server stop-server wait-for-server build-s3ec PID_FILE := server.pid -PORT := 8090 +PORT := 8088 build-s3ec: @echo "Building S3EC from source..." diff --git a/test-server/java-v4-server/README.md b/test-server/java-v4-server/README.md index d011daa2..70d60914 100644 --- a/test-server/java-v4-server/README.md +++ b/test-server/java-v4-server/README.md @@ -18,6 +18,6 @@ To run the server: gradle run ``` -This will start the server running on port `8090`. +This will start the server running on port `8088`. The server is used as part of the testing framework to verify cross-language compatibility of the S3 Encryption Client implementations. diff --git a/test-server/java-v4-server/src/main/java/software/amazon/encryption/s3/S3ECJavaTestServer.java b/test-server/java-v4-server/src/main/java/software/amazon/encryption/s3/S3ECJavaTestServer.java index 7b73ffd1..9ff79e89 100644 --- a/test-server/java-v4-server/src/main/java/software/amazon/encryption/s3/S3ECJavaTestServer.java +++ b/test-server/java-v4-server/src/main/java/software/amazon/encryption/s3/S3ECJavaTestServer.java @@ -15,7 +15,7 @@ import software.amazon.encryption.s3.service.S3ECTestServer; public class S3ECJavaTestServer implements Runnable { - static final URI endpoint = URI.create("http://localhost:8090"); + static final URI endpoint = URI.create("http://localhost:8098"); public static void main(String[] args) { new S3ECJavaTestServer().run(); From 153b7fc8b98467ff31557ff4168bbf76bf89a2c0 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Wed, 29 Oct 2025 00:43:35 -0700 Subject: [PATCH 12/28] auto commit --- .../Controllers/ClientController.cs | 22 ++++++++++--------- .../net-v4-server/Models/ClientRequest.cs | 6 ++--- test-server/net-v4-server/README.md | 4 ++-- .../net-v4-server/s3ec-net-v4-improved | 2 +- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/test-server/net-v4-server/Controllers/ClientController.cs b/test-server/net-v4-server/Controllers/ClientController.cs index 26668300..60671ffc 100644 --- a/test-server/net-v4-server/Controllers/ClientController.cs +++ b/test-server/net-v4-server/Controllers/ClientController.cs @@ -15,7 +15,7 @@ public class ClientController(IClientCacheService clientCacheService, ILogger Date: Wed, 29 Oct 2025 07:38:37 -0700 Subject: [PATCH 13/28] Update S3ECJavaTestServer.java --- .../java/software/amazon/encryption/s3/S3ECJavaTestServer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-server/java-v4-server/src/main/java/software/amazon/encryption/s3/S3ECJavaTestServer.java b/test-server/java-v4-server/src/main/java/software/amazon/encryption/s3/S3ECJavaTestServer.java index 9ff79e89..c3fee4f1 100644 --- a/test-server/java-v4-server/src/main/java/software/amazon/encryption/s3/S3ECJavaTestServer.java +++ b/test-server/java-v4-server/src/main/java/software/amazon/encryption/s3/S3ECJavaTestServer.java @@ -15,7 +15,7 @@ import software.amazon.encryption.s3.service.S3ECTestServer; public class S3ECJavaTestServer implements Runnable { - static final URI endpoint = URI.create("http://localhost:8098"); + static final URI endpoint = URI.create("http://localhost:8088"); public static void main(String[] args) { new S3ECJavaTestServer().run(); From 79bb08e01867bc275a8b56071c8baceb12ceebf9 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Wed, 29 Oct 2025 09:26:33 -0700 Subject: [PATCH 14/28] bump --- .../Controllers/ClientController.cs | 18 ++++++++++++++---- test-server/net-v4-server/s3ec-net-v4-improved | 2 +- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/test-server/net-v4-server/Controllers/ClientController.cs b/test-server/net-v4-server/Controllers/ClientController.cs index 60671ffc..b1ffcfc5 100644 --- a/test-server/net-v4-server/Controllers/ClientController.cs +++ b/test-server/net-v4-server/Controllers/ClientController.cs @@ -32,6 +32,9 @@ public IActionResult CreateClient([FromBody] ClientRequest request) var commitmentPolicy = MapCommitmentPolicy(request.Config.CommitmentPolicy); var isSecurityProfileProvided = request.Config.EnableLegacyUnauthenticatedModes.HasValue || request.Config.EnableLegacyWrappingAlgorithms.HasValue; var isCommitmentPolicyProvided = request.Config.CommitmentPolicy.HasValue; + var useDefaultConf = !isSecurityProfileProvided && !isCommitmentPolicyProvided; + + logger.LogInformation("isSecurityProfileProvided: {isSecurityProfileProvided}, isCommitmentPolicyProvided: {isCommitmentPolicyProvided}, useDefaultConf: {useDefaultConf}", isSecurityProfileProvided, isCommitmentPolicyProvided, useDefaultConf); // The POST request does not contain encryption context. // However, encryption context is a required field when using KMS. @@ -45,15 +48,22 @@ public IActionResult CreateClient([FromBody] ClientRequest request) // SecurityProfile V4AndLegacy can decrypt from legacy S3EC but V4 cannot var enableLegacyMode = enableLegacyUnauthenticatedModes || enableLegacyWrappingAlgorithms; var securityProfile = enableLegacyMode ? SecurityProfile.V4AndLegacy : SecurityProfile.V4; - logger.LogInformation("Created securityProfile= {securityProfile}", securityProfile.ToString()); // Currently, tests does not send EncryptionAlgorithm // var encryptionAlgorithm = MapEncryptionAlgorithm(request.Config.EncryptionAlgorithm); var encryptionAlgorithm = commitmentPolicy == Amazon.Extensions.S3.Encryption.CommitmentPolicy.ForbidEncryptAllowDecrypt ? ContentEncryptionAlgorithm.AesGcm : ContentEncryptionAlgorithm.AesGcmWithCommitment; - logger.LogInformation("Created commitmentPolicy= {commitmentPolicy}", commitmentPolicy); - logger.LogInformation("Created encryptionAlgorithm= {encryptionAlgorithm}", encryptionAlgorithm); + + if (!useDefaultConf) + { + logger.LogInformation("Created securityProfile= {securityProfile}", securityProfile.ToString()); + logger.LogInformation("Created commitmentPolicy= {commitmentPolicy}", commitmentPolicy); + logger.LogInformation("Created encryptionAlgorithm= {encryptionAlgorithm}", encryptionAlgorithm); + } else + { + logger.LogInformation("Using default configuration for securityProfile, commitmentPolicy and encryptionAlgorithm"); + } - var configuration = (!isSecurityProfileProvided && !isCommitmentPolicyProvided) + var configuration = useDefaultConf ? new AmazonS3CryptoConfigurationV4() : new AmazonS3CryptoConfigurationV4(securityProfile, commitmentPolicy, encryptionAlgorithm); diff --git a/test-server/net-v4-server/s3ec-net-v4-improved b/test-server/net-v4-server/s3ec-net-v4-improved index 18621b2a..c647789d 160000 --- a/test-server/net-v4-server/s3ec-net-v4-improved +++ b/test-server/net-v4-server/s3ec-net-v4-improved @@ -1 +1 @@ -Subproject commit 18621b2aabca432697c4208b854d1504d997a8d1 +Subproject commit c647789d34964f23bf2b3d07e2f686ecf43140a6 From a23050b309ae46d6a99904fec8db5e959babedcd Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Thu, 30 Oct 2025 09:29:32 -0700 Subject: [PATCH 15/28] auto commit --- .../Controllers/ClientController.cs | 26 +++++++++---------- .../Controllers/ObjectController.cs | 18 ++++++------- test-server/net-v4-server/Makefile | 2 +- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/test-server/net-v4-server/Controllers/ClientController.cs b/test-server/net-v4-server/Controllers/ClientController.cs index b1ffcfc5..3634b0a8 100644 --- a/test-server/net-v4-server/Controllers/ClientController.cs +++ b/test-server/net-v4-server/Controllers/ClientController.cs @@ -16,13 +16,13 @@ public IActionResult CreateClient([FromBody] ClientRequest request) { // Return 501 for not implemented features by the server if (request.Config.EnableDelayedAuthenticationMode ?? false) - return StatusCode(501, new GenericServerError { Message = "EnableDelayedAuthenticationMode not supported" }); + return StatusCode(501, new GenericServerError { Message = "[NET-V4] EnableDelayedAuthenticationMode not supported" }); if (request.Config.SetBufferSize.HasValue) - return StatusCode(501, new GenericServerError { Message = "SetBufferSize not supported" }); + return StatusCode(501, new GenericServerError { Message = "[NET-V4] SetBufferSize not supported" }); if (request.Config.KeyMaterial.RsaKey != null) - return StatusCode(501, new GenericServerError { Message = "RsaKey not supported" }); + return StatusCode(501, new GenericServerError { Message = "[NET-V4] RsaKey not supported" }); if (request.Config.KeyMaterial.AesKey != null) - return StatusCode(501, new GenericServerError { Message = "AesKey not supported" }); + return StatusCode(501, new GenericServerError { Message = "[NET-V4] AesKey not supported" }); try { @@ -34,7 +34,7 @@ public IActionResult CreateClient([FromBody] ClientRequest request) var isCommitmentPolicyProvided = request.Config.CommitmentPolicy.HasValue; var useDefaultConf = !isSecurityProfileProvided && !isCommitmentPolicyProvided; - logger.LogInformation("isSecurityProfileProvided: {isSecurityProfileProvided}, isCommitmentPolicyProvided: {isCommitmentPolicyProvided}, useDefaultConf: {useDefaultConf}", isSecurityProfileProvided, isCommitmentPolicyProvided, useDefaultConf); + logger.LogInformation("[NET-V4] isSecurityProfileProvided: {isSecurityProfileProvided}, isCommitmentPolicyProvided: {isCommitmentPolicyProvided}, useDefaultConf: {useDefaultConf}", isSecurityProfileProvided, isCommitmentPolicyProvided, useDefaultConf); // The POST request does not contain encryption context. // However, encryption context is a required field when using KMS. @@ -42,7 +42,7 @@ public IActionResult CreateClient([FromBody] ClientRequest request) var encryptionContext = new Dictionary(); var encryptionMaterial = new EncryptionMaterialsV4(kmsKeyId, KmsType.KmsContext, encryptionContext); logger.LogInformation( - "Created EncryptionMaterialsV4: KMS={KmsKeyId}", + "[NET-V4] Created EncryptionMaterialsV4: KMS={KmsKeyId}", kmsKeyId); // SecurityProfile V4AndLegacy can decrypt from legacy S3EC but V4 cannot @@ -55,12 +55,12 @@ public IActionResult CreateClient([FromBody] ClientRequest request) if (!useDefaultConf) { - logger.LogInformation("Created securityProfile= {securityProfile}", securityProfile.ToString()); - logger.LogInformation("Created commitmentPolicy= {commitmentPolicy}", commitmentPolicy); - logger.LogInformation("Created encryptionAlgorithm= {encryptionAlgorithm}", encryptionAlgorithm); + logger.LogInformation("[NET-V4] Created securityProfile= {securityProfile}", securityProfile.ToString()); + logger.LogInformation("[NET-V4] Created commitmentPolicy= {commitmentPolicy}", commitmentPolicy); + logger.LogInformation("[NET-V4] Created encryptionAlgorithm= {encryptionAlgorithm}", encryptionAlgorithm); } else { - logger.LogInformation("Using default configuration for securityProfile, commitmentPolicy and encryptionAlgorithm"); + logger.LogInformation("[NET-V4] Using default configuration for securityProfile, commitmentPolicy and encryptionAlgorithm"); } var configuration = useDefaultConf @@ -73,7 +73,7 @@ public IActionResult CreateClient([FromBody] ClientRequest request) var clientId = clientCacheService.AddClient(encryptionClient); var response = new ClientResponse { ClientId = clientId }; - logger.LogInformation("Created S3EC client with ID: {clientId}", clientId); + logger.LogInformation("[NET-V4] Created S3EC client with ID: {clientId}", clientId); return new ContentResult { @@ -84,10 +84,10 @@ public IActionResult CreateClient([FromBody] ClientRequest request) } catch (Exception ex) { - logger.LogError(ex, "Failed to create S3EC client"); + logger.LogError(ex, "[NET-V4] Failed to create S3EC client"); return StatusCode(500, new S3EncryptionClientError { - Message = $"Failed to create client: {ex.Message}" + Message = $"[NET-V4] Failed to create client: {ex.Message}" }); } } diff --git a/test-server/net-v4-server/Controllers/ObjectController.cs b/test-server/net-v4-server/Controllers/ObjectController.cs index e4b9f022..7ebd8fd1 100644 --- a/test-server/net-v4-server/Controllers/ObjectController.cs +++ b/test-server/net-v4-server/Controllers/ObjectController.cs @@ -16,11 +16,11 @@ public async Task PutObject(string bucket, string key) logger.LogInformation("Starting PutObject"); var clientId = Request.Headers["clientId"].FirstOrDefault(); if (string.IsNullOrEmpty(clientId)) - return BadRequest(new GenericServerError { Message = "ClientID header is required" }); + return BadRequest(new GenericServerError { Message = "[NET-V4] ClientID header is required" }); var client = clientCacheService.GetClient(clientId); if (client == null) - return NotFound(new GenericServerError { Message = $"No client found for ClientID: {clientId}" }); + return NotFound(new GenericServerError { Message = $"[NET-V4] No client found for ClientID: {clientId}" }); try { @@ -43,7 +43,7 @@ public async Task PutObject(string bucket, string key) var response = new { bucket, key }; logger.LogInformation( - "Put object succeeded for bucket={bucket}, key={key} and clientId = {clientId}", + "[NET-V4] Put object succeeded for bucket={bucket}, key={key} and clientId = {clientId}", bucket, key, clientId); return new ContentResult { @@ -54,7 +54,7 @@ public async Task PutObject(string bucket, string key) } catch (Exception ex) { - logger.LogError(ex, "Failed to put object from S3 for bucket={bucket}, key={key}", bucket, key); + logger.LogError(ex, "[NET-V4] Failed to put object from S3 for bucket={bucket}, key={key}", bucket, key); return StatusCode(500, new S3EncryptionClientError { Message = $"Failed to put object: {ex.Message}" }); } } @@ -62,14 +62,14 @@ public async Task PutObject(string bucket, string key) [HttpGet("{bucket}/{key}")] public async Task GetObject(string bucket, string key) { - logger.LogInformation("Starting GetObject"); + logger.LogInformation("[NET-V4] Starting GetObject"); var clientId = Request.Headers["clientId"].FirstOrDefault(); if (string.IsNullOrEmpty(clientId)) - return BadRequest(new GenericServerError { Message = "ClientID header is required" }); + return BadRequest(new GenericServerError { Message = "[NET-V4] ClientID header is required" }); var client = clientCacheService.GetClient(clientId); if (client == null) - return NotFound(new GenericServerError { Message = $"No client found for ClientID: {clientId}" }); + return NotFound(new GenericServerError { Message = $"[NET-V4] No client found for ClientID: {clientId}" }); try { @@ -79,7 +79,7 @@ public async Task GetObject(string bucket, string key) Key = key }; var response = await client.GetObjectAsync(getRequest); - logger.LogInformation("Got object from S3 for bucket={bucket}, key={key}", bucket, key); + logger.LogInformation("[NET-V4] Got object from S3 for bucket={bucket}, key={key}", bucket, key); // Read response body using var memoryStream = new MemoryStream(); await response.ResponseStream.CopyToAsync(memoryStream); @@ -98,7 +98,7 @@ public async Task GetObject(string bucket, string key) } catch (Exception ex) { - logger.LogError(ex, "Failed to get object from S3 for bucket={bucket}, key={key}", bucket, key); + logger.LogError(ex, "[NET-V4] Failed to get object from S3 for bucket={bucket}, key={key}", bucket, key); return StatusCode(500, new S3EncryptionClientError { Message = ex.Message }); } } diff --git a/test-server/net-v4-server/Makefile b/test-server/net-v4-server/Makefile index e667971d..49e4db32 100644 --- a/test-server/net-v4-server/Makefile +++ b/test-server/net-v4-server/Makefile @@ -23,7 +23,7 @@ start-net-V4-server: AWS_SECRET_ACCESS_KEY="$$AWS_SECRET_ACCESS_KEY" \ AWS_SESSION_TOKEN="$$AWS_SESSION_TOKEN" \ AWS_REGION="us-west-2" \ - dotnet run > net-v3-transition-server.log 2>&1 & echo $$! > net-v3-transition-server.pid + dotnet run & echo $! > net-v3-transition-server.pid @echo ".NET V4 server starting..." wait-for-server: From 00ac5e249fc547cf3b5c861193458c9f992146cb Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Thu, 30 Oct 2025 10:08:17 -0700 Subject: [PATCH 16/28] auto commit --- test-server/net-v4-server/Controllers/ClientController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-server/net-v4-server/Controllers/ClientController.cs b/test-server/net-v4-server/Controllers/ClientController.cs index 3634b0a8..0339ab9f 100644 --- a/test-server/net-v4-server/Controllers/ClientController.cs +++ b/test-server/net-v4-server/Controllers/ClientController.cs @@ -32,7 +32,7 @@ public IActionResult CreateClient([FromBody] ClientRequest request) var commitmentPolicy = MapCommitmentPolicy(request.Config.CommitmentPolicy); var isSecurityProfileProvided = request.Config.EnableLegacyUnauthenticatedModes.HasValue || request.Config.EnableLegacyWrappingAlgorithms.HasValue; var isCommitmentPolicyProvided = request.Config.CommitmentPolicy.HasValue; - var useDefaultConf = !isSecurityProfileProvided && !isCommitmentPolicyProvided; + var useDefaultConf = !isCommitmentPolicyProvided; logger.LogInformation("[NET-V4] isSecurityProfileProvided: {isSecurityProfileProvided}, isCommitmentPolicyProvided: {isCommitmentPolicyProvided}, useDefaultConf: {useDefaultConf}", isSecurityProfileProvided, isCommitmentPolicyProvided, useDefaultConf); From 060bb4c607348654523eb1930236abb6d5bf872b Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Thu, 30 Oct 2025 10:16:22 -0700 Subject: [PATCH 17/28] auto commit --- test-server/net-v4-server/Controllers/ClientController.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/test-server/net-v4-server/Controllers/ClientController.cs b/test-server/net-v4-server/Controllers/ClientController.cs index 0339ab9f..934c9fac 100644 --- a/test-server/net-v4-server/Controllers/ClientController.cs +++ b/test-server/net-v4-server/Controllers/ClientController.cs @@ -99,7 +99,6 @@ private static Amazon.Extensions.S3.Encryption.CommitmentPolicy MapCommitmentPol Models.CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT => Amazon.Extensions.S3.Encryption.CommitmentPolicy.RequireEncryptRequireDecrypt, Models.CommitmentPolicy.REQUIRE_ENCRYPT_ALLOW_DECRYPT => Amazon.Extensions.S3.Encryption.CommitmentPolicy.RequireEncryptAllowDecrypt, Models.CommitmentPolicy.FORBID_ENCRYPT_ALLOW_DECRYPT => Amazon.Extensions.S3.Encryption.CommitmentPolicy.ForbidEncryptAllowDecrypt, - _ => Amazon.Extensions.S3.Encryption.CommitmentPolicy.ForbidEncryptAllowDecrypt }; } From fdc388c00a8008a920cd79945cfc1983689fe902 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Thu, 30 Oct 2025 11:04:33 -0700 Subject: [PATCH 18/28] auto commit --- test-server/net-v4-server/Controllers/ClientController.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/test-server/net-v4-server/Controllers/ClientController.cs b/test-server/net-v4-server/Controllers/ClientController.cs index 934c9fac..91fcc055 100644 --- a/test-server/net-v4-server/Controllers/ClientController.cs +++ b/test-server/net-v4-server/Controllers/ClientController.cs @@ -99,6 +99,7 @@ private static Amazon.Extensions.S3.Encryption.CommitmentPolicy MapCommitmentPol Models.CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT => Amazon.Extensions.S3.Encryption.CommitmentPolicy.RequireEncryptRequireDecrypt, Models.CommitmentPolicy.REQUIRE_ENCRYPT_ALLOW_DECRYPT => Amazon.Extensions.S3.Encryption.CommitmentPolicy.RequireEncryptAllowDecrypt, Models.CommitmentPolicy.FORBID_ENCRYPT_ALLOW_DECRYPT => Amazon.Extensions.S3.Encryption.CommitmentPolicy.ForbidEncryptAllowDecrypt, + _ => Amazon.Extensions.S3.Encryption.CommitmentPolicy.RequireEncryptRequireDecrypt }; } From 8c3f1dbd682bf8454b87b4cf94fc1d3a9d756215 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Thu, 6 Nov 2025 10:24:18 -0800 Subject: [PATCH 19/28] duvet --- .../client/aws-sdk-compatibility.toml | 27 +++ .../client/cryptographic-materials.toml | 38 +++ .../client/enable-delayed-authentication.toml | 33 +++ .../enable-legacy-unauthenticated-modes.toml | 33 +++ .../enable-legacy-wrapping-algorithms.toml | 33 +++ .../client/encryption-algorithm.toml | 26 +++ .../client/inherited-sdk-configuration.toml | 34 +++ .../instruction-file-configuration.toml | 26 +++ .../s3-encryption/client/key-commitment.toml | 26 +++ .../client/optional-api-operations.toml | 101 ++++++++ .../s3-encryption/client/randomness.toml | 13 ++ .../client/required-api-operations.toml | 77 +++++++ .../s3-encryption/client/set-buffer-size.toml | 26 +++ .../client/wrapped-s3-client-s.toml | 19 ++ ...-message-format-version-compatibility.toml | 34 +++ .../content-metadata-mapkeys.toml | 217 ++++++++++++++++++ .../determining-s3ec-object-status.toml | 60 +++++ .../content-metadata/v1-v2-shared.toml | 24 ++ .../data-format/content-metadata/v3-only.toml | 91 ++++++++ .../metadata-strategy/instruction-file.toml | 66 ++++++ .../metadata-strategy/object-metadata.toml | 28 +++ .../v1-v2-instruction-files.toml | 12 + .../v3-instruction-files.toml | 81 +++++++ .../decrypting-with-commitment.toml | 33 +++ .../decryption/key-commitment.toml | 20 ++ .../decryption/legacy-decryption.toml | 19 ++ .../s3-encryption/decryption/ranged-gets.toml | 44 ++++ ...lg-aes-256-ctr-hkdf-sha512-commit-key.toml | 14 ++ .../alg-aes-256-ctr-iv16-tag16-no-kdf.toml | 14 ++ ...lg-aes-256-gcm-hkdf-sha512-commit-key.toml | 27 +++ .../alg-aes-256-gcm-iv12-tag16-no-kdf.toml | 26 +++ .../encryption/cipher-initialization.toml | 16 ++ .../encryption/content-encryption.toml | 43 ++++ .../key-commitment/commitment-policy.toml | 58 +++++ .../key-derivation/hkdf-operation.toml | 106 +++++++++ 35 files changed, 1545 insertions(+) create mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/aws-sdk-compatibility.toml create mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/cryptographic-materials.toml create mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/enable-delayed-authentication.toml create mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/enable-legacy-unauthenticated-modes.toml create mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/enable-legacy-wrapping-algorithms.toml create mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/encryption-algorithm.toml create mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/inherited-sdk-configuration.toml create mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/instruction-file-configuration.toml create mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/key-commitment.toml create mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/optional-api-operations.toml create mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/randomness.toml create mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/required-api-operations.toml create mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/set-buffer-size.toml create mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/wrapped-s3-client-s.toml create mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/algorithm-suite-and-message-format-version-compatibility.toml create mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/content-metadata-mapkeys.toml create mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/determining-s3ec-object-status.toml create mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/v1-v2-shared.toml create mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/v3-only.toml create mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/metadata-strategy/instruction-file.toml create mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/metadata-strategy/object-metadata.toml create mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/metadata-strategy/v1-v2-instruction-files.toml create mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/metadata-strategy/v3-instruction-files.toml create mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/decryption/decrypting-with-commitment.toml create mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/decryption/key-commitment.toml create mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/decryption/legacy-decryption.toml create mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/decryption/ranged-gets.toml create mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/alg-aes-256-ctr-hkdf-sha512-commit-key.toml create mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/alg-aes-256-ctr-iv16-tag16-no-kdf.toml create mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/alg-aes-256-gcm-hkdf-sha512-commit-key.toml create mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/alg-aes-256-gcm-iv12-tag16-no-kdf.toml create mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/cipher-initialization.toml create mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/content-encryption.toml create mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/key-commitment/commitment-policy.toml create mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/key-derivation/hkdf-operation.toml diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/aws-sdk-compatibility.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/aws-sdk-compatibility.toml new file mode 100644 index 00000000..ddaf61a2 --- /dev/null +++ b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/aws-sdk-compatibility.toml @@ -0,0 +1,27 @@ +target = "../specification/s3-encryption/client.md#aws-sdk-compatibility" + +# AWS SDK Compatibility +# +# The S3EC MUST adhere to the same interface for API operations as the conventional AWS SDK S3 client. +# In other words, the SDK's conventional S3 client is able to be substituted for the S3EC. +# The S3EC SHOULD support invoking operations unrelated to client-side encryption e.g. CopyObject as the conventional AWS SDK S3 client would. +# The S3EC MUST provide a different set of configuration options than the conventional S3 client. + +[[spec]] +level = "MUST" +quote = ''' +The S3EC MUST adhere to the same interface for API operations as the conventional AWS SDK S3 client. +''' + +[[spec]] +level = "SHOULD" +quote = ''' +The S3EC SHOULD support invoking operations unrelated to client-side encryption e.g. +''' + +[[spec]] +level = "MUST" +quote = ''' +The S3EC MUST provide a different set of configuration options than the conventional S3 client. +''' + diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/cryptographic-materials.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/cryptographic-materials.toml new file mode 100644 index 00000000..1f9aac05 --- /dev/null +++ b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/cryptographic-materials.toml @@ -0,0 +1,38 @@ +target = "../specification/s3-encryption/client.md#cryptographic-materials" + +# Cryptographic Materials +# +# The S3EC MUST accept either one CMM or one Keyring instance upon initialization. +# If both a CMM and a Keyring are provided, the S3EC MUST throw an exception. +# When a Keyring is provided, the S3EC MUST create an instance of the DefaultCMM using the provided Keyring. +# +# The S3EC MAY accept key material directly. +# When only key material is provided, a Keyring corresponding to the type of key material is created by default. +# This behavior is discouraged, as it requires all Keyring configuration options to be supported by client initialization. +# This leads to customer confusion when a Keyring is provided and a Keyring option is set on the client, and thus not applied. +# It is considered deprecated, meaning it will be removed in the next major version (v4). + +[[spec]] +level = "MUST" +quote = ''' +The S3EC MUST accept either one CMM or one Keyring instance upon initialization. +''' + +[[spec]] +level = "MUST" +quote = ''' +If both a CMM and a Keyring are provided, the S3EC MUST throw an exception. +''' + +[[spec]] +level = "MUST" +quote = ''' +When a Keyring is provided, the S3EC MUST create an instance of the DefaultCMM using the provided Keyring. +''' + +[[spec]] +level = "MAY" +quote = ''' +The S3EC MAY accept key material directly. +''' + diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/enable-delayed-authentication.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/enable-delayed-authentication.toml new file mode 100644 index 00000000..15473a14 --- /dev/null +++ b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/enable-delayed-authentication.toml @@ -0,0 +1,33 @@ +target = "../specification/s3-encryption/client.md#enable-delayed-authentication" + +# Enable Delayed Authentication +# +# The S3EC MUST support the option to enable or disable Delayed Authentication mode. +# Delayed Authentication mode MUST be set to false by default. +# When enabled, the S3EC MAY release plaintext from a stream which has not been authenticated. +# When disabled the S3EC MUST NOT release plaintext from a stream which has not been authenticated. + +[[spec]] +level = "MUST" +quote = ''' +The S3EC MUST support the option to enable or disable Delayed Authentication mode. +''' + +[[spec]] +level = "MUST" +quote = ''' +Delayed Authentication mode MUST be set to false by default. +''' + +[[spec]] +level = "MAY" +quote = ''' +When enabled, the S3EC MAY release plaintext from a stream which has not been authenticated. +''' + +[[spec]] +level = "MUST" +quote = ''' +When disabled the S3EC MUST NOT release plaintext from a stream which has not been authenticated. +''' + diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/enable-legacy-unauthenticated-modes.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/enable-legacy-unauthenticated-modes.toml new file mode 100644 index 00000000..b571e1b1 --- /dev/null +++ b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/enable-legacy-unauthenticated-modes.toml @@ -0,0 +1,33 @@ +target = "../specification/s3-encryption/client.md#enable-legacy-unauthenticated-modes" + +# Enable Legacy Unauthenticated Modes +# +# The S3EC MUST support the option to enable or disable legacy unauthenticated modes (content encryption algorithms). +# The option to enable legacy unauthenticated modes MUST be set to false by default. +# When enabled, the S3EC MUST be able to decrypt objects encrypted with all content encryption algorithms (both legacy and fully supported). +# When disabled, the S3EC MUST NOT decrypt objects encrypted using legacy content encryption algorithms; it MUST throw an exception when attempting to decrypt an object encrypted with a legacy content encryption algorithm. + +[[spec]] +level = "MUST" +quote = ''' +The S3EC MUST support the option to enable or disable legacy unauthenticated modes (content encryption algorithms). +''' + +[[spec]] +level = "MUST" +quote = ''' +The option to enable legacy unauthenticated modes MUST be set to false by default. +''' + +[[spec]] +level = "MUST" +quote = ''' +When enabled, the S3EC MUST be able to decrypt objects encrypted with all content encryption algorithms (both legacy and fully supported). +''' + +[[spec]] +level = "MUST" +quote = ''' +When disabled, the S3EC MUST NOT decrypt objects encrypted using legacy content encryption algorithms; it MUST throw an exception when attempting to decrypt an object encrypted with a legacy content encryption algorithm. +''' + diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/enable-legacy-wrapping-algorithms.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/enable-legacy-wrapping-algorithms.toml new file mode 100644 index 00000000..20fedc49 --- /dev/null +++ b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/enable-legacy-wrapping-algorithms.toml @@ -0,0 +1,33 @@ +target = "../specification/s3-encryption/client.md#enable-legacy-wrapping-algorithms" + +# Enable Legacy Wrapping Algorithms +# +# The S3EC MUST support the option to enable or disable legacy wrapping algorithms. +# The option to enable legacy wrapping algorithms MUST be set to false by default. +# When enabled, the S3EC MUST be able to decrypt objects encrypted with all supported wrapping algorithms (both legacy and fully supported). +# When disabled, the S3EC MUST NOT decrypt objects encrypted using legacy wrapping algorithms; it MUST throw an exception when attempting to decrypt an object encrypted with a legacy wrapping algorithm. + +[[spec]] +level = "MUST" +quote = ''' +The S3EC MUST support the option to enable or disable legacy wrapping algorithms. +''' + +[[spec]] +level = "MUST" +quote = ''' +The option to enable legacy wrapping algorithms MUST be set to false by default. +''' + +[[spec]] +level = "MUST" +quote = ''' +When enabled, the S3EC MUST be able to decrypt objects encrypted with all supported wrapping algorithms (both legacy and fully supported). +''' + +[[spec]] +level = "MUST" +quote = ''' +When disabled, the S3EC MUST NOT decrypt objects encrypted using legacy wrapping algorithms; it MUST throw an exception when attempting to decrypt an object encrypted with a legacy wrapping algorithm. +''' + diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/encryption-algorithm.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/encryption-algorithm.toml new file mode 100644 index 00000000..a3cfb41e --- /dev/null +++ b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/encryption-algorithm.toml @@ -0,0 +1,26 @@ +target = "../specification/s3-encryption/client.md#encryption-algorithm" + +# Encryption Algorithm +# +# The S3EC MUST support configuration of the encryption algorithm (or algorithm suite) during its initialization. +# The S3EC MUST validate that the configured encryption algorithm is not legacy. +# If the configured encryption algorithm is legacy, then the S3EC MUST throw an exception. + +[[spec]] +level = "MUST" +quote = ''' +The S3EC MUST support configuration of the encryption algorithm (or algorithm suite) during its initialization. +''' + +[[spec]] +level = "MUST" +quote = ''' +The S3EC MUST validate that the configured encryption algorithm is not legacy. +''' + +[[spec]] +level = "MUST" +quote = ''' +If the configured encryption algorithm is legacy, then the S3EC MUST throw an exception. +''' + diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/inherited-sdk-configuration.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/inherited-sdk-configuration.toml new file mode 100644 index 00000000..36a1132a --- /dev/null +++ b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/inherited-sdk-configuration.toml @@ -0,0 +1,34 @@ +target = "../specification/s3-encryption/client.md#inherited-sdk-configuration" + +# Inherited SDK Configuration +# +# The S3EC MAY support directly configuring the wrapped SDK clients through its initialization. +# For example, the S3EC MAY accept a credentials provider instance during its initialization. +# If the S3EC accepts SDK client configuration, the configuration MUST be applied to all wrapped S3 clients. +# If the S3EC accepts SDK client configuration, the configuration MUST be applied to all wrapped SDK clients including the KMS client. +# If the S3EC accepts any SDK client configuration options, then the S3EC should support all possible configuration options. + +[[spec]] +level = "MAY" +quote = ''' +The S3EC MAY support directly configuring the wrapped SDK clients through its initialization. +''' + +[[spec]] +level = "MAY" +quote = ''' +For example, the S3EC MAY accept a credentials provider instance during its initialization. +''' + +[[spec]] +level = "MUST" +quote = ''' +If the S3EC accepts SDK client configuration, the configuration MUST be applied to all wrapped S3 clients. +''' + +[[spec]] +level = "MUST" +quote = ''' +If the S3EC accepts SDK client configuration, the configuration MUST be applied to all wrapped SDK clients including the KMS client. +''' + diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/instruction-file-configuration.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/instruction-file-configuration.toml new file mode 100644 index 00000000..2f1ae4e6 --- /dev/null +++ b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/instruction-file-configuration.toml @@ -0,0 +1,26 @@ +target = "../specification/s3-encryption/client.md#instruction-file-configuration" + +# Instruction File Configuration +# +# The S3EC MAY support the option to provide Instruction File Configuration during its initialization. +# If the S3EC in a given language supports Instruction Files, then it MUST accept Instruction File Configuration during its initialization. +# In this case, the Instruction File Configuration SHOULD be optional, such that its default configuration is used when none is provided. + +[[spec]] +level = "MAY" +quote = ''' +The S3EC MAY support the option to provide Instruction File Configuration during its initialization. +''' + +[[spec]] +level = "MUST" +quote = ''' +If the S3EC in a given language supports Instruction Files, then it MUST accept Instruction File Configuration during its initialization. +''' + +[[spec]] +level = "SHOULD" +quote = ''' +In this case, the Instruction File Configuration SHOULD be optional, such that its default configuration is used when none is provided. +''' + diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/key-commitment.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/key-commitment.toml new file mode 100644 index 00000000..ea8326bb --- /dev/null +++ b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/key-commitment.toml @@ -0,0 +1,26 @@ +target = "../specification/s3-encryption/client.md#key-commitment" + +# Key Commitment +# +# The S3EC MUST support configuration of the [Key Commitment policy](./key-commitment.md) during its initialization. +# The S3EC MUST validate the configured Encryption Algorithm against the provided key commitment policy. +# If the configured Encryption Algorithm is incompatible with the key commitment policy, then it MUST throw an exception. + +[[spec]] +level = "MUST" +quote = ''' +The S3EC MUST support configuration of the [Key Commitment policy](./key-commitment.md) during its initialization. +''' + +[[spec]] +level = "MUST" +quote = ''' +The S3EC MUST validate the configured Encryption Algorithm against the provided key commitment policy. +''' + +[[spec]] +level = "MUST" +quote = ''' +If the configured Encryption Algorithm is incompatible with the key commitment policy, then it MUST throw an exception. +''' + diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/optional-api-operations.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/optional-api-operations.toml new file mode 100644 index 00000000..8822b14c --- /dev/null +++ b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/optional-api-operations.toml @@ -0,0 +1,101 @@ +target = "../specification/s3-encryption/client.md#optional-api-operations" + +# Optional API Operations +# +# The S3EC may provide implementations for the following S3 operations: +# +# - CreateMultipartUpload MAY be implemented by the S3EC. +# - If implemented, CreateMultipartUpload MUST initiate a multipart upload. +# - UploadPart MAY be implemented by the S3EC. +# - UploadPart MUST encrypt each part. +# - Each part MUST be encrypted in sequence. +# - Each part MUST be encrypted using the same cipher instance for each part. +# - CompleteMultipartUpload MAY be implemented by the S3EC. +# - CompleteMultipartUpload MUST complete the multipart upload. +# - AbortMultipartUpload MAY be implemented by the S3EC. +# - AbortMultipartUpload MUST abort the multipart upload. +# +# The S3EC may provide implementations for the following S3EC-specific operation(s): +# +# - ReEncryptInstructionFile MAY be implemented by the S3EC. +# - ReEncryptInstructionFile MUST decrypt the instruction file's encrypted data key for the given object using the client's CMM. +# - ReEncryptInstructionFile MUST re-encrypt the plaintext data key with a provided keyring. + +[[spec]] +level = "MAY" +quote = ''' +- CreateMultipartUpload MAY be implemented by the S3EC. +''' + +[[spec]] +level = "MUST" +quote = ''' +- If implemented, CreateMultipartUpload MUST initiate a multipart upload. +''' + +[[spec]] +level = "MAY" +quote = ''' +- UploadPart MAY be implemented by the S3EC. +''' + +[[spec]] +level = "MUST" +quote = ''' +- UploadPart MUST encrypt each part. +''' + +[[spec]] +level = "MUST" +quote = ''' +- Each part MUST be encrypted in sequence. +''' + +[[spec]] +level = "MUST" +quote = ''' +- Each part MUST be encrypted using the same cipher instance for each part. +''' + +[[spec]] +level = "MAY" +quote = ''' +- CompleteMultipartUpload MAY be implemented by the S3EC. +''' + +[[spec]] +level = "MUST" +quote = ''' +- CompleteMultipartUpload MUST complete the multipart upload. +''' + +[[spec]] +level = "MAY" +quote = ''' +- AbortMultipartUpload MAY be implemented by the S3EC. +''' + +[[spec]] +level = "MUST" +quote = ''' +- AbortMultipartUpload MUST abort the multipart upload. +''' + +[[spec]] +level = "MAY" +quote = ''' +- ReEncryptInstructionFile MAY be implemented by the S3EC. +''' + +[[spec]] +level = "MUST" +quote = ''' +- ReEncryptInstructionFile MUST decrypt the instruction file's encrypted data key for the given object using the client's CMM. +''' + +[[spec]] +level = "MUST" +quote = ''' +- ReEncryptInstructionFile MUST re-encrypt the plaintext data key with a provided keyring. +''' + diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/randomness.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/randomness.toml new file mode 100644 index 00000000..22f93991 --- /dev/null +++ b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/randomness.toml @@ -0,0 +1,13 @@ +target = "../specification/s3-encryption/client.md#randomness" + +# Randomness +# +# The S3EC MAY accept a source of randomness during client initialization. +# The inclusion of a source of randomness is subject to language availability. + +[[spec]] +level = "MAY" +quote = ''' +The S3EC MAY accept a source of randomness during client initialization. +''' + diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/required-api-operations.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/required-api-operations.toml new file mode 100644 index 00000000..36500f6e --- /dev/null +++ b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/required-api-operations.toml @@ -0,0 +1,77 @@ +target = "../specification/s3-encryption/client.md#required-api-operations" + +# Required API Operations +# +# The S3EC must provide implementations for the following S3 operations: +# +# - GetObject MUST be implemented by the S3EC. +# - GetObject MUST decrypt data received from the S3 server and return it as plaintext. +# - PutObject MUST be implemented by the S3EC. +# - PutObject MUST encrypt its input data before it is uploaded to S3. +# - DeleteObject MUST be implemented by the S3EC. +# - DeleteObject MUST delete the given object key. +# - DeleteObject MUST delete the associated instruction file using the default instruction file suffix. +# - DeleteObjects MUST be implemented by the S3EC. +# - DeleteObjects MUST delete each of the given objects. +# - DeleteObjects MUST delete each of the corresponding instruction files using the default instruction file suffix. + +[[spec]] +level = "MUST" +quote = ''' +- GetObject MUST be implemented by the S3EC. +''' + +[[spec]] +level = "MUST" +quote = ''' +- GetObject MUST decrypt data received from the S3 server and return it as plaintext. +''' + +[[spec]] +level = "MUST" +quote = ''' +- PutObject MUST be implemented by the S3EC. +''' + +[[spec]] +level = "MUST" +quote = ''' +- PutObject MUST encrypt its input data before it is uploaded to S3. +''' + +[[spec]] +level = "MUST" +quote = ''' +- DeleteObject MUST be implemented by the S3EC. +''' + +[[spec]] +level = "MUST" +quote = ''' +- DeleteObject MUST delete the given object key. +''' + +[[spec]] +level = "MUST" +quote = ''' +- DeleteObject MUST delete the associated instruction file using the default instruction file suffix. +''' + +[[spec]] +level = "MUST" +quote = ''' +- DeleteObjects MUST be implemented by the S3EC. +''' + +[[spec]] +level = "MUST" +quote = ''' +- DeleteObjects MUST delete each of the given objects. +''' + +[[spec]] +level = "MUST" +quote = ''' +- DeleteObjects MUST delete each of the corresponding instruction files using the default instruction file suffix. +''' + diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/set-buffer-size.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/set-buffer-size.toml new file mode 100644 index 00000000..0701cfe3 --- /dev/null +++ b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/set-buffer-size.toml @@ -0,0 +1,26 @@ +target = "../specification/s3-encryption/client.md#set-buffer-size" + +# Set Buffer Size +# +# The S3EC SHOULD accept a configurable buffer size which refers to the maximum ciphertext length in bytes to store in memory when Delayed Authentication mode is disabled. +# If Delayed Authentication mode is enabled, and the buffer size has been set to a value other than its default, the S3EC MUST throw an exception. +# If Delayed Authentication mode is disabled, and no buffer size is provided, the S3EC MUST set the buffer size to a reasonable default. + +[[spec]] +level = "SHOULD" +quote = ''' +The S3EC SHOULD accept a configurable buffer size which refers to the maximum ciphertext length in bytes to store in memory when Delayed Authentication mode is disabled. +''' + +[[spec]] +level = "MUST" +quote = ''' +If Delayed Authentication mode is enabled, and the buffer size has been set to a value other than its default, the S3EC MUST throw an exception. +''' + +[[spec]] +level = "MUST" +quote = ''' +If Delayed Authentication mode is disabled, and no buffer size is provided, the S3EC MUST set the buffer size to a reasonable default. +''' + diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/wrapped-s3-client-s.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/wrapped-s3-client-s.toml new file mode 100644 index 00000000..427764b5 --- /dev/null +++ b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/wrapped-s3-client-s.toml @@ -0,0 +1,19 @@ +target = "../specification/s3-encryption/client.md#wrapped-s3-client-s" + +# Wrapped S3 Client(s) +# +# The S3EC MUST support the option to provide an SDK S3 client instance during its initialization. +# The S3EC MUST NOT support use of S3EC as the provided S3 client during its initialization; it MUST throw an exception in this case. + +[[spec]] +level = "MUST" +quote = ''' +The S3EC MUST support the option to provide an SDK S3 client instance during its initialization. +''' + +[[spec]] +level = "MUST" +quote = ''' +The S3EC MUST NOT support use of S3EC as the provided S3 client during its initialization; it MUST throw an exception in this case. +''' + diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/algorithm-suite-and-message-format-version-compatibility.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/algorithm-suite-and-message-format-version-compatibility.toml new file mode 100644 index 00000000..1e382ff0 --- /dev/null +++ b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/algorithm-suite-and-message-format-version-compatibility.toml @@ -0,0 +1,34 @@ +target = "../specification/s3-encryption/data-format/content-metadata.md#algorithm-suite-and-message-format-version-compatibility" + +# Algorithm Suite and Message Format Version Compatibility +# +# The S3EC supports encryption with various content encryption Algorithm Suites: +# +# - ALG_AES_256_CBC_IV16_NO_KDF +# - ALG_AES_256_GCM_IV12_TAG16_NO_KDF +# - ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY +# +# The mapping of Algorithm Suite to Message Format Versions follows: +# +# Objects encrypted with ALG_AES_256_CBC_IV16_NO_KDF MAY use either the V1 or V2 message format version. +# Objects encrypted with ALG_AES_256_GCM_IV12_TAG16_NO_KDF MUST use the V2 message format version only. +# Objects encrypted with ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY MUST use the V3 message format version only. + +[[spec]] +level = "MAY" +quote = ''' +Objects encrypted with ALG_AES_256_CBC_IV16_NO_KDF MAY use either the V1 or V2 message format version. +''' + +[[spec]] +level = "MUST" +quote = ''' +Objects encrypted with ALG_AES_256_GCM_IV12_TAG16_NO_KDF MUST use the V2 message format version only. +''' + +[[spec]] +level = "MUST" +quote = ''' +Objects encrypted with ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY MUST use the V3 message format version only. +''' + diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/content-metadata-mapkeys.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/content-metadata-mapkeys.toml new file mode 100644 index 00000000..c8d14030 --- /dev/null +++ b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/content-metadata-mapkeys.toml @@ -0,0 +1,217 @@ +target = "../specification/s3-encryption/data-format/content-metadata.md#content-metadata-mapkeys" + +# Content Metadata MapKeys +# +# Metadata is stored as a string -> string map (see TODO for further specification of "string"). +# Metadata is responsible for storing data which is critical for decryption of the object. +# The mapkeys contained in the metadata depends on the format version used. +# The "x-amz-meta-" prefix is automatically added by the S3 server and MUST NOT be included in implementation code. +# The "x-amz-" prefix denotes that the metadata is owned by an Amazon product and MUST be prepended to all S3EC metadata mapkeys. +# +# When the object is encrypted using the V1 format: +# +# - The mapkey "x-amz-unencrypted-content-length" SHOULD be present for V1 format objects. +# - The mapkey "x-amz-key" MUST be present for V1 format objects. +# - The mapkey "x-amz-matdesc" MUST be present for V1 format objects. +# - The mapkey "x-amz-iv" MUST be present for V1 format objects. +# +# When the object is encrypted using the V2 format: +# +# - The mapkey "x-amz-key-v2" MUST be present for V2 format objects. +# - The mapkey "x-amz-matdesc" MUST be present for V2 format objects. +# - The mapkey "x-amz-iv" MUST be present for V2 format objects. +# - The mapkey "x-amz-wrap-alg" MUST be present for V2 format objects. +# - The mapkey "x-amz-cek-alg" MUST be present for V2 format objects. +# - The mapkey "x-amz-tag-len" MUST be present for V2 format objects. +# +# The V3 format introduces the use of compression to reduce the size of S3EC-specific metadata. +# The V3 format uses the following mapkeys: +# +# - The mapkey "x-amz-c" MUST be present for V3 format objects. +# - This mapkey ("x-amz-c") SHOULD be represented by a constant named "CONTENT_CIPHER_V3" or similar in the implementation code. +# - This mapkey is the V3 version of the "x-amz-cek-alg" mapkey. +# - The mapkey "x-amz-3" MUST be present for V3 format objects. +# - This mapkey ("x-amz-3") SHOULD be represented by a constant named "ENCRYPTED_DATA_KEY_V3" or similar in the implementation code. +# - This mapkey is the V3 version of the "x-amz-key" and "x-amz-key-v2" mapkeys. +# - The mapkey "x-amz-m" SHOULD be present for V3 format objects that use Raw Keyring Material Description. +# - This mapkey ("x-amz-m") SHOULD be represented by a constant named "MAT_DESC_V3" or similar in the implementation code. +# - This mapkey is the V3 version of the "x-amz-matdesc" mapkey. +# - The mapkey "x-amz-t" SHOULD be present for V3 format objects that use KMS Encryption Context. +# - This mapkey ("x-amz-t") SHOULD be represented by a constant named "ENCRYPTION_CONTEXT_V3" or similar in the implementation code. +# - This mapkey is new for V3 and serves to distinguish KMS Encryption Context from Raw Keyring Material Description. +# - The mapkey "x-amz-w" MUST be present for V3 format objects. +# - This mapkey ("x-amz-w") SHOULD be represented by a constant named "ENCRYPTED_DATA_KEY_ALGORITHM_V3" or similar in the implementation code. +# - This mapkey is the V3 version of "x-amz-wrap-alg" mapkey. +# - The mapkey "x-amz-d" MUST be present for V3 format objects. +# - This mapkey ("x-amz-d") SHOULD be represented by a constant named "KEY_COMMITMENT_V3" or similar in the implementation code. +# - This mapkey is new for V3 and refers to the Key Commitment value used by committing algorithm suites. +# - The mapkey "x-amz-i" MUST be present for V3 format objects. +# - This mapkey ("x-amz-i") SHOULD be represented by a constant named "MESSAGE_ID_V3" or similar in the implementation code. +# - This mapkey is new for V3 and refers to the Message ID value used by committing algorithm suites. +# +# In general, the storage medium is independent from the format, with the exception of the V3 format. +# In the V3 format, the mapkeys "x-amz-c", "x-amz-d", and "x-amz-i" MUST be stored exclusively in the Object Metadata. +# See [metadata-strategy](./metadata-strategy.md) for more details. + +[[spec]] +level = "MUST" +quote = ''' +The "x-amz-meta-" prefix is automatically added by the S3 server and MUST NOT be included in implementation code. +''' + +[[spec]] +level = "MUST" +quote = ''' +The "x-amz-" prefix denotes that the metadata is owned by an Amazon product and MUST be prepended to all S3EC metadata mapkeys. +''' + +[[spec]] +level = "SHOULD" +quote = ''' +- The mapkey "x-amz-unencrypted-content-length" SHOULD be present for V1 format objects. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The mapkey "x-amz-key" MUST be present for V1 format objects. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The mapkey "x-amz-matdesc" MUST be present for V1 format objects. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The mapkey "x-amz-iv" MUST be present for V1 format objects. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The mapkey "x-amz-key-v2" MUST be present for V2 format objects. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The mapkey "x-amz-matdesc" MUST be present for V2 format objects. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The mapkey "x-amz-iv" MUST be present for V2 format objects. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The mapkey "x-amz-wrap-alg" MUST be present for V2 format objects. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The mapkey "x-amz-cek-alg" MUST be present for V2 format objects. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The mapkey "x-amz-tag-len" MUST be present for V2 format objects. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The mapkey "x-amz-c" MUST be present for V3 format objects. +''' + +[[spec]] +level = "SHOULD" +quote = ''' +- This mapkey ("x-amz-c") SHOULD be represented by a constant named "CONTENT_CIPHER_V3" or similar in the implementation code. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The mapkey "x-amz-3" MUST be present for V3 format objects. +''' + +[[spec]] +level = "SHOULD" +quote = ''' +- This mapkey ("x-amz-3") SHOULD be represented by a constant named "ENCRYPTED_DATA_KEY_V3" or similar in the implementation code. +''' + +[[spec]] +level = "SHOULD" +quote = ''' +- The mapkey "x-amz-m" SHOULD be present for V3 format objects that use Raw Keyring Material Description. +''' + +[[spec]] +level = "SHOULD" +quote = ''' +- This mapkey ("x-amz-m") SHOULD be represented by a constant named "MAT_DESC_V3" or similar in the implementation code. +''' + +[[spec]] +level = "SHOULD" +quote = ''' +- The mapkey "x-amz-t" SHOULD be present for V3 format objects that use KMS Encryption Context. +''' + +[[spec]] +level = "SHOULD" +quote = ''' +- This mapkey ("x-amz-t") SHOULD be represented by a constant named "ENCRYPTION_CONTEXT_V3" or similar in the implementation code. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The mapkey "x-amz-w" MUST be present for V3 format objects. +''' + +[[spec]] +level = "SHOULD" +quote = ''' +- This mapkey ("x-amz-w") SHOULD be represented by a constant named "ENCRYPTED_DATA_KEY_ALGORITHM_V3" or similar in the implementation code. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The mapkey "x-amz-d" MUST be present for V3 format objects. +''' + +[[spec]] +level = "SHOULD" +quote = ''' +- This mapkey ("x-amz-d") SHOULD be represented by a constant named "KEY_COMMITMENT_V3" or similar in the implementation code. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The mapkey "x-amz-i" MUST be present for V3 format objects. +''' + +[[spec]] +level = "SHOULD" +quote = ''' +- This mapkey ("x-amz-i") SHOULD be represented by a constant named "MESSAGE_ID_V3" or similar in the implementation code. +''' + +[[spec]] +level = "MUST" +quote = ''' +In the V3 format, the mapkeys "x-amz-c", "x-amz-d", and "x-amz-i" MUST be stored exclusively in the Object Metadata. +''' + diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/determining-s3ec-object-status.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/determining-s3ec-object-status.toml new file mode 100644 index 00000000..9a06cf0e --- /dev/null +++ b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/determining-s3ec-object-status.toml @@ -0,0 +1,60 @@ +target = "../specification/s3-encryption/data-format/content-metadata.md#determining-s3ec-object-status" + +# Determining S3EC Object Status +# +# Whether or not an object is determined to be a valid object encrypted by S3EC is done via the following logic: +# +# V1: +# +# - If the metadata contains "x-amz-iv" and "x-amz-key" then the object MUST be considered as an S3EC-encrypted object using the V1 format. +# +# V2: +# +# - If the metadata contains "x-amz-iv" and "x-amz-metadata-x-amz-key-v2" then the object MUST be considered as an S3EC-encrypted object using the V2 format. +# +# V3: +# +# - If the metadata contains "x-amz-3" and "x-amz-d" and "x-amz-i" then the object MUST be considered an S3EC-encrypted object using the V3 format. +# +# This logic applies only to objects using ObjectMetadata to store cryptographic metadata. +# If the object matches none of the V1/V2/V3 formats, the S3EC MUST attempt to get the instruction file. +# +# If there are multiple mapkeys which are meant to be exclusive, such as "x-amz-key", "x-amz-key-v2", and "x-amz-3" then the S3EC SHOULD throw an exception. +# In general, if there is any deviation from the above format, with the exception of additional unrelated mapkeys, then the S3EC SHOULD throw an exception. + +[[spec]] +level = "MUST" +quote = ''' +- If the metadata contains "x-amz-iv" and "x-amz-key" then the object MUST be considered as an S3EC-encrypted object using the V1 format. +''' + +[[spec]] +level = "MUST" +quote = ''' +- If the metadata contains "x-amz-iv" and "x-amz-metadata-x-amz-key-v2" then the object MUST be considered as an S3EC-encrypted object using the V2 format. +''' + +[[spec]] +level = "MUST" +quote = ''' +- If the metadata contains "x-amz-3" and "x-amz-d" and "x-amz-i" then the object MUST be considered an S3EC-encrypted object using the V3 format. +''' + +[[spec]] +level = "MUST" +quote = ''' +If the object matches none of the V1/V2/V3 formats, the S3EC MUST attempt to get the instruction file. +''' + +[[spec]] +level = "SHOULD" +quote = ''' +If there are multiple mapkeys which are meant to be exclusive, such as "x-amz-key", "x-amz-key-v2", and "x-amz-3" then the S3EC SHOULD throw an exception. +''' + +[[spec]] +level = "SHOULD" +quote = ''' +In general, if there is any deviation from the above format, with the exception of additional unrelated mapkeys, then the S3EC SHOULD throw an exception. +''' + diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/v1-v2-shared.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/v1-v2-shared.toml new file mode 100644 index 00000000..d45b598b --- /dev/null +++ b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/v1-v2-shared.toml @@ -0,0 +1,24 @@ +target = "../specification/s3-encryption/data-format/content-metadata.md#v1-v2-shared" + +# V1/V2 Shared +# +# The following mapkeys are used in both the V1 and V2 format. +# +# _x-amz-matdesc_ +# +# A JSON string containing the Material Description OR Encryption Context used when encrypting the data key. +# See TODO-link for more details on Material Description and Encryption Context. +# This string MAY be encoded by the esoteric double-encoding scheme used by the S3 web server. +# See TODO-link for more details on the S3 double-encoding scheme. +# The default value is the an empty JSON map (`{}`). +# +# _x-amz-iv_ +# +# The base64-encoded bytes used as the IV when encrypting the content. + +[[spec]] +level = "MAY" +quote = ''' +This string MAY be encoded by the esoteric double-encoding scheme used by the S3 web server. +''' + diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/v3-only.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/v3-only.toml new file mode 100644 index 00000000..075455fd --- /dev/null +++ b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/v3-only.toml @@ -0,0 +1,91 @@ +target = "../specification/s3-encryption/data-format/content-metadata.md#v3-only" + +# V3 Only +# +# _x-amz-m_ +# +# A JSON string representing the Material Description of the key material used to encrypt the data key. +# This material description string MAY be encoded by the esoteric double-encoding scheme used by the S3 web server. +# The Material Description MUST be used for wrapping algorithms `AES/GCM` (`02`) and `RSA-OAEP-SHA1` (`22`). +# If the mapkey is not present, the default Material Description value MUST be set to an empty map (`{}`). +# See TODO-link for more details on the S3 double-encoding scheme. +# +# _x-amz-t_ +# +# A JSON string representing the AWS KMS Encryption Context associated with the encrypted object. +# This encryption context string MAY be encoded by the esoteric double-encoding scheme used by the S3 web server. +# The Encryption Context value MUST be used for wrapping algorithm `kms+context` or `12`. +# See TODO-link for more details on the S3 double-encoding scheme. +# +# _x-amz-w_ +# +# The wrapping algorithm used to encrypt the data key. +# The V3 format uses compression here such that each wrapping algorithm is represented by a two digit string. +# The valid values and their mapping to pre-existing values are: +# +# - 02 +# - AES/GCM +# - The wrapping algorithm value "02" MUST be translated to AES/GCM upon retrieval, and vice versa on write. +# - 12 +# - kms+context +# - The wrapping algorithm value "12" MUST be translated to kms+context upon retrieval, and vice versa on write. +# - 22 +# - RSA-OAEP-SHA1 +# - The wrapping algorithm value "22" MUST be translated to RSA-OAEP-SHA1 upon retrieval, and vice versa on write. +# +# _x-amz-d_ +# +# The base64-encoded bytes representing the Key Commitment associated with the encrypted object. +# +# _x-amz-i_ +# +# The base64-encoded bytes representing the Message ID associated with the encrypted object. + +[[spec]] +level = "MAY" +quote = ''' +This material description string MAY be encoded by the esoteric double-encoding scheme used by the S3 web server. +''' + +[[spec]] +level = "MUST" +quote = ''' +The Material Description MUST be used for wrapping algorithms `AES/GCM` (`02`) and `RSA-OAEP-SHA1` (`22`). +''' + +[[spec]] +level = "MUST" +quote = ''' +If the mapkey is not present, the default Material Description value MUST be set to an empty map (`{}`). +''' + +[[spec]] +level = "MAY" +quote = ''' +This encryption context string MAY be encoded by the esoteric double-encoding scheme used by the S3 web server. +''' + +[[spec]] +level = "MUST" +quote = ''' +The Encryption Context value MUST be used for wrapping algorithm `kms+context` or `12`. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The wrapping algorithm value "02" MUST be translated to AES/GCM upon retrieval, and vice versa on write. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The wrapping algorithm value "12" MUST be translated to kms+context upon retrieval, and vice versa on write. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The wrapping algorithm value "22" MUST be translated to RSA-OAEP-SHA1 upon retrieval, and vice versa on write. +''' + diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/metadata-strategy/instruction-file.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/metadata-strategy/instruction-file.toml new file mode 100644 index 00000000..1717e630 --- /dev/null +++ b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/metadata-strategy/instruction-file.toml @@ -0,0 +1,66 @@ +target = "../specification/s3-encryption/data-format/metadata-strategy.md#instruction-file" + +# Instruction File +# +# Instruction Files are a separate S3 object which contain content metadata. +# The S3EC MUST support writing some or all (depending on format) content metadata to an Instruction File. +# The content metadata stored in the Instruction File MUST be serialized to a JSON string. +# The serialized JSON string MUST be the only contents of the Instruction File. +# +# Instruction File writes MUST NOT be enabled by default. +# Instruction File writes MUST be optionally configured during client creation or on each PutObject request. +# The default Instruction File behavior uses the same S3 object key as its associated object suffixed with ".instruction". +# +# The S3EC MAY support re-encryption/key rotation via Instruction Files. +# Further details on Instruction File re-encryption can be found in (TODO). +# The S3EC MUST NOT support providing a custom Instruction File suffix on ordinary writes; custom suffixes MUST only be used during re-encryption. +# The S3EC SHOULD support providing a custom Instruction File suffix on GetObject requests, regardless of whether or not re-encryption is supported. + +[[spec]] +level = "MUST" +quote = ''' +The S3EC MUST support writing some or all (depending on format) content metadata to an Instruction File. +''' + +[[spec]] +level = "MUST" +quote = ''' +The content metadata stored in the Instruction File MUST be serialized to a JSON string. +''' + +[[spec]] +level = "MUST" +quote = ''' +The serialized JSON string MUST be the only contents of the Instruction File. +''' + +[[spec]] +level = "MUST" +quote = ''' +Instruction File writes MUST NOT be enabled by default. +''' + +[[spec]] +level = "MUST" +quote = ''' +Instruction File writes MUST be optionally configured during client creation or on each PutObject request. +''' + +[[spec]] +level = "MAY" +quote = ''' +The S3EC MAY support re-encryption/key rotation via Instruction Files. +''' + +[[spec]] +level = "MUST" +quote = ''' +The S3EC MUST NOT support providing a custom Instruction File suffix on ordinary writes; custom suffixes MUST only be used during re-encryption. +''' + +[[spec]] +level = "SHOULD" +quote = ''' +The S3EC SHOULD support providing a custom Instruction File suffix on GetObject requests, regardless of whether or not re-encryption is supported. +''' + diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/metadata-strategy/object-metadata.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/metadata-strategy/object-metadata.toml new file mode 100644 index 00000000..5a80b66e --- /dev/null +++ b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/metadata-strategy/object-metadata.toml @@ -0,0 +1,28 @@ +target = "../specification/s3-encryption/data-format/metadata-strategy.md#object-metadata" + +# Object Metadata +# +# Object Metadata refers to the set of mapkey-value pairs stored alongside an object in S3. +# By default, the S3EC MUST store content metadata in the S3 Object Metadata. +# When an encrypted object is stored in S3 with non-US-ASCII Materials Description or Encryption Context, the S3 Server will apply an esoteric "double encoding" to the metadata. +# The S3EC SHOULD support decoding the S3 Server's "double encoding". +# If the S3EC does not support decoding the S3 Server's "double encoding" then it MUST return the content metadata untouched. + +[[spec]] +level = "MUST" +quote = ''' +By default, the S3EC MUST store content metadata in the S3 Object Metadata. +''' + +[[spec]] +level = "SHOULD" +quote = ''' +The S3EC SHOULD support decoding the S3 Server's "double encoding". +''' + +[[spec]] +level = "MUST" +quote = ''' +If the S3EC does not support decoding the S3 Server's "double encoding" then it MUST return the content metadata untouched. +''' + diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/metadata-strategy/v1-v2-instruction-files.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/metadata-strategy/v1-v2-instruction-files.toml new file mode 100644 index 00000000..e34118ea --- /dev/null +++ b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/metadata-strategy/v1-v2-instruction-files.toml @@ -0,0 +1,12 @@ +target = "../specification/s3-encryption/data-format/metadata-strategy.md#v1-v2-instruction-files" + +# V1/V2 Instruction Files +# +# In the V1/V2 message format, all of the content metadata MUST be stored in the Instruction File. + +[[spec]] +level = "MUST" +quote = ''' +In the V1/V2 message format, all of the content metadata MUST be stored in the Instruction File. +''' + diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/metadata-strategy/v3-instruction-files.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/metadata-strategy/v3-instruction-files.toml new file mode 100644 index 00000000..47ec29a9 --- /dev/null +++ b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/metadata-strategy/v3-instruction-files.toml @@ -0,0 +1,81 @@ +target = "../specification/s3-encryption/data-format/metadata-strategy.md#v3-instruction-files" + +# V3 Instruction Files +# +# In the V3 message format, only the content metadata related to the encrypted data is stored in the Instruction File. +# In the V3 message format, the content metadata related to the encrypted content is stored in the Object Metadata. +# +# - The V3 message format MUST store the mapkey "x-amz-c" and its value in the Object Metadata when writing with an Instruction File. +# - The V3 message format MUST NOT store the mapkey "x-amz-c" and its value in the Instruction File. +# - The V3 message format MUST store the mapkey "x-amz-d" and its value in the Object Metadata when writing with an Instruction File. +# - The V3 message format MUST NOT store the mapkey "x-amz-d" and its value in the Instruction File. +# - The V3 message format MUST store the mapkey "x-amz-i" and its value in the Object Metadata when writing with an Instruction File. +# - The V3 message format MUST NOT store the mapkey "x-amz-i" and its value in the Instruction File. +# +# - The V3 message format MUST store the mapkey "x-amz-3" and its value in the Instruction File. +# - The V3 message format MUST store the mapkey "x-amz-w" and its value in the Instruction File. +# - The V3 message format MUST store the mapkey "x-amz-m" and its value (when present in the content metadata) in the Instruction File. +# - The V3 message format MUST store the mapkey "x-amz-t" and its value (when present in the content metadata) in the Instruction File. +# +# This is done to facilitate data key re-encryption via Instruction File. + +[[spec]] +level = "MUST" +quote = ''' +- The V3 message format MUST store the mapkey "x-amz-c" and its value in the Object Metadata when writing with an Instruction File. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The V3 message format MUST NOT store the mapkey "x-amz-c" and its value in the Instruction File. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The V3 message format MUST store the mapkey "x-amz-d" and its value in the Object Metadata when writing with an Instruction File. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The V3 message format MUST NOT store the mapkey "x-amz-d" and its value in the Instruction File. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The V3 message format MUST store the mapkey "x-amz-i" and its value in the Object Metadata when writing with an Instruction File. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The V3 message format MUST NOT store the mapkey "x-amz-i" and its value in the Instruction File. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The V3 message format MUST store the mapkey "x-amz-3" and its value in the Instruction File. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The V3 message format MUST store the mapkey "x-amz-w" and its value in the Instruction File. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The V3 message format MUST store the mapkey "x-amz-m" and its value (when present in the content metadata) in the Instruction File. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The V3 message format MUST store the mapkey "x-amz-t" and its value (when present in the content metadata) in the Instruction File. +''' + diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/decryption/decrypting-with-commitment.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/decryption/decrypting-with-commitment.toml new file mode 100644 index 00000000..630c2aa3 --- /dev/null +++ b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/decryption/decrypting-with-commitment.toml @@ -0,0 +1,33 @@ +target = "../specification/s3-encryption/decryption.md#decrypting-with-commitment" + +# Decrypting With Commitment +# +# When using an algorithm suite which supports key commitment, the client MUST verify that the [derived key commitment](./key-derivation.md#hkdf-operation) contains the same bytes as the stored key commitment retrieved from the stored object's metadata. +# When using an algorithm suite which supports key commitment, the verification of the derived key commitment value MUST be done in constant time. +# When using an algorithm suite which supports key commitment, the client MUST throw an exception when the derived key commitment value and stored key commitment value do not match. +# When using an algorithm suite which supports key commitment, the client MUST verify the key commitment values match before deriving the [derived encryption key](./key-derivation.md#hkdf-operation). + +[[spec]] +level = "MUST" +quote = ''' +When using an algorithm suite which supports key commitment, the client MUST verify that the [derived key commitment](./key-derivation.md#hkdf-operation) contains the same bytes as the stored key commitment retrieved from the stored object's metadata. +''' + +[[spec]] +level = "MUST" +quote = ''' +When using an algorithm suite which supports key commitment, the verification of the derived key commitment value MUST be done in constant time. +''' + +[[spec]] +level = "MUST" +quote = ''' +When using an algorithm suite which supports key commitment, the client MUST throw an exception when the derived key commitment value and stored key commitment value do not match. +''' + +[[spec]] +level = "MUST" +quote = ''' +When using an algorithm suite which supports key commitment, the client MUST verify the key commitment values match before deriving the [derived encryption key](./key-derivation.md#hkdf-operation). +''' + diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/decryption/key-commitment.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/decryption/key-commitment.toml new file mode 100644 index 00000000..db5e960f --- /dev/null +++ b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/decryption/key-commitment.toml @@ -0,0 +1,20 @@ +target = "../specification/s3-encryption/decryption.md#key-commitment" + +# Key Commitment +# +# The S3EC supports algorithm suite(s) which provide [key commitment](./key-commitment.md). +# The S3EC MUST validate the algorithm suite used for decryption against the key commitment policy before attempting to decrypt the content ciphertext. +# If the commitment policy requires decryption using a committing algorithm suite, and the algorithm suite associated with the object does not support key commitment, then the S3EC MUST throw an exception. + +[[spec]] +level = "MUST" +quote = ''' +The S3EC MUST validate the algorithm suite used for decryption against the key commitment policy before attempting to decrypt the content ciphertext. +''' + +[[spec]] +level = "MUST" +quote = ''' +If the commitment policy requires decryption using a committing algorithm suite, and the algorithm suite associated with the object does not support key commitment, then the S3EC MUST throw an exception. +''' + diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/decryption/legacy-decryption.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/decryption/legacy-decryption.toml new file mode 100644 index 00000000..1db5b14d --- /dev/null +++ b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/decryption/legacy-decryption.toml @@ -0,0 +1,19 @@ +target = "../specification/s3-encryption/decryption.md#legacy-decryption" + +# Legacy Decryption +# +# The S3EC MUST NOT decrypt objects encrypted using legacy unauthenticated algorithm suites unless specifically configured to do so. +# If the S3EC is not configured to enable legacy unauthenticated content decryption, the client MUST throw an exception when attempting to decrypt an object encrypted with a legacy unauthenticated algorithm suite. + +[[spec]] +level = "MUST" +quote = ''' +The S3EC MUST NOT decrypt objects encrypted using legacy unauthenticated algorithm suites unless specifically configured to do so. +''' + +[[spec]] +level = "MUST" +quote = ''' +If the S3EC is not configured to enable legacy unauthenticated content decryption, the client MUST throw an exception when attempting to decrypt an object encrypted with a legacy unauthenticated algorithm suite. +''' + diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/decryption/ranged-gets.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/decryption/ranged-gets.toml new file mode 100644 index 00000000..d958e2ce --- /dev/null +++ b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/decryption/ranged-gets.toml @@ -0,0 +1,44 @@ +target = "../specification/s3-encryption/decryption.md#ranged-gets" + +# Ranged Gets +# +# The S3EC MAY support the "range" parameter on GetObject which specifies a subset of bytes to download and decrypt. +# If the S3EC supports Ranged Gets, the S3EC MUST adjust the customer-provided range to include the beginning and end of the cipher blocks for the given range. +# TODO: Fully spec out all edge cases for Ranged Gets. +# For requests which provide a range to decrypt an object encrypted with an authenticated algorithm suite, the corresponding CTR-based algorithm suite is used. +# If the object was encrypted with ALG_AES_256_GCM_IV12_TAG16_NO_KDF, then ALG_AES_256_CTR_IV16_TAG16_NO_KDF MUST be used to decrypt the range of the object. +# If the object was encrypted with ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY, then ALG_AES_256_CTR_HKDF_SHA512_COMMIT_KEY MUST be used to decrypt the range of the object. +# +# If the GetObject response contains a range, but the GetObject request does not contain a range, the S3EC MUST throw an exception. +# This behavior indicates that this is a "multipart download" which is currently not supported. + +[[spec]] +level = "MAY" +quote = ''' +The S3EC MAY support the "range" parameter on GetObject which specifies a subset of bytes to download and decrypt. +''' + +[[spec]] +level = "MUST" +quote = ''' +If the S3EC supports Ranged Gets, the S3EC MUST adjust the customer-provided range to include the beginning and end of the cipher blocks for the given range. +''' + +[[spec]] +level = "MUST" +quote = ''' +If the object was encrypted with ALG_AES_256_GCM_IV12_TAG16_NO_KDF, then ALG_AES_256_CTR_IV16_TAG16_NO_KDF MUST be used to decrypt the range of the object. +''' + +[[spec]] +level = "MUST" +quote = ''' +If the object was encrypted with ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY, then ALG_AES_256_CTR_HKDF_SHA512_COMMIT_KEY MUST be used to decrypt the range of the object. +''' + +[[spec]] +level = "MUST" +quote = ''' +If the GetObject response contains a range, but the GetObject request does not contain a range, the S3EC MUST throw an exception. +''' + diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/alg-aes-256-ctr-hkdf-sha512-commit-key.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/alg-aes-256-ctr-hkdf-sha512-commit-key.toml new file mode 100644 index 00000000..7aeb5501 --- /dev/null +++ b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/alg-aes-256-ctr-hkdf-sha512-commit-key.toml @@ -0,0 +1,14 @@ +target = "../specification/s3-encryption/encryption.md#alg-aes-256-ctr-hkdf-sha512-commit-key" + +# ALG_AES_256_CTR_HKDF_SHA512_COMMIT_KEY +# +# Encryption using AES-CTR is not supported. +# This algorithm suite is only used to decrypt ranges of a ciphertext encrypted using key committing AES-GCM. +# Attempts to encrypt using key committing AES-CTR MUST fail. + +[[spec]] +level = "MUST" +quote = ''' +Attempts to encrypt using key committing AES-CTR MUST fail. +''' + diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/alg-aes-256-ctr-iv16-tag16-no-kdf.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/alg-aes-256-ctr-iv16-tag16-no-kdf.toml new file mode 100644 index 00000000..7cfac97f --- /dev/null +++ b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/alg-aes-256-ctr-iv16-tag16-no-kdf.toml @@ -0,0 +1,14 @@ +target = "../specification/s3-encryption/encryption.md#alg-aes-256-ctr-iv16-tag16-no-kdf" + +# ALG_AES_256_CTR_IV16_TAG16_NO_KDF +# +# Encryption using AES-CTR is not supported. +# This algorithm suite is only used to decrypt ranges of a ciphertext encrypted using AES-GCM. +# Attempts to encrypt using AES-CTR MUST fail. + +[[spec]] +level = "MUST" +quote = ''' +Attempts to encrypt using AES-CTR MUST fail. +''' + diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/alg-aes-256-gcm-hkdf-sha512-commit-key.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/alg-aes-256-gcm-hkdf-sha512-commit-key.toml new file mode 100644 index 00000000..d4f6f1f1 --- /dev/null +++ b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/alg-aes-256-gcm-hkdf-sha512-commit-key.toml @@ -0,0 +1,27 @@ +target = "../specification/s3-encryption/encryption.md#alg-aes-256-gcm-hkdf-sha512-commit-key" + +# ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY +# +# This algorithm suite supports Key Commitment and therefore requires deriving a key commitment value and a derived encryption key. +# The client MUST use HKDF to derive the key commitment value and the derived encrypting key as described in [Key Derivation](key-derivation.md). +# The derived key commitment value MUST be set or returned from the encryption process such that it can be included in the content metadata. +# The client MUST append the GCM auth tag to the ciphertext if the underlying crypto provider does not do so automatically. + +[[spec]] +level = "MUST" +quote = ''' +The client MUST use HKDF to derive the key commitment value and the derived encrypting key as described in [Key Derivation](key-derivation.md). +''' + +[[spec]] +level = "MUST" +quote = ''' +The derived key commitment value MUST be set or returned from the encryption process such that it can be included in the content metadata. +''' + +[[spec]] +level = "MUST" +quote = ''' +The client MUST append the GCM auth tag to the ciphertext if the underlying crypto provider does not do so automatically. +''' + diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/alg-aes-256-gcm-iv12-tag16-no-kdf.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/alg-aes-256-gcm-iv12-tag16-no-kdf.toml new file mode 100644 index 00000000..033137de --- /dev/null +++ b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/alg-aes-256-gcm-iv12-tag16-no-kdf.toml @@ -0,0 +1,26 @@ +target = "../specification/s3-encryption/encryption.md#alg-aes-256-gcm-iv12-tag16-no-kdf" + +# ALG_AES_256_GCM_IV12_TAG16_NO_KDF +# +# The client MUST initialize the cipher, or call an AES-GCM encryption API, with the plaintext data key, the generated IV, and the tag length defined in the Algorithm Suite when encrypting with ALG_AES_256_GCM_IV12_TAG16_NO_KDF. +# The client MUST NOT provide any AAD when encrypting with ALG_AES_256_GCM_IV12_TAG16_NO_KDF. +# The client MUST append the GCM auth tag to the ciphertext if the underlying crypto provider does not do so automatically. + +[[spec]] +level = "MUST" +quote = ''' +The client MUST initialize the cipher, or call an AES-GCM encryption API, with the plaintext data key, the generated IV, and the tag length defined in the Algorithm Suite when encrypting with ALG_AES_256_GCM_IV12_TAG16_NO_KDF. +''' + +[[spec]] +level = "MUST" +quote = ''' +The client MUST NOT provide any AAD when encrypting with ALG_AES_256_GCM_IV12_TAG16_NO_KDF. +''' + +[[spec]] +level = "MUST" +quote = ''' +The client MUST append the GCM auth tag to the ciphertext if the underlying crypto provider does not do so automatically. +''' + diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/cipher-initialization.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/cipher-initialization.toml new file mode 100644 index 00000000..651b5e41 --- /dev/null +++ b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/cipher-initialization.toml @@ -0,0 +1,16 @@ +target = "../specification/s3-encryption/encryption.md#cipher-initialization" + +# Cipher Initialization +# +# The client SHOULD validate that the generated IV or Message ID is not zeros. +# There is an astoundingly small chance that an IV or Message ID is generated as all zeros. +# An IV or Message ID containing all zeros is valid, but it is more likely that the IV/Message ID was not initialized or generated correctly. +# +# The rest of the cipher initialization depends on the algorithm suite: + +[[spec]] +level = "SHOULD" +quote = ''' +The client SHOULD validate that the generated IV or Message ID is not zeros. +''' + diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/content-encryption.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/content-encryption.toml new file mode 100644 index 00000000..2eb6378c --- /dev/null +++ b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/content-encryption.toml @@ -0,0 +1,43 @@ +target = "../specification/s3-encryption/encryption.md#content-encryption" + +# Content Encryption +# +# The S3EC MUST use the encryption algorithm configured during [client](./client.md) initialization. +# +# Once the requisite encryption materials have been provided, the client proceeds to encrypting the plaintext object content. +# +# The client MUST validate that the length of the plaintext bytes does not exceed the algorithm suite's cipher's maximum content length in bytes. +# +# For algorithm suites which support Key Commitment, a fixed IV is used for GCM content encryption. +# Instead of generating an IV, committing algorithm suites use a Message ID which is used as input to the HKDF. +# Otherwise, the IV and the Message ID are similar in some ways. +# For example, the Message ID, like the IV, is stored in the persisted content metadata. +# When implementing the S3EC, it is useful to generate the Message ID by the same process that generates the IV in non-committing algorithm suites. +# The client MUST generate an IV or Message ID using the length of the IV or Message ID defined in the algorithm suite. +# +# The generated IV or Message ID MUST be set or returned from the encryption process such that it can be included in the content metadata. + +[[spec]] +level = "MUST" +quote = ''' +The S3EC MUST use the encryption algorithm configured during [client](./client.md) initialization. +''' + +[[spec]] +level = "MUST" +quote = ''' +The client MUST validate that the length of the plaintext bytes does not exceed the algorithm suite's cipher's maximum content length in bytes. +''' + +[[spec]] +level = "MUST" +quote = ''' +The client MUST generate an IV or Message ID using the length of the IV or Message ID defined in the algorithm suite. +''' + +[[spec]] +level = "MUST" +quote = ''' +The generated IV or Message ID MUST be set or returned from the encryption process such that it can be included in the content metadata. +''' + diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/key-commitment/commitment-policy.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/key-commitment/commitment-policy.toml new file mode 100644 index 00000000..1b58a9aa --- /dev/null +++ b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/key-commitment/commitment-policy.toml @@ -0,0 +1,58 @@ +target = "../specification/s3-encryption/key-commitment.md#commitment-policy" + +# Commitment Policy +# +# In order to provide a way to migrate from previous algorithm suites which do not support key commitment to algorithm suites which do support key commitment, the S3EC provides a configurable key commitment policy. +# The values of the policy are represented using an enum type: +# +# | S3EC Commitment Policy ENUM | +# | ------------------------------- | +# | FORBID_ENCRYPT_ALLOW_DECRYPT | +# | REQUIRE_ENCRYPT_ALLOW_DECRYPT | +# | REQUIRE_ENCRYPT_REQUIRE_DECRYPT | +# +# When the commitment policy is FORBID_ENCRYPT_ALLOW_DECRYPT, the S3EC MUST NOT encrypt using an algorithm suite which supports key commitment. +# When the commitment policy is FORBID_ENCRYPT_ALLOW_DECRYPT, the S3EC MUST allow decryption using algorithm suites which do not support key commitment. +# +# When the commitment policy is REQUIRE_ENCRYPT_ALLOW_DECRYPT, the S3EC MUST only encrypt using an algorithm suite which supports key commitment. +# When the commitment policy is REQUIRE_ENCRYPT_ALLOW_DECRYPT, the S3EC MUST allow decryption using algorithm suites which do not support key commitment. +# +# When the commitment policy is REQUIRE_ENCRYPT_REQUIRE_DECRYPT, the S3EC MUST only encrypt using an algorithm suite which supports key commitment. +# When the commitment policy is REQUIRE_ENCRYPT_REQUIRE_DECRYPT, the S3EC MUST NOT allow decryption using algorithm suites which do not support key commitment. + +[[spec]] +level = "MUST" +quote = ''' +When the commitment policy is FORBID_ENCRYPT_ALLOW_DECRYPT, the S3EC MUST NOT encrypt using an algorithm suite which supports key commitment. +''' + +[[spec]] +level = "MUST" +quote = ''' +When the commitment policy is FORBID_ENCRYPT_ALLOW_DECRYPT, the S3EC MUST allow decryption using algorithm suites which do not support key commitment. +''' + +[[spec]] +level = "MUST" +quote = ''' +When the commitment policy is REQUIRE_ENCRYPT_ALLOW_DECRYPT, the S3EC MUST only encrypt using an algorithm suite which supports key commitment. +''' + +[[spec]] +level = "MUST" +quote = ''' +When the commitment policy is REQUIRE_ENCRYPT_ALLOW_DECRYPT, the S3EC MUST allow decryption using algorithm suites which do not support key commitment. +''' + +[[spec]] +level = "MUST" +quote = ''' +When the commitment policy is REQUIRE_ENCRYPT_REQUIRE_DECRYPT, the S3EC MUST only encrypt using an algorithm suite which supports key commitment. +''' + +[[spec]] +level = "MUST" +quote = ''' +When the commitment policy is REQUIRE_ENCRYPT_REQUIRE_DECRYPT, the S3EC MUST NOT allow decryption using algorithm suites which do not support key commitment. +''' + diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/key-derivation/hkdf-operation.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/key-derivation/hkdf-operation.toml new file mode 100644 index 00000000..be23a6ce --- /dev/null +++ b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/key-derivation/hkdf-operation.toml @@ -0,0 +1,106 @@ +target = "../specification/s3-encryption/key-derivation.md#hkdf-operation" + +# HKDF Operation +# +# When the algorithm suite is key committing, the S3EC uses HKDF with the following specifics using the generated IV as the Message ID: +# +# For the extract step: +# +# - The hash function MUST be specified by the algorithm suite commitment settings. +# - The input keying material MUST be the plaintext data key (PDK) generated by the key provider. +# - The length of the input keying material MUST equal the key derivation input length specified by the algorithm suite commit key derivation setting. +# - The salt MUST be the Message ID with the length defined in the algorithm suite. +# +# For the expand step: +# +# - For the Derived Encryption Key: +# - The DEK input pseudorandom key MUST be the output from the extract step. +# - The length of the output keying material MUST equal the encryption key length specified by the algorithm suite encryption settings. +# - The input info MUST be a concatenation of the algorithm suite ID as bytes followed by the string DERIVEKEY as UTF8 encoded bytes. +# - For the Commit Key: +# - The CK input pseudorandom key MUST be the output from the extract step. +# - The length of the output keying material MUST equal the commit key length specified by the supported algorithm suites. +# - The input info MUST be a concatenation of the algorithm suite ID as bytes followed by the string COMMITKEY as UTF8 encoded bytes. +# +# When encrypting or decrypting with ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY, the IV used in the AES-GCM content encryption/decryption MUST contain only zeros of the length defined in the algorithm suite. +# The client MUST initialize the cipher, or call an AES-GCM encryption API, with the derived encryption key, an IV containing only zeros, and the tag length defined in the Algorithm Suite when encrypting or decrypting with ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY. +# The client MUST set the AAD to the Algorithm Suite ID represented as bytes. + +[[spec]] +level = "MUST" +quote = ''' +- The hash function MUST be specified by the algorithm suite commitment settings. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The input keying material MUST be the plaintext data key (PDK) generated by the key provider. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The length of the input keying material MUST equal the key derivation input length specified by the algorithm suite commit key derivation setting. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The salt MUST be the Message ID with the length defined in the algorithm suite. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The DEK input pseudorandom key MUST be the output from the extract step. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The length of the output keying material MUST equal the encryption key length specified by the algorithm suite encryption settings. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The input info MUST be a concatenation of the algorithm suite ID as bytes followed by the string DERIVEKEY as UTF8 encoded bytes. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The CK input pseudorandom key MUST be the output from the extract step. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The length of the output keying material MUST equal the commit key length specified by the supported algorithm suites. +''' + +[[spec]] +level = "MUST" +quote = ''' +- The input info MUST be a concatenation of the algorithm suite ID as bytes followed by the string COMMITKEY as UTF8 encoded bytes. +''' + +[[spec]] +level = "MUST" +quote = ''' +When encrypting or decrypting with ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY, the IV used in the AES-GCM content encryption/decryption MUST contain only zeros of the length defined in the algorithm suite. +''' + +[[spec]] +level = "MUST" +quote = ''' +The client MUST initialize the cipher, or call an AES-GCM encryption API, with the derived encryption key, an IV containing only zeros, and the tag length defined in the Algorithm Suite when encrypting or decrypting with ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY. +''' + +[[spec]] +level = "MUST" +quote = ''' +The client MUST set the AAD to the Algorithm Suite ID represented as bytes. +''' + From e7bb8d3e258d4ad9bb680537b1a0aeed66b7ba62 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Thu, 6 Nov 2025 20:54:05 -0800 Subject: [PATCH 20/28] bump --- test-server/net-v4-server/s3ec-net-v4-improved | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-server/net-v4-server/s3ec-net-v4-improved b/test-server/net-v4-server/s3ec-net-v4-improved index c647789d..dbb3efe0 160000 --- a/test-server/net-v4-server/s3ec-net-v4-improved +++ b/test-server/net-v4-server/s3ec-net-v4-improved @@ -1 +1 @@ -Subproject commit c647789d34964f23bf2b3d07e2f686ecf43140a6 +Subproject commit dbb3efe0c2947c6f122c516b9ac2891f6cf905e3 From d6c6c6ddbf087f90406dbbbba02935f150c3e12d Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Thu, 6 Nov 2025 20:56:39 -0800 Subject: [PATCH 21/28] auto commit --- test-server/net-v4-server/.duvet/.gitignore | 3 + test-server/net-v4-server/.duvet/config.toml | 27 +++ .../client/aws-sdk-compatibility.toml | 27 --- .../client/cryptographic-materials.toml | 38 --- .../client/enable-delayed-authentication.toml | 33 --- .../enable-legacy-unauthenticated-modes.toml | 33 --- .../enable-legacy-wrapping-algorithms.toml | 33 --- .../client/encryption-algorithm.toml | 26 --- .../client/inherited-sdk-configuration.toml | 34 --- .../instruction-file-configuration.toml | 26 --- .../s3-encryption/client/key-commitment.toml | 26 --- .../client/optional-api-operations.toml | 101 -------- .../s3-encryption/client/randomness.toml | 13 -- .../client/required-api-operations.toml | 77 ------- .../s3-encryption/client/set-buffer-size.toml | 26 --- .../client/wrapped-s3-client-s.toml | 19 -- ...-message-format-version-compatibility.toml | 34 --- .../content-metadata-mapkeys.toml | 217 ------------------ .../determining-s3ec-object-status.toml | 60 ----- .../content-metadata/v1-v2-shared.toml | 24 -- .../data-format/content-metadata/v3-only.toml | 91 -------- .../metadata-strategy/instruction-file.toml | 66 ------ .../metadata-strategy/object-metadata.toml | 28 --- .../v1-v2-instruction-files.toml | 12 - .../v3-instruction-files.toml | 81 ------- .../decrypting-with-commitment.toml | 33 --- .../decryption/key-commitment.toml | 20 -- .../decryption/legacy-decryption.toml | 19 -- .../s3-encryption/decryption/ranged-gets.toml | 44 ---- ...lg-aes-256-ctr-hkdf-sha512-commit-key.toml | 14 -- .../alg-aes-256-ctr-iv16-tag16-no-kdf.toml | 14 -- ...lg-aes-256-gcm-hkdf-sha512-commit-key.toml | 27 --- .../alg-aes-256-gcm-iv12-tag16-no-kdf.toml | 26 --- .../encryption/cipher-initialization.toml | 16 -- .../encryption/content-encryption.toml | 43 ---- .../key-commitment/commitment-policy.toml | 58 ----- .../key-derivation/hkdf-operation.toml | 106 --------- 37 files changed, 30 insertions(+), 1545 deletions(-) create mode 100644 test-server/net-v4-server/.duvet/.gitignore create mode 100644 test-server/net-v4-server/.duvet/config.toml delete mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/aws-sdk-compatibility.toml delete mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/cryptographic-materials.toml delete mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/enable-delayed-authentication.toml delete mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/enable-legacy-unauthenticated-modes.toml delete mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/enable-legacy-wrapping-algorithms.toml delete mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/encryption-algorithm.toml delete mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/inherited-sdk-configuration.toml delete mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/instruction-file-configuration.toml delete mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/key-commitment.toml delete mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/optional-api-operations.toml delete mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/randomness.toml delete mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/required-api-operations.toml delete mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/set-buffer-size.toml delete mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/wrapped-s3-client-s.toml delete mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/algorithm-suite-and-message-format-version-compatibility.toml delete mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/content-metadata-mapkeys.toml delete mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/determining-s3ec-object-status.toml delete mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/v1-v2-shared.toml delete mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/v3-only.toml delete mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/metadata-strategy/instruction-file.toml delete mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/metadata-strategy/object-metadata.toml delete mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/metadata-strategy/v1-v2-instruction-files.toml delete mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/metadata-strategy/v3-instruction-files.toml delete mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/decryption/decrypting-with-commitment.toml delete mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/decryption/key-commitment.toml delete mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/decryption/legacy-decryption.toml delete mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/decryption/ranged-gets.toml delete mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/alg-aes-256-ctr-hkdf-sha512-commit-key.toml delete mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/alg-aes-256-ctr-iv16-tag16-no-kdf.toml delete mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/alg-aes-256-gcm-hkdf-sha512-commit-key.toml delete mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/alg-aes-256-gcm-iv12-tag16-no-kdf.toml delete mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/cipher-initialization.toml delete mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/content-encryption.toml delete mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/key-commitment/commitment-policy.toml delete mode 100644 test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/key-derivation/hkdf-operation.toml diff --git a/test-server/net-v4-server/.duvet/.gitignore b/test-server/net-v4-server/.duvet/.gitignore new file mode 100644 index 00000000..93956e36 --- /dev/null +++ b/test-server/net-v4-server/.duvet/.gitignore @@ -0,0 +1,3 @@ +reports/ +requirements/ +specification/ \ No newline at end of file diff --git a/test-server/net-v4-server/.duvet/config.toml b/test-server/net-v4-server/.duvet/config.toml new file mode 100644 index 00000000..0548b05c --- /dev/null +++ b/test-server/net-v4-server/.duvet/config.toml @@ -0,0 +1,27 @@ +'$schema' = "https://awslabs.github.io/duvet/config/v0.4.0.json" + +[[source]] +pattern = "**/*.cs" + +# Include required specifications here +[[specification]] +source = "../specification/s3-encryption/client.md" +[[specification]] +source = "../specification/s3-encryption/decryption.md" +[[specification]] +source = "../specification/s3-encryption/encryption.md" +[[specification]] +source = "../specification/s3-encryption/key-commitment.md" +[[specification]] +source = "../specification/s3-encryption/key-derivation.md" +[[specification]] +source = "../specification/s3-encryption/data-format/content-metadata.md" +[[specification]] +source = "../specification/s3-encryption/data-format/metadata-strategy.md" + +[report.html] +enabled = true + +# Enable snapshots to prevent requirement coverage regressions +[report.snapshot] +enabled = false \ No newline at end of file diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/aws-sdk-compatibility.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/aws-sdk-compatibility.toml deleted file mode 100644 index ddaf61a2..00000000 --- a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/aws-sdk-compatibility.toml +++ /dev/null @@ -1,27 +0,0 @@ -target = "../specification/s3-encryption/client.md#aws-sdk-compatibility" - -# AWS SDK Compatibility -# -# The S3EC MUST adhere to the same interface for API operations as the conventional AWS SDK S3 client. -# In other words, the SDK's conventional S3 client is able to be substituted for the S3EC. -# The S3EC SHOULD support invoking operations unrelated to client-side encryption e.g. CopyObject as the conventional AWS SDK S3 client would. -# The S3EC MUST provide a different set of configuration options than the conventional S3 client. - -[[spec]] -level = "MUST" -quote = ''' -The S3EC MUST adhere to the same interface for API operations as the conventional AWS SDK S3 client. -''' - -[[spec]] -level = "SHOULD" -quote = ''' -The S3EC SHOULD support invoking operations unrelated to client-side encryption e.g. -''' - -[[spec]] -level = "MUST" -quote = ''' -The S3EC MUST provide a different set of configuration options than the conventional S3 client. -''' - diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/cryptographic-materials.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/cryptographic-materials.toml deleted file mode 100644 index 1f9aac05..00000000 --- a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/cryptographic-materials.toml +++ /dev/null @@ -1,38 +0,0 @@ -target = "../specification/s3-encryption/client.md#cryptographic-materials" - -# Cryptographic Materials -# -# The S3EC MUST accept either one CMM or one Keyring instance upon initialization. -# If both a CMM and a Keyring are provided, the S3EC MUST throw an exception. -# When a Keyring is provided, the S3EC MUST create an instance of the DefaultCMM using the provided Keyring. -# -# The S3EC MAY accept key material directly. -# When only key material is provided, a Keyring corresponding to the type of key material is created by default. -# This behavior is discouraged, as it requires all Keyring configuration options to be supported by client initialization. -# This leads to customer confusion when a Keyring is provided and a Keyring option is set on the client, and thus not applied. -# It is considered deprecated, meaning it will be removed in the next major version (v4). - -[[spec]] -level = "MUST" -quote = ''' -The S3EC MUST accept either one CMM or one Keyring instance upon initialization. -''' - -[[spec]] -level = "MUST" -quote = ''' -If both a CMM and a Keyring are provided, the S3EC MUST throw an exception. -''' - -[[spec]] -level = "MUST" -quote = ''' -When a Keyring is provided, the S3EC MUST create an instance of the DefaultCMM using the provided Keyring. -''' - -[[spec]] -level = "MAY" -quote = ''' -The S3EC MAY accept key material directly. -''' - diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/enable-delayed-authentication.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/enable-delayed-authentication.toml deleted file mode 100644 index 15473a14..00000000 --- a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/enable-delayed-authentication.toml +++ /dev/null @@ -1,33 +0,0 @@ -target = "../specification/s3-encryption/client.md#enable-delayed-authentication" - -# Enable Delayed Authentication -# -# The S3EC MUST support the option to enable or disable Delayed Authentication mode. -# Delayed Authentication mode MUST be set to false by default. -# When enabled, the S3EC MAY release plaintext from a stream which has not been authenticated. -# When disabled the S3EC MUST NOT release plaintext from a stream which has not been authenticated. - -[[spec]] -level = "MUST" -quote = ''' -The S3EC MUST support the option to enable or disable Delayed Authentication mode. -''' - -[[spec]] -level = "MUST" -quote = ''' -Delayed Authentication mode MUST be set to false by default. -''' - -[[spec]] -level = "MAY" -quote = ''' -When enabled, the S3EC MAY release plaintext from a stream which has not been authenticated. -''' - -[[spec]] -level = "MUST" -quote = ''' -When disabled the S3EC MUST NOT release plaintext from a stream which has not been authenticated. -''' - diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/enable-legacy-unauthenticated-modes.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/enable-legacy-unauthenticated-modes.toml deleted file mode 100644 index b571e1b1..00000000 --- a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/enable-legacy-unauthenticated-modes.toml +++ /dev/null @@ -1,33 +0,0 @@ -target = "../specification/s3-encryption/client.md#enable-legacy-unauthenticated-modes" - -# Enable Legacy Unauthenticated Modes -# -# The S3EC MUST support the option to enable or disable legacy unauthenticated modes (content encryption algorithms). -# The option to enable legacy unauthenticated modes MUST be set to false by default. -# When enabled, the S3EC MUST be able to decrypt objects encrypted with all content encryption algorithms (both legacy and fully supported). -# When disabled, the S3EC MUST NOT decrypt objects encrypted using legacy content encryption algorithms; it MUST throw an exception when attempting to decrypt an object encrypted with a legacy content encryption algorithm. - -[[spec]] -level = "MUST" -quote = ''' -The S3EC MUST support the option to enable or disable legacy unauthenticated modes (content encryption algorithms). -''' - -[[spec]] -level = "MUST" -quote = ''' -The option to enable legacy unauthenticated modes MUST be set to false by default. -''' - -[[spec]] -level = "MUST" -quote = ''' -When enabled, the S3EC MUST be able to decrypt objects encrypted with all content encryption algorithms (both legacy and fully supported). -''' - -[[spec]] -level = "MUST" -quote = ''' -When disabled, the S3EC MUST NOT decrypt objects encrypted using legacy content encryption algorithms; it MUST throw an exception when attempting to decrypt an object encrypted with a legacy content encryption algorithm. -''' - diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/enable-legacy-wrapping-algorithms.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/enable-legacy-wrapping-algorithms.toml deleted file mode 100644 index 20fedc49..00000000 --- a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/enable-legacy-wrapping-algorithms.toml +++ /dev/null @@ -1,33 +0,0 @@ -target = "../specification/s3-encryption/client.md#enable-legacy-wrapping-algorithms" - -# Enable Legacy Wrapping Algorithms -# -# The S3EC MUST support the option to enable or disable legacy wrapping algorithms. -# The option to enable legacy wrapping algorithms MUST be set to false by default. -# When enabled, the S3EC MUST be able to decrypt objects encrypted with all supported wrapping algorithms (both legacy and fully supported). -# When disabled, the S3EC MUST NOT decrypt objects encrypted using legacy wrapping algorithms; it MUST throw an exception when attempting to decrypt an object encrypted with a legacy wrapping algorithm. - -[[spec]] -level = "MUST" -quote = ''' -The S3EC MUST support the option to enable or disable legacy wrapping algorithms. -''' - -[[spec]] -level = "MUST" -quote = ''' -The option to enable legacy wrapping algorithms MUST be set to false by default. -''' - -[[spec]] -level = "MUST" -quote = ''' -When enabled, the S3EC MUST be able to decrypt objects encrypted with all supported wrapping algorithms (both legacy and fully supported). -''' - -[[spec]] -level = "MUST" -quote = ''' -When disabled, the S3EC MUST NOT decrypt objects encrypted using legacy wrapping algorithms; it MUST throw an exception when attempting to decrypt an object encrypted with a legacy wrapping algorithm. -''' - diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/encryption-algorithm.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/encryption-algorithm.toml deleted file mode 100644 index a3cfb41e..00000000 --- a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/encryption-algorithm.toml +++ /dev/null @@ -1,26 +0,0 @@ -target = "../specification/s3-encryption/client.md#encryption-algorithm" - -# Encryption Algorithm -# -# The S3EC MUST support configuration of the encryption algorithm (or algorithm suite) during its initialization. -# The S3EC MUST validate that the configured encryption algorithm is not legacy. -# If the configured encryption algorithm is legacy, then the S3EC MUST throw an exception. - -[[spec]] -level = "MUST" -quote = ''' -The S3EC MUST support configuration of the encryption algorithm (or algorithm suite) during its initialization. -''' - -[[spec]] -level = "MUST" -quote = ''' -The S3EC MUST validate that the configured encryption algorithm is not legacy. -''' - -[[spec]] -level = "MUST" -quote = ''' -If the configured encryption algorithm is legacy, then the S3EC MUST throw an exception. -''' - diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/inherited-sdk-configuration.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/inherited-sdk-configuration.toml deleted file mode 100644 index 36a1132a..00000000 --- a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/inherited-sdk-configuration.toml +++ /dev/null @@ -1,34 +0,0 @@ -target = "../specification/s3-encryption/client.md#inherited-sdk-configuration" - -# Inherited SDK Configuration -# -# The S3EC MAY support directly configuring the wrapped SDK clients through its initialization. -# For example, the S3EC MAY accept a credentials provider instance during its initialization. -# If the S3EC accepts SDK client configuration, the configuration MUST be applied to all wrapped S3 clients. -# If the S3EC accepts SDK client configuration, the configuration MUST be applied to all wrapped SDK clients including the KMS client. -# If the S3EC accepts any SDK client configuration options, then the S3EC should support all possible configuration options. - -[[spec]] -level = "MAY" -quote = ''' -The S3EC MAY support directly configuring the wrapped SDK clients through its initialization. -''' - -[[spec]] -level = "MAY" -quote = ''' -For example, the S3EC MAY accept a credentials provider instance during its initialization. -''' - -[[spec]] -level = "MUST" -quote = ''' -If the S3EC accepts SDK client configuration, the configuration MUST be applied to all wrapped S3 clients. -''' - -[[spec]] -level = "MUST" -quote = ''' -If the S3EC accepts SDK client configuration, the configuration MUST be applied to all wrapped SDK clients including the KMS client. -''' - diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/instruction-file-configuration.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/instruction-file-configuration.toml deleted file mode 100644 index 2f1ae4e6..00000000 --- a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/instruction-file-configuration.toml +++ /dev/null @@ -1,26 +0,0 @@ -target = "../specification/s3-encryption/client.md#instruction-file-configuration" - -# Instruction File Configuration -# -# The S3EC MAY support the option to provide Instruction File Configuration during its initialization. -# If the S3EC in a given language supports Instruction Files, then it MUST accept Instruction File Configuration during its initialization. -# In this case, the Instruction File Configuration SHOULD be optional, such that its default configuration is used when none is provided. - -[[spec]] -level = "MAY" -quote = ''' -The S3EC MAY support the option to provide Instruction File Configuration during its initialization. -''' - -[[spec]] -level = "MUST" -quote = ''' -If the S3EC in a given language supports Instruction Files, then it MUST accept Instruction File Configuration during its initialization. -''' - -[[spec]] -level = "SHOULD" -quote = ''' -In this case, the Instruction File Configuration SHOULD be optional, such that its default configuration is used when none is provided. -''' - diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/key-commitment.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/key-commitment.toml deleted file mode 100644 index ea8326bb..00000000 --- a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/key-commitment.toml +++ /dev/null @@ -1,26 +0,0 @@ -target = "../specification/s3-encryption/client.md#key-commitment" - -# Key Commitment -# -# The S3EC MUST support configuration of the [Key Commitment policy](./key-commitment.md) during its initialization. -# The S3EC MUST validate the configured Encryption Algorithm against the provided key commitment policy. -# If the configured Encryption Algorithm is incompatible with the key commitment policy, then it MUST throw an exception. - -[[spec]] -level = "MUST" -quote = ''' -The S3EC MUST support configuration of the [Key Commitment policy](./key-commitment.md) during its initialization. -''' - -[[spec]] -level = "MUST" -quote = ''' -The S3EC MUST validate the configured Encryption Algorithm against the provided key commitment policy. -''' - -[[spec]] -level = "MUST" -quote = ''' -If the configured Encryption Algorithm is incompatible with the key commitment policy, then it MUST throw an exception. -''' - diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/optional-api-operations.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/optional-api-operations.toml deleted file mode 100644 index 8822b14c..00000000 --- a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/optional-api-operations.toml +++ /dev/null @@ -1,101 +0,0 @@ -target = "../specification/s3-encryption/client.md#optional-api-operations" - -# Optional API Operations -# -# The S3EC may provide implementations for the following S3 operations: -# -# - CreateMultipartUpload MAY be implemented by the S3EC. -# - If implemented, CreateMultipartUpload MUST initiate a multipart upload. -# - UploadPart MAY be implemented by the S3EC. -# - UploadPart MUST encrypt each part. -# - Each part MUST be encrypted in sequence. -# - Each part MUST be encrypted using the same cipher instance for each part. -# - CompleteMultipartUpload MAY be implemented by the S3EC. -# - CompleteMultipartUpload MUST complete the multipart upload. -# - AbortMultipartUpload MAY be implemented by the S3EC. -# - AbortMultipartUpload MUST abort the multipart upload. -# -# The S3EC may provide implementations for the following S3EC-specific operation(s): -# -# - ReEncryptInstructionFile MAY be implemented by the S3EC. -# - ReEncryptInstructionFile MUST decrypt the instruction file's encrypted data key for the given object using the client's CMM. -# - ReEncryptInstructionFile MUST re-encrypt the plaintext data key with a provided keyring. - -[[spec]] -level = "MAY" -quote = ''' -- CreateMultipartUpload MAY be implemented by the S3EC. -''' - -[[spec]] -level = "MUST" -quote = ''' -- If implemented, CreateMultipartUpload MUST initiate a multipart upload. -''' - -[[spec]] -level = "MAY" -quote = ''' -- UploadPart MAY be implemented by the S3EC. -''' - -[[spec]] -level = "MUST" -quote = ''' -- UploadPart MUST encrypt each part. -''' - -[[spec]] -level = "MUST" -quote = ''' -- Each part MUST be encrypted in sequence. -''' - -[[spec]] -level = "MUST" -quote = ''' -- Each part MUST be encrypted using the same cipher instance for each part. -''' - -[[spec]] -level = "MAY" -quote = ''' -- CompleteMultipartUpload MAY be implemented by the S3EC. -''' - -[[spec]] -level = "MUST" -quote = ''' -- CompleteMultipartUpload MUST complete the multipart upload. -''' - -[[spec]] -level = "MAY" -quote = ''' -- AbortMultipartUpload MAY be implemented by the S3EC. -''' - -[[spec]] -level = "MUST" -quote = ''' -- AbortMultipartUpload MUST abort the multipart upload. -''' - -[[spec]] -level = "MAY" -quote = ''' -- ReEncryptInstructionFile MAY be implemented by the S3EC. -''' - -[[spec]] -level = "MUST" -quote = ''' -- ReEncryptInstructionFile MUST decrypt the instruction file's encrypted data key for the given object using the client's CMM. -''' - -[[spec]] -level = "MUST" -quote = ''' -- ReEncryptInstructionFile MUST re-encrypt the plaintext data key with a provided keyring. -''' - diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/randomness.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/randomness.toml deleted file mode 100644 index 22f93991..00000000 --- a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/randomness.toml +++ /dev/null @@ -1,13 +0,0 @@ -target = "../specification/s3-encryption/client.md#randomness" - -# Randomness -# -# The S3EC MAY accept a source of randomness during client initialization. -# The inclusion of a source of randomness is subject to language availability. - -[[spec]] -level = "MAY" -quote = ''' -The S3EC MAY accept a source of randomness during client initialization. -''' - diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/required-api-operations.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/required-api-operations.toml deleted file mode 100644 index 36500f6e..00000000 --- a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/required-api-operations.toml +++ /dev/null @@ -1,77 +0,0 @@ -target = "../specification/s3-encryption/client.md#required-api-operations" - -# Required API Operations -# -# The S3EC must provide implementations for the following S3 operations: -# -# - GetObject MUST be implemented by the S3EC. -# - GetObject MUST decrypt data received from the S3 server and return it as plaintext. -# - PutObject MUST be implemented by the S3EC. -# - PutObject MUST encrypt its input data before it is uploaded to S3. -# - DeleteObject MUST be implemented by the S3EC. -# - DeleteObject MUST delete the given object key. -# - DeleteObject MUST delete the associated instruction file using the default instruction file suffix. -# - DeleteObjects MUST be implemented by the S3EC. -# - DeleteObjects MUST delete each of the given objects. -# - DeleteObjects MUST delete each of the corresponding instruction files using the default instruction file suffix. - -[[spec]] -level = "MUST" -quote = ''' -- GetObject MUST be implemented by the S3EC. -''' - -[[spec]] -level = "MUST" -quote = ''' -- GetObject MUST decrypt data received from the S3 server and return it as plaintext. -''' - -[[spec]] -level = "MUST" -quote = ''' -- PutObject MUST be implemented by the S3EC. -''' - -[[spec]] -level = "MUST" -quote = ''' -- PutObject MUST encrypt its input data before it is uploaded to S3. -''' - -[[spec]] -level = "MUST" -quote = ''' -- DeleteObject MUST be implemented by the S3EC. -''' - -[[spec]] -level = "MUST" -quote = ''' -- DeleteObject MUST delete the given object key. -''' - -[[spec]] -level = "MUST" -quote = ''' -- DeleteObject MUST delete the associated instruction file using the default instruction file suffix. -''' - -[[spec]] -level = "MUST" -quote = ''' -- DeleteObjects MUST be implemented by the S3EC. -''' - -[[spec]] -level = "MUST" -quote = ''' -- DeleteObjects MUST delete each of the given objects. -''' - -[[spec]] -level = "MUST" -quote = ''' -- DeleteObjects MUST delete each of the corresponding instruction files using the default instruction file suffix. -''' - diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/set-buffer-size.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/set-buffer-size.toml deleted file mode 100644 index 0701cfe3..00000000 --- a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/set-buffer-size.toml +++ /dev/null @@ -1,26 +0,0 @@ -target = "../specification/s3-encryption/client.md#set-buffer-size" - -# Set Buffer Size -# -# The S3EC SHOULD accept a configurable buffer size which refers to the maximum ciphertext length in bytes to store in memory when Delayed Authentication mode is disabled. -# If Delayed Authentication mode is enabled, and the buffer size has been set to a value other than its default, the S3EC MUST throw an exception. -# If Delayed Authentication mode is disabled, and no buffer size is provided, the S3EC MUST set the buffer size to a reasonable default. - -[[spec]] -level = "SHOULD" -quote = ''' -The S3EC SHOULD accept a configurable buffer size which refers to the maximum ciphertext length in bytes to store in memory when Delayed Authentication mode is disabled. -''' - -[[spec]] -level = "MUST" -quote = ''' -If Delayed Authentication mode is enabled, and the buffer size has been set to a value other than its default, the S3EC MUST throw an exception. -''' - -[[spec]] -level = "MUST" -quote = ''' -If Delayed Authentication mode is disabled, and no buffer size is provided, the S3EC MUST set the buffer size to a reasonable default. -''' - diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/wrapped-s3-client-s.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/wrapped-s3-client-s.toml deleted file mode 100644 index 427764b5..00000000 --- a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/client/wrapped-s3-client-s.toml +++ /dev/null @@ -1,19 +0,0 @@ -target = "../specification/s3-encryption/client.md#wrapped-s3-client-s" - -# Wrapped S3 Client(s) -# -# The S3EC MUST support the option to provide an SDK S3 client instance during its initialization. -# The S3EC MUST NOT support use of S3EC as the provided S3 client during its initialization; it MUST throw an exception in this case. - -[[spec]] -level = "MUST" -quote = ''' -The S3EC MUST support the option to provide an SDK S3 client instance during its initialization. -''' - -[[spec]] -level = "MUST" -quote = ''' -The S3EC MUST NOT support use of S3EC as the provided S3 client during its initialization; it MUST throw an exception in this case. -''' - diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/algorithm-suite-and-message-format-version-compatibility.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/algorithm-suite-and-message-format-version-compatibility.toml deleted file mode 100644 index 1e382ff0..00000000 --- a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/algorithm-suite-and-message-format-version-compatibility.toml +++ /dev/null @@ -1,34 +0,0 @@ -target = "../specification/s3-encryption/data-format/content-metadata.md#algorithm-suite-and-message-format-version-compatibility" - -# Algorithm Suite and Message Format Version Compatibility -# -# The S3EC supports encryption with various content encryption Algorithm Suites: -# -# - ALG_AES_256_CBC_IV16_NO_KDF -# - ALG_AES_256_GCM_IV12_TAG16_NO_KDF -# - ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY -# -# The mapping of Algorithm Suite to Message Format Versions follows: -# -# Objects encrypted with ALG_AES_256_CBC_IV16_NO_KDF MAY use either the V1 or V2 message format version. -# Objects encrypted with ALG_AES_256_GCM_IV12_TAG16_NO_KDF MUST use the V2 message format version only. -# Objects encrypted with ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY MUST use the V3 message format version only. - -[[spec]] -level = "MAY" -quote = ''' -Objects encrypted with ALG_AES_256_CBC_IV16_NO_KDF MAY use either the V1 or V2 message format version. -''' - -[[spec]] -level = "MUST" -quote = ''' -Objects encrypted with ALG_AES_256_GCM_IV12_TAG16_NO_KDF MUST use the V2 message format version only. -''' - -[[spec]] -level = "MUST" -quote = ''' -Objects encrypted with ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY MUST use the V3 message format version only. -''' - diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/content-metadata-mapkeys.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/content-metadata-mapkeys.toml deleted file mode 100644 index c8d14030..00000000 --- a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/content-metadata-mapkeys.toml +++ /dev/null @@ -1,217 +0,0 @@ -target = "../specification/s3-encryption/data-format/content-metadata.md#content-metadata-mapkeys" - -# Content Metadata MapKeys -# -# Metadata is stored as a string -> string map (see TODO for further specification of "string"). -# Metadata is responsible for storing data which is critical for decryption of the object. -# The mapkeys contained in the metadata depends on the format version used. -# The "x-amz-meta-" prefix is automatically added by the S3 server and MUST NOT be included in implementation code. -# The "x-amz-" prefix denotes that the metadata is owned by an Amazon product and MUST be prepended to all S3EC metadata mapkeys. -# -# When the object is encrypted using the V1 format: -# -# - The mapkey "x-amz-unencrypted-content-length" SHOULD be present for V1 format objects. -# - The mapkey "x-amz-key" MUST be present for V1 format objects. -# - The mapkey "x-amz-matdesc" MUST be present for V1 format objects. -# - The mapkey "x-amz-iv" MUST be present for V1 format objects. -# -# When the object is encrypted using the V2 format: -# -# - The mapkey "x-amz-key-v2" MUST be present for V2 format objects. -# - The mapkey "x-amz-matdesc" MUST be present for V2 format objects. -# - The mapkey "x-amz-iv" MUST be present for V2 format objects. -# - The mapkey "x-amz-wrap-alg" MUST be present for V2 format objects. -# - The mapkey "x-amz-cek-alg" MUST be present for V2 format objects. -# - The mapkey "x-amz-tag-len" MUST be present for V2 format objects. -# -# The V3 format introduces the use of compression to reduce the size of S3EC-specific metadata. -# The V3 format uses the following mapkeys: -# -# - The mapkey "x-amz-c" MUST be present for V3 format objects. -# - This mapkey ("x-amz-c") SHOULD be represented by a constant named "CONTENT_CIPHER_V3" or similar in the implementation code. -# - This mapkey is the V3 version of the "x-amz-cek-alg" mapkey. -# - The mapkey "x-amz-3" MUST be present for V3 format objects. -# - This mapkey ("x-amz-3") SHOULD be represented by a constant named "ENCRYPTED_DATA_KEY_V3" or similar in the implementation code. -# - This mapkey is the V3 version of the "x-amz-key" and "x-amz-key-v2" mapkeys. -# - The mapkey "x-amz-m" SHOULD be present for V3 format objects that use Raw Keyring Material Description. -# - This mapkey ("x-amz-m") SHOULD be represented by a constant named "MAT_DESC_V3" or similar in the implementation code. -# - This mapkey is the V3 version of the "x-amz-matdesc" mapkey. -# - The mapkey "x-amz-t" SHOULD be present for V3 format objects that use KMS Encryption Context. -# - This mapkey ("x-amz-t") SHOULD be represented by a constant named "ENCRYPTION_CONTEXT_V3" or similar in the implementation code. -# - This mapkey is new for V3 and serves to distinguish KMS Encryption Context from Raw Keyring Material Description. -# - The mapkey "x-amz-w" MUST be present for V3 format objects. -# - This mapkey ("x-amz-w") SHOULD be represented by a constant named "ENCRYPTED_DATA_KEY_ALGORITHM_V3" or similar in the implementation code. -# - This mapkey is the V3 version of "x-amz-wrap-alg" mapkey. -# - The mapkey "x-amz-d" MUST be present for V3 format objects. -# - This mapkey ("x-amz-d") SHOULD be represented by a constant named "KEY_COMMITMENT_V3" or similar in the implementation code. -# - This mapkey is new for V3 and refers to the Key Commitment value used by committing algorithm suites. -# - The mapkey "x-amz-i" MUST be present for V3 format objects. -# - This mapkey ("x-amz-i") SHOULD be represented by a constant named "MESSAGE_ID_V3" or similar in the implementation code. -# - This mapkey is new for V3 and refers to the Message ID value used by committing algorithm suites. -# -# In general, the storage medium is independent from the format, with the exception of the V3 format. -# In the V3 format, the mapkeys "x-amz-c", "x-amz-d", and "x-amz-i" MUST be stored exclusively in the Object Metadata. -# See [metadata-strategy](./metadata-strategy.md) for more details. - -[[spec]] -level = "MUST" -quote = ''' -The "x-amz-meta-" prefix is automatically added by the S3 server and MUST NOT be included in implementation code. -''' - -[[spec]] -level = "MUST" -quote = ''' -The "x-amz-" prefix denotes that the metadata is owned by an Amazon product and MUST be prepended to all S3EC metadata mapkeys. -''' - -[[spec]] -level = "SHOULD" -quote = ''' -- The mapkey "x-amz-unencrypted-content-length" SHOULD be present for V1 format objects. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The mapkey "x-amz-key" MUST be present for V1 format objects. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The mapkey "x-amz-matdesc" MUST be present for V1 format objects. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The mapkey "x-amz-iv" MUST be present for V1 format objects. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The mapkey "x-amz-key-v2" MUST be present for V2 format objects. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The mapkey "x-amz-matdesc" MUST be present for V2 format objects. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The mapkey "x-amz-iv" MUST be present for V2 format objects. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The mapkey "x-amz-wrap-alg" MUST be present for V2 format objects. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The mapkey "x-amz-cek-alg" MUST be present for V2 format objects. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The mapkey "x-amz-tag-len" MUST be present for V2 format objects. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The mapkey "x-amz-c" MUST be present for V3 format objects. -''' - -[[spec]] -level = "SHOULD" -quote = ''' -- This mapkey ("x-amz-c") SHOULD be represented by a constant named "CONTENT_CIPHER_V3" or similar in the implementation code. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The mapkey "x-amz-3" MUST be present for V3 format objects. -''' - -[[spec]] -level = "SHOULD" -quote = ''' -- This mapkey ("x-amz-3") SHOULD be represented by a constant named "ENCRYPTED_DATA_KEY_V3" or similar in the implementation code. -''' - -[[spec]] -level = "SHOULD" -quote = ''' -- The mapkey "x-amz-m" SHOULD be present for V3 format objects that use Raw Keyring Material Description. -''' - -[[spec]] -level = "SHOULD" -quote = ''' -- This mapkey ("x-amz-m") SHOULD be represented by a constant named "MAT_DESC_V3" or similar in the implementation code. -''' - -[[spec]] -level = "SHOULD" -quote = ''' -- The mapkey "x-amz-t" SHOULD be present for V3 format objects that use KMS Encryption Context. -''' - -[[spec]] -level = "SHOULD" -quote = ''' -- This mapkey ("x-amz-t") SHOULD be represented by a constant named "ENCRYPTION_CONTEXT_V3" or similar in the implementation code. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The mapkey "x-amz-w" MUST be present for V3 format objects. -''' - -[[spec]] -level = "SHOULD" -quote = ''' -- This mapkey ("x-amz-w") SHOULD be represented by a constant named "ENCRYPTED_DATA_KEY_ALGORITHM_V3" or similar in the implementation code. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The mapkey "x-amz-d" MUST be present for V3 format objects. -''' - -[[spec]] -level = "SHOULD" -quote = ''' -- This mapkey ("x-amz-d") SHOULD be represented by a constant named "KEY_COMMITMENT_V3" or similar in the implementation code. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The mapkey "x-amz-i" MUST be present for V3 format objects. -''' - -[[spec]] -level = "SHOULD" -quote = ''' -- This mapkey ("x-amz-i") SHOULD be represented by a constant named "MESSAGE_ID_V3" or similar in the implementation code. -''' - -[[spec]] -level = "MUST" -quote = ''' -In the V3 format, the mapkeys "x-amz-c", "x-amz-d", and "x-amz-i" MUST be stored exclusively in the Object Metadata. -''' - diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/determining-s3ec-object-status.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/determining-s3ec-object-status.toml deleted file mode 100644 index 9a06cf0e..00000000 --- a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/determining-s3ec-object-status.toml +++ /dev/null @@ -1,60 +0,0 @@ -target = "../specification/s3-encryption/data-format/content-metadata.md#determining-s3ec-object-status" - -# Determining S3EC Object Status -# -# Whether or not an object is determined to be a valid object encrypted by S3EC is done via the following logic: -# -# V1: -# -# - If the metadata contains "x-amz-iv" and "x-amz-key" then the object MUST be considered as an S3EC-encrypted object using the V1 format. -# -# V2: -# -# - If the metadata contains "x-amz-iv" and "x-amz-metadata-x-amz-key-v2" then the object MUST be considered as an S3EC-encrypted object using the V2 format. -# -# V3: -# -# - If the metadata contains "x-amz-3" and "x-amz-d" and "x-amz-i" then the object MUST be considered an S3EC-encrypted object using the V3 format. -# -# This logic applies only to objects using ObjectMetadata to store cryptographic metadata. -# If the object matches none of the V1/V2/V3 formats, the S3EC MUST attempt to get the instruction file. -# -# If there are multiple mapkeys which are meant to be exclusive, such as "x-amz-key", "x-amz-key-v2", and "x-amz-3" then the S3EC SHOULD throw an exception. -# In general, if there is any deviation from the above format, with the exception of additional unrelated mapkeys, then the S3EC SHOULD throw an exception. - -[[spec]] -level = "MUST" -quote = ''' -- If the metadata contains "x-amz-iv" and "x-amz-key" then the object MUST be considered as an S3EC-encrypted object using the V1 format. -''' - -[[spec]] -level = "MUST" -quote = ''' -- If the metadata contains "x-amz-iv" and "x-amz-metadata-x-amz-key-v2" then the object MUST be considered as an S3EC-encrypted object using the V2 format. -''' - -[[spec]] -level = "MUST" -quote = ''' -- If the metadata contains "x-amz-3" and "x-amz-d" and "x-amz-i" then the object MUST be considered an S3EC-encrypted object using the V3 format. -''' - -[[spec]] -level = "MUST" -quote = ''' -If the object matches none of the V1/V2/V3 formats, the S3EC MUST attempt to get the instruction file. -''' - -[[spec]] -level = "SHOULD" -quote = ''' -If there are multiple mapkeys which are meant to be exclusive, such as "x-amz-key", "x-amz-key-v2", and "x-amz-3" then the S3EC SHOULD throw an exception. -''' - -[[spec]] -level = "SHOULD" -quote = ''' -In general, if there is any deviation from the above format, with the exception of additional unrelated mapkeys, then the S3EC SHOULD throw an exception. -''' - diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/v1-v2-shared.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/v1-v2-shared.toml deleted file mode 100644 index d45b598b..00000000 --- a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/v1-v2-shared.toml +++ /dev/null @@ -1,24 +0,0 @@ -target = "../specification/s3-encryption/data-format/content-metadata.md#v1-v2-shared" - -# V1/V2 Shared -# -# The following mapkeys are used in both the V1 and V2 format. -# -# _x-amz-matdesc_ -# -# A JSON string containing the Material Description OR Encryption Context used when encrypting the data key. -# See TODO-link for more details on Material Description and Encryption Context. -# This string MAY be encoded by the esoteric double-encoding scheme used by the S3 web server. -# See TODO-link for more details on the S3 double-encoding scheme. -# The default value is the an empty JSON map (`{}`). -# -# _x-amz-iv_ -# -# The base64-encoded bytes used as the IV when encrypting the content. - -[[spec]] -level = "MAY" -quote = ''' -This string MAY be encoded by the esoteric double-encoding scheme used by the S3 web server. -''' - diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/v3-only.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/v3-only.toml deleted file mode 100644 index 075455fd..00000000 --- a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/content-metadata/v3-only.toml +++ /dev/null @@ -1,91 +0,0 @@ -target = "../specification/s3-encryption/data-format/content-metadata.md#v3-only" - -# V3 Only -# -# _x-amz-m_ -# -# A JSON string representing the Material Description of the key material used to encrypt the data key. -# This material description string MAY be encoded by the esoteric double-encoding scheme used by the S3 web server. -# The Material Description MUST be used for wrapping algorithms `AES/GCM` (`02`) and `RSA-OAEP-SHA1` (`22`). -# If the mapkey is not present, the default Material Description value MUST be set to an empty map (`{}`). -# See TODO-link for more details on the S3 double-encoding scheme. -# -# _x-amz-t_ -# -# A JSON string representing the AWS KMS Encryption Context associated with the encrypted object. -# This encryption context string MAY be encoded by the esoteric double-encoding scheme used by the S3 web server. -# The Encryption Context value MUST be used for wrapping algorithm `kms+context` or `12`. -# See TODO-link for more details on the S3 double-encoding scheme. -# -# _x-amz-w_ -# -# The wrapping algorithm used to encrypt the data key. -# The V3 format uses compression here such that each wrapping algorithm is represented by a two digit string. -# The valid values and their mapping to pre-existing values are: -# -# - 02 -# - AES/GCM -# - The wrapping algorithm value "02" MUST be translated to AES/GCM upon retrieval, and vice versa on write. -# - 12 -# - kms+context -# - The wrapping algorithm value "12" MUST be translated to kms+context upon retrieval, and vice versa on write. -# - 22 -# - RSA-OAEP-SHA1 -# - The wrapping algorithm value "22" MUST be translated to RSA-OAEP-SHA1 upon retrieval, and vice versa on write. -# -# _x-amz-d_ -# -# The base64-encoded bytes representing the Key Commitment associated with the encrypted object. -# -# _x-amz-i_ -# -# The base64-encoded bytes representing the Message ID associated with the encrypted object. - -[[spec]] -level = "MAY" -quote = ''' -This material description string MAY be encoded by the esoteric double-encoding scheme used by the S3 web server. -''' - -[[spec]] -level = "MUST" -quote = ''' -The Material Description MUST be used for wrapping algorithms `AES/GCM` (`02`) and `RSA-OAEP-SHA1` (`22`). -''' - -[[spec]] -level = "MUST" -quote = ''' -If the mapkey is not present, the default Material Description value MUST be set to an empty map (`{}`). -''' - -[[spec]] -level = "MAY" -quote = ''' -This encryption context string MAY be encoded by the esoteric double-encoding scheme used by the S3 web server. -''' - -[[spec]] -level = "MUST" -quote = ''' -The Encryption Context value MUST be used for wrapping algorithm `kms+context` or `12`. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The wrapping algorithm value "02" MUST be translated to AES/GCM upon retrieval, and vice versa on write. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The wrapping algorithm value "12" MUST be translated to kms+context upon retrieval, and vice versa on write. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The wrapping algorithm value "22" MUST be translated to RSA-OAEP-SHA1 upon retrieval, and vice versa on write. -''' - diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/metadata-strategy/instruction-file.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/metadata-strategy/instruction-file.toml deleted file mode 100644 index 1717e630..00000000 --- a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/metadata-strategy/instruction-file.toml +++ /dev/null @@ -1,66 +0,0 @@ -target = "../specification/s3-encryption/data-format/metadata-strategy.md#instruction-file" - -# Instruction File -# -# Instruction Files are a separate S3 object which contain content metadata. -# The S3EC MUST support writing some or all (depending on format) content metadata to an Instruction File. -# The content metadata stored in the Instruction File MUST be serialized to a JSON string. -# The serialized JSON string MUST be the only contents of the Instruction File. -# -# Instruction File writes MUST NOT be enabled by default. -# Instruction File writes MUST be optionally configured during client creation or on each PutObject request. -# The default Instruction File behavior uses the same S3 object key as its associated object suffixed with ".instruction". -# -# The S3EC MAY support re-encryption/key rotation via Instruction Files. -# Further details on Instruction File re-encryption can be found in (TODO). -# The S3EC MUST NOT support providing a custom Instruction File suffix on ordinary writes; custom suffixes MUST only be used during re-encryption. -# The S3EC SHOULD support providing a custom Instruction File suffix on GetObject requests, regardless of whether or not re-encryption is supported. - -[[spec]] -level = "MUST" -quote = ''' -The S3EC MUST support writing some or all (depending on format) content metadata to an Instruction File. -''' - -[[spec]] -level = "MUST" -quote = ''' -The content metadata stored in the Instruction File MUST be serialized to a JSON string. -''' - -[[spec]] -level = "MUST" -quote = ''' -The serialized JSON string MUST be the only contents of the Instruction File. -''' - -[[spec]] -level = "MUST" -quote = ''' -Instruction File writes MUST NOT be enabled by default. -''' - -[[spec]] -level = "MUST" -quote = ''' -Instruction File writes MUST be optionally configured during client creation or on each PutObject request. -''' - -[[spec]] -level = "MAY" -quote = ''' -The S3EC MAY support re-encryption/key rotation via Instruction Files. -''' - -[[spec]] -level = "MUST" -quote = ''' -The S3EC MUST NOT support providing a custom Instruction File suffix on ordinary writes; custom suffixes MUST only be used during re-encryption. -''' - -[[spec]] -level = "SHOULD" -quote = ''' -The S3EC SHOULD support providing a custom Instruction File suffix on GetObject requests, regardless of whether or not re-encryption is supported. -''' - diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/metadata-strategy/object-metadata.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/metadata-strategy/object-metadata.toml deleted file mode 100644 index 5a80b66e..00000000 --- a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/metadata-strategy/object-metadata.toml +++ /dev/null @@ -1,28 +0,0 @@ -target = "../specification/s3-encryption/data-format/metadata-strategy.md#object-metadata" - -# Object Metadata -# -# Object Metadata refers to the set of mapkey-value pairs stored alongside an object in S3. -# By default, the S3EC MUST store content metadata in the S3 Object Metadata. -# When an encrypted object is stored in S3 with non-US-ASCII Materials Description or Encryption Context, the S3 Server will apply an esoteric "double encoding" to the metadata. -# The S3EC SHOULD support decoding the S3 Server's "double encoding". -# If the S3EC does not support decoding the S3 Server's "double encoding" then it MUST return the content metadata untouched. - -[[spec]] -level = "MUST" -quote = ''' -By default, the S3EC MUST store content metadata in the S3 Object Metadata. -''' - -[[spec]] -level = "SHOULD" -quote = ''' -The S3EC SHOULD support decoding the S3 Server's "double encoding". -''' - -[[spec]] -level = "MUST" -quote = ''' -If the S3EC does not support decoding the S3 Server's "double encoding" then it MUST return the content metadata untouched. -''' - diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/metadata-strategy/v1-v2-instruction-files.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/metadata-strategy/v1-v2-instruction-files.toml deleted file mode 100644 index e34118ea..00000000 --- a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/metadata-strategy/v1-v2-instruction-files.toml +++ /dev/null @@ -1,12 +0,0 @@ -target = "../specification/s3-encryption/data-format/metadata-strategy.md#v1-v2-instruction-files" - -# V1/V2 Instruction Files -# -# In the V1/V2 message format, all of the content metadata MUST be stored in the Instruction File. - -[[spec]] -level = "MUST" -quote = ''' -In the V1/V2 message format, all of the content metadata MUST be stored in the Instruction File. -''' - diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/metadata-strategy/v3-instruction-files.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/metadata-strategy/v3-instruction-files.toml deleted file mode 100644 index 47ec29a9..00000000 --- a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/data-format/metadata-strategy/v3-instruction-files.toml +++ /dev/null @@ -1,81 +0,0 @@ -target = "../specification/s3-encryption/data-format/metadata-strategy.md#v3-instruction-files" - -# V3 Instruction Files -# -# In the V3 message format, only the content metadata related to the encrypted data is stored in the Instruction File. -# In the V3 message format, the content metadata related to the encrypted content is stored in the Object Metadata. -# -# - The V3 message format MUST store the mapkey "x-amz-c" and its value in the Object Metadata when writing with an Instruction File. -# - The V3 message format MUST NOT store the mapkey "x-amz-c" and its value in the Instruction File. -# - The V3 message format MUST store the mapkey "x-amz-d" and its value in the Object Metadata when writing with an Instruction File. -# - The V3 message format MUST NOT store the mapkey "x-amz-d" and its value in the Instruction File. -# - The V3 message format MUST store the mapkey "x-amz-i" and its value in the Object Metadata when writing with an Instruction File. -# - The V3 message format MUST NOT store the mapkey "x-amz-i" and its value in the Instruction File. -# -# - The V3 message format MUST store the mapkey "x-amz-3" and its value in the Instruction File. -# - The V3 message format MUST store the mapkey "x-amz-w" and its value in the Instruction File. -# - The V3 message format MUST store the mapkey "x-amz-m" and its value (when present in the content metadata) in the Instruction File. -# - The V3 message format MUST store the mapkey "x-amz-t" and its value (when present in the content metadata) in the Instruction File. -# -# This is done to facilitate data key re-encryption via Instruction File. - -[[spec]] -level = "MUST" -quote = ''' -- The V3 message format MUST store the mapkey "x-amz-c" and its value in the Object Metadata when writing with an Instruction File. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The V3 message format MUST NOT store the mapkey "x-amz-c" and its value in the Instruction File. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The V3 message format MUST store the mapkey "x-amz-d" and its value in the Object Metadata when writing with an Instruction File. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The V3 message format MUST NOT store the mapkey "x-amz-d" and its value in the Instruction File. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The V3 message format MUST store the mapkey "x-amz-i" and its value in the Object Metadata when writing with an Instruction File. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The V3 message format MUST NOT store the mapkey "x-amz-i" and its value in the Instruction File. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The V3 message format MUST store the mapkey "x-amz-3" and its value in the Instruction File. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The V3 message format MUST store the mapkey "x-amz-w" and its value in the Instruction File. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The V3 message format MUST store the mapkey "x-amz-m" and its value (when present in the content metadata) in the Instruction File. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The V3 message format MUST store the mapkey "x-amz-t" and its value (when present in the content metadata) in the Instruction File. -''' - diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/decryption/decrypting-with-commitment.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/decryption/decrypting-with-commitment.toml deleted file mode 100644 index 630c2aa3..00000000 --- a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/decryption/decrypting-with-commitment.toml +++ /dev/null @@ -1,33 +0,0 @@ -target = "../specification/s3-encryption/decryption.md#decrypting-with-commitment" - -# Decrypting With Commitment -# -# When using an algorithm suite which supports key commitment, the client MUST verify that the [derived key commitment](./key-derivation.md#hkdf-operation) contains the same bytes as the stored key commitment retrieved from the stored object's metadata. -# When using an algorithm suite which supports key commitment, the verification of the derived key commitment value MUST be done in constant time. -# When using an algorithm suite which supports key commitment, the client MUST throw an exception when the derived key commitment value and stored key commitment value do not match. -# When using an algorithm suite which supports key commitment, the client MUST verify the key commitment values match before deriving the [derived encryption key](./key-derivation.md#hkdf-operation). - -[[spec]] -level = "MUST" -quote = ''' -When using an algorithm suite which supports key commitment, the client MUST verify that the [derived key commitment](./key-derivation.md#hkdf-operation) contains the same bytes as the stored key commitment retrieved from the stored object's metadata. -''' - -[[spec]] -level = "MUST" -quote = ''' -When using an algorithm suite which supports key commitment, the verification of the derived key commitment value MUST be done in constant time. -''' - -[[spec]] -level = "MUST" -quote = ''' -When using an algorithm suite which supports key commitment, the client MUST throw an exception when the derived key commitment value and stored key commitment value do not match. -''' - -[[spec]] -level = "MUST" -quote = ''' -When using an algorithm suite which supports key commitment, the client MUST verify the key commitment values match before deriving the [derived encryption key](./key-derivation.md#hkdf-operation). -''' - diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/decryption/key-commitment.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/decryption/key-commitment.toml deleted file mode 100644 index db5e960f..00000000 --- a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/decryption/key-commitment.toml +++ /dev/null @@ -1,20 +0,0 @@ -target = "../specification/s3-encryption/decryption.md#key-commitment" - -# Key Commitment -# -# The S3EC supports algorithm suite(s) which provide [key commitment](./key-commitment.md). -# The S3EC MUST validate the algorithm suite used for decryption against the key commitment policy before attempting to decrypt the content ciphertext. -# If the commitment policy requires decryption using a committing algorithm suite, and the algorithm suite associated with the object does not support key commitment, then the S3EC MUST throw an exception. - -[[spec]] -level = "MUST" -quote = ''' -The S3EC MUST validate the algorithm suite used for decryption against the key commitment policy before attempting to decrypt the content ciphertext. -''' - -[[spec]] -level = "MUST" -quote = ''' -If the commitment policy requires decryption using a committing algorithm suite, and the algorithm suite associated with the object does not support key commitment, then the S3EC MUST throw an exception. -''' - diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/decryption/legacy-decryption.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/decryption/legacy-decryption.toml deleted file mode 100644 index 1db5b14d..00000000 --- a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/decryption/legacy-decryption.toml +++ /dev/null @@ -1,19 +0,0 @@ -target = "../specification/s3-encryption/decryption.md#legacy-decryption" - -# Legacy Decryption -# -# The S3EC MUST NOT decrypt objects encrypted using legacy unauthenticated algorithm suites unless specifically configured to do so. -# If the S3EC is not configured to enable legacy unauthenticated content decryption, the client MUST throw an exception when attempting to decrypt an object encrypted with a legacy unauthenticated algorithm suite. - -[[spec]] -level = "MUST" -quote = ''' -The S3EC MUST NOT decrypt objects encrypted using legacy unauthenticated algorithm suites unless specifically configured to do so. -''' - -[[spec]] -level = "MUST" -quote = ''' -If the S3EC is not configured to enable legacy unauthenticated content decryption, the client MUST throw an exception when attempting to decrypt an object encrypted with a legacy unauthenticated algorithm suite. -''' - diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/decryption/ranged-gets.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/decryption/ranged-gets.toml deleted file mode 100644 index d958e2ce..00000000 --- a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/decryption/ranged-gets.toml +++ /dev/null @@ -1,44 +0,0 @@ -target = "../specification/s3-encryption/decryption.md#ranged-gets" - -# Ranged Gets -# -# The S3EC MAY support the "range" parameter on GetObject which specifies a subset of bytes to download and decrypt. -# If the S3EC supports Ranged Gets, the S3EC MUST adjust the customer-provided range to include the beginning and end of the cipher blocks for the given range. -# TODO: Fully spec out all edge cases for Ranged Gets. -# For requests which provide a range to decrypt an object encrypted with an authenticated algorithm suite, the corresponding CTR-based algorithm suite is used. -# If the object was encrypted with ALG_AES_256_GCM_IV12_TAG16_NO_KDF, then ALG_AES_256_CTR_IV16_TAG16_NO_KDF MUST be used to decrypt the range of the object. -# If the object was encrypted with ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY, then ALG_AES_256_CTR_HKDF_SHA512_COMMIT_KEY MUST be used to decrypt the range of the object. -# -# If the GetObject response contains a range, but the GetObject request does not contain a range, the S3EC MUST throw an exception. -# This behavior indicates that this is a "multipart download" which is currently not supported. - -[[spec]] -level = "MAY" -quote = ''' -The S3EC MAY support the "range" parameter on GetObject which specifies a subset of bytes to download and decrypt. -''' - -[[spec]] -level = "MUST" -quote = ''' -If the S3EC supports Ranged Gets, the S3EC MUST adjust the customer-provided range to include the beginning and end of the cipher blocks for the given range. -''' - -[[spec]] -level = "MUST" -quote = ''' -If the object was encrypted with ALG_AES_256_GCM_IV12_TAG16_NO_KDF, then ALG_AES_256_CTR_IV16_TAG16_NO_KDF MUST be used to decrypt the range of the object. -''' - -[[spec]] -level = "MUST" -quote = ''' -If the object was encrypted with ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY, then ALG_AES_256_CTR_HKDF_SHA512_COMMIT_KEY MUST be used to decrypt the range of the object. -''' - -[[spec]] -level = "MUST" -quote = ''' -If the GetObject response contains a range, but the GetObject request does not contain a range, the S3EC MUST throw an exception. -''' - diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/alg-aes-256-ctr-hkdf-sha512-commit-key.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/alg-aes-256-ctr-hkdf-sha512-commit-key.toml deleted file mode 100644 index 7aeb5501..00000000 --- a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/alg-aes-256-ctr-hkdf-sha512-commit-key.toml +++ /dev/null @@ -1,14 +0,0 @@ -target = "../specification/s3-encryption/encryption.md#alg-aes-256-ctr-hkdf-sha512-commit-key" - -# ALG_AES_256_CTR_HKDF_SHA512_COMMIT_KEY -# -# Encryption using AES-CTR is not supported. -# This algorithm suite is only used to decrypt ranges of a ciphertext encrypted using key committing AES-GCM. -# Attempts to encrypt using key committing AES-CTR MUST fail. - -[[spec]] -level = "MUST" -quote = ''' -Attempts to encrypt using key committing AES-CTR MUST fail. -''' - diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/alg-aes-256-ctr-iv16-tag16-no-kdf.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/alg-aes-256-ctr-iv16-tag16-no-kdf.toml deleted file mode 100644 index 7cfac97f..00000000 --- a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/alg-aes-256-ctr-iv16-tag16-no-kdf.toml +++ /dev/null @@ -1,14 +0,0 @@ -target = "../specification/s3-encryption/encryption.md#alg-aes-256-ctr-iv16-tag16-no-kdf" - -# ALG_AES_256_CTR_IV16_TAG16_NO_KDF -# -# Encryption using AES-CTR is not supported. -# This algorithm suite is only used to decrypt ranges of a ciphertext encrypted using AES-GCM. -# Attempts to encrypt using AES-CTR MUST fail. - -[[spec]] -level = "MUST" -quote = ''' -Attempts to encrypt using AES-CTR MUST fail. -''' - diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/alg-aes-256-gcm-hkdf-sha512-commit-key.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/alg-aes-256-gcm-hkdf-sha512-commit-key.toml deleted file mode 100644 index d4f6f1f1..00000000 --- a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/alg-aes-256-gcm-hkdf-sha512-commit-key.toml +++ /dev/null @@ -1,27 +0,0 @@ -target = "../specification/s3-encryption/encryption.md#alg-aes-256-gcm-hkdf-sha512-commit-key" - -# ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY -# -# This algorithm suite supports Key Commitment and therefore requires deriving a key commitment value and a derived encryption key. -# The client MUST use HKDF to derive the key commitment value and the derived encrypting key as described in [Key Derivation](key-derivation.md). -# The derived key commitment value MUST be set or returned from the encryption process such that it can be included in the content metadata. -# The client MUST append the GCM auth tag to the ciphertext if the underlying crypto provider does not do so automatically. - -[[spec]] -level = "MUST" -quote = ''' -The client MUST use HKDF to derive the key commitment value and the derived encrypting key as described in [Key Derivation](key-derivation.md). -''' - -[[spec]] -level = "MUST" -quote = ''' -The derived key commitment value MUST be set or returned from the encryption process such that it can be included in the content metadata. -''' - -[[spec]] -level = "MUST" -quote = ''' -The client MUST append the GCM auth tag to the ciphertext if the underlying crypto provider does not do so automatically. -''' - diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/alg-aes-256-gcm-iv12-tag16-no-kdf.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/alg-aes-256-gcm-iv12-tag16-no-kdf.toml deleted file mode 100644 index 033137de..00000000 --- a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/alg-aes-256-gcm-iv12-tag16-no-kdf.toml +++ /dev/null @@ -1,26 +0,0 @@ -target = "../specification/s3-encryption/encryption.md#alg-aes-256-gcm-iv12-tag16-no-kdf" - -# ALG_AES_256_GCM_IV12_TAG16_NO_KDF -# -# The client MUST initialize the cipher, or call an AES-GCM encryption API, with the plaintext data key, the generated IV, and the tag length defined in the Algorithm Suite when encrypting with ALG_AES_256_GCM_IV12_TAG16_NO_KDF. -# The client MUST NOT provide any AAD when encrypting with ALG_AES_256_GCM_IV12_TAG16_NO_KDF. -# The client MUST append the GCM auth tag to the ciphertext if the underlying crypto provider does not do so automatically. - -[[spec]] -level = "MUST" -quote = ''' -The client MUST initialize the cipher, or call an AES-GCM encryption API, with the plaintext data key, the generated IV, and the tag length defined in the Algorithm Suite when encrypting with ALG_AES_256_GCM_IV12_TAG16_NO_KDF. -''' - -[[spec]] -level = "MUST" -quote = ''' -The client MUST NOT provide any AAD when encrypting with ALG_AES_256_GCM_IV12_TAG16_NO_KDF. -''' - -[[spec]] -level = "MUST" -quote = ''' -The client MUST append the GCM auth tag to the ciphertext if the underlying crypto provider does not do so automatically. -''' - diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/cipher-initialization.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/cipher-initialization.toml deleted file mode 100644 index 651b5e41..00000000 --- a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/cipher-initialization.toml +++ /dev/null @@ -1,16 +0,0 @@ -target = "../specification/s3-encryption/encryption.md#cipher-initialization" - -# Cipher Initialization -# -# The client SHOULD validate that the generated IV or Message ID is not zeros. -# There is an astoundingly small chance that an IV or Message ID is generated as all zeros. -# An IV or Message ID containing all zeros is valid, but it is more likely that the IV/Message ID was not initialized or generated correctly. -# -# The rest of the cipher initialization depends on the algorithm suite: - -[[spec]] -level = "SHOULD" -quote = ''' -The client SHOULD validate that the generated IV or Message ID is not zeros. -''' - diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/content-encryption.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/content-encryption.toml deleted file mode 100644 index 2eb6378c..00000000 --- a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/encryption/content-encryption.toml +++ /dev/null @@ -1,43 +0,0 @@ -target = "../specification/s3-encryption/encryption.md#content-encryption" - -# Content Encryption -# -# The S3EC MUST use the encryption algorithm configured during [client](./client.md) initialization. -# -# Once the requisite encryption materials have been provided, the client proceeds to encrypting the plaintext object content. -# -# The client MUST validate that the length of the plaintext bytes does not exceed the algorithm suite's cipher's maximum content length in bytes. -# -# For algorithm suites which support Key Commitment, a fixed IV is used for GCM content encryption. -# Instead of generating an IV, committing algorithm suites use a Message ID which is used as input to the HKDF. -# Otherwise, the IV and the Message ID are similar in some ways. -# For example, the Message ID, like the IV, is stored in the persisted content metadata. -# When implementing the S3EC, it is useful to generate the Message ID by the same process that generates the IV in non-committing algorithm suites. -# The client MUST generate an IV or Message ID using the length of the IV or Message ID defined in the algorithm suite. -# -# The generated IV or Message ID MUST be set or returned from the encryption process such that it can be included in the content metadata. - -[[spec]] -level = "MUST" -quote = ''' -The S3EC MUST use the encryption algorithm configured during [client](./client.md) initialization. -''' - -[[spec]] -level = "MUST" -quote = ''' -The client MUST validate that the length of the plaintext bytes does not exceed the algorithm suite's cipher's maximum content length in bytes. -''' - -[[spec]] -level = "MUST" -quote = ''' -The client MUST generate an IV or Message ID using the length of the IV or Message ID defined in the algorithm suite. -''' - -[[spec]] -level = "MUST" -quote = ''' -The generated IV or Message ID MUST be set or returned from the encryption process such that it can be included in the content metadata. -''' - diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/key-commitment/commitment-policy.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/key-commitment/commitment-policy.toml deleted file mode 100644 index 1b58a9aa..00000000 --- a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/key-commitment/commitment-policy.toml +++ /dev/null @@ -1,58 +0,0 @@ -target = "../specification/s3-encryption/key-commitment.md#commitment-policy" - -# Commitment Policy -# -# In order to provide a way to migrate from previous algorithm suites which do not support key commitment to algorithm suites which do support key commitment, the S3EC provides a configurable key commitment policy. -# The values of the policy are represented using an enum type: -# -# | S3EC Commitment Policy ENUM | -# | ------------------------------- | -# | FORBID_ENCRYPT_ALLOW_DECRYPT | -# | REQUIRE_ENCRYPT_ALLOW_DECRYPT | -# | REQUIRE_ENCRYPT_REQUIRE_DECRYPT | -# -# When the commitment policy is FORBID_ENCRYPT_ALLOW_DECRYPT, the S3EC MUST NOT encrypt using an algorithm suite which supports key commitment. -# When the commitment policy is FORBID_ENCRYPT_ALLOW_DECRYPT, the S3EC MUST allow decryption using algorithm suites which do not support key commitment. -# -# When the commitment policy is REQUIRE_ENCRYPT_ALLOW_DECRYPT, the S3EC MUST only encrypt using an algorithm suite which supports key commitment. -# When the commitment policy is REQUIRE_ENCRYPT_ALLOW_DECRYPT, the S3EC MUST allow decryption using algorithm suites which do not support key commitment. -# -# When the commitment policy is REQUIRE_ENCRYPT_REQUIRE_DECRYPT, the S3EC MUST only encrypt using an algorithm suite which supports key commitment. -# When the commitment policy is REQUIRE_ENCRYPT_REQUIRE_DECRYPT, the S3EC MUST NOT allow decryption using algorithm suites which do not support key commitment. - -[[spec]] -level = "MUST" -quote = ''' -When the commitment policy is FORBID_ENCRYPT_ALLOW_DECRYPT, the S3EC MUST NOT encrypt using an algorithm suite which supports key commitment. -''' - -[[spec]] -level = "MUST" -quote = ''' -When the commitment policy is FORBID_ENCRYPT_ALLOW_DECRYPT, the S3EC MUST allow decryption using algorithm suites which do not support key commitment. -''' - -[[spec]] -level = "MUST" -quote = ''' -When the commitment policy is REQUIRE_ENCRYPT_ALLOW_DECRYPT, the S3EC MUST only encrypt using an algorithm suite which supports key commitment. -''' - -[[spec]] -level = "MUST" -quote = ''' -When the commitment policy is REQUIRE_ENCRYPT_ALLOW_DECRYPT, the S3EC MUST allow decryption using algorithm suites which do not support key commitment. -''' - -[[spec]] -level = "MUST" -quote = ''' -When the commitment policy is REQUIRE_ENCRYPT_REQUIRE_DECRYPT, the S3EC MUST only encrypt using an algorithm suite which supports key commitment. -''' - -[[spec]] -level = "MUST" -quote = ''' -When the commitment policy is REQUIRE_ENCRYPT_REQUIRE_DECRYPT, the S3EC MUST NOT allow decryption using algorithm suites which do not support key commitment. -''' - diff --git a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/key-derivation/hkdf-operation.toml b/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/key-derivation/hkdf-operation.toml deleted file mode 100644 index be23a6ce..00000000 --- a/test-server/net-v4-server/.duvet/requirements/specification/s3-encryption/key-derivation/hkdf-operation.toml +++ /dev/null @@ -1,106 +0,0 @@ -target = "../specification/s3-encryption/key-derivation.md#hkdf-operation" - -# HKDF Operation -# -# When the algorithm suite is key committing, the S3EC uses HKDF with the following specifics using the generated IV as the Message ID: -# -# For the extract step: -# -# - The hash function MUST be specified by the algorithm suite commitment settings. -# - The input keying material MUST be the plaintext data key (PDK) generated by the key provider. -# - The length of the input keying material MUST equal the key derivation input length specified by the algorithm suite commit key derivation setting. -# - The salt MUST be the Message ID with the length defined in the algorithm suite. -# -# For the expand step: -# -# - For the Derived Encryption Key: -# - The DEK input pseudorandom key MUST be the output from the extract step. -# - The length of the output keying material MUST equal the encryption key length specified by the algorithm suite encryption settings. -# - The input info MUST be a concatenation of the algorithm suite ID as bytes followed by the string DERIVEKEY as UTF8 encoded bytes. -# - For the Commit Key: -# - The CK input pseudorandom key MUST be the output from the extract step. -# - The length of the output keying material MUST equal the commit key length specified by the supported algorithm suites. -# - The input info MUST be a concatenation of the algorithm suite ID as bytes followed by the string COMMITKEY as UTF8 encoded bytes. -# -# When encrypting or decrypting with ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY, the IV used in the AES-GCM content encryption/decryption MUST contain only zeros of the length defined in the algorithm suite. -# The client MUST initialize the cipher, or call an AES-GCM encryption API, with the derived encryption key, an IV containing only zeros, and the tag length defined in the Algorithm Suite when encrypting or decrypting with ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY. -# The client MUST set the AAD to the Algorithm Suite ID represented as bytes. - -[[spec]] -level = "MUST" -quote = ''' -- The hash function MUST be specified by the algorithm suite commitment settings. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The input keying material MUST be the plaintext data key (PDK) generated by the key provider. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The length of the input keying material MUST equal the key derivation input length specified by the algorithm suite commit key derivation setting. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The salt MUST be the Message ID with the length defined in the algorithm suite. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The DEK input pseudorandom key MUST be the output from the extract step. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The length of the output keying material MUST equal the encryption key length specified by the algorithm suite encryption settings. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The input info MUST be a concatenation of the algorithm suite ID as bytes followed by the string DERIVEKEY as UTF8 encoded bytes. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The CK input pseudorandom key MUST be the output from the extract step. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The length of the output keying material MUST equal the commit key length specified by the supported algorithm suites. -''' - -[[spec]] -level = "MUST" -quote = ''' -- The input info MUST be a concatenation of the algorithm suite ID as bytes followed by the string COMMITKEY as UTF8 encoded bytes. -''' - -[[spec]] -level = "MUST" -quote = ''' -When encrypting or decrypting with ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY, the IV used in the AES-GCM content encryption/decryption MUST contain only zeros of the length defined in the algorithm suite. -''' - -[[spec]] -level = "MUST" -quote = ''' -The client MUST initialize the cipher, or call an AES-GCM encryption API, with the derived encryption key, an IV containing only zeros, and the tag length defined in the Algorithm Suite when encrypting or decrypting with ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY. -''' - -[[spec]] -level = "MUST" -quote = ''' -The client MUST set the AAD to the Algorithm Suite ID represented as bytes. -''' - From 1894b9140cfab433e7b6a325e039f92d9dec7f55 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Thu, 6 Nov 2025 22:25:15 -0800 Subject: [PATCH 22/28] auto commit --- .../src/it/java/software/amazon/encryption/s3/TestUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-server/java-tests/src/it/java/software/amazon/encryption/s3/TestUtils.java b/test-server/java-tests/src/it/java/software/amazon/encryption/s3/TestUtils.java index 46604f2a..bc741ae2 100644 --- a/test-server/java-tests/src/it/java/software/amazon/encryption/s3/TestUtils.java +++ b/test-server/java-tests/src/it/java/software/amazon/encryption/s3/TestUtils.java @@ -99,7 +99,7 @@ public class TestUtils { // .NET only supports decrypting instruction files using AES and RSA. // Python MUST support decrypting KMS instruction files, but does not yet. public static final Set KMS_INSTRUCTION_FILE_UNSUPPORTED = - Set.of(NET_V2_CURRENT, NET_V2_TRANSITION, NET_V3); + Set.of(NET_V2_CURRENT, NET_V3_CURRENT, NET_V2_TRANSITION, NET_V4); // Go does not write with instruction files public static final Set INSTRUCTION_FILE_PUT_UNSUPPORTED = From 4eb4396a7105afd24b754916bb39547d31260085 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Fri, 7 Nov 2025 10:45:17 -0800 Subject: [PATCH 23/28] bump --- test-server/net-v4-server/s3ec-net-v4-improved | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-server/net-v4-server/s3ec-net-v4-improved b/test-server/net-v4-server/s3ec-net-v4-improved index dbb3efe0..ebbc5d84 160000 --- a/test-server/net-v4-server/s3ec-net-v4-improved +++ b/test-server/net-v4-server/s3ec-net-v4-improved @@ -1 +1 @@ -Subproject commit dbb3efe0c2947c6f122c516b9ac2891f6cf905e3 +Subproject commit ebbc5d849371fe5d7f5f2dfc2d8f772458f7fcd8 From aa38086a9eb31488ba110f1bfb6b3d07f34f5d7d Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Fri, 7 Nov 2025 11:58:26 -0800 Subject: [PATCH 24/28] auto commit --- .../src/it/java/software/amazon/encryption/s3/TestUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-server/java-tests/src/it/java/software/amazon/encryption/s3/TestUtils.java b/test-server/java-tests/src/it/java/software/amazon/encryption/s3/TestUtils.java index d4a5c017..0d9599ec 100644 --- a/test-server/java-tests/src/it/java/software/amazon/encryption/s3/TestUtils.java +++ b/test-server/java-tests/src/it/java/software/amazon/encryption/s3/TestUtils.java @@ -99,7 +99,7 @@ public class TestUtils { // .NET only supports decrypting instruction files using AES and RSA. // Python MUST support decrypting KMS instruction files, but does not yet. public static final Set KMS_INSTRUCTION_FILE_UNSUPPORTED = - Set.of(NET_V2_CURRENT, NET_V3_CURRENT, NET_V2_TRANSITION, NET_V4); + Set.of(NET_V2_CURRENT, NET_V2_TRANSITION, NET_V3_CURRENT, NET_V3_TRANSITION, NET_V4); // Go does not write with instruction files public static final Set INSTRUCTION_FILE_PUT_UNSUPPORTED = From 7fa3b45c5ae2d2aff5dc1c881b994628b5bec9fa Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Fri, 7 Nov 2025 11:59:51 -0800 Subject: [PATCH 25/28] merge --- .gitmodules | 3 --- 1 file changed, 3 deletions(-) diff --git a/.gitmodules b/.gitmodules index 8a2d329f..7549d3a2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -39,14 +39,11 @@ 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 -<<<<<<< HEAD [submodule "test-server/net-v4-server/s3ec-net-v4-improved"] path = test-server/net-v4-server/s3ec-net-v4-improved url = https://github.com/aws/private-amazon-s3-encryption-client-dotnet-staging.git branch = s3ec-v4-WIP -======= [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 branch = rishav/key-commitment ->>>>>>> fireegg-test-servers From 2aeceddf3055bd8eda4b13ecb982c49642844879 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Mon, 10 Nov 2025 11:10:04 -0800 Subject: [PATCH 26/28] Add JsonStringEnumConverter --- test-server/net-v4-server/Models/ClientRequest.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/test-server/net-v4-server/Models/ClientRequest.cs b/test-server/net-v4-server/Models/ClientRequest.cs index 9c4ad725..52dd0317 100644 --- a/test-server/net-v4-server/Models/ClientRequest.cs +++ b/test-server/net-v4-server/Models/ClientRequest.cs @@ -40,6 +40,7 @@ public enum CommitmentPolicy FORBID_ENCRYPT_ALLOW_DECRYPT } +[JsonConverter(typeof(JsonStringEnumConverter))] public enum EncryptionAlgorithm { ALG_AES_256_CBC_IV16_NO_KDF, From a4864bbb88aed3a883e35c2a7e14b301214a1778 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Mon, 10 Nov 2025 11:50:21 -0800 Subject: [PATCH 27/28] auto commit --- test-server/net-v4-server/Controllers/ClientController.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test-server/net-v4-server/Controllers/ClientController.cs b/test-server/net-v4-server/Controllers/ClientController.cs index 91fcc055..c4d6c1d0 100644 --- a/test-server/net-v4-server/Controllers/ClientController.cs +++ b/test-server/net-v4-server/Controllers/ClientController.cs @@ -49,9 +49,7 @@ public IActionResult CreateClient([FromBody] ClientRequest request) var enableLegacyMode = enableLegacyUnauthenticatedModes || enableLegacyWrappingAlgorithms; var securityProfile = enableLegacyMode ? SecurityProfile.V4AndLegacy : SecurityProfile.V4; - // Currently, tests does not send EncryptionAlgorithm - // var encryptionAlgorithm = MapEncryptionAlgorithm(request.Config.EncryptionAlgorithm); - var encryptionAlgorithm = commitmentPolicy == Amazon.Extensions.S3.Encryption.CommitmentPolicy.ForbidEncryptAllowDecrypt ? ContentEncryptionAlgorithm.AesGcm : ContentEncryptionAlgorithm.AesGcmWithCommitment; + var encryptionAlgorithm = MapEncryptionAlgorithm(request.Config.EncryptionAlgorithm); if (!useDefaultConf) { From c35f9782f24262dd783e7e9de950f170f403f359 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Mon, 10 Nov 2025 14:09:52 -0800 Subject: [PATCH 28/28] auto commit --- test-server/net-v4-server/Controllers/ClientController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-server/net-v4-server/Controllers/ClientController.cs b/test-server/net-v4-server/Controllers/ClientController.cs index c4d6c1d0..9e9ae66e 100644 --- a/test-server/net-v4-server/Controllers/ClientController.cs +++ b/test-server/net-v4-server/Controllers/ClientController.cs @@ -107,7 +107,7 @@ private static ContentEncryptionAlgorithm MapEncryptionAlgorithm(Models.Encrypti { Models.EncryptionAlgorithm.ALG_AES_256_GCM_IV12_TAG16_NO_KDF => ContentEncryptionAlgorithm.AesGcm, Models.EncryptionAlgorithm.ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY => ContentEncryptionAlgorithm.AesGcmWithCommitment, - _ => ContentEncryptionAlgorithm.AesGcm + _ => ContentEncryptionAlgorithm.AesGcmWithCommitment }; } } \ No newline at end of file