From 37f9a9fa9496c353d3e2c0c3b2d842aea60a0d11 Mon Sep 17 00:00:00 2001 From: Daenney Date: Tue, 10 Jun 2025 01:08:57 +0200 Subject: [PATCH] [chore] Upgrade to SQLite 3.50.1 (#4255) # Description ## Checklist Please put an x inside each checkbox to indicate that you've read and followed it: `[ ]` -> `[x]` If this is a documentation change, only the first checkbox must be filled (you can delete the others if you want). - [x] I/we have read the [GoToSocial contribution guidelines](https://codeberg.org/superseriousbusiness/gotosocial/src/branch/main/CONTRIBUTING.md). - [ ] I/we have discussed the proposed changes already, either in an issue on the repository, or in the Matrix chat. - [x] I/we have not leveraged AI to create the proposed changes. - [ ] I/we have performed a self-review of added code. - [ ] I/we have written code that is legible and maintainable by others. - [ ] I/we have commented the added code, particularly in hard-to-understand areas. - [ ] I/we have made any necessary changes to documentation. - [ ] I/we have added tests that cover new code. - [ ] I/we have run tests and they pass locally with the changes. - [ ] I/we have run `go fmt ./...` and `golangci-lint run`. Reviewed-on: https://codeberg.org/superseriousbusiness/gotosocial/pulls/4255 Co-authored-by: Daenney Co-committed-by: Daenney --- go.mod | 10 +- go.sum | 20 +- .../ncruces/go-sqlite3/embed/README.md | 2 +- .../ncruces/go-sqlite3/embed/sqlite3.wasm | Bin 1372201 -> 1372440 bytes .../ncruces/go-sqlite3/vfs/README.md | 2 +- vendor/golang.org/x/crypto/acme/acme.go | 55 +-- vendor/golang.org/x/crypto/bcrypt/bcrypt.go | 2 +- vendor/golang.org/x/crypto/ssh/certs.go | 41 +- vendor/golang.org/x/crypto/ssh/cipher.go | 40 +- vendor/golang.org/x/crypto/ssh/client.go | 1 + vendor/golang.org/x/crypto/ssh/common.go | 377 +++++++++++++----- vendor/golang.org/x/crypto/ssh/connection.go | 12 + vendor/golang.org/x/crypto/ssh/handshake.go | 24 +- vendor/golang.org/x/crypto/ssh/kex.go | 107 ++--- vendor/golang.org/x/crypto/ssh/keys.go | 25 +- vendor/golang.org/x/crypto/ssh/mac.go | 12 +- vendor/golang.org/x/crypto/ssh/messages.go | 6 +- vendor/golang.org/x/crypto/ssh/mlkem.go | 10 +- vendor/golang.org/x/crypto/ssh/server.go | 12 +- vendor/golang.org/x/crypto/ssh/transport.go | 15 +- vendor/golang.org/x/mod/module/module.go | 19 +- vendor/golang.org/x/mod/semver/semver.go | 30 +- vendor/golang.org/x/sync/errgroup/errgroup.go | 9 +- vendor/modules.txt | 10 +- 24 files changed, 502 insertions(+), 339 deletions(-) diff --git a/go.mod b/go.mod index ac9206afe..7b11e69d7 100644 --- a/go.mod +++ b/go.mod @@ -54,7 +54,7 @@ require ( github.com/miekg/dns v1.1.66 github.com/minio/minio-go/v7 v7.0.92 github.com/mitchellh/mapstructure v1.5.0 - github.com/ncruces/go-sqlite3 v0.26.0 + github.com/ncruces/go-sqlite3 v0.26.1 github.com/oklog/ulid v1.3.1 github.com/pquerna/otp v1.5.0 github.com/rivo/uniseg v0.4.7 @@ -83,12 +83,12 @@ require ( go.opentelemetry.io/otel/sdk/metric v1.36.0 go.opentelemetry.io/otel/trace v1.36.0 go.uber.org/automaxprocs v1.6.0 - golang.org/x/crypto v0.38.0 + golang.org/x/crypto v0.39.0 golang.org/x/image v0.27.0 golang.org/x/net v0.40.0 golang.org/x/oauth2 v0.30.0 golang.org/x/sys v0.33.0 - golang.org/x/text v0.25.0 + golang.org/x/text v0.26.0 gopkg.in/mcuadros/go-syslog.v2 v2.3.0 gopkg.in/yaml.v3 v3.0.1 modernc.org/sqlite v1.37.1 @@ -228,8 +228,8 @@ require ( go.uber.org/multierr v1.11.0 // indirect golang.org/x/arch v0.16.0 // indirect golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 // indirect - golang.org/x/mod v0.24.0 // indirect - golang.org/x/sync v0.14.0 // indirect + golang.org/x/mod v0.25.0 // indirect + golang.org/x/sync v0.15.0 // indirect golang.org/x/tools v0.33.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250519155744-55703ea1f237 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237 // indirect diff --git a/go.sum b/go.sum index 0db72cc56..86ca1b289 100644 --- a/go.sum +++ b/go.sum @@ -332,8 +332,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/ncruces/go-sqlite3 v0.26.0 h1:dY6ASfuhSEbtSge6kJwjyJVC7bXCpgEVOycmdboKJek= -github.com/ncruces/go-sqlite3 v0.26.0/go.mod h1:46HIzeCQQ+aNleAxCli+vpA2tfh7ttSnw24kQahBc1o= +github.com/ncruces/go-sqlite3 v0.26.1 h1:lBXmbmucH1Bsj57NUQR6T84UoMN7jnNImhF+ibEITJU= +github.com/ncruces/go-sqlite3 v0.26.1/go.mod h1:XFTPtFIo1DmGCh+XVP8KGn9b/o2f+z0WZuT09x2N6eo= github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= github.com/ncruces/julianday v1.0.0 h1:fH0OKwa7NWvniGQtxdJRxAgkBMolni2BjDHaWTxqt7M= @@ -568,8 +568,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8= -golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw= +golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM= +golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U= golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM= golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8= golang.org/x/image v0.27.0 h1:C8gA4oWU/tKkdCfYT6T2u4faJu3MeNS5O8UPWlPF61w= @@ -579,8 +579,8 @@ golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU= -golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= +golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w= +golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -607,8 +607,8 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= -golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8= +golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -648,8 +648,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= -golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= +golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= +golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= diff --git a/vendor/github.com/ncruces/go-sqlite3/embed/README.md b/vendor/github.com/ncruces/go-sqlite3/embed/README.md index ba279a60b..0f79f7a48 100644 --- a/vendor/github.com/ncruces/go-sqlite3/embed/README.md +++ b/vendor/github.com/ncruces/go-sqlite3/embed/README.md @@ -1,6 +1,6 @@ # Embeddable Wasm build of SQLite -This folder includes an embeddable Wasm build of SQLite 3.50.0 for use with +This folder includes an embeddable Wasm build of SQLite 3.50.1 for use with [`github.com/ncruces/go-sqlite3`](https://pkg.go.dev/github.com/ncruces/go-sqlite3). The following optional features are compiled in: diff --git a/vendor/github.com/ncruces/go-sqlite3/embed/sqlite3.wasm b/vendor/github.com/ncruces/go-sqlite3/embed/sqlite3.wasm index c596e63e41ee26bada540a8bed0d2409018910eb..be08c9d1e3d8048bcd90517d80d6c5efb2397957 100644 GIT binary patch delta 116356 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

3R3%js3`nIIjx-nMYSS#wCVV9L& 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%0DJQu3Qdox}gLjrvs|$P2vgV4cs^6j*q+ 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 diff --git a/vendor/github.com/ncruces/go-sqlite3/vfs/README.md b/vendor/github.com/ncruces/go-sqlite3/vfs/README.md index 17c24ec65..68cb92dcc 100644 --- a/vendor/github.com/ncruces/go-sqlite3/vfs/README.md +++ b/vendor/github.com/ncruces/go-sqlite3/vfs/README.md @@ -23,7 +23,7 @@ POSIX advisory locks, which SQLite uses on [Unix](https://github.com/sqlite/sqlite/blob/5d60f4/src/os_unix.c#L13-L14), are [broken by design](https://github.com/sqlite/sqlite/blob/5d60f4/src/os_unix.c#L1074-L1162). Instead, on Linux and macOS, this package uses -[OFD locks](https://www.gnu.org/software/libc/manual/html_node/Open-File-Description-Locks.html) +[OFD locks](https://gnu.org/software/libc/manual/html_node/Open-File-Description-Locks.html) to synchronize access to database files. This package can also use diff --git a/vendor/golang.org/x/crypto/acme/acme.go b/vendor/golang.org/x/crypto/acme/acme.go index cfb1dfd8c..6be00d1d0 100644 --- a/vendor/golang.org/x/crypto/acme/acme.go +++ b/vendor/golang.org/x/crypto/acme/acme.go @@ -31,9 +31,7 @@ import ( "crypto/x509/pkix" "encoding/asn1" "encoding/base64" - "encoding/hex" "encoding/json" - "encoding/pem" "errors" "fmt" "math/big" @@ -471,7 +469,7 @@ func (c *Client) WaitAuthorization(ctx context.Context, url string) (*Authorizat // while waiting for a final authorization status. d := retryAfter(res.Header.Get("Retry-After")) if d == 0 { - // Given that the fastest challenges TLS-SNI and HTTP-01 + // Given that the fastest challenges TLS-ALPN and HTTP-01 // require a CA to make at least 1 network round trip // and most likely persist a challenge state, // this default delay seems reasonable. @@ -572,44 +570,21 @@ func (c *Client) HTTP01ChallengePath(token string) string { } // TLSSNI01ChallengeCert creates a certificate for TLS-SNI-01 challenge response. +// Always returns an error. // -// Deprecated: This challenge type is unused in both draft-02 and RFC versions of the ACME spec. -func (c *Client) TLSSNI01ChallengeCert(token string, opt ...CertOption) (cert tls.Certificate, name string, err error) { - ka, err := keyAuth(c.Key.Public(), token) - if err != nil { - return tls.Certificate{}, "", err - } - b := sha256.Sum256([]byte(ka)) - h := hex.EncodeToString(b[:]) - name = fmt.Sprintf("%s.%s.acme.invalid", h[:32], h[32:]) - cert, err = tlsChallengeCert([]string{name}, opt) - if err != nil { - return tls.Certificate{}, "", err - } - return cert, name, nil +// Deprecated: This challenge type was only present in pre-standardized ACME +// protocol drafts and is insecure for use in shared hosting environments. +func (c *Client) TLSSNI01ChallengeCert(token string, opt ...CertOption) (tls.Certificate, string, error) { + return tls.Certificate{}, "", errPreRFC } // TLSSNI02ChallengeCert creates a certificate for TLS-SNI-02 challenge response. +// Always returns an error. // -// Deprecated: This challenge type is unused in both draft-02 and RFC versions of the ACME spec. -func (c *Client) TLSSNI02ChallengeCert(token string, opt ...CertOption) (cert tls.Certificate, name string, err error) { - b := sha256.Sum256([]byte(token)) - h := hex.EncodeToString(b[:]) - sanA := fmt.Sprintf("%s.%s.token.acme.invalid", h[:32], h[32:]) - - ka, err := keyAuth(c.Key.Public(), token) - if err != nil { - return tls.Certificate{}, "", err - } - b = sha256.Sum256([]byte(ka)) - h = hex.EncodeToString(b[:]) - sanB := fmt.Sprintf("%s.%s.ka.acme.invalid", h[:32], h[32:]) - - cert, err = tlsChallengeCert([]string{sanA, sanB}, opt) - if err != nil { - return tls.Certificate{}, "", err - } - return cert, sanA, nil +// Deprecated: This challenge type was only present in pre-standardized ACME +// protocol drafts and is insecure for use in shared hosting environments. +func (c *Client) TLSSNI02ChallengeCert(token string, opt ...CertOption) (tls.Certificate, string, error) { + return tls.Certificate{}, "", errPreRFC } // TLSALPN01ChallengeCert creates a certificate for TLS-ALPN-01 challenge response. @@ -773,7 +748,7 @@ func defaultTLSChallengeCertTemplate() *x509.Certificate { } } -// tlsChallengeCert creates a temporary certificate for TLS-SNI challenges +// tlsChallengeCert creates a temporary certificate for TLS-ALPN challenges // with the given SANs and auto-generated public/private key pair. // The Subject Common Name is set to the first SAN to aid debugging. // To create a cert with a custom key pair, specify WithKey option. @@ -816,11 +791,5 @@ func tlsChallengeCert(san []string, opt []CertOption) (tls.Certificate, error) { }, nil } -// encodePEM returns b encoded as PEM with block of type typ. -func encodePEM(typ string, b []byte) []byte { - pb := &pem.Block{Type: typ, Bytes: b} - return pem.EncodeToMemory(pb) -} - // timeNow is time.Now, except in tests which can mess with it. var timeNow = time.Now diff --git a/vendor/golang.org/x/crypto/bcrypt/bcrypt.go b/vendor/golang.org/x/crypto/bcrypt/bcrypt.go index dc9311870..3e7f8df87 100644 --- a/vendor/golang.org/x/crypto/bcrypt/bcrypt.go +++ b/vendor/golang.org/x/crypto/bcrypt/bcrypt.go @@ -50,7 +50,7 @@ func (ih InvalidHashPrefixError) Error() string { type InvalidCostError int func (ic InvalidCostError) Error() string { - return fmt.Sprintf("crypto/bcrypt: cost %d is outside allowed range (%d,%d)", int(ic), MinCost, MaxCost) + return fmt.Sprintf("crypto/bcrypt: cost %d is outside allowed inclusive range %d..%d", int(ic), MinCost, MaxCost) } const ( diff --git a/vendor/golang.org/x/crypto/ssh/certs.go b/vendor/golang.org/x/crypto/ssh/certs.go index 27d0e14aa..a3dc629c6 100644 --- a/vendor/golang.org/x/crypto/ssh/certs.go +++ b/vendor/golang.org/x/crypto/ssh/certs.go @@ -20,14 +20,19 @@ import ( // returned by MultiAlgorithmSigner and don't appear in the Signature.Format // field. const ( - CertAlgoRSAv01 = "ssh-rsa-cert-v01@openssh.com" - CertAlgoDSAv01 = "ssh-dss-cert-v01@openssh.com" - CertAlgoECDSA256v01 = "ecdsa-sha2-nistp256-cert-v01@openssh.com" - CertAlgoECDSA384v01 = "ecdsa-sha2-nistp384-cert-v01@openssh.com" - CertAlgoECDSA521v01 = "ecdsa-sha2-nistp521-cert-v01@openssh.com" - CertAlgoSKECDSA256v01 = "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com" - CertAlgoED25519v01 = "ssh-ed25519-cert-v01@openssh.com" - CertAlgoSKED25519v01 = "sk-ssh-ed25519-cert-v01@openssh.com" + CertAlgoRSAv01 = "ssh-rsa-cert-v01@openssh.com" + // Deprecated: DSA is only supported at insecure key sizes, and was removed + // from major implementations. + CertAlgoDSAv01 = InsecureCertAlgoDSAv01 + // Deprecated: DSA is only supported at insecure key sizes, and was removed + // from major implementations. + InsecureCertAlgoDSAv01 = "ssh-dss-cert-v01@openssh.com" + CertAlgoECDSA256v01 = "ecdsa-sha2-nistp256-cert-v01@openssh.com" + CertAlgoECDSA384v01 = "ecdsa-sha2-nistp384-cert-v01@openssh.com" + CertAlgoECDSA521v01 = "ecdsa-sha2-nistp521-cert-v01@openssh.com" + CertAlgoSKECDSA256v01 = "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com" + CertAlgoED25519v01 = "ssh-ed25519-cert-v01@openssh.com" + CertAlgoSKED25519v01 = "sk-ssh-ed25519-cert-v01@openssh.com" // CertAlgoRSASHA256v01 and CertAlgoRSASHA512v01 can't appear as a // Certificate.Type (or PublicKey.Type), but only in @@ -485,16 +490,16 @@ func (c *Certificate) SignCert(rand io.Reader, authority Signer) error { // // This map must be kept in sync with the one in agent/client.go. var certKeyAlgoNames = map[string]string{ - CertAlgoRSAv01: KeyAlgoRSA, - CertAlgoRSASHA256v01: KeyAlgoRSASHA256, - CertAlgoRSASHA512v01: KeyAlgoRSASHA512, - CertAlgoDSAv01: KeyAlgoDSA, - CertAlgoECDSA256v01: KeyAlgoECDSA256, - CertAlgoECDSA384v01: KeyAlgoECDSA384, - CertAlgoECDSA521v01: KeyAlgoECDSA521, - CertAlgoSKECDSA256v01: KeyAlgoSKECDSA256, - CertAlgoED25519v01: KeyAlgoED25519, - CertAlgoSKED25519v01: KeyAlgoSKED25519, + CertAlgoRSAv01: KeyAlgoRSA, + CertAlgoRSASHA256v01: KeyAlgoRSASHA256, + CertAlgoRSASHA512v01: KeyAlgoRSASHA512, + InsecureCertAlgoDSAv01: InsecureKeyAlgoDSA, + CertAlgoECDSA256v01: KeyAlgoECDSA256, + CertAlgoECDSA384v01: KeyAlgoECDSA384, + CertAlgoECDSA521v01: KeyAlgoECDSA521, + CertAlgoSKECDSA256v01: KeyAlgoSKECDSA256, + CertAlgoED25519v01: KeyAlgoED25519, + CertAlgoSKED25519v01: KeyAlgoSKED25519, } // underlyingAlgo returns the signature algorithm associated with algo (which is diff --git a/vendor/golang.org/x/crypto/ssh/cipher.go b/vendor/golang.org/x/crypto/ssh/cipher.go index 741e984f3..6a5b582aa 100644 --- a/vendor/golang.org/x/crypto/ssh/cipher.go +++ b/vendor/golang.org/x/crypto/ssh/cipher.go @@ -58,11 +58,11 @@ func newRC4(key, iv []byte) (cipher.Stream, error) { type cipherMode struct { keySize int ivSize int - create func(key, iv []byte, macKey []byte, algs directionAlgorithms) (packetCipher, error) + create func(key, iv []byte, macKey []byte, algs DirectionAlgorithms) (packetCipher, error) } -func streamCipherMode(skip int, createFunc func(key, iv []byte) (cipher.Stream, error)) func(key, iv []byte, macKey []byte, algs directionAlgorithms) (packetCipher, error) { - return func(key, iv, macKey []byte, algs directionAlgorithms) (packetCipher, error) { +func streamCipherMode(skip int, createFunc func(key, iv []byte) (cipher.Stream, error)) func(key, iv []byte, macKey []byte, algs DirectionAlgorithms) (packetCipher, error) { + return func(key, iv, macKey []byte, algs DirectionAlgorithms) (packetCipher, error) { stream, err := createFunc(key, iv) if err != nil { return nil, err @@ -98,36 +98,36 @@ func streamCipherMode(skip int, createFunc func(key, iv []byte) (cipher.Stream, var cipherModes = map[string]*cipherMode{ // Ciphers from RFC 4344, which introduced many CTR-based ciphers. Algorithms // are defined in the order specified in the RFC. - "aes128-ctr": {16, aes.BlockSize, streamCipherMode(0, newAESCTR)}, - "aes192-ctr": {24, aes.BlockSize, streamCipherMode(0, newAESCTR)}, - "aes256-ctr": {32, aes.BlockSize, streamCipherMode(0, newAESCTR)}, + CipherAES128CTR: {16, aes.BlockSize, streamCipherMode(0, newAESCTR)}, + CipherAES192CTR: {24, aes.BlockSize, streamCipherMode(0, newAESCTR)}, + CipherAES256CTR: {32, aes.BlockSize, streamCipherMode(0, newAESCTR)}, // Ciphers from RFC 4345, which introduces security-improved arcfour ciphers. // They are defined in the order specified in the RFC. - "arcfour128": {16, 0, streamCipherMode(1536, newRC4)}, - "arcfour256": {32, 0, streamCipherMode(1536, newRC4)}, + InsecureCipherRC4128: {16, 0, streamCipherMode(1536, newRC4)}, + InsecureCipherRC4256: {32, 0, streamCipherMode(1536, newRC4)}, // Cipher defined in RFC 4253, which describes SSH Transport Layer Protocol. // Note that this cipher is not safe, as stated in RFC 4253: "Arcfour (and // RC4) has problems with weak keys, and should be used with caution." // RFC 4345 introduces improved versions of Arcfour. - "arcfour": {16, 0, streamCipherMode(0, newRC4)}, + InsecureCipherRC4: {16, 0, streamCipherMode(0, newRC4)}, // AEAD ciphers - gcm128CipherID: {16, 12, newGCMCipher}, - gcm256CipherID: {32, 12, newGCMCipher}, - chacha20Poly1305ID: {64, 0, newChaCha20Cipher}, + CipherAES128GCM: {16, 12, newGCMCipher}, + CipherAES256GCM: {32, 12, newGCMCipher}, + CipherChaCha20Poly1305: {64, 0, newChaCha20Cipher}, // CBC mode is insecure and so is not included in the default config. // (See https://www.ieee-security.org/TC/SP2013/papers/4977a526.pdf). If absolutely // needed, it's possible to specify a custom Config to enable it. // You should expect that an active attacker can recover plaintext if // you do. - aes128cbcID: {16, aes.BlockSize, newAESCBCCipher}, + InsecureCipherAES128CBC: {16, aes.BlockSize, newAESCBCCipher}, // 3des-cbc is insecure and is not included in the default // config. - tripledescbcID: {24, des.BlockSize, newTripleDESCBCCipher}, + InsecureCipherTripleDESCBC: {24, des.BlockSize, newTripleDESCBCCipher}, } // prefixLen is the length of the packet prefix that contains the packet length @@ -307,7 +307,7 @@ type gcmCipher struct { buf []byte } -func newGCMCipher(key, iv, unusedMacKey []byte, unusedAlgs directionAlgorithms) (packetCipher, error) { +func newGCMCipher(key, iv, unusedMacKey []byte, unusedAlgs DirectionAlgorithms) (packetCipher, error) { c, err := aes.NewCipher(key) if err != nil { return nil, err @@ -429,7 +429,7 @@ type cbcCipher struct { oracleCamouflage uint32 } -func newCBCCipher(c cipher.Block, key, iv, macKey []byte, algs directionAlgorithms) (packetCipher, error) { +func newCBCCipher(c cipher.Block, key, iv, macKey []byte, algs DirectionAlgorithms) (packetCipher, error) { cbc := &cbcCipher{ mac: macModes[algs.MAC].new(macKey), decrypter: cipher.NewCBCDecrypter(c, iv), @@ -443,7 +443,7 @@ func newCBCCipher(c cipher.Block, key, iv, macKey []byte, algs directionAlgorith return cbc, nil } -func newAESCBCCipher(key, iv, macKey []byte, algs directionAlgorithms) (packetCipher, error) { +func newAESCBCCipher(key, iv, macKey []byte, algs DirectionAlgorithms) (packetCipher, error) { c, err := aes.NewCipher(key) if err != nil { return nil, err @@ -457,7 +457,7 @@ func newAESCBCCipher(key, iv, macKey []byte, algs directionAlgorithms) (packetCi return cbc, nil } -func newTripleDESCBCCipher(key, iv, macKey []byte, algs directionAlgorithms) (packetCipher, error) { +func newTripleDESCBCCipher(key, iv, macKey []byte, algs DirectionAlgorithms) (packetCipher, error) { c, err := des.NewTripleDESCipher(key) if err != nil { return nil, err @@ -635,8 +635,6 @@ func (c *cbcCipher) writeCipherPacket(seqNum uint32, w io.Writer, rand io.Reader return nil } -const chacha20Poly1305ID = "chacha20-poly1305@openssh.com" - // chacha20Poly1305Cipher implements the chacha20-poly1305@openssh.com // AEAD, which is described here: // @@ -650,7 +648,7 @@ type chacha20Poly1305Cipher struct { buf []byte } -func newChaCha20Cipher(key, unusedIV, unusedMACKey []byte, unusedAlgs directionAlgorithms) (packetCipher, error) { +func newChaCha20Cipher(key, unusedIV, unusedMACKey []byte, unusedAlgs DirectionAlgorithms) (packetCipher, error) { if len(key) != 64 { panic(len(key)) } diff --git a/vendor/golang.org/x/crypto/ssh/client.go b/vendor/golang.org/x/crypto/ssh/client.go index fd8c49749..33079789b 100644 --- a/vendor/golang.org/x/crypto/ssh/client.go +++ b/vendor/golang.org/x/crypto/ssh/client.go @@ -110,6 +110,7 @@ func (c *connection) clientHandshake(dialAddress string, config *ClientConfig) e } c.sessionID = c.transport.getSessionID() + c.algorithms = c.transport.getAlgorithms() return c.clientAuthenticate(config) } diff --git a/vendor/golang.org/x/crypto/ssh/common.go b/vendor/golang.org/x/crypto/ssh/common.go index 7e9c2cbc6..0415d3396 100644 --- a/vendor/golang.org/x/crypto/ssh/common.go +++ b/vendor/golang.org/x/crypto/ssh/common.go @@ -10,6 +10,7 @@ import ( "fmt" "io" "math" + "slices" "sync" _ "crypto/sha1" @@ -24,69 +25,258 @@ const ( serviceSSH = "ssh-connection" ) -// supportedCiphers lists ciphers we support but might not recommend. -var supportedCiphers = []string{ - "aes128-ctr", "aes192-ctr", "aes256-ctr", - "aes128-gcm@openssh.com", gcm256CipherID, - chacha20Poly1305ID, - "arcfour256", "arcfour128", "arcfour", - aes128cbcID, - tripledescbcID, +// The ciphers currently or previously implemented by this library, to use in +// [Config.Ciphers]. For a list, see the [Algorithms.Ciphers] returned by +// [SupportedAlgorithms] or [InsecureAlgorithms]. +const ( + CipherAES128GCM = "aes128-gcm@openssh.com" + CipherAES256GCM = "aes256-gcm@openssh.com" + CipherChaCha20Poly1305 = "chacha20-poly1305@openssh.com" + CipherAES128CTR = "aes128-ctr" + CipherAES192CTR = "aes192-ctr" + CipherAES256CTR = "aes256-ctr" + InsecureCipherAES128CBC = "aes128-cbc" + InsecureCipherTripleDESCBC = "3des-cbc" + InsecureCipherRC4 = "arcfour" + InsecureCipherRC4128 = "arcfour128" + InsecureCipherRC4256 = "arcfour256" +) + +// The key exchanges currently or previously implemented by this library, to use +// in [Config.KeyExchanges]. For a list, see the +// [Algorithms.KeyExchanges] returned by [SupportedAlgorithms] or +// [InsecureAlgorithms]. +const ( + InsecureKeyExchangeDH1SHA1 = "diffie-hellman-group1-sha1" + InsecureKeyExchangeDH14SHA1 = "diffie-hellman-group14-sha1" + KeyExchangeDH14SHA256 = "diffie-hellman-group14-sha256" + KeyExchangeDH16SHA512 = "diffie-hellman-group16-sha512" + KeyExchangeECDHP256 = "ecdh-sha2-nistp256" + KeyExchangeECDHP384 = "ecdh-sha2-nistp384" + KeyExchangeECDHP521 = "ecdh-sha2-nistp521" + KeyExchangeCurve25519 = "curve25519-sha256" + InsecureKeyExchangeDHGEXSHA1 = "diffie-hellman-group-exchange-sha1" + KeyExchangeDHGEXSHA256 = "diffie-hellman-group-exchange-sha256" + // KeyExchangeMLKEM768X25519 is supported from Go 1.24. + KeyExchangeMLKEM768X25519 = "mlkem768x25519-sha256" + + // An alias for KeyExchangeCurve25519SHA256. This kex ID will be added if + // KeyExchangeCurve25519SHA256 is requested for backward compatibility with + // OpenSSH versions up to 7.2. + keyExchangeCurve25519LibSSH = "curve25519-sha256@libssh.org" +) + +// The message authentication code (MAC) currently or previously implemented by +// this library, to use in [Config.MACs]. For a list, see the +// [Algorithms.MACs] returned by [SupportedAlgorithms] or +// [InsecureAlgorithms]. +const ( + HMACSHA256ETM = "hmac-sha2-256-etm@openssh.com" + HMACSHA512ETM = "hmac-sha2-512-etm@openssh.com" + HMACSHA256 = "hmac-sha2-256" + HMACSHA512 = "hmac-sha2-512" + HMACSHA1 = "hmac-sha1" + InsecureHMACSHA196 = "hmac-sha1-96" +) + +var ( + // supportedKexAlgos specifies key-exchange algorithms implemented by this + // package in preference order, excluding those with security issues. + supportedKexAlgos = []string{ + KeyExchangeCurve25519, + KeyExchangeECDHP256, + KeyExchangeECDHP384, + KeyExchangeECDHP521, + KeyExchangeDH14SHA256, + KeyExchangeDH16SHA512, + KeyExchangeDHGEXSHA256, + } + // defaultKexAlgos specifies the default preference for key-exchange + // algorithms in preference order. + defaultKexAlgos = []string{ + KeyExchangeCurve25519, + KeyExchangeECDHP256, + KeyExchangeECDHP384, + KeyExchangeECDHP521, + KeyExchangeDH14SHA256, + InsecureKeyExchangeDH14SHA1, + } + // insecureKexAlgos specifies key-exchange algorithms implemented by this + // package and which have security issues. + insecureKexAlgos = []string{ + InsecureKeyExchangeDH14SHA1, + InsecureKeyExchangeDH1SHA1, + InsecureKeyExchangeDHGEXSHA1, + } + // supportedCiphers specifies cipher algorithms implemented by this package + // in preference order, excluding those with security issues. + supportedCiphers = []string{ + CipherAES128GCM, + CipherAES256GCM, + CipherChaCha20Poly1305, + CipherAES128CTR, + CipherAES192CTR, + CipherAES256CTR, + } + // defaultCiphers specifies the default preference for ciphers algorithms + // in preference order. + defaultCiphers = supportedCiphers + // insecureCiphers specifies cipher algorithms implemented by this + // package and which have security issues. + insecureCiphers = []string{ + InsecureCipherAES128CBC, + InsecureCipherTripleDESCBC, + InsecureCipherRC4256, + InsecureCipherRC4128, + InsecureCipherRC4, + } + // supportedMACs specifies MAC algorithms implemented by this package in + // preference order, excluding those with security issues. + supportedMACs = []string{ + HMACSHA256ETM, + HMACSHA512ETM, + HMACSHA256, + HMACSHA512, + HMACSHA1, + } + // defaultMACs specifies the default preference for MAC algorithms in + // preference order. + defaultMACs = []string{ + HMACSHA256ETM, + HMACSHA512ETM, + HMACSHA256, + HMACSHA512, + HMACSHA1, + InsecureHMACSHA196, + } + // insecureMACs specifies MAC algorithms implemented by this + // package and which have security issues. + insecureMACs = []string{ + InsecureHMACSHA196, + } + // supportedHostKeyAlgos specifies the supported host-key algorithms (i.e. + // methods of authenticating servers) implemented by this package in + // preference order, excluding those with security issues. + supportedHostKeyAlgos = []string{ + CertAlgoRSASHA256v01, + CertAlgoRSASHA512v01, + CertAlgoECDSA256v01, + CertAlgoECDSA384v01, + CertAlgoECDSA521v01, + CertAlgoED25519v01, + KeyAlgoRSASHA256, + KeyAlgoRSASHA512, + KeyAlgoECDSA256, + KeyAlgoECDSA384, + KeyAlgoECDSA521, + KeyAlgoED25519, + } + // defaultHostKeyAlgos specifies the default preference for host-key + // algorithms in preference order. + defaultHostKeyAlgos = []string{ + CertAlgoRSASHA256v01, + CertAlgoRSASHA512v01, + CertAlgoRSAv01, + InsecureCertAlgoDSAv01, + CertAlgoECDSA256v01, + CertAlgoECDSA384v01, + CertAlgoECDSA521v01, + CertAlgoED25519v01, + KeyAlgoECDSA256, + KeyAlgoECDSA384, + KeyAlgoECDSA521, + KeyAlgoRSASHA256, + KeyAlgoRSASHA512, + KeyAlgoRSA, + InsecureKeyAlgoDSA, + KeyAlgoED25519, + } + // insecureHostKeyAlgos specifies host-key algorithms implemented by this + // package and which have security issues. + insecureHostKeyAlgos = []string{ + KeyAlgoRSA, + InsecureKeyAlgoDSA, + CertAlgoRSAv01, + InsecureCertAlgoDSAv01, + } + // supportedPubKeyAuthAlgos specifies the supported client public key + // authentication algorithms. Note that this doesn't include certificate + // types since those use the underlying algorithm. Order is irrelevant. + supportedPubKeyAuthAlgos = []string{ + KeyAlgoED25519, + KeyAlgoSKED25519, + KeyAlgoSKECDSA256, + KeyAlgoECDSA256, + KeyAlgoECDSA384, + KeyAlgoECDSA521, + KeyAlgoRSASHA256, + KeyAlgoRSASHA512, + } + + // defaultPubKeyAuthAlgos specifies the preferred client public key + // authentication algorithms. This list is sent to the client if it supports + // the server-sig-algs extension. Order is irrelevant. + defaultPubKeyAuthAlgos = []string{ + KeyAlgoED25519, + KeyAlgoSKED25519, + KeyAlgoSKECDSA256, + KeyAlgoECDSA256, + KeyAlgoECDSA384, + KeyAlgoECDSA521, + KeyAlgoRSASHA256, + KeyAlgoRSASHA512, + KeyAlgoRSA, + InsecureKeyAlgoDSA, + } + // insecurePubKeyAuthAlgos specifies client public key authentication + // algorithms implemented by this package and which have security issues. + insecurePubKeyAuthAlgos = []string{ + KeyAlgoRSA, + InsecureKeyAlgoDSA, + } +) + +// NegotiatedAlgorithms defines algorithms negotiated between client and server. +type NegotiatedAlgorithms struct { + KeyExchange string + HostKey string + Read DirectionAlgorithms + Write DirectionAlgorithms } -// preferredCiphers specifies the default preference for ciphers. -var preferredCiphers = []string{ - "aes128-gcm@openssh.com", gcm256CipherID, - chacha20Poly1305ID, - "aes128-ctr", "aes192-ctr", "aes256-ctr", +// Algorithms defines a set of algorithms that can be configured in the client +// or server config for negotiation during a handshake. +type Algorithms struct { + KeyExchanges []string + Ciphers []string + MACs []string + HostKeys []string + PublicKeyAuths []string } -// supportedKexAlgos specifies the supported key-exchange algorithms in -// preference order. -var supportedKexAlgos = []string{ - kexAlgoCurve25519SHA256, kexAlgoCurve25519SHA256LibSSH, - // P384 and P521 are not constant-time yet, but since we don't - // reuse ephemeral keys, using them for ECDH should be OK. - kexAlgoECDH256, kexAlgoECDH384, kexAlgoECDH521, - kexAlgoDH14SHA256, kexAlgoDH16SHA512, kexAlgoDH14SHA1, - kexAlgoDH1SHA1, +// SupportedAlgorithms returns algorithms currently implemented by this package, +// excluding those with security issues, which are returned by +// InsecureAlgorithms. The algorithms listed here are in preference order. +func SupportedAlgorithms() Algorithms { + return Algorithms{ + Ciphers: slices.Clone(supportedCiphers), + MACs: slices.Clone(supportedMACs), + KeyExchanges: slices.Clone(supportedKexAlgos), + HostKeys: slices.Clone(supportedHostKeyAlgos), + PublicKeyAuths: slices.Clone(supportedPubKeyAuthAlgos), + } } -// serverForbiddenKexAlgos contains key exchange algorithms, that are forbidden -// for the server half. -var serverForbiddenKexAlgos = map[string]struct{}{ - kexAlgoDHGEXSHA1: {}, // server half implementation is only minimal to satisfy the automated tests - kexAlgoDHGEXSHA256: {}, // server half implementation is only minimal to satisfy the automated tests -} - -// preferredKexAlgos specifies the default preference for key-exchange -// algorithms in preference order. The diffie-hellman-group16-sha512 algorithm -// is disabled by default because it is a bit slower than the others. -var preferredKexAlgos = []string{ - kexAlgoCurve25519SHA256, kexAlgoCurve25519SHA256LibSSH, - kexAlgoECDH256, kexAlgoECDH384, kexAlgoECDH521, - kexAlgoDH14SHA256, kexAlgoDH14SHA1, -} - -// supportedHostKeyAlgos specifies the supported host-key algorithms (i.e. methods -// of authenticating servers) in preference order. -var supportedHostKeyAlgos = []string{ - CertAlgoRSASHA256v01, CertAlgoRSASHA512v01, - CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, - CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoED25519v01, - - KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521, - KeyAlgoRSASHA256, KeyAlgoRSASHA512, - KeyAlgoRSA, KeyAlgoDSA, - - KeyAlgoED25519, -} - -// supportedMACs specifies a default set of MAC algorithms in preference order. -// This is based on RFC 4253, section 6.4, but with hmac-md5 variants removed -// because they have reached the end of their useful life. -var supportedMACs = []string{ - "hmac-sha2-256-etm@openssh.com", "hmac-sha2-512-etm@openssh.com", "hmac-sha2-256", "hmac-sha2-512", "hmac-sha1", "hmac-sha1-96", +// InsecureAlgorithms returns algorithms currently implemented by this package +// and which have security issues. +func InsecureAlgorithms() Algorithms { + return Algorithms{ + KeyExchanges: slices.Clone(insecureKexAlgos), + Ciphers: slices.Clone(insecureCiphers), + MACs: slices.Clone(insecureMACs), + HostKeys: slices.Clone(insecureHostKeyAlgos), + PublicKeyAuths: slices.Clone(insecurePubKeyAuthAlgos), + } } var supportedCompressions = []string{compressionNone} @@ -94,13 +284,13 @@ var supportedCompressions = []string{compressionNone} // hashFuncs keeps the mapping of supported signature algorithms to their // respective hashes needed for signing and verification. var hashFuncs = map[string]crypto.Hash{ - KeyAlgoRSA: crypto.SHA1, - KeyAlgoRSASHA256: crypto.SHA256, - KeyAlgoRSASHA512: crypto.SHA512, - KeyAlgoDSA: crypto.SHA1, - KeyAlgoECDSA256: crypto.SHA256, - KeyAlgoECDSA384: crypto.SHA384, - KeyAlgoECDSA521: crypto.SHA512, + KeyAlgoRSA: crypto.SHA1, + KeyAlgoRSASHA256: crypto.SHA256, + KeyAlgoRSASHA512: crypto.SHA512, + InsecureKeyAlgoDSA: crypto.SHA1, + KeyAlgoECDSA256: crypto.SHA256, + KeyAlgoECDSA384: crypto.SHA384, + KeyAlgoECDSA521: crypto.SHA512, // KeyAlgoED25519 doesn't pre-hash. KeyAlgoSKECDSA256: crypto.SHA256, KeyAlgoSKED25519: crypto.SHA256, @@ -135,18 +325,6 @@ func isRSACert(algo string) bool { return isRSA(algo) } -// supportedPubKeyAuthAlgos specifies the supported client public key -// authentication algorithms. Note that this doesn't include certificate types -// since those use the underlying algorithm. This list is sent to the client if -// it supports the server-sig-algs extension. Order is irrelevant. -var supportedPubKeyAuthAlgos = []string{ - KeyAlgoED25519, - KeyAlgoSKED25519, KeyAlgoSKECDSA256, - KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521, - KeyAlgoRSASHA256, KeyAlgoRSASHA512, KeyAlgoRSA, - KeyAlgoDSA, -} - // unexpectedMessageError results when the SSH message that we received didn't // match what we wanted. func unexpectedMessageError(expected, got uint8) error { @@ -169,20 +347,21 @@ func findCommon(what string, client []string, server []string) (common string, e return "", fmt.Errorf("ssh: no common algorithm for %s; client offered: %v, server offered: %v", what, client, server) } -// directionAlgorithms records algorithm choices in one direction (either read or write) -type directionAlgorithms struct { +// DirectionAlgorithms defines the algorithms negotiated in one direction +// (either read or write). +type DirectionAlgorithms struct { Cipher string MAC string - Compression string + compression string } // rekeyBytes returns a rekeying intervals in bytes. -func (a *directionAlgorithms) rekeyBytes() int64 { +func (a *DirectionAlgorithms) rekeyBytes() int64 { // According to RFC 4344 block ciphers should rekey after // 2^(BLOCKSIZE/4) blocks. For all AES flavors BLOCKSIZE is // 128. switch a.Cipher { - case "aes128-ctr", "aes192-ctr", "aes256-ctr", gcm128CipherID, gcm256CipherID, aes128cbcID: + case CipherAES128CTR, CipherAES192CTR, CipherAES256CTR, CipherAES128GCM, CipherAES256GCM, InsecureCipherAES128CBC: return 16 * (1 << 32) } @@ -192,32 +371,25 @@ func (a *directionAlgorithms) rekeyBytes() int64 { } var aeadCiphers = map[string]bool{ - gcm128CipherID: true, - gcm256CipherID: true, - chacha20Poly1305ID: true, + CipherAES128GCM: true, + CipherAES256GCM: true, + CipherChaCha20Poly1305: true, } -type algorithms struct { - kex string - hostKey string - w directionAlgorithms - r directionAlgorithms -} +func findAgreedAlgorithms(isClient bool, clientKexInit, serverKexInit *kexInitMsg) (algs *NegotiatedAlgorithms, err error) { + result := &NegotiatedAlgorithms{} -func findAgreedAlgorithms(isClient bool, clientKexInit, serverKexInit *kexInitMsg) (algs *algorithms, err error) { - result := &algorithms{} - - result.kex, err = findCommon("key exchange", clientKexInit.KexAlgos, serverKexInit.KexAlgos) + result.KeyExchange, err = findCommon("key exchange", clientKexInit.KexAlgos, serverKexInit.KexAlgos) if err != nil { return } - result.hostKey, err = findCommon("host key", clientKexInit.ServerHostKeyAlgos, serverKexInit.ServerHostKeyAlgos) + result.HostKey, err = findCommon("host key", clientKexInit.ServerHostKeyAlgos, serverKexInit.ServerHostKeyAlgos) if err != nil { return } - stoc, ctos := &result.w, &result.r + stoc, ctos := &result.Write, &result.Read if isClient { ctos, stoc = stoc, ctos } @@ -246,12 +418,12 @@ func findAgreedAlgorithms(isClient bool, clientKexInit, serverKexInit *kexInitMs } } - ctos.Compression, err = findCommon("client to server compression", clientKexInit.CompressionClientServer, serverKexInit.CompressionClientServer) + ctos.compression, err = findCommon("client to server compression", clientKexInit.CompressionClientServer, serverKexInit.CompressionClientServer) if err != nil { return } - stoc.Compression, err = findCommon("server to client compression", clientKexInit.CompressionServerClient, serverKexInit.CompressionServerClient) + stoc.compression, err = findCommon("server to client compression", clientKexInit.CompressionServerClient, serverKexInit.CompressionServerClient) if err != nil { return } @@ -297,7 +469,7 @@ func (c *Config) SetDefaults() { c.Rand = rand.Reader } if c.Ciphers == nil { - c.Ciphers = preferredCiphers + c.Ciphers = defaultCiphers } var ciphers []string for _, c := range c.Ciphers { @@ -309,19 +481,22 @@ func (c *Config) SetDefaults() { c.Ciphers = ciphers if c.KeyExchanges == nil { - c.KeyExchanges = preferredKexAlgos + c.KeyExchanges = defaultKexAlgos } var kexs []string for _, k := range c.KeyExchanges { if kexAlgoMap[k] != nil { // Ignore the KEX if we have no kexAlgoMap definition. kexs = append(kexs, k) + if k == KeyExchangeCurve25519 && !contains(c.KeyExchanges, keyExchangeCurve25519LibSSH) { + kexs = append(kexs, keyExchangeCurve25519LibSSH) + } } } c.KeyExchanges = kexs if c.MACs == nil { - c.MACs = supportedMACs + c.MACs = defaultMACs } var macs []string for _, m := range c.MACs { diff --git a/vendor/golang.org/x/crypto/ssh/connection.go b/vendor/golang.org/x/crypto/ssh/connection.go index 8f345ee92..613a71a7b 100644 --- a/vendor/golang.org/x/crypto/ssh/connection.go +++ b/vendor/golang.org/x/crypto/ssh/connection.go @@ -74,6 +74,13 @@ type Conn interface { // Disconnect } +// AlgorithmsConnMetadata is a ConnMetadata that can return the algorithms +// negotiated between client and server. +type AlgorithmsConnMetadata interface { + ConnMetadata + Algorithms() NegotiatedAlgorithms +} + // DiscardRequests consumes and rejects all requests from the // passed-in channel. func DiscardRequests(in <-chan *Request) { @@ -106,6 +113,7 @@ type sshConn struct { sessionID []byte clientVersion []byte serverVersion []byte + algorithms NegotiatedAlgorithms } func dup(src []byte) []byte { @@ -141,3 +149,7 @@ func (c *sshConn) ClientVersion() []byte { func (c *sshConn) ServerVersion() []byte { return dup(c.serverVersion) } + +func (c *sshConn) Algorithms() NegotiatedAlgorithms { + return c.algorithms +} diff --git a/vendor/golang.org/x/crypto/ssh/handshake.go b/vendor/golang.org/x/crypto/ssh/handshake.go index b6bf546b4..a90bfe331 100644 --- a/vendor/golang.org/x/crypto/ssh/handshake.go +++ b/vendor/golang.org/x/crypto/ssh/handshake.go @@ -38,7 +38,7 @@ type keyingTransport interface { // prepareKeyChange sets up a key change. The key change for a // direction will be effected if a msgNewKeys message is sent // or received. - prepareKeyChange(*algorithms, *kexResult) error + prepareKeyChange(*NegotiatedAlgorithms, *kexResult) error // setStrictMode sets the strict KEX mode, notably triggering // sequence number resets on sending or receiving msgNewKeys. @@ -115,7 +115,7 @@ type handshakeTransport struct { bannerCallback BannerCallback // Algorithms agreed in the last key exchange. - algorithms *algorithms + algorithms *NegotiatedAlgorithms // Counters exclusively owned by readLoop. readPacketsLeft uint32 @@ -164,7 +164,7 @@ func newClientTransport(conn keyingTransport, clientVersion, serverVersion []byt if config.HostKeyAlgorithms != nil { t.hostKeyAlgorithms = config.HostKeyAlgorithms } else { - t.hostKeyAlgorithms = supportedHostKeyAlgos + t.hostKeyAlgorithms = defaultHostKeyAlgos } go t.readLoop() go t.kexLoop() @@ -184,6 +184,10 @@ func (t *handshakeTransport) getSessionID() []byte { return t.sessionID } +func (t *handshakeTransport) getAlgorithms() NegotiatedAlgorithms { + return *t.algorithms +} + // waitSession waits for the session to be established. This should be // the first thing to call after instantiating handshakeTransport. func (t *handshakeTransport) waitSession() error { @@ -290,7 +294,7 @@ func (t *handshakeTransport) resetWriteThresholds() { if t.config.RekeyThreshold > 0 { t.writeBytesLeft = int64(t.config.RekeyThreshold) } else if t.algorithms != nil { - t.writeBytesLeft = t.algorithms.w.rekeyBytes() + t.writeBytesLeft = t.algorithms.Write.rekeyBytes() } else { t.writeBytesLeft = 1 << 30 } @@ -407,7 +411,7 @@ func (t *handshakeTransport) resetReadThresholds() { if t.config.RekeyThreshold > 0 { t.readBytesLeft = int64(t.config.RekeyThreshold) } else if t.algorithms != nil { - t.readBytesLeft = t.algorithms.r.rekeyBytes() + t.readBytesLeft = t.algorithms.Read.rekeyBytes() } else { t.readBytesLeft = 1 << 30 } @@ -700,9 +704,9 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error { } } - kex, ok := kexAlgoMap[t.algorithms.kex] + kex, ok := kexAlgoMap[t.algorithms.KeyExchange] if !ok { - return fmt.Errorf("ssh: unexpected key exchange algorithm %v", t.algorithms.kex) + return fmt.Errorf("ssh: unexpected key exchange algorithm %v", t.algorithms.KeyExchange) } var result *kexResult @@ -809,12 +813,12 @@ func pickHostKey(hostKeys []Signer, algo string) AlgorithmSigner { } func (t *handshakeTransport) server(kex kexAlgorithm, magics *handshakeMagics) (*kexResult, error) { - hostKey := pickHostKey(t.hostKeys, t.algorithms.hostKey) + hostKey := pickHostKey(t.hostKeys, t.algorithms.HostKey) if hostKey == nil { return nil, errors.New("ssh: internal error: negotiated unsupported signature type") } - r, err := kex.Server(t.conn, t.config.Rand, magics, hostKey, t.algorithms.hostKey) + r, err := kex.Server(t.conn, t.config.Rand, magics, hostKey, t.algorithms.HostKey) return r, err } @@ -829,7 +833,7 @@ func (t *handshakeTransport) client(kex kexAlgorithm, magics *handshakeMagics) ( return nil, err } - if err := verifyHostKeySignature(hostKey, t.algorithms.hostKey, result); err != nil { + if err := verifyHostKeySignature(hostKey, t.algorithms.HostKey, result); err != nil { return nil, err } diff --git a/vendor/golang.org/x/crypto/ssh/kex.go b/vendor/golang.org/x/crypto/ssh/kex.go index 8a05f7990..cf388a92a 100644 --- a/vendor/golang.org/x/crypto/ssh/kex.go +++ b/vendor/golang.org/x/crypto/ssh/kex.go @@ -20,21 +20,18 @@ import ( ) const ( - kexAlgoDH1SHA1 = "diffie-hellman-group1-sha1" - kexAlgoDH14SHA1 = "diffie-hellman-group14-sha1" - kexAlgoDH14SHA256 = "diffie-hellman-group14-sha256" - kexAlgoDH16SHA512 = "diffie-hellman-group16-sha512" - kexAlgoECDH256 = "ecdh-sha2-nistp256" - kexAlgoECDH384 = "ecdh-sha2-nistp384" - kexAlgoECDH521 = "ecdh-sha2-nistp521" - kexAlgoCurve25519SHA256LibSSH = "curve25519-sha256@libssh.org" - kexAlgoCurve25519SHA256 = "curve25519-sha256" - - // For the following kex only the client half contains a production - // ready implementation. The server half only consists of a minimal - // implementation to satisfy the automated tests. - kexAlgoDHGEXSHA1 = "diffie-hellman-group-exchange-sha1" - kexAlgoDHGEXSHA256 = "diffie-hellman-group-exchange-sha256" + // This is the group called diffie-hellman-group1-sha1 in RFC 4253 and + // Oakley Group 2 in RFC 2409. + oakleyGroup2 = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF" + // This is the group called diffie-hellman-group14-sha1 in RFC 4253 and + // Oakley Group 14 in RFC 3526. + oakleyGroup14 = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF" + // This is the group called diffie-hellman-group15-sha512 in RFC 8268 and + // Oakley Group 15 in RFC 3526. + oakleyGroup15 = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF" + // This is the group called diffie-hellman-group16-sha512 in RFC 8268 and + // Oakley Group 16 in RFC 3526. + oakleyGroup16 = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF" ) // kexResult captures the outcome of a key exchange. @@ -402,53 +399,46 @@ func ecHash(curve elliptic.Curve) crypto.Hash { var kexAlgoMap = map[string]kexAlgorithm{} func init() { - // This is the group called diffie-hellman-group1-sha1 in - // RFC 4253 and Oakley Group 2 in RFC 2409. - p, _ := new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF", 16) - kexAlgoMap[kexAlgoDH1SHA1] = &dhGroup{ + p, _ := new(big.Int).SetString(oakleyGroup2, 16) + kexAlgoMap[InsecureKeyExchangeDH1SHA1] = &dhGroup{ g: new(big.Int).SetInt64(2), p: p, pMinus1: new(big.Int).Sub(p, bigOne), hashFunc: crypto.SHA1, } - // This are the groups called diffie-hellman-group14-sha1 and - // diffie-hellman-group14-sha256 in RFC 4253 and RFC 8268, - // and Oakley Group 14 in RFC 3526. - p, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF", 16) + p, _ = new(big.Int).SetString(oakleyGroup14, 16) group14 := &dhGroup{ g: new(big.Int).SetInt64(2), p: p, pMinus1: new(big.Int).Sub(p, bigOne), } - kexAlgoMap[kexAlgoDH14SHA1] = &dhGroup{ + kexAlgoMap[InsecureKeyExchangeDH14SHA1] = &dhGroup{ g: group14.g, p: group14.p, pMinus1: group14.pMinus1, hashFunc: crypto.SHA1, } - kexAlgoMap[kexAlgoDH14SHA256] = &dhGroup{ + kexAlgoMap[KeyExchangeDH14SHA256] = &dhGroup{ g: group14.g, p: group14.p, pMinus1: group14.pMinus1, hashFunc: crypto.SHA256, } - // This is the group called diffie-hellman-group16-sha512 in RFC - // 8268 and Oakley Group 16 in RFC 3526. - p, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF", 16) + p, _ = new(big.Int).SetString(oakleyGroup16, 16) - kexAlgoMap[kexAlgoDH16SHA512] = &dhGroup{ + kexAlgoMap[KeyExchangeDH16SHA512] = &dhGroup{ g: new(big.Int).SetInt64(2), p: p, pMinus1: new(big.Int).Sub(p, bigOne), hashFunc: crypto.SHA512, } - kexAlgoMap[kexAlgoECDH521] = &ecdh{elliptic.P521()} - kexAlgoMap[kexAlgoECDH384] = &ecdh{elliptic.P384()} - kexAlgoMap[kexAlgoECDH256] = &ecdh{elliptic.P256()} - kexAlgoMap[kexAlgoCurve25519SHA256] = &curve25519sha256{} - kexAlgoMap[kexAlgoCurve25519SHA256LibSSH] = &curve25519sha256{} - kexAlgoMap[kexAlgoDHGEXSHA1] = &dhGEXSHA{hashFunc: crypto.SHA1} - kexAlgoMap[kexAlgoDHGEXSHA256] = &dhGEXSHA{hashFunc: crypto.SHA256} + kexAlgoMap[KeyExchangeECDHP521] = &ecdh{elliptic.P521()} + kexAlgoMap[KeyExchangeECDHP384] = &ecdh{elliptic.P384()} + kexAlgoMap[KeyExchangeECDHP256] = &ecdh{elliptic.P256()} + kexAlgoMap[KeyExchangeCurve25519] = &curve25519sha256{} + kexAlgoMap[keyExchangeCurve25519LibSSH] = &curve25519sha256{} + kexAlgoMap[InsecureKeyExchangeDHGEXSHA1] = &dhGEXSHA{hashFunc: crypto.SHA1} + kexAlgoMap[KeyExchangeDHGEXSHA256] = &dhGEXSHA{hashFunc: crypto.SHA256} } // curve25519sha256 implements the curve25519-sha256 (formerly known as @@ -601,9 +591,9 @@ const ( func (gex *dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshakeMagics) (*kexResult, error) { // Send GexRequest kexDHGexRequest := kexDHGexRequestMsg{ - MinBits: dhGroupExchangeMinimumBits, - PreferedBits: dhGroupExchangePreferredBits, - MaxBits: dhGroupExchangeMaximumBits, + MinBits: dhGroupExchangeMinimumBits, + PreferredBits: dhGroupExchangePreferredBits, + MaxBits: dhGroupExchangeMaximumBits, } if err := c.writePacket(Marshal(&kexDHGexRequest)); err != nil { return nil, err @@ -690,9 +680,7 @@ func (gex *dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshak } // Server half implementation of the Diffie Hellman Key Exchange with SHA1 and SHA256. -// -// This is a minimal implementation to satisfy the automated tests. -func (gex dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshakeMagics, priv AlgorithmSigner, algo string) (result *kexResult, err error) { +func (gex *dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshakeMagics, priv AlgorithmSigner, algo string) (result *kexResult, err error) { // Receive GexRequest packet, err := c.readPacket() if err != nil { @@ -702,13 +690,32 @@ func (gex dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshake if err = Unmarshal(packet, &kexDHGexRequest); err != nil { return } + // We check that the request received is valid and that the MaxBits + // requested are at least equal to our supported minimum. This is the same + // check done in OpenSSH: + // https://github.com/openssh/openssh-portable/blob/80a2f64b/kexgexs.c#L94 + // + // Furthermore, we also check that the required MinBits are less than or + // equal to 4096 because we can use up to Oakley Group 16. + if kexDHGexRequest.MaxBits < kexDHGexRequest.MinBits || kexDHGexRequest.PreferredBits < kexDHGexRequest.MinBits || + kexDHGexRequest.MaxBits < kexDHGexRequest.PreferredBits || kexDHGexRequest.MaxBits < dhGroupExchangeMinimumBits || + kexDHGexRequest.MinBits > 4096 { + return nil, fmt.Errorf("ssh: DH GEX request out of range, min: %d, max: %d, preferred: %d", kexDHGexRequest.MinBits, + kexDHGexRequest.MaxBits, kexDHGexRequest.PreferredBits) + } + + var p *big.Int + // We hardcode sending Oakley Group 14 (2048 bits), Oakley Group 15 (3072 + // bits) or Oakley Group 16 (4096 bits), based on the requested max size. + if kexDHGexRequest.MaxBits < 3072 { + p, _ = new(big.Int).SetString(oakleyGroup14, 16) + } else if kexDHGexRequest.MaxBits < 4096 { + p, _ = new(big.Int).SetString(oakleyGroup15, 16) + } else { + p, _ = new(big.Int).SetString(oakleyGroup16, 16) + } - // Send GexGroup - // This is the group called diffie-hellman-group14-sha1 in RFC - // 4253 and Oakley Group 14 in RFC 3526. - p, _ := new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF", 16) g := big.NewInt(2) - msg := &kexDHGexGroupMsg{ P: p, G: g, @@ -746,9 +753,9 @@ func (gex dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshake h := gex.hashFunc.New() magics.write(h) writeString(h, hostKeyBytes) - binary.Write(h, binary.BigEndian, uint32(dhGroupExchangeMinimumBits)) - binary.Write(h, binary.BigEndian, uint32(dhGroupExchangePreferredBits)) - binary.Write(h, binary.BigEndian, uint32(dhGroupExchangeMaximumBits)) + binary.Write(h, binary.BigEndian, kexDHGexRequest.MinBits) + binary.Write(h, binary.BigEndian, kexDHGexRequest.PreferredBits) + binary.Write(h, binary.BigEndian, kexDHGexRequest.MaxBits) writeInt(h, p) writeInt(h, g) writeInt(h, kexDHGexInit.X) diff --git a/vendor/golang.org/x/crypto/ssh/keys.go b/vendor/golang.org/x/crypto/ssh/keys.go index 98e6706d5..566e09d5a 100644 --- a/vendor/golang.org/x/crypto/ssh/keys.go +++ b/vendor/golang.org/x/crypto/ssh/keys.go @@ -36,14 +36,19 @@ import ( // ClientConfig.HostKeyAlgorithms, Signature.Format, or as AlgorithmSigner // arguments. const ( - KeyAlgoRSA = "ssh-rsa" - KeyAlgoDSA = "ssh-dss" - KeyAlgoECDSA256 = "ecdsa-sha2-nistp256" - KeyAlgoSKECDSA256 = "sk-ecdsa-sha2-nistp256@openssh.com" - KeyAlgoECDSA384 = "ecdsa-sha2-nistp384" - KeyAlgoECDSA521 = "ecdsa-sha2-nistp521" - KeyAlgoED25519 = "ssh-ed25519" - KeyAlgoSKED25519 = "sk-ssh-ed25519@openssh.com" + KeyAlgoRSA = "ssh-rsa" + // Deprecated: DSA is only supported at insecure key sizes, and was removed + // from major implementations. + KeyAlgoDSA = InsecureKeyAlgoDSA + // Deprecated: DSA is only supported at insecure key sizes, and was removed + // from major implementations. + InsecureKeyAlgoDSA = "ssh-dss" + KeyAlgoECDSA256 = "ecdsa-sha2-nistp256" + KeyAlgoSKECDSA256 = "sk-ecdsa-sha2-nistp256@openssh.com" + KeyAlgoECDSA384 = "ecdsa-sha2-nistp384" + KeyAlgoECDSA521 = "ecdsa-sha2-nistp521" + KeyAlgoED25519 = "ssh-ed25519" + KeyAlgoSKED25519 = "sk-ssh-ed25519@openssh.com" // KeyAlgoRSASHA256 and KeyAlgoRSASHA512 are only public key algorithms, not // public key formats, so they can't appear as a PublicKey.Type. The @@ -67,7 +72,7 @@ func parsePubKey(in []byte, algo string) (pubKey PublicKey, rest []byte, err err switch algo { case KeyAlgoRSA: return parseRSA(in) - case KeyAlgoDSA: + case InsecureKeyAlgoDSA: return parseDSA(in) case KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521: return parseECDSA(in) @@ -77,7 +82,7 @@ func parsePubKey(in []byte, algo string) (pubKey PublicKey, rest []byte, err err return parseED25519(in) case KeyAlgoSKED25519: return parseSKEd25519(in) - case CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoSKECDSA256v01, CertAlgoED25519v01, CertAlgoSKED25519v01: + case CertAlgoRSAv01, InsecureCertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoSKECDSA256v01, CertAlgoED25519v01, CertAlgoSKED25519v01: cert, err := parseCert(in, certKeyAlgoNames[algo]) if err != nil { return nil, nil, err diff --git a/vendor/golang.org/x/crypto/ssh/mac.go b/vendor/golang.org/x/crypto/ssh/mac.go index 06a1b2750..de2639d57 100644 --- a/vendor/golang.org/x/crypto/ssh/mac.go +++ b/vendor/golang.org/x/crypto/ssh/mac.go @@ -47,22 +47,22 @@ func (t truncatingMAC) Size() int { func (t truncatingMAC) BlockSize() int { return t.hmac.BlockSize() } var macModes = map[string]*macMode{ - "hmac-sha2-512-etm@openssh.com": {64, true, func(key []byte) hash.Hash { + HMACSHA512ETM: {64, true, func(key []byte) hash.Hash { return hmac.New(sha512.New, key) }}, - "hmac-sha2-256-etm@openssh.com": {32, true, func(key []byte) hash.Hash { + HMACSHA256ETM: {32, true, func(key []byte) hash.Hash { return hmac.New(sha256.New, key) }}, - "hmac-sha2-512": {64, false, func(key []byte) hash.Hash { + HMACSHA512: {64, false, func(key []byte) hash.Hash { return hmac.New(sha512.New, key) }}, - "hmac-sha2-256": {32, false, func(key []byte) hash.Hash { + HMACSHA256: {32, false, func(key []byte) hash.Hash { return hmac.New(sha256.New, key) }}, - "hmac-sha1": {20, false, func(key []byte) hash.Hash { + HMACSHA1: {20, false, func(key []byte) hash.Hash { return hmac.New(sha1.New, key) }}, - "hmac-sha1-96": {20, false, func(key []byte) hash.Hash { + InsecureHMACSHA196: {20, false, func(key []byte) hash.Hash { return truncatingMAC{12, hmac.New(sha1.New, key)} }}, } diff --git a/vendor/golang.org/x/crypto/ssh/messages.go b/vendor/golang.org/x/crypto/ssh/messages.go index 118427bc0..251b9d06a 100644 --- a/vendor/golang.org/x/crypto/ssh/messages.go +++ b/vendor/golang.org/x/crypto/ssh/messages.go @@ -122,9 +122,9 @@ type kexDHGexReplyMsg struct { const msgKexDHGexRequest = 34 type kexDHGexRequestMsg struct { - MinBits uint32 `sshtype:"34"` - PreferedBits uint32 - MaxBits uint32 + MinBits uint32 `sshtype:"34"` + PreferredBits uint32 + MaxBits uint32 } // See RFC 4253, section 10. diff --git a/vendor/golang.org/x/crypto/ssh/mlkem.go b/vendor/golang.org/x/crypto/ssh/mlkem.go index 40681dd69..657e1079d 100644 --- a/vendor/golang.org/x/crypto/ssh/mlkem.go +++ b/vendor/golang.org/x/crypto/ssh/mlkem.go @@ -19,19 +19,15 @@ import ( "golang.org/x/crypto/curve25519" ) -const ( - kexAlgoMLKEM768xCurve25519SHA256 = "mlkem768x25519-sha256" -) - func init() { // After Go 1.24rc1 mlkem swapped the order of return values of Encapsulate. // See #70950. if runtime.Version() == "go1.24rc1" { return } - supportedKexAlgos = slices.Insert(supportedKexAlgos, 0, kexAlgoMLKEM768xCurve25519SHA256) - preferredKexAlgos = slices.Insert(preferredKexAlgos, 0, kexAlgoMLKEM768xCurve25519SHA256) - kexAlgoMap[kexAlgoMLKEM768xCurve25519SHA256] = &mlkem768WithCurve25519sha256{} + supportedKexAlgos = slices.Insert(supportedKexAlgos, 0, KeyExchangeMLKEM768X25519) + defaultKexAlgos = slices.Insert(defaultKexAlgos, 0, KeyExchangeMLKEM768X25519) + kexAlgoMap[KeyExchangeMLKEM768X25519] = &mlkem768WithCurve25519sha256{} } // mlkem768WithCurve25519sha256 implements the hybrid ML-KEM768 with diff --git a/vendor/golang.org/x/crypto/ssh/server.go b/vendor/golang.org/x/crypto/ssh/server.go index 1839ddc6a..98679ba5b 100644 --- a/vendor/golang.org/x/crypto/ssh/server.go +++ b/vendor/golang.org/x/crypto/ssh/server.go @@ -243,22 +243,15 @@ func NewServerConn(c net.Conn, config *ServerConfig) (*ServerConn, <-chan NewCha fullConf.MaxAuthTries = 6 } if len(fullConf.PublicKeyAuthAlgorithms) == 0 { - fullConf.PublicKeyAuthAlgorithms = supportedPubKeyAuthAlgos + fullConf.PublicKeyAuthAlgorithms = defaultPubKeyAuthAlgos } else { for _, algo := range fullConf.PublicKeyAuthAlgorithms { - if !contains(supportedPubKeyAuthAlgos, algo) { + if !contains(SupportedAlgorithms().PublicKeyAuths, algo) && !contains(InsecureAlgorithms().PublicKeyAuths, algo) { c.Close() return nil, nil, nil, fmt.Errorf("ssh: unsupported public key authentication algorithm %s", algo) } } } - // Check if the config contains any unsupported key exchanges - for _, kex := range fullConf.KeyExchanges { - if _, ok := serverForbiddenKexAlgos[kex]; ok { - c.Close() - return nil, nil, nil, fmt.Errorf("ssh: unsupported key exchange %s for server", kex) - } - } s := &connection{ sshConn: sshConn{conn: c}, @@ -315,6 +308,7 @@ func (s *connection) serverHandshake(config *ServerConfig) (*Permissions, error) // We just did the key change, so the session ID is established. s.sessionID = s.transport.getSessionID() + s.algorithms = s.transport.getAlgorithms() var packet []byte if packet, err = s.transport.readPacket(); err != nil { diff --git a/vendor/golang.org/x/crypto/ssh/transport.go b/vendor/golang.org/x/crypto/ssh/transport.go index 0424d2d37..663619845 100644 --- a/vendor/golang.org/x/crypto/ssh/transport.go +++ b/vendor/golang.org/x/crypto/ssh/transport.go @@ -16,13 +16,6 @@ import ( // wire. No message decoding is done, to minimize the impact on timing. const debugTransport = false -const ( - gcm128CipherID = "aes128-gcm@openssh.com" - gcm256CipherID = "aes256-gcm@openssh.com" - aes128cbcID = "aes128-cbc" - tripledescbcID = "3des-cbc" -) - // packetConn represents a transport that implements packet based // operations. type packetConn interface { @@ -92,14 +85,14 @@ func (t *transport) setInitialKEXDone() { // prepareKeyChange sets up key material for a keychange. The key changes in // both directions are triggered by reading and writing a msgNewKey packet // respectively. -func (t *transport) prepareKeyChange(algs *algorithms, kexResult *kexResult) error { - ciph, err := newPacketCipher(t.reader.dir, algs.r, kexResult) +func (t *transport) prepareKeyChange(algs *NegotiatedAlgorithms, kexResult *kexResult) error { + ciph, err := newPacketCipher(t.reader.dir, algs.Read, kexResult) if err != nil { return err } t.reader.pendingKeyChange <- ciph - ciph, err = newPacketCipher(t.writer.dir, algs.w, kexResult) + ciph, err = newPacketCipher(t.writer.dir, algs.Write, kexResult) if err != nil { return err } @@ -259,7 +252,7 @@ var ( // setupKeys sets the cipher and MAC keys from kex.K, kex.H and sessionId, as // described in RFC 4253, section 6.4. direction should either be serverKeys // (to setup server->client keys) or clientKeys (for client->server keys). -func newPacketCipher(d direction, algs directionAlgorithms, kex *kexResult) (packetCipher, error) { +func newPacketCipher(d direction, algs DirectionAlgorithms, kex *kexResult) (packetCipher, error) { cipherMode := cipherModes[algs.Cipher] iv := make([]byte, cipherMode.ivSize) diff --git a/vendor/golang.org/x/mod/module/module.go b/vendor/golang.org/x/mod/module/module.go index 2a364b229..16e1aa7ab 100644 --- a/vendor/golang.org/x/mod/module/module.go +++ b/vendor/golang.org/x/mod/module/module.go @@ -96,10 +96,11 @@ package module // Changes to the semantics in this file require approval from rsc. import ( + "cmp" "errors" "fmt" "path" - "sort" + "slices" "strings" "unicode" "unicode/utf8" @@ -657,17 +658,15 @@ func CanonicalVersion(v string) string { // optionally followed by a tie-breaking suffix introduced by a slash character, // like in "v0.0.1/go.mod". func Sort(list []Version) { - sort.Slice(list, func(i, j int) bool { - mi := list[i] - mj := list[j] - if mi.Path != mj.Path { - return mi.Path < mj.Path + slices.SortFunc(list, func(i, j Version) int { + if i.Path != j.Path { + return strings.Compare(i.Path, j.Path) } // To help go.sum formatting, allow version/file. // Compare semver prefix by semver rules, // file by string order. - vi := mi.Version - vj := mj.Version + vi := i.Version + vj := j.Version var fi, fj string if k := strings.Index(vi, "/"); k >= 0 { vi, fi = vi[:k], vi[k:] @@ -676,9 +675,9 @@ func Sort(list []Version) { vj, fj = vj[:k], vj[k:] } if vi != vj { - return semver.Compare(vi, vj) < 0 + return semver.Compare(vi, vj) } - return fi < fj + return cmp.Compare(fi, fj) }) } diff --git a/vendor/golang.org/x/mod/semver/semver.go b/vendor/golang.org/x/mod/semver/semver.go index 9a2dfd33a..628f8fd68 100644 --- a/vendor/golang.org/x/mod/semver/semver.go +++ b/vendor/golang.org/x/mod/semver/semver.go @@ -22,7 +22,10 @@ // as shorthands for vMAJOR.0.0 and vMAJOR.MINOR.0. package semver -import "sort" +import ( + "slices" + "strings" +) // parsed returns the parsed form of a semantic version string. type parsed struct { @@ -154,19 +157,22 @@ func Max(v, w string) string { // ByVersion implements [sort.Interface] for sorting semantic version strings. type ByVersion []string -func (vs ByVersion) Len() int { return len(vs) } -func (vs ByVersion) Swap(i, j int) { vs[i], vs[j] = vs[j], vs[i] } -func (vs ByVersion) Less(i, j int) bool { - cmp := Compare(vs[i], vs[j]) - if cmp != 0 { - return cmp < 0 - } - return vs[i] < vs[j] +func (vs ByVersion) Len() int { return len(vs) } +func (vs ByVersion) Swap(i, j int) { vs[i], vs[j] = vs[j], vs[i] } +func (vs ByVersion) Less(i, j int) bool { return compareVersion(vs[i], vs[j]) < 0 } + +// Sort sorts a list of semantic version strings using [Compare] and falls back +// to use [strings.Compare] if both versions are considered equal. +func Sort(list []string) { + slices.SortFunc(list, compareVersion) } -// Sort sorts a list of semantic version strings using [ByVersion]. -func Sort(list []string) { - sort.Sort(ByVersion(list)) +func compareVersion(a, b string) int { + cmp := Compare(a, b) + if cmp != 0 { + return cmp + } + return strings.Compare(a, b) } func parse(v string) (p parsed, ok bool) { diff --git a/vendor/golang.org/x/sync/errgroup/errgroup.go b/vendor/golang.org/x/sync/errgroup/errgroup.go index cfafed5b5..cb6bb9ad3 100644 --- a/vendor/golang.org/x/sync/errgroup/errgroup.go +++ b/vendor/golang.org/x/sync/errgroup/errgroup.go @@ -76,10 +76,8 @@ func (g *Group) Wait() error { } // Go calls the given function in a new goroutine. -// The first call to Go must happen before a Wait. -// It blocks until the new goroutine can be added without the number of -// active goroutines in the group exceeding the configured limit. // +// The first call to Go must happen before a Wait. // It blocks until the new goroutine can be added without the number of // goroutines in the group exceeding the configured limit. // @@ -185,8 +183,9 @@ type PanicError struct { } func (p PanicError) Error() string { - // A Go Error method conventionally does not include a stack dump, so omit it - // here. (Callers who care can extract it from the Stack field.) + if len(p.Stack) > 0 { + return fmt.Sprintf("recovered from errgroup.Group: %v\n%s", p.Recovered, p.Stack) + } return fmt.Sprintf("recovered from errgroup.Group: %v", p.Recovered) } diff --git a/vendor/modules.txt b/vendor/modules.txt index 37d6ae13c..7941198b0 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -710,7 +710,7 @@ github.com/modern-go/reflect2 # github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 ## explicit github.com/munnerz/goautoneg -# github.com/ncruces/go-sqlite3 v0.26.0 +# github.com/ncruces/go-sqlite3 v0.26.1 ## explicit; go 1.23.0 github.com/ncruces/go-sqlite3 github.com/ncruces/go-sqlite3/driver @@ -1131,7 +1131,7 @@ go.uber.org/multierr # golang.org/x/arch v0.16.0 ## explicit; go 1.23.0 golang.org/x/arch/x86/x86asm -# golang.org/x/crypto v0.38.0 +# golang.org/x/crypto v0.39.0 ## explicit; go 1.23.0 golang.org/x/crypto/acme golang.org/x/crypto/acme/autocert @@ -1161,7 +1161,7 @@ golang.org/x/image/riff golang.org/x/image/vp8 golang.org/x/image/vp8l golang.org/x/image/webp -# golang.org/x/mod v0.24.0 +# golang.org/x/mod v0.25.0 ## explicit; go 1.23.0 golang.org/x/mod/internal/lazyregexp golang.org/x/mod/module @@ -1189,7 +1189,7 @@ golang.org/x/net/trace ## explicit; go 1.23.0 golang.org/x/oauth2 golang.org/x/oauth2/internal -# golang.org/x/sync v0.14.0 +# golang.org/x/sync v0.15.0 ## explicit; go 1.23.0 golang.org/x/sync/errgroup golang.org/x/sync/semaphore @@ -1199,7 +1199,7 @@ golang.org/x/sys/cpu golang.org/x/sys/unix golang.org/x/sys/windows golang.org/x/sys/windows/registry -# golang.org/x/text v0.25.0 +# golang.org/x/text v0.26.0 ## explicit; go 1.23.0 golang.org/x/text/cases golang.org/x/text/encoding