Browse Source

Certificate stuff, but not plumbled through to CLI yet to actually make them.

Adam Ierymenko 5 years ago
parent
commit
5e1b7f2ba6
11 changed files with 76 additions and 60 deletions
  1. 3 0
      core/Blob.hpp
  2. 2 0
      core/CMakeLists.txt
  3. 0 1
      core/Certificate.cpp
  4. 5 0
      core/Certificate.hpp
  5. 17 0
      core/Defaults.cpp
  6. 21 0
      core/Defaults.hpp
  7. 3 0
      core/SharedPtr.hpp
  8. 1 2
      core/Topology.cpp
  9. 1 1
      core/Topology.hpp
  10. 4 39
      core/Utils.hpp
  11. 19 17
      pkg/zerotier/node.go

+ 3 - 0
core/Blob.hpp

@@ -32,6 +32,9 @@ struct Blob
 	ZT_INLINE Blob() noexcept { Utils::zero<S>(data); }
 	ZT_INLINE Blob() noexcept { Utils::zero<S>(data); }
 	explicit ZT_INLINE Blob(const void *const d) noexcept { Utils::copy<S>(data,d); }
 	explicit ZT_INLINE Blob(const void *const d) noexcept { Utils::copy<S>(data,d); }
 
 
+	ZT_INLINE unsigned long hashCode() const noexcept
+	{ return (unsigned long)Utils::fnv1a32(data, S); }
+
 	ZT_INLINE operator bool() const noexcept { return !Utils::allZero(data); }
 	ZT_INLINE operator bool() const noexcept { return !Utils::allZero(data); }
 
 
 	ZT_INLINE bool operator==(const Blob &b) const noexcept { return (memcmp(data,b.data,S) == 0); }
 	ZT_INLINE bool operator==(const Blob &b) const noexcept { return (memcmp(data,b.data,S) == 0); }

+ 2 - 0
core/CMakeLists.txt

@@ -14,6 +14,7 @@ set(core_headers
 	C25519.hpp
 	C25519.hpp
 	CapabilityCredential.hpp
 	CapabilityCredential.hpp
 	Certificate.hpp
 	Certificate.hpp
+	Defaults.hpp
 	MembershipCredential.hpp
 	MembershipCredential.hpp
 	OwnershipCredential.hpp
 	OwnershipCredential.hpp
 	Constants.hpp
 	Constants.hpp
@@ -64,6 +65,7 @@ set(core_src
 	C25519.cpp
 	C25519.cpp
 	CapabilityCredential.cpp
 	CapabilityCredential.cpp
 	Certificate.cpp
 	Certificate.cpp
+	Defaults.cpp
 	MembershipCredential.cpp
 	MembershipCredential.cpp
 	OwnershipCredential.cpp
 	OwnershipCredential.cpp
 	Credential.cpp
 	Credential.cpp

+ 0 - 1
core/Certificate.cpp

@@ -152,7 +152,6 @@ void Certificate::addUpdateUrl(const char *url)
 
 
 Vector< uint8_t > Certificate::encode(const bool omitSignature) const
 Vector< uint8_t > Certificate::encode(const bool omitSignature) const
 {
 {
-	char tmp[256];
 	Vector< uint8_t > enc;
 	Vector< uint8_t > enc;
 	Dictionary d;
 	Dictionary d;
 
 

+ 5 - 0
core/Certificate.hpp

@@ -47,6 +47,9 @@ namespace ZeroTier {
  */
  */
 class Certificate : public ZT_Certificate
 class Certificate : public ZT_Certificate
 {
 {
+	friend class SharedPtr< Certificate >;
+	friend class SharedPtr< const Certificate >;
+
 public:
 public:
 	ZT_INLINE Certificate() noexcept
 	ZT_INLINE Certificate() noexcept
 	{ this->clear(); }
 	{ this->clear(); }
@@ -174,6 +177,8 @@ private:
 	Vector< ZT_Certificate_Network > m_subjectNetworks;
 	Vector< ZT_Certificate_Network > m_subjectNetworks;
 	Vector< const uint8_t * > m_subjectCertificates;
 	Vector< const uint8_t * > m_subjectCertificates;
 	Vector< const char * > m_updateUrls;
 	Vector< const char * > m_updateUrls;
+
+	std::atomic<int> __refCount;
 };
 };
 
 
 } // namespace ZeroTier
 } // namespace ZeroTier

+ 17 - 0
core/Defaults.cpp

@@ -0,0 +1,17 @@
+/*
+ * Copyright (c)2013-2020 ZeroTier, Inc.
+ *
+ * Use of this software is governed by the Business Source License included
+ * in the LICENSE.TXT file in the project's root directory.
+ *
+ * Change Date: 2024-01-01
+ *
+ * On the date above, in accordance with the Business Source License, use
+ * of this software will be governed by version 2.0 of the Apache License.
+ */
+/****/
+
+#include "Defaults.hpp"
+
+namespace ZeroTier {
+} // namespace ZeroTier

+ 21 - 0
core/Defaults.hpp

@@ -0,0 +1,21 @@
+/*
+ * Copyright (c)2013-2020 ZeroTier, Inc.
+ *
+ * Use of this software is governed by the Business Source License included
+ * in the LICENSE.TXT file in the project's root directory.
+ *
+ * Change Date: 2024-01-01
+ *
+ * On the date above, in accordance with the Business Source License, use
+ * of this software will be governed by version 2.0 of the Apache License.
+ */
+/****/
+
+#ifndef ZT_DEFAULTS_HPP
+#define ZT_DEFAULTS_HPP
+
+namespace ZeroTier {
+
+} // namespace ZeroTier
+
+#endif

+ 3 - 0
core/SharedPtr.hpp

@@ -177,6 +177,9 @@ public:
 		return 0;
 		return 0;
 	}
 	}
 
 
+	ZT_INLINE unsigned long hashCode() const noexcept
+	{ return (unsigned long)Utils::hash64((uint64_t)((uintptr_t)m_ptr)); }
+
 	ZT_INLINE bool operator==(const SharedPtr &sp) const noexcept
 	ZT_INLINE bool operator==(const SharedPtr &sp) const noexcept
 	{ return (m_ptr == sp.m_ptr); }
 	{ return (m_ptr == sp.m_ptr); }
 
 

+ 1 - 2
core/Topology.cpp

@@ -431,8 +431,7 @@ void Topology::m_updateRootPeers_l_roots_certs(void *tPtr)
 
 
 	// Populate m_roots from certificate subject identities from certificates flagged
 	// Populate m_roots from certificate subject identities from certificates flagged
 	// as local root set certificates.
 	// as local root set certificates.
-	for (Map< FCV< uint8_t, ZT_CERTIFICATE_MAX_UNIQUE_ID_SIZE >, std::pair< SharedPtr< const Certificate >, unsigned int > >::const_iterator c(m_certsBySubjectUniqueId.begin()); c != m_certsBySubjectUniqueId.end();
-	     ++c) {
+	for (SortedMap< FCV< uint8_t, ZT_CERTIFICATE_MAX_UNIQUE_ID_SIZE >, std::pair< SharedPtr< const Certificate >, unsigned int > >::const_iterator c(m_certsBySubjectUniqueId.begin()); c != m_certsBySubjectUniqueId.end(); ++c) {
 		if ((c->second.second & ZT_CERTIFICATE_LOCAL_TRUST_FLAG_ZEROTIER_ROOT_SET) != 0) {
 		if ((c->second.second & ZT_CERTIFICATE_LOCAL_TRUST_FLAG_ZEROTIER_ROOT_SET) != 0) {
 			for (unsigned int i = 0; i < c->second.first->subject.identityCount; ++i)
 			for (unsigned int i = 0; i < c->second.first->subject.identityCount; ++i)
 				m_roots[*reinterpret_cast<const Identity *>(c->second.first->subject.identities[i].identity)].insert(c->second.first);
 				m_roots[*reinterpret_cast<const Identity *>(c->second.first->subject.identities[i].identity)].insert(c->second.first);

+ 1 - 1
core/Topology.hpp

@@ -273,7 +273,7 @@ private:
 
 
 	Map< SHA384Hash, std::pair< SharedPtr< const Certificate >, unsigned int > > m_certs;
 	Map< SHA384Hash, std::pair< SharedPtr< const Certificate >, unsigned int > > m_certs;
 	Map< Fingerprint, Map< SharedPtr< const Certificate >, unsigned int > > m_certsBySubjectIdentity;
 	Map< Fingerprint, Map< SharedPtr< const Certificate >, unsigned int > > m_certsBySubjectIdentity;
-	Map< FCV< uint8_t, ZT_CERTIFICATE_MAX_UNIQUE_ID_SIZE >, std::pair< SharedPtr< const Certificate >, unsigned int > > m_certsBySubjectUniqueId;
+	SortedMap< FCV< uint8_t, ZT_CERTIFICATE_MAX_UNIQUE_ID_SIZE >, std::pair< SharedPtr< const Certificate >, unsigned int > > m_certsBySubjectUniqueId;
 };
 };
 
 
 } // namespace ZeroTier
 } // namespace ZeroTier

+ 4 - 39
core/Utils.hpp

@@ -55,9 +55,11 @@ namespace Utils {
 #define ZT_ROL32(x, r) (((x) << (r)) | ((x) >> (32 - (r))))
 #define ZT_ROL32(x, r) (((x) << (r)) | ((x) >> (32 - (r))))
 
 
 #ifdef ZT_ARCH_X64
 #ifdef ZT_ARCH_X64
+
 struct CPUIDRegisters
 struct CPUIDRegisters
 {
 {
 	CPUIDRegisters() noexcept;
 	CPUIDRegisters() noexcept;
+
 	bool rdrand;
 	bool rdrand;
 	bool aes;
 	bool aes;
 	bool avx;
 	bool avx;
@@ -68,6 +70,7 @@ struct CPUIDRegisters
 	bool sha;
 	bool sha;
 	bool fsrm;
 	bool fsrm;
 };
 };
+
 extern const CPUIDRegisters CPUID;
 extern const CPUIDRegisters CPUID;
 #endif
 #endif
 
 
@@ -772,45 +775,7 @@ static ZT_INLINE void copy(void *const dest, const void *const src, unsigned int
  */
  */
 template< unsigned int L >
 template< unsigned int L >
 static ZT_INLINE void zero(void *const dest) noexcept
 static ZT_INLINE void zero(void *const dest) noexcept
-{
-#ifdef ZT_ARCH_X64
-	uint8_t *volatile d = reinterpret_cast<uint8_t *>(dest);
-	__m128i z = _mm_setzero_si128();
-	for (unsigned int i = 0; i < (L >> 6U); ++i) {
-		_mm_storeu_si128(reinterpret_cast<__m128i *>(d), z);
-		_mm_storeu_si128(reinterpret_cast<__m128i *>(d + 16), z);
-		_mm_storeu_si128(reinterpret_cast<__m128i *>(d + 32), z);
-		_mm_storeu_si128(reinterpret_cast<__m128i *>(d + 48), z);
-		d += 64;
-	}
-	if ((L & 32U) != 0) {
-		_mm_storeu_si128(reinterpret_cast<__m128i *>(d), z);
-		_mm_storeu_si128(reinterpret_cast<__m128i *>(d + 16), z);
-		d += 32;
-	}
-	if ((L & 16U) != 0) {
-		_mm_storeu_si128(reinterpret_cast<__m128i *>(d), z);
-		d += 16;
-	}
-	if ((L & 8U) != 0) {
-		*reinterpret_cast<volatile uint64_t *>(d) = 0;
-		d += 8;
-	}
-	if ((L & 4U) != 0) {
-		*reinterpret_cast<volatile uint32_t *>(d) = 0;
-		d += 4;
-	}
-	if ((L & 2U) != 0) {
-		*reinterpret_cast<volatile uint16_t *>(d) = 0;
-		d += 2;
-	}
-	if ((L & 1U) != 0) {
-		*d = 0;
-	}
-#else
-	memset(dest,0,L);
-#endif
-}
+{ memset(dest, 0, L); }
 
 
 /**
 /**
  * Zero memory block whose size is known at run time
  * Zero memory block whose size is known at run time

+ 19 - 17
pkg/zerotier/node.go

@@ -724,7 +724,7 @@ func (n *Node) pathLookup(id *Identity) (net.IP, int) {
 	return nil, 0
 	return nil, 0
 }
 }
 
 
-func (n *Node) makeStateObjectPath(objType int, id [2]uint64) (string, bool) {
+func (n *Node) makeStateObjectPath(objType int, id []uint64) (string, bool) {
 	var fp string
 	var fp string
 	secret := false
 	secret := false
 	switch objType {
 	switch objType {
@@ -744,13 +744,17 @@ func (n *Node) makeStateObjectPath(objType int, id [2]uint64) (string, bool) {
 		fp = path.Join(n.basePath, "networks.d")
 		fp = path.Join(n.basePath, "networks.d")
 		_ = os.Mkdir(fp, 0755)
 		_ = os.Mkdir(fp, 0755)
 		fp = path.Join(fp, fmt.Sprintf("%.16x.conf", id[0]))
 		fp = path.Join(fp, fmt.Sprintf("%.16x.conf", id[0]))
-	case C.ZT_STATE_OBJECT_ROOTS:
-		fp = path.Join(n.basePath, "roots")
+	case C.ZT_STATE_OBJECT_TRUST_STORE:
+		fp = path.Join(n.basePath, "truststore")
+	case C.ZT_STATE_OBJECT_CERT:
+		fp = path.Join(n.basePath, "certs.d")
+		_ = os.Mkdir(fp, 0755)
+		fp = path.Join(fp, Base32StdLowerCase.EncodeToString((*[48]byte)(unsafe.Pointer(&id[0]))[:]))
 	}
 	}
 	return fp, secret
 	return fp, secret
 }
 }
 
 
-func (n *Node) stateObjectPut(objType int, id [2]uint64, data []byte) {
+func (n *Node) stateObjectPut(objType int, id []uint64, data []byte) {
 	fp, secret := n.makeStateObjectPath(objType, id)
 	fp, secret := n.makeStateObjectPath(objType, id)
 	if len(fp) > 0 {
 	if len(fp) > 0 {
 		fileMode := os.FileMode(0644)
 		fileMode := os.FileMode(0644)
@@ -764,14 +768,14 @@ func (n *Node) stateObjectPut(objType int, id [2]uint64, data []byte) {
 	}
 	}
 }
 }
 
 
-func (n *Node) stateObjectDelete(objType int, id [2]uint64) {
+func (n *Node) stateObjectDelete(objType int, id []uint64) {
 	fp, _ := n.makeStateObjectPath(objType, id)
 	fp, _ := n.makeStateObjectPath(objType, id)
 	if len(fp) > 0 {
 	if len(fp) > 0 {
 		_ = os.Remove(fp)
 		_ = os.Remove(fp)
 	}
 	}
 }
 }
 
 
-func (n *Node) stateObjectGet(objType int, id [2]uint64) ([]byte, bool) {
+func (n *Node) stateObjectGet(objType int, id []uint64) ([]byte, bool) {
 	fp, _ := n.makeStateObjectPath(objType, id)
 	fp, _ := n.makeStateObjectPath(objType, id)
 	if len(fp) > 0 {
 	if len(fp) > 0 {
 		fd, err := ioutil.ReadFile(fp)
 		fd, err := ioutil.ReadFile(fp)
@@ -854,21 +858,19 @@ func goStateObjectPutFunc(gn unsafe.Pointer, objType C.int, id, data unsafe.Poin
 		return
 		return
 	}
 	}
 
 
-	id2 := *((*[2]uint64)(id))
+	// NOTE: this is unsafe and depends on node.stateObjectDelete() and node.stateObjectPut()
+	// not accessing beyond the expected number of elements in the id.
+	id2 := (*[6]uint64)(id)
 	var data2 []byte
 	var data2 []byte
 	if len > 0 {
 	if len > 0 {
 		data2 = C.GoBytes(data, len)
 		data2 = C.GoBytes(data, len)
 	}
 	}
 
 
-	node.runWaitGroup.Add(1)
-	go func() {
-		if len < 0 {
-			node.stateObjectDelete(int(objType), id2)
-		} else {
-			node.stateObjectPut(int(objType), id2, data2)
-		}
-		node.runWaitGroup.Done()
-	}()
+	if len < 0 {
+		node.stateObjectDelete(int(objType), id2[:])
+	} else {
+		node.stateObjectPut(int(objType), id2[:], data2)
+	}
 }
 }
 
 
 //export goStateObjectGetFunc
 //export goStateObjectGetFunc
@@ -879,7 +881,7 @@ func goStateObjectGetFunc(gn unsafe.Pointer, objType C.int, id, dataP unsafe.Poi
 	}
 	}
 
 
 	*((*uintptr)(dataP)) = 0
 	*((*uintptr)(dataP)) = 0
-	tmp, found := node.stateObjectGet(int(objType), *((*[2]uint64)(id)))
+	tmp, found := node.stateObjectGet(int(objType), ((*[6]uint64)(id))[:])
 	if found && len(tmp) > 0 {
 	if found && len(tmp) > 0 {
 		cData := C.ZT_malloc(C.ulong(len(tmp))) // GoGlue sends free() to the core as the free function
 		cData := C.ZT_malloc(C.ulong(len(tmp))) // GoGlue sends free() to the core as the free function
 		if uintptr(cData) == 0 {
 		if uintptr(cData) == 0 {