mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-01-24 14:23:36 -05:00
Fixed up validate / create Signature logic.
Added comments about missing re-try for Keys that are not in Cache. git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@6159 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
ebce79f9fa
commit
c13192b4c3
@ -314,74 +314,38 @@ bool RsGenExchange::createMsgSignatures(RsTlvKeySignatureSet& signSet, RsTlvBina
|
|||||||
// restricted is a special case which heeds whether publish sign needs to be checked or not
|
// restricted is a special case which heeds whether publish sign needs to be checked or not
|
||||||
// one may or may not want
|
// one may or may not want
|
||||||
|
|
||||||
if(msgMeta.mParentId.empty())
|
uint8_t author_flag = GXS_SERV::MSG_AUTHEN_ROOT_AUTHOR_SIGN;
|
||||||
|
uint8_t publish_flag = GXS_SERV::MSG_AUTHEN_ROOT_PUBLISH_SIGN;
|
||||||
|
|
||||||
|
if(!msgMeta.mParentId.empty())
|
||||||
{
|
{
|
||||||
isParent = true;
|
// Child Message.
|
||||||
}
|
author_flag = GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN;
|
||||||
else
|
publish_flag = GXS_SERV::MSG_AUTHEN_CHILD_PUBLISH_SIGN;
|
||||||
{
|
|
||||||
isParent = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PrivacyBitPos pos = PUBLIC_GRP_BITS;
|
||||||
if(isParent)
|
if (grpFlag & GXS_SERV::FLAG_PRIVACY_RESTRICTED)
|
||||||
{
|
{
|
||||||
needIdentitySign = false;
|
pos = RESTRICTED_GRP_BITS;
|
||||||
needPublishSign = false;
|
|
||||||
|
|
||||||
if(grpFlag & GXS_SERV::FLAG_PRIVACY_PUBLIC)
|
|
||||||
{
|
|
||||||
needPublishSign = false;
|
|
||||||
|
|
||||||
if(checkMsgAuthenFlag(PUBLIC_GRP_BITS, GXS_SERV::MSG_AUTHEN_ROOT_AUTHOR_SIGN))
|
|
||||||
needIdentitySign = true;
|
|
||||||
|
|
||||||
}
|
|
||||||
else if(grpFlag & GXS_SERV::FLAG_PRIVACY_RESTRICTED)
|
|
||||||
{
|
|
||||||
needPublishSign = true;
|
|
||||||
|
|
||||||
if(checkMsgAuthenFlag(RESTRICTED_GRP_BITS, GXS_SERV::MSG_AUTHEN_ROOT_AUTHOR_SIGN))
|
|
||||||
needIdentitySign = true;
|
|
||||||
}
|
|
||||||
else if(grpFlag & GXS_SERV::FLAG_PRIVACY_PRIVATE)
|
|
||||||
{
|
|
||||||
needPublishSign = false;
|
|
||||||
|
|
||||||
if(checkMsgAuthenFlag(PRIVATE_GRP_BITS, GXS_SERV::MSG_AUTHEN_ROOT_AUTHOR_SIGN))
|
|
||||||
needIdentitySign = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}else
|
|
||||||
{
|
|
||||||
if(grpFlag & GXS_SERV::FLAG_PRIVACY_PUBLIC)
|
|
||||||
{
|
|
||||||
needPublishSign = false;
|
|
||||||
|
|
||||||
if(checkMsgAuthenFlag(PUBLIC_GRP_BITS, GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN))
|
|
||||||
needIdentitySign = true;
|
|
||||||
|
|
||||||
}
|
|
||||||
else if(grpFlag & GXS_SERV::FLAG_PRIVACY_RESTRICTED)
|
|
||||||
{
|
|
||||||
if(checkMsgAuthenFlag(RESTRICTED_GRP_BITS, GXS_SERV::MSG_AUTHEN_CHILD_PUBLISH_SIGN))
|
|
||||||
needPublishSign = true;
|
|
||||||
|
|
||||||
if(checkMsgAuthenFlag(RESTRICTED_GRP_BITS, GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN))
|
|
||||||
needIdentitySign = true;
|
|
||||||
}
|
|
||||||
else if(grpFlag & GXS_SERV::FLAG_PRIVACY_PRIVATE)
|
|
||||||
{
|
|
||||||
needPublishSign = false;
|
|
||||||
|
|
||||||
if(checkMsgAuthenFlag(PRIVATE_GRP_BITS, GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN))
|
|
||||||
needIdentitySign = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else if (grpFlag & GXS_SERV::FLAG_PRIVACY_PRIVATE)
|
||||||
|
{
|
||||||
|
pos = PRIVATE_GRP_BITS;
|
||||||
|
}
|
||||||
|
|
||||||
|
needIdentitySign = false;
|
||||||
|
needPublishSign = false;
|
||||||
|
if (checkMsgAuthenFlag(pos, publish_flag))
|
||||||
|
needPublishSign = true;
|
||||||
|
|
||||||
|
// Check required permissions, and allow them to sign it - if they want too - as well!
|
||||||
|
if ((checkMsgAuthenFlag(pos, author_flag)) || (!msgMeta.mAuthorId.empty()))
|
||||||
|
needIdentitySign = true;
|
||||||
|
|
||||||
|
|
||||||
if(needPublishSign)
|
if(needPublishSign)
|
||||||
{
|
{
|
||||||
|
|
||||||
// public and shared is publish key
|
// public and shared is publish key
|
||||||
RsTlvSecurityKeySet& keys = grpMeta.keys;
|
RsTlvSecurityKeySet& keys = grpMeta.keys;
|
||||||
RsTlvSecurityKey* pubKey;
|
RsTlvSecurityKey* pubKey;
|
||||||
@ -397,6 +361,13 @@ bool RsGenExchange::createMsgSignatures(RsTlvKeySignatureSet& signSet, RsTlvBina
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!pub_key_found)
|
||||||
|
{
|
||||||
|
std::cerr << "RsGenExchange::createMsgSignatures()";
|
||||||
|
std::cerr << " ERROR Cannot find PUBLISH KEY for Message Signing";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// private publish key
|
// private publish key
|
||||||
pubKey = &(mit->second);
|
pubKey = &(mit->second);
|
||||||
|
|
||||||
@ -409,10 +380,18 @@ bool RsGenExchange::createMsgSignatures(RsTlvKeySignatureSet& signSet, RsTlvBina
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(needIdentitySign)
|
if (needIdentitySign)
|
||||||
{
|
{
|
||||||
if(mGixs)
|
if(mGixs)
|
||||||
{
|
{
|
||||||
|
/***************************************************************
|
||||||
|
* NOTE: The logic below is wrong.
|
||||||
|
* mGixs->havePrivateKey(msgMeta.mAuthorId) can return False if the Key isn't cached.
|
||||||
|
*
|
||||||
|
* This Operation should be retried again - later.
|
||||||
|
*
|
||||||
|
**************************************************************/
|
||||||
|
|
||||||
bool haveKey = mGixs->havePrivateKey(msgMeta.mAuthorId);
|
bool haveKey = mGixs->havePrivateKey(msgMeta.mAuthorId);
|
||||||
|
|
||||||
if(haveKey)
|
if(haveKey)
|
||||||
@ -424,19 +403,27 @@ bool RsGenExchange::createMsgSignatures(RsTlvKeySignatureSet& signSet, RsTlvBina
|
|||||||
double timeDelta = 0.002; // fast polling
|
double timeDelta = 0.002; // fast polling
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
|
|
||||||
|
bool auth_key_fetched = false;
|
||||||
// poll immediately but, don't spend more than a second polling
|
// poll immediately but, don't spend more than a second polling
|
||||||
while( (mGixs->getPrivateKey(msgMeta.mAuthorId, authorKey) == -1) &&
|
while((!auth_key_fetched) && ((now + 5) > time(NULL)))
|
||||||
((now + 5) > time(NULL))
|
{
|
||||||
)
|
auth_key_fetched = (mGixs->getPrivateKey(msgMeta.mAuthorId, authorKey) == 1);
|
||||||
{
|
#ifndef WINDOWS_SYS
|
||||||
#ifndef WINDOWS_SYS
|
usleep((int) (timeDelta * 1000000));
|
||||||
usleep((int) (timeDelta * 1000000));
|
#else
|
||||||
#else
|
Sleep((int) (timeDelta * 1000));
|
||||||
Sleep((int) (timeDelta * 1000));
|
#endif
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!auth_key_fetched)
|
||||||
|
{
|
||||||
|
std::cerr << "RsGenExchange::createMsgSignatures()";
|
||||||
|
std::cerr << " ERROR Cannot find AUTHOR KEY for Message Signing";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
RsTlvKeySignature sign;
|
RsTlvKeySignature sign;
|
||||||
ok &= GxsSecurity::getSignature((char*)msgData.bin_data, msgData.bin_len,
|
ok &= GxsSecurity::getSignature((char*)msgData.bin_data, msgData.bin_len,
|
||||||
&authorKey, sign);
|
&authorKey, sign);
|
||||||
@ -455,10 +442,7 @@ bool RsGenExchange::createMsgSignatures(RsTlvKeySignatureSet& signSet, RsTlvBina
|
|||||||
ok = false;
|
ok = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ok;
|
return ok;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RsGenExchange::createMessage(RsNxsMsg* msg)
|
bool RsGenExchange::createMessage(RsNxsMsg* msg)
|
||||||
@ -518,85 +502,41 @@ bool RsGenExchange::createMessage(RsNxsMsg* msg)
|
|||||||
|
|
||||||
bool RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, RsTlvSecurityKeySet& grpKeySet)
|
bool RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, RsTlvSecurityKeySet& grpKeySet)
|
||||||
{
|
{
|
||||||
bool isParent = false;
|
bool needIdentitySign = false;
|
||||||
bool checkPublishSign, checkIdentitySign;
|
bool needPublishSign = false;
|
||||||
bool valid = true;
|
bool valid = true;
|
||||||
|
|
||||||
// publish signature is determined by whether group is public or not
|
uint8_t author_flag = GXS_SERV::MSG_AUTHEN_ROOT_AUTHOR_SIGN;
|
||||||
// for private group signature is not needed as it needs decrypting with
|
uint8_t publish_flag = GXS_SERV::MSG_AUTHEN_ROOT_PUBLISH_SIGN;
|
||||||
// the private publish key anyways
|
|
||||||
|
|
||||||
// restricted is a special case which heeds whether publish sign needs to be checked or not
|
if(!msg->metaData->mParentId.empty())
|
||||||
// one may or may not want
|
|
||||||
|
|
||||||
if(msg->metaData->mParentId.empty())
|
|
||||||
{
|
{
|
||||||
isParent = true;
|
// Child Message.
|
||||||
}
|
author_flag = GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN;
|
||||||
else
|
publish_flag = GXS_SERV::MSG_AUTHEN_CHILD_PUBLISH_SIGN;
|
||||||
{
|
|
||||||
isParent = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PrivacyBitPos pos = PUBLIC_GRP_BITS;
|
||||||
if(isParent)
|
if (grpFlag & GXS_SERV::FLAG_PRIVACY_RESTRICTED)
|
||||||
{
|
{
|
||||||
checkIdentitySign = false;
|
pos = RESTRICTED_GRP_BITS;
|
||||||
checkPublishSign = false;
|
|
||||||
|
|
||||||
if(grpFlag & GXS_SERV::FLAG_PRIVACY_PUBLIC)
|
|
||||||
{
|
|
||||||
checkPublishSign = false;
|
|
||||||
|
|
||||||
if(checkMsgAuthenFlag(PUBLIC_GRP_BITS, GXS_SERV::MSG_AUTHEN_ROOT_AUTHOR_SIGN))
|
|
||||||
checkIdentitySign = true;
|
|
||||||
|
|
||||||
}
|
|
||||||
else if(grpFlag & GXS_SERV::FLAG_PRIVACY_RESTRICTED)
|
|
||||||
{
|
|
||||||
checkPublishSign = true;
|
|
||||||
|
|
||||||
if(checkMsgAuthenFlag(RESTRICTED_GRP_BITS, GXS_SERV::MSG_AUTHEN_ROOT_AUTHOR_SIGN))
|
|
||||||
checkIdentitySign = true;
|
|
||||||
}
|
|
||||||
else if(grpFlag & GXS_SERV::FLAG_PRIVACY_PRIVATE)
|
|
||||||
{
|
|
||||||
checkPublishSign = false;
|
|
||||||
|
|
||||||
if(checkMsgAuthenFlag(PRIVATE_GRP_BITS, GXS_SERV::MSG_AUTHEN_ROOT_AUTHOR_SIGN))
|
|
||||||
checkIdentitySign = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}else
|
|
||||||
{
|
|
||||||
if(grpFlag & GXS_SERV::FLAG_PRIVACY_PUBLIC)
|
|
||||||
{
|
|
||||||
checkPublishSign = false;
|
|
||||||
|
|
||||||
if(checkMsgAuthenFlag(PUBLIC_GRP_BITS, GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN))
|
|
||||||
checkIdentitySign = true;
|
|
||||||
|
|
||||||
}
|
|
||||||
else if(grpFlag & GXS_SERV::FLAG_PRIVACY_RESTRICTED)
|
|
||||||
{
|
|
||||||
if(checkMsgAuthenFlag(RESTRICTED_GRP_BITS, GXS_SERV::MSG_AUTHEN_CHILD_PUBLISH_SIGN))
|
|
||||||
checkPublishSign = true;
|
|
||||||
|
|
||||||
if(checkMsgAuthenFlag(RESTRICTED_GRP_BITS, GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN))
|
|
||||||
checkIdentitySign = true;
|
|
||||||
}
|
|
||||||
else if(grpFlag & GXS_SERV::FLAG_PRIVACY_PRIVATE)
|
|
||||||
{
|
|
||||||
checkPublishSign = false;
|
|
||||||
|
|
||||||
if(checkMsgAuthenFlag(PRIVATE_GRP_BITS, GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN))
|
|
||||||
checkIdentitySign = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else if (grpFlag & GXS_SERV::FLAG_PRIVACY_PRIVATE)
|
||||||
|
{
|
||||||
|
pos = PRIVATE_GRP_BITS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checkMsgAuthenFlag(pos, publish_flag))
|
||||||
|
needPublishSign = true;
|
||||||
|
|
||||||
|
// Check required permissions, if they have signed it anyway - we need to validate it.
|
||||||
|
if ((checkMsgAuthenFlag(pos, author_flag)) || (!msg->metaData->mAuthorId.empty()))
|
||||||
|
needIdentitySign = true;
|
||||||
|
|
||||||
|
|
||||||
RsGxsMsgMetaData& metaData = *(msg->metaData);
|
RsGxsMsgMetaData& metaData = *(msg->metaData);
|
||||||
|
|
||||||
if(checkPublishSign)
|
if(needPublishSign)
|
||||||
{
|
{
|
||||||
RsTlvKeySignature sign = metaData.signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_PUBLISH];
|
RsTlvKeySignature sign = metaData.signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_PUBLISH];
|
||||||
|
|
||||||
@ -628,7 +568,7 @@ bool RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, RsTlvSec
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(checkIdentitySign)
|
if(needIdentitySign)
|
||||||
{
|
{
|
||||||
if(mGixs)
|
if(mGixs)
|
||||||
{
|
{
|
||||||
@ -641,20 +581,31 @@ bool RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, RsTlvSec
|
|||||||
|
|
||||||
double timeDelta = 0.002; // fast polling
|
double timeDelta = 0.002; // fast polling
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
|
bool auth_key_fetched = false;
|
||||||
// poll immediately but, don't spend more than a second polling
|
// poll immediately but, don't spend more than a second polling
|
||||||
while( (mGixs->getKey(metaData.mAuthorId, authorKey) == -1) &&
|
while((!auth_key_fetched) && ((now + 1) > time(NULL)))
|
||||||
((now + 1) >> time(NULL))
|
{
|
||||||
)
|
auth_key_fetched = (mGixs->getKey(metaData.mAuthorId, authorKey) == 1);
|
||||||
{
|
#ifndef WINDOWS_SYS
|
||||||
#ifndef WINDOWS_SYS
|
usleep((int) (timeDelta * 1000000));
|
||||||
usleep((int) (timeDelta * 1000000));
|
#else
|
||||||
#else
|
Sleep((int) (timeDelta * 1000));
|
||||||
Sleep((int) (timeDelta * 1000));
|
#endif
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!auth_key_fetched)
|
||||||
|
{
|
||||||
|
std::cerr << "RsGenExchange::validateMsg()";
|
||||||
|
std::cerr << " ERROR Cannot find AUTHOR KEY for Message Validation";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
RsTlvKeySignature sign = metaData.signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_IDENTITY];
|
RsTlvKeySignature sign = metaData.signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_IDENTITY];
|
||||||
valid &= GxsSecurity::validateNxsMsg(*msg, sign, authorKey);
|
valid &= GxsSecurity::validateNxsMsg(*msg, sign, authorKey);
|
||||||
|
|
||||||
}else
|
}else
|
||||||
{
|
{
|
||||||
std::list<std::string> peers;
|
std::list<std::string> peers;
|
||||||
@ -1209,6 +1160,8 @@ void RsGenExchange::publishMsgs()
|
|||||||
|
|
||||||
for(; mit != mMsgsToPublish.end(); mit++)
|
for(; mit != mMsgsToPublish.end(); mit++)
|
||||||
{
|
{
|
||||||
|
std::cerr << "RsGenExchange::publishMsgs() Publishing a Message";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
|
||||||
RsNxsMsg* msg = new RsNxsMsg(mServType);
|
RsNxsMsg* msg = new RsNxsMsg(mServType);
|
||||||
RsGxsMsgItem* msgItem = mit->second;
|
RsGxsMsgItem* msgItem = mit->second;
|
||||||
@ -1296,6 +1249,14 @@ void RsGenExchange::publishMsgs()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// delete msg if created wasn't ok
|
// delete msg if created wasn't ok
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* NOTE: THIS LOGIC IS WRONG.
|
||||||
|
* It is possible, that message creation failed because Author Keys
|
||||||
|
* were not cached... If this is the case - it should be re-tried
|
||||||
|
* in a few seconds - when the cache has been loaded.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
delete msg;
|
delete msg;
|
||||||
mDataAccess->updatePublicRequestStatus(mit->first, RsTokenService::GXS_REQUEST_V2_STATUS_FAILED);
|
mDataAccess->updatePublicRequestStatus(mit->first, RsTokenService::GXS_REQUEST_V2_STATUS_FAILED);
|
||||||
|
|
||||||
@ -1631,6 +1592,20 @@ void RsGenExchange::processRecvdMessages()
|
|||||||
|
|
||||||
if(!ok)
|
if(!ok)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* ONCE AGAIN - You fail to handle the case where the Key is not in the Cache.
|
||||||
|
* When this happens -- and it will happen frequently!
|
||||||
|
* You MUST retry.
|
||||||
|
*
|
||||||
|
* Suggested approach:
|
||||||
|
* 1) Change validateMsg() and createMsgSignatures to return INT instead of BOOL.
|
||||||
|
* 2) return -1 for fail , 0 for missing keys, 1 for success.
|
||||||
|
* 3) if missing keys, put on queue and retry in 1 or 2 seconds.
|
||||||
|
*
|
||||||
|
************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifdef GXS_GENX_DEBUG
|
#ifdef GXS_GENX_DEBUG
|
||||||
std::cerr << "failed to deserialise incoming meta, grpId: "
|
std::cerr << "failed to deserialise incoming meta, grpId: "
|
||||||
<< msg->grpId << ", msgId: " << msg->msgId << std::endl;
|
<< msg->grpId << ", msgId: " << msg->msgId << std::endl;
|
||||||
|
Loading…
Reference in New Issue
Block a user