Compare commits

...
26 Commits
Author SHA1 Message Date
Gopher Robot 959f8f3db0 go.mod: update golang.org/x dependencies
Update golang.org/x dependencies to their latest tagged versions.

Change-Id: I1e9480e5897a08cac746309acdc8bbdf0bce8060
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/663256
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Auto-Submit: Gopher Robot <gobot@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-04-06 09:04:20 -07:00
Nicola Murino 769bcd6997 ssh: use the configured rand in kex init
Change-Id: I4f89c395886b9dd07b584d1fcf1a0f2df215b91b
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/644435
Reviewed-by: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Carlos Amedee <carlos@golang.org>
Reviewed-by: Carlos Amedee <carlos@golang.org>
2025-04-03 13:05:29 -07:00
Simon Josefsson d0a798f774 cryptobyte: fix typo 'octects' into 'octets' for asn1.go
This typo ends up into lots of executables that trigger 'codespell'-style linter checks.

Change-Id: I2a7e3a6597272ca7c97ebddc54c5eef4cb5cab88
GitHub-Last-Rev: e42f734f00aa575030b72dd1e328d2acefb02625
GitHub-Pull-Request: golang/crypto#310
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/646375
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
2025-03-17 08:22:34 -07:00
Mateusz Poliwczak acbcbef23f acme: remove unnecessary []byte conversion
Change-Id: Iddbe6bcb7a5487678c48df65903571b4625fc9f9
GitHub-Last-Rev: 2552a8d99c7472f029d7da270fa814398793b564
GitHub-Pull-Request: golang/crypto#243
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/456438
Reviewed-by: Roland Shoemaker <roland@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Sean Liao <sean@liao.dev>
Auto-Submit: Sean Liao <sean@liao.dev>
2025-03-17 08:22:03 -07:00
Roland Shoemaker 376eb14006 x509roots: support constrained roots
Adds support for roots with the distrust-after bit set. The constraint
function construction is a little funky, but I couldn't think of an
obvious better way to do it.

Fixes golang/go#70777
Fixes golang/go#70623

Change-Id: I780f866416b626360eaee9368185768da7bc75ef
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/652996
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Daniel McCarney <daniel@binaryparadox.net>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-03-13 16:44:06 -07:00
Xiaolin Zhao b369b723c8 crypto/internal/poly1305: implement function update in assembly on loong64
The performance improvements on Loongson-3A5000 and Loongson-3A6000 are as follows:

goos: linux
goarch: loong64
pkg: golang.org/x/crypto/internal/poly1305
cpu: Loongson-3A5000 @ 2500.00MHz
                 |  bench.old   |              bench.new              |
                 |    sec/op    |   sec/op     vs base                |
64                  122.8n ± 0%   100.0n ± 0%  -18.57% (p=0.000 n=10)
1K                 1152.0n ± 0%   732.2n ± 0%  -36.44% (p=0.000 n=10)
2M                  2.356m ± 0%   1.443m ± 0%  -38.74% (p=0.000 n=10)
64Unaligned         122.7n ± 0%   101.5n ± 0%  -17.24% (p=0.000 n=10)
1KUnaligned        1152.0n ± 0%   745.4n ± 0%  -35.30% (p=0.000 n=10)
2MUnaligned         2.336m ± 0%   1.473m ± 0%  -36.94% (p=0.000 n=10)
Write64             77.92n ± 0%   54.88n ± 0%  -29.57% (p=0.000 n=10)
Write1K            1106.0n ± 0%   683.3n ± 0%  -38.22% (p=0.000 n=10)
Write2M             2.356m ± 0%   1.444m ± 0%  -38.72% (p=0.000 n=10)
Write64Unaligned    77.87n ± 0%   55.69n ± 0%  -28.49% (p=0.000 n=10)
Write1KUnaligned   1106.0n ± 0%   708.1n ± 0%  -35.97% (p=0.000 n=10)
Write2MUnaligned    2.335m ± 0%   1.471m ± 0%  -37.01% (p=0.000 n=10)
geomean             6.373µ        4.272µ       -32.96%

                 |  bench.old   |               bench.new               |
                 |     B/s      |      B/s       vs base                |
64                 497.1Mi ± 0%    610.3Mi ± 0%  +22.78% (p=0.000 n=10)
1K                 847.6Mi ± 0%   1333.7Mi ± 0%  +57.35% (p=0.000 n=10)
2M                 849.0Mi ± 0%   1385.9Mi ± 0%  +63.24% (p=0.000 n=10)
64Unaligned        497.4Mi ± 0%    600.9Mi ± 0%  +20.81% (p=0.000 n=10)
1KUnaligned        847.6Mi ± 0%   1310.1Mi ± 0%  +54.57% (p=0.000 n=10)
2MUnaligned        856.3Mi ± 0%   1357.9Mi ± 0%  +58.58% (p=0.000 n=10)
Write64            783.3Mi ± 0%   1112.2Mi ± 0%  +41.99% (p=0.000 n=10)
Write1K            882.8Mi ± 0%   1429.1Mi ± 0%  +61.88% (p=0.000 n=10)
Write2M            849.0Mi ± 0%   1385.4Mi ± 0%  +63.18% (p=0.000 n=10)
Write64Unaligned   783.8Mi ± 0%   1096.1Mi ± 0%  +39.85% (p=0.000 n=10)
Write1KUnaligned   882.8Mi ± 0%   1379.0Mi ± 0%  +56.20% (p=0.000 n=10)
Write2MUnaligned   856.5Mi ± 0%   1359.9Mi ± 0%  +58.76% (p=0.000 n=10)
geomean            772.2Mi         1.125Gi       +49.18%

goos: linux
goarch: loong64
pkg: golang.org/x/crypto/internal/poly1305
cpu: Loongson-3A6000-HV @ 2500.00MHz
                 |  bench.old  |              bench.new              |
                 |   sec/op    |   sec/op     vs base                |
64                 92.06n ± 0%   71.55n ± 0%  -22.28% (p=0.000 n=10)
1K                 998.4n ± 0%   607.7n ± 0%  -39.13% (p=0.000 n=10)
2M                 1.976m ± 0%   1.165m ± 0%  -41.07% (p=0.000 n=10)
64Unaligned        92.05n ± 0%   71.55n ± 0%  -22.27% (p=0.000 n=10)
1KUnaligned        998.3n ± 0%   607.6n ± 0%  -39.13% (p=0.000 n=10)
2MUnaligned        1.975m ± 0%   1.222m ± 0%  -38.11% (p=0.000 n=10)
Write64            65.24n ± 0%   45.23n ± 0%  -30.67% (p=0.000 n=10)
Write1K            970.8n ± 0%   577.6n ± 0%  -40.51% (p=0.000 n=10)
Write2M            1.965m ± 0%   1.163m ± 0%  -40.81% (p=0.000 n=10)
Write64Unaligned   65.24n ± 0%   45.24n ± 0%  -30.66% (p=0.000 n=10)
Write1KUnaligned   970.8n ± 0%   577.6n ± 0%  -40.50% (p=0.000 n=10)
Write2MUnaligned   1.965m ± 0%   1.222m ± 0%  -37.81% (p=0.000 n=10)
geomean            5.317µ        3.426µ       -35.58%

                 |   bench.old   |               bench.new               |
                 |      B/s      |      B/s       vs base                |
64                  663.0Mi ± 0%    853.1Mi ± 0%  +28.67% (p=0.000 n=10)
1K                  978.1Mi ± 0%   1606.9Mi ± 0%  +64.28% (p=0.000 n=10)
2M                 1012.0Mi ± 0%   1717.4Mi ± 0%  +69.70% (p=0.000 n=10)
64Unaligned         663.1Mi ± 0%    853.1Mi ± 0%  +28.65% (p=0.000 n=10)
1KUnaligned         978.2Mi ± 0%   1607.1Mi ± 0%  +64.29% (p=0.000 n=10)
2MUnaligned        1012.6Mi ± 0%   1636.2Mi ± 0%  +61.58% (p=0.000 n=10)
Write64             935.5Mi ± 0%   1349.3Mi ± 0%  +44.23% (p=0.000 n=10)
Write1K            1005.9Mi ± 0%   1690.9Mi ± 0%  +68.09% (p=0.000 n=10)
Write2M            1017.7Mi ± 0%   1719.5Mi ± 0%  +68.95% (p=0.000 n=10)
Write64Unaligned    935.6Mi ± 0%   1349.3Mi ± 0%  +44.22% (p=0.000 n=10)
Write1KUnaligned   1006.0Mi ± 0%   1690.9Mi ± 0%  +68.08% (p=0.000 n=10)
Write2MUnaligned   1017.7Mi ± 0%   1636.4Mi ± 0%  +60.80% (p=0.000 n=10)
geomean             925.6Mi         1.403Gi       +55.22%

Change-Id: If05a8bfc868b3e6f903ff169eed7a894af741f9b
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/638455
Reviewed-by: David Chase <drchase@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Junyang Shao <shaojunyang@google.com>
Reviewed-by: abner chenc <chenguoqi@loongson.cn>
2025-03-11 17:59:26 -07:00
Carlos A Becker 6b853fbea3 ssh/knownhosts: check more than one key
I believe this fixes https://github.com/golang/go/issues/36126 .

The problem was that it was keeping only the first known key of each
type found.
If you have a server advertising multiple keys of the same type,
you might get a missmatch key error.

Per sshd(8) man page, it should allow reapeatable hosts with
different host keys, although it don't specify anything about
hosts being from different types:

"It is permissible (but not recommended) to have several lines or
different host keys for the same names.  This will inevitably happen when
short forms of host names from different domains are put in the file.  It
is possible that the files contain conflicting information;
authentication is accepted if valid information can be found from either
file."

So, this changes knownhosts behavior to accept any of the keys for a
given host, regardless of type.

Fixes #36126

Change-Id: I3450ff954259a403f2471082d013a5f79def0e16
GitHub-Last-Rev: 361bd2bcd20348956aaf114ef159a5350397eaf4
GitHub-Pull-Request: golang/crypto#254
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/478535
Reviewed-by: Junyang Shao <shaojunyang@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Nicola Murino <nicola.murino@gmail.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
Auto-Submit: Nicola Murino <nicola.murino@gmail.com>
2025-03-06 10:51:46 -08:00
Gopher Robot 49bf5b80c8 go.mod: update golang.org/x dependencies
Update golang.org/x dependencies to their latest tagged versions.

Change-Id: Ieae7a2d210a65d5cd2cb7e2670d283176922c767
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/655018
Auto-Submit: Gopher Robot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: David Chase <drchase@google.com>
2025-03-05 09:04:21 -08:00
Ilia Mirkin 24852b6b3f ssh: add decode support for banners
These banners can be printed when enabling debugHandshake, add decode
support so that they're not printed as unknown messages.

Change-Id: Ic8d56079d8225c35aac843accdbc80a642dd6249
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/650635
Reviewed-by: Junyang Shao <shaojunyang@google.com>
Reviewed-by: Nicola Murino <nicola.murino@gmail.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Nicola Murino <nicola.murino@gmail.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
2025-03-03 11:16:37 -08:00
cuishuang bbc689cf5c ssh: use a more straightforward return value
Change-Id: Ie5ee95efe4924f75719087c6fe8d4867607934bf
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/653198
Reviewed-by: Ian Lance Taylor <iant@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
Reviewed-by: Nicola Murino <nicola.murino@gmail.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
2025-02-28 12:03:19 -08:00
Nicola Murino 7292932d45 ssh: limit the size of the internal packet queue while waiting for KEX
In the SSH protocol, clients and servers execute the key exchange to
generate one-time session keys used for encryption and authentication.
The key exchange is performed initially after the connection is
established and then periodically after a configurable amount of data.
While a key exchange is in progress, we add the received packets to an
internal queue until we receive SSH_MSG_KEXINIT from the other side.
This can result in high memory usage if the other party is slow to
respond to the SSH_MSG_KEXINIT packet, or memory exhaustion if a
malicious client never responds to an SSH_MSG_KEXINIT packet during a
large file transfer.
We now limit the internal queue to 64 packets: this means 2MB with the
typical 32KB packet size.
When the internal queue is full we block further writes until the
pending key exchange is completed or there is a read or write error.

Thanks to Yuichi Watanabe for reporting this issue.

Change-Id: I1ce2214cc16e08b838d4bc346c74c72addafaeec
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/652135
Reviewed-by: Neal Patel <nealpatel@google.com>
Auto-Submit: Gopher Robot <gobot@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-02-24 09:39:25 -08:00
Roland Shoemaker f66f74b0a4 acme/autocert: check host policy before probing the cache
Avoid unnessecary cache probes for names that don't match the host
policy.

Fixes golang/go#71199

Change-Id: I11e8465b0416e960a549b0c0d74a622026c39931
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/651296
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Gopher Robot <gobot@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
2025-02-21 16:31:38 -08:00
Dmitri Shuralyov b0784b7bfb x509roots/fallback: drop obsolete build constraint
Back when Go 1.20 and 1.19 were supported, the go1.20 build constraint
was there to establish 1.20 as the minimum for the package, because it
requires an API that was added only in Go 1.20 and there was no way to
make it work with 1.19's APIs.

By now only Go 1.24 and 1.23 are supported, and the minimum is set via
the go directive in go.mod.

For golang/go#57792.

Change-Id: Ie4d37d34993374cdd380667930ee667af97eeccb
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/649716
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Auto-Submit: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-02-21 09:26:01 -08:00
Roland Shoemaker 911360c8a4 all: bump golang.org/x/crypto dependencies of asm generators
Change-Id: Ieb2f0d45f82647978f0bd1eb47bb347f0bfb7d13
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/649499
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-02-14 15:32:41 -08:00
Gopher Robot 89ff08d67c all: upgrade go directive to at least 1.23.0 [generated]
By now Go 1.24.0 has been released, and Go 1.22 is no longer supported
per the Go Release Policy (https://go.dev/doc/devel/release#policy).

For golang/go#69095.

[git-generate]
(cd . && go get go@1.23.0 && go mod tidy && go fix ./... && go mod edit -toolchain=none)
(cd x509roots/fallback && go get go@1.23.0 && go mod tidy && go fix ./... && go mod edit -toolchain=none)

Change-Id: I879bced994b310927c41f820ec272a518aa0c8a5
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/649715
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Auto-Submit: Gopher Robot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
2025-02-14 12:15:19 -08:00
Sean Liao e47973b1c1 all: update certs for go1.24
Fixes golang/go#71612

Change-Id: I5cb0596b33cb18016eb1883d1518319588ae1454
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/647975
Reviewed-by: Roland Shoemaker <roland@golang.org>
Reviewed-by: Nicola Murino <nicola.murino@gmail.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Nicola Murino <nicola.murino@gmail.com>
2025-02-10 08:33:42 -08:00
Gopher Robot 9290511cd2 go.mod: update golang.org/x dependencies
Update golang.org/x dependencies to their latest tagged versions.

Change-Id: Ib9440df43bc2fde0268cbe327c1df839e793f675
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/646220
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: David Chase <drchase@google.com>
Auto-Submit: Gopher Robot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
2025-02-04 11:03:03 -08:00
Gopher Robot fa5273e461 x509roots/fallback: update bundle
This is an automated CL which updates the NSS root bundle.

Change-Id: I3a4388574221a77486b184e73f4b776ff0afc09f
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/646215
Auto-Submit: Gopher Robot <gobot@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
2025-02-03 08:51:27 -08:00
Brad Fitzpatrick a8ea4be81f ssh: add ServerConfig.PreAuthConnCallback, ServerPreAuthConn (banner) interface
Fixes golang/go#68688

Change-Id: Id5f72b32c61c9383a26ec182339486a432c7cdf5
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/613856
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Nicola Murino <nicola.murino@gmail.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Nicola Murino <nicola.murino@gmail.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
2025-01-18 11:27:23 -08:00
Evgeny Shatokhin 71d3a4cfdb acme: support challenges that require the ACME client to send a non-empty JSON body in a response to the challenge.
A new extension to the ACME protocol is proposed to support device attestation: https://datatracker.ietf.org/doc/draft-acme-device-attest/
Based on the recent IETF meetings, the proposal is likely to be accepted.
To support the new extension, the ACME client will need to send a non-empty JSON body in the response to a "device-attest-01" challenge.
Fixes golang/go#68674

Change-Id: I29b420ec837f682e3d59071a4a82af56dc319134
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/608975
Reviewed-by: Roland Shoemaker <roland@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Roland Shoemaker <roland@golang.org>
2025-01-16 08:17:40 -08:00
Gopher Robot 8929309228 go.mod: update golang.org/x dependencies
Update golang.org/x dependencies to their latest tagged versions.

Change-Id: I86bc4657bf10e469231536cff39cbdb86c1135c7
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/640455
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Auto-Submit: Gopher Robot <gobot@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: David Chase <drchase@google.com>
2025-01-06 06:44:30 -08:00
cuishuang 4a75ba54c2 all: make function and struct comments match the names
Change-Id: Iba9c1fc2895adca0d3455f8068b040d0ca006408
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/639575
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Auto-Submit: Ian Lance Taylor <iant@google.com>
2025-01-02 08:15:46 -08:00
Roland Shoemaker b4f1988a35 ssh: make the public key cache a 1-entry FIFO cache
Users of the the ssh package seem to extremely commonly misuse the
PublicKeyCallback API, assuming that the key passed in the last call
before a connection is established is the key used for authentication.
Some users then make authorization decisions based on this key. This
property is not documented, and may not be correct, due to the caching
behavior of the package, resulting in users making incorrect
authorization decisions about the connection.

This change makes the cache a one entry FIFO cache, making the assumed
property, that the last call to PublicKeyCallback represents the key
actually used for authentication, actually hold.

Thanks to Damien Tournoud, Patrick Dawkins, Vince Parker, and
Jules Duvivier from the Platform.sh / Upsun engineering team
for reporting this issue.

Fixes golang/go#70779
Fixes CVE-2024-45337

Change-Id: Ife7c7b4045d8b6bcd7e3a417bdfae370c709797f
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/635315
Reviewed-by: Roland Shoemaker <roland@golang.org>
Auto-Submit: Gopher Robot <gobot@golang.org>
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Nicola Murino <nicola.murino@gmail.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2024-12-11 09:50:49 -08:00
Roland Shoemaker 7042ebcbe0 openpgp/clearsign: just use rand.Reader in tests
Instead of a convoluted fake rand, it is _basically_ just as fast, and
fixes errors that pop up due to bad entropy.

Fixes golang/go#70682

Change-Id: Ib0f605398d1092b516b03135f602c644be2a060f
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/633655
Reviewed-by: Tatiana Bradley <tatianabradley@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Roland Shoemaker <roland@golang.org>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
2024-12-04 19:36:17 +00:00
Gopher Robot 3e90321ac7 go.mod: update golang.org/x dependencies
Update golang.org/x dependencies to their latest tagged versions.

Change-Id: I580d412fc4a135696d4054f8007593cfa4f64224
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/633480
Reviewed-by: David Chase <drchase@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Auto-Submit: Gopher Robot <gobot@golang.org>
2024-12-04 16:35:48 +00:00
Gopher Robot 8c4e668694 x509roots/fallback: update bundle
This is an automated CL which updates the NSS root bundle.

Change-Id: Ic5267bf9d66b676e1cfc5fc2ae153afb8f33b29c
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/631635
Auto-Submit: Gopher Robot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2024-11-27 18:44:53 +00:00
46 changed files with 1887 additions and 828 deletions
+5 -1
View File
@@ -514,7 +514,11 @@ func (c *Client) Accept(ctx context.Context, chal *Challenge) (*Challenge, error
return nil, err
}
res, err := c.post(ctx, nil, chal.URI, json.RawMessage("{}"), wantStatus(
payload := json.RawMessage("{}")
if len(chal.Payload) != 0 {
payload = chal.Payload
}
res, err := c.post(ctx, nil, chal.URI, payload, wantStatus(
http.StatusOK, // according to the spec
http.StatusAccepted, // Let's Encrypt: see https://goo.gl/WsJ7VT (acme-divergences.md)
))
+1 -1
View File
@@ -757,7 +757,7 @@ func TestTLSALPN01ChallengeCert(t *testing.T) {
}
func TestTLSChallengeCertOpt(t *testing.T) {
key, err := rsa.GenerateKey(rand.Reader, 512)
key, err := rsa.GenerateKey(rand.Reader, 1024)
if err != nil {
t.Fatal(err)
}
+4 -3
View File
@@ -292,6 +292,10 @@ func (m *Manager) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate,
}
// regular domain
if err := m.hostPolicy()(ctx, name); err != nil {
return nil, err
}
ck := certKey{
domain: strings.TrimSuffix(name, "."), // golang.org/issue/18114
isRSA: !supportsECDSA(hello),
@@ -305,9 +309,6 @@ func (m *Manager) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate,
}
// first-time
if err := m.hostPolicy()(ctx, name); err != nil {
return nil, err
}
cert, err = m.createCert(ctx, ck)
if err != nil {
return nil, err
+2 -2
View File
@@ -619,7 +619,7 @@ func TestCache(t *testing.T) {
PrivateKey: ecdsaKey,
}
rsaKey, err := rsa.GenerateKey(rand.Reader, 512)
rsaKey, err := rsa.GenerateKey(rand.Reader, 1024)
if err != nil {
t.Fatal(err)
}
@@ -694,7 +694,7 @@ func TestValidCert(t *testing.T) {
if err != nil {
t.Fatal(err)
}
key3, err := rsa.GenerateKey(rand.Reader, 512)
key3, err := rsa.GenerateKey(rand.Reader, 1024)
if err != nil {
t.Fatal(err)
}
+1 -1
View File
@@ -92,7 +92,7 @@ func jwsEncodeJSON(claimset interface{}, key crypto.Signer, kid KeyID, nonce, ur
if err != nil {
return nil, err
}
phead := base64.RawURLEncoding.EncodeToString([]byte(phJSON))
phead := base64.RawURLEncoding.EncodeToString(phJSON)
var payload string
if val, ok := claimset.(string); ok {
payload = val
+12 -1
View File
@@ -7,6 +7,7 @@ package acme
import (
"crypto"
"crypto/x509"
"encoding/json"
"errors"
"fmt"
"net/http"
@@ -288,7 +289,7 @@ type Directory struct {
// KeyChangeURL allows to perform account key rollover flow.
KeyChangeURL string
// Term is a URI identifying the current terms of service.
// Terms is a URI identifying the current terms of service.
Terms string
// Website is an HTTP or HTTPS URL locating a website
@@ -527,6 +528,16 @@ type Challenge struct {
// when this challenge was used.
// The type of a non-nil value is *Error.
Error error
// Payload is the JSON-formatted payload that the client sends
// to the server to indicate it is ready to respond to the challenge.
// When unset, it defaults to an empty JSON object: {}.
// For most challenges, the client must not set Payload,
// see https://tools.ietf.org/html/rfc8555#section-7.5.1.
// Payload is used only for newer challenges (such as "device-attest-01")
// where the client must send additional data for the server to validate
// the challenge.
Payload json.RawMessage
}
// wireChallenge is ACME JSON challenge representation.
+2 -2
View File
@@ -4,12 +4,12 @@ go 1.23
require (
github.com/mmcloughlin/avo v0.6.0
golang.org/x/crypto v0.26.0
golang.org/x/crypto v0.33.0
)
require (
golang.org/x/mod v0.20.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.24.0 // indirect
golang.org/x/sys v0.30.0 // indirect
golang.org/x/tools v0.24.0 // indirect
)
+4 -4
View File
@@ -1,12 +1,12 @@
github.com/mmcloughlin/avo v0.6.0 h1:QH6FU8SKoTLaVs80GA8TJuLNkUYl4VokHKlPhVDg4YY=
github.com/mmcloughlin/avo v0.6.0/go.mod h1:8CoAGaCSYXtCPR+8y18Y9aB/kxb8JSS6FRI7mSkvD+8=
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
+2 -2
View File
@@ -4,13 +4,13 @@ go 1.23
require (
github.com/mmcloughlin/avo v0.6.0
golang.org/x/crypto v0.26.0
golang.org/x/crypto v0.33.0
)
require (
golang.org/x/mod v0.20.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.24.0 // indirect
golang.org/x/sys v0.30.0 // indirect
golang.org/x/tools v0.24.0 // indirect
)
+4 -4
View File
@@ -1,12 +1,12 @@
github.com/mmcloughlin/avo v0.6.0 h1:QH6FU8SKoTLaVs80GA8TJuLNkUYl4VokHKlPhVDg4YY=
github.com/mmcloughlin/avo v0.6.0/go.mod h1:8CoAGaCSYXtCPR+8y18Y9aB/kxb8JSS6FRI7mSkvD+8=
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
+2 -2
View File
@@ -4,12 +4,12 @@ go 1.23
require (
github.com/mmcloughlin/avo v0.6.0
golang.org/x/crypto v0.26.0
golang.org/x/crypto v0.33.0
)
require (
golang.org/x/mod v0.20.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.24.0 // indirect
golang.org/x/sys v0.30.0 // indirect
golang.org/x/tools v0.24.0 // indirect
)
+4 -4
View File
@@ -1,12 +1,12 @@
github.com/mmcloughlin/avo v0.6.0 h1:QH6FU8SKoTLaVs80GA8TJuLNkUYl4VokHKlPhVDg4YY=
github.com/mmcloughlin/avo v0.6.0/go.mod h1:8CoAGaCSYXtCPR+8y18Y9aB/kxb8JSS6FRI7mSkvD+8=
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
+2 -2
View File
@@ -4,12 +4,12 @@ go 1.23
require (
github.com/mmcloughlin/avo v0.6.0
golang.org/x/crypto v0.26.0
golang.org/x/crypto v0.33.0
)
require (
golang.org/x/mod v0.20.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.24.0 // indirect
golang.org/x/sys v0.30.0 // indirect
golang.org/x/tools v0.24.0 // indirect
)
+4 -4
View File
@@ -1,12 +1,12 @@
github.com/mmcloughlin/avo v0.6.0 h1:QH6FU8SKoTLaVs80GA8TJuLNkUYl4VokHKlPhVDg4YY=
github.com/mmcloughlin/avo v0.6.0/go.mod h1:8CoAGaCSYXtCPR+8y18Y9aB/kxb8JSS6FRI7mSkvD+8=
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
+2 -2
View File
@@ -4,12 +4,12 @@ go 1.23
require (
github.com/mmcloughlin/avo v0.6.0
golang.org/x/crypto v0.26.0
golang.org/x/crypto v0.33.0
)
require (
golang.org/x/mod v0.20.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.24.0 // indirect
golang.org/x/sys v0.30.0 // indirect
golang.org/x/tools v0.24.0 // indirect
)
+4 -4
View File
@@ -1,12 +1,12 @@
github.com/mmcloughlin/avo v0.6.0 h1:QH6FU8SKoTLaVs80GA8TJuLNkUYl4VokHKlPhVDg4YY=
github.com/mmcloughlin/avo v0.6.0/go.mod h1:8CoAGaCSYXtCPR+8y18Y9aB/kxb8JSS6FRI7mSkvD+8=
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
+1 -1
View File
@@ -234,7 +234,7 @@ func (b *Builder) AddASN1(tag asn1.Tag, f BuilderContinuation) {
// Identifiers with the low five bits set indicate high-tag-number format
// (two or more octets), which we don't support.
if tag&0x1f == 0x1f {
b.err = fmt.Errorf("cryptobyte: high-tag number identifier octects not supported: 0x%x", tag)
b.err = fmt.Errorf("cryptobyte: high-tag number identifier octets not supported: 0x%x", tag)
return
}
b.AddUint8(uint8(tag))
+4 -4
View File
@@ -1,11 +1,11 @@
module golang.org/x/crypto
go 1.20
go 1.23.0
require (
golang.org/x/net v0.21.0 // tagx:ignore
golang.org/x/sys v0.27.0
golang.org/x/term v0.26.0
golang.org/x/sys v0.32.0
golang.org/x/term v0.31.0
)
require golang.org/x/text v0.20.0 // indirect
require golang.org/x/text v0.24.0 // indirect
+6 -6
View File
@@ -1,8 +1,8 @@
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU=
golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E=
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o=
golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw=
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
+2 -2
View File
@@ -4,12 +4,12 @@ go 1.23
require (
github.com/mmcloughlin/avo v0.6.0
golang.org/x/crypto v0.26.0
golang.org/x/crypto v0.33.0
)
require (
golang.org/x/mod v0.20.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.24.0 // indirect
golang.org/x/sys v0.30.0 // indirect
golang.org/x/tools v0.24.0 // indirect
)
+4 -4
View File
@@ -1,12 +1,12 @@
github.com/mmcloughlin/avo v0.6.0 h1:QH6FU8SKoTLaVs80GA8TJuLNkUYl4VokHKlPhVDg4YY=
github.com/mmcloughlin/avo v0.6.0/go.mod h1:8CoAGaCSYXtCPR+8y18Y9aB/kxb8JSS6FRI7mSkvD+8=
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
+1 -1
View File
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build (!amd64 && !ppc64le && !ppc64 && !s390x) || !gc || purego
//go:build (!amd64 && !loong64 && !ppc64le && !ppc64 && !s390x) || !gc || purego
package poly1305
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build gc && !purego
//go:build gc && !purego && (amd64 || loong64 || ppc64 || ppc64le)
package poly1305
+123
View File
@@ -0,0 +1,123 @@
// Copyright 2025 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build gc && !purego
// func update(state *macState, msg []byte)
TEXT ·update(SB), $0-32
MOVV state+0(FP), R4
MOVV msg_base+8(FP), R5
MOVV msg_len+16(FP), R6
MOVV $0x10, R7
MOVV (R4), R8 // h0
MOVV 8(R4), R9 // h1
MOVV 16(R4), R10 // h2
MOVV 24(R4), R11 // r0
MOVV 32(R4), R12 // r1
BLT R6, R7, bytes_between_0_and_15
loop:
MOVV (R5), R14 // msg[0:8]
MOVV 8(R5), R16 // msg[8:16]
ADDV R14, R8, R8 // h0 (x1 + y1 = z1', if z1' < x1 then z1' overflow)
ADDV R16, R9, R27
SGTU R14, R8, R24 // h0.carry
SGTU R9, R27, R28
ADDV R27, R24, R9 // h1
SGTU R27, R9, R24
OR R24, R28, R24 // h1.carry
ADDV $0x01, R24, R24
ADDV R10, R24, R10 // h2
ADDV $16, R5, R5 // msg = msg[16:]
multiply:
MULV R8, R11, R14 // h0r0.lo
MULHVU R8, R11, R15 // h0r0.hi
MULV R9, R11, R13 // h1r0.lo
MULHVU R9, R11, R16 // h1r0.hi
ADDV R13, R15, R15
SGTU R13, R15, R24
ADDV R24, R16, R16
MULV R10, R11, R25
ADDV R16, R25, R25
MULV R8, R12, R13 // h0r1.lo
MULHVU R8, R12, R16 // h0r1.hi
ADDV R13, R15, R15
SGTU R13, R15, R24
ADDV R24, R16, R16
MOVV R16, R8
MULV R10, R12, R26 // h2r1
MULV R9, R12, R13 // h1r1.lo
MULHVU R9, R12, R16 // h1r1.hi
ADDV R13, R25, R25
ADDV R16, R26, R27
SGTU R13, R25, R24
ADDV R27, R24, R26
ADDV R8, R25, R25
SGTU R8, R25, R24
ADDV R24, R26, R26
AND $3, R25, R10
AND $-4, R25, R17
ADDV R17, R14, R8
ADDV R26, R15, R27
SGTU R17, R8, R24
SGTU R26, R27, R28
ADDV R27, R24, R9
SGTU R27, R9, R24
OR R24, R28, R24
ADDV R24, R10, R10
SLLV $62, R26, R27
SRLV $2, R25, R28
SRLV $2, R26, R26
OR R27, R28, R25
ADDV R25, R8, R8
ADDV R26, R9, R27
SGTU R25, R8, R24
SGTU R26, R27, R28
ADDV R27, R24, R9
SGTU R27, R9, R24
OR R24, R28, R24
ADDV R24, R10, R10
SUBV $16, R6, R6
BGE R6, R7, loop
bytes_between_0_and_15:
BEQ R6, R0, done
MOVV $1, R14
XOR R15, R15
ADDV R6, R5, R5
flush_buffer:
MOVBU -1(R5), R25
SRLV $56, R14, R24
SLLV $8, R15, R28
SLLV $8, R14, R14
OR R24, R28, R15
XOR R25, R14, R14
SUBV $1, R6, R6
SUBV $1, R5, R5
BNE R6, R0, flush_buffer
ADDV R14, R8, R8
SGTU R14, R8, R24
ADDV R15, R9, R27
SGTU R15, R27, R28
ADDV R27, R24, R9
SGTU R27, R9, R24
OR R24, R28, R24
ADDV R10, R24, R10
MOVV $16, R6
JMP multiply
done:
MOVV R8, (R4)
MOVV R9, 8(R4)
MOVV R10, 16(R4)
RET
-47
View File
@@ -1,47 +0,0 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build gc && !purego && (ppc64 || ppc64le)
package poly1305
//go:noescape
func update(state *macState, msg []byte)
// mac is a wrapper for macGeneric that redirects calls that would have gone to
// updateGeneric to update.
//
// Its Write and Sum methods are otherwise identical to the macGeneric ones, but
// using function pointers would carry a major performance cost.
type mac struct{ macGeneric }
func (h *mac) Write(p []byte) (int, error) {
nn := len(p)
if h.offset > 0 {
n := copy(h.buffer[h.offset:], p)
if h.offset+n < TagSize {
h.offset += n
return nn, nil
}
p = p[n:]
h.offset = 0
update(&h.macState, h.buffer[:])
}
if n := len(p) - (len(p) % TagSize); n > 0 {
update(&h.macState, p[:n])
p = p[n:]
}
if len(p) > 0 {
h.offset += copy(h.buffer[h.offset:], p)
}
return nn, nil
}
func (h *mac) Sum(out *[16]byte) {
state := h.macState
if h.offset > 0 {
update(&state, h.buffer[:h.offset])
}
finalize(out, &state.h, &state.s)
}
+1 -13
View File
@@ -123,24 +123,12 @@ func TestSigning(t *testing.T) {
}
}
// We use this to make test keys, so that they aren't all the same.
type quickRand byte
func (qr *quickRand) Read(p []byte) (int, error) {
for i := range p {
p[i] = byte(*qr)
}
*qr++
return len(p), nil
}
func TestMultiSign(t *testing.T) {
if testing.Short() {
t.Skip("skipping long test in -short mode")
}
zero := quickRand(0)
config := packet.Config{Rand: &zero}
var config packet.Config
for nKeys := 0; nKeys < 4; nKeys++ {
nextTest:
+1 -1
View File
@@ -26,7 +26,7 @@ type pbeCipher interface {
create(key []byte) (cipher.Block, error)
// deriveKey returns a key derived from the given password and salt.
deriveKey(salt, password []byte, iterations int) []byte
// deriveKey returns an IV derived from the given password and salt.
// deriveIV returns an IV derived from the given password and salt.
deriveIV(salt, password []byte, iterations int) []byte
}
+1 -1
View File
@@ -4,7 +4,7 @@ go 1.23
require (
github.com/mmcloughlin/avo v0.6.0
golang.org/x/crypto v0.26.0
golang.org/x/crypto v0.33.0
)
require (
+2 -2
View File
@@ -1,7 +1,7 @@
github.com/mmcloughlin/avo v0.6.0 h1:QH6FU8SKoTLaVs80GA8TJuLNkUYl4VokHKlPhVDg4YY=
github.com/mmcloughlin/avo v0.6.0/go.mod h1:8CoAGaCSYXtCPR+8y18Y9aB/kxb8JSS6FRI7mSkvD+8=
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
+2 -2
View File
@@ -4,12 +4,12 @@ go 1.22
require (
github.com/mmcloughlin/avo v0.6.0
golang.org/x/crypto v0.25.0
golang.org/x/crypto v0.33.0
)
require (
golang.org/x/mod v0.19.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.22.0 // indirect
golang.org/x/sys v0.30.0 // indirect
golang.org/x/tools v0.23.0 // indirect
)
+4 -4
View File
@@ -1,12 +1,12 @@
github.com/mmcloughlin/avo v0.6.0 h1:QH6FU8SKoTLaVs80GA8TJuLNkUYl4VokHKlPhVDg4YY=
github.com/mmcloughlin/avo v0.6.0/go.mod h1:8CoAGaCSYXtCPR+8y18Y9aB/kxb8JSS6FRI7mSkvD+8=
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8=
golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg=
golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI=
+6 -8
View File
@@ -15,14 +15,12 @@ import (
"reflect"
"testing"
"time"
"golang.org/x/crypto/ssh/testdata"
)
// Cert generated by ssh-keygen 6.0p1 Debian-4.
// % ssh-keygen -s ca-key -I test user-key
const exampleSSHCert = `ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgb1srW/W3ZDjYAO45xLYAwzHBDLsJ4Ux6ICFIkTjb1LEAAAADAQABAAAAYQCkoR51poH0wE8w72cqSB8Sszx+vAhzcMdCO0wqHTj7UNENHWEXGrU0E0UQekD7U+yhkhtoyjbPOVIP7hNa6aRk/ezdh/iUnCIt4Jt1v3Z1h1P+hA4QuYFMHNB+rmjPwAcAAAAAAAAAAAAAAAEAAAAEdGVzdAAAAAAAAAAAAAAAAP//////////AAAAAAAAAIIAAAAVcGVybWl0LVgxMS1mb3J3YXJkaW5nAAAAAAAAABdwZXJtaXQtYWdlbnQtZm9yd2FyZGluZwAAAAAAAAAWcGVybWl0LXBvcnQtZm9yd2FyZGluZwAAAAAAAAAKcGVybWl0LXB0eQAAAAAAAAAOcGVybWl0LXVzZXItcmMAAAAAAAAAAAAAAHcAAAAHc3NoLXJzYQAAAAMBAAEAAABhANFS2kaktpSGc+CcmEKPyw9mJC4nZKxHKTgLVZeaGbFZOvJTNzBspQHdy7Q1uKSfktxpgjZnksiu/tFF9ngyY2KFoc+U88ya95IZUycBGCUbBQ8+bhDtw/icdDGQD5WnUwAAAG8AAAAHc3NoLXJzYQAAAGC8Y9Z2LQKhIhxf52773XaWrXdxP0t3GBVo4A10vUWiYoAGepr6rQIoGGXFxT4B9Gp+nEBJjOwKDXPrAevow0T9ca8gZN+0ykbhSrXLE5Ao48rqr3zP4O1/9P7e6gp0gw8=`
func TestParseCert(t *testing.T) {
authKeyBytes := []byte(exampleSSHCert)
authKeyBytes := bytes.TrimSuffix(testdata.SSHCertificates["rsa"], []byte(" host.example.com\n"))
key, _, _, rest, err := ParseAuthorizedKey(authKeyBytes)
if err != nil {
@@ -103,7 +101,7 @@ func TestParseCertWithOptions(t *testing.T) {
}
func TestValidateCert(t *testing.T) {
key, _, _, _, err := ParseAuthorizedKey([]byte(exampleSSHCert))
key, _, _, _, err := ParseAuthorizedKey(testdata.SSHCertificates["rsa-user-testcertificate"])
if err != nil {
t.Fatalf("ParseAuthorizedKey: %v", err)
}
@@ -116,7 +114,7 @@ func TestValidateCert(t *testing.T) {
return bytes.Equal(k.Marshal(), validCert.SignatureKey.Marshal())
}
if err := checker.CheckCert("user", validCert); err != nil {
if err := checker.CheckCert("testcertificate", validCert); err != nil {
t.Errorf("Unable to validate certificate: %v", err)
}
invalidCert := &Certificate{
@@ -125,7 +123,7 @@ func TestValidateCert(t *testing.T) {
ValidBefore: CertTimeInfinity,
Signature: &Signature{},
}
if err := checker.CheckCert("user", invalidCert); err == nil {
if err := checker.CheckCert("testcertificate", invalidCert); err == nil {
t.Error("Invalid cert signature passed validation")
}
}
+1 -1
View File
@@ -38,7 +38,7 @@ func tryAuth(t *testing.T, config *ClientConfig) error {
return err
}
// tryAuth runs a handshake with a given config against an SSH server
// tryAuthWithGSSAPIWithMICConfig runs a handshake with a given config against an SSH server
// with a given GSSAPIWithMICConfig and config serverConfig. Returns both client and server side errors.
func tryAuthWithGSSAPIWithMICConfig(t *testing.T, clientConfig *ClientConfig, gssAPIWithMICConfig *GSSAPIWithMICConfig) error {
err, _ := tryAuthBothSides(t, clientConfig, gssAPIWithMICConfig)
+50 -14
View File
@@ -5,7 +5,6 @@
package ssh
import (
"crypto/rand"
"errors"
"fmt"
"io"
@@ -25,6 +24,11 @@ const debugHandshake = false
// quickly.
const chanSize = 16
// maxPendingPackets sets the maximum number of packets to queue while waiting
// for KEX to complete. This limits the total pending data to maxPendingPackets
// * maxPacket bytes, which is ~16.8MB.
const maxPendingPackets = 64
// keyingTransport is a packet based transport that supports key
// changes. It need not be thread-safe. It should pass through
// msgNewKeys in both directions.
@@ -73,13 +77,22 @@ type handshakeTransport struct {
incoming chan []byte
readError error
mu sync.Mutex
writeError error
sentInitPacket []byte
sentInitMsg *kexInitMsg
pendingPackets [][]byte // Used when a key exchange is in progress.
mu sync.Mutex
// Condition for the above mutex. It is used to notify a completed key
// exchange or a write failure. Writes can wait for this condition while a
// key exchange is in progress.
writeCond *sync.Cond
writeError error
sentInitPacket []byte
sentInitMsg *kexInitMsg
// Used to queue writes when a key exchange is in progress. The length is
// limited by pendingPacketsSize. Once full, writes will block until the key
// exchange is completed or an error occurs. If not empty, it is emptied
// all at once when the key exchange is completed in kexLoop.
pendingPackets [][]byte
writePacketsLeft uint32
writeBytesLeft int64
userAuthComplete bool // whether the user authentication phase is complete
// If the read loop wants to schedule a kex, it pings this
// channel, and the write loop will send out a kex
@@ -133,6 +146,7 @@ func newHandshakeTransport(conn keyingTransport, config *Config, clientVersion,
config: config,
}
t.writeCond = sync.NewCond(&t.mu)
t.resetReadThresholds()
t.resetWriteThresholds()
@@ -259,6 +273,7 @@ func (t *handshakeTransport) recordWriteError(err error) {
defer t.mu.Unlock()
if t.writeError == nil && err != nil {
t.writeError = err
t.writeCond.Broadcast()
}
}
@@ -362,6 +377,8 @@ write:
}
}
t.pendingPackets = t.pendingPackets[:0]
// Unblock writePacket if waiting for KEX.
t.writeCond.Broadcast()
t.mu.Unlock()
}
@@ -483,7 +500,7 @@ func (t *handshakeTransport) sendKexInit() error {
CompressionClientServer: supportedCompressions,
CompressionServerClient: supportedCompressions,
}
io.ReadFull(rand.Reader, msg.Cookie[:])
io.ReadFull(t.config.Rand, msg.Cookie[:])
// We mutate the KexAlgos slice, in order to add the kex-strict extension algorithm,
// and possibly to add the ext-info extension algorithm. Since the slice may be the
@@ -552,26 +569,44 @@ func (t *handshakeTransport) sendKexInit() error {
return nil
}
var errSendBannerPhase = errors.New("ssh: SendAuthBanner outside of authentication phase")
func (t *handshakeTransport) writePacket(p []byte) error {
t.mu.Lock()
defer t.mu.Unlock()
switch p[0] {
case msgKexInit:
return errors.New("ssh: only handshakeTransport can send kexInit")
case msgNewKeys:
return errors.New("ssh: only handshakeTransport can send newKeys")
case msgUserAuthBanner:
if t.userAuthComplete {
return errSendBannerPhase
}
case msgUserAuthSuccess:
t.userAuthComplete = true
}
t.mu.Lock()
defer t.mu.Unlock()
if t.writeError != nil {
return t.writeError
}
if t.sentInitMsg != nil {
// Copy the packet so the writer can reuse the buffer.
cp := make([]byte, len(p))
copy(cp, p)
t.pendingPackets = append(t.pendingPackets, cp)
return nil
if len(t.pendingPackets) < maxPendingPackets {
// Copy the packet so the writer can reuse the buffer.
cp := make([]byte, len(p))
copy(cp, p)
t.pendingPackets = append(t.pendingPackets, cp)
return nil
}
for t.sentInitMsg != nil {
// Block and wait for KEX to complete or an error.
t.writeCond.Wait()
if t.writeError != nil {
return t.writeError
}
}
}
if t.writeBytesLeft > 0 {
@@ -588,6 +623,7 @@ func (t *handshakeTransport) writePacket(p []byte) error {
if err := t.pushPacket(p); err != nil {
t.writeError = err
t.writeCond.Broadcast()
}
return nil
+220
View File
@@ -539,6 +539,226 @@ func TestDisconnect(t *testing.T) {
}
}
type mockKeyingTransport struct {
packetConn
kexInitAllowed chan struct{}
kexInitSent chan struct{}
}
func (n *mockKeyingTransport) prepareKeyChange(*algorithms, *kexResult) error {
return nil
}
func (n *mockKeyingTransport) writePacket(packet []byte) error {
if packet[0] == msgKexInit {
<-n.kexInitAllowed
n.kexInitSent <- struct{}{}
}
return n.packetConn.writePacket(packet)
}
func (n *mockKeyingTransport) readPacket() ([]byte, error) {
return n.packetConn.readPacket()
}
func (n *mockKeyingTransport) setStrictMode() error { return nil }
func (n *mockKeyingTransport) setInitialKEXDone() {}
func TestHandshakePendingPacketsWait(t *testing.T) {
a, b := memPipe()
trS := &mockKeyingTransport{
packetConn: a,
kexInitAllowed: make(chan struct{}, 2),
kexInitSent: make(chan struct{}, 2),
}
// Allow the first KEX.
trS.kexInitAllowed <- struct{}{}
trC := &mockKeyingTransport{
packetConn: b,
kexInitAllowed: make(chan struct{}, 2),
kexInitSent: make(chan struct{}, 2),
}
// Allow the first KEX.
trC.kexInitAllowed <- struct{}{}
clientConf := &ClientConfig{
HostKeyCallback: InsecureIgnoreHostKey(),
}
clientConf.SetDefaults()
v := []byte("version")
client := newClientTransport(trC, v, v, clientConf, "addr", nil)
serverConf := &ServerConfig{}
serverConf.AddHostKey(testSigners["ecdsa"])
serverConf.AddHostKey(testSigners["rsa"])
serverConf.SetDefaults()
server := newServerTransport(trS, v, v, serverConf)
if err := server.waitSession(); err != nil {
t.Fatalf("server.waitSession: %v", err)
}
if err := client.waitSession(); err != nil {
t.Fatalf("client.waitSession: %v", err)
}
<-trC.kexInitSent
<-trS.kexInitSent
// Allow and request new KEX server side.
trS.kexInitAllowed <- struct{}{}
server.requestKeyExchange()
// Wait until the KEX init is sent.
<-trS.kexInitSent
// The client is not allowed to respond to the KEX, so writes will be
// blocked on the server side once the packets queue is full.
for i := 0; i < maxPendingPackets; i++ {
p := []byte{msgRequestSuccess, byte(i)}
if err := server.writePacket(p); err != nil {
t.Errorf("unexpected write error: %v", err)
}
}
// The packets queue is now full, the next write will block.
server.mu.Lock()
if len(server.pendingPackets) != maxPendingPackets {
t.Errorf("unexpected pending packets size; got: %d, want: %d", len(server.pendingPackets), maxPendingPackets)
}
server.mu.Unlock()
writeDone := make(chan struct{})
go func() {
defer close(writeDone)
p := []byte{msgRequestSuccess, byte(65)}
// This write will block until KEX completes.
err := server.writePacket(p)
if err != nil {
t.Errorf("unexpected write error: %v", err)
}
}()
// Consume packets on the client side
readDone := make(chan bool)
go func() {
defer close(readDone)
for {
if _, err := client.readPacket(); err != nil {
if err != io.EOF {
t.Errorf("unexpected read error: %v", err)
}
break
}
}
}()
// Allow the client to reply to the KEX and so unblock the write goroutine.
trC.kexInitAllowed <- struct{}{}
<-trC.kexInitSent
<-writeDone
// Close the client to unblock the read goroutine.
client.Close()
<-readDone
server.Close()
}
func TestHandshakePendingPacketsError(t *testing.T) {
a, b := memPipe()
trS := &mockKeyingTransport{
packetConn: a,
kexInitAllowed: make(chan struct{}, 2),
kexInitSent: make(chan struct{}, 2),
}
// Allow the first KEX.
trS.kexInitAllowed <- struct{}{}
trC := &mockKeyingTransport{
packetConn: b,
kexInitAllowed: make(chan struct{}, 2),
kexInitSent: make(chan struct{}, 2),
}
// Allow the first KEX.
trC.kexInitAllowed <- struct{}{}
clientConf := &ClientConfig{
HostKeyCallback: InsecureIgnoreHostKey(),
}
clientConf.SetDefaults()
v := []byte("version")
client := newClientTransport(trC, v, v, clientConf, "addr", nil)
serverConf := &ServerConfig{}
serverConf.AddHostKey(testSigners["ecdsa"])
serverConf.AddHostKey(testSigners["rsa"])
serverConf.SetDefaults()
server := newServerTransport(trS, v, v, serverConf)
if err := server.waitSession(); err != nil {
t.Fatalf("server.waitSession: %v", err)
}
if err := client.waitSession(); err != nil {
t.Fatalf("client.waitSession: %v", err)
}
<-trC.kexInitSent
<-trS.kexInitSent
// Allow and request new KEX server side.
trS.kexInitAllowed <- struct{}{}
server.requestKeyExchange()
// Wait until the KEX init is sent.
<-trS.kexInitSent
// The client is not allowed to respond to the KEX, so writes will be
// blocked on the server side once the packets queue is full.
for i := 0; i < maxPendingPackets; i++ {
p := []byte{msgRequestSuccess, byte(i)}
if err := server.writePacket(p); err != nil {
t.Errorf("unexpected write error: %v", err)
}
}
// The packets queue is now full, the next write will block.
writeDone := make(chan struct{})
go func() {
defer close(writeDone)
p := []byte{msgRequestSuccess, byte(65)}
// This write will block until KEX completes.
err := server.writePacket(p)
if err != io.EOF {
t.Errorf("unexpected write error: %v", err)
}
}()
// Consume packets on the client side
readDone := make(chan bool)
go func() {
defer close(readDone)
for {
if _, err := client.readPacket(); err != nil {
if err != io.EOF {
t.Errorf("unexpected read error: %v", err)
}
break
}
}
}()
// Close the server to unblock the write after an error
server.Close()
<-writeDone
// Unblock the pending write and close the client to unblock the read
// goroutine.
trC.kexInitAllowed <- struct{}{}
client.Close()
<-readDone
}
func TestHandshakeRekeyDefault(t *testing.T) {
clientConf := &ClientConfig{
Config: Config{
+12 -26
View File
@@ -302,8 +302,8 @@ func (k *KnownKey) String() string {
// applications can offer an interactive prompt to the user.
type KeyError struct {
// Want holds the accepted host keys. For each key algorithm,
// there can be one hostkey. If Want is empty, the host is
// unknown. If Want is non-empty, there was a mismatch, which
// there can be multiple hostkeys. If Want is empty, the host
// is unknown. If Want is non-empty, there was a mismatch, which
// can signify a MITM attack.
Want []KnownKey
}
@@ -358,34 +358,20 @@ func (db *hostKeyDB) checkAddr(a addr, remoteKey ssh.PublicKey) error {
// is just a key for the IP address, but not for the
// hostname?
// Algorithm => key.
knownKeys := map[string]KnownKey{}
keyErr := &KeyError{}
for _, l := range db.lines {
if l.match(a) {
typ := l.knownKey.Key.Type()
if _, ok := knownKeys[typ]; !ok {
knownKeys[typ] = l.knownKey
}
if !l.match(a) {
continue
}
keyErr.Want = append(keyErr.Want, l.knownKey)
if keyEq(l.knownKey.Key, remoteKey) {
return nil
}
}
keyErr := &KeyError{}
for _, v := range knownKeys {
keyErr.Want = append(keyErr.Want, v)
}
// Unknown remote host.
if len(knownKeys) == 0 {
return keyErr
}
// If the remote host starts using a different, unknown key type, we
// also interpret that as a mismatch.
if known, ok := knownKeys[remoteKey.Type()]; !ok || !keyEq(known.Key, remoteKey) {
return keyErr
}
return nil
return keyErr
}
// The Read function parses file contents.
+13 -11
View File
@@ -201,17 +201,6 @@ func TestHostNamePrecedence(t *testing.T) {
}
}
func TestDBOrderingPrecedenceKeyType(t *testing.T) {
str := fmt.Sprintf("server.org,%s %s\nserver.org,%s %s", testAddr, edKeyStr, testAddr, alternateEdKeyStr)
db := testDB(t, str)
if err := db.check("server.org:22", testAddr, alternateEdKey); err == nil {
t.Errorf("check succeeded")
} else if _, ok := err.(*KeyError); !ok {
t.Errorf("got %T, want *KeyError", err)
}
}
func TestNegate(t *testing.T) {
str := fmt.Sprintf("%s,!server.org %s", testAddr, edKeyStr)
db := testDB(t, str)
@@ -354,3 +343,16 @@ func TestHashedHostkeyCheck(t *testing.T) {
t.Errorf("got error %v, want %v", got, want)
}
}
func TestIssue36126(t *testing.T) {
str := fmt.Sprintf("server.org,%s %s\nserver.org,%s %s", testAddr, edKeyStr, testAddr, alternateEdKeyStr)
db := testDB(t, str)
if err := db.check("server.org:22", testAddr, edKey); err != nil {
t.Errorf("should have passed the check, got %v", err)
}
if err := db.check("server.org:22", testAddr, alternateEdKey); err != nil {
t.Errorf("should have passed the check, got %v", err)
}
}
+2
View File
@@ -818,6 +818,8 @@ func decode(packet []byte) (interface{}, error) {
return new(userAuthSuccessMsg), nil
case msgUserAuthFailure:
msg = new(userAuthFailureMsg)
case msgUserAuthBanner:
msg = new(userAuthBannerMsg)
case msgUserAuthPubKeyOk:
msg = new(userAuthPubKeyOkMsg)
case msgGlobalRequest:
+56
View File
@@ -206,6 +206,62 @@ func TestMarshalMultiTag(t *testing.T) {
}
}
func TestDecode(t *testing.T) {
rnd := rand.New(rand.NewSource(0))
kexInit := new(kexInitMsg).Generate(rnd, 10).Interface()
kexDHInit := new(kexDHInitMsg).Generate(rnd, 10).Interface()
kexDHReply := new(kexDHReplyMsg)
kexDHReply.Y = randomInt(rnd)
// Note: userAuthSuccessMsg can't be tested directly since it
// doesn't have a field for sshtype. So it's tested separately
// at the end.
decodeMessageTypes := []interface{}{
new(disconnectMsg),
new(serviceRequestMsg),
new(serviceAcceptMsg),
new(extInfoMsg),
kexInit,
kexDHInit,
kexDHReply,
new(userAuthRequestMsg),
new(userAuthFailureMsg),
new(userAuthBannerMsg),
new(userAuthPubKeyOkMsg),
new(globalRequestMsg),
new(globalRequestSuccessMsg),
new(globalRequestFailureMsg),
new(channelOpenMsg),
new(channelDataMsg),
new(channelOpenConfirmMsg),
new(channelOpenFailureMsg),
new(windowAdjustMsg),
new(channelEOFMsg),
new(channelCloseMsg),
new(channelRequestMsg),
new(channelRequestSuccessMsg),
new(channelRequestFailureMsg),
new(userAuthGSSAPIToken),
new(userAuthGSSAPIMIC),
new(userAuthGSSAPIErrTok),
new(userAuthGSSAPIError),
}
for _, msg := range decodeMessageTypes {
decoded, err := decode(Marshal(msg))
if err != nil {
t.Errorf("error decoding %T", msg)
} else if reflect.TypeOf(msg) != reflect.TypeOf(decoded) {
t.Errorf("error decoding %T, unexpected %T", msg, decoded)
}
}
userAuthSuccess, err := decode([]byte{msgUserAuthSuccess})
if err != nil {
t.Errorf("error decoding userAuthSuccessMsg")
} else if reflect.TypeOf(userAuthSuccess) != reflect.TypeOf((*userAuthSuccessMsg)(nil)) {
t.Errorf("error decoding userAuthSuccessMsg, unexpected %T", userAuthSuccess)
}
}
func randomBytes(out []byte, rand *rand.Rand) {
for i := 0; i < len(out); i++ {
out[i] = byte(rand.Int31())
+48 -17
View File
@@ -59,6 +59,27 @@ type GSSAPIWithMICConfig struct {
Server GSSAPIServer
}
// SendAuthBanner implements [ServerPreAuthConn].
func (s *connection) SendAuthBanner(msg string) error {
return s.transport.writePacket(Marshal(&userAuthBannerMsg{
Message: msg,
}))
}
func (*connection) unexportedMethodForFutureProofing() {}
// ServerPreAuthConn is the interface available on an incoming server
// connection before authentication has completed.
type ServerPreAuthConn interface {
unexportedMethodForFutureProofing() // permits growing ServerPreAuthConn safely later, ala testing.TB
ConnMetadata
// SendAuthBanner sends a banner message to the client.
// It returns an error once the authentication phase has ended.
SendAuthBanner(string) error
}
// ServerConfig holds server specific configuration data.
type ServerConfig struct {
// Config contains configuration shared between client and server.
@@ -118,6 +139,12 @@ type ServerConfig struct {
// attempts.
AuthLogCallback func(conn ConnMetadata, method string, err error)
// PreAuthConnCallback, if non-nil, is called upon receiving a new connection
// before any authentication has started. The provided ServerPreAuthConn
// can be used at any time before authentication is complete, including
// after this callback has returned.
PreAuthConnCallback func(ServerPreAuthConn)
// ServerVersion is the version identification string to announce in
// the public handshake.
// If empty, a reasonable default is used.
@@ -149,7 +176,7 @@ func (s *ServerConfig) AddHostKey(key Signer) {
}
// cachedPubKey contains the results of querying whether a public key is
// acceptable for a user.
// acceptable for a user. This is a FIFO cache.
type cachedPubKey struct {
user string
pubKeyData []byte
@@ -157,7 +184,13 @@ type cachedPubKey struct {
perms *Permissions
}
const maxCachedPubKeys = 16
// maxCachedPubKeys is the number of cache entries we store.
//
// Due to consistent misuse of the PublicKeyCallback API, we have reduced this
// to 1, such that the only key in the cache is the most recently seen one. This
// forces the behavior that the last call to PublicKeyCallback will always be
// with the key that is used for authentication.
const maxCachedPubKeys = 1
// pubKeyCache caches tests for public keys. Since SSH clients
// will query whether a public key is acceptable before attempting to
@@ -179,9 +212,10 @@ func (c *pubKeyCache) get(user string, pubKeyData []byte) (cachedPubKey, bool) {
// add adds the given tuple to the cache.
func (c *pubKeyCache) add(candidate cachedPubKey) {
if len(c.keys) < maxCachedPubKeys {
c.keys = append(c.keys, candidate)
if len(c.keys) >= maxCachedPubKeys {
c.keys = c.keys[1:]
}
c.keys = append(c.keys, candidate)
}
// ServerConn is an authenticated SSH connection, as seen from the
@@ -481,6 +515,10 @@ func (b *BannerError) Error() string {
}
func (s *connection) serverAuthenticate(config *ServerConfig) (*Permissions, error) {
if config.PreAuthConnCallback != nil {
config.PreAuthConnCallback(s)
}
sessionID := s.transport.getSessionID()
var cache pubKeyCache
var perms *Permissions
@@ -488,7 +526,7 @@ func (s *connection) serverAuthenticate(config *ServerConfig) (*Permissions, err
authFailures := 0
noneAuthCount := 0
var authErrs []error
var displayedBanner bool
var calledBannerCallback bool
partialSuccessReturned := false
// Set the initial authentication callbacks from the config. They can be
// changed if a PartialSuccessError is returned.
@@ -535,14 +573,10 @@ userAuthLoop:
s.user = userAuthReq.User
if !displayedBanner && config.BannerCallback != nil {
displayedBanner = true
msg := config.BannerCallback(s)
if msg != "" {
bannerMsg := &userAuthBannerMsg{
Message: msg,
}
if err := s.transport.writePacket(Marshal(bannerMsg)); err != nil {
if !calledBannerCallback && config.BannerCallback != nil {
calledBannerCallback = true
if msg := config.BannerCallback(s); msg != "" {
if err := s.SendAuthBanner(msg); err != nil {
return nil, err
}
}
@@ -755,10 +789,7 @@ userAuthLoop:
var bannerErr *BannerError
if errors.As(authErr, &bannerErr) {
if bannerErr.Message != "" {
bannerMsg := &userAuthBannerMsg{
Message: bannerErr.Message,
}
if err := s.transport.writePacket(Marshal(bannerMsg)); err != nil {
if err := s.SendAuthBanner(bannerErr.Message); err != nil {
return nil, err
}
}
+135
View File
@@ -5,6 +5,7 @@
package ssh
import (
"bytes"
"errors"
"fmt"
"io"
@@ -299,6 +300,140 @@ func TestBannerError(t *testing.T) {
}
}
func TestPublicKeyCallbackLastSeen(t *testing.T) {
var lastSeenKey PublicKey
c1, c2, err := netPipe()
if err != nil {
t.Fatalf("netPipe: %v", err)
}
defer c1.Close()
defer c2.Close()
serverConf := &ServerConfig{
PublicKeyCallback: func(conn ConnMetadata, key PublicKey) (*Permissions, error) {
lastSeenKey = key
fmt.Printf("seen %#v\n", key)
if _, ok := key.(*dsaPublicKey); !ok {
return nil, errors.New("nope")
}
return nil, nil
},
}
serverConf.AddHostKey(testSigners["ecdsap256"])
done := make(chan struct{})
go func() {
defer close(done)
NewServerConn(c1, serverConf)
}()
clientConf := ClientConfig{
User: "user",
Auth: []AuthMethod{
PublicKeys(testSigners["rsa"], testSigners["dsa"], testSigners["ed25519"]),
},
HostKeyCallback: InsecureIgnoreHostKey(),
}
_, _, _, err = NewClientConn(c2, "", &clientConf)
if err != nil {
t.Fatal(err)
}
<-done
expectedPublicKey := testSigners["dsa"].PublicKey().Marshal()
lastSeenMarshalled := lastSeenKey.Marshal()
if !bytes.Equal(lastSeenMarshalled, expectedPublicKey) {
t.Errorf("unexpected key: got %#v, want %#v", lastSeenKey, testSigners["dsa"].PublicKey())
}
}
func TestPreAuthConnAndBanners(t *testing.T) {
testDone := make(chan struct{})
defer close(testDone)
authConnc := make(chan ServerPreAuthConn, 1)
serverConfig := &ServerConfig{
PreAuthConnCallback: func(c ServerPreAuthConn) {
t.Logf("got ServerPreAuthConn: %v", c)
authConnc <- c // for use later in the test
for _, s := range []string{"hello1", "hello2"} {
if err := c.SendAuthBanner(s); err != nil {
t.Errorf("failed to send banner %q: %v", s, err)
}
}
// Now start a goroutine to spam SendAuthBanner in hopes
// of hitting a race.
go func() {
for {
select {
case <-testDone:
return
default:
if err := c.SendAuthBanner("attempted-race"); err != nil && err != errSendBannerPhase {
t.Errorf("unexpected error from SendAuthBanner: %v", err)
}
time.Sleep(5 * time.Millisecond)
}
}
}()
},
NoClientAuth: true,
NoClientAuthCallback: func(ConnMetadata) (*Permissions, error) {
t.Logf("got NoClientAuthCallback")
return &Permissions{}, nil
},
}
serverConfig.AddHostKey(testSigners["rsa"])
var banners []string
clientConfig := &ClientConfig{
User: "test",
HostKeyCallback: InsecureIgnoreHostKey(),
BannerCallback: func(msg string) error {
if msg != "attempted-race" {
banners = append(banners, msg)
}
return nil
},
}
c1, c2, err := netPipe()
if err != nil {
t.Fatalf("netPipe: %v", err)
}
defer c1.Close()
defer c2.Close()
go newServer(c1, serverConfig)
c, _, _, err := NewClientConn(c2, "", clientConfig)
if err != nil {
t.Fatalf("client connection failed: %v", err)
}
defer c.Close()
wantBanners := []string{
"hello1",
"hello2",
}
if !reflect.DeepEqual(banners, wantBanners) {
t.Errorf("got banners:\n%q\nwant banners:\n%q", banners, wantBanners)
}
// Now that we're authenticated, verify that use of SendBanner
// is an error.
var bc ServerPreAuthConn
select {
case bc = <-authConnc:
default:
t.Fatal("expected ServerPreAuthConn")
}
if err := bc.SendAuthBanner("wrong-phase"); err == nil {
t.Error("unexpected success of SendAuthBanner after authentication")
} else if err != errSendBannerPhase {
t.Errorf("unexpected error: %v; want %v", err, errSendBannerPhase)
}
}
type markerConn struct {
closed uint32
used uint32
+1 -1
View File
@@ -459,7 +459,7 @@ func (c *Client) dial(laddr string, lport int, raddr string, rport int) (Channel
return nil, err
}
go DiscardRequests(in)
return ch, err
return ch, nil
}
type tcpChan struct {
+1048 -589
View File
File diff suppressed because it is too large Load Diff
+13 -4
View File
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build go1.20
// Package fallback embeds a set of fallback X.509 trusted roots in the
// application by automatically invoking [x509.SetFallbackRoots]. This allows
// the application to work correctly even if the operating system does not
@@ -24,8 +22,19 @@ import "crypto/x509"
func init() {
p := x509.NewCertPool()
for _, c := range bundle {
p.AddCert(c)
for _, c := range parsedCertificates {
if len(c.constraints) == 0 {
p.AddCert(c.cert)
} else {
p.AddCertWithConstraint(c.cert, func(chain []*x509.Certificate) error {
for _, constraint := range c.constraints {
if err := constraint(chain); err != nil {
return err
}
}
return nil
})
}
}
x509.SetFallbackRoots(p)
}
+1 -1
View File
@@ -1,3 +1,3 @@
module golang.org/x/crypto/x509roots/fallback
go 1.20
go 1.23.0
+73 -28
View File
@@ -21,46 +21,77 @@ import (
"net/http"
"os"
"sort"
"time"
"golang.org/x/crypto/x509roots/nss"
)
const tmpl = `// Code generated by gen_fallback_bundle.go; DO NOT EDIT.
//go:build go1.20
package fallback
import "crypto/x509"
import "encoding/pem"
import (
"crypto/x509"
"encoding/pem"
"fmt"
"time"
)
func mustParse(b []byte) []*x509.Certificate {
var roots []*x509.Certificate
for len(b) > 0 {
var block *pem.Block
block, b = pem.Decode(b)
type unparsedCertificate struct {
cn string
sha256Hash string
pem string
// possible constraints
distrustAfter string
}
type parsedCertificate struct {
cert *x509.Certificate
constraints []func([]*x509.Certificate) error
}
func mustParse(unparsedCerts []unparsedCertificate) []parsedCertificate {
var b []parsedCertificate
for _, unparsed := range unparsedCerts {
block, rest := pem.Decode([]byte(unparsed.pem))
if block == nil {
break
panic(fmt.Sprintf("unexpected nil PEM block for %q", unparsed.cn))
}
if len(rest) != 0 {
panic(fmt.Sprintf("unexpected trailing data in PEM for %q", unparsed.cn))
}
if block.Type != "CERTIFICATE" {
panic("unexpected PEM block type: " + block.Type)
panic(fmt.Sprintf("unexpected PEM block type for %q: %s", unparsed.cn, block.Type))
}
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
panic(err)
}
roots = append(roots, cert)
parsed := parsedCertificate{cert: cert}
// parse possible constraints, this should check all fields of unparsedCertificate.
if unparsed.distrustAfter != "" {
distrustAfter, err := time.Parse(time.RFC3339, unparsed.distrustAfter)
if err != nil {
panic(fmt.Sprintf("failed to parse distrustAfter %q: %s", unparsed.distrustAfter, err))
}
parsed.constraints = append(parsed.constraints, func(chain []*x509.Certificate) error {
for _, c := range chain {
if c.NotBefore.After(distrustAfter) {
return fmt.Errorf("certificate issued after distrust-after date %q", distrustAfter)
}
}
return nil
})
}
b = append(b, parsed)
}
return roots
return b
}
var bundle = mustParse([]byte(pemRoots))
// Format of the PEM list is:
// * Subject common name
// * SHA256 hash
// * PEM block
var parsedCertificates = mustParse(unparsedCertificates)
var unparsedCertificates = []unparsedCertificate{
`
var (
@@ -124,19 +155,33 @@ func main() {
b := new(bytes.Buffer)
b.WriteString(tmpl)
fmt.Fprintln(b, "const pemRoots = `")
for _, c := range certs {
if len(c.Constraints) > 0 {
// Until the constrained roots API lands, skip anything that has any
// additional constraints. Once that API is available, we can add
// build constraints that support both the current version and the
// new version.
var constraints []string
var skip bool
for _, constraint := range c.Constraints {
switch t := constraint.(type) {
case nss.DistrustAfter:
constraints = append(constraints, fmt.Sprintf("distrustAfter: \"%s\",", time.Time(t).Format(time.RFC3339)))
default:
// If we encounter any constraints we don't support, skip the certificate.
skip = true
break
}
}
if skip {
continue
}
fmt.Fprintf(b, "# %s\n# %x\n", c.X509.Subject.String(), sha256.Sum256(c.X509.Raw))
pem.Encode(b, &pem.Block{Type: "CERTIFICATE", Bytes: c.X509.Raw})
fmt.Fprintf(b, "{\ncn: %q,\nsha256Hash: \"%x\",\npem: `%s`,\n",
c.X509.Subject.String(),
sha256.Sum256(c.X509.Raw),
string(pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: c.X509.Raw})),
)
for _, constraint := range constraints {
fmt.Fprintln(b, constraint)
}
fmt.Fprintln(b, "},")
}
fmt.Fprintln(b, "`")
fmt.Fprintln(b, "}")
formatted, err := format.Source(b.Bytes())
if err != nil {