From 0f77bd49dc04947c427df6869db478c8430f2de4 Mon Sep 17 00:00:00 2001 From: Kyle Isom Date: Sun, 16 Nov 2025 01:32:19 -0800 Subject: [PATCH] cmd: continue lint fixes. --- .golangci.yml | 3 +- cache/lru/lru_internal_test.go | 126 +++++++-------- cache/lru/timestamps_internal_test.go | 64 ++++---- cache/mru/mru_internal_test.go | 28 ++-- cache/mru/timestamps_internal_test.go | 4 +- cmd/cert-revcheck/main.go | 107 +++++++------ cmd/certchain/{certchain.go => main.go} | 5 +- cmd/certdump/{certdump.go => main.go} | 197 ++++++++++++------------ cmd/certdump/util.go | 141 ++++++++--------- cmd/certexpiry/main.go | 52 +++---- cmd/certverify/main.go | 3 +- cmd/clustersh/main.go | 84 +++++----- cmd/cruntar/main.go | 11 +- cmd/csrpubdump/{pubdump.go => main.go} | 6 +- cmd/data_sync/main.go | 1 - cmd/diskimg/main.go | 32 ++-- cmd/dumpbytes/main.go | 22 +-- cmd/eig/main.go | 6 +- cmd/fragment/{fragment.go => main.go} | 18 +-- cmd/jlp/{jlp.go => main.go} | 103 ++++++------- cmd/kgz/main.go | 92 +++++------ cmd/minmax/{minmax.go => main.go} | 12 +- cmd/parts/main.go | 5 +- cmd/pem2bin/main.go | 5 +- cmd/pembody/{pembody.go => main.go} | 24 +-- cmd/pemit/main.go | 2 +- cmd/readchain/{chain.go => main.go} | 18 +-- cmd/renfnv/{renfnv.go => main.go} | 42 ++--- cmd/rolldie/main.go | 10 +- cmd/showimp/main.go | 14 +- cmd/ski/main.go | 93 ++++++----- cmd/sprox/main.go | 42 ++--- cmd/stealchain-server/main.go | 92 +++++------ cmd/stealchain/{thief.go => main.go} | 5 +- cmd/subjhash/main.go | 31 ++-- cmd/tlsinfo/main.go | 1 - cmd/tlskeypair/main.go | 167 ++++++++++---------- cmd/utc/main.go | 4 - cmd/yamll/main.go | 7 +- cmd/zsearch/main.go | 4 +- lib/ftime_bsd.go | 2 +- lib/ftime_unix.go | 4 +- lib/lib.go | 42 ++--- logging/file.go | 32 ++-- 44 files changed, 888 insertions(+), 875 deletions(-) rename cmd/certchain/{certchain.go => main.go} (81%) rename cmd/certdump/{certdump.go => main.go} (55%) rename cmd/csrpubdump/{pubdump.go => main.go} (85%) rename cmd/fragment/{fragment.go => main.go} (85%) rename cmd/jlp/{jlp.go => main.go} (51%) rename cmd/minmax/{minmax.go => main.go} (74%) rename cmd/pembody/{pembody.go => main.go} (50%) rename cmd/readchain/{chain.go => main.go} (64%) rename cmd/renfnv/{renfnv.go => main.go} (78%) rename cmd/stealchain/{thief.go => main.go} (91%) diff --git a/.golangci.yml b/.golangci.yml index 76095d4..8c5ca0f 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -86,7 +86,6 @@ linters: - godoclint # checks Golang's documentation practice - godot # checks if comments end in a period - gomoddirectives # manages the use of 'replace', 'retract', and 'excludes' directives in go.mod - - goprintffuncname # checks that printf-like functions are named with f at the end - gosec # inspects source code for security problems - govet # reports suspicious constructs, such as Printf calls whose arguments do not align with the format string - iface # checks the incorrect use of interfaces, helping developers avoid interface pollution @@ -465,6 +464,8 @@ linters: linters: [ testableexamples ] - path: 'main.go' linters: [ forbidigo, mnd, reassign ] + - path: 'cmd/cruntar/main.go' + linters: [ unparam ] - source: 'TODO' linters: [ godot ] - text: 'should have a package comment' diff --git a/cache/lru/lru_internal_test.go b/cache/lru/lru_internal_test.go index c994b82..f6040d4 100644 --- a/cache/lru/lru_internal_test.go +++ b/cache/lru/lru_internal_test.go @@ -1,87 +1,87 @@ package lru import ( - "testing" - "time" + "testing" + "time" - "github.com/benbjohnson/clock" + "github.com/benbjohnson/clock" ) // These tests mirror the MRU-style behavior present in this LRU package // implementation (eviction removes the most-recently-used entry). func TestBasicCacheEviction(t *testing.T) { - mock := clock.NewMock() - c := NewStringKeyCache[int](2) - c.clock = mock + mock := clock.NewMock() + c := NewStringKeyCache[int](2) + c.clock = mock - if err := c.ConsistencyCheck(); err != nil { - t.Fatal(err) - } + if err := c.ConsistencyCheck(); err != nil { + t.Fatal(err) + } - if c.Len() != 0 { - t.Fatal("cache should have size 0") - } + if c.Len() != 0 { + t.Fatal("cache should have size 0") + } - c.evict() - if err := c.ConsistencyCheck(); err != nil { - t.Fatal(err) - } + c.evict() + if err := c.ConsistencyCheck(); err != nil { + t.Fatal(err) + } - c.Store("raven", 1) - if err := c.ConsistencyCheck(); err != nil { - t.Fatal(err) - } + c.Store("raven", 1) + if err := c.ConsistencyCheck(); err != nil { + t.Fatal(err) + } - if len(c.store) != 1 { - t.Fatalf("store should have length=1, have length=%d", len(c.store)) - } + if len(c.store) != 1 { + t.Fatalf("store should have length=1, have length=%d", len(c.store)) + } - mock.Add(time.Second) - c.Store("owl", 2) - if err := c.ConsistencyCheck(); err != nil { - t.Fatal(err) - } + mock.Add(time.Second) + c.Store("owl", 2) + if err := c.ConsistencyCheck(); err != nil { + t.Fatal(err) + } - if len(c.store) != 2 { - t.Fatalf("store should have length=2, have length=%d", len(c.store)) - } + if len(c.store) != 2 { + t.Fatalf("store should have length=2, have length=%d", len(c.store)) + } - mock.Add(time.Second) - c.Store("goat", 3) - if err := c.ConsistencyCheck(); err != nil { - t.Fatal(err) - } + mock.Add(time.Second) + c.Store("goat", 3) + if err := c.ConsistencyCheck(); err != nil { + t.Fatal(err) + } - if len(c.store) != 2 { - t.Fatalf("store should have length=2, have length=%d", len(c.store)) - } + if len(c.store) != 2 { + t.Fatalf("store should have length=2, have length=%d", len(c.store)) + } - // Since this implementation evicts the most-recently-used item, inserting - // "goat" when full evicts "owl" (the most recent at that time). - mock.Add(time.Second) - if _, ok := c.Get("owl"); ok { - t.Fatal("store should not have an entry for owl (MRU-evicted)") - } - if err := c.ConsistencyCheck(); err != nil { - t.Fatal(err) - } + // Since this implementation evicts the most-recently-used item, inserting + // "goat" when full evicts "owl" (the most recent at that time). + mock.Add(time.Second) + if _, ok := c.Get("owl"); ok { + t.Fatal("store should not have an entry for owl (MRU-evicted)") + } + if err := c.ConsistencyCheck(); err != nil { + t.Fatal(err) + } - mock.Add(time.Second) - c.Store("elk", 4) - if err := c.ConsistencyCheck(); err != nil { - t.Fatal(err) - } + mock.Add(time.Second) + c.Store("elk", 4) + if err := c.ConsistencyCheck(); err != nil { + t.Fatal(err) + } - if !c.Has("elk") { - t.Fatal("store should contain an entry for 'elk'") - } + if !c.Has("elk") { + t.Fatal("store should contain an entry for 'elk'") + } - // Before storing elk, keys were: raven (older), goat (newer). Evict MRU -> goat. - if !c.Has("raven") { - t.Fatal("store should contain an entry for 'raven'") - } + // Before storing elk, keys were: raven (older), goat (newer). Evict MRU -> goat. + if !c.Has("raven") { + t.Fatal("store should contain an entry for 'raven'") + } - if c.Has("goat") { - t.Fatal("store should not contain an entry for 'goat'") - } + if c.Has("goat") { + t.Fatal("store should not contain an entry for 'goat'") + } } diff --git a/cache/lru/timestamps_internal_test.go b/cache/lru/timestamps_internal_test.go index 4f9cac6..acbbd85 100644 --- a/cache/lru/timestamps_internal_test.go +++ b/cache/lru/timestamps_internal_test.go @@ -1,50 +1,50 @@ package lru import ( - "testing" - "time" + "testing" + "time" - "github.com/benbjohnson/clock" + "github.com/benbjohnson/clock" ) // These tests validate timestamps ordering semantics for the LRU package. // Note: The LRU timestamps are sorted with most-recent-first (descending by t). func TestTimestamps(t *testing.T) { - ts := newTimestamps[string](3) - mock := clock.NewMock() + ts := newTimestamps[string](3) + mock := clock.NewMock() - // raven - ts.Update("raven", mock.Now().UnixNano()) + // raven + ts.Update("raven", mock.Now().UnixNano()) - // raven, owl - mock.Add(time.Millisecond) - ts.Update("owl", mock.Now().UnixNano()) + // raven, owl + mock.Add(time.Millisecond) + ts.Update("owl", mock.Now().UnixNano()) - // raven, owl, goat - mock.Add(time.Second) - ts.Update("goat", mock.Now().UnixNano()) + // raven, owl, goat + mock.Add(time.Second) + ts.Update("goat", mock.Now().UnixNano()) - if err := ts.ConsistencyCheck(); err != nil { - t.Fatal(err) - } + if err := ts.ConsistencyCheck(); err != nil { + t.Fatal(err) + } - // make owl the most recent - mock.Add(time.Millisecond) - ts.Update("owl", mock.Now().UnixNano()) - if err := ts.ConsistencyCheck(); err != nil { - t.Fatal(err) - } + // make owl the most recent + mock.Add(time.Millisecond) + ts.Update("owl", mock.Now().UnixNano()) + if err := ts.ConsistencyCheck(); err != nil { + t.Fatal(err) + } - // For LRU timestamps: most recent first. Expected order: owl, goat, raven. - if ts.K(0) != "owl" { - t.Fatalf("first key should be owl, have %s", ts.K(0)) - } + // For LRU timestamps: most recent first. Expected order: owl, goat, raven. + if ts.K(0) != "owl" { + t.Fatalf("first key should be owl, have %s", ts.K(0)) + } - if ts.K(1) != "goat" { - t.Fatalf("second key should be goat, have %s", ts.K(1)) - } + if ts.K(1) != "goat" { + t.Fatalf("second key should be goat, have %s", ts.K(1)) + } - if ts.K(2) != "raven" { - t.Fatalf("third key should be raven, have %s", ts.K(2)) - } + if ts.K(2) != "raven" { + t.Fatalf("third key should be raven, have %s", ts.K(2)) + } } diff --git a/cache/mru/mru_internal_test.go b/cache/mru/mru_internal_test.go index 8bb9a5b..0bf639b 100644 --- a/cache/mru/mru_internal_test.go +++ b/cache/mru/mru_internal_test.go @@ -8,9 +8,9 @@ import ( ) func TestBasicCacheEviction(t *testing.T) { - mock := clock.NewMock() - c := NewStringKeyCache[int](2) - c.clock = mock + mock := clock.NewMock() + c := NewStringKeyCache[int](2) + c.clock = mock if err := c.ConsistencyCheck(); err != nil { t.Fatal(err) @@ -55,18 +55,18 @@ func TestBasicCacheEviction(t *testing.T) { } mock.Add(time.Second) - v, ok := c.Get("owl") - if !ok { - t.Fatal("store should have an entry for owl") - } - if err := c.ConsistencyCheck(); err != nil { - t.Fatal(err) - } + v, ok := c.Get("owl") + if !ok { + t.Fatal("store should have an entry for owl") + } + if err := c.ConsistencyCheck(); err != nil { + t.Fatal(err) + } - itm := v - if err := c.ConsistencyCheck(); err != nil { - t.Fatal(err) - } + itm := v + if err := c.ConsistencyCheck(); err != nil { + t.Fatal(err) + } if itm != 2 { t.Fatalf("stored item should be 2, have %d", itm) diff --git a/cache/mru/timestamps_internal_test.go b/cache/mru/timestamps_internal_test.go index 0728480..64e012c 100644 --- a/cache/mru/timestamps_internal_test.go +++ b/cache/mru/timestamps_internal_test.go @@ -8,8 +8,8 @@ import ( ) func TestTimestamps(t *testing.T) { - ts := newTimestamps[string](3) - mock := clock.NewMock() + ts := newTimestamps[string](3) + mock := clock.NewMock() // raven ts.Update("raven", mock.Now().UnixNano()) diff --git a/cmd/cert-revcheck/main.go b/cmd/cert-revcheck/main.go index 037bea7..be467d4 100644 --- a/cmd/cert-revcheck/main.go +++ b/cmd/cert-revcheck/main.go @@ -1,20 +1,21 @@ package main import ( - "crypto/tls" - "crypto/x509" - "errors" - "flag" - "fmt" - "net" - "os" - "strings" - "time" + "context" + "crypto/tls" + "crypto/x509" + "errors" + "flag" + "fmt" + "net" + "os" + "strings" + "time" - "git.wntrmute.dev/kyle/goutils/certlib" - hosts "git.wntrmute.dev/kyle/goutils/certlib/hosts" - "git.wntrmute.dev/kyle/goutils/certlib/revoke" - "git.wntrmute.dev/kyle/goutils/fileutil" + "git.wntrmute.dev/kyle/goutils/certlib" + hosts "git.wntrmute.dev/kyle/goutils/certlib/hosts" + "git.wntrmute.dev/kyle/goutils/certlib/revoke" + "git.wntrmute.dev/kyle/goutils/fileutil" ) var ( @@ -78,17 +79,17 @@ func processTarget(target string) (string, error) { } func checkFile(path string) (string, error) { - // Prefer high-level helpers from certlib to load certificates from disk - if certs, err := certlib.LoadCertificates(path); err == nil && len(certs) > 0 { - // Evaluate the first certificate (leaf) by default - return evaluateCert(certs[0]) - } + // Prefer high-level helpers from certlib to load certificates from disk + if certs, err := certlib.LoadCertificates(path); err == nil && len(certs) > 0 { + // Evaluate the first certificate (leaf) by default + return evaluateCert(certs[0]) + } - cert, err := certlib.LoadCertificate(path) - if err != nil || cert == nil { - return strUnknown, err - } - return evaluateCert(cert) + cert, err := certlib.LoadCertificate(path) + if err != nil || cert == nil { + return strUnknown, err + } + return evaluateCert(cert) } func checkSite(hostport string) (string, error) { @@ -99,18 +100,27 @@ func checkSite(hostport string) (string, error) { } d := &net.Dialer{Timeout: timeout} - conn, err := tls.DialWithDialer( - d, - "tcp", - target.String(), - &tls.Config{InsecureSkipVerify: true, ServerName: target.Host}, // #nosec G402 - ) + tcfg := &tls.Config{ + InsecureSkipVerify: true, + ServerName: target.Host, + } // #nosec G402 -- CLI tool only verifies revocation + td := &tls.Dialer{NetDialer: d, Config: tcfg} + + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + + conn, err := td.DialContext(ctx, "tcp", target.String()) if err != nil { return strUnknown, err } defer conn.Close() - state := conn.ConnectionState() + tconn, ok := conn.(*tls.Conn) + if !ok { + return strUnknown, errors.New("connection is not TLS") + } + + state := tconn.ConnectionState() if len(state.PeerCertificates) == 0 { return strUnknown, errors.New("no peer certificates presented") } @@ -118,23 +128,24 @@ func checkSite(hostport string) (string, error) { } func evaluateCert(cert *x509.Certificate) (string, error) { - // Delegate validity and revocation checks to certlib/revoke helper. - // It returns revoked=true for both revoked and expired/not-yet-valid. - // Map those cases back to our statuses using the returned error text. - revoked, ok, err := revoke.VerifyCertificateError(cert) - if revoked { - if err != nil { - msg := err.Error() - if strings.Contains(msg, "expired") || strings.Contains(msg, "isn't valid until") || strings.Contains(msg, "not valid until") { - return strExpired, err - } - } - return strRevoked, err - } - if !ok { - // Revocation status could not be determined - return strUnknown, err - } + // Delegate validity and revocation checks to certlib/revoke helper. + // It returns revoked=true for both revoked and expired/not-yet-valid. + // Map those cases back to our statuses using the returned error text. + revoked, ok, err := revoke.VerifyCertificateError(cert) + if revoked { + if err != nil { + msg := err.Error() + if strings.Contains(msg, "expired") || strings.Contains(msg, "isn't valid until") || + strings.Contains(msg, "not valid until") { + return strExpired, err + } + } + return strRevoked, err + } + if !ok { + // Revocation status could not be determined + return strUnknown, err + } - return strOK, nil + return strOK, nil } diff --git a/cmd/certchain/certchain.go b/cmd/certchain/main.go similarity index 81% rename from cmd/certchain/certchain.go rename to cmd/certchain/main.go index 45fb44a..097b451 100644 --- a/cmd/certchain/certchain.go +++ b/cmd/certchain/main.go @@ -7,6 +7,7 @@ import ( "fmt" "os" "regexp" + "strings" "git.wntrmute.dev/kyle/goutils/die" ) @@ -27,13 +28,15 @@ func main() { die.If(err) details := conn.ConnectionState() + var chainSb30 strings.Builder for _, cert := range details.PeerCertificates { p := pem.Block{ Type: "CERTIFICATE", Bytes: cert.Raw, } - chain += string(pem.EncodeToMemory(&p)) + chainSb30.WriteString(string(pem.EncodeToMemory(&p))) } + chain += chainSb30.String() fmt.Fprintln(os.Stdout, chain) } diff --git a/cmd/certdump/certdump.go b/cmd/certdump/main.go similarity index 55% rename from cmd/certdump/certdump.go rename to cmd/certdump/main.go index 392353c..4c93371 100644 --- a/cmd/certdump/certdump.go +++ b/cmd/certdump/main.go @@ -1,3 +1,4 @@ +//lint:file-ignore SA1019 allow strict compatibility for old certs package main import ( @@ -101,30 +102,30 @@ func extUsage(ext []x509.ExtKeyUsage) string { } func showBasicConstraints(cert *x509.Certificate) { - fmt.Fprint(os.Stdout, "\tBasic constraints: ") - if cert.BasicConstraintsValid { - fmt.Fprint(os.Stdout, "valid") - } else { - fmt.Fprint(os.Stdout, "invalid") - } + fmt.Fprint(os.Stdout, "\tBasic constraints: ") + if cert.BasicConstraintsValid { + fmt.Fprint(os.Stdout, "valid") + } else { + fmt.Fprint(os.Stdout, "invalid") + } - if cert.IsCA { - fmt.Fprint(os.Stdout, ", is a CA certificate") - if !cert.BasicConstraintsValid { - fmt.Fprint(os.Stdout, " (basic constraint failure)") - } - } else { - fmt.Fprint(os.Stdout, "is not a CA certificate") - if cert.KeyUsage&x509.KeyUsageKeyEncipherment != 0 { - fmt.Fprint(os.Stdout, " (key encipherment usage enabled!)") - } - } + if cert.IsCA { + fmt.Fprint(os.Stdout, ", is a CA certificate") + if !cert.BasicConstraintsValid { + fmt.Fprint(os.Stdout, " (basic constraint failure)") + } + } else { + fmt.Fprint(os.Stdout, "is not a CA certificate") + if cert.KeyUsage&x509.KeyUsageKeyEncipherment != 0 { + fmt.Fprint(os.Stdout, " (key encipherment usage enabled!)") + } + } - if (cert.MaxPathLen == 0 && cert.MaxPathLenZero) || (cert.MaxPathLen > 0) { - fmt.Fprintf(os.Stdout, ", max path length %d", cert.MaxPathLen) - } + if (cert.MaxPathLen == 0 && cert.MaxPathLenZero) || (cert.MaxPathLen > 0) { + fmt.Fprintf(os.Stdout, ", max path length %d", cert.MaxPathLen) + } - fmt.Fprintln(os.Stdout) + fmt.Fprintln(os.Stdout) } const oneTrueDateFormat = "2006-01-02T15:04:05-0700" @@ -135,41 +136,43 @@ var ( ) func wrapPrint(text string, indent int) { - tabs := "" - for i := 0; i < indent; i++ { - tabs += "\t" - } + tabs := "" + var tabsSb140 strings.Builder + for range indent { + tabsSb140.WriteString("\t") + } + tabs += tabsSb140.String() - fmt.Fprintf(os.Stdout, tabs+"%s\n", wrap(text, indent)) + fmt.Fprintf(os.Stdout, tabs+"%s\n", wrap(text, indent)) } func displayCert(cert *x509.Certificate) { - fmt.Fprintln(os.Stdout, "CERTIFICATE") - if showHash { - fmt.Fprintln(os.Stdout, wrap(fmt.Sprintf("SHA256: %x", sha256.Sum256(cert.Raw)), 0)) - } - fmt.Fprintln(os.Stdout, wrap("Subject: "+displayName(cert.Subject), 0)) - fmt.Fprintln(os.Stdout, wrap("Issuer: "+displayName(cert.Issuer), 0)) - fmt.Fprintf(os.Stdout, "\tSignature algorithm: %s / %s\n", sigAlgoPK(cert.SignatureAlgorithm), - sigAlgoHash(cert.SignatureAlgorithm)) - fmt.Fprintln(os.Stdout, "Details:") - wrapPrint("Public key: "+certPublic(cert), 1) - fmt.Fprintf(os.Stdout, "\tSerial number: %s\n", cert.SerialNumber) + fmt.Fprintln(os.Stdout, "CERTIFICATE") + if showHash { + fmt.Fprintln(os.Stdout, wrap(fmt.Sprintf("SHA256: %x", sha256.Sum256(cert.Raw)), 0)) + } + fmt.Fprintln(os.Stdout, wrap("Subject: "+displayName(cert.Subject), 0)) + fmt.Fprintln(os.Stdout, wrap("Issuer: "+displayName(cert.Issuer), 0)) + fmt.Fprintf(os.Stdout, "\tSignature algorithm: %s / %s\n", sigAlgoPK(cert.SignatureAlgorithm), + sigAlgoHash(cert.SignatureAlgorithm)) + fmt.Fprintln(os.Stdout, "Details:") + wrapPrint("Public key: "+certPublic(cert), 1) + fmt.Fprintf(os.Stdout, "\tSerial number: %s\n", cert.SerialNumber) - if len(cert.AuthorityKeyId) > 0 { - fmt.Fprintf(os.Stdout, "\t%s\n", wrap("AKI: "+dumpHex(cert.AuthorityKeyId), 1)) - } - if len(cert.SubjectKeyId) > 0 { - fmt.Fprintf(os.Stdout, "\t%s\n", wrap("SKI: "+dumpHex(cert.SubjectKeyId), 1)) - } + if len(cert.AuthorityKeyId) > 0 { + fmt.Fprintf(os.Stdout, "\t%s\n", wrap("AKI: "+dumpHex(cert.AuthorityKeyId), 1)) + } + if len(cert.SubjectKeyId) > 0 { + fmt.Fprintf(os.Stdout, "\t%s\n", wrap("SKI: "+dumpHex(cert.SubjectKeyId), 1)) + } wrapPrint("Valid from: "+cert.NotBefore.Format(dateFormat), 1) - fmt.Fprintf(os.Stdout, "\t until: %s\n", cert.NotAfter.Format(dateFormat)) - fmt.Fprintf(os.Stdout, "\tKey usages: %s\n", keyUsages(cert.KeyUsage)) + fmt.Fprintf(os.Stdout, "\t until: %s\n", cert.NotAfter.Format(dateFormat)) + fmt.Fprintf(os.Stdout, "\tKey usages: %s\n", keyUsages(cert.KeyUsage)) - if len(cert.ExtKeyUsage) > 0 { - fmt.Fprintf(os.Stdout, "\tExtended usages: %s\n", extUsage(cert.ExtKeyUsage)) - } + if len(cert.ExtKeyUsage) > 0 { + fmt.Fprintf(os.Stdout, "\tExtended usages: %s\n", extUsage(cert.ExtKeyUsage)) + } showBasicConstraints(cert) @@ -217,19 +220,19 @@ func displayCert(cert *x509.Certificate) { } func displayAllCerts(in []byte, leafOnly bool) { - certs, err := certlib.ParseCertificatesPEM(in) - if err != nil { - certs, _, err = certlib.ParseCertificatesDER(in, "") - if err != nil { - _, _ = lib.Warn(err, "failed to parse certificates") - return - } - } + certs, err := certlib.ParseCertificatesPEM(in) + if err != nil { + certs, _, err = certlib.ParseCertificatesDER(in, "") + if err != nil { + _, _ = lib.Warn(err, "failed to parse certificates") + return + } + } if len(certs) == 0 { - _, _ = lib.Warnx("no certificates found") - return - } + _, _ = lib.Warnx("no certificates found") + return + } if leafOnly { displayCert(certs[0]) @@ -243,11 +246,11 @@ func displayAllCerts(in []byte, leafOnly bool) { func displayAllCertsWeb(uri string, leafOnly bool) { ci := getConnInfo(uri) - conn, err := tls.Dial("tcp", ci.Addr, permissiveConfig()) - if err != nil { - _, _ = lib.Warn(err, "couldn't connect to %s", ci.Addr) - return - } + conn, err := tls.Dial("tcp", ci.Addr, permissiveConfig()) + if err != nil { + _, _ = lib.Warn(err, "couldn't connect to %s", ci.Addr) + return + } defer conn.Close() state := conn.ConnectionState() @@ -260,34 +263,34 @@ func displayAllCertsWeb(uri string, leafOnly bool) { state = conn.ConnectionState() } conn.Close() - } else { - _, _ = lib.Warn(err, "TLS verification error with server name %s", ci.Host) - } + } else { + _, _ = lib.Warn(err, "TLS verification error with server name %s", ci.Host) + } - if len(state.PeerCertificates) == 0 { - _, _ = lib.Warnx("no certificates found") - return - } + if len(state.PeerCertificates) == 0 { + _, _ = lib.Warnx("no certificates found") + return + } if leafOnly { displayCert(state.PeerCertificates[0]) return } - if len(state.VerifiedChains) == 0 { - _, _ = lib.Warnx("no verified chains found; using peer chain") - for i := range state.PeerCertificates { - displayCert(state.PeerCertificates[i]) - } - } else { - fmt.Fprintln(os.Stdout, "TLS chain verified successfully.") - for i := range state.VerifiedChains { - fmt.Fprintf(os.Stdout, "--- Verified certificate chain %d ---%s", i+1, "\n") - for j := range state.VerifiedChains[i] { - displayCert(state.VerifiedChains[i][j]) - } - } - } + if len(state.VerifiedChains) == 0 { + _, _ = lib.Warnx("no verified chains found; using peer chain") + for i := range state.PeerCertificates { + displayCert(state.PeerCertificates[i]) + } + } else { + fmt.Fprintln(os.Stdout, "TLS chain verified successfully.") + for i := range state.VerifiedChains { + fmt.Fprintf(os.Stdout, "--- Verified certificate chain %d ---%s", i+1, "\n") + for j := range state.VerifiedChains[i] { + displayCert(state.VerifiedChains[i][j]) + } + } + } } func main() { @@ -298,28 +301,28 @@ func main() { flag.Parse() if flag.NArg() == 0 || (flag.NArg() == 1 && flag.Arg(0) == "-") { - certs, err := io.ReadAll(os.Stdin) - if err != nil { - _, _ = lib.Warn(err, "couldn't read certificates from standard input") - os.Exit(1) - } + certs, err := io.ReadAll(os.Stdin) + if err != nil { + _, _ = lib.Warn(err, "couldn't read certificates from standard input") + os.Exit(1) + } // This is needed for getting certs from JSON/jq. certs = bytes.TrimSpace(certs) - certs = bytes.Replace(certs, []byte(`\n`), []byte{0xa}, -1) + certs = bytes.ReplaceAll(certs, []byte(`\n`), []byte{0xa}) certs = bytes.Trim(certs, `"`) displayAllCerts(certs, leafOnly) } else { for _, filename := range flag.Args() { - fmt.Fprintf(os.Stdout, "--%s ---%s", filename, "\n") + fmt.Fprintf(os.Stdout, "--%s ---%s", filename, "\n") if strings.HasPrefix(filename, "https://") { displayAllCertsWeb(filename, leafOnly) } else { - in, err := os.ReadFile(filename) - if err != nil { - _, _ = lib.Warn(err, "couldn't read certificate") - continue - } + in, err := os.ReadFile(filename) + if err != nil { + _, _ = lib.Warn(err, "couldn't read certificate") + continue + } displayAllCerts(in, leafOnly) } diff --git a/cmd/certdump/util.go b/cmd/certdump/util.go index f4c818d..3b104d0 100644 --- a/cmd/certdump/util.go +++ b/cmd/certdump/util.go @@ -26,94 +26,79 @@ var keyUsage = map[x509.KeyUsage]string{ } var extKeyUsages = map[x509.ExtKeyUsage]string{ - x509.ExtKeyUsageAny: "any", - x509.ExtKeyUsageServerAuth: "server auth", - x509.ExtKeyUsageClientAuth: "client auth", - x509.ExtKeyUsageCodeSigning: "code signing", - x509.ExtKeyUsageEmailProtection: "s/mime", - x509.ExtKeyUsageIPSECEndSystem: "ipsec end system", - x509.ExtKeyUsageIPSECTunnel: "ipsec tunnel", - x509.ExtKeyUsageIPSECUser: "ipsec user", - x509.ExtKeyUsageTimeStamping: "timestamping", - x509.ExtKeyUsageOCSPSigning: "ocsp signing", - x509.ExtKeyUsageMicrosoftServerGatedCrypto: "microsoft sgc", - x509.ExtKeyUsageNetscapeServerGatedCrypto: "netscape sgc", - x509.ExtKeyUsageMicrosoftCommercialCodeSigning: "microsoft commercial code signing", - x509.ExtKeyUsageMicrosoftKernelCodeSigning: "microsoft kernel code signing", -} - -func pubKeyAlgo(a x509.PublicKeyAlgorithm) string { - switch a { - case x509.UnknownPublicKeyAlgorithm: - return "unknown public key algorithm" - case x509.RSA: - return "RSA" - case x509.ECDSA: - return "ECDSA" - case x509.DSA: - return "DSA" - case x509.Ed25519: - return "Ed25519" - default: - return "unknown public key algorithm" - } + x509.ExtKeyUsageAny: "any", + x509.ExtKeyUsageServerAuth: "server auth", + x509.ExtKeyUsageClientAuth: "client auth", + x509.ExtKeyUsageCodeSigning: "code signing", + x509.ExtKeyUsageEmailProtection: "s/mime", + x509.ExtKeyUsageIPSECEndSystem: "ipsec end system", + x509.ExtKeyUsageIPSECTunnel: "ipsec tunnel", + x509.ExtKeyUsageIPSECUser: "ipsec user", + x509.ExtKeyUsageTimeStamping: "timestamping", + x509.ExtKeyUsageOCSPSigning: "ocsp signing", + x509.ExtKeyUsageMicrosoftServerGatedCrypto: "microsoft sgc", + x509.ExtKeyUsageNetscapeServerGatedCrypto: "netscape sgc", + x509.ExtKeyUsageMicrosoftCommercialCodeSigning: "microsoft commercial code signing", + x509.ExtKeyUsageMicrosoftKernelCodeSigning: "microsoft kernel code signing", } func sigAlgoPK(a x509.SignatureAlgorithm) string { - switch a { - case x509.MD2WithRSA, x509.MD5WithRSA, x509.SHA1WithRSA, x509.SHA256WithRSA, x509.SHA384WithRSA, x509.SHA512WithRSA: - return "RSA" - case x509.SHA256WithRSAPSS, x509.SHA384WithRSAPSS, x509.SHA512WithRSAPSS: - return "RSA-PSS" - case x509.ECDSAWithSHA1, x509.ECDSAWithSHA256, x509.ECDSAWithSHA384, x509.ECDSAWithSHA512: - return "ECDSA" - case x509.DSAWithSHA1, x509.DSAWithSHA256: - return "DSA" - case x509.PureEd25519: - return "Ed25519" - case x509.UnknownSignatureAlgorithm: - return "unknown public key algorithm" - default: - return "unknown public key algorithm" - } + switch a { + case x509.MD2WithRSA, x509.MD5WithRSA, x509.SHA1WithRSA, x509.SHA256WithRSA, x509.SHA384WithRSA, x509.SHA512WithRSA: + return "RSA" + case x509.SHA256WithRSAPSS, x509.SHA384WithRSAPSS, x509.SHA512WithRSAPSS: + return "RSA-PSS" + case x509.ECDSAWithSHA1, x509.ECDSAWithSHA256, x509.ECDSAWithSHA384, x509.ECDSAWithSHA512: + return "ECDSA" + case x509.DSAWithSHA1, x509.DSAWithSHA256: + return "DSA" + case x509.PureEd25519: + return "Ed25519" + case x509.UnknownSignatureAlgorithm: + return "unknown public key algorithm" + default: + return "unknown public key algorithm" + } } func sigAlgoHash(a x509.SignatureAlgorithm) string { - switch a { - case x509.MD2WithRSA: - return "MD2" - case x509.MD5WithRSA: - return "MD5" - case x509.SHA1WithRSA, x509.ECDSAWithSHA1, x509.DSAWithSHA1: - return "SHA1" - case x509.SHA256WithRSA, x509.ECDSAWithSHA256, x509.DSAWithSHA256: - return "SHA256" - case x509.SHA256WithRSAPSS: - return "SHA256" - case x509.SHA384WithRSA, x509.ECDSAWithSHA384: - return "SHA384" - case x509.SHA384WithRSAPSS: - return "SHA384" - case x509.SHA512WithRSA, x509.ECDSAWithSHA512: - return "SHA512" - case x509.SHA512WithRSAPSS: - return "SHA512" - case x509.PureEd25519: - return "SHA512" - case x509.UnknownSignatureAlgorithm: - return "unknown hash algorithm" - default: - return "unknown hash algorithm" - } + switch a { + case x509.MD2WithRSA: + return "MD2" + case x509.MD5WithRSA: + return "MD5" + case x509.SHA1WithRSA, x509.ECDSAWithSHA1, x509.DSAWithSHA1: + return "SHA1" + case x509.SHA256WithRSA, x509.ECDSAWithSHA256, x509.DSAWithSHA256: + return "SHA256" + case x509.SHA256WithRSAPSS: + return "SHA256" + case x509.SHA384WithRSA, x509.ECDSAWithSHA384: + return "SHA384" + case x509.SHA384WithRSAPSS: + return "SHA384" + case x509.SHA512WithRSA, x509.ECDSAWithSHA512: + return "SHA512" + case x509.SHA512WithRSAPSS: + return "SHA512" + case x509.PureEd25519: + return "SHA512" + case x509.UnknownSignatureAlgorithm: + return "unknown hash algorithm" + default: + return "unknown hash algorithm" + } } const maxLine = 78 func makeIndent(n int) string { s := " " - for i := 0; i < n; i++ { - s += " " + var sSb97 strings.Builder + for range n { + sSb97.WriteString(" ") } + s += sSb97.String() return s } @@ -121,7 +106,7 @@ func indentLen(n int) int { return 4 + (8 * n) } -// this isn't real efficient, but that's not a problem here +// this isn't real efficient, but that's not a problem here. func wrap(s string, indent int) string { if indent > 3 { indent = 3 @@ -144,9 +129,11 @@ func wrap(s string, indent int) string { func dumpHex(in []byte) string { var s string + var sSb130 strings.Builder for i := range in { - s += fmt.Sprintf("%02X:", in[i]) + sSb130.WriteString(fmt.Sprintf("%02X:", in[i])) } + s += sSb130.String() return strings.Trim(s, ":") } diff --git a/cmd/certexpiry/main.go b/cmd/certexpiry/main.go index c0ed5c7..a604fb2 100644 --- a/cmd/certexpiry/main.go +++ b/cmd/certexpiry/main.go @@ -1,17 +1,17 @@ package main import ( - "crypto/x509" - "crypto/x509/pkix" - "flag" - "fmt" - "os" - "strings" - "time" + "crypto/x509" + "crypto/x509/pkix" + "flag" + "fmt" + "os" + "strings" + "time" - "git.wntrmute.dev/kyle/goutils/certlib" - "git.wntrmute.dev/kyle/goutils/die" - "git.wntrmute.dev/kyle/goutils/lib" + "git.wntrmute.dev/kyle/goutils/certlib" + "git.wntrmute.dev/kyle/goutils/die" + "git.wntrmute.dev/kyle/goutils/lib" ) var warnOnly bool @@ -53,7 +53,7 @@ func displayName(name pkix.Name) string { } func expires(cert *x509.Certificate) time.Duration { - return cert.NotAfter.Sub(time.Now()) + return time.Until(cert.NotAfter) } func inDanger(cert *x509.Certificate) bool { @@ -79,21 +79,21 @@ func main() { flag.DurationVar(&leeway, "t", leeway, "warn if certificates are closer than this to expiring") flag.Parse() - for _, file := range flag.Args() { - in, err := os.ReadFile(file) - if err != nil { - _, _ = lib.Warn(err, "failed to read file") - continue - } + for _, file := range flag.Args() { + in, err := os.ReadFile(file) + if err != nil { + _, _ = lib.Warn(err, "failed to read file") + continue + } - certs, err := certlib.ParseCertificatesPEM(in) - if err != nil { - _, _ = lib.Warn(err, "while parsing certificates") - continue - } + certs, err := certlib.ParseCertificatesPEM(in) + if err != nil { + _, _ = lib.Warn(err, "while parsing certificates") + continue + } - for _, cert := range certs { - checkCert(cert) - } - } + for _, cert := range certs { + checkCert(cert) + } + } } diff --git a/cmd/certverify/main.go b/cmd/certverify/main.go index 3f64992..a78cd6b 100644 --- a/cmd/certverify/main.go +++ b/cmd/certverify/main.go @@ -4,7 +4,6 @@ import ( "crypto/x509" "flag" "fmt" - "io/ioutil" "os" "time" @@ -68,7 +67,7 @@ func main() { lib.ProgName()) } - fileData, err := ioutil.ReadFile(flag.Arg(0)) + fileData, err := os.ReadFile(flag.Arg(0)) die.If(err) chain, err := certlib.ParseCertificatesPEM(fileData) diff --git a/cmd/clustersh/main.go b/cmd/clustersh/main.go index f168b8f..1f8abfd 100644 --- a/cmd/clustersh/main.go +++ b/cmd/clustersh/main.go @@ -1,16 +1,16 @@ package main import ( - "bufio" - "flag" - "fmt" - "io" - "errors" - "log" - "net" - "os" - "strings" - "sync" + "bufio" + "errors" + "flag" + "fmt" + "io" + "log" + "net" + "os" + "strings" + "sync" "git.wntrmute.dev/kyle/goutils/lib" "github.com/pkg/sftp" @@ -83,7 +83,7 @@ func scanner(host string, in io.Reader, out io.Writer) { } } -func logError(host string, err error, format string, args ...interface{}) { +func logError(host string, err error, format string, args ...any) { msg := fmt.Sprintf(format, args...) log.Printf("[%s] FAILED: %s: %v\n", host, msg, err) } @@ -93,12 +93,12 @@ func exec(wg *sync.WaitGroup, user, host string, commands []string) { defer func() { for i := len(shutdown) - 1; i >= 0; i-- { - err := shutdown[i]() - if err != nil && !errors.Is(err, io.EOF) { - logError(host, err, "shutting down") - } - } - }() + err := shutdown[i]() + if err != nil && !errors.Is(err, io.EOF) { + logError(host, err, "shutting down") + } + } + }() defer wg.Done() conf := sshConfig(user) @@ -150,12 +150,12 @@ func upload(wg *sync.WaitGroup, user, host, local, remote string) { defer func() { for i := len(shutdown) - 1; i >= 0; i-- { - err := shutdown[i]() - if err != nil && !errors.Is(err, io.EOF) { - logError(host, err, "shutting down") - } - } - }() + err := shutdown[i]() + if err != nil && !errors.Is(err, io.EOF) { + logError(host, err, "shutting down") + } + } + }() defer wg.Done() conf := sshConfig(user) @@ -200,13 +200,13 @@ func upload(wg *sync.WaitGroup, user, host, local, remote string) { fmt.Printf("[%s] wrote %d-byte chunk\n", host, n) } - if errors.Is(err, io.EOF) { - break - } else if err != nil { - logError(host, err, "reading chunk") - return - } - } + if errors.Is(err, io.EOF) { + break + } else if err != nil { + logError(host, err, "reading chunk") + return + } + } fmt.Printf("[%s] %s uploaded to %s\n", host, remote, local) } @@ -215,12 +215,12 @@ func download(wg *sync.WaitGroup, user, host, local, remote string) { defer func() { for i := len(shutdown) - 1; i >= 0; i-- { - err := shutdown[i]() - if err != nil && !errors.Is(err, io.EOF) { - logError(host, err, "shutting down") - } - } - }() + err := shutdown[i]() + if err != nil && !errors.Is(err, io.EOF) { + logError(host, err, "shutting down") + } + } + }() defer wg.Done() conf := sshConfig(user) @@ -266,12 +266,12 @@ func download(wg *sync.WaitGroup, user, host, local, remote string) { fmt.Printf("[%s] wrote %d-byte chunk\n", host, n) } - if errors.Is(err, io.EOF) { - break - } else if err != nil { - logError(host, err, "reading chunk") - return - } + if errors.Is(err, io.EOF) { + break + } else if err != nil { + logError(host, err, "reading chunk") + return + } } fmt.Printf("[%s] %s downloaded to %s\n", host, remote, local) } diff --git a/cmd/cruntar/main.go b/cmd/cruntar/main.go index c6ea64e..9b43cd1 100644 --- a/cmd/cruntar/main.go +++ b/cmd/cruntar/main.go @@ -262,15 +262,14 @@ func main() { tfr := tar.NewReader(r) for { - hdr, err := tfr.Next() - if errors.Is(err, io.EOF) { - break - } - die.If(err) + hdr, err := tfr.Next() + if errors.Is(err, io.EOF) { + break + } + die.If(err) err = processFile(tfr, hdr, top) die.If(err) - } r.Close() diff --git a/cmd/csrpubdump/pubdump.go b/cmd/csrpubdump/main.go similarity index 85% rename from cmd/csrpubdump/pubdump.go rename to cmd/csrpubdump/main.go index a608621..7aca42b 100644 --- a/cmd/csrpubdump/pubdump.go +++ b/cmd/csrpubdump/main.go @@ -47,8 +47,8 @@ func main() { Bytes: out, } - err = os.WriteFile(fileName+".pub", pem.EncodeToMemory(p), 0o644) - die.If(err) - fmt.Fprintf(os.Stdout, "[+] wrote %s.\n", fileName+".pub") + err = os.WriteFile(fileName+".pub", pem.EncodeToMemory(p), 0o644) + die.If(err) + fmt.Fprintf(os.Stdout, "[+] wrote %s.\n", fileName+".pub") } } diff --git a/cmd/data_sync/main.go b/cmd/data_sync/main.go index d752172..016e3d0 100644 --- a/cmd/data_sync/main.go +++ b/cmd/data_sync/main.go @@ -163,7 +163,6 @@ func init() { } func main() { - var logLevel, mountDir, syncDir, target string var dryRun, quietMode, noSyslog, verboseRsync bool diff --git a/cmd/diskimg/main.go b/cmd/diskimg/main.go index f73cb62..bda07aa 100644 --- a/cmd/diskimg/main.go +++ b/cmd/diskimg/main.go @@ -15,43 +15,41 @@ import ( const defaultHashAlgorithm = "sha256" var ( - hAlgo string + hAlgo string debug = dbg.New() ) - -func openImage(imageFile string) (image *os.File, hash []byte, err error) { - image, err = os.Open(imageFile) +func openImage(imageFile string) (*os.File, []byte, error) { + f, err := os.Open(imageFile) if err != nil { - return + return nil, nil, err } - hash, err = ahash.SumReader(hAlgo, image) + h, err := ahash.SumReader(hAlgo, f) if err != nil { - return + return nil, nil, err } - _, err = image.Seek(0, 0) - if err != nil { - return + if _, err := f.Seek(0, 0); err != nil { + return nil, nil, err } - debug.Printf("%s %x\n", imageFile, hash) - return + debug.Printf("%s %x\n", imageFile, h) + return f, h, nil } -func openDevice(devicePath string) (device *os.File, err error) { +func openDevice(devicePath string) (*os.File, error) { fi, err := os.Stat(devicePath) if err != nil { - return + return nil, err } - device, err = os.OpenFile(devicePath, os.O_RDWR|os.O_SYNC, fi.Mode()) + device, err := os.OpenFile(devicePath, os.O_RDWR|os.O_SYNC, fi.Mode()) if err != nil { - return + return nil, err } - return + return device, nil } func main() { diff --git a/cmd/dumpbytes/main.go b/cmd/dumpbytes/main.go index defccbc..114d538 100644 --- a/cmd/dumpbytes/main.go +++ b/cmd/dumpbytes/main.go @@ -3,28 +3,30 @@ package main import ( "flag" "fmt" - "git.wntrmute.dev/kyle/goutils/die" "io" "os" + "strings" + + "git.wntrmute.dev/kyle/goutils/die" ) func usage(w io.Writer, exc int) { - fmt.Fprintln(w, `usage: dumpbytes `) + fmt.Fprintln(w, `usage: dumpbytes -n tabs `) os.Exit(exc) } func printBytes(buf []byte) { fmt.Printf("\t") - for i := 0; i < len(buf); i++ { + for i := range buf { fmt.Printf("0x%02x, ", buf[i]) } fmt.Println() } func dumpFile(path string, indentLevel int) error { - indent := "" - for i := 0; i < indentLevel; i++ { - indent += "\t" + var indent strings.Builder + for range indentLevel { + indent.WriteByte('\t') } file, err := os.Open(path) @@ -34,13 +36,13 @@ func dumpFile(path string, indentLevel int) error { defer file.Close() - fmt.Printf("%svar buffer = []byte{\n", indent) + fmt.Printf("%svar buffer = []byte{\n", indent.String()) for { buf := make([]byte, 8) n, err := file.Read(buf) if err == io.EOF { if n > 0 { - fmt.Printf("%s", indent) + fmt.Printf("%s", indent.String()) printBytes(buf[:n]) } break @@ -50,11 +52,11 @@ func dumpFile(path string, indentLevel int) error { return err } - fmt.Printf("%s", indent) + fmt.Printf("%s", indent.String()) printBytes(buf[:n]) } - fmt.Printf("%s}\n", indent) + fmt.Printf("%s}\n", indent.String()) return nil } diff --git a/cmd/eig/main.go b/cmd/eig/main.go index 583d897..18354ab 100644 --- a/cmd/eig/main.go +++ b/cmd/eig/main.go @@ -7,7 +7,7 @@ import ( "git.wntrmute.dev/kyle/goutils/die" ) -// size of a kilobit in bytes +// size of a kilobit in bytes. const kilobit = 128 const pageSize = 4096 @@ -29,7 +29,7 @@ func main() { fillByte := uint8(*fill) buf := make([]byte, pageSize) - for i := 0; i < pageSize; i++ { + for i := range pageSize { buf[i] = fillByte } @@ -40,7 +40,7 @@ func main() { die.If(err) defer file.Close() - for i := 0; i < pages; i++ { + for range pages { _, err = file.Write(buf) die.If(err) } diff --git a/cmd/fragment/fragment.go b/cmd/fragment/main.go similarity index 85% rename from cmd/fragment/fragment.go rename to cmd/fragment/main.go index c64fe69..db1495e 100644 --- a/cmd/fragment/fragment.go +++ b/cmd/fragment/main.go @@ -80,7 +80,7 @@ func main() { var fmtStr string if !*quiet { - maxLine := fmt.Sprintf("%d", len(lines)) + maxLine := strconv.Itoa(len(lines)) fmtStr = fmt.Sprintf("%%0%dd: %%s", len(maxLine)) } @@ -95,12 +95,12 @@ func main() { return false } - fmtStr += "\n" - for i := start; !endFunc(i); i++ { - if *quiet { - fmt.Fprintln(os.Stdout, lines[i]) - } else { - fmt.Fprintf(os.Stdout, fmtStr, i, lines[i]) - } - } + fmtStr += "\n" + for i := start; !endFunc(i); i++ { + if *quiet { + fmt.Fprintln(os.Stdout, lines[i]) + } else { + fmt.Fprintf(os.Stdout, fmtStr, i, lines[i]) + } + } } diff --git a/cmd/jlp/jlp.go b/cmd/jlp/main.go similarity index 51% rename from cmd/jlp/jlp.go rename to cmd/jlp/main.go index 49b1c62..1293242 100644 --- a/cmd/jlp/jlp.go +++ b/cmd/jlp/main.go @@ -1,51 +1,51 @@ package main import ( - "bytes" - "encoding/json" - "flag" - "fmt" - "io" - "os" + "bytes" + "encoding/json" + "flag" + "fmt" + "io" + "os" - "git.wntrmute.dev/kyle/goutils/lib" + "git.wntrmute.dev/kyle/goutils/lib" ) func prettify(file string, validateOnly bool) error { var in []byte var err error - if file == "-" { - in, err = io.ReadAll(os.Stdin) - } else { - in, err = os.ReadFile(file) - } + if file == "-" { + in, err = io.ReadAll(os.Stdin) + } else { + in, err = os.ReadFile(file) + } - if err != nil { - _, _ = lib.Warn(err, "ReadFile") - return err - } + if err != nil { + _, _ = lib.Warn(err, "ReadFile") + return err + } var buf = &bytes.Buffer{} err = json.Indent(buf, in, "", " ") - if err != nil { - _, _ = lib.Warn(err, "%s", file) - return err - } + if err != nil { + _, _ = lib.Warn(err, "%s", file) + return err + } if validateOnly { return nil } - if file == "-" { - _, err = os.Stdout.Write(buf.Bytes()) - } else { - err = os.WriteFile(file, buf.Bytes(), 0o644) - } + if file == "-" { + _, err = os.Stdout.Write(buf.Bytes()) + } else { + err = os.WriteFile(file, buf.Bytes(), 0o644) + } - if err != nil { - _, _ = lib.Warn(err, "WriteFile") - } + if err != nil { + _, _ = lib.Warn(err, "WriteFile") + } return err } @@ -54,44 +54,44 @@ func compact(file string, validateOnly bool) error { var in []byte var err error - if file == "-" { - in, err = io.ReadAll(os.Stdin) - } else { - in, err = os.ReadFile(file) - } + if file == "-" { + in, err = io.ReadAll(os.Stdin) + } else { + in, err = os.ReadFile(file) + } - if err != nil { - _, _ = lib.Warn(err, "ReadFile") - return err - } + if err != nil { + _, _ = lib.Warn(err, "ReadFile") + return err + } var buf = &bytes.Buffer{} err = json.Compact(buf, in) - if err != nil { - _, _ = lib.Warn(err, "%s", file) - return err - } + if err != nil { + _, _ = lib.Warn(err, "%s", file) + return err + } if validateOnly { return nil } - if file == "-" { - _, err = os.Stdout.Write(buf.Bytes()) - } else { - err = os.WriteFile(file, buf.Bytes(), 0o644) - } + if file == "-" { + _, err = os.Stdout.Write(buf.Bytes()) + } else { + err = os.WriteFile(file, buf.Bytes(), 0o644) + } - if err != nil { - _, _ = lib.Warn(err, "WriteFile") - } + if err != nil { + _, _ = lib.Warn(err, "WriteFile") + } return err } func usage() { - progname := lib.ProgName() - fmt.Fprintf(os.Stdout, `Usage: %s [-h] files... + progname := lib.ProgName() + fmt.Fprintf(os.Stdout, `Usage: %s [-h] files... %s is used to lint and prettify (or compact) JSON files. The files will be updated in-place. @@ -100,7 +100,6 @@ func usage() { -h Print this help message. -n Don't prettify; only perform validation. `, progname, progname) - } func init() { diff --git a/cmd/kgz/main.go b/cmd/kgz/main.go index c7e915b..2215769 100644 --- a/cmd/kgz/main.go +++ b/cmd/kgz/main.go @@ -1,68 +1,68 @@ package main import ( - "compress/flate" - "compress/gzip" - "flag" - "fmt" - "io" - "os" - "path/filepath" - "strings" + "compress/flate" + "compress/gzip" + "flag" + "fmt" + "io" + "os" + "path/filepath" + "strings" ) const gzipExt = ".gz" func compress(path, target string, level int) error { - sourceFile, err := os.Open(path) - if err != nil { - return fmt.Errorf("opening file for read: %w", err) - } + sourceFile, err := os.Open(path) + if err != nil { + return fmt.Errorf("opening file for read: %w", err) + } defer sourceFile.Close() - destFile, err := os.Create(target) - if err != nil { - return fmt.Errorf("opening file for write: %w", err) - } + destFile, err := os.Create(target) + if err != nil { + return fmt.Errorf("opening file for write: %w", err) + } defer destFile.Close() - gzipCompressor, err := gzip.NewWriterLevel(destFile, level) - if err != nil { - return fmt.Errorf("invalid compression level: %w", err) - } + gzipCompressor, err := gzip.NewWriterLevel(destFile, level) + if err != nil { + return fmt.Errorf("invalid compression level: %w", err) + } defer gzipCompressor.Close() - _, err = io.Copy(gzipCompressor, sourceFile) - if err != nil { - return fmt.Errorf("compressing file: %w", err) - } + _, err = io.Copy(gzipCompressor, sourceFile) + if err != nil { + return fmt.Errorf("compressing file: %w", err) + } return nil } func uncompress(path, target string) error { - sourceFile, err := os.Open(path) - if err != nil { - return fmt.Errorf("opening file for read: %w", err) - } + sourceFile, err := os.Open(path) + if err != nil { + return fmt.Errorf("opening file for read: %w", err) + } defer sourceFile.Close() - gzipUncompressor, err := gzip.NewReader(sourceFile) - if err != nil { - return fmt.Errorf("reading gzip headers: %w", err) - } + gzipUncompressor, err := gzip.NewReader(sourceFile) + if err != nil { + return fmt.Errorf("reading gzip headers: %w", err) + } defer gzipUncompressor.Close() - destFile, err := os.Create(target) - if err != nil { - return fmt.Errorf("opening file for write: %w", err) - } + destFile, err := os.Create(target) + if err != nil { + return fmt.Errorf("opening file for write: %w", err) + } defer destFile.Close() - _, err = io.Copy(destFile, gzipUncompressor) - if err != nil { - return fmt.Errorf("uncompressing file: %w", err) - } + _, err = io.Copy(destFile, gzipUncompressor) + if err != nil { + return fmt.Errorf("uncompressing file: %w", err) + } return nil } @@ -106,9 +106,9 @@ func pathForUncompressing(source, dest string) (string, error) { } source = filepath.Base(source) - if !strings.HasSuffix(source, gzipExt) { - return "", fmt.Errorf("%s is a not gzip-compressed file", source) - } + if !strings.HasSuffix(source, gzipExt) { + return "", fmt.Errorf("%s is a not gzip-compressed file", source) + } outFile := source[:len(source)-len(gzipExt)] outFile = filepath.Join(dest, outFile) return outFile, nil @@ -120,9 +120,9 @@ func pathForCompressing(source, dest string) (string, error) { } source = filepath.Base(source) - if strings.HasSuffix(source, gzipExt) { - return "", fmt.Errorf("%s is a gzip-compressed file", source) - } + if strings.HasSuffix(source, gzipExt) { + return "", fmt.Errorf("%s is a gzip-compressed file", source) + } dest = filepath.Join(dest, source+gzipExt) return dest, nil diff --git a/cmd/minmax/minmax.go b/cmd/minmax/main.go similarity index 74% rename from cmd/minmax/minmax.go rename to cmd/minmax/main.go index d369d88..0ece1d6 100644 --- a/cmd/minmax/minmax.go +++ b/cmd/minmax/main.go @@ -40,14 +40,14 @@ func main() { usage() } - min, err := strconv.Atoi(flag.Arg(1)) + minVal, err := strconv.Atoi(flag.Arg(1)) dieIf(err) - max, err := strconv.Atoi(flag.Arg(2)) + maxVal, err := strconv.Atoi(flag.Arg(2)) dieIf(err) - code := kind << 6 - code += (min << 3) - code += max - fmt.Fprintf(os.Stdout, "%0o\n", code) + code := kind << 6 + code += (minVal << 3) + code += maxVal + fmt.Fprintf(os.Stdout, "%0o\n", code) } diff --git a/cmd/parts/main.go b/cmd/parts/main.go index 83ac2fe..1466960 100644 --- a/cmd/parts/main.go +++ b/cmd/parts/main.go @@ -5,7 +5,6 @@ import ( "flag" "fmt" "io" - "io/ioutil" "os" "path/filepath" "sort" @@ -47,7 +46,7 @@ func help(w io.Writer) { } func loadDatabase() { - data, err := ioutil.ReadFile(dbFile) + data, err := os.ReadFile(dbFile) if err != nil && os.IsNotExist(err) { partsDB = &database{ Version: dbVersion, @@ -74,7 +73,7 @@ func writeDB() { data, err := json.Marshal(partsDB) die.If(err) - err = ioutil.WriteFile(dbFile, data, 0644) + err = os.WriteFile(dbFile, data, 0644) die.If(err) } diff --git a/cmd/pem2bin/main.go b/cmd/pem2bin/main.go index b7594a8..e3570bc 100644 --- a/cmd/pem2bin/main.go +++ b/cmd/pem2bin/main.go @@ -4,14 +4,13 @@ import ( "encoding/pem" "flag" "fmt" - "io/ioutil" "os" ) var ext = ".bin" func stripPEM(path string) error { - data, err := ioutil.ReadFile(path) + data, err := os.ReadFile(path) if err != nil { return err } @@ -22,7 +21,7 @@ func stripPEM(path string) error { fmt.Fprintf(os.Stderr, " (only the first object will be decoded)\n") } - return ioutil.WriteFile(path+ext, p.Bytes, 0644) + return os.WriteFile(path+ext, p.Bytes, 0644) } func main() { diff --git a/cmd/pembody/pembody.go b/cmd/pembody/main.go similarity index 50% rename from cmd/pembody/pembody.go rename to cmd/pembody/main.go index f885531..b7b6b01 100644 --- a/cmd/pembody/pembody.go +++ b/cmd/pembody/main.go @@ -18,21 +18,21 @@ func main() { var in []byte var err error - path := flag.Arg(0) - if path == "-" { - in, err = io.ReadAll(os.Stdin) - } else { - in, err = os.ReadFile(flag.Arg(0)) - } + path := flag.Arg(0) + if path == "-" { + in, err = io.ReadAll(os.Stdin) + } else { + in, err = os.ReadFile(flag.Arg(0)) + } if err != nil { lib.Err(lib.ExitFailure, err, "couldn't read file") } p, _ := pem.Decode(in) - if p == nil { - lib.Errx(lib.ExitFailure, "%s isn't a PEM-encoded file", flag.Arg(0)) - } - if _, err := os.Stdout.Write(p.Bytes); err != nil { - lib.Err(lib.ExitFailure, err, "writing body") - } + if p == nil { + lib.Errx(lib.ExitFailure, "%s isn't a PEM-encoded file", flag.Arg(0)) + } + if _, err := os.Stdout.Write(p.Bytes); err != nil { + lib.Err(lib.ExitFailure, err, "writing body") + } } diff --git a/cmd/pemit/main.go b/cmd/pemit/main.go index 094aee7..b56b3e3 100644 --- a/cmd/pemit/main.go +++ b/cmd/pemit/main.go @@ -70,7 +70,7 @@ func main() { lib.Err(lib.ExitFailure, err, "failed to read input") } case argc > 1: - for i := 0; i < argc; i++ { + for i := range argc { path := flag.Arg(i) err = copyFile(path, buf) if err != nil { diff --git a/cmd/readchain/chain.go b/cmd/readchain/main.go similarity index 64% rename from cmd/readchain/chain.go rename to cmd/readchain/main.go index 89d5b4d..8809611 100644 --- a/cmd/readchain/chain.go +++ b/cmd/readchain/main.go @@ -1,25 +1,25 @@ package main import ( - "crypto/x509" - "encoding/pem" - "flag" - "fmt" - "os" + "crypto/x509" + "encoding/pem" + "flag" + "fmt" + "os" ) func main() { flag.Parse() for _, fileName := range flag.Args() { - data, err := os.ReadFile(fileName) + data, err := os.ReadFile(fileName) if err != nil { fmt.Fprintf(os.Stderr, "[!] %s: %v\n", fileName, err) continue } - fmt.Fprintf(os.Stdout, "[+] %s:\n", fileName) - rest := data[:] + fmt.Fprintf(os.Stdout, "[+] %s:\n", fileName) + rest := data for { var p *pem.Block p, rest = pem.Decode(rest) @@ -33,7 +33,7 @@ func main() { break } - fmt.Fprintf(os.Stdout, "\t%+v\n", cert.Subject.CommonName) + fmt.Fprintf(os.Stdout, "\t%+v\n", cert.Subject.CommonName) } } } diff --git a/cmd/renfnv/renfnv.go b/cmd/renfnv/main.go similarity index 78% rename from cmd/renfnv/renfnv.go rename to cmd/renfnv/main.go index 1f9008c..c9c14e6 100644 --- a/cmd/renfnv/renfnv.go +++ b/cmd/renfnv/main.go @@ -43,7 +43,7 @@ func newName(path string) (string, error) { return hashName(path, encodedHash), nil } -func move(dst, src string, force bool) (err error) { +func move(dst, src string, force bool) error { if fileutil.FileDoesExist(dst) && !force { return fmt.Errorf("%s exists (pass the -f flag to overwrite)", dst) } @@ -52,21 +52,23 @@ func move(dst, src string, force bool) (err error) { return err } - defer func(e error) { + var retErr error + defer func(e *error) { dstFile.Close() - if e != nil { + if *e != nil { os.Remove(dst) } - }(err) + }(&retErr) srcFile, err := os.Open(src) if err != nil { + retErr = err return err } defer srcFile.Close() - _, err = io.Copy(dstFile, srcFile) - if err != nil { + if _, err = io.Copy(dstFile, srcFile); err != nil { + retErr = err return err } @@ -109,27 +111,27 @@ func main() { for _, file := range flag.Args() { renamed, err := newName(file) - if err != nil { - _, _ = lib.Warn(err, "failed to get new file name") - continue - } + if err != nil { + _, _ = lib.Warn(err, "failed to get new file name") + continue + } - if verbose && !printChanged { - fmt.Fprintln(os.Stdout, file) - } + if verbose && !printChanged { + fmt.Fprintln(os.Stdout, file) + } if renamed != file { if !dryRun { err = move(renamed, file, force) - if err != nil { - _, _ = lib.Warn(err, "failed to rename file from %s to %s", file, renamed) - continue - } + if err != nil { + _, _ = lib.Warn(err, "failed to rename file from %s to %s", file, renamed) + continue + } } - if printChanged && !verbose { - fmt.Fprintln(os.Stdout, file, "->", renamed) - } + if printChanged && !verbose { + fmt.Fprintln(os.Stdout, file, "->", renamed) + } } } } diff --git a/cmd/rolldie/main.go b/cmd/rolldie/main.go index aef7ce1..7fa9696 100644 --- a/cmd/rolldie/main.go +++ b/cmd/rolldie/main.go @@ -17,11 +17,11 @@ func rollDie(count, sides int) []int { sum := 0 var rolls []int - for i := 0; i < count; i++ { - roll := rand.IntN(sides) + 1 - sum += roll - rolls = append(rolls, roll) - } + for range count { + roll := rand.IntN(sides) + 1 + sum += roll + rolls = append(rolls, roll) + } rolls = append(rolls, sum) return rolls diff --git a/cmd/showimp/main.go b/cmd/showimp/main.go index 6299e55..e565ec3 100644 --- a/cmd/showimp/main.go +++ b/cmd/showimp/main.go @@ -53,7 +53,7 @@ func init() { project = wd[len(gopath):] } -func walkFile(path string, info os.FileInfo, err error) error { +func walkFile(path string, _ os.FileInfo, err error) error { if ignores[path] { return filepath.SkipDir } @@ -62,13 +62,17 @@ func walkFile(path string, info os.FileInfo, err error) error { return nil } - debug.Println(path) - - f, err := parser.ParseFile(fset, path, nil, parser.ImportsOnly) if err != nil { return err } + debug.Println(path) + + f, err2 := parser.ParseFile(fset, path, nil, parser.ImportsOnly) + if err2 != nil { + return err2 + } + for _, importSpec := range f.Imports { importPath := strings.Trim(importSpec.Path.Value, `"`) if stdLibRegexp.MatchString(importPath) { @@ -102,7 +106,7 @@ func main() { ignores["vendor"] = true } - for _, word := range strings.Split(ignoreLine, ",") { + for word := range strings.SplitSeq(ignoreLine, ",") { ignores[strings.TrimSpace(word)] = true } diff --git a/cmd/ski/main.go b/cmd/ski/main.go index ac61e6d..16544dd 100644 --- a/cmd/ski/main.go +++ b/cmd/ski/main.go @@ -1,23 +1,23 @@ package main import ( - "bytes" - "crypto" - "crypto/ecdsa" - "crypto/rsa" - "crypto/sha1" - "crypto/x509" - "crypto/x509/pkix" - "encoding/asn1" - "encoding/pem" - "flag" - "fmt" - "io" - "os" - "strings" + "bytes" + "crypto" + "crypto/ecdsa" + "crypto/rsa" + "crypto/sha1" + "crypto/x509" + "crypto/x509/pkix" + "encoding/asn1" + "encoding/pem" + "flag" + "fmt" + "io" + "os" + "strings" - "git.wntrmute.dev/kyle/goutils/die" - "git.wntrmute.dev/kyle/goutils/lib" + "git.wntrmute.dev/kyle/goutils/die" + "git.wntrmute.dev/kyle/goutils/lib" ) func usage(w io.Writer) { @@ -38,15 +38,15 @@ func init() { flag.Usage = func() { usage(os.Stderr) } } -func parse(path string) (public []byte, kt, ft string) { - data, err := os.ReadFile(path) +func parse(path string) ([]byte, string, string) { + data, err := os.ReadFile(path) die.If(err) data = bytes.TrimSpace(data) p, rest := pem.Decode(data) - if len(rest) > 0 { - _, _ = lib.Warnx("trailing data in PEM file") - } + if len(rest) > 0 { + _, _ = lib.Warnx("trailing data in PEM file") + } if p == nil { die.With("no PEM data found") @@ -54,6 +54,12 @@ func parse(path string) (public []byte, kt, ft string) { data = p.Bytes + var ( + public []byte + kt string + ft string + ) + switch p.Type { case "PRIVATE KEY", "RSA PRIVATE KEY", "EC PRIVATE KEY": public, kt = parseKey(data) @@ -68,11 +74,11 @@ func parse(path string) (public []byte, kt, ft string) { die.With("unknown PEM type %s", p.Type) } - return + return public, kt, ft } -func parseKey(data []byte) (public []byte, kt string) { - privInterface, err := x509.ParsePKCS8PrivateKey(data) +func parseKey(data []byte) ([]byte, string) { + privInterface, err := x509.ParsePKCS8PrivateKey(data) if err != nil { privInterface, err = x509.ParsePKCS1PrivateKey(data) if err != nil { @@ -84,6 +90,7 @@ func parseKey(data []byte) (public []byte, kt string) { } var priv crypto.Signer + var kt string switch p := privInterface.(type) { case *rsa.PrivateKey: priv = p @@ -95,17 +102,18 @@ func parseKey(data []byte) (public []byte, kt string) { die.With("unknown private key type %T", privInterface) } - public, err = x509.MarshalPKIXPublicKey(priv.Public()) + public, err := x509.MarshalPKIXPublicKey(priv.Public()) die.If(err) - return + return public, kt } -func parseCertificate(data []byte) (public []byte, kt string) { +func parseCertificate(data []byte) ([]byte, string) { cert, err := x509.ParseCertificate(data) die.If(err) pub := cert.PublicKey + var kt string switch pub.(type) { case *rsa.PublicKey: kt = "RSA" @@ -115,16 +123,17 @@ func parseCertificate(data []byte) (public []byte, kt string) { die.With("unknown public key type %T", pub) } - public, err = x509.MarshalPKIXPublicKey(pub) + public, err := x509.MarshalPKIXPublicKey(pub) die.If(err) - return + return public, kt } -func parseCSR(data []byte) (public []byte, kt string) { +func parseCSR(data []byte) ([]byte, string) { csr, err := x509.ParseCertificateRequest(data) die.If(err) pub := csr.PublicKey + var kt string switch pub.(type) { case *rsa.PublicKey: kt = "RSA" @@ -134,16 +143,18 @@ func parseCSR(data []byte) (public []byte, kt string) { die.With("unknown public key type %T", pub) } - public, err = x509.MarshalPKIXPublicKey(pub) + public, err := x509.MarshalPKIXPublicKey(pub) die.If(err) - return + return public, kt } func dumpHex(in []byte) string { var s string + var sSb153 strings.Builder for i := range in { - s += fmt.Sprintf("%02X:", in[i]) + sSb153.WriteString(fmt.Sprintf("%02X:", in[i])) } + s += sSb153.String() return strings.Trim(s, ":") } @@ -170,10 +181,10 @@ func main() { var subPKI subjectPublicKeyInfo _, err := asn1.Unmarshal(public, &subPKI) - if err != nil { - _, _ = lib.Warn(err, "failed to get subject PKI") - continue - } + if err != nil { + _, _ = lib.Warn(err, "failed to get subject PKI") + continue + } pubHash := sha1.Sum(subPKI.SubjectPublicKey.Bytes) pubHashString := dumpHex(pubHash[:]) @@ -181,10 +192,10 @@ func main() { ski = pubHashString } - if shouldMatch && ski != pubHashString { - _, _ = lib.Warnx("%s: SKI mismatch (%s != %s)", - path, ski, pubHashString) - } + if shouldMatch && ski != pubHashString { + _, _ = lib.Warnx("%s: SKI mismatch (%s != %s)", + path, ski, pubHashString) + } fmt.Printf("%s %s (%s %s)\n", path, pubHashString, kt, ft) } } diff --git a/cmd/sprox/main.go b/cmd/sprox/main.go index eaee652..080f818 100644 --- a/cmd/sprox/main.go +++ b/cmd/sprox/main.go @@ -10,19 +10,19 @@ import ( ) func proxy(conn net.Conn, inside string) error { - proxyConn, err := net.Dial("tcp", inside) - if err != nil { - return err - } + proxyConn, err := net.Dial("tcp", inside) + if err != nil { + return err + } defer proxyConn.Close() defer conn.Close() - go func() { - _, _ = io.Copy(conn, proxyConn) - }() - _, err = io.Copy(proxyConn, conn) - return err + go func() { + _, _ = io.Copy(conn, proxyConn) + }() + _, err = io.Copy(proxyConn, conn) + return err } func main() { @@ -34,17 +34,17 @@ func main() { l, err := net.Listen("tcp", "0.0.0.0:"+outside) die.If(err) - for { - conn, err := l.Accept() - if err != nil { - _, _ = lib.Warn(err, "accept failed") - continue - } + for { + conn, err := l.Accept() + if err != nil { + _, _ = lib.Warn(err, "accept failed") + continue + } - go func() { - if err := proxy(conn, "127.0.0.1:"+inside); err != nil { - _, _ = lib.Warn(err, "proxy error") - } - }() - } + go func() { + if err := proxy(conn, "127.0.0.1:"+inside); err != nil { + _, _ = lib.Warn(err, "proxy error") + } + }() + } } diff --git a/cmd/stealchain-server/main.go b/cmd/stealchain-server/main.go index badbb86..71cfb09 100644 --- a/cmd/stealchain-server/main.go +++ b/cmd/stealchain-server/main.go @@ -45,18 +45,18 @@ func main() { os.Exit(1) } cfg.Certificates = append(cfg.Certificates, cert) - if sysRoot != "" { - pemList, err := os.ReadFile(sysRoot) - die.If(err) + if sysRoot != "" { + pemList, err := os.ReadFile(sysRoot) + die.If(err) - roots := x509.NewCertPool() - if !roots.AppendCertsFromPEM(pemList) { - fmt.Printf("[!] no valid roots found") - roots = nil - } + roots := x509.NewCertPool() + if !roots.AppendCertsFromPEM(pemList) { + fmt.Printf("[!] no valid roots found") + roots = nil + } - cfg.RootCAs = roots - } + cfg.RootCAs = roots + } l, err := net.Listen("tcp", listenAddr) if err != nil { @@ -64,46 +64,46 @@ func main() { os.Exit(1) } - for { - conn, err := l.Accept() - if err != nil { - fmt.Println(err.Error()) - continue - } - handleConn(conn, cfg) - } + for { + conn, err := l.Accept() + if err != nil { + fmt.Println(err.Error()) + continue + } + handleConn(conn, cfg) + } } // handleConn performs a TLS handshake, extracts the peer chain, and writes it to a file. func handleConn(conn net.Conn, cfg *tls.Config) { - defer conn.Close() - raddr := conn.RemoteAddr() - tconn := tls.Server(conn, cfg) - if err := tconn.Handshake(); err != nil { - fmt.Printf("[+] %v: failed to complete handshake: %v\n", raddr, err) - return - } - cs := tconn.ConnectionState() - if len(cs.PeerCertificates) == 0 { - fmt.Printf("[+] %v: no chain presented\n", raddr) - return - } + defer conn.Close() + raddr := conn.RemoteAddr() + tconn := tls.Server(conn, cfg) + if err := tconn.Handshake(); err != nil { + fmt.Printf("[+] %v: failed to complete handshake: %v\n", raddr, err) + return + } + cs := tconn.ConnectionState() + if len(cs.PeerCertificates) == 0 { + fmt.Printf("[+] %v: no chain presented\n", raddr) + return + } - var chain []byte - for _, cert := range cs.PeerCertificates { - p := &pem.Block{Type: "CERTIFICATE", Bytes: cert.Raw} - chain = append(chain, pem.EncodeToMemory(p)...) - } + var chain []byte + for _, cert := range cs.PeerCertificates { + p := &pem.Block{Type: "CERTIFICATE", Bytes: cert.Raw} + chain = append(chain, pem.EncodeToMemory(p)...) + } - var nonce [16]byte - if _, err := rand.Read(nonce[:]); err != nil { - fmt.Printf("[+] %v: failed to generate filename nonce: %v\n", raddr, err) - return - } - fname := fmt.Sprintf("%v-%v.pem", raddr, hex.EncodeToString(nonce[:])) - if err := os.WriteFile(fname, chain, 0o644); err != nil { - fmt.Printf("[+] %v: failed to write %v: %v\n", raddr, fname, err) - return - } - fmt.Printf("%v: [+] wrote %v.\n", raddr, fname) + var nonce [16]byte + if _, err := rand.Read(nonce[:]); err != nil { + fmt.Printf("[+] %v: failed to generate filename nonce: %v\n", raddr, err) + return + } + fname := fmt.Sprintf("%v-%v.pem", raddr, hex.EncodeToString(nonce[:])) + if err := os.WriteFile(fname, chain, 0o644); err != nil { + fmt.Printf("[+] %v: failed to write %v: %v\n", raddr, fname, err) + return + } + fmt.Printf("%v: [+] wrote %v.\n", raddr, fname) } diff --git a/cmd/stealchain/thief.go b/cmd/stealchain/main.go similarity index 91% rename from cmd/stealchain/thief.go rename to cmd/stealchain/main.go index 19d1da2..2911cab 100644 --- a/cmd/stealchain/thief.go +++ b/cmd/stealchain/main.go @@ -6,7 +6,6 @@ import ( "encoding/pem" "flag" "fmt" - "io/ioutil" "net" "os" @@ -23,7 +22,7 @@ func main() { flag.Parse() if sysRoot != "" { - pemList, err := ioutil.ReadFile(sysRoot) + pemList, err := os.ReadFile(sysRoot) die.If(err) roots := x509.NewCertPool() @@ -61,7 +60,7 @@ func main() { chain = append(chain, pem.EncodeToMemory(p)...) } - err = ioutil.WriteFile(site+".pem", chain, 0644) + err = os.WriteFile(site+".pem", chain, 0644) die.If(err) fmt.Printf("[+] wrote %s.pem.\n", site) } diff --git a/cmd/subjhash/main.go b/cmd/subjhash/main.go index 7baf42b..25a2fea 100644 --- a/cmd/subjhash/main.go +++ b/cmd/subjhash/main.go @@ -57,16 +57,16 @@ func getSubjectInfoHash(cert *x509.Certificate, issuer bool) []byte { } func printDigests(paths []string, issuer bool) { - for _, path := range paths { - cert, err := certlib.LoadCertificate(path) - if err != nil { - _, _ = lib.Warn(err, "failed to load certificate from %s", path) - continue - } + for _, path := range paths { + cert, err := certlib.LoadCertificate(path) + if err != nil { + _, _ = lib.Warn(err, "failed to load certificate from %s", path) + continue + } digest := getSubjectInfoHash(cert, issuer) - fmt.Printf("%x %s\n", digest, path) - } + fmt.Printf("%x %s\n", digest, path) + } } func matchDigests(paths []string, issuer bool) { @@ -75,22 +75,21 @@ func matchDigests(paths []string, issuer bool) { } var invalid int - for { - if len(paths) == 0 { - break - } + for len(paths) > 0 { fst := paths[0] snd := paths[1] paths = paths[2:] fstCert, err := certlib.LoadCertificate(fst) die.If(err) + sndCert, err := certlib.LoadCertificate(snd) die.If(err) - if !bytes.Equal(getSubjectInfoHash(fstCert, issuer), getSubjectInfoHash(sndCert, issuer)) { - _, _ = lib.Warnx("certificates don't match: %s and %s", fst, snd) - invalid++ - } + + if !bytes.Equal(getSubjectInfoHash(fstCert, issuer), getSubjectInfoHash(sndCert, issuer)) { + _, _ = lib.Warnx("certificates don't match: %s and %s", fst, snd) + invalid++ + } } if invalid > 0 { diff --git a/cmd/tlsinfo/main.go b/cmd/tlsinfo/main.go index 0d2fb45..2c09125 100644 --- a/cmd/tlsinfo/main.go +++ b/cmd/tlsinfo/main.go @@ -37,7 +37,6 @@ func printConnectionDetails(state tls.ConnectionState) { func tlsVersion(version uint16) string { switch version { - case tls.VersionTLS13: return "TLS 1.3" case tls.VersionTLS12: diff --git a/cmd/tlskeypair/main.go b/cmd/tlskeypair/main.go index 4992852..32d8ef1 100644 --- a/cmd/tlskeypair/main.go +++ b/cmd/tlskeypair/main.go @@ -1,19 +1,19 @@ package main import ( - "bytes" - "crypto" - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rsa" - "crypto/x509" - "encoding/pem" - "errors" - "flag" - "fmt" - "os" + "bytes" + "crypto" + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rsa" + "crypto/x509" + "encoding/pem" + "errors" + "flag" + "fmt" + "os" - "git.wntrmute.dev/kyle/goutils/die" + "git.wntrmute.dev/kyle/goutils/die" ) var validPEMs = map[string]bool{ @@ -30,7 +30,7 @@ const ( curveP521 ) -func getECCurve(pub interface{}) int { +func getECCurve(pub any) int { switch pub := pub.(type) { case *ecdsa.PublicKey: switch pub.Curve { @@ -53,72 +53,72 @@ func getECCurve(pub interface{}) int { // matchRSA compares an RSA public key from certificate against RSA public key from private key. // It returns true on match. func matchRSA(certPub *rsa.PublicKey, keyPub *rsa.PublicKey) bool { - return keyPub.N.Cmp(certPub.N) == 0 && keyPub.E == certPub.E + return keyPub.N.Cmp(certPub.N) == 0 && keyPub.E == certPub.E } // matchECDSA compares ECDSA public keys for equality and compatible curve. // It returns match=true when they are on the same curve and have the same X/Y. // If curves mismatch, match is false. func matchECDSA(certPub *ecdsa.PublicKey, keyPub *ecdsa.PublicKey) bool { - if getECCurve(certPub) != getECCurve(keyPub) { - return false - } - if keyPub.X.Cmp(certPub.X) != 0 { - return false - } - if keyPub.Y.Cmp(certPub.Y) != 0 { - return false - } - return true + if getECCurve(certPub) != getECCurve(keyPub) { + return false + } + if keyPub.X.Cmp(certPub.X) != 0 { + return false + } + if keyPub.Y.Cmp(certPub.Y) != 0 { + return false + } + return true } // matchKeys determines whether the certificate's public key matches the given private key. // It returns true if they match; otherwise, it returns false and a human-friendly reason. func matchKeys(cert *x509.Certificate, priv crypto.Signer) (bool, string) { - switch keyPub := priv.Public().(type) { - case *rsa.PublicKey: - switch certPub := cert.PublicKey.(type) { - case *rsa.PublicKey: - if matchRSA(certPub, keyPub) { - return true, "" - } - return false, "public keys don't match" - case *ecdsa.PublicKey: - return false, "RSA private key, EC public key" - default: - return false, fmt.Sprintf("unsupported certificate public key type: %T", cert.PublicKey) - } - case *ecdsa.PublicKey: - switch certPub := cert.PublicKey.(type) { - case *ecdsa.PublicKey: - if matchECDSA(certPub, keyPub) { - return true, "" - } - // Determine a more precise reason - kc := getECCurve(keyPub) - cc := getECCurve(certPub) - if kc == curveInvalid { - return false, "invalid private key curve" - } - if cc == curveRSA { - return false, "private key is EC, certificate is RSA" - } - if kc != cc { - return false, "EC curves don't match" - } - return false, "public keys don't match" - case *rsa.PublicKey: - return false, "private key is EC, certificate is RSA" - default: - return false, fmt.Sprintf("unsupported certificate public key type: %T", cert.PublicKey) - } - default: - return false, fmt.Sprintf("unrecognised private key type: %T", priv.Public()) - } + switch keyPub := priv.Public().(type) { + case *rsa.PublicKey: + switch certPub := cert.PublicKey.(type) { + case *rsa.PublicKey: + if matchRSA(certPub, keyPub) { + return true, "" + } + return false, "public keys don't match" + case *ecdsa.PublicKey: + return false, "RSA private key, EC public key" + default: + return false, fmt.Sprintf("unsupported certificate public key type: %T", cert.PublicKey) + } + case *ecdsa.PublicKey: + switch certPub := cert.PublicKey.(type) { + case *ecdsa.PublicKey: + if matchECDSA(certPub, keyPub) { + return true, "" + } + // Determine a more precise reason + kc := getECCurve(keyPub) + cc := getECCurve(certPub) + if kc == curveInvalid { + return false, "invalid private key curve" + } + if cc == curveRSA { + return false, "private key is EC, certificate is RSA" + } + if kc != cc { + return false, "EC curves don't match" + } + return false, "public keys don't match" + case *rsa.PublicKey: + return false, "private key is EC, certificate is RSA" + default: + return false, fmt.Sprintf("unsupported certificate public key type: %T", cert.PublicKey) + } + default: + return false, fmt.Sprintf("unrecognised private key type: %T", priv.Public()) + } } func loadKey(path string) (crypto.Signer, error) { - in, err := os.ReadFile(path) + in, err := os.ReadFile(path) if err != nil { return nil, err } @@ -132,7 +132,7 @@ func loadKey(path string) (crypto.Signer, error) { in = p.Bytes } - priv, err := x509.ParsePKCS8PrivateKey(in) + priv, err := x509.ParsePKCS8PrivateKey(in) if err != nil { priv, err = x509.ParsePKCS1PrivateKey(in) if err != nil { @@ -143,16 +143,15 @@ func loadKey(path string) (crypto.Signer, error) { } } - switch p := priv.(type) { - case *rsa.PrivateKey: - return p, nil - case *ecdsa.PrivateKey: - return p, nil - default: - // should never reach here - return nil, errors.New("invalid private key") - } - + switch p := priv.(type) { + case *rsa.PrivateKey: + return p, nil + case *ecdsa.PrivateKey: + return p, nil + default: + // should never reach here + return nil, errors.New("invalid private key") + } } func main() { @@ -161,7 +160,7 @@ func main() { flag.StringVar(&certFile, "c", "", "TLS `certificate` file") flag.Parse() - in, err := os.ReadFile(certFile) + in, err := os.ReadFile(certFile) die.If(err) p, _ := pem.Decode(in) @@ -177,11 +176,11 @@ func main() { priv, err := loadKey(keyFile) die.If(err) - matched, reason := matchKeys(cert, priv) - if matched { - fmt.Println("Match.") - return - } - fmt.Printf("No match (%s).\n", reason) - os.Exit(1) + matched, reason := matchKeys(cert, priv) + if matched { + fmt.Println("Match.") + return + } + fmt.Printf("No match (%s).\n", reason) + os.Exit(1) } diff --git a/cmd/utc/main.go b/cmd/utc/main.go index 9ebcf4c..aa617ff 100644 --- a/cmd/utc/main.go +++ b/cmd/utc/main.go @@ -201,10 +201,6 @@ func init() { os.Exit(1) } - if fromLoc == time.UTC { - - } - toLoc = time.UTC } diff --git a/cmd/yamll/main.go b/cmd/yamll/main.go index 8919876..2573d2f 100644 --- a/cmd/yamll/main.go +++ b/cmd/yamll/main.go @@ -4,7 +4,6 @@ import ( "flag" "fmt" "io" - "io/ioutil" "os" "gopkg.in/yaml.v2" @@ -12,7 +11,7 @@ import ( type empty struct{} -func errorf(format string, args ...interface{}) { +func errorf(format string, args ...any) { format += "\n" fmt.Fprintf(os.Stderr, format, args...) } @@ -44,7 +43,7 @@ func main() { if flag.NArg() == 1 && flag.Arg(0) == "-" { path := "stdin" - in, err := ioutil.ReadAll(os.Stdin) + in, err := io.ReadAll(os.Stdin) if err != nil { errorf("%s FAILED: %s", path, err) os.Exit(1) @@ -65,7 +64,7 @@ func main() { } for _, path := range flag.Args() { - in, err := ioutil.ReadFile(path) + in, err := os.ReadFile(path) if err != nil { errorf("%s FAILED: %s", path, err) continue diff --git a/cmd/zsearch/main.go b/cmd/zsearch/main.go index 82d765c..5a2e1ac 100644 --- a/cmd/zsearch/main.go +++ b/cmd/zsearch/main.go @@ -18,7 +18,7 @@ import ( const defaultDirectory = ".git/objects" -func errorf(format string, a ...interface{}) { +func errorf(format string, a ...any) { fmt.Fprintf(os.Stderr, format, a...) if format[len(format)-1] != '\n' { fmt.Fprintf(os.Stderr, "\n") @@ -93,7 +93,7 @@ func searchFile(path string, search *regexp.Regexp) error { } func buildWalker(searchExpr *regexp.Regexp) filepath.WalkFunc { - return func(path string, info os.FileInfo, err error) error { + return func(path string, info os.FileInfo, _ error) error { if info.Mode().IsRegular() { return searchFile(path, searchExpr) } diff --git a/lib/ftime_bsd.go b/lib/ftime_bsd.go index a190051..1b509f3 100644 --- a/lib/ftime_bsd.go +++ b/lib/ftime_bsd.go @@ -1,4 +1,4 @@ -// +build freebsd darwin,386 netbsd +//go:build bsd package lib diff --git a/lib/ftime_unix.go b/lib/ftime_unix.go index c5f9a3c..ef0e7e5 100644 --- a/lib/ftime_unix.go +++ b/lib/ftime_unix.go @@ -1,4 +1,4 @@ -// +build unix linux openbsd darwin,amd64 +//go:build unix || linux || openbsd || (darwin && amd64) package lib @@ -18,7 +18,7 @@ type FileTime struct { func timeSpecToTime(ts unix.Timespec) time.Time { // The casts to int64 are needed because on 386, these are int32s. - return time.Unix(int64(ts.Sec), int64(ts.Nsec)) + return time.Unix(ts.Sec, ts.Nsec) } // LoadFileTime returns a FileTime associated with the file. diff --git a/lib/lib.go b/lib/lib.go index 216b0cc..c10712c 100644 --- a/lib/lib.go +++ b/lib/lib.go @@ -10,6 +10,12 @@ import ( var progname = filepath.Base(os.Args[0]) +const ( + daysInYear = 365 + digitWidth = 10 + hoursInQuarterDay = 6 +) + // ProgName returns what lib thinks the program name is, namely the // basename of argv0. // @@ -20,7 +26,7 @@ func ProgName() string { // Warnx displays a formatted error message to standard error, à la // warnx(3). -func Warnx(format string, a ...interface{}) (int, error) { +func Warnx(format string, a ...any) (int, error) { format = fmt.Sprintf("[%s] %s", progname, format) format += "\n" return fmt.Fprintf(os.Stderr, format, a...) @@ -28,7 +34,7 @@ func Warnx(format string, a ...interface{}) (int, error) { // Warn displays a formatted error message to standard output, // appending the error string, à la warn(3). -func Warn(err error, format string, a ...interface{}) (int, error) { +func Warn(err error, format string, a ...any) (int, error) { format = fmt.Sprintf("[%s] %s", progname, format) format += ": %v\n" a = append(a, err) @@ -37,7 +43,7 @@ func Warn(err error, format string, a ...interface{}) (int, error) { // Errx displays a formatted error message to standard error and exits // with the status code from `exit`, à la errx(3). -func Errx(exit int, format string, a ...interface{}) { +func Errx(exit int, format string, a ...any) { format = fmt.Sprintf("[%s] %s", progname, format) format += "\n" fmt.Fprintf(os.Stderr, format, a...) @@ -47,7 +53,7 @@ func Errx(exit int, format string, a ...interface{}) { // Err displays a formatting error message to standard error, // appending the error string, and exits with the status code from // `exit`, à la err(3). -func Err(exit int, err error, format string, a ...interface{}) { +func Err(exit int, err error, format string, a ...any) { format = fmt.Sprintf("[%s] %s", progname, format) format += ": %v\n" a = append(a, err) @@ -62,31 +68,31 @@ func Itoa(i int, wid int) string { // Assemble decimal in reverse order. var b [20]byte bp := len(b) - 1 - for i >= 10 || wid > 1 { + for i >= digitWidth || wid > 1 { wid-- - q := i / 10 - b[bp] = byte('0' + i - q*10) + q := i / digitWidth + b[bp] = byte('0' + i - q*digitWidth) bp-- i = q } - // i < 10 + b[bp] = byte('0' + i) return string(b[bp:]) } var ( dayDuration = 24 * time.Hour - yearDuration = (365 * dayDuration) + (6 * time.Hour) + yearDuration = (daysInYear * dayDuration) + (hoursInQuarterDay * time.Hour) ) // Duration returns a prettier string for time.Durations. func Duration(d time.Duration) string { - var s string - if d >= yearDuration { - years := int64(d / yearDuration) - s += fmt.Sprintf("%dy", years) - d -= time.Duration(years) * yearDuration - } + var s string + if d >= yearDuration { + years := int64(d / yearDuration) + s += fmt.Sprintf("%dy", years) + d -= time.Duration(years) * yearDuration + } if d >= dayDuration { days := d / dayDuration @@ -97,9 +103,9 @@ func Duration(d time.Duration) string { return s } - d %= 1 * time.Second - hours := int64(d / time.Hour) - d -= time.Duration(hours) * time.Hour + d %= 1 * time.Second + hours := int64(d / time.Hour) + d -= time.Duration(hours) * time.Hour s += fmt.Sprintf("%dh%s", hours, d) return s } diff --git a/logging/file.go b/logging/file.go index 655b81c..526c353 100644 --- a/logging/file.go +++ b/logging/file.go @@ -1,9 +1,9 @@ package logging import ( - "errors" - "fmt" - "os" + "errors" + "fmt" + "os" ) // File writes its logs to file. @@ -60,12 +60,12 @@ func NewSplitFile(outpath, errpath string, overwrite bool) (*File, error) { fl.fe, err = os.OpenFile(errpath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0600) } - if err != nil { - if closeErr := fl.Close(); closeErr != nil { - return nil, fmt.Errorf("failed to open error log: %w", errors.Join(closeErr, err)) - } - return nil, fmt.Errorf("failed to open error log: %w", err) - } + if err != nil { + if closeErr := fl.Close(); closeErr != nil { + return nil, fmt.Errorf("failed to open error log: %w", errors.Join(closeErr, err)) + } + return nil, fmt.Errorf("failed to open error log: %w", err) + } fl.LogWriter = NewLogWriter(fl.fo, fl.fe) return fl, nil @@ -95,13 +95,13 @@ func (fl *File) Flush() error { } func (fl *File) Chmod(mode os.FileMode) error { - if err := fl.fo.Chmod(mode); err != nil { - return fmt.Errorf("failed to chmod output log: %w", err) - } + if err := fl.fo.Chmod(mode); err != nil { + return fmt.Errorf("failed to chmod output log: %w", err) + } - if err := fl.fe.Chmod(mode); err != nil { - return fmt.Errorf("failed to chmod error log: %w", err) - } + if err := fl.fe.Chmod(mode); err != nil { + return fmt.Errorf("failed to chmod error log: %w", err) + } - return nil + return nil }