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]; /// /// The modulus of this key /// 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); } } } /// /// The public exponent of this key /// 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); } } } /// /// Binary serialisation of this key /// 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)); } } } /// /// Set the public key to a RSACryptoServiceProvider /// /// The CSP to set the key to public void ToCSP(RSACryptoServiceProvider csp) { var p = csp.ExportParameters(false); p.Modulus = Modulus; p.Exponent = Exponent; csp.ImportParameters(p); } /// /// Get the public key information from an RSACryptoServiceProvider and return it in an RSAPublicKey struct /// /// The CSP /// A new RSAPublicKey struct 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(); } } }