merging distrib split into trunk

suppressed p3distrib in services 


git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@4600 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
chrisparker126 2011-09-10 15:20:15 +00:00
parent dc0f4ef68a
commit 7e8d8aea9c
10 changed files with 867 additions and 1780 deletions

View File

@ -1,9 +1,9 @@
/*
* libretroshare/src/services: p3distrib.h
* libretroshare/src/distrib: p3distrib.h
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2008 by Robert Fernie.
* Copyright 2004-2011 by Robert Fernie.
* 2010-2011 Christopher Evi-Parker
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@ -56,42 +56,6 @@
const uint32_t GROUP_MAX_FWD_OFFSET = (60 * 60 * 24 * 2); /* 2 Days */
/************* The Messages that are serialised ****************/
#if 0
class RsConfigDistrib: public RsSerialType
{
public:
RsConfigDistrib();
};
class RsSerialDistrib: public RsSerialType
{
public:
RsSerialDistrib();
};
#endif
/************* The Messages that are serialised ****************/
#if 0
const uint32_t GROUP_KEY_TYPE_MASK = 0x000f;
const uint32_t GROUP_KEY_DISTRIB_MASK = 0x00f0;
const uint32_t GROUP_KEY_TYPE_PUBLIC_ONLY = 0x0001;
const uint32_t GROUP_KEY_TYPE_FULL = 0x0002;
const uint32_t GROUP_KEY_DISTRIB_PUBLIC = 0x0010;
const uint32_t GROUP_KEY_DISTRIB_PRIVATE = 0x0020;
const uint32_t GROUP_KEY_DISTRIB_ADMIN = 0x0040;
#endif
/*
* A data structure to store dummy (missing) msgs.
@ -243,26 +207,9 @@ const uint32_t GRP_SUBSCRIBED = 0x0005;
const uint32_t GRP_UNSUBSCRIBED = 0x0006;
typedef std::map<std::string, std::list<CacheData> > CacheOptData;
typedef std::pair<std::string, pugi::xml_node > grpNodePair; // (is loaded, iterator pointing to node)
// these make up a cache list
typedef std::pair<std::string, uint16_t> pCacheId; //(pid, subid)
typedef std::pair<std::string, pCacheId> grpCachePair; // (grpid, cid)
/*!
* grp node content for faster access
*/
struct nodeCache
{
bool cached;
pugi::xml_node_iterator it;
pCacheId cid;
std::set<pCacheId> cIdSet;
pugi::xml_node node;
};
//! Cache based service to implement group messaging
/*!
*
@ -338,87 +285,6 @@ class p3GroupDistrib: public CacheSource, public CacheStore, public p3Config, pu
void HistoricalCachesDone(); // called when Stored Caches have been added to Pending List.
private:
/*!
* called when all historical caches have been loaded
*/
void HistoricalCachesLoaded();
/*!
* This updates the cache document with pending msg and grp cache data
*/
void updateCacheDocument();
/*!
* @param grpIter this is a list of iterators point to newly added grp nodes
*/
void locked_updateCacheTableGrp(const std::vector<grpNodePair>& grpNodes, bool historical);
/*!
* @param msgCacheMap each entry a set of cache ids that are to be loaded if grpId(entry) is requested to be cached
*/
void locked_updateCacheTableMsg(const std::map<std::string, std::set<pCacheId> >& msgCacheMap);
/*!
* @param grpId indicates which grp entry to update
* @param cached pass as true to update entry as true and vice versa
*/
void locked_updateCacheTableEntry(const std::string& grpId, bool cached);
/*!
* TODO: will be used to unpack cache doc from config load
* @param cacheBinDoc contains cache document as binary
*/
bool loadCacheDoc(RsDistribConfigData& cacheBinDoc);
/*!
* to find if grps messages have been loaded (assumes grps have been loaded first)
* @param cached true if grp has been loaded, false if not
* @return true is grp entry does not exist in table, false if not
*/
bool locked_historyCached(const std::string& grpId, bool& cached);
/*!
* @param cache cache data id
* @return false if cache entry does not exist in table
*/
bool locked_historyCached(const pCacheId& cId);
/*!
* builds cache table from loaded cached document
* @return false if cache document is empty
*/
bool locked_buildCacheTable(void);
/*!
* if grp's message is not loaded, load it, and update cache table
* @param grpId group whose messages to load if not cached
*/
void locked_processHistoryCached(const std::string& grpId);
/*!
* loads cache data which contains location of cache files belonging
* to group
* @param grpId grp for which to get list of cache data
* @param cDataSet cache data belonging to grp is loaded into this list
*/
void locked_getHistoryCacheData(const std::string& grpId, std::list<CacheData>& cDataSet);
/*!
* encrypts and saves cache file
*/
bool locked_saveHistoryCacheFile();
/*!
* decrypte and save cache file
*/
bool locked_loadHistoryCacheFile();
private:
/* these lists are filled by the overloaded fns... then cleared by the thread */
@ -429,9 +295,8 @@ class p3GroupDistrib: public CacheSource, public CacheStore, public p3Config, pu
int loadAnyCache(const CacheData &data, bool local, bool historical);
/* load cache files */
void loadFileGroups(const std::string &filename, const std::string &src, bool local, bool historical, const pCacheId& cid);
void loadFileMsgs(const std::string &filename, uint16_t cacheSubId, const std::string &src, uint32_t ts, bool local, bool historical);
void locked_loadFileMsgs(const std::string &filename, uint16_t cacheSubId, const std::string &src, uint32_t ts, bool local, bool historical);
void loadFileGroups(const std::string &filename, const std::string &src, bool local, bool historical);
void loadFileMsgs(const std::string &filename, const CacheData& , bool local, bool historical);
bool backUpKeys(const std::list<RsDistribGrpKey* > &keysToBackUp, std::string grpId);
void locked_sharePubKey();
@ -439,12 +304,28 @@ class p3GroupDistrib: public CacheSource, public CacheStore, public p3Config, pu
* Attempt to load public key from recvd list if it exists for grpId
* @param grpId the id for the group for which private publish key is wanted
*/
bool attemptPublishKeysRecvd();
bool attemptPublishKeysRecvd();
/*!
* Simply load cache opt messages
* @param data
*/
void loadCacheOptMsgs(const CacheData& data, const std::string& grpId);
protected:
/* load cache msgs */
/*!
* processes cache opt request by loading data for group
* @param grpId the group to process request for
* @return false if group does not exist
*/
bool processCacheOptReq(std::string grpId);
/*!
* msg is loaded to its group and republished,
* msg decrypted if grp is private
@ -688,26 +569,6 @@ class p3GroupDistrib: public CacheSource, public CacheStore, public p3Config, pu
*/
virtual bool locked_editGroup(std::string grpId, GroupInfo& gi);
/*!
* Encrypts data using envelope encryption (taken from open ssl's evp_sealinit )
* only full publish key holders can encrypt data for given group
*@param out
*@param outlen
*@param in
*@param inlen
*/
virtual bool encrypt(void *&out, int &outlen, const void *in, int inlen, std::string grpId);
/**
* Decrypts data using evelope decryption (taken from open ssl's evp_sealinit )
* only full publish key holders can decrypt data for a group
*@param out where decrypted data is written to
*@param outlen
*@param in
*@param inlen
*/
virtual bool decrypt(void *&out, int &outlen, const void *in, int inlen, std::string grpId);
/***************************************************************************************/
/***************************************************************************************/
@ -730,12 +591,6 @@ class p3GroupDistrib: public CacheSource, public CacheStore, public p3Config, pu
*/
virtual pqistore *createStore(BinInterface *bio, const std::string &src, uint32_t bioflags);
/*!
* checks to see if admin signature is valid
* @param newGrp grp to validate
* @return true if group's signature is valid
*/
virtual bool validateDistribGrp(RsDistribGrp *newGrp);
virtual bool locked_checkGroupInfo(GroupInfo &info, RsDistribGrp *newGrp);
virtual bool locked_updateGroupInfo(GroupInfo &info, RsDistribGrp *newGrp);
virtual bool locked_checkGroupKeys(GroupInfo &info);
@ -755,15 +610,6 @@ class p3GroupDistrib: public CacheSource, public CacheStore, public p3Config, pu
*/
virtual bool locked_updateGroupPublishKey(GroupInfo &info, RsDistribGrpKey *newKey);
/*!
* uses groupinfo public key to verify signature of signed message
* @param info groupinfo for which msg is meant for
* @param msg
* @return false if verfication of signature is not passed
*/
virtual bool locked_validateDistribSignedMsg(GroupInfo &info, RsDistribSignedMsg *msg);
/*!
* Use this to retrieve packed message from a signed message
* @param newMsg signed message
@ -871,28 +717,31 @@ RsDistribDummyMsg *locked_getGroupDummyMsg(const std::string& grpId, const std::
std::set<std::string> mPubKeyAvailableGrpId; // groups id for which public keys are available
time_t mLastKeyPublishTime, mLastRecvdKeyTime;
////////////// cache optimisation ////////////////
int mCount;
/// table containing new msg cache data to be added to xml doc ( grpid, (cid,pid) )
std::vector<grpCachePair> mGrpHistPending;
/// table containing new grp cache data to be added to xml doc (grpid, (cid,pid) )
std::vector<grpCachePair> mMsgHistPending;
/**** cache opt ****/
std::set<pCacheId> mCachePairsInTable, mCacheFailedTable;
/*
* 1. when rs starts it loads only subscribed groups
* 2. and for unsubscribed groups these are store with their grp to cache mappings
* 3. when user clicks on a group this activates process cache which loads cache for only that group
*
*/
std::list<CacheDataPending> mPendingHistCaches;
/// stores map of grp to cache mapping
CacheOptData mGrpCacheMap;
/// group subscribed to at start of rs
std::set<std::string> mSubscribedGrp;
/// unsubscribed groups that are already loaded
std::set<std::string> mCacheOptLoaded;
/// current exception group
std::string mCurrGrpException;
std::map<CacheId, CacheData> mLocalHistCachesAvail;
time_t mLastCacheDocUpdate;
bool mUpdateCacheDoc, mHistoricalCachesLoaded;
std::map<std::string, nodeCache> mCacheTable; // (cid, node)
/// contains information on cached data
pugi::xml_document mCacheDoc;
};

View File

@ -0,0 +1,483 @@
/*
* libretroshare/src/distrib: p3distribverify.cc
*
*
* Copyright 2008-2010 by Robert Fernie
* 2011 Christopher Evi-Parker
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#include "p3distribsecurity.h"
#include "pqi/authgpg.h"
#include "retroshare/rsdistrib.h"
#include "retroshare/rspeers.h"
p3DistribSecurity::p3DistribSecurity()
{
}
p3DistribSecurity::~p3DistribSecurity()
{
}
RSA *p3DistribSecurity::extractPublicKey(RsTlvSecurityKey& key)
{
const unsigned char *keyptr = (const unsigned char *) key.keyData.bin_data;
long keylen = key.keyData.bin_len;
/* extract admin key */
RSA *rsakey = d2i_RSAPublicKey(NULL, &(keyptr), keylen);
return rsakey;
}
bool p3DistribSecurity::validateDistribSignedMsg(GroupInfo & info, RsDistribSignedMsg *newMsg)
{
#ifdef DISTRIB_DEBUG
std::cerr << "p3GroupDistrib::locked_validateDistribSignedMsg()";
std::cerr << std::endl;
std::cerr << "GroupInfo -> distribGrp:";
std::cerr << std::endl;
info.distribGroup->print(std::cerr, 10);
std::cerr << std::endl;
std::cerr << "RsDistribSignedMsg: ";
std::cerr << std::endl;
newMsg->print(std::cerr, 10);
std::cerr << std::endl;
#endif
#ifdef DISTRIB_DEBUG
std::cerr << "p3GroupDistrib::locked_validateDistribSignedMsg() publish KeyId: " << newMsg->publishSignature.keyId << std::endl;
std::cerr << "p3GroupDistrib::locked_validateDistribSignedMsg() personal KeyId: " << newMsg->personalSignature.keyId << std::endl;
#endif
/********************* check signature *******************/
/* find the right key */
RsTlvSecurityKeySet &keyset = info.distribGroup->publishKeys;
std::map<std::string, RsTlvSecurityKey>::iterator kit;
kit = keyset.keys.find(newMsg->publishSignature.keyId);
if (kit == keyset.keys.end())
{
#ifdef DISTRIB_DEBUG
std::cerr << "p3GroupDistrib::locked_validateDistribSignedMsg() Missing Publish Key";
std::cerr << std::endl;
#endif
return false;
}
/* check signature timeperiod */
if ((newMsg->timestamp < kit->second.startTS) ||
(newMsg->timestamp > kit->second.endTS))
{
#ifdef DISTRIB_DEBUG
std::cerr << "p3GroupDistrib::locked_validateDistribSignedMsg() TS out of range";
std::cerr << std::endl;
#endif
return false;
}
/* decode key */
const unsigned char *keyptr = (const unsigned char *) kit->second.keyData.bin_data;
long keylen = kit->second.keyData.bin_len;
unsigned int siglen = newMsg->publishSignature.signData.bin_len;
unsigned char *sigbuf = (unsigned char *) newMsg->publishSignature.signData.bin_data;
#ifdef DISTRIB_DEBUG
std::cerr << "p3GroupDistrib::locked_validateDistribSignedMsg() Decode Key";
std::cerr << " keylen: " << keylen << " siglen: " << siglen;
std::cerr << std::endl;
#endif
/* extract admin key */
RSA *rsakey = d2i_RSAPublicKey(NULL, &(keyptr), keylen);
if (!rsakey)
{
#ifdef DISTRIB_DEBUG
std::cerr << "p3GroupDistrib::locked_validateDistribSignedMsg()";
std::cerr << " Invalid RSA Key";
std::cerr << std::endl;
unsigned long err = ERR_get_error();
std::cerr << "RSA Load Failed .... CODE(" << err << ")" << std::endl;
std::cerr << ERR_error_string(err, NULL) << std::endl;
kit->second.print(std::cerr, 10);
#endif
}
EVP_PKEY *signKey = EVP_PKEY_new();
EVP_PKEY_assign_RSA(signKey, rsakey);
/* calc and check signature */
EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
EVP_VerifyInit(mdctx, EVP_sha1());
EVP_VerifyUpdate(mdctx, newMsg->packet.bin_data, newMsg->packet.bin_len);
int signOk = EVP_VerifyFinal(mdctx, sigbuf, siglen, signKey);
/* clean up */
EVP_PKEY_free(signKey);
EVP_MD_CTX_destroy(mdctx);
/* now verify Personal signature */
if ((signOk == 1) && ((info.grpFlags & RS_DISTRIB_AUTHEN_MASK) & RS_DISTRIB_AUTHEN_REQ))
{
unsigned int personalsiglen =
newMsg->personalSignature.signData.bin_len;
unsigned char *personalsigbuf = (unsigned char *)
newMsg->personalSignature.signData.bin_data;
RsPeerDetails signerDetails;
std::string gpg_fpr;
if (AuthGPG::getAuthGPG()->getGPGDetails(newMsg->personalSignature.keyId, signerDetails))
{
gpg_fpr = signerDetails.fpr;
}
bool gpgSign = AuthGPG::getAuthGPG()->VerifySignBin(
newMsg->packet.bin_data, newMsg->packet.bin_len,
personalsigbuf, personalsiglen, gpg_fpr);
if (gpgSign) {
#ifdef DISTRIB_DEBUG
std::cerr << "p3GroupDistrib::locked_validateDistribSignedMsg() Success for gpg signature." << std::endl;
#endif
signOk = 1;
} else {
#ifdef DISTRIB_DEBUG
std::cerr << "p3GroupDistrib::locked_validateDistribSignedMsg() Fail for gpg signature." << std::endl;
#endif
signOk = 0;
}
}
if (signOk == 1)
{
#ifdef DISTRIB_DEBUG
std::cerr << "p3GroupDistrib::locked_validateDistribSignedMsg() Signature OK";
std::cerr << std::endl;
#endif
return true;
}
#ifdef DISTRIB_DEBUG
std::cerr << "p3GroupDistrib::locked_validateDistribSignedMsg() Signature invalid";
std::cerr << std::endl;
#endif
return false;
}
std::string p3DistribSecurity::getBinDataSign(void *data, int len)
{
unsigned char *tmp = (unsigned char *) data;
// copy first CERTSIGNLEN bytes...
if (len > CERTSIGNLEN)
{
len = CERTSIGNLEN;
}
std::ostringstream id;
for(uint32_t i = 0; i < CERTSIGNLEN; i++)
{
id << std::hex << std::setw(2) << std::setfill('0')
<< (uint16_t) (((uint8_t *) (tmp))[i]);
}
std::string Id = id.str();
return Id;
}
bool p3DistribSecurity::encrypt(void *& out, int & outlen, const void *in, int inlen, EVP_PKEY *privateKey)
{
#ifdef DISTRIB_DEBUG
std::cerr << "p3DistribSecurity::encrypt() " << std::endl;
#endif
RSA *rsa_publish_pub = NULL;
EVP_PKEY *public_key = NULL;
RSA* rsa_publish = EVP_PKEY_get1_RSA(privateKey);
rsa_publish_pub = RSAPublicKey_dup(rsa_publish);
if(rsa_publish_pub != NULL){
public_key = EVP_PKEY_new();
EVP_PKEY_assign_RSA(public_key, rsa_publish_pub);
}else{
#ifdef DISTRIB_DEBUG
std::cerr << "p3DistribSecurity(): Could not generate publish key " << grpId
<< std::endl;
#endif
return false;
}
EVP_CIPHER_CTX ctx;
int eklen, net_ekl;
unsigned char *ek;
unsigned char iv[EVP_MAX_IV_LENGTH];
EVP_CIPHER_CTX_init(&ctx);
int out_currOffset = 0;
int out_offset = 0;
int max_evp_key_size = EVP_PKEY_size(public_key);
ek = (unsigned char*)malloc(max_evp_key_size);
const EVP_CIPHER *cipher = EVP_aes_128_cbc();
int cipher_block_size = EVP_CIPHER_block_size(cipher);
int size_net_ekl = sizeof(net_ekl);
int max_outlen = inlen + cipher_block_size + EVP_MAX_IV_LENGTH + max_evp_key_size + size_net_ekl;
// intialize context and send store encrypted cipher in ek
if(!EVP_SealInit(&ctx, EVP_aes_128_cbc(), &ek, &eklen, iv, &public_key, 1)) return false;
// now assign memory to out accounting for data, and cipher block size, key length, and key length val
out = new unsigned char[inlen + cipher_block_size + size_net_ekl + eklen + EVP_MAX_IV_LENGTH];
net_ekl = htonl(eklen);
memcpy((unsigned char*)out + out_offset, &net_ekl, size_net_ekl);
out_offset += size_net_ekl;
memcpy((unsigned char*)out + out_offset, ek, eklen);
out_offset += eklen;
memcpy((unsigned char*)out + out_offset, iv, EVP_MAX_IV_LENGTH);
out_offset += EVP_MAX_IV_LENGTH;
// now encrypt actual data
if(!EVP_SealUpdate(&ctx, (unsigned char*) out + out_offset, &out_currOffset, (unsigned char*) in, inlen)) return false;
// move along to partial block space
out_offset += out_currOffset;
// add padding
if(!EVP_SealFinal(&ctx, (unsigned char*) out + out_offset, &out_currOffset)) return false;
// move to end
out_offset += out_currOffset;
// make sure offset has not gone passed valid memory bounds
if(out_offset > max_outlen) return false;
// free encrypted key data
free(ek);
outlen = out_offset;
return true;
delete[] ek;
#ifdef DISTRIB_DEBUG
std::cerr << "p3DistribSecurity::encrypt() finished with outlen : " << outlen << std::endl;
#endif
return true;
}
bool p3DistribSecurity::decrypt(void *& out, int & outlen, const void *in, int inlen, EVP_PKEY *privateKey)
{
#ifdef DISTRIB_DEBUG
std::cerr << "p3DistribSecurity::decrypt() " << std::endl;
#endif
EVP_CIPHER_CTX ctx;
int eklen = 0, net_ekl = 0;
unsigned char *ek = NULL;
unsigned char iv[EVP_MAX_IV_LENGTH];
ek = (unsigned char*)malloc(EVP_PKEY_size(privateKey));
EVP_CIPHER_CTX_init(&ctx);
int in_offset = 0, out_currOffset = 0;
int size_net_ekl = sizeof(net_ekl);
memcpy(&net_ekl, (unsigned char*)in, size_net_ekl);
eklen = ntohl(net_ekl);
in_offset += size_net_ekl;
memcpy(ek, (unsigned char*)in + in_offset, eklen);
in_offset += eklen;
memcpy(iv, (unsigned char*)in + in_offset, EVP_MAX_IV_LENGTH);
in_offset += EVP_MAX_IV_LENGTH;
const EVP_CIPHER* cipher = EVP_aes_128_cbc();
if(!EVP_OpenInit(&ctx, cipher, ek, eklen, iv, privateKey)) return false;
out = new unsigned char[inlen - in_offset];
if(!EVP_OpenUpdate(&ctx, (unsigned char*) out, &out_currOffset, (unsigned char*)in + in_offset, inlen - in_offset)) return false;
in_offset += out_currOffset;
outlen += out_currOffset;
if(!EVP_OpenFinal(&ctx, (unsigned char*)out + out_currOffset, &out_currOffset)) return false;
outlen += out_currOffset;
free(ek);
return true;
}
std::string p3DistribSecurity::getRsaKeySign(RSA *pubkey)
{
int len = BN_num_bytes(pubkey -> n);
unsigned char tmp[len];
BN_bn2bin(pubkey -> n, tmp);
// copy first CERTSIGNLEN bytes...
if (len > CERTSIGNLEN)
{
len = CERTSIGNLEN;
}
std::ostringstream id;
for(uint32_t i = 0; i < CERTSIGNLEN; i++)
{
id << std::hex << std::setw(2) << std::setfill('0')
<< (uint16_t) (((uint8_t *) (tmp))[i]);
}
std::string rsaId = id.str();
return rsaId;
}
bool p3DistribSecurity::validateDistribGrp(RsDistribGrp *newGrp)
{
#ifdef DISTRIB_DEBUG
std::cerr << "p3GroupDistrib::validateDistribGrp()";
std::cerr << std::endl;
#endif
/* check signature */
RsSerialType *serialType = new RsDistribSerialiser();
/* copy out signature (shallow copy) */
RsTlvKeySignature tmpSign = newGrp->adminSignature;
unsigned char *sigbuf = (unsigned char *) tmpSign.signData.bin_data;
unsigned int siglen = tmpSign.signData.bin_len;
/* clear signature */
newGrp->adminSignature.ShallowClear();
uint32_t size = serialType->size(newGrp);
char* data = new char[size];
serialType->serialise(newGrp, data, &size);
const unsigned char *keyptr = (const unsigned char *) newGrp->adminKey.keyData.bin_data;
long keylen = newGrp->adminKey.keyData.bin_len;
/* extract admin key */
RSA *rsakey = d2i_RSAPublicKey(NULL, &(keyptr), keylen);
EVP_PKEY *key = EVP_PKEY_new();
EVP_PKEY_assign_RSA(key, rsakey);
/* calc and check signature */
EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
EVP_VerifyInit(mdctx, EVP_sha1());
EVP_VerifyUpdate(mdctx, data, size);
int ans = EVP_VerifyFinal(mdctx, sigbuf, siglen, key);
/* restore signature */
newGrp->adminSignature = tmpSign;
tmpSign.ShallowClear();
/* clean up */
EVP_PKEY_free(key);
delete serialType;
EVP_MD_CTX_destroy(mdctx);
delete[] data;
if (ans == 1)
return true;
#ifdef DISTRIB_DEBUG
std::cerr << "p3GroupDistrib::validateDistribGrp() Signature invalid";
std::cerr << std::endl;
#endif
return false;
}
void p3DistribSecurity::setRSAPublicKey(RsTlvSecurityKey & key, RSA *rsa_pub)
{
unsigned char data[10240]; /* more than enough space */
unsigned char *ptr = data;
int reqspace = i2d_RSAPublicKey(rsa_pub, &ptr);
key.keyData.setBinData(data, reqspace);
std::string keyId = getRsaKeySign(rsa_pub);
key.keyId = keyId;
}
void p3DistribSecurity::setRSAPrivateKey(RsTlvSecurityKey & key, RSA *rsa_priv)
{
unsigned char data[10240]; /* more than enough space */
unsigned char *ptr = data;
int reqspace = i2d_RSAPrivateKey(rsa_priv, &ptr);
key.keyData.setBinData(data, reqspace);
std::string keyId = getRsaKeySign(rsa_priv);
key.keyId = keyId;
}
RSA *p3DistribSecurity::extractPrivateKey(RsTlvSecurityKey & key)
{
const unsigned char *keyptr = (const unsigned char *) key.keyData.bin_data;
long keylen = key.keyData.bin_len;
/* extract admin key */
RSA *rsakey = d2i_RSAPrivateKey(NULL, &(keyptr), keylen);
return rsakey;
}

View File

@ -0,0 +1,133 @@
/*
* libretroshare/src/distrib: p3distribverify.h
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2008-2010 by Robert Fernie
* 2011 Christopher Evi-Parker
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#ifndef P3DISTRIBVERIFY_H_
#define P3DISTRIBVERIFY_H_
#include <openssl/ssl.h>
#include <openssl/evp.h>
#include "serialiser/rstlvkeys.h"
#include "distrib/p3distrib.h"
/*!
* This contains functionality for performing security
* operations needed to validate data received in p3GroupDistrib
* Also has functionality to receive data
*/
class p3DistribSecurity {
public:
p3DistribSecurity();
~p3DistribSecurity();
/*!
* extracts the public key from an RsTlvSecurityKey
* @param key RsTlvSecurityKey to extract public RSA key from
* @return pointer to the public RSA key if successful, null otherwise
*/
static RSA *extractPublicKey(RsTlvSecurityKey &key);
/*!
* extracts the public key from an RsTlvSecurityKey
* @param key RsTlvSecurityKey to extract private RSA key from
* @return pointer to the private RSA key if successful, null otherwise
*/
static RSA *extractPrivateKey(RsTlvSecurityKey &key);
/*!
* stores the rsa public key in a RsTlvSecurityKey
* @param key RsTlvSecurityKey to store the public rsa key in
* @param rsa_pub
*/
static void setRSAPublicKey(RsTlvSecurityKey &key, RSA *rsa_pub);
/*!
* stores the rsa private key in a RsTlvSecurityKey
* @param key stores the rsa private key in a RsTlvSecurityKey
* @param rsa_priv the rsa private key to store
*/
static void setRSAPrivateKey(RsTlvSecurityKey &key, RSA *rsa_priv);
/*!
* extracts signature from RSA key
* @param pubkey
* @return signature of RSA key in hex format
*/
static std::string getRsaKeySign(RSA *pubkey);
/*!
* extracts the signature and stores it in a string
* in hex format
* @param data
* @param len
* @return
*/
static std::string getBinDataSign(void *data, int len);
/*!
* Encrypts data using envelope encryption (taken from open ssl's evp_sealinit )
* only full publish key holders can encrypt data for given group
*@param out
*@param outlen
*@param in
*@param inlen
*/
static bool encrypt(void *&out, int &outlen, const void *in, int inlen, EVP_PKEY *privateKey);
/**
* Decrypts data using evelope decryption (taken from open ssl's evp_sealinit )
* only full publish key holders can decrypt data for a group
* @param out where decrypted data is written to
* @param outlen
* @param in
* @param inlen
* @return false if encryption failed
*/
static bool decrypt(void *&out, int &outlen, const void *in, int inlen, EVP_PKEY *privateKey);
/*!
* uses grp signature to check if group has been
* tampered with
* @param newGrp
* @return true if group valid false otherwise
*/
static bool validateDistribGrp(RsDistribGrp *newGrp);
/*!
* uses groupinfo public key to verify signature of signed message
* @param info groupinfo for which msg is meant for
* @param msg
* @return false if verfication of signature is not passed
*/
static bool validateDistribSignedMsg(GroupInfo &info, RsDistribSignedMsg *msg);
};
#endif /* P3DISTRIBVERIFY_H_ */

View File

@ -411,7 +411,6 @@ HEADERS += serialiser/rsbaseitems.h \
HEADERS += services/p3channels.h \
services/p3chatservice.h \
services/p3disc.h \
services/p3distrib.h \
services/p3forums.h \
services/p3gamelauncher.h \
services/p3gameservice.h \
@ -420,6 +419,9 @@ HEADERS += services/p3channels.h \
services/p3service.h \
services/p3statusservice.h \
services/p3tunnel.h
HEADERS += distrib/p3distrib.h \
distrib/p3distribsecurity.h
# services/p3blogs.h \
HEADERS += turtle/p3turtle.h \
@ -538,7 +540,6 @@ SOURCES += serialiser/rsbaseitems.cc \
SOURCES += services/p3channels.cc \
services/p3chatservice.cc \
services/p3disc.cc \
services/p3distrib.cc \
services/p3forums.cc \
services/p3gamelauncher.cc \
services/p3msgservice.cc \
@ -547,7 +548,9 @@ SOURCES += services/p3channels.cc \
services/p3statusservice.cc
# removed because getPeer() doesn t exist services/p3tunnel.cc
SOURCES += distrib/p3distrib.cc \
distrib/p3distribsecurity.cc
SOURCES += turtle/p3turtle.cc \
turtle/rsturtleitem.cc
# turtle/turtlerouting.cc \

View File

@ -28,7 +28,7 @@
#include "retroshare/rsblogs.h"
#include "retroshare/rsfiles.h"
#include "services/p3distrib.h"
#include "distrib/p3distrib.h"
#include "serialiser/rstlvtypes.h"
#include "serialiser/rsblogitems.h"

View File

@ -186,6 +186,8 @@ bool p3Channels::getChannelMessage(std::string cId, std::string mId, ChannelMsgI
std::list<std::string> msgIds;
std::list<std::string>::iterator it;
processCacheOptReq(cId);
RsStackMutex stack(distribMtx); /***** STACK LOCKED MUTEX *****/
RsDistribMsg *msg = locked_getGroupMsg(cId, mId);

View File

@ -28,7 +28,7 @@
#include "retroshare/rschannels.h"
#include "retroshare/rsfiles.h"
#include "services/p3distrib.h"
#include "distrib/p3distrib.h"
#include "serialiser/rstlvtypes.h"
#include "serialiser/rschannelitems.h"

View File

@ -294,6 +294,8 @@ bool p3Forums::getForumThreadMsgList(const std::string &fId, const std::string &
bool p3Forums::getForumMessage(const std::string &fId, const std::string &mId, ForumMsgInfo &info)
{
processCacheOptReq(fId);
RsStackMutex stack(distribMtx); /***** STACK LOCKED MUTEX *****/
RsDistribMsg *msg = locked_getGroupMsg(fId, mId);
@ -437,6 +439,7 @@ std::string p3Forums::createForumMsg(std::string fId, std::string pId,
RsForumMsg *fmsg = new RsForumMsg();
fmsg->grpId = fId;
fmsg->parentId = pId;
processCacheOptReq(fId);
{
RsStackMutex stack(distribMtx); /***** STACK LOCKED MUTEX *****/

View File

@ -27,7 +27,7 @@
*/
#include "retroshare/rsforums.h"
#include "services/p3distrib.h"
#include "distrib/p3distrib.h"
#include "serialiser/rsforumitems.h"