up
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
using System.Net.Http.Json;
|
||||
|
||||
namespace StellaOps.Cryptography.Plugin.SmRemote;
|
||||
|
||||
public sealed class SmRemoteHttpClient
|
||||
{
|
||||
private readonly HttpClient client;
|
||||
|
||||
public SmRemoteHttpClient(HttpClient client)
|
||||
{
|
||||
this.client = client ?? throw new ArgumentNullException(nameof(client));
|
||||
}
|
||||
|
||||
public async Task<SmRemoteStatus> GetStatusAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
var response = await client.GetAsync("/status", cancellationToken).ConfigureAwait(false);
|
||||
response.EnsureSuccessStatusCode();
|
||||
var status = await response.Content.ReadFromJsonAsync<SmRemoteStatus>(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
return status ?? new SmRemoteStatus { IsAvailable = false, Error = "empty response" };
|
||||
}
|
||||
|
||||
public async Task<string> SignAsync(string keyId, string algorithmId, byte[] pae, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var request = new SmRemoteSignRequest
|
||||
{
|
||||
KeyId = keyId,
|
||||
AlgorithmId = algorithmId,
|
||||
PayloadBase64 = Convert.ToBase64String(pae)
|
||||
};
|
||||
|
||||
var response = await client.PostAsJsonAsync("/sign", request, cancellationToken).ConfigureAwait(false);
|
||||
response.EnsureSuccessStatusCode();
|
||||
var envelope = await response.Content.ReadFromJsonAsync<SmRemoteSignResponse>(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
if (envelope is null || string.IsNullOrWhiteSpace(envelope.Signature))
|
||||
{
|
||||
throw new InvalidOperationException("SM remote sign response was empty.");
|
||||
}
|
||||
|
||||
return envelope.Signature;
|
||||
}
|
||||
|
||||
public async Task<bool> VerifyAsync(string keyId, string algorithmId, byte[] pae, string signatureBase64, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var request = new SmRemoteVerifyRequest
|
||||
{
|
||||
KeyId = keyId,
|
||||
AlgorithmId = algorithmId,
|
||||
PayloadBase64 = Convert.ToBase64String(pae),
|
||||
Signature = signatureBase64
|
||||
};
|
||||
|
||||
var response = await client.PostAsJsonAsync("/verify", request, cancellationToken).ConfigureAwait(false);
|
||||
response.EnsureSuccessStatusCode();
|
||||
var result = await response.Content.ReadFromJsonAsync<SmRemoteVerifyResponse>(cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
return result?.Valid == true;
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class SmRemoteSignRequest
|
||||
{
|
||||
public string KeyId { get; set; } = string.Empty;
|
||||
public string AlgorithmId { get; set; } = string.Empty;
|
||||
public string PayloadBase64 { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public sealed class SmRemoteSignResponse
|
||||
{
|
||||
public string Signature { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public sealed class SmRemoteVerifyRequest
|
||||
{
|
||||
public string KeyId { get; set; } = string.Empty;
|
||||
public string AlgorithmId { get; set; } = string.Empty;
|
||||
public string PayloadBase64 { get; set; } = string.Empty;
|
||||
public string Signature { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public sealed class SmRemoteVerifyResponse
|
||||
{
|
||||
public bool Valid { get; set; }
|
||||
}
|
||||
|
||||
public sealed class SmRemoteStatus
|
||||
{
|
||||
public bool IsAvailable { get; set; }
|
||||
public string? ProviderName { get; set; }
|
||||
public string[] SupportedAlgorithms { get; set; } = Array.Empty<string>();
|
||||
public string? Error { get; set; }
|
||||
}
|
||||
Reference in New Issue
Block a user