Browse Source

CGO glue for certificates, and Go formatting and other boring stuff.

Adam Ierymenko 5 years ago
parent
commit
0d764f5a3d

+ 1 - 1
cmd/zerotier/cli/help.go

@@ -81,7 +81,7 @@ Commands:
     verify <identity> <file> <sig>       Verify a signature
     verify <identity> <file> <sig>       Verify a signature
   certificate <command> [args]         - Certificate commands
   certificate <command> [args]         - Certificate commands
     newid                                Create a new unique subject ID
     newid                                Create a new unique subject ID
-    newcsr <settings path>               Create a new CSR (signing request)
+    newcsr <subject json path>           Create a new CSR (signing request)
     sign <csr path> <identity path>      Sign a CSR to create a certificate
     sign <csr path> <identity path>      Sign a CSR to create a certificate
     verify <certificate>                 Verify a certificate
     verify <certificate>                 Verify a certificate
     show                                 List certificate for current node
     show                                 List certificate for current node

+ 17 - 17
core/Certificate.cpp

@@ -50,8 +50,8 @@ Certificate &Certificate::operator=(const ZT_Certificate &cert)
 	this->subject.networkCount = 0;
 	this->subject.networkCount = 0;
 	this->subject.certificates = nullptr;
 	this->subject.certificates = nullptr;
 	this->subject.certificateCount = 0;
 	this->subject.certificateCount = 0;
-	this->subject.updateUrls = nullptr;
-	this->subject.updateUrlCount = 0;
+	this->subject.updateURLs = nullptr;
+	this->subject.updateURLCount = 0;
 	this->subject.uniqueId = nullptr;
 	this->subject.uniqueId = nullptr;
 	this->subject.uniqueIdProofSignature = nullptr;
 	this->subject.uniqueIdProofSignature = nullptr;
 	this->subject.uniqueIdSize = 0;
 	this->subject.uniqueIdSize = 0;
@@ -80,10 +80,10 @@ Certificate &Certificate::operator=(const ZT_Certificate &cert)
 			addSubjectCertificate(cert.subject.certificates[i]);
 			addSubjectCertificate(cert.subject.certificates[i]);
 	}
 	}
 
 
-	if (cert.subject.updateUrls) {
-		for (unsigned int i = 0; i < cert.subject.updateUrlCount; ++i) {
-			if (cert.subject.updateUrls[i])
-				addSubjectUpdateUrl(cert.subject.updateUrls[i]);
+	if (cert.subject.updateURLs) {
+		for (unsigned int i = 0; i < cert.subject.updateURLCount; ++i) {
+			if (cert.subject.updateURLs[i])
+				addSubjectUpdateUrl(cert.subject.updateURLs[i]);
 		}
 		}
 	}
 	}
 
 
@@ -181,8 +181,8 @@ void Certificate::addSubjectUpdateUrl(const char *url)
 	// Add pointer to local copy to pointer array and update C structure to point to
 	// Add pointer to local copy to pointer array and update C structure to point to
 	// potentially reallocated array.
 	// potentially reallocated array.
 	m_updateUrls.push_back(m_strings.back().c_str());
 	m_updateUrls.push_back(m_strings.back().c_str());
-	this->subject.updateUrls = m_updateUrls.data();
-	this->subject.updateUrlCount = (unsigned int)m_updateUrls.size();
+	this->subject.updateURLs = m_updateUrls.data();
+	this->subject.updateURLCount = (unsigned int)m_updateUrls.size();
 }
 }
 
 
 void Certificate::setExtendedAttributes(const Dictionary &x)
 void Certificate::setExtendedAttributes(const Dictionary &x)
@@ -456,14 +456,14 @@ ZT_CertificateError Certificate::verify() const
 				return ZT_CERTIFICATE_ERROR_MISSING_REQUIRED_FIELDS;
 				return ZT_CERTIFICATE_ERROR_MISSING_REQUIRED_FIELDS;
 		}
 		}
 
 
-		if (this->subject.updateUrlCount) {
-			if (!this->subject.updateUrls)
+		if (this->subject.updateURLCount) {
+			if (!this->subject.updateURLs)
 				return ZT_CERTIFICATE_ERROR_INVALID_FORMAT;
 				return ZT_CERTIFICATE_ERROR_INVALID_FORMAT;
-			for (unsigned int i = 0; i < this->subject.updateUrlCount; ++i) {
-				if (!this->subject.updateUrls[i])
+			for (unsigned int i = 0; i < this->subject.updateURLCount; ++i) {
+				if (!this->subject.updateURLs[i])
 					return ZT_CERTIFICATE_ERROR_MISSING_REQUIRED_FIELDS;
 					return ZT_CERTIFICATE_ERROR_MISSING_REQUIRED_FIELDS;
 			}
 			}
-		} else if (this->subject.updateUrls) {
+		} else if (this->subject.updateURLs) {
 			return ZT_CERTIFICATE_ERROR_INVALID_FORMAT;
 			return ZT_CERTIFICATE_ERROR_INVALID_FORMAT;
 		}
 		}
 	} catch (...) {}
 	} catch (...) {}
@@ -538,10 +538,10 @@ void Certificate::m_encodeSubject(const ZT_Certificate_Subject &s, Dictionary &d
 			d[Dictionary::arraySubscript(tmp, "s.c$", i)].assign(s.certificates[i], s.certificates[i] + ZT_SHA384_DIGEST_SIZE);
 			d[Dictionary::arraySubscript(tmp, "s.c$", i)].assign(s.certificates[i], s.certificates[i] + ZT_SHA384_DIGEST_SIZE);
 	}
 	}
 
 
-	d.add("s.u$", (uint64_t)s.updateUrlCount);
-	if (s.updateUrls) {
-		for (unsigned int i = 0; i < s.updateUrlCount; ++i)
-			d.add(Dictionary::arraySubscript(tmp, "s.u$", i), s.updateUrls[i]);
+	d.add("s.u$", (uint64_t)s.updateURLCount);
+	if (s.updateURLs) {
+		for (unsigned int i = 0; i < s.updateURLCount; ++i)
+			d.add(Dictionary::arraySubscript(tmp, "s.u$", i), s.updateURLs[i]);
 	}
 	}
 
 
 	if (s.name.country[0])
 	if (s.name.country[0])

+ 5 - 5
core/Tests.cpp

@@ -272,7 +272,7 @@ static bool ZTT_deepCompareCertificates(const Certificate &a, const Certificate
 		(a.subject.timestamp != b.subject.timestamp) ||
 		(a.subject.timestamp != b.subject.timestamp) ||
 		(a.subject.identityCount != b.subject.identityCount) ||
 		(a.subject.identityCount != b.subject.identityCount) ||
 		(a.subject.networkCount != b.subject.networkCount) ||
 		(a.subject.networkCount != b.subject.networkCount) ||
-		(a.subject.updateUrlCount != b.subject.updateUrlCount) ||
+		(a.subject.updateURLCount != b.subject.updateURLCount) ||
 		(a.subject.uniqueIdSize != b.subject.uniqueIdSize) ||
 		(a.subject.uniqueIdSize != b.subject.uniqueIdSize) ||
 		(a.subject.uniqueIdProofSignatureSize != b.subject.uniqueIdProofSignatureSize) ||
 		(a.subject.uniqueIdProofSignatureSize != b.subject.uniqueIdProofSignatureSize) ||
 		(a.maxPathLength != b.maxPathLength) ||
 		(a.maxPathLength != b.maxPathLength) ||
@@ -324,12 +324,12 @@ static bool ZTT_deepCompareCertificates(const Certificate &a, const Certificate
 			return false;
 			return false;
 	}
 	}
 
 
-	for(unsigned int i=0;i<a.subject.updateUrlCount;++i) {
-		if ((!a.subject.updateUrls) || (!b.subject.updateUrls))
+	for(unsigned int i=0;i<a.subject.updateURLCount; ++i) {
+		if ((!a.subject.updateURLs) || (!b.subject.updateURLs))
 			return false;
 			return false;
-		if ((!a.subject.updateUrls[i]) || (!b.subject.updateUrls[i]))
+		if ((!a.subject.updateURLs[i]) || (!b.subject.updateURLs[i]))
 			return false;
 			return false;
-		if (strcmp(a.subject.updateUrls[i], b.subject.updateUrls[i]) != 0)
+		if (strcmp(a.subject.updateURLs[i], b.subject.updateURLs[i]) != 0)
 			return false;
 			return false;
 	}
 	}
 
 

+ 4 - 4
core/zerotier.h

@@ -467,7 +467,7 @@ typedef struct
 	/**
 	/**
 	 * URLs that can be consulted for updates to this certificate.
 	 * URLs that can be consulted for updates to this certificate.
 	 */
 	 */
-	const char *const *updateUrls;
+	const char *const *updateURLs;
 
 
 	/**
 	/**
 	 * Number of identities
 	 * Number of identities
@@ -487,7 +487,7 @@ typedef struct
 	/**
 	/**
 	 * Number of update URLs
 	 * Number of update URLs
 	 */
 	 */
-	unsigned int updateUrlCount;
+	unsigned int updateURLCount;
 
 
 	/**
 	/**
 	 * Information about owner of items.
 	 * Information about owner of items.
@@ -581,7 +581,7 @@ typedef struct
 	/**
 	/**
 	 * Extended attributes set by issuer (in Dictionary format, NULL if none)
 	 * Extended attributes set by issuer (in Dictionary format, NULL if none)
 	 */
 	 */
-	uint8_t *extendedAttributes;
+	const uint8_t *extendedAttributes;
 
 
 	/**
 	/**
 	 * Size of extended attributes field in bytes
 	 * Size of extended attributes field in bytes
@@ -2702,7 +2702,7 @@ ZT_SDK_API void ZT_Locator_delete(ZT_Locator *loc);
 /* ---------------------------------------------------------------------------------------------------------------- */
 /* ---------------------------------------------------------------------------------------------------------------- */
 
 
 /**
 /**
- * Get ZeroTier One version
+ * Get ZeroTier core version
  *
  *
  * @param major Result: major version
  * @param major Result: major version
  * @param minor Result: minor version
  * @param minor Result: minor version

+ 1 - 1
pkg/zerotier/address.go

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c)2013-2020 ZeroTier, Inc.
+ * Copyright (C)2013-2020 ZeroTier, Inc.
  *
  *
  * Use of this software is governed by the Business Source License included
  * Use of this software is governed by the Business Source License included
  * in the LICENSE.TXT file in the project's root directory.
  * in the LICENSE.TXT file in the project's root directory.

+ 1 - 1
pkg/zerotier/api.go

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c)2013-2020 ZeroTier, Inc.
+ * Copyright (C)2013-2020 ZeroTier, Inc.
  *
  *
  * Use of this software is governed by the Business Source License included
  * Use of this software is governed by the Business Source License included
  * in the LICENSE.TXT file in the project's root directory.
  * in the LICENSE.TXT file in the project's root directory.

+ 203 - 0
pkg/zerotier/certificate.go

@@ -0,0 +1,203 @@
+/*
+ * 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.
+ */
+/****/
+
+package zerotier
+
+// #include "../../serviceiocore/GoGlue.h"
+import "C"
+
+import (
+	"unsafe"
+)
+
+const (
+	CertificateSerialNoSize    = 48
+	CertificateMaxStringLength = int(C.ZT_CERTIFICATE_MAX_STRING_LENGTH)
+)
+
+type CertificateName struct {
+	SerialNo      string `json:"serialNo,omitempty"`
+	CommonName    string `json:"commonName,omitempty"`
+	StreetAddress string `json:"streetAddress,omitempty"`
+	Locality      string `json:"locality,omitempty"`
+	Province      string `json:"province,omitempty"`
+	PostalCode    string `json:"postalCode,omitempty"`
+	Country       string `json:"country,omitempty"`
+	Organization  string `json:"organization,omitempty"`
+	Unit          string `json:"unit,omitempty"`
+	Email         string `json:"email,omitempty"`
+	URL           string `json:"url,omitempty"`
+	Host          string `json:"host,omitempty"`
+}
+
+type CertificateIdentity struct {
+	Identity *Identity `json:"identity"`
+	Locator  *Locator  `json:"locator,omitempty"`
+}
+
+type CertificateNetwork struct {
+	ID         uint64       `json:"id"`
+	Controller *Fingerprint `json:"controller"`
+}
+
+type CertificateSubject struct {
+	Timestamp              int64                           `json:"timestamp"`
+	Identities             []CertificateIdentity           `json:"identities,omitempty"`
+	Networks               []CertificateNetwork            `json:"networks,omitempty"`
+	Certificates           [][CertificateSerialNoSize]byte `json:"certificates,omitempty"`
+	UpdateURLs             []string                        `json:"updateURLs,omitempty"`
+	Name                   CertificateName                 `json:"name"`
+	UniqueID               []byte                          `json:"uniqueId,omitempty"`
+	UniqueIDProofSignature []byte                          `json:"uniqueIdProofSignature,omitempty"`
+}
+
+type Certificate struct {
+	SerialNo           []byte             `json:"serialNo,omitempty"`
+	Flags              uint64             `json:"flags"`
+	Timestamp          int64              `json:"timestamp"`
+	Validity           [2]int64           `json:"validity"`
+	Subject            CertificateSubject `json:"subject"`
+	Issuer             *Identity          `json:"issuer,omitempty"`
+	IssuerName         CertificateName    `json:"issuerName"`
+	ExtendedAttributes []byte             `json:"extendedAttributes,omitempty"`
+	MaxPathLength      uint               `json:"maxPathLength,omitempty"`
+	Signature          []byte             `json:"signature,omitempty"`
+}
+
+type cCertificate struct {
+	C                             C.ZT_Certificate
+	internalSubjectIdentities     []C.ZT_Certificate_Identity
+	internalSubjectNetworks       []C.ZT_Certificate_Network
+	internalSubjectUpdateURLs     []*C.char
+	internalSubjectUpdateURLsData [][]byte
+}
+
+// cCertificate creates a C ZT_Certificate structure
+// The returned Go structure bundles this with some objects that have
+// to be created to set their pointers in ZT_Certificate. It's easier to
+// manage allocation of these in Go and bundle them so Go's GC will clean
+// them up automatically when cCertificate is releaed. Only the 'C' field
+// in cCertificate should be directly used.
+func (c *Certificate) cCertificate() *cCertificate {
+	var cc cCertificate
+
+	if len(c.SerialNo) == 48 {
+		copy((*[48]byte)(unsafe.Pointer(&cc.C.serialNo[0]))[:], c.SerialNo[:])
+	}
+	cc.C.flags = C.uint64_t(c.Flags)
+	cc.C.timestamp = C.int64_t(c.Timestamp)
+	cc.C.validity[0] = C.int64_t(c.Validity[0])
+	cc.C.validity[1] = C.int64_t(c.Validity[1])
+
+	cc.C.subject.timestamp = C.int64_t(c.Subject.Timestamp)
+
+	if len(c.Subject.Identities) > 0 {
+		cc.internalSubjectIdentities = make([]C.ZT_Certificate_Identity, len(c.Subject.Identities))
+		for i, id := range c.Subject.Identities {
+			if id.Identity == nil || !id.Identity.initCIdentityPtr() {
+				return nil
+			}
+			cc.internalSubjectIdentities[i].identity = id.Identity.cid
+			if id.Locator != nil {
+				cc.internalSubjectIdentities[i].locator = id.Locator.cl
+			}
+		}
+		cc.C.subject.identities = &cc.internalSubjectIdentities[0]
+		cc.C.subject.identityCount = C.uint(len(c.Subject.Identities))
+	}
+
+	if len(c.Subject.Networks) > 0 {
+		cc.internalSubjectNetworks = make([]C.ZT_Certificate_Network, len(c.Subject.Networks))
+		for i, n := range c.Subject.Networks {
+			cc.internalSubjectNetworks[i].id = C.uint64_t(n.ID)
+			cc.internalSubjectNetworks[i].controller.address = C.uint64_t(n.Controller.Address)
+			if len(n.Controller.Hash) == 48 {
+				copy((*[48]byte)(unsafe.Pointer(&cc.internalSubjectNetworks[i].controller.hash[0]))[:], n.Controller.Hash)
+			}
+		}
+		cc.C.subject.networks = &cc.internalSubjectNetworks[0]
+		cc.C.subject.networkCount = C.uint(len(c.Subject.Networks))
+	}
+
+	if len(c.Subject.Certificates) > 0 {
+		cc.C.subject.certificates = (**C.uint8_t)(unsafe.Pointer(&c.Subject.Certificates[0]))
+		cc.C.subject.certificateCount = C.uint(len(c.Subject.Certificates))
+	}
+
+	if len(c.Subject.UpdateURLs) > 0 {
+		cc.internalSubjectUpdateURLs = make([]*C.char, len(c.Subject.UpdateURLs))
+		cc.internalSubjectUpdateURLsData = make([][]byte, len(c.Subject.UpdateURLs))
+		for i, u := range c.Subject.UpdateURLs {
+			cc.internalSubjectUpdateURLsData[i] = stringAsZeroTerminatedBytes(u)
+			cc.internalSubjectUpdateURLs[i] = (*C.char)(unsafe.Pointer(&cc.internalSubjectUpdateURLsData[0]))
+		}
+		cc.C.subject.updateURLs = (**C.char)(unsafe.Pointer(&cc.internalSubjectUpdateURLs[0]))
+		cc.C.subject.updateURLCount = C.uint(len(c.Subject.UpdateURLs))
+	}
+
+	cStrCopy(unsafe.Pointer(&cc.C.subject.name.serialNo[0]), CertificateMaxStringLength+1, c.Subject.Name.SerialNo)
+	cStrCopy(unsafe.Pointer(&cc.C.subject.name.commonName[0]), CertificateMaxStringLength+1, c.Subject.Name.CommonName)
+	cStrCopy(unsafe.Pointer(&cc.C.subject.name.country[0]), CertificateMaxStringLength+1, c.Subject.Name.Country)
+	cStrCopy(unsafe.Pointer(&cc.C.subject.name.organization[0]), CertificateMaxStringLength+1, c.Subject.Name.Organization)
+	cStrCopy(unsafe.Pointer(&cc.C.subject.name.unit[0]), CertificateMaxStringLength+1, c.Subject.Name.Unit)
+	cStrCopy(unsafe.Pointer(&cc.C.subject.name.locality[0]), CertificateMaxStringLength+1, c.Subject.Name.Locality)
+	cStrCopy(unsafe.Pointer(&cc.C.subject.name.province[0]), CertificateMaxStringLength+1, c.Subject.Name.Province)
+	cStrCopy(unsafe.Pointer(&cc.C.subject.name.streetAddress[0]), CertificateMaxStringLength+1, c.Subject.Name.StreetAddress)
+	cStrCopy(unsafe.Pointer(&cc.C.subject.name.postalCode[0]), CertificateMaxStringLength+1, c.Subject.Name.PostalCode)
+	cStrCopy(unsafe.Pointer(&cc.C.subject.name.email[0]), CertificateMaxStringLength+1, c.Subject.Name.Email)
+	cStrCopy(unsafe.Pointer(&cc.C.subject.name.url[0]), CertificateMaxStringLength+1, c.Subject.Name.URL)
+	cStrCopy(unsafe.Pointer(&cc.C.subject.name.host[0]), CertificateMaxStringLength+1, c.Subject.Name.Host)
+
+	if len(c.Subject.UniqueID) > 0 {
+		cc.C.subject.uniqueId = (*C.uint8_t)(unsafe.Pointer(&c.Subject.UniqueID[0]))
+		cc.C.subject.uniqueIdSize = C.uint(len(c.Subject.UniqueID))
+		if len(c.Subject.UniqueIDProofSignature) > 0 {
+			cc.C.subject.uniqueIdProofSignature = (*C.uint8_t)(unsafe.Pointer(&c.Subject.UniqueIDProofSignature[0]))
+			cc.C.subject.uniqueIdProofSignatureSize = C.uint(len(c.Subject.UniqueIDProofSignature))
+		}
+	}
+
+	if c.Issuer != nil {
+		if !c.Issuer.initCIdentityPtr() {
+			return nil
+		}
+		cc.C.issuer = c.Issuer.cid
+	}
+
+	cStrCopy(unsafe.Pointer(&cc.C.issuerName.serialNo[0]), CertificateMaxStringLength+1, c.IssuerName.SerialNo)
+	cStrCopy(unsafe.Pointer(&cc.C.issuerName.commonName[0]), CertificateMaxStringLength+1, c.IssuerName.CommonName)
+	cStrCopy(unsafe.Pointer(&cc.C.issuerName.country[0]), CertificateMaxStringLength+1, c.IssuerName.Country)
+	cStrCopy(unsafe.Pointer(&cc.C.issuerName.organization[0]), CertificateMaxStringLength+1, c.IssuerName.Organization)
+	cStrCopy(unsafe.Pointer(&cc.C.issuerName.unit[0]), CertificateMaxStringLength+1, c.IssuerName.Unit)
+	cStrCopy(unsafe.Pointer(&cc.C.issuerName.locality[0]), CertificateMaxStringLength+1, c.IssuerName.Locality)
+	cStrCopy(unsafe.Pointer(&cc.C.issuerName.province[0]), CertificateMaxStringLength+1, c.IssuerName.Province)
+	cStrCopy(unsafe.Pointer(&cc.C.issuerName.streetAddress[0]), CertificateMaxStringLength+1, c.IssuerName.StreetAddress)
+	cStrCopy(unsafe.Pointer(&cc.C.issuerName.postalCode[0]), CertificateMaxStringLength+1, c.IssuerName.PostalCode)
+	cStrCopy(unsafe.Pointer(&cc.C.issuerName.email[0]), CertificateMaxStringLength+1, c.IssuerName.Email)
+	cStrCopy(unsafe.Pointer(&cc.C.issuerName.url[0]), CertificateMaxStringLength+1, c.IssuerName.URL)
+	cStrCopy(unsafe.Pointer(&cc.C.issuerName.host[0]), CertificateMaxStringLength+1, c.IssuerName.Host)
+
+	if len(c.ExtendedAttributes) > 0 {
+		cc.C.extendedAttributes = (*C.uint8_t)(unsafe.Pointer(&c.ExtendedAttributes[0]))
+		cc.C.extendedAttributesSize = C.uint(len(c.ExtendedAttributes))
+	}
+
+	cc.C.maxPathLength = C.uint(c.MaxPathLength)
+
+	if len(c.Signature) > 0 {
+		cc.C.signature = (*C.uint8_t)(unsafe.Pointer(&c.Signature[0]))
+		cc.C.signatureSize = C.uint(len(c.Signature))
+	}
+
+	return &cc
+}

+ 1 - 1
pkg/zerotier/endpoint.go

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c)2013-2020 ZeroTier, Inc.
+ * Copyright (C)2013-2020 ZeroTier, Inc.
  *
  *
  * Use of this software is governed by the Business Source License included
  * Use of this software is governed by the Business Source License included
  * in the LICENSE.TXT file in the project's root directory.
  * in the LICENSE.TXT file in the project's root directory.

+ 1 - 1
pkg/zerotier/errors.go

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c)2013-2020 ZeroTier, Inc.
+ * Copyright (C)2013-2020 ZeroTier, Inc.
  *
  *
  * Use of this software is governed by the Business Source License included
  * Use of this software is governed by the Business Source License included
  * in the LICENSE.TXT file in the project's root directory.
  * in the LICENSE.TXT file in the project's root directory.

+ 1 - 1
pkg/zerotier/fingerprint.go

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c)2013-2020 ZeroTier, Inc.
+ * Copyright (C)2013-2020 ZeroTier, Inc.
  *
  *
  * Use of this software is governed by the Business Source License included
  * Use of this software is governed by the Business Source License included
  * in the LICENSE.TXT file in the project's root directory.
  * in the LICENSE.TXT file in the project's root directory.

+ 1 - 1
pkg/zerotier/identity.go

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c)2013-2020 ZeroTier, Inc.
+ * Copyright (C)2013-2020 ZeroTier, Inc.
  *
  *
  * Use of this software is governed by the Business Source License included
  * Use of this software is governed by the Business Source License included
  * in the LICENSE.TXT file in the project's root directory.
  * in the LICENSE.TXT file in the project's root directory.

+ 1 - 1
pkg/zerotier/inetaddress.go

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c)2013-2020 ZeroTier, Inc.
+ * Copyright (C)2013-2020 ZeroTier, Inc.
  *
  *
  * Use of this software is governed by the Business Source License included
  * Use of this software is governed by the Business Source License included
  * in the LICENSE.TXT file in the project's root directory.
  * in the LICENSE.TXT file in the project's root directory.

+ 1 - 1
pkg/zerotier/localconfig.go

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c)2013-2020 ZeroTier, Inc.
+ * Copyright (C)2013-2020 ZeroTier, Inc.
  *
  *
  * Use of this software is governed by the Business Source License included
  * Use of this software is governed by the Business Source License included
  * in the LICENSE.TXT file in the project's root directory.
  * in the LICENSE.TXT file in the project's root directory.

+ 1 - 1
pkg/zerotier/locator.go

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c)2013-2020 ZeroTier, Inc.
+ * Copyright (C)2013-2020 ZeroTier, Inc.
  *
  *
  * Use of this software is governed by the Business Source License included
  * Use of this software is governed by the Business Source License included
  * in the LICENSE.TXT file in the project's root directory.
  * in the LICENSE.TXT file in the project's root directory.

+ 1 - 1
pkg/zerotier/mac.go

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c)2013-2020 ZeroTier, Inc.
+ * Copyright (C)2013-2020 ZeroTier, Inc.
  *
  *
  * Use of this software is governed by the Business Source License included
  * Use of this software is governed by the Business Source License included
  * in the LICENSE.TXT file in the project's root directory.
  * in the LICENSE.TXT file in the project's root directory.

+ 25 - 1
pkg/zerotier/misc.go

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c)2013-2020 ZeroTier, Inc.
+ * Copyright (C)2013-2020 ZeroTier, Inc.
  *
  *
  * Use of this software is governed by the Business Source License included
  * Use of this software is governed by the Business Source License included
  * in the LICENSE.TXT file in the project's root directory.
  * in the LICENSE.TXT file in the project's root directory.
@@ -259,3 +259,27 @@ func ipClassify(ip net.IP) int {
 
 
 	return ipClassificationNone
 	return ipClassificationNone
 }
 }
+
+// stringAsZeroTerminatedBytes creates a C string but as a Go []byte
+func stringAsZeroTerminatedBytes(s string) (b []byte) {
+	if len(s) == 0 {
+		b = []byte{0} // single zero
+		return
+	}
+	sb := []byte(s)
+	b = make([]byte, len(sb) + 1)
+	copy(b, sb)
+	// make() will zero memory, so b[len(sb)+1] will be 0
+	return
+}
+
+// cStrCopy copies src into dest as a zero-terminated C string
+func cStrCopy(dest unsafe.Pointer, destSize int, src string) {
+	sb := []byte(src)
+	b := C.GoBytes(dest, C.int(destSize))
+	if len(sb) > (destSize - 1) {
+		sb = sb[0:destSize - 1]
+	}
+	copy(b[:], sb[:])
+	b[len(sb)] = 0
+}

+ 1 - 1
pkg/zerotier/multicastgroup.go

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c)2013-2020 ZeroTier, Inc.
+ * Copyright (C)2013-2020 ZeroTier, Inc.
  *
  *
  * Use of this software is governed by the Business Source License included
  * Use of this software is governed by the Business Source License included
  * in the LICENSE.TXT file in the project's root directory.
  * in the LICENSE.TXT file in the project's root directory.

+ 1 - 1
pkg/zerotier/nativetap.go

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c)2013-2020 ZeroTier, Inc.
+ * Copyright (C)2013-2020 ZeroTier, Inc.
  *
  *
  * Use of this software is governed by the Business Source License included
  * Use of this software is governed by the Business Source License included
  * in the LICENSE.TXT file in the project's root directory.
  * in the LICENSE.TXT file in the project's root directory.

+ 1 - 1
pkg/zerotier/network.go

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c)2013-2020 ZeroTier, Inc.
+ * Copyright (C)2013-2020 ZeroTier, Inc.
  *
  *
  * Use of this software is governed by the Business Source License included
  * Use of this software is governed by the Business Source License included
  * in the LICENSE.TXT file in the project's root directory.
  * in the LICENSE.TXT file in the project's root directory.

+ 1 - 1
pkg/zerotier/node.go

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c)2013-2020 ZeroTier, Inc.
+ * Copyright (C)2013-2020 ZeroTier, Inc.
  *
  *
  * Use of this software is governed by the Business Source License included
  * Use of this software is governed by the Business Source License included
  * in the LICENSE.TXT file in the project's root directory.
  * in the LICENSE.TXT file in the project's root directory.

+ 1 - 1
pkg/zerotier/osdep-posix.go

@@ -1,7 +1,7 @@
 // +build !windows
 // +build !windows
 
 
 /*
 /*
- * Copyright (c)2013-2020 ZeroTier, Inc.
+ * Copyright (C)2013-2020 ZeroTier, Inc.
  *
  *
  * Use of this software is governed by the Business Source License included
  * Use of this software is governed by the Business Source License included
  * in the LICENSE.TXT file in the project's root directory.
  * in the LICENSE.TXT file in the project's root directory.

+ 1 - 1
pkg/zerotier/osdep-windows.go

@@ -1,7 +1,7 @@
 // +build windows
 // +build windows
 
 
 /*
 /*
- * Copyright (c)2013-2020 ZeroTier, Inc.
+ * Copyright (C)2013-2020 ZeroTier, Inc.
  *
  *
  * Use of this software is governed by the Business Source License included
  * Use of this software is governed by the Business Source License included
  * in the LICENSE.TXT file in the project's root directory.
  * in the LICENSE.TXT file in the project's root directory.

+ 1 - 1
pkg/zerotier/path.go

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c)2013-2020 ZeroTier, Inc.
+ * Copyright (C)2013-2020 ZeroTier, Inc.
  *
  *
  * Use of this software is governed by the Business Source License included
  * Use of this software is governed by the Business Source License included
  * in the LICENSE.TXT file in the project's root directory.
  * in the LICENSE.TXT file in the project's root directory.

+ 1 - 1
pkg/zerotier/peer.go

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c)2013-2020 ZeroTier, Inc.
+ * Copyright (C)2013-2020 ZeroTier, Inc.
  *
  *
  * Use of this software is governed by the Business Source License included
  * Use of this software is governed by the Business Source License included
  * in the LICENSE.TXT file in the project's root directory.
  * in the LICENSE.TXT file in the project's root directory.

+ 1 - 1
pkg/zerotier/route.go

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c)2013-2020 ZeroTier, Inc.
+ * Copyright (C)2013-2020 ZeroTier, Inc.
  *
  *
  * Use of this software is governed by the Business Source License included
  * Use of this software is governed by the Business Source License included
  * in the LICENSE.TXT file in the project's root directory.
  * in the LICENSE.TXT file in the project's root directory.

+ 1 - 1
pkg/zerotier/sizelimitwriter.go

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c)2013-2020 ZeroTier, Inc.
+ * Copyright (C)2013-2020 ZeroTier, Inc.
  *
  *
  * Use of this software is governed by the Business Source License included
  * Use of this software is governed by the Business Source License included
  * in the LICENSE.TXT file in the project's root directory.
  * in the LICENSE.TXT file in the project's root directory.

+ 1 - 1
pkg/zerotier/tap.go

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c)2013-2020 ZeroTier, Inc.
+ * Copyright (C)2013-2020 ZeroTier, Inc.
  *
  *
  * Use of this software is governed by the Business Source License included
  * Use of this software is governed by the Business Source License included
  * in the LICENSE.TXT file in the project's root directory.
  * in the LICENSE.TXT file in the project's root directory.