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 ;
};