mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
started to move FT encryption into p3turtle
This commit is contained in:
parent
3407604a54
commit
00a6bd5b73
@ -24,6 +24,7 @@
|
||||
*/
|
||||
|
||||
#include "util/rsdir.h"
|
||||
#include "retroshare/rspeers.h"
|
||||
#include "rsgxsnettunnel.h"
|
||||
|
||||
#define DEBUG_RSGXSNETTUNNEL 1
|
||||
@ -42,7 +43,7 @@ bool RsGxsNetTunnelService::manage(const RsGxsGroupId& group_id)
|
||||
|
||||
RsStackMutex stack(mGxsNetTunnelMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
RsGxsNetTunnelGroupInfo& info(mClientGroups[group_id]) ;
|
||||
RsGxsNetTunnelGroupInfo& info(mGroups[group_id]) ;
|
||||
|
||||
time_t now = time(NULL) ;
|
||||
|
||||
@ -73,15 +74,15 @@ bool RsGxsNetTunnelService::release(const RsGxsGroupId& group_id)
|
||||
|
||||
// Here we need to clean the stuff that was created by this group id.
|
||||
|
||||
auto it = mClientGroups.find(group_id) ;
|
||||
auto it = mGroups.find(group_id) ;
|
||||
|
||||
if(it == mClientGroups.end())
|
||||
if(it == mGroups.end())
|
||||
{
|
||||
std::cerr << "RsGxsNetTunnelService::release(): Weird. Cannot release client group " << group_id << " that is not known." << std::endl;
|
||||
return false ;
|
||||
}
|
||||
|
||||
mClientGroups.erase(it) ;
|
||||
mGroups.erase(it) ;
|
||||
|
||||
RsFileHash hash = calculateGroupHash(group_id) ;
|
||||
|
||||
@ -89,12 +90,66 @@ bool RsGxsNetTunnelService::release(const RsGxsGroupId& group_id)
|
||||
return true ;
|
||||
}
|
||||
|
||||
bool RsGxsNetTunnelService::sendData(const unsigned char *data,uint32_t size,const RsGxsNetTunnelVirtualPeerId& virtual_peer)
|
||||
class ItemAutoDelete
|
||||
{
|
||||
// The data is encrypted using chacha20+SHA256 and sent to the turtle router.
|
||||
public:
|
||||
ItemAutoDelete(RsItem *& item) : mItem(item) {}
|
||||
~ItemAutoDelete() { delete mItem; mItem=NULL ; }
|
||||
RsItem *& mItem;
|
||||
};
|
||||
|
||||
bool RsGxsNetTunnelService::sendItem(RsItem *& item,const RsGxsNetTunnelVirtualPeerId& virtual_peer)
|
||||
{
|
||||
// The item is serialized and encrypted using chacha20+SHA256, using the generic turtle encryption, and then sent to the turtle router.
|
||||
|
||||
ItemAutoDelete iad(item) ; // This ensures the item is deleted whatsoever when leaving
|
||||
|
||||
// 1 - find the virtual peer and the proper master key to encrypt with, and check that all the info is known
|
||||
|
||||
auto it = mVirtualPeers.find(virtual_peer) ;
|
||||
|
||||
if(it == mVirtualPeers.end())
|
||||
{
|
||||
std::cerr << "(EE) RsGxsNetTunnelService::sendData(): cannot find virtual peer " << virtual_peer << ". Data is dropped." << std::endl;
|
||||
return false ;
|
||||
}
|
||||
|
||||
auto it2 = mGroups.find(it->second.first);
|
||||
|
||||
if(it2 == mGroups.end())
|
||||
{
|
||||
std::cerr << "(EE) RsGxsNetTunnelService::sendData(): cannot find virtual peer " << virtual_peer << ". Data is dropped." << std::endl;
|
||||
return false ;
|
||||
}
|
||||
|
||||
auto it3 = it2->second.virtual_peers.find(it->second.second);
|
||||
|
||||
if(it3 == it2->second.virtual_peers.end())
|
||||
{
|
||||
std::cerr << "(EE) RsGxsNetTunnelService::sendData(): cannot find turtle virtual peer " << it->second.second << ". Data is dropped." << std::endl;
|
||||
return false ;
|
||||
}
|
||||
|
||||
if(it3->second.vpid_status != RsGxsNetTunnelVirtualPeerInfo::RS_GXS_NET_TUNNEL_VP_STATUS_ACTIVE)
|
||||
{
|
||||
std::cerr << "(EE) RsGxsNetTunnelService::sendData(): virtual peer " << it->second.second << " is not active. Data is dropped." << std::endl;
|
||||
return false ;
|
||||
}
|
||||
|
||||
// 2 - encrypt and send the item.
|
||||
|
||||
RsTurtleGenericDataItem *encrypted_turtle_item = NULL ;
|
||||
|
||||
NOT_IMPLEMENTED();
|
||||
return false ;
|
||||
// if(!p3Turtle::encryptItem(item,it3->second.encryption_master_key,encrypted_turtle_item))
|
||||
// {
|
||||
// std::cerr << "(EE) RsGxsNetTunnelService::sendData(): cannot encrypt. Something's wrong. Data is dropped." << std::endl;
|
||||
// return false ;
|
||||
// }
|
||||
|
||||
mTurtle->sendTurtleData(it->second.second,encrypted_turtle_item) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
bool RsGxsNetTunnelService::getVirtualPeers(const RsGxsGroupId&, std::list<RsPeerId>& peers)
|
||||
@ -104,14 +159,60 @@ bool RsGxsNetTunnelService::getVirtualPeers(const RsGxsGroupId&, std::list<RsPee
|
||||
return false ;
|
||||
}
|
||||
|
||||
RsGxsNetTunnelVirtualPeerInfo RsGxsNetTunnelService::makeVirtualPeerIdForGroup(const RsGxsGroupId& group_id) const
|
||||
RsGxsNetTunnelVirtualPeerId RsGxsNetTunnelService::makeServerVirtualPeerIdForGroup(const RsGxsGroupId& group_id) const
|
||||
{
|
||||
NOT_IMPLEMENTED();
|
||||
return RsGxsNetTunnelVirtualPeerInfo();
|
||||
assert(RsPeerId::SIZE_IN_BYTES <= Sha1CheckSum::SIZE_IN_BYTES) ;
|
||||
|
||||
// We compute sha1( SSL_id | group_id | mRandomBias ) and trunk it to 16 bytes in order to compute a RsPeerId
|
||||
|
||||
RsPeerId ssl_id = rsPeers->getOwnId() ;
|
||||
|
||||
unsigned char mem[RsPeerId::SIZE_IN_BYTES + RsGxsGroupId::SIZE_IN_BYTES + RS_GXS_TUNNEL_CONST_RANDOM_BIAS_SIZE];
|
||||
|
||||
memcpy(mem ,ssl_id.toByteArray() ,RsPeerId::SIZE_IN_BYTES) ;
|
||||
memcpy(mem+RsPeerId::SIZE_IN_BYTES ,group_id.toByteArray(),RsGxsGroupId::SIZE_IN_BYTES) ;
|
||||
memcpy(mem+RsPeerId::SIZE_IN_BYTES+RsGxsGroupId::SIZE_IN_BYTES,mRandomBias ,RS_GXS_TUNNEL_CONST_RANDOM_BIAS_SIZE) ;
|
||||
|
||||
return RsGxsNetTunnelVirtualPeerId(RsDirUtil::sha1sum(mem,RsPeerId::SIZE_IN_BYTES+RsGxsGroupId::SIZE_IN_BYTES+RS_GXS_TUNNEL_CONST_RANDOM_BIAS_SIZE).toByteArray());
|
||||
}
|
||||
|
||||
void RsGxsNetTunnelService::dump() const
|
||||
{
|
||||
NOT_IMPLEMENTED();
|
||||
RS_STACK_MUTEX(mGxsNetTunnelMtx);
|
||||
|
||||
static std::string group_status_str[3] = {
|
||||
std::string("[RS_GXS_NET_TUNNEL_GRP_STATUS_UNKNOWN ]"),
|
||||
std::string("[RS_GXS_NET_TUNNEL_GRP_STATUS_TUNNELS_REQUESTED]"),
|
||||
std::string("[RS_GXS_NET_TUNNEL_GRP_STATUS_VPIDS_AVAILABLE ]")
|
||||
};
|
||||
|
||||
static std::string vpid_status_str[3] = {
|
||||
std::string("[RS_GXS_NET_TUNNEL_VP_STATUS_UNKNOWN ]"),
|
||||
std::string("[RS_GXS_NET_TUNNEL_VP_STATUS_TUNNEL_OK ]"),
|
||||
std::string("[RS_GXS_NET_TUNNEL_VP_STATUS_ACTIVE ]")
|
||||
};
|
||||
|
||||
std::cerr << "GxsNetTunnelService dump: " << std::endl;
|
||||
std::cerr << "Managed GXS groups: " << std::endl;
|
||||
|
||||
for(auto it(mGroups.begin());it!=mGroups.end();++it)
|
||||
{
|
||||
std::cerr << " " << it->first << " hash: " << it->second.hash << " status: " << group_status_str[it->second.group_status] << "] Last contact: " << time(NULL) - it->second.last_contact << " secs ago" << std::endl;
|
||||
|
||||
for(auto it2(it->second.virtual_peers.begin());it2!=it->second.virtual_peers.end();++it2)
|
||||
std::cerr << " turtle:" << it2->first << " status: " << vpid_status_str[it2->second.vpid_status] << " s: "
|
||||
<< (int)it2->second.side << " last seen " << time(NULL)-it2->second.last_contact
|
||||
<< " ekey: " << RsUtil::BinToHex(it2->second.encryption_master_key,RS_GXS_TUNNEL_CONST_EKEY_SIZE)
|
||||
<< " pending (" << it2->second.incoming_items.size() << "," << it2->second.outgoing_items.size() << ")" << std::endl;
|
||||
}
|
||||
|
||||
std::cerr << "Virtual peers: " << std::endl;
|
||||
for(auto it(mVirtualPeers.begin());it!=mVirtualPeers.end();++it)
|
||||
std::cerr << " GXS Peer:" << it->first << " group_id: " << it->second.first << " Turtle:" << it->second.second << std::endl;
|
||||
|
||||
std::cerr << "Hashes: " << std::endl;
|
||||
for(auto it(mHandledHashes.begin());it!=mHandledHashes.end();++it)
|
||||
std::cerr << " hash: " << it->first << " GroupId: " << it->second << std::endl;
|
||||
}
|
||||
|
||||
//===========================================================================================================================================//
|
||||
@ -151,7 +252,7 @@ void RsGxsNetTunnelService::addVirtualPeer(const TurtleFileHash& hash, const Tur
|
||||
|
||||
const RsGxsGroupId group_id(it->second) ;
|
||||
|
||||
RsGxsNetTunnelGroupInfo& ginfo( mClientGroups[group_id] ) ;
|
||||
RsGxsNetTunnelGroupInfo& ginfo( mGroups[group_id] ) ;
|
||||
ginfo.group_status = RsGxsNetTunnelGroupInfo::RS_GXS_NET_TUNNEL_GRP_STATUS_VPIDS_AVAILABLE ;
|
||||
|
||||
RsGxsNetTunnelVirtualPeerInfo& vpinfo( ginfo.virtual_peers[vpid] ) ;
|
||||
@ -161,7 +262,7 @@ void RsGxsNetTunnelService::addVirtualPeer(const TurtleFileHash& hash, const Tur
|
||||
vpinfo.side = dir ;
|
||||
vpinfo.last_contact = time(NULL) ;
|
||||
|
||||
generateEncryptionKey(group_id,vpid,vpinfo.encryption_key );
|
||||
generateEncryptionKey(group_id,vpid,vpinfo.encryption_master_key );
|
||||
}
|
||||
|
||||
void RsGxsNetTunnelService::removeVirtualPeer(const TurtleFileHash& hash, const TurtleVirtualPeerId& vpid)
|
||||
@ -176,7 +277,7 @@ void RsGxsNetTunnelService::removeVirtualPeer(const TurtleFileHash& hash, const
|
||||
|
||||
const RsGxsGroupId group_id(it->second) ;
|
||||
|
||||
RsGxsNetTunnelGroupInfo& ginfo( mClientGroups[group_id] ) ;
|
||||
RsGxsNetTunnelGroupInfo& ginfo( mGroups[group_id] ) ;
|
||||
|
||||
ginfo.virtual_peers.erase(vpid);
|
||||
|
||||
@ -189,6 +290,21 @@ RsFileHash RsGxsNetTunnelService::calculateGroupHash(const RsGxsGroupId& group_i
|
||||
return RsDirUtil::sha1sum(group_id.toByteArray(),RsGxsGroupId::SIZE_IN_BYTES) ;
|
||||
}
|
||||
|
||||
void RsGxsNetTunnelService::generateEncryptionKey(const RsGxsGroupId& group_id,const TurtleVirtualPeerId& vpid,unsigned char key[RS_GXS_TUNNEL_CONST_EKEY_SIZE]) const
|
||||
{
|
||||
// The key is generated as H(group_id | vpid)
|
||||
// Because group_id is not known it shouldn't be possible to recover the key by observing the traffic.
|
||||
|
||||
assert(Sha256CheckSum::SIZE_IN_BYTES == 32) ;
|
||||
|
||||
unsigned char mem[RsGxsGroupId::SIZE_IN_BYTES + TurtleVirtualPeerId::SIZE_IN_BYTES] ;
|
||||
|
||||
memcpy(mem ,group_id.toByteArray(),RsGxsGroupId::SIZE_IN_BYTES) ;
|
||||
memcpy(mem+RsGxsGroupId::SIZE_IN_BYTES,vpid.toByteArray() ,TurtleVirtualPeerId::SIZE_IN_BYTES) ;
|
||||
|
||||
memcpy( key, RsDirUtil::sha256sum(mem,RsGxsGroupId::SIZE_IN_BYTES+TurtleVirtualPeerId::SIZE_IN_BYTES).toByteArray(), RS_GXS_TUNNEL_CONST_EKEY_SIZE ) ;
|
||||
}
|
||||
|
||||
//===========================================================================================================================================//
|
||||
// Service parts //
|
||||
//===========================================================================================================================================//
|
||||
|
@ -75,11 +75,16 @@ struct RsGxsNetTunnelVirtualPeerInfo
|
||||
|
||||
RsGxsNetTunnelVirtualPeerInfo() : vpid_status(RS_GXS_NET_TUNNEL_VP_STATUS_UNKNOWN) { memset(encryption_master_key,0,16) ; }
|
||||
|
||||
uint8_t vpid_status ;
|
||||
RsGxsNetTunnelVirtualPeerId net_service_virtual_peer ;
|
||||
uint8_t vpid_status ; // status of the peer
|
||||
uint8_t side ; // client/server
|
||||
uint8_t encryption_master_key[16] ; // key from which the encryption key is derived for each virtual peer (using H(master_key | random IV))
|
||||
time_t last_contact ; // last time some data was sent/recvd
|
||||
|
||||
RsGxsNetTunnelVirtualPeerId net_service_virtual_peer ; // anonymised peer that is used to communicate with client services
|
||||
RsGxsGroupId group_id ; // group id
|
||||
|
||||
std::list<RsItem*> incoming_items ;
|
||||
std::list<RsItem*> outgoing_items ;
|
||||
};
|
||||
|
||||
struct RsGxsNetTunnelGroupInfo
|
||||
@ -115,10 +120,24 @@ public:
|
||||
*/
|
||||
bool release(const RsGxsGroupId&group_id) ;
|
||||
|
||||
|
||||
/*!
|
||||
* sends data to this virtual peer ID
|
||||
* \brief sendItem
|
||||
* send data to this virtual peer, and takes memory ownership (deletes the item)
|
||||
* \param item item to send
|
||||
* \param virtual_peer destination virtual peer
|
||||
* \return
|
||||
* true if succeeded.
|
||||
*/
|
||||
bool sendData(const unsigned char *data,uint32_t size,const RsGxsNetTunnelVirtualPeerId& virtual_peer) ; // send data to this virtual peer
|
||||
bool sendItem(RsItem *& item, const RsGxsNetTunnelVirtualPeerId& virtual_peer) ;
|
||||
|
||||
/*!
|
||||
* \brief receivedItem
|
||||
* returns the next received item from the given virtual peer.
|
||||
* \param virtual_peer
|
||||
* \return
|
||||
*/
|
||||
RsItem *receivedItem(const RsGxsNetTunnelVirtualPeerId& virtual_peer) ;
|
||||
|
||||
/*!
|
||||
* \brief Get the list of active virtual peers for a given group. This implies that the tunnel is up and
|
||||
@ -147,11 +166,13 @@ protected:
|
||||
|
||||
p3turtle *mTurtle ;
|
||||
private:
|
||||
std::map<RsGxsGroupId,RsGxsNetTunnelGroupInfo> mClientGroups ; // groups on the client side
|
||||
std::map<RsGxsGroupId,RsGxsNetTunnelGroupInfo> mServerGroups ; // groups on the server side
|
||||
static const uint32_t RS_GXS_TUNNEL_CONST_RANDOM_BIAS_SIZE = 16 ;
|
||||
static const uint32_t RS_GXS_TUNNEL_CONST_EKEY_SIZE = 32 ;
|
||||
|
||||
std::map<RsGxsNetTunnelVirtualPeerId, std::pair<RsGxsGroupId,TurtleVirtualPeerId> > mVirtualPeers ; // current virtual peers, with the (group,turtle vpid) they are for
|
||||
std::map<RsFileHash, RsGxsGroupId> mHandledHashes ; // hashes asked to turtle
|
||||
std::map<RsGxsGroupId,RsGxsNetTunnelGroupInfo> mGroups ; // groups on the client and server side
|
||||
|
||||
std::map<RsGxsNetTunnelVirtualPeerId, std::pair<RsGxsGroupId,TurtleVirtualPeerId> > mVirtualPeers ; // current virtual peers,
|
||||
std::map<RsFileHash, RsGxsGroupId> mHandledHashes ; // hashes asked to turtle
|
||||
|
||||
/*!
|
||||
* \brief Generates the hash to request tunnels for this group. This hash is only used by turtle, and is used to
|
||||
@ -165,12 +186,12 @@ private:
|
||||
* tunnel ID and turtle virtual peer id. This allows RsGxsNetService to keep sync-ing the data consistently.
|
||||
*/
|
||||
|
||||
RsGxsNetTunnelVirtualPeerInfo makeVirtualPeerIdForGroup(const RsGxsGroupId&group_id) const ;
|
||||
RsGxsNetTunnelVirtualPeerId makeServerVirtualPeerIdForGroup(const RsGxsGroupId&group_id) const ;
|
||||
|
||||
void generateEncryptionKey(const RsGxsGroupId& group_id,const TurtleVirtualPeerId& vpid) const ;
|
||||
void generateEncryptionKey(const RsGxsGroupId& group_id,const TurtleVirtualPeerId& vpid,unsigned char key[RS_GXS_TUNNEL_CONST_EKEY_SIZE]) const ;
|
||||
|
||||
uint8_t mRandomBias[16] ; // constant accross reboots. Allows to disguise the real SSL id while providing a consistent value accross time.
|
||||
uint8_t mRandomBias[RS_GXS_TUNNEL_CONST_RANDOM_BIAS_SIZE] ; // constant accross reboots. Allows to disguise the real SSL id while providing a consistent value accross time.
|
||||
|
||||
RsMutex mGxsNetTunnelMtx;
|
||||
mutable RsMutex mGxsNetTunnelMtx;
|
||||
};
|
||||
|
||||
|
@ -2080,6 +2080,178 @@ std::string p3turtle::getPeerNameForVirtualPeerId(const RsPeerId& virtual_peer_i
|
||||
return name;
|
||||
}
|
||||
|
||||
#ifdef TODO
|
||||
static const uint32_t ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE = 12 ;
|
||||
static const uint32_t ENCRYPTED_FT_AUTHENTICATION_TAG_SIZE = 16 ;
|
||||
static const uint32_t ENCRYPTED_FT_HEADER_SIZE = 4 ;
|
||||
static const uint32_t ENCRYPTED_FT_EDATA_SIZE = 4 ;
|
||||
|
||||
static const uint8_t ENCRYPTED_FT_FORMAT_AEAD_CHACHA20_POLY1305 = 0x01 ;
|
||||
static const uint8_t ENCRYPTED_FT_FORMAT_AEAD_CHACHA20_SHA256 = 0x02 ;
|
||||
|
||||
bool p3turtle::encryptItem(const RsItem *item,uint8_t *encryption_master_key,RsTurtleGenericDataItem *& encrypted_item)
|
||||
{
|
||||
uint8_t initialization_vector[ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE] ;
|
||||
|
||||
RSRandom::random_bytes(initialization_vector,ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE) ;
|
||||
|
||||
#ifdef SERVER_DEBUG
|
||||
FTSERVER_DEBUG() << "ftServer::Encrypting ft item." << std::endl;
|
||||
FTSERVER_DEBUG() << " random nonce : " << RsUtil::BinToHex(initialization_vector,ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE) << std::endl;
|
||||
#endif
|
||||
|
||||
uint32_t item_serialized_size = RsGenericSerializer().size(clear_item) ;
|
||||
uint32_t total_data_size = ENCRYPTED_FT_HEADER_SIZE + ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE + ENCRYPTED_FT_EDATA_SIZE + item_serialized_size + ENCRYPTED_FT_AUTHENTICATION_TAG_SIZE ;
|
||||
|
||||
#ifdef SERVER_DEBUG
|
||||
FTSERVER_DEBUG() << " clear part size : " << size(clear_item) << std::endl;
|
||||
FTSERVER_DEBUG() << " total item size : " << total_data_size << std::endl;
|
||||
#endif
|
||||
|
||||
encrypted_item = new RsTurtleGenericDataItem ;
|
||||
encrypted_item->data_bytes = rs_malloc( total_data_size ) ;
|
||||
encrypted_item->data_size = total_data_size ;
|
||||
|
||||
if(encrypted_item->data_bytes == NULL)
|
||||
return false ;
|
||||
|
||||
uint8_t *edata = (uint8_t*)encrypted_item->data_bytes ;
|
||||
uint32_t edata_size = item_serialized_size;
|
||||
uint32_t offset = 0;
|
||||
|
||||
edata[0] = 0xae ;
|
||||
edata[1] = 0xad ;
|
||||
edata[2] = ENCRYPTED_FT_FORMAT_AEAD_CHACHA20_SHA256 ; // means AEAD_chacha20_sha256
|
||||
edata[3] = 0x01 ;
|
||||
|
||||
offset += ENCRYPTED_FT_HEADER_SIZE;
|
||||
uint32_t aad_offset = offset ;
|
||||
uint32_t aad_size = ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE + ENCRYPTED_FT_EDATA_SIZE ;
|
||||
|
||||
memcpy(&edata[offset], initialization_vector, ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE) ;
|
||||
offset += ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE ;
|
||||
|
||||
edata[offset+0] = (edata_size >> 0) & 0xff ;
|
||||
edata[offset+1] = (edata_size >> 8) & 0xff ;
|
||||
edata[offset+2] = (edata_size >> 16) & 0xff ;
|
||||
edata[offset+3] = (edata_size >> 24) & 0xff ;
|
||||
|
||||
offset += ENCRYPTED_FT_EDATA_SIZE ;
|
||||
|
||||
uint32_t ser_size = (uint32_t)((int)total_data_size - (int)offset);
|
||||
|
||||
serialise(clear_item,&edata[offset], &ser_size);
|
||||
|
||||
#ifdef SERVER_DEBUG
|
||||
FTSERVER_DEBUG() << " clear item : " << RsUtil::BinToHex(&edata[offset],std::min(50,(int)total_data_size-(int)offset)) << "(...)" << std::endl;
|
||||
#endif
|
||||
|
||||
uint32_t clear_item_offset = offset ;
|
||||
offset += edata_size ;
|
||||
|
||||
uint32_t authentication_tag_offset = offset ;
|
||||
assert(ENCRYPTED_FT_AUTHENTICATION_TAG_SIZE + offset == total_data_size) ;
|
||||
|
||||
uint8_t encryption_key[32] ;
|
||||
deriveEncryptionKey(hash,encryption_key) ;
|
||||
|
||||
if(edata[2] == ENCRYPTED_FT_FORMAT_AEAD_CHACHA20_POLY1305)
|
||||
librs::crypto::AEAD_chacha20_poly1305(encryption_key,initialization_vector,&edata[clear_item_offset],edata_size, &edata[aad_offset],aad_size, &edata[authentication_tag_offset],true) ;
|
||||
else if(edata[2] == ENCRYPTED_FT_FORMAT_AEAD_CHACHA20_SHA256)
|
||||
librs::crypto::AEAD_chacha20_sha256 (encryption_key,initialization_vector,&edata[clear_item_offset],edata_size, &edata[aad_offset],aad_size, &edata[authentication_tag_offset],true) ;
|
||||
else
|
||||
return false ;
|
||||
|
||||
#ifdef SERVER_DEBUG
|
||||
FTSERVER_DEBUG() << " encryption key : " << RsUtil::BinToHex(encryption_key,32) << std::endl;
|
||||
FTSERVER_DEBUG() << " authen. tag : " << RsUtil::BinToHex(&edata[authentication_tag_offset],ENCRYPTED_FT_AUTHENTICATION_TAG_SIZE) << std::endl;
|
||||
FTSERVER_DEBUG() << " final item : " << RsUtil::BinToHex(&edata[0],std::min(50u,total_data_size)) << "(...)" << std::endl;
|
||||
#endif
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
// Decrypts the given item using aead-chacha20-poly1305
|
||||
bool p3turtle::decryptItem(RsTurtleGenericDataItem *item, uint8_t* encryption_master_key, RsItem *& decrypted_item)
|
||||
{
|
||||
uint8_t encryption_key[32] ;
|
||||
deriveEncryptionKey(hash,encryption_key) ;
|
||||
|
||||
uint8_t *edata = (uint8_t*)encrypted_item->data_bytes ;
|
||||
uint32_t offset = 0;
|
||||
|
||||
if(encrypted_item->data_size < ENCRYPTED_FT_HEADER_SIZE + ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE + ENCRYPTED_FT_EDATA_SIZE) return false ;
|
||||
|
||||
if(edata[0] != 0xae) return false ;
|
||||
if(edata[1] != 0xad) return false ;
|
||||
if(edata[2] != ENCRYPTED_FT_FORMAT_AEAD_CHACHA20_POLY1305 && edata[2] != ENCRYPTED_FT_FORMAT_AEAD_CHACHA20_SHA256) return false ;
|
||||
if(edata[3] != 0x01) return false ;
|
||||
|
||||
offset += ENCRYPTED_FT_HEADER_SIZE ;
|
||||
uint32_t aad_offset = offset ;
|
||||
uint32_t aad_size = ENCRYPTED_FT_EDATA_SIZE + ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE ;
|
||||
|
||||
uint8_t *initialization_vector = &edata[offset] ;
|
||||
|
||||
#ifdef SERVER_DEBUG
|
||||
FTSERVER_DEBUG() << "ftServer::decrypting ft item." << std::endl;
|
||||
FTSERVER_DEBUG() << " item data : " << RsUtil::BinToHex(edata,std::min(50u,encrypted_item->data_size)) << "(...)" << std::endl;
|
||||
FTSERVER_DEBUG() << " hash : " << hash << std::endl;
|
||||
FTSERVER_DEBUG() << " encryption key : " << RsUtil::BinToHex(encryption_key,32) << std::endl;
|
||||
FTSERVER_DEBUG() << " random nonce : " << RsUtil::BinToHex(initialization_vector,ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE) << std::endl;
|
||||
#endif
|
||||
|
||||
offset += ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE ;
|
||||
|
||||
uint32_t edata_size = 0 ;
|
||||
edata_size += ((uint32_t)edata[offset+0]) << 0 ;
|
||||
edata_size += ((uint32_t)edata[offset+1]) << 8 ;
|
||||
edata_size += ((uint32_t)edata[offset+2]) << 16 ;
|
||||
edata_size += ((uint32_t)edata[offset+3]) << 24 ;
|
||||
|
||||
if(edata_size + ENCRYPTED_FT_EDATA_SIZE + ENCRYPTED_FT_AUTHENTICATION_TAG_SIZE + ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE + ENCRYPTED_FT_HEADER_SIZE != encrypted_item->data_size)
|
||||
{
|
||||
FTSERVER_ERROR() << " ERROR: encrypted data size is " << edata_size << ", should be " << encrypted_item->data_size - (ENCRYPTED_FT_EDATA_SIZE + ENCRYPTED_FT_AUTHENTICATION_TAG_SIZE + ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE + ENCRYPTED_FT_HEADER_SIZE ) << std::endl;
|
||||
return false ;
|
||||
}
|
||||
|
||||
offset += ENCRYPTED_FT_EDATA_SIZE ;
|
||||
uint32_t clear_item_offset = offset ;
|
||||
|
||||
uint32_t authentication_tag_offset = offset + edata_size ;
|
||||
#ifdef SERVER_DEBUG
|
||||
FTSERVER_DEBUG() << " authen. tag : " << RsUtil::BinToHex(&edata[authentication_tag_offset],ENCRYPTED_FT_AUTHENTICATION_TAG_SIZE) << std::endl;
|
||||
#endif
|
||||
|
||||
bool result ;
|
||||
|
||||
if(edata[2] == ENCRYPTED_FT_FORMAT_AEAD_CHACHA20_POLY1305)
|
||||
result = librs::crypto::AEAD_chacha20_poly1305(encryption_key,initialization_vector,&edata[clear_item_offset],edata_size, &edata[aad_offset],aad_size, &edata[authentication_tag_offset],false) ;
|
||||
else if(edata[2] == ENCRYPTED_FT_FORMAT_AEAD_CHACHA20_SHA256)
|
||||
result = librs::crypto::AEAD_chacha20_sha256 (encryption_key,initialization_vector,&edata[clear_item_offset],edata_size, &edata[aad_offset],aad_size, &edata[authentication_tag_offset],false) ;
|
||||
else
|
||||
return false ;
|
||||
|
||||
#ifdef SERVER_DEBUG
|
||||
FTSERVER_DEBUG() << " authen. result : " << result << std::endl;
|
||||
FTSERVER_DEBUG() << " decrypted daya : " << RsUtil::BinToHex(&edata[clear_item_offset],std::min(50u,edata_size)) << "(...)" << std::endl;
|
||||
#endif
|
||||
|
||||
if(!result)
|
||||
{
|
||||
FTSERVER_ERROR() << "(EE) decryption/authentication went wrong." << std::endl;
|
||||
return false ;
|
||||
}
|
||||
|
||||
decrypted_item = dynamic_cast<RsTurtleGenericTunnelItem*>(deserialise(&edata[clear_item_offset],&edata_size)) ;
|
||||
|
||||
if(decrypted_item == NULL)
|
||||
return false ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
#endif
|
||||
|
||||
void p3turtle::getInfo( std::vector<std::vector<std::string> >& hashes_info,
|
||||
std::vector<std::vector<std::string> >& tunnels_info,
|
||||
std::vector<TurtleSearchRequestDisplayInfo >& search_reqs_info,
|
||||
|
@ -332,6 +332,13 @@ class p3turtle: public p3Service, public RsTurtle, public p3Config
|
||||
/// Send a data request into the correct tunnel for the given file hash
|
||||
void sendTurtleData(const RsPeerId& virtual_peer_id, RsTurtleGenericTunnelItem *item) ;
|
||||
|
||||
#ifdef TODO
|
||||
/// Encrypts/decrypts an item, using a autenticated construction + chacha20, based on the given 32 bytes master key.
|
||||
///
|
||||
static bool encryptItem(const RsItem *item, uint8_t* encryption_master_key, RsTurtleGenericDataItem *& encrypted_item) ;
|
||||
static bool decryptItem(RsTurtleGenericDataItem *item,uint8_t *encryption_master_key,RsItem *& decrypted_item) ;
|
||||
#endif
|
||||
|
||||
private:
|
||||
//--------------------------- Admin/Helper functions -------------------------//
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user