private void Dispose(bool Disposing) { if (!m_isDisposed && Disposing) { try { if (m_asmParameters != null) { m_asmParameters.Dispose(); m_asmParameters = null; } if (m_publicKey != null) { m_publicKey.Dispose(); m_publicKey = null; } if (m_privateKey != null) { m_privateKey.Dispose(); m_privateKey = null; } if (m_idTag != null) { Array.Clear(m_idTag, 0, m_idTag.Length); m_idTag = null; } } finally { m_isDisposed = true; } } }
/// <summary> /// Initialize this class /// </summary> /// /// <param name="Parameters">The cipher Parameters</param> /// <param name="KeyPair">The public or private key</param> /// <param name="Tag">An identity field</param> /// /// <exception cref="CryptoAsymmetricException">Thrown if an invalid key is used</exception> public AsymmetricContainer(IAsymmetricParameters Parameters, IAsymmetricKeyPair KeyPair, byte[] Tag = null) { if (!(KeyPair is IAsymmetricKeyPair)) throw new CryptoAsymmetricException("KeyContainer:Ctor", "Not a valid key-pair!", new InvalidDataException()); _publicKey = KeyPair.PublicKey; _privateKey = KeyPair.PrivateKey; _asmParameters = Parameters; _idTag = Tag; }
/// <summary> /// Initialize this class /// </summary> /// /// <param name="Parameters">The cipher Parameters</param> /// <param name="AsmKey">The Public or Private asymmetric key</param> /// <param name="Tag">An identity field</param> /// /// <exception cref="CryptoAsymmetricException">Thrown if an invalid key is used</exception> public AsymmetricContainer(IAsymmetricParameters Parameters, IAsymmetricKey AsmKey, byte[] Tag = null) { _asmParameters = Parameters; _idTag = Tag; if (AsymmetricUtils.IsPublicKey(AsmKey)) _publicKey = AsmKey; else _privateKey = AsmKey; }
/// <summary> /// Initialize this class /// </summary> /// /// <param name="Parameters">The cipher Parameters</param> /// <param name="KeyPair">The public or private key</param> /// <param name="Tag">An identity field</param> /// /// <exception cref="CryptoAsymmetricException">Thrown if an invalid key is used</exception> public AsymmetricContainer(IAsymmetricParameters Parameters, IAsymmetricKeyPair KeyPair, byte[] Tag = null) { if (!(KeyPair is IAsymmetricKeyPair)) { throw new CryptoAsymmetricException("KeyContainer:Ctor", "Not a valid key-pair!", new InvalidDataException()); } m_publicKey = KeyPair.PublicKey; m_privateKey = KeyPair.PrivateKey; m_asmParameters = Parameters; m_idTag = Tag; }
/// <summary> /// Returns the asymmetric parameters family type /// </summary> /// /// <param name="Parameters">An asymmetric ciphers Parameters</param> /// /// <returns>The asymmetric family designator</returns> public static AsymmetricEngines GetParametersType(IAsymmetricParameters Parameters) { if (Parameters.GetType().Equals(typeof(NTRUParameters))) return AsymmetricEngines.NTRU; else if (Parameters.GetType().Equals(typeof(MPKCParameters))) return AsymmetricEngines.McEliece; else if (Parameters.GetType().Equals(typeof(RLWEParameters))) return AsymmetricEngines.RingLWE; else if (Parameters.GetType().Equals(typeof(RNBWParameters))) return AsymmetricEngines.Rainbow; else return AsymmetricEngines.GMSS; }
/// <summary> /// Initialize this class /// </summary> /// /// <param name="Parameters">The cipher Parameters</param> /// <param name="AsmKey">The Public or Private asymmetric key</param> /// <param name="Tag">An identity field</param> /// /// <exception cref="CryptoAsymmetricException">Thrown if an invalid key is used</exception> public AsymmetricContainer(IAsymmetricParameters Parameters, IAsymmetricKey AsmKey, byte[] Tag = null) { m_asmParameters = Parameters; m_idTag = Tag; if (AsymmetricUtils.IsPublicKey(AsmKey)) { m_publicKey = AsmKey; } else { m_privateKey = AsmKey; } }
/// <summary> /// Reads the key container from an input stream /// </summary> /// /// <param name="KeyStream">An input stream containing an encoded key container</param> public AsymmetricContainer(MemoryStream KeyStream) { BinaryReader reader = new BinaryReader(KeyStream); byte[] data; int len; m_idTag = null; m_publicKey = null; m_publicKey = null; // tag len = reader.ReadInt32(); if (len > 0) { m_idTag = reader.ReadBytes(len); } // family m_asmEngine = (AsymmetricEngines)reader.ReadByte(); // parameters len = reader.ReadInt32(); data = reader.ReadBytes(len); m_asmParameters = ParamsFromBytes(data); // public key len = reader.ReadInt32(); if (len > 0) { data = reader.ReadBytes(len); m_publicKey = PublicKeyFromBytes(data); } // private key len = reader.ReadInt32(); if (len > 0) { data = reader.ReadBytes(len); m_privateKey = PrivateKeyFromBytes(data); } }
/// <summary> /// Returns the asymmetric parameters family type /// </summary> /// /// <param name="Parameters">An asymmetric ciphers Parameters</param> /// /// <returns>The asymmetric family designator</returns> public static AsymmetricEngines GetParametersType(IAsymmetricParameters Parameters) { if (Parameters.GetType().Equals(typeof(NTRUParameters))) { return(AsymmetricEngines.NTRU); } else if (Parameters.GetType().Equals(typeof(MPKCParameters))) { return(AsymmetricEngines.McEliece); } else if (Parameters.GetType().Equals(typeof(RLWEParameters))) { return(AsymmetricEngines.RingLWE); } else if (Parameters.GetType().Equals(typeof(RNBWParameters))) { return(AsymmetricEngines.Rainbow); } else { return(AsymmetricEngines.GMSS); } }
/// <summary> /// Get the asymmetric public key from a stream /// </summary> /// /// <param name="KeyStream">The encoded public key</param> /// <param name="Parameters">The cipher parameters</param> /// /// <returns>The public key</returns> private IAsymmetricKey GetAsymmetricPublicKey(Stream KeyStream, IAsymmetricParameters Parameters) { IAsymmetricKey key = null; try { if (Parameters.GetType().Equals(typeof(NTRUParameters))) key = new NTRUPublicKey(KeyStream); else if (Parameters.GetType().Equals(typeof(MPKCParameters))) key = new MPKCPublicKey(KeyStream); else if (Parameters.GetType().Equals(typeof(RLWEParameters))) key = new RLWEPublicKey(KeyStream); return key; } catch (Exception ex) { throw new CryptoProcessingException("DtmKex:GetAsymmetricPublicKey", "The public key could not be loaded!", ex); } }
/// <summary> /// Get the asymmetric cipher instance /// </summary> /// /// <param name="Parameters">The cipher parameters</param> /// /// <returns>The cipher instance</returns> private IAsymmetricCipher GetAsymmetricCipher(IAsymmetricParameters Parameters) { IAsymmetricCipher cipher = null; try { if (Parameters.GetType().Equals(typeof(NTRUParameters))) cipher = new NTRUEncrypt((NTRUParameters)Parameters); else if (Parameters.GetType().Equals(typeof(MPKCParameters))) cipher = new MPKCEncrypt((MPKCParameters)Parameters); else if (Parameters.GetType().Equals(typeof(RLWEParameters))) cipher = new RLWEEncrypt((RLWEParameters)Parameters); return cipher; } catch (Exception ex) { throw new CryptoProcessingException("DtmKex:GetAsymmetricCipher", "The cipher could not be loaded!", ex); } }
/// <summary> /// Get the asymmetric generator instance /// </summary> /// /// <param name="Parameters">The cipher parameters</param> /// /// <returns>The generator instance</returns> private IAsymmetricGenerator GetAsymmetricGenerator(IAsymmetricParameters Parameters) { IAsymmetricGenerator gen = null; try { if (Parameters.GetType().Equals(typeof(NTRUParameters))) gen = new NTRUKeyGenerator((NTRUParameters)Parameters); else if (Parameters.GetType().Equals(typeof(MPKCParameters))) gen = new MPKCKeyGenerator((MPKCParameters)Parameters); else if (Parameters.GetType().Equals(typeof(RLWEParameters))) gen = new RLWEKeyGenerator((RLWEParameters)Parameters); return gen; } catch (Exception ex) { throw new CryptoProcessingException("DtmKex:GetAsymmetricGenerator", "The generator could not be loaded!", ex); } }
/// <summary> /// Sends the servers Primary-Stage <see cref="IAsymmetricKey">AsymmetricKey</see> Public key. /// </summary> /// /// <returns>A Stream containing the raw packet data</returns> private MemoryStream CreatePrimeEx() { // get the cipher parameters _srvAsmParams = GetAsymmetricParams(_srvIdentity.PkeId); // create new public key pair _primKeyPair = GenerateAsymmetricKeyPair(_srvAsmParams); // serailize the public key byte[] keyBytes = _primKeyPair.PublicKey.ToBytes(); // pad public key keyBytes = WrapMessage(keyBytes, _dtmParameters.MaxAsmKeyAppend, _dtmParameters.MaxAsmKeyPrePend); // encrypt the servers public key byte[] enc = SymmetricTransform(_srvSymProcessor, keyBytes); // payload container MemoryStream pldStm = new MemoryStream(enc); // stage completed _exchangeState = DtmExchangeFlags.PrimeEx; // optional wait random timeout if (_dtmParameters.MaxAsmKeyDelayMS > 0) SendWait(_dtmParameters.MaxAsmKeyDelayMS, _dtmParameters.MaxAsmKeyDelayMS / 2); return pldStm; }
/// <summary> /// Generat an asymmetric key-pair /// </summary> private IAsymmetricKeyPair GenerateAsymmetricKeyPair(IAsymmetricParameters Parameters) { using (IAsymmetricGenerator gen = GetAsymmetricGenerator(Parameters)) _authKeyPair = gen.GenerateKeyPair(); return (IAsymmetricKeyPair)_authKeyPair.Clone(); }
/// <summary> /// Send the servers Auth-Stage Asymmetric Public key; <see cref="IAsymmetricKey"/>, built using the PKE params id from the servers identity structure. /// <para>The packet header; <see cref="DtmPacket"/>, contains the message type, payload length, sequence number, and exchange state. /// The payload is the servers Auth-Stage asymmetric Public Key.</para> /// </summary> /// /// <returns>A raw packet containing the packet header, and the servers Auth-Stage asymmetric Public Key</returns> private MemoryStream CreatePreAuth() { // server asym params _srvAsmParams = GetAsymmetricParams(_srvIdentity.PkeId); // generate the servers auth-stage key pair _authKeyPair = GenerateAsymmetricKeyPair(_srvAsmParams); // serialize servers public key MemoryStream pbk = _authKeyPair.PublicKey.ToStream(); // stage completed _exchangeState = DtmExchangeFlags.PreAuth; return pbk; }
private void Dispose(bool Disposing) { if (!_isDisposed && Disposing) { try { if (_asmParameters != null) { _asmParameters.Dispose(); _asmParameters = null; } if (_publicKey != null) { _publicKey.Dispose(); _publicKey = null; } if (_privateKey != null) { _privateKey.Dispose(); _privateKey = null; } if (_idTag != null) { Array.Clear(_idTag, 0, _idTag.Length); _idTag = null; } } finally { _isDisposed = true; } } }
/// <summary> /// Process the clients identity structure <see cref="DtmIdentity"/>. /// </summary> /// /// <param name="PacketStream">A Stream containing the raw packet data</param> private void ProcessSync(MemoryStream PacketStream) { // get the header DtmPacket pktHdr = new DtmPacket(PacketStream); // read the data byte[] data = new byte[pktHdr.PayloadLength]; PacketStream.Read(data, 0, data.Length); // use clients symmetric key to decrypt data byte[] dec = SymmetricTransform(_cltSymProcessor, data); // remove random padding dec = UnwrapMessage(dec); // get the identity _cltIdentity = new DtmIdentity(dec); // pass id to the client, include oid long resp = 0; if (IdentityReceived != null) { DtmIdentityEventArgs args = new DtmIdentityEventArgs(DtmExchangeFlags.Init, _cltIdentity.OptionFlag, _cltIdentity); IdentityReceived(this, args); resp = args.Flag; if (args.Cancel) { // back out of session TearDown(); } } // get the params oid _cltAsmParams = GetAsymmetricParams(_cltIdentity.PkeId); }
/// <summary> /// Processes the clients public identity and clients Auth-Stage PKE parameter set Id; <see cref="IAsymmetricParameters"/>. /// <para>Process the clients Auth-Stage public identity structure; <see cref="DtmIdentity"/></para> /// </summary> /// /// <param name="PacketStream">A Stream containing the raw packet data</param> /// /// <remarks>Fires the <see cref="IdentityReceived"/> event; returning the <see cref="DtmIdentityEventArgs"/> object containing the clients public id structure. /// <para>The session can be aborted by setting the DtmIdentityEventArgs Cancel flag to true.</para> /// </remarks> private void ProcessInit(MemoryStream PacketStream) { // seek past header PacketStream.Seek(DtmPacket.GetHeaderSize(), SeekOrigin.Begin); // get the clients id structure _cltIdentity = new DtmIdentity(PacketStream); // get client asymmetric params _cltAsmParams = GetAsymmetricParams(_cltIdentity.PkeId); // store the auth session _cltAuthSession = _cltIdentity.Session; // pass it to the client again, so it can be refused on basis of params long resp = 0; if (IdentityReceived != null) { DtmIdentityEventArgs args = new DtmIdentityEventArgs(DtmExchangeFlags.Init, 0, _cltIdentity); IdentityReceived(this, args); resp = args.Flag; if (args.Cancel) { // back out of session TearDown(); } } }
/// <summary> /// Reads the key container from an input stream /// </summary> /// /// <param name="KeyStream">An input stream containing an encoded key container</param> public AsymmetricContainer(MemoryStream KeyStream) { BinaryReader reader = new BinaryReader(KeyStream); byte[] data; int len; _idTag = null; _publicKey = null; _publicKey = null; // tag len = reader.ReadInt32(); if (len > 0) _idTag = reader.ReadBytes(len); // family _asmEngine = (AsymmetricEngines)reader.ReadByte(); // parameters len = reader.ReadInt32(); data = reader.ReadBytes(len); _asmParameters = ParamsFromBytes(data); // public key len = reader.ReadInt32(); if (len > 0) { data = reader.ReadBytes(len); _publicKey = PublicKeyFromBytes(data); } // private key len = reader.ReadInt32(); if (len > 0) { data = reader.ReadBytes(len); _privateKey = PrivateKeyFromBytes(data); } }
/// <summary> /// Processes the clients Auth-Stage <see cref="IAsymmetricKey">AsymmetricKey</see> Public key. /// <para>Stores the clients Auth-Stage Asymmetric Public Key.</para> /// </summary> /// /// <param name="PacketStream">A Stream containing the raw packet data</param> private void ProcessPreAuth(MemoryStream PacketStream) { // seek past header PacketStream.Seek(DtmPacket.GetHeaderSize(), SeekOrigin.Begin); // get client params _cltAsmParams = GetAsymmetricParams(_cltIdentity.PkeId); // store client public key _cltPublicKey = GetAsymmetricPublicKey(PacketStream, _cltAsmParams); }
/// <summary> /// Decrypt an array with an asymmetric cipher /// </summary> private byte[] AsymmetricDecrypt(IAsymmetricParameters Parameters, IAsymmetricKeyPair KeyPair, byte[] Data) { using (IAsymmetricCipher cipher = GetAsymmetricCipher(Parameters)) { if (cipher.GetType().Equals(typeof(NTRUEncrypt))) ((NTRUEncrypt)cipher).Initialize(KeyPair); else cipher.Initialize(KeyPair.PrivateKey); return cipher.Decrypt(Data); } }
/// <summary> /// Tear down the connection; destroys all structures provided by this class /// </summary> private void TearDown() { if (_rndGenerator != null) { _rndGenerator.Dispose(); _rndGenerator = null; } if (_authKeyPair != null) { _authKeyPair.Dispose(); _authKeyPair = null; } if (_cltAsmParams != null) { _cltAsmParams.Dispose(); _cltAsmParams = null; } if (_cltPublicKey != null) { _cltPublicKey.Dispose(); _cltPublicKey = null; } if (_primKeyPair != null) { _primKeyPair.Dispose(); _primKeyPair = null; } // cipher streaming managed through class if (SessionEstablished == null || _disposeEngines == true) { if (_cltKeyParams != null) { _cltKeyParams.Dispose(); _cltKeyParams = null; } if (_srvKeyParams != null) { _srvKeyParams.Dispose(); _srvKeyParams = null; } if (_srvSymProcessor != null) { _srvSymProcessor.Dispose(); _srvSymProcessor = null; } if (_cltSymProcessor != null) { _cltSymProcessor.Dispose(); _cltSymProcessor = null; } } _bufferCount = 0; _bytesSent = 0; _bytesReceived = 0; _cltIdentity.Reset(); _fileCounter = 0; _maxSendCounter = 0; _maxSendAttempts = MAXSNDATTEMPT; _rcvSequence = 0; _sndSequence = 0; }
/// <summary> /// Encrypt an array with an asymmetric cipher /// </summary> private byte[] AsymmetricEncrypt(IAsymmetricParameters Parameters, IAsymmetricKey PublicKey, byte[] Data) { using (IAsymmetricCipher cipher = GetAsymmetricCipher(Parameters)) { cipher.Initialize(PublicKey); return cipher.Encrypt(Data); } }