Exemplo n.º 1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="NetworkConnectionProvider" /> class.
        /// </summary>
        /// <param name="endPoint">The endpoint to listen to.</param>
        /// <param name="maxConnections">Maximum number of connections to allow.</param>
        /// <param name="protocols">The protocols to accept.</param>
        /// <param name="pkCryptoFactory">The public key cryptography provider factory.</param>
        /// <param name="enabledHashAlgs">
        /// The signature hash algorithms (in order of preference) to enable from <paramref name="pkCryptoFactory"/>.
        /// <c>null</c> or an empty collection will enable all of the signature hash algorithms.
        /// </param>
        /// <exception cref="ArgumentNullException"><paramref name="endPoint"/>, <paramref name="protocols" /> or <paramref name="pkCryptoFactory" /> is <c>null</c>.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="maxConnections"/> is &lt;= 0</exception>
        public NetworkConnectionProvider(IEnumerable<Protocol> protocols, IPEndPoint endPoint, int maxConnections, Func<IPublicKeyCrypto> pkCryptoFactory, IEnumerable<string> enabledHashAlgs = null)
        {
            if (pkCryptoFactory == null)
                throw new ArgumentNullException ("pkCryptoFactory");
            if (protocols == null)
                throw new ArgumentNullException ("protocols");
            if (endPoint == null)
                throw new ArgumentNullException ("endPoint");
            if (maxConnections <= 0)
                throw new ArgumentOutOfRangeException ("maxConnections");

            this.protocols = protocols;
            this.endPoint = endPoint;
            MaxConnections = maxConnections;
            this.serverConnections = new List<NetworkServerConnection> (maxConnections);

            this.pkCryptoFactory = pkCryptoFactory;

            if (protocols.Any (p => p != null && p.RequiresHandshake))
            {
                ThreadPool.QueueUserWorkItem (s =>
                {
                    #if NET_4
                    Task encryptKeyGen = Task.Factory.StartNew (() =>
                    {
                    #endif
                        this.pkEncryption = this.pkCryptoFactory();
                        this.publicEncryptionKey = this.pkEncryption.ExportKey (false);
                    #if NET_4
                    });
                    #endif

                    #if NET_4
                    Task authKeyGen = Task.Factory.StartNew (() =>
                    {
                    #endif
                        this.authentication = this.pkCryptoFactory();
                        if (this.authenticationKey == null)
                            this.authenticationKey = this.authentication.ExportKey (true);
                        else
                            this.authentication.ImportKey (this.authenticationKey);

                        this.publicAuthenticationKey = this.authentication.ExportKey (false);

                        if (enabledHashAlgs == null || !enabledHashAlgs.Any())
                            this.enabledHashAlgorithms.AddRange (this.authentication.SupportedHashAlgs);
                        else // Need to maintain preference order
                            this.enabledHashAlgorithms.AddRange (enabledHashAlgs.Where (a => this.authentication.SupportedHashAlgs.Contains (a)));
                    #if NET_4
                    });

                    authKeyGen.Wait();
                    encryptKeyGen.Wait();
                    #endif

                    this.keyWait.Set();
                });
            }
            else
                this.keyWait.Set();
        }
Exemplo n.º 2
0
        protected override bool VerifyMessage(string hashAlg, Message message, byte[] signature, byte[] data, int moffset, int length)
        {
            if (this.hmac == null)
            {
                byte[] resized = new byte[length];
                Buffer.BlockCopy (data, moffset, resized, 0, length);

                var msg = (AcknowledgeConnectMessage)message;

                this.serverAuthentication = this.publicKeyCryptoFactory();
                this.serverAuthenticationKey = msg.PublicAuthenticationKey;
                this.serverAuthentication.ImportKey (this.serverAuthenticationKey);

                this.signingHashAlgorithm = msg.SignatureHashAlgorithm;
                return this.serverAuthentication.VerifySignedHash (this.signingHashAlgorithm, resized, signature);
            }
            else
                return base.VerifyMessage (hashAlg, message, signature, data, moffset, length);
        }
Exemplo n.º 3
0
        protected override void Recycle()
        {
            Interlocked.Add (ref sendBufferLimit, AutoSizeFactor * -1);

            this.serverEncryption = null;
            this.serverEncryptionKey = null;
            this.serverAuthenticationKey = null;

            base.Recycle();
        }
Exemplo n.º 4
0
        protected override void OnTempestMessageReceived(MessageEventArgs e)
        {
            switch (e.Message.MessageType)
            {
                case (ushort)TempestMessageType.Ping:
                    var ping = (PingMessage)e.Message;
                    if (this.pingFrequency == 0 || this.activityTimer == null)
                    {
                        if (this.activityTimer != null)
                            this.activityTimer.Dispose();

                        if (ping.Interval != 0)
                        {
                            this.activityTimer = new Tempest.Timer (ping.Interval);
                            this.activityTimer.TimesUp += ActivityCallback;
                            this.activityTimer.Start();
                        }
                    }
                    else if (ping.Interval != this.pingFrequency)
                        this.activityTimer.Interval = ping.Interval;

                    this.pingFrequency = ((PingMessage)e.Message).Interval;
                    break;

                case (ushort)TempestMessageType.AcknowledgeConnect:
                    var msg = (AcknowledgeConnectMessage)e.Message;

                    this.protocols = this.protocols.Values.Intersect (msg.EnabledProtocols).ToDictionary (pr => pr.id);
                    ConnectionId = msg.ConnectionId;

                    this.serverEncryption = this.publicKeyCryptoFactory();
                    this.serverEncryption.ImportKey (msg.PublicEncryptionKey);
                    this.serverEncryptionKey = msg.PublicEncryptionKey;

                    var encryption = new AesManaged { KeySize = 256 };
                    encryption.GenerateKey();

                    BufferValueWriter authKeyWriter = new BufferValueWriter (new byte[1600]);
                    this.publicAuthenticationKey.Serialize (authKeyWriter, this.serverEncryption);

                    Send (new FinalConnectMessage
                    {
                        AESKey = this.serverEncryption.Encrypt (encryption.Key),
                        PublicAuthenticationKeyType = this.publicAuthenticationKey.GetType(),
                        PublicAuthenticationKey = authKeyWriter.ToArray()
                    });

                    this.aes = encryption;
                    this.hmac = new HMACSHA256 (this.aes.Key);
                    break;

                case (ushort)TempestMessageType.Connected:
                    var connected = (ConnectedMessage) e.Message;
                    ConnectionId = connected.ConnectionId;

                    OnConnected (new ClientConnectionEventArgs (this));

                    var tcs = Interlocked.Exchange (ref this.connectCompletion, null);
                    if (tcs != null)
                        tcs.SetResult (new ClientConnectionResult (ConnectionResult.Success, this.serverAuthenticationKey));

                    break;
            }

            base.OnTempestMessageReceived(e);
        }
Exemplo n.º 5
0
        public void Serialize(IValueWriter writer, IPublicKeyCrypto crypto)
        {
            if (writer.WriteBool (D != null))
            {
                writer.WriteBytes (crypto.Encrypt (D));
                writer.WriteBytes (crypto.Encrypt (DP));
                writer.WriteBytes (crypto.Encrypt (DQ));
                writer.WriteBytes (crypto.Encrypt (InverseQ));
                writer.WriteBytes (crypto.Encrypt (P));
                writer.WriteBytes (crypto.Encrypt (Q));
            }

            if (writer.WriteBool (this.publicKey != null))
            {
                writer.WriteBytes (crypto.Encrypt (Exponent));

                int first = Modulus.Length / 2;
                writer.WriteBytes (crypto.Encrypt (Modulus.Copy (0, first)));
                writer.WriteBytes (crypto.Encrypt (Modulus.Copy (first, Modulus.Length - first)));
            }
        }
Exemplo n.º 6
0
        public void Deserialize(IValueReader reader, IPublicKeyCrypto crypto)
        {
            if (reader == null)
                throw new ArgumentNullException ("reader");
            if (crypto == null)
                throw new ArgumentNullException ("crypto");

            if (reader.ReadBool())
            {
                D = crypto.Decrypt (reader.ReadBytes());
                DP = crypto.Decrypt (reader.ReadBytes());
                DQ = crypto.Decrypt (reader.ReadBytes());
                InverseQ = crypto.Decrypt (reader.ReadBytes());
                P = crypto.Decrypt (reader.ReadBytes());
                Q = crypto.Decrypt (reader.ReadBytes());
            }

            if (reader.ReadBool())
            {
                byte[] exponent = crypto.Decrypt (reader.ReadBytes());

                byte[] modulus1 = crypto.Decrypt (reader.ReadBytes());
                byte[] modulus2 = crypto.Decrypt (reader.ReadBytes());
                byte[] modulus = modulus1.Concat (modulus2).ToArray();

                this.exponentOffset = modulus.Length;
                this.publicKey = new byte[exponent.Length + modulus.Length];
                Buffer.BlockCopy (modulus, 0, this.publicKey, 0, modulus.Length);
                Buffer.BlockCopy (exponent, 0, this.publicKey, exponentOffset, exponent.Length);
            }

            SetupSignature();
        }