Browse Source

More certificate stuff...

Adam Ierymenko 5 years ago
parent
commit
2abf2c5695
6 changed files with 83 additions and 7 deletions
  1. 22 0
      core/Node.cpp
  2. 4 0
      core/Node.hpp
  3. 27 2
      core/Topology.cpp
  4. 20 4
      core/Topology.hpp
  5. 1 0
      core/zerotier.h
  6. 9 1
      pkg/zerotier/node.go

+ 22 - 0
core/Node.cpp

@@ -586,6 +586,16 @@ ZT_CertificateError Node::addCertificate(
 	return RR->topology->addCertificate(tptr, c, now, localTrust, true, true, true);
 	return RR->topology->addCertificate(tptr, c, now, localTrust, true, true, true);
 }
 }
 
 
+ZT_ResultCode Node::deleteCertificate(
+	void *tptr,
+	const void *serialNo)
+{
+	if (!serialNo)
+		return ZT_RESULT_ERROR_BAD_PARAMETER;
+	RR->topology->deleteCertificate(tptr, reinterpret_cast<const uint8_t *>(serialNo));
+	return ZT_RESULT_OK;
+}
+
 struct p_certificateListInternal
 struct p_certificateListInternal
 {
 {
 	Vector< SharedPtr< const Certificate > > c;
 	Vector< SharedPtr< const Certificate > > c;
@@ -1106,6 +1116,18 @@ enum ZT_CertificateError ZT_Node_addCertificate(
 	}
 	}
 }
 }
 
 
+ZT_SDK_API enum ZT_ResultCode ZT_Node_deleteCertificate(
+	ZT_Node *node,
+	void *tptr,
+	const void *serialNo)
+{
+	try {
+		return reinterpret_cast<ZeroTier::Node *>(node)->deleteCertificate(tptr, serialNo);
+	} catch (...) {
+		return ZT_RESULT_ERROR_INTERNAL;
+	}
+}
+
 ZT_SDK_API ZT_CertificateList *ZT_Node_listCertificates(ZT_Node *node)
 ZT_SDK_API ZT_CertificateList *ZT_Node_listCertificates(ZT_Node *node)
 {
 {
 	try {
 	try {

+ 4 - 0
core/Node.hpp

@@ -147,6 +147,10 @@ public:
 		const void *certData,
 		const void *certData,
 		unsigned int certSize);
 		unsigned int certSize);
 
 
+	ZT_ResultCode deleteCertificate(
+		void *tptr,
+		const void *serialNo);
+
 	ZT_CertificateList *listCertificates();
 	ZT_CertificateList *listCertificates();
 
 
 	int sendUserMessage(
 	int sendUserMessage(

+ 27 - 2
core/Topology.cpp

@@ -242,6 +242,32 @@ ZT_CertificateError Topology::addCertificate(void *tPtr, const Certificate &cert
 	return ZT_CERTIFICATE_ERROR_NONE;
 	return ZT_CERTIFICATE_ERROR_NONE;
 }
 }
 
 
+unsigned int Topology::deleteCertificate(void *tPtr,const uint8_t serialNo[ZT_SHA384_DIGEST_SIZE])
+{
+	Mutex::Lock l(m_certs_l);
+	const unsigned long origCertCount = (unsigned long)m_certs.size();
+	Map< SHA384Hash, p_CertEntry >::const_iterator c(m_certs.find(SHA384Hash(serialNo)));
+	if (c != m_certs.end()) {
+		if ((c->second.certificate->subject.uniqueId) && (c->second.certificate->subject.uniqueIdSize > 0)) {
+			SHA384Hash uniqueIdHash;
+			SHA384(uniqueIdHash.data, c->second.certificate->subject.uniqueId, c->second.certificate->subject.uniqueIdSize);
+			m_eraseCertificate(tPtr, c->second.certificate, &uniqueIdHash);
+		} else {
+			m_eraseCertificate(tPtr, c->second.certificate, nullptr);
+		}
+
+		const int64_t now = RR->node->now();
+		m_cleanCertificates(tPtr, now);
+		m_writeTrustStore(tPtr);
+		{
+			RWMutex::Lock l3(m_peers_l);
+			RWMutex::Lock l2(m_roots_l);
+			m_updateRootPeers(tPtr, now);
+		}
+	}
+	return (unsigned int)(origCertCount - (unsigned long)m_certs.size());
+}
+
 void Topology::allCerts(Vector< SharedPtr<const Certificate> > &c,Vector< unsigned int > &t) const noexcept
 void Topology::allCerts(Vector< SharedPtr<const Certificate> > &c,Vector< unsigned int > &t) const noexcept
 {
 {
 	Mutex::Lock l(m_certs_l);
 	Mutex::Lock l(m_certs_l);
@@ -296,8 +322,7 @@ void Topology::m_eraseCertificate(void *tPtr, const SharedPtr< const Certificate
 
 
 	for (unsigned int i = 0; i < cert->subject.identityCount; ++i) {
 	for (unsigned int i = 0; i < cert->subject.identityCount; ++i) {
 		const Identity *const ii = reinterpret_cast<const Identity *>(cert->subject.identities[i].identity);
 		const Identity *const ii = reinterpret_cast<const Identity *>(cert->subject.identities[i].identity);
-		Map< Fingerprint, Map< SharedPtr< const Certificate >, unsigned int > >::iterator
-			bySubjectIdentity(m_certsBySubjectIdentity.find(ii->fingerprint()));
+		Map< Fingerprint, Map< SharedPtr< const Certificate >, unsigned int > >::iterator bySubjectIdentity(m_certsBySubjectIdentity.find(ii->fingerprint()));
 		if (bySubjectIdentity != m_certsBySubjectIdentity.end()) {
 		if (bySubjectIdentity != m_certsBySubjectIdentity.end()) {
 			bySubjectIdentity->second.erase(cert);
 			bySubjectIdentity->second.erase(cert);
 			if (bySubjectIdentity->second.empty())
 			if (bySubjectIdentity->second.empty())

+ 20 - 4
core/Topology.hpp

@@ -140,7 +140,23 @@ public:
 	 * @param verify If true, verify certificate and certificate chain (default: true)
 	 * @param verify If true, verify certificate and certificate chain (default: true)
 	 * @return Error or 0 on success
 	 * @return Error or 0 on success
 	 */
 	 */
-	ZT_CertificateError addCertificate(void *tPtr, const Certificate &cert, const int64_t now, unsigned int localTrust, bool writeToLocalStore, bool refreshRootSets = true, bool verify = true);
+	ZT_CertificateError addCertificate(
+		void *tPtr,
+		const Certificate &cert,
+		int64_t now,
+		unsigned int localTrust,
+		bool writeToLocalStore,
+		bool refreshRootSets = true,
+		bool verify = true);
+
+	/**
+	 * Delete certificate
+	 *
+	 * @param tPtr Thread pointer
+	 * @param serialNo Serial number to delete
+	 * @return Number of deleted certificates
+	 */
+	unsigned int deleteCertificate(void *tPtr,const uint8_t serialNo[ZT_SHA384_DIGEST_SIZE]);
 
 
 	/**
 	/**
 	 * Fill vectors with all certificates and their corresponding local trust flags
 	 * Fill vectors with all certificates and their corresponding local trust flags
@@ -154,11 +170,11 @@ private:
 	void m_rankRoots(int64_t now);
 	void m_rankRoots(int64_t now);
 	void m_eraseCertificate(void *tPtr, const SharedPtr< const Certificate > &cert, const SHA384Hash *uniqueIdHash);
 	void m_eraseCertificate(void *tPtr, const SharedPtr< const Certificate > &cert, const SHA384Hash *uniqueIdHash);
 	bool m_cleanCertificates(void *tPtr, int64_t now);
 	bool m_cleanCertificates(void *tPtr, int64_t now);
-	bool m_verifyCertificateChain(const Certificate *current, const int64_t now) const;
-	ZT_CertificateError m_verifyCertificate(const Certificate &cert, const int64_t now, unsigned int localTrust, bool skipSignatureCheck) const;
+	bool m_verifyCertificateChain(const Certificate *current, int64_t now) const;
+	ZT_CertificateError m_verifyCertificate(const Certificate &cert, int64_t now, unsigned int localTrust, bool skipSignatureCheck) const;
 	void m_loadCached(void *tPtr, const Address &zta, SharedPtr< Peer > &peer);
 	void m_loadCached(void *tPtr, const Address &zta, SharedPtr< Peer > &peer);
 	SharedPtr< Peer > m_peerFromCached(void *tPtr, const Address &zta);
 	SharedPtr< Peer > m_peerFromCached(void *tPtr, const Address &zta);
-	SharedPtr< Path > m_newPath(const int64_t l, const InetAddress &r, const UniqueID &k);
+	SharedPtr< Path > m_newPath(int64_t l, const InetAddress &r, const UniqueID &k);
 	void m_updateRootPeers(void *tPtr, int64_t now);
 	void m_updateRootPeers(void *tPtr, int64_t now);
 	void m_writeTrustStore(void *tPtr);
 	void m_writeTrustStore(void *tPtr);
 
 

+ 1 - 0
core/zerotier.h

@@ -2407,6 +2407,7 @@ ZT_SDK_API int ZT_Node_tryPeer(
  *
  *
  * @param node Node instance
  * @param node Node instance
  * @param tptr Thread pointer to pass to functions/callbacks resulting from this call
  * @param tptr Thread pointer to pass to functions/callbacks resulting from this call
+ * @param now Current time
  * @param localTrust Local trust flags (ORed together)
  * @param localTrust Local trust flags (ORed together)
  * @param cert Certificate object, or set to NULL if certData and certSize are to be used
  * @param cert Certificate object, or set to NULL if certData and certSize are to be used
  * @param certData Certificate binary data if 'cert' is NULL, NULL otherwise
  * @param certData Certificate binary data if 'cert' is NULL, NULL otherwise

+ 9 - 1
pkg/zerotier/node.go

@@ -535,11 +535,19 @@ func (n *Node) ListCertificates() (certs []LocalCertificate, err error) {
 }
 }
 
 
 // AddCertificate adds a certificate to this node's local certificate store (after verification).
 // AddCertificate adds a certificate to this node's local certificate store (after verification).
-func (n *Node) AddCertificate(cert *Certificate) error {
+func (n *Node) AddCertificate(cert *Certificate, localTrust uint) error {
+	ccert := cert.cCertificate()
+	defer deleteCCertificate(ccert)
+	return certificateErrorToError(int(C.ZT_Node_addCertificate(n.zn, nil, C.int64_t(TimeMs()), C.uint(localTrust), (*C.ZT_Certificate)(ccert), nil, 0)))
 }
 }
 
 
 // DeleteCertificate deletes a certificate from this node's local certificate store.
 // DeleteCertificate deletes a certificate from this node's local certificate store.
 func (n *Node) DeleteCertificate(serialNo []byte) error {
 func (n *Node) DeleteCertificate(serialNo []byte) error {
+	if len(serialNo) != CertificateSerialNoSize {
+		return ErrInvalidParameter
+	}
+	C.ZT_Node_deleteCertificate(n.zn, nil, unsafe.Pointer(&serialNo[0]))
+	return nil
 }
 }
 
 
 // -------------------------------------------------------------------------------------------------------------------
 // -------------------------------------------------------------------------------------------------------------------