initial commit
This commit is contained in:
Vendored
BIN
Binary file not shown.
@@ -0,0 +1,10 @@
|
||||
using Pulsar.Common.Messages.Other;
|
||||
|
||||
namespace Pulsar.Common.Networking
|
||||
{
|
||||
public interface ISender
|
||||
{
|
||||
void Send<T>(T message) where T : IMessage;
|
||||
void Disconnect();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
using Pulsar.Common.Cryptography;
|
||||
using Pulsar.Common.Messages.Other;
|
||||
using System;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
|
||||
namespace Pulsar.Common.Networking
|
||||
{
|
||||
public static class SecureMessageEnvelopeHelper
|
||||
{
|
||||
public static bool CanUse(X509Certificate2 certificate)
|
||||
{
|
||||
return certificate != null && certificate.RawData != null && certificate.RawData.Length > 0;
|
||||
}
|
||||
|
||||
public static SecureMessageEnvelope Wrap(IMessage message, X509Certificate2 certificate)
|
||||
{
|
||||
if (message == null)
|
||||
throw new ArgumentNullException(nameof(message));
|
||||
|
||||
if (message is SecureMessageEnvelope)
|
||||
throw new InvalidOperationException("Message is already wrapped in a secure envelope.");
|
||||
|
||||
if (!CanUse(certificate))
|
||||
throw new ArgumentException("A valid certificate is required to wrap the message.", nameof(certificate));
|
||||
|
||||
var serialized = PulsarMessagePackSerializer.Serialize(message);
|
||||
var keyMaterial = DeriveKeyMaterial(certificate);
|
||||
|
||||
var cipher = new Aes256(keyMaterial);
|
||||
var payload = cipher.Encrypt(serialized);
|
||||
|
||||
return new SecureMessageEnvelope
|
||||
{
|
||||
Payload = payload
|
||||
};
|
||||
}
|
||||
|
||||
public static IMessage Unwrap(SecureMessageEnvelope envelope, X509Certificate2 certificate)
|
||||
{
|
||||
if (envelope == null)
|
||||
throw new ArgumentNullException(nameof(envelope));
|
||||
|
||||
if (envelope.Payload == null || envelope.Payload.Length == 0)
|
||||
throw new ArgumentException("Envelope payload is empty.", nameof(envelope));
|
||||
|
||||
if (!CanUse(certificate))
|
||||
throw new ArgumentException("A valid certificate is required to unwrap the message.", nameof(certificate));
|
||||
|
||||
var keyMaterial = DeriveKeyMaterial(certificate);
|
||||
|
||||
var cipher = new Aes256(keyMaterial);
|
||||
var decrypted = cipher.Decrypt(envelope.Payload);
|
||||
try
|
||||
{
|
||||
return PulsarMessagePackSerializer.Deserialize(decrypted);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new InvalidOperationException($"Failed to deserialize secure payload (length={decrypted?.Length ?? 0}).", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static string DeriveKeyMaterial(X509Certificate2 certificate)
|
||||
{
|
||||
var thumbprint = certificate.Thumbprint?.Replace(" ", string.Empty)?.ToUpperInvariant();
|
||||
if (string.IsNullOrEmpty(thumbprint))
|
||||
throw new InvalidOperationException("Certificate thumbprint is unavailable for secure envelope key derivation.");
|
||||
|
||||
var hash = Sha256.ComputeHash(Encoding.UTF8.GetBytes(thumbprint));
|
||||
return Convert.ToBase64String(hash);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user