summaryrefslogtreecommitdiff
path: root/node
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@gmail.com>2013-09-16 13:57:57 -0400
committerAdam Ierymenko <adam.ierymenko@gmail.com>2013-09-16 13:57:57 -0400
commite376c6f6a989d99d873918b349405302b62403a5 (patch)
tree446962e3a4d17a6d6aaa2976c2da156f5a5e2a03 /node
parentceb024ab03a114c8dadbbd393032231069981c45 (diff)
downloadinfinitytier-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.cpp2
-rw-r--r--node/Identity.cpp7
-rw-r--r--node/Identity.hpp42
-rw-r--r--node/Multicaster.hpp59
-rw-r--r--node/Network.cpp2
-rw-r--r--node/Node.cpp10
-rw-r--r--node/NodeConfig.cpp2
-rw-r--r--node/Peer.hpp3
-rw-r--r--node/Switch.cpp10
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) {