half way through RsNxsItem encryption

This commit is contained in:
csoler 2015-09-27 23:53:55 -04:00
parent e8c93a5639
commit 6626538cab
6 changed files with 215 additions and 95 deletions

View file

@ -217,9 +217,10 @@ class RsGcxs
virtual bool isLoaded(const RsGxsCircleId &circleId) = 0; virtual bool isLoaded(const RsGxsCircleId &circleId) = 0;
virtual bool loadCircle(const RsGxsCircleId &circleId) = 0; virtual bool loadCircle(const RsGxsCircleId &circleId) = 0;
virtual int canSend(const RsGxsCircleId &circleId, const RsPgpId &id) = 0; virtual int canSend(const RsGxsCircleId &circleId, const RsPgpId &id) = 0;
virtual int canReceive(const RsGxsCircleId &circleId, const RsPgpId &id) = 0; virtual int canReceive(const RsGxsCircleId &circleId, const RsPgpId &id) = 0;
virtual bool recipients(const RsGxsCircleId &circleId, std::list<RsPgpId> &friendlist) = 0; virtual bool recipients(const RsGxsCircleId &circleId, std::list<RsPgpId>& friendlist) = 0;
virtual bool recipients(const RsGxsCircleId &circleId, std::list<RsGxsId>& idlist) = 0;
}; };

View file

@ -29,6 +29,7 @@
#include <math.h> #include <math.h>
#include "rsgxsnetservice.h" #include "rsgxsnetservice.h"
#include "gxssecurity.h"
#include "retroshare/rsconfig.h" #include "retroshare/rsconfig.h"
#include "retroshare/rsgxsflags.h" #include "retroshare/rsgxsflags.h"
#include "retroshare/rsgxscircles.h" #include "retroshare/rsgxscircles.h"
@ -2356,6 +2357,11 @@ void RsGxsNetService::locked_genSendGrpsTransaction(NxsTransaction* tr)
void RsGxsNetService::runVetting() void RsGxsNetService::runVetting()
{ {
// The vetting operation consists in transforming pending group/msg Id requests and grp/msg content requests
// into real transactions, based on the authorisations of the Peer Id these transactions are targeted to using the
// reputation system.
//
RS_STACK_MUTEX(mNxsMutex) ; RS_STACK_MUTEX(mNxsMutex) ;
std::vector<AuthorPending*>::iterator vit = mPendingResp.begin(); std::vector<AuthorPending*>::iterator vit = mPendingResp.begin();
@ -2364,6 +2370,8 @@ void RsGxsNetService::runVetting()
{ {
AuthorPending* ap = *vit; AuthorPending* ap = *vit;
// ap->accepted() looks into the reputation of the destination
if(ap->accepted() || ap->expired()) if(ap->accepted() || ap->expired())
{ {
// add to transactions // add to transactions
@ -2439,115 +2447,120 @@ void RsGxsNetService::locked_genSendMsgsTransaction(NxsTransaction* tr)
{ {
#ifdef NXS_NET_DEBUG #ifdef NXS_NET_DEBUG
std::cerr << "locked_genSendMsgsTransaction()" << std::endl; std::cerr << "locked_genSendMsgsTransaction()" << std::endl;
std::cerr << "Generating Msg data send fron TransN: " << tr->mTransaction->transactionNumber std::cerr << "Generating Msg data send fron TransN: " << tr->mTransaction->transactionNumber
<< std::endl; << std::endl;
#endif #endif
// go groups requested in transaction tr // go groups requested in transaction tr
std::list<RsNxsItem*>::iterator lit = tr->mItems.begin(); std::list<RsNxsItem*>::iterator lit = tr->mItems.begin();
GxsMsgReq msgIds; GxsMsgReq msgIds;
GxsMsgResult msgs; GxsMsgResult msgs;
if(tr->mItems.empty()){ if(tr->mItems.empty()){
return; return;
} }
// hacky assumes a transaction only consist of a single grpId // hacky assumes a transaction only consist of a single grpId
RsGxsGroupId grpId; RsGxsGroupId grpId;
for(;lit != tr->mItems.end(); ++lit) for(;lit != tr->mItems.end(); ++lit)
{ {
RsNxsSyncMsgItem* item = dynamic_cast<RsNxsSyncMsgItem*>(*lit); RsNxsSyncMsgItem* item = dynamic_cast<RsNxsSyncMsgItem*>(*lit);
if (item) if (item)
{ {
msgIds[item->grpId].push_back(item->msgId); msgIds[item->grpId].push_back(item->msgId);
if(grpId.isNull()) if(grpId.isNull())
grpId = item->grpId; grpId = item->grpId;
} }
else else
{ {
#ifdef NXS_NET_DEBUG #ifdef NXS_NET_DEBUG
std::cerr << "RsGxsNetService::locked_genSendMsgsTransaction(): item failed to caste to RsNxsSyncMsgItem* " std::cerr << "RsGxsNetService::locked_genSendMsgsTransaction(): item failed to caste to RsNxsSyncMsgItem* "
<< std::endl; << std::endl;
#endif #endif
} }
} }
mDataStore->retrieveNxsMsgs(msgIds, msgs, false, false); mDataStore->retrieveNxsMsgs(msgIds, msgs, false, false);
NxsTransaction* newTr = new NxsTransaction(); NxsTransaction* newTr = new NxsTransaction();
newTr->mFlag = NxsTransaction::FLAG_STATE_WAITING_CONFIRM; newTr->mFlag = NxsTransaction::FLAG_STATE_WAITING_CONFIRM;
uint32_t transN = locked_getTransactionId(); uint32_t transN = locked_getTransactionId();
// store msg items to send in transaction // store msg items to send in transaction
GxsMsgResult::iterator mit = msgs.begin(); GxsMsgResult::iterator mit = msgs.begin();
RsPeerId peerId = tr->mTransaction->PeerId(); RsPeerId peerId = tr->mTransaction->PeerId();
uint32_t msgSize = 0; uint32_t msgSize = 0;
for(;mit != msgs.end(); ++mit) for(;mit != msgs.end(); ++mit)
{ {
std::vector<RsNxsMsg*>& msgV = mit->second; std::vector<RsNxsMsg*>& msgV = mit->second;
std::vector<RsNxsMsg*>::iterator vit = msgV.begin(); std::vector<RsNxsMsg*>::iterator vit = msgV.begin();
for(; vit != msgV.end(); ++vit)
{
RsNxsMsg* msg = *vit;
msg->PeerId(peerId);
msg->transactionNumber = transN;
for(; vit != msgV.end(); ++vit)
{
RsNxsMsg* msg = *vit;
msg->PeerId(peerId);
msg->transactionNumber = transN;
#ifndef NXS_FRAG #ifndef NXS_FRAG
newTr->mItems.push_back(msg); newTr->mItems.push_back(msg);
msgSize++; msgSize++;
#else #else
MsgFragments fragments; MsgFragments fragments;
fragmentMsg(*msg, fragments); fragmentMsg(*msg, fragments);
MsgFragments::iterator mit = fragments.begin(); MsgFragments::iterator mit = fragments.begin();
for(; mit != fragments.end(); ++mit) for(; mit != fragments.end(); ++mit)
{ {
newTr->mItems.push_back(*mit); newTr->mItems.push_back(*mit);
msgSize++; msgSize++;
} }
#endif #endif
} }
} }
if(newTr->mItems.empty()){ if(newTr->mItems.empty()){
delete newTr; delete newTr;
return; return;
} }
uint32_t updateTS = 0; // now if transaction is limited to an external group, encrypt it for members of the group.
ServerMsgMap::const_iterator cit = mServerMsgUpdateMap.find(grpId); if()
encryptTransaction(newTr,circl_EId
if(cit != mServerMsgUpdateMap.end()) uint32_t updateTS = 0;
updateTS = cit->second->msgUpdateTS;
RsNxsTransacItem* ntr = new RsNxsTransacItem(mServType); ServerMsgMap::const_iterator cit = mServerMsgUpdateMap.find(grpId);
ntr->transactionNumber = transN;
ntr->transactFlag = RsNxsTransacItem::FLAG_BEGIN_P1 |
RsNxsTransacItem::FLAG_TYPE_MSGS;
ntr->updateTS = updateTS;
ntr->nItems = msgSize;
ntr->PeerId(peerId);
newTr->mTransaction = new RsNxsTransacItem(*ntr); if(cit != mServerMsgUpdateMap.end())
newTr->mTransaction->PeerId(mOwnId); updateTS = cit->second->msgUpdateTS;
RsNxsTransacItem* ntr = new RsNxsTransacItem(mServType);
ntr->transactionNumber = transN;
ntr->transactFlag = RsNxsTransacItem::FLAG_BEGIN_P1 |
RsNxsTransacItem::FLAG_TYPE_MSGS;
ntr->updateTS = updateTS;
ntr->nItems = msgSize;
ntr->PeerId(peerId);
newTr->mTransaction = new RsNxsTransacItem(*ntr);
newTr->mTransaction->PeerId(mOwnId);
newTr->mTimeOut = time(NULL) + mTransactionTimeOut; newTr->mTimeOut = time(NULL) + mTransactionTimeOut;
ntr->PeerId(tr->mTransaction->PeerId()); ntr->PeerId(tr->mTransaction->PeerId());
sendItem(ntr); sendItem(ntr);
locked_addTransaction(newTr); locked_addTransaction(newTr);
return; return;
} }
uint32_t RsGxsNetService::locked_getTransactionId() uint32_t RsGxsNetService::locked_getTransactionId()
{ {
@ -2559,23 +2572,112 @@ bool RsGxsNetService::locked_addTransaction(NxsTransaction* tr)
uint32_t transN = tr->mTransaction->transactionNumber; uint32_t transN = tr->mTransaction->transactionNumber;
TransactionIdMap& transMap = mTransactions[peer]; TransactionIdMap& transMap = mTransactions[peer];
bool transNumExist = transMap.find(transN) bool transNumExist = transMap.find(transN)
!= transMap.end(); != transMap.end();
if(transNumExist){ if(transNumExist)
{
#ifdef NXS_NET_DEBUG #ifdef NXS_NET_DEBUG
std::cerr << "locked_addTransaction() " << std::endl; std::cerr << "locked_addTransaction() " << std::endl;
std::cerr << "Transaction number exist already, transN: " << transN << std::endl; std::cerr << "Transaction number exist already, transN: " << transN << std::endl;
#endif #endif
return false; return false;
}else{
#ifdef NXS_NET_DEBUG
std::cerr << "locked_addTransaction() " << std::endl;
std::cerr << "Added transaction number " << transN << std::endl;
#endif
transMap[transN] = tr;
return true;
} }
#ifdef NXS_NET_DEBUG
std::cerr << "locked_addTransaction() " << std::endl;
std::cerr << "Added transaction number " << transN << std::endl;
#endif
transMap[transN] = tr;
if(!tr->destination_circle.isNull())
encryptTransaction(tr);
return true;
}
bool RsGxsNetService::encryptTransaction(NxsTransaction *tr)
{
std::cerr << "RsGxsNetService::encryptTransaction()" << std::endl;
std::cerr << " Circle Id: " << tr->destination_circle << std::endl;
// 1 - Find out the list of GXS ids to encrypt for
// We could do smarter things (like see if the peer_id owns one of the circle's identities
// but for now we aim at the simplest solution: encrypt for all identities in the circle.
std::list<RsGxsId> recipients ;
if(!mCircles->recipients(tr->destination_circle,recipients))
{
std::cerr << " (EE) Cannot encrypt transaction: recipients list not available." << std::endl;
return false ;
}
std::cerr << " Dest Ids: " << std::endl;
for(std::list<RsGxsId>::const_iterator it(recipients.begin());it!=recipients.end();++it)
std::cerr << " " << *it << std::endl;
// 2 - call GXSSecurity to make a header item that encrypts for the given list of peers.
GxsSecurity::MultiEncryptionContext muctx ;
GxsSecurity::initMultiEncryption(muctx,recipients);
// 3 - serialise and encrypt each message, converting it into a NxsEncryptedDataItem
std::list<RsNxsItem*> encrypted_items ;
for(std::list<RsNxsItem*>::const_iterator it(tr->mItems.begin());it!=tr->mItems.end();++it)
{
uint32_t size = (*it)->serial_size() ;
RsTemporaryMemory tempmem( size ) ;
if(!(*it)->serialise(tempmem,size))
{
std::cerr << " (EE) Cannot serialise item. Something went wrong." << std::endl;
continue ;
}
unsigned char *encrypted_data = NULL ;
unsigned char *encrypted_len = 0 ;
if(!GxsSecurity::encrypt(muctx,tempmem,tempmemsize,encryted_data, encryted_len))
{
std::cerr << " (EE) Cannot multi-encrypt item. Something went wrong." << std::endl;
continue ;
}
RsNxsEncryptedDataItem *enc_item = new RsNxsEncryptedDataItem() ;
enc_item->aes_encrypted_data.bin_len = encrypted_len ;
enc_item->aes_encrypted_data.bin_data = encrypted_data ;
enc_item->aes_encrypted_data.tlvtype = TLV_TYPE_BIN_ENCRYPTED ;
encrypted_items.push_back(enc_item) ;
}
// 4 - put back in transaction.
for(std::list<RsNxsItem*>::const_iterator it(tr->mItems.begin());it!=tr->mItems.end();++it)
delete *it ;
tr->mItems = encrypted_items ;
tr->mItems.push_front(session_key_item) ;
}
bool RsGxsNetService::decryptTransaction(NxsTransaction *tr)
{
// 1 - Checks that the transaction is encrypted. It should contain
// one packet with an encrypted session key for the group,
// and as many encrypted data items as necessary.
// 2 - Try to decrypt the session key. If not, return false. That probably means
// we don't own that identity.
// 3 - Using session key, decrypt all packets, by calling GXSSecurity.
// 4 - Deserialise packets from the decrypted data and restore the clear transaction.
} }
void RsGxsNetService::cleanTransactionItems(NxsTransaction* tr) const void RsGxsNetService::cleanTransactionItems(NxsTransaction* tr) const
@ -2775,6 +2877,9 @@ bool RsGxsNetService::canSendGrpId(const RsPeerId& sslId, RsGxsGrpMetaData& grpM
std::cerr << "RsGxsNetService::canSendGrpId() EXTERNAL_CIRCLE, checking mCircles->canSend"; std::cerr << "RsGxsNetService::canSendGrpId() EXTERNAL_CIRCLE, checking mCircles->canSend";
std::cerr << std::endl; std::cerr << std::endl;
#endif #endif
// the sending authorisation is based on:
// getPgpId(peer_id) being a signer of one GxsId in the Circle
//
const RsPgpId& pgpId = mPgpUtils->getPGPId(sslId); const RsPgpId& pgpId = mPgpUtils->getPGPId(sslId);
return mCircles->canSend(circleId, pgpId); return mCircles->canSend(circleId, pgpId);
} }

View file

@ -68,6 +68,8 @@ public:
*/ */
RsNxsTransacItem* mTransaction; RsNxsTransacItem* mTransaction;
std::list<RsNxsItem*> mItems; // items received or sent std::list<RsNxsItem*> mItems; // items received or sent
mGxsCircleId destination_circle;
}; };
/*! /*!

View file

@ -182,12 +182,10 @@ const uint16_t TLV_TYPE_KEY_PUB_RSA = 0x0112; /* not used yet */
const uint16_t TLV_TYPE_SIGN_RSA_SHA1 = 0x0120; /* Used (Distrib/Forums) */ const uint16_t TLV_TYPE_SIGN_RSA_SHA1 = 0x0120; /* Used (Distrib/Forums) */
const uint16_t TLV_TYPE_BIN_IMAGE = 0x0130; /* Used (Generic - Forums) */ const uint16_t TLV_TYPE_BIN_IMAGE = 0x0130; /* Used (Generic - Forums) */
const uint16_t TLV_TYPE_BIN_FILEDATA = 0x0140; /* Used - ACTIVE! */ const uint16_t TLV_TYPE_BIN_FILEDATA = 0x0140; /* Used - ACTIVE! */
const uint16_t TLV_TYPE_BIN_SERIALISE = 0x0150; /* Used (Generic - Distrib) */ const uint16_t TLV_TYPE_BIN_SERIALISE = 0x0150; /* Used (Generic - Distrib) */
const uint16_t TLV_TYPE_BIN_GENERIC = 0x0160; /* Used (DSDV Data) */ const uint16_t TLV_TYPE_BIN_GENERIC = 0x0160; /* Used (DSDV Data) */
const uint16_t TLV_TYPE_BIN_ENCRYPTED = 0x0170; /* Encrypted data
/**** Compound Types ****/ /**** Compound Types ****/

View file

@ -371,7 +371,7 @@ int p3GxsCircles::canReceive(const RsGxsCircleId &circleId, const RsPgpId &id)
return -1; return -1;
} }
bool p3GxsCircles::recipients(const RsGxsCircleId &circleId, std::list<RsPgpId> &friendlist) bool p3GxsCircles::recipients(const RsGxsCircleId &circleId, std::list<RsPgpId>& friendlist)
{ {
RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/ RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/
if (mCircleCache.is_cached(circleId)) if (mCircleCache.is_cached(circleId))
@ -383,6 +383,19 @@ bool p3GxsCircles::recipients(const RsGxsCircleId &circleId, std::list<RsPgpId>
return false; return false;
} }
bool p3GxsCircles::recipients(const RsGxsCircleId& circleId, std::list<RsGxsId>& gxs_ids)
{
RsGxsCircleDetails details ;
if(!getCircleDetails(circleId, details))
return false;
for(std::set<RsGxsId>::const_iterator it(details.mUnknownPeers.begin());it!=details.mUnknownPeers.end();+it)
gxs_ids.push_back(*it) ;
return true;
}
/********************************************************************************/ /********************************************************************************/
/******************* Get/Set Data ******************************************/ /******************* Get/Set Data ******************************************/
/********************************************************************************/ /********************************************************************************/

View file

@ -178,6 +178,7 @@ virtual RsServiceInfo getServiceInfo();
virtual int canSend(const RsGxsCircleId &circleId, const RsPgpId &id); virtual int canSend(const RsGxsCircleId &circleId, const RsPgpId &id);
virtual int canReceive(const RsGxsCircleId &circleId, const RsPgpId &id); virtual int canReceive(const RsGxsCircleId &circleId, const RsPgpId &id);
virtual bool recipients(const RsGxsCircleId &circleId, std::list<RsPgpId> &friendlist); virtual bool recipients(const RsGxsCircleId &circleId, std::list<RsPgpId> &friendlist);
virtual bool recipients(const RsGxsCircleId &circleId, std::list<RsGxsId> &gxs_ids);
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsCircleGroup> &groups); virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsCircleGroup> &groups);