mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-06 12:33:44 +02:00
A bunch of compile fixes, and an edge case fix in Dictionary.
This commit is contained in:
parent
53b85a2bbb
commit
3f4809457f
10 changed files with 293 additions and 303 deletions
29
core/AES.cpp
29
core/AES.cpp
|
@ -512,7 +512,9 @@ void AES::GMAC::finish(uint8_t tag[16]) noexcept
|
||||||
|
|
||||||
#ifdef ZT_AES_AESNI
|
#ifdef ZT_AES_AESNI
|
||||||
|
|
||||||
#if !defined(__WINDOWS__)
|
// Disable VAES stuff on compilers too old to compile these intrinsics,
|
||||||
|
// and MinGW64 also seems not to support them so disable on Windows.
|
||||||
|
#if !defined(__WINDOWS__) && ((__GNUC__ >= 8) || (__clang_major__ >= 7))
|
||||||
|
|
||||||
#define ZT_AES_VAES512
|
#define ZT_AES_VAES512
|
||||||
static
|
static
|
||||||
|
@ -793,19 +795,34 @@ void AES::CTR::crypt(const void *const input, unsigned int len) noexcept
|
||||||
_len = totalLen + len;
|
_len = totalLen + len;
|
||||||
|
|
||||||
if (likely(len >= 64)) {
|
if (likely(len >= 64)) {
|
||||||
|
|
||||||
|
// Compiler supports both AVX256 VAES and AVX512 VAES
|
||||||
#if defined(ZT_AES_VAES512) && defined(ZT_AES_VAES256)
|
#if defined(ZT_AES_VAES512) && defined(ZT_AES_VAES256)
|
||||||
if (Utils::CPUID.vaes) {
|
if (Utils::CPUID.vaes) {
|
||||||
if ((!Utils::CPUID.avx512f) || ((len < 1024))) {
|
if ((!Utils::CPUID.avx512f) || (len < 512)) {
|
||||||
p_aesCtrInnerVAES256(len, c0, c1, in, out, k);
|
p_aesCtrInnerVAES256(len, c0, c1, in, out, k);
|
||||||
} else {
|
} else {
|
||||||
p_aesCtrInnerVAES512(len, c0, c1, in, out, k);
|
p_aesCtrInnerVAES512(len, c0, c1, in, out, k);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#endif
|
|
||||||
p_aesCtrInner128(len, c0, c1, in, out, k);
|
p_aesCtrInner128(len, c0, c1, in, out, k);
|
||||||
#if defined(ZT_AES_VAES512) && defined(ZT_AES_VAES256)
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Compiler only supports AVX256 VAES
|
||||||
|
#if !defined(ZT_AES_VAES512) && defined(ZT_AES_VAES256)
|
||||||
|
if (Utils::CPUID.vaes) {
|
||||||
|
p_aesCtrInnerVAES256(len, c0, c1, in, out, k);
|
||||||
|
} else {
|
||||||
|
p_aesCtrInner128(len, c0, c1, in, out, k);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Compiler only support conventional AES-NI
|
||||||
|
#if !defined(ZT_AES_VAES512) && !defined(ZT_AES_VAES256)
|
||||||
|
p_aesCtrInner128(len, c0, c1, in, out, k);
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (len >= 16) {
|
while (len >= 16) {
|
||||||
|
@ -1194,7 +1211,7 @@ void AES::_decryptSW(const uint8_t in[16], uint8_t out[16]) const noexcept
|
||||||
|
|
||||||
#ifdef ZT_AES_AESNI
|
#ifdef ZT_AES_AESNI
|
||||||
|
|
||||||
static ZT_INLINE __m128i _init256_1_aesni(__m128i a, __m128i b) noexcept
|
static __m128i _init256_1_aesni(__m128i a, __m128i b) noexcept
|
||||||
{
|
{
|
||||||
__m128i x, y;
|
__m128i x, y;
|
||||||
b = _mm_shuffle_epi32(b, 0xff);
|
b = _mm_shuffle_epi32(b, 0xff);
|
||||||
|
@ -1208,7 +1225,7 @@ static ZT_INLINE __m128i _init256_1_aesni(__m128i a, __m128i b) noexcept
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ZT_INLINE __m128i _init256_2_aesni(__m128i a, __m128i b) noexcept
|
static __m128i _init256_2_aesni(__m128i a, __m128i b) noexcept
|
||||||
{
|
{
|
||||||
__m128i x, y, z;
|
__m128i x, y, z;
|
||||||
y = _mm_aeskeygenassist_si128(a, 0x00);
|
y = _mm_aeskeygenassist_si128(a, 0x00);
|
||||||
|
|
|
@ -17,35 +17,30 @@
|
||||||
|
|
||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
|
|
||||||
void Certificate::clear()
|
Certificate::Certificate() noexcept
|
||||||
{
|
{
|
||||||
Utils::zero< sizeof(ZT_Certificate) >((ZT_Certificate *)this);
|
ZT_Certificate *const sup = this;
|
||||||
|
Utils::zero< sizeof(ZT_Certificate) >(sup);
|
||||||
m_identities.clear();
|
|
||||||
m_locators.clear();
|
|
||||||
m_strings.clear();
|
|
||||||
m_serials.clear();
|
|
||||||
|
|
||||||
m_subjectIdentities.clear();
|
|
||||||
m_subjectNetworks.clear();
|
|
||||||
m_updateUrls.clear();
|
|
||||||
m_subjectCertificates.clear();
|
|
||||||
m_extendedAttributes.clear();
|
|
||||||
m_subjectUniqueId.clear();
|
|
||||||
m_subjectUniqueIdProofSignature.clear();
|
|
||||||
m_signature.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Certificate &Certificate::operator=(const ZT_Certificate &apiCert)
|
Certificate::Certificate(const ZT_Certificate &apiCert)
|
||||||
{
|
{
|
||||||
clear();
|
ZT_Certificate *const sup = this;
|
||||||
Utils::copy< sizeof(ZT_Certificate) >((ZT_Certificate *)this, &apiCert);
|
Utils::copy< sizeof(ZT_Certificate) >(sup, &apiCert);
|
||||||
return *this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Certificate &Certificate::operator=(const Certificate &cert)
|
Certificate::Certificate(const Certificate &cert)
|
||||||
|
{ *this = cert; }
|
||||||
|
|
||||||
|
Certificate::~Certificate()
|
||||||
|
{}
|
||||||
|
|
||||||
|
Certificate &Certificate::operator=(const ZT_Certificate &cert)
|
||||||
{
|
{
|
||||||
*this = *((const ZT_Certificate *)(&cert));
|
m_clear();
|
||||||
|
|
||||||
|
ZT_Certificate *const sup = this;
|
||||||
|
Utils::copy< sizeof(ZT_Certificate) >(sup, &cert);
|
||||||
|
|
||||||
// Zero these since we must explicitly attach all the objects from
|
// Zero these since we must explicitly attach all the objects from
|
||||||
// the other certificate to copy them into our containers.
|
// the other certificate to copy them into our containers.
|
||||||
|
@ -57,9 +52,15 @@ Certificate &Certificate::operator=(const Certificate &cert)
|
||||||
this->subject.certificateCount = 0;
|
this->subject.certificateCount = 0;
|
||||||
this->subject.updateUrls = nullptr;
|
this->subject.updateUrls = nullptr;
|
||||||
this->subject.updateUrlCount = 0;
|
this->subject.updateUrlCount = 0;
|
||||||
|
this->subject.uniqueId = nullptr;
|
||||||
|
this->subject.uniqueIdProofSignature = nullptr;
|
||||||
|
this->subject.uniqueIdSize = 0;
|
||||||
|
this->subject.uniqueIdProofSignatureSize = 0;
|
||||||
this->extendedAttributes = nullptr;
|
this->extendedAttributes = nullptr;
|
||||||
this->extendedAttributesSize = 0;
|
this->extendedAttributesSize = 0;
|
||||||
this->issuer = nullptr;
|
this->issuer = nullptr;
|
||||||
|
this->signature = nullptr;
|
||||||
|
this->signatureSize = 0;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < cert.subject.identityCount; ++i) {
|
for (unsigned int i = 0; i < cert.subject.identityCount; ++i) {
|
||||||
if (cert.subject.identities[i].identity) {
|
if (cert.subject.identities[i].identity) {
|
||||||
|
@ -86,15 +87,32 @@ Certificate &Certificate::operator=(const Certificate &cert)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((cert.subject.uniqueId) && (cert.subject.uniqueIdSize > 0)) {
|
||||||
|
m_subjectUniqueId.assign(cert.subject.uniqueId, cert.subject.uniqueId + cert.subject.uniqueIdSize);
|
||||||
|
this->subject.uniqueId = m_subjectUniqueId.data();
|
||||||
|
this->subject.uniqueIdSize = (unsigned int)m_subjectUniqueId.size();
|
||||||
|
}
|
||||||
|
if ((cert.subject.uniqueIdProofSignature) && (cert.subject.uniqueIdProofSignatureSize > 0)) {
|
||||||
|
m_subjectUniqueIdProofSignature.assign(cert.subject.uniqueIdProofSignature, cert.subject.uniqueIdProofSignature + cert.subject.uniqueIdProofSignatureSize);
|
||||||
|
this->subject.uniqueIdProofSignature = m_subjectUniqueIdProofSignature.data();
|
||||||
|
this->subject.uniqueIdProofSignatureSize = (unsigned int)m_subjectUniqueIdProofSignature.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cert.issuer) {
|
||||||
|
m_identities.push_back(*reinterpret_cast<const Identity *>(cert.issuer));
|
||||||
|
this->issuer = &(m_identities.back());
|
||||||
|
}
|
||||||
|
|
||||||
if ((cert.extendedAttributes) && (cert.extendedAttributesSize > 0)) {
|
if ((cert.extendedAttributes) && (cert.extendedAttributesSize > 0)) {
|
||||||
m_extendedAttributes.assign(cert.extendedAttributes, cert.extendedAttributes + cert.extendedAttributesSize);
|
m_extendedAttributes.assign(cert.extendedAttributes, cert.extendedAttributes + cert.extendedAttributesSize);
|
||||||
this->extendedAttributes = m_extendedAttributes.data();
|
this->extendedAttributes = m_extendedAttributes.data();
|
||||||
this->extendedAttributesSize = (unsigned int)m_extendedAttributes.size();
|
this->extendedAttributesSize = (unsigned int)m_extendedAttributes.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cert.issuer) {
|
if ((cert.signature) && (cert.signatureSize > 0)) {
|
||||||
m_identities.push_back(*reinterpret_cast<const Identity *>(cert.issuer));
|
m_signature.assign(cert.signature, cert.signature + cert.signatureSize);
|
||||||
this->issuer = &(m_identities.back());
|
this->signature = m_signature.data();
|
||||||
|
this->signatureSize = (unsigned int)m_signature.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -215,7 +233,10 @@ Vector< uint8_t > Certificate::encode(const bool omitSignature) const
|
||||||
if (this->issuerName.host[0])
|
if (this->issuerName.host[0])
|
||||||
d.add("iN.h", this->issuerName.host);
|
d.add("iN.h", this->issuerName.host);
|
||||||
|
|
||||||
if ((!omitSignature) && (this->signatureSize > 0) && (this->signatureSize <= sizeof(this->signature)))
|
if ((this->extendedAttributes) && (this->extendedAttributesSize > 0))
|
||||||
|
d["x"].assign(this->extendedAttributes, this->extendedAttributes + this->extendedAttributesSize);
|
||||||
|
|
||||||
|
if ((!omitSignature) && (this->signatureSize > 0) && (this->signature))
|
||||||
d["si"].assign(this->signature, this->signature + this->signatureSize);
|
d["si"].assign(this->signature, this->signature + this->signatureSize);
|
||||||
|
|
||||||
d.encode(enc);
|
d.encode(enc);
|
||||||
|
@ -226,7 +247,7 @@ bool Certificate::decode(const Vector< uint8_t > &data)
|
||||||
{
|
{
|
||||||
char tmp[256], tmp2[ZT_CERTIFICATE_MAX_STRING_LENGTH + 1];
|
char tmp[256], tmp2[ZT_CERTIFICATE_MAX_STRING_LENGTH + 1];
|
||||||
|
|
||||||
clear();
|
m_clear();
|
||||||
|
|
||||||
Dictionary d;
|
Dictionary d;
|
||||||
if (!d.decode(data.data(), (unsigned int)data.size()))
|
if (!d.decode(data.data(), (unsigned int)data.size()))
|
||||||
|
@ -238,12 +259,6 @@ bool Certificate::decode(const Vector< uint8_t > &data)
|
||||||
this->validity[1] = (int64_t)d.getUI("v#1");
|
this->validity[1] = (int64_t)d.getUI("v#1");
|
||||||
this->maxPathLength = (unsigned int)d.getUI("mP");
|
this->maxPathLength = (unsigned int)d.getUI("mP");
|
||||||
|
|
||||||
m_extendedAttributes = d["x"];
|
|
||||||
if (!m_extendedAttributes.empty()) {
|
|
||||||
this->extendedAttributes = m_extendedAttributes.data();
|
|
||||||
this->extendedAttributesSize = (unsigned int)m_extendedAttributes.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
this->subject.timestamp = (int64_t)d.getUI("s.t");
|
this->subject.timestamp = (int64_t)d.getUI("s.t");
|
||||||
|
|
||||||
unsigned int cnt = (unsigned int)d.getUI("s.i$");
|
unsigned int cnt = (unsigned int)d.getUI("s.i$");
|
||||||
|
@ -343,6 +358,12 @@ bool Certificate::decode(const Vector< uint8_t > &data)
|
||||||
else return false;
|
else return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_extendedAttributes = d["x"];
|
||||||
|
if (!m_extendedAttributes.empty()) {
|
||||||
|
this->extendedAttributes = m_extendedAttributes.data();
|
||||||
|
this->extendedAttributesSize = (unsigned int)m_extendedAttributes.size();
|
||||||
|
}
|
||||||
|
|
||||||
m_signature = d["si"];
|
m_signature = d["si"];
|
||||||
if (!m_signature.empty()) {
|
if (!m_signature.empty()) {
|
||||||
this->signature = m_signature.data();
|
this->signature = m_signature.data();
|
||||||
|
@ -453,9 +474,29 @@ bool Certificate::setSubjectUniqueId(const uint8_t uniqueId[ZT_CERTIFICATE_UNIQU
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Certificate::m_clear()
|
||||||
|
{
|
||||||
|
ZT_Certificate *const sup = this;
|
||||||
|
Utils::zero< sizeof(ZT_Certificate) >(sup);
|
||||||
|
|
||||||
|
m_identities.clear();
|
||||||
|
m_locators.clear();
|
||||||
|
m_strings.clear();
|
||||||
|
m_serials.clear();
|
||||||
|
|
||||||
|
m_subjectIdentities.clear();
|
||||||
|
m_subjectNetworks.clear();
|
||||||
|
m_updateUrls.clear();
|
||||||
|
m_subjectCertificates.clear();
|
||||||
|
m_extendedAttributes.clear();
|
||||||
|
m_subjectUniqueId.clear();
|
||||||
|
m_subjectUniqueIdProofSignature.clear();
|
||||||
|
m_signature.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void Certificate::m_encodeSubject(const ZT_Certificate_Subject &s, Dictionary &d, bool omitUniqueIdProofSignature)
|
void Certificate::m_encodeSubject(const ZT_Certificate_Subject &s, Dictionary &d, bool omitUniqueIdProofSignature)
|
||||||
{
|
{
|
||||||
char tmp[256];
|
char tmp[64];
|
||||||
|
|
||||||
d.add("s.t", (uint64_t)s.timestamp);
|
d.add("s.t", (uint64_t)s.timestamp);
|
||||||
|
|
||||||
|
|
|
@ -48,25 +48,28 @@ namespace ZeroTier {
|
||||||
class Certificate : public ZT_Certificate
|
class Certificate : public ZT_Certificate
|
||||||
{
|
{
|
||||||
friend class SharedPtr< Certificate >;
|
friend class SharedPtr< Certificate >;
|
||||||
|
|
||||||
friend class SharedPtr< const Certificate >;
|
friend class SharedPtr< const Certificate >;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ZT_INLINE Certificate() noexcept
|
Certificate() noexcept;
|
||||||
{ this->clear(); }
|
|
||||||
|
|
||||||
ZT_INLINE Certificate(const ZT_Certificate &apiCert)
|
Certificate(const ZT_Certificate &apiCert);
|
||||||
{ *this = apiCert; }
|
|
||||||
|
|
||||||
ZT_INLINE Certificate(const Certificate &cert)
|
Certificate(const Certificate &cert);
|
||||||
{ *this = cert; }
|
|
||||||
|
|
||||||
/**
|
~Certificate();
|
||||||
* Zero all fields and release all extra memory
|
|
||||||
*/
|
|
||||||
void clear();
|
|
||||||
|
|
||||||
Certificate &operator=(const ZT_Certificate &apiCert);
|
Certificate &operator=(const ZT_Certificate &cert);
|
||||||
Certificate &operator=(const Certificate &cert);
|
|
||||||
|
ZT_INLINE Certificate &operator=(const Certificate &cert)
|
||||||
|
{
|
||||||
|
if (likely(&cert != this)) {
|
||||||
|
const ZT_Certificate *const sup = &cert;
|
||||||
|
*this = *sup;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a subject node/identity without a locator
|
* Add a subject node/identity without a locator
|
||||||
|
@ -186,18 +189,25 @@ public:
|
||||||
|
|
||||||
ZT_INLINE bool operator==(const ZT_Certificate &c) const noexcept
|
ZT_INLINE bool operator==(const ZT_Certificate &c) const noexcept
|
||||||
{ return memcmp(this->serialNo, c.serialNo, ZT_SHA384_DIGEST_SIZE) == 0; }
|
{ return memcmp(this->serialNo, c.serialNo, ZT_SHA384_DIGEST_SIZE) == 0; }
|
||||||
|
|
||||||
ZT_INLINE bool operator!=(const ZT_Certificate &c) const noexcept
|
ZT_INLINE bool operator!=(const ZT_Certificate &c) const noexcept
|
||||||
{ return memcmp(this->serialNo, c.serialNo, ZT_SHA384_DIGEST_SIZE) != 0; }
|
{ return memcmp(this->serialNo, c.serialNo, ZT_SHA384_DIGEST_SIZE) != 0; }
|
||||||
|
|
||||||
ZT_INLINE bool operator<(const ZT_Certificate &c) const noexcept
|
ZT_INLINE bool operator<(const ZT_Certificate &c) const noexcept
|
||||||
{ return memcmp(this->serialNo, c.serialNo, ZT_SHA384_DIGEST_SIZE) < 0; }
|
{ return memcmp(this->serialNo, c.serialNo, ZT_SHA384_DIGEST_SIZE) < 0; }
|
||||||
|
|
||||||
ZT_INLINE bool operator<=(const ZT_Certificate &c) const noexcept
|
ZT_INLINE bool operator<=(const ZT_Certificate &c) const noexcept
|
||||||
{ return memcmp(this->serialNo, c.serialNo, ZT_SHA384_DIGEST_SIZE) <= 0; }
|
{ return memcmp(this->serialNo, c.serialNo, ZT_SHA384_DIGEST_SIZE) <= 0; }
|
||||||
|
|
||||||
ZT_INLINE bool operator>(const ZT_Certificate &c) const noexcept
|
ZT_INLINE bool operator>(const ZT_Certificate &c) const noexcept
|
||||||
{ return memcmp(this->serialNo, c.serialNo, ZT_SHA384_DIGEST_SIZE) > 0; }
|
{ return memcmp(this->serialNo, c.serialNo, ZT_SHA384_DIGEST_SIZE) > 0; }
|
||||||
|
|
||||||
ZT_INLINE bool operator>=(const ZT_Certificate &c) const noexcept
|
ZT_INLINE bool operator>=(const ZT_Certificate &c) const noexcept
|
||||||
{ return memcmp(this->serialNo, c.serialNo, ZT_SHA384_DIGEST_SIZE) >= 0; }
|
{ return memcmp(this->serialNo, c.serialNo, ZT_SHA384_DIGEST_SIZE) >= 0; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void m_clear();
|
||||||
|
|
||||||
static void m_encodeSubject(const ZT_Certificate_Subject &s, Dictionary &d, bool omitUniqueIdProofSignature);
|
static void m_encodeSubject(const ZT_Certificate_Subject &s, Dictionary &d, bool omitUniqueIdProofSignature);
|
||||||
|
|
||||||
// These hold any identity or locator objects that are owned by and should
|
// These hold any identity or locator objects that are owned by and should
|
||||||
|
@ -218,7 +228,7 @@ private:
|
||||||
Vector< uint8_t > m_subjectUniqueIdProofSignature;
|
Vector< uint8_t > m_subjectUniqueIdProofSignature;
|
||||||
Vector< uint8_t > m_signature;
|
Vector< uint8_t > m_signature;
|
||||||
|
|
||||||
std::atomic<int> __refCount;
|
std::atomic< int > __refCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ZeroTier
|
} // namespace ZeroTier
|
||||||
|
|
|
@ -19,18 +19,17 @@
|
||||||
#include "Constants.hpp"
|
#include "Constants.hpp"
|
||||||
#include "Utils.hpp"
|
#include "Utils.hpp"
|
||||||
|
|
||||||
#ifdef __CPP11__
|
|
||||||
|
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#ifdef __CPP11__
|
||||||
|
#include <atomic>
|
||||||
|
#include <unordered_map>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
|
|
||||||
#ifdef __CPP11__
|
#ifdef __CPP11__
|
||||||
|
@ -51,7 +50,7 @@ struct intl_MapHasher
|
||||||
};
|
};
|
||||||
|
|
||||||
template< typename K, typename V >
|
template< typename K, typename V >
|
||||||
class Map : public std::unordered_map< K, V, intl_MapHasher, std::equal_to< K >, Utils::Mallocator < std::pair< const K, V > > >
|
class Map : public std::unordered_map< K, V, intl_MapHasher >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ZT_INLINE V *get(const K &key) noexcept
|
ZT_INLINE V *get(const K &key) noexcept
|
||||||
|
@ -72,13 +71,13 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
template< typename K, typename V >
|
template< typename K, typename V >
|
||||||
class MultiMap : public std::unordered_multimap< K, V, intl_MapHasher, std::equal_to< K >, Utils::Mallocator < std::pair< const K, V > > >
|
class MultiMap : public std::unordered_multimap< K, V, intl_MapHasher, std::equal_to< K > >
|
||||||
{};
|
{};
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
template<typename K,typename V>
|
template<typename K,typename V>
|
||||||
class Map : public std::map< K,V,std::less<K>,Utils::Mallocator< std::pair<const K,V> > >
|
class Map : public std::map< K,V,std::less<K> >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ZT_INLINE V *get(const K &key) noexcept
|
ZT_INLINE V *get(const K &key) noexcept
|
||||||
|
@ -109,55 +108,31 @@ class MultiMap : public std::multimap< K,V,std::less<K>,Utils::Mallocator< std::
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template< typename K, typename V >
|
template< typename K, typename V >
|
||||||
class SortedMap : public std::map< K, V, std::less< K >, Utils::Mallocator < std::pair< const K, V > > >
|
class SortedMap : public std::map< K, V >
|
||||||
{
|
{};
|
||||||
public:
|
|
||||||
ZT_INLINE V *get(const K &key) noexcept
|
|
||||||
{
|
|
||||||
typename SortedMap::iterator i(this->find(key));
|
|
||||||
if (i == this->end())
|
|
||||||
return nullptr;
|
|
||||||
return &(i->second);
|
|
||||||
}
|
|
||||||
ZT_INLINE const V *get(const K &key) const noexcept
|
|
||||||
{
|
|
||||||
typename SortedMap::const_iterator i(this->find(key));
|
|
||||||
if (i == this->end())
|
|
||||||
return nullptr;
|
|
||||||
return &(i->second);
|
|
||||||
}
|
|
||||||
ZT_INLINE void set(const K &key, const V &value) { (*this)[key] = value; }
|
|
||||||
};
|
|
||||||
|
|
||||||
template< typename V >
|
template< typename V >
|
||||||
class Vector : public std::vector< V, Utils::Mallocator < V > >
|
class Vector : public std::vector< V >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ZT_INLINE Vector() {}
|
ZT_INLINE Vector()
|
||||||
|
{}
|
||||||
|
|
||||||
template< typename I >
|
template< typename I >
|
||||||
ZT_INLINE Vector(I begin,I end) : std::vector< V, Utils::Mallocator < V > >(begin,end) {}
|
ZT_INLINE Vector(I begin,I end) :
|
||||||
|
std::vector< V >(begin, end)
|
||||||
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
template< typename V >
|
template< typename V >
|
||||||
class List : public std::list< V, Utils::Mallocator < V > >
|
class List : public std::list< V >
|
||||||
{
|
{};
|
||||||
};
|
|
||||||
|
|
||||||
template< typename V >
|
template< typename V >
|
||||||
class Set : public std::set< V, std::less< V >, Utils::Mallocator < V > >
|
class Set : public std::set< V, std::less< V > >
|
||||||
{
|
{};
|
||||||
};
|
|
||||||
|
|
||||||
class String : public std::basic_string< char, std::char_traits< char >, Utils::Mallocator < char > >
|
typedef std::string String;
|
||||||
{
|
|
||||||
public:
|
|
||||||
ZT_INLINE String() {}
|
|
||||||
ZT_INLINE String(const String &s) : std::basic_string< char, std::char_traits< char >, Utils::Mallocator < char > >(s.c_str()) {}
|
|
||||||
ZT_INLINE String(const std::string &s) : std::basic_string< char, std::char_traits< char >, Utils::Mallocator < char > >(s.c_str()) {}
|
|
||||||
ZT_INLINE String(const char *const s) : std::basic_string< char, std::char_traits< char >, Utils::Mallocator < char > >(s) {}
|
|
||||||
ZT_INLINE String &operator=(const char *const s) { assign(s); return *this; }
|
|
||||||
ZT_INLINE String &operator=(const std::string &s) { assign(s.c_str()); return *this; }
|
|
||||||
};
|
|
||||||
|
|
||||||
} // ZeroTier
|
} // ZeroTier
|
||||||
|
|
||||||
|
|
|
@ -21,23 +21,14 @@ Dictionary::Dictionary()
|
||||||
Dictionary::~Dictionary()
|
Dictionary::~Dictionary()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Vector< uint8_t > &Dictionary::operator[](const char *k)
|
Vector< uint8_t > &Dictionary::operator[](const char *const k)
|
||||||
{
|
{ return m_entries[s_key(k)]; }
|
||||||
if (k)
|
|
||||||
return m_entries[s_key(k)];
|
|
||||||
else return m_entries[""];
|
|
||||||
}
|
|
||||||
|
|
||||||
const Vector< uint8_t > &Dictionary::operator[](const char *k) const
|
const Vector< uint8_t > &Dictionary::operator[](const char *const k) const
|
||||||
{
|
{
|
||||||
static const Vector< uint8_t > s_emptyEntry;
|
static const Vector< uint8_t > s_emptyEntry;
|
||||||
if (k) {
|
const SortedMap< String, Vector< uint8_t > >::const_iterator e(m_entries.find(s_key(k)));
|
||||||
SortedMap< String, Vector< uint8_t > >::const_iterator e(m_entries.find(s_key(k)));
|
return (e == m_entries.end()) ? s_emptyEntry : e->second;
|
||||||
return (e == m_entries.end()) ? s_emptyEntry : e->second;
|
|
||||||
} else {
|
|
||||||
SortedMap< String, Vector< uint8_t > >::const_iterator e(m_entries.find(""));
|
|
||||||
return (e == m_entries.end()) ? s_emptyEntry : e->second;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dictionary::add(const char *k, bool v)
|
void Dictionary::add(const char *k, bool v)
|
||||||
|
@ -50,16 +41,16 @@ void Dictionary::add(const char *k, bool v)
|
||||||
|
|
||||||
void Dictionary::add(const char *k, const Address &v)
|
void Dictionary::add(const char *k, const Address &v)
|
||||||
{
|
{
|
||||||
Vector< uint8_t > &e = (*this)[k];
|
char tmp[ZT_ADDRESS_STRING_SIZE_MAX];
|
||||||
e.resize(ZT_ADDRESS_STRING_SIZE_MAX);
|
v.toString(tmp);
|
||||||
v.toString((char *)e.data());
|
add(k, tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dictionary::add(const char *k, const char *v)
|
void Dictionary::add(const char *k, const char *v)
|
||||||
{
|
{
|
||||||
if ((v) && (*v)) {
|
Vector< uint8_t > &e = (*this)[k];
|
||||||
Vector< uint8_t > &e = (*this)[k];
|
e.clear();
|
||||||
e.clear();
|
if (v) {
|
||||||
while (*v)
|
while (*v)
|
||||||
e.push_back((uint8_t)*(v++));
|
e.push_back((uint8_t)*(v++));
|
||||||
}
|
}
|
||||||
|
@ -68,7 +59,7 @@ void Dictionary::add(const char *k, const char *v)
|
||||||
void Dictionary::add(const char *k, const void *data, unsigned int len)
|
void Dictionary::add(const char *k, const void *data, unsigned int len)
|
||||||
{
|
{
|
||||||
Vector< uint8_t > &e = (*this)[k];
|
Vector< uint8_t > &e = (*this)[k];
|
||||||
if (len != 0) {
|
if (likely(len != 0)) {
|
||||||
e.assign((const uint8_t *)data, (const uint8_t *)data + len);
|
e.assign((const uint8_t *)data, (const uint8_t *)data + len);
|
||||||
} else {
|
} else {
|
||||||
e.clear();
|
e.clear();
|
||||||
|
@ -150,48 +141,48 @@ bool Dictionary::decode(const void *data, unsigned int len)
|
||||||
Vector< uint8_t > *v = nullptr;
|
Vector< uint8_t > *v = nullptr;
|
||||||
bool escape = false;
|
bool escape = false;
|
||||||
for (unsigned int di = 0; di < len; ++di) {
|
for (unsigned int di = 0; di < len; ++di) {
|
||||||
uint8_t c = reinterpret_cast<const uint8_t *>(data)[di];
|
const uint8_t c = reinterpret_cast<const uint8_t *>(data)[di];
|
||||||
if (!c) break;
|
if (c) {
|
||||||
if (v) {
|
if (v) {
|
||||||
if (escape) {
|
if (escape) {
|
||||||
escape = false;
|
escape = false;
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 48:
|
case 48:
|
||||||
v->push_back(0);
|
v->push_back(0);
|
||||||
break;
|
break;
|
||||||
case 101:
|
case 101:
|
||||||
v->push_back(61);
|
v->push_back(61);
|
||||||
break;
|
break;
|
||||||
case 110:
|
case 110:
|
||||||
v->push_back(10);
|
v->push_back(10);
|
||||||
break;
|
break;
|
||||||
case 114:
|
case 114:
|
||||||
v->push_back(13);
|
v->push_back(13);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
v->push_back(c);
|
v->push_back(c);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (c == (uint8_t)'\n') {
|
|
||||||
k.clear();
|
|
||||||
v = nullptr;
|
|
||||||
} else if (c == 92) { // backslash
|
|
||||||
escape = true;
|
|
||||||
} else {
|
} else {
|
||||||
v->push_back(c);
|
if (c == (uint8_t)'\n') {
|
||||||
|
k.clear();
|
||||||
|
v = nullptr;
|
||||||
|
} else if (c == 92) { // backslash
|
||||||
|
escape = true;
|
||||||
|
} else {
|
||||||
|
v->push_back(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (c == (uint8_t)'=') {
|
||||||
|
v = &m_entries[k];
|
||||||
|
} else if ((c < 33) || (c > 126) || (c == 92)) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
k.push_back(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else break;
|
||||||
if ((c < 33) || (c > 126) || (c == 92)) {
|
|
||||||
return false;
|
|
||||||
} else if (c == (uint8_t)'=') {
|
|
||||||
k.push_back(0);
|
|
||||||
v = &m_entries[k];
|
|
||||||
} else {
|
|
||||||
k.push_back(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -209,4 +200,19 @@ char *Dictionary::arraySubscript(char buf[256],const char *name,const unsigned l
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String Dictionary::s_key(const char *k) noexcept
|
||||||
|
{
|
||||||
|
String buf;
|
||||||
|
if (likely(k != nullptr)) {
|
||||||
|
for (;;) {
|
||||||
|
const char c = *(k++);
|
||||||
|
if ((c >= 33) && (c <= 126) && (c != 61) && (c != 92)) // printable ASCII with no spaces, equals, or backslash
|
||||||
|
buf.push_back(c);
|
||||||
|
else if (c == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ZeroTier
|
} // namespace ZeroTier
|
||||||
|
|
|
@ -268,6 +268,7 @@ public:
|
||||||
template< typename V >
|
template< typename V >
|
||||||
ZT_INLINE static void append(V &out, const char *const k, const uint64_t v)
|
ZT_INLINE static void append(V &out, const char *const k, const uint64_t v)
|
||||||
{
|
{
|
||||||
|
s_appendKey(out, k);
|
||||||
char buf[17];
|
char buf[17];
|
||||||
Utils::hex(v, buf);
|
Utils::hex(v, buf);
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
|
@ -370,6 +371,14 @@ public:
|
||||||
return mlen;
|
return mlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append #sub where sub is a hexadecimal string to 'name' and store in 'buf'
|
||||||
|
*
|
||||||
|
* @param buf Buffer to store subscript key
|
||||||
|
* @param name Root name
|
||||||
|
* @param sub Subscript index
|
||||||
|
* @return Pointer to 'buf'
|
||||||
|
*/
|
||||||
static char *arraySubscript(char buf[256],const char *name,const unsigned long sub) noexcept;
|
static char *arraySubscript(char buf[256],const char *name,const unsigned long sub) noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -407,27 +416,16 @@ private:
|
||||||
ZT_INLINE static void s_appendKey(V &out, const char *k)
|
ZT_INLINE static void s_appendKey(V &out, const char *k)
|
||||||
{
|
{
|
||||||
for (;;) {
|
for (;;) {
|
||||||
char c = *(k++);
|
const char c = *(k++);
|
||||||
if (c == 0)
|
|
||||||
break;
|
|
||||||
if ((c >= 33) && (c <= 126) && (c != 61) && (c != 92)) // printable ASCII with no spaces, equals, or backslash
|
if ((c >= 33) && (c <= 126) && (c != 61) && (c != 92)) // printable ASCII with no spaces, equals, or backslash
|
||||||
out.push_back((uint8_t)c);
|
out.push_back((uint8_t)c);
|
||||||
|
else if (c == 0)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
out.push_back((uint8_t)'=');
|
out.push_back((uint8_t)'=');
|
||||||
}
|
}
|
||||||
|
|
||||||
ZT_INLINE static String s_key(const char *k) noexcept
|
static String s_key(const char *k) noexcept;
|
||||||
{
|
|
||||||
String buf;
|
|
||||||
for(;;) {
|
|
||||||
char c = *(k++);
|
|
||||||
if (c == 0)
|
|
||||||
break;
|
|
||||||
if ((c >= 33) && (c <= 126) && (c != 61) && (c != 92)) // printable ASCII with no spaces, equals, or backslash
|
|
||||||
buf.push_back(c);
|
|
||||||
}
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dictionary maps need to be sorted so that they always encode in the same order
|
// Dictionary maps need to be sorted so that they always encode in the same order
|
||||||
// to yield blobs that can be hashed and signed reproducibly. Other than for areas
|
// to yield blobs that can be hashed and signed reproducibly. Other than for areas
|
||||||
|
|
|
@ -18,9 +18,10 @@
|
||||||
#include "Poly1305.hpp"
|
#include "Poly1305.hpp"
|
||||||
#include "Utils.hpp"
|
#include "Utils.hpp"
|
||||||
#include "Endpoint.hpp"
|
#include "Endpoint.hpp"
|
||||||
#include "Locator.hpp"
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <memory>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
|
|
||||||
|
@ -93,10 +94,8 @@ struct p_CompareLittleEndian
|
||||||
};
|
};
|
||||||
|
|
||||||
// This is a simpler memory-intensive frankenhash for V1 identity generation.
|
// This is a simpler memory-intensive frankenhash for V1 identity generation.
|
||||||
bool identityV1ProofOfWorkCriteria(const void *in, const unsigned int len)
|
bool identityV1ProofOfWorkCriteria(const void *in, const unsigned int len, uint64_t *const w)
|
||||||
{
|
{
|
||||||
uint64_t w[ZT_IDENTITY_V1_POW_MEMORY_SIZE / 8];
|
|
||||||
|
|
||||||
// Fill work buffer with pseudorandom bytes using a construction that should be
|
// Fill work buffer with pseudorandom bytes using a construction that should be
|
||||||
// relatively hostile to GPU acceleration. GPUs usually implement branching by
|
// relatively hostile to GPU acceleration. GPUs usually implement branching by
|
||||||
// executing all branches and then selecting the answer, which means this
|
// executing all branches and then selecting the answer, which means this
|
||||||
|
@ -165,29 +164,36 @@ bool Identity::generate(const Type t)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case P384: {
|
case P384: {
|
||||||
for (;;) {
|
//uint64_t w[ZT_IDENTITY_V1_POW_MEMORY_SIZE / 8];
|
||||||
// Loop until we pass the PoW criteria. The nonce is only 8 bits, so generate
|
uint64_t *const w = (uint64_t *)malloc(ZT_IDENTITY_V1_POW_MEMORY_SIZE);
|
||||||
// some new key material every time it wraps. The ECC384 generator is slightly
|
if (!w)
|
||||||
// faster so use that one.
|
return false;
|
||||||
m_pub[0] = 0; // zero nonce
|
try {
|
||||||
C25519::generateCombined(m_pub + 1, m_priv + 1);
|
|
||||||
ECC384GenerateKey(m_pub + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE, m_priv + ZT_C25519_COMBINED_PRIVATE_KEY_SIZE);
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (identityV1ProofOfWorkCriteria(m_pub, sizeof(m_pub)))
|
// Loop until we pass the PoW criteria. The nonce is only 8 bits, so generate
|
||||||
break;
|
// some new key material every time it wraps. The ECC384 generator is slightly
|
||||||
if (++m_pub[0] == 0)
|
// faster so use that one.
|
||||||
ECC384GenerateKey(m_pub + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE, m_priv + ZT_C25519_COMBINED_PRIVATE_KEY_SIZE);
|
m_pub[0] = 0; // zero nonce
|
||||||
}
|
C25519::generateCombined(m_pub + 1, m_priv + 1);
|
||||||
|
ECC384GenerateKey(m_pub + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE, m_priv + ZT_C25519_COMBINED_PRIVATE_KEY_SIZE);
|
||||||
|
for (;;) {
|
||||||
|
if (identityV1ProofOfWorkCriteria(m_pub, sizeof(m_pub), w))
|
||||||
|
break;
|
||||||
|
if (++m_pub[0] == 0)
|
||||||
|
ECC384GenerateKey(m_pub + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE, m_priv + ZT_C25519_COMBINED_PRIVATE_KEY_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
// If we passed PoW then check that the address is valid, otherwise loop
|
// If we passed PoW then check that the address is valid, otherwise loop
|
||||||
// back around and run the whole process again.
|
// back around and run the whole process again.
|
||||||
m_computeHash();
|
m_computeHash();
|
||||||
const Address addr(m_fp.hash);
|
const Address addr(m_fp.hash);
|
||||||
if (!addr.isReserved()) {
|
if (!addr.isReserved()) {
|
||||||
m_fp.address = addr;
|
m_fp.address = addr;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
} catch ( ... ) {}
|
||||||
|
free(w);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -215,7 +221,12 @@ bool Identity::locallyValidate() const noexcept
|
||||||
case P384: {
|
case P384: {
|
||||||
if (Address(m_fp.hash) != m_fp.address)
|
if (Address(m_fp.hash) != m_fp.address)
|
||||||
return false;
|
return false;
|
||||||
return identityV1ProofOfWorkCriteria(m_pub, sizeof(m_pub));
|
uint64_t *const w = (uint64_t *)malloc(ZT_IDENTITY_V1_POW_MEMORY_SIZE);
|
||||||
|
if (!w)
|
||||||
|
return false;
|
||||||
|
const bool valid = identityV1ProofOfWorkCriteria(m_pub, sizeof(m_pub), w);
|
||||||
|
free(w);
|
||||||
|
return valid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,6 +110,7 @@
|
||||||
#include <xmmintrin.h>
|
#include <xmmintrin.h>
|
||||||
#include <emmintrin.h>
|
#include <emmintrin.h>
|
||||||
#include <immintrin.h>
|
#include <immintrin.h>
|
||||||
|
#include <tmmintrin.h>
|
||||||
#include <mmintrin.h>
|
#include <mmintrin.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -283,6 +283,7 @@ static bool ZTT_deepCompareCertificates(const Certificate &a, const Certificate
|
||||||
return false;
|
return false;
|
||||||
if ((a.subject.uniqueIdProofSignature == nullptr) != (b.subject.uniqueIdProofSignature == nullptr))
|
if ((a.subject.uniqueIdProofSignature == nullptr) != (b.subject.uniqueIdProofSignature == nullptr))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if ((a.subject.uniqueId != nullptr) && (a.subject.uniqueIdProofSignature != nullptr)) {
|
if ((a.subject.uniqueId != nullptr) && (a.subject.uniqueIdProofSignature != nullptr)) {
|
||||||
if (
|
if (
|
||||||
(memcmp(a.subject.uniqueId, b.subject.uniqueId, a.subject.uniqueIdSize) != 0) ||
|
(memcmp(a.subject.uniqueId, b.subject.uniqueId, a.subject.uniqueIdSize) != 0) ||
|
||||||
|
@ -1082,10 +1083,9 @@ extern "C" const char *ZTT_crypto()
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
char tmp[4096];
|
char tmp[256];
|
||||||
|
|
||||||
ZT_T_PRINTF("[crypto] Testing Certificate..." ZT_EOL_S);
|
ZT_T_PRINTF("[crypto] Testing Certificate..." ZT_EOL_S);
|
||||||
Certificate cert;
|
|
||||||
|
|
||||||
ZT_T_PRINTF(" Create test subject and issuer identities... ");
|
ZT_T_PRINTF(" Create test subject and issuer identities... ");
|
||||||
Identity testSubjectId, testIssuerId;
|
Identity testSubjectId, testIssuerId;
|
||||||
|
@ -1100,53 +1100,57 @@ extern "C" const char *ZTT_crypto()
|
||||||
ZT_T_PRINTF("OK %s" ZT_EOL_S, tmp);
|
ZT_T_PRINTF("OK %s" ZT_EOL_S, tmp);
|
||||||
|
|
||||||
ZT_T_PRINTF(" Create and sign certificate... ");
|
ZT_T_PRINTF(" Create and sign certificate... ");
|
||||||
cert.subject.timestamp = now();
|
SharedPtr<Certificate> cert(new Certificate());
|
||||||
cert.addSubjectIdentity(testSubjectId);
|
cert->subject.timestamp = now();
|
||||||
cert.addSubjectNetwork(12345, testSubjectId.fingerprint());
|
cert->addSubjectIdentity(testSubjectId);
|
||||||
cert.addSubjectUpdateUrl("https://www.zerotier.com/");
|
cert->addSubjectNetwork(12345, testSubjectId.fingerprint());
|
||||||
ZT_SETSTR(cert.subject.name.serialNo, "serialNo");
|
cert->addSubjectUpdateUrl("https://www.zerotier.com/");
|
||||||
ZT_SETSTR(cert.subject.name.commonName, "commonName");
|
ZT_SETSTR(cert->subject.name.serialNo, "serialNo");
|
||||||
ZT_SETSTR(cert.subject.name.country, "country");
|
ZT_SETSTR(cert->subject.name.commonName, "commonName");
|
||||||
ZT_SETSTR(cert.subject.name.organization, "organization");
|
ZT_SETSTR(cert->subject.name.country, "country");
|
||||||
ZT_SETSTR(cert.subject.name.unit, "unit");
|
ZT_SETSTR(cert->subject.name.organization, "organization");
|
||||||
ZT_SETSTR(cert.subject.name.locality, "locality");
|
ZT_SETSTR(cert->subject.name.unit, "unit");
|
||||||
ZT_SETSTR(cert.subject.name.province, "province");
|
ZT_SETSTR(cert->subject.name.locality, "locality");
|
||||||
ZT_SETSTR(cert.subject.name.streetAddress, "streetAddress");
|
ZT_SETSTR(cert->subject.name.province, "province");
|
||||||
ZT_SETSTR(cert.subject.name.postalCode, "postalCode");
|
ZT_SETSTR(cert->subject.name.streetAddress, "streetAddress");
|
||||||
ZT_SETSTR(cert.subject.name.email, "email");
|
ZT_SETSTR(cert->subject.name.postalCode, "postalCode");
|
||||||
ZT_SETSTR(cert.subject.name.url, "url");
|
ZT_SETSTR(cert->subject.name.email, "email");
|
||||||
ZT_SETSTR(cert.subject.name.host, "host");
|
ZT_SETSTR(cert->subject.name.url, "url");
|
||||||
cert.timestamp = cert.subject.timestamp;
|
ZT_SETSTR(cert->subject.name.host, "host");
|
||||||
cert.validity[0] = 0;
|
cert->timestamp = cert->subject.timestamp;
|
||||||
cert.validity[1] = 9223372036854775807LL;
|
cert->validity[0] = 0;
|
||||||
Utils::copy<sizeof(ZT_Certificate_Subject)>(&cert.issuerName, &cert.subject.name);
|
cert->validity[1] = 9223372036854775807LL;
|
||||||
cert.setSubjectUniqueId(uniqueId, uniqueIdPrivate);
|
Utils::copy<sizeof(ZT_Certificate_Name)>(&cert->issuerName, &cert->subject.name);
|
||||||
cert.sign(testIssuerId);
|
cert->setSubjectUniqueId(uniqueId, uniqueIdPrivate);
|
||||||
Vector< uint8_t > enc(cert.encode());
|
cert->sign(testIssuerId);
|
||||||
|
Vector< uint8_t > enc(cert->encode());
|
||||||
ZT_T_PRINTF("OK (%d bytes)" ZT_EOL_S, (int)enc.size());
|
ZT_T_PRINTF("OK (%d bytes)" ZT_EOL_S, (int)enc.size());
|
||||||
|
|
||||||
ZT_T_PRINTF(" Testing certificate verify... ");
|
ZT_T_PRINTF(" Testing certificate verify... ");
|
||||||
if (!cert.verify()) {
|
if (!cert->verify()) {
|
||||||
ZT_T_PRINTF("FAILED (verify original)" ZT_EOL_S);
|
ZT_T_PRINTF("FAILED (verify original)" ZT_EOL_S);
|
||||||
return "Verify original certificate";
|
return "Verify original certificate";
|
||||||
}
|
}
|
||||||
ZT_T_PRINTF("OK" ZT_EOL_S);
|
ZT_T_PRINTF("OK" ZT_EOL_S);
|
||||||
|
|
||||||
ZT_T_PRINTF(" Test certificate decode from marshaled format... ");
|
ZT_T_PRINTF(" Test certificate decode from marshaled format... ");
|
||||||
Certificate cert2;
|
SharedPtr<Certificate> cert2(new Certificate());
|
||||||
if (!cert2.decode(enc)) {
|
if (!cert2->decode(enc)) {
|
||||||
ZT_T_PRINTF("FAILED (decode)" ZT_EOL_S);
|
ZT_T_PRINTF("FAILED (decode)" ZT_EOL_S);
|
||||||
return "Certificate decode";
|
return "Certificate decode";
|
||||||
}
|
}
|
||||||
if (!ZTT_deepCompareCertificates(cert, cert2)) {
|
if (!ZTT_deepCompareCertificates(*cert, *cert2)) {
|
||||||
ZT_T_PRINTF("FAILED (compare decoded with original)" ZT_EOL_S);
|
ZT_T_PRINTF("FAILED (compare decoded with original)" ZT_EOL_S);
|
||||||
return "Certificate decode and compare";
|
return "Certificate decode and compare";
|
||||||
}
|
}
|
||||||
if (!cert2.verify()) {
|
if (!cert2->verify()) {
|
||||||
ZT_T_PRINTF("FAILED (verify decoded certificate)");
|
ZT_T_PRINTF("FAILED (verify decoded certificate)");
|
||||||
return "Verify decoded certificate";
|
return "Verify decoded certificate";
|
||||||
}
|
}
|
||||||
ZT_T_PRINTF("OK" ZT_EOL_S);
|
ZT_T_PRINTF("OK" ZT_EOL_S);
|
||||||
|
|
||||||
|
cert.zero();
|
||||||
|
cert2.zero();
|
||||||
}
|
}
|
||||||
} catch (std::exception &e) {
|
} catch (std::exception &e) {
|
||||||
ZT_T_PRINTF(ZT_EOL_S "[crypto] Unexpected exception: %s" ZT_EOL_S, e.what());
|
ZT_T_PRINTF(ZT_EOL_S "[crypto] Unexpected exception: %s" ZT_EOL_S, e.what());
|
||||||
|
|
|
@ -762,79 +762,6 @@ static ZT_INLINE void zero(void *const dest) noexcept
|
||||||
static ZT_INLINE void zero(void *const dest, const unsigned long len) noexcept
|
static ZT_INLINE void zero(void *const dest, const unsigned long len) noexcept
|
||||||
{ memset(dest, 0, len); }
|
{ memset(dest, 0, len); }
|
||||||
|
|
||||||
/**
|
|
||||||
* Simple malloc/free based C++ STL allocator.
|
|
||||||
*
|
|
||||||
* This is used to make sure our containers don't use weird libc++
|
|
||||||
* allocators but instead use whatever malloc() is, which in turn
|
|
||||||
* can be overridden by things like jemaclloc or tcmalloc.
|
|
||||||
*
|
|
||||||
* @tparam T Allocated type
|
|
||||||
*/
|
|
||||||
template< typename T >
|
|
||||||
struct Mallocator
|
|
||||||
{
|
|
||||||
typedef size_t size_type;
|
|
||||||
typedef ptrdiff_t difference_type;
|
|
||||||
typedef T *pointer;
|
|
||||||
typedef const T *const_pointer;
|
|
||||||
typedef T &reference;
|
|
||||||
typedef const T &const_reference;
|
|
||||||
typedef T value_type;
|
|
||||||
|
|
||||||
template< class U >
|
|
||||||
struct rebind
|
|
||||||
{
|
|
||||||
typedef Mallocator< U > other;
|
|
||||||
};
|
|
||||||
ZT_INLINE Mallocator() noexcept
|
|
||||||
{}
|
|
||||||
|
|
||||||
ZT_INLINE Mallocator(const Mallocator &) noexcept
|
|
||||||
{}
|
|
||||||
|
|
||||||
template< class U >
|
|
||||||
ZT_INLINE Mallocator(const Mallocator< U > &) noexcept
|
|
||||||
{}
|
|
||||||
|
|
||||||
ZT_INLINE ~Mallocator() noexcept
|
|
||||||
{}
|
|
||||||
|
|
||||||
ZT_INLINE pointer allocate(size_type s, void const * = nullptr)
|
|
||||||
{
|
|
||||||
if (0 == s)
|
|
||||||
return nullptr;
|
|
||||||
pointer temp = (pointer)malloc(s * sizeof(T));
|
|
||||||
if (temp == nullptr)
|
|
||||||
throw BadAllocException;
|
|
||||||
return temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
ZT_INLINE pointer address(reference x) const
|
|
||||||
{ return &x; }
|
|
||||||
|
|
||||||
ZT_INLINE const_pointer address(const_reference x) const
|
|
||||||
{ return &x; }
|
|
||||||
|
|
||||||
ZT_INLINE void deallocate(pointer p, size_type)
|
|
||||||
{ free(p); }
|
|
||||||
|
|
||||||
ZT_INLINE size_type max_size() const noexcept
|
|
||||||
{ return std::numeric_limits< size_t >::max() / sizeof(T); }
|
|
||||||
|
|
||||||
ZT_INLINE void construct(pointer p, const T &val)
|
|
||||||
{ new((void *)p) T(val); }
|
|
||||||
|
|
||||||
ZT_INLINE void destroy(pointer p)
|
|
||||||
{ p->~T(); }
|
|
||||||
|
|
||||||
constexpr bool operator==(const Mallocator &) const noexcept
|
|
||||||
{ return true; }
|
|
||||||
|
|
||||||
constexpr bool operator!=(const Mallocator &) const noexcept
|
|
||||||
{ return false; }
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Utils
|
} // namespace Utils
|
||||||
|
|
||||||
} // namespace ZeroTier
|
} // namespace ZeroTier
|
||||||
|
|
Loading…
Add table
Reference in a new issue