mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-05 20:13: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
|
||||
Poly1305.cpp
|
||||
Protocol.cpp
|
||||
Revocation.cpp
|
||||
Salsa20.cpp
|
||||
SelfAwareness.cpp
|
||||
SHA512.cpp
|
||||
Switch.cpp
|
||||
Tag.cpp
|
||||
Topology.cpp
|
||||
Trace.cpp
|
||||
Utils.cpp
|
||||
|
|
|
@ -122,7 +122,7 @@ int Capability::unmarshal(const uint8_t *data,int len)
|
|||
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;
|
||||
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 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);
|
||||
|
||||
// Provides natural sort order by ID
|
||||
|
|
|
@ -233,10 +233,6 @@
|
|||
|
||||
// Exceptions thrown in core ZT code
|
||||
#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 */
|
||||
#define ZT_ETHERTYPE_IPV4 0x0800
|
||||
|
|
|
@ -313,7 +313,7 @@ bool InetAddress::isNetwork() const
|
|||
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;
|
||||
switch(ss_family) {
|
||||
|
|
|
@ -494,7 +494,7 @@ public:
|
|||
explicit ZT_ALWAYS_INLINE operator bool() const { return (ss_family != 0); }
|
||||
|
||||
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);
|
||||
|
||||
bool operator==(const InetAddress &a) const;
|
||||
|
|
|
@ -43,7 +43,8 @@ NetworkConfig::NetworkConfig() :
|
|||
|
||||
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];
|
||||
|
||||
d.clear();
|
||||
|
@ -64,62 +65,90 @@ bool NetworkConfig::toDictionary(Dictionary &d,bool includeLegacy) const
|
|||
// Then add binary blobs
|
||||
|
||||
if (this->com) {
|
||||
tmp->clear();
|
||||
this->com.serialize(*tmp);
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_COM,*tmp)) return false;
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_COM,(const char *)tmp,this->com.marshal(tmp)))
|
||||
return false;
|
||||
}
|
||||
|
||||
tmp->clear();
|
||||
for(unsigned int i=0;i<this->capabilityCount;++i)
|
||||
this->capabilities[i].serialize(*tmp);
|
||||
if (tmp->size()) {
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_CAPABILITIES,*tmp)) return false;
|
||||
buf.clear();
|
||||
for(unsigned int i=0;i<this->capabilityCount;++i) {
|
||||
int l = this->capabilities[i].marshal(tmp);
|
||||
if (l < 0)
|
||||
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();
|
||||
for(unsigned int i=0;i<this->tagCount;++i)
|
||||
this->tags[i].serialize(*tmp);
|
||||
if (tmp->size()) {
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_TAGS,*tmp)) return false;
|
||||
buf.clear();
|
||||
for(unsigned int i=0;i<this->tagCount;++i) {
|
||||
int l = this->tags[i].marshal(tmp);
|
||||
if (l < 0)
|
||||
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();
|
||||
for(unsigned int i=0;i<this->certificateOfOwnershipCount;++i)
|
||||
this->certificatesOfOwnership[i].serialize(*tmp);
|
||||
if (tmp->size()) {
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_CERTIFICATES_OF_OWNERSHIP,*tmp)) return false;
|
||||
buf.clear();
|
||||
for(unsigned int i=0;i<this->certificateOfOwnershipCount;++i) {
|
||||
int l = this->certificatesOfOwnership[i].marshal(tmp);
|
||||
if (l < 0)
|
||||
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();
|
||||
for(unsigned int i=0;i<this->specialistCount;++i)
|
||||
tmp->append((uint64_t)this->specialists[i]);
|
||||
if (tmp->size()) {
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_SPECIALISTS,*tmp)) return false;
|
||||
buf.clear();
|
||||
for(unsigned int i=0;i<this->specialistCount;++i) {
|
||||
Utils::storeBigEndian<uint64_t>(tmp,this->specialists[i]);
|
||||
buf.insert(buf.end(),tmp,tmp + 8);
|
||||
}
|
||||
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) {
|
||||
reinterpret_cast<const InetAddress *>(&(this->routes[i].target))->serialize(*tmp);
|
||||
reinterpret_cast<const InetAddress *>(&(this->routes[i].via))->serialize(*tmp);
|
||||
tmp->append((uint16_t)this->routes[i].flags);
|
||||
tmp->append((uint16_t)this->routes[i].metric);
|
||||
int l = asInetAddress(this->routes[i].target).marshal(tmp);
|
||||
if (l < 0)
|
||||
return false;
|
||||
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 (!d.add(ZT_NETWORKCONFIG_DICT_KEY_ROUTES,*tmp)) return false;
|
||||
if (!buf.empty()) {
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_ROUTES,(const char *)buf.data(),(int)buf.size()))
|
||||
return false;
|
||||
}
|
||||
|
||||
tmp->clear();
|
||||
for(unsigned int i=0;i<this->staticIpCount;++i)
|
||||
this->staticIps[i].serialize(*tmp);
|
||||
if (tmp->size()) {
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_STATIC_IPS,*tmp)) return false;
|
||||
buf.clear();
|
||||
for(unsigned int i=0;i<this->staticIpCount;++i) {
|
||||
int l = this->staticIps[i].marshal(tmp);
|
||||
if (l < 0)
|
||||
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) {
|
||||
tmp->clear();
|
||||
Capability::serializeRules(*tmp,rules,ruleCount);
|
||||
if (tmp->size()) {
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_RULES,*tmp)) return false;
|
||||
buf.resize(ruleCount * ZT_VIRTUALNETWORKRULE_MARSHAL_SIZE_MAX);
|
||||
int l = Capability::marshalVirtualNetworkRules(buf.data(),rules,ruleCount);
|
||||
if (l > 0) {
|
||||
if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_RULES,(const char *)buf.data(),l))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace Protocol {
|
|||
|
||||
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
|
||||
|
|
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_MARSHAL_SIZE_MAX (4 + 4 + 8 + 4 + 4 + 8 + 8 + 5 + 5 + 1 + 1 + 2 + ZT_SIGNATURE_BUFFER_SIZE + 2)
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
class RuntimeEnvironment;
|
||||
|
@ -95,17 +97,7 @@ public:
|
|||
* @param signer Signing identity, must have private key
|
||||
* @return True if signature was successful
|
||||
*/
|
||||
ZT_ALWAYS_INLINE 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;
|
||||
}
|
||||
bool sign(const Identity &signer);
|
||||
|
||||
/**
|
||||
* 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); }
|
||||
|
||||
template<unsigned int C>
|
||||
inline void serialize(Buffer<C> &b,const bool forSign = false) const
|
||||
{
|
||||
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);
|
||||
}
|
||||
static ZT_ALWAYS_INLINE int marshalSizeMax() { return ZT_REVOCATION_MARSHAL_SIZE_MAX; }
|
||||
int marshal(uint8_t data[ZT_REVOCATION_MARSHAL_SIZE_MAX],bool forSign = false) const;
|
||||
int unmarshal(const uint8_t *restrict data,const int len);
|
||||
|
||||
private:
|
||||
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 "Identity.hpp"
|
||||
|
||||
#define ZT_TAG_MARSHAL_SIZE_MAX (8 + 8 + 4 + 4 + 5 + 5 + 1 + 2 + ZT_SIGNATURE_BUFFER_SIZE + 2)
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
class RuntimeEnvironment;
|
||||
|
@ -95,17 +97,7 @@ public:
|
|||
* @param signer Signing identity, must have private key
|
||||
* @return True if signature was successful
|
||||
*/
|
||||
inline 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;
|
||||
}
|
||||
bool sign(const Identity &signer);
|
||||
|
||||
/**
|
||||
* 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); }
|
||||
|
||||
template<unsigned int C>
|
||||
inline void serialize(Buffer<C> &b,const bool forSign = false) const
|
||||
{
|
||||
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);
|
||||
}
|
||||
static ZT_ALWAYS_INLINE int marshalSizeMax() { return ZT_TAG_MARSHAL_SIZE_MAX; }
|
||||
int marshal(uint8_t data[ZT_TAG_MARSHAL_SIZE_MAX],bool forSign = false) const;
|
||||
int unmarshal(const uint8_t *data,int len);
|
||||
|
||||
// Provides natural sort order by 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); }
|
||||
#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)
|
||||
{
|
||||
#ifdef __WINDOWS__
|
||||
return (unsigned long long)_strtoui64(s,(char **)0,10);
|
||||
#else
|
||||
return strtoull(s,(char **)0,10);
|
||||
return strtoull(s,nullptr,10);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -228,16 +228,16 @@ static ZT_ALWAYS_INLINE long long hexStrTo64(const char *s)
|
|||
#ifdef __WINDOWS__
|
||||
return (long long)_strtoi64(s,(char **)0,16);
|
||||
#else
|
||||
return strtoll(s,(char **)0,16);
|
||||
return strtoll(s,nullptr,16);
|
||||
#endif
|
||||
}
|
||||
|
||||
static ZT_ALWAYS_INLINE unsigned long long hexStrToU64(const char *s)
|
||||
{
|
||||
#ifdef __WINDOWS__
|
||||
return (unsigned long long)_strtoui64(s,(char **)0,16);
|
||||
return (unsigned long long)_strtoui64(s,nullptr,16);
|
||||
#else
|
||||
return strtoull(s,(char **)0,16);
|
||||
return strtoull(s,nullptr,16);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue