separated RsTlvSecurityKey into two incompatible classes to enforce the correct usage of private vs. public keys

This commit is contained in:
csoler 2016-06-02 23:47:57 -04:00
parent cbef01451c
commit 590be092e5
26 changed files with 600 additions and 351 deletions

View file

@ -117,7 +117,7 @@ virtual void clear();
std::ostream &print(std::ostream &out, uint16_t indent = 0);
RsTlvServiceIdSet signing_classes;
RsTlvSecurityKey key; // has from->to, and flags.
RsTlvSecurityKey_deprecated key; // has from->to, and flags.
RsTlvKeySignature sign;
};

View file

@ -1237,7 +1237,7 @@ RsNxsGrp* RsNxsGrp::clone() const {
if(this->metaData)
{
grp->metaData = new RsGxsGrpMetaData();
*(grp->metaData) = *(this->metaData);
// *(grp->metaData) = *(this->metaData);
}
return grp;

View file

@ -157,7 +157,8 @@ public:
virtual uint32_t serial_size() const;
RsGxsGroupId grpId ;
RsTlvSecurityKey key ;
#warning should be renamed private_key
RsTlvPrivateRSAKey key ;
};
@ -330,9 +331,12 @@ public:
* This should contains all data
* which is not specific to the Gxs service data
*/
// This is the binary data for the group meta that is sent to friends. It *should not* contain any private
// key parts. This is ensured in RsGenExchange
RsTlvBinaryData meta;
// deserialised metaData, this is not serialised
// Deserialised metaData, this is not serialised by the serialize() method. So it may contain private key parts in some cases.
RsGxsGrpMetaData* metaData;
};

View file

@ -207,8 +207,10 @@ const uint16_t TLV_TYPE_GXSCIRCLEIDSET= 0x1026;
const uint16_t TLV_TYPE_SERVICESET = 0x1030;
const uint16_t TLV_TYPE_SECURITYKEY = 0x1040;
const uint16_t TLV_TYPE_SECURITYKEYSET= 0x1041;
const uint16_t TLV_TYPE_SECURITYKEY_deprecated = 0x1040;
const uint16_t TLV_TYPE_SECURITYKEYSET = 0x1041;
const uint16_t TLV_TYPE_RSA_KEY_PUBLIC = 0x1042;
const uint16_t TLV_TYPE_RSA_KEY_PRIVATE= 0x1043;
const uint16_t TLV_TYPE_KEYSIGNATURE = 0x1050;
const uint16_t TLV_TYPE_KEYSIGNATURESET = 0x1051;

View file

@ -27,6 +27,7 @@
#include "rstlvkeys.h"
#include "rstlvbase.h"
#include "rsbaseserial.h"
#include "util/stacktrace.h"
#include <iostream>
@ -37,13 +38,13 @@
/************************************* RsTlvSecurityKey ************************************/
RsTlvSecurityKey::RsTlvSecurityKey()
RsTlvSecurityKey_deprecated::RsTlvSecurityKey_deprecated()
:RsTlvItem(), keyFlags(0), startTS(0), endTS(0), keyData(TLV_TYPE_KEY_EVP_PKEY)
{
return;
}
void RsTlvSecurityKey::TlvClear()
void RsTlvSecurityKey_deprecated::TlvClear()
{
keyId.clear();
keyFlags = 0;
@ -53,7 +54,7 @@ void RsTlvSecurityKey::TlvClear()
}
/* clears keyData - but doesn't delete */
void RsTlvSecurityKey::ShallowClear()
void RsTlvSecurityKey_deprecated::ShallowClear()
{
keyId.clear();
keyFlags = 0;
@ -63,8 +64,22 @@ void RsTlvSecurityKey::ShallowClear()
keyData.bin_len = 0;
}
uint32_t RsTlvRSAKey::TlvSize() const
{
uint32_t s = TLV_HEADER_SIZE; /* header + 4 for size */
uint32_t RsTlvSecurityKey::TlvSize() const
/* now add comment and title length of this tlv object */
s += keyId.serial_size();
s += 4;
s += 4;
s += 4;
s += keyData.TlvSize();
return s;
}
uint32_t RsTlvSecurityKey_deprecated::TlvSize() const
{
uint32_t s = TLV_HEADER_SIZE; /* header + 4 for size */
@ -81,15 +96,48 @@ uint32_t RsTlvSecurityKey::TlvSize() const
s += keyData.TlvSize();
return s;
}
bool RsTlvSecurityKey::SetTlv(void *data, uint32_t size, uint32_t *offset) const
bool RsTlvRSAKey::SetTlv(void *data, uint32_t size, uint32_t *offset) const
{
/* must check sizes */
uint32_t tlvsize = TlvSize();
uint32_t tlvend = *offset + tlvsize;
if (size < tlvend)
{
std::cerr << "RsTlvSecurityKey::SetTlv() Failed not enough space";
std::cerr << std::endl;
return false; /* not enough space */
}
bool ok = checkFlags(keyFlags); // check before serialise, just in case
/* start at data[offset] */
/* add mandatory parts first */
ok &= SetTlvBase(data, tlvend, offset, tlvType(), tlvsize);
ok &= keyId.serialise(data, tlvend, *offset) ;
ok &= setRawUInt32(data, tlvend, offset, keyFlags);
ok &= setRawUInt32(data, tlvend, offset, startTS);
ok &= setRawUInt32(data, tlvend, offset, endTS);
ok &= keyData.SetTlv(data, tlvend, offset);
return ok;
}
bool RsTlvSecurityKey_deprecated::SetTlv(void *data, uint32_t size, uint32_t *offset) const
{
std::cerr << "(EE) Serialisation of an old security key format. Will not be done! callstack is:" << std::cerr << std::endl;
print_stacktrace() ;
#warning REMOVE THIS CODE BELOW WHEN IT IS NOT CALLED ANYMORE
/* must check sizes */
uint32_t tlvsize = TlvSize();
uint32_t tlvend = *offset + tlvsize;
if (size < tlvend)
{
//#ifdef TLV_DEBUG
@ -104,7 +152,7 @@ bool RsTlvSecurityKey::SetTlv(void *data, uint32_t size, uint32_t *offset) cons
/* start at data[offset] */
/* add mandatory parts first */
ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_SECURITYKEY, tlvsize);
ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_SECURITYKEY_deprecated, tlvsize);
#ifdef KEEP_OLD_SIGNATURE_SERIALISE_FORMAT
ok &= SetTlvString(data, tlvend, offset, TLV_TYPE_STR_KEYID, keyId.toStdString());
@ -120,8 +168,7 @@ bool RsTlvSecurityKey::SetTlv(void *data, uint32_t size, uint32_t *offset) cons
}
bool RsTlvSecurityKey::GetTlv(void *data, uint32_t size, uint32_t *offset)
bool RsTlvRSAKey::GetTlv(void *data, uint32_t size, uint32_t *offset)
{
if (size < *offset + TLV_HEADER_SIZE)
return false;
@ -139,7 +186,75 @@ bool RsTlvSecurityKey::GetTlv(void *data, uint32_t size, uint32_t *offset)
return false; /* not enough space */
}
if (tlvtype != TLV_TYPE_SECURITYKEY) /* check type */
if (tlvtype != tlvType()) /* check type */
{
#ifdef TLV_DEBUG
std::cerr << "RsTlvSecurityKey::GetTlv() Fail, wrong type";
std::cerr << std::endl;
#endif
return false;
}
bool ok = true;
/* ready to load */
TlvClear();
/* skip the header */
(*offset) += TLV_HEADER_SIZE;
ok &= keyId.deserialise(data, tlvend, *offset) ;
ok &= getRawUInt32(data, tlvend, offset, &(keyFlags));
ok &= getRawUInt32(data, tlvend, offset, &(startTS));
ok &= getRawUInt32(data, tlvend, offset, &(endTS));
ok &= keyData.GetTlv(data, tlvend, offset);
ok &= checkFlags(keyFlags) ;
/***************************************************************************
* NB: extra components could be added (for future expansion of the type).
* or be present (if this code is reading an extended version).
*
* We must chew up the extra characters to conform with TLV specifications
***************************************************************************/
if (*offset != tlvend)
{
#ifdef TLV_DEBUG
std::cerr << "RsTlvSecurityKey::GetTlv() Warning extra bytes at end of item";
std::cerr << std::endl;
#endif
*offset = tlvend;
}
if (!ok)
{
#ifdef TLV_DEBUG
std::cerr << "RsTlvSecurityKey::GetTlv() Failed somewhere ok == false";
std::cerr << std::endl;
#endif
}
return ok;
}
bool RsTlvSecurityKey_deprecated::GetTlv(void *data, uint32_t size, uint32_t *offset)
{
if (size < *offset + TLV_HEADER_SIZE)
return false;
uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) );
uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) );
uint32_t tlvend = *offset + tlvsize;
if (size < tlvend) /* check size */
{
#ifdef TLV_DEBUG
std::cerr << "RsTlvSecurityKey::GetTlv() Fail, not enough space";
std::cerr << std::endl;
#endif
return false; /* not enough space */
}
if (tlvtype != TLV_TYPE_SECURITYKEY_deprecated) /* check type */
{
#ifdef TLV_DEBUG
std::cerr << "RsTlvSecurityKey::GetTlv() Fail, wrong type";
@ -196,7 +311,7 @@ bool RsTlvSecurityKey::GetTlv(void *data, uint32_t size, uint32_t *offset)
}
std::ostream &RsTlvSecurityKey::print(std::ostream &out, uint16_t indent) const
std::ostream &RsTlvSecurityKey_deprecated::print(std::ostream &out, uint16_t indent) const
{
printBase(out, "RsTlvSecurityKey", indent);
uint16_t int_Indent = indent + 2;
@ -233,7 +348,10 @@ std::ostream &RsTlvSecurityKey::print(std::ostream &out, uint16_t indent) const
void RsTlvSecurityKeySet::TlvClear()
{
groupId.clear();
keys.clear(); //empty list
#ifdef TODO
public_keys.clear(); //empty list
private_keys.clear(); //empty list
#endif
}
uint32_t RsTlvSecurityKeySet::TlvSize() const
@ -241,17 +359,13 @@ uint32_t RsTlvSecurityKeySet::TlvSize() const
uint32_t s = TLV_HEADER_SIZE; /* header */
std::map<RsGxsId, RsTlvSecurityKey>::const_iterator it;
s += GetTlvStringSize(groupId);
if(!keys.empty())
{
for(it = keys.begin(); it != keys.end() ; ++it)
s += (it->second).TlvSize();
}
for(std::map<RsGxsId, RsTlvPublicRSAKey>::const_iterator it = public_keys.begin(); it != public_keys.end() ; ++it)
s += (it->second).TlvSize();
for(std::map<RsGxsId, RsTlvPrivateRSAKey>::const_iterator it = private_keys.begin(); it != private_keys.end() ; ++it)
s += (it->second).TlvSize();
return s;
}
@ -279,17 +393,13 @@ bool RsTlvSecurityKeySet::SetTlv(void *data, uint32_t size, uint32_t *offset) c
/* groupId */
ok &= SetTlvString(data, tlvend, offset, TLV_TYPE_STR_GROUPID, groupId);
if(!keys.empty())
{
std::map<RsGxsId, RsTlvSecurityKey>::const_iterator it;
for(it = keys.begin(); it != keys.end() ; ++it)
for(std::map<RsGxsId, RsTlvPublicRSAKey>::const_iterator it = public_keys.begin(); it != public_keys.end() ; ++it)
ok &= (it->second).SetTlv(data, size, offset);
for(std::map<RsGxsId, RsTlvPrivateRSAKey>::const_iterator it = private_keys.begin(); it != private_keys.end() ; ++it)
ok &= (it->second).SetTlv(data, size, offset);
}
return ok;
return ok;
}
@ -319,37 +429,72 @@ bool RsTlvSecurityKeySet::GetTlv(void *data, uint32_t size, uint32_t *offset)
/* groupId */
ok &= GetTlvString(data, tlvend, offset, TLV_TYPE_STR_GROUPID, groupId);
/* while there is TLV */
while((*offset) + 2 < tlvend)
{
/* get the next type */
uint16_t tlvsubtype = GetTlvType( &(((uint8_t *) data)[*offset]) );
/* while there is TLV */
while((*offset) + 2 < tlvend)
{
/* get the next type */
uint16_t tlvsubtype = GetTlvType( &(((uint8_t *) data)[*offset]) );
switch(tlvsubtype)
{
case TLV_TYPE_SECURITYKEY:
switch(tlvsubtype)
{
case TLV_TYPE_SECURITYKEY_deprecated:
{
RsTlvSecurityKey_deprecated key;
ok &= key.GetTlv(data, size, offset);
if (ok)
{
RsTlvSecurityKey key;
ok &= key.GetTlv(data, size, offset);
if (ok)
{
keys[key.keyId] = key;
key.TlvClear(); /* so that the Map can get control - should be ref counted*/
}
std::cerr << "(WW) read RSA key with old format. Will be converted to new format. Flags=" << std::hex << key.keyFlags << std::dec << std::endl;
if(key.keyFlags & RSTLV_KEY_TYPE_FULL)
private_keys[key.keyId] = RsTlvPrivateRSAKey(key);
else
public_keys[key.keyId] = RsTlvPublicRSAKey(key);
key.TlvClear(); /* so that the Map can get control - should be ref counted*/
}
break;
default:
ok &= SkipUnknownTlv(data, tlvend, offset);
break;
}
break ;
}
case TLV_TYPE_RSA_KEY_PRIVATE:
{
RsTlvPrivateRSAKey key;
if (!ok)
if(key.GetTlv(data, size, offset))
private_keys[key.keyId] = key;
else
ok = false ;
key.TlvClear(); /* so that the Map can get control - should be ref counted*/
}
break;
case TLV_TYPE_RSA_KEY_PUBLIC:
{
RsTlvPublicRSAKey key;
if(key.GetTlv(data, size, offset))
public_keys[key.keyId] = key;
else
ok = false ;
key.TlvClear(); /* so that the Map can get control - should be ref counted*/
}
break;
default:
ok &= SkipUnknownTlv(data, tlvend, offset);
break;
}
if (!ok)
break;
}
/***************************************************************************
* NB: extra components could be added (for future expansion of the type).
* or be present (if this code is reading an extended version).
@ -378,8 +523,9 @@ std::ostream &RsTlvSecurityKeySet::print(std::ostream &out, uint16_t indent) con
out << "GroupId: " << groupId;
out << std::endl;
std::map<RsGxsId, RsTlvSecurityKey>::const_iterator it;
for(it = keys.begin(); it != keys.end() ; ++it)
for( std::map<RsGxsId, RsTlvPublicRSAKey>::const_iterator it = public_keys.begin(); it != public_keys.end() ; ++it)
(it->second).print(out, int_Indent);
for( std::map<RsGxsId, RsTlvPrivateRSAKey>::const_iterator it = private_keys.begin(); it != private_keys.end() ; ++it)
(it->second).print(out, int_Indent);
printEnd(out, "RsTlvSecurityKeySet", indent);

View file

@ -31,6 +31,7 @@
#include "serialiser/rstlvitem.h"
#include "serialiser/rstlvbinary.h"
#include "serialiser/rstlvbase.h"
#include "retroshare/rsgxsifacetypes.h"
#include <map>
@ -46,11 +47,13 @@ const uint32_t RSTLV_KEY_DISTRIB_ADMIN = 0x0040;
const uint32_t RSTLV_KEY_DISTRIB_IDENTITY = 0x0080;
const uint32_t RSTLV_KEY_DISTRIB_MASK = 0x00f0;
class RsTlvSecurityKey: public RsTlvItem
// Old class for RsTlvSecurityKey. Is kept for backward compatibility, but should not be serialised anymore
class RsTlvSecurityKey_deprecated: public RsTlvItem
{
public:
RsTlvSecurityKey();
virtual ~RsTlvSecurityKey() {}
RsTlvSecurityKey_deprecated();
virtual ~RsTlvSecurityKey_deprecated() {}
virtual uint32_t TlvSize() const;
virtual void TlvClear();
@ -61,26 +64,83 @@ class RsTlvSecurityKey: public RsTlvItem
/* clears KeyData - but doesn't delete - to transfer ownership */
void ShallowClear();
RsGxsId keyId; // Mandatory :
RsGxsId keyId; // Mandatory :
uint32_t keyFlags; // Mandatory ;
uint32_t startTS; // Mandatory :
uint32_t endTS; // Mandatory :
RsTlvBinaryData keyData; // Mandatory :
};
class RsTlvRSAKey
{
public:
virtual uint32_t tlvType() const = 0 ;
virtual bool checkFlags(uint32_t flags) const = 0 ;
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;
/* clears KeyData - but doesn't delete - to transfer ownership */
void ShallowClear();
bool check() const { return checkFlags(keyFlags) && (!keyId.isNull()) ; }
RsGxsId keyId; // Mandatory :
uint32_t keyFlags; // Mandatory ;
uint32_t startTS; // Mandatory :
uint32_t endTS; // Mandatory :
RsTlvBinaryData keyData; // Mandatory :
};
// The two classes below are by design incompatible, making it impossible to pass a private key as a public key
class RsTlvPrivateRSAKey: public RsTlvRSAKey
{
public:
RsTlvPrivateRSAKey();
explicit RsTlvPrivateRSAKey(RsTlvSecurityKey_deprecated& key); // convertion tool. Should be called explicitely and performs some checks
virtual ~RsTlvPrivateRSAKey() {}
virtual bool checkFlags(uint32_t flags) const { return bool(flags & RSTLV_KEY_TYPE_FULL) && !bool(flags & RSTLV_KEY_TYPE_PUBLIC_ONLY) ; }
virtual uint32_t tlvType() const { return TLV_TYPE_RSA_KEY_PRIVATE ; }
};
class RsTlvPublicRSAKey: public RsTlvRSAKey
{
#warning TEST IF WE CAN CONVERT PUBLIC TO PRIVATE AND VIS VERSA. NORMALLY WE SHOULDNT
public:
RsTlvPublicRSAKey();
virtual ~RsTlvPublicRSAKey() {}
explicit RsTlvPublicRSAKey(RsTlvSecurityKey_deprecated& key); // convertion tool. Should be called explicitely and performs some checks
virtual bool checkFlags(uint32_t flags) const { return bool(flags & RSTLV_KEY_TYPE_PUBLIC_ONLY) && !bool(flags & RSTLV_KEY_TYPE_FULL) ; }
virtual uint32_t tlvType() const { return TLV_TYPE_RSA_KEY_PUBLIC ; }
};
class RsTlvSecurityKeySet: public RsTlvItem
{
public:
RsTlvSecurityKeySet() { return; }
virtual ~RsTlvSecurityKeySet() { 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;
public:
RsTlvSecurityKeySet() { return; }
virtual ~RsTlvSecurityKeySet() { return; }
void initFromPublicKeys(const RsTlvSecurityKeySet& skset) ;
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 groupId; // Mandatory :
std::map<RsGxsId, RsTlvSecurityKey> keys; // Mandatory :
std::string groupId; // Mandatory :
std::map<RsGxsId, RsTlvPublicRSAKey> public_keys; // Mandatory :
std::map<RsGxsId, RsTlvPrivateRSAKey> private_keys; // Mandatory :
//private:
// RsTlvSecurityKeySet& operator=(const RsTlvSecurityKeySet&) { std::cerr << "(EE) " <<__PRETTY_FUNCTION__ << " shouldn't be called!" << std::endl; return *this;}
// RsTlvSecurityKeySet(const RsTlvSecurityKeySet&) { std::cerr << "(EE) " <<__PRETTY_FUNCTION__ << " shouldn't be called!" << std::endl;}
};