public bool SendPacket(Packet packet, uint dwIP, ushort nPort, bool bEncrypt, byte[] pachTargetClientHashORKadID, bool bKad, uint nReceiverVerifyKey) { UDPPack newpending = new UDPPack(); newpending.dwIP = dwIP; newpending.nPort = nPort; newpending.packet = packet; newpending.dwTime = MpdUtilities.GetTickCount(); newpending.bEncrypt = bEncrypt && (pachTargetClientHashORKadID != null || (bKad && nReceiverVerifyKey != 0)); newpending.bKad = bKad; newpending.nReceiverVerifyKey = nReceiverVerifyKey; if (newpending.bEncrypt && pachTargetClientHashORKadID != null) { MpdUtilities.Md4Cpy(newpending.pachTargetClientHashORKadID, pachTargetClientHashORKadID); } else { MpdUtilities.Md4Clr(newpending.pachTargetClientHashORKadID); } lock (sendLocker_) { controlpacketQueue_.Add(newpending); }// sendLocker.Unlock(); MuleApplication.Instance.UploadBandwidthThrottler.QueueForSendingControlPacket(this); return(true); }
public DeadSource(byte[] paucHash) { id_ = 0; serverIP_ = 0; port_ = 0; kadPort_ = 0; MpdUtilities.Md4Cpy(hash_, paucHash); }
public DeadSource(DeadSource ds) { id_ = ds.id_; serverIP_ = ds.serverIP_; port_ = ds.port_; kadPort_ = ds.kadPort_; MpdUtilities.Md4Cpy(hash_, ds.hash_); }
public ClientCreditsImpl(byte[] key) { credits_ = new CreditStruct(); MpdUtilities.Md4Cpy(credits_.abyKey, key); InitalizeIdent(); unSecureWaitTime_ = MpdUtilities.GetTickCount(); secureWaitTime_ = MpdUtilities.GetTickCount(); waitTimeIP_ = 0; }
public MapSKey(byte[] key) { if (key != null) { MpdUtilities.Md4Cpy(key_, key); } else { MpdUtilities.Md4Clr(key_); } }
public void SetConnectionEncryption(bool bEnabled, byte[] pTargetClientHash, bool bServerConnection) { if (streamCryptState_ != StreamCryptStateEnum.ECS_UNKNOWN && streamCryptState_ != StreamCryptStateEnum.ECS_NONE) { if (!(streamCryptState_ == StreamCryptStateEnum.ECS_NONE) || bEnabled) { Debug.Assert(false); } return; } Debug.Assert(rc4SendKey_ == null); Debug.Assert(rc4ReceiveKey_ == null); if (bEnabled && pTargetClientHash != null && !bServerConnection) { streamCryptState_ = StreamCryptStateEnum.ECS_PENDING; // create obfuscation keys, see on top for key format // use the crypt random generator randomKeyPart_ = MpdUtilities.GetRandomUInt32(); byte[] achKeyData = new byte[21]; MpdUtilities.Md4Cpy(achKeyData, pTargetClientHash); Array.Copy(BitConverter.GetBytes(randomKeyPart_), 0, achKeyData, 17, 4); achKeyData[16] = Convert.ToByte(MuleConstants.MAGICVALUE_REQUESTER); MD5 md5 = MD5.Create(); rc4SendKey_ = MuleUtilities.RC4CreateKey(md5.ComputeHash(achKeyData), 16); achKeyData[16] = Convert.ToByte(MuleConstants.MAGICVALUE_SERVER); rc4ReceiveKey_ = MuleUtilities.RC4CreateKey(md5.ComputeHash(achKeyData), 16); } else if (bServerConnection && bEnabled) { serverCrypt_ = true; streamCryptState_ = StreamCryptStateEnum.ECS_PENDING_SERVER; } else { Debug.Assert(!bEnabled); streamCryptState_ = StreamCryptStateEnum.ECS_NONE; } }
public FileIdentifierImpl(FileIdentifier rFileIdentifier, ulong rFileSize) : base(rFileIdentifier) { m_rFileSize = rFileSize; for (int i = 0; i < rFileIdentifier.RawMD4HashSet.Count; i++) { byte[] pucHashSetPart = new byte[16]; MpdUtilities.Md4Cpy(pucHashSetPart, rFileIdentifier.RawMD4HashSet[i]); m_aMD4HashSet.Add(pucHashSetPart); } for (int i = 0; i < rFileIdentifier.RawAICHHashSet.Count; i++) { m_aAICHPartHashSet.Add(rFileIdentifier.RawAICHHashSet[i]); } }
public bool LoadMD4HashsetFromFile(Mpd.Generic.IO.FileDataIO file, bool bVerifyExistingHash) { byte[] checkid = new byte[16]; file.ReadHash16(checkid); DeleteMD4Hashset(); uint parts = file.ReadUInt16(); //TRACE("Nr. hashs: %u\n", (uint)parts); if (bVerifyExistingHash && (MpdUtilities.Md4Cmp(MD4Hash, checkid) != 0 || parts != TheoreticalMD4PartHashCount)) { return(false); } for (uint i = 0; i < parts; i++) { byte[] cur_hash = new byte[16]; file.ReadHash16(cur_hash); m_aMD4HashSet.Add(cur_hash); } if (!bVerifyExistingHash) { MpdUtilities.Md4Cpy(MD4Hash, checkid); } // Calculate hash out of hashset and compare to existing filehash if (m_aMD4HashSet.Count > 0) { return(CalculateMD4HashByHashSet(true, true)); } else { return(true); } }
public bool CalculateMD4HashByHashSet(bool bVerifyOnly, bool bDeleteOnVerifyFail) { if (m_aMD4HashSet.Count <= 1) { return(false); } byte[] buffer = new byte[m_aMD4HashSet.Count * 16]; for (int i = 0; i < m_aMD4HashSet.Count; i++) { MpdUtilities.Md4Cpy(buffer, i * 16, m_aMD4HashSet[i], 0, m_aMD4HashSet[i].Length); } byte[] aucResult = new byte[16]; KnownFile knownFile = MuleApplication.Instance.FileObjectManager.CreateKnownFile(); knownFile.CreateHash(buffer, (ulong)m_aMD4HashSet.Count * 16, aucResult); if (bVerifyOnly) { if (MpdUtilities.Md4Cmp(aucResult, MD4Hash) != 0) { if (bDeleteOnVerifyFail) { DeleteMD4Hashset(); } return(false); } else { return(true); } } else { MpdUtilities.Md4Cpy(MD4Hash, aucResult); return(true); } }
public bool InitFromLink(string sLink) { ED2KLink pLink = null; ED2KFileLink pFileLink = null; try { pLink = MuleApplication.Instance.ED2KObjectManager.CreateLinkFromUrl(sLink); if (pLink == null) { throw new Exception("Not a Valid file link:" + sLink); } pFileLink = pLink.FileLink; if (pFileLink == null) { throw new Exception("Not a Valid file link:" + sLink); } } catch (Exception) { //TODO:Log return(false); } tagList_.Add(MpdObjectManager.CreateTag(MuleConstants.FT_FILEHASH, pFileLink.HashKey)); MpdUtilities.Md4Cpy(FileHash, pFileLink.HashKey); tagList_.Add(MpdObjectManager.CreateTag(MuleConstants.FT_FILESIZE, pFileLink.Size, true)); FileSize = pFileLink.Size; tagList_.Add(MpdObjectManager.CreateTag(MuleConstants.FT_FILENAME, pFileLink.Name)); SetFileName(pFileLink.Name, false, false, false); return(true); }
public MapSKey(MapSKey key) { MpdUtilities.Md4Cpy(key_, key.key_); }
public virtual int DecryptReceivedClient(byte[] pbyBufIn, int nBufLen, out byte[] ppbyBufOut, uint dwIP, out uint nReceiverVerifyKey, out uint nSenderVerifyKey) { int nResult = nBufLen; ppbyBufOut = pbyBufIn; nReceiverVerifyKey = 0; nSenderVerifyKey = 0; if (nResult <= CRYPT_HEADER_WITHOUTPADDING /*|| !MuleApplication.Instance.Preference.IsClientCryptLayerSupported()*/) { return(nResult); } switch (pbyBufIn[0]) { case MuleConstants.PROTOCOL_EMULEPROT: case MuleConstants.PROTOCOL_KADEMLIAPACKEDPROT: case MuleConstants.PROTOCOL_KADEMLIAHEADER: case MuleConstants.PROTOCOL_UDPRESERVEDPROT1: case MuleConstants.PROTOCOL_UDPRESERVEDPROT2: case MuleConstants.PROTOCOL_PACKEDPROT: return(nResult); // no encrypted packet (see description on top) } // might be an encrypted packet, try to decrypt RC4Key keyReceiveKey = null; uint dwValue = 0; // check the marker bit which type this packet could be and which key to test first, this is only an indicator since old clients have it set random // see the header for marker bits explanation byte byCurrentTry = (byte)(((pbyBufIn[0] & 0x03) == 3) ? 1 : (pbyBufIn[0] & 0x03)); byte byTries; if (MuleApplication.Instance.KadEngine.Preference == null) { // if kad never run, no point in checking anything except for ed2k encryption byTries = 1; byCurrentTry = 1; } else { byTries = 3; } bool bKadRecvKeyUsed = false; bool bKad = false; do { byTries--; MD5 md5 = MD5.Create(); byte[] rawHash = null; if (byCurrentTry == 0) { // kad packet with NodeID as key bKad = true; bKadRecvKeyUsed = false; if (MuleApplication.Instance.KadEngine.Preference != null) { byte[] achKeyData = new byte[18]; Array.Copy(MuleApplication.Instance.KadEngine.Preference.KadID.Bytes, 0, achKeyData, 0, 16); Array.Copy(pbyBufIn, 1, achKeyData, 16, 2); // random key part sent from remote client rawHash = md5.ComputeHash(achKeyData); } } else if (byCurrentTry == 1) { // ed2k packet bKad = false; bKadRecvKeyUsed = false; byte[] achKeyData = new byte[23]; MpdUtilities.Md4Cpy(achKeyData, MuleApplication.Instance.Preference.UserHash); achKeyData[20] = MAGICVALUE_UDP; Array.Copy(BitConverter.GetBytes(dwIP), 0, achKeyData, 16, 4); Array.Copy(pbyBufIn, 1, achKeyData, 21, 2); // random key part sent from remote client rawHash = md5.ComputeHash(achKeyData); } else if (byCurrentTry == 2) { // kad packet with ReceiverKey as key bKad = true; bKadRecvKeyUsed = true; if (MuleApplication.Instance.KadEngine.Preference != null) { byte[] achKeyData = new byte[6]; Array.Copy(BitConverter.GetBytes(MuleApplication.Instance.KadEngine.Preference.GetUDPVerifyKey(dwIP)), achKeyData, 4); Array.Copy(pbyBufIn, 1, achKeyData, 4, 2); // random key part sent from remote client rawHash = md5.ComputeHash(achKeyData); } } else { Debug.Assert(false); } MuleUtilities.RC4CreateKey(rawHash, 16, ref keyReceiveKey, true); byte[] outBuf = new byte[4]; MuleUtilities.RC4Crypt(pbyBufIn, 3, outBuf, 0, 4, keyReceiveKey); dwIP = BitConverter.ToUInt32(outBuf, 0); byCurrentTry = (byte)((byCurrentTry + 1) % 3); } while (dwValue != MAGICVALUE_UDP_SYNC_CLIENT && byTries > 0); // try to decrypt as ed2k as well as kad packet if needed (max 3 rounds) if (dwValue == MAGICVALUE_UDP_SYNC_CLIENT) { // yup this is an encrypted packet // debugoutput notices // the following cases are "allowed" but shouldn't happen given that there is only our implementation yet if (bKad && (pbyBufIn[0] & 0x01) != 0) { MpdUtilities.DebugLog( string.Format("Received obfuscated UDP packet from clientIP: {0} with wrong key marker bits (kad packet, ed2k bit)", MpdUtilities.IP2String(dwIP))); } else if (bKad && !bKadRecvKeyUsed && (pbyBufIn[0] & 0x02) != 0) { MpdUtilities.DebugLog( string.Format("Received obfuscated UDP packet from clientIP: {0} with wrong key marker bits (kad packet, nodeid key, recvkey bit)", MpdUtilities.IP2String(dwIP))); } else if (bKad && bKadRecvKeyUsed && (pbyBufIn[0] & 0x02) == 0) { MpdUtilities.DebugLog( string.Format("Received obfuscated UDP packet from clientIP: {0} with wrong key marker bits (kad packet, recvkey key, nodeid bit)", MpdUtilities.IP2String(dwIP))); } byte byPadLen; byte[] outBuf = new byte[1]; MuleUtilities.RC4Crypt(pbyBufIn, 7, outBuf, 0, 1, keyReceiveKey); byPadLen = outBuf[0]; nResult -= CRYPT_HEADER_WITHOUTPADDING; if (nResult <= byPadLen) { MpdUtilities.DebugLogError( string.Format("Invalid obfuscated UDP packet from clientIP: {0}, Paddingsize ({1}) larger than received bytes", MpdUtilities.IP2String(dwIP), byPadLen)); return(nBufLen); // pass through, let the Receivefunction do the errorhandling on this junk } if (byPadLen > 0) { MuleUtilities.RC4Crypt(null, null, byPadLen, keyReceiveKey); } nResult -= byPadLen; if (bKad) { if (nResult <= 8) { MpdUtilities.DebugLogError( string.Format("Obfuscated Kad packet with mismatching size (verify keys missing) received from clientIP: {0}", MpdUtilities.IP2String(dwIP))); return(nBufLen); // pass through, let the Receivefunction do the errorhandling on this junk; } // read the verify keys outBuf = new byte[4]; MuleUtilities.RC4Crypt(pbyBufIn, (int)(CRYPT_HEADER_WITHOUTPADDING + byPadLen), outBuf, 0, 4, keyReceiveKey); nReceiverVerifyKey = BitConverter.ToUInt32(outBuf, 0); MuleUtilities.RC4Crypt(pbyBufIn, (int)(CRYPT_HEADER_WITHOUTPADDING + byPadLen + 4), outBuf, 0, 4, keyReceiveKey); nSenderVerifyKey = BitConverter.ToUInt32(outBuf, 0); nResult -= 8; } ppbyBufOut = new byte[nResult]; Array.Copy(pbyBufIn, (nBufLen - nResult), ppbyBufOut, 0, nResult); MuleUtilities.RC4Crypt(ppbyBufOut, ppbyBufOut, (uint)nResult, keyReceiveKey); MuleApplication.Instance.Statistics.AddDownDataOverheadCrypt((uint)(nBufLen - nResult)); //DEBUG_ONLY( MpdUtilities.DebugLog(("Received obfuscated UDP packet from clientIP: %s, Key: %s, RKey: %u, SKey: %u"), MpdUtilities.IP2String(dwIP), bKad ? (bKadRecvKeyUsed ? ("ReceiverKey") : ("NodeID")) : ("UserHash") // , nReceiverVerifyKey != 0 ? *nReceiverVerifyKey : 0, nSenderVerifyKey != 0 ? *nSenderVerifyKey : 0) ); return(nResult); // done } else { MpdUtilities.DebugLogWarning( string.Format("Obfuscated packet expected but magicvalue mismatch on UDP packet from clientIP: {0}, Possible RecvKey: {1}", MpdUtilities.IP2String(dwIP), MuleApplication.Instance.KadEngine.Preference.GetUDPVerifyKey(dwIP))); return(nBufLen); // pass through, let the Receivefunction do the errorhandling on this junk } }
public virtual int EncryptSendClient(ref byte[] ppbyBuf, int nBufLen, byte[] pachClientHashOrKadID, bool bKad, uint nReceiverVerifyKey, uint nSenderVerifyKey) { Debug.Assert(MuleApplication.Instance.PublicIP != 0 || bKad); Debug.Assert(MuleApplication.Instance.Preference.IsClientCryptLayerSupported); Debug.Assert(pachClientHashOrKadID != null || nReceiverVerifyKey != 0); Debug.Assert((nReceiverVerifyKey == 0 && nSenderVerifyKey == 0) || bKad); byte byPadLen = 0; // padding disabled for UDP currently int nCryptHeaderLen = byPadLen + CRYPT_HEADER_WITHOUTPADDING + (bKad ? 8 : 0); int nCryptedLen = nBufLen + nCryptHeaderLen; byte[] pachCryptedBuffer = new byte[nCryptedLen]; bool bKadRecKeyUsed = false; ushort nRandomKeyPart = MpdUtilities.GetRandomUInt16(); MD5 md5 = MD5.Create(); byte[] rawHash = null; if (bKad) { if ((pachClientHashOrKadID == null || MpdUtilities.IsNullMd4(pachClientHashOrKadID)) && nReceiverVerifyKey != 0) { bKadRecKeyUsed = true; byte[] achKeyData = new byte[6]; Array.Copy(BitConverter.GetBytes(nReceiverVerifyKey), achKeyData, 4); Array.Copy(BitConverter.GetBytes(nRandomKeyPart), 0, achKeyData, 4, 2); rawHash = md5.ComputeHash(achKeyData); //DEBUG_ONLY( DebugLog(_T("Creating obfuscated Kad packet encrypted by ReceiverKey (%u)"), nReceiverVerifyKey) ); } else if (pachClientHashOrKadID != null && !MpdUtilities.IsNullMd4(pachClientHashOrKadID)) { byte[] achKeyData = new byte[18]; MpdUtilities.Md4Cpy(achKeyData, pachClientHashOrKadID); Array.Copy(BitConverter.GetBytes(nRandomKeyPart), 0, achKeyData, 16, 2); rawHash = md5.ComputeHash(achKeyData); //DEBUG_ONLY( DebugLog(_T("Creating obfuscated Kad packet encrypted by Hash/NodeID %s"), md4str(pachClientHashOrKadID)) ); } else { ppbyBuf = null; Debug.Assert(false); return(nBufLen); } } else { byte[] achKeyData = new byte[23]; MpdUtilities.Md4Cpy(achKeyData, pachClientHashOrKadID); uint dwIP = (uint)MuleApplication.Instance.PublicIP; Array.Copy(BitConverter.GetBytes(dwIP), 0, achKeyData, 16, 4); Array.Copy(BitConverter.GetBytes(nRandomKeyPart), 0, achKeyData, 21, 2); achKeyData[20] = MAGICVALUE_UDP; rawHash = md5.ComputeHash(achKeyData); } RC4Key keySendKey = null; MuleUtilities.RC4CreateKey(rawHash, 16, ref keySendKey, true); // create the semi random byte encryption header byte bySemiRandomNotProtocolMarker = 0; int i; for (i = 0; i < 128; i++) { bySemiRandomNotProtocolMarker = MpdUtilities.GetRandomUInt8(); bySemiRandomNotProtocolMarker = (byte)(bKad ? (bySemiRandomNotProtocolMarker & 0xFE) : (bySemiRandomNotProtocolMarker | 0x01)); // set the ed2k/kad marker bit if (bKad) { bySemiRandomNotProtocolMarker = (byte)(bKadRecKeyUsed ? ((bySemiRandomNotProtocolMarker & 0xFE) | 0x02) : (bySemiRandomNotProtocolMarker & 0xFC)); // set the ed2k/kad and nodeid/reckey markerbit } else { bySemiRandomNotProtocolMarker = (byte)(bySemiRandomNotProtocolMarker | 0x01); // set the ed2k/kad marker bit } bool bOk = false; switch (bySemiRandomNotProtocolMarker) { // not allowed values case MuleConstants.PROTOCOL_EMULEPROT: case MuleConstants.PROTOCOL_KADEMLIAPACKEDPROT: case MuleConstants.PROTOCOL_KADEMLIAHEADER: case MuleConstants.PROTOCOL_UDPRESERVEDPROT1: case MuleConstants.PROTOCOL_UDPRESERVEDPROT2: case MuleConstants.PROTOCOL_PACKEDPROT: break; default: bOk = true; break; } if (bOk) { break; } } if (i >= 128) { // either we have _really_ bad luck or the randomgenerator is a bit messed up Debug.Assert(false); bySemiRandomNotProtocolMarker = 0x01; } uint dwMagicValue = MAGICVALUE_UDP_SYNC_CLIENT; pachCryptedBuffer[0] = bySemiRandomNotProtocolMarker; Array.Copy(BitConverter.GetBytes(nRandomKeyPart), 0, pachCryptedBuffer, 1, 2); MuleUtilities.RC4Crypt(BitConverter.GetBytes(dwMagicValue), 0, pachCryptedBuffer, 3, 4, keySendKey); MuleUtilities.RC4Crypt(BitConverter.GetBytes(byPadLen), 0, pachCryptedBuffer, 7, 1, keySendKey); Random rand = new Random(); for (int j = 0; j < byPadLen; j++) { byte byRand = (byte)rand.Next(255); // they actually dont really need to be random, but it doesn't hurts either MuleUtilities.RC4Crypt(BitConverter.GetBytes(byRand), 0, pachCryptedBuffer, CRYPT_HEADER_WITHOUTPADDING + j, 1, keySendKey); } if (bKad) { MuleUtilities.RC4Crypt(BitConverter.GetBytes(nReceiverVerifyKey), 0, pachCryptedBuffer, CRYPT_HEADER_WITHOUTPADDING + byPadLen, 4, keySendKey); MuleUtilities.RC4Crypt(BitConverter.GetBytes(nSenderVerifyKey), 0, pachCryptedBuffer, CRYPT_HEADER_WITHOUTPADDING + byPadLen + 4, 4, keySendKey); } MuleUtilities.RC4Crypt(ppbyBuf, 0, pachCryptedBuffer, nCryptHeaderLen, (uint)nBufLen, keySendKey); ppbyBuf = pachCryptedBuffer; MuleApplication.Instance.Statistics.AddUpDataOverheadCrypt((uint)(nCryptedLen - nBufLen)); return(nCryptedLen); }
private int Negotiate(byte[] pBuffer, int offset, int nLen) { int nRead = 0; Debug.Assert(receiveBytesWanted_ > 0); try { while (negotiatingState_ != NegotiatingStateEnum.ONS_COMPLETE && receiveBytesWanted_ > 0) { if (receiveBytesWanted_ > 512) { Debug.Assert(false); return(0); } if (fiReceiveBuffer_ == null) { byte[] pReceiveBuffer = new byte[512]; // use a fixed size buffer fiReceiveBuffer_ = MpdObjectManager.CreateSafeMemFile(pReceiveBuffer); } int nToRead = Math.Min(Convert.ToInt32(nLen) - nRead, Convert.ToInt32(receiveBytesWanted_)); fiReceiveBuffer_.Write(pBuffer, nRead, nToRead); nRead += nToRead; receiveBytesWanted_ -= Convert.ToUInt32(nToRead); if (receiveBytesWanted_ > 0) { return(nRead); } uint nCurrentBytesLen = (uint)fiReceiveBuffer_.Position; if (negotiatingState_ != NegotiatingStateEnum.ONS_BASIC_CLIENTA_RANDOMPART && negotiatingState_ != NegotiatingStateEnum.ONS_BASIC_SERVER_DHANSWER) { // don't have the keys yet byte[] pCryptBuffer = fiReceiveBuffer_.Buffer; MuleUtilities.RC4Crypt(pCryptBuffer, pCryptBuffer, nCurrentBytesLen, rc4ReceiveKey_); } fiReceiveBuffer_.SeekToBegin(); switch (negotiatingState_) { case NegotiatingStateEnum.ONS_NONE: // would be a bug Debug.Assert(false); return(0); case NegotiatingStateEnum.ONS_BASIC_CLIENTA_RANDOMPART: { Debug.Assert(rc4ReceiveKey_ == null); byte[] achKeyData = new byte[21]; MpdUtilities.Md4Cpy(achKeyData, MuleApplication.Instance.Preference.UserHash); achKeyData[16] = Convert.ToByte(MuleConstants.MAGICVALUE_REQUESTER); fiReceiveBuffer_.Read(achKeyData, 17, 4); // random key part sent from remote client MD5 md5 = MD5.Create(); rc4ReceiveKey_ = MuleUtilities.RC4CreateKey(md5.ComputeHash(achKeyData), 16); achKeyData[16] = Convert.ToByte(MuleConstants.MAGICVALUE_SERVER); rc4SendKey_ = MuleUtilities.RC4CreateKey(md5.ComputeHash(achKeyData), 16); negotiatingState_ = NegotiatingStateEnum.ONS_BASIC_CLIENTA_MAGICVALUE; receiveBytesWanted_ = 4; break; } case NegotiatingStateEnum.ONS_BASIC_CLIENTA_MAGICVALUE: { uint dwValue = fiReceiveBuffer_.ReadUInt32(); if (dwValue == MuleConstants.MAGICVALUE_SYNC) { // yup, the one or the other way it worked, this is an encrypted stream //DEBUG_ONLY( MpdUtilities.DebugLog(("Received proper magic value, clientIP: %s"), DbgGetIPString()) ); // set the receiver key negotiatingState_ = NegotiatingStateEnum.ONS_BASIC_CLIENTA_METHODTAGSPADLEN; receiveBytesWanted_ = 3; } else { MpdUtilities.DebugLogError(("CEncryptedStreamSocket: Received wrong magic value from clientIP %s on a supposly encrytped stream / Wrong Header"), DbgGetIPString()); OnError(Convert.ToInt32(EMSocketErrorCodeEnum.ERR_ENCRYPTION)); return(-1); } break; } case NegotiatingStateEnum.ONS_BASIC_CLIENTA_METHODTAGSPADLEN: DbgByEncryptionSupported = fiReceiveBuffer_.ReadUInt8(); DbgByEncryptionRequested = fiReceiveBuffer_.ReadUInt8(); if (DbgByEncryptionRequested != Convert.ToByte(EncryptionMethodsEnum.ENM_OBFUSCATION)) { MpdUtilities.AddDebugLogLine(EDebugLogPriority.DLP_LOW, false, ("CEncryptedStreamSocket: Client %s preffered unsupported encryption method (%i)"), DbgGetIPString(), DbgByEncryptionRequested); } receiveBytesWanted_ = fiReceiveBuffer_.ReadUInt8(); negotiatingState_ = NegotiatingStateEnum.ONS_BASIC_CLIENTA_PADDING; if (receiveBytesWanted_ > 0) { break; } else { goto case NegotiatingStateEnum.ONS_BASIC_CLIENTA_PADDING; } case NegotiatingStateEnum.ONS_BASIC_CLIENTA_PADDING: { // ignore the random bytes, send the response, set status complete SafeMemFile fileResponse = MpdObjectManager.CreateSafeMemFile(26); fileResponse.WriteUInt32(MuleConstants.MAGICVALUE_SYNC); byte bySelectedEncryptionMethod = Convert.ToByte(EncryptionMethodsEnum.ENM_OBFUSCATION); // we do not support any further encryption in this version, so no need to look which the other client preferred fileResponse.WriteUInt8(bySelectedEncryptionMethod); IPEndPoint remoteEp = RemoteEndPoint as IPEndPoint; byte byPaddingLen = MuleApplication.Instance.ServerConnect.AwaitingTestFromIP(BitConverter.ToUInt32(remoteEp.Address.GetAddressBytes(), 0)) ? Convert.ToByte(16) : Convert.ToByte(MuleApplication.Instance.Preference.CryptTCPPaddingLength + 1); byte byPadding = Convert.ToByte(MpdUtilities.GetRandomUInt8() % byPaddingLen); fileResponse.WriteUInt8(byPadding); for (int i = 0; i < byPadding; i++) { fileResponse.WriteUInt8(MpdUtilities.GetRandomUInt8()); } SendNegotiatingData(fileResponse.Buffer, (uint)fileResponse.Length); negotiatingState_ = NegotiatingStateEnum.ONS_COMPLETE; streamCryptState_ = StreamCryptStateEnum.ECS_ENCRYPTING; //DEBUG_ONLY( MpdUtilities.DebugLog(("CEncryptedStreamSocket: Finished Obufscation handshake with client %s (incoming)"), DbgGetIPString()) ); break; } case NegotiatingStateEnum.ONS_BASIC_CLIENTB_MAGICVALUE: { if (fiReceiveBuffer_.ReadUInt32() != MuleConstants.MAGICVALUE_SYNC) { MpdUtilities.DebugLogError(("CEncryptedStreamSocket: EncryptedstreamSyncError: Client sent wrong Magic Value as answer, cannot complete handshake (%s)"), DbgGetIPString()); OnError(Convert.ToInt32(EMSocketErrorCodeEnum.ERR_ENCRYPTION)); return(-1); } negotiatingState_ = NegotiatingStateEnum.ONS_BASIC_CLIENTB_METHODTAGSPADLEN; receiveBytesWanted_ = 2; break; } case NegotiatingStateEnum.ONS_BASIC_CLIENTB_METHODTAGSPADLEN: { DbgByEncryptionMethodSet = fiReceiveBuffer_.ReadUInt8(); if (DbgByEncryptionMethodSet != Convert.ToByte(EncryptionMethodsEnum.ENM_OBFUSCATION)) { MpdUtilities.DebugLogError(("CEncryptedStreamSocket: Client %s set unsupported encryption method (%i), handshake failed"), DbgGetIPString(), DbgByEncryptionMethodSet); OnError(Convert.ToInt32(EMSocketErrorCodeEnum.ERR_ENCRYPTION)); return(-1); } receiveBytesWanted_ = fiReceiveBuffer_.ReadUInt8(); negotiatingState_ = NegotiatingStateEnum.ONS_BASIC_CLIENTB_PADDING; if (receiveBytesWanted_ > 0) { break; } else { goto case NegotiatingStateEnum.ONS_BASIC_CLIENTB_PADDING; } } case NegotiatingStateEnum.ONS_BASIC_CLIENTB_PADDING: // ignore the random bytes, the handshake is complete negotiatingState_ = NegotiatingStateEnum.ONS_COMPLETE; streamCryptState_ = StreamCryptStateEnum.ECS_ENCRYPTING; //DEBUG_ONLY( MpdUtilities.DebugLog(("CEncryptedStreamSocket: Finished Obufscation handshake with client %s (outgoing)"), DbgGetIPString()) ); break; case NegotiatingStateEnum.ONS_BASIC_SERVER_DHANSWER: { Debug.Assert(cryptDHA_ != new BigInteger(0)); byte[] aBuffer = new byte[MuleConstants.PRIMESIZE_BYTES + 1]; fiReceiveBuffer_.Read(aBuffer, 0, Convert.ToInt32(MuleConstants.PRIMESIZE_BYTES)); BigInteger cryptDHAnswer = new BigInteger(aBuffer, (int)MuleConstants.PRIMESIZE_BYTES); BigInteger cryptDHPrime = new BigInteger(dh768_p_, (int)MuleConstants.PRIMESIZE_BYTES); // our fixed prime BigInteger cryptResult = cryptDHAnswer.modPow(cryptDHA_, cryptDHPrime); cryptDHA_ = 0; Array.Clear(aBuffer, 0, aBuffer.Length); // create the keys Array.Copy(cryptResult.getBytes(), aBuffer, MuleConstants.PRIMESIZE_BYTES); aBuffer[MuleConstants.PRIMESIZE_BYTES] = Convert.ToByte(MuleConstants.MAGICVALUE_REQUESTER); MD5 md5 = MD5.Create(); rc4SendKey_ = MuleUtilities.RC4CreateKey(md5.ComputeHash(aBuffer), 16); aBuffer[MuleConstants.PRIMESIZE_BYTES] = Convert.ToByte(MuleConstants.MAGICVALUE_SERVER); rc4ReceiveKey_ = MuleUtilities.RC4CreateKey(md5.ComputeHash(aBuffer), 16); negotiatingState_ = NegotiatingStateEnum.ONS_BASIC_SERVER_MAGICVALUE; receiveBytesWanted_ = 4; break; } case NegotiatingStateEnum.ONS_BASIC_SERVER_MAGICVALUE: { uint dwValue = fiReceiveBuffer_.ReadUInt32(); if (dwValue == MuleConstants.MAGICVALUE_SYNC) { // yup, the one or the other way it worked, this is an encrypted stream MpdUtilities.DebugLog(("Received proper magic value after DH-Agreement from Serverconnection IP: %s"), DbgGetIPString()); // set the receiver key negotiatingState_ = NegotiatingStateEnum.ONS_BASIC_SERVER_METHODTAGSPADLEN; receiveBytesWanted_ = 3; } else { MpdUtilities.DebugLogError(("CEncryptedStreamSocket: Received wrong magic value after DH-Agreement from Serverconnection"), DbgGetIPString()); OnError(Convert.ToInt32(EMSocketErrorCodeEnum.ERR_ENCRYPTION)); return(-1); } break; } case NegotiatingStateEnum.ONS_BASIC_SERVER_METHODTAGSPADLEN: DbgByEncryptionSupported = fiReceiveBuffer_.ReadUInt8(); DbgByEncryptionRequested = fiReceiveBuffer_.ReadUInt8(); if (DbgByEncryptionRequested != Convert.ToByte(EncryptionMethodsEnum.ENM_OBFUSCATION)) { MpdUtilities.AddDebugLogLine(EDebugLogPriority.DLP_LOW, false, ("CEncryptedStreamSocket: Server %s preffered unsupported encryption method (%i)"), DbgGetIPString(), DbgByEncryptionRequested); } receiveBytesWanted_ = fiReceiveBuffer_.ReadUInt8(); negotiatingState_ = NegotiatingStateEnum.ONS_BASIC_SERVER_PADDING; if (receiveBytesWanted_ > 16) { MpdUtilities.AddDebugLogLine(EDebugLogPriority.DLP_LOW, false, ("CEncryptedStreamSocket: Server %s sent more than 16 (%i) padding bytes"), DbgGetIPString(), receiveBytesWanted_); } if (receiveBytesWanted_ > 0) { break; } else { goto case NegotiatingStateEnum.ONS_BASIC_SERVER_PADDING; } case NegotiatingStateEnum.ONS_BASIC_SERVER_PADDING: { // ignore the random bytes (they are decrypted already), send the response, set status complete SafeMemFile fileResponse = MpdObjectManager.CreateSafeMemFile(26); fileResponse.WriteUInt32(MuleConstants.MAGICVALUE_SYNC); byte bySelectedEncryptionMethod = Convert.ToByte(EncryptionMethodsEnum.ENM_OBFUSCATION); // we do not support any further encryption in this version, so no need to look which the other client preferred fileResponse.WriteUInt8(bySelectedEncryptionMethod); byte byPadding = (byte)(MpdUtilities.GetRandomUInt8() % 16); fileResponse.WriteUInt8(byPadding); for (int i = 0; i < byPadding; i++) { fileResponse.WriteUInt8(MpdUtilities.GetRandomUInt8()); } negotiatingState_ = NegotiatingStateEnum.ONS_BASIC_SERVER_DELAYEDSENDING; SendNegotiatingData(fileResponse.Buffer, (uint)fileResponse.Length, 0, true); // don't actually send it right now, store it in our sendbuffer streamCryptState_ = StreamCryptStateEnum.ECS_ENCRYPTING; MpdUtilities.DebugLog(("CEncryptedStreamSocket: Finished DH Obufscation handshake with Server %s"), DbgGetIPString()); break; } default: Debug.Assert(false); break; } fiReceiveBuffer_.SeekToBegin(); } fiReceiveBuffer_ = null; return(nRead); } catch (Exception) { Debug.Assert(false); OnError(Convert.ToInt32(EMSocketErrorCodeEnum.ERR_ENCRYPTION)); fiReceiveBuffer_ = null; return(-1); } }
protected FileIdentifierBaseImpl(FileIdentifierBase rFileIdentifier) { MpdUtilities.Md4Cpy(md4Hash_, rFileIdentifier.MD4Hash); HasAICHHash = rFileIdentifier.HasAICHHash; AICHHash = rFileIdentifier.AICHHash; }