diff options
author | Adam Ierymenko <adam.ierymenko@gmail.com> | 2013-09-16 13:57:57 -0400 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@gmail.com> | 2013-09-16 13:57:57 -0400 |
commit | e376c6f6a989d99d873918b349405302b62403a5 (patch) | |
tree | 446962e3a4d17a6d6aaa2976c2da156f5a5e2a03 /node | |
parent | ceb024ab03a114c8dadbbd393032231069981c45 (diff) | |
download | infinitytier-e376c6f6a989d99d873918b349405302b62403a5.tar.gz infinitytier-e376c6f6a989d99d873918b349405302b62403a5.zip |
New crypto integrated -- going to be testing new identity address generation algo a bit more before finalizing.
Diffstat (limited to 'node')
-rw-r--r-- | node/Defaults.cpp | 2 | ||||
-rw-r--r-- | node/Identity.cpp | 7 | ||||
-rw-r--r-- | node/Identity.hpp | 42 | ||||
-rw-r--r-- | node/Multicaster.hpp | 59 | ||||
-rw-r--r-- | node/Network.cpp | 2 | ||||
-rw-r--r-- | node/Node.cpp | 10 | ||||
-rw-r--r-- | node/NodeConfig.cpp | 2 | ||||
-rw-r--r-- | node/Peer.hpp | 3 | ||||
-rw-r--r-- | node/Switch.cpp | 10 |
9 files changed, 78 insertions, 59 deletions
diff --git a/node/Defaults.cpp b/node/Defaults.cpp index 9f7d04fe..d50e1840 100644 --- a/node/Defaults.cpp +++ b/node/Defaults.cpp @@ -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; } diff --git a/node/Identity.cpp b/node/Identity.cpp index 5a752e85..67892232 100644 --- a/node/Identity.cpp +++ b/node/Identity.cpp @@ -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) { diff --git a/node/Identity.hpp b/node/Identity.hpp index de4ad2a0..eb8b19a4 100644 --- a/node/Identity.hpp +++ b/node/Identity.hpp @@ -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 { /** @@ -149,6 +151,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 * * This identity must have a private key. (Check hasPrivate()) @@ -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; } diff --git a/node/Multicaster.hpp b/node/Multicaster.hpp index 58bfeed1..8ff8e65e 100644 --- a/node/Multicaster.hpp +++ b/node/Multicaster.hpp @@ -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; diff --git a/node/Network.cpp b/node/Network.cpp index fa5b86d3..6a28228b 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -30,8 +30,6 @@ #include <stdlib.h> #include <math.h> -#include <openssl/sha.h> - #include "RuntimeEnvironment.hpp" #include "NodeConfig.hpp" #include "Network.hpp" diff --git a/node/Node.cpp b/node/Node.cpp index 590b9662..c3771df0 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -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; diff --git a/node/NodeConfig.cpp b/node/NodeConfig.cpp index 4567d410..823e2798 100644 --- a/node/NodeConfig.cpp +++ b/node/NodeConfig.cpp @@ -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); } diff --git a/node/Peer.hpp b/node/Peer.hpp index 85f045ef..f1ea653c 100644 --- a/node/Peer.hpp +++ b/node/Peer.hpp @@ -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) + \ diff --git a/node/Switch.cpp b/node/Switch.cpp index e17f2196..92fb7876 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -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) { |