mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-05 03:53:44 +02:00
Roots now understand encrypted HELLO.
This commit is contained in:
parent
2316a45a45
commit
0ab4e2f750
4 changed files with 57 additions and 11 deletions
|
@ -135,17 +135,8 @@ public:
|
||||||
while (len >= 16) {
|
while (len >= 16) {
|
||||||
_encryptSW((const uint8_t *)ctr,(uint8_t *)cenc);
|
_encryptSW((const uint8_t *)ctr,(uint8_t *)cenc);
|
||||||
ctr[1] = Utils::hton(++bctr);
|
ctr[1] = Utils::hton(++bctr);
|
||||||
#ifdef ZT_NO_TYPE_PUNNING
|
|
||||||
for(unsigned int k=0;k<16;++k)
|
for(unsigned int k=0;k<16;++k)
|
||||||
*(o++) = *(i++) ^ ((uint8_t *)cenc)[k];
|
*(o++) = *(i++) ^ ((uint8_t *)cenc)[k];
|
||||||
#else
|
|
||||||
*((uint64_t *)o) = *((const uint64_t *)i) ^ cenc[0];
|
|
||||||
o += 8;
|
|
||||||
i += 8;
|
|
||||||
*((uint64_t *)o) = *((const uint64_t *)i) ^ cenc[1];
|
|
||||||
o += 8;
|
|
||||||
i += 8;
|
|
||||||
#endif
|
|
||||||
len -= 16;
|
len -= 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -447,7 +447,9 @@ public:
|
||||||
|
|
||||||
ZT_ALWAYS_INLINE unsigned long hashCode() const { return ((unsigned long)_address.toInt() + (unsigned long)_pub.c25519[0] + (unsigned long)_pub.c25519[1] + (unsigned long)_pub.c25519[2]); }
|
ZT_ALWAYS_INLINE unsigned long hashCode() const { return ((unsigned long)_address.toInt() + (unsigned long)_pub.c25519[0] + (unsigned long)_pub.c25519[1] + (unsigned long)_pub.c25519[2]); }
|
||||||
|
|
||||||
private:
|
ZT_ALWAYS_INLINE const uint8_t *c25519SecretKey() const { return this->_priv.c25519; }
|
||||||
|
|
||||||
|
private:
|
||||||
Address _address;
|
Address _address;
|
||||||
Type _type;
|
Type _type;
|
||||||
bool _hasPrivate;
|
bool _hasPrivate;
|
||||||
|
|
|
@ -111,6 +111,17 @@
|
||||||
*/
|
*/
|
||||||
#define ZT_PROTO_FLAG_FRAGMENTED 0x40
|
#define ZT_PROTO_FLAG_FRAGMENTED 0x40
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Header flag indicating ephemeral keying and second encryption pass.
|
||||||
|
*
|
||||||
|
* If this is set, the packet will have an ephemeral key appended to it its payload
|
||||||
|
* will be encrypted with AES-CTR using this ephemeral key and the packet's header
|
||||||
|
* as an IV.
|
||||||
|
*
|
||||||
|
* Note that this is a reuse of a flag that has long been deprecated and ignored.
|
||||||
|
*/
|
||||||
|
#define ZT_PROTO_FLAG_EXTENDED_ARMOR 0x80
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verb flag indicating payload is compressed with LZ4
|
* Verb flag indicating payload is compressed with LZ4
|
||||||
*/
|
*/
|
||||||
|
@ -1153,6 +1164,29 @@ public:
|
||||||
b = (b & 0xc7) | (unsigned char)((c << 3) & 0x38); // bits: FFCCCHHH
|
b = (b & 0xc7) | (unsigned char)((c << 3) & 0x38); // bits: FFCCCHHH
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return True if packet is encrypted with an extra ephemeral key
|
||||||
|
*/
|
||||||
|
inline bool extendedArmor() const
|
||||||
|
{
|
||||||
|
return (((unsigned char)(*this)[ZT_PACKET_IDX_FLAGS] & ZT_PROTO_FLAG_EXTENDED_ARMOR) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this packet's extended armor flag
|
||||||
|
*
|
||||||
|
* @param f Extended armor flag value
|
||||||
|
*/
|
||||||
|
inline void setExtendedArmor(bool f)
|
||||||
|
{
|
||||||
|
if (f) {
|
||||||
|
(*this)[ZT_PACKET_IDX_FLAGS] |= (char)ZT_PROTO_FLAG_EXTENDED_ARMOR;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
(*this)[ZT_PACKET_IDX_FLAGS] &= (char)(~ZT_PROTO_FLAG_EXTENDED_ARMOR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the trusted path ID for this packet (only meaningful if cipher is trusted path)
|
* Get the trusted path ID for this packet (only meaningful if cipher is trusted path)
|
||||||
*
|
*
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
#include "../node/Packet.hpp"
|
#include "../node/Packet.hpp"
|
||||||
#include "../node/SharedPtr.hpp"
|
#include "../node/SharedPtr.hpp"
|
||||||
#include "../node/Utils.hpp"
|
#include "../node/Utils.hpp"
|
||||||
|
#include "../node/AES.hpp"
|
||||||
#include "../osdep/BlockingQueue.hpp"
|
#include "../osdep/BlockingQueue.hpp"
|
||||||
#include "../osdep/OSUtils.hpp"
|
#include "../osdep/OSUtils.hpp"
|
||||||
#include "geoip-html.h"
|
#include "geoip-html.h"
|
||||||
|
@ -265,6 +266,8 @@ static ZT_ALWAYS_INLINE std::array<uint64_t, 2> ip6ToH128(const InetAddress& ip)
|
||||||
return i128;
|
return i128;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define ZT_PACKET_IDX_EXTENDED_ARMOR_START 19
|
||||||
|
|
||||||
static void handlePacket(const int sock, const InetAddress* const ip, Packet& pkt)
|
static void handlePacket(const int sock, const InetAddress* const ip, Packet& pkt)
|
||||||
{
|
{
|
||||||
char ipstr[128], ipstr2[128], astr[32], astr2[32], tmpstr[256];
|
char ipstr[128], ipstr2[128], astr[32], astr2[32], tmpstr[256];
|
||||||
|
@ -281,6 +284,23 @@ static void handlePacket(const int sock, const InetAddress* const ip, Packet& pk
|
||||||
if ((! fragment) && (! pkt.fragmented()) && (dest == s_self.address())) {
|
if ((! fragment) && (! pkt.fragmented()) && (dest == s_self.address())) {
|
||||||
SharedPtr<RootPeer> peer;
|
SharedPtr<RootPeer> peer;
|
||||||
|
|
||||||
|
if ((pkt.cipher() == ZT_PROTO_CIPHER_SUITE__POLY1305_NONE) && pkt.extendedArmor()) {
|
||||||
|
if (pkt.size() < (ZT_PROTO_MIN_PACKET_LENGTH + 32)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uint8_t ephemeralSymmetric[64];
|
||||||
|
C25519::agree(s_self.c25519SecretKey(), (const uint8_t *)pkt.data() + (pkt.size() - 32), ephemeralSymmetric);
|
||||||
|
SHA512(ephemeralSymmetric, ephemeralSymmetric, 32);
|
||||||
|
|
||||||
|
AES cipher(ephemeralSymmetric);
|
||||||
|
uint32_t ctrIv[4];
|
||||||
|
memcpy(ctrIv, pkt.data(), 12);
|
||||||
|
ctrIv[3] = 0;
|
||||||
|
cipher.ctr((const uint8_t *)ctrIv, (const uint8_t *)pkt.data() + ZT_PACKET_IDX_EXTENDED_ARMOR_START, (pkt.size() - ZT_PACKET_IDX_EXTENDED_ARMOR_START) - 32, (uint8_t *)pkt.data() + ZT_PACKET_IDX_EXTENDED_ARMOR_START);
|
||||||
|
|
||||||
|
pkt.setSize(pkt.size() - 32);
|
||||||
|
}
|
||||||
|
|
||||||
// If this is an un-encrypted HELLO, either learn a new peer or verify
|
// If this is an un-encrypted HELLO, either learn a new peer or verify
|
||||||
// that this is a peer we already know.
|
// that this is a peer we already know.
|
||||||
if ((pkt.cipher() == ZT_PROTO_CIPHER_SUITE__POLY1305_NONE) && (pkt.verb() == Packet::VERB_HELLO)) {
|
if ((pkt.cipher() == ZT_PROTO_CIPHER_SUITE__POLY1305_NONE) && (pkt.verb() == Packet::VERB_HELLO)) {
|
||||||
|
@ -304,7 +324,6 @@ static void handlePacket(const int sock, const InetAddress* const ip, Packet& pk
|
||||||
pkt.reset(source, s_self.address(), Packet::VERB_ERROR);
|
pkt.reset(source, s_self.address(), Packet::VERB_ERROR);
|
||||||
pkt.append((uint8_t)Packet::VERB_HELLO);
|
pkt.append((uint8_t)Packet::VERB_HELLO);
|
||||||
pkt.append(origId);
|
pkt.append(origId);
|
||||||
;
|
|
||||||
pkt.append((uint8_t)Packet::ERROR_IDENTITY_COLLISION);
|
pkt.append((uint8_t)Packet::ERROR_IDENTITY_COLLISION);
|
||||||
pkt.armor(key, true);
|
pkt.armor(key, true);
|
||||||
sendto(sock, pkt.data(), pkt.size(), SENDTO_FLAGS, (const struct sockaddr*)ip, (socklen_t)((ip->ss_family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6)));
|
sendto(sock, pkt.data(), pkt.size(), SENDTO_FLAGS, (const struct sockaddr*)ip, (socklen_t)((ip->ss_family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6)));
|
||||||
|
|
Loading…
Add table
Reference in a new issue