void CEncryptedStreamSocket::StartNegotiation(bool bOutgoing){ if (!bOutgoing){ m_NegotiatingState = ONS_BASIC_CLIENTA_RANDOMPART; m_StreamCryptState = ECS_NEGOTIATING; m_nReceiveBytesWanted = 4; } else if (m_StreamCryptState == ECS_PENDING){ CSafeMemFile fileRequest(29); const uint8_t bySemiRandomNotProtocolMarker = GetSemiRandomNotProtocolMarker(); fileRequest.WriteUInt8(bySemiRandomNotProtocolMarker); fileRequest.WriteUInt32(m_nRandomKeyPart); fileRequest.WriteUInt32(MAGICVALUE_SYNC); const uint8_t bySupportedEncryptionMethod = ENM_OBFUSCATION; // we do not support any further encryption in this version fileRequest.WriteUInt8(bySupportedEncryptionMethod); fileRequest.WriteUInt8(bySupportedEncryptionMethod); // so we also prefer this one uint8_t byPadding = (uint8_t)(cryptRandomGen.GenerateByte() % (thePrefs.GetCryptTCPPaddingLength() + 1)); fileRequest.WriteUInt8(byPadding); for (int i = 0; i < byPadding; i++) fileRequest.WriteUInt8(cryptRandomGen.GenerateByte()); m_NegotiatingState = ONS_BASIC_CLIENTB_MAGICVALUE; m_StreamCryptState = ECS_NEGOTIATING; m_nReceiveBytesWanted = 4; SendNegotiatingData(fileRequest.GetBuffer(), (uint32_t)fileRequest.GetLength(), 5); } else if (m_StreamCryptState == ECS_PENDING_SERVER){ CSafeMemFile fileRequest(113); const uint8_t bySemiRandomNotProtocolMarker = GetSemiRandomNotProtocolMarker(); fileRequest.WriteUInt8(bySemiRandomNotProtocolMarker); m_cryptDHA.Randomize(cryptRandomGen, DHAGREEMENT_A_BITS); // our random a ASSERT( m_cryptDHA.MinEncodedSize() <= DHAGREEMENT_A_BITS / 8 ); CryptoPP::Integer cryptDHPrime((byte*)dh768_p, PRIMESIZE_BYTES); // our fixed prime // calculate g^a % p CryptoPP::Integer cryptDHGexpAmodP = CryptoPP::a_exp_b_mod_c(CryptoPP::Integer(2), m_cryptDHA, cryptDHPrime); ASSERT( m_cryptDHA.MinEncodedSize() <= PRIMESIZE_BYTES ); // put the result into a buffer uchar aBuffer[PRIMESIZE_BYTES]; cryptDHGexpAmodP.Encode(aBuffer, PRIMESIZE_BYTES); fileRequest.Write(aBuffer, PRIMESIZE_BYTES); uint8_t byPadding = (uint8_t)(cryptRandomGen.GenerateByte() % 16); // add random padding fileRequest.WriteUInt8(byPadding); for (int i = 0; i < byPadding; i++) fileRequest.WriteUInt8(cryptRandomGen.GenerateByte()); m_NegotiatingState = ONS_BASIC_SERVER_DHANSWER; m_StreamCryptState = ECS_NEGOTIATING; m_nReceiveBytesWanted = 96; SendNegotiatingData(fileRequest.GetBuffer(), (uint32_t)fileRequest.GetLength(), (uint32_t)fileRequest.GetLength()); } else{ ASSERT( false ); m_StreamCryptState = ECS_NONE; return; } }
void CEncryptedStreamSocket::StartNegotiation(bool bOutgoing) { //printf("Starting socket negotiation\n"); if (!bOutgoing) { //printf("Incoming connection negotiation on %s\n", (const char*) unicode2char(DbgGetIPString())); m_NegotiatingState = ONS_BASIC_CLIENTA_RANDOMPART; m_StreamCryptState = ECS_NEGOTIATING; m_nReceiveBytesWanted = 4; } else if (m_StreamCryptState == ECS_PENDING) { //printf("Socket is client.pending on negotiation\n"); CMemFile fileRequest(29); const uint8_t bySemiRandomNotProtocolMarker = GetSemiRandomNotProtocolMarker(); fileRequest.WriteUInt8(bySemiRandomNotProtocolMarker); fileRequest.WriteUInt32(m_nRandomKeyPart); fileRequest.WriteUInt32(MAGICVALUE_SYNC); const uint8_t bySupportedEncryptionMethod = ENM_OBFUSCATION; // we do not support any further encryption in this version fileRequest.WriteUInt8(bySupportedEncryptionMethod); fileRequest.WriteUInt8(bySupportedEncryptionMethod); // so we also prefer this one uint8_t byPadding = (uint8_t)(GetRandomUint8() % (thePrefs::GetCryptTCPPaddingLength() + 1)); fileRequest.WriteUInt8(byPadding); for (int i = 0; i < byPadding; i++) { fileRequest.WriteUInt8(GetRandomUint8()); } m_NegotiatingState = ONS_BASIC_CLIENTB_MAGICVALUE; m_StreamCryptState = ECS_NEGOTIATING; m_nReceiveBytesWanted = 4; SendNegotiatingData(fileRequest.GetRawBuffer(), (uint32_t)fileRequest.GetLength(), 5); } else if (m_StreamCryptState == ECS_PENDING_SERVER) { //printf("Socket is server.pending on negotiation\n"); CMemFile fileRequest(113); const uint8_t bySemiRandomNotProtocolMarker = GetSemiRandomNotProtocolMarker(); fileRequest.WriteUInt8(bySemiRandomNotProtocolMarker); m_cryptDHA.Randomize((CryptoPP::AutoSeededRandomPool&)GetRandomPool(), DHAGREEMENT_A_BITS); // our random a wxASSERT( m_cryptDHA.MinEncodedSize() <= DHAGREEMENT_A_BITS / 8 ); CryptoPP::Integer cryptDHPrime((byte*)dh768_p, PRIMESIZE_BYTES); // our fixed prime // calculate g^a % p CryptoPP::Integer cryptDHGexpAmodP = a_exp_b_mod_c(CryptoPP::Integer(2), m_cryptDHA, cryptDHPrime); wxASSERT( m_cryptDHA.MinEncodedSize() <= PRIMESIZE_BYTES ); // put the result into a buffer uint8_t aBuffer[PRIMESIZE_BYTES]; cryptDHGexpAmodP.Encode(aBuffer, PRIMESIZE_BYTES); fileRequest.Write(aBuffer, PRIMESIZE_BYTES); uint8 byPadding = (uint8)(GetRandomUint8() % 16); // add random padding fileRequest.WriteUInt8(byPadding); for (int i = 0; i < byPadding; i++) { fileRequest.WriteUInt8(GetRandomUint8()); } m_NegotiatingState = ONS_BASIC_SERVER_DHANSWER; m_StreamCryptState = ECS_NEGOTIATING; m_nReceiveBytesWanted = 96; SendNegotiatingData(fileRequest.GetRawBuffer(), (uint32_t)fileRequest.GetLength(), (uint32_t)fileRequest.GetLength()); } else { wxFAIL; m_StreamCryptState = ECS_NONE; return; } }