mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-05-02 14:16:16 -04:00
Refactored signature creation to Gxs security
Fixed signing of msgs Added signing of groups (follows p3distrib grp creation method) Refactored GxsGroupDialog in 2 new UIs, GxsCreateGroupDialog and GxsViewGroup for ease of logic, retaining flexibility across GXS services. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5762 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
563e3df91e
commit
6f6f55c166
10 changed files with 286 additions and 62 deletions
|
@ -1,10 +1,10 @@
|
|||
|
||||
/*
|
||||
* libretroshare/src/distrib: p3distribverify.cc
|
||||
* libretroshare/src/gxs: gxssecurity.cc
|
||||
*
|
||||
*
|
||||
* Copyright 2008-2010 by Robert Fernie
|
||||
* 2011 Christopher Evi-Parker
|
||||
* 2011-2012 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
|
||||
|
@ -49,6 +49,30 @@ RSA *GxsSecurity::extractPublicKey(RsTlvSecurityKey& key)
|
|||
return rsakey;
|
||||
}
|
||||
|
||||
bool GxsSecurity::getSignature(char* data, uint32_t data_len, RsTlvSecurityKey* privKey, RsTlvKeySignature& sign)
|
||||
{
|
||||
RSA* rsa_pub = extractPrivateKey(*privKey);
|
||||
EVP_PKEY *key_pub = EVP_PKEY_new();
|
||||
EVP_PKEY_assign_RSA(key_pub, rsa_pub);
|
||||
|
||||
/* calc and check signature */
|
||||
EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
|
||||
bool ok = EVP_SignInit(mdctx, EVP_sha1()) == 1;
|
||||
ok &= EVP_SignUpdate(mdctx, data, data_len) == 1;
|
||||
|
||||
unsigned int siglen = EVP_PKEY_size(key_pub);
|
||||
unsigned char sigbuf[siglen];
|
||||
ok &= EVP_SignFinal(mdctx, sigbuf, &siglen, key_pub) == 1;
|
||||
|
||||
// clean up
|
||||
EVP_MD_CTX_destroy(mdctx);
|
||||
EVP_PKEY_free(key_pub);
|
||||
|
||||
sign.signData.setBinData(sigbuf, siglen);
|
||||
sign.keyId = privKey->keyId;
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool GxsSecurity::validateNxsMsg(RsNxsMsg *msg, RsTlvKeySignature& sign, RsTlvSecurityKeySet& key)
|
||||
{
|
||||
|
@ -135,7 +159,7 @@ bool GxsSecurity::validateNxsMsg(RsNxsMsg *msg, RsTlvKeySignature& sign, RsTlvSe
|
|||
// std::cerr << std::endl;
|
||||
//#endif
|
||||
|
||||
// return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -321,7 +345,7 @@ std::string GxsSecurity::getRsaKeySign(RSA *pubkey)
|
|||
|
||||
bool GxsSecurity::validateNxsGrp(RsNxsGrp *newGrp, RsTlvKeySignature& sign, RsTlvSecurityKey& key)
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void GxsSecurity::setRSAPublicKey(RsTlvSecurityKey & key, RSA *rsa_pub)
|
||||
|
|
|
@ -130,6 +130,16 @@ public:
|
|||
* @return false if verfication of signature is not passed
|
||||
*/
|
||||
static bool validateNxsMsg(RsNxsMsg *msg, RsTlvKeySignature& sign, RsTlvSecurityKeySet& key);
|
||||
|
||||
|
||||
/*!
|
||||
* @param data data to be signed
|
||||
* @param data_len length of data to be signed
|
||||
* @param privKey private key to used to make signature
|
||||
* @param sign the signature is stored here
|
||||
* @return false if signature creation failed, true is signature created
|
||||
*/
|
||||
static bool getSignature(char* data, uint32_t data_len, RsTlvSecurityKey* privKey, RsTlvKeySignature& sign);
|
||||
};
|
||||
|
||||
#endif // GXSSECURITY_H
|
||||
|
|
|
@ -125,7 +125,7 @@ bool RsGenExchange::acknowledgeTokenGrp(const uint32_t& token,
|
|||
return true;
|
||||
}
|
||||
|
||||
void RsGenExchange::createGroup(RsNxsGrp *grp)
|
||||
bool RsGenExchange::createGroup(RsNxsGrp *grp)
|
||||
{
|
||||
/* create Keys */
|
||||
|
||||
|
@ -162,17 +162,40 @@ void RsGenExchange::createGroup(RsNxsGrp *grp)
|
|||
adminKey.endTS = 0; /* no end */
|
||||
RsGxsGrpMetaData* meta = grp->metaData;
|
||||
|
||||
/* add keys to grp */
|
||||
/* add public keys to grp */
|
||||
|
||||
meta->keys.keys[adminKey.keyId] = adminKey;
|
||||
meta->keys.keys[privAdminKey.keyId] = privAdminKey;
|
||||
meta->keys.keys[pubKey.keyId] = pubKey;
|
||||
|
||||
// group is self signing
|
||||
// for the creation of group signature
|
||||
// only public admin and publish keys are present
|
||||
// key set
|
||||
uint32_t metaDataLen = meta->serial_size();
|
||||
uint32_t allGrpDataLen = metaDataLen + grp->grp.bin_len;
|
||||
char* metaData = new char[metaDataLen];
|
||||
char* allGrpData = new char[allGrpDataLen]; // msgData + metaData
|
||||
|
||||
meta->serialise(metaData, metaDataLen);
|
||||
|
||||
// copy msg data and meta in allMsgData buffer
|
||||
memcpy(allGrpData, grp->grp.bin_data, grp->grp.bin_len);
|
||||
memcpy(allGrpData+(grp->grp.bin_len), metaData, metaDataLen);
|
||||
|
||||
RsTlvKeySignature adminSign;
|
||||
bool ok = GxsSecurity::getSignature(allGrpData, allGrpDataLen, &privAdminKey, adminSign);
|
||||
|
||||
/* now add private keys to grp */
|
||||
meta->keys.keys[privAdminKey.keyId] = privAdminKey;
|
||||
meta->keys.keys[privPubKey.keyId] = privPubKey;
|
||||
|
||||
// add admin sign to grpMeta
|
||||
meta->signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_ADMIN] = adminSign;
|
||||
|
||||
pqihash hash;
|
||||
|
||||
// get hash of msg data to create msg id
|
||||
hash.addData(grp->grp.bin_data, grp->grp.bin_len);
|
||||
hash.addData(allGrpData, allGrpDataLen);
|
||||
hash.Complete(meta->mGroupId);
|
||||
grp->grpId = meta->mGroupId;
|
||||
|
||||
|
@ -181,12 +204,17 @@ void RsGenExchange::createGroup(RsNxsGrp *grp)
|
|||
privPubKey.TlvClear();
|
||||
pubKey.TlvClear();
|
||||
|
||||
// free the private key for now, as it is not in use
|
||||
// clean up
|
||||
RSA_free(rsa_admin);
|
||||
RSA_free(rsa_admin_pub);
|
||||
|
||||
RSA_free(rsa_publish);
|
||||
RSA_free(rsa_publish_pub);
|
||||
|
||||
delete[] allGrpData;
|
||||
delete[] metaData;
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool RsGenExchange::createMessage(RsNxsMsg* msg)
|
||||
|
@ -198,7 +226,7 @@ bool RsGenExchange::createMessage(RsNxsMsg* msg)
|
|||
metaMap.insert(std::make_pair(id, (RsGxsGrpMetaData*)(NULL)));
|
||||
mDataStore->retrieveGxsGrpMetaData(metaMap);
|
||||
bool ok = true;
|
||||
RSA* rsa_pub = NULL;
|
||||
RSA* rsa_pub = NULL;
|
||||
|
||||
if(!metaMap[id])
|
||||
{
|
||||
|
@ -207,7 +235,7 @@ bool RsGenExchange::createMessage(RsNxsMsg* msg)
|
|||
else
|
||||
{
|
||||
// get publish key
|
||||
RsGxsGrpMetaData* grpMeta = metaMap[id];
|
||||
RsGxsGrpMetaData* grpMeta = metaMap[id];
|
||||
|
||||
// public and shared is publish key
|
||||
RsTlvSecurityKeySet& keys = grpMeta->keys;
|
||||
|
@ -219,70 +247,56 @@ bool RsGenExchange::createMessage(RsNxsMsg* msg)
|
|||
for(; mit != mit_end; mit++)
|
||||
{
|
||||
|
||||
pub_key_found = mit->second.keyFlags & (RSTLV_KEY_DISTRIB_PRIVATE | RSTLV_KEY_TYPE_FULL);
|
||||
pub_key_found = mit->second.keyFlags & (RSTLV_KEY_DISTRIB_PRIVATE | RSTLV_KEY_TYPE_FULL);
|
||||
if(pub_key_found)
|
||||
break;
|
||||
}
|
||||
|
||||
if(pub_key_found)
|
||||
{
|
||||
RsGxsMsgMetaData &meta = *(msg->metaData);
|
||||
|
||||
uint32_t metaDataLen = meta.serial_size();
|
||||
uint32_t allMsgDataLen = metaDataLen + msg->msg.bin_len;
|
||||
char* metaData = new char[metaDataLen];
|
||||
char* allMsgData = new char[allMsgDataLen]; // msgData + metaData
|
||||
|
||||
meta.serialise(metaData, &metaDataLen);
|
||||
|
||||
// copy msg data and meta in allmsgData buffer
|
||||
memcpy(allMsgData, msg->msg.bin_data, msg->msg.bin_len);
|
||||
memcpy(allMsgData+(msg->msg.bin_len), metaData, metaDataLen);
|
||||
|
||||
// private publish key
|
||||
pubKey = &(mit->second);
|
||||
rsa_pub = GxsSecurity::extractPrivateKey(*pubKey);
|
||||
EVP_PKEY *key_pub = EVP_PKEY_new();
|
||||
EVP_PKEY_assign_RSA(key_pub, rsa_pub);
|
||||
|
||||
/* calc and check signature */
|
||||
EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
|
||||
RsTlvKeySignatureSet& signSet = meta.signSet;
|
||||
RsTlvKeySignature pubSign = signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_PUBLISH];
|
||||
|
||||
RsGxsMsgMetaData &meta = *(msg->metaData);
|
||||
GxsSecurity::getSignature(allMsgData, allMsgDataLen, pubKey, pubSign);
|
||||
|
||||
uint32_t metaDataLen = meta.serial_size();
|
||||
uint32_t allMsgDataLen = metaDataLen + msg->msg.bin_len;
|
||||
char* metaData = new char[metaDataLen];
|
||||
char* allMsgData = new char[allMsgDataLen]; // msgData + metaData
|
||||
// get hash of msg data to create msg id
|
||||
pqihash hash;
|
||||
hash.addData(allMsgData, allMsgDataLen);
|
||||
hash.Complete(msg->msgId);
|
||||
|
||||
meta.serialise(metaData, &metaDataLen);
|
||||
// assign msg id to msg meta
|
||||
msg->metaData->mMsgId = msg->msgId;
|
||||
|
||||
// copy msg data and meta in allmsgData buffer
|
||||
memcpy(allMsgData, msg->msg.bin_data, msg->msg.bin_len);
|
||||
memcpy(allMsgData+(msg->msg.bin_len), metaData, metaDataLen);
|
||||
|
||||
ok = EVP_SignInit(mdctx, EVP_sha1()) == 1;
|
||||
ok = EVP_SignUpdate(mdctx, allMsgData, allMsgDataLen) == 1;
|
||||
|
||||
unsigned int siglen = EVP_PKEY_size(key_pub);
|
||||
unsigned char sigbuf[siglen];
|
||||
ok = EVP_SignFinal(mdctx, sigbuf, &siglen, key_pub) == 1;
|
||||
|
||||
//place signature in msg meta
|
||||
|
||||
RsTlvKeySignatureSet& signSet = meta.signSet;
|
||||
RsTlvKeySignature pubSign = signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_PUBLISH];
|
||||
pubSign.signData.setBinData(sigbuf, siglen);
|
||||
pubSign.keyId = pubKey->keyId;
|
||||
|
||||
// get hash of msg data to create msg id
|
||||
pqihash hash;
|
||||
hash.addData(allMsgData, allMsgDataLen);
|
||||
hash.Complete(msg->msgId);
|
||||
|
||||
msg->metaData->mMsgId = msg->msgId;
|
||||
//place signature in msg meta
|
||||
signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_PUBLISH] = pubSign;
|
||||
|
||||
// clean up
|
||||
EVP_MD_CTX_destroy(mdctx);
|
||||
//RSA_free(rsa_pub);
|
||||
EVP_PKEY_free(key_pub);
|
||||
// no need to free rsa key as evp key is considered parent key by SSL
|
||||
|
||||
delete[] metaData;
|
||||
delete[] allMsgData;
|
||||
delete[] metaData;
|
||||
delete[] allMsgData;
|
||||
}
|
||||
else
|
||||
{
|
||||
ok = false;
|
||||
}
|
||||
|
||||
delete grpMeta;
|
||||
delete grpMeta;
|
||||
}
|
||||
|
||||
return ok;
|
||||
|
@ -694,11 +708,11 @@ void RsGenExchange::publishGrps()
|
|||
grpItem->meta.mPublishTs = time(NULL);
|
||||
*(grp->metaData) = grpItem->meta;
|
||||
grp->metaData->mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_ADMIN;
|
||||
createGroup(grp);
|
||||
ok &= createGroup(grp);
|
||||
size = grp->metaData->serial_size();
|
||||
char mData[size];
|
||||
grp->metaData->mGroupId = grp->grpId;
|
||||
ok = grp->metaData->serialise(mData, size);
|
||||
ok &= grp->metaData->serialise(mData, size);
|
||||
grp->meta.setBinData(mData, size);
|
||||
RsGxsGroupId grpId = grp->grpId;
|
||||
mDataAccess->addGroupData(grp);
|
||||
|
|
|
@ -158,7 +158,7 @@ protected:
|
|||
|
||||
/*!
|
||||
* @param grpItem
|
||||
* @deprecated only here to temporarily to testing
|
||||
* @deprecated only here temporarily for testing
|
||||
*/
|
||||
void createDummyGroup(RsGxsGrpItem* grpItem);
|
||||
|
||||
|
@ -231,7 +231,7 @@ public:
|
|||
bool acknowledgeTokenMsg(const uint32_t& token, RsGxsGrpMsgIdPair& msgId);
|
||||
|
||||
/*!
|
||||
* This allows the client service to acknowledge that their grps has \n
|
||||
* This allows the client service to acknowledge that their grps has \n
|
||||
* been created/modified and retrieve the create/modified grp ids
|
||||
* @param token the token related to modification/create request
|
||||
* @param msgIds vector of ids of groups created/modified
|
||||
|
@ -270,20 +270,46 @@ public:
|
|||
/*!
|
||||
* sets the group subscribe flag
|
||||
* @param token this is set to token value associated to this request
|
||||
* @param
|
||||
* @param grpId Id of group whose subscribe file will be changed
|
||||
* @param status
|
||||
* @param mask
|
||||
*/
|
||||
void setGroupSubscribeFlags(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& status, const uint32_t& mask);
|
||||
|
||||
/*!
|
||||
* sets the group subscribe flag
|
||||
* @param token this is set to token value associated to this request
|
||||
* @param grpId Id of group whose subscribe file will be changed
|
||||
* @param status
|
||||
* @param mask
|
||||
*/
|
||||
void setGroupStatusFlags(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& status, const uint32_t& mask);
|
||||
|
||||
/*!
|
||||
* sets the group service string
|
||||
* @param token this is set to token value associated to this request
|
||||
* @param grpId Id of group whose subscribe file will be changed
|
||||
* @param servString
|
||||
*/
|
||||
void setGroupServiceString(uint32_t& token, const RsGxsGroupId& grpId, const std::string& servString);
|
||||
|
||||
/*!
|
||||
* sets the msg status flag
|
||||
* @param token this is set to token value associated to this request
|
||||
* @param grpId Id of group whose subscribe file will be changed
|
||||
* @param status
|
||||
* @param mask Mask to apply to status flag
|
||||
*/
|
||||
void setMsgStatusFlags(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, const uint32_t& status, const uint32_t& mask);
|
||||
|
||||
/*!
|
||||
* sets the message service string
|
||||
* @param token this is set to token value associated to this request
|
||||
* @param msgId Id of message whose service string will be changed
|
||||
* @param servString The service string to set msg to
|
||||
*/
|
||||
void setMsgServiceString(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, const std::string& servString );
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
/** Notifications **/
|
||||
|
@ -324,7 +350,20 @@ private:
|
|||
*/
|
||||
void processGrpMetaChanges();
|
||||
|
||||
void createGroup(RsNxsGrp* grp);
|
||||
/*!
|
||||
* This completes the creation of an instance on RsNxsGrp
|
||||
* by assigning it a groupId and signature via SHA1 and EVP_sign respectively
|
||||
* @param grp Nxs group to create
|
||||
*/
|
||||
bool createGroup(RsNxsGrp* grp);
|
||||
|
||||
/*!
|
||||
* This completes the creation of an instance on RsNxsMsg
|
||||
* by assigning it a groupId and signature via SHA1 and EVP_sign respectively
|
||||
* What signatures are calculated are based on the authentication policy
|
||||
* of the service
|
||||
* @param msg the Nxs message to create
|
||||
*/
|
||||
bool createMessage(RsNxsMsg* msg);
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue