added secure retrieval of distant groups

This commit is contained in:
csoler 2018-06-30 21:52:25 +02:00
parent db06c32e80
commit 80a43fe3d5
No known key found for this signature in database
GPG Key ID: 7BCA522266C0804C
6 changed files with 199 additions and 9 deletions

View File

@ -1807,6 +1807,23 @@ bool RsGxsDataAccess::updateGroupData(RsNxsGrp* grp) {
return mDataStore->updateGroup(grpM);
}
bool RsGxsDataAccess::getGroupData(const RsGxsGroupId& grpId, RsNxsGrp *& grp_data)
{
RsStackMutex stack(mDataMutex);
std::map<RsGxsGroupId, RsNxsGrp*> grps ;
grps[grpId] = NULL ;
if(mDataStore->retrieveNxsGrps(grps, false, true)) // the false here is very important: it removes the private key parts.
{
grp_data = grps.begin()->second;
return true;
}
else
return false ;
}
bool RsGxsDataAccess::addMsgData(RsNxsMsg* msg) {
RsStackMutex stack(mDataMutex);

View File

@ -156,6 +156,14 @@ public:
*/
bool addMsgData(RsNxsMsg* msg);
/*!
* This retrieves a group from the gxs data base, this is a blocking call \n
* @param grp the group to add, memory ownership passed to the callee
* @return false if group cound not be retrieved
*/
bool getGroupData(const RsGxsGroupId& grpId,RsNxsGrp *& grp_data);
public:

View File

@ -254,6 +254,7 @@
#include "retroshare/rsgxscircles.h"
#include "retroshare/rspeers.h"
#include "pgp/pgpauxutils.h"
#include "crypto/rscrypto.h"
#include "util/rsdir.h"
#include "util/rstime.h"
#include "util/rsmemory.h"
@ -5105,7 +5106,10 @@ bool RsGxsNetService::locked_stampMsgServerUpdateTS(const RsGxsGroupId& gid)
TurtleRequestId RsGxsNetService::turtleGroupRequest(const RsGxsGroupId& group_id)
{
return mGxsNetTunnel->turtleGroupRequest(group_id,this) ;
TurtleRequestId req = mGxsNetTunnel->turtleGroupRequest(group_id,this) ;
mSearchRequests[req] = group_id;
return req;
}
TurtleRequestId RsGxsNetService::turtleSearchRequest(const std::string& match_string)
{
@ -5192,6 +5196,58 @@ void RsGxsNetService::receiveTurtleSearchResults(TurtleRequestId req, const std:
}
}
void RsGxsNetService::receiveTurtleSearchResults(TurtleRequestId req,const unsigned char *encrypted_group_data,uint32_t encrypted_group_data_len)
{
#ifdef NXS_NET_DEBUG_8
GXSNETDEBUG___ << " received encrypted group data for turtle search request " << std::hex << req << std::dec << ": " << RsUtil::BinToHex(encrypted_group_data,encrypted_group_data_len,50) << std::endl;
#endif
auto it = mSearchRequests.find(req);
if(mSearchRequests.end() == it)
{
std::cerr << "(EE) received search results for unknown request " << std::hex << req << std::dec ;
return;
}
RsGxsGroupId grpId = it->second;
uint8_t encryption_master_key[32];
Sha256CheckSum s = RsDirUtil::sha256sum(grpId.toByteArray(),grpId.SIZE_IN_BYTES);
memcpy(encryption_master_key,s.toByteArray(),32);
#ifdef NXS_NET_DEBUG_8
GXSNETDEBUG___ << " attempting data decryption with master key " << RsUtil::BinToHex(encryption_master_key,32) << std::endl;
#endif
unsigned char *clear_group_data = NULL;
uint32_t clear_group_data_len ;
if(!librs::crypto::decryptAuthenticateData(encrypted_group_data,encrypted_group_data_len,encryption_master_key,clear_group_data,clear_group_data_len))
{
std::cerr << "(EE) Could not decrypt data. Something went wrong. Wrong key??" << std::endl;
return ;
}
#ifdef NXS_NET_DEBUG_8
GXSNETDEBUG___ << " successfuly decrypted data : " << RsUtil::BinToHex(clear_group_data,clear_group_data_len,50) << std::endl;
#endif
RsItem *item = RsNxsSerialiser(mServType).deserialise(clear_group_data,&clear_group_data_len) ;
free(clear_group_data);
clear_group_data = NULL ;
RsNxsGrp *nxs_grp = dynamic_cast<RsNxsGrp*>(item) ;
if(nxs_grp == NULL)
{
std::cerr << "(EE) decrypted item is not a RsNxsGrp. Weird!" << std::endl;
return ;
}
std::vector<RsNxsGrp*> new_grps(1,nxs_grp);
#ifdef NXS_NET_DEBUG_8
GXSNETDEBUG___ << " passing the grp data to observer." << std::endl;
#endif
mObserver->receiveNewGroups(new_grps);
}
bool RsGxsNetService::search(const std::string& substring,std::list<RsGxsGroupSummary>& group_infos)
{
RsGxsGrpMetaTemporaryMap grpMetaMap;
@ -5228,4 +5284,80 @@ bool RsGxsNetService::search(const std::string& substring,std::list<RsGxsGroupSu
return !group_infos.empty();
}
bool RsGxsNetService::search(const Sha1CheckSum& hashed_group_id,unsigned char *& encrypted_group_data,uint32_t& encrypted_group_data_len)
{
// First look into the grp hash cache
#ifdef NXS_NET_DEBUG_8
GXSNETDEBUG___ << " Received group data request for hash " << hashed_group_id << std::endl;
#endif
auto it = mGroupHashCache.find(hashed_group_id) ;
RsNxsGrp *grp_data = NULL ;
if(mGroupHashCache.end() != it)
{
grp_data = it->second;
}
else
{
// Now check if the last request was too close in time, in which case, we dont retrieve data.
if(mLastCacheReloadTS + 60 < time(NULL))
{
std::cerr << "(WW) Not found in cache, and last cache reload less than 60 secs ago. Returning false. " << std::endl;
return false ;
}
#ifdef NXS_NET_DEBUG_8
GXSNETDEBUG___ << " reloading group cache information" << std::endl;
#endif
RsNxsGrpDataTemporaryMap grpDataMap;
{
RS_STACK_MUTEX(mNxsMutex) ;
mDataStore->retrieveNxsGrps(grpDataMap, true, true);
}
for(auto it(grpDataMap.begin());it!=grpDataMap.end();++it)
if(it->second->metaData->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED ) // only cache subscribed groups
{
RsNxsGrp *grp = it->second ;
delete grp->metaData ; // clean private keys
grp->metaData = NULL ;
Sha1CheckSum hash(RsDirUtil::sha1sum(it->first.toByteArray(),it->first.SIZE_IN_BYTES));
mGroupHashCache[hash] = grp ;
if(hash == hashed_group_id)
grp_data = grp ;
}
}
if(!grp_data)
{
#ifdef NXS_NET_DEBUG_8
GXSNETDEBUG___ << " no group found for hash " << hashed_group_id << ": returning false." << std::endl;
#endif
return false ;
}
#ifdef NXS_NET_DEBUG_8
GXSNETDEBUG___ << " found corresponding group data group id in cache group_id=" << grp_data->grpId << std::endl;
#endif
// Finally, serialize and encrypt the grp data
uint32_t size = RsNxsSerialiser(mServType).size(grp_data);
RsTemporaryMemory mem(size) ;
RsNxsSerialiser(mServType).serialise(grp_data,mem,&size) ;
uint8_t encryption_master_key[32];
Sha256CheckSum s = RsDirUtil::sha256sum(grp_data->grpId.toByteArray(),grp_data->grpId.SIZE_IN_BYTES);
memcpy(encryption_master_key,s.toByteArray(),32);
#ifdef NXS_NET_DEBUG_8
GXSNETDEBUG___ << " sending data encrypted with master key " << RsUtil::BinToHex(encryption_master_key,32) << std::endl;
#endif
return librs::crypto::encryptAuthenticateData(mem,size,encryption_master_key,encrypted_group_data,encrypted_group_data_len);
}

View File

@ -131,7 +131,10 @@ public:
virtual TurtleRequestId turtleSearchRequest(const std::string& match_string);
virtual bool search(const std::string& substring,std::list<RsGxsGroupSummary>& group_infos) ;
virtual bool search(const Sha1CheckSum& hashed_group_id,unsigned char *& encrypted_group_data,uint32_t& encrypted_group_data_len);
virtual void receiveTurtleSearchResults(TurtleRequestId req,const std::list<RsGxsGroupSummary>& group_infos);
virtual void receiveTurtleSearchResults(TurtleRequestId req,const unsigned char *encrypted_group_data,uint32_t encrypted_group_data_len);
virtual bool retrieveDistantSearchResults(TurtleRequestId req, std::map<RsGxsGroupId, RsGxsGroupSummary> &group_infos);
virtual bool clearDistantSearchResults(const TurtleRequestId& id);
virtual bool retrieveDistantGroupSummary(const RsGxsGroupId&,RsGxsGroupSummary&);
@ -609,6 +612,10 @@ private:
uint32_t mDefaultMsgStorePeriod ;
uint32_t mDefaultMsgSyncPeriod ;
std::map<Sha1CheckSum, RsNxsGrp*> mGroupHashCache;
std::map<TurtleRequestId,RsGxsGroupId> mSearchRequests;
time_t mLastCacheReloadTS ;
};
#endif // RSGXSNETSERVICE_H

View File

@ -163,6 +163,27 @@ public:
RsTypeSerializer::serial_process(j,ctx,group_infos,"group_infos") ;
}
};
class RsGxsNetTunnelTurtleSearchGroupDataItem: public RsGxsNetTunnelItem
{
public:
explicit RsGxsNetTunnelTurtleSearchGroupDataItem(): RsGxsNetTunnelItem(RS_PKT_SUBTYPE_GXS_NET_TUNNEL_TURTLE_SEARCH_GROUP_DATA) {}
virtual ~RsGxsNetTunnelTurtleSearchGroupDataItem() {}
uint16_t service ;
unsigned char *encrypted_group_data ;
uint32_t encrypted_group_data_len ;
virtual void clear() { free(encrypted_group_data);encrypted_group_data=NULL;encrypted_group_data_len=0; }
virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
{
RsTypeSerializer::serial_process<uint16_t>(j,ctx,service,"service") ;
RsTypeSerializer::TlvMemBlock_proxy prox(encrypted_group_data,encrypted_group_data_len) ;
RsTypeSerializer::serial_process(j,ctx,prox,"encrypted_group_data") ;
}
};
class RsGxsNetTunnelSerializer: public RsServiceSerializer
{
public:
@ -184,7 +205,7 @@ public:
case RS_PKT_SUBTYPE_GXS_NET_TUNNEL_TURTLE_SEARCH_SUBSTRING : return new RsGxsNetTunnelTurtleSearchSubstringItem;
case RS_PKT_SUBTYPE_GXS_NET_TUNNEL_TURTLE_SEARCH_GROUP_REQUEST : return new RsGxsNetTunnelTurtleSearchGroupRequestItem;
case RS_PKT_SUBTYPE_GXS_NET_TUNNEL_TURTLE_SEARCH_GROUP_SUMMARY : return new RsGxsNetTunnelTurtleSearchGroupSummaryItem;
//case RS_PKT_SUBTYPE_GXS_NET_TUNNEL_TURTLE_SEARCH_GROUP_DATA : return new RsGxsNetTunnelTurtleSearchGroupDataItem;
case RS_PKT_SUBTYPE_GXS_NET_TUNNEL_TURTLE_SEARCH_GROUP_DATA : return new RsGxsNetTunnelTurtleSearchGroupDataItem;
default:
GXS_NET_TUNNEL_ERROR() << "type ID " << std::hex << (int)item_subtype << std::dec << " is not handled!" << std::endl;
return NULL ;
@ -1033,20 +1054,22 @@ bool RsGxsNetTunnelService::receiveSearchRequest(unsigned char *search_request_d
if(substring_gr != NULL)
{
#ifdef TODO
auto it = mSearchableGxsServices.find(substring_sr->service) ;
RS_STACK_MUTEX(mGxsNetTunnelMtx);
auto it = mSearchableServices.find(substring_gr->service) ;
RsNxsGrp *grp = NULL ;
unsigned char *encrypted_group_data = NULL ;
uint32_t encrypted_group_data_len = 0 ;
if(it != mSearchableGxsServices.end() && it->second.search(substring_sr->group_id,grp))
if(it != mSearchableServices.end() && it->second->search(substring_gr->hashed_group_id,encrypted_group_data,encrypted_group_data_len))
{
RsGxsNetTunnelTurtleSearchGroupDataItem search_result_item ;
search_result_item.service = substring_sr->service ;
search_result_item.group_infos = results ;
search_result_item.encrypted_group_data = encrypted_group_data ;
search_result_item.encrypted_group_data_len = encrypted_group_data_len;
search_result_data_size = RsGxsNetTunnelSerializer().size(&search_result_item) ;
search_result_data = (unsigned char*)rs_malloc(size) ;
search_result_data = (unsigned char*)rs_malloc(search_result_data_size) ;
if(search_result_data == NULL)
return false ;
@ -1055,7 +1078,6 @@ bool RsGxsNetTunnelService::receiveSearchRequest(unsigned char *search_request_d
return true ;
}
#endif
}
return false ;

View File

@ -133,6 +133,7 @@ public:
virtual bool retrieveDistantGroupSummary(const RsGxsGroupId&,RsGxsGroupSummary&)=0;
virtual bool search(const std::string& substring,std::list<RsGxsGroupSummary>& group_infos) =0;
virtual bool search(const Sha1CheckSum& hashed_group_id,unsigned char *& encrypted_group_data,uint32_t& encrypted_group_data_len)=0;
/*!
* Initiates a search through the network
@ -152,6 +153,9 @@ public:
*/
//virtual int searchGrps(RsGxsSearch* search, uint8_t hops = 1, bool retrieve = 0) = 0;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// DATA ACCESS FUNCTIONS ///
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*!
* pauses synchronisation of subscribed groups and request for group id