private void Announce(BinaryID[] networkIDs, IPAddress[] remoteIPs, int times, bool isReply)
        {
            List <byte[]> packets = new List <byte[]>(networkIDs.Length);

            //CREATE ADVERTISEMENT
            foreach (BinaryID networkID in networkIDs)
            {
                byte[] challenge = BinaryID.GenerateRandomID256().ID;

                using (MemoryStream mS = new MemoryStream(BUFFER_MAX_SIZE))
                {
                    //version 1 byte
                    if (isReply)
                    {
                        mS.WriteByte(4);
                    }
                    else
                    {
                        mS.WriteByte(3);
                    }

                    mS.Write(BitConverter.GetBytes(_announcePort), 0, 2); //service port
                    mS.Write(challenge, 0, 32);                           //challenge

                    using (HMACSHA256 hmacSHA256 = new HMACSHA256(networkID.ID))
                    {
                        byte[] hmac = hmacSHA256.ComputeHash(challenge);
                        mS.Write(hmac, 0, 32);
                    }

                    packets.Add(mS.ToArray());
                }
            }

            //SEND ADVERTISEMENT
            for (int i = 0; i < times; i++)
            {
                foreach (byte[] packet in packets)
                {
                    if (remoteIPs == null)
                    {
                        _listener.Broadcast(packet, 0, packet.Length);
                    }
                    else
                    {
                        foreach (IPAddress remoteIP in remoteIPs)
                        {
                            _listener.SendTo(packet, 0, packet.Length, remoteIP);
                        }
                    }
                }

                if (i < times - 1)
                {
                    Thread.Sleep(ANNOUNCEMENT_RETRY_INTERVAL);
                }
            }
        }
示例#2
0
        private void Announce(BinaryID networkID, IPAddress[] remoteIPs, int times, bool isReply)
        {
            //CREATE ADVERTISEMENT
            byte[] challenge = BinaryID.GenerateRandomID256().ID;
            byte[] buffer    = new byte[BUFFER_MAX_SIZE];

            using (MemoryStream mS = new MemoryStream(buffer))
            {
                //version 1 byte
                if (isReply)
                {
                    mS.WriteByte(4);
                }
                else
                {
                    mS.WriteByte(3);
                }

                mS.Write(BitConverter.GetBytes(_announcePort), 0, 2); //service port
                mS.Write(challenge, 0, 32);                           //challenge

                using (HMACSHA256 hmacSHA256 = new HMACSHA256(networkID.ID))
                {
                    byte[] hmac = hmacSHA256.ComputeHash(challenge);
                    mS.Write(hmac, 0, 32);
                }

                int length = Convert.ToInt32(mS.Position);

                //SEND ADVERTISEMENT
                for (int i = 0; i < times; i++)
                {
                    if (remoteIPs == null)
                    {
                        _listener.Broadcast(buffer, 0, length);
                    }
                    else
                    {
                        foreach (IPAddress remoteIP in remoteIPs)
                        {
                            _listener.SendTo(buffer, 0, length, remoteIP);
                        }
                    }

                    if (i < times - 1)
                    {
                        Thread.Sleep(ANNOUNCEMENT_INTERVAL);
                    }
                }
            }
        }
        public BitChat CreateGroupChat(string networkName, string sharedSecret, bool enableTracking, bool dhtOnlyTracking)
        {
            Uri[] trackerURIs;

            if (dhtOnlyTracking)
            {
                trackerURIs = new Uri[] { }
            }
            ;
            else
            {
                trackerURIs = _profile.TrackerURIs;
            }

            BitChatNetwork network = new BitChatNetwork(_connectionManager, _trustedRootCertificates, _supportedCryptoOptions, networkName, sharedSecret, null, null, new Certificate[] { }, BitChatNetworkStatus.Online);

            return(CreateBitChat(network, BinaryID.GenerateRandomID160().ToString(), BinaryID.GenerateRandomID256().ID, -1, null, new BitChatProfile.SharedFileInfo[] { }, trackerURIs, enableTracking, false, false));
        }
        public BitChat CreatePrivateChat(MailAddress peerEmailAddress, string sharedSecret, bool enableTracking, bool dhtOnlyTracking, string invitationMessage)
        {
            Uri[] trackerURIs;

            if (dhtOnlyTracking)
            {
                trackerURIs = new Uri[] { }
            }
            ;
            else
            {
                trackerURIs = _profile.TrackerURIs;
            }

            BitChatNetwork network = new BitChatNetwork(_connectionManager, _trustedRootCertificates, _supportedCryptoOptions, peerEmailAddress, sharedSecret, null, null, new Certificate[] { }, BitChatNetworkStatus.Online, _profile.LocalCertificateStore.Certificate.IssuedTo.EmailAddress.Address, invitationMessage);

            return(CreateBitChat(network, BinaryID.GenerateRandomID160().ToString(), BinaryID.GenerateRandomID256().ID, 0, null, new BitChatProfile.SharedFileInfo[] { }, trackerURIs, enableTracking, !string.IsNullOrEmpty(invitationMessage), false));
        }
示例#5
0
        private void ProtocolV4(Stream stream)
        {
            #region 1. hello handshake

            //read client hello
            SecureChannelPacket.Hello clientHello = (new SecureChannelPacket(stream)).GetHello();

            //select crypto option
            _selectedCryptoOption = _supportedOptions & clientHello.CryptoOptions;

            if (_selectedCryptoOption == SecureChannelCryptoOptionFlags.None)
            {
                throw new SecureChannelException(SecureChannelCode.NoMatchingCryptoAvailable, _remotePeerEP, _remotePeerCert);
            }
            else if ((_selectedCryptoOption & SecureChannelCryptoOptionFlags.ECDHE256_RSA_WITH_AES256_CBC_HMAC_SHA256) > 0)
            {
                _selectedCryptoOption = SecureChannelCryptoOptionFlags.ECDHE256_RSA_WITH_AES256_CBC_HMAC_SHA256;
            }
            else if ((_selectedCryptoOption & SecureChannelCryptoOptionFlags.DHE2048_RSA_WITH_AES256_CBC_HMAC_SHA256) > 0)
            {
                _selectedCryptoOption = SecureChannelCryptoOptionFlags.DHE2048_RSA_WITH_AES256_CBC_HMAC_SHA256;
            }
            else
            {
                throw new SecureChannelException(SecureChannelCode.NoMatchingCryptoAvailable, _remotePeerEP, _remotePeerCert);
            }

            //send server hello
            SecureChannelPacket.Hello serverHello = new SecureChannelPacket.Hello(BinaryID.GenerateRandomID256(), _selectedCryptoOption);
            SecureChannelPacket.WritePacket(stream, serverHello);

            #endregion

            #region 2. key exchange

            SymmetricEncryptionAlgorithm encAlgo;
            string       hashAlgo;
            KeyAgreement keyAgreement;

            switch (_selectedCryptoOption)
            {
            case SecureChannelCryptoOptionFlags.DHE2048_RSA_WITH_AES256_CBC_HMAC_SHA256:
                encAlgo      = SymmetricEncryptionAlgorithm.Rijndael;
                hashAlgo     = "SHA256";
                keyAgreement = new DiffieHellman(DiffieHellmanGroupType.RFC3526, 2048, KeyAgreementKeyDerivationFunction.Hmac, KeyAgreementKeyDerivationHashAlgorithm.SHA256);
                break;

            case SecureChannelCryptoOptionFlags.ECDHE256_RSA_WITH_AES256_CBC_HMAC_SHA256:
                encAlgo      = SymmetricEncryptionAlgorithm.Rijndael;
                hashAlgo     = "SHA256";
                keyAgreement = new TechnitiumLibrary.Security.Cryptography.ECDiffieHellman(256, KeyAgreementKeyDerivationFunction.Hmac, KeyAgreementKeyDerivationHashAlgorithm.SHA256);
                break;

            default:
                throw new SecureChannelException(SecureChannelCode.NoMatchingCryptoAvailable, _remotePeerEP, _remotePeerCert);
            }

            //send server key exchange data
            SecureChannelPacket.KeyExchange serverKeyExchange = new SecureChannelPacket.KeyExchange(keyAgreement.GetPublicKey(), _serverCredentials.PrivateKey, hashAlgo);
            SecureChannelPacket.WritePacket(stream, serverKeyExchange);

            //read client key exchange data
            SecureChannelPacket.KeyExchange clientKeyExchange = (new SecureChannelPacket(stream)).GetKeyExchange();

            //generate master key
            byte[] masterKey = GenerateMasterKey(clientHello, serverHello, _preSharedKey, keyAgreement, clientKeyExchange.PublicKey);

            //verify master key using HMAC authentication
            {
                SecureChannelPacket.Authentication clientAuthentication = (new SecureChannelPacket(stream)).GetAuthentication();
                if (!clientAuthentication.IsValid(serverHello, masterKey))
                {
                    throw new SecureChannelException(SecureChannelCode.ProtocolAuthenticationFailed, _remotePeerEP, _remotePeerCert);
                }

                SecureChannelPacket.Authentication serverAuthentication = new SecureChannelPacket.Authentication(clientHello, masterKey);
                SecureChannelPacket.WritePacket(stream, serverAuthentication);
            }

            //enable channel encryption
            switch (encAlgo)
            {
            case SymmetricEncryptionAlgorithm.Rijndael:
                //using MD5 for generating AES IV of 128bit block size
                HashAlgorithm md5Hash = HashAlgorithm.Create("MD5");
                byte[]        eIV     = md5Hash.ComputeHash(serverHello.Nonce.ID);
                byte[]        dIV     = md5Hash.ComputeHash(clientHello.Nonce.ID);

                //create encryption and decryption objects
                SymmetricCryptoKey encryptionKey = new SymmetricCryptoKey(SymmetricEncryptionAlgorithm.Rijndael, masterKey, eIV, PaddingMode.None);
                SymmetricCryptoKey decryptionKey = new SymmetricCryptoKey(SymmetricEncryptionAlgorithm.Rijndael, masterKey, dIV, PaddingMode.None);

                //enable encryption
                EnableEncryption(stream, encryptionKey, decryptionKey, new HMACSHA256(masterKey), new HMACSHA256(masterKey));
                break;

            default:
                throw new SecureChannelException(SecureChannelCode.NoMatchingCryptoAvailable, _remotePeerEP, _remotePeerCert);
            }

            //channel encryption is ON!

            #endregion

            #region 3. exchange & verify certificates & signatures

            if (!IsReNegotiating())
            {
                //read client certificate
                _remotePeerCert = (new SecureChannelPacket(this)).GetCertificate();

                //verify client certificate
                try
                {
                    _remotePeerCert.Verify(_trustedRootCertificates);
                }
                catch (Exception ex)
                {
                    throw new SecureChannelException(SecureChannelCode.InvalidRemoteCertificate, _remotePeerEP, _remotePeerCert, "Invalid remote certificate.", ex);
                }
            }

            //verify key exchange signature
            switch (_selectedCryptoOption)
            {
            case SecureChannelCryptoOptionFlags.DHE2048_RSA_WITH_AES256_CBC_HMAC_SHA256:
            case SecureChannelCryptoOptionFlags.ECDHE256_RSA_WITH_AES256_CBC_HMAC_SHA256:
                if (_remotePeerCert.PublicKeyEncryptionAlgorithm != AsymmetricEncryptionAlgorithm.RSA)
                {
                    throw new SecureChannelException(SecureChannelCode.InvalidRemoteCertificateAlgorithm, _remotePeerEP, _remotePeerCert);
                }

                if (!clientKeyExchange.IsSignatureValid(_remotePeerCert, "SHA256"))
                {
                    throw new SecureChannelException(SecureChannelCode.InvalidRemoteKeyExchangeSignature, _remotePeerEP, _remotePeerCert);
                }

                break;

            default:
                throw new SecureChannelException(SecureChannelCode.NoMatchingCryptoAvailable, _remotePeerEP, _remotePeerCert);
            }

            if ((_manager != null) && !_manager.ProceedConnection(_remotePeerCert))
            {
                throw new SecureChannelException(SecureChannelCode.SecurityManagerDeclinedAccess, _remotePeerEP, _remotePeerCert, "Security manager declined access.");
            }

            //send server certificate
            if (!IsReNegotiating())
            {
                SecureChannelPacket.WritePacket(this, _serverCredentials.Certificate);
            }

            #endregion
        }
        private void CreateInvitationPrivateChat(BinaryID hashedPeerEmailAddress, BinaryID networkID, IPEndPoint peerEP, string message)
        {
            BitChatNetwork network = new BitChatNetwork(_connectionManager, _trustedRootCertificates, _supportedCryptoOptions, hashedPeerEmailAddress, networkID, null, BitChatNetworkStatus.Offline, peerEP.ToString(), message);
            BitChat        chat    = CreateBitChat(network, BinaryID.GenerateRandomID160().ToString(), BinaryID.GenerateRandomID256().ID, 0, null, new BitChatProfile.SharedFileInfo[] { }, _profile.TrackerURIs, true, false, false);

            RaiseEventBitChatInvitationReceived(chat);
        }