mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-07 04:53:44 +02:00
Continuing work on new buffer type...
This commit is contained in:
parent
59da359b06
commit
d5b9a54c55
13 changed files with 263 additions and 191 deletions
|
@ -70,10 +70,12 @@ set(core_src
|
||||||
Peer.cpp
|
Peer.cpp
|
||||||
Poly1305.cpp
|
Poly1305.cpp
|
||||||
Protocol.cpp
|
Protocol.cpp
|
||||||
|
Revocation.cpp
|
||||||
Salsa20.cpp
|
Salsa20.cpp
|
||||||
SelfAwareness.cpp
|
SelfAwareness.cpp
|
||||||
SHA512.cpp
|
SHA512.cpp
|
||||||
Switch.cpp
|
Switch.cpp
|
||||||
|
Tag.cpp
|
||||||
Topology.cpp
|
Topology.cpp
|
||||||
Trace.cpp
|
Trace.cpp
|
||||||
Utils.cpp
|
Utils.cpp
|
||||||
|
|
|
@ -122,7 +122,7 @@ int Capability::unmarshal(const uint8_t *data,int len)
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Capability::marshalVirtualNetworkRules(uint8_t data[ZT_VIRTUALNETWORKRULE_MARSHAL_SIZE_MAX],const ZT_VirtualNetworkRule *const rules,const unsigned int ruleCount)
|
int Capability::marshalVirtualNetworkRules(uint8_t *data,const ZT_VirtualNetworkRule *const rules,const unsigned int ruleCount)
|
||||||
{
|
{
|
||||||
int p = 0;
|
int p = 0;
|
||||||
for(unsigned int i=0;i<ruleCount;++i) {
|
for(unsigned int i=0;i<ruleCount;++i) {
|
||||||
|
|
|
@ -159,7 +159,7 @@ public:
|
||||||
int marshal(uint8_t data[ZT_CAPABILITY_MARSHAL_SIZE_MAX],bool forSign = false) const;
|
int marshal(uint8_t data[ZT_CAPABILITY_MARSHAL_SIZE_MAX],bool forSign = false) const;
|
||||||
int unmarshal(const uint8_t *data,int len);
|
int unmarshal(const uint8_t *data,int len);
|
||||||
|
|
||||||
static int marshalVirtualNetworkRules(uint8_t data[ZT_VIRTUALNETWORKRULE_MARSHAL_SIZE_MAX],const ZT_VirtualNetworkRule *rules,unsigned int ruleCount);
|
static int marshalVirtualNetworkRules(uint8_t *data,const ZT_VirtualNetworkRule *rules,unsigned int ruleCount);
|
||||||
static int unmarshalVirtualNetworkRules(const uint8_t *data,int len,ZT_VirtualNetworkRule *rules,unsigned int &ruleCount,unsigned int maxRuleCount);
|
static int unmarshalVirtualNetworkRules(const uint8_t *data,int len,ZT_VirtualNetworkRule *rules,unsigned int &ruleCount,unsigned int maxRuleCount);
|
||||||
|
|
||||||
// Provides natural sort order by ID
|
// Provides natural sort order by ID
|
||||||
|
|
|
@ -233,10 +233,6 @@
|
||||||
|
|
||||||
// Exceptions thrown in core ZT code
|
// Exceptions thrown in core ZT code
|
||||||
#define ZT_EXCEPTION_OUT_OF_BOUNDS 100
|
#define ZT_EXCEPTION_OUT_OF_BOUNDS 100
|
||||||
#define ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_TYPE 200
|
|
||||||
#define ZT_EXCEPTION_INVALID_SERIALIZED_DATA_OVERFLOW 201
|
|
||||||
#define ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_CRYPTOGRAPHIC_TOKEN 202
|
|
||||||
#define ZT_EXCEPTION_INVALID_SERIALIZED_DATA_BAD_ENCODING 203
|
|
||||||
|
|
||||||
/* Ethernet frame types that might be relevant to us */
|
/* Ethernet frame types that might be relevant to us */
|
||||||
#define ZT_ETHERTYPE_IPV4 0x0800
|
#define ZT_ETHERTYPE_IPV4 0x0800
|
||||||
|
|
|
@ -313,7 +313,7 @@ bool InetAddress::isNetwork() const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int InetAddress::marshal(uint8_t data[19]) const
|
int InetAddress::marshal(uint8_t data[ZT_INETADDRESS_MARSHAL_SIZE_MAX]) const
|
||||||
{
|
{
|
||||||
unsigned int port;
|
unsigned int port;
|
||||||
switch(ss_family) {
|
switch(ss_family) {
|
||||||
|
|
|
@ -494,7 +494,7 @@ public:
|
||||||
explicit ZT_ALWAYS_INLINE operator bool() const { return (ss_family != 0); }
|
explicit ZT_ALWAYS_INLINE operator bool() const { return (ss_family != 0); }
|
||||||
|
|
||||||
static ZT_ALWAYS_INLINE int marshalSizeMax() { return ZT_INETADDRESS_MARSHAL_SIZE_MAX; }
|
static ZT_ALWAYS_INLINE int marshalSizeMax() { return ZT_INETADDRESS_MARSHAL_SIZE_MAX; }
|
||||||
int marshal(uint8_t data[19]) const;
|
int marshal(uint8_t data[ZT_INETADDRESS_MARSHAL_SIZE_MAX]) const;
|
||||||
int unmarshal(const uint8_t *restrict data,const int len);
|
int unmarshal(const uint8_t *restrict data,const int len);
|
||||||
|
|
||||||
bool operator==(const InetAddress &a) const;
|
bool operator==(const InetAddress &a) const;
|
||||||
|
|
|
@ -43,7 +43,8 @@ NetworkConfig::NetworkConfig() :
|
||||||
|
|
||||||
bool NetworkConfig::toDictionary(Dictionary &d,bool includeLegacy) const
|
bool NetworkConfig::toDictionary(Dictionary &d,bool includeLegacy) const
|
||||||
{
|
{
|
||||||
ScopedPtr< Buffer<ZT_NETWORKCONFIG_DICT_CAPACITY> > tmp(new Buffer<ZT_NETWORKCONFIG_DICT_CAPACITY>());
|
uint8_t tmp[16384];
|
||||||
|
std::vector<uint8_t> buf;
|
||||||
char tmp2[128];
|
char tmp2[128];
|
||||||
|
|
||||||
d.clear();
|
d.clear();
|
||||||
|
@ -64,62 +65,90 @@ bool NetworkConfig::toDictionary(Dictionary &d,bool includeLegacy) const
|
||||||
// Then add binary blobs
|
// Then add binary blobs
|
||||||
|
|
||||||
if (this->com) {
|
if (this->com) {
|
||||||
tmp->clear();
|
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_COM,(const char *)tmp,this->com.marshal(tmp)))
|
||||||
this->com.serialize(*tmp);
|
return false;
|
||||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_COM,*tmp)) return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp->clear();
|
buf.clear();
|
||||||
for(unsigned int i=0;i<this->capabilityCount;++i)
|
for(unsigned int i=0;i<this->capabilityCount;++i) {
|
||||||
this->capabilities[i].serialize(*tmp);
|
int l = this->capabilities[i].marshal(tmp);
|
||||||
if (tmp->size()) {
|
if (l < 0)
|
||||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_CAPABILITIES,*tmp)) return false;
|
return false;
|
||||||
|
buf.insert(buf.end(),tmp,tmp + l);
|
||||||
|
}
|
||||||
|
if (!buf.empty()) {
|
||||||
|
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_CAPABILITIES,(const char *)buf.data(),(int)buf.size()))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp->clear();
|
buf.clear();
|
||||||
for(unsigned int i=0;i<this->tagCount;++i)
|
for(unsigned int i=0;i<this->tagCount;++i) {
|
||||||
this->tags[i].serialize(*tmp);
|
int l = this->tags[i].marshal(tmp);
|
||||||
if (tmp->size()) {
|
if (l < 0)
|
||||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_TAGS,*tmp)) return false;
|
return false;
|
||||||
|
buf.insert(buf.end(),tmp,tmp + l);
|
||||||
|
}
|
||||||
|
if (!buf.empty()) {
|
||||||
|
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_TAGS,(const char *)buf.data(),(int)buf.size()))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp->clear();
|
buf.clear();
|
||||||
for(unsigned int i=0;i<this->certificateOfOwnershipCount;++i)
|
for(unsigned int i=0;i<this->certificateOfOwnershipCount;++i) {
|
||||||
this->certificatesOfOwnership[i].serialize(*tmp);
|
int l = this->certificatesOfOwnership[i].marshal(tmp);
|
||||||
if (tmp->size()) {
|
if (l < 0)
|
||||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_CERTIFICATES_OF_OWNERSHIP,*tmp)) return false;
|
return false;
|
||||||
|
buf.insert(buf.end(),tmp,tmp + l);
|
||||||
|
}
|
||||||
|
if (!buf.empty()) {
|
||||||
|
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_CERTIFICATES_OF_OWNERSHIP,(const char *)buf.data(),(int)buf.size()))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp->clear();
|
buf.clear();
|
||||||
for(unsigned int i=0;i<this->specialistCount;++i)
|
for(unsigned int i=0;i<this->specialistCount;++i) {
|
||||||
tmp->append((uint64_t)this->specialists[i]);
|
Utils::storeBigEndian<uint64_t>(tmp,this->specialists[i]);
|
||||||
if (tmp->size()) {
|
buf.insert(buf.end(),tmp,tmp + 8);
|
||||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_SPECIALISTS,*tmp)) return false;
|
}
|
||||||
|
if (!buf.empty()) {
|
||||||
|
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_SPECIALISTS,(const char *)buf.data(),(int)buf.size()))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp->clear();
|
buf.clear();
|
||||||
for(unsigned int i=0;i<this->routeCount;++i) {
|
for(unsigned int i=0;i<this->routeCount;++i) {
|
||||||
reinterpret_cast<const InetAddress *>(&(this->routes[i].target))->serialize(*tmp);
|
int l = asInetAddress(this->routes[i].target).marshal(tmp);
|
||||||
reinterpret_cast<const InetAddress *>(&(this->routes[i].via))->serialize(*tmp);
|
if (l < 0)
|
||||||
tmp->append((uint16_t)this->routes[i].flags);
|
return false;
|
||||||
tmp->append((uint16_t)this->routes[i].metric);
|
buf.insert(buf.end(),tmp,tmp + l);
|
||||||
|
l = asInetAddress(this->routes[i].via).marshal(tmp);
|
||||||
|
if (l < 0)
|
||||||
|
return false;
|
||||||
|
buf.insert(buf.end(),tmp,tmp + l);
|
||||||
}
|
}
|
||||||
if (tmp->size()) {
|
if (!buf.empty()) {
|
||||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_ROUTES,*tmp)) return false;
|
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_ROUTES,(const char *)buf.data(),(int)buf.size()))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp->clear();
|
buf.clear();
|
||||||
for(unsigned int i=0;i<this->staticIpCount;++i)
|
for(unsigned int i=0;i<this->staticIpCount;++i) {
|
||||||
this->staticIps[i].serialize(*tmp);
|
int l = this->staticIps[i].marshal(tmp);
|
||||||
if (tmp->size()) {
|
if (l < 0)
|
||||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_STATIC_IPS,*tmp)) return false;
|
return false;
|
||||||
|
buf.insert(buf.end(),tmp,tmp + l);
|
||||||
|
}
|
||||||
|
if (!buf.empty()) {
|
||||||
|
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_STATIC_IPS,(const char *)buf.data(),(int)buf.size()))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->ruleCount) {
|
if (this->ruleCount) {
|
||||||
tmp->clear();
|
buf.resize(ruleCount * ZT_VIRTUALNETWORKRULE_MARSHAL_SIZE_MAX);
|
||||||
Capability::serializeRules(*tmp,rules,ruleCount);
|
int l = Capability::marshalVirtualNetworkRules(buf.data(),rules,ruleCount);
|
||||||
if (tmp->size()) {
|
if (l > 0) {
|
||||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_RULES,*tmp)) return false;
|
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_RULES,(const char *)buf.data(),l))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ namespace Protocol {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
const uint8_t ZEROES32[32] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
|
const uint64_t ZEROES32[4] = { 0,0,0,0 };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deterministically mangle a 256-bit crypto key based on packet
|
* Deterministically mangle a 256-bit crypto key based on packet
|
||||||
|
|
89
node/Revocation.cpp
Normal file
89
node/Revocation.cpp
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c)2013-2020 ZeroTier, Inc.
|
||||||
|
*
|
||||||
|
* Use of this software is governed by the Business Source License included
|
||||||
|
* in the LICENSE.TXT file in the project's root directory.
|
||||||
|
*
|
||||||
|
* Change Date: 2024-01-01
|
||||||
|
*
|
||||||
|
* On the date above, in accordance with the Business Source License, use
|
||||||
|
* of this software will be governed by version 2.0 of the Apache License.
|
||||||
|
*/
|
||||||
|
/****/
|
||||||
|
|
||||||
|
#include "Revocation.hpp"
|
||||||
|
|
||||||
|
namespace ZeroTier {
|
||||||
|
|
||||||
|
bool Revocation::sign(const Identity &signer)
|
||||||
|
{
|
||||||
|
uint8_t buf[ZT_REVOCATION_MARSHAL_SIZE_MAX+32];
|
||||||
|
if (signer.hasPrivate()) {
|
||||||
|
_signedBy = signer.address();
|
||||||
|
_signatureLength = signer.sign(buf,(unsigned int)marshal(buf,true),_signature,sizeof(_signature));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Revocation::marshal(uint8_t data[ZT_REVOCATION_MARSHAL_SIZE_MAX],bool forSign) const
|
||||||
|
{
|
||||||
|
int p = 0;
|
||||||
|
if (forSign) {
|
||||||
|
for(int k=0;k<8;++k)
|
||||||
|
data[p++] = 0x7f;
|
||||||
|
}
|
||||||
|
Utils::storeBigEndian<uint32_t>(data + p,0); p += 4;
|
||||||
|
Utils::storeBigEndian<uint32_t>(data + p,_id); p += 4;
|
||||||
|
Utils::storeBigEndian<uint64_t>(data + p,_networkId); p += 8;
|
||||||
|
Utils::storeBigEndian<uint32_t>(data + p,0); p += 4;
|
||||||
|
Utils::storeBigEndian<uint32_t>(data + p,_credentialId); p += 4;
|
||||||
|
Utils::storeBigEndian<uint64_t>(data + p,(uint64_t)_threshold); p += 8;
|
||||||
|
Utils::storeBigEndian<uint64_t>(data + p,_flags); p += 8;
|
||||||
|
_target.copyTo(data + p); p += ZT_ADDRESS_LENGTH;
|
||||||
|
_signedBy.copyTo(data + p); p += ZT_ADDRESS_LENGTH;
|
||||||
|
data[p++] = (uint8_t)_type;
|
||||||
|
if (!forSign) {
|
||||||
|
data[p++] = 1;
|
||||||
|
Utils::storeBigEndian<uint16_t>(data + p,(uint16_t)_signatureLength);
|
||||||
|
memcpy(data + p,_signature,_signatureLength);
|
||||||
|
p += (int)_signatureLength;
|
||||||
|
}
|
||||||
|
data[p++] = 0;
|
||||||
|
data[p++] = 0;
|
||||||
|
if (forSign) {
|
||||||
|
for(int k=0;k<8;++k)
|
||||||
|
data[p++] = 0x7f;
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Revocation::unmarshal(const uint8_t *restrict data,const int len)
|
||||||
|
{
|
||||||
|
if (len < 54)
|
||||||
|
return -1;
|
||||||
|
// 4 bytes reserved
|
||||||
|
_id = Utils::loadBigEndian<uint32_t>(data + 4);
|
||||||
|
_networkId = Utils::loadBigEndian<uint64_t>(data + 8);
|
||||||
|
// 4 bytes reserved
|
||||||
|
_credentialId = Utils::loadBigEndian<uint32_t>(data + 20);
|
||||||
|
_threshold = (int64_t)Utils::loadBigEndian<uint64_t>(data + 24);
|
||||||
|
_flags = Utils::loadBigEndian<uint64_t>(data + 32);
|
||||||
|
_target.setTo(data + 40);
|
||||||
|
_signedBy.setTo(data + 45);
|
||||||
|
_type = (ZT_CredentialType)data[50];
|
||||||
|
// 1 byte reserved
|
||||||
|
_signatureLength = Utils::loadBigEndian<uint16_t>(data + 52);
|
||||||
|
int p = 54 + (int)_signatureLength;
|
||||||
|
if ((_signatureLength > ZT_SIGNATURE_BUFFER_SIZE)||(p > len))
|
||||||
|
return -1;
|
||||||
|
memcpy(_signature,data + 54,_signatureLength);
|
||||||
|
if ((p + 2) > len)
|
||||||
|
return -1;
|
||||||
|
p += 2 + Utils::loadBigEndian<uint16_t>(data + p);
|
||||||
|
if (p > len)
|
||||||
|
return -1;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ZeroTier
|
|
@ -31,6 +31,8 @@
|
||||||
*/
|
*/
|
||||||
#define ZT_REVOCATION_FLAG_FAST_PROPAGATE 0x1ULL
|
#define ZT_REVOCATION_FLAG_FAST_PROPAGATE 0x1ULL
|
||||||
|
|
||||||
|
#define ZT_REVOCATION_MARSHAL_SIZE_MAX (4 + 4 + 8 + 4 + 4 + 8 + 8 + 5 + 5 + 1 + 1 + 2 + ZT_SIGNATURE_BUFFER_SIZE + 2)
|
||||||
|
|
||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
|
|
||||||
class RuntimeEnvironment;
|
class RuntimeEnvironment;
|
||||||
|
@ -95,17 +97,7 @@ public:
|
||||||
* @param signer Signing identity, must have private key
|
* @param signer Signing identity, must have private key
|
||||||
* @return True if signature was successful
|
* @return True if signature was successful
|
||||||
*/
|
*/
|
||||||
ZT_ALWAYS_INLINE bool sign(const Identity &signer)
|
bool sign(const Identity &signer);
|
||||||
{
|
|
||||||
if (signer.hasPrivate()) {
|
|
||||||
Buffer<sizeof(Revocation) + 64> tmp;
|
|
||||||
_signedBy = signer.address();
|
|
||||||
this->serialize(tmp,true);
|
|
||||||
_signatureLength = signer.sign(tmp.data(),tmp.size(),_signature,sizeof(_signature));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify this revocation's signature
|
* Verify this revocation's signature
|
||||||
|
@ -115,67 +107,9 @@ public:
|
||||||
*/
|
*/
|
||||||
ZT_ALWAYS_INLINE Credential::VerifyResult verify(const RuntimeEnvironment *RR,void *tPtr) const { return _verify(RR,tPtr,*this); }
|
ZT_ALWAYS_INLINE Credential::VerifyResult verify(const RuntimeEnvironment *RR,void *tPtr) const { return _verify(RR,tPtr,*this); }
|
||||||
|
|
||||||
template<unsigned int C>
|
static ZT_ALWAYS_INLINE int marshalSizeMax() { return ZT_REVOCATION_MARSHAL_SIZE_MAX; }
|
||||||
inline void serialize(Buffer<C> &b,const bool forSign = false) const
|
int marshal(uint8_t data[ZT_REVOCATION_MARSHAL_SIZE_MAX],bool forSign = false) const;
|
||||||
{
|
int unmarshal(const uint8_t *restrict data,const int len);
|
||||||
if (forSign) b.append((uint64_t)0x7f7f7f7f7f7f7f7fULL);
|
|
||||||
|
|
||||||
b.append((uint32_t)0); // 4 unused bytes, currently set to 0
|
|
||||||
b.append(_id);
|
|
||||||
b.append(_networkId);
|
|
||||||
b.append((uint32_t)0); // 4 unused bytes, currently set to 0
|
|
||||||
b.append(_credentialId);
|
|
||||||
b.append(_threshold);
|
|
||||||
b.append(_flags);
|
|
||||||
_target.appendTo(b);
|
|
||||||
_signedBy.appendTo(b);
|
|
||||||
b.append((uint8_t)_type);
|
|
||||||
|
|
||||||
if (!forSign) {
|
|
||||||
b.append((uint8_t)1);
|
|
||||||
b.append((uint16_t)_signatureLength);
|
|
||||||
b.append(_signature,_signatureLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is the size of any additional fields, currently 0.
|
|
||||||
b.append((uint16_t)0);
|
|
||||||
|
|
||||||
if (forSign) b.append((uint64_t)0x7f7f7f7f7f7f7f7fULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<unsigned int C>
|
|
||||||
inline unsigned int deserialize(const Buffer<C> &b,unsigned int startAt = 0)
|
|
||||||
{
|
|
||||||
*this = Revocation();
|
|
||||||
|
|
||||||
unsigned int p = startAt;
|
|
||||||
|
|
||||||
p += 4; // 4 bytes, currently unused
|
|
||||||
_id = b.template at<uint32_t>(p); p += 4;
|
|
||||||
_networkId = b.template at<uint64_t>(p); p += 8;
|
|
||||||
p += 4; // 4 bytes, currently unused
|
|
||||||
_credentialId = b.template at<uint32_t>(p); p += 4;
|
|
||||||
_threshold = b.template at<uint64_t>(p); p += 8;
|
|
||||||
_flags = b.template at<uint64_t>(p); p += 8;
|
|
||||||
_target.setTo(b.field(p,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); p += ZT_ADDRESS_LENGTH;
|
|
||||||
_signedBy.setTo(b.field(p,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); p += ZT_ADDRESS_LENGTH;
|
|
||||||
_type = (ZT_CredentialType)b[p++];
|
|
||||||
|
|
||||||
if (b[p++] == 1) {
|
|
||||||
_signatureLength = b.template at<uint16_t>(p);
|
|
||||||
if (_signatureLength > sizeof(_signature))
|
|
||||||
throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_CRYPTOGRAPHIC_TOKEN;
|
|
||||||
memcpy(_signature,b.field(p,_signatureLength),_signatureLength);
|
|
||||||
} else {
|
|
||||||
p += 2 + b.template at<uint16_t>(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
p += 2 + b.template at<uint16_t>(p);
|
|
||||||
if (p > b.size())
|
|
||||||
throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_OVERFLOW;
|
|
||||||
|
|
||||||
return (p - startAt);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t _id;
|
uint32_t _id;
|
||||||
|
|
81
node/Tag.cpp
Normal file
81
node/Tag.cpp
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c)2013-2020 ZeroTier, Inc.
|
||||||
|
*
|
||||||
|
* Use of this software is governed by the Business Source License included
|
||||||
|
* in the LICENSE.TXT file in the project's root directory.
|
||||||
|
*
|
||||||
|
* Change Date: 2024-01-01
|
||||||
|
*
|
||||||
|
* On the date above, in accordance with the Business Source License, use
|
||||||
|
* of this software will be governed by version 2.0 of the Apache License.
|
||||||
|
*/
|
||||||
|
/****/
|
||||||
|
|
||||||
|
#include "Tag.hpp"
|
||||||
|
|
||||||
|
namespace ZeroTier {
|
||||||
|
|
||||||
|
bool Tag::sign(const Identity &signer)
|
||||||
|
{
|
||||||
|
uint8_t buf[ZT_TAG_MARSHAL_SIZE_MAX];
|
||||||
|
if (signer.hasPrivate()) {
|
||||||
|
_signedBy = signer.address();
|
||||||
|
_signatureLength = signer.sign(buf,(unsigned int)marshal(buf,true),_signature,sizeof(_signature));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Tag::marshal(uint8_t data[ZT_TAG_MARSHAL_SIZE_MAX],bool forSign) const
|
||||||
|
{
|
||||||
|
int p = 0;
|
||||||
|
if (forSign) {
|
||||||
|
for(int k=0;k<8;++k)
|
||||||
|
data[p++] = 0x7f;
|
||||||
|
}
|
||||||
|
Utils::storeBigEndian<uint64_t>(data + p,_networkId); p += 8;
|
||||||
|
Utils::storeBigEndian<uint64_t>(data + p,(uint64_t)_ts); p += 8;
|
||||||
|
Utils::storeBigEndian<uint32_t>(data + p,_id); p += 4;
|
||||||
|
Utils::storeBigEndian<uint32_t>(data + p,_value); p += 4;
|
||||||
|
_issuedTo.copyTo(data + p); p += ZT_ADDRESS_LENGTH;
|
||||||
|
_signedBy.copyTo(data + p); p += ZT_ADDRESS_LENGTH;
|
||||||
|
if (!forSign) {
|
||||||
|
data[p++] = 1;
|
||||||
|
Utils::storeBigEndian<uint16_t>(data + p,(uint16_t)_signatureLength); p += 2;
|
||||||
|
memcpy(data + p,_signature,_signatureLength);
|
||||||
|
p += (int)_signatureLength;
|
||||||
|
}
|
||||||
|
data[p++] = 0;
|
||||||
|
data[p++] = 0;
|
||||||
|
if (forSign) {
|
||||||
|
for(int k=0;k<8;++k)
|
||||||
|
data[p++] = 0x7f;
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Tag::unmarshal(const uint8_t *data,int len)
|
||||||
|
{
|
||||||
|
if (len < 37)
|
||||||
|
return -1;
|
||||||
|
_networkId = Utils::loadBigEndian<uint64_t>(data);
|
||||||
|
_ts = (int64_t)Utils::loadBigEndian<uint64_t>(data + 8);
|
||||||
|
_id = Utils::loadBigEndian<uint32_t>(data + 16);
|
||||||
|
_value = Utils::loadBigEndian<uint32_t>(data + 20);
|
||||||
|
_issuedTo.setTo(data + 24);
|
||||||
|
_signedBy.setTo(data + 29);
|
||||||
|
// 1 byte reserved
|
||||||
|
_signatureLength = Utils::loadBigEndian<uint16_t>(data + 35);
|
||||||
|
int p = 37 + (int)_signatureLength;
|
||||||
|
if ((_signatureLength > ZT_SIGNATURE_BUFFER_SIZE)||(p > len))
|
||||||
|
return -1;
|
||||||
|
memcpy(_signature,data + p,_signatureLength);
|
||||||
|
if ((p + 2) > len)
|
||||||
|
return -1;
|
||||||
|
p += 2 + Utils::loadBigEndian<uint16_t>(data + p);
|
||||||
|
if (p > len)
|
||||||
|
return -1;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ZeroTier
|
71
node/Tag.hpp
71
node/Tag.hpp
|
@ -25,6 +25,8 @@
|
||||||
#include "Address.hpp"
|
#include "Address.hpp"
|
||||||
#include "Identity.hpp"
|
#include "Identity.hpp"
|
||||||
|
|
||||||
|
#define ZT_TAG_MARSHAL_SIZE_MAX (8 + 8 + 4 + 4 + 5 + 5 + 1 + 2 + ZT_SIGNATURE_BUFFER_SIZE + 2)
|
||||||
|
|
||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
|
|
||||||
class RuntimeEnvironment;
|
class RuntimeEnvironment;
|
||||||
|
@ -95,17 +97,7 @@ public:
|
||||||
* @param signer Signing identity, must have private key
|
* @param signer Signing identity, must have private key
|
||||||
* @return True if signature was successful
|
* @return True if signature was successful
|
||||||
*/
|
*/
|
||||||
inline bool sign(const Identity &signer)
|
bool sign(const Identity &signer);
|
||||||
{
|
|
||||||
if (signer.hasPrivate()) {
|
|
||||||
Buffer<sizeof(Tag) + 64> tmp;
|
|
||||||
_signedBy = signer.address();
|
|
||||||
this->serialize(tmp,true);
|
|
||||||
_signatureLength = signer.sign(tmp.data(),tmp.size(),_signature,sizeof(_signature));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check this tag's signature
|
* Check this tag's signature
|
||||||
|
@ -115,60 +107,9 @@ public:
|
||||||
*/
|
*/
|
||||||
ZT_ALWAYS_INLINE Credential::VerifyResult verify(const RuntimeEnvironment *RR,void *tPtr) const { return _verify(RR,tPtr,*this); }
|
ZT_ALWAYS_INLINE Credential::VerifyResult verify(const RuntimeEnvironment *RR,void *tPtr) const { return _verify(RR,tPtr,*this); }
|
||||||
|
|
||||||
template<unsigned int C>
|
static ZT_ALWAYS_INLINE int marshalSizeMax() { return ZT_TAG_MARSHAL_SIZE_MAX; }
|
||||||
inline void serialize(Buffer<C> &b,const bool forSign = false) const
|
int marshal(uint8_t data[ZT_TAG_MARSHAL_SIZE_MAX],bool forSign = false) const;
|
||||||
{
|
int unmarshal(const uint8_t *data,int len);
|
||||||
if (forSign) b.append((uint64_t)0x7f7f7f7f7f7f7f7fULL);
|
|
||||||
|
|
||||||
b.append(_networkId);
|
|
||||||
b.append(_ts);
|
|
||||||
b.append(_id);
|
|
||||||
b.append(_value);
|
|
||||||
|
|
||||||
_issuedTo.appendTo(b);
|
|
||||||
_signedBy.appendTo(b);
|
|
||||||
if (!forSign) {
|
|
||||||
b.append((uint8_t)1);
|
|
||||||
b.append((uint16_t)_signatureLength);
|
|
||||||
b.append(_signature,_signatureLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
b.append((uint16_t)0); // length of additional fields, currently 0
|
|
||||||
|
|
||||||
if (forSign) b.append((uint64_t)0x7f7f7f7f7f7f7f7fULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<unsigned int C>
|
|
||||||
inline unsigned int deserialize(const Buffer<C> &b,unsigned int startAt = 0)
|
|
||||||
{
|
|
||||||
unsigned int p = startAt;
|
|
||||||
|
|
||||||
*this = Tag();
|
|
||||||
|
|
||||||
_networkId = b.template at<uint64_t>(p); p += 8;
|
|
||||||
_ts = b.template at<uint64_t>(p); p += 8;
|
|
||||||
_id = b.template at<uint32_t>(p); p += 4;
|
|
||||||
|
|
||||||
_value = b.template at<uint32_t>(p); p += 4;
|
|
||||||
|
|
||||||
_issuedTo.setTo(b.field(p,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); p += ZT_ADDRESS_LENGTH;
|
|
||||||
_signedBy.setTo(b.field(p,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); p += ZT_ADDRESS_LENGTH;
|
|
||||||
if (b[p++] == 1) {
|
|
||||||
_signatureLength = b.template at<uint16_t>(p);
|
|
||||||
if (_signatureLength > sizeof(_signature))
|
|
||||||
throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_CRYPTOGRAPHIC_TOKEN;
|
|
||||||
p += 2;
|
|
||||||
memcpy(_signature,b.field(p,_signatureLength),_signatureLength); p += _signatureLength;
|
|
||||||
} else {
|
|
||||||
p += 2 + b.template at<uint16_t>(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
p += 2 + b.template at<uint16_t>(p);
|
|
||||||
if (p > b.size())
|
|
||||||
throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_OVERFLOW;
|
|
||||||
|
|
||||||
return (p - startAt);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Provides natural sort order by ID
|
// Provides natural sort order by ID
|
||||||
ZT_ALWAYS_INLINE bool operator<(const Tag &t) const { return (_id < t._id); }
|
ZT_ALWAYS_INLINE bool operator<(const Tag &t) const { return (_id < t._id); }
|
||||||
|
|
|
@ -212,14 +212,14 @@ static ZT_ALWAYS_INLINE unsigned long hexStrToULong(const char *s) { return strt
|
||||||
static ZT_ALWAYS_INLINE long hexStrToLong(const char *s) { return strtol(s,(char **)0,16); }
|
static ZT_ALWAYS_INLINE long hexStrToLong(const char *s) { return strtol(s,(char **)0,16); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static ZT_ALWAYS_INLINE unsigned int strToUInt(const char *s) { return (unsigned int)strtoul(s,(char **)0,10); }
|
static ZT_ALWAYS_INLINE unsigned int strToUInt(const char *s) { return (unsigned int)strtoul(s,nullptr,10); }
|
||||||
|
|
||||||
static ZT_ALWAYS_INLINE unsigned long long strToU64(const char *s)
|
static ZT_ALWAYS_INLINE unsigned long long strToU64(const char *s)
|
||||||
{
|
{
|
||||||
#ifdef __WINDOWS__
|
#ifdef __WINDOWS__
|
||||||
return (unsigned long long)_strtoui64(s,(char **)0,10);
|
return (unsigned long long)_strtoui64(s,(char **)0,10);
|
||||||
#else
|
#else
|
||||||
return strtoull(s,(char **)0,10);
|
return strtoull(s,nullptr,10);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,16 +228,16 @@ static ZT_ALWAYS_INLINE long long hexStrTo64(const char *s)
|
||||||
#ifdef __WINDOWS__
|
#ifdef __WINDOWS__
|
||||||
return (long long)_strtoi64(s,(char **)0,16);
|
return (long long)_strtoi64(s,(char **)0,16);
|
||||||
#else
|
#else
|
||||||
return strtoll(s,(char **)0,16);
|
return strtoll(s,nullptr,16);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static ZT_ALWAYS_INLINE unsigned long long hexStrToU64(const char *s)
|
static ZT_ALWAYS_INLINE unsigned long long hexStrToU64(const char *s)
|
||||||
{
|
{
|
||||||
#ifdef __WINDOWS__
|
#ifdef __WINDOWS__
|
||||||
return (unsigned long long)_strtoui64(s,(char **)0,16);
|
return (unsigned long long)_strtoui64(s,nullptr,16);
|
||||||
#else
|
#else
|
||||||
return strtoull(s,(char **)0,16);
|
return strtoull(s,nullptr,16);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue