mirror of
https://github.com/ZeroTier/ZeroTierOne
synced 2025-08-20 05:13:58 -07:00
New crypto integrated -- going to be testing new identity address generation algo a bit more before finalizing.
This commit is contained in:
parent
ceb024ab03
commit
e376c6f6a9
12 changed files with 84 additions and 115 deletions
|
@ -52,6 +52,7 @@ static inline std::map< Identity,std::vector<InetAddress> > _mkSupernodeMap()
|
|||
// Nothing special about a supernode... except that they are
|
||||
// designated as such.
|
||||
|
||||
#if 0
|
||||
// cthulhu.zerotier.com - New York, New York, USA
|
||||
addrs.clear();
|
||||
if (!id.fromString("271ee006a0:1:AgGXs3I+9CWrEmGMxc50x3E+trwtaa2ZMXDU6ezz92fFJXzlhRKGUY/uAToHDdH9XiLxtcA+kUQAZdC4Dy2xtqXxjw==:QgH5Nlx4oWEGVrwhNocqem+3VNd4qzt7RLrmuvqZvKPRS9R70LJYJQLlKZj0ri55Pzg+Mlwy4a4nAgfnRAWA+TW6R0EjSmq72MG585XGNfWBVk3LxMvxlNWErnVNFr2BQS9yzVp4pRjPLdCW4RB3dwEHBUgJ78rwMxQ6IghVCl8CjkDapg=="))
|
||||
|
@ -72,6 +73,7 @@ static inline std::map< Identity,std::vector<InetAddress> > _mkSupernodeMap()
|
|||
throw std::runtime_error("invalid identity in Defaults");
|
||||
addrs.push_back(InetAddress("198.211.127.172",ZT_DEFAULT_UDP_PORT));
|
||||
sn[id] = addrs;
|
||||
#endif
|
||||
|
||||
return sn;
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#include "Identity.hpp"
|
||||
#include "SHA512.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
|
@ -76,7 +77,7 @@ std::string Identity::toString(bool includePrivate) const
|
|||
r.append(Utils::hex(_signature.data,_signature.size()));
|
||||
if ((_privateKey)&&(includePrivate)) {
|
||||
r.push_back(':');
|
||||
r.append(Utils::hex(_privateKey.data,_privateKey.size()));
|
||||
r.append(Utils::hex(_privateKey->data,_privateKey->size()));
|
||||
}
|
||||
|
||||
return r;
|
||||
|
@ -129,8 +130,8 @@ bool Identity::fromString(const char *str)
|
|||
|
||||
// These are fixed parameters and can't be changed without a new
|
||||
// identity type.
|
||||
#define ZT_IDENTITY_DERIVEADDRESS_DIGESTS 540672
|
||||
#define ZT_IDENTITY_DERIVEADDRESS_ROUNDS 4
|
||||
#define ZT_IDENTITY_DERIVEADDRESS_DIGESTS 2048
|
||||
#define ZT_IDENTITY_DERIVEADDRESS_ROUNDS 8
|
||||
|
||||
Address Identity::deriveAddress(const void *keyBytes,unsigned int keyLen)
|
||||
{
|
||||
|
|
|
@ -39,6 +39,8 @@
|
|||
#include "C25519.hpp"
|
||||
#include "Buffer.hpp"
|
||||
|
||||
#define ZT_IDENTITY_MAX_BINARY_SERIALIZED_LENGTH (ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + ZT_C25519_SIGNATURE_LEN + 1 + ZT_C25519_PRIVATE_KEY_LEN)
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
/**
|
||||
|
@ -148,6 +150,36 @@ public:
|
|||
*/
|
||||
inline bool hasPrivate() const throw() { return (_privateKey != (C25519::Private *)0); }
|
||||
|
||||
/**
|
||||
* Sign a message with this identity (private key required)
|
||||
*
|
||||
* @param data Data to sign
|
||||
* @param len Length of data
|
||||
*/
|
||||
inline C25519::Signature sign(const void *data,unsigned int len) const
|
||||
throw(std::runtime_error)
|
||||
{
|
||||
if (_privateKey)
|
||||
return C25519::sign(*_privateKey,_publicKey,data,len);
|
||||
throw std::runtime_error("sign() requires a private key");
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify a message signature against this identity
|
||||
*
|
||||
* @param data Data to check
|
||||
* @param len Length of data
|
||||
* @param signature Signature bytes
|
||||
* @param siglen Length of signature in bytes
|
||||
* @return True if signature validates and data integrity checks
|
||||
*/
|
||||
inline bool verify(const void *data,unsigned int len,const void *signature,unsigned int siglen) const
|
||||
{
|
||||
if (siglen != ZT_C25519_SIGNATURE_LEN)
|
||||
return false;
|
||||
return C25519::verify(_publicKey,data,len,signature);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut method to perform key agreement with another identity
|
||||
*
|
||||
|
@ -193,8 +225,8 @@ public:
|
|||
b.append(_publicKey.data,_publicKey.size());
|
||||
b.append(_signature.data,_signature.size());
|
||||
if ((_privateKey)&&(includePrivate)) {
|
||||
b.append((unsigned char)_privateKey.size());
|
||||
b.append(_privateKey.data,_privateKey.size());
|
||||
b.append((unsigned char)_privateKey->size());
|
||||
b.append(_privateKey->data,_privateKey->size());
|
||||
} else b.append((unsigned char)0);
|
||||
}
|
||||
|
||||
|
@ -225,15 +257,15 @@ public:
|
|||
if (b[p++] != IDENTITY_TYPE_C25519)
|
||||
throw std::invalid_argument("Identity: deserialize(): unsupported identity type");
|
||||
|
||||
memcpy(_publicKey.data,field(p,_publicKey.size()),_publicKey.size());
|
||||
memcpy(_publicKey.data,b.field(p,_publicKey.size()),_publicKey.size());
|
||||
p += _publicKey.size();
|
||||
memcpy(_signature.data,field(p,_signature.size()),_signature.size());
|
||||
memcpy(_signature.data,b.field(p,_signature.size()),_signature.size());
|
||||
p += _signature.size();
|
||||
|
||||
unsigned int privateKeyLength = b[p++];
|
||||
if ((privateKeyLength)&&(privateKeyLength == ZT_C25519_PRIVATE_KEY_LEN)) {
|
||||
_privateKey = new C25519::Private();
|
||||
memcpy(_privateKey->data,field(p,ZT_C25519_PRIVATE_KEY_LEN),ZT_C25519_PRIVATE_KEY_LEN);
|
||||
memcpy(_privateKey->data,b.field(p,ZT_C25519_PRIVATE_KEY_LEN),ZT_C25519_PRIVATE_KEY_LEN);
|
||||
p += ZT_C25519_PRIVATE_KEY_LEN;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,10 +31,9 @@
|
|||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
@ -51,6 +50,7 @@
|
|||
#include "BloomFilter.hpp"
|
||||
#include "Identity.hpp"
|
||||
#include "CMWC4096.hpp"
|
||||
#include "C25519.hpp"
|
||||
|
||||
// Maximum sample size to pick during choice of multicast propagation peers
|
||||
#define ZT_MULTICAST_PICK_MAX_SAMPLE_SIZE (ZT_MULTICAST_PROPAGATION_BREADTH * 8)
|
||||
|
@ -92,13 +92,20 @@ public:
|
|||
* @param etherType 16-bit ethernet type
|
||||
* @param data Ethernet frame data
|
||||
* @param len Length of frame
|
||||
* @return ECDSA signature
|
||||
* @return Signature of packet data and attributes
|
||||
* @throws std::runtime_error Cannot sign, e.g. identity has no private key
|
||||
*/
|
||||
static inline std::string signMulticastPacket(const Identity &id,uint64_t nwid,const MAC &from,const MulticastGroup &to,unsigned int etherType,const void *data,unsigned int len)
|
||||
static inline C25519::Signature signMulticastPacket(const Identity &id,uint64_t nwid,const MAC &from,const MulticastGroup &to,unsigned int etherType,const void *data,unsigned int len)
|
||||
throw(std::runtime_error)
|
||||
{
|
||||
unsigned char digest[32];
|
||||
_hashMulticastPacketForSig(nwid,from,to,etherType,data,len,digest);
|
||||
return id.sign(digest);
|
||||
char tmp[65536];
|
||||
*((uint64_t *)tmp) = Utils::hton(nwid);
|
||||
memcpy(tmp + 8,from.data,6);
|
||||
memcpy(tmp + 14,to.mac().data,6);
|
||||
*((uint32_t *)(tmp + 20)) = Utils::hton(to.adi());
|
||||
*((uint16_t *)(tmp + 24)) = Utils::hton((uint16_t)etherType);
|
||||
memcpy(tmp + 26,data,std::min((unsigned int)(sizeof(tmp) - 26),len)); // min() is a sanity check here, no packet is that big
|
||||
return id.sign(tmp,len + 26);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -111,15 +118,20 @@ public:
|
|||
* @param etherType 16-bit ethernet type
|
||||
* @param data Ethernet frame data
|
||||
* @param len Length of frame
|
||||
* @param signature ECDSA signature
|
||||
* @param signature Signature
|
||||
* @param siglen Length of signature in bytes
|
||||
* @return ECDSA signature
|
||||
* @return True if signature verification was successful
|
||||
*/
|
||||
static bool verifyMulticastPacket(const Identity &id,uint64_t nwid,const MAC &from,const MulticastGroup &to,unsigned int etherType,const void *data,unsigned int len,const void *signature,unsigned int siglen)
|
||||
{
|
||||
unsigned char digest[32];
|
||||
_hashMulticastPacketForSig(nwid,from,to,etherType,data,len,digest);
|
||||
return id.verifySignature(digest,signature,siglen);
|
||||
char tmp[65536];
|
||||
*((uint64_t *)tmp) = Utils::hton(nwid);
|
||||
memcpy(tmp + 8,from.data,6);
|
||||
memcpy(tmp + 14,to.mac().data,6);
|
||||
*((uint32_t *)(tmp + 20)) = Utils::hton(to.adi());
|
||||
*((uint16_t *)(tmp + 24)) = Utils::hton((uint16_t)etherType);
|
||||
memcpy(tmp + 26,data,std::min((unsigned int)(sizeof(tmp) - 26),len)); // min() is a sanity check here, no packet is that big
|
||||
return id.verify(tmp,len + 26,signature,siglen);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -349,29 +361,6 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
static inline void _hashMulticastPacketForSig(uint64_t nwid,const MAC &from,const MulticastGroup &to,unsigned int etherType,const void *data,unsigned int len,unsigned char *digest)
|
||||
throw()
|
||||
{
|
||||
unsigned char zero = 0;
|
||||
SHA256_CTX sha;
|
||||
SHA256_Init(&sha);
|
||||
uint64_t _nwid = Utils::hton(nwid);
|
||||
SHA256_Update(&sha,(unsigned char *)&_nwid,sizeof(_nwid));
|
||||
SHA256_Update(&sha,&zero,1);
|
||||
SHA256_Update(&sha,(unsigned char *)from.data,6);
|
||||
SHA256_Update(&sha,&zero,1);
|
||||
SHA256_Update(&sha,(unsigned char *)to.mac().data,6);
|
||||
SHA256_Update(&sha,&zero,1);
|
||||
uint32_t _adi = Utils::hton(to.adi());
|
||||
SHA256_Update(&sha,(unsigned char *)&_adi,sizeof(_adi));
|
||||
SHA256_Update(&sha,&zero,1);
|
||||
uint16_t _etype = Utils::hton((uint16_t)etherType);
|
||||
SHA256_Update(&sha,(unsigned char *)&_etype,sizeof(_etype));
|
||||
SHA256_Update(&sha,&zero,1);
|
||||
SHA256_Update(&sha,(unsigned char *)data,len);
|
||||
SHA256_Final(digest,&sha);
|
||||
}
|
||||
|
||||
// ring buffer: [0] - CRC, [1] - timestamp
|
||||
uint64_t _multicastHistory[ZT_MULTICAST_DEDUP_HISTORY_LENGTH][2];
|
||||
volatile unsigned int _multicastHistoryPtr;
|
||||
|
|
|
@ -30,8 +30,6 @@
|
|||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
#include "NodeConfig.hpp"
|
||||
#include "Network.hpp"
|
||||
|
|
|
@ -66,6 +66,7 @@
|
|||
#include "Mutex.hpp"
|
||||
#include "Multicaster.hpp"
|
||||
#include "CMWC4096.hpp"
|
||||
#include "SHA512.hpp"
|
||||
#include "Service.hpp"
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
|
@ -128,10 +129,11 @@ Node::LocalClient::LocalClient(const char *authToken,void (*resultHandler)(void
|
|||
|
||||
// If socket fails to bind, there's a big problem like missing IPv4 stack
|
||||
if (sock) {
|
||||
SHA256_CTX sha;
|
||||
SHA256_Init(&sha);
|
||||
SHA256_Update(&sha,authToken,strlen(authToken));
|
||||
SHA256_Final(impl->key,&sha);
|
||||
{
|
||||
unsigned int csk[64];
|
||||
SHA512::hash(csk,authToken,strlen(authToken));
|
||||
memcpy(impl->key,csk,32);
|
||||
}
|
||||
|
||||
impl->sock = sock;
|
||||
impl->resultHandler = resultHandler;
|
||||
|
|
|
@ -69,7 +69,7 @@ NodeConfig::NodeConfig(const RuntimeEnvironment *renv,const char *authToken)
|
|||
{
|
||||
{
|
||||
unsigned int csk[64];
|
||||
SHA512::hash(authToken,strlen(authToken));
|
||||
SHA512::hash(csk,authToken,strlen(authToken));
|
||||
memcpy(_controlSocketKey,csk,32);
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
#include "Demarc.hpp"
|
||||
#include "RuntimeEnvironment.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
#include "EllipticCurveKey.hpp"
|
||||
#include "Packet.hpp"
|
||||
#include "SharedPtr.hpp"
|
||||
#include "AtomicCounter.hpp"
|
||||
|
@ -54,7 +53,7 @@
|
|||
*/
|
||||
#define ZT_PEER_MAX_SERIALIZED_LENGTH ( \
|
||||
64 + \
|
||||
IDENTITY_MAX_BINARY_SERIALIZED_LENGTH + \
|
||||
ZT_IDENTITY_MAX_BINARY_SERIALIZED_LENGTH + \
|
||||
( ( \
|
||||
(sizeof(uint64_t) * 4) + \
|
||||
sizeof(uint16_t) + \
|
||||
|
|
|
@ -135,11 +135,7 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c
|
|||
if (!np)
|
||||
return;
|
||||
|
||||
std::string signature(Multicaster::signMulticastPacket(_r->identity,network->id(),from,mg,etherType,data.data(),data.size()));
|
||||
if (!signature.length()) {
|
||||
TRACE("failure signing multicast message!");
|
||||
return;
|
||||
}
|
||||
C25519::Signature signature(Multicaster::signMulticastPacket(_r->identity,network->id(),from,mg,etherType,data.data(),data.size()));
|
||||
|
||||
Packet outpTmpl(propPeers[0]->address(),_r->identity.address(),Packet::VERB_MULTICAST_FRAME);
|
||||
outpTmpl.append((uint8_t)0);
|
||||
|
@ -152,9 +148,9 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c
|
|||
outpTmpl.append((uint8_t)0); // 0 hops
|
||||
outpTmpl.append((uint16_t)etherType);
|
||||
outpTmpl.append((uint16_t)data.size());
|
||||
outpTmpl.append((uint16_t)signature.length());
|
||||
outpTmpl.append((uint16_t)signature.size());
|
||||
outpTmpl.append(data.data(),data.size());
|
||||
outpTmpl.append(signature.data(),(unsigned int)signature.length());
|
||||
outpTmpl.append(signature.data,(unsigned int)signature.size());
|
||||
outpTmpl.compress();
|
||||
send(outpTmpl,true);
|
||||
for(unsigned int i=1;i<np;++i) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue