Safer rsids API

Deprecate unsafe costructor, substituted by fromBufferUnsafe which explicitely
  marked suggest the caller to pay attention.
Use enum class for id types instead of constants
Make size constants more private
Use internal Id_t alias to avoid huge template lines
Remove and deprecate oguly names in favor of consistent names
This commit is contained in:
Gioacchino Mazzurco 2019-04-28 18:10:17 +02:00
parent ccf7dc24b8
commit 7642216912
No known key found for this signature in database
GPG Key ID: A1FBCA3872E87051
12 changed files with 337 additions and 267 deletions

View File

@ -67,13 +67,10 @@ uint32_t msecs_of_day()
static const uint32_t DISTANT_CHAT_GXS_TUNNEL_SERVICE_ID = 0xa0001 ;
typedef RsGxsTunnelService::RsGxsTunnelId RsGxsTunnelId;
DistantChatService::DistantChatService() : mDistantChatMtx("distant chat")
{
mGxsTunnels = NULL ;
mDistantChatPermissions = RS_DISTANT_CHAT_CONTACT_PERMISSION_FLAG_FILTER_NONE ; // default: accept everyone
}
DistantChatService::DistantChatService() :
// default: accept everyone
mDistantChatPermissions(RS_DISTANT_CHAT_CONTACT_PERMISSION_FLAG_FILTER_NONE),
mGxsTunnels(nullptr), mDistantChatMtx("distant chat") {}
void DistantChatService::connectToGxsTunnelService(RsGxsTunnelService *tr)
{
@ -181,7 +178,8 @@ bool DistantChatService::acceptDataFromPeer(const RsGxsId& gxs_id,const RsGxsTun
return res ;
}
void DistantChatService::notifyTunnelStatus(const RsGxsTunnelService::RsGxsTunnelId &tunnel_id, uint32_t tunnel_status)
void DistantChatService::notifyTunnelStatus(
const RsGxsTunnelId& tunnel_id, uint32_t tunnel_status )
{
#ifdef DEBUG_DISTANT_CHAT
DISTANT_CHAT_DEBUG() << "DistantChatService::notifyTunnelStatus(): got notification " << std::hex << tunnel_status << std::dec << " for tunnel " << tunnel_id << std::endl;
@ -207,7 +205,8 @@ void DistantChatService::notifyTunnelStatus(const RsGxsTunnelService::RsGxsTunne
}
}
void DistantChatService::receiveData(const RsGxsTunnelService::RsGxsTunnelId &tunnel_id, unsigned char *data, uint32_t data_size)
void DistantChatService::receiveData(
const RsGxsTunnelId& tunnel_id, unsigned char* data, uint32_t data_size)
{
#ifdef DEBUG_DISTANT_CHAT
DISTANT_CHAT_DEBUG() << "DistantChatService::receiveData(): got data of size " << std::dec << data_size << " for tunnel " << tunnel_id << std::endl;
@ -249,7 +248,8 @@ void DistantChatService::receiveData(const RsGxsTunnelService::RsGxsTunnelId &tu
void DistantChatService::markDistantChatAsClosed(const DistantChatPeerId& dcpid)
{
mGxsTunnels->closeExistingTunnel(RsGxsTunnelService::RsGxsTunnelId(dcpid),DISTANT_CHAT_GXS_TUNNEL_SERVICE_ID) ;
mGxsTunnels->closeExistingTunnel(
RsGxsTunnelId(dcpid), DISTANT_CHAT_GXS_TUNNEL_SERVICE_ID );
RS_STACK_MUTEX(mDistantChatMtx) ;

View File

@ -30,12 +30,13 @@ class RsGixs ;
static const uint32_t DISTANT_CHAT_AES_KEY_SIZE = 16 ;
/**
* Public interface only uses DistandChatPeerId, but internally, this is
* converted into a RsGxsTunnelId
*/
class DistantChatService: public RsGxsTunnelService::RsGxsTunnelClientService
{
public:
// So, public interface only uses DistandChatPeerId, but internally, this is converted into a RsGxsTunnelService::RsGxsTunnelId
DistantChatService() ;
virtual void triggerConfigSave()=0 ;
@ -91,9 +92,13 @@ public:
virtual void connectToGxsTunnelService(RsGxsTunnelService *tunnel_service) ;
private:
virtual bool acceptDataFromPeer(const RsGxsId& gxs_id, const RsGxsTunnelService::RsGxsTunnelId& tunnel_id, bool am_I_client_side) ;
virtual void notifyTunnelStatus(const RsGxsTunnelService::RsGxsTunnelId& tunnel_id,uint32_t tunnel_status) ;
virtual void receiveData(const RsGxsTunnelService::RsGxsTunnelId& id,unsigned char *data,uint32_t data_size) ;
virtual bool acceptDataFromPeer(
const RsGxsId& gxs_id, const RsGxsTunnelId& tunnel_id,
bool am_I_client_side);
virtual void notifyTunnelStatus(
const RsGxsTunnelId& tunnel_id, uint32_t tunnel_status);
virtual void receiveData(
const RsGxsTunnelId& id, unsigned char* data, uint32_t data_size );
// Utility functions.

View File

@ -47,10 +47,10 @@ namespace librs
template<class T> friend HashStream& operator<<(HashStream& u, const T&) ;
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER>
friend HashStream& operator<<(HashStream& u,const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& r)
template<uint32_t ID_SIZE_IN_BYTES, bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
friend HashStream& operator<<(HashStream& u, const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& r)
{
EVP_DigestUpdate(u.mdctx,r.toByteArray(),ID_SIZE_IN_BYTES);
EVP_DigestUpdate(u.mdctx, r.toByteArray(), ID_SIZE_IN_BYTES);
return u;
}
private:

View File

@ -92,8 +92,6 @@
* as these will be used very frequently.
*****/
typedef PGPIdType RsPgpId;
/* Identity Interface for GXS Message Verification.
*/
class RsGixs

View File

@ -217,7 +217,9 @@ bool GrpCircleVetting::expired()
{
return time(NULL) > (mTimeStamp + EXPIRY_PERIOD_OFFSET);
}
bool GrpCircleVetting::canSend(const SSLIdType& peerId, const RsGxsCircleId& circleId,bool& should_encrypt)
bool GrpCircleVetting::canSend(
const RsPeerId& peerId, const RsGxsCircleId& circleId,
bool& should_encrypt )
{
if(mCircles->isLoaded(circleId))
{

View File

@ -1062,7 +1062,7 @@ void p3GxsTunnelService::handleRecvDHPublicKey(RsGxsTunnelDHPublicKeyItem *item)
// Note: for some obscure reason, the typedef does not work here. Looks like a compiler error. So I use the primary type.
/*static*/ GXSTunnelId p3GxsTunnelService::makeGxsTunnelId(
/*static*/ RsGxsTunnelId p3GxsTunnelService::makeGxsTunnelId(
const RsGxsId &own_id, const RsGxsId &distant_id )
{
unsigned char mem[RsGxsId::SIZE_IN_BYTES * 2] ;

View File

@ -908,12 +908,14 @@ bool PGPHandler::checkAndImportKeyPair(ops_keyring_t *tmp_keyring, RsPgpId &impo
return false ;
}
if(pubkey == NULL || seckey == NULL || pubkey == seckey)
if(pubkey == nullptr || seckey == nullptr || pubkey == seckey)
{
import_error = "File does not contain a public and a private key. Sorry." ;
return false ;
}
if(memcmp(pubkey->fingerprint.fingerprint,seckey->fingerprint.fingerprint,PGP_KEY_FINGERPRINT_SIZE) != 0)
if(memcmp( pubkey->fingerprint.fingerprint,
seckey->fingerprint.fingerprint,
RsPpgFingerprint::SIZE_IN_BYTES ) != 0)
{
import_error = "Public and private keys do nt have the same fingerprint. Sorry!" ;
return false ;
@ -940,7 +942,10 @@ bool PGPHandler::checkAndImportKeyPair(ops_keyring_t *tmp_keyring, RsPgpId &impo
bool found = false ;
for(uint32_t i=0;i<result->valid_count;++i)
if(!memcmp((unsigned char*)result->valid_sigs[i].signer_id,pubkey->key_id,PGP_KEY_ID_SIZE))
if(!memcmp(
static_cast<uint8_t*>(result->valid_sigs[i].signer_id),
pubkey->key_id,
RsPpgFingerprint::SIZE_IN_BYTES ))
{
found = true ;
break ;
@ -1087,7 +1092,10 @@ bool PGPHandler::LoadCertificateFromString(const std::string& pgp_cert,RsPgpId&
bool found = false ;
for(uint32_t i=0;i<result->valid_count;++i)
if(!memcmp((unsigned char*)result->valid_sigs[i].signer_id,keydata->key_id,PGP_KEY_ID_SIZE))
if(!memcmp(
static_cast<uint8_t*>(result->valid_sigs[i].signer_id),
keydata->key_id,
RsPpgFingerprint::SIZE_IN_BYTES ))
{
found = true ;
break ;
@ -1164,7 +1172,9 @@ bool PGPHandler::locked_addOrMergeKey(ops_keyring_t *keyring,std::map<RsPgpId,PG
}
else
{
if(memcmp(existing_key->fingerprint.fingerprint, keydata->fingerprint.fingerprint,PGP_KEY_FINGERPRINT_SIZE))
if(memcmp( existing_key->fingerprint.fingerprint,
keydata->fingerprint.fingerprint,
RsPpgFingerprint::SIZE_IN_BYTES ))
{
std::cerr << "(EE) attempt to merge key with identical id, but different fingerprint!" << std::endl;
return false ;
@ -1792,7 +1802,8 @@ bool PGPHandler::privateTrustCertificate(const RsPgpId& id,int trustlvl)
struct PrivateTrustPacket
{
unsigned char user_id[PGP_KEY_ID_SIZE] ; // pgp id in unsigned char format.
/// pgp id in unsigned char format.
unsigned char user_id[RsPgpId::SIZE_IN_BYTES];
uint8_t trust_level ; // trust level. From 0 to 6.
uint32_t time_stamp ; // last time the cert was ever used, in seconds since the epoch. 0 means not initialized.
};
@ -1854,9 +1865,12 @@ bool PGPHandler::locked_writePrivateTrustDatabase()
}
PrivateTrustPacket trustpacket ;
for(std::map<RsPgpId,PGPCertificateInfo>::iterator it = _public_keyring_map.begin();it!=_public_keyring_map.end() ;++it)
for( std::map<RsPgpId,PGPCertificateInfo>::iterator it =
_public_keyring_map.begin(); it!=_public_keyring_map.end(); ++it )
{
memcpy(trustpacket.user_id,RsPgpId(it->first).toByteArray(),PGP_KEY_ID_SIZE) ;
memcpy( trustpacket.user_id,
it->first.toByteArray(),
RsPgpId::SIZE_IN_BYTES );
trustpacket.trust_level = it->second._trustLvl ;
trustpacket.time_stamp = it->second._time_stamp ;

View File

@ -34,10 +34,7 @@
#include "serialiser/rstypeserializer.h"
#include "util/rstime.h"
typedef GXSGroupId RsGxsGroupId;
typedef Sha1CheckSum RsGxsMessageId;
typedef GXSId RsGxsId;
typedef GXSCircleId RsGxsCircleId;
typedef std::map<RsGxsGroupId, std::set<RsGxsMessageId> > GxsMsgIdResult;
typedef std::pair<RsGxsGroupId, RsGxsMessageId> RsGxsGrpMsgIdPair;

View File

@ -29,8 +29,6 @@
class RsGxsTunnelService
{
public:
typedef GXSTunnelId RsGxsTunnelId ;
enum {
RS_GXS_TUNNEL_ERROR_NO_ERROR = 0x0000,
RS_GXS_TUNNEL_ERROR_UNKNOWN_GXS_ID = 0x0001

View File

@ -3,7 +3,8 @@
* *
* libretroshare: retroshare core library *
* *
* Copyright 2013 by Cyril Soler <csoler@users.sourceforge.net> *
* Copyright (C) 2013 Cyril Soler <csoler@users.sourceforge.net> *
* Copyright (C) 2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -19,35 +20,6 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
// This class aims at defining a generic ID type that is a list of bytes. It
// can be converted into a hexadecial string for printing, mainly) or for
// compatibility with old methods.
//
// To use this class, derive your own ID type from it. Examples include:
//
// class RsPgpId: public t_RsGenericIdType<8>
// {
// [..]
// };
//
// class PGPFingerprintType: public t_RsGenericIdType<20>
// {
// [..]
// };
//
// With this, there is no implicit conversion between subtypes, and therefore ID mixup
// is impossible.
//
// A simpler way to make ID types is to
// typedef t_RsGenericIdType<MySize> MyType ;
//
// ID Types with different lengths will be incompatible on compilation.
//
// Warning: never store references to a t_RsGenericIdType accross threads, since the
// cached string convertion is not thread safe.
//
#pragma once
#include <stdexcept>
@ -55,125 +27,213 @@
#include <iostream>
#include <ostream>
#include <string.h>
#include <stdint.h>
#include <util/rsrandom.h>
#include <cstdint>
#include <vector>
#include <list>
#include <set>
#include <memory>
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> class t_RsGenericIdType
#include "util/rsdebug.h"
#include "util/rsrandom.h"
#include "util/stacktrace.h"
/**
* RsGenericIdType values might be random, but must be different, in order to
* make the various IDs incompatible with each other.
*/
enum class RsGenericIdType
{
public:
typedef std::list<t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER> > std_list;
typedef std::vector<t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER> > std_vector;
typedef std::set<t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER> > std_set;
t_RsGenericIdType()
{
memset(bytes,0,ID_SIZE_IN_BYTES) ; // by default, ids are set to null()
}
virtual ~t_RsGenericIdType() {}
// Explicit constructor from a hexadecimal string
//
explicit t_RsGenericIdType(const std::string& hex_string) ;
// Explicit constructor from a byte array. The array should have size at least ID_SIZE_IN_BYTES
//
explicit t_RsGenericIdType(const unsigned char bytes[]) ;
// Explicit constructor from a different type, checking that the sizes are compatible.
// This is used for conversions such as
//
// GroupId -> CircleId
// GroupId -> GxsId
//
template<bool UPPER_CASE2,uint32_t UNIQUE_IDENTIFIER2>
explicit t_RsGenericIdType(const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE2,UNIQUE_IDENTIFIER2>& id)
{
memcpy(bytes,id.toByteArray(),ID_SIZE_IN_BYTES) ;
}
// Random initialization. Can be useful for testing and to generate new ids.
//
static t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER> random()
{
t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER> id ;
RSRandom::random_bytes(id.bytes,ID_SIZE_IN_BYTES) ;
return id ;
}
inline void clear() { memset(bytes,0,SIZE_IN_BYTES) ; }
// Converts to a std::string using cached value.
//
const unsigned char *toByteArray() const { return &bytes[0] ; }
static const uint32_t SIZE_IN_BYTES = ID_SIZE_IN_BYTES ;
inline bool operator==(const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& fp) const { return !memcmp(bytes,fp.bytes,ID_SIZE_IN_BYTES) ; }
inline bool operator!=(const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& fp) const { return !!memcmp(bytes,fp.bytes,ID_SIZE_IN_BYTES); }
inline bool operator< (const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& fp) const { return (memcmp(bytes,fp.bytes,ID_SIZE_IN_BYTES) < 0) ; }
inline t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>
operator~ () const
{
t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER> ret;
for(uint32_t i=0; i < ID_SIZE_IN_BYTES; ++i)
ret.bytes[i] = ~bytes[i];
return ret;
}
inline t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>
operator| (const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& fp) const
{
t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER> ret;
for(uint32_t i=0; i < ID_SIZE_IN_BYTES; ++i)
ret.bytes[i] = bytes[i] | fp.bytes[i];
return ret;
}
inline bool isNull() const
{
for(uint32_t i=0;i<SIZE_IN_BYTES;++i)
if(bytes[i] != 0)
return false ;
return true ;
}
friend std::ostream& operator<<(std::ostream& out,const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& id)
{
return out << id.toStdString(UPPER_CASE) ;
}
inline std::string toStdString() const { return toStdString(UPPER_CASE) ; }
inline static uint32_t serial_size() { return SIZE_IN_BYTES ; }
bool serialise(void *data,uint32_t pktsize,uint32_t& offset) const
{
if(offset + SIZE_IN_BYTES > pktsize)
return false ;
memcpy(&((uint8_t*)data)[offset],bytes,SIZE_IN_BYTES) ;
offset += SIZE_IN_BYTES ;
return true ;
}
bool deserialise(const void *data,uint32_t pktsize,uint32_t& offset)
{
if(offset + SIZE_IN_BYTES > pktsize)
return false ;
memcpy(bytes,&((uint8_t*)data)[offset],SIZE_IN_BYTES) ;
offset += SIZE_IN_BYTES ;
return true ;
}
private:
std::string toStdString(bool upper_case) const ;
unsigned char bytes[ID_SIZE_IN_BYTES] ;
SSL,
PGP_ID,
SHA1,
PGP_FINGERPRINT,
GXS_GROUP,
GXS_ID,
GXS_MSG,
GXS_CIRCLE,
GROUTER,
GXS_TUNNEL,
DISTANT_CHAT,
NODE_GROUP,
SHA256,
BIAS_20_BYTES
};
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> std::string t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>::toStdString(bool upper_case) const
/**
* This class aims at defining a generic ID type that is a list of bytes. It
* can be converted into a hexadecial string for printing, mainly) or for
* compatibility with old methods.
*
* To use this class, derive your own ID type from it.
* @see RsPpgFingerprint as an example.
*
* Take care to define and use a different @see RsGenericIdType for each ne type
* of ID you create, to avoid implicit conversion between subtypes, and
* therefore accidental ID mixup is impossible.
*
* ID Types with different lengths are not convertible even using explicit
* constructor and compilation would fail if that is attempted.
*
* Warning: never store references to a t_RsGenericIdType accross threads, since
* the cached string convertion is not thread safe.
*/
template<uint32_t ID_SIZE_IN_BYTES, bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
struct t_RsGenericIdType
{
using Id_t = t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>;
using std_list = std::list<Id_t>;
using std_vector = std::vector<Id_t>;
using std_set = std::set<Id_t>;
/// by default, ids are set to null()
t_RsGenericIdType() { memset(bytes, 0, ID_SIZE_IN_BYTES); }
/// Explicit constructor from a hexadecimal string
explicit t_RsGenericIdType(const std::string& hex_string);
/**
* @brief Construct from a buffer of at least the size of SIZE_IN_BYTES
* This is dangerous if used without being absolutely sure of buffer size,
* nothing prevent a buffer of wrong size being passed at runtime!
* @param[in] buff pointer to the buffer
* @return empty id on failure, an id initialized from the bytes in the
* buffer
*/
static Id_t fromBufferUnsafe(const uint8_t* buff)
{
Id_t ret;
if(!buff)
{
RsErr() << __PRETTY_FUNCTION__ << " invalid paramethers buff: "
<< buff << std::endl;
print_stacktrace();
return ret;
}
memmove(ret.bytes, buff, SIZE_IN_BYTES);
return ret;
}
/**
* Explicit constructor from a different type but with same size.
*
* This is used for conversions such as
* GroupId -> CircleId
* GroupId -> GxsId
*/
template<bool UPPER_CASE2, RsGenericIdType UNIQUE_IDENTIFIER2>
explicit t_RsGenericIdType(
const t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE2, UNIQUE_IDENTIFIER2>&
id )
{ memmove(bytes, id.toByteArray(), ID_SIZE_IN_BYTES); }
/// Random initialization. Can be useful for testing and to generate new ids.
static Id_t random()
{
Id_t id;
RsRandom::random_bytes(id.bytes, ID_SIZE_IN_BYTES);
return id;
}
inline void clear() { memset(bytes, 0, SIZE_IN_BYTES); }
/// Converts to a std::string using cached value.
const uint8_t* toByteArray() const { return &bytes[0]; }
static constexpr uint32_t SIZE_IN_BYTES = ID_SIZE_IN_BYTES;
inline bool operator==(const Id_t& fp) const
{ return !memcmp(bytes, fp.bytes, ID_SIZE_IN_BYTES); }
inline bool operator!=(const Id_t& fp) const
{ return !!memcmp(bytes, fp.bytes, ID_SIZE_IN_BYTES); }
inline bool operator< (const Id_t& fp) const
{ return (memcmp(bytes, fp.bytes, ID_SIZE_IN_BYTES) < 0); }
inline Id_t operator~ () const
{
Id_t ret;
for(uint32_t i=0; i < ID_SIZE_IN_BYTES; ++i)
ret.bytes[i] = ~bytes[i];
return ret;
}
inline Id_t operator| (const Id_t& fp) const
{
Id_t ret;
for(uint32_t i=0; i < ID_SIZE_IN_BYTES; ++i)
ret.bytes[i] = bytes[i] | fp.bytes[i];
return ret;
}
inline bool isNull() const
{
for(uint32_t i=0; i < SIZE_IN_BYTES; ++i)
if(bytes[i] != 0) return false;
return true;
}
friend std::ostream& operator<<(std::ostream& out, const Id_t& id)
{
switch (UNIQUE_IDENTIFIER)
{
case RsGenericIdType::PGP_FINGERPRINT:
{
uint8_t index = 0;
for(char c : id.toStdString())
{
out << c;
if(++index % 4 == 0 && index < id.SIZE_IN_BYTES*2) out << ' ';
}
}
break;
default: out << id.toStdString(UPPER_CASE); break;
}
return out;
}
inline std::string toStdString() const { return toStdString(UPPER_CASE); }
inline static uint32_t serial_size() { return SIZE_IN_BYTES; }
bool serialise(void* data,uint32_t pktsize,uint32_t& offset) const
{
if(offset + SIZE_IN_BYTES > pktsize) return false;
memmove( &(reinterpret_cast<uint8_t*>(data))[offset],
bytes, SIZE_IN_BYTES );
offset += SIZE_IN_BYTES;
return true;
}
bool deserialise(const void* data, uint32_t pktsize, uint32_t& offset)
{
if(offset + SIZE_IN_BYTES > pktsize) return false;
memmove( bytes,
&(reinterpret_cast<const uint8_t*>(data))[offset],
SIZE_IN_BYTES );
offset += SIZE_IN_BYTES;
return true;
}
/** Explicit constructor from a byte array. The array must have size at
* least ID_SIZE_IN_BYTES
* @deprecated This is too dangerous!
* Nothing prevent a buffer of wrong size being passed at runtime!
*/
RS_DEPRECATED_FOR("fromBufferUnsafe(const uint8_t* buff)")
explicit t_RsGenericIdType(const uint8_t bytes[]);
private:
std::string toStdString(bool upper_case) const;
uint8_t bytes[ID_SIZE_IN_BYTES];
};
template<uint32_t ID_SIZE_IN_BYTES, bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
std::string t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>
::toStdString(bool upper_case) const
{
static const char outh[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' } ;
static const char outl[16] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' } ;
@ -195,14 +255,20 @@ template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> s
return res ;
}
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>::t_RsGenericIdType(const std::string& s)
template<uint32_t ID_SIZE_IN_BYTES, bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>
::t_RsGenericIdType(const std::string& s)
{
int n=0;
std::string::size_type n = 0;
if(s.length() != ID_SIZE_IN_BYTES*2)
{
if(!s.empty())
std::cerr << "t_RsGenericIdType<>::t_RsGenericIdType(std::string&): supplied string in constructor has wrong size. Expected ID size=" << ID_SIZE_IN_BYTES*2 << " String=\"" << s << "\" = " << s.length() << std::endl;
{
RsErr() << __PRETTY_FUNCTION__ << " supplied string in constructor "
<< "has wrong size. Expected ID size=" << ID_SIZE_IN_BYTES*2
<< " String=\"" << s << "\" = " << s.length() << std::endl;
print_stacktrace();
}
clear();
return;
}
@ -221,58 +287,52 @@ template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> t
bytes[i] += (b-'a'+10) << 4*(1-k) ;
else if(b >= '0' && b <= '9')
bytes[i] += (b-'0') << 4*(1-k) ;
else {
std::cerr << "t_RsGenericIdType<>::t_RsGenericIdType(std::string&): supplied string is not purely hexadecimal: s=\"" << s << "\"" << std::endl;
clear();
else
{
RsErr() << __PRETTY_FUNCTION__ << "supplied string is not "
<< "purely hexadecimal: s=\"" << s << "\"" << std::endl;
clear();
return;
}
}
}
}
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>::t_RsGenericIdType(const unsigned char *mem)
template<uint32_t ID_SIZE_IN_BYTES, bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
RS_DEPRECATED_FOR("t_RsGenericIdType::fromBuffer(...)")
t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>::
t_RsGenericIdType(const uint8_t mem[]) /// @deprecated Too dangerous!
{
if(mem == NULL)
memset(bytes,0,ID_SIZE_IN_BYTES) ;
else
memcpy(bytes,mem,ID_SIZE_IN_BYTES) ;
if(mem == nullptr) memset(bytes, 0, ID_SIZE_IN_BYTES);
else memcpy(bytes, mem, ID_SIZE_IN_BYTES);
}
static const int SSL_ID_SIZE = 16 ; // = CERTSIGNLEN
static const int CERT_SIGN_LEN = 16 ; // = CERTSIGNLEN
static const int PGP_KEY_ID_SIZE = 8 ;
static const int PGP_KEY_FINGERPRINT_SIZE = 20 ;
static const int SHA1_SIZE = 20 ;
static const int SHA256_SIZE = 32 ;
/**
* This constants are meant to be used only inside this file.
* Use @see t_RsGenericIdType::SIZE_IN_BYTES in other places.
*/
namespace _RsIdSize
{
constexpr uint32_t SSL_ID = 16; // = CERT_SIGN
constexpr uint32_t CERT_SIGN = 16; // = SSL_ID
constexpr uint32_t PGP_ID = 8;
constexpr uint32_t PGP_FINGERPRINT = 20;
constexpr uint32_t SHA1 = 20;
constexpr uint32_t SHA256 = 32;
}
// These constants are random, but should be different, in order to make the various IDs incompatible with each other.
//
static const uint32_t RS_GENERIC_ID_SSL_ID_TYPE = 0x0001 ;
static const uint32_t RS_GENERIC_ID_PGP_ID_TYPE = 0x0002 ;
static const uint32_t RS_GENERIC_ID_SHA1_ID_TYPE = 0x0003 ;
static const uint32_t RS_GENERIC_ID_PGP_FINGERPRINT_TYPE = 0x0004 ;
static const uint32_t RS_GENERIC_ID_GXS_GROUP_ID_TYPE = 0x0005 ;
static const uint32_t RS_GENERIC_ID_GXS_ID_TYPE = 0x0006 ;
static const uint32_t RS_GENERIC_ID_GXS_MSG_ID_TYPE = 0x0007 ;
static const uint32_t RS_GENERIC_ID_GXS_CIRCLE_ID_TYPE = 0x0008 ;
static const uint32_t RS_GENERIC_ID_GROUTER_ID_TYPE = 0x0009 ;
static const uint32_t RS_GENERIC_ID_GXS_TUNNEL_ID_TYPE = 0x0010 ;
static const uint32_t RS_GENERIC_ID_GXS_DISTANT_CHAT_ID_TYPE = 0x0011 ;
static const uint32_t RS_GENERIC_ID_NODE_GROUP_ID_TYPE = 0x0012 ;
static const uint32_t RS_GENERIC_ID_SHA256_ID_TYPE = 0x0013 ;
static const uint32_t RS_GENERIC_ID_20_BYTES_UNTYPED = 0x0014 ;
typedef t_RsGenericIdType< SSL_ID_SIZE , false, RS_GENERIC_ID_SSL_ID_TYPE> SSLIdType ;
typedef t_RsGenericIdType< PGP_KEY_ID_SIZE , true, RS_GENERIC_ID_PGP_ID_TYPE> PGPIdType ;
typedef t_RsGenericIdType< SHA1_SIZE , false, RS_GENERIC_ID_SHA1_ID_TYPE> Sha1CheckSum ;
typedef t_RsGenericIdType< SHA256_SIZE , false, RS_GENERIC_ID_SHA256_ID_TYPE> Sha256CheckSum ;
typedef t_RsGenericIdType< PGP_KEY_FINGERPRINT_SIZE, true, RS_GENERIC_ID_PGP_FINGERPRINT_TYPE> PGPFingerprintType ;
typedef t_RsGenericIdType< SHA1_SIZE , true, RS_GENERIC_ID_20_BYTES_UNTYPED> Bias20Bytes ;
typedef t_RsGenericIdType< CERT_SIGN_LEN , false, RS_GENERIC_ID_GXS_GROUP_ID_TYPE > GXSGroupId ;
typedef t_RsGenericIdType< CERT_SIGN_LEN , false, RS_GENERIC_ID_GXS_ID_TYPE > GXSId ;
typedef t_RsGenericIdType< CERT_SIGN_LEN , false, RS_GENERIC_ID_GXS_CIRCLE_ID_TYPE > GXSCircleId ;
typedef t_RsGenericIdType< SSL_ID_SIZE , false, RS_GENERIC_ID_GXS_TUNNEL_ID_TYPE > GXSTunnelId ;
typedef t_RsGenericIdType< SSL_ID_SIZE , false, RS_GENERIC_ID_GXS_DISTANT_CHAT_ID_TYPE > DistantChatPeerId ;
typedef t_RsGenericIdType< CERT_SIGN_LEN , false, RS_GENERIC_ID_NODE_GROUP_ID_TYPE > RsNodeGroupId ;
using RsPeerId = t_RsGenericIdType<_RsIdSize::SSL_ID , false, RsGenericIdType::SSL >;
using RsPgpId = t_RsGenericIdType<_RsIdSize::PGP_ID , true, RsGenericIdType::PGP_ID >;
using Sha1CheckSum = t_RsGenericIdType<_RsIdSize::SHA1 , false, RsGenericIdType::SHA1 >;
using Sha256CheckSum = t_RsGenericIdType<_RsIdSize::SHA256 , false, RsGenericIdType::SHA256 >;
using RsPpgFingerprint = t_RsGenericIdType<_RsIdSize::PGP_FINGERPRINT, true, RsGenericIdType::PGP_FINGERPRINT>;
using Bias20Bytes = t_RsGenericIdType<_RsIdSize::SHA1 , true, RsGenericIdType::BIAS_20_BYTES >;
using RsGxsGroupId = t_RsGenericIdType<_RsIdSize::CERT_SIGN , false, RsGenericIdType::GXS_GROUP >;
using RsGxsId = t_RsGenericIdType<_RsIdSize::CERT_SIGN , false, RsGenericIdType::GXS_ID >;
using RsGxsCircleId = t_RsGenericIdType<_RsIdSize::CERT_SIGN , false, RsGenericIdType::GXS_CIRCLE >;
using RsGxsTunnelId = t_RsGenericIdType<_RsIdSize::SSL_ID , false, RsGenericIdType::GXS_TUNNEL >;
using DistantChatPeerId = t_RsGenericIdType<_RsIdSize::SSL_ID , false, RsGenericIdType::DISTANT_CHAT >;
using RsNodeGroupId = t_RsGenericIdType<_RsIdSize::CERT_SIGN , false, RsGenericIdType::NODE_GROUP >;
/// @deprecated Ugly name kept temporarly only because it is used in many places
using PGPFingerprintType RS_DEPRECATED_FOR(RsPpgFingerprint) = RsPpgFingerprint;

View File

@ -37,15 +37,6 @@
#define USE_NEW_CHUNK_CHECKING_CODE
// This adds a level of indirection to types, so we can easily change them if needed
//
//typedef std::string RsCertId; // unused
//typedef std::string RsChanId;
//typedef std::string RsMsgId;
//typedef std::string RsAuthId;
typedef SSLIdType RsPeerId ;
typedef PGPIdType RsPgpId ;
typedef Sha1CheckSum RsFileHash ;
typedef Sha1CheckSum RsMessageId ;

View File

@ -844,36 +844,36 @@ protected:
// t_RsGenericId<...> declarations //
//============================================================================//
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER>
template<uint32_t ID_SIZE_IN_BYTES, bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
static bool serialize(
uint8_t data[], uint32_t size, uint32_t &offset,
const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& member );
const t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>& member );
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER>
template<uint32_t ID_SIZE_IN_BYTES, bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
static bool deserialize(
const uint8_t data[], uint32_t size, uint32_t &offset,
t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& member );
t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>& member );
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER>
template<uint32_t ID_SIZE_IN_BYTES, bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
static uint32_t serial_size(
const t_RsGenericIdType<
ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& member );
ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>& member );
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER>
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
static void print_data(
const std::string& name,
const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& member );
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER>
template<uint32_t ID_SIZE_IN_BYTES, bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
static bool to_JSON(
const std::string& membername,
const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& member,
const t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>& member,
RsJson& jVal );
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER>
template<uint32_t ID_SIZE_IN_BYTES, bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
static bool from_JSON(
const std::string& memberName,
t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& member,
t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>& member,
RsJson& jDoc );
//============================================================================//
@ -914,41 +914,43 @@ protected:
// t_RsGenericId<...> //
//============================================================================//
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER>
template<uint32_t ID_SIZE_IN_BYTES, bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
bool RsTypeSerializer::serialize (
uint8_t data[], uint32_t size, uint32_t &offset,
const t_RsGenericIdType<
ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& member )
ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>& member )
{
return (*const_cast<const t_RsGenericIdType<
ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER> *>(&member)
).serialise(data,size,offset);
ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER> *>(&member)
).serialise(data, size, offset);
}
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER>
template<uint32_t ID_SIZE_IN_BYTES, bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
bool RsTypeSerializer::deserialize(
const uint8_t data[], uint32_t size, uint32_t &offset,
t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& member )
{ return member.deserialise(data,size,offset); }
t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>& member )
{ return member.deserialise(data, size, offset); }
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER>
template<uint32_t ID_SIZE_IN_BYTES, bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
uint32_t RsTypeSerializer::serial_size(
const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& member )
const t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>& member )
{ return member.serial_size(); }
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER>
template<uint32_t ID_SIZE_IN_BYTES, bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
void RsTypeSerializer::print_data(
const std::string& /*name*/,
const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& member )
const t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>& member )
{
std::cerr << " [RsGenericId<" << std::hex << UNIQUE_IDENTIFIER << ">] : "
std::cerr << " [RsGenericId<" << std::hex
<< static_cast<uint32_t>(UNIQUE_IDENTIFIER) << ">] : "
<< member << std::endl;
}
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER>
bool RsTypeSerializer::to_JSON( const std::string& memberName,
const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& member,
RsJson& jDoc )
template<uint32_t ID_SIZE_IN_BYTES, bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
bool RsTypeSerializer::to_JSON(
const std::string& memberName,
const t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>& member,
RsJson& jDoc )
{
rapidjson::Document::AllocatorType& allocator = jDoc.GetAllocator();
@ -964,10 +966,11 @@ bool RsTypeSerializer::to_JSON( const std::string& memberName,
return true;
}
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER>
bool RsTypeSerializer::from_JSON( const std::string& membername,
t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& member,
RsJson& jVal )
template<uint32_t ID_SIZE_IN_BYTES, bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
bool RsTypeSerializer::from_JSON(
const std::string& membername,
t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>& member,
RsJson& jVal )
{
const char* mName = membername.c_str();
bool ret = jVal.HasMember(mName);
@ -975,7 +978,9 @@ bool RsTypeSerializer::from_JSON( const std::string& membername,
{
rapidjson::Value& v = jVal[mName];
ret = ret && v.IsString();
if(ret) member = t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>(std::string(v.GetString()));
if(ret) member =
t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>(
std::string(v.GetString()) );
}
return ret;
}