Bug 3279 - UpdateHostKeys triggers "client_global_hostkeys_private_confirm: server gave bad signature for RSA key 0" error message
Summary: UpdateHostKeys triggers "client_global_hostkeys_private_confirm: server gave ...
Status: NEW
Alias: None
Product: Portable OpenSSH
Classification: Unclassified
Component: ssh (show other bugs)
Version: 8.5p1
Hardware: Other Windows 10
: P5 normal
Assignee: Assigned to nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-03-13 00:52 AEDT by Thomas Braun
Modified: 2021-07-16 10:32 AEST (History)
3 users (show)

See Also:


Attachments
stderr output (12.56 KB, text/plain)
2021-04-30 20:20 AEST, Thomas Braun
no flags Details
stdout output (25 bytes, text/plain)
2021-04-30 20:21 AEST, Thomas Braun
no flags Details
use old-style RSA signature algorithm for SSH_BUG_SIGTYPE servers (587 bytes, patch)
2021-05-03 12:03 AEST, Damien Miller
no flags Details | Diff
stderr with ac31aa3c63 applied (9.13 KB, text/plain)
2021-05-11 23:43 AEST, Thomas Braun
no flags Details
stdout with ac31aa3c63 applied (25 bytes, text/plain)
2021-05-11 23:44 AEST, Thomas Braun
no flags Details
dump failed key and signature (1.65 KB, patch)
2021-05-20 11:43 AEST, Damien Miller
no flags Details | Diff
debug failed libcrypto call (1.12 KB, patch)
2021-05-20 12:05 AEST, Damien Miller
no flags Details | Diff
debug output with latest patches (9.81 KB, text/plain)
2021-07-15 06:46 AEST, Thomas Braun
no flags Details
openssl test result (9.83 KB, text/plain)
2021-07-16 00:59 AEST, Thomas Braun
no flags Details
test "program" (1.27 KB, patch)
2021-07-16 10:07 AEST, Damien Miller
no flags Details | Diff
Better RSA verification debugging (1.55 KB, patch)
2021-07-16 10:32 AEST, Damien Miller
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Braun 2021-03-13 00:52:00 AEDT
Upstream issue: https://github.com/git-for-windows/git/issues/3108

$ ssh -V
OpenSSH_8.5p1, OpenSSL 1.1.1j  16 Feb 2021

Platform:
Windows 10

The following recipe requires a gitlab.com account with ssh key attached.

```
$ ssh git@gitlab.com -i ~/.ssh/XXX
client_global_hostkeys_private_confirm: server gave bad signature for RSA key 0
PTY allocation request failed on channel 0
Welcome to GitLab, @XXX!
Connection to gitlab.com closed.
```

As found on the internet disabling UpdateHostKeys turns the error message off:

```
$ ssh -o UpdateHostKeys=no git@gitlab.com -i ~/.ssh/github_ed255519
PTY allocation request failed on channel 0
Welcome to GitLab, @t-b!
Connection to gitlab.com closed.
```

The ssh server:

```
debug1: Remote protocol version 2.0, remote software version OpenSSH_7.9p1 Debian-10+deb10u2
debug1: compat_banner: match: OpenSSH_7.9p1 Debian-10+deb10u2 pat OpenSSH* compat 0x04000000
````

Host Key of the server:

```
gitlab.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf
```
Comment 1 Damien Miller 2021-04-30 13:20:14 AEST
Could you please attach a complete debug trace (ssh -vvv ...)?
Comment 2 Thomas Braun 2021-04-30 20:20:42 AEST
Created attachment 3505 [details]
stderr output
Comment 3 Thomas Braun 2021-04-30 20:21:01 AEST
Created attachment 3506 [details]
stdout output
Comment 4 Thomas Braun 2021-04-30 20:21:20 AEST
Done.
Comment 5 Damien Miller 2021-05-03 11:48:43 AEST
Are you able to test OpenSSH git head or otherwise apply commit ac31aa3c63 ? It adds some debugging that might be useful in figuring out what is going wrong.

Also a workaround: add

Host gitlab.com
    UpdateHostkeys no

to your ~/.ssh/config
Comment 6 Damien Miller 2021-05-03 12:03:47 AEST
Created attachment 3507 [details]
use old-style RSA signature algorithm for SSH_BUG_SIGTYPE servers

Please also try this patch
Comment 7 Thomas Braun 2021-05-04 01:28:42 AEST
Yes I should be able compile openssh HEAD. I presume we are talking about https://github.com/openssh/openssh-portable?

Do you think I can test that on linux as well or is that specific to Windows?
Comment 8 Thomas Braun 2021-05-11 23:43:45 AEST
Created attachment 3513 [details]
stderr with ac31aa3c63 applied
Comment 9 Thomas Braun 2021-05-11 23:44:11 AEST
Created attachment 3514 [details]
stdout with ac31aa3c63 applied
Comment 10 Thomas Braun 2021-05-12 00:00:33 AEST
I've applied the SSH_BUG_SIGTYPE fix but that did not solve the issue.

I also added the requested debug output with ac31aa3c63 applied.
Comment 11 Damien Miller 2021-05-14 13:35:42 AEST
> client_global_hostkeys_private_confirm: server gave bad signature for RSA key 0: error in libcrypto

hmm, this is not what I expected. This particular error can only occur during RSA verification here: https://github.com/openssh/openssh-portable/blob/e86968280e358e62649d268d41f698d64d0dc9fa/ssh-rsa.c#L429 and indicates an RSA decryption failure in OpenSSL libcrypto.

Moreover I can't reproduce the same problem with OpenSSH 7.9 sshd locally - the hostkey update signature function fine for RSA keys.

This makes me suspect that either gitlab.com is returning an incorrect signature, or OpenSSL libcrypto is failing to verify a good one on your platform.

I don't know much about how the ssh client in git-for-windows works. Is it built from Cygwin, Microsoft's OpenSSH port or something else?
Comment 12 Thomas Braun 2021-05-20 05:08:19 AEST
> I don't know much about how the ssh client in git-for-windows works. Is it built from Cygwin, Microsoft's OpenSSH port or something else?

It's basically built from cygwin. It's called MSYS which is a derivation of cygwin.

The sources are available at https://github.com/git-for-windows/MSYS2-packages/tree/main/openssh. It is not particular easy to build though.

Is there a way I can store the failing RSA key in a file?
Comment 13 Damien Miller 2021-05-20 11:43:37 AEST
Created attachment 3521 [details]
dump failed key and signature

This will log the failing key and signature.

You can convert the key to an OpenSSL PEM format key using something like:

ssh-keygen -ef /path/key.pub -m pem

Verifying the contents of the signature blob is more difficult. Some extra debug logging in ssh-rsa.c might be required there
Comment 14 Damien Miller 2021-05-20 12:05:12 AEST
Created attachment 3522 [details]
debug failed libcrypto call

This will dump the actual data passed to RSA_public_decrypt() and the detailed errors from libcrypto when it fails
Comment 15 Damien Miller 2021-07-02 14:51:01 AEST
Any update on this?
Comment 16 Thomas Braun 2021-07-15 06:46:44 AEST
Created attachment 3535 [details]
debug output with latest patches

Sorry for taking so long to respond.

Attached is the output generated with `ssh.exe -vv git@gitlab.com -i ~/.ssh/github_ed255519 2> output-with-debug-info.txt`.
Comment 17 Thomas Braun 2021-07-15 06:47:42 AEST
I've applied both the " dump failed key and signature" and the " dump failed key and signature" patches.
Comment 18 Damien Miller 2021-07-15 10:06:14 AEST
The debugging contains a signature from the server, being (hex encoded):

484a9f2d247575206758581a99945cc0964dcb38e83ec57204d10f3421180131677082cb4aaa90a0bd2df2927e40382903866677caf2553f152156a77fe8462ce20466a08ec530ee3be6f9780e39b9f112d98db389e225d2025ad0b2a27498b56f36ce322f03124f911f4bb92311d3870dbfb988b46898d6a7b94833a6af9c9eefab7c77ca082aba62161c79d7f73842681e8da68d4b527b27104701f5e74136028550ccca3f55a1c0cafa35be7afdda609712d5d278122977867c9d1925cfee89687950be9837e696a472f9cd92a9dd7afbf4eae25d225b497da87d24af99ead3302dfbbf2085d04a91277e850ebf46828da7e5b04a9938649fe0c94a240d42

I retrieved gitlab.com's rsa key. It's:

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsj2bNKTBSpIYDEGk9KxsGh3mySTRgMtXL583qmBpzeQ+jqCMRgBqB98u3z++J1sKlXHWfM9dyhSevkMwSbhoR8XIq/U0tCNyokEi/ueaBMCvbcTHhO7FcwzY92WK4Yt0aGROY5qX2UKSeOvuP4D6TPqKF1onrSzH9bx9XUf2lEdWT/ia1NEKjunUqu1xOB/StKDHMoX4/OKyIzuS0q/T1zOATthvasJFoPrAjkohTyaDUz2LN5JoH839hViyEG82yB+MjcFV5MU3N1l1QL3cVUCh93xSaua1N85qivl+siMkPGbO5xR/En4iEY6K2XPASUEMaieWVNTRCtJ4S8H+9

With these, I hacked up a small program to load the key and run the  libcrypto RSA_public_decrypt() operation that fails in your case.

It worked for me and yielded a decrypted signature:

decrypted: len=35
0000: 30 21 30 09 06 05 2b 0e 03 02 1a 05 00 04 14 59  0!0...+........Y
0016: 90 c1 b8 16 fd f3 aa a4 d8 a6 3f 94 e0 21 03 c5  ..........?..!..
0032: e4 c2 c7   

This is a structurally valid PKCS#1 1.5 rsa-sha1 padded hash.

So I think that something is wrong inside your libcrypto/OpenSSL
Comment 19 Darren Tucker 2021-07-15 11:03:12 AEST
(In reply to Damien Miller from comment #18)
[...]
> So I think that something is wrong inside your libcrypto/OpenSSL

If you built your own libcrypto, try running its self-tests (OpenSSL: "make test", LibreSSL: "make check") and see if those pass.
Comment 20 Thomas Braun 2021-07-16 00:59:13 AEST
Created attachment 3536 [details]
openssl test result

Thanks both.

I just rebuilt openssl and ran it's tests and all pass.

Just out of curiosity:
Why is the error I'm seeing only present when "UpdateHostKeys" is turned on? And why does the decryption error not influence my ability to connect to the server?
Comment 21 Thomas Braun 2021-07-16 02:52:04 AEST
@Damien Can you post your small program so that I can run it here as well?
Comment 22 Damien Miller 2021-07-16 10:07:47 AEST
Created attachment 3537 [details]
test "program"

This is what I used, I basically hacked it in to ssh-keygen.c. It's the opposite of pretty :)

You'll also need to repack the dumped signature into base64 and paste it in to the sshbuf_b64tod() call. I used something like:

$ python3
>>> h='484a9f2d24757...' # Line from RSA_public_decrypt: sig=...
>>> import base64
>>> b=base64.b16decode(h, True)
>>> base64.b64encode(b)
b'SEqfLSR1dS...'

As to why ssh works while this particular operation is failing while your ssh connection remains successful - it's probably because you're not using RSA for the regular key exchange signature, but Ed25519:

debug1: kex: host key algorithm: ssh-ed25519


If you try something like:

for x in rsa-sha2-512 rsa-sha2-256 ssh-rsa ; do ssh -oHostkeyAlgorithms=$x -oStrictHostkeyChecking=no -oUserKnownHostsFile=/tmp/gitlab git@gitlab.com ; done

Then you can exercise RSA (across its variants) in the signature path too
Comment 23 Damien Miller 2021-07-16 10:32:14 AEST
Created attachment 3538 [details]
Better RSA verification debugging

Actually, instead of messing around with python please replace the previous debugging diff with this one. It dumps the key in usable format and the signature blob in base64