Clean up some old stuff.

This commit is contained in:
Adam Ierymenko 2018-01-26 20:00:37 -05:00
parent 5f5302e595
commit f3dfd63634
14 changed files with 101 additions and 236 deletions

View file

@ -1,117 +0,0 @@
/*
* ZeroTier One - Network Virtualization Everywhere
* Copyright (C) 2011-2018 ZeroTier, Inc. https://www.zerotier.com/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial closed-source software that incorporates or links
* directly against ZeroTier software without disclosing the source code
* of your own application.
*/
#ifndef ZT_ARRAY_HPP
#define ZT_ARRAY_HPP
#include <algorithm>
namespace ZeroTier {
/**
* Static array -- a simple thing that's belonged in STL since the time of the dinosaurs
*/
template<typename T,std::size_t S>
class Array
{
public:
Array() {}
Array(const Array &a)
{
for(unsigned long i=0;i<S;++i)
data[i] = a.data[i];
}
Array(const T *ptr)
{
for(unsigned long i=0;i<S;++i)
data[i] = ptr[i];
}
inline Array &operator=(const Array &a)
{
for(unsigned long i=0;i<S;++i)
data[i] = a.data[i];
return *this;
}
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef unsigned long size_type;
typedef long difference_type;
/*
typedef T* iterator;
typedef const T* const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
inline iterator begin() { return data; }
inline iterator end() { return &(data[S]); }
inline const_iterator begin() const { return data; }
inline const_iterator end() const { return &(data[S]); }
inline reverse_iterator rbegin() { return reverse_iterator(begin()); }
inline reverse_iterator rend() { return reverse_iterator(end()); }
inline const_reverse_iterator rbegin() const { return const_reverse_iterator(begin()); }
inline const_reverse_iterator rend() const { return const_reverse_iterator(end()); }
*/
inline unsigned long size() const { return S; }
inline unsigned long max_size() const { return S; }
inline reference operator[](const std::size_t n) { return data[n]; }
inline const_reference operator[](const std::size_t n) const { return data[n]; }
inline reference front() { return data[0]; }
inline const_reference front() const { return data[0]; }
inline reference back() { return data[S-1]; }
inline const_reference back() const { return data[S-1]; }
inline bool operator==(const Array &k) const
{
for(unsigned long i=0;i<S;++i) {
if (data[i] != k.data[i])
return false;
}
return true;
}
inline bool operator!=(const Array &k) const { return !(*this == k); }
inline bool operator<(const Array &k) const { return std::lexicographical_compare(data,data + S,k.data,k.data + S); }
inline bool operator>(const Array &k) const { return (k < *this); }
inline bool operator<=(const Array &k) const { return !(k < *this); }
inline bool operator>=(const Array &k) const { return !(*this < k); }
T data[S];
};
} // namespace ZeroTier
#endif

View file

@ -27,7 +27,6 @@
#ifndef ZT_C25519_HPP #ifndef ZT_C25519_HPP
#define ZT_C25519_HPP #define ZT_C25519_HPP
#include "Array.hpp"
#include "Utils.hpp" #include "Utils.hpp"
namespace ZeroTier { namespace ZeroTier {
@ -42,28 +41,10 @@ namespace ZeroTier {
class C25519 class C25519
{ {
public: public:
/** struct Public { uint8_t data[ZT_C25519_PUBLIC_KEY_LEN]; };
* Public key (both crypto and signing) struct Private { uint8_t data[ZT_C25519_PRIVATE_KEY_LEN]; };
*/ struct Signature { uint8_t data[ZT_C25519_SIGNATURE_LEN]; };
typedef Array<unsigned char,ZT_C25519_PUBLIC_KEY_LEN> Public; // crypto key, signing key (both 32 bytes) struct Pair { Public pub; Private priv; };
/**
* Private key (both crypto and signing)
*/
typedef Array<unsigned char,ZT_C25519_PRIVATE_KEY_LEN> Private; // crypto key, signing key (both 32 bytes)
/**
* Message signature
*/
typedef Array<unsigned char,ZT_C25519_SIGNATURE_LEN> Signature;
/**
* Public/private key pair
*/
typedef struct {
Public pub;
Private priv;
} Pair;
/** /**
* Generate a C25519 elliptic curve key pair * Generate a C25519 elliptic curve key pair
@ -71,7 +52,7 @@ public:
static inline Pair generate() static inline Pair generate()
{ {
Pair kp; Pair kp;
Utils::getSecureRandom(kp.priv.data,(unsigned int)kp.priv.size()); Utils::getSecureRandom(kp.priv.data,ZT_C25519_PRIVATE_KEY_LEN);
_calcPubDH(kp); _calcPubDH(kp);
_calcPubED(kp); _calcPubED(kp);
return kp; return kp;
@ -95,7 +76,7 @@ public:
{ {
Pair kp; Pair kp;
void *const priv = (void *)kp.priv.data; void *const priv = (void *)kp.priv.data;
Utils::getSecureRandom(priv,(unsigned int)kp.priv.size()); Utils::getSecureRandom(priv,ZT_C25519_PRIVATE_KEY_LEN);
_calcPubED(kp); // do Ed25519 key -- bytes 32-63 of pub and priv _calcPubED(kp); // do Ed25519 key -- bytes 32-63 of pub and priv
do { do {
++(((uint64_t *)priv)[1]); ++(((uint64_t *)priv)[1]);

View file

@ -84,7 +84,7 @@ std::string CertificateOfMembership::toString() const
if (_signedBy) { if (_signedBy) {
s.push_back(':'); s.push_back(':');
s.append(Utils::hex(_signature.data,(unsigned int)_signature.size(),tmp)); s.append(Utils::hex(_signature.data,ZT_C25519_SIGNATURE_LEN,tmp));
} }
return s; return s;
@ -94,7 +94,7 @@ void CertificateOfMembership::fromString(const char *s)
{ {
_qualifierCount = 0; _qualifierCount = 0;
_signedBy.zero(); _signedBy.zero();
memset(_signature.data,0,_signature.size()); memset(_signature.data,0,ZT_C25519_SIGNATURE_LEN);
if (!*s) if (!*s)
return; return;
@ -145,7 +145,7 @@ void CertificateOfMembership::fromString(const char *s)
colonAt = 0; colonAt = 0;
while ((s[colonAt])&&(s[colonAt] != ':')) ++colonAt; while ((s[colonAt])&&(s[colonAt] != ':')) ++colonAt;
if (colonAt) { if (colonAt) {
if (Utils::unhex(s,colonAt,_signature.data,(unsigned int)_signature.size()) != _signature.size()) if (Utils::unhex(s,colonAt,_signature.data,ZT_C25519_SIGNATURE_LEN) != ZT_C25519_SIGNATURE_LEN)
_signedBy.zero(); _signedBy.zero();
} else { } else {
_signedBy.zero(); _signedBy.zero();

View file

@ -142,7 +142,7 @@ public:
_qualifiers[2].value = issuedTo.toInt(); _qualifiers[2].value = issuedTo.toInt();
_qualifiers[2].maxDelta = 0xffffffffffffffffULL; _qualifiers[2].maxDelta = 0xffffffffffffffffULL;
_qualifierCount = 3; _qualifierCount = 3;
memset(_signature.data,0,_signature.size()); memset(_signature.data,0,ZT_C25519_SIGNATURE_LEN);
} }
inline CertificateOfMembership &operator=(const CertificateOfMembership &c) inline CertificateOfMembership &operator=(const CertificateOfMembership &c)
@ -293,7 +293,7 @@ public:
} }
_signedBy.appendTo(b); _signedBy.appendTo(b);
if (_signedBy) if (_signedBy)
b.append(_signature.data,(unsigned int)_signature.size()); b.append(_signature.data,ZT_C25519_SIGNATURE_LEN);
} }
template<unsigned int C> template<unsigned int C>
@ -329,8 +329,8 @@ public:
p += ZT_ADDRESS_LENGTH; p += ZT_ADDRESS_LENGTH;
if (_signedBy) { if (_signedBy) {
ZT_FAST_MEMCPY(_signature.data,b.field(p,(unsigned int)_signature.size()),_signature.size()); ZT_FAST_MEMCPY(_signature.data,b.field(p,ZT_C25519_SIGNATURE_LEN),ZT_C25519_SIGNATURE_LEN);
p += (unsigned int)_signature.size(); p += ZT_C25519_SIGNATURE_LEN;
} }
return (p - startAt); return (p - startAt);
@ -348,7 +348,7 @@ public:
if ((a.id != b.id)||(a.value != b.value)||(a.maxDelta != b.maxDelta)) if ((a.id != b.id)||(a.value != b.value)||(a.maxDelta != b.maxDelta))
return false; return false;
} }
return (_signature == c._signature); return (memcmp(_signature.data,c._signature.data,ZT_C25519_SIGNATURE_LEN) == 0);
} }
inline bool operator!=(const CertificateOfMembership &c) const { return (!(*this == c)); } inline bool operator!=(const CertificateOfMembership &c) const { return (!(*this == c)); }

View file

@ -87,7 +87,7 @@ struct _Identity_generate_cond
_Identity_generate_cond(unsigned char *sb,char *gm) : digest(sb),genmem(gm) {} _Identity_generate_cond(unsigned char *sb,char *gm) : digest(sb),genmem(gm) {}
inline bool operator()(const C25519::Pair &kp) const inline bool operator()(const C25519::Pair &kp) const
{ {
_computeMemoryHardHash(kp.pub.data,(unsigned int)kp.pub.size(),digest,genmem); _computeMemoryHardHash(kp.pub.data,ZT_C25519_PUBLIC_KEY_LEN,digest,genmem);
return (digest[0] < ZT_IDENTITY_GEN_HASHCASH_FIRST_BYTE_LESS_THAN); return (digest[0] < ZT_IDENTITY_GEN_HASHCASH_FIRST_BYTE_LESS_THAN);
} }
unsigned char *digest; unsigned char *digest;
@ -120,7 +120,7 @@ bool Identity::locallyValidate() const
unsigned char digest[64]; unsigned char digest[64];
char *genmem = new char[ZT_IDENTITY_GEN_MEMORY]; char *genmem = new char[ZT_IDENTITY_GEN_MEMORY];
_computeMemoryHardHash(_publicKey.data,(unsigned int)_publicKey.size(),digest,genmem); _computeMemoryHardHash(_publicKey.data,ZT_C25519_PUBLIC_KEY_LEN,digest,genmem);
delete [] genmem; delete [] genmem;
unsigned char addrb[5]; unsigned char addrb[5];
@ -187,14 +187,14 @@ bool Identity::fromString(const char *str)
} }
break; break;
case 2: case 2:
if (Utils::unhex(f,_publicKey.data,(unsigned int)_publicKey.size()) != _publicKey.size()) { if (Utils::unhex(f,_publicKey.data,ZT_C25519_PUBLIC_KEY_LEN) != ZT_C25519_PUBLIC_KEY_LEN) {
_address.zero(); _address.zero();
return false; return false;
} }
break; break;
case 3: case 3:
_privateKey = new C25519::Private(); _privateKey = new C25519::Private();
if (Utils::unhex(f,_privateKey->data,(unsigned int)_privateKey->size()) != _privateKey->size()) { if (Utils::unhex(f,_privateKey->data,ZT_C25519_PRIVATE_KEY_LEN) != ZT_C25519_PRIVATE_KEY_LEN) {
_address.zero(); _address.zero();
return false; return false;
} }

View file

@ -215,10 +215,10 @@ public:
{ {
_address.appendTo(b); _address.appendTo(b);
b.append((uint8_t)0); // C25519/Ed25519 identity type b.append((uint8_t)0); // C25519/Ed25519 identity type
b.append(_publicKey.data,(unsigned int)_publicKey.size()); b.append(_publicKey.data,ZT_C25519_PUBLIC_KEY_LEN);
if ((_privateKey)&&(includePrivate)) { if ((_privateKey)&&(includePrivate)) {
b.append((unsigned char)_privateKey->size()); b.append((unsigned char)ZT_C25519_PRIVATE_KEY_LEN);
b.append(_privateKey->data,(unsigned int)_privateKey->size()); b.append(_privateKey->data,ZT_C25519_PRIVATE_KEY_LEN);
} else b.append((unsigned char)0); } else b.append((unsigned char)0);
} }
@ -248,8 +248,8 @@ public:
if (b[p++] != 0) if (b[p++] != 0)
throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_TYPE; throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_TYPE;
ZT_FAST_MEMCPY(_publicKey.data,b.field(p,(unsigned int)_publicKey.size()),(unsigned int)_publicKey.size()); ZT_FAST_MEMCPY(_publicKey.data,b.field(p,ZT_C25519_PUBLIC_KEY_LEN),ZT_C25519_PUBLIC_KEY_LEN);
p += (unsigned int)_publicKey.size(); p += ZT_C25519_PUBLIC_KEY_LEN;
unsigned int privateKeyLength = (unsigned int)b[p++]; unsigned int privateKeyLength = (unsigned int)b[p++];
if (privateKeyLength) { if (privateKeyLength) {
@ -306,8 +306,8 @@ public:
*/ */
inline operator bool() const { return (_address); } inline operator bool() const { return (_address); }
inline bool operator==(const Identity &id) const { return ((_address == id._address)&&(_publicKey == id._publicKey)); } inline bool operator==(const Identity &id) const { return ((_address == id._address)&&(memcmp(_publicKey.data,id._publicKey.data,ZT_C25519_PUBLIC_KEY_LEN) == 0)); }
inline bool operator<(const Identity &id) const { return ((_address < id._address)||((_address == id._address)&&(_publicKey < id._publicKey))); } inline bool operator<(const Identity &id) const { return ((_address < id._address)||((_address == id._address)&&(memcmp(_publicKey.data,id._publicKey.data,ZT_C25519_PUBLIC_KEY_LEN) < 0))); }
inline bool operator!=(const Identity &id) const { return !(*this == id); } inline bool operator!=(const Identity &id) const { return !(*this == id); }
inline bool operator>(const Identity &id) const { return (id < *this); } inline bool operator>(const Identity &id) const { return (id < *this); }
inline bool operator<=(const Identity &id) const { return !(id < *this); } inline bool operator<=(const Identity &id) const { return !(id < *this); }

View file

@ -42,7 +42,6 @@
#include "OutboundMulticast.hpp" #include "OutboundMulticast.hpp"
#include "Utils.hpp" #include "Utils.hpp"
#include "Mutex.hpp" #include "Mutex.hpp"
#include "NonCopyable.hpp"
namespace ZeroTier { namespace ZeroTier {
@ -53,39 +52,8 @@ class Packet;
/** /**
* Database of known multicast peers within a network * Database of known multicast peers within a network
*/ */
class Multicaster : NonCopyable class Multicaster
{ {
private:
struct Key
{
Key() : nwid(0),mg() {}
Key(uint64_t n,const MulticastGroup &g) : nwid(n),mg(g) {}
uint64_t nwid;
MulticastGroup mg;
inline bool operator==(const Key &k) const { return ((nwid == k.nwid)&&(mg == k.mg)); }
inline unsigned long hashCode() const { return (mg.hashCode() ^ (unsigned long)(nwid ^ (nwid >> 32))); }
};
struct MulticastGroupMember
{
MulticastGroupMember() {}
MulticastGroupMember(const Address &a,uint64_t ts) : address(a),timestamp(ts) {}
Address address;
uint64_t timestamp; // time of last notification
};
struct MulticastGroupStatus
{
MulticastGroupStatus() : lastExplicitGather(0) {}
uint64_t lastExplicitGather;
std::list<OutboundMulticast> txQueue; // pending outbound multicasts
std::vector<MulticastGroupMember> members; // members of this group
};
public: public:
Multicaster(const RuntimeEnvironment *renv); Multicaster(const RuntimeEnvironment *renv);
~Multicaster(); ~Multicaster();
@ -220,9 +188,39 @@ public:
} }
private: private:
struct Key
{
Key() : nwid(0),mg() {}
Key(uint64_t n,const MulticastGroup &g) : nwid(n),mg(g) {}
uint64_t nwid;
MulticastGroup mg;
inline bool operator==(const Key &k) const { return ((nwid == k.nwid)&&(mg == k.mg)); }
inline unsigned long hashCode() const { return (mg.hashCode() ^ (unsigned long)(nwid ^ (nwid >> 32))); }
};
struct MulticastGroupMember
{
MulticastGroupMember() {}
MulticastGroupMember(const Address &a,uint64_t ts) : address(a),timestamp(ts) {}
Address address;
uint64_t timestamp; // time of last notification
};
struct MulticastGroupStatus
{
MulticastGroupStatus() : lastExplicitGather(0) {}
uint64_t lastExplicitGather;
std::list<OutboundMulticast> txQueue; // pending outbound multicasts
std::vector<MulticastGroupMember> members; // members of this group
};
void _add(void *tPtr,int64_t now,uint64_t nwid,const MulticastGroup &mg,MulticastGroupStatus &gs,const Address &member); void _add(void *tPtr,int64_t now,uint64_t nwid,const MulticastGroup &mg,MulticastGroupStatus &gs,const Address &member);
const RuntimeEnvironment *RR; const RuntimeEnvironment *const RR;
Hashtable<Multicaster::Key,MulticastGroupStatus> _groups; Hashtable<Multicaster::Key,MulticastGroupStatus> _groups;
Mutex _groups_m; Mutex _groups_m;

View file

@ -240,11 +240,9 @@ public:
return (p - startAt); return (p - startAt);
} }
inline bool operator==(const World &w) const { return ((_id == w._id)&&(_ts == w._ts)&&(_updatesMustBeSignedBy == w._updatesMustBeSignedBy)&&(_signature == w._signature)&&(_roots == w._roots)&&(_type == w._type)); } inline bool operator==(const World &w) const { return ((_id == w._id)&&(_ts == w._ts)&&(memcmp(_updatesMustBeSignedBy.data,w._updatesMustBeSignedBy.data,ZT_C25519_PUBLIC_KEY_LEN) == 0)&&(memcmp(_signature.data,w._signature.data,ZT_C25519_SIGNATURE_LEN) == 0)&&(_roots == w._roots)&&(_type == w._type)); }
inline bool operator!=(const World &w) const { return (!(*this == w)); } inline bool operator!=(const World &w) const { return (!(*this == w)); }
inline bool operator<(const World &w) const { return (((int)_type < (int)w._type) ? true : ((_type == w._type) ? (_id < w._id) : false)); }
/** /**
* Create a World object signed with a key pair * Create a World object signed with a key pair
* *

12
one.cpp
View file

@ -795,7 +795,7 @@ static int idtool(int argc,char **argv)
} }
C25519::Signature signature = id.sign(inf.data(),(unsigned int)inf.length()); C25519::Signature signature = id.sign(inf.data(),(unsigned int)inf.length());
char hexbuf[1024]; char hexbuf[1024];
printf("%s",Utils::hex(signature.data,(unsigned int)signature.size(),hexbuf)); printf("%s",Utils::hex(signature.data,ZT_C25519_SIGNATURE_LEN,hexbuf));
} else if (!strcmp(argv[1],"verify")) { } else if (!strcmp(argv[1],"verify")) {
if (argc < 4) { if (argc < 4) {
idtoolPrintHelp(stdout,argv[0]); idtoolPrintHelp(stdout,argv[0]);
@ -838,8 +838,8 @@ static int idtool(int argc,char **argv)
nlohmann::json mj; nlohmann::json mj;
mj["objtype"] = "world"; mj["objtype"] = "world";
mj["worldType"] = "moon"; mj["worldType"] = "moon";
mj["updatesMustBeSignedBy"] = mj["signingKey"] = Utils::hex(kp.pub.data,(unsigned int)kp.pub.size(),idtmp); mj["updatesMustBeSignedBy"] = mj["signingKey"] = Utils::hex(kp.pub.data,ZT_C25519_PUBLIC_KEY_LEN,idtmp);
mj["signingKey_SECRET"] = Utils::hex(kp.priv.data,(unsigned int)kp.priv.size(),idtmp); mj["signingKey_SECRET"] = Utils::hex(kp.priv.data,ZT_C25519_PRIVATE_KEY_LEN,idtmp);
mj["id"] = id.address().toString(idtmp); mj["id"] = id.address().toString(idtmp);
nlohmann::json seedj; nlohmann::json seedj;
seedj["identity"] = id.toString(false,idtmp); seedj["identity"] = id.toString(false,idtmp);
@ -878,9 +878,9 @@ static int idtool(int argc,char **argv)
C25519::Pair signingKey; C25519::Pair signingKey;
C25519::Public updatesMustBeSignedBy; C25519::Public updatesMustBeSignedBy;
Utils::unhex(OSUtils::jsonString(mj["signingKey"],"").c_str(),signingKey.pub.data,(unsigned int)signingKey.pub.size()); Utils::unhex(OSUtils::jsonString(mj["signingKey"],"").c_str(),signingKey.pub.data,ZT_C25519_PUBLIC_KEY_LEN);
Utils::unhex(OSUtils::jsonString(mj["signingKey_SECRET"],"").c_str(),signingKey.priv.data,(unsigned int)signingKey.priv.size()); Utils::unhex(OSUtils::jsonString(mj["signingKey_SECRET"],"").c_str(),signingKey.priv.data,ZT_C25519_PRIVATE_KEY_LEN);
Utils::unhex(OSUtils::jsonString(mj["updatesMustBeSignedBy"],"").c_str(),updatesMustBeSignedBy.data,(unsigned int)updatesMustBeSignedBy.size()); Utils::unhex(OSUtils::jsonString(mj["updatesMustBeSignedBy"],"").c_str(),updatesMustBeSignedBy.data,ZT_C25519_PUBLIC_KEY_LEN);
std::vector<World::Root> roots; std::vector<World::Root> roots;
nlohmann::json &rootsj = mj["roots"]; nlohmann::json &rootsj = mj["roots"];

View file

@ -688,25 +688,26 @@ public:
* until one works. * until one works.
* *
* @param sock Socket * @param sock Socket
* @param bufferSize Desired buffer sizes * @param receiveBufferSize Desired size of receive buffer
* @param sendBufferSize Desired size of send buffer
*/ */
inline void setBufferSizes(const PhySocket *sock,int bufferSize) inline void setBufferSizes(const PhySocket *sock,int receiveBufferSize,int sendBufferSize)
{ {
PhySocketImpl &sws = *(reinterpret_cast<PhySocketImpl *>(sock)); PhySocketImpl &sws = *(reinterpret_cast<PhySocketImpl *>(sock));
if (bufferSize > 0) { if (receiveBufferSize > 0) {
int bs = bufferSize; while (receiveBufferSize > 0) {
while (bs >= 65536) { int tmpbs = receiveBufferSize;
int tmpbs = bs;
if (::setsockopt(sws.sock,SOL_SOCKET,SO_RCVBUF,(const char *)&tmpbs,sizeof(tmpbs)) == 0) if (::setsockopt(sws.sock,SOL_SOCKET,SO_RCVBUF,(const char *)&tmpbs,sizeof(tmpbs)) == 0)
break; break;
bs -= 16384; receiveBufferSize -= 16384;
} }
bs = bufferSize; }
while (bs >= 65536) { if (sendBufferSize > 0) {
int tmpbs = bs; while (sendBufferSize > 0) {
int tmpbs = sendBufferSize;
if (::setsockopt(sws.sock,SOL_SOCKET,SO_SNDBUF,(const char *)&tmpbs,sizeof(tmpbs)) == 0) if (::setsockopt(sws.sock,SOL_SOCKET,SO_SNDBUF,(const char *)&tmpbs,sizeof(tmpbs)) == 0)
break; break;
bs -= 16384; sendBufferSize -= 16384;
} }
} }
} }

View file

@ -321,10 +321,10 @@ static int testCrypto()
std::cout << "[crypto] Testing C25519 and Ed25519 against test vectors... "; std::cout.flush(); std::cout << "[crypto] Testing C25519 and Ed25519 against test vectors... "; std::cout.flush();
for(int k=0;k<ZT_NUM_C25519_TEST_VECTORS;++k) { for(int k=0;k<ZT_NUM_C25519_TEST_VECTORS;++k) {
C25519::Pair p1,p2; C25519::Pair p1,p2;
memcpy(p1.pub.data,C25519_TEST_VECTORS[k].pub1,p1.pub.size()); memcpy(p1.pub.data,C25519_TEST_VECTORS[k].pub1,ZT_C25519_PUBLIC_KEY_LEN);
memcpy(p1.priv.data,C25519_TEST_VECTORS[k].priv1,p1.priv.size()); memcpy(p1.priv.data,C25519_TEST_VECTORS[k].priv1,ZT_C25519_PRIVATE_KEY_LEN);
memcpy(p2.pub.data,C25519_TEST_VECTORS[k].pub2,p2.pub.size()); memcpy(p2.pub.data,C25519_TEST_VECTORS[k].pub2,ZT_C25519_PUBLIC_KEY_LEN);
memcpy(p2.priv.data,C25519_TEST_VECTORS[k].priv2,p2.priv.size()); memcpy(p2.priv.data,C25519_TEST_VECTORS[k].priv2,ZT_C25519_PRIVATE_KEY_LEN);
C25519::agree(p1,p2.pub,buf1,64); C25519::agree(p1,p2.pub,buf1,64);
C25519::agree(p2,p1.pub,buf2,64); C25519::agree(p2,p1.pub,buf2,64);
if (memcmp(buf1,buf2,64)) { if (memcmp(buf1,buf2,64)) {
@ -410,7 +410,7 @@ static int testCrypto()
} }
for(unsigned int k=0;k<64;++k) { for(unsigned int k=0;k<64;++k) {
C25519::Signature sig2(sig); C25519::Signature sig2(sig);
sig2.data[rand() % sig2.size()] ^= (unsigned char)(1 << (rand() & 7)); sig2.data[rand() % ZT_C25519_SIGNATURE_LEN] ^= (unsigned char)(1 << (rand() & 7));
if (C25519::verify(p1.pub,buf1,sizeof(buf1),sig2)) { if (C25519::verify(p1.pub,buf1,sizeof(buf1),sig2)) {
std::cout << "FAIL (5)" << std::endl; std::cout << "FAIL (5)" << std::endl;
return -1; return -1;

View file

@ -285,8 +285,8 @@ static void _moonToJson(nlohmann::json &mj,const World &world)
OSUtils::ztsnprintf(tmp,sizeof(tmp),"%.16llx",world.id()); OSUtils::ztsnprintf(tmp,sizeof(tmp),"%.16llx",world.id());
mj["id"] = tmp; mj["id"] = tmp;
mj["timestamp"] = world.timestamp(); mj["timestamp"] = world.timestamp();
mj["signature"] = Utils::hex(world.signature().data,(unsigned int)world.signature().size(),tmp); mj["signature"] = Utils::hex(world.signature().data,ZT_C25519_SIGNATURE_LEN,tmp);
mj["updatesMustBeSignedBy"] = Utils::hex(world.updatesMustBeSignedBy().data,(unsigned int)world.updatesMustBeSignedBy().size(),tmp); mj["updatesMustBeSignedBy"] = Utils::hex(world.updatesMustBeSignedBy().data,ZT_C25519_PUBLIC_KEY_LEN,tmp);
nlohmann::json ra = nlohmann::json::array(); nlohmann::json ra = nlohmann::json::array();
for(std::vector<World::Root>::const_iterator r(world.roots().begin());r!=world.roots().end();++r) { for(std::vector<World::Root>::const_iterator r(world.roots().begin());r!=world.roots().end();++r) {
nlohmann::json rj; nlohmann::json rj;

View file

@ -126,11 +126,13 @@ void SoftwareUpdater::setUpdateDistribution(bool distribute)
const std::string binPath(udd + ZT_PATH_SEPARATOR_S + u->substr(0,u->length() - 5)); const std::string binPath(udd + ZT_PATH_SEPARATOR_S + u->substr(0,u->length() - 5));
const std::string metaHash(OSUtils::jsonBinFromHex(d.meta[ZT_SOFTWARE_UPDATE_JSON_UPDATE_HASH])); const std::string metaHash(OSUtils::jsonBinFromHex(d.meta[ZT_SOFTWARE_UPDATE_JSON_UPDATE_HASH]));
if ((metaHash.length() == ZT_SHA512_DIGEST_LEN)&&(OSUtils::readFile(binPath.c_str(),d.bin))) { if ((metaHash.length() == ZT_SHA512_DIGEST_LEN)&&(OSUtils::readFile(binPath.c_str(),d.bin))) {
uint8_t sha512[ZT_SHA512_DIGEST_LEN]; std::array<uint8_t,ZT_SHA512_DIGEST_LEN> sha512;
SHA512::hash(sha512,d.bin.data(),(unsigned int)d.bin.length()); SHA512::hash(sha512.data(),d.bin.data(),(unsigned int)d.bin.length());
if (!memcmp(sha512,metaHash.data(),ZT_SHA512_DIGEST_LEN)) { // double check that hash in JSON is correct if (!memcmp(sha512.data(),metaHash.data(),ZT_SHA512_DIGEST_LEN)) { // double check that hash in JSON is correct
d.meta[ZT_SOFTWARE_UPDATE_JSON_UPDATE_SIZE] = d.bin.length(); // override with correct value -- setting this in meta json is optional d.meta[ZT_SOFTWARE_UPDATE_JSON_UPDATE_SIZE] = d.bin.length(); // override with correct value -- setting this in meta json is optional
_dist[Array<uint8_t,16>(sha512)] = d; std::array<uint8_t,16> shakey;
memcpy(shakey.data(),sha512.data(),16);
_dist[shakey] = d;
if (_distLog) { if (_distLog) {
fprintf(_distLog,".......... INIT: DISTRIBUTING %s (%u bytes)" ZT_EOL_S,binPath.c_str(),(unsigned int)d.bin.length()); fprintf(_distLog,".......... INIT: DISTRIBUTING %s (%u bytes)" ZT_EOL_S,binPath.c_str(),(unsigned int)d.bin.length());
fflush(_distLog); fflush(_distLog);
@ -179,7 +181,7 @@ void SoftwareUpdater::handleSoftwareUpdateUserMessage(uint64_t origin,const void
unsigned int bestVMin = rvMin; unsigned int bestVMin = rvMin;
unsigned int bestVRev = rvRev; unsigned int bestVRev = rvRev;
unsigned int bestVBld = rvBld; unsigned int bestVBld = rvBld;
for(std::map< Array<uint8_t,16>,_D >::const_iterator d(_dist.begin());d!=_dist.end();++d) { for(std::map< std::array<uint8_t,16>,_D >::const_iterator d(_dist.begin());d!=_dist.end();++d) {
// The arch field in update description .json files can be an array for e.g. multi-arch update files // The arch field in update description .json files can be an array for e.g. multi-arch update files
const nlohmann::json &dvArch2 = d->second.meta[ZT_SOFTWARE_UPDATE_JSON_ARCHITECTURE]; const nlohmann::json &dvArch2 = d->second.meta[ZT_SOFTWARE_UPDATE_JSON_ARCHITECTURE];
std::vector<unsigned int> dvArch; std::vector<unsigned int> dvArch;
@ -233,14 +235,14 @@ void SoftwareUpdater::handleSoftwareUpdateUserMessage(uint64_t origin,const void
_latestValid = false; _latestValid = false;
OSUtils::rm((_homePath + ZT_PATH_SEPARATOR_S ZT_SOFTWARE_UPDATE_BIN_FILENAME).c_str()); OSUtils::rm((_homePath + ZT_PATH_SEPARATOR_S ZT_SOFTWARE_UPDATE_BIN_FILENAME).c_str());
_download = std::string(); _download = std::string();
memcpy(_downloadHashPrefix.data,hash.data(),16); memcpy(_downloadHashPrefix.data(),hash.data(),16);
_downloadLength = len; _downloadLength = len;
} }
if ((_downloadLength > 0)&&(_download.length() < _downloadLength)) { if ((_downloadLength > 0)&&(_download.length() < _downloadLength)) {
Buffer<128> gd; Buffer<128> gd;
gd.append((uint8_t)VERB_GET_DATA); gd.append((uint8_t)VERB_GET_DATA);
gd.append(_downloadHashPrefix.data,16); gd.append(_downloadHashPrefix.data(),16);
gd.append((uint32_t)_download.length()); gd.append((uint32_t)_download.length());
_node.sendUserMessage((void *)0,ZT_SOFTWARE_UPDATE_SERVICE,ZT_SOFTWARE_UPDATE_USER_MESSAGE_TYPE,gd.data(),gd.size()); _node.sendUserMessage((void *)0,ZT_SOFTWARE_UPDATE_SERVICE,ZT_SOFTWARE_UPDATE_USER_MESSAGE_TYPE,gd.data(),gd.size());
} }
@ -257,7 +259,9 @@ void SoftwareUpdater::handleSoftwareUpdateUserMessage(uint64_t origin,const void
idx |= (unsigned long)*(reinterpret_cast<const uint8_t *>(data) + 18) << 16; idx |= (unsigned long)*(reinterpret_cast<const uint8_t *>(data) + 18) << 16;
idx |= (unsigned long)*(reinterpret_cast<const uint8_t *>(data) + 19) << 8; idx |= (unsigned long)*(reinterpret_cast<const uint8_t *>(data) + 19) << 8;
idx |= (unsigned long)*(reinterpret_cast<const uint8_t *>(data) + 20); idx |= (unsigned long)*(reinterpret_cast<const uint8_t *>(data) + 20);
std::map< Array<uint8_t,16>,_D >::iterator d(_dist.find(Array<uint8_t,16>(reinterpret_cast<const uint8_t *>(data) + 1))); std::array<uint8_t,16> shakey;
memcpy(shakey.data(),reinterpret_cast<const uint8_t *>(data) + 1,16);
std::map< std::array<uint8_t,16>,_D >::iterator d(_dist.find(shakey));
if ((d != _dist.end())&&(idx < (unsigned long)d->second.bin.length())) { if ((d != _dist.end())&&(idx < (unsigned long)d->second.bin.length())) {
Buffer<ZT_SOFTWARE_UPDATE_CHUNK_SIZE + 128> buf; Buffer<ZT_SOFTWARE_UPDATE_CHUNK_SIZE + 128> buf;
buf.append((uint8_t)VERB_DATA); buf.append((uint8_t)VERB_DATA);
@ -270,7 +274,7 @@ void SoftwareUpdater::handleSoftwareUpdateUserMessage(uint64_t origin,const void
break; break;
case VERB_DATA: case VERB_DATA:
if ((len >= 21)&&(_downloadLength > 0)&&(!memcmp(_downloadHashPrefix.data,reinterpret_cast<const uint8_t *>(data) + 1,16))) { if ((len >= 21)&&(_downloadLength > 0)&&(!memcmp(_downloadHashPrefix.data(),reinterpret_cast<const uint8_t *>(data) + 1,16))) {
unsigned long idx = (unsigned long)*(reinterpret_cast<const uint8_t *>(data) + 17) << 24; unsigned long idx = (unsigned long)*(reinterpret_cast<const uint8_t *>(data) + 17) << 24;
idx |= (unsigned long)*(reinterpret_cast<const uint8_t *>(data) + 18) << 16; idx |= (unsigned long)*(reinterpret_cast<const uint8_t *>(data) + 18) << 16;
idx |= (unsigned long)*(reinterpret_cast<const uint8_t *>(data) + 19) << 8; idx |= (unsigned long)*(reinterpret_cast<const uint8_t *>(data) + 19) << 8;
@ -280,7 +284,7 @@ void SoftwareUpdater::handleSoftwareUpdateUserMessage(uint64_t origin,const void
if (_download.length() < _downloadLength) { if (_download.length() < _downloadLength) {
Buffer<128> gd; Buffer<128> gd;
gd.append((uint8_t)VERB_GET_DATA); gd.append((uint8_t)VERB_GET_DATA);
gd.append(_downloadHashPrefix.data,16); gd.append(_downloadHashPrefix.data(),16);
gd.append((uint32_t)_download.length()); gd.append((uint32_t)_download.length());
_node.sendUserMessage((void *)0,ZT_SOFTWARE_UPDATE_SERVICE,ZT_SOFTWARE_UPDATE_USER_MESSAGE_TYPE,gd.data(),gd.size()); _node.sendUserMessage((void *)0,ZT_SOFTWARE_UPDATE_SERVICE,ZT_SOFTWARE_UPDATE_USER_MESSAGE_TYPE,gd.data(),gd.size());
} }
@ -371,7 +375,7 @@ bool SoftwareUpdater::check(const int64_t now)
} else { } else {
Buffer<128> gd; Buffer<128> gd;
gd.append((uint8_t)VERB_GET_DATA); gd.append((uint8_t)VERB_GET_DATA);
gd.append(_downloadHashPrefix.data,16); gd.append(_downloadHashPrefix.data(),16);
gd.append((uint32_t)_download.length()); gd.append((uint32_t)_download.length());
_node.sendUserMessage((void *)0,ZT_SOFTWARE_UPDATE_SERVICE,ZT_SOFTWARE_UPDATE_USER_MESSAGE_TYPE,gd.data(),gd.size()); _node.sendUserMessage((void *)0,ZT_SOFTWARE_UPDATE_SERVICE,ZT_SOFTWARE_UPDATE_USER_MESSAGE_TYPE,gd.data(),gd.size());
} }

View file

@ -33,11 +33,11 @@
#include <vector> #include <vector>
#include <map> #include <map>
#include <string> #include <string>
#include <array>
#include "../include/ZeroTierOne.h" #include "../include/ZeroTierOne.h"
#include "../node/Identity.hpp" #include "../node/Identity.hpp"
#include "../node/Array.hpp"
#include "../node/Packet.hpp" #include "../node/Packet.hpp"
#include "../ext/json/json.hpp" #include "../ext/json/json.hpp"
@ -202,13 +202,13 @@ private:
nlohmann::json meta; nlohmann::json meta;
std::string bin; std::string bin;
}; };
std::map< Array<uint8_t,16>,_D > _dist; // key is first 16 bytes of hash std::map< std::array<uint8_t,16>,_D > _dist; // key is first 16 bytes of hash
nlohmann::json _latestMeta; nlohmann::json _latestMeta;
bool _latestValid; bool _latestValid;
std::string _download; std::string _download;
Array<uint8_t,16> _downloadHashPrefix; std::array<uint8_t,16> _downloadHashPrefix;
unsigned long _downloadLength; unsigned long _downloadLength;
}; };