/// <summary> /// The identity exchanged event args constructor; contains the identity and Asymmetric parameters OId from an Identity structure /// </summary> /// /// <param name="Message">The <see cref="DtmServiceFlags"/> (Auth or Primary), from which this message originated</param> /// <param name="Flag">An option flag that contains the clients Asymmetric parameters OId</param> /// <param name="DtmID">The <see cref="DtmIdentity"/> containing identity and session parameters</param> public DtmIdentityEventArgs(DtmExchangeFlags Message, long Flag, DtmIdentity DtmID) { this.Message = Message; this.Flag = Flag; this.DtmID = DtmID; this.Cancel = false; }
/// <summary> /// The identity exchanged event args constructor; contains the identity and Asymmetric parameters OId from an Identity structure /// </summary> /// /// <param name="Message">The <see cref="DtmServiceFlags"/> (Auth or Primary), from which this message originated</param> /// <param name="Flag">An option flag that contains the clients Asymmetric parameters OId</param> /// <param name="DtmID">The <see cref="DtmIdentityStruct"/> containing identity and session parameters</param> public DtmIdentityArgs(DtmExchangeFlags Message, long Flag, DtmIdentityStruct DtmID) { this.Message = Message; this.Flag = Flag; this.DtmID = DtmID; this.Cancel = false; }
/// <summary> /// Initialize this class with a random generator /// </summary> /// /// <param name="Parameters">A populated <see cref="DtmParameters"/> class containing the session parameters</param> /// <param name="Host">A populated <see cref="DtmClient"/> class containing the servers identity data</param> /// <param name="Generator">The initialized <see cref="IRandom"/> Prng instance</param> /// <param name="BufferCount">The number of send/receive buffers, default is 1024</param> /// <param name="DisposeEngines">if set to true (default), the primary symmetric ciphers are disposed when this class is disposed</param> public DtmKex(DtmParameters Parameters, DtmClient Host, IRandom Generator, int BufferCount = 1024, bool DisposeEngines = true) { _disposeEngines = DisposeEngines; _dtmParameters = Parameters; _dtmHost = Host; _srvIdentity = new DtmIdentity(Host.PublicId, Parameters.AuthPkeId, Parameters.AuthSession, 0); _exchangeState = DtmExchangeFlags.Connect; _rcvBuffer = new PacketBuffer(BufferCount); _sndBuffer = new PacketBuffer(BufferCount); _rndGenerator = Generator; _bufferCount = BufferCount; }
/// <summary> /// Send the servers Primary-Stage session parameters in a <see cref="DtmIdentity"/> structure. /// <para>The packet header; <see cref="DtmPacket"/>, contains the message type, payload length, sequence number, and exchange state. /// The payload is the servers identity structure (DtmIdentity), containing the secret id field, the session key parameters <see cref="DtmSession"/>, and the /// primary-stage PKE parameters Id.</para> /// </summary> /// /// <returns>A raw packet containing the packet header, and the servers private identity</returns> private MemoryStream CreateSync() { // change to primary parameters _srvIdentity = new DtmIdentity(_dtmHost.SecretId, _dtmParameters.PrimaryPkeId, _dtmParameters.PrimarySession, 0); // serialize identity byte[] data = _srvIdentity.ToBytes(); // wrap the id with random data = WrapMessage(data, _dtmParameters.MaxMessageAppend, _dtmParameters.MaxMessagePrePend); // encrypt with servers session key byte[] enc = SymmetricTransform(_srvSymProcessor, data); // payload container MemoryStream pldStm = new MemoryStream(enc); // stage completed _exchangeState = DtmExchangeFlags.Sync; return pldStm; }
/// <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> /// Sends the servers primary-stage Symmetric <see cref="KeyParams"/>. /// </summary> /// /// <returns>A Stream containing the raw packet data</returns> private MemoryStream CreatePrimary() { // create the primary session key KeyParams tmpKey = GenerateSymmetricKey(_srvIdentity.Session); // serialize the keyparams structure byte[] srvKrw = ((MemoryStream)KeyParams.Serialize(tmpKey)).ToArray(); // encrypt the symmetric key with the primary asymmetric cipher byte[] enc = AsymmetricEncrypt(_cltAsmParams, _cltPublicKey, srvKrw); // pad the encrypted key with random enc = WrapMessage(enc, _dtmParameters.MaxSymKeyAppend, _dtmParameters.MaxSymKeyPrePend); // encrypt the result with the auth symmetric key enc = SymmetricTransform(_srvSymProcessor, enc); // clear auth key _srvKeyParams.Dispose(); // swap to primary symmetric key _srvKeyParams = tmpKey; // payload container MemoryStream pldStm = new MemoryStream(enc); // stage completed _exchangeState = DtmExchangeFlags.Primary; return pldStm; }
/// <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; }
/// <summary> /// Send the servers full public identity structure <see cref="DtmIdentity"/>; contains the public id field, the asymmetric parameters, and the symmetric session parameters. /// <para>The packet header; <see cref="DtmPacket"/>, contains the message type, payload length, sequence number, and exchange state. /// The payload is the servers preliminary identity structure (DtmIdentity), containing the public id field, the session key parameters <see cref="DtmSession"/>, and the /// Auth-Stage PKE parameters OId.</para> /// </summary> /// /// <returns>A raw packet containing the packet header, and the servers public identity structure</returns> private MemoryStream CreateInit() { // create a partial id and add auth asymmetric and session params MemoryStream sid = _srvIdentity.ToStream(); // stage completed _exchangeState = DtmExchangeFlags.Init; return sid; }
/// <summary> /// Notify that the VPN is established /// </summary> /// /// <returns>A Stream containing the raw packet data</returns> private MemoryStream CreateEstablish() { MemoryStream pktStm = new DtmPacket(DtmPacketTypes.Exchange, 0, _sndSequence, (short)DtmExchangeFlags.Established).ToStream(); // notify if (PacketSent != null) PacketSent(this, new DtmPacketEventArgs((short)_exchangeState, pktStm.Length)); // stage completed _exchangeState = DtmExchangeFlags.Established; return pktStm; }
// Functions are in order of execution. The Create functions create a response packet, the Process functions process the result. /// <summary> /// Send the servers partial public identity structure <see cref="DtmIdentity"/>. /// <para>The packet header; <see cref="DtmPacket"/>, contains the message type, payload length, sequence number, and exchange state. /// The payload is the servers public identity field in a default DtmIdentity structure.</para> /// </summary> /// /// <param name="Trust">The level of trust expected (for future use)</param> /// /// <returns>A raw packet containing the packet header, and the servers public identity structure</returns> private MemoryStream CreateConnect(DtmTrustStates Trust = DtmTrustStates.None) { // the option flag is used to describe minimum security level required from this instance int sec = (int)DtmParamSets.GetContext(_dtmParameters.OId); // create a partial id and add auth asymmetric and session params. MemoryStream sid = new DtmIdentity(_srvIdentity.Identity, new byte[] { 0, 0, 0, 0 }, new DtmSession(), sec).ToStream(); // stage completed _exchangeState = DtmExchangeFlags.Connect; return sid; }
/// <summary> /// Send the servers Auth-Stage Symmetric <see cref="KeyParams"/>, encrypted with the clients Public Key. /// <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 Symmetric KeyParams, encrypted with the clients Asymmetric Public Key.</para> /// </summary> /// /// <returns>A raw packet containing the packet header, and the servers Auth-Stage Symmetric Key</returns> private MemoryStream CreateAuthEx() { // create a session key based on servers symmetric session params _srvKeyParams = GenerateSymmetricKey(_srvIdentity.Session); // serialize the keyparams structure byte[] srvKrw = ((MemoryStream)KeyParams.Serialize(_srvKeyParams)).ToArray(); // encrypt the servers symmetric key with the clients public key byte[] enc = AsymmetricEncrypt(_cltAsmParams, _cltPublicKey, srvKrw); // payload container MemoryStream pldStm = new MemoryStream(enc); // stage completed _exchangeState = DtmExchangeFlags.AuthEx; // optional delay before transmission if (_dtmParameters.MaxSymKeyDelayMS > 0) SendWait(_dtmParameters.MaxSymKeyDelayMS, _dtmParameters.MaxSymKeyDelayMS / 2); return pldStm; }
/// <summary> /// Sends the servers private identity; <see cref="DtmIdentity"/>, encrypted with the servers Symmetric Key. /// </summary> /// /// <returns>A raw packet containing the packet header, and the servers private identity</returns> private MemoryStream CreateAuth() { // send secret id and return auth status in options flag _srvIdentity.Identity = _dtmHost.SecretId; // create the servers auth-stage symmetric cipher _srvSymProcessor = SymmetricInit(_srvIdentity.Session, _srvKeyParams); byte[] data = _srvIdentity.ToBytes(); // wrap the id with random data = WrapMessage(data, _dtmParameters.MaxMessageAppend, _dtmParameters.MaxMessagePrePend); // encrypt the identity byte[] enc = SymmetricTransform(_srvSymProcessor, data); // payload container MemoryStream pldStm = new MemoryStream(enc); // stage completed _exchangeState = DtmExchangeFlags.Auth; return pldStm; }