mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-02-17 13:24:15 -05:00
fixed bug in distant chat randomly screwing up key exchange, and causing distant chat to be unreliable.
git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@7677 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
f2a6d9f35e
commit
a3eea2cfb1
@ -45,7 +45,7 @@
|
|||||||
#include <retroshare/rsids.h>
|
#include <retroshare/rsids.h>
|
||||||
#include "distantchat.h"
|
#include "distantchat.h"
|
||||||
|
|
||||||
//#define DEBUG_DISTANT_CHAT
|
#define DEBUG_DISTANT_CHAT
|
||||||
|
|
||||||
void DistantChatService::connectToTurtleRouter(p3turtle *tr)
|
void DistantChatService::connectToTurtleRouter(p3turtle *tr)
|
||||||
{
|
{
|
||||||
@ -199,7 +199,18 @@ void DistantChatService::addVirtualPeer(const TurtleFileHash& hash,const TurtleV
|
|||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
DistantChatPeerInfo info ;
|
// make sure the DH session does not already exist. If so, remove it.
|
||||||
|
std::map<TurtleFileHash,DistantChatPeerInfo>::iterator it = _distant_chat_peers.find(hash) ;
|
||||||
|
if(it != _distant_chat_peers.end())
|
||||||
|
{
|
||||||
|
std::cerr << " (WW) weird. Already existing DH session found. Removing it." << std::endl ;
|
||||||
|
if(it->second.dh != NULL)
|
||||||
|
DH_free(it->second.dh) ;
|
||||||
|
|
||||||
|
_distant_chat_peers.erase(it) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
DistantChatPeerInfo info ;
|
||||||
info.last_contact = now ;
|
info.last_contact = now ;
|
||||||
info.status = RS_DISTANT_CHAT_STATUS_TUNNEL_OK ;
|
info.status = RS_DISTANT_CHAT_STATUS_TUNNEL_OK ;
|
||||||
info.virtual_peer_id = virtual_peer_id ;
|
info.virtual_peer_id = virtual_peer_id ;
|
||||||
@ -212,22 +223,28 @@ void DistantChatService::addVirtualPeer(const TurtleFileHash& hash,const TurtleV
|
|||||||
_distant_chat_peers[hash] = info ;
|
_distant_chat_peers[hash] = info ;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// Start a new DH session for this tunnel
|
// Start a new DH session for this tunnel
|
||||||
|
RS_STACK_MUTEX(mDistantChatMtx); /********** STACK LOCKED MTX ******/
|
||||||
|
|
||||||
RsStackMutex stack(mDistantChatMtx); /********** STACK LOCKED MTX ******/
|
DistantChatPeerInfo& info(_distant_chat_peers[hash]) ;
|
||||||
DistantChatPeerInfo& info(_distant_chat_peers[hash]) ;
|
|
||||||
|
|
||||||
std::cerr << " Starting new DH session." << std::endl;
|
std::cerr << " Starting new DH session." << std::endl;
|
||||||
|
|
||||||
if(!locked_initDHSessionKey(info))
|
if(!locked_initDHSessionKey(info))
|
||||||
std::cerr << " (EE) Cannot start DH session. Something went wrong." << std::endl;
|
{
|
||||||
|
std::cerr << " (EE) Cannot start DH session. Something went wrong." << std::endl;
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
if(!locked_sendDHPublicKey(info))
|
if(!locked_sendDHPublicKey(info))
|
||||||
std::cerr << " (EE) Cannot send DH public key. Something went wrong." << std::endl;
|
{
|
||||||
|
std::cerr << " (EE) Cannot send DH public key. Something went wrong." << std::endl;
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
info.status = RS_DISTANT_CHAT_STATUS_WAITING_DH ;
|
_distant_chat_peers[hash].status = RS_DISTANT_CHAT_STATUS_WAITING_DH ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// RsChatMsgItem *item = new RsChatMsgItem;
|
// RsChatMsgItem *item = new RsChatMsgItem;
|
||||||
// item->message = std::string("Tunnel is secured") ;
|
// item->message = std::string("Tunnel is secured") ;
|
||||||
@ -327,21 +344,36 @@ void DistantChatService::receiveTurtleData( RsTurtleGenericTunnelItem *gitem,con
|
|||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
uint32_t decrypted_size = RsAES::get_buffer_size(item->data_size-8);
|
uint32_t decrypted_size = RsAES::get_buffer_size(item->data_size-8);
|
||||||
uint8_t *decrypted_data = new uint8_t[decrypted_size];
|
uint8_t *decrypted_data = new uint8_t[decrypted_size];
|
||||||
|
bool decrypted = false ;
|
||||||
|
|
||||||
|
unsigned char no_key[DISTANT_CHAT_AES_KEY_SIZE] ;
|
||||||
|
memset(no_key,0,DISTANT_CHAT_AES_KEY_SIZE) ;
|
||||||
|
|
||||||
|
if(RsAES::aes_decrypt_8_16((uint8_t*)item->data_bytes+8,item->data_size-8,no_key,(uint8_t*)item->data_bytes,decrypted_data,decrypted_size))
|
||||||
|
{
|
||||||
|
decrypted = true ;
|
||||||
|
|
||||||
#ifdef DEBUG_DISTANT_CHAT
|
#ifdef DEBUG_DISTANT_CHAT
|
||||||
std::cerr << " Using IV: " << std::hex << *(uint64_t*)item->data_bytes << std::dec << std::endl;
|
std::cerr << " Data is not encrypted. Probably a DH session key." << std::endl;
|
||||||
std::cerr << " Decrypted buffer size: " << decrypted_size << std::endl;
|
#endif
|
||||||
std::cerr << " key : " ; printBinaryData(aes_key,16) ; std::cerr << std::endl;
|
}
|
||||||
std::cerr << " data : " ; printBinaryData(item->data_bytes,item->data_size) ; std::cerr << std::endl;
|
if(!decrypted)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_DISTANT_CHAT
|
||||||
|
std::cerr << " Using IV: " << std::hex << *(uint64_t*)item->data_bytes << std::dec << std::endl;
|
||||||
|
std::cerr << " Decrypted buffer size: " << decrypted_size << std::endl;
|
||||||
|
std::cerr << " key : " ; printBinaryData(aes_key,16) ; std::cerr << std::endl;
|
||||||
|
std::cerr << " data : " ; printBinaryData(item->data_bytes,item->data_size) ; std::cerr << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(!RsAES::aes_decrypt_8_16((uint8_t*)item->data_bytes+8,item->data_size-8,aes_key,(uint8_t*)item->data_bytes,decrypted_data,decrypted_size))
|
if(!RsAES::aes_decrypt_8_16((uint8_t*)item->data_bytes+8,item->data_size-8,aes_key,(uint8_t*)item->data_bytes,decrypted_data,decrypted_size))
|
||||||
{
|
{
|
||||||
std::cerr << "(EE) packet decryption failed." << std::endl;
|
std::cerr << "(EE) packet decryption failed." << std::endl;
|
||||||
delete[] decrypted_data ;
|
delete[] decrypted_data ;
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_DISTANT_CHAT
|
#ifdef DEBUG_DISTANT_CHAT
|
||||||
std::cerr << "(II) Decrypted data: size=" << decrypted_size << std::endl;
|
std::cerr << "(II) Decrypted data: size=" << decrypted_size << std::endl;
|
||||||
@ -531,14 +563,21 @@ bool DistantChatService::locked_sendDHPublicKey(const DistantChatPeerInfo& pinfo
|
|||||||
RsIdentityDetails details ;
|
RsIdentityDetails details ;
|
||||||
mIdService->getIdDetails(pinfo.own_gxs_id,details);
|
mIdService->getIdDetails(pinfo.own_gxs_id,details);
|
||||||
|
|
||||||
for(int i=0;i<6;++i)
|
int i ;
|
||||||
|
for(i=0;i<6;++i)
|
||||||
if(!mIdService->getPrivateKey(pinfo.own_gxs_id,signature_key) || signature_key.keyData.bin_data == NULL)
|
if(!mIdService->getPrivateKey(pinfo.own_gxs_id,signature_key) || signature_key.keyData.bin_data == NULL)
|
||||||
{
|
{
|
||||||
std::cerr << " Cannot get key. Waiting for caching. try " << i << "/6" << std::endl;
|
std::cerr << " Cannot get key. Waiting for caching. try " << i << "/6" << std::endl;
|
||||||
usleep(500 * 1000) ; // sleep for 500 msec.
|
usleep(500 * 1000) ; // sleep for 500 msec.
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
break ;
|
break ;
|
||||||
|
|
||||||
|
if(i == 6)
|
||||||
|
{
|
||||||
|
std::cerr << " (EE) Could not retrieve own private key for ID = " << pinfo.own_gxs_id << ". Giging up sending DH session params." << std::endl;
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
GxsSecurity::extractPublicKey(signature_key,signature_key_public) ;
|
GxsSecurity::extractPublicKey(signature_key,signature_key_public) ;
|
||||||
|
|
||||||
@ -563,7 +602,10 @@ bool DistantChatService::locked_sendDHPublicKey(const DistantChatPeerInfo& pinfo
|
|||||||
dhitem->gxs_key = signature_key_public ;
|
dhitem->gxs_key = signature_key_public ;
|
||||||
dhitem->PeerId(pinfo.virtual_peer_id) ;
|
dhitem->PeerId(pinfo.virtual_peer_id) ;
|
||||||
|
|
||||||
pendingDistantChatItems.push_back(dhitem) ;
|
#ifdef DEBUG_DISTANT_MSG
|
||||||
|
std::cerr << " Pushing DH session key item to pending distant messages..." << std::endl;
|
||||||
|
#endif
|
||||||
|
pendingDistantChatItems.push_back(dhitem) ;
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
@ -601,7 +643,8 @@ bool DistantChatService::locked_initDHSessionKey(DistantChatPeerInfo& pinfo)
|
|||||||
{
|
{
|
||||||
std::cerr << " (EE) DH generate_key() failed! Error code = " << ERR_get_error() << std::endl;
|
std::cerr << " (EE) DH generate_key() failed! Error code = " << ERR_get_error() << std::endl;
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
|
std::cerr << " (II) DH Session key inited." << std::endl;
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -657,15 +700,22 @@ void DistantChatService::sendTurtleData(RsChatItem *item)
|
|||||||
//
|
//
|
||||||
uint8_t *encrypted_data = new uint8_t[RsAES::get_buffer_size(rssize)];
|
uint8_t *encrypted_data = new uint8_t[RsAES::get_buffer_size(rssize)];
|
||||||
uint32_t encrypted_size = RsAES::get_buffer_size(rssize);
|
uint32_t encrypted_size = RsAES::get_buffer_size(rssize);
|
||||||
|
uint64_t IV = RSRandom::random_u64() ; // make a random 8 bytes IV
|
||||||
|
|
||||||
uint64_t IV = RSRandom::random_u64() ; // make a random 8 bytes IV
|
if(dynamic_cast<RsChatDHPublicKeyItem*>(item) != NULL)
|
||||||
|
{
|
||||||
|
memset(aes_key,0,16) ;
|
||||||
|
IV = 0 ;
|
||||||
|
#ifdef DEBUG_DISTANT_CHAT
|
||||||
|
std::cerr << " Special item DH session key --> will be sent unencrypted." << std::endl ;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_DISTANT_CHAT
|
#ifdef DEBUG_DISTANT_CHAT
|
||||||
std::cerr << " Using IV: " << std::hex << IV << std::dec << std::endl;
|
std::cerr << " Using IV: " << std::hex << IV << std::dec << std::endl;
|
||||||
std::cerr << " Using Key: " ; printBinaryData(aes_key,16) ; std::cerr << std::endl;
|
std::cerr << " Using Key: " ; printBinaryData(aes_key,16) ; std::cerr << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
if(!RsAES::aes_crypt_8_16(buff,rssize,aes_key,(uint8_t*)&IV,encrypted_data,encrypted_size))
|
||||||
if(!RsAES::aes_crypt_8_16(buff,rssize,aes_key,(uint8_t*)&IV,encrypted_data,encrypted_size))
|
|
||||||
{
|
{
|
||||||
std::cerr << "(EE) packet encryption failed." << std::endl;
|
std::cerr << "(EE) packet encryption failed." << std::endl;
|
||||||
delete[] encrypted_data ;
|
delete[] encrypted_data ;
|
||||||
@ -767,7 +817,8 @@ DistantChatPeerId DistantChatService::virtualPeerIdFromHash(const TurtleFileHash
|
|||||||
TurtleFileHash DistantChatService::hashFromGxsId(const RsGxsId& gid)
|
TurtleFileHash DistantChatService::hashFromGxsId(const RsGxsId& gid)
|
||||||
{
|
{
|
||||||
if(DistantChatPeerId::SIZE_IN_BYTES > Sha1CheckSum::SIZE_IN_BYTES)
|
if(DistantChatPeerId::SIZE_IN_BYTES > Sha1CheckSum::SIZE_IN_BYTES)
|
||||||
std::cerr << __PRETTY_FUNCTION__ << ": Serious inconsistency error." << std::endl;
|
std::cerr << __PRETTY_FUNCTION__ << ": Serious inconsistency error." << std::endl;
|
||||||
|
assert(Sha1CheckSum::SIZE_IN_BYTES >= DistantChatPeerId::SIZE_IN_BYTES) ;
|
||||||
|
|
||||||
unsigned char tmp[Sha1CheckSum::SIZE_IN_BYTES] ;
|
unsigned char tmp[Sha1CheckSum::SIZE_IN_BYTES] ;
|
||||||
memset(tmp,0,Sha1CheckSum::SIZE_IN_BYTES) ;
|
memset(tmp,0,Sha1CheckSum::SIZE_IN_BYTES) ;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user