- implemented DH protocol for PFS encryption in distant chat between GXS ids.

- changed format of keyId in rstlvkeys.{h,cc}, but kept the serialisation for backward compatibility (A #define needs to be removed to fix it for good). Updated rsrecogn, rsmsgitems, gxssecurity accordingly
- added "chat peer" in IdDialog to help testing distant chat.

Distant chat works and is now encrypted. The GUI still needs some smoothing: display of correct peer names
in chat window, remove the need to add a message in p3chatservice.cc:3217 to force poping up the chat window.

- added MsgAddress class to handle generic address types while keeping type separation in Messages. Not used yet.



git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@7403 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2014-06-12 10:28:23 +00:00
parent 114352c0d6
commit 80f4401e88
21 changed files with 720 additions and 182 deletions

View file

@ -57,6 +57,19 @@ std::ostream& RsChatMsgItem::print(std::ostream &out, uint16_t indent)
printRsItemEnd(out, "RsChatMsgItem", indent);
return out;
}
std::ostream& RsChatDHPublicKeyItem::print(std::ostream &out, uint16_t indent)
{
printRsItemBase(out, "RsChatDHPublicKeyItem", indent);
uint16_t int_Indent = indent + 2;
printIndent(out, int_Indent);
out << " Signature Key ID: " << signature.keyId << std::endl ;
out << " Public Key ID: " << gxs_key.keyId << std::endl ;
printRsItemEnd(out, "RsChatMsgItem", indent);
return out;
}
std::ostream& RsChatLobbyListItem_deprecated2::print(std::ostream &out, uint16_t indent)
{
printRsItemBase(out, "RsChatLobbyListItem_deprecated2", indent);
@ -296,6 +309,7 @@ RsItem *RsChatSerialiser::deserialise(void *data, uint32_t *pktsize)
case RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_deprecated: return new RsChatLobbyListItem_deprecated(data,*pktsize) ;
case RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_deprecated2:return new RsChatLobbyListItem_deprecated2(data,*pktsize) ;
case RS_PKT_SUBTYPE_CHAT_LOBBY_CONFIG: return new RsChatLobbyConfigItem(data,*pktsize) ;
case RS_PKT_SUBTYPE_DISTANT_CHAT_DH_PUBLIC_KEY: return new RsChatDHPublicKeyItem(data,*pktsize) ;
default:
std::cerr << "Unknown packet type in chat!" << std::endl ;
return NULL ;
@ -466,6 +480,17 @@ uint32_t RsChatLobbyConfigItem::serial_size()
return s;
}
uint32_t RsChatDHPublicKeyItem::serial_size()
{
uint32_t s = 8 ; // header
s += 4 ; // BN size
s += BN_num_bytes(public_key) ; // public_key
s += signature.TlvSize() ; // signature
s += gxs_key.TlvSize() ; // gxs_key
return s ;
}
/*************************************************************************/
RsChatAvatarItem::~RsChatAvatarItem()
@ -477,6 +502,41 @@ RsChatAvatarItem::~RsChatAvatarItem()
}
}
bool RsChatDHPublicKeyItem::serialise(void *data,uint32_t& pktsize)
{
uint32_t tlvsize = serial_size() ;
uint32_t offset = 0;
if (pktsize < tlvsize)
return false; /* not enough space */
pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, PacketId(), tlvsize);
/* skip the header */
offset += 8;
uint32_t s = BN_num_bytes(public_key) ;
ok &= setRawUInt32(data, tlvsize, &offset, s);
BN_bn2bin(public_key,&((unsigned char *)data)[offset]) ;
offset += s ;
ok &= signature.SetTlv(data, tlvsize, &offset);
ok &= gxs_key.SetTlv(data, tlvsize, &offset);
if (offset != tlvsize)
{
ok = false;
std::cerr << "RsChatDHPublicKeyItem::serialiseItem() Size Error! offset=" << offset << ", tlvsize=" << tlvsize << std::endl;
}
return ok ;
}
/* serialise the data to the buffer */
bool RsChatMsgItem::serialise(void *data, uint32_t& pktsize)
{
@ -981,6 +1041,28 @@ bool RsChatLobbyConfigItem::serialise(void *data, uint32_t& pktsize)
return ok;
}
RsChatDHPublicKeyItem::RsChatDHPublicKeyItem(void *data,uint32_t /*size*/)
: RsChatItem(RS_PKT_SUBTYPE_DISTANT_CHAT_DH_PUBLIC_KEY)
{
uint32_t offset = 8; // skip the header
uint32_t rssize = getRsItemSize(data);
bool ok = true ;
uint32_t s=0 ;
/* get mandatory parts first */
ok &= getRawUInt32(data, rssize, &offset, &s);
public_key = BN_bin2bn(&((unsigned char *)data)[offset],s,NULL) ;
offset += s ;
ok &= signature.GetTlv(data, rssize, &offset) ;
ok &= gxs_key.GetTlv(data, rssize, &offset) ;
if (offset != rssize)
std::cerr << "RsChatDHPublicKeyItem::() Size error while deserializing." << std::endl ;
if (!ok)
std::cerr << "RsChatDHPublicKeyItem::() Unknown error while deserializing." << std::endl ;
}
RsChatMsgItem::RsChatMsgItem(void *data,uint32_t /*size*/,uint8_t subtype)
: RsChatItem(subtype)
{

View file

@ -28,7 +28,10 @@
#include <map>
#include "openssl/bn.h"
#include "retroshare/rstypes.h"
#include "serialiser/rstlvkeys.h"
#include "serialiser/rsserviceids.h"
#include "serialiser/rsserial.h"
@ -76,6 +79,7 @@ const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_deprecated2 = 0x11 ; // to be remov
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_LIST = 0x12 ;
const uint8_t RS_PKT_SUBTYPE_DISTANT_INVITE_CONFIG = 0x13 ;
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_CONFIG = 0x15 ;
const uint8_t RS_PKT_SUBTYPE_DISTANT_CHAT_DH_PUBLIC_KEY = 0x16 ;
// for defining tags themselves and msg tags
const uint8_t RS_PKT_SUBTYPE_MSG_TAG_TYPE = 0x03;
@ -87,6 +91,7 @@ const uint8_t RS_PKT_SUBTYPE_MSG_INVITE = 0x07;
typedef uint64_t ChatLobbyId ;
typedef uint64_t ChatLobbyMsgId ;
typedef std::string ChatLobbyNickName ;
typedef uint64_t DistantChatDHSessionId ;
class RsChatItem: public RsItem
{
@ -402,6 +407,32 @@ class RsChatAvatarItem: public RsChatItem
unsigned char *image_data ; // image
};
// This class contains the public Diffie-Hellman parameters to be sent
// when performing a DH agreement over a distant chat tunnel.
//
class RsChatDHPublicKeyItem: public RsChatItem
{
public:
RsChatDHPublicKeyItem() :RsChatItem(RS_PKT_SUBTYPE_DISTANT_CHAT_DH_PUBLIC_KEY) {setPriorityLevel(QOS_PRIORITY_RS_CHAT_ITEM) ;}
RsChatDHPublicKeyItem(void *data,uint32_t size) ; // deserialization
virtual ~RsChatDHPublicKeyItem() { BN_free(public_key) ; }
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ?
virtual uint32_t serial_size() ; // deserialise is handled using a constructor
// Private data to DH public key item
//
BIGNUM *public_key ;
RsTlvKeySignature signature ; // signs the public key in a row.
RsTlvSecurityKey gxs_key ; // public key of the signer
private:
RsChatDHPublicKeyItem(const RsChatDHPublicKeyItem&) : RsChatItem(RS_PKT_SUBTYPE_DISTANT_CHAT_DH_PUBLIC_KEY) {} // make the object non copy-able
const RsChatDHPublicKeyItem& operator=(const RsChatDHPublicKeyItem&) { return *this ;}
};
class RsChatSerialiser: public RsSerialType
{

View file

@ -32,6 +32,9 @@
#define TLV_DEBUG 1
// This should be removed eventually, but will break backward compatibility
#define KEEP_OLD_SIGNATURE_SERIALISE_FORMAT
/************************************* RsTlvSecurityKey ************************************/
RsTlvSecurityKey::RsTlvSecurityKey()
@ -67,7 +70,11 @@ uint32_t RsTlvSecurityKey::TlvSize() const
/* now add comment and title length of this tlv object */
s += GetTlvStringSize(keyId);
#ifdef KEEP_OLD_SIGNATURE_SERIALISE_FORMAT
s += GetTlvStringSize(keyId.toStdString()) ;
#else
s += keyId.serial_size();
#endif
s += 4;
s += 4;
s += 4;
@ -85,10 +92,10 @@ bool RsTlvSecurityKey::SetTlv(void *data, uint32_t size, uint32_t *offset) cons
if (size < tlvend)
{
#ifdef TLV_DEBUG
//#ifdef TLV_DEBUG
std::cerr << "RsTlvSecurityKey::SetTlv() Failed not enough space";
std::cerr << std::endl;
#endif
//#endif
return false; /* not enough space */
}
@ -99,7 +106,11 @@ bool RsTlvSecurityKey::SetTlv(void *data, uint32_t size, uint32_t *offset) cons
ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_SECURITYKEY, tlvsize);
ok &= SetTlvString(data, tlvend, offset, TLV_TYPE_STR_KEYID, keyId);
#ifdef KEEP_OLD_SIGNATURE_SERIALISE_FORMAT
ok &= SetTlvString(data, tlvend, offset, TLV_TYPE_STR_KEYID, keyId.toStdString());
#else
ok &= keyId.serialise(data, tlvend, *offset) ;
#endif
ok &= setRawUInt32(data, tlvend, offset, keyFlags);
ok &= setRawUInt32(data, tlvend, offset, startTS);
ok &= setRawUInt32(data, tlvend, offset, endTS);
@ -145,7 +156,13 @@ bool RsTlvSecurityKey::GetTlv(void *data, uint32_t size, uint32_t *offset)
/* skip the header */
(*offset) += TLV_HEADER_SIZE;
ok &= GetTlvString(data, tlvend, offset, TLV_TYPE_STR_KEYID, keyId);
#ifdef KEEP_OLD_SIGNATURE_SERIALISE_FORMAT
std::string s ;
ok &= GetTlvString(data, tlvend, offset, TLV_TYPE_STR_KEYID, s);
keyId = RsGxsId(s) ;
#else
ok &= keyId.deserialise(data, tlvend, *offset) ;
#endif
ok &= getRawUInt32(data, tlvend, offset, &(keyFlags));
ok &= getRawUInt32(data, tlvend, offset, &(startTS));
ok &= getRawUInt32(data, tlvend, offset, &(endTS));
@ -224,7 +241,7 @@ uint32_t RsTlvSecurityKeySet::TlvSize() const
uint32_t s = TLV_HEADER_SIZE; /* header */
std::map<std::string, RsTlvSecurityKey>::const_iterator it;
std::map<RsGxsId, RsTlvSecurityKey>::const_iterator it;
s += GetTlvStringSize(groupId);
@ -264,7 +281,7 @@ bool RsTlvSecurityKeySet::SetTlv(void *data, uint32_t size, uint32_t *offset) c
if(!keys.empty())
{
std::map<std::string, RsTlvSecurityKey>::const_iterator it;
std::map<RsGxsId, RsTlvSecurityKey>::const_iterator it;
for(it = keys.begin(); it != keys.end() ; ++it)
ok &= (it->second).SetTlv(data, size, offset);
@ -361,7 +378,7 @@ std::ostream &RsTlvSecurityKeySet::print(std::ostream &out, uint16_t indent) con
out << "GroupId: " << groupId;
out << std::endl;
std::map<std::string, RsTlvSecurityKey>::const_iterator it;
std::map<RsGxsId, RsTlvSecurityKey>::const_iterator it;
for(it = keys.begin(); it != keys.end() ; ++it)
(it->second).print(out, int_Indent);
@ -396,7 +413,11 @@ uint32_t RsTlvKeySignature::TlvSize() const
{
uint32_t s = TLV_HEADER_SIZE; /* header + 4 for size */
s += GetTlvStringSize(keyId);
#ifdef KEEP_OLD_SIGNATURE_SERIALISE_FORMAT
s += GetTlvStringSize(keyId.toStdString()) ;
#else
s += keyId.serial_size() ;
#endif
s += signData.TlvSize();
return s;
@ -424,7 +445,11 @@ bool RsTlvKeySignature::SetTlv(void *data, uint32_t size, uint32_t *offset) con
ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_KEYSIGNATURE, tlvsize);
ok &= SetTlvString(data, tlvend, offset, TLV_TYPE_STR_KEYID, keyId);
#ifdef KEEP_OLD_SIGNATURE_SERIALISE_FORMAT
ok &= SetTlvString(data, tlvend, offset, TLV_TYPE_STR_KEYID, keyId.toStdString());
#else
ok &= keyId.serialise(data, tlvend, *offset) ;
#endif
ok &= signData.SetTlv(data, tlvend, offset);
if (!ok)
@ -475,7 +500,13 @@ bool RsTlvKeySignature::GetTlv(void *data, uint32_t size, uint32_t *offset)
/* skip the header */
(*offset) += TLV_HEADER_SIZE;
ok &= GetTlvString(data, tlvend, offset, TLV_TYPE_STR_KEYID, keyId);
#ifdef KEEP_OLD_SIGNATURE_SERIALISE_FORMAT
std::string s ;
ok &= GetTlvString(data, tlvend, offset, TLV_TYPE_STR_KEYID, s);
keyId = RsGxsId(s) ;
#else
ok &= keyId.deserialise(data, tlvend, *offset) ;
#endif
ok &= signData.GetTlv(data, tlvend, offset);
/***************************************************************************

View file

@ -31,6 +31,7 @@
#include "serialiser/rstlvitem.h"
#include "serialiser/rstlvbinary.h"
#include "retroshare/rsgxsifacetypes.h"
#include <map>
@ -48,22 +49,23 @@ const uint32_t RSTLV_KEY_DISTRIB_IDENTITY = 0x0080;
class RsTlvSecurityKey: public RsTlvItem
{
public:
RsTlvSecurityKey();
virtual ~RsTlvSecurityKey() { return; }
virtual uint32_t TlvSize() const;
virtual void TlvClear();
virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) const;
virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset);
virtual std::ostream &print(std::ostream &out, uint16_t indent) const;
RsTlvSecurityKey();
virtual ~RsTlvSecurityKey() {}
/* clears KeyData - but doesn't delete - to transfer ownership */
void ShallowClear();
virtual uint32_t TlvSize() const;
virtual void TlvClear();
virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) const;
virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset);
virtual std::ostream &print(std::ostream &out, uint16_t indent) const;
std::string keyId; // Mandatory :
uint32_t keyFlags; // Mandatory ;
uint32_t startTS; // Mandatory :
uint32_t endTS; // Mandatory :
RsTlvBinaryData keyData; // Mandatory :
/* clears KeyData - but doesn't delete - to transfer ownership */
void ShallowClear();
RsGxsId keyId; // Mandatory :
uint32_t keyFlags; // Mandatory ;
uint32_t startTS; // Mandatory :
uint32_t endTS; // Mandatory :
RsTlvBinaryData keyData; // Mandatory :
};
class RsTlvSecurityKeySet: public RsTlvItem
@ -78,26 +80,25 @@ virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset);
virtual std::ostream &print(std::ostream &out, uint16_t indent) const;
std::string groupId; // Mandatory :
std::map<std::string, RsTlvSecurityKey> keys; // Mandatory :
std::map<RsGxsId, RsTlvSecurityKey> keys; // Mandatory :
};
class RsTlvKeySignature: public RsTlvItem
{
public:
RsTlvKeySignature();
virtual ~RsTlvKeySignature() { return; }
virtual uint32_t TlvSize() const;
virtual void TlvClear();
virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) const;
virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset);
virtual std::ostream &print(std::ostream &out, uint16_t indent) const;
RsTlvKeySignature();
virtual ~RsTlvKeySignature() { return; }
virtual uint32_t TlvSize() const;
virtual void TlvClear();
virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) const;
virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset);
virtual std::ostream &print(std::ostream &out, uint16_t indent) const;
void ShallowClear(); /* clears signData - but doesn't delete */
void ShallowClear(); /* clears signData - but doesn't delete */
std::string keyId; // Mandatory :
RsTlvBinaryData signData; // Mandatory :
// NO Certificates in Signatures... add as separate data type.
RsGxsId keyId; // Mandatory :
RsTlvBinaryData signData; // Mandatory :
};
typedef uint32_t SignType;