implemented per-item encryption and Vetting method compatibility layer

This commit is contained in:
csoler 2016-02-20 17:53:03 -05:00
parent b2a6bfbbd0
commit 6a4add8806
10 changed files with 533 additions and 390 deletions

View file

@ -98,7 +98,9 @@ static void setRSAPublicKeyData(RsTlvSecurityKey & key, RSA *rsa_pub)
bool GxsSecurity::checkPrivateKey(const RsTlvSecurityKey& key) bool GxsSecurity::checkPrivateKey(const RsTlvSecurityKey& key)
{ {
#ifdef GXS_SECURITY_DEBUG
std::cerr << "Checking private key " << key.keyId << " ..." << std::endl; std::cerr << "Checking private key " << key.keyId << " ..." << std::endl;
#endif
if( (key.keyFlags & RSTLV_KEY_TYPE_MASK) != RSTLV_KEY_TYPE_FULL) if( (key.keyFlags & RSTLV_KEY_TYPE_MASK) != RSTLV_KEY_TYPE_FULL)
{ {
@ -133,7 +135,9 @@ bool GxsSecurity::checkPrivateKey(const RsTlvSecurityKey& key)
} }
bool GxsSecurity::checkPublicKey(const RsTlvSecurityKey& key) bool GxsSecurity::checkPublicKey(const RsTlvSecurityKey& key)
{ {
#ifdef GXS_SECURITY_DEBUG
std::cerr << "Checking public key " << key.keyId << " ..." << std::endl; std::cerr << "Checking public key " << key.keyId << " ..." << std::endl;
#endif
if( (key.keyFlags & RSTLV_KEY_TYPE_MASK) != RSTLV_KEY_TYPE_PUBLIC_ONLY) if( (key.keyFlags & RSTLV_KEY_TYPE_MASK) != RSTLV_KEY_TYPE_PUBLIC_ONLY)
{ {
@ -229,7 +233,7 @@ bool GxsSecurity::extractPublicKey(const RsTlvSecurityKey& private_key,RsTlvSecu
{ {
std::cerr << std::endl; std::cerr << std::endl;
std::cerr << "WARNING: GXS ID key pair " << private_key.keyId << " has inconsistent fingerprint. This is an old key " << std::endl; std::cerr << "WARNING: GXS ID key pair " << private_key.keyId << " has inconsistent fingerprint. This is an old key " << std::endl;
std::cerr << " that is unsecured (can be faked easily) should not be used anymore. Please delete it." << std::endl; std::cerr << " that is unsecure (can be faked easily). You should delete it!" << std::endl;
std::cerr << std::endl; std::cerr << std::endl;
public_key.keyId = private_key.keyId ; public_key.keyId = private_key.keyId ;
@ -875,7 +879,7 @@ bool GxsSecurity::decrypt(uint8_t *& out, uint32_t & outlen, const uint8_t *in,
// //
// This method can be used to decrypt multi-encrypted data, if passing he correct encrypted key block (corresponding to the given key) // This method can be used to decrypt multi-encrypted data, if passing he correct encrypted key block (corresponding to the given key)
#ifdef DISTRIB_DEBUG #ifdef GXS_SECURITY_DEBUG
std::cerr << "GxsSecurity::decrypt() " << std::endl; std::cerr << "GxsSecurity::decrypt() " << std::endl;
#endif #endif
RSA *rsa_publish = extractPrivateKey(key) ; RSA *rsa_publish = extractPrivateKey(key) ;
@ -891,7 +895,7 @@ bool GxsSecurity::decrypt(uint8_t *& out, uint32_t & outlen, const uint8_t *in,
} }
else else
{ {
#ifdef DISTRIB_DEBUG #ifdef GXS_SECURITY_DEBUG
std::cerr << "GxsSecurity(): Could not generate publish key " << grpId std::cerr << "GxsSecurity(): Could not generate publish key " << grpId
<< std::endl; << std::endl;
#endif #endif
@ -1017,10 +1021,12 @@ bool GxsSecurity::decrypt(uint8_t *& out, uint32_t & outlen, const uint8_t *in,
throw std::runtime_error("Offset error") ; throw std::runtime_error("Offset error") ;
encrypted_block_size = inlen - encrypted_block_offset ; encrypted_block_size = inlen - encrypted_block_offset ;
#ifdef GXS_SECURITY_DEBUG
std::cerr << " number of keys in envelop: " << number_of_keys << std::endl; std::cerr << " number of keys in envelop: " << number_of_keys << std::endl;
std::cerr << " IV offset : " << IV_offset << std::endl; std::cerr << " IV offset : " << IV_offset << std::endl;
std::cerr << " encrypted block offset : " << encrypted_block_offset << std::endl; std::cerr << " encrypted block offset : " << encrypted_block_offset << std::endl;
std::cerr << " encrypted block size : " << encrypted_block_size << std::endl; std::cerr << " encrypted block size : " << encrypted_block_size << std::endl;
#endif
// decrypt // decrypt
@ -1033,7 +1039,9 @@ bool GxsSecurity::decrypt(uint8_t *& out, uint32_t & outlen, const uint8_t *in,
RSA *rsa_private = extractPrivateKey(keys[j]) ; RSA *rsa_private = extractPrivateKey(keys[j]) ;
EVP_PKEY *privateKey = NULL; EVP_PKEY *privateKey = NULL;
#ifdef GXS_SECURITY_DEBUG
std::cerr << " trying key " << keys[j].keyId << std::endl; std::cerr << " trying key " << keys[j].keyId << std::endl;
#endif
if(rsa_private != NULL) if(rsa_private != NULL)
{ {
@ -1051,7 +1059,9 @@ bool GxsSecurity::decrypt(uint8_t *& out, uint32_t & outlen, const uint8_t *in,
{ {
succeed = EVP_OpenInit(&ctx, EVP_aes_128_cbc(),in + encrypted_keys_offset + i*MULTI_ENCRYPTION_FORMAT_v001_ENCRYPTED_KEY_SIZE , MULTI_ENCRYPTION_FORMAT_v001_ENCRYPTED_KEY_SIZE, in+IV_offset, privateKey); succeed = EVP_OpenInit(&ctx, EVP_aes_128_cbc(),in + encrypted_keys_offset + i*MULTI_ENCRYPTION_FORMAT_v001_ENCRYPTED_KEY_SIZE , MULTI_ENCRYPTION_FORMAT_v001_ENCRYPTED_KEY_SIZE, in+IV_offset, privateKey);
#ifdef GXS_SECURITY_DEBUG
std::cerr << " encrypted key at offset " << encrypted_keys_offset + i*MULTI_ENCRYPTION_FORMAT_v001_ENCRYPTED_KEY_SIZE << ": " << succeed << std::endl; std::cerr << " encrypted key at offset " << encrypted_keys_offset + i*MULTI_ENCRYPTION_FORMAT_v001_ENCRYPTED_KEY_SIZE << ": " << succeed << std::endl;
#endif
} }
EVP_PKEY_free(privateKey) ; EVP_PKEY_free(privateKey) ;
@ -1060,7 +1070,9 @@ bool GxsSecurity::decrypt(uint8_t *& out, uint32_t & outlen, const uint8_t *in,
if(!succeed) if(!succeed)
throw std::runtime_error("No matching key available.") ; throw std::runtime_error("No matching key available.") ;
#ifdef GXS_SECURITY_DEBUG
std::cerr << " now decrypting with the matching key." << std::endl; std::cerr << " now decrypting with the matching key." << std::endl;
#endif
out = (uint8_t*)rs_malloc(encrypted_block_size) ; out = (uint8_t*)rs_malloc(encrypted_block_size) ;
@ -1079,7 +1091,9 @@ bool GxsSecurity::decrypt(uint8_t *& out, uint32_t & outlen, const uint8_t *in,
outlen += out_currOffset; outlen += out_currOffset;
#ifdef GXS_SECURITY_DEBUG
std::cerr << " successfully decrypted block of size " << outlen << std::endl; std::cerr << " successfully decrypted block of size " << outlen << std::endl;
#endif
return true; return true;
} }
catch(std::exception& e) catch(std::exception& e)

View file

@ -211,7 +211,7 @@ 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,bool& should_encrypt) = 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; virtual bool recipients(const RsGxsCircleId &circleId, std::list<RsGxsId>& idlist) = 0;

View file

@ -279,6 +279,13 @@ static std::string nice_time_stamp(time_t now,time_t TS)
} }
#endif #endif
static const uint32_t RS_NXS_ITEM_ENCRYPTION_STATUS_UNKNOWN = 0x00 ;
static const uint32_t RS_NXS_ITEM_ENCRYPTION_STATUS_NO_ERROR = 0x01 ;
static const uint32_t RS_NXS_ITEM_ENCRYPTION_STATUS_CIRCLE_ERROR = 0x02 ;
static const uint32_t RS_NXS_ITEM_ENCRYPTION_STATUS_ENCRYPTION_ERROR = 0x03 ;
static const uint32_t RS_NXS_ITEM_ENCRYPTION_STATUS_SERIALISATION_ERROR = 0x04 ;
static const uint32_t RS_NXS_ITEM_ENCRYPTION_STATUS_GXS_KEY_MISSING = 0x05 ;
static std::ostream& gxsnetdebug(const RsPeerId& peer_id,const RsGxsGroupId& grp_id,uint32_t service_type) static std::ostream& gxsnetdebug(const RsPeerId& peer_id,const RsGxsGroupId& grp_id,uint32_t service_type)
{ {
static nullstream null ; static nullstream null ;
@ -1182,7 +1189,7 @@ void RsGxsNetService::locked_createTransactionFromPending(GrpRespPending* grpPen
} }
void RsGxsNetService::locked_createTransactionFromPending(GrpCircleIdRequestVetting* grpPend) bool RsGxsNetService::locked_createTransactionFromPending(GrpCircleIdRequestVetting* grpPend)
{ {
#ifdef NXS_NET_DEBUG_1 #ifdef NXS_NET_DEBUG_1
GXSNETDEBUG_P_(grpPend->mPeerId) << "locked_createTransactionFromPending(GrpCircleIdReq)" << std::endl; GXSNETDEBUG_P_(grpPend->mPeerId) << "locked_createTransactionFromPending(GrpCircleIdReq)" << std::endl;
@ -1193,6 +1200,7 @@ void RsGxsNetService::locked_createTransactionFromPending(GrpCircleIdRequestVett
for(; cit != grpPend->mGrpCircleV.end(); ++cit) for(; cit != grpPend->mGrpCircleV.end(); ++cit)
{ {
const GrpIdCircleVet& entry = *cit; const GrpIdCircleVet& entry = *cit;
if(entry.mCleared) if(entry.mCleared)
{ {
#ifdef NXS_NET_DEBUG_1 #ifdef NXS_NET_DEBUG_1
@ -1206,6 +1214,26 @@ void RsGxsNetService::locked_createTransactionFromPending(GrpCircleIdRequestVett
gItem->transactionNumber = transN; gItem->transactionNumber = transN;
gItem->authorId = entry.mAuthorId; gItem->authorId = entry.mAuthorId;
// why it authorId not set here??? // why it authorId not set here???
if(entry.mShouldEncrypt)
{
#ifdef NXS_NET_DEBUG_7
GXSNETDEBUG_PG(grpPend->mPeerId,entry.mGroupId) << " item for this grpId should be encrypted." << std::endl;
#endif
RsNxsItem *encrypted_item = NULL ;
uint32_t status = RS_NXS_ITEM_ENCRYPTION_STATUS_UNKNOWN ;
if(encryptSingleNxsItem(gItem, entry.mCircleId, encrypted_item,status))
{
itemL.push_back(encrypted_item) ;
delete gItem ;
}
#ifdef NXS_NET_DEBUG_7
else
GXSNETDEBUG_PG(grpPend->mPeerId,entry.mGroupId) << " Could not encrypt item for grpId " << entry.mGroupId << " for circle " << entry.mCircleId << ". Will try later. Adding to vetting list." << std::endl;
#endif
}
else
itemL.push_back(gItem); itemL.push_back(gItem);
} }
#ifdef NXS_NET_DEBUG_1 #ifdef NXS_NET_DEBUG_1
@ -1216,9 +1244,11 @@ void RsGxsNetService::locked_createTransactionFromPending(GrpCircleIdRequestVett
if(!itemL.empty()) if(!itemL.empty())
locked_pushGrpRespFromList(itemL, grpPend->mPeerId, transN); locked_pushGrpRespFromList(itemL, grpPend->mPeerId, transN);
return true ;
} }
void RsGxsNetService::locked_createTransactionFromPending(MsgCircleIdsRequestVetting* msgPend) bool RsGxsNetService::locked_createTransactionFromPending(MsgCircleIdsRequestVetting* msgPend)
{ {
std::vector<MsgIdCircleVet>::iterator vit = msgPend->mMsgs.begin(); std::vector<MsgIdCircleVet>::iterator vit = msgPend->mMsgs.begin();
std::list<RsNxsItem*> itemL; std::list<RsNxsItem*> itemL;
@ -1236,13 +1266,33 @@ void RsGxsNetService::locked_createTransactionFromPending(MsgCircleIdsRequestVet
mItem->authorId = mic.mAuthorId; mItem->authorId = mic.mAuthorId;
mItem->PeerId(msgPend->mPeerId); mItem->PeerId(msgPend->mPeerId);
mItem->transactionNumber = transN; mItem->transactionNumber = transN;
itemL.push_back(mItem);
grp_id = msgPend->mGrpId ; grp_id = msgPend->mGrpId ;
if(msgPend->mShouldEncrypt)
{
RsNxsItem *encrypted_item = NULL ;
uint32_t status = RS_NXS_ITEM_ENCRYPTION_STATUS_UNKNOWN ;
if(encryptSingleNxsItem(mItem,msgPend->mCircleId,encrypted_item,status))
{
itemL.push_back(encrypted_item) ;
delete mItem ;
}
else
{
std::cerr << "(EE) cannot encrypt Msg ids in circle-restriced response to grp " << msgPend->mGrpId << " for circle " << msgPend->mCircleId << std::endl;
return false ;
}
}
else
itemL.push_back(mItem);
} }
if(!itemL.empty()) if(!itemL.empty())
locked_pushMsgRespFromList(itemL, msgPend->mPeerId,grp_id, transN,msgPend->mCircleId); locked_pushMsgRespFromList(itemL, msgPend->mPeerId,grp_id, transN);
return true ;
} }
/*bool RsGxsNetService::locked_canReceive(const RsGxsGrpMetaData * const grpMeta /*bool RsGxsNetService::locked_canReceive(const RsGxsGrpMetaData * const grpMeta
@ -2146,7 +2196,7 @@ void RsGxsNetService::processTransactions()
// Try to decrypt the items that need to be decrypted. This function returns true if the transaction is not encrypted. // Try to decrypt the items that need to be decrypted. This function returns true if the transaction is not encrypted.
if(decryptTransaction(tr)) if(processTransactionForDecryption(tr))
{ {
#ifdef NXS_NET_DEBUG_7 #ifdef NXS_NET_DEBUG_7
GXSNETDEBUG_P_(tr->mTransaction->PeerId()) << " successfully decrypted/processed transaction " << transN << ". Adding to completed list." << std::endl; GXSNETDEBUG_P_(tr->mTransaction->PeerId()) << " successfully decrypted/processed transaction " << transN << ". Adding to completed list." << std::endl;
@ -3213,14 +3263,19 @@ void RsGxsNetService::runVetting()
{ {
GrpCircleIdRequestVetting* gcirv = static_cast<GrpCircleIdRequestVetting*>(gcv); GrpCircleIdRequestVetting* gcirv = static_cast<GrpCircleIdRequestVetting*>(gcv);
locked_createTransactionFromPending(gcirv); if(!locked_createTransactionFromPending(gcirv))
{
++vit2 ;
continue ;
}
} }
else if(gcv->getType() == GrpCircleVetting::MSG_ID_SEND_PEND) else if(gcv->getType() == GrpCircleVetting::MSG_ID_SEND_PEND)
{ {
MsgCircleIdsRequestVetting* mcirv = static_cast<MsgCircleIdsRequestVetting*>(gcv); MsgCircleIdsRequestVetting* mcirv = static_cast<MsgCircleIdsRequestVetting*>(gcv);
if(mcirv->cleared()) if(mcirv->cleared())
locked_createTransactionFromPending(mcirv); if(!locked_createTransactionFromPending(mcirv))
continue ; // keep it in the list for retry
} }
else else
{ {
@ -3282,6 +3337,31 @@ void RsGxsNetService::locked_genSendMsgsTransaction(NxsTransaction* tr)
} }
} }
#ifdef CODE_TO_ENCRYPT_MESSAGE_DATA
// now if transaction is limited to an external group, encrypt it for members of the group.
RsGxsCircleId encryption_circle ;
std::map<RsGxsGroupId, RsGxsGrpMetaData*> grp;
grp[grpId] = NULL ;
mDataStore->retrieveGxsGrpMetaData(grp);
RsGxsGrpMetaData *grpMeta = grp[grpId] ;
if(grpMeta == NULL)
{
std::cerr << "(EE) cannot retrieve group meta data for message transaction " << tr->mTransaction->transactionNumber << std::endl;
return ;
}
encryption_circle = grpMeta->mCircleId ;
delete grpMeta ;
grp.clear() ;
#ifdef NXS_NET_DEBUG_7
GXSNETDEBUG_PG(tr->mTransaction->PeerId(),grpId) << " Msg transaction items will be encrypted for circle " << std::endl;
#endif
#endif
mDataStore->retrieveNxsMsgs(msgIds, msgs, false, false); mDataStore->retrieveNxsMsgs(msgIds, msgs, false, false);
NxsTransaction* newTr = new NxsTransaction(); NxsTransaction* newTr = new NxsTransaction();
@ -3313,6 +3393,7 @@ void RsGxsNetService::locked_genSendMsgsTransaction(NxsTransaction* tr)
std::cerr << "(WW) message with ID " << msg->msgId << " in group " << msg->grpId << " exceeds size limit of " << MAX_ALLOWED_GXS_MESSAGE_SIZE << " bytes. Actual size is " << msg->msg.bin_len << " bytes. Message will be truncated and rejected at client." << std::endl; std::cerr << "(WW) message with ID " << msg->msgId << " in group " << msg->grpId << " exceeds size limit of " << MAX_ALLOWED_GXS_MESSAGE_SIZE << " bytes. Actual size is " << msg->msg.bin_len << " bytes. Message will be truncated and rejected at client." << std::endl;
msg->msg.bin_len = 1 ; // arbitrary small size, but not 0. No need to send the data since it's going to be rejected. msg->msg.bin_len = 1 ; // arbitrary small size, but not 0. No need to send the data since it's going to be rejected.
} }
#ifdef NXS_FRAG #ifdef NXS_FRAG
MsgFragments fragments; MsgFragments fragments;
fragmentMsg(*msg, fragments); fragmentMsg(*msg, fragments);
@ -3327,6 +3408,7 @@ void RsGxsNetService::locked_genSendMsgsTransaction(NxsTransaction* tr)
msgSize++; msgSize++;
} }
#else #else
msg->count = 1; // only one piece. This is to keep compatibility if we ever implement fragmenting in the future. msg->count = 1; // only one piece. This is to keep compatibility if we ever implement fragmenting in the future.
msg->pos = 0; msg->pos = 0;
@ -3334,6 +3416,31 @@ void RsGxsNetService::locked_genSendMsgsTransaction(NxsTransaction* tr)
msgSize++; msgSize++;
#endif #endif
#ifdef CODE_TO_ENCRYPT_MESSAGE_DATA
// encrypt
if(!encryption_circle.isNull())
{
uint32_t status = RS_NXS_ITEM_ENCRYPTION_STATUS_UNKNOWN ;
RsNxsEncryptedDataItem encrypted_msg_item = NULL ;
if(encryptSingleNxsItem(msg,encryption_circle,encrypted_msg_item,status))
{
newTr->mItems.push_back(msg);
delete msg ;
}
else
{
}
}
else
{
newTr->mItems.push_back(msg);
msgSize++;
}
#endif
} }
} }
@ -3342,22 +3449,6 @@ void RsGxsNetService::locked_genSendMsgsTransaction(NxsTransaction* tr)
return; return;
} }
// now if transaction is limited to an external group, encrypt it for members of the group.
std::map<RsGxsGroupId, RsGxsGrpMetaData*> grp;
grp[grpId] = NULL ;
mDataStore->retrieveGxsGrpMetaData(grp);
RsGxsGrpMetaData *grpMeta = grp[grpId] ;
if(grpMeta != NULL)
{
newTr->destination_circle = grpMeta->mCircleId ;
delete grpMeta ;
grp.clear() ;
}
// now send a transaction item and store the transaction data // now send a transaction item and store the transaction data
uint32_t updateTS = 0; uint32_t updateTS = 0;
@ -3384,8 +3475,6 @@ void RsGxsNetService::locked_genSendMsgsTransaction(NxsTransaction* tr)
#endif #endif
ntr->PeerId(tr->mTransaction->PeerId()); ntr->PeerId(tr->mTransaction->PeerId());
// Encryption will happen here if needed.
if(locked_addTransaction(newTr)) if(locked_addTransaction(newTr))
sendItem(ntr); sendItem(ntr);
else else
@ -3418,24 +3507,105 @@ bool RsGxsNetService::locked_addTransaction(NxsTransaction* tr)
return false; return false;
} }
if(!tr->destination_circle.isNull())
{
#ifdef NXS_NET_DEBUG_7
GXSNETDEBUG_P_(peer) << " Calling transaction encryption on transaction " << transN << " for circle " << tr->destination_circle << std::endl;
#endif
if(!encryptTransaction(tr))
return false ;
}
#ifdef NXS_NET_DEBUG_7
else
GXSNETDEBUG_P_(peer) << " Transaction " << transN << " sent in clear since no circle restriction found!" << std::endl;
#endif
transMap[transN] = tr; transMap[transN] = tr;
return true; return true;
} }
// Turns a single RsNxsItem into an encrypted one, suitable for the supplied destination circle.
// Returns false when the keys are not loaded. Question to solve: what do we do if we miss some keys??
// We should probably send anyway.
bool RsGxsNetService::encryptSingleNxsItem(RsNxsItem *item, const RsGxsCircleId& destination_circle, RsNxsItem *&encrypted_item, uint32_t& status)
{
encrypted_item = NULL ;
status = RS_NXS_ITEM_ENCRYPTION_STATUS_UNKNOWN ;
#ifdef NXS_NET_DEBUG_7
GXSNETDEBUG_P_ (item->PeerId()) << "Service " << std::hex << ((mServiceInfo.mServiceType >> 8)& 0xffff) << std::dec << " - Encrypting single item for peer " << item->PeerId() << ", for circle ID " << destination_circle << std::endl;
#endif
std::cerr << "RsGxsNetService::encryptSingleNxsItem()" << 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(destination_circle,recipients))
{
std::cerr << " (EE) Cannot encrypt transaction: recipients list not available. Should re-try later." << std::endl;
status = RS_NXS_ITEM_ENCRYPTION_STATUS_CIRCLE_ERROR ;
return false ;
}
#ifdef NXS_NET_DEBUG_7
GXSNETDEBUG_P_ (item->PeerId()) << " Dest Ids: " << std::endl;
#endif
std::vector<RsTlvSecurityKey> recipient_keys ;
for(std::list<RsGxsId>::const_iterator it(recipients.begin());it!=recipients.end();++it)
{
RsTlvSecurityKey pkey ;
if(!mGixs->getKey(*it,pkey))
{
std::cerr << " (EE) Cannot retrieve public key " << *it << " for circle encryption. Should retry later?" << std::endl;
// we should probably request the key?
status = RS_NXS_ITEM_ENCRYPTION_STATUS_GXS_KEY_MISSING ;
continue ;
}
#ifdef NXS_NET_DEBUG_7
GXSNETDEBUG_P_ (item->PeerId()) << " added key " << *it << std::endl;
#endif
recipient_keys.push_back(pkey) ;
}
// 2 - call GXSSecurity to make a header item that encrypts for the given list of peers.
#ifdef NXS_NET_DEBUG_7
GXSNETDEBUG_P_ (item->PeerId()) << " Encrypting..." << std::endl;
#endif
uint32_t size = item->serial_size() ;
RsTemporaryMemory tempmem( size ) ;
if(!item->serialise(tempmem,size))
{
std::cerr << " (EE) Cannot serialise item. Something went wrong." << std::endl;
status = RS_NXS_ITEM_ENCRYPTION_STATUS_SERIALISATION_ERROR ;
return false ;
}
unsigned char *encrypted_data = NULL ;
uint32_t encrypted_len = 0 ;
if(!GxsSecurity::encrypt(encrypted_data, encrypted_len,tempmem,size,recipient_keys))
{
std::cerr << " (EE) Cannot multi-encrypt item. Something went wrong." << std::endl;
status = RS_NXS_ITEM_ENCRYPTION_STATUS_ENCRYPTION_ERROR ;
return false ;
}
RsNxsEncryptedDataItem *enc_item = new RsNxsEncryptedDataItem(mServType) ;
enc_item->encrypted_data.bin_len = encrypted_len ;
enc_item->encrypted_data.bin_data = encrypted_data ;
// also copy all the important data.
enc_item->transactionNumber = item->transactionNumber ;
enc_item->PeerId(item->PeerId()) ;
encrypted_item = enc_item ;
#ifdef NXS_NET_DEBUG_7
GXSNETDEBUG_P_(item->PeerId()) << " encrypted item of size " << encrypted_len << std::endl;
#endif
status = RS_NXS_ITEM_ENCRYPTION_STATUS_NO_ERROR ;
return true ;
}
#ifdef TO_REMOVE
bool RsGxsNetService::encryptTransaction(NxsTransaction *tr) bool RsGxsNetService::encryptTransaction(NxsTransaction *tr)
{ {
#ifdef NXS_NET_DEBUG_7 #ifdef NXS_NET_DEBUG_7
@ -3585,8 +3755,8 @@ bool RsGxsNetService::encryptTransaction(NxsTransaction *tr)
RsNxsEncryptedDataItem *enc_item = new RsNxsEncryptedDataItem(mServType) ; RsNxsEncryptedDataItem *enc_item = new RsNxsEncryptedDataItem(mServType) ;
enc_item->aes_encrypted_data.bin_len = encrypted_len ; enc_item->encrypted_data.bin_len = encrypted_len ;
enc_item->aes_encrypted_data.bin_data = encrypted_data ; enc_item->encrypted_data.bin_data = encrypted_data ;
enc_item->transactionNumber = (*it)->transactionNumber ; enc_item->transactionNumber = (*it)->transactionNumber ;
enc_item->PeerId((*it)->PeerId()) ; enc_item->PeerId((*it)->PeerId()) ;
@ -3603,117 +3773,19 @@ bool RsGxsNetService::encryptTransaction(NxsTransaction *tr)
return true ; return true ;
} }
#endif
// Tries to decrypt the transaction. First load the keys and process all items. // Tries to decrypt the transaction. First load the keys and process all items.
// If keys are loaded, encrypted items that cannot be decrypted are discarded. // If keys are loaded, encrypted items that cannot be decrypted are discarded.
// Otherwise the transaction is untouched for retry later. // Otherwise the transaction is untouched for retry later.
bool RsGxsNetService::decryptTransaction(NxsTransaction *tr) bool RsGxsNetService::processTransactionForDecryption(NxsTransaction *tr)
{ {
#ifdef NXS_NET_DEBUG_7 #ifdef NXS_NET_DEBUG_7
RsPeerId peerId = tr->mTransaction->PeerId() ; RsPeerId peerId = tr->mTransaction->PeerId() ;
GXSNETDEBUG_P_(peerId) << "RsGxsNetService::decryptTransaction()" << std::endl; GXSNETDEBUG_P_(peerId) << "RsGxsNetService::decryptTransaction()" << std::endl;
GXSNETDEBUG_P_(peerId) << " Circle Id: " << tr->destination_circle << std::endl;
#endif #endif
#ifdef USE_MULTI_ENCRYPTION_WITH_SESSION_KEY
// 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.
RsNxsSessionKeyItem *esk = NULL;
for(std::list<RsNxsItem*>::const_iterator it(tr->mItems.begin());it!=tr->mItems.end();++it)
if(NULL != (esk = dynamic_cast<RsNxsSessionKeyItem*>(*it)))
break ;
if(esk == NULL)
{
#ifdef NXS_NET_DEBUG_7
GXSNETDEBUG_P_(peerId) << " (II) nothing to decrypt. No session key packet in this transaction. Transaction is not encrypted" << std::endl;
#endif
return true ;
}
// 2 - Try to decrypt the session key. If not, return false. That probably means
// we don't own that identity.
GxsSecurity::MultiEncryptionContext muctx ;
RsGxsId private_key_id ;
RsTlvBinaryData ek ;
RsTlvSecurityKey private_key;
bool found = false ;
for(std::map<RsGxsId,RsTlvBinaryData>::const_iterator it(esk->encrypted_session_keys.begin());it!=esk->encrypted_session_keys.end();++it)
if(mGixs->havePrivateKey(it->first))
{
found = true ;
private_key_id = it->first ;
ek = it->second ;
if(!mGixs->getPrivateKey(private_key_id,private_key))
{
std::cerr << " (EE) Cannot find private key to decrypt incoming transaction, for ID " << it->first << ". This is a bug since the key is supposed ot be here." << std::endl;
return false;
}
#ifdef NXS_NET_DEBUG_7
GXSNETDEBUG_P_(peerId) << " found appropriate private key to decrypt session key: " << it->first << std::endl;
#endif
break ;
}
if(!found)
{
std::cerr << " (EE) no private key for this encrypted transaction. Cannot decrypt!" << std::endl;
return false ;
}
if(!GxsSecurity::initDecryption(muctx,private_key,esk->iv,EVP_MAX_IV_LENGTH,(unsigned char*)ek.bin_data,ek.bin_len))
{
std::cerr << " (EE) cannot decrypt transaction. initDecryption() failed." << std::endl;
return false ;
}
#ifdef NXS_NET_DEBUG_7
GXSNETDEBUG_P_(peerId) << " Session key successfully decrypted, with length " << ek.bin_len << std::endl;
GXSNETDEBUG_P_(peerId) << " Now, decrypting transaction items..." << std::endl;
#endif
// 3 - Using session key, decrypt all packets, by calling GXSSecurity.
std::list<RsNxsItem*> decrypted_items ;
RsNxsEncryptedDataItem *encrypted_item ;
RsNxsSerialiser serial(mServType) ;
for(std::list<RsNxsItem*>::const_iterator it(tr->mItems.begin());it!=tr->mItems.end();++it)
if(NULL != (encrypted_item = dynamic_cast<RsNxsEncryptedDataItem*>(*it)))
{
unsigned char *tempmem;
uint32_t tempmemsize ;
if(!GxsSecurity::decrypt(tempmem,tempmemsize,(uint8_t*)encrypted_item->aes_encrypted_data.bin_data, encrypted_item->aes_encrypted_data.bin_len,muctx))
{
std::cerr << " (EE) Cannot decrypt item. Something went wrong. Skipping this item." << std::endl;
continue ;
}
RsItem *ditem = serial.deserialise(tempmem,&tempmemsize) ;
#ifdef NXS_NET_DEBUG_7
GXSNETDEBUG_P_(peerId) << " Decrypted an item of type " << std::hex << ditem->PacketId() << std::dec << std::endl;
#endif
RsNxsItem *nxsi = dynamic_cast<RsNxsItem*>(ditem) ;
if(nxsi != NULL)
decrypted_items.push_back(nxsi) ;
else
{
std::cerr << " (EE) decrypted an item of unknown type!" << std::endl;
}
free(tempmem) ;
}
#else
std::list<RsNxsItem*> decrypted_items ; std::list<RsNxsItem*> decrypted_items ;
std::vector<RsTlvSecurityKey> private_keys ; std::vector<RsTlvSecurityKey> private_keys ;
@ -3770,7 +3842,7 @@ bool RsGxsNetService::decryptTransaction(NxsTransaction *tr)
std::cerr << " Trying to decrypt item..." ; std::cerr << " Trying to decrypt item..." ;
if(!GxsSecurity::decrypt(decrypted_mem,decrypted_len, (uint8_t*)encrypted_item->aes_encrypted_data.bin_data,encrypted_item->aes_encrypted_data.bin_len,private_keys)) if(!GxsSecurity::decrypt(decrypted_mem,decrypted_len, (uint8_t*)encrypted_item->encrypted_data.bin_data,encrypted_item->encrypted_data.bin_len,private_keys))
{ {
std::cerr << "Failed! Cannot decrypt this item." << std::endl; std::cerr << "Failed! Cannot decrypt this item." << std::endl;
decrypted_mem = NULL ; // for safety decrypted_mem = NULL ; // for safety
@ -3807,7 +3879,6 @@ bool RsGxsNetService::decryptTransaction(NxsTransaction *tr)
delete encrypted_item ; delete encrypted_item ;
} }
#endif
#ifdef NXS_NET_DEBUG_7 #ifdef NXS_NET_DEBUG_7
GXSNETDEBUG_P_(peerId) << " Decryption successful: replacing items with clear items" << std::endl; GXSNETDEBUG_P_(peerId) << " Decryption successful: replacing items with clear items" << std::endl;
@ -3947,7 +4018,9 @@ void RsGxsNetService::handleRecvSyncGroup(RsNxsSyncGrpReqItem *item)
// or if you need to add to the holding // or if you need to add to the holding
// pen for peer to be vetted // pen for peer to be vetted
if(canSendGrpId(peer, *grpMeta, toVet)) bool should_encrypt = false ;
if(canSendGrpId(peer, *grpMeta, toVet,should_encrypt))
{ {
RsNxsSyncGrpItem* gItem = new RsNxsSyncGrpItem(mServType); RsNxsSyncGrpItem* gItem = new RsNxsSyncGrpItem(mServType);
gItem->flag = RsNxsSyncGrpItem::FLAG_RESPONSE; gItem->flag = RsNxsSyncGrpItem::FLAG_RESPONSE;
@ -3956,7 +4029,38 @@ void RsGxsNetService::handleRecvSyncGroup(RsNxsSyncGrpReqItem *item)
gItem->authorId = grpMeta->mAuthorId; gItem->authorId = grpMeta->mAuthorId;
gItem->PeerId(peer); gItem->PeerId(peer);
gItem->transactionNumber = transN; gItem->transactionNumber = transN;
if(should_encrypt)
{
#ifdef NXS_NET_DEBUG_7
GXSNETDEBUG_PG(peer,mit->first) << " item for this grpId should be encrypted." << std::endl;
#endif
RsNxsItem *encrypted_item = NULL ;
uint32_t status = RS_NXS_ITEM_ENCRYPTION_STATUS_UNKNOWN ;
if(encryptSingleNxsItem(gItem, grpMeta->mCircleId, encrypted_item,status))
{
itemL.push_back(encrypted_item) ;
delete gItem ;
}
else
{
switch(status)
{
case RS_NXS_ITEM_ENCRYPTION_STATUS_CIRCLE_ERROR:
case RS_NXS_ITEM_ENCRYPTION_STATUS_GXS_KEY_MISSING: toVet.push_back(GrpIdCircleVet(grpMeta->mGroupId, grpMeta->mCircleId, grpMeta->mAuthorId));
#ifdef NXS_NET_DEBUG_7
GXSNETDEBUG_PG(peer,mit->first) << " Could not encrypt item for grpId " << grpMeta->mGroupId << " for circle " << grpMeta->mCircleId << ". Will try later. Adding to vetting list." << std::endl;
#endif
break ;
default:
std::cerr << " Could not encrypt item for grpId " << grpMeta->mGroupId << " for circle " << grpMeta->mCircleId << ". Not sending it." << std::endl;
}
}
}
else
itemL.push_back(gItem); itemL.push_back(gItem);
#ifdef NXS_NET_DEBUG_0 #ifdef NXS_NET_DEBUG_0
GXSNETDEBUG_PG(peer,mit->first) << " sending item for Grp " << mit->first << " name=" << grpMeta->mGroupName << ", publishTS=" << std::dec<< time(NULL) - mit->second->mPublishTs << " secs ago to peer ID " << peer << std::endl; GXSNETDEBUG_PG(peer,mit->first) << " sending item for Grp " << mit->first << " name=" << grpMeta->mGroupName << ", publishTS=" << std::dec<< time(NULL) - mit->second->mPublishTs << " secs ago to peer ID " << peer << std::endl;
#endif #endif
@ -3965,9 +4069,7 @@ void RsGxsNetService::handleRecvSyncGroup(RsNxsSyncGrpReqItem *item)
} }
if(!toVet.empty()) if(!toVet.empty())
{
mPendingCircleVets.push_back(new GrpCircleIdRequestVetting(mCircles, mPgpUtils, toVet, peer)); mPendingCircleVets.push_back(new GrpCircleIdRequestVetting(mCircles, mPgpUtils, toVet, peer));
}
#ifdef NXS_NET_DEBUG_0 #ifdef NXS_NET_DEBUG_0
GXSNETDEBUG_P_(peer) << " final list sent (after vetting): " << itemL.size() << " elements." << std::endl; GXSNETDEBUG_P_(peer) << " final list sent (after vetting): " << itemL.size() << " elements." << std::endl;
@ -3979,7 +4081,7 @@ void RsGxsNetService::handleRecvSyncGroup(RsNxsSyncGrpReqItem *item)
bool RsGxsNetService::canSendGrpId(const RsPeerId& sslId, RsGxsGrpMetaData& grpMeta, std::vector<GrpIdCircleVet>& toVet) bool RsGxsNetService::canSendGrpId(const RsPeerId& sslId, RsGxsGrpMetaData& grpMeta, std::vector<GrpIdCircleVet>& toVet, bool& should_encrypt)
{ {
#ifdef NXS_NET_DEBUG_4 #ifdef NXS_NET_DEBUG_4
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << "RsGxsNetService::canSendGrpId()"<< std::endl; GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << "RsGxsNetService::canSendGrpId()"<< std::endl;
@ -4008,6 +4110,7 @@ bool RsGxsNetService::canSendGrpId(const RsPeerId& sslId, RsGxsGrpMetaData& grpM
#ifdef NXS_NET_DEBUG_4 #ifdef NXS_NET_DEBUG_4
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId)<< " EXTERNAL_CIRCLE, will be sent encrypted."<< std::endl; GXSNETDEBUG_PG(sslId,grpMeta.mGroupId)<< " EXTERNAL_CIRCLE, will be sent encrypted."<< std::endl;
#endif #endif
should_encrypt = true ;
return true ; return true ;
#ifdef TO_BE_REMOVED_OLD_VETTING_FOR_EXTERNAL_CIRCLES #ifdef TO_BE_REMOVED_OLD_VETTING_FOR_EXTERNAL_CIRCLES
@ -4067,7 +4170,9 @@ bool RsGxsNetService::canSendGrpId(const RsPeerId& sslId, RsGxsGrpMetaData& grpM
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " circle Loaded - checking mCircles->canSend" << std::endl; GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " circle Loaded - checking mCircles->canSend" << std::endl;
#endif #endif
const RsPgpId& pgpId = mPgpUtils->getPGPId(sslId); const RsPgpId& pgpId = mPgpUtils->getPGPId(sslId);
bool res = mCircles->canSend(internalCircleId, pgpId); bool should_encrypt = false ;
bool res = mCircles->canSend(internalCircleId, pgpId,should_encrypt);
#ifdef NXS_NET_DEBUG_4 #ifdef NXS_NET_DEBUG_4
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " answer is: " << res << std::endl; GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " answer is: " << res << std::endl;
#endif #endif
@ -4135,7 +4240,6 @@ bool RsGxsNetService::checkCanRecvMsgFromPeer(const RsPeerId& sslId, const RsGxs
if(circleType == GXS_CIRCLE_TYPE_EXTERNAL) if(circleType == GXS_CIRCLE_TYPE_EXTERNAL)
{ {
#warning Here we can keep a test based on whether we are in the circle or not. Returning true also works but the transaction might turn out to be useless
#ifdef NXS_NET_DEBUG_4 #ifdef NXS_NET_DEBUG_4
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Circle type: EXTERNAL => returning true. Msgs will be encrypted." << std::endl; GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Circle type: EXTERNAL => returning true. Msgs will be encrypted." << std::endl;
#endif #endif
@ -4192,7 +4296,8 @@ bool RsGxsNetService::checkCanRecvMsgFromPeer(const RsPeerId& sslId, const RsGxs
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " circle Loaded - checking mCircles->canSend" << std::endl; GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " circle Loaded - checking mCircles->canSend" << std::endl;
#endif #endif
const RsPgpId& pgpId = mPgpUtils->getPGPId(sslId); const RsPgpId& pgpId = mPgpUtils->getPGPId(sslId);
return mCircles->canSend(internalCircleId, pgpId); bool should_encrypt ;
return mCircles->canSend(internalCircleId, pgpId,should_encrypt);
} }
else else
mCircles->loadCircle(internalCircleId); // request for next pass mCircles->loadCircle(internalCircleId); // request for next pass
@ -4337,13 +4442,30 @@ void RsGxsNetService::handleRecvSyncMessage(RsNxsSyncMsgReqItem *item)
mItem->authorId = m->mAuthorId; mItem->authorId = m->mAuthorId;
mItem->PeerId(peer); mItem->PeerId(peer);
mItem->transactionNumber = transN; mItem->transactionNumber = transN;
itemL.push_back(mItem);
#ifdef NXS_NET_DEBUG_0
if(!should_encrypt_to_this_circle_id.isNull()) if(!should_encrypt_to_this_circle_id.isNull())
{
#ifdef NXS_NET_DEBUG_7
GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " sending info item for msg id " << mItem->msgId << ". Transaction will be encrypted for group " << should_encrypt_to_this_circle_id << std::endl; GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " sending info item for msg id " << mItem->msgId << ". Transaction will be encrypted for group " << should_encrypt_to_this_circle_id << std::endl;
else
GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " sending info item for msg id " << mItem->msgId ;
#endif #endif
RsNxsItem *encrypted_item = NULL ;
uint32_t status = RS_NXS_ITEM_ENCRYPTION_STATUS_UNKNOWN ;
if(encryptSingleNxsItem(mItem, grpMeta->mCircleId, encrypted_item,status))
{
itemL.push_back(encrypted_item) ;
delete mItem ;
}
else
std::cerr << " (EE) Cannot encrypt msg meta data. MsgId=" << mItem->msgId << ", grpId=" << mItem->grpId << ", circleId=" << should_encrypt_to_this_circle_id << std::endl;
}
else
{
#ifdef NXS_NET_DEBUG_7
GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " sending info item for msg id " << mItem->msgId << " in clear." << std::endl;
#endif
itemL.push_back(mItem);
}
} }
if(!itemL.empty()) if(!itemL.empty())
@ -4351,7 +4473,7 @@ void RsGxsNetService::handleRecvSyncMessage(RsNxsSyncMsgReqItem *item)
#ifdef NXS_NET_DEBUG_0 #ifdef NXS_NET_DEBUG_0
GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " sending final msg info list of " << itemL.size() << " items." << std::endl; GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " sending final msg info list of " << itemL.size() << " items." << std::endl;
#endif #endif
locked_pushMsgRespFromList(itemL, peer, item->grpId,transN,should_encrypt_to_this_circle_id); locked_pushMsgRespFromList(itemL, peer, item->grpId,transN);
} }
#ifdef NXS_NET_DEBUG_0 #ifdef NXS_NET_DEBUG_0
else else
@ -4369,7 +4491,7 @@ void RsGxsNetService::handleRecvSyncMessage(RsNxsSyncMsgReqItem *item)
delete *vit; delete *vit;
} }
void RsGxsNetService::locked_pushMsgRespFromList(std::list<RsNxsItem*>& itemL, const RsPeerId& sslId, const RsGxsGroupId& grp_id,const uint32_t& transN,const RsGxsCircleId& destination_circle) void RsGxsNetService::locked_pushMsgRespFromList(std::list<RsNxsItem*>& itemL, const RsPeerId& sslId, const RsGxsGroupId& grp_id,const uint32_t& transN)
{ {
#ifdef NXS_NET_DEBUG_1 #ifdef NXS_NET_DEBUG_1
GXSNETDEBUG_PG(sslId,grp_id) << "locked_pushMsgResponseFromList()" << std::endl; GXSNETDEBUG_PG(sslId,grp_id) << "locked_pushMsgResponseFromList()" << std::endl;
@ -4392,7 +4514,6 @@ void RsGxsNetService::locked_pushMsgRespFromList(std::list<RsNxsItem*>& itemL, c
tr->mTransaction = new RsNxsTransacItem(*trItem); tr->mTransaction = new RsNxsTransacItem(*trItem);
tr->mTransaction->PeerId(mOwnId); tr->mTransaction->PeerId(mOwnId);
tr->mTimeOut = time(NULL) + mTransactionTimeOut; tr->mTimeOut = time(NULL) + mTransactionTimeOut;
tr->destination_circle = destination_circle;
ServerMsgMap::const_iterator cit = mServerMsgUpdateMap.find(grp_id); ServerMsgMap::const_iterator cit = mServerMsgUpdateMap.find(grp_id);
@ -4508,7 +4629,12 @@ bool RsGxsNetService::canSendMsgIds(const std::vector<RsGxsMsgMetaData*>& msgMet
if(mCircles->isLoaded(internalCircleId)) if(mCircles->isLoaded(internalCircleId))
{ {
const RsPgpId& pgpId = mPgpUtils->getPGPId(sslId); const RsPgpId& pgpId = mPgpUtils->getPGPId(sslId);
bool res= mCircles->canSend(internalCircleId, pgpId); bool should_encrypt = false ;
bool res= mCircles->canSend(internalCircleId, pgpId,should_encrypt);
if(should_encrypt)
std::cerr << "(EE) inconsistent response: vetting requests to encrypt circle of type YOUR_EYES_ONLY" << std::endl;
#ifdef NXS_NET_DEBUG_4 #ifdef NXS_NET_DEBUG_4
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Answer from circle::canSend(): " << res << std::endl; GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Answer from circle::canSend(): " << res << std::endl;
#endif #endif

View file

@ -349,22 +349,20 @@ private:
* @param toVet groupid/peer to vet are stored here if their circle id is not cached * @param toVet groupid/peer to vet are stored here if their circle id is not cached
* @return false, if you cannot send to this peer, true otherwise * @return false, if you cannot send to this peer, true otherwise
*/ */
bool canSendGrpId(const RsPeerId& sslId, RsGxsGrpMetaData& grpMeta, std::vector<GrpIdCircleVet>& toVet); bool canSendGrpId(const RsPeerId& sslId, RsGxsGrpMetaData& grpMeta, std::vector<GrpIdCircleVet>& toVet, bool &should_encrypt);
bool canSendMsgIds(const std::vector<RsGxsMsgMetaData*>& msgMetas, const RsGxsGrpMetaData&, const RsPeerId& sslId, RsGxsCircleId &should_encrypt_id); bool canSendMsgIds(const std::vector<RsGxsMsgMetaData*>& msgMetas, const RsGxsGrpMetaData&, const RsPeerId& sslId, RsGxsCircleId &should_encrypt_id);
bool checkCanRecvMsgFromPeer(const RsPeerId& sslId, const RsGxsGrpMetaData& meta); bool checkCanRecvMsgFromPeer(const RsPeerId& sslId, const RsGxsGrpMetaData& meta);
void locked_createTransactionFromPending(MsgRespPending* grpPend); void locked_createTransactionFromPending(MsgRespPending* grpPend);
void locked_createTransactionFromPending(GrpRespPending* msgPend); void locked_createTransactionFromPending(GrpRespPending* msgPend);
void locked_createTransactionFromPending(GrpCircleIdRequestVetting* grpPend); bool locked_createTransactionFromPending(GrpCircleIdRequestVetting* grpPend) ;
void locked_createTransactionFromPending(MsgCircleIdsRequestVetting* grpPend); bool locked_createTransactionFromPending(MsgCircleIdsRequestVetting* grpPend) ;
void locked_pushGrpTransactionFromList(std::list<RsNxsItem*>& reqList, const RsPeerId& peerId, const uint32_t& transN); // forms a grp list request void locked_pushGrpTransactionFromList(std::list<RsNxsItem*>& reqList, const RsPeerId& peerId, const uint32_t& transN); // forms a grp list request
void locked_pushMsgTransactionFromList(std::list<RsNxsItem*>& reqList, const RsPeerId& peerId, const uint32_t& transN); // forms a msg list request void locked_pushMsgTransactionFromList(std::list<RsNxsItem*>& reqList, const RsPeerId& peerId, const uint32_t& transN); // forms a msg list request
void locked_pushGrpRespFromList(std::list<RsNxsItem*>& respList, const RsPeerId& peer, const uint32_t& transN); void locked_pushGrpRespFromList(std::list<RsNxsItem*>& respList, const RsPeerId& peer, const uint32_t& transN);
void locked_pushMsgRespFromList(std::list<RsNxsItem*>& itemL, const RsPeerId& sslId, const RsGxsGroupId &grp_id, const uint32_t& transN,const RsGxsCircleId& destination_circle); void locked_pushMsgRespFromList(std::list<RsNxsItem*>& itemL, const RsPeerId& sslId, const RsGxsGroupId &grp_id, const uint32_t& transN);
void syncWithPeers(); void syncWithPeers();
void syncGrpStatistics(); void syncGrpStatistics();
@ -454,8 +452,11 @@ private:
/*! /*!
* encrypts/decrypts the transaction for the destination circle id. * encrypts/decrypts the transaction for the destination circle id.
*/ */
#ifdef TO_REMOVE
bool encryptTransaction(NxsTransaction *tr); bool encryptTransaction(NxsTransaction *tr);
bool decryptTransaction(NxsTransaction *tr); // return false when the keys are not loaded => need retry later #endif
bool encryptSingleNxsItem(RsNxsItem *item, const RsGxsCircleId& destination_circle, RsNxsItem *& encrypted_item, uint32_t &status) ;
bool processTransactionForDecryption(NxsTransaction *tr); // return false when the keys are not loaded => need retry later
void cleanRejectedMessages(); void cleanRejectedMessages();
void processObserverNotifications(); void processObserverNotifications();

View file

@ -222,12 +222,12 @@ bool GrpCircleVetting::expired()
{ {
return time(NULL) > (mTimeStamp + EXPIRY_PERIOD_OFFSET); return time(NULL) > (mTimeStamp + EXPIRY_PERIOD_OFFSET);
} }
bool GrpCircleVetting::canSend(const SSLIdType& peerId, const RsGxsCircleId& circleId) bool GrpCircleVetting::canSend(const SSLIdType& peerId, const RsGxsCircleId& circleId,bool& should_encrypt)
{ {
if(mCircles->isLoaded(circleId)) if(mCircles->isLoaded(circleId))
{ {
const RsPgpId& pgpId = mPgpUtils->getPGPId(peerId); const RsPgpId& pgpId = mPgpUtils->getPGPId(peerId);
return mCircles->canSend(circleId, pgpId); return mCircles->canSend(circleId, pgpId,should_encrypt);
} }
mCircles->loadCircle(circleId); mCircles->loadCircle(circleId);
@ -250,7 +250,7 @@ bool GrpCircleIdRequestVetting::cleared()
if(!gic.mCleared) if(!gic.mCleared)
{ {
if(canSend(mPeerId, gic.mCircleId)) if(canSend(mPeerId, gic.mCircleId,gic.mShouldEncrypt))
{ {
gic.mCleared = true; gic.mCleared = true;
count++; count++;
@ -285,7 +285,7 @@ MsgCircleIdsRequestVetting::MsgCircleIdsRequestVetting(RsGcxs* const circles,
bool MsgCircleIdsRequestVetting::cleared() bool MsgCircleIdsRequestVetting::cleared()
{ {
return canSend(mPeerId, mCircleId); return canSend(mPeerId, mCircleId, mShouldEncrypt);
} }

View file

@ -68,8 +68,6 @@ public:
*/ */
RsNxsTransacItem* mTransaction; RsNxsTransacItem* mTransaction;
std::list<RsNxsItem*> mItems; // items received or sent std::list<RsNxsItem*> mItems; // items received or sent
RsGxsCircleId destination_circle;
}; };
/*! /*!
@ -216,7 +214,9 @@ public:
RsGxsGroupId mGroupId; RsGxsGroupId mGroupId;
RsGxsCircleId mCircleId; RsGxsCircleId mCircleId;
RsGxsId mAuthorId; RsGxsId mAuthorId;
bool mCleared; bool mCleared;
bool mShouldEncrypt;
}; };
class MsgIdCircleVet class MsgIdCircleVet
@ -254,7 +254,7 @@ public:
virtual bool cleared() = 0; virtual bool cleared() = 0;
protected: protected:
bool canSend(const RsPeerId& peerId, const RsGxsCircleId& circleId); bool canSend(const RsPeerId& peerId, const RsGxsCircleId& circleId, bool& should_encrypt);
private: private:
@ -288,6 +288,7 @@ public:
RsGxsGroupId mGrpId; RsGxsGroupId mGrpId;
RsPeerId mPeerId; RsPeerId mPeerId;
RsGxsCircleId mCircleId; RsGxsCircleId mCircleId;
bool mShouldEncrypt;
}; };

View file

@ -463,7 +463,7 @@ bool RsNxsEncryptedDataItem::serialise(void *data, uint32_t& size) const
return false ; return false ;
ok &= setRawUInt32(data, size, &offset, transactionNumber); ok &= setRawUInt32(data, size, &offset, transactionNumber);
ok &= aes_encrypted_data.SetTlv(data, size, &offset) ; ok &= encrypted_data.SetTlv(data, size, &offset) ;
if(offset != tlvsize) if(offset != tlvsize)
{ {
@ -897,9 +897,9 @@ RsNxsEncryptedDataItem *RsNxsSerialiser::deserialNxsEncryptedDataItem(void* da
RsNxsEncryptedDataItem* item = new RsNxsEncryptedDataItem(SERVICE_TYPE); RsNxsEncryptedDataItem* item = new RsNxsEncryptedDataItem(SERVICE_TYPE);
ok &= getRawUInt32(data, *size, &offset, &(item->transactionNumber)); ok &= getRawUInt32(data, *size, &offset, &(item->transactionNumber));
item->aes_encrypted_data.tlvtype = TLV_TYPE_BIN_ENCRYPTED ; item->encrypted_data.tlvtype = TLV_TYPE_BIN_ENCRYPTED ;
ok &= item->aes_encrypted_data.GetTlv(data,*size,&offset) ; ok &= item->encrypted_data.GetTlv(data,*size,&offset) ;
if (offset != *size) if (offset != *size)
{ {
@ -1046,7 +1046,7 @@ uint32_t RsNxsEncryptedDataItem::serial_size() const
uint32_t s = 8; // header size uint32_t s = 8; // header size
s += 4; // transaction number s += 4; // transaction number
s += aes_encrypted_data.TlvSize() ; s += encrypted_data.TlvSize() ;
return s; return s;
} }
@ -1127,7 +1127,7 @@ void RsNxsTransacItem::clear(){
transactionNumber = 0; transactionNumber = 0;
} }
void RsNxsEncryptedDataItem::clear(){ void RsNxsEncryptedDataItem::clear(){
aes_encrypted_data.TlvClear() ; encrypted_data.TlvClear() ;
} }
void RsNxsSessionKeyItem::clear() void RsNxsSessionKeyItem::clear()
{ {
@ -1337,9 +1337,9 @@ std::ostream& RsNxsEncryptedDataItem::print(std::ostream &out, uint16_t indent)
{ {
printRsItemBase(out, "RsNxsEncryptedDataItem", indent); printRsItemBase(out, "RsNxsEncryptedDataItem", indent);
out << " encrypted data: " << RsUtil::BinToHex((char*)aes_encrypted_data.bin_data,std::min(50u,aes_encrypted_data.bin_len)) ; out << " encrypted data: " << RsUtil::BinToHex((char*)encrypted_data.bin_data,std::min(50u,encrypted_data.bin_len)) ;
if(aes_encrypted_data.bin_len > 50u) if(encrypted_data.bin_len > 50u)
out << "..." ; out << "..." ;
out << std::endl; out << std::endl;

View file

@ -277,9 +277,9 @@ class RsNxsEncryptedDataItem : public RsNxsItem
public: public:
RsNxsEncryptedDataItem(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_ENCRYPTED_DATA_ITEM),aes_encrypted_data(servtype) RsNxsEncryptedDataItem(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_ENCRYPTED_DATA_ITEM),encrypted_data(servtype)
{ {
aes_encrypted_data.tlvtype = TLV_TYPE_BIN_ENCRYPTED ; encrypted_data.tlvtype = TLV_TYPE_BIN_ENCRYPTED ;
clear(); clear();
} }
virtual ~RsNxsEncryptedDataItem() {} virtual ~RsNxsEncryptedDataItem() {}
@ -292,7 +292,7 @@ public:
/// grpId of grp held by sending peer /// grpId of grp held by sending peer
/// ///
RsTlvBinaryData aes_encrypted_data ; RsTlvBinaryData encrypted_data ;
}; };

View file

@ -341,16 +341,17 @@ bool p3GxsCircles::loadCircle(const RsGxsCircleId &circleId)
return cache_request_load(circleId); return cache_request_load(circleId);
} }
int p3GxsCircles::canSend(const RsGxsCircleId &circleId, const RsPgpId &id) int p3GxsCircles::canSend(const RsGxsCircleId &circleId, const RsPgpId &id, bool& should_encrypt)
{ {
RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/ RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/
if (mCircleCache.is_cached(circleId)) if (mCircleCache.is_cached(circleId))
{ {
RsGxsCircleCache &data = mCircleCache.ref(circleId); RsGxsCircleCache &data = mCircleCache.ref(circleId);
should_encrypt = (data.mCircleType == GXS_CIRCLE_TYPE_EXTERNAL);
if (data.isAllowedPeer(id)) if (data.isAllowedPeer(id))
{
return 1; return 1;
}
return 0; return 0;
} }
return -1; return -1;

View file

@ -175,7 +175,7 @@ virtual RsServiceInfo getServiceInfo();
virtual bool isLoaded(const RsGxsCircleId &circleId); virtual bool isLoaded(const RsGxsCircleId &circleId);
virtual bool loadCircle(const RsGxsCircleId &circleId); virtual bool loadCircle(const RsGxsCircleId &circleId);
virtual int canSend(const RsGxsCircleId &circleId, const RsPgpId &id); virtual int canSend(const RsGxsCircleId &circleId, const RsPgpId &id, bool &should_encrypt);
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 recipients(const RsGxsCircleId &circleId, std::list<RsGxsId> &gxs_ids);