Initial version
This commit is contained in:
commit
e5b6226a85
68 changed files with 7338 additions and 0 deletions
53
DataTransfer.Client/Services/HandshakeCodec.cs
Normal file
53
DataTransfer.Client/Services/HandshakeCodec.cs
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
namespace DataTransfer.Client.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Plaintext messages of the commit-then-reveal key exchange (see <see cref="SecureChannel" />). They are relayed
|
||||
/// like frames, but before the channel is encrypted. Layout: version (byte) | type (byte) | payload.
|
||||
/// </summary>
|
||||
internal static class HandshakeCodec
|
||||
{
|
||||
public const int CommitmentBytes = 32;
|
||||
|
||||
// A P-256 SPKI key has 91 bytes; anything much larger is not a key.
|
||||
private const int MaxPublicKeyBytes = 512;
|
||||
private const byte Version = 1;
|
||||
|
||||
private enum MessageType : byte
|
||||
{
|
||||
Commitment = 1,
|
||||
PublicKey = 2
|
||||
}
|
||||
|
||||
public static byte[] EncodeCommitment(byte[] commitment) => Encode(MessageType.Commitment, commitment);
|
||||
|
||||
public static byte[] EncodePublicKey(byte[] publicKey) => Encode(MessageType.PublicKey, publicKey);
|
||||
|
||||
/// <exception cref="InvalidDataException">The message is not a commitment.</exception>
|
||||
public static byte[] DecodeCommitment(byte[] message) =>
|
||||
Decode(message, MessageType.Commitment, CommitmentBytes, CommitmentBytes);
|
||||
|
||||
/// <exception cref="InvalidDataException">The message is not a public key.</exception>
|
||||
public static byte[] DecodePublicKey(byte[] message) => Decode(message, MessageType.PublicKey, 1, MaxPublicKeyBytes);
|
||||
|
||||
private static byte[] Encode(MessageType type, byte[] payload)
|
||||
{
|
||||
var message = new byte[payload.Length + 2];
|
||||
message[0] = Version;
|
||||
message[1] = (byte)type;
|
||||
payload.CopyTo(message, 2);
|
||||
return message;
|
||||
}
|
||||
|
||||
private static byte[] Decode(byte[] message, MessageType type, int minPayloadBytes, int maxPayloadBytes)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(message);
|
||||
|
||||
var payloadBytes = message.Length - 2;
|
||||
if (payloadBytes < minPayloadBytes || payloadBytes > maxPayloadBytes || message[0] != Version || message[1] != (byte)type)
|
||||
{
|
||||
throw new InvalidDataException($"Expected a valid key-exchange message of type {type}.");
|
||||
}
|
||||
|
||||
return message[2..];
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue