Previously the library did not verify the "User Presence" (UP) bit in
signatures generated by FIDO/U2F security keys
(sk-ecdsa-sha2-nistp256@openssh.com and sk-ssh-ed25519@openssh.com).
This allowed signatures without physical interaction to be accepted
if the underlying hardware produced them, deviating from the default
secure behavior expected by the FIDO standards and OpenSSH.
skECDSAPublicKey.Verify and skEd25519PublicKey.Verify now enforce
the user-presence bit (0x01, constant flagUserPresence) by default.
Signatures whose flags byte has UP clear fail with the sentinel
errSKMissingUserPresence.
The server public-key authentication path honors the OpenSSH
"no-touch-required" extension as an opt-out. noTouchAllowed reports
true when the extension is present either in the Permissions
returned by PublicKeyCallback (authorized_keys-level opt-out) or in
the certificate's own Extensions (CA-level opt-out); in that case
skKeyWithoutUP is used to derive a clone of the SK public key (and,
for certificates, a clone of the wrapping Certificate whose inner
Key is the cloned SK key) whose Verify accepts UP-clear signatures.
The originals are never mutated, so a per-session opt-out cannot
leak across authentication attempts or connections. Matching
OpenSSH, the opt-out is read only from Extensions, never from
CriticalOptions.
skKeyWithoutUP is iterative and unwraps at most one level of
*Certificate: the SSH cert format forbids Certificate.Key from being
another Certificate (parseCert rejects it) but callers can still
construct such a value directly in Go, so a recursive descent would
be driven to unbounded depth by malformed or cyclic input. Any such
pathological *Certificate is returned unchanged.
CertChecker.CheckCert applies skKeyWithoutUP unconditionally to the
certificate's CA key before verifying the CA signature, matching
OpenSSH, which calls sshkey_verify with detailsp==NULL in
sshkey.c:cert_parse and never extracts or enforces UP/UV flags on
CA signatures. The UP bit on a CA signature reflects the CA
operator's presence at cert-issuance time, which has no bearing on
whether the user being authenticated is present now, so enforcing it
here would only break interop with certificates issued by
non-interactive SK CAs without a corresponding security benefit. The
skKeyWithoutUP call is a no-op for non-SK CA keys (the common case).
This change breaks backward compatibility for clients or keys that
generate user-authentication signatures without the User Presence
flag set. Previously those signatures were accepted by the server.
They will now be rejected with "ssh: signature missing required user
presence flag" unless the "no-touch-required" extension is
explicitly granted to the session by the server callbacks, or
carried by the user certificate.
This issue was found during a security audit by NCC Group
Cryptography Services, sponsored by Teleport.
Fixesgolang/go#79566
Fixes CVE-2026-39831
Change-Id: I74b6de3bb6a2d7a0f34d7fa36bbbbf06f0b3fc6b
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/781662
Reviewed-by: Neal Patel <nealpatel@google.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
The parseDSA function previously accepted DSA keys with arbitrary values
for the sub-prime Q and did not validate that group elements G and Y
were within the modulus P.
Malicious actors could provide a key with a massively large Q (e.g.,
millions of bits), leading to excessive CPU consumption during signature
verification.
This change restricts the sub-prime Q to exactly 160 bits, as required
by FIPS 186-2, and ensures that G and Y are strictly less than P.
This issue was found during a security audit by NCC Group Cryptography
Services, sponsored by Teleport.
Fixesgolang/go#79565
Fixes CVE-2026-39829
Change-Id: I526118d94684076088d0625178844f64c1303ec8
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/781661
Reviewed-by: Roland Shoemaker <roland@golang.org>
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Neal Patel <nealpatel@google.com>
Previously, the RSA key parser accepted keys with arbitrary modulus
sizes. Processing keys with extremely large moduli (e.g., > 8192 bits)
can consume excessive CPU resources during verification, potentially
leading to a Denial of Service (DoS).
This change introduces a limit of 8192 bits for the RSA modulus in
parseRSA, rejecting keys that exceed this size in line with the limit
enforced by crypto/tls.
This issue was found during a security audit by NCC Group Cryptography
Services, sponsored by Teleport.
Fixesgolang/go#79565
Fixes CVE-2026-39829
Change-Id: Ibdddad1859a4d9db5c9f052d06c82f29bfc2e5e5
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/781641
Reviewed-by: Neal Patel <nealpatel@google.com>
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
In serverAuthenticate, the permissions variable is reset to nil at the
beginning of the authentication loop. If an authentication callback
returns a PartialSuccessError along with non-nil Permissions, those
permissions are currently silently discarded before the next
authentication step.
This change returns an error if a callback returns both a PartialSuccessError
and non-nil Permissions, preventing API misuse where the user might
erroneously expect those permissions to be preserved or merged into the
final session permissions.
This issue was found during a security audit by NCC Group Cryptography
Services, sponsored by Teleport.
Fixesgolang/go#79562
Fixes CVE-2026-39828
Change-Id: I632c9e46e2b5e8804ef88081063a3612a2462f9f
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/781621
Reviewed-by: Neal Patel <nealpatel@google.com>
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Gopher Robot <gobot@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
The original SSH RFC 4253 explicitly disallows padding. This applies to
ssh-rsa signatures.
The updated SSH RFC 8332 which defines the SHA2 RSA signature variants
explicitly calls out the existence of signers who produce short
signatures and specifies that verifiers may allow this behavior.
In practice, PuTTY 0.81 and prior versions, as well as SSH.NET prior to
2024.1.0 always generated short signatures. Furthermore, PuTTY is
embedded in other software like WinSCP and FileZilla, which are updated
on their own schedules as well. This leads to occasional unexplained
login errors, when using RSA keys.
OpenSSH server allows these short signatures for all RSA algorithms.
Fixesgolang/go#68286
Change-Id: Ia60ece21bf9c111c490fac0c066443ed5ff7dd29
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/598534
Reviewed-by: Nicola Murino <nicola.murino@gmail.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Auto-Submit: Nicola Murino <nicola.murino@gmail.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
on RHEL 9 OpenSSH does not support DSA keys and RSA keys with size less
than 2048 bits, furthermore signing with ssh-rsa (SHA-1 signatures) and
ssh-dss is not allowed, therefore:
1) replaced the 1024-bit RSA key used in the test with a new 2048-bit
one
2) removed DSA key from itegration tests
3) allowed signature errors using ssh-rsa in agent integration tests, we
also check SHA-2 variants that are not skipped
Fixesgolang/go#65581
Change-Id: I54bf997b61ef4d91d38eb624275737ba7291bb20
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/562755
Reviewed-by: Roland Shoemaker <roland@golang.org>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
Auto-Submit: Nicola Murino <nicola.murino@gmail.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This is a follow-up to CL 317169, which dropped go1.12 compatibility,
and made the golang.org/x/crypto/ed25519 package an alias / wrapper for
crypto/ed25519 in stdlib.
This patch updates uses within this repository to use stdlib instead of
depending on the wrapper. With this patch applied, the only remaining
use of the wrapper is in ed25519_test, which appears to be in place to
verify compatibility of the wrapper itself.
Change-Id: I0195396102a75ae20bdd82ca8ab59855c0eb5cea
GitHub-Last-Rev: 24dbec563cbd84bc47bdc7736b0245fc83dd3353
GitHub-Pull-Request: golang/crypto#238
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/448238
Reviewed-by: Bryan Mills <bcmills@google.com>
Run-TryBot: Nicola Murino <nicola.murino@gmail.com>
Reviewed-by: Nicola Murino <nicola.murino@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Joedian Reid <joedian@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
RFC 8332, Section 2 sets up two overlapping namespaces: public key
formats and public key algorithms.
* The formats are what we currently have KeyAlgo constants for, and they
appear in PublicKey.Type.
* The algorithms are the set of both KeyAlgo and SigAlgo constants, and
they appear in Signature.Format (amongst other places).
This is incoherent, because that means Signature.Format can be both a
KeyAlgo (like KeyAlgoECDSA256) or a SigAlgo (like SigAlgoRSASHA2256).
One solution would be to duplicate all the KeyAlgo constants into the
SigAlgo namespace, but that would be confusing because applications are
currently using KeyAlgos where they'd be supposed to use the new
SigAlgos (while we can't deprecate the KeyAlgos because they are still
necessary for the PublicKey.Type namespace).
Instead, drop the separate namespaces, and use KeyAlgos throughout.
There are simply some KeyAlgos that can't be a PublicKey.Type.
Take the opportunity to fix the stuttering SHA22565/SHA2512 names. It's
totally ok to call those hashes SHA-256 and SHA-512 without the family
infix.
For golang/go#49952
Change-Id: Ia1fce3912a7e60aa70a88f75ed311be331fd19d5
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/392354
Trust: Filippo Valsorda <filippo@golang.org>
Run-TryBot: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
The behavior of ParsePrivateKeyWithPassphrase when the key is
unencrypted is unspecified. Currently, it just parses them like
ParsePrivateKey, which is unlikely to be what anyone wants: for us to
ignore a passphrase that they explicitly passed. It also makes the
implementation of encrypted OpenSSH keys in the next CL more confused.
Instead, make ParsePrivateKey return a PassphraseNeededError, so the
application logic can be ParsePrivateKey -> detect encrypted key ->
obtain passphrase -> ParsePrivateKeyWithPassphrase. That error will also
let us return the public key for OpenSSH keys.
Change-Id: Ife4fb2499ae538bef36e353adf9bc8e902662386
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/207599
Run-TryBot: Filippo Valsorda <filippo@golang.org>
Run-TryBot: Han-Wen Nienhuys <hanwen@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Han-Wen Nienhuys <hanwen@google.com>
This commit implements two new features. To preserve backwards
compatibility the new methods are added to an `ExtendedAgent` interface
which extends `Agent`. The client code implements `ExtendedAgent`
(which extends Agent) so you can call these additional methods against
SSH agents such as the OpenSSH agent. The ServeAgent method still
accepts Agent but will attempt to upcast the agent to `ExtendedAgent`
as needed, so if you supply an ExtendedAgent implementation you can
implement these additional methods (which keyring does).
The first feature is supporting the standard flags that can be passed to
SSH Sign requests, requesting that RSA signatures use SHA-256 or
SHA-512. See section 4.5.1 of the SSH agent protocol draft:
https://tools.ietf.org/html/draft-miller-ssh-agent-02
The second feature is supporting calling custom extensions from clients
and implementing custom extensions from servers. See section 4.7 of the
SSH agent protocol draft:
https://tools.ietf.org/html/draft-miller-ssh-agent-02
Change-Id: I0f74feb893762c27e921ec37604d3a46434ee6ef
GitHub-Last-Rev: 2e23fd01c0e95b664e8507682f0bd5bd61d4c146
GitHub-Pull-Request: golang/crypto#53
Reviewed-on: https://go-review.googlesource.com/c/123955
Reviewed-by: Han-Wen Nienhuys <hanwen@google.com>
Run-TryBot: Han-Wen Nienhuys <hanwen@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
The existing client side authentication does not handle correctly
the partial success flag in SSH_MSG_USERAUTH_FAILURE authentication
responses.
This commit fixes two problems in ssh library:
1) RetryableAuthMethod() now breaks out from the retry loop and
returns when underlying auth method fails with partial success
set to true.
2) Book keeping of tried (and failed) auth methods in
clientAuthenticate() does not mark an auth method failed if it
fails with partial success set to true.
Fixesgolang/go#23461
Change-Id: Ib2e1a1d54bfe2549496199bb2f66ebbce58d130d
Reviewed-on: https://go-review.googlesource.com/88035
Reviewed-by: Han-Wen Nienhuys <hanwen@google.com>
Run-TryBot: Han-Wen Nienhuys <hanwen@google.com>
RSA and DSA keys if encrypted have the
phrase ENCRYPTED in their Proc-Type block
header according to RFC 1421 Section 4.6.1.1.
This CL checks for that phrase and errors out
if we encounter it, since we don't yet have
decryption of encrypted private keys.
Fixesgolang/go#6650
Change-Id: I5b157716a2f93557d289af5f62994234a2e7a0ed
Reviewed-on: https://go-review.googlesource.com/29676
Reviewed-by: Han-Wen Nienhuys <hanwen@google.com>
Run-TryBot: Han-Wen Nienhuys <hanwen@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Added support for parsing the "new" openssh private key format.
(ed25519 keys only in this format for now)
Signing and verifying functions now work with ed25519 keys.
ed25519 can now be accepted by the server to authenticate a client.
ed25519 can now be accepted by a client as a server host key.
Related documentation used:
https://www.ietf.org/archive/id/draft-bjh21-ssh-ed25519-02.txt
Change-Id: I84385f24d666fea08de21f980f78623f7bff8007
Reviewed-on: https://go-review.googlesource.com/22512
Reviewed-by: Han-Wen Nienhuys <hanwen@google.com>
Run-TryBot: Han-Wen Nienhuys <hanwen@google.com>
This adds a NewSignerFromSigner to crypto/ssh which takes a
crypto.Signer and turns it into an ssh.Signer, helpful if, e.g., your
crypto.Signer is backed by some sort of hardware device.
The interfaces are very similar - the biggest differences are that a
crypto.Signer accepts hashed data, while an ssh.Signer does not, and
some differences in encoding for DSA and ECDSA signatures.
This also adjusts NewSignerFromKey to use NewSignerFromSigner where
possible, dropping the rsaPrivateKey and ecdsaPrivateKey types in
favor of wrappedSigner. (However, because *dsa.PrivateKey is not a
crypto.Signer, we still have to keep dsaPrivateKey)
Change-Id: Ia2e20ece9c9d3844b4e5a64c1a7d997178ec8781
Reviewed-on: https://go-review.googlesource.com/10953
Reviewed-by: Adam Langley <agl@golang.org>
The change to add the PublicKey interface accidentally caused certificate handling to expect an extra copy of the private key algorithm name in the binary representation. This change adapts a suitable parsing API and adds a test to ensure that cert handling isn't easily broken in the future.
R=agl, hanwen, jmpittman
CC=golang-dev
https://golang.org/cl/13272055