moved signature validation and encryption one level up into p3IdService. Added timestamp for GXS identities and auto-removal after 7 days. Updated display in IdDialog

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@8015 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2015-03-14 14:33:23 +00:00
parent b46c3b4852
commit 48ea291d95
24 changed files with 944 additions and 415 deletions

View File

@ -528,10 +528,8 @@ void DistantChatService::handleRecvDHPublicKey(RsChatDHPublicKeyItem *item)
RsIdentityDetails details ;
RsGxsId senders_id( item->signature.keyId ) ;
mIdService->getIdDetails(senders_id,details);
for(int i=0;i<6;++i)
if(!mIdService->getKey(senders_id,signature_key) || signature_key.keyData.bin_data == NULL)
if(!mGixs->getKey(senders_id,signature_key) || signature_key.keyData.bin_data == NULL)
{
#ifdef DEBUG_DISTANT_CHAT
std::cerr << " Cannot get key. Waiting for caching. try " << i << "/6" << std::endl;
@ -561,6 +559,28 @@ void DistantChatService::handleRecvDHPublicKey(RsChatDHPublicKeyItem *item)
std::cerr << " (EE) Signature was verified and it doesn't check! This is a security issue!" << std::endl;
return ;
}
#ifdef SUSPENDED
if(signature_key.keyId != item->gxs_key.keyId)
{
std::cerr << "(EE) DH session key is signed by an ID that is not the ID of the key provided inthe packet. Refusing distant chat with this peer." << std::endl;
return;
}
uint32_t error_status ;
if(!mGixs->validateData((unsigned char*)data,pubkey_size,item->signature,true,error_status))
{
switch(error_status)
{
case RsGixs::RS_GIXS_ERROR_KEY_NOT_AVAILABLE: std::cerr << "(EE) Key is not available. Cannot verify." << std::endl;
break ;
case RsGixs::RS_GIXS_ERROR_SIGNATURE_MISMATCH: std::cerr << "(EE) Signature mismatch. Spoofing/MITM?." << std::endl;
break ;
default: break ;
}
return ;
}
#endif
#ifdef DEBUG_DISTANT_CHAT
std::cerr << " Signature checks! Sender's ID = " << senders_id << std::endl;
std::cerr << " Computing AES key" << std::endl;
@ -652,12 +672,38 @@ bool DistantChatService::locked_sendDHPublicKey(const DH *dh,const RsGxsId& own_
dhitem->public_key = BN_dup(dh->pub_key) ;
// we should also sign the data and check the signature on the other end.
// we should also sign the data and check the signature on the other end.
//
RsTlvKeySignature signature ;
RsTlvSecurityKey signature_key ;
RsTlvSecurityKey signature_key_public ;
uint32_t error_status ;
uint32_t size = BN_num_bytes(dhitem->public_key) ;
unsigned char *data = (unsigned char *)malloc(size) ;
BN_bn2bin(dhitem->public_key, data) ;
if(!mGixs->signData((unsigned char*)data,size,own_gxs_id,signature,error_status))
{
switch(error_status)
{
case RsGixs::RS_GIXS_ERROR_KEY_NOT_AVAILABLE: std::cerr << "(EE) Key is not available. Cannot sign." << std::endl;
break ;
default: std::cerr << "(EE) Unknown error when signing" << std::endl;
break ;
}
free(data) ;
return false;
}
free(data) ;
if(!mGixs->getKey(own_gxs_id,signature_key_public))
{
std::cerr << " (EE) Could not retrieve own public key for ID = " << own_gxs_id << ". Giging up sending DH session params." << std::endl;
return false ;
}
#ifdef SUSPENDED
#ifdef DEBUG_DISTANT_CHAT
std::cerr << " Getting key material for signature with GXS id " << own_gxs_id << std::endl;
#endif
@ -699,11 +745,12 @@ bool DistantChatService::locked_sendDHPublicKey(const DH *dh,const RsGxsId& own_
{
std::cerr << " (EE) Cannot sign for id " << own_gxs_id << ". Signature call failed." << std::endl;
return false ;
}
}
#endif
free(data) ;
assert(!(signature_key_public.keyFlags & RSTLV_KEY_TYPE_FULL)) ;
dhitem->signature = signature ;
dhitem->signature = signature ;
dhitem->gxs_key = signature_key_public ;
dhitem->PeerId(RsPeerId(virtual_peer_id)) ; // special case for DH items
@ -890,7 +937,7 @@ bool DistantChatService::initiateDistantChatConnexion(const RsGxsId& to_gxs_id,c
// should be a parameter.
std::list<RsGxsId> lst ;
mIdService->getOwnIds(lst) ;
mGixs->getOwnIds(lst) ;
bool found = false ;
for(std::list<RsGxsId>::const_iterator it = lst.begin();it!=lst.end();++it)

View File

@ -29,16 +29,15 @@
#include <chat/rschatitems.h>
#include <retroshare/rsmsgs.h>
class p3IdService ;
class RsGixs ;
static const uint32_t DISTANT_CHAT_AES_KEY_SIZE = 16 ;
class DistantChatService: public RsTurtleClientService
{
public:
DistantChatService(p3IdService *pids)
: mIdService(pids), mDistantChatMtx("distant chat")
DistantChatService(RsGixs *pids)
: mGixs(pids), mDistantChatMtx("distant chat")
{
mTurtle = NULL ;
}
@ -129,7 +128,7 @@ private:
static TurtleFileHash hashFromVirtualPeerId(const DistantChatPeerId& peerId) ; // converts IDs so that we can talk to RsPeerId from outside
p3turtle *mTurtle ;
p3IdService *mIdService ;
RsGixs *mGixs ;
RsMutex mDistantChatMtx ;
};

View File

@ -35,7 +35,7 @@
#include "retroshare/rsiface.h"
#include "retroshare/rsidentity.h"
#include "rsserver/p3face.h"
#include "gxs/gxssecurity.h"
#include "gxs/rsgixs.h"
#include "services/p3idservice.h"
//#define DEBUG_CHAT_LOBBIES 1
@ -62,8 +62,8 @@ static const uint32_t MAX_MESSAGES_PER_SECONDS_PERIOD = 10 ; // duration win
#define EXTRACT_PRIVACY_FLAGS(flags) (ChatLobbyFlags(flags.toUInt32()) & RS_CHAT_LOBBY_FLAGS_PUBLIC)
DistributedChatService::DistributedChatService(uint32_t serv_type,p3ServiceControl *sc,p3HistoryMgr *hm, p3IdService *is)
: mServType(serv_type),mDistributedChatMtx("Distributed Chat"), mServControl(sc), mHistMgr(hm),mIdService(is)
DistributedChatService::DistributedChatService(uint32_t serv_type,p3ServiceControl *sc,p3HistoryMgr *hm, RsGixs *is)
: mServType(serv_type),mDistributedChatMtx("Distributed Chat"), mServControl(sc), mHistMgr(hm),mGixs(is)
{
_time_shift_average = 0.0f ;
_should_reset_lobby_counts = false ;
@ -80,7 +80,21 @@ void DistributedChatService::flush()
if(last_clean_time_lobby + LOBBY_CACHE_CLEANING_PERIOD < now)
{
cleanLobbyCaches() ;
last_clean_time_lobby = now ;
last_clean_time_lobby = now ;
// also make sure that the default identity is not null
if(_default_identity.isNull())
{
std::list<RsGxsId> ids ;
mGixs->getOwnIds(ids) ;
if(!ids.empty())
{
_default_identity = ids.front() ;
triggerConfigSave() ;
}
}
}
if(last_req_chat_lobby_list + LOBBY_LIST_AUTO_UPDATE_TIME < now)
{
@ -156,7 +170,7 @@ bool DistributedChatService::checkSignature(RsChatLobbyBouncingObject *obj,const
// network pre-request key to allow message authentication.
mIdService->requestKey(obj->signature.keyId,peer_list);
mGixs->requestKey(obj->signature.keyId,peer_list);
uint32_t size = obj->signed_serial_size() ;
unsigned char *memory = (unsigned char *)malloc(size) ;
@ -173,11 +187,29 @@ bool DistributedChatService::checkSignature(RsChatLobbyBouncingObject *obj,const
return false ;
}
uint32_t error_status ;
if(!mGixs->validateData(memory,obj->signed_serial_size(),obj->signature,false,error_status))
{
switch(error_status)
{
case RsGixs::RS_GIXS_ERROR_KEY_NOT_AVAILABLE: std::cerr << "(EE) Key is not available. Cannot verify." << std::endl;
break ;
case RsGixs::RS_GIXS_ERROR_SIGNATURE_MISMATCH: std::cerr << "(EE) Signature mismatch. Spoofing/MITM?." << std::endl;
break ;
default: break ;
}
free(memory) ;
return false;
}
free(memory) ;
#ifdef SUSPENDED
RsTlvSecurityKey signature_public_key ;
if(!mIdService->getKey(obj->signature.keyId,signature_public_key) || signature_public_key.keyData.bin_data == NULL)
{
std::cerr << " (EE) Could not retrieve public key for ID = " << obj->signature.keyId << ". Giging up sending signed lobby message." << std::endl;
std::cerr << " (EE) Could not retrieve public key for ID = " << obj->signature.keyId << ". Lobby message is not authenticated." << std::endl;
free(memory) ;
// no public key. We continue. If the lobby has strict authentication, we should return false.
@ -200,6 +232,7 @@ bool DistributedChatService::checkSignature(RsChatLobbyBouncingObject *obj,const
return false ;
}
free(memory) ;
#endif
#ifdef DEBUG_CHAT_LOBBIES
std::cerr << " signature: CHECKS" << std::endl;
@ -898,6 +931,22 @@ bool DistributedChatService::locked_initLobbyBouncableObject(const ChatLobbyId&
return false ;
}
uint32_t error_status ;
if(!mGixs->signData(memory,size,lobby.gxs_id,item.signature,error_status))
{
switch(error_status)
{
case RsGixs::RS_GIXS_ERROR_KEY_NOT_AVAILABLE: std::cerr << "(EE) Cannot sign item: key not available for ID " << lobby.gxs_id << std::endl;
break ;
default: std::cerr << "(EE) Cannot sign item: unknown error" << std::endl;
break ;
}
free(memory) ;
return false ;
}
#ifdef SUSPENDED
RsTlvSecurityKey signature_private_key ;
int i ;
@ -930,22 +979,22 @@ bool DistributedChatService::locked_initLobbyBouncableObject(const ChatLobbyId&
std::cerr << "(EE) Cannot sign message item. " << std::endl;
return false ;
}
#endif
#ifdef DEBUG_CHAT_LOBBIES
std::cerr << " signature done." << std::endl;
// check signature
RsTlvSecurityKey public_key ;
GxsSecurity::extractPublicKey(signature_private_key,public_key) ;
if(!GxsSecurity::validateSignature((const char *)memory,item.signed_serial_size(),public_key,item.signature))
if(!mGixs->validateSignature((const char *)memory,item.signed_serial_size(),lobby.gxs_id,item.signature,true,error_status))
{
std::cerr << "(EE) Cannot sign message item. " << std::endl;
std::cerr << "(EE) Cannot check message item. " << std::endl;
return false ;
}
std::cerr << " signature checks!" << std::endl;
std::cerr << " Item dump:" << std::endl;
item.print(std::cerr,2) ;
#endif
free(memory) ;
}
return true ;
@ -1272,6 +1321,7 @@ bool DistributedChatService::acceptLobbyInvite(const ChatLobbyId& lobby_id,const
return true ;
}
#ifdef SUSPENDED
RsIdentityDetails details ;
// This is our own identity. We force the loading from the cache.
@ -1281,6 +1331,7 @@ bool DistributedChatService::acceptLobbyInvite(const ChatLobbyId& lobby_id,const
break ;
else
usleep(500*1000) ;
#endif
#ifdef DEBUG_CHAT_LOBBIES
std::cerr << " Creating new Lobby entry." << std::endl;
@ -1364,6 +1415,7 @@ void DistributedChatService::denyLobbyInvite(const ChatLobbyId& lobby_id)
bool DistributedChatService::joinVisibleChatLobby(const ChatLobbyId& lobby_id,const RsGxsId& gxs_id)
{
#ifdef SUSPENDED
RsIdentityDetails details ;
// This is our own identity. We force the loading from the cache.
@ -1379,6 +1431,13 @@ bool DistributedChatService::joinVisibleChatLobby(const ChatLobbyId& lobby_id,co
std::cerr << "(EE) Cannot lobby using gxs id " << gxs_id << std::endl;
return false ;
}
#endif
if(!mGixs->isOwnId(gxs_id))
{
std::cerr << "(EE) Cannot lobby using gxs id " << gxs_id << std::endl;
return false ;
}
#ifdef DEBUG_CHAT_LOBBIES
std::cerr << "Joining public chat lobby " << std::hex << lobby_id << std::dec << std::endl;
#endif

View File

@ -46,11 +46,12 @@ class RsChatLobbyUnsubscribeItem ;
class RsChatItem ;
class RsChatMsgItem ;
class RsGixs ;
class DistributedChatService
{
public:
DistributedChatService(uint32_t service_type,p3ServiceControl *sc,p3HistoryMgr *hm,p3IdService *is) ;
DistributedChatService(uint32_t service_type,p3ServiceControl *sc,p3HistoryMgr *hm,RsGixs *is) ;
virtual ~DistributedChatService() {}
@ -164,5 +165,5 @@ class DistributedChatService
p3ServiceControl *mServControl;
p3HistoryMgr *mHistMgr;
p3IdService *mIdService ;
RsGixs *mGixs ;
};

View File

@ -186,8 +186,8 @@
#include "util/rsprint.h"
#include "serialiser/rsconfigitems.h"
#include "services/p3idservice.h"
#include "gxs/gxssecurity.h"
#include "turtle/p3turtle.h"
#include "gxs/rsgixs.h"
#include "p3grouter.h"
#include "grouteritems.h"
@ -207,8 +207,8 @@ static const uint32_t MAX_RECEIPT_WAIT_TIME = 20 ; // wait for at
const std::string p3GRouter::SERVICE_INFO_APP_NAME = "Global Router" ;
p3GRouter::p3GRouter(p3ServiceControl *sc, p3IdService *is)
: p3Service(), p3Config(), mServiceControl(sc), mIdService(is), grMtx("GRouter")
p3GRouter::p3GRouter(p3ServiceControl *sc, RsGixs *is)
: p3Service(), p3Config(), mServiceControl(sc), mGixs(is), grMtx("GRouter")
{
addSerialType(new RsGRouterSerialiser()) ;
@ -1211,6 +1211,8 @@ bool p3GRouter::encryptDataItem(RsGRouterGenericDataItem *item,const RsGxsId& de
std::cerr << " Encrypting data for key " << destination_key << std::endl;
std::cerr << " Decrypted size = " << item->data_size << std::endl;
#endif
#ifdef SUSPENDED
RsTlvSecurityKey encryption_key ;
// get the key, and let the cache find it.
@ -1234,6 +1236,19 @@ bool p3GRouter::encryptDataItem(RsGRouterGenericDataItem *item,const RsGxsId& de
std::cerr << " (EE) Encryption failed." << std::endl;
return false ;
}
#endif
uint8_t *encrypted_data =NULL;
uint32_t encrypted_size =0;
uint32_t error_status ;
if(!mGixs->encryptData(item->data_bytes,item->data_size,encrypted_data,encrypted_size,destination_key,true,error_status))
{
std::cerr << "(EE) Cannot encrypt: " ;
if(error_status == RsGixs::RS_GIXS_ERROR_KEY_NOT_AVAILABLE) std::cerr << " key not available for ID = " << destination_key << std::endl;
if(error_status == RsGixs::RS_GIXS_ERROR_UNKNOWN ) std::cerr << " unknown error for ID = " << destination_key << std::endl;
return false ;
}
free(item->data_bytes) ;
item->data_bytes = encrypted_data ;
@ -1255,6 +1270,19 @@ bool p3GRouter::decryptDataItem(RsGRouterGenericDataItem *item)
std::cerr << " decrypting data for key " << item->destination_key << std::endl;
std::cerr << " encrypted size = " << item->data_size << std::endl;
#endif
uint8_t *decrypted_data =NULL;
uint32_t decrypted_size =0;
uint32_t error_status ;
if(mGixs->decryptData(item->data_bytes,item->data_size,decrypted_data,decrypted_size,item->destination_key,error_status))
{
if(error_status == RsGixs::RS_GIXS_ERROR_KEY_NOT_AVAILABLE)
std::cerr << "(EE) Cannot decrypt incoming message. Key " << item->destination_key << " unknown." << std::endl;
else
std::cerr << "(EE) Cannot decrypt incoming message. Unknown error. " << std::endl;
}
#ifdef SUSPENDED
RsTlvSecurityKey encryption_key ;
// get the key, and let the cache find it.
@ -1278,6 +1306,7 @@ bool p3GRouter::decryptDataItem(RsGRouterGenericDataItem *item)
std::cerr << " (EE) Decryption failed." << std::endl;
return false ;
}
#endif
free(item->data_bytes) ;
item->data_bytes = decrypted_data ;
@ -1303,12 +1332,12 @@ bool p3GRouter::signDataItem(RsGRouterAbstractMsgItem *item,const RsGxsId& signi
uint32_t data_size = item->signed_data_size() ;
uint8_t *data = (uint8_t*)malloc(data_size) ;
if(!item->serialise_signed_data(data,data_size))
throw std::runtime_error("Cannot serialise signed data.") ;
if(data == NULL)
throw std::runtime_error("Cannot allocate memory for signing data.") ;
if(!item->serialise_signed_data(data,data_size))
throw std::runtime_error("Cannot serialise signed data.") ;
#ifdef SUSPENDED
if(!mIdService->getPrivateKey(signing_id,signature_key))
throw std::runtime_error("Cannot get signature key for id " + signing_id.toStdString()) ;
@ -1319,6 +1348,11 @@ bool p3GRouter::signDataItem(RsGRouterAbstractMsgItem *item,const RsGxsId& signi
if(!GxsSecurity::getSignature((char *)data,data_size,signature_key,item->signature))
throw std::runtime_error("Cannot sign for id " + signing_id.toStdString() + ". Signature call failed.") ;
#endif
uint32_t error_status ;
if(!mGixs->signData(data,data_size,signing_id,item->signature,error_status))
throw std::runtime_error("Cannot sign for id " + signing_id.toStdString() + ". Signature call failed.") ;
#ifdef GROUTER_DEBUG
std::cerr << "Created signature for data hash: " << RsDirUtil::sha1sum(data,data_size) << " and key id=" << signing_id << std::endl;
@ -1331,6 +1365,7 @@ bool p3GRouter::signDataItem(RsGRouterAbstractMsgItem *item,const RsGxsId& signi
std::cerr << " signing failed. Error: " << e.what() << std::endl;
if(data != NULL)
free(data) ;
item->signature.TlvClear() ;
return false ;
}
@ -1349,6 +1384,7 @@ bool p3GRouter::verifySignedDataItem(RsGRouterAbstractMsgItem *item)
if(!item->serialise_signed_data(data,data_size))
throw std::runtime_error("Cannot serialise signed data.") ;
#ifdef SUSPENDED
for(int i=0;i<6;++i)
if(!mIdService->getKey(item->signature.keyId,signature_key) || signature_key.keyData.bin_data == NULL)
{
@ -1368,6 +1404,22 @@ bool p3GRouter::verifySignedDataItem(RsGRouterAbstractMsgItem *item)
if(!GxsSecurity::validateSignature((char*)data,data_size,signature_key,item->signature))
throw std::runtime_error("Signature was verified and it doesn't check! This is a security issue!") ;
#endif
uint32_t error_status ;
if(!mGixs->validateData(data,data_size,item->signature,true,error_status))
{
switch(error_status)
{
case RsGixs::RS_GIXS_ERROR_KEY_NOT_AVAILABLE: std::cerr << "(EE) Key is not available. Cannot verify." << std::endl;
break ;
case RsGixs::RS_GIXS_ERROR_SIGNATURE_MISMATCH: std::cerr << "(EE) Signature mismatch. Spoofing/Corrupted/MITM?." << std::endl;
break ;
default: break ;
}
free(data) ;
return false;
}
free(data) ;
return true ;

View File

@ -49,7 +49,7 @@ static const uint32_t RS_GROUTER_DATA_FLAGS_ENCRYPTED = 0x0001 ;
class p3LinkMgr ;
class p3turtle ;
class p3IdService ;
class RsGixs ;
class RsGRouterItem ;
class RsGRouterGenericDataItem ;
class RsGRouterTransactionChunkItem ;
@ -79,7 +79,7 @@ public:
class p3GRouter: public RsGRouter, public RsTurtleClientService, public p3Service, public p3Config
{
public:
p3GRouter(p3ServiceControl *sc,p3IdService *is) ;
p3GRouter(p3ServiceControl *sc,RsGixs *is) ;
//===================================================//
// Router clients business //
@ -298,7 +298,7 @@ private:
//
p3ServiceControl *mServiceControl ;
p3turtle *mTurtle ;
p3IdService *mIdService ;
RsGixs *mGixs ;
// Multi-thread protection mutex.
//

View File

@ -338,7 +338,7 @@ bool GxsSecurity::validateNxsMsg(RsNxsMsg& msg, RsTlvKeySignature& sign, RsTlvSe
return false;
}
bool GxsSecurity::encrypt(uint8_t *& out, int & outlen, const uint8_t *in, int inlen, const RsTlvSecurityKey& key)
bool GxsSecurity::encrypt(uint8_t *& out, uint32_t &outlen, const uint8_t *in, uint32_t inlen, const RsTlvSecurityKey& key)
{
#ifdef DISTRIB_DEBUG
std::cerr << "GxsSecurity::encrypt() " << std::endl;
@ -441,7 +441,7 @@ bool GxsSecurity::encrypt(uint8_t *& out, int & outlen, const uint8_t *in, int i
}
bool GxsSecurity::decrypt(uint8_t *& out, int & outlen, const uint8_t *in, int inlen, const RsTlvSecurityKey& key)
bool GxsSecurity::decrypt(uint8_t *& out, uint32_t & outlen, const uint8_t *in, uint32_t inlen, const RsTlvSecurityKey& key)
{
#ifdef DISTRIB_DEBUG
@ -519,7 +519,7 @@ bool GxsSecurity::decrypt(uint8_t *& out, int & outlen, const uint8_t *in, int i
return false;
}
outlen += out_currOffset;
outlen = out_currOffset;
if(!EVP_OpenFinal(&ctx, (unsigned char*)out + out_currOffset, &out_currOffset))
{

View File

@ -63,7 +63,7 @@ class GxsSecurity
*@param in
*@param inlen
*/
static bool encrypt(uint8_t *&out, int &outlen, const uint8_t *in, int inlen, const RsTlvSecurityKey& key) ;
static bool encrypt(uint8_t *&out, uint32_t &outlen, const uint8_t *in, uint32_t inlen, const RsTlvSecurityKey& key) ;
/**
* Decrypts data using evelope decryption (taken from open ssl's evp_sealinit )
@ -74,7 +74,7 @@ class GxsSecurity
* @param inlen
* @return false if encryption failed
*/
static bool decrypt(uint8_t *&out, int &outlen, const uint8_t *in, int inlen, const RsTlvSecurityKey& key) ;
static bool decrypt(uint8_t *&out, uint32_t &outlen, const uint8_t *in, uint32_t inlen, const RsTlvSecurityKey& key) ;
/*!
* uses grp signature to check if group has been

View File

@ -919,7 +919,9 @@ int RsGenExchange::validateGrp(RsNxsGrp* grp)
{
RsTlvKeySignature sign = metaData.signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_IDENTITY];
idValidate = GxsSecurity::validateNxsGrp(*grp, sign, authorKey);
idValidate = GxsSecurity::validateNxsGrp(*grp, sign, authorKey);
mGixs->timeStampKey(metaData.mAuthorId) ;
}
else
{
@ -2887,7 +2889,8 @@ bool RsGenExchange::updateValid(RsGxsGrpMetaData& oldGrpMeta, RsNxsGrp& newGrp)
// also check this is the latest published group
bool latest = newGrp.metaData->mPublishTs > oldGrpMeta.mPublishTs;
return GxsSecurity::validateNxsGrp(newGrp, adminSign, keyMit->second) && latest;
mGixs->timeStampKey(newGrp.metaData->mAuthorId) ;
return GxsSecurity::validateNxsGrp(newGrp, adminSign, keyMit->second) && latest;
}
void RsGenExchange::setGroupReputationCutOff(uint32_t& token, const RsGxsGroupId& grpId, int CutOff)

View File

@ -99,30 +99,39 @@
typedef RsPeerId PeerId; // SHOULD BE REMOVED => RsPeerId (SSLID)
typedef PGPIdType RsPgpId;
//
//// External Interface -
//class RsIdentityService
//{
// enum IdentityType { Pseudonym, Signed, Anonymous };
//
// virtual bool loadId(const GxsId &id) = 0;
//
// virtual bool getNickname(const GxsId &id, std::string &nickname) = 0;
//
// virtual bool createKey(RsGixsProfile& profile, uint32_t type) = 0; /* fills in mKeyId, and signature */
//
// virtual RsGixsProfile* getProfile(const KeyRef& keyref) = 0;
//
// // modify reputation.
//
//};
/* Identity Interface for GXS Message Verification.
*/
class RsGixs
{
public:
static const uint32_t RS_GIXS_ERROR_NO_ERROR = 0x0000 ;
static const uint32_t RS_GIXS_ERROR_UNKNOWN = 0x0001 ;
static const uint32_t RS_GIXS_ERROR_KEY_NOT_AVAILABLE = 0x0002 ;
static const uint32_t RS_GIXS_ERROR_SIGNATURE_MISMATCH = 0x0003 ;
/* Performs/validate a signature with the given key ID. The key must be available, otherwise the signature error
* will report it. Each time a key is used to validate a signature, its usage timestamp is updated.
*
* If force_load is true, the key will be forced loaded from the cache. If not, uncached keys will return
* with error_status=RS_GIXS_SIGNATURE_ERROR_KEY_NOT_AVAILABLE, but will likely be cached on the next call.
*/
virtual bool signData(const uint8_t *data,uint32_t data_size,const RsGxsId& signer_id,RsTlvKeySignature& signature,uint32_t& signing_error) = 0 ;
virtual bool validateData(const uint8_t *data,uint32_t data_size,const RsTlvKeySignature& signature,bool force_load,uint32_t& signing_error) = 0 ;
virtual bool encryptData(const uint8_t *clear_data,uint32_t clear_data_size,uint8_t *& encrypted_data,uint32_t& encrypted_data_size,const RsGxsId& encryption_key_id,bool force_load,uint32_t& encryption_error) = 0 ;
virtual bool decryptData(const uint8_t *encrypted_data,uint32_t encrypted_data_size,uint8_t *& clear_data,uint32_t& clear_data_size,const RsGxsId& encryption_key_id,uint32_t& encryption_error) = 0 ;
// virtual bool getPublicKey(const RsGxsId &id, RsTlvSecurityKey &key) = 0;
virtual void getOwnIds(std::list<RsGxsId>& ids) = 0;
virtual bool isOwnId(const RsGxsId& key_id) = 0 ;
virtual void timeStampKey(const RsGxsId& key_id) = 0 ;
// virtual void networkRequestPublicKey(const RsGxsId& key_id,const std::list<RsPeerId>& peer_ids) = 0 ;
// Key related interface - used for validating msgs and groups.
/*!
* Use to query a whether given key is available by its key reference
@ -157,7 +166,8 @@ public:
*/
virtual bool getKey(const RsGxsId &id, RsTlvSecurityKey &key) = 0;
virtual bool getPrivateKey(const RsGxsId &id, RsTlvSecurityKey &key) = 0; // For signing outgoing messages.
#ifdef SUSPENDED
#endif
};

View File

@ -109,6 +109,7 @@ class RsGxsIdGroup
// Avatar
RsGxsImage mImage ;
time_t mLastUsageTS ;
// Not Serialised - for GUI's benefit.
bool mPgpKnown;
@ -153,30 +154,33 @@ class RsRecognTagDetails
class RsIdentityDetails
{
public:
RsIdentityDetails()
:mIsOwnId(false), mPgpLinked(false), mPgpKnown(false),
mReputation() { return; }
public:
RsIdentityDetails()
:mIsOwnId(false), mPgpLinked(false), mPgpKnown(false),
mReputation() { return; }
RsGxsId mId;
RsGxsId mId;
// identity details.
std::string mNickname;
bool mIsOwnId;
// identity details.
std::string mNickname;
bool mIsOwnId;
// PGP Stuff.
bool mPgpLinked;
bool mPgpKnown;
RsPgpId mPgpId;
// PGP Stuff.
bool mPgpLinked;
bool mPgpKnown;
RsPgpId mPgpId;
// Recogn details.
std::list<RsRecognTag> mRecognTags;
// Recogn details.
std::list<RsRecognTag> mRecognTags;
// reputation details.
// reputation details.
GxsReputation mReputation;
// avatar
RsGxsImage mAvatar ;
// last usage
time_t mLastUsageTS ;
};

View File

@ -1476,7 +1476,7 @@ int RsServer::StartupRetroShare()
pqih -> addService(mDisc,true);
pqih -> addService(msgSrv,true);
pqih -> addService(chatSrv,true);
pqih ->addService(mStatusSrv,true);
pqih -> addService(mStatusSrv,true);
// set interfaces for plugins
@ -1592,6 +1592,7 @@ int RsServer::StartupRetroShare()
#ifdef ENABLE_GROUTER
mConfigMgr->addConfiguration("grouter.cfg", gr);
#endif
mConfigMgr->addConfiguration("identity.cfg", mGxsIdService);
#ifdef RS_USE_BITDHT
mConfigMgr->addConfiguration("bitdht.cfg", mBitDht);

View File

@ -44,8 +44,9 @@ uint32_t RsGxsCircleSerialiser::size(RsItem *item)
else if((snap_item = dynamic_cast<RsGxsCircleMsgItem*>(item)) != NULL)
{
return sizeGxsCircleMsgItem(snap_item);
}
return NULL;
}
else
return 0 ;
}
bool RsGxsCircleSerialiser::serialise(RsItem *item, void *data, uint32_t *size)

View File

@ -33,102 +33,61 @@
#define GXSID_DEBUG 1
uint32_t RsGxsIdSerialiser::size(RsItem *item)
{
RsGxsIdGroupItem* grp_item = NULL;
#if 0
RsGxsIdOpinionItem* op_item = NULL;
RsGxsIdCommentItem* com_item = NULL;
#endif
if((grp_item = dynamic_cast<RsGxsIdGroupItem*>(item)) != NULL)
{
return sizeGxsIdGroupItem(grp_item);
}
#if 0
else if((op_item = dynamic_cast<RsGxsIdOpinionItem*>(item)) != NULL)
{
return sizeGxsIdOpinionItem(op_item);
}
else if((com_item = dynamic_cast<RsGxsIdCommentItem*>(item)) != NULL)
{
return sizeGxsIdCommentItem(com_item);
}
#endif
std::cerr << "RsGxsIdSerialiser::size() ERROR invalid item" << std::endl;
return 0;
}
bool RsGxsIdSerialiser::serialise(RsItem *item, void *data, uint32_t *size)
{
RsGxsIdGroupItem* grp_item = NULL;
#if 0
RsGxsIdOpinionItem* op_item = NULL;
RsGxsIdCommentItem* com_item = NULL;
#endif
if((grp_item = dynamic_cast<RsGxsIdGroupItem*>(item)) != NULL)
{
return serialiseGxsIdGroupItem(grp_item, data, size);
}
#if 0
else if((op_item = dynamic_cast<RsGxsIdOpinionItem*>(item)) != NULL)
{
return serialiseGxsIdOpinionItem(op_item, data, size);
}
else if((com_item = dynamic_cast<RsGxsIdCommentItem*>(item)) != NULL)
{
return serialiseGxsIdCommentItem(com_item, data, size);
}
#endif
std::cerr << "RsGxsIdSerialiser::serialise() ERROR invalid item" << std::endl;
return false;
}
RsItem* RsGxsIdSerialiser::deserialise(void* data, uint32_t* size)
{
/* get the type and size */
uint32_t rstype = getRsItemId(data);
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
(RS_SERVICE_GXS_TYPE_GXSID != getRsItemService(rstype)))
{
return NULL; /* wrong type */
}
switch(getRsItemSubType(rstype))
{
case RS_PKT_SUBTYPE_GXSID_GROUP_ITEM:
return deserialiseGxsIdGroupItem(data, size);
break;
/* get the type and size */
uint32_t rstype = getRsItemId(data);
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || (RS_SERVICE_GXS_TYPE_GXSID != getRsItemService(rstype)))
return NULL; /* wrong type */
switch(getRsItemSubType(rstype))
{
case RS_PKT_SUBTYPE_GXSID_GROUP_ITEM: return deserialise_GxsIdGroupItem(data, size);
case RS_PKT_SUBTYPE_GXSID_LOCAL_INFO_ITEM: return deserialise_GxsIdLocalInfoItem(data, size);
#if 0
case RS_PKT_SUBTYPE_GXSID_OPINION_ITEM:
return deserialiseGxsIdOpinionItem(data, size);
break;
case RS_PKT_SUBTYPE_GXSID_COMMENT_ITEM:
return deserialiseGxsIdCommentItem(data, size);
break;
case RS_PKT_SUBTYPE_GXSID_OPINION_ITEM: return deserialise_GxsIdOpinionItem(data, size);
case RS_PKT_SUBTYPE_GXSID_COMMENT_ITEM: return deserialise_GxsIdCommentItem(data, size);
#endif
default:
default:
#ifdef GXSID_DEBUG
std::cerr << "RsGxsIdSerialiser::deserialise(): unknown subtype";
std::cerr << std::endl;
std::cerr << "RsGxsIdSerialiser::deserialise(): unknown subtype";
std::cerr << std::endl;
#endif
break;
}
return NULL;
break;
}
return NULL;
}
bool RsGxsIdItem::serialise_header(void *data,uint32_t& pktsize,uint32_t& tlvsize, uint32_t& offset)
{
tlvsize = serial_size() ;
offset = 0;
if (pktsize < tlvsize)
return false; /* not enough space */
pktsize = tlvsize;
if(!setRsItemHeader(data, tlvsize, PacketId(), tlvsize))
{
std::cerr << "RsItem::serialise_header(): ERROR. Not enough size!" << std::endl;
return false ;
}
offset += 8;
return true ;
}
/*****************************************************************************************/
/*****************************************************************************************/
/*****************************************************************************************/
void RsGxsIdLocalInfoItem::clear()
{
mTimeStamps.clear() ;
}
void RsGxsIdGroupItem::clear()
{
mPgpIdHash.clear();
@ -137,7 +96,27 @@ void RsGxsIdGroupItem::clear()
mRecognTags.clear();
mImage.TlvClear();
}
uint32_t RsGxsIdLocalInfoItem::serial_size()
{
uint32_t s = 8 ; // header
s += 4 ; // number of items
s += mTimeStamps.size() * (RsGxsId::SIZE_IN_BYTES + 8) ;
return s;
}
std::ostream& RsGxsIdLocalInfoItem::print(std::ostream& out, uint16_t indent)
{
printRsItemBase(out, "RsGxsIdLocalInfoItem", indent);
uint16_t int_Indent = indent + 2;
// convert from binary to hex.
for(std::map<RsGxsId,time_t>::const_iterator it(mTimeStamps.begin());it!=mTimeStamps.end();++it)
out << it->first << " : " << it->second << std::endl;
printRsItemEnd(out ,"RsGxsIdLocalInfoItem", indent);
return out;
}
std::ostream& RsGxsIdGroupItem::print(std::ostream& out, uint16_t indent)
{
printRsItemBase(out, "RsGxsIdGroupItem", indent);
@ -167,71 +146,88 @@ std::ostream& RsGxsIdGroupItem::print(std::ostream& out, uint16_t indent)
}
uint32_t RsGxsIdSerialiser::sizeGxsIdGroupItem(RsGxsIdGroupItem *item)
uint32_t RsGxsIdGroupItem::serial_size()
{
uint32_t s = 8; // header
s += Sha1CheckSum::SIZE_IN_BYTES;
s += GetTlvStringSize(item->mPgpIdSign);
s += GetTlvStringSize(mPgpIdSign);
RsTlvStringSetRef set(TLV_TYPE_RECOGNSET, item->mRecognTags);
RsTlvStringSetRef set(TLV_TYPE_RECOGNSET, mRecognTags);
s += set.TlvSize();
s += item->mImage.TlvSize() ;
s += mImage.TlvSize() ;
return s;
}
bool RsGxsIdSerialiser::serialiseGxsIdGroupItem(RsGxsIdGroupItem *item, void *data, uint32_t *size)
bool RsGxsIdLocalInfoItem::serialise(void *data, uint32_t& size)
{
uint32_t tlvsize = sizeGxsIdGroupItem(item);
uint32_t offset = 0;
if(*size < tlvsize)
{
#ifdef GXSID_DEBUG
std::cerr << "RsGxsIdSerialiser::serialiseGxsIdGroupItem() Size too small" << std::endl;
#endif
return false;
}
*size = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
/* skip the header */
offset += 8;
/* GxsIdGroupItem */
ok &= item->mPgpIdHash.serialise(data, tlvsize, offset);
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_SIGN, item->mPgpIdSign);
uint32_t tlvsize,offset=0;
bool ok = true;
RsTlvStringSetRef set(TLV_TYPE_RECOGNSET, item->mRecognTags);
ok &= set.SetTlv(data, tlvsize, &offset);
if(!serialise_header(data,size,tlvsize,offset))
return false ;
ok &= item->mImage.SetTlv(data,tlvsize,&offset) ;
ok &= setRawUInt32(data, tlvsize, &offset, mTimeStamps.size()) ;
if(offset != tlvsize)
{
for(std::map<RsGxsId,time_t>::const_iterator it = mTimeStamps.begin();it!=mTimeStamps.end();++it)
{
ok &= it->first.serialise(data,tlvsize,offset) ;
ok &= setRawTimeT(data,tlvsize,&offset,it->second) ;
}
if(offset != tlvsize)
{
#ifdef GXSID_DEBUG
std::cerr << "RsGxsIdSerialiser::serialiseGxsIdGroupItem() FAIL Size Error! " << std::endl;
std::cerr << "RsGxsIdSerialiser::serialiseGxsIdGroupItem() FAIL Size Error! " << std::endl;
#endif
ok = false;
}
ok = false;
}
#ifdef GXSID_DEBUG
if (!ok)
{
std::cerr << "RsGxsIdSerialiser::serialiseGxsIdgroupItem() NOK" << std::endl;
}
if (!ok)
{
std::cerr << "RsGxsIdSerialiser::serialiseGxsIdgroupItem() NOK" << std::endl;
}
#endif
return ok;
}
return ok;
}
bool RsGxsIdGroupItem::serialise(void *data, uint32_t& size)
{
uint32_t tlvsize,offset=0;
bool ok = true;
if(!serialise_header(data,size,tlvsize,offset))
return false ;
/* GxsIdGroupItem */
ok &= mPgpIdHash.serialise(data, tlvsize, offset);
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_SIGN, mPgpIdSign);
RsTlvStringSetRef set(TLV_TYPE_RECOGNSET, mRecognTags);
ok &= set.SetTlv(data, tlvsize, &offset);
ok &= mImage.SetTlv(data,tlvsize,&offset) ;
if(offset != tlvsize)
{
#ifdef GXSID_DEBUG
std::cerr << "RsGxsIdSerialiser::serialiseGxsIdGroupItem() FAIL Size Error! " << std::endl;
#endif
ok = false;
}
#ifdef GXSID_DEBUG
if (!ok)
{
std::cerr << "RsGxsIdSerialiser::serialiseGxsIdgroupItem() NOK" << std::endl;
}
#endif
return ok;
}
bool RsGxsIdGroupItem::fromGxsIdGroup(RsGxsIdGroup &group, bool moveImage)
@ -273,8 +269,74 @@ bool RsGxsIdGroupItem::toGxsIdGroup(RsGxsIdGroup &group, bool moveImage)
}
return true ;
}
RsGxsIdGroupItem* RsGxsIdSerialiser::deserialise_GxsIdGroupItem(void *data, uint32_t *size)
{
/* get the type and size */
uint32_t rstype = getRsItemId(data);
uint32_t rssize = getRsItemSize(data);
RsGxsIdGroupItem* RsGxsIdSerialiser::deserialiseGxsIdGroupItem(void *data, uint32_t *size)
uint32_t offset = 0;
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
(RS_SERVICE_GXS_TYPE_GXSID != getRsItemService(rstype)) ||
(RS_PKT_SUBTYPE_GXSID_GROUP_ITEM != getRsItemSubType(rstype)))
{
#ifdef GXSID_DEBUG
std::cerr << "RsGxsIdSerialiser::deserialiseGxsIdGroupItem() FAIL wrong type" << std::endl;
#endif
return NULL; /* wrong type */
}
if (*size < rssize) /* check size */
{
#ifdef GXSID_DEBUG
std::cerr << "RsGxsIdSerialiser::deserialiseGxsIdGroupItem() FAIL wrong size" << std::endl;
#endif
return NULL; /* not enough data */
}
/* set the packet length */
*size = rssize;
bool ok = true;
RsGxsIdGroupItem* item = new RsGxsIdGroupItem();
/* skip the header */
offset += 8;
ok &= item->mPgpIdHash.deserialise(data, rssize, offset);
ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_SIGN, item->mPgpIdSign);
RsTlvStringSetRef set(TLV_TYPE_RECOGNSET, item->mRecognTags);
ok &= set.GetTlv(data, rssize, &offset);
// image is optional,so that we can continue reading old items.
if(offset < rssize)
ok &= item->mImage.GetTlv(data,rssize,&offset) ;
if (offset != rssize)
{
#ifdef GXSID_DEBUG
std::cerr << "RsGxsIdSerialiser::deserialiseGxsIdGroupItem() FAIL size mismatch" << std::endl;
#endif
/* error */
delete item;
return NULL;
}
if (!ok)
{
#ifdef GXSID_DEBUG
std::cerr << "RsGxsIdSerialiser::deserialiseGxsIdGroupItem() NOK" << std::endl;
#endif
delete item;
return NULL;
}
return item;
}
RsGxsIdLocalInfoItem *RsGxsIdSerialiser::deserialise_GxsIdLocalInfoItem(void *data, uint32_t *size)
{
/* get the type and size */
uint32_t rstype = getRsItemId(data);
@ -285,7 +347,7 @@ RsGxsIdGroupItem* RsGxsIdSerialiser::deserialiseGxsIdGroupItem(void *data, uint3
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
(RS_SERVICE_GXS_TYPE_GXSID != getRsItemService(rstype)) ||
(RS_PKT_SUBTYPE_GXSID_GROUP_ITEM != getRsItemSubType(rstype)))
(RS_PKT_SUBTYPE_GXSID_LOCAL_INFO_ITEM != getRsItemSubType(rstype)))
{
#ifdef GXSID_DEBUG
std::cerr << "RsGxsIdSerialiser::deserialiseGxsIdGroupItem() FAIL wrong type" << std::endl;
@ -306,19 +368,23 @@ RsGxsIdGroupItem* RsGxsIdSerialiser::deserialiseGxsIdGroupItem(void *data, uint3
bool ok = true;
RsGxsIdGroupItem* item = new RsGxsIdGroupItem();
RsGxsIdLocalInfoItem* item = new RsGxsIdLocalInfoItem();
/* skip the header */
offset += 8;
ok &= item->mPgpIdHash.deserialise(data, rssize, offset);
ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_SIGN, item->mPgpIdSign);
RsTlvStringSetRef set(TLV_TYPE_RECOGNSET, item->mRecognTags);
ok &= set.GetTlv(data, rssize, &offset);
uint32_t n=0 ;
ok &= getRawUInt32(data, rssize, &offset, &n) ;
// image is optional,so that we can continue reading old items.
if(offset < rssize)
ok &= item->mImage.GetTlv(data,rssize,&offset) ;
for(int i=0;ok && i<n;++i)
{
RsGxsId gxsid ;
time_t TS ;
ok &= gxsid.deserialise(data,rssize,offset) ;
ok &= getRawTimeT(data,rssize,&offset,TS) ;
item->mTimeStamps[gxsid] = TS ;
}
if (offset != rssize)
{
@ -374,7 +440,7 @@ std::ostream& RsGxsIdOpinionItem::print(std::ostream& out, uint16_t indent)
}
uint32_t RsGxsIdSerialiser::sizeGxsIdOpinionItem(RsGxsIdOpinionItem *item)
uint32_t RsGxsIdOpinionItem::serial_size()
{
const RsGxsIdOpinion& opinion = item->opinion;
@ -387,29 +453,13 @@ uint32_t RsGxsIdSerialiser::sizeGxsIdOpinionItem(RsGxsIdOpinionItem *item)
return s;
}
bool RsGxsIdSerialiser::serialiseGxsIdOpinionItem(RsGxsIdOpinionItem *item, void *data, uint32_t *size)
bool RsGxsIdOpinionItem::serialise(void *data, uint32_t *size)
{
uint32_t tlvsize = sizeGxsIdOpinionItem(item);
uint32_t offset = 0;
if(*size < tlvsize)
{
#ifdef GXSID_DEBUG
std::cerr << "RsGxsIdSerialiser::serialiseGxsIdOpinionItem()" << std::endl;
#endif
return false;
}
*size = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
/* skip the header */
offset += 8;
uint32_t tlvsize,offset=0;
bool ok = true;
if(!serialise_header(data,size,tlvsize,offset))
return false ;
/* GxsIdOpinionItem */
ok &= setRawUInt32(data, tlvsize, &offset, item->opinion.mOpinion);
@ -434,7 +484,7 @@ bool RsGxsIdSerialiser::serialiseGxsIdOpinionItem(RsGxsIdOpinionItem *item, void
return ok;
}
RsGxsIdOpinionItem* RsGxsIdSerialiser::deserialiseGxsIdOpinionItem(void *data, uint32_t *size)
RsGxsIdOpinionItem* RsGxsIdSerialiser::deserialise_GxsIdOpinionItem(void *data, uint32_t *size)
{
/* get the type and size */
@ -521,7 +571,7 @@ std::ostream& RsGxsIdCommentItem::print(std::ostream& out, uint16_t indent)
}
uint32_t RsGxsIdSerialiser::sizeGxsIdCommentItem(RsGxsIdCommentItem *item)
uint32_t RsGxsIdCommentItem::serial_size()
{
const RsGxsIdComment& comment = item->comment;
@ -532,28 +582,13 @@ uint32_t RsGxsIdSerialiser::sizeGxsIdCommentItem(RsGxsIdCommentItem *item)
return s;
}
bool RsGxsIdSerialiser::serialiseGxsIdCommentItem(RsGxsIdCommentItem *item, void *data, uint32_t *size)
bool RsGxsIdCommentItem::serialise(void *data, uint32_t *size)
{
uint32_t tlvsize = sizeGxsIdCommentItem(item);
uint32_t offset = 0;
if(*size < tlvsize)
{
#ifdef GXSID_DEBUG
std::cerr << "RsGxsIdSerialiser::serialiseGxsIdCommentItem() Not enough space" << std::endl;
#endif
return false;
}
*size = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
/* skip the header */
offset += 8;
uint32_t tlvsize,offset=0;
bool ok = true;
if(!serialise_header(data,size,tlvsize,offset))
return false ;
/* GxsIdCommentItem */
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_COMMENT, item->comment.mComment);
@ -576,7 +611,7 @@ bool RsGxsIdSerialiser::serialiseGxsIdCommentItem(RsGxsIdCommentItem *item, void
return ok;
}
RsGxsIdCommentItem* RsGxsIdSerialiser::deserialiseGxsIdCommentItem(void *data, uint32_t *size)
RsGxsIdCommentItem* RsGxsIdSerialiser::deserialise_GxsIdCommentItem(void *data, uint32_t *size)
{
/* get the type and size */

View File

@ -36,21 +36,37 @@
//const uint8_t RS_PKT_SUBTYPE_GXSID_GROUP_ITEM_deprecated = 0x02;
const uint8_t RS_PKT_SUBTYPE_GXSID_GROUP_ITEM = 0x02;
const uint8_t RS_PKT_SUBTYPE_GXSID_OPINION_ITEM = 0x03;
const uint8_t RS_PKT_SUBTYPE_GXSID_COMMENT_ITEM = 0x04;
const uint8_t RS_PKT_SUBTYPE_GXSID_GROUP_ITEM = 0x02;
const uint8_t RS_PKT_SUBTYPE_GXSID_OPINION_ITEM = 0x03;
const uint8_t RS_PKT_SUBTYPE_GXSID_COMMENT_ITEM = 0x04;
const uint8_t RS_PKT_SUBTYPE_GXSID_LOCAL_INFO_ITEM = 0x05;
class RsGxsIdGroupItem : public RsGxsGrpItem
class RsGxsIdItem: public RsGxsGrpItem
{
public:
RsGxsIdItem(uint8_t item_subtype) : RsGxsGrpItem(RS_SERVICE_GXS_TYPE_GXSID,item_subtype) {}
virtual bool serialise(void *data,uint32_t& size) = 0 ;
virtual uint32_t serial_size() = 0 ;
virtual void clear() = 0 ;
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0) = 0;
bool serialise_header(void *data,uint32_t& pktsize,uint32_t& tlvsize, uint32_t& offset) ;
};
class RsGxsIdGroupItem : public RsGxsIdItem
{
public:
RsGxsIdGroupItem(): RsGxsGrpItem(RS_SERVICE_GXS_TYPE_GXSID,
RS_PKT_SUBTYPE_GXSID_GROUP_ITEM) { return;}
virtual ~RsGxsIdGroupItem() { return;}
RsGxsIdGroupItem(): RsGxsIdItem(RS_PKT_SUBTYPE_GXSID_GROUP_ITEM) {}
virtual ~RsGxsIdGroupItem() {}
void clear();
std::ostream &print(std::ostream &out, uint16_t indent = 0);
virtual void clear();
virtual std::ostream &print(std::ostream &out, uint16_t indent = 0);
virtual bool serialise(void *data,uint32_t& size) ;
virtual uint32_t serial_size() ;
bool fromGxsIdGroup(RsGxsIdGroup &group, bool moveImage);
bool toGxsIdGroup(RsGxsIdGroup &group, bool moveImage);
@ -66,6 +82,22 @@ public:
// Avatar
RsTlvImage mImage ;
};
class RsGxsIdLocalInfoItem : public RsGxsIdItem
{
public:
RsGxsIdLocalInfoItem(): RsGxsIdItem(RS_PKT_SUBTYPE_GXSID_LOCAL_INFO_ITEM) {}
virtual ~RsGxsIdLocalInfoItem() {}
virtual void clear();
virtual std::ostream &print(std::ostream &out, uint16_t indent = 0);
virtual bool serialise(void *data,uint32_t& size) ;
virtual uint32_t serial_size() ;
std::map<RsGxsId,time_t> mTimeStamps ;
};
#if 0
class RsGxsIdOpinionItem : public RsGxsMsgItem
@ -76,7 +108,10 @@ public:
RS_PKT_SUBTYPE_GXSID_OPINION_ITEM) {return; }
virtual ~RsGxsIdOpinionItem() { return;}
void clear();
std::ostream &print(std::ostream &out, uint16_t indent = 0);
virtual bool serialise(void *data,uint32_t& size) = 0 ;
virtual uint32_t serial_size() = 0 ;
std::ostream &print(std::ostream &out, uint16_t indent = 0);
RsGxsIdOpinion opinion;
};
@ -88,6 +123,9 @@ public:
RS_PKT_SUBTYPE_GXSID_COMMENT_ITEM) { return; }
virtual ~RsGxsIdCommentItem() { return; }
void clear();
virtual bool serialise(void *data,uint32_t& size) = 0 ;
virtual uint32_t serial_size() = 0 ;
std::ostream &print(std::ostream &out, uint16_t indent = 0);
RsGxsIdComment comment;
@ -97,33 +135,26 @@ public:
class RsGxsIdSerialiser : public RsSerialType
{
public:
RsGxsIdSerialiser() :RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_GXS_TYPE_GXSID) {}
virtual ~RsGxsIdSerialiser() {}
RsGxsIdSerialiser()
:RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_GXS_TYPE_GXSID)
{ return; }
virtual ~RsGxsIdSerialiser() { return; }
uint32_t size(RsItem *item);
bool serialise (RsItem *item, void *data, uint32_t *size);
RsItem * deserialise(void *data, uint32_t *size);
private:
uint32_t sizeGxsIdGroupItem(RsGxsIdGroupItem *item);
bool serialiseGxsIdGroupItem (RsGxsIdGroupItem *item, void *data, uint32_t *size);
RsGxsIdGroupItem * deserialiseGxsIdGroupItem(void *data, uint32_t *size);
virtual uint32_t size (RsItem *item)
{
return dynamic_cast<RsGxsIdItem *>(item)->serial_size() ;
}
virtual bool serialise(RsItem *item, void *data, uint32_t *size)
{
return dynamic_cast<RsGxsIdItem *>(item)->serialise(data,*size) ;
}
virtual RsItem *deserialise (void *data, uint32_t *size) ;
private:
#if 0
uint32_t sizeGxsIdOpinionItem(RsGxsIdOpinionItem *item);
bool serialiseGxsIdOpinionItem (RsGxsIdOpinionItem *item, void *data, uint32_t *size);
RsGxsIdOpinionItem * deserialiseGxsIdOpinionItem(void *data, uint32_t *size);
uint32_t sizeGxsIdCommentItem(RsGxsIdCommentItem *item);
bool serialiseGxsIdCommentItem (RsGxsIdCommentItem *item, void *data, uint32_t *size);
RsGxsIdCommentItem * deserialiseGxsIdCommentItem(void *data, uint32_t *size);
static RsGxsIdOpinionItem *deserialise_GxsIdOpinionItem(void *data, uint32_t *size);
static RsGxsIdCommentItem *deserialise_GxsIdCommentItem(void *data, uint32_t *size);
#endif
static RsGxsIdGroupItem *deserialise_GxsIdGroupItem(void *data, uint32_t *size);
static RsGxsIdLocalInfoItem *deserialise_GxsIdLocalInfoItem(void *data, uint32_t *size);
};
#endif /* RS_GXS_IDENTITY_ITEMS_H */

View File

@ -52,7 +52,8 @@ RsItem::RsItem(uint32_t t)
{
_priority_level = QOS_PRIORITY_UNKNOWN ; // This value triggers PQIInterface to complain about undefined priorities
}
#ifdef DO_STATISTICS
class Counter
{

View File

@ -104,7 +104,8 @@ class RsItem: public RsMemoryManagement::SmallObject
void setPacketService(uint16_t service);
inline uint8_t priority_level() const { return _priority_level ;}
inline void setPriorityLevel(uint8_t l) { _priority_level = l ;}
inline void setPriorityLevel(uint8_t l) { _priority_level = l ;}
private:
uint32_t type;
RsPeerId peerId;

View File

@ -218,14 +218,14 @@ std::ostream &RsTlvStringSet::printHex(std::ostream &out, uint16_t indent) const
/************************************* String Set Ref ************************************/
/* This is exactly the same as StringSet, but it uses an alternative list.
*/
RsTlvStringSetRef::RsTlvStringSetRef(uint16_t type, std::list<std::string> &refids)
RsTlvStringSetRef::RsTlvStringSetRef(uint16_t type, std::list<std::string> &refids)
:mType(type), ids(refids)
{
}
void RsTlvStringSetRef::TlvClear()
{
ids.clear();
ids.clear();
}

View File

@ -53,7 +53,7 @@ virtual std::ostream &printHex(std::ostream &out, uint16_t indent) const;
class RsTlvStringSetRef: public RsTlvItem
{
public:
RsTlvStringSetRef(uint16_t type, std::list<std::string> &refids);
RsTlvStringSetRef(uint16_t type, std::list<std::string> &refids);
virtual ~RsTlvStringSetRef() { return; }
virtual uint32_t TlvSize() const;
virtual void TlvClear();
@ -62,7 +62,7 @@ virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset);
virtual std::ostream &print(std::ostream &out, uint16_t indent) const;
uint16_t mType;
std::list<std::string> &ids; /* Mandatory */
std::list<std::string> &ids; /* Mandatory */
};

View File

@ -26,6 +26,7 @@
#include "services/p3idservice.h"
#include "pgp/pgpauxutils.h"
#include "serialiser/rsgxsiditems.h"
#include "serialiser/rsconfigitems.h"
#include "retroshare/rsgxsflags.h"
#include "util/rsrandom.h"
#include "util/rsstring.h"
@ -52,10 +53,11 @@
#define ID_REQUEST_REPUTATION 0x0003
#define ID_REQUEST_OPINION 0x0004
static const uint32_t MAX_KEEP_UNUSED_KEYS = 30*86400 ; // remove unused keys after 30 days
static const uint32_t MAX_DELAY_BEFORE_CLEANING = 3601 ; // clean old keys every hour
RsIdentity *rsIdentity = NULL;
/******
* Some notes:
* Identity tasks:
@ -144,7 +146,8 @@ p3IdService::p3IdService(RsGeneralDataService *gds, RsNetworkExchangeService *ne
mPgpUtils(pgpUtils)
{
mBgSchedule_Mode = 0;
mBgSchedule_Active = false;
mBgSchedule_Active = false;
mLastKeyCleaningTime = time(NULL) ;
// Kick off Cache Testing, + Others.
RsTickEvent::schedule_in(GXSID_EVENT_PGPHASH, PGPHASH_PERIOD);
@ -201,12 +204,86 @@ uint32_t p3IdService::idAuthenPolicy()
return policy;
}
time_t p3IdService::locked_getLastUsageTS(const RsGxsId& gxs_id)
{
std::map<RsGxsId,time_t>::const_iterator it = mKeysTS.find(gxs_id) ;
if(it == mKeysTS.end())
{
IndicateConfigChanged() ;
return mKeysTS[gxs_id] = time(NULL) ;
}
else
return it->second ;
}
void p3IdService::timeStampKey(const RsGxsId& gxs_id)
{
RS_STACK_MUTEX(mIdMtx) ;
mKeysTS[gxs_id] = time(NULL) ;
IndicateConfigChanged() ;
}
bool p3IdService::loadList(std::list<RsItem*>& items)
{
RS_STACK_MUTEX(mIdMtx) ;
RsGxsIdLocalInfoItem *lii;
for(std::list<RsItem*>::const_iterator it = items.begin();it!=items.end();++it)
if( (lii = dynamic_cast<RsGxsIdLocalInfoItem*>(*it)) != NULL)
for(std::map<RsGxsId,time_t>::const_iterator it2 = lii->mTimeStamps.begin();it2!=lii->mTimeStamps.end();++it2)
mKeysTS.insert(*it2) ;
return true ;
}
bool p3IdService::saveList(bool& cleanup,std::list<RsItem*>& items)
{
std::cerr << "p3IdService::saveList()" << std::endl;
RS_STACK_MUTEX(mIdMtx) ;
cleanup = true ;
RsGxsIdLocalInfoItem *item = new RsGxsIdLocalInfoItem ;
item->mTimeStamps = mKeysTS ;
items.push_back(item) ;
return true ;
}
void p3IdService::cleanUnusedKeys()
{
RS_STACK_MUTEX(mIdMtx) ;
time_t now = time(NULL) ;
for(std::map<RsGxsId,time_t>::iterator it(mKeysTS.begin());it!=mKeysTS.end();)
if(it->second + MAX_KEEP_UNUSED_KEYS < now && !isOwnId(it->first))
{
std::cerr << "Deleting identity " << it->first << " which is too old." << std::endl;
uint32_t token ;
RsGxsIdGroup group;
group.mMeta.mGroupId=RsGxsGroupId(it->first);
rsIdentity->deleteIdentity(token, group);
std::map<RsGxsId,time_t>::iterator tmp = it ;
++tmp ;
mKeysTS.erase(it) ;
}
else
++it ;
}
void p3IdService::service_tick()
{
RsTickEvent::tick_events();
GxsTokenQueue::checkRequests(); // GxsTokenQueue handles all requests.
GxsTokenQueue::checkRequests(); // GxsTokenQueue handles all requests.
time_t now = time(NULL) ;
if(mLastKeyCleaningTime + MAX_DELAY_BEFORE_CLEANING < now)
{
cleanUnusedKeys() ;
mLastKeyCleaningTime = now ;
}
return;
}
@ -288,22 +365,25 @@ bool p3IdService:: getIdDetails(const RsGxsId &id, RsIdentityDetails &details)
std::cerr << std::endl;
#endif
{
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
RsGxsIdCache data;
if (mPublicKeyCache.fetch(id, data))
{
details = data.details;
return true;
}
/* try private cache too */
if (mPrivateKeyCache.fetch(id, data))
{
details = data.details;
return true;
}
}
{
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
RsGxsIdCache data;
if (mPublicKeyCache.fetch(id, data))
{
details = data.details;
details.mLastUsageTS = locked_getLastUsageTS(id) ;
return true;
}
/* try private cache too */
if (mPrivateKeyCache.fetch(id, data))
{
details = data.details;
details.mLastUsageTS = locked_getLastUsageTS(id) ;
return true;
}
}
/* it isn't there - add to public requests */
cache_request_load(id);
@ -312,6 +392,12 @@ bool p3IdService:: getIdDetails(const RsGxsId &id, RsIdentityDetails &details)
}
bool p3IdService::isOwnId(const RsGxsId& id)
{
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
return std::find(mOwnIds.begin(),mOwnIds.end(),id) != mOwnIds.end() ;
}
void p3IdService::getOwnIds(std::list<RsGxsId> &ownIds)
{
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
@ -524,6 +610,144 @@ bool p3IdService::getPrivateKey(const RsGxsId &id, RsTlvSecurityKey &key)
}
bool p3IdService::signData(const uint8_t *data,uint32_t data_size,const RsGxsId& own_gxs_id,RsTlvKeySignature& signature,uint32_t& error_status)
{
//RsIdentityDetails details ;
RsTlvSecurityKey signature_key ;
//getIdDetails(own_gxs_id,details);
int i ;
for(i=0;i<6;++i)
if(!getPrivateKey(own_gxs_id,signature_key) || signature_key.keyData.bin_data == NULL)
{
#ifdef DEBUG_IDS
std::cerr << " Cannot get key. Waiting for caching. try " << i << "/6" << std::endl;
#endif
usleep(500 * 1000) ; // sleep for 500 msec.
}
else
break ;
if(i == 6)
{
std::cerr << " (EE) Could not retrieve own private key for ID = " << own_gxs_id << ". Giging up sending DH session params. This should not happen." << std::endl;
error_status = RS_GIXS_ERROR_KEY_NOT_AVAILABLE ;
return false ;
}
#ifdef DEBUG_IDS
std::cerr << " Signing..." << std::endl;
#endif
if(!GxsSecurity::getSignature((char *)data,data_size,signature_key,signature))
{
std::cerr << " (EE) Cannot sign for id " << own_gxs_id << ". Signature call failed." << std::endl;
error_status = RS_GIXS_ERROR_UNKNOWN ;
return false ;
}
error_status = RS_GIXS_ERROR_NO_ERROR ;
timeStampKey(own_gxs_id) ;
return true ;
}
bool p3IdService::validateData(const uint8_t *data,uint32_t data_size,const RsTlvKeySignature& signature,bool force_load,uint32_t& signing_error)
{
// RsIdentityDetails details ;
// getIdDetails(signature.keyId,details);
RsTlvSecurityKey signature_key ;
for(int i=0;i< (force_load?6:1);++i)
if(!getKey(signature.keyId,signature_key) || signature_key.keyData.bin_data == NULL)
{
#ifdef DEBUG_IDS
std::cerr << " Cannot get key. Waiting for caching. try " << i << "/6" << std::endl;
#endif
usleep(500 * 1000) ; // sleep for 500 msec.
}
else
break ;
if(signature_key.keyData.bin_data == NULL)
{
std::cerr << "(EE) Cannot validate signature for unknown key " << signature.keyId << std::endl;
signing_error = RS_GIXS_ERROR_KEY_NOT_AVAILABLE ;
return false;
}
if(!GxsSecurity::validateSignature((char*)data,data_size,signature_key,signature))
{
std::cerr << "(EE) Signature was verified and it doesn't check! This is a security issue!" << std::endl;
signing_error = RS_GIXS_ERROR_SIGNATURE_MISMATCH ;
return false;
}
signing_error = RS_GIXS_ERROR_NO_ERROR ;
timeStampKey(signature.keyId) ;
return true ;
}
bool p3IdService::encryptData(const uint8_t *decrypted_data,uint32_t decrypted_data_size,uint8_t *& encrypted_data,uint32_t& encrypted_data_size,const RsGxsId& encryption_key_id,bool force_load,uint32_t& error_status)
{
RsTlvSecurityKey encryption_key ;
// get the key, and let the cache find it.
for(int i=0;i<(force_load?6:1);++i)
if(getKey(encryption_key_id,encryption_key))
break ;
else
usleep(500*1000) ; // sleep half a sec.
if(encryption_key.keyId.isNull())
{
std::cerr << " (EE) Cannot get encryption key for id " << encryption_key_id << std::endl;
error_status = RS_GIXS_ERROR_KEY_NOT_AVAILABLE ;
return false ;
}
if(!GxsSecurity::encrypt(encrypted_data,encrypted_data_size,decrypted_data,decrypted_data_size,encryption_key))
{
std::cerr << " (EE) Encryption failed." << std::endl;
error_status = RS_GIXS_ERROR_UNKNOWN ;
return false ;
}
error_status = RS_GIXS_ERROR_NO_ERROR ;
timeStampKey(encryption_key_id) ;
return true ;
}
bool p3IdService::decryptData(const uint8_t *encrypted_data,uint32_t encrypted_data_size,uint8_t *& decrypted_data,uint32_t& decrypted_size,const RsGxsId& key_id,uint32_t& error_status)
{
RsTlvSecurityKey encryption_key ;
// Get the key, and let the cache find it. It's our own key, so we should be able to find it, even if it takes
// some seconds.
for(int i=0;i<4;++i)
if(getPrivateKey(key_id,encryption_key))
break ;
else
usleep(500*1000) ; // sleep half a sec.
if(encryption_key.keyId.isNull())
{
std::cerr << " (EE) Cannot get own encryption key for id " << key_id << " to decrypt data. This should not happen." << std::endl;
error_status = RS_GIXS_ERROR_KEY_NOT_AVAILABLE;
return false ;
}
if(!GxsSecurity::decrypt(decrypted_data,decrypted_size,encrypted_data,encrypted_data_size,encryption_key))
{
std::cerr << " (EE) Decryption failed." << std::endl;
error_status = RS_GIXS_ERROR_UNKNOWN ;
return false ;
}
error_status = RS_GIXS_ERROR_NO_ERROR ;
timeStampKey(key_id) ;
return true ;
}
/********************************************************************************/
/******************* RsGixsReputation ***************************************/
/********************************************************************************/
@ -722,6 +946,16 @@ bool p3IdService::opinion_handlerequest(uint32_t token)
/******************* Get/Set Data ******************************************/
/********************************************************************************/
RsSerialiser *p3IdService::setupSerialiser()
{
RsSerialiser *rss = new RsSerialiser ;
rss->addSerialType(new RsGxsIdSerialiser()) ;
rss->addSerialType(new RsGeneralConfigSerialiser());
return rss ;
}
bool p3IdService::getGroupData(const uint32_t &token, std::vector<RsGxsIdGroup> &groups)
{
std::vector<RsGxsGrpItem*> grpData;
@ -745,6 +979,11 @@ bool p3IdService::getGroupData(const uint32_t &token, std::vector<RsGxsIdGroup>
RsGxsIdGroup group ;
item->toGxsIdGroup(group,false) ;
{
RS_STACK_MUTEX(mIdMtx) ;
group.mLastUsageTS = locked_getLastUsageTS(RsGxsId(group.mMeta.mGroupId)) ;
}
// Decode information from serviceString.
SSGxsIdGroup ssdata;
if (ssdata.load(group.mMeta.mServiceString))
@ -1282,32 +1521,31 @@ RsGxsIdCache::RsGxsIdCache()
RsGxsIdCache::RsGxsIdCache(const RsGxsIdGroupItem *item, const RsTlvSecurityKey &in_pkey, const std::list<RsRecognTag> &tagList)
{
// Save Keys.
pubkey = in_pkey;
// Save Keys.
pubkey = in_pkey;
// Save Time for ServiceString comparisions.
mPublishTs = item->meta.mPublishTs;
// Save RecognTags.
// Save Time for ServiceString comparisions.
mPublishTs = item->meta.mPublishTs;
// Save RecognTags.
mRecognTags = tagList;
details.mAvatar.copy((uint8_t *) item->mImage.binData.bin_data, item->mImage.binData.bin_len);
details.mAvatar.copy((uint8_t *) item->mImage.binData.bin_data, item->mImage.binData.bin_len);
// Fill in Details.
details.mNickname = item->meta.mGroupName;
details.mId = RsGxsId(item->meta.mGroupId);
// Fill in Details.
details.mNickname = item->meta.mGroupName;
details.mId = RsGxsId(item->meta.mGroupId);
#ifdef DEBUG_IDS
std::cerr << "RsGxsIdCache::RsGxsIdCache() for: " << details.mId;
std::cerr << std::endl;
std::cerr << "RsGxsIdCache::RsGxsIdCache() for: " << details.mId;
std::cerr << std::endl;
#endif // DEBUG_IDS
details.mIsOwnId = (item->meta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN);
details.mIsOwnId = (item->meta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN);
details.mPgpLinked = (item->meta.mGroupFlags & RSGXSID_GROUPFLAG_REALID);
details.mPgpLinked = (item->meta.mGroupFlags & RSGXSID_GROUPFLAG_REALID);
/* rest must be retrived from ServiceString */
updateServiceString(item->meta.mServiceString);
/* rest must be retrived from ServiceString */
updateServiceString(item->meta.mServiceString);
}
void RsGxsIdCache::updateServiceString(std::string serviceString)
@ -1729,7 +1967,7 @@ bool p3IdService::cache_load_for_token(uint32_t token)
{
// remove identities that are present
// remove identities that are present
RsStackMutex stack(mIdMtx);
mPendingCache.erase(RsGxsId(item->meta.mGroupId.toStdString()));
}
@ -2005,7 +2243,7 @@ bool p3IdService::cachetest_handlerequest(uint32_t token)
else
{
RsTlvSecurityKey seckey;
if (getKey(*vit, seckey))
if (getKey(*vit, seckey))
{
#ifdef DEBUG_IDS
std::cerr << "p3IdService::cachetest_request() Got Key OK Id: " << *vit;
@ -2195,8 +2433,8 @@ RsGenExchange::ServiceCreate_Return p3IdService::service_CreateGroup(RsGxsGrpIte
std::cerr << "p3IdService::service_CreateGroup() ERROR no admin key";
std::cerr << std::endl;
return SERVICE_CREATE_FAIL;
}
}
mKeysTS[RsGxsId(item->meta.mGroupId)] = time(NULL) ;
/********************* TEMP HACK UNTIL GXS FILLS IN GROUP_ID *****************/

View File

@ -213,8 +213,7 @@ void updateServiceString(std::string serviceString);
// Not sure exactly what should be inherited here?
// Chris - please correct as necessary.
class p3IdService: public RsGxsIdExchange, public RsIdentity,
public GxsTokenQueue, public RsTickEvent
class p3IdService: public RsGxsIdExchange, public RsIdentity, public GxsTokenQueue, public RsTickEvent, public p3Config
{
public:
p3IdService(RsGeneralDataService* gds, RsNetworkExchangeService* nes, PgpAuxUtils *pgpUtils);
@ -254,12 +253,8 @@ virtual bool deleteGroup(uint32_t& token, RsGxsIdGroup &group);
* Also need to handle Cache updates / invalidation from internal changes.
*
*/
//virtual bool getNickname(const RsGxsId &id, std::string &nickname);
virtual bool getIdDetails(const RsGxsId &id, RsIdentityDetails &details);
virtual void getOwnIds(std::list<RsGxsId> &ownIds);
//
virtual bool submitOpinion(uint32_t& token, const RsGxsId &id,
@ -274,25 +269,32 @@ virtual bool parseRecognTag(const RsGxsId &id, const std::string &nickname,
virtual bool getRecognTagRequest(const RsGxsId &id, const std::string &comment,
uint16_t tag_class, uint16_t tag_type, std::string &tag);
/**************** RsGixs Implementation ***************/
/**************** RsGixs Implementation
* Notes:
* Interface is only suggestion at the moment, will be changed as necessary.
* Results should be cached / preloaded for maximum speed.
*
*/
virtual bool haveKey(const RsGxsId &id);
virtual bool requestKey(const RsGxsId &id, const std::list<PeerId> &peers);
virtual bool getKey(const RsGxsId &id, RsTlvSecurityKey &key);
virtual void getOwnIds(std::list<RsGxsId> &ownIds);
virtual bool havePrivateKey(const RsGxsId &id);
virtual bool requestPrivateKey(const RsGxsId &id);
virtual bool getPrivateKey(const RsGxsId &id, RsTlvSecurityKey &key);
//virtual bool getPublicKey(const RsGxsId &id, RsTlvSecurityKey &key) ;
//virtual void networkRequestPublicKey(const RsGxsId& key_id,const std::list<RsPeerId>& peer_ids) ;
/**************** RsGixsReputation Implementation
* Notes:
* Again should be cached if possible.
*/
virtual bool isOwnId(const RsGxsId& key_id) ;
virtual bool signData(const uint8_t *data,uint32_t data_size,const RsGxsId& signer_id,RsTlvKeySignature& signature,uint32_t& signing_error) ;
virtual bool validateData(const uint8_t *data,uint32_t data_size,const RsTlvKeySignature& signature,bool force_load,uint32_t& signing_error) ;
virtual bool encryptData(const uint8_t *decrypted_data,uint32_t decrypted_data_size,uint8_t *& encrypted_data,uint32_t& encrypted_data_size,const RsGxsId& encryption_key_id,bool force_load,uint32_t& encryption_error) ;
virtual bool decryptData(const uint8_t *encrypted_data,uint32_t encrypted_data_size,uint8_t *& decrypted_data,uint32_t& decrypted_data_size,const RsGxsId& encryption_key_id,uint32_t& encryption_error) ;
virtual bool haveKey(const RsGxsId &id);
virtual bool havePrivateKey(const RsGxsId &id);
virtual bool getKey(const RsGxsId &id, RsTlvSecurityKey &key);
virtual bool getPrivateKey(const RsGxsId &id, RsTlvSecurityKey &key);
virtual bool requestKey(const RsGxsId &id, const std::list<PeerId> &peers);
virtual bool requestPrivateKey(const RsGxsId &id);
/**************** RsGixsReputation Implementation ****************/
// get Reputation.
virtual bool haveReputation(const RsGxsId &id);
@ -300,9 +302,8 @@ virtual bool loadReputation(const RsGxsId &id, const std::list<RsPeerId>& peers)
virtual bool getReputation(const RsGxsId &id, GixsReputation &rep);
protected:
/** Notifications **/
protected:
/** Notifications **/
virtual void notifyChanges(std::vector<RsGxsNotify*>& changes);
/** Overloaded to add PgpIdHash to Group Definition **/
@ -314,6 +315,18 @@ virtual void handleResponse(uint32_t token, uint32_t req_type);
// Overloaded from RsTickEvent.
virtual void handle_event(uint32_t event_type, const std::string &elabel);
//===================================================//
// p3Config methods //
//===================================================//
// Load/save the routing info, the pending items in transit, and the config variables.
//
virtual bool loadList(std::list<RsItem*>& items) ;
virtual bool saveList(bool& cleanup,std::list<RsItem*>& items) ;
virtual RsSerialiser *setupSerialiser() ;
private:
/************************************************************************
@ -441,6 +454,10 @@ virtual void generateDummyData();
void generateDummy_UnknownPGP();
void generateDummy_UnknownPseudo();
void cleanUnusedKeys() ;
virtual void timeStampKey(const RsGxsId& id) ;
time_t locked_getLastUsageTS(const RsGxsId& gxs_id);
std::string genRandomId(int len = 20);
#if 0
@ -480,7 +497,8 @@ std::string genRandomId(int len = 20);
std::map<uint32_t, std::set<RsGxsGroupId> > mIdsPendingCache;
std::map<uint32_t, std::list<RsGxsGroupId> > mGroupNotPresent;
std::map<RsGxsId, std::list<RsPeerId> > mIdsNotPresent;
std::map<RsGxsId, std::list<RsPeerId> > mIdsNotPresent;
std::map<RsGxsId,time_t> mKeysTS ;
RsNetworkExchangeService* mNes;
/**************************
@ -488,7 +506,9 @@ std::string genRandomId(int len = 20);
* without depending directly on all these classes.
*/
PgpAuxUtils *mPgpUtils;
PgpAuxUtils *mPgpUtils;
time_t mLastKeyCleaningTime ;
};
#endif // P3_IDENTITY_SERVICE_HEADER

View File

@ -92,7 +92,8 @@ IdDialog::IdDialog(QWidget *parent) :
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_GpgId);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_GpgName);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_Type);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->toolButton_Reputation);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_LastUsed);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->toolButton_Reputation);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->line_RatingOverall);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->line_RatingImplicit);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->line_RatingOwn);
@ -112,7 +113,8 @@ IdDialog::IdDialog(QWidget *parent) :
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_GpgId);
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_Type);
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_GpgName);
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->line_RatingOverall);
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_LastUsed);
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->line_RatingOverall);
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->line_RatingImplicit);
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->line_RatingOwn);
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->line_RatingPeers);
@ -122,8 +124,9 @@ IdDialog::IdDialog(QWidget *parent) :
// mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_GpgHash);
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_GpgId);
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_Type);
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_GpgName);
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->line_RatingOverall);
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_GpgName);
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_LastUsed);
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->line_RatingOverall);
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->line_RatingImplicit);
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->line_RatingOwn);
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->line_RatingPeers);
@ -542,6 +545,18 @@ void IdDialog::requestIdDetails()
mIdQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds, IDDIALOG_IDDETAILS);
}
static QString getHumanReadableDuration(uint32_t seconds)
{
if(seconds < 60)
return QString::number(seconds) + QObject::tr(" seconds ago") ;
else if(seconds < 3600)
return QString::number(seconds/60) + QObject::tr(" minute(s) ago") ;
else if(seconds < 24*3600)
return QString::number(seconds/3600) + QObject::tr(" hour(s) ago") ;
else
return QString::number(seconds/86400) + QObject::tr(" day(s) ago") ;
}
void IdDialog::insertIdDetails(uint32_t token)
{
mStateHelper->setLoading(IDDIALOG_IDDETAILS, false);
@ -583,9 +598,11 @@ void IdDialog::insertIdDetails(uint32_t token)
ui->lineEdit_Nickname->setText(QString::fromUtf8(data.mMeta.mGroupName.c_str()));
ui->lineEdit_KeyId->setText(QString::fromStdString(data.mMeta.mGroupId.toStdString()));
//ui->lineEdit_GpgHash->setText(QString::fromStdString(data.mPgpIdHash.toStdString()));
ui->lineEdit_GpgId->setText(QString::fromStdString(data.mPgpId.toStdString()));
ui->headerTextLabel->setText(QString::fromUtf8(data.mMeta.mGroupName.c_str()));
ui->lineEdit_GpgId->setText(QString::fromStdString(data.mPgpId.toStdString()));
time_t now = time(NULL) ;
ui->lineEdit_LastUsed->setText(getHumanReadableDuration(now - data.mLastUsageTS)) ;
ui->headerTextLabel->setText(QString::fromUtf8(data.mMeta.mGroupName.c_str()));
QPixmap pixmap ;
@ -1117,4 +1134,4 @@ int IdDialog::getNumColVisible()
}
}
return iNumColVis;
}
}

View File

@ -307,6 +307,26 @@
<property name="margin">
<number>6</number>
</property>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Identity name :</string>
</property>
</widget>
</item>
<item row="7" column="1">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
@ -321,19 +341,6 @@
</property>
</widget>
</item>
<item row="6" column="1">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="lineEdit_Nickname">
<property name="enabled">
@ -344,15 +351,18 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Identity name :</string>
<item row="2" column="1">
<widget class="QLineEdit" name="lineEdit_KeyId">
<property name="enabled">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="lineEdit_KeyId">
<item row="4" column="1">
<widget class="QLineEdit" name="lineEdit_GpgId">
<property name="enabled">
<bool>true</bool>
</property>
@ -378,16 +388,6 @@
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="lineEdit_GpgId">
<property name="enabled">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
@ -398,6 +398,16 @@
<item row="3" column="1">
<widget class="QLineEdit" name="lineEdit_Type"/>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Last used:</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLineEdit" name="lineEdit_LastUsed"/>
</item>
</layout>
</item>
<item row="0" column="1">
@ -692,6 +702,11 @@
</action>
</widget>
<customwidgets>
<customwidget>
<class>StyledLabel</class>
<extends>QLabel</extends>
<header>gui/common/StyledLabel.h</header>
</customwidget>
<customwidget>
<class>RSTreeWidget</class>
<extends>QTreeWidget</extends>
@ -702,11 +717,6 @@
<extends>QLineEdit</extends>
<header location="global">gui/common/LineEditClear.h</header>
</customwidget>
<customwidget>
<class>StyledLabel</class>
<extends>QLabel</extends>
<header>gui/common/StyledLabel.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>todoPushButton</tabstop>

View File

@ -557,7 +557,6 @@ void ChatWidget::completeNickname(bool reverse)
word.chop(2);
}
#warning still need to use real nicknames for nickname completion.
if (word.length() > 0) {
// Sort participants list
std::list<QString> participants;