Add support for ГОСТ Р 34.10 digital signatures
- Implemented the GostKeyValue class for handling public key parameters in ГОСТ Р 34.10 digital signatures. - Created the GostSignedXml class to manage XML signatures using ГОСТ 34.10, including methods for computing and checking signatures. - Developed the GostSignedXmlImpl class to encapsulate the signature computation logic and public key retrieval. - Added specific key value classes for ГОСТ Р 34.10-2001, ГОСТ Р 34.10-2012/256, and ГОСТ Р 34.10-2012/512 to support different signature algorithms. - Ensured compatibility with existing XML signature standards while integrating ГОСТ cryptography.
This commit is contained in:
@@ -354,6 +354,111 @@ public class StellaOpsScopeAuthorizationHandlerTests
|
||||
Assert.Equal("INC-741", GetPropertyValue(record, "backfill.ticket"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task HandleRequirement_Fails_WhenPackApprovalMetadataMissing()
|
||||
{
|
||||
var optionsMonitor = CreateOptionsMonitor(options =>
|
||||
{
|
||||
options.Authority = "https://authority.example";
|
||||
options.RequiredTenants.Add("tenant-alpha");
|
||||
options.Validate();
|
||||
});
|
||||
|
||||
var (handler, accessor, sink) = CreateHandler(optionsMonitor, IPAddress.Parse("203.0.113.10"));
|
||||
var requirement = new StellaOpsScopeRequirement(new[] { StellaOpsScopes.PacksApprove });
|
||||
var now = DateTimeOffset.Parse("2025-11-09T12:00:00Z", CultureInfo.InvariantCulture);
|
||||
var principal = new StellaOpsPrincipalBuilder()
|
||||
.WithSubject("approver")
|
||||
.WithTenant("tenant-alpha")
|
||||
.WithScopes(new[] { StellaOpsScopes.PacksApprove })
|
||||
.AddClaim(OpenIddictConstants.Claims.AuthenticationTime, now.ToUnixTimeSeconds().ToString(CultureInfo.InvariantCulture))
|
||||
.Build();
|
||||
|
||||
var context = new AuthorizationHandlerContext(new[] { requirement }, principal, accessor.HttpContext);
|
||||
|
||||
await handler.HandleAsync(context);
|
||||
|
||||
Assert.False(context.HasSucceeded);
|
||||
var record = Assert.Single(sink.Records);
|
||||
Assert.Equal("packs.approve tokens require pack_run_id claim.", record.Reason);
|
||||
Assert.Equal("false", GetPropertyValue(record, "pack.approval_metadata_satisfied"));
|
||||
Assert.Equal(StellaOpsScopes.PacksApprove, Assert.Single(record.Scopes));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task HandleRequirement_Fails_WhenPackApprovalFreshAuthStale()
|
||||
{
|
||||
var optionsMonitor = CreateOptionsMonitor(options =>
|
||||
{
|
||||
options.Authority = "https://authority.example";
|
||||
options.RequiredTenants.Add("tenant-alpha");
|
||||
options.Validate();
|
||||
});
|
||||
|
||||
var fakeTime = new FakeTimeProvider(DateTimeOffset.Parse("2025-11-09T14:00:00Z", CultureInfo.InvariantCulture));
|
||||
var (handler, accessor, sink) = CreateHandler(optionsMonitor, IPAddress.Parse("203.0.113.11"), fakeTime);
|
||||
var requirement = new StellaOpsScopeRequirement(new[] { StellaOpsScopes.PacksApprove });
|
||||
var staleAuthTime = fakeTime.GetUtcNow().AddMinutes(-10);
|
||||
var principal = new StellaOpsPrincipalBuilder()
|
||||
.WithSubject("approver")
|
||||
.WithTenant("tenant-alpha")
|
||||
.WithScopes(new[] { StellaOpsScopes.PacksApprove })
|
||||
.AddClaim(StellaOpsClaimTypes.PackRunId, "run-123")
|
||||
.AddClaim(StellaOpsClaimTypes.PackGateId, "security-review")
|
||||
.AddClaim(StellaOpsClaimTypes.PackPlanHash, new string(a, 64))
|
||||
.AddClaim(OpenIddictConstants.Claims.AuthenticationTime, staleAuthTime.ToUnixTimeSeconds().ToString(CultureInfo.InvariantCulture))
|
||||
.Build();
|
||||
|
||||
var context = new AuthorizationHandlerContext(new[] { requirement }, principal, accessor.HttpContext);
|
||||
|
||||
await handler.HandleAsync(context);
|
||||
|
||||
Assert.False(context.HasSucceeded);
|
||||
var record = Assert.Single(sink.Records);
|
||||
Assert.Equal("packs.approve tokens require fresh authentication.", record.Reason);
|
||||
Assert.Equal("false", GetPropertyValue(record, "pack.fresh_auth_satisfied"));
|
||||
Assert.Equal("true", GetPropertyValue(record, "pack.approval_metadata_satisfied"));
|
||||
Assert.Equal(StellaOpsScopes.PacksApprove, Assert.Single(record.Scopes));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task HandleRequirement_Succeeds_WhenPackApprovalMetadataPresent()
|
||||
{
|
||||
var optionsMonitor = CreateOptionsMonitor(options =>
|
||||
{
|
||||
options.Authority = "https://authority.example";
|
||||
options.RequiredTenants.Add("tenant-alpha");
|
||||
options.Validate();
|
||||
});
|
||||
|
||||
var fakeTime = new FakeTimeProvider(DateTimeOffset.Parse("2025-11-09T14:30:00Z", CultureInfo.InvariantCulture));
|
||||
var (handler, accessor, sink) = CreateHandler(optionsMonitor, IPAddress.Parse("203.0.113.12"), fakeTime);
|
||||
var requirement = new StellaOpsScopeRequirement(new[] { StellaOpsScopes.PacksApprove });
|
||||
var freshAuthTime = fakeTime.GetUtcNow().AddMinutes(-2);
|
||||
var principal = new StellaOpsPrincipalBuilder()
|
||||
.WithSubject("approver")
|
||||
.WithTenant("tenant-alpha")
|
||||
.WithScopes(new[] { StellaOpsScopes.PacksApprove })
|
||||
.AddClaim(StellaOpsClaimTypes.PackRunId, "run-456")
|
||||
.AddClaim(StellaOpsClaimTypes.PackGateId, "security-review")
|
||||
.AddClaim(StellaOpsClaimTypes.PackPlanHash, new string(b, 64))
|
||||
.AddClaim(OpenIddictConstants.Claims.AuthenticationTime, freshAuthTime.ToUnixTimeSeconds().ToString(CultureInfo.InvariantCulture))
|
||||
.Build();
|
||||
|
||||
var context = new AuthorizationHandlerContext(new[] { requirement }, principal, accessor.HttpContext);
|
||||
|
||||
await handler.HandleAsync(context);
|
||||
|
||||
Assert.True(context.HasSucceeded);
|
||||
var record = Assert.Single(sink.Records);
|
||||
Assert.Equal(AuthEventOutcome.Success, record.Outcome);
|
||||
Assert.Equal("true", GetPropertyValue(record, "pack.approval_metadata_satisfied"));
|
||||
Assert.Equal("true", GetPropertyValue(record, "pack.fresh_auth_satisfied"));
|
||||
Assert.Equal("run-456", GetPropertyValue(record, "pack.run_id"));
|
||||
Assert.Equal("security-review", GetPropertyValue(record, "pack.gate_id"));
|
||||
Assert.Equal(new string(b, 64), GetPropertyValue(record, "pack.plan_hash"));
|
||||
}
|
||||
|
||||
private static (StellaOpsScopeAuthorizationHandler Handler, IHttpContextAccessor Accessor, RecordingAuthEventSink Sink) CreateHandler(IOptionsMonitor<StellaOpsResourceServerOptions> optionsMonitor, IPAddress remoteAddress, TimeProvider? timeProvider = null)
|
||||
{
|
||||
var accessor = new HttpContextAccessor();
|
||||
|
||||
Reference in New Issue
Block a user