You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

118 lines
3.8 KiB

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
namespace EncryptedNetwork
{
public unsafe struct RSAPublicKey
{
public const int ModulusSize = 128;
public const int ExponentSize = 3;
internal fixed byte mod[ModulusSize];
internal fixed byte exp[ExponentSize];
/// <summary>
/// The modulus of this key
/// </summary>
public byte[] Modulus
{
get
{
byte[] bytes = new byte[ModulusSize];
fixed (byte* m = mod)
{
Marshal.Copy((IntPtr)m, bytes, 0, ModulusSize);
}
return bytes;
}
set
{
if (value.Length != ModulusSize) throw new ArgumentException(nameof(value) + " must be exaclty " + ModulusSize + " bytes (not " + value.Length + ")");
fixed (byte* m = mod)
{
Marshal.Copy(value, 0, (IntPtr)m, ModulusSize);
}
}
}
/// <summary>
/// The public exponent of this key
/// </summary>
public byte[] Exponent
{
get
{
byte[] bytes = new byte[ExponentSize];
fixed (byte* m = exp)
{
Marshal.Copy((IntPtr)m, bytes, 0, ExponentSize);
}
return bytes;
}
set
{
if (value.Length != ExponentSize) throw new ArgumentException(nameof(value) + " must be exaclty " + ExponentSize + " bytes (not " + value.Length + ")");
fixed (byte* m = exp)
{
Marshal.Copy(value, 0, (IntPtr)m, ExponentSize);
}
}
}
/// <summary>
/// Binary serialisation of this key
/// </summary>
public byte[] BinaryData
{
get
{
return this.ToByteArrayUnmanaged();
}
set
{
if (value.Length < sizeof(RSAPublicKey)) throw new ArgumentException(nameof(value) + " must be at least " + sizeof(RSAPublicKey) + " bytes (not " + value.Length + ")");
fixed (RSAPublicKey* k = &this)
{
Marshal.Copy(value, 0, (IntPtr)k, sizeof(RSAPublicKey));
}
}
}
/// <summary>
/// Set the public key to a RSACryptoServiceProvider
/// </summary>
/// <param name="csp">The CSP to set the key to</param>
public void ToCSP(RSACryptoServiceProvider csp)
{
var p = csp.ExportParameters(false);
p.Modulus = Modulus;
p.Exponent = Exponent;
csp.ImportParameters(p);
}
/// <summary>
/// Get the public key information from an RSACryptoServiceProvider and return it in an RSAPublicKey struct
/// </summary>
/// <param name="csp">The CSP</param>
/// <returns>A new RSAPublicKey struct</returns>
public static RSAPublicKey FromCSP(RSACryptoServiceProvider csp)
{
RSAPublicKey rp = new RSAPublicKey();
var p = csp.ExportParameters(false);
rp.Modulus = p.Modulus;
rp.Exponent = p.Exponent;
return rp;
}
public static implicit operator byte[](RSAPublicKey rp)
{
return rp.ToByteArrayUnmanaged();
}
public static explicit operator RSAPublicKey(byte[] byt)
{
return byt.ToStructureUnmanaged<RSAPublicKey>();
}
}
}