Added Authenticated Forums. This required quite a bit of

additional functionality in other places, including:
 * add Sign / Verify functions to authxpgp
 * sign/verify messages, and control flags for p3distrib/p3forums.
 * add authmgr to p3distrib etc.
 * added AUTH flags to rsforums interface.



git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@867 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
drbob 2008-12-06 00:23:43 +00:00
parent 889ad3555b
commit 1efe8a2cb1
15 changed files with 260 additions and 45 deletions

View File

@ -360,8 +360,16 @@ bool AuthXPGP::isValid(std::string id)
std::cerr << std::endl;
#endif
xpgpMtx.lock(); /***** LOCK *****/
bool valid = false;
bool valid = (mCerts.end() != mCerts.find(id));
if (id == mOwnId)
{
valid = true;
}
else
{
valid = (mCerts.end() != mCerts.find(id));
}
xpgpMtx.unlock(); /**** UNLOCK ****/
@ -848,12 +856,116 @@ bool AuthXPGP::SignData(const void *data, const uint32_t len, std::string &sign)
}
bool AuthXPGP::SignDataBin(std::string input, unsigned char *sign, unsigned int *signlen)
{
return SignDataBin(input.c_str(), input.length(), sign, signlen);
}
bool AuthXPGP::SignDataBin(const void *data, const uint32_t len,
unsigned char *sign, unsigned int *signlen)
{
RsStackMutex stack(xpgpMtx); /***** STACK LOCK MUTEX *****/
EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
unsigned int req_signlen = EVP_PKEY_size(pkey);
if (req_signlen > *signlen)
{
/* not enough space */
std::cerr << "SignDataBin() Not Enough Sign SpacegnInit Failure!" << std::endl;
return false;
}
if (0 == EVP_SignInit(mdctx, EVP_sha1()))
{
std::cerr << "EVP_SignInit Failure!" << std::endl;
EVP_MD_CTX_destroy(mdctx);
return false;
}
if (0 == EVP_SignUpdate(mdctx, data, len))
{
std::cerr << "EVP_SignUpdate Failure!" << std::endl;
EVP_MD_CTX_destroy(mdctx);
return false;
}
if (0 == EVP_SignFinal(mdctx, sign, signlen, pkey))
{
std::cerr << "EVP_SignFinal Failure!" << std::endl;
EVP_MD_CTX_destroy(mdctx);
return false;
}
EVP_MD_CTX_destroy(mdctx);
return true;
}
bool AuthXPGP::VerifySignBin(std::string pid,
const void *data, const uint32_t len,
unsigned char *sign, unsigned int signlen)
{
RsStackMutex stack(xpgpMtx); /***** STACK LOCK MUTEX *****/
/* find the peer */
xpgpcert *peer;
if (pid == mOwnId)
{
peer = mOwnCert;
}
else if (!locked_FindCert(pid, &peer))
{
std::cerr << "VerifySignBin() no peer" << std::endl;
return false;
}
EVP_PKEY *peerkey = peer->certificate->key->key->pkey;
EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
if (0 == EVP_VerifyInit(mdctx, EVP_sha1()))
{
std::cerr << "EVP_VerifyInit Failure!" << std::endl;
EVP_MD_CTX_destroy(mdctx);
return false;
}
if (0 == EVP_VerifyUpdate(mdctx, data, len))
{
std::cerr << "EVP_VerifyUpdate Failure!" << std::endl;
EVP_MD_CTX_destroy(mdctx);
return false;
}
if (0 == EVP_VerifyFinal(mdctx, sign, signlen, peerkey))
{
std::cerr << "EVP_VerifyFinal Failure!" << std::endl;
EVP_MD_CTX_destroy(mdctx);
return false;
}
EVP_MD_CTX_destroy(mdctx);
return true;
}
/**** NEW functions we've added ****/
/**** AUX Functions ****/
bool AuthXPGP::locked_FindCert(std::string id, xpgpcert **cert)
{

View File

@ -127,6 +127,14 @@ virtual bool TrustCertificate(std::string id, bool trust);
/* Sign / Encrypt / Verify Data (TODO) */
virtual bool SignData(std::string input, std::string &sign);
virtual bool SignData(const void *data, const uint32_t len, std::string &sign);
/* for proper signatures! */
virtual bool SignDataBin(std::string input, unsigned char *sign, unsigned int *signlen);
virtual bool SignDataBin(const void *data, const uint32_t len,
unsigned char *sign, unsigned int *signlen);
virtual bool VerifySignBin(std::string pid,
const void *data, const uint32_t len,
unsigned char *sign, unsigned int signlen);
/*********** Overloaded Functions from p3AuthMgr **********/

View File

@ -310,6 +310,18 @@ bool GPGAuthMgr::SignData(const void *data, const uint32_t len, std::string &sig
}
bool GPGAuthMgr::SignDataBin(std::string input, unsigned char *sign, unsigned int *signlen)
{
return false;
}
bool GPGAuthMgr::SignDataBin(const void *data, const uint32_t len,
unsigned char *sign, unsigned int *signlen)
{
return false;
}

View File

@ -154,8 +154,11 @@ class GPGAuthMgr: public p3AuthMgr
*
****/
bool SignData(std::string input, std::string &sign);
bool SignData(const void *data, const uint32_t len, std::string &sign);
virtual bool SignData(std::string input, std::string &sign);
virtual bool SignData(const void *data, const uint32_t len, std::string &sign);
virtual bool SignDataBin(std::string input, unsigned char *sign, unsigned int *signlen);
virtual bool SignDataBin(const void *data, const uint32_t len,
unsigned char *sign, unsigned int *signlen);
/*********************************************************************************/
/************************* PGP Specific functions ********************************/

View File

@ -268,4 +268,23 @@ bool p3DummyAuthMgr::SignData(const void *data, const uint32_t len, std::string
return false;
}
bool p3DummyAuthMgr::SignDataBin(std::string input,
unsigned char *sign, unsigned int *signlen)
{
return false;
}
bool p3DummyAuthMgr::SignDataBin(const void *data, const uint32_t len,
unsigned char *sign, unsigned int *signlen)
{
return false;
}
bool p3DummyAuthMgr::VerifySignBin(std::string pid,
const void *data, const uint32_t len,
unsigned char *sign, unsigned int signlen)
{
return false;
}

View File

@ -123,6 +123,13 @@ virtual bool TrustCertificate(std::string id, bool trust) = 0;
/* Sign / Encrypt / Verify Data (TODO) */
virtual bool SignData(std::string input, std::string &sign) = 0;
virtual bool SignData(const void *data, const uint32_t len, std::string &sign) = 0;
virtual bool SignDataBin(std::string input, unsigned char *sign, unsigned int *signlen) = 0;
virtual bool SignDataBin(const void *data, const uint32_t len,
unsigned char *sign, unsigned int *signlen) = 0;
virtual bool VerifySignBin(std::string pid,
const void *data, const uint32_t len,
unsigned char *sign, unsigned int signlen) = 0;
//virtual bool encryptData(std::string recipientId, std::string plaindata, std::string &result);
@ -180,6 +187,13 @@ virtual bool TrustCertificate(std::string id, bool trust);
virtual bool SignData(std::string input, std::string &sign);
virtual bool SignData(const void *data, const uint32_t len, std::string &sign);
virtual bool SignDataBin(std::string input, unsigned char *sign, unsigned int *signlen);
virtual bool SignDataBin(const void *data, const uint32_t len,
unsigned char *sign, unsigned int *signlen);
virtual bool VerifySignBin(std::string pid,
const void *data, const uint32_t len,
unsigned char *sign, unsigned int signlen);
std::string mOwnId;
std::map<std::string, pqiAuthDetails> mPeerList;

View File

@ -43,6 +43,8 @@ class ForumInfo
std::wstring forumDesc;
uint32_t forumFlags;
uint32_t subscribeFlags;
uint32_t pop;
time_t lastPost;

View File

@ -634,7 +634,7 @@ int RsServer::StartupRetroShare(RsInit *config)
p3Forums *mForums = new p3Forums(RS_SERVICE_TYPE_FORUM,
mCacheStrapper, mCacheTransfer,
localcachedir, remotecachedir);
localcachedir, remotecachedir, mAuthMgr);
CachePair cp4(mForums, mForums, CacheId(RS_SERVICE_TYPE_FORUM, 0));
mCacheStrapper -> addCachePair(cp4);
@ -642,7 +642,7 @@ int RsServer::StartupRetroShare(RsInit *config)
p3Channels *mChannels = new p3Channels(RS_SERVICE_TYPE_CHANNEL,
mCacheStrapper, mCacheTransfer, rsFiles,
localcachedir, remotecachedir, channelsdir);
localcachedir, remotecachedir, channelsdir, mAuthMgr);
CachePair cp5(mChannels, mChannels, CacheId(RS_SERVICE_TYPE_CHANNEL, 0));
mCacheStrapper -> addCachePair(cp5);

View File

@ -58,7 +58,8 @@ int main(int argc, char **argv)
std::string srcdir = "./";
std::string storedir = "./";
p3Forums *forum = new p3Forums(type, cs, cft, srcdir, storedir);
p3AuthMgr *dAuthMgr = new p3DummyAuthMgr();
p3Forums *forum = new p3Forums(type, cs, cft, srcdir, storedir, dAuthMgr);
testForums(forum);
@ -116,7 +117,7 @@ int testForums(p3Forums *forum)
sleep(1);
#endif
std::string mId1 = forum->createForumMsg(fId2, "", L"Forum 2 Msg 1", L"first forum msg");
std::string mId1 = forum->createForumMsg(fId2, "", L"Forum 2 Msg 1", L"first forum msg", true);
forum->tick(); /* expect msg publish */
#ifdef WIN32
@ -131,7 +132,7 @@ int testForums(p3Forums *forum)
sleep(1);
#endif
std::string mId2 = forum->createForumMsg(fId2, "", L"Forum 2 Msg 2", L"second forum msg");
std::string mId2 = forum->createForumMsg(fId2, "", L"Forum 2 Msg 2", L"second forum msg", false);
forum->tick(); /* expect msg publish */
#ifdef WIN32

View File

@ -73,9 +73,10 @@ RsChannels *rsChannels = NULL;
p3Channels::p3Channels(uint16_t type, CacheStrapper *cs,
CacheTransfer *cft, RsFiles *files,
std::string srcdir, std::string storedir, std::string chanDir)
std::string srcdir, std::string storedir, std::string chanDir,
p3AuthMgr *mgr)
:p3GroupDistrib(type, cs, cft, srcdir, storedir,
CONFIG_TYPE_CHANNELS, CHANNEL_STOREPERIOD, CHANNEL_PUBPERIOD),
CONFIG_TYPE_CHANNELS, CHANNEL_STOREPERIOD, CHANNEL_PUBPERIOD, mgr),
mRsFiles(files),
mChannelsDir(chanDir)
{

View File

@ -39,7 +39,7 @@ class p3Channels: public p3GroupDistrib, public RsChannels
public:
p3Channels(uint16_t type, CacheStrapper *cs, CacheTransfer *cft, RsFiles *files,
std::string srcdir, std::string storedir, std::string channelsdir);
std::string srcdir, std::string storedir, std::string channelsdir, p3AuthMgr *mgr);
virtual ~p3Channels();
/****************************************/

View File

@ -37,6 +37,8 @@
* #define DISTRIB_DEBUG 1
****/
#define DISTRIB_DEBUG 1
RSA *extractPublicKey(RsTlvSecurityKey &key);
RSA *extractPrivateKey(RsTlvSecurityKey &key);
void setRSAPublicKey(RsTlvSecurityKey &key, RSA *rsa_pub);
@ -47,11 +49,13 @@ p3GroupDistrib::p3GroupDistrib(uint16_t subtype,
CacheStrapper *cs, CacheTransfer *cft,
std::string sourcedir, std::string storedir,
uint32_t configId,
uint32_t storePeriod, uint32_t pubPeriod)
uint32_t storePeriod, uint32_t pubPeriod,
p3AuthMgr *mgr)
:CacheSource(subtype, true, cs, sourcedir),
CacheStore(subtype, true, cs, cft, storedir),
p3Config(configId), nullService(subtype),
mAuthMgr(mgr),
mStorePeriod(storePeriod),
mPubPeriod(pubPeriod),
mLastPublishTime(0),
@ -63,6 +67,7 @@ p3GroupDistrib::p3GroupDistrib(uint16_t subtype,
/* force publication of groups (cleared if local cache file found) */
mGroupsRepublish = true;
mOwnId = mAuthMgr->OwnId();
return;
}
@ -1702,25 +1707,16 @@ std::string p3GroupDistrib::publishMsg(RsDistribMsg *msg, bool personalSign)
signedMsg->publishSignature.signData.setBinData(sigbuf, siglen);
signedMsg->publishSignature.keyId = gi->publishKeyId;
#if 0
if (personalSign)
{
/* calc and check signature */
EVP_MD_CTX *mdctx2 = EVP_MD_CTX_create();
EVP_SignInit(mdctx2, EVP_sha1());
EVP_SignUpdate(mdctx2, data, size);
unsigned int siglen = EVP_PKEY_size(personal_admin);
unsigned int siglen = EVP_PKEY_size(publishKey);
unsigned char sigbuf[siglen];
int ans = EVP_SignFinal(mdctx2, sigbuf, &siglen, personal_admin);
if (mAuthMgr->SignDataBin(data, size, sigbuf, &siglen))
{
signedMsg->personalSignature.signData.setBinData(sigbuf, siglen);
signedMsg->personalSignature.keyId = ownId;
EVP_MD_CTX_destroy(mdctx2);
signedMsg->personalSignature.keyId = mAuthMgr->OwnId();
}
}
#endif
/* clean up */
delete serialType;
@ -2434,10 +2430,44 @@ bool p3GroupDistrib::locked_validateDistribSignedMsg(
/* now verify Personal signature */
#ifdef DISTRIB_DEBUG
std::cerr << "p3GroupDistrib::locked_validateDistribSignedMsg() Personal Signature TODO";
std::cerr << "p3GroupDistrib::locked_validateDistribSignedMsg() Personal Signature";
std::cerr << std::endl;
#endif
if (mAuthMgr->isValid(newMsg->personalSignature.keyId))
{
#ifdef DISTRIB_DEBUG
std::cerr << "p3GroupDistrib::locked_validateDistribSignedMsg() Peer Known";
std::cerr << std::endl;
#endif
unsigned int personalsiglen =
newMsg->personalSignature.signData.bin_len;
unsigned char *personalsigbuf = (unsigned char *)
newMsg->personalSignature.signData.bin_data;
if (!mAuthMgr->VerifySignBin(
newMsg->personalSignature.keyId,
newMsg->packet.bin_data, newMsg->packet.bin_len,
personalsigbuf, personalsiglen))
{
#ifdef DISTRIB_DEBUG
std::cerr << "p3GroupDistrib::locked_validateDistribSignedMsg() VerifySign Failed";
std::cerr << std::endl;
#endif
signOk = 0;
}
}
else if ((info.grpFlags & RS_DISTRIB_AUTHEN_MASK)
& RS_DISTRIB_AUTHEN_REQ)
{
#ifdef DISTRIB_DEBUG
std::cerr << "p3GroupDistrib::locked_validateDistribSignedMsg() Fail - No Personal Sign on AUTH grp";
std::cerr << std::endl;
#endif
/* must know the signer */
signOk = 0;
}
if (signOk == 1)
{
#ifdef DISTRIB_DEBUG

View File

@ -29,6 +29,7 @@
#include "pqi/pqi.h"
#include "pqi/pqistreamer.h"
#include "pqi/p3cfgmgr.h"
#include "pqi/p3authmgr.h"
#include "services/p3service.h"
#include "dbase/cachestrapper.h"
#include "serialiser/rsforumitems.h"
@ -211,7 +212,8 @@ class p3GroupDistrib: public CacheSource, public CacheStore, public p3Config, pu
CacheStrapper *cs, CacheTransfer *cft,
std::string sourcedir, std::string storedir,
uint32_t configId,
uint32_t storePeriod, uint32_t pubPeriod);
uint32_t storePeriod, uint32_t pubPeriod,
p3AuthMgr *mgr);
/***************************************************************************************/
@ -388,6 +390,7 @@ bool groupsChanged(std::list<std::string> &groupIds);
RsMutex distribMtx; /* Protects All Data Below */
std::string mOwnId;
p3AuthMgr *mAuthMgr;
private:

View File

@ -23,7 +23,6 @@
*
*/
#include "rsiface/rspeers.h"
#include "services/p3forums.h"
uint32_t convertToInternalFlags(uint32_t extFlags);
@ -77,9 +76,11 @@ RsForums *rsForums = NULL;
#define FORUM_PUBPERIOD 600 /* 10 minutes ... (max = 455 days) */
p3Forums::p3Forums(uint16_t type, CacheStrapper *cs, CacheTransfer *cft,
std::string srcdir, std::string storedir)
std::string srcdir, std::string storedir,
p3AuthMgr *mgr)
:p3GroupDistrib(type, cs, cft, srcdir, storedir,
CONFIG_TYPE_FORUMS, FORUM_STOREPERIOD, FORUM_PUBPERIOD),
CONFIG_TYPE_FORUMS, FORUM_STOREPERIOD, FORUM_PUBPERIOD,
mgr),
mForumsChanged(false)
{
//loadDummyData();
@ -111,8 +112,9 @@ bool p3Forums::getForumInfo(std::string fId, ForumInfo &fi)
fi.forumId = gi->grpId;
fi.forumName = gi->grpName;
fi.forumDesc = gi->grpDesc;
fi.forumFlags = gi->grpFlags;
fi.forumFlags = gi->flags;
fi.subscribeFlags = gi->flags;
fi.pop = gi->sources.size();
fi.lastPost = gi->lastPost;
@ -233,15 +235,20 @@ bool p3Forums::getForumMessage(std::string fId, std::string mId, ForumMsgInfo &i
info.title = fmsg->title;
info.msg = fmsg->msg;
info.srcId = rsPeers->getPeerName(fmsg->srcId);
// should only use actual signature ....
//info.srcId = fmsg->srcId;
info.srcId = fmsg->personalSignature.keyId;
return true;
}
bool p3Forums::ForumMessageSend(ForumMsgInfo &info)
{
bool signIt = (info.msgflags == RS_DISTRIB_AUTHEN_REQ);
createForumMsg(info.forumId, info.parentId,
info.title, info.msg, signIt);
createForumMsg(info.forumId, info.parentId, info.title, info.msg);
return true;
}
@ -255,7 +262,7 @@ std::string p3Forums::createForum(std::wstring forumName, std::wstring forumDesc
}
std::string p3Forums::createForumMsg(std::string fId, std::string pId,
std::wstring title, std::wstring msg)
std::wstring title, std::wstring msg, bool signIt)
{
RsForumMsg *fmsg = new RsForumMsg();
@ -286,10 +293,13 @@ std::string p3Forums::createForumMsg(std::string fId, std::string pId,
fmsg->title = title;
fmsg->msg = msg;
fmsg->srcId = rsPeers->getOwnId();
if (signIt)
{
fmsg->srcId = mAuthMgr->OwnId();
}
fmsg->timestamp = time(NULL);
std::string msgId = publishMsg(fmsg, true);
std::string msgId = publishMsg(fmsg, signIt);
return msgId;
}
@ -431,8 +441,8 @@ void p3Forums::loadDummyData()
fi.lastPost = now - 1234;
forumId = createForum(fi.forumName, fi.forumDesc, fi.forumFlags);
msgId = createForumMsg(forumId, "", L"WELCOME TO Forum1", L"Hello!");
msgId = createForumMsg(forumId, msgId, L"Love this forum", L"Hello2!");
msgId = createForumMsg(forumId, "", L"WELCOME TO Forum1", L"Hello!", true);
msgId = createForumMsg(forumId, msgId, L"Love this forum", L"Hello2!", true);
return;

View File

@ -73,7 +73,7 @@ class p3Forums: public p3GroupDistrib, public RsForums
public:
p3Forums(uint16_t type, CacheStrapper *cs, CacheTransfer *cft,
std::string srcdir, std::string storedir);
std::string srcdir, std::string storedir, p3AuthMgr *mgr);
virtual ~p3Forums();
void loadDummyData();
@ -119,8 +119,8 @@ virtual RsDistribGrp *locked_createPrivateDistribGrp(GroupInfo &info);
/****************************************/
std::string createForumMsg(std::string fid, std::string pid,
std::wstring title, std::wstring msg);
std::string createForumMsg(std::string fId, std::string pId,
std::wstring title, std::wstring msg, bool signIt);
private: