mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-05 20:13:44 +02:00
Various little things...
This commit is contained in:
parent
a0ac4a744e
commit
8c8a3c58ec
7 changed files with 94 additions and 76 deletions
|
@ -26,6 +26,7 @@ bool Endpoint::operator==(const Endpoint &ep) const
|
|||
case ZEROTIER: return ((_v.zt.a == ep._v.zt.a)&&(memcmp(_v.zt.idh,ep._v.zt.idh,sizeof(_v.zt.idh)) == 0));
|
||||
case URL: return (strcmp(_v.url,ep._v.url) == 0);
|
||||
case ETHERNET: return (_v.eth == ep._v.eth);
|
||||
case WEBRTC: return ((_v.webrtc.offerLen == ep._v.webrtc.offerLen)&&(memcmp(_v.webrtc.offer,ep._v.webrtc.offer,_v.webrtc.offerLen) == 0));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -47,6 +48,11 @@ bool Endpoint::operator<(const Endpoint &ep) const
|
|||
case ZEROTIER: return (_v.zt.a < ep._v.zt.a) ? true : ((_v.zt.a == ep._v.zt.a)&&(memcmp(_v.zt.idh,ep._v.zt.idh,sizeof(_v.zt.idh)) < 0));
|
||||
case URL: return (strcmp(_v.url,ep._v.url) < 0);
|
||||
case ETHERNET: return (_v.eth < ep._v.eth);
|
||||
case WEBRTC:
|
||||
if (_v.webrtc.offerLen < ep._v.webrtc.offerLen)
|
||||
return true;
|
||||
else if (_v.webrtc.offerLen == ep._v.webrtc.offerLen)
|
||||
return memcmp(_v.webrtc.offer,ep._v.webrtc.offer,_v.webrtc.offerLen) < 0;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
@ -102,6 +108,10 @@ int Endpoint::marshal(uint8_t data[ZT_ENDPOINT_MARSHAL_SIZE_MAX]) const noexcept
|
|||
data[11] = (uint8_t)(_v.eth >> 8U);
|
||||
data[12] = (uint8_t)_v.eth;
|
||||
return 13;
|
||||
case WEBRTC:
|
||||
Utils::storeBigEndian(data + 7,(uint16_t)_v.webrtc.offerLen);
|
||||
memcpy(data + 9,_v.webrtc.offer,_v.webrtc.offerLen);
|
||||
return 9 + _v.webrtc.offerLen;
|
||||
default:
|
||||
data[0] = (uint8_t)NIL;
|
||||
return 7;
|
||||
|
@ -173,6 +183,14 @@ int Endpoint::unmarshal(const uint8_t *restrict data,const int len) noexcept
|
|||
_v.eth |= ((uint64_t)data[11]) << 8U;
|
||||
_v.eth |= (uint64_t)data[12];
|
||||
return 13;
|
||||
case WEBRTC:
|
||||
if (len < 9)
|
||||
return -1;
|
||||
_v.webrtc.offerLen = Utils::loadBigEndian<uint16_t>(data + 7);
|
||||
if ((len < (9 + _v.webrtc.offerLen))||(_v.webrtc.offerLen > ZT_ENDPOINT_MAX_NAME_SIZE))
|
||||
return -1;
|
||||
memcpy(_v.webrtc.offer,data + 9,_v.webrtc.offerLen);
|
||||
return 9 + _v.webrtc.offerLen;
|
||||
default:
|
||||
// Unrecognized endpoint types not yet specified must start with a byte
|
||||
// length size so that older versions of ZeroTier can skip them.
|
||||
|
|
|
@ -48,6 +48,7 @@ public:
|
|||
ZEROTIER = 4, // ZeroTier Address (for relaying and meshy behavior)
|
||||
URL = 5, // URL for http/https/ws/etc. (not implemented yet)
|
||||
ETHERNET = 6, // 48-bit LAN-local Ethernet address
|
||||
WEBRTC = 7, // WebRTC data channels
|
||||
UNRECOGNIZED = 255 // Unrecognized endpoint type encountered in stream
|
||||
};
|
||||
|
||||
|
@ -152,6 +153,10 @@ private:
|
|||
uint16_t port;
|
||||
char name[ZT_ENDPOINT_MAX_NAME_SIZE];
|
||||
} dns;
|
||||
struct {
|
||||
uint16_t offerLen;
|
||||
uint8_t offer[ZT_ENDPOINT_MAX_NAME_SIZE];
|
||||
} webrtc;
|
||||
struct {
|
||||
uint64_t a;
|
||||
uint8_t idh[ZT_IDENTITY_HASH_SIZE];
|
||||
|
|
|
@ -46,9 +46,6 @@ namespace ZeroTier {
|
|||
* Type 1 identities also use a simpler mechanism to rate limit identity generation (as
|
||||
* a defense in depth against intentional collision) that makes local identity validation
|
||||
* faster, allowing full identity validation on all unmarshal() operations.
|
||||
*
|
||||
* The default is still type 0, but this may change in future versions once 1.x is no
|
||||
* longer common in the wild.
|
||||
*/
|
||||
class Identity : public TriviallyCopyable
|
||||
{
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
#include "SHA512.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
@ -68,7 +66,7 @@ static const uint64_t K[80] = {
|
|||
#define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7))
|
||||
#define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6))
|
||||
|
||||
static inline void sha512_compress(sha512_state *const md,uint8_t *const buf)
|
||||
static void sha512_compress(sha512_state *const md,uint8_t *const buf)
|
||||
{
|
||||
uint64_t S[8], W[80], t0, t1;
|
||||
int i;
|
||||
|
@ -101,7 +99,7 @@ static inline void sha512_compress(sha512_state *const md,uint8_t *const buf)
|
|||
md->state[i] = md->state[i] + S[i];
|
||||
}
|
||||
|
||||
static inline void sha384_init(sha512_state *const md)
|
||||
static ZT_ALWAYS_INLINE void sha384_init(sha512_state *const md)
|
||||
{
|
||||
md->curlen = 0;
|
||||
md->length = 0;
|
||||
|
@ -115,7 +113,7 @@ static inline void sha384_init(sha512_state *const md)
|
|||
md->state[7] = 0x47b5481dbefa4fa4ULL;
|
||||
}
|
||||
|
||||
static inline void sha512_init(sha512_state *const md)
|
||||
static ZT_ALWAYS_INLINE void sha512_init(sha512_state *const md)
|
||||
{
|
||||
md->curlen = 0;
|
||||
md->length = 0;
|
||||
|
@ -129,7 +127,7 @@ static inline void sha512_init(sha512_state *const md)
|
|||
md->state[7] = 0x5be0cd19137e2179ULL;
|
||||
}
|
||||
|
||||
static inline void sha512_process(sha512_state *const md,const uint8_t *in,unsigned long inlen)
|
||||
static ZT_ALWAYS_INLINE void sha512_process(sha512_state *const md,const uint8_t *in,unsigned long inlen)
|
||||
{
|
||||
while (inlen > 0) {
|
||||
if (md->curlen == 0 && inlen >= 128) {
|
||||
|
@ -152,7 +150,7 @@ static inline void sha512_process(sha512_state *const md,const uint8_t *in,unsig
|
|||
}
|
||||
}
|
||||
|
||||
static inline void sha512_done(sha512_state *const md,uint8_t *out)
|
||||
static ZT_ALWAYS_INLINE void sha512_done(sha512_state *const md,uint8_t *out)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -217,31 +215,49 @@ void HMACSHA384(const uint8_t key[32],const void *msg,const unsigned int msglen,
|
|||
uint64_t kInPadded[16]; // input padded key
|
||||
uint64_t outer[22]; // output padded key | H(input padded key | msg)
|
||||
|
||||
#ifdef ZT_NO_UNALIGNED_ACCESS
|
||||
for(int i=0;i<32;++i) ((uint8_t *)kInPadded)[i] = key[i] ^ 0x36;
|
||||
for(int i=4;i<16;++i) kInPadded[i] = 0x3636363636363636ULL;
|
||||
for(int i=0;i<32;++i) ((uint8_t *)outer)[i] = key[i] ^ 0x5c;
|
||||
for(int i=4;i<16;++i) outer[i] = 0x5c5c5c5c5c5c5c5cULL;
|
||||
#else
|
||||
{
|
||||
const uint64_t k0 = ((const uint64_t *)key)[0];
|
||||
const uint64_t k1 = ((const uint64_t *)key)[1];
|
||||
const uint64_t k2 = ((const uint64_t *)key)[2];
|
||||
const uint64_t k3 = ((const uint64_t *)key)[3];
|
||||
kInPadded[0] = k0 ^ 0x3636363636363636ULL;
|
||||
kInPadded[1] = k1 ^ 0x3636363636363636ULL;
|
||||
kInPadded[2] = k2 ^ 0x3636363636363636ULL;
|
||||
kInPadded[3] = k3 ^ 0x3636363636363636ULL;
|
||||
for(int i=4;i<16;++i) kInPadded[i] = 0x3636363636363636ULL;
|
||||
outer[0] = k0 ^ 0x5c5c5c5c5c5c5c5cULL;
|
||||
outer[1] = k1 ^ 0x5c5c5c5c5c5c5c5cULL;
|
||||
outer[2] = k2 ^ 0x5c5c5c5c5c5c5c5cULL;
|
||||
outer[3] = k3 ^ 0x5c5c5c5c5c5c5c5cULL;
|
||||
for(int i=4;i<16;++i) outer[i] = 0x5c5c5c5c5c5c5c5cULL;
|
||||
}
|
||||
#endif
|
||||
const uint64_t k0 = Utils::loadAsIsEndian<uint64_t>(key);
|
||||
const uint64_t k1 = Utils::loadAsIsEndian<uint64_t>(key + 8);
|
||||
const uint64_t k2 = Utils::loadAsIsEndian<uint64_t>(key + 16);
|
||||
const uint64_t k3 = Utils::loadAsIsEndian<uint64_t>(key + 24);
|
||||
|
||||
const uint64_t ipad = 0x3636363636363636ULL;
|
||||
kInPadded[0] = k0 ^ ipad;
|
||||
kInPadded[1] = k1 ^ ipad;
|
||||
kInPadded[2] = k2 ^ ipad;
|
||||
kInPadded[3] = k3 ^ ipad;
|
||||
kInPadded[4] = ipad;
|
||||
kInPadded[5] = ipad;
|
||||
kInPadded[6] = ipad;
|
||||
kInPadded[7] = ipad;
|
||||
kInPadded[8] = ipad;
|
||||
kInPadded[9] = ipad;
|
||||
kInPadded[10] = ipad;
|
||||
kInPadded[11] = ipad;
|
||||
kInPadded[12] = ipad;
|
||||
kInPadded[13] = ipad;
|
||||
kInPadded[14] = ipad;
|
||||
kInPadded[15] = ipad;
|
||||
|
||||
const uint64_t opad = 0x5c5c5c5c5c5c5c5cULL;
|
||||
outer[0] = k0 ^ opad;
|
||||
outer[1] = k1 ^ opad;
|
||||
outer[2] = k2 ^ opad;
|
||||
outer[3] = k3 ^ opad;
|
||||
outer[4] = opad;
|
||||
outer[5] = opad;
|
||||
outer[6] = opad;
|
||||
outer[7] = opad;
|
||||
outer[8] = opad;
|
||||
outer[9] = opad;
|
||||
outer[10] = opad;
|
||||
outer[11] = opad;
|
||||
outer[12] = opad;
|
||||
outer[13] = opad;
|
||||
outer[14] = opad;
|
||||
outer[15] = opad;
|
||||
|
||||
SHA384(reinterpret_cast<uint8_t *>(outer) + 128,kInPadded,128,msg,msglen); // H(input padded key | msg)
|
||||
|
||||
SHA384(((uint8_t *)outer) + 128,kInPadded,128,msg,msglen); // H(input padded key | msg)
|
||||
SHA384(mac,outer,176); // H(output padded key | H(input padded key | msg))
|
||||
}
|
||||
|
||||
|
@ -249,10 +265,7 @@ void KBKDFHMACSHA384(const uint8_t key[32],const char label,const char context,c
|
|||
{
|
||||
uint8_t kbkdfMsg[13];
|
||||
uint8_t kbuf[48];
|
||||
kbkdfMsg[0] = (uint8_t)(iter >> 24U);
|
||||
kbkdfMsg[1] = (uint8_t)(iter >> 16U);
|
||||
kbkdfMsg[2] = (uint8_t)(iter >> 8U);
|
||||
kbkdfMsg[3] = (uint8_t)iter;
|
||||
Utils::storeBigEndian<uint32_t>(kbkdfMsg,(uint32_t)iter);
|
||||
kbkdfMsg[4] = (uint8_t)'Z';
|
||||
kbkdfMsg[5] = (uint8_t)'T'; // preface our labels with something ZT-specific
|
||||
kbkdfMsg[6] = (uint8_t)label;
|
||||
|
|
|
@ -18,10 +18,6 @@
|
|||
|
||||
#ifdef __APPLE__
|
||||
#include <CommonCrypto/CommonDigest.h>
|
||||
#else
|
||||
#ifdef ZT_USE_LIBCRYPTO
|
||||
#include <openssl/sha.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define ZT_SHA512_DIGEST_LEN 64
|
||||
|
@ -34,6 +30,7 @@
|
|||
|
||||
namespace ZeroTier {
|
||||
|
||||
// SHA384 and SHA512 are actually in the standard libraries on MacOS and iOS
|
||||
#ifdef __APPLE__
|
||||
#define ZT_HAVE_NATIVE_SHA512 1
|
||||
static ZT_ALWAYS_INLINE void SHA512(void *digest,const void *data,unsigned int len)
|
||||
|
@ -60,34 +57,6 @@ static ZT_ALWAYS_INLINE void SHA384(void *digest,const void *data0,unsigned int
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifndef ZT_HAVE_NATIVE_SHA512
|
||||
#ifdef ZT_USE_LIBCRYPTO
|
||||
#define ZT_HAVE_NATIVE_SHA512 1
|
||||
static ZT_ALWAYS_INLINE void SHA512(void *digest,const void *data,unsigned int len)
|
||||
{
|
||||
SHA512_CTX ctx;
|
||||
SHA512_Init(&ctx);
|
||||
SHA512_Update(&ctx,data,len);
|
||||
SHA512_Final(reinterpret_cast<unsigned char *>(digest),&ctx);
|
||||
}
|
||||
static ZT_ALWAYS_INLINE void SHA384(void *digest,const void *data,unsigned int len)
|
||||
{
|
||||
SHA512_CTX ctx;
|
||||
SHA384_Init(&ctx);
|
||||
SHA384_Update(&ctx,data,len);
|
||||
SHA384_Final(reinterpret_cast<unsigned char *>(digest),&ctx);
|
||||
}
|
||||
static ZT_ALWAYS_INLINE void SHA384(void *digest,const void *data0,unsigned int len0,const void *data1,unsigned int len1)
|
||||
{
|
||||
SHA512_CTX ctx;
|
||||
SHA384_Init(&ctx);
|
||||
SHA384_Update(&ctx,data0,len0);
|
||||
SHA384_Update(&ctx,data1,len1);
|
||||
SHA384_Final(reinterpret_cast<unsigned char *>(digest),&ctx);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ZT_HAVE_NATIVE_SHA512
|
||||
void SHA512(void *digest,const void *data,unsigned int len);
|
||||
void SHA384(void *digest,const void *data,unsigned int len);
|
||||
|
|
|
@ -62,7 +62,7 @@ Topology::Topology(const RuntimeEnvironment *renv,const Identity &myId,void *tPt
|
|||
_loadCached(tPtr,r->address(),p);
|
||||
if ((!p)||(p->identity() != *r)) {
|
||||
p.set(new Peer(RR));
|
||||
p->init(myId,*r);
|
||||
p->init(*r);
|
||||
}
|
||||
_rootPeers.push_back(p);
|
||||
}
|
||||
|
@ -147,7 +147,7 @@ void Topology::addRoot(void *tPtr,const Identity &id,const InetAddress &bootstra
|
|||
SharedPtr<Peer> &p = _peers[id.address()];
|
||||
if (!p) {
|
||||
p.set(new Peer(RR));
|
||||
p->init(_myIdentity,id);
|
||||
p->init(id);
|
||||
if (bootstrap)
|
||||
p->setBootstrap(Endpoint(bootstrap));
|
||||
}
|
||||
|
|
24
node/VL1.cpp
24
node/VL1.cpp
|
@ -676,6 +676,13 @@ bool VL1::_ERROR(void *tPtr,const SharedPtr<Path> &path,const SharedPtr<Peer> &p
|
|||
return false;
|
||||
}
|
||||
Protocol::ERROR::Header &eh = pkt.as<Protocol::ERROR::Header>();
|
||||
|
||||
const int64_t now = RR->node->now();
|
||||
if (!RR->expect->expecting(eh.inRePacketId,now)) {
|
||||
RR->t->incomingPacketDropped(tPtr,0x4c1f1ff7,0,0,identityFromPeerPtr(peer),path->address(),0,Protocol::VERB_OK,ZT_TRACE_PACKET_DROP_REASON_REPLY_NOT_EXPECTED);
|
||||
return false;
|
||||
}
|
||||
|
||||
switch(eh.error) {
|
||||
|
||||
//case Protocol::ERROR_INVALID_REQUEST:
|
||||
|
@ -881,7 +888,7 @@ bool VL1::_PUSH_DIRECT_PATHS(void *tPtr,const SharedPtr<Path> &path,const Shared
|
|||
InetAddress a;
|
||||
Endpoint ep;
|
||||
for(unsigned int pi=0;pi<numPaths;++pi) {
|
||||
/*const uint8_t flags = pkt.rI8(ptr);*/ ++ptr;
|
||||
/*const uint8_t flags = pkt.rI8(ptr);*/ ++ptr; // flags are not presently used
|
||||
ptr += pkt.rI16(ptr); // extended attributes size, currently always 0
|
||||
const unsigned int addrType = pkt.rI8(ptr);
|
||||
const unsigned int addrRecordLen = pkt.rI8(ptr);
|
||||
|
@ -908,6 +915,7 @@ bool VL1::_PUSH_DIRECT_PATHS(void *tPtr,const SharedPtr<Path> &path,const Shared
|
|||
addrLen = 16;
|
||||
addrPort = pkt.rI16(ptr);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
if (Buf::readOverflow(ptr,packetSize)) {
|
||||
|
@ -919,11 +927,18 @@ bool VL1::_PUSH_DIRECT_PATHS(void *tPtr,const SharedPtr<Path> &path,const Shared
|
|||
a.set(addrBytes,addrLen,addrPort);
|
||||
} else if (addrLen) {
|
||||
if (ep.unmarshal(reinterpret_cast<const uint8_t *>(addrBytes),(int)addrLen) <= 0) {
|
||||
RR->t->incomingPacketDropped(tPtr,0xbad0f00d,pdp.h.packetId,0,peer->identity(),path->address(),Protocol::packetHops(pdp.h),Protocol::VERB_PUSH_DIRECT_PATHS,ZT_TRACE_PACKET_DROP_REASON_MALFORMED_PACKET);
|
||||
RR->t->incomingPacketDropped(tPtr,0x00e0f00d,pdp.h.packetId,0,peer->identity(),path->address(),Protocol::packetHops(pdp.h),Protocol::VERB_PUSH_DIRECT_PATHS,ZT_TRACE_PACKET_DROP_REASON_MALFORMED_PACKET);
|
||||
return false;
|
||||
}
|
||||
if ((ep.type() == Endpoint::INETADDR_V4)||(ep.type() == Endpoint::INETADDR_V6))
|
||||
a = ep.inetAddr();
|
||||
|
||||
switch(ep.type()) {
|
||||
case Endpoint::INETADDR_V4:
|
||||
case Endpoint::INETADDR_V6:
|
||||
a = ep.inetAddr();
|
||||
break;
|
||||
default: // other types are not supported yet
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (a) {
|
||||
|
@ -937,6 +952,7 @@ bool VL1::_PUSH_DIRECT_PATHS(void *tPtr,const SharedPtr<Path> &path,const Shared
|
|||
|
||||
bool VL1::_USER_MESSAGE(void *tPtr,const SharedPtr<Path> &path,const SharedPtr<Peer> &peer,Buf &pkt,int packetSize)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
bool VL1::_ENCAP(void *tPtr,const SharedPtr<Path> &path,const SharedPtr<Peer> &peer,Buf &pkt,int packetSize)
|
||||
|
|
Loading…
Add table
Reference in a new issue