This commit is contained in:
Adam Ierymenko 2020-01-20 11:18:38 -08:00
parent 03190c5a55
commit 5a29f9ba2d
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
7 changed files with 90 additions and 60 deletions

View file

@ -51,6 +51,7 @@ set(core_src
AES.cpp
Buf.cpp
C25519.cpp
Capability.cpp
Credential.cpp
ECC384.cpp
Endpoint.cpp

35
node/Capability.cpp Normal file
View file

@ -0,0 +1,35 @@
/*
* 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 "Capability.hpp"
namespace ZeroTier {
bool Capability::sign(const Identity &from,const Address &to)
{
try {
for(unsigned int i=0;((i<_maxCustodyChainLength)&&(i<ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH));++i) {
if (!(_custody[i].to)) {
Buffer<(sizeof(Capability) * 2)> tmp;
this->serialize(tmp,true);
_custody[i].to = to;
_custody[i].from = from.address();
_custody[i].signatureLength = from.sign(tmp.data(),tmp.size(),_custody[i].signature,sizeof(_custody[i].signature));
return true;
}
}
} catch ( ... ) {}
return false;
}
} // namespace ZeroTier

View file

@ -58,9 +58,9 @@ class Capability : public Credential
friend class Credential;
public:
static inline Credential::Type credentialType() { return Credential::CREDENTIAL_TYPE_CAPABILITY; }
static ZT_ALWAYS_INLINE Credential::Type credentialType() { return Credential::CREDENTIAL_TYPE_CAPABILITY; }
inline Capability() :
ZT_ALWAYS_INLINE Capability() :
_nwid(0),
_ts(0),
_id(0),
@ -79,7 +79,7 @@ public:
* @param rules Network flow rules for this capability
* @param ruleCount Number of flow rules
*/
inline Capability(uint32_t id,uint64_t nwid,int64_t ts,unsigned int mccl,const ZT_VirtualNetworkRule *rules,unsigned int ruleCount) :
ZT_ALWAYS_INLINE Capability(uint32_t id,uint64_t nwid,int64_t ts,unsigned int mccl,const ZT_VirtualNetworkRule *rules,unsigned int ruleCount) :
_nwid(nwid),
_ts(ts),
_id(id),
@ -93,32 +93,32 @@ public:
/**
* @return Rules -- see ruleCount() for size of array
*/
inline const ZT_VirtualNetworkRule *rules() const { return _rules; }
ZT_ALWAYS_INLINE const ZT_VirtualNetworkRule *rules() const { return _rules; }
/**
* @return Number of rules in rules()
*/
inline unsigned int ruleCount() const { return _ruleCount; }
ZT_ALWAYS_INLINE unsigned int ruleCount() const { return _ruleCount; }
/**
* @return ID and evaluation order of this capability in network
*/
inline uint32_t id() const { return _id; }
ZT_ALWAYS_INLINE uint32_t id() const { return _id; }
/**
* @return Network ID for which this capability was issued
*/
inline uint64_t networkId() const { return _nwid; }
ZT_ALWAYS_INLINE uint64_t networkId() const { return _nwid; }
/**
* @return Timestamp
*/
inline int64_t timestamp() const { return _ts; }
ZT_ALWAYS_INLINE int64_t timestamp() const { return _ts; }
/**
* @return Last 'to' address in chain of custody
*/
inline Address issuedTo() const
ZT_ALWAYS_INLINE Address issuedTo() const
{
Address i2;
for(unsigned int i=0;i<ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH;++i) {
@ -142,29 +142,14 @@ public:
* @param to Recipient of this signature
* @return True if signature successful and chain of custody appended
*/
inline bool sign(const Identity &from,const Address &to)
{
try {
for(unsigned int i=0;((i<_maxCustodyChainLength)&&(i<ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH));++i) {
if (!(_custody[i].to)) {
Buffer<(sizeof(Capability) * 2)> tmp;
this->serialize(tmp,true);
_custody[i].to = to;
_custody[i].from = from.address();
_custody[i].signatureLength = from.sign(tmp.data(),tmp.size(),_custody[i].signature,sizeof(_custody[i].signature));
return true;
}
}
} catch ( ... ) {}
return false;
}
bool sign(const Identity &from,const Address &to);
/**
* Verify this capability's chain of custody and signatures
*
* @param RR Runtime environment to provide for peer lookup, etc.
*/
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 inline void serializeRules(Buffer<C> &b,const ZT_VirtualNetworkRule *rules,unsigned int ruleCount)
@ -459,10 +444,10 @@ public:
}
// Provides natural sort order by ID
inline bool operator<(const Capability &c) const { return (_id < c._id); }
ZT_ALWAYS_INLINE bool operator<(const Capability &c) const { return (_id < c._id); }
inline bool operator==(const Capability &c) const { return (memcmp(this,&c,sizeof(Capability)) == 0); }
inline bool operator!=(const Capability &c) const { return (memcmp(this,&c,sizeof(Capability)) != 0); }
ZT_ALWAYS_INLINE bool operator==(const Capability &c) const { return (memcmp(this,&c,sizeof(Capability)) == 0); }
ZT_ALWAYS_INLINE bool operator!=(const Capability &c) const { return (memcmp(this,&c,sizeof(Capability)) != 0); }
private:
uint64_t _nwid;

View file

@ -64,11 +64,11 @@ public:
};
protected:
VerifyResult _verify(const RuntimeEnvironment *const RR,void *tPtr,const CertificateOfMembership &credential) const;
VerifyResult _verify(const RuntimeEnvironment *const RR,void *tPtr,const Revocation &credential) const;
VerifyResult _verify(const RuntimeEnvironment *const RR,void *tPtr,const Tag &credential) const;
VerifyResult _verify(const RuntimeEnvironment *const RR,void *tPtr,const CertificateOfOwnership &credential) const;
VerifyResult _verify(const RuntimeEnvironment *const RR,void *tPtr,const Capability &credential) const;
VerifyResult _verify(const RuntimeEnvironment *RR,void *tPtr,const CertificateOfMembership &credential) const;
VerifyResult _verify(const RuntimeEnvironment *RR,void *tPtr,const Revocation &credential) const;
VerifyResult _verify(const RuntimeEnvironment *RR,void *tPtr,const Tag &credential) const;
VerifyResult _verify(const RuntimeEnvironment *RR,void *tPtr,const CertificateOfOwnership &credential) const;
VerifyResult _verify(const RuntimeEnvironment *RR,void *tPtr,const Capability &credential) const;
};
} // namespace ZeroTier

View file

@ -264,7 +264,7 @@ char *Identity::toString(bool includePrivate,char buf[ZT_IDENTITY_STRING_BUFFER_
}
*p = (char)0;
return buf;
} break;
}
case P384: {
char *p = buf;
@ -284,7 +284,7 @@ char *Identity::toString(bool includePrivate,char buf[ZT_IDENTITY_STRING_BUFFER_
}
*p = (char)0;
return buf;
} break;
}
}
return nullptr;

View file

@ -18,9 +18,16 @@
#include "Mutex.hpp"
#include "LZ4.hpp"
#if (defined(_MSC_VER) || defined(__GNUC__) || defined(__clang)) && (defined(__amd64) || defined(__amd64__) || defined(__x86_64) || defined(__x86_64__) || defined(__AMD64) || defined(__AMD64__) || defined(_M_X64))
#define ZT_PACKET_USE_ATOMIC_INTRINSICS
#endif
#ifndef ZT_PACKET_USE_ATOMIC_INTRINSICS
#include <atomic>
#endif
namespace ZeroTier {
const unsigned char Packet::ZERO_KEY[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 uint8_t Packet::ZERO_KEY[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 };
void Packet::armor(const void *key,bool encryptPayload)
{
@ -116,24 +123,27 @@ bool Packet::uncompress()
return true;
}
static unsigned long long s_initPacketID()
{
unsigned long long tmp = 0;
Utils::getSecureRandom(&tmp,sizeof(tmp));
tmp >>= 31U;
tmp |= (((uint64_t)time(nullptr)) & 0xffffffffULL) << 33U;
return tmp;
}
#ifdef ZT_PACKET_USE_ATOMIC_INTRINSICS
static unsigned long long s_packetIdCtr = s_initPacketID();
#else
static std::atomic<unsigned long long> s_packetIdCtr(s_initPacketID());
#endif
uint64_t Packet::nextPacketId()
{
// The packet ID which is also the packet's nonce/IV can be sequential but
// it should never repeat. This scheme minimizes the chance of nonce
// repetition if (as will usually be the case) the clock is relatively
// accurate.
static uint64_t ctr = 0;
static Mutex lock;
lock.lock();
while (ctr == 0) {
Utils::getSecureRandom(&ctr,sizeof(ctr));
ctr >>= 32;
ctr |= (((uint64_t)time(nullptr)) & 0xffffffffULL) << 32;
}
const uint64_t i = ctr++;
lock.unlock();
return i;
#ifdef ZT_PACKET_USE_ATOMIC_INTRINSICS
return __sync_add_and_fetch(&s_packetIdCtr,1ULL);
#else
return ++s_packetIdCtr;
#endif
}
} // namespace ZeroTier

View file

@ -1174,8 +1174,7 @@ public:
bool uncompress();
private:
static const unsigned char ZERO_KEY[32];
static const uint8_t ZERO_KEY[32];
static uint64_t nextPacketId();
/**
@ -1189,9 +1188,9 @@ private:
* @param in Input key (32 bytes)
* @param out Output buffer (32 bytes)
*/
inline void _salsa20MangleKey(const unsigned char *in,unsigned char *out) const
ZT_ALWAYS_INLINE void _salsa20MangleKey(const uint8_t *in,uint8_t *out) const
{
const unsigned char *d = (const unsigned char *)data();
const uint8_t *const d = (const unsigned char *)data();
// IV and source/destination addresses. Using the addresses divides the
// key space into two halves-- A->B and B->A (since order will change).
@ -1201,12 +1200,12 @@ private:
// Flags, but with hop count masked off. Hop count is altered by forwarding
// nodes. It's one of the only parts of a packet modifiable by people
// without the key.
out[18] = in[18] ^ (d[ZT_PACKET_IDX_FLAGS] & 0xf8);
out[18] = in[18] ^ (d[ZT_PACKET_IDX_FLAGS] & 0xf8U);
// Raw packet size in bytes -- thus each packet size defines a new
// key space.
out[19] = in[19] ^ (unsigned char)(size() & 0xff);
out[20] = in[20] ^ (unsigned char)((size() >> 8) & 0xff); // little endian
out[19] = in[19] ^ (uint8_t)size();
out[20] = in[20] ^ (uint8_t)(size() >> 8U); // little endian
// Rest of raw key is used unchanged
for(unsigned int i=21;i<32;++i)