From 5a29f9ba2d4885955840d7560b98d2bc7faf6566 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Mon, 20 Jan 2020 11:18:38 -0800 Subject: [PATCH] cleanup --- node/CMakeLists.txt | 1 + node/Capability.cpp | 35 +++++++++++++++++++++++++++++++++++ node/Capability.hpp | 43 ++++++++++++++----------------------------- node/Credential.hpp | 10 +++++----- node/Identity.cpp | 4 ++-- node/Packet.cpp | 44 +++++++++++++++++++++++++++----------------- node/Packet.hpp | 13 ++++++------- 7 files changed, 90 insertions(+), 60 deletions(-) create mode 100644 node/Capability.cpp diff --git a/node/CMakeLists.txt b/node/CMakeLists.txt index a5043b8fe..71a9f5c79 100644 --- a/node/CMakeLists.txt +++ b/node/CMakeLists.txt @@ -51,6 +51,7 @@ set(core_src AES.cpp Buf.cpp C25519.cpp + Capability.cpp Credential.cpp ECC384.cpp Endpoint.cpp diff --git a/node/Capability.cpp b/node/Capability.cpp new file mode 100644 index 000000000..327927035 --- /dev/null +++ b/node/Capability.cpp @@ -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 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 diff --git a/node/Capability.hpp b/node/Capability.hpp index 0a6a3ee8b..3a7037ee9 100644 --- a/node/Capability.hpp +++ b/node/Capability.hpp @@ -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 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 static inline void serializeRules(Buffer &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; diff --git a/node/Credential.hpp b/node/Credential.hpp index 106a5b726..33cb33ee8 100644 --- a/node/Credential.hpp +++ b/node/Credential.hpp @@ -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 diff --git a/node/Identity.cpp b/node/Identity.cpp index d29fe8d62..045dca52a 100644 --- a/node/Identity.cpp +++ b/node/Identity.cpp @@ -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; diff --git a/node/Packet.cpp b/node/Packet.cpp index f17b29bdd..0e680a3cd 100644 --- a/node/Packet.cpp +++ b/node/Packet.cpp @@ -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 +#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 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 diff --git a/node/Packet.hpp b/node/Packet.hpp index f20eb7f36..4ba7ab1e1 100644 --- a/node/Packet.hpp +++ b/node/Packet.hpp @@ -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)