First round of linter cleanups.

This commit is contained in:
2025-11-15 15:11:07 -08:00
parent 5fcba0e814
commit aba5e519a4
9 changed files with 200 additions and 190 deletions

View File

@@ -65,8 +65,6 @@ linters:
- funcorder # checks the order of functions, methods, and constructors
- funlen # tool for detection of long functions
- gocheckcompilerdirectives # validates go compiler directive comments (//go:)
- gochecknoglobals # checks that no global variables exist
- gochecknoinits # checks that no init functions are present in Go code
- gochecksumtype # checks exhaustiveness on Go "sum types"
- gocognit # computes and checks the cognitive complexity of functions
- goconst # finds repeated strings that could be replaced by a constant
@@ -368,7 +366,7 @@ linters:
max-func-lines: 0
nolintlint:
# Exclude following linters from requiring an explanation.
# Exclude the following linters from requiring an explanation.
# Default: []
allow-no-explanation: [ funlen, gocognit, golines ]
# Enable to require an explanation of nonzero length after each nolint directive.
@@ -444,8 +442,11 @@ linters:
presets:
- std-error-handling
- common-false-positives
# Excluding configuration per-path, per-linter, per-text and per-source.
rules:
- path: 'ahash/ahash.go'
linters: [ staticcheck, gosec ]
- path: 'backoff/backoff_test.go'
linters: [ testpackage ]
- source: 'TODO'
linters: [ godot ]
- text: 'should have a package comment'

View File

@@ -4,8 +4,8 @@
package ahash
import (
"crypto/md5"
"crypto/sha1"
"crypto/md5" // #nosec G505
"crypto/sha1" // #nosec G501
"crypto/sha256"
"crypto/sha512"
"errors"
@@ -17,34 +17,15 @@ import (
"io"
"sort"
"git.wntrmute.dev/kyle/goutils/assert"
"golang.org/x/crypto/blake2b"
"golang.org/x/crypto/blake2s"
"golang.org/x/crypto/md4"
"golang.org/x/crypto/ripemd160"
"golang.org/x/crypto/md4" // #nosec G506
"golang.org/x/crypto/ripemd160" // #nosec G507
"golang.org/x/crypto/sha3"
"git.wntrmute.dev/kyle/goutils/assert"
)
func sha224Slicer(bs []byte) []byte {
sum := sha256.Sum224(bs)
return sum[:]
}
func sha256Slicer(bs []byte) []byte {
sum := sha256.Sum256(bs)
return sum[:]
}
func sha384Slicer(bs []byte) []byte {
sum := sha512.Sum384(bs)
return sum[:]
}
func sha512Slicer(bs []byte) []byte {
sum := sha512.Sum512(bs)
return sum[:]
}
// Hash represents a generic hash function that may or may not be secure. It
// satisfies the hash.Hash interface.
type Hash struct {
@@ -247,17 +228,17 @@ func init() {
// HashList returns a sorted list of all the hash algorithms supported by the
// package.
func HashList() []string {
return hashList[:]
return hashList
}
// SecureHashList returns a sorted list of all the secure (cryptographic) hash
// algorithms supported by the package.
func SecureHashList() []string {
return secureHashList[:]
return secureHashList
}
// InsecureHashList returns a sorted list of all the insecure hash algorithms
// supported by the package.
func InsecureHashList() []string {
return insecureHashList[:]
return insecureHashList
}

View File

@@ -1,16 +1,18 @@
package ahash
package ahash_test
import (
"bytes"
"encoding/hex"
"fmt"
"testing"
"git.wntrmute.dev/kyle/goutils/ahash"
"git.wntrmute.dev/kyle/goutils/assert"
)
func TestSecureHash(t *testing.T) {
algo := "sha256"
h, err := New(algo)
h, err := ahash.New(algo)
assert.NoErrorT(t, err)
assert.BoolT(t, h.IsSecure(), algo+" should be a secure hash")
assert.BoolT(t, h.HashAlgo() == algo, "hash returned the wrong HashAlgo")
@@ -19,28 +21,28 @@ func TestSecureHash(t *testing.T) {
var data []byte
var expected = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
sum, err := Sum(algo, data)
sum, err := ahash.Sum(algo, data)
assert.NoErrorT(t, err)
assert.BoolT(t, fmt.Sprintf("%x", sum) == expected, fmt.Sprintf("expected hash %s but have %x", expected, sum))
assert.BoolT(t, hex.EncodeToString(sum) == expected, fmt.Sprintf("expected hash %s but have %x", expected, sum))
data = []byte("hello, world")
buf := bytes.NewBuffer(data)
expected = "09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b"
sum, err = SumReader(algo, buf)
sum, err = ahash.SumReader(algo, buf)
assert.NoErrorT(t, err)
assert.BoolT(t, fmt.Sprintf("%x", sum) == expected, fmt.Sprintf("expected hash %s but have %x", expected, sum))
assert.BoolT(t, hex.EncodeToString(sum) == expected, fmt.Sprintf("expected hash %s but have %x", expected, sum))
data = []byte("hello world")
_, err = h.Write(data)
assert.NoErrorT(t, err)
unExpected := "09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b"
sum = h.Sum(nil)
assert.BoolT(t, fmt.Sprintf("%x", sum) != unExpected, fmt.Sprintf("hash shouldn't have returned %x", unExpected))
assert.BoolT(t, hex.EncodeToString(sum) != unExpected, fmt.Sprintf("hash shouldn't have returned %x", unExpected))
}
func TestInsecureHash(t *testing.T) {
algo := "md5"
h, err := New(algo)
h, err := ahash.New(algo)
assert.NoErrorT(t, err)
assert.BoolT(t, !h.IsSecure(), algo+" shouldn't be a secure hash")
assert.BoolT(t, h.HashAlgo() == algo, "hash returned the wrong HashAlgo")
@@ -49,28 +51,28 @@ func TestInsecureHash(t *testing.T) {
var data []byte
var expected = "d41d8cd98f00b204e9800998ecf8427e"
sum, err := Sum(algo, data)
sum, err := ahash.Sum(algo, data)
assert.NoErrorT(t, err)
assert.BoolT(t, fmt.Sprintf("%x", sum) == expected, fmt.Sprintf("expected hash %s but have %x", expected, sum))
assert.BoolT(t, hex.EncodeToString(sum) == expected, fmt.Sprintf("expected hash %s but have %x", expected, sum))
data = []byte("hello, world")
buf := bytes.NewBuffer(data)
expected = "e4d7f1b4ed2e42d15898f4b27b019da4"
sum, err = SumReader(algo, buf)
sum, err = ahash.SumReader(algo, buf)
assert.NoErrorT(t, err)
assert.BoolT(t, fmt.Sprintf("%x", sum) == expected, fmt.Sprintf("expected hash %s but have %x", expected, sum))
assert.BoolT(t, hex.EncodeToString(sum) == expected, fmt.Sprintf("expected hash %s but have %x", expected, sum))
data = []byte("hello world")
_, err = h.Write(data)
assert.NoErrorT(t, err)
unExpected := "e4d7f1b4ed2e42d15898f4b27b019da4"
sum = h.Sum(nil)
assert.BoolT(t, fmt.Sprintf("%x", sum) != unExpected, fmt.Sprintf("hash shouldn't have returned %x", unExpected))
assert.BoolT(t, hex.EncodeToString(sum) != unExpected, fmt.Sprintf("hash shouldn't have returned %x", unExpected))
}
func TestHash32(t *testing.T) {
algo := "crc32-ieee"
h, err := New(algo)
h, err := ahash.New(algo)
assert.NoErrorT(t, err)
assert.BoolT(t, !h.IsSecure(), algo+" shouldn't be a secure hash")
assert.BoolT(t, h.HashAlgo() == algo, "hash returned the wrong HashAlgo")
@@ -102,7 +104,7 @@ func TestHash32(t *testing.T) {
func TestHash64(t *testing.T) {
algo := "crc64"
h, err := New(algo)
h, err := ahash.New(algo)
assert.NoErrorT(t, err)
assert.BoolT(t, !h.IsSecure(), algo+" shouldn't be a secure hash")
assert.BoolT(t, h.HashAlgo() == algo, "hash returned the wrong HashAlgo")
@@ -133,9 +135,9 @@ func TestHash64(t *testing.T) {
}
func TestListLengthSanity(t *testing.T) {
all := HashList()
secure := SecureHashList()
insecure := InsecureHashList()
all := ahash.HashList()
secure := ahash.SecureHashList()
insecure := ahash.InsecureHashList()
assert.BoolT(t, len(all) == len(secure)+len(insecure))
}
@@ -146,11 +148,11 @@ func TestSumLimitedReader(t *testing.T) {
extendedData := bytes.NewBufferString("hello, world! this is an extended message")
expected := "09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b"
hash, err := SumReader("sha256", data)
hash, err := ahash.SumReader("sha256", data)
assert.NoErrorT(t, err)
assert.BoolT(t, fmt.Sprintf("%x", hash) == expected, fmt.Sprintf("have hash %x, want %s", hash, expected))
assert.BoolT(t, hex.EncodeToString(hash) == expected, fmt.Sprintf("have hash %x, want %s", hash, expected))
extendedHash, err := SumLimitedReader("sha256", extendedData, int64(dataLen))
extendedHash, err := ahash.SumLimitedReader("sha256", extendedData, int64(dataLen))
assert.NoErrorT(t, err)
assert.BoolT(t, bytes.Equal(hash, extendedHash), fmt.Sprintf("have hash %x, want %x", extendedHash, hash))

View File

@@ -9,6 +9,7 @@
package assert
import (
"errors"
"fmt"
"os"
"runtime"
@@ -16,11 +17,13 @@ import (
"testing"
)
const callerSkip = 2
// NoDebug can be set to true to cause all asserts to be ignored.
var NoDebug bool
func die(what string, a ...string) {
_, file, line, ok := runtime.Caller(2)
_, file, line, ok := runtime.Caller(callerSkip)
if !ok {
panic(what)
}
@@ -31,7 +34,8 @@ func die(what string, a ...string) {
s = ": " + s
}
panic(what + s)
} else {
}
fmt.Fprintf(os.Stderr, "%s", what)
if len(a) > 0 {
s := strings.Join(a, ", ")
@@ -44,16 +48,17 @@ func die(what string, a ...string) {
os.Exit(1)
}
}
// Bool asserts that cond is false.
//
// For example, this would replace
//
// if x < 0 {
// log.Fatal("x is subzero")
// }
//
// The same assertion would be
//
// assert.Bool(x, "x is subzero")
func Bool(cond bool, s ...string) {
if NoDebug {
@@ -68,6 +73,7 @@ func Bool(cond bool, s ...string) {
// Error asserts that err is not nil, e.g. that an error has occurred.
//
// For example,
//
// if err == nil {
// log.Fatal("call to <something> should have failed")
// }
@@ -100,7 +106,7 @@ func NoError(err error, s ...string) {
// ErrorEq asserts that the actual error is the expected error.
func ErrorEq(expected, actual error) {
if NoDebug || (expected == actual) {
if NoDebug || (errors.Is(expected, actual)) {
return
}
@@ -155,7 +161,7 @@ func NoErrorT(t *testing.T, err error) {
// ErrorEqT compares a pair of errors, calling Fatal on it if they
// don't match.
func ErrorEqT(t *testing.T, expected, actual error) {
if NoDebug || (expected == actual) {
if NoDebug || (errors.Is(expected, actual)) {
return
}

View File

@@ -10,29 +10,21 @@
// backoff is configured with a maximum duration that will not be
// exceeded.
//
// The `New` function will attempt to use the system's cryptographic
// random number generator to seed a Go math/rand random number
// source. If this fails, the package will panic on startup.
// This package uses math/rand/v2 for jitter, which is automatically
// seeded from a cryptographically secure source.
package backoff
import (
"crypto/rand"
"encoding/binary"
"io"
"math"
mrand "math/rand"
"sync"
"math/rand/v2"
"time"
)
var prngMu sync.Mutex
var prng *mrand.Rand
// DefaultInterval is used when a Backoff is initialised with a
// zero-value Interval.
var DefaultInterval = 5 * time.Minute
// DefaultMaxDuration is maximum amount of time that the backoff will
// DefaultMaxDuration is the maximum amount of time that the backoff will
// delay for.
var DefaultMaxDuration = 6 * time.Hour
@@ -50,10 +42,9 @@ type Backoff struct {
// interval controls the time step for backing off.
interval time.Duration
// noJitter controls whether to use the "Full Jitter"
// improvement to attempt to smooth out spikes in a high
// contention scenario. If noJitter is set to true, no
// jitter will be introduced.
// noJitter controls whether to use the "Full Jitter" improvement to attempt
// to smooth out spikes in a high-contention scenario. If noJitter is set to
// true, no jitter will be introduced.
noJitter bool
// decay controls the decay of n. If it is non-zero, n is
@@ -65,17 +56,17 @@ type Backoff struct {
lastTry time.Time
}
// New creates a new backoff with the specified max duration and
// New creates a new backoff with the specified maxDuration duration and
// interval. Zero values may be used to use the default values.
//
// Panics if either max or interval is negative.
func New(max time.Duration, interval time.Duration) *Backoff {
if max < 0 || interval < 0 {
panic("backoff: max or interval is negative")
// Panics if either dMax or interval is negative.
func New(dMax time.Duration, interval time.Duration) *Backoff {
if dMax < 0 || interval < 0 {
panic("backoff: dMax or interval is negative")
}
b := &Backoff{
maxDuration: max,
maxDuration: dMax,
interval: interval,
}
b.setup()
@@ -84,31 +75,12 @@ func New(max time.Duration, interval time.Duration) *Backoff {
// NewWithoutJitter works similarly to New, except that the created
// Backoff will not use jitter.
func NewWithoutJitter(max time.Duration, interval time.Duration) *Backoff {
b := New(max, interval)
func NewWithoutJitter(dMax time.Duration, interval time.Duration) *Backoff {
b := New(dMax, interval)
b.noJitter = true
return b
}
func init() {
var buf [8]byte
var n int64
_, err := io.ReadFull(rand.Reader, buf[:])
if err != nil {
panic(err.Error())
}
// G115: Intentional uint64->int64 conversion. Overflow is acceptable here
// since math/rand.NewSource accepts any int64 value (positive or negative)
// as a valid seed. The conversion ensures uniform distribution across the
// entire int64 range.
n = int64(binary.LittleEndian.Uint64(buf[:])) // #nosec G115
src := mrand.NewSource(n)
prng = mrand.New(src)
}
func (b *Backoff) setup() {
if b.interval == 0 {
b.interval = DefaultInterval
@@ -126,35 +98,44 @@ func (b *Backoff) Duration() time.Duration {
b.decayN()
t := b.duration(b.n)
d := b.duration(b.n)
if b.n < math.MaxUint64 {
b.n++
}
if !b.noJitter {
prngMu.Lock()
t = time.Duration(prng.Int63n(int64(t)))
prngMu.Unlock()
d = time.Duration(rand.Int64N(int64(d))) // #nosec G404
}
return t
return d
}
const maxN uint64 = 63
// requires b to be locked.
func (b *Backoff) duration(n uint64) (t time.Duration) {
// Saturate pow
pow := time.Duration(math.MaxInt64)
if n < 63 {
pow = 1 << n
func (b *Backoff) duration(n uint64) time.Duration {
// Use left shift on the underlying integer representation to avoid
// multiplying time.Duration by time.Duration (which is semantically
// incorrect and flagged by linters).
if n >= maxN {
// Saturate when n would overflow a 64-bit shift or exceed maxDuration.
return b.maxDuration
}
t = b.interval * pow
if t/pow != b.interval || t > b.maxDuration {
t = b.maxDuration
// Calculate 2^n * interval using a shift. Detect overflow by checking
// for sign change or monotonicity loss and clamp to maxDuration.
shifted := b.interval << n
if shifted < 0 || shifted < b.interval {
// Overflow occurred during the shift; clamp to maxDuration.
return b.maxDuration
}
return
if shifted > b.maxDuration {
return b.maxDuration
}
return shifted
}
// Reset resets the attempt counter of a backoff.
@@ -178,7 +159,7 @@ func (b *Backoff) SetDecay(decay time.Duration) {
b.decay = decay
}
// requires b to be locked
// requires b to be locked.
func (b *Backoff) decayN() {
if b.decay == 0 {
return
@@ -190,7 +171,9 @@ func (b *Backoff) decayN() {
}
lastDuration := b.duration(b.n - 1)
decayed := time.Since(b.lastTry) > lastDuration+b.decay
// Reset when the elapsed time is at least the previous backoff plus decay.
// Using ">=" avoids boundary flakiness in tests and real usage.
decayed := time.Since(b.lastTry) >= lastDuration+b.decay
b.lastTry = time.Now()
if !decayed {

View File

@@ -9,7 +9,7 @@ import (
// If given New with 0's and no jitter, ensure that certain invariants are met:
//
// - the default max duration and interval should be used
// - the default maxDuration duration and interval should be used
// - noJitter should be true
// - the RNG should not be initialised
// - the first duration should be equal to the default interval
@@ -17,7 +17,11 @@ func TestDefaults(t *testing.T) {
b := NewWithoutJitter(0, 0)
if b.maxDuration != DefaultMaxDuration {
t.Fatalf("expected new backoff to use the default max duration (%s), but have %s", DefaultMaxDuration, b.maxDuration)
t.Fatalf(
"expected new backoff to use the default maxDuration duration (%s), but have %s",
DefaultMaxDuration,
b.maxDuration,
)
}
if b.interval != DefaultInterval {
@@ -48,7 +52,7 @@ func TestSetup(t *testing.T) {
func TestTries(t *testing.T) {
b := NewWithoutJitter(5, 1)
for i := uint64(0); i < 3; i++ {
for i := range uint64(3) {
if b.n != i {
t.Fatalf("want tries=%d, have tries=%d", i, b.n)
}
@@ -73,7 +77,7 @@ func TestTries(t *testing.T) {
func TestReset(t *testing.T) {
const iter = 10
b := New(1000, 1)
for i := 0; i < iter; i++ {
for range iter {
_ = b.Duration()
}
@@ -88,17 +92,17 @@ func TestReset(t *testing.T) {
}
const decay = 5 * time.Millisecond
const max = 10 * time.Millisecond
const maxDuration = 10 * time.Millisecond
const interval = time.Millisecond
func TestDecay(t *testing.T) {
const iter = 10
b := NewWithoutJitter(max, 1)
b := NewWithoutJitter(maxDuration, 1)
b.SetDecay(decay)
var backoff time.Duration
for i := 0; i < iter; i++ {
for range iter {
backoff = b.Duration()
}
@@ -127,7 +131,7 @@ func TestDecaySaturation(t *testing.T) {
b.SetDecay(decay)
var duration time.Duration
for i := 0; i <= 2; i++ {
for range 3 {
duration = b.Duration()
}
@@ -145,7 +149,7 @@ func TestDecaySaturation(t *testing.T) {
}
func ExampleBackoff_SetDecay() {
b := NewWithoutJitter(max, interval)
b := NewWithoutJitter(maxDuration, interval)
b.SetDecay(decay)
// try 0

View File

@@ -158,59 +158,87 @@ type EncryptedContentInfo struct {
EncryptedContent []byte `asn1:"tag:0,optional"`
}
func unmarshalInit(raw []byte) (init initPKCS7, err error) {
_, err = asn1.Unmarshal(raw, &init)
if err != nil {
return initPKCS7{}, certerr.ParsingError(certerr.ErrorSourceCertificate, err)
}
return init, nil
}
func populateData(msg *PKCS7, content asn1.RawValue) error {
msg.ContentInfo = "Data"
_, err := asn1.Unmarshal(content.Bytes, &msg.Content.Data)
if err != nil {
return certerr.ParsingError(certerr.ErrorSourceCertificate, err)
}
return nil
}
func populateSignedData(msg *PKCS7, contentBytes []byte) error {
msg.ContentInfo = "SignedData"
var sd signedData
if _, err := asn1.Unmarshal(contentBytes, &sd); err != nil {
return certerr.ParsingError(certerr.ErrorSourceCertificate, err)
}
if len(sd.Certificates.Bytes) != 0 {
certs, err := x509.ParseCertificates(sd.Certificates.Bytes)
if err != nil {
return certerr.ParsingError(certerr.ErrorSourceCertificate, err)
}
msg.Content.SignedData.Certificates = certs
}
if len(sd.Crls.Bytes) != 0 {
crl, err := x509.ParseRevocationList(sd.Crls.Bytes)
if err != nil {
return certerr.ParsingError(certerr.ErrorSourceCertificate, err)
}
msg.Content.SignedData.Crl = crl
}
msg.Content.SignedData.Version = sd.Version
msg.Content.SignedData.Raw = contentBytes
return nil
}
func populateEncryptedData(msg *PKCS7, contentBytes []byte) error {
msg.ContentInfo = "EncryptedData"
var ed EncryptedData
if _, err := asn1.Unmarshal(contentBytes, &ed); err != nil {
return certerr.ParsingError(certerr.ErrorSourceCertificate, err)
}
if ed.Version != 0 {
return certerr.ParsingError(certerr.ErrorSourceCertificate, errors.New("only PKCS #7 encryptedData version 0 is supported"))
}
msg.Content.EncryptedData = ed
return nil
}
// ParsePKCS7 attempts to parse the DER encoded bytes of a
// PKCS7 structure.
func ParsePKCS7(raw []byte) (msg *PKCS7, err error) {
var pkcs7 initPKCS7
_, err = asn1.Unmarshal(raw, &pkcs7)
pkcs7, err := unmarshalInit(raw)
if err != nil {
return nil, certerr.ParsingError(certerr.ErrorSourceCertificate, err)
return nil, err
}
msg = new(PKCS7)
msg.Raw = pkcs7.Raw
msg.ContentInfo = pkcs7.ContentType.String()
switch {
case msg.ContentInfo == ObjIDData:
msg.ContentInfo = "Data"
_, err = asn1.Unmarshal(pkcs7.Content.Bytes, &msg.Content.Data)
if err != nil {
return nil, certerr.ParsingError(certerr.ErrorSourceCertificate, err)
}
case msg.ContentInfo == ObjIDSignedData:
msg.ContentInfo = "SignedData"
var signedData signedData
_, err = asn1.Unmarshal(pkcs7.Content.Bytes, &signedData)
if err != nil {
return nil, certerr.ParsingError(certerr.ErrorSourceCertificate, err)
}
if len(signedData.Certificates.Bytes) != 0 {
msg.Content.SignedData.Certificates, err = x509.ParseCertificates(signedData.Certificates.Bytes)
if err != nil {
return nil, certerr.ParsingError(certerr.ErrorSourceCertificate, err)
}
}
if len(signedData.Crls.Bytes) != 0 {
msg.Content.SignedData.Crl, err = x509.ParseRevocationList(signedData.Crls.Bytes)
if err != nil {
return nil, certerr.ParsingError(certerr.ErrorSourceCertificate, err)
}
}
msg.Content.SignedData.Version = signedData.Version
msg.Content.SignedData.Raw = pkcs7.Content.Bytes
case msg.ContentInfo == ObjIDEncryptedData:
msg.ContentInfo = "EncryptedData"
var encryptedData EncryptedData
_, err = asn1.Unmarshal(pkcs7.Content.Bytes, &encryptedData)
if err != nil {
return nil, certerr.ParsingError(certerr.ErrorSourceCertificate, err)
}
if encryptedData.Version != 0 {
return nil, certerr.ParsingError(certerr.ErrorSourceCertificate, errors.New("only PKCS #7 encryptedData version 0 is supported"))
}
msg.Content.EncryptedData = encryptedData
switch msg.ContentInfo {
case ObjIDData:
if err := populateData(msg, pkcs7.Content); err != nil {
return nil, err
}
case ObjIDSignedData:
if err := populateSignedData(msg, pkcs7.Content.Bytes); err != nil {
return nil, err
}
case ObjIDEncryptedData:
if err := populateEncryptedData(msg, pkcs7.Content.Bytes); err != nil {
return nil, err
}
default:
return nil, certerr.ParsingError(certerr.ErrorSourceCertificate, errors.New("only PKCS# 7 content of type data, signed data or encrypted data can be parsed"))
}

6
go.mod
View File

@@ -1,14 +1,14 @@
module git.wntrmute.dev/kyle/goutils
go 1.22
go 1.24.0
require (
github.com/hashicorp/go-syslog v1.0.0
github.com/kr/text v0.2.0
github.com/pkg/errors v0.9.1
github.com/pkg/sftp v1.12.0
golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad
golang.org/x/crypto v0.44.0
golang.org/x/sys v0.38.0
gopkg.in/yaml.v2 v2.4.0
)

5
go.sum
View File

@@ -27,12 +27,17 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b h1:Qwe1rC8PSniVfAFPFJeyUkB+zcysC3RgJBAGk7eqBEU=
golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU=
golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=