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); } } }
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)); }
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); }