public EncryptedSocket(EncryptionTypes allowedEncryption) { #if NETSTANDARD1_5 random = RandomNumberGenerator.Create(); hasher = SHA1.Create(); #else random = RNGCryptoServiceProvider.Create(); hasher = HashAlgoFactory.Create <SHA1>(); #endif GenerateX(); GenerateY(); InitialPayload = BufferManager.EmptyBuffer; RemoteInitialPayload = BufferManager.EmptyBuffer; doneSendCallback = doneSend; doneReceiveCallback = doneReceive; doneReceiveYCallback = delegate { doneReceiveY(); }; doneSynchronizeCallback = delegate { doneSynchronize(); }; fillSynchronizeBytesCallback = fillSynchronizeBytes; bytesReceived = 0; SetMinCryptoAllowed(allowedEncryption); }
private void EndCheckEncryption(IAsyncResult result) { PeerId id = (PeerId)result.AsyncState; byte[] initialData; try { EncryptorFactory.EndCheckEncryption(result, out initialData); if (initialData != null && initialData.Length > 0) { throw new EncryptionException("unhandled initial data"); } EncryptionTypes e = engine.Settings.AllowedEncryption; if (id.Encryptor is RC4 && !Toolbox.HasEncryption(e, EncryptionTypes.RC4Full) || id.Encryptor is RC4Header && !Toolbox.HasEncryption(e, EncryptionTypes.RC4Header) || id.Encryptor is PlainTextEncryption && !Toolbox.HasEncryption(e, EncryptionTypes.PlainText)) { CleanupSocket(id, id.Encryptor.GetType().Name + " encryption is not enabled"); } else { // Create a handshake message to send to the peer HandshakeMessage handshake = new HandshakeMessage(id.TorrentManager.InfoHash, engine.PeerId, VersionInfo.ProtocolStringV100); SendMessage(id, handshake, this.handshakeSentCallback); } } catch { id.Peer.Encryption &= ~EncryptionTypes.RC4Full; id.Peer.Encryption &= ~EncryptionTypes.RC4Header; CleanupSocket(id, "Failed encryptor check"); } }
/// <summary> /// The method for encrypt or dncrypt the specified data. /// </summary> /// <param name="type">The type.</param> /// <param name="source">The source data for <paramref name="type"/>.</param> /// <param name="key">Gets or sets the secret key for the symmetric algorithm.</param> /// <param name="iv">The initialization vector (IV) to use to derive the key.</param> /// <param name="keySize">Size of the key.</param> /// <param name="mode">The mode.</param> /// <param name="padding">The padding.</param> /// <returns></returns> /// <exception cref="ArgumentNullException">source</exception> internal static byte[] EncryptOrDecrypt(EncryptionTypes type, byte[] source, byte[] key, byte[] iv, int keySize = 128, CipherMode mode = CipherMode.ECB, PaddingMode padding = PaddingMode.PKCS7) { ArgumentValidator.Validate(source, key); byte[] output = null; using (TSymmetricAlgorithm provider = new TSymmetricAlgorithm() { KeySize = keySize, Mode = mode, Padding = padding, Key = key }) { if (iv != null) { provider.IV = iv; } using (ICryptoTransform encryptor = type == EncryptionTypes.Encrypt ? provider.CreateEncryptor() : provider.CreateDecryptor()) { output = encryptor.TransformFinalBlock(source, 0, source.Length); } provider.Clear(); } return(output); }
public PeerBEncryption(InfoHash[] possibleSkeYs, EncryptionTypes allowedEncryption) : base(allowedEncryption) { _possibleSkeYs = possibleSkeYs; _gotVerificationCallback = GotVerification; _gotPadCCallback = GotPadC; }
public BroadcastMessageCommand(Guid[] clientList, string response, ResponseTypes responseType, MessageHeader header) { _clientList = clientList; _response = response; _responseType = responseType; _compressionType = header.CompressionType; _encryptionType = header.EncryptionHeader.EncryptionType; }
public PeerAEncryption(InfoHash infoHash, EncryptionTypes allowedEncryption) : base(allowedEncryption) { _gotVerificationCallback = GotVerification; _gotPadDCallback = GotPadD; SKEY = infoHash; }
public PeerAEncryption(InfoHash InfoHash, EncryptionTypes allowedEncryption) : base(allowedEncryption) { gotVerificationCallback = new AsyncCallback(gotVerification); gotPadDCallback = new AsyncCallback(gotPadD); SKEY = InfoHash; }
public PeerBEncryption(InfoHash[] possibleSKEYs, EncryptionTypes allowedEncryption) : base(allowedEncryption) { _possibleSKEYs = possibleSKEYs; _gotVerificationCallback = GotVerification; _gotPadCCallback = gotPadC; }
public PeerAEncryption(InfoHash infoHash, EncryptionTypes allowedEncryption) : base(allowedEncryption) { _gotVerificationCallback = GotVerification; _gotPadDCallback = GotPadD; Skey = infoHash; }
public SendServerResponseCommand(Guid clientId, string response, ResponseTypes responseType, MessageHeader header) { _clientId = clientId; _response = response; _responseType = responseType; _compressionType = header.CompressionType; _encryptionType = header.EncryptionHeader.EncryptionType; }
public PeerBEncryption(InfoHash[] possibleSKEYs, EncryptionTypes allowedEncryption) : base(allowedEncryption) { this.possibleSKEYs = possibleSKEYs; gotVerificationCallback = new AsyncCallback(gotVerification); gotPadCCallback = new AsyncCallback(gotPadC); }
public PeerAEncryption(InfoHash InfoHash, EncryptionTypes allowedEncryption) : base(allowedEncryption) { gotVerificationCallback = gotVerification; gotPadDCallback = gotPadD; SKEY = InfoHash; }
public static Encryption Generate(EncryptionTypes encryptionType, ArraySegment <byte> data, byte[] password) { if (encryptionType == EncryptionTypes.Aes256) { return(new Aes256Encryption(data, password)); } throw new ArgumentException(string.Format("Encryption type not implemented {0}", encryptionType)); }
async Task Handshake(EncryptionTypes outgoingEncryption, EncryptionTypes incomingEncryption, bool appendInitialPayload) { var handshakeIn = new HandshakeMessage(InfoHash, IncomingId, VersionInfo.ProtocolStringV100); var handshakeOut = new HandshakeMessage(InfoHash, OutgoingId, VersionInfo.ProtocolStringV100); var incomingTask = EncryptorFactory.CheckIncomingConnectionAsync(Incoming, incomingEncryption, new EngineSettings(), SKeys); var outgoingTask = EncryptorFactory.CheckOutgoingConnectionAsync(Outgoing, outgoingEncryption, new EngineSettings(), InfoHash, appendInitialPayload ? handshakeOut : null); // If the handshake was not part of the initial payload, send it now. var outgoingCrypto = await outgoingTask; if (!appendInitialPayload) { await PeerIO.SendMessageAsync(Outgoing, outgoingCrypto.Encryptor, handshakeOut, null, null, null); } // Receive the handshake and make sure it decrypted correctly. var incomingCrypto = await incomingTask; Assert.AreEqual(OutgoingId, incomingCrypto.Handshake.PeerId, "#1a"); // Send the other handshake. await PeerIO.SendMessageAsync(Incoming, incomingCrypto.Encryptor, handshakeIn, null, null, null); // Receive the other handshake and make sure it decrypted ok on the other side. handshakeIn = await PeerIO.ReceiveHandshakeAsync(Outgoing, outgoingCrypto.Decryptor); Assert.AreEqual(IncomingId, handshakeIn.PeerId, "#1b"); // Make sure we got the crypto we asked for. if (incomingEncryption == EncryptionTypes.PlainText) { Assert.IsInstanceOf <PlainTextEncryption> (incomingCrypto.Decryptor, "#2"); } else if (incomingEncryption == EncryptionTypes.RC4Full) { Assert.IsInstanceOf <RC4> (incomingCrypto.Decryptor, "#3"); } else if (incomingEncryption == EncryptionTypes.RC4Header) { Assert.IsInstanceOf <RC4Header> (incomingCrypto.Decryptor, "#4"); } if (outgoingEncryption == EncryptionTypes.PlainText) { Assert.IsInstanceOf <PlainTextEncryption> (outgoingCrypto.Decryptor, "#5"); } else if (outgoingEncryption == EncryptionTypes.RC4Full) { Assert.IsInstanceOf <RC4> (outgoingCrypto.Decryptor, "#6"); } else if (outgoingEncryption == EncryptionTypes.RC4Header) { Assert.IsInstanceOf <RC4Header> (outgoingCrypto.Decryptor, "#7"); } }
public static bool CheckEncryptionType(EncryptionTypes encryptionType, bool throwException) { var valid = Enum.IsDefined(typeof(EncryptionTypes), encryptionType); if (!valid && throwException) { throw new ArgumentException(string.Format("Invalid encryption type {0}", encryptionType)); } return(valid); }
public EngineSettings(string defaultSavePath, int listenPort, int globalMaxConnections, int globalHalfOpenConnections, int globalMaxDownloadSpeed, int globalMaxUploadSpeed, EncryptionTypes allowedEncryption) { this.globalMaxConnections = globalMaxConnections; this.globalMaxDownloadSpeed = globalMaxDownloadSpeed; this.globalMaxUploadSpeed = globalMaxUploadSpeed; this.globalMaxHalfOpenConnections = globalHalfOpenConnections; this.listenPort = listenPort; this.allowedEncryption = allowedEncryption; this.savePath = defaultSavePath; }
private void Handshake(EncryptionTypes encryptionA, EncryptionTypes encryptionB, bool addInitial) { HandshakeMessage m = new HandshakeMessage(rig.Torrent.InfoHash, "12345123451234512345", VersionInfo.ProtocolStringV100); byte[] handshake = m.Encode(); PeerAEncryption a = new PeerAEncryption(rig.Torrent.InfoHash, encryptionA); if (addInitial) { a.AddPayload(handshake); } PeerBEncryption b = new PeerBEncryption(new InfoHash[] { rig.Torrent.InfoHash }, encryptionB); var resultA = a.HandshakeAsync(conn.Outgoing); var resultB = b.HandshakeAsync(conn.Incoming); if (!Task.WhenAll(resultA, resultB).Wait(5000)) { Assert.Fail("Could not handshake"); } HandshakeMessage d = new HandshakeMessage(); if (!addInitial) { a.Encrypt(handshake, 0, handshake.Length); b.Decrypt(handshake, 0, handshake.Length); d.Decode(handshake, 0, handshake.Length); } else { d.Decode(b.InitialData, 0, b.InitialData.Length); } Assert.AreEqual(m, d); if (encryptionA == EncryptionTypes.RC4Full || encryptionB == EncryptionTypes.RC4Full) { Assert.IsTrue(a.Encryptor is RC4); Assert.IsTrue(b.Encryptor is RC4); } else if (encryptionA == EncryptionTypes.RC4Header || encryptionB == EncryptionTypes.RC4Header) { Assert.IsTrue(a.Encryptor is RC4Header); Assert.IsTrue(b.Encryptor is RC4Header); } else if (encryptionA == EncryptionTypes.PlainText || encryptionB == EncryptionTypes.PlainText) { Assert.IsTrue(a.Encryptor is PlainTextEncryption); Assert.IsTrue(b.Encryptor is PlainTextEncryption); } }
public Peer(string peerId, Uri connectionUri, EncryptionTypes encryption) { if (peerId == null) throw new ArgumentNullException("peerId"); if (connectionUri == null) throw new ArgumentNullException("connectionUri"); this.connectionUri = connectionUri; this.encryption = encryption; this.peerId = peerId; }
protected EncryptedSocket(EncryptionTypes allowedEncryption) { random = RandomNumberGenerator.Create(); hasher = HashAlgoFactory.Create <SHA1> (); X = new byte[20]; random.GetBytes(X); Y = ModuloCalculator.Calculate(ModuloCalculator.TWO, X); SetMinCryptoAllowed(allowedEncryption); }
private void PeerATest(EncryptionTypes encryption, bool addInitial) { rig.Engine.Settings.AllowedEncryption = encryption; rig.Engine.StartAll(); HandshakeMessage message = new HandshakeMessage(rig.Manager.InfoHash, "ABC123ABC123ABC123AB", VersionInfo.ProtocolStringV100); byte[] buffer = message.Encode(); PeerAEncryption a = new PeerAEncryption(rig.Manager.InfoHash, encryption); if (addInitial) { a.AddPayload(buffer); } rig.AddConnection(conn.Incoming); IAsyncResult result = a.BeginHandshake(conn.Outgoing, null, null); #if NETSTANDARD1_5 if (!result.AsyncWaitHandle.WaitOne(4000)) #else if (!result.AsyncWaitHandle.WaitOne(4000, true)) #endif { Assert.True(false, "Handshake timed out"); } a.EndHandshake(result); if (!addInitial) { a.Encryptor.Encrypt(buffer); conn.Outgoing.EndSend(conn.Outgoing.BeginSend(buffer, 0, buffer.Length, null, null)); } int received = conn.Outgoing.EndReceive(conn.Outgoing.BeginReceive(buffer, 0, buffer.Length, null, null)); Assert.True(68 == received, "Recived handshake"); a.Decryptor.Decrypt(buffer); message.Decode(buffer, 0, buffer.Length); Assert.Equal(VersionInfo.ProtocolStringV100, message.ProtocolString); if (encryption == EncryptionTypes.RC4Full) { Assert.True(a.Encryptor is RC4); } else if (encryption == EncryptionTypes.RC4Header) { Assert.True(a.Encryptor is RC4Header); } else if (encryption == EncryptionTypes.PlainText) { Assert.True(a.Encryptor is RC4Header); } }
static async ReusableTask <EncryptorResult> DoCheckIncomingConnectionAsync(IConnection2 connection, EncryptionTypes encryption, EngineSettings settings, InfoHash[] sKeys) { EncryptionTypes allowedEncryption = (settings?.AllowedEncryption ?? EncryptionTypes.All) & encryption; bool supportsRC4Header = allowedEncryption.HasFlag(EncryptionTypes.RC4Header); bool supportsRC4Full = allowedEncryption.HasFlag(EncryptionTypes.RC4Full); bool supportsPlainText = allowedEncryption.HasFlag(EncryptionTypes.PlainText); // If the connection is incoming, receive the handshake before // trying to decide what encryption to use var message = new HandshakeMessage(); using (ClientEngine.BufferPool.Rent(HandshakeMessage.HandshakeLength, out byte[] buffer)) {
public EngineSettings(StorageFolder defaultSaveFolder, int listenPort, int globalMaxConnections, int globalHalfOpenConnections, int globalMaxDownloadSpeed, int globalMaxUploadSpeed, EncryptionTypes allowedEncryption) { GlobalMaxConnections = globalMaxConnections; GlobalMaxDownloadSpeed = globalMaxDownloadSpeed; GlobalMaxUploadSpeed = globalMaxUploadSpeed; GlobalMaxHalfOpenConnections = globalHalfOpenConnections; ListenPort = listenPort; AllowedEncryption = allowedEncryption; SaveFolder = defaultSaveFolder; HaveSupressionEnabled = DefaultEnableHaveSupression; }
private void PeerATest(EncryptionTypes encryption, bool addInitial) { rig.Engine.Settings.AllowedEncryption = encryption; rig.Engine.StartAll(); var message = new HandshakeMessage(rig.Manager.InfoHash, "ABC123ABC123ABC123AB", VersionInfo.ProtocolStringV100); var buffer = message.Encode(); var a = new PeerAEncryption(rig.Manager.InfoHash, encryption); if (addInitial) { a.AddPayload(buffer); } rig.AddConnection(conn.Incoming); var result = a.BeginHandshake(conn.Outgoing, null, null); if (!result.AsyncWaitHandle.WaitOne(4000, true)) { Assert.Fail("Handshake timed out"); } a.EndHandshake(result); if (!addInitial) { a.Encryptor.Encrypt(buffer); conn.Outgoing.EndSend(conn.Outgoing.BeginSend(buffer, 0, buffer.Length, null, null)); } int received = conn.Outgoing.EndReceive(conn.Outgoing.BeginReceive(buffer, 0, buffer.Length, null, null)); Assert.AreEqual(68, received, "Recived handshake"); a.Decryptor.Decrypt(buffer); message.Decode(buffer, 0, buffer.Length); Assert.AreEqual(VersionInfo.ProtocolStringV100, message.ProtocolString); if (encryption == EncryptionTypes.RC4Full) { Assert.IsInstanceOf <RC4>(a.Encryptor); } else if (encryption == EncryptionTypes.RC4Header) { Assert.IsInstanceOf <RC4Header>(a.Encryptor); } else if (encryption == EncryptionTypes.PlainText) { Assert.IsInstanceOf <RC4Header>(a.Encryptor); } }
async Task PeerATest(EncryptionTypes encryption, bool addInitial) { rig.Engine.Settings.AllowedEncryption = encryption; await rig.Engine.StartAll(); HandshakeMessage message = new HandshakeMessage(rig.Manager.InfoHash, "ABC123ABC123ABC123AB", VersionInfo.ProtocolStringV100); byte[] buffer = message.Encode(); PeerAEncryption a = new PeerAEncryption(rig.Manager.InfoHash, encryption); if (addInitial) { a.AddPayload(buffer); } rig.AddConnection(conn.Incoming); var result = a.HandshakeAsync(conn.Outgoing); if (!result.Wait(4000)) { Assert.Fail("Handshake timed out"); } if (!addInitial) { a.Encryptor.Encrypt(buffer); await conn.Outgoing.SendAsync(buffer, 0, buffer.Length); } int received = await conn.Outgoing.ReceiveAsync(buffer, 0, buffer.Length); Assert.AreEqual(HandshakeMessage.HandshakeLength, received, "Recived handshake"); a.Decryptor.Decrypt(buffer); message.Decode(buffer, 0, buffer.Length); Assert.AreEqual(VersionInfo.ProtocolStringV100, message.ProtocolString); if (encryption == EncryptionTypes.RC4Full) { Assert.IsTrue(a.Encryptor is RC4); } else if (encryption == EncryptionTypes.RC4Header) { Assert.IsTrue(a.Encryptor is RC4Header); } else if (encryption == EncryptionTypes.PlainText) { Assert.IsTrue(a.Encryptor is RC4Header); } }
/// <summary> /// The method for encrypt or dncrypt the specified <paramref name="data"/> with <paramref name="password"/>, <paramref name="vector"/>, <paramref name="salt"/>. /// </summary> /// <param name="type">The type.</param> /// <param name="data">The string to be encrypted or decrypted,not null.</param> /// <param name="password">The password used to derive the key.</param> /// <param name="vector">The initialization vector (IV) to use to derive the key.</param> /// <param name="salt">The key salt to use to derive the key.The default is <paramref name="password"/>.</param> /// <param name="keySize">The size, in bits, of the secret key used by the symmetric algorithm.</param> /// <param name="blockSize">The block size, in bits, of the cryptographic operation.</param> /// <param name="encoding">The <see cref="T:System.Text.Encoding"/>,default is <see cref="Encoding.UTF8"/>.</param> /// <param name="iterations">The number of iterations for the operation.</param> /// <param name="mode">The mode for operation of the symmetric algorithm.</param> /// <param name="padding">The padding mode used in the symmetric algorithm. The default is System.Security.Cryptography.PaddingMode.PKCS7.</param> /// <returns>The array of <see cref="byte"/> value by <paramref name="type"/>. </returns> internal static byte[] EncryptOrDecryptBytes(EncryptionTypes type, string data, string password, string vector = null, string salt = null, int keySize = 128, int blockSize = 128, Encoding encoding = null, int iterations = 1000, CipherMode mode = CipherMode.ECB, PaddingMode padding = PaddingMode.PKCS7) { ArgumentValidator.Validate(data, password); if (encoding == null) { encoding = Encoding.UTF8; } return(EncryptOrDecrypt(type, type == EncryptionTypes.Encrypt ? encoding.GetBytes(data) : Convert.FromBase64String(data), GetKeyBytes(password, salt, keySize, encoding, iterations), GetVectorBytes(vector, blockSize, encoding) , keySize, mode, padding)); }
public Peer(string peerId, Uri connectionUri, EncryptionTypes encryption = EncryptionTypes.All) { if (peerId == null) { throw new ArgumentNullException("peerId"); } if (connectionUri == null) { throw new ArgumentNullException("connectionUri"); } _connectionUri = connectionUri; Encryption = encryption; PeerId = peerId; }
public EncryptedSocket(EncryptionTypes allowedEncryption) { random = RNGCryptoServiceProvider.Create(); hasher = HashAlgoFactory.Create <SHA1>(); GenerateX(); GenerateY(); InitialPayload = BufferManager.EmptyBuffer; RemoteInitialPayload = BufferManager.EmptyBuffer; bytesReceived = 0; SetMinCryptoAllowed(allowedEncryption); }
private static void HandshakeReceived(bool succeeded, int count, object state) { EncryptorAsyncResult result = (EncryptorAsyncResult)state; IConnection connection = result.Id.Connection; try { if (!succeeded) { throw new EncryptionException("Couldn't receive the handshake"); } result.Available += count; HandshakeMessage message = new HandshakeMessage(); message.Decode(result.Buffer, 0, result.Buffer.Length); bool valid = message.ProtocolString == VersionInfo.ProtocolStringV100; EncryptionTypes usable = CheckRC4(result.Id); bool canUseRC4 = Toolbox.HasEncryption(usable, EncryptionTypes.RC4Header) || Toolbox.HasEncryption(usable, EncryptionTypes.RC4Full); // If encryption is disabled and we received an invalid handshake - abort! if (valid) { result.InitialData = result.Buffer; result.Complete(); return; } if (!canUseRC4 && !valid) { result.Complete(new EncryptionException("Invalid handshake received and no decryption works")); return; } if (canUseRC4) { // The data we just received was part of an encrypted handshake and was *not* the BitTorrent handshake result.EncSocket = new PeerBEncryption(result.SKeys, EncryptionTypes.All); result.EncSocket.BeginHandshake(connection, result.Buffer, 0, result.Buffer.Length, CompletedEncryptedHandshakeCallback, result); } else { result.Complete(); } } catch (Exception ex) { result.Complete(ex); return; } }
private WaitHandle Announce(Tracker.Tracker tracker, TorrentEvent clientEvent, bool trySubsequent, ManualResetEvent waitHandle) { ClientEngine engine = _manager.Engine; // If the engine is null, we have been unregistered if (engine == null) { waitHandle.Set(); return(waitHandle); } UpdateSucceeded = true; LastUpdated = DateTime.Now; EncryptionTypes e = engine.Settings.AllowedEncryption; var requireEncryption = !Toolbox.HasEncryption(e, EncryptionTypes.PlainText); var supportsEncryption = Toolbox.HasEncryption(e, EncryptionTypes.RC4Full) || Toolbox.HasEncryption(e, EncryptionTypes.RC4Header); requireEncryption = requireEncryption && ClientEngine.SupportsEncryption; supportsEncryption = supportsEncryption && ClientEngine.SupportsEncryption; IPEndPoint reportedAddress = engine.Settings.ReportedAddress; var ip = reportedAddress?.Address.ToString(); int port = reportedAddress?.Port ?? engine.Listener.Endpoint.Port; // FIXME: In metadata mode we need to pretend we need to download data otherwise // tracker optimisations might result in no peers being sent back. long bytesLeft = 1000; if (_manager.HasMetadata) { bytesLeft = (long)((1 - _manager.Bitfield.PercentComplete / 100.0) * _manager.Torrent.Size); } var p = new AnnounceParameters(_manager.Monitor.DataBytesDownloaded, _manager.Monitor.DataBytesUploaded, bytesLeft, clientEvent, _infoHash, requireEncryption, _manager.Engine.PeerId, ip, port) { SupportsEncryption = supportsEncryption }; var id = new TrackerConnectionID(tracker, trySubsequent, clientEvent, waitHandle); tracker.Announce(p, id); return(waitHandle); }
private async Task Announce(ITracker tracker, TorrentEvent clientEvent, bool trySubsequent) { ClientEngine engine = manager.Engine; // If the engine is null, we have been unregistered if (engine == null) { return; } this.updateSucceeded = true; this.lastUpdated = DateTime.Now; EncryptionTypes e = engine.Settings.AllowedEncryption; bool requireEncryption = !Toolbox.HasEncryption(e, EncryptionTypes.PlainText); bool supportsEncryption = Toolbox.HasEncryption(e, EncryptionTypes.RC4Full) || Toolbox.HasEncryption(e, EncryptionTypes.RC4Header); requireEncryption = requireEncryption && ClientEngine.SupportsEncryption; supportsEncryption = supportsEncryption && ClientEngine.SupportsEncryption; IPEndPoint reportedAddress = engine.Settings.ReportedAddress; string ip = reportedAddress == null ? null : reportedAddress.Address.ToString(); int port = reportedAddress == null ? engine.Listener.Endpoint.Port : reportedAddress.Port; // FIXME: In metadata mode we need to pretend we need to download data otherwise // tracker optimisations might result in no peers being sent back. long bytesLeft = 1000; if (manager.HasMetadata) { bytesLeft = (long)((1 - this.manager.Bitfield.PercentComplete / 100.0) * this.manager.Torrent.Size); } AnnounceParameters p = new AnnounceParameters(this.manager.Monitor.DataBytesDownloaded, this.manager.Monitor.DataBytesUploaded, bytesLeft, clientEvent, this.infoHash, requireEncryption, manager.Engine.PeerId, ip, port); p.SupportsEncryption = supportsEncryption; try { var peers = await tracker.AnnounceAsync(p); await OnAnnounceComplete(tracker, peers, trySubsequent, clientEvent, true); } catch { await OnAnnounceComplete(tracker, new List <Peer>(), trySubsequent, clientEvent, false); } }
static async ReusableTask <EncryptorResult> DoCheckOutgoingConnectionAsync(IConnection2 connection, EncryptionTypes encryption, EngineSettings settings, InfoHash infoHash, HandshakeMessage handshake) { EncryptionTypes allowedEncryption = settings.AllowedEncryption & encryption; bool supportsRC4Header = allowedEncryption.HasFlag(EncryptionTypes.RC4Header); bool supportsRC4Full = allowedEncryption.HasFlag(EncryptionTypes.RC4Full); bool supportsPlainText = allowedEncryption.HasFlag(EncryptionTypes.PlainText); if ((settings.PreferEncryption || !supportsPlainText) && (supportsRC4Header || supportsRC4Full)) { // First switch to the threadpool as creating encrypted sockets runs expensive computations in the ctor await MainLoop.SwitchToThreadpool(); var encSocket = new PeerAEncryption(infoHash, allowedEncryption, handshake?.Encode()); await encSocket.HandshakeAsync(connection).ConfigureAwait(false); if (encSocket.Decryptor is RC4Header && !supportsRC4Header) { throw new EncryptionException("Decryptor was RC4Header but that is not allowed"); } if (encSocket.Decryptor is RC4 && !supportsRC4Full) { throw new EncryptionException("Decryptor was RC4Full but that is not allowed"); } return(new EncryptorResult(encSocket.Decryptor, encSocket.Encryptor, null)); } else if (supportsPlainText) { if (handshake != null) { int length = handshake.ByteLength; byte[] buffer = ClientEngine.BufferPool.Rent(length); handshake.Encode(buffer, 0); try { await NetworkIO.SendAsync(connection, buffer, 0, length, null, null, null).ConfigureAwait(false); } finally { ClientEngine.BufferPool.Return(buffer); } } return(new EncryptorResult(PlainTextEncryption.Instance, PlainTextEncryption.Instance, null)); } connection.Dispose(); throw new EncryptionException("Invalid handshake received and no decryption works"); }
public EncryptedSocket(EncryptionTypes allowedEncryption) { GenerateX(); GenerateY(); InitialPayload = BufferManager.EmptyBuffer; RemoteInitialPayload = BufferManager.EmptyBuffer; _doneSendCallback = DoneSend; _doneReceiveCallback = DoneReceive; _doneReceiveYCallback = delegate { DoneReceiveY(); }; _doneSynchronizeCallback = delegate { DoneSynchronize(); }; _fillSynchronizeBytesCallback = FillSynchronizeBytes; _bytesReceived = 0; SetMinCryptoAllowed(allowedEncryption); }
public EngineSettings(string defaultSavePath = DefaultSavePath, int listenPort = DefaultListenPort, int globalMaxConnections = DefaultMaxConnections, int globalHalfOpenConnections = DefaultMaxHalfOpenConnections, int globalMaxDownloadSpeed = DefaultMaxDownloadSpeed, int globalMaxUploadSpeed = DefaultMaxUploadSpeed, EncryptionTypes allowedEncryption = DefaultAllowedEncryption, string fastResumePath = null) { MaxOpenFiles = 15; GlobalMaxConnections = globalMaxConnections; GlobalMaxDownloadSpeed = globalMaxDownloadSpeed; GlobalMaxUploadSpeed = globalMaxUploadSpeed; GlobalMaxHalfOpenConnections = globalHalfOpenConnections; ListenPort = listenPort; AllowedEncryption = allowedEncryption; FastResumePath = fastResumePath; SavePath = defaultSavePath; }
protected void SetMinCryptoAllowed(EncryptionTypes allowedEncryption) { this.allowedEncryption = allowedEncryption; // EncryptionType is basically a bit position starting from the right. // This sets all bits in CryptoProvide 0 that is to the right of minCryptoAllowed. CryptoProvide[0] = CryptoProvide[1] = CryptoProvide[2] = CryptoProvide[3] = 0; if (allowedEncryption.HasFlag(EncryptionTypes.RC4Full)) { CryptoProvide[3] |= 1 << 1; } if (allowedEncryption.HasFlag(EncryptionTypes.RC4Header)) { CryptoProvide[3] |= 1; } }
public EncryptedSocket(EncryptionTypes allowedEncryption) { random = RandomNumberGenerator.Create(); hasher = HashAlgoFactory.Create<SHA1>(); GenerateX(); GenerateY(); InitialPayload = BufferManager.EmptyBuffer; RemoteInitialPayload = BufferManager.EmptyBuffer; doneSendCallback = doneSend; doneReceiveCallback = doneReceive; doneReceiveYCallback = delegate { doneReceiveY(); }; doneSynchronizeCallback = delegate { doneSynchronize(); }; fillSynchronizeBytesCallback = fillSynchronizeBytes; bytesReceived = 0; SetMinCryptoAllowed(allowedEncryption); }
private void PeerATest(EncryptionTypes encryption, bool addInitial) { rig.Engine.Settings.AllowedEncryption = encryption; rig.Engine.StartAll(); var message = new HandshakeMessage(rig.Manager.InfoHash, "ABC123ABC123ABC123AB", VersionInfo.ProtocolStringV100); var buffer = message.Encode(); var a = new PeerAEncryption(rig.Manager.InfoHash, encryption); if (addInitial) a.AddPayload(buffer); rig.AddConnection(conn.Incoming); var result = a.BeginHandshake(conn.Outgoing, null, null); if (!result.AsyncWaitHandle.WaitOne(4000, true)) Assert.True(false, "Handshake timed out"); a.EndHandshake(result); if (!addInitial) { a.Encryptor.Encrypt(buffer); conn.Outgoing.EndSend(conn.Outgoing.BeginSend(buffer, 0, buffer.Length, null, null)); } var received = conn.Outgoing.EndReceive(conn.Outgoing.BeginReceive(buffer, 0, buffer.Length, null, null)); Assert.Equal(68, received); a.Decryptor.Decrypt(buffer); message.Decode(buffer, 0, buffer.Length); Assert.Equal(VersionInfo.ProtocolStringV100, message.ProtocolString); if (encryption == EncryptionTypes.RC4Full) Assert.True(a.Encryptor is RC4); else if (encryption == EncryptionTypes.RC4Header) Assert.True(a.Encryptor is RC4Header); else if (encryption == EncryptionTypes.PlainText) Assert.True(a.Encryptor is RC4Header); }
public static RequestHeader BuildRequestHeader(EncryptionTypes encryptionType, CompressionTypes compressionType, RequestTypes requestType) { // first create headers EncryptionHeader encryptionHeader = new EncryptionHeader() { EncryptionType = encryptionType }; MessageHeader messageHeader = new MessageHeader() { CompressionType = compressionType, EncryptionHeader = encryptionHeader }; RequestHeader requestHeader = new RequestHeader() { RequestType = requestType, MessageHeader = messageHeader }; // send response header first return requestHeader; }
public EngineSettings(string defaultSavePath, int listenPort, int globalMaxConnections, int globalHalfOpenConnections, int globalMaxDownloadSpeed, int globalMaxUploadSpeed, EncryptionTypes allowedEncryption) { this.globalMaxConnections = globalMaxConnections; this.globalMaxDownloadSpeed = globalMaxDownloadSpeed; this.globalMaxUploadSpeed = globalMaxUploadSpeed; globalMaxHalfOpenConnections = globalHalfOpenConnections; this.listenPort = listenPort; this.allowedEncryption = allowedEncryption; savePath = defaultSavePath; }
private byte[] Y; // 2^X mod P #endregion Fields #region Constructors public EncryptedSocket(EncryptionTypes allowedEncryption) { random = RNGCryptoServiceProvider.Create(); hasher = SHA1.Create(); GenerateX(); GenerateY(); InitialPayload = new byte[0]; RemoteInitialPayload = new byte[0]; doneSendCallback = doneSend; doneReceiveCallback = doneReceive; doneReceiveYCallback = delegate { doneReceiveY(); }; doneSynchronizeCallback = delegate { doneSynchronize(); }; fillSynchronizeBytesCallback = fillSynchronizeBytes; bytesReceived = 0; SetMinCryptoAllowed(allowedEncryption); }
public Encryption(EncryptionTypes type) { m_EncryptionType = type; }
/// <summary> /// Static encrypt method /// </summary> public static string EncryptText(string inputText, EncryptionTypes type) { return new Encryption(type).Encrypt(inputText); }
private void PeerBTest(EncryptionTypes encryption) { rig.Engine.Settings.AllowedEncryption = encryption; rig.Engine.StartAll(); rig.AddConnection(conn.Outgoing); PeerBEncryption a = new PeerBEncryption(new byte[][] { rig.Manager.Torrent.InfoHash }, EncryptionTypes.All); IAsyncResult result = a.BeginHandshake(conn.Incoming, null, null); if (!result.AsyncWaitHandle.WaitOne(4000, true)) Assert.Fail("Handshake timed out"); a.EndHandshake(result); HandshakeMessage message = new HandshakeMessage(); byte[] buffer = new byte[68]; conn.Incoming.EndReceive(conn.Incoming.BeginReceive(buffer, 0, buffer.Length, null, null)); a.Decryptor.Decrypt(buffer); message.Decode(buffer, 0, buffer.Length); Assert.AreEqual(VersionInfo.ProtocolStringV100, message.ProtocolString); if (encryption == EncryptionTypes.RC4Full) Assert.IsTrue(a.Encryptor is RC4); else if (encryption == EncryptionTypes.RC4Header) Assert.IsTrue(a.Encryptor is RC4Header); else if (encryption == EncryptionTypes.PlainText) Assert.IsTrue(a.Encryptor is RC4Header); }
private void Handshake(EncryptionTypes encryptionA, EncryptionTypes encryptionB, bool addInitial) { bool doneA = false; bool doneB = false; HandshakeMessage m = new HandshakeMessage(rig.Torrent.InfoHash, "12345123451234512345", VersionInfo.ProtocolStringV100); byte[] handshake = m.Encode(); PeerAEncryption a = new PeerAEncryption(rig.Torrent.InfoHash, encryptionA); if (addInitial) a.AddPayload(handshake); PeerBEncryption b = new PeerBEncryption(new byte[][] { rig.Torrent.InfoHash }, encryptionB); IAsyncResult resultA = a.BeginHandshake(conn.Outgoing, null, null); IAsyncResult resultB = b.BeginHandshake(conn.Incoming, null, null); WaitHandle[] handles = new WaitHandle[] { resultA.AsyncWaitHandle, resultB.AsyncWaitHandle }; int count = 1000; while (!WaitHandle.WaitAll(handles, 5, true)) { if (!doneA && (doneA = resultA.IsCompleted)) a.EndHandshake(resultA); if (!doneB && (doneB = resultB.IsCompleted)) b.EndHandshake(resultB); if (count-- == 0) Assert.Fail("Could not handshake"); } if (!doneA) a.EndHandshake(resultA); if (!doneB) b.EndHandshake(resultB); HandshakeMessage d = new HandshakeMessage(); if (!addInitial) { a.Encrypt(handshake, 0, handshake.Length); b.Decrypt(handshake, 0, handshake.Length); d.Decode(handshake, 0, handshake.Length); } else { d.Decode(b.InitialData, 0, b.InitialData.Length); } Assert.AreEqual(m, d); if (encryptionA == EncryptionTypes.RC4Full || encryptionB == EncryptionTypes.RC4Full) { Assert.IsTrue(a.Encryptor is RC4); Assert.IsTrue(b.Encryptor is RC4); } else if (encryptionA == EncryptionTypes.RC4Header || encryptionB == EncryptionTypes.RC4Header) { Assert.IsTrue(a.Encryptor is RC4Header); Assert.IsTrue(b.Encryptor is RC4Header); } else if (encryptionA == EncryptionTypes.PlainText || encryptionB == EncryptionTypes.PlainText) { Assert.IsTrue(a.Encryptor is PlainTextEncryption); Assert.IsTrue(b.Encryptor is PlainTextEncryption); } }
protected void SetMinCryptoAllowed(EncryptionTypes allowedEncryption) { this.allowedEncryption = allowedEncryption; // EncryptionType is basically a bit position starting from the right. // This sets all bits in CryptoProvide 0 that is to the right of minCryptoAllowed. CryptoProvide[0] = CryptoProvide[1] = CryptoProvide[2] = CryptoProvide[3] = 0; if (Toolbox.HasEncryption(allowedEncryption, EncryptionTypes.RC4Full)) CryptoProvide[3] |= 1 << 1; if (Toolbox.HasEncryption(allowedEncryption, EncryptionTypes.RC4Header)) CryptoProvide[3] |= 1; }