From 8d2a0f764bae6fd6d9620ad2b500c7a00a5471ab Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Tue, 16 Jun 2020 11:51:41 -0700 Subject: [PATCH] Some minor reorg. --- cmd/zerotier/cli/help.go | 4 ++-- core/Dictionary.cpp | 13 +++++++++++ core/Dictionary.hpp | 13 +---------- core/IdentificationCertificate.cpp | 31 ++++++++++++++++++++++++- core/IdentificationCertificate.hpp | 30 ++++++++++++++++++------ core/Utils.hpp | 4 +--- core/zerotier.h | 37 +++++++++++++++++++++--------- 7 files changed, 96 insertions(+), 36 deletions(-) diff --git a/cmd/zerotier/cli/help.go b/cmd/zerotier/cli/help.go index a217c8952..403923fd1 100644 --- a/cmd/zerotier/cli/help.go +++ b/cmd/zerotier/cli/help.go @@ -57,8 +57,8 @@ Commands: locator Explicitly update peer locator roots List root peers root [command] - Root management commands - add [endpoint] Add a root or a root set - remove
Remove a root or root set + add [endpoint] Add a root or a set of roots + remove
Remove a root or set of roots set [option] [value] - Get or set a core config option port Primary P2P port secondaryport Secondary P2P port (0 to disable) diff --git a/core/Dictionary.cpp b/core/Dictionary.cpp index 2240d061d..2854a84aa 100644 --- a/core/Dictionary.cpp +++ b/core/Dictionary.cpp @@ -199,4 +199,17 @@ bool Dictionary::decode(const void *data, unsigned int len) return true; } +char *Dictionary::arraySubscript(char buf[256],const char *name,const unsigned long sub) noexcept +{ + for(unsigned int i=0;i<(256 - 17);++i) { + if ((buf[i] = name[i]) == 0) { + buf[i++] = '#'; + Utils::hex(sub, buf + i); + return buf; + } + } + buf[0] = 0; + return buf; +} + } // namespace ZeroTier diff --git a/core/Dictionary.hpp b/core/Dictionary.hpp index 2ec2ce15d..d0c836d90 100644 --- a/core/Dictionary.hpp +++ b/core/Dictionary.hpp @@ -370,18 +370,7 @@ public: return mlen; } - static ZT_INLINE char *arraySubscript(char buf[256],const char *name,const unsigned long sub) noexcept - { - for(unsigned int i=0;i<(256 - 17);++i) { - if ((buf[i] = name[i]) == 0) { - buf[i++] = '#'; - Utils::hex(sub, buf + i); - return buf; - } - } - buf[0] = 0; - return buf; - } + static char *arraySubscript(char buf[256],const char *name,const unsigned long sub) noexcept; private: template< typename V > diff --git a/core/IdentificationCertificate.cpp b/core/IdentificationCertificate.cpp index 10ee1985e..55f714560 100644 --- a/core/IdentificationCertificate.cpp +++ b/core/IdentificationCertificate.cpp @@ -21,8 +21,10 @@ void IdentificationCertificate::clear() Utils::zero< sizeof(ZT_IdentificationCertificate) >((ZT_IdentificationCertificate *)this); m_identities.clear(); m_locators.clear(); + m_strings.clear(); m_nodes.clear(); m_networks.clear(); + m_updateUrls.clear(); } IdentificationCertificate &IdentificationCertificate::operator=(const ZT_IdentificationCertificate &apiCert) @@ -54,6 +56,11 @@ IdentificationCertificate &IdentificationCertificate::operator=(const Identifica for (unsigned int i = 0; i < cert.subject.networkCount; ++i) addSubjectNetwork(cert.subject.networks[i].id, cert.subject.networks[i].controller); + if (cert.updateUrls) { + for (unsigned int i = 0; i < cert.updateUrlCount; ++i) + addUpdateUrl(cert.updateUrls[i]); + } + return *this; } @@ -84,6 +91,14 @@ ZT_IdentificationCertificate_Network *IdentificationCertificate::addSubjectNetwo return &(m_networks.back()); } +void IdentificationCertificate::addUpdateUrl(const char *url) +{ + m_strings.push_back(url); + m_updateUrls.push_back(m_strings.back().c_str()); + this->updateUrls = m_updateUrls.data(); + this->updateUrlCount = (unsigned int)m_updateUrls.size(); +} + Vector< uint8_t > IdentificationCertificate::encode(const bool omitSignature) const { char tmp[256]; @@ -137,6 +152,12 @@ Vector< uint8_t > IdentificationCertificate::encode(const bool omitSignature) co d.add("iN.e", this->issuerName.email); d.add("iN.ur", this->issuerName.url); + d.add("uU[]", (uint64_t)this->updateUrlCount); + if (this->updateUrls) { + for (unsigned int i = 0; i < this->updateUrlCount; ++i) + d.add(Dictionary::arraySubscript(tmp, "uU[]", i), this->updateUrls[i]); + } + if ((!omitSignature) && (this->signatureSize > 0) && (this->signatureSize <= sizeof(this->signature))) d["si"].assign(this->signature, this->signature + this->signatureSize); @@ -146,7 +167,7 @@ Vector< uint8_t > IdentificationCertificate::encode(const bool omitSignature) co bool IdentificationCertificate::decode(const Vector< uint8_t > &data) { - char tmp[256]; + char tmp[256], tmp2[ZT_IDENTIFICATION_CERTIFICATE_MAX_STRING_LENGTH + 1]; clear(); @@ -226,6 +247,14 @@ bool IdentificationCertificate::decode(const Vector< uint8_t > &data) d.getS("iN.e", this->issuerName.email, sizeof(this->issuerName.email)); d.getS("iN.ur", this->issuerName.url, sizeof(this->issuerName.url)); + cnt = (unsigned int)d.getUI("uU[]"); + for (unsigned int i = 0; i < cnt; ++i) { + const char *const url = d.getS(Dictionary::arraySubscript(tmp, "uU[]", i), tmp2, sizeof(tmp2)); + if (url) + addUpdateUrl(tmp2); + else return false; + } + const Vector< uint8_t > &sig = d["si"]; if (sig.size() > sizeof(this->signature)) return false; diff --git a/core/IdentificationCertificate.hpp b/core/IdentificationCertificate.hpp index 0ea0e9f24..17060d74b 100644 --- a/core/IdentificationCertificate.hpp +++ b/core/IdentificationCertificate.hpp @@ -62,6 +62,7 @@ public: void clear(); IdentificationCertificate &operator=(const ZT_IdentificationCertificate &apiCert); + IdentificationCertificate &operator=(const IdentificationCertificate &cert); /** @@ -90,6 +91,13 @@ public: */ ZT_IdentificationCertificate_Network *addSubjectNetwork(const uint64_t id, const ZT_Fingerprint &controller); + /** + * Add an update URL to the updateUrls list + * + * @param url Update URL + */ + void addUpdateUrl(const char *url); + /** * Marshal this certificate in binary form * @@ -124,20 +132,26 @@ public: */ bool verify() const; - ZT_INLINE unsigned long hashCode() const noexcept { return (unsigned long)Utils::loadAsIsEndian(this->serialNo); } + ZT_INLINE unsigned long hashCode() const noexcept + { return (unsigned long)Utils::loadAsIsEndian< uint32_t >(this->serialNo); } ZT_INLINE bool operator==(const ZT_IdentificationCertificate &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_IdentificationCertificate &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_IdentificationCertificate &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_IdentificationCertificate &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_IdentificationCertificate &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_IdentificationCertificate &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: // These hold any identity or locator objects that are owned by and should @@ -145,10 +159,12 @@ private: // change. List< Identity > m_identities; List< Locator > m_locators; + List< String > m_strings; // These are stored in a vector because the memory needs to be contiguous. Vector< ZT_IdentificationCertificate_Node > m_nodes; Vector< ZT_IdentificationCertificate_Network > m_networks; + Vector< const char * > m_updateUrls; }; } // namespace ZeroTier diff --git a/core/Utils.hpp b/core/Utils.hpp index 9da4e4729..6d7b3078e 100644 --- a/core/Utils.hpp +++ b/core/Utils.hpp @@ -319,9 +319,7 @@ static ZT_INLINE char *stok(char *str, const char *delim, char **saveptr) noexce } static ZT_INLINE unsigned int strToUInt(const char *s) noexcept -{ - return (unsigned int)strtoul(s, nullptr, 10); -} +{ return (unsigned int)strtoul(s, nullptr, 10); } static ZT_INLINE unsigned long long hexStrToU64(const char *s) noexcept { diff --git a/core/zerotier.h b/core/zerotier.h index 66275b093..e6e189697 100644 --- a/core/zerotier.h +++ b/core/zerotier.h @@ -302,6 +302,11 @@ typedef struct */ #define ZT_IDENTIFICATION_CERTIFICATE_MAX_SIGNATURE_SIZE 256 +/** + * Flag indicating that the nodes in the subject are a set of roots + */ +#define ZT_IDENTIFICATION_CERTIFICATE_FLAG_ROOT_SET 0x0000000000000001ULL + /** * Information about a real world entity. */ @@ -362,16 +367,16 @@ typedef struct */ ZT_IdentificationCertificate_Node *nodes; - /** - * Number of nodes - */ - unsigned int nodeCount; - /** * Networks owned by this entity */ ZT_IdentificationCertificate_Network *networks; + /** + * Number of nodes + */ + unsigned int nodeCount; + /** * Number of networks */ @@ -413,15 +418,15 @@ typedef struct unsigned int maxPathLength; /** - * Flags (for future use, currently zero). - * - * This could be used to implement key usage flags similar to X509 if - * these are needed. + * Flags indicating certificate usage and any other attributes. */ uint64_t flags; /** * Valid time range: not before, not after. + * + * In ZeroTier the not before field is also the certificate issued time + * and timestamp. */ int64_t validity[2]; @@ -441,14 +446,24 @@ typedef struct ZT_IdentificationCertificate_Name issuerName; /** - * Signature by issuer (algorithm determined by identity type). + * URLs that can be consulted for updates to this certificate. */ - uint8_t signature[ZT_IDENTIFICATION_CERTIFICATE_MAX_SIGNATURE_SIZE]; + const char *const *updateUrls; + + /** + * Number of update URLs + */ + unsigned int updateUrlCount; /** * Size of signature in bytes. */ unsigned int signatureSize; + + /** + * Signature by issuer (algorithm determined by identity type). + */ + uint8_t signature[ZT_IDENTIFICATION_CERTIFICATE_MAX_SIGNATURE_SIZE]; } ZT_IdentificationCertificate; /**