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;

File diff suppressed because it is too large Load diff

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);