Przeglądaj źródła

Use Base32 everywhere for blobs to be consistent with core.

Adam Ierymenko 4 lat temu
rodzic
commit
387d293793

+ 7 - 0
cmd/zerotier/cli/cert.go

@@ -20,6 +20,13 @@ import (
 	"zerotier/pkg/zerotier"
 )
 
+func interactiveMakeSubject() *zerotier.CertificateSubject {
+	s := new(zerotier.CertificateSubject)
+
+
+	return s
+}
+
 func Cert(basePath string, authTokenGenerator func() string, args []string, jsonOutput bool) int {
 	if len(args) < 1 {
 		Help()

+ 72 - 71
cmd/zerotier/cli/help.go

@@ -34,80 +34,81 @@ Global Options:
 
 Common Operations:
 
-  help                                   Show this help
-  version                                Print version
-  now [duration]                         Print current time [-]#[ms|s|m|h]
-
-· status                                 Show node status and configuration
-
-· set [option] [value]                 - Get or set node configuration
-    port <port>                          Primary P2P port
-    secondaryport <port/0>               Secondary P2P port (0 to disable)
-    blacklist cidr <IP/bits> <boolean>   Toggle physical path blacklisting
-    blacklist if <prefix> <boolean>      Toggle interface prefix blacklisting
-    portmap <boolean>                    Toggle use of uPnP or NAT-PMP
-
-· peer [address] [command] [option]    - Peer management commands
-    list                                 List peers
-    listroots                            List root peers
-    show                                 Show peer details
-    try <endpoint> [...]                 Try peer at explicit endpoint
-
-· network list                           List VL2 networks
-· network <network> [command] [option] - Network management commands
-    show                                 Show network details (default)
-    set [option] [value]               - Get or set network options
-      manageips <boolean>                Is IP management allowed?
-      manageroutes <boolean>             Is route management allowed?
-      globalips <boolean>                Allow assignment of global IPs?
-      globalroutes <boolean>             Can global IP space routes be set?
-      defaultroute <boolean>             Can default route be overridden?
-
-· join [-options] <network>              Join a virtual network
-    -a <token>                           Token to submit to controller
-    -c <identity | fingerprint>          Controller identity or fingerprint
-· leave <network>                        Leave a virtual network
+  help                                    Show this help
+  version                                 Print version
+
+· status                                  Show node status and configuration
+
+· set [option] [value]                    List all settings (with no args)
+·    port <port>                          Primary P2P port
+·    secondaryport <port/0>               Secondary P2P port (0 to disable)
+·    blacklist cidr <IP/bits> <boolean>   Toggle physical path blacklisting
+·    blacklist if <prefix> <boolean>      Toggle interface prefix blacklisting
+·    portmap <boolean>                    Toggle use of uPnP or NAT-PMP
+
+· peer [address] [command] [option]       Peer management commands
+·   list                                  List peers
+·   listroots                             List root peers
+·   show                                  Show peer details
+·   try <endpoint> [...]                  Try peer at explicit endpoint
+
+· network list                            List VL2 networks
+· network <network> [command] [option]
+·   show                                  Show network details (default)
+·   set [option] [value]                  Get or set network options
+·     manageips <boolean>                 Is IP management allowed?
+·     manageroutes <boolean>              Is route management allowed?
+·     globalips <boolean>                 Allow assignment of global IPs?
+·     globalroutes <boolean>              Can global IP space routes be set?
+·     defaultroute <boolean>              Can default route be overridden?
+
+· join [-options] <network>               Join a virtual network
+    -a <token>                            Token to submit to controller
+    -c <identity | fingerprint>           Controller identity or fingerprint
+· leave <network>                         Leave a virtual network
 
 Advanced Operations:
 
-  service                                Start node (seldom used from CLI)
-
-· controller <command> [option]        - Local controller management commands
-·   list                                 List networks run by local controller
-·   new                                  Create a new network
-·   set <network> [setting] [value]      Show or modify network settings
-·   members <network>                    List members of a network
-·   member <network> [setting] [value]   Show or modify member level settings
-·   auth <address>                       Authorize a peer
-·   deauth <address>                     Deauthorize a peer
-
-  identity <command> [args]            - Identity management
-    new [c25519 | p384]                  Create identity (default: c25519)
-    getpublic <identity>                 Extract only public part of identity
-    fingerprint <identity>               Get an identity's fingerprint
-    validate <identity>                  Locally validate an identity
-    sign <identity> <file>               Sign a file with an identity's key
-    verify <identity> <file> <sig>       Verify a signature
-
-  locator <command> [args]             - Locator management
-    new <identity> <endpoint> [...]      Create new signed locator
-    verify <identity> <locator>          Verify locator signature
-    show <locator>                       Show contents of a locator
-
-  cert <command> [args]                - Certificate management
-·   list                                 List certificates in local node store
-·   show <serial>                        List or show details of a certificate
-    newsid <secret out>                  Create a new subject unique ID
-    newcsr <subject> <secret> <csr out>  Create a subject CSR
-    sign <csr> <identity> <cert out>     Sign a CSR to create a certificate
-    verify <cert>                        Verify certificate (not entire chain)
-    dump <cert>                          Verify and print certificate
-·   import <cert> [trust,[trust]]        Import certificate into this node
-      trust flag: rootca                 Certificate is a root CA
-      trust flag: ztrootset              ZeroTier root node set
-·   restore                              Re-import default certificates
-·   export <serial> [path]               Export a certificate from this node
-·   delete <serial|ALL>                  Delete certificate from this node
+  service                                 Start this node (runs until stopped)
+  now [duration]                          Print current time [-]#[ms|s|m|h]
+
+  controller <command> [option]
+·   list                                  List networks on controller
+·   new                                   Create a new network
+·   set <network> [setting] [value]       Show or modify network settings
+·   members <network>                     List members of a network
+·   member <network> [setting] [value]    Show or modify member level settings
+·   auth <address>                        Authorize a peer
+·   deauth <address>                      Deauthorize a peer
+
+  identity <command> [args]
+    new [c25519 | p384]                   Create identity (default: c25519)
+    getpublic <identity>                  Extract only public part of identity
+    fingerprint <identity>                Get an identity's fingerprint
+    validate <identity>                   Locally validate an identity
+    sign <identity> <file>                Sign a file with an identity's key
+    verify <identity> <file> <sig>        Verify a signature
+
+  locator <command> [args]
+    new <identity> <endpoint> [...]       Create new signed locator
+    verify <identity> <locator>           Verify locator signature
+    show <locator>                        Show contents of a locator
+
+  cert <command> [args]
+·   list                                  List certificates at local node
+·   show <serial>                         Show certificate details
+    newsubject <subject out>              Interactive subject creation
+    newsid <secret out>                   Create a new subject unique ID
+    newcsr <subject|-> <secret> <csr out> Create a subject CSR
+    sign <csr> <identity> <cert out>      Sign a CSR to create a certificate
+    verify <cert>                         Verify certificate (not chain)
+    dump <cert>                           Verify and print certificate
+·   import <cert> [trust,[trust]]         Import certificate into this node
+      trust flag: rootca                  Certificate is a root CA
+      trust flag: ztrootset               ZeroTier root node set
+·   restore                               Re-import default certificates
+·   export <serial> [path]                Export a certificate from this node
+·   delete <serial|ALL>                   Delete certificate from this node
 
      · Command requires a running node and access to a local API token.
 

+ 39 - 0
cmd/zerotier/cli/misc.go

@@ -14,11 +14,13 @@
 package cli
 
 import (
+	"bufio"
 	"encoding/json"
 	"fmt"
 	"io/ioutil"
 	"net/http"
 	"os"
+	"strconv"
 	"strings"
 
 	"zerotier/pkg/zerotier"
@@ -235,3 +237,40 @@ func isValidNetworkID(a string) bool {
 	}
 	return false
 }
+
+func prompt(str string, dfl string) string {
+	if len(dfl) > 0 {
+		fmt.Printf("%s [%s]: ", str, dfl)
+		text, _ := bufio.NewReader(os.Stdin).ReadString('\n')
+		text = strings.TrimSpace(text)
+		if len(text) == 0 {
+			text = dfl
+		}
+		return text
+	}
+	fmt.Print(str)
+	text, _ := bufio.NewReader(os.Stdin).ReadString('\n')
+	return strings.TrimSpace(text)
+}
+
+func promptInt(str string, dfl int64) int64 {
+	s := prompt(str, "")
+	if len(s) > 0 {
+		i, err := strconv.ParseInt(s, 10, 64)
+		if err == nil {
+			return i
+		}
+	}
+	return dfl
+}
+
+func promptFile(str string) []byte {
+	s := prompt(str, "")
+	if len(s) > 0 {
+		b, err := ioutil.ReadFile(s)
+		if err == nil {
+			return b
+		}
+	}
+	return nil
+}

+ 38 - 0
pkg/zerotier/base32blob.go

@@ -0,0 +1,38 @@
+/*
+ * 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: 2025-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
+
+import (
+	"encoding/json"
+	"strings"
+)
+
+// Base32Blob is a byte array that JSON serializes to a Base32 string.
+type Base32Blob []byte
+
+// MarshalJSON returns this blob marshaled as a byte array or a string.
+func (b *Base32Blob) MarshalJSON() ([]byte, error) {
+	return []byte("\""+Base32.EncodeToString(*b)+"\""), nil
+}
+
+// UnmarshalJSON unmarshals this blob from a JSON array or string.
+func (b *Base32Blob) UnmarshalJSON(j []byte) error {
+	var b32 string
+	err := json.Unmarshal(j, &b32)
+	if err != nil {
+		return err
+	}
+	*b, err = Base32.DecodeString(strings.TrimSpace(b32))
+	return err
+}

+ 9 - 15
pkg/zerotier/certificate.go

@@ -18,7 +18,6 @@ package zerotier
 import "C"
 
 import (
-	"encoding/base64"
 	"encoding/json"
 	"fmt"
 	"unsafe"
@@ -69,32 +68,32 @@ type CertificateSubject struct {
 	Timestamp              int64                 `json:"timestamp"`
 	Identities             []CertificateIdentity `json:"identities,omitempty"`
 	Networks               []CertificateNetwork  `json:"networks,omitempty"`
-	Certificates           [][]byte              `json:"certificates,omitempty"`
+	Certificates           []Base32Blob          `json:"certificates,omitempty"`
 	UpdateURLs             []string              `json:"updateURLs,omitempty"`
 	Name                   CertificateName       `json:"name"`
-	UniqueID               []byte                `json:"uniqueId,omitempty"`
-	UniqueIDProofSignature []byte                `json:"uniqueIdProofSignature,omitempty"`
+	UniqueID               Base32Blob            `json:"uniqueId,omitempty"`
+	UniqueIDProofSignature Base32Blob            `json:"uniqueIdProofSignature,omitempty"`
 }
 
 // Certificate is a Go reflection of the C ZT_Certificate struct.
 type Certificate struct {
-	SerialNo           []byte             `json:"serialNo,omitempty"`
+	SerialNo           Base32Blob         `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"`
+	ExtendedAttributes Base32Blob         `json:"extendedAttributes,omitempty"`
 	MaxPathLength      uint               `json:"maxPathLength,omitempty"`
-	CRL                [][]byte           `json:"crl,omitempty"`
-	Signature          []byte             `json:"signature,omitempty"`
+	CRL                []Base32Blob       `json:"crl,omitempty"`
+	Signature          Base32Blob         `json:"signature,omitempty"`
 }
 
 // CertificateSubjectUniqueIDSecret bundles a certificate subject unique ID and its secret key.
 type CertificateSubjectUniqueIDSecret struct {
-	UniqueID       []byte `json:"uniqueId,omitempty"`
-	UniqueIDSecret []byte `json:"uniqueIdSecret,omitempty"`
+	UniqueID       Base32Blob `json:"uniqueId,omitempty"`
+	UniqueIDSecret Base32Blob `json:"uniqueIdSecret,omitempty"`
 }
 
 // LocalCertificate combines a certificate with its local trust flags.
@@ -495,11 +494,6 @@ func (c *Certificate) JSON() string {
 	return string(j)
 }
 
-// URLSerialNo returns the serial number encoded for use in /cert/### local API URLs.
-func (c *Certificate) URLSerialNo() string {
-	return base64.URLEncoding.EncodeToString(c.SerialNo)
-}
-
 // NewCertificateSubjectUniqueId creates a new certificate subject unique ID and corresponding private key.
 // Right now only one type is supported: CertificateUniqueIdTypeNistP384
 func NewCertificateSubjectUniqueId(uniqueIdType int) (id []byte, priv []byte, err error) {

+ 2 - 2
pkg/zerotier/fingerprint.go

@@ -51,7 +51,7 @@ func NewFingerprintFromString(fps string) (*Fingerprint, error) {
 		return nil, err
 	}
 	if len(ss) == 2 {
-		h, err := Base32StdLowerCase.DecodeString(ss[1])
+		h, err := Base32.DecodeString(ss[1])
 		if err != nil {
 			return nil, err
 		}
@@ -78,7 +78,7 @@ func newFingerprintFromCFingerprint(cfp *C.ZT_Fingerprint) *Fingerprint {
 // String returns an address or a full address-hash depenting on whether a hash is present.
 func (fp *Fingerprint) String() string {
 	if len(fp.Hash) == FingerprintHashSize {
-		return fmt.Sprintf("%.10x-%s", uint64(fp.Address), Base32StdLowerCase.EncodeToString(fp.Hash))
+		return fmt.Sprintf("%.10x-%s", uint64(fp.Address), Base32.EncodeToString(fp.Hash))
 	}
 	return fp.Address.String()
 }

+ 5 - 2
pkg/zerotier/misc.go

@@ -32,8 +32,11 @@ const LogoChar = "⏁"
 // pointerSize is the size of a pointer on this system
 const pointerSize = unsafe.Sizeof(uintptr(0))
 
-// Base32StdLowerCase is a base32 encoder/decoder using a lower-case standard alphabet and no padding.
-var Base32StdLowerCase = base32.NewEncoding("abcdefghijklmnopqrstuvwxyz234567").WithPadding(base32.NoPadding)
+// Base32Alphabet is the Base32 alphabet used in ZeroTier.
+const Base32Alphabet = "abcdefghijklmnopqrstuvwxyz234567"
+
+// Base32 is an encoder using the ZeroTier base32 encoding.
+var Base32 = base32.NewEncoding(Base32Alphabet)
 
 // unassignedPrivilegedPorts are ports below 1024 that do not appear to be assigned by IANA.
 // The new 2.0+ ZeroTier default is 793, which we will eventually seek to have assigned. These

+ 1 - 1
pkg/zerotier/node.go

@@ -731,7 +731,7 @@ func (n *Node) makeStateObjectPath(objType int, id []uint64) (string, bool) {
 		fp = path.Join(n.basePath, "truststore")
 	case C.ZT_STATE_OBJECT_CERT:
 		_ = os.Mkdir(n.certsPath, 0755)
-		fp = path.Join(n.certsPath, Base32StdLowerCase.EncodeToString((*[48]byte)(unsafe.Pointer(&id[0]))[:]))
+		fp = path.Join(n.certsPath, Base32.EncodeToString((*[48]byte)(unsafe.Pointer(&id[0]))[:]))
 	}
 	return fp, secret
 }