Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for sha2 rsa keys in local signer #138

Closed
wants to merge 1 commit into from

Conversation

pablo-ruth
Copy link
Contributor

Fix #133

@pablo-ruth pablo-ruth force-pushed the ssh-rsa-cert-v01-deprecation branch from e1518bf to 8e79254 Compare August 18, 2022 16:03
@codeclimate
Copy link

codeclimate bot commented Aug 18, 2022

Code Climate has analyzed commit 8e79254 and detected 0 issues on this pull request.

View more on Code Climate.

@pablo-ruth
Copy link
Contributor Author

Hello @tierpod,

I found that certificates are already signed with SHA-2 algorithm by default (https://cs.opensource.google/go/x/crypto/+/bc19a97f:ssh/certs.go;l=443) and it's the marshaling of it that apply the wrong "identifier" to it. I added a MarshalCertificate function with the missing detection.

Can you test if it resolves your issue #133 ?

@tierpod
Copy link
Contributor

tierpod commented Aug 19, 2022

Hello @pablo-ruth ! Thank you for your investigation. I tested this branch and unfortunately it doesn't fix my problem.

If I print certificate after client.Sign function call, I see rsa-sha2-512-cert-v01@openssh.com at the beginning of the certificate string, but certificate type from ssh-keygen command is still ssh-rsa-cert-v01@openssh.com:

ssh-keygen -Lf ./id_rsa-cert.pub
        Type: ssh-rsa-cert-v01@openssh.com user certificate

and I still cannot use this certificate against Centos 7 server without ssh -o PubkeyAcceptedKeyTypes=+ssh-rsa-cert-v01@openssh.com ...:

# from server
debug1: userauth_pubkey: test whether pkalg/pkblob are acceptable for RSA ...
debug3: mm_answer_keyallowed: key 0x55c819ccdca0 is not allowed
Failed publickey for ...

# from client
Offering public key ... RSA-CERT ...
send_pubkey_test: no mutual signature algorithm

Server OS is Centos 7.9, openssh version is SSH-2.0-OpenSSH_7.4

Client OS is Fedora 36, openssh version is OpenSSH_8.8p1, OpenSSL 3.0.5 5 Jul 2022.

I expected to see:

ssh-keygen -Lf ./id_rsa-cert.pub
        Type: rsa-sha2-512-cert-v01@openssh.com user certificate

to fix my problem, but here I found the comment:

By the way, "CertAlgoRSASHA256v01 and CertAlgoRSASHA512v01 can't appear as a Certificate.Type (or PublicKey.Type)" doesn't mean they can't be used for signing, but means that the certificate type will still be CertAlgoRSAv01, the same way as a KeyAlgoRSA public key generates KeyAlgoRSASHA256/512 signatures.

Sorry, I'm confused about it, maybe my problem is not connected with original issue.

@pablo-ruth
Copy link
Contributor Author

Ok thanks for your test, and you're right it's confusing ^^

So to try to better understand the problem I reproduce it without signmykey, using only "official" openssh tools (ssh-keygen). I used a Centos 7 with openssh 7.4 as a server, and a Fedora 36 with openssh 8.8 as a client.

I generate an RSA SSH Certificate Authority:

[root@9556493260ae build]# ssh-keygen -t rsa -f ~/.ssh/ca_user_key
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/ca_user_key
Your public key has been saved in /root/.ssh/ca_user_key.pub
The key fingerprint is:
SHA256:anFqwSNF8mJXcUF8N52u4zkz94YUdGoEp13tCe9F5VY root@9556493260ae
The key's randomart image is:
+---[RSA 3072]----+
|    . . o++.....E|
|     + . .. .==+*|
|    o +    ..+=*+|
|   . =        +=o|
|    . = S    .o..|
|     . B     o.. |
|      =     ..o. |
|     o       *...|
|              =.o|
+----[SHA256]-----+

I generate a "client" key pair:

[root@9556493260ae build]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa
Your public key has been saved in /root/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:arWwIAGWfRCQYnhuJmEQkJiHnPF50sKFOAgppaac5Nc root@9556493260ae
The key's randomart image is:
+---[RSA 3072]----+
|#@Xo+.           |
|&%=o+.           |
|*Bo*.o           |
|B =.=            |
|.B...E. S        |
|  .. . = .       |
|      + .        |
|     .           |
|                 |
+----[SHA256]-----+

I sign the client public key with the certificate authority:

[root@9556493260ae build]# ssh-keygen -n pablo -s ~/.ssh/ca_user_key -I test_id ~/.ssh/id_rsa.pub 
Signed user key /root/.ssh/id_rsa-cert.pub: id "test_id" serial 0 for pablo valid forever

I setup the CA public key on my remote Centos 7 server and I test to connect to it:

# ssh pablo@myremoteserver

...
debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic,password                                                                                                                                                                                        
debug1: Offering public key: /root/.ssh/id_rsa RSA-CERT SHA256:uLNU9oWTo21sx1PfCslwpWh7pDIMDWuI8ZenNYZMF3o                                                                                                                                                                        
debug1: send_pubkey_test: no mutual signature algorithm
...

So I reproduce your issue. And like you if I add -o PubkeyAcceptedKeyTypes=+ssh-rsa-cert-v01@openssh.com or if I change the system crypto policies `update-crypto-policies --set LEGACY", I can connect.

The confusing thing is that I use "up-to-date" ssh-keygen to generate the certificate, but if dump the cert file, it's still in ssh-rsa-cert-v01@openssh.com format:

[root@9556493260ae build]# cat /root/.ssh/id_rsa-cert.pub 
ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgvT0wOJd6D83EZ5Tprt4eaxOLW4RH9pz6q/816m6cevgAAAADAQABAAABgQDS2/ajz0GXbTixNaMbir7B3Xls5l4QXBF9/tNozEFhZXG8e3j/JKOHNJ9MMLs8/7gf1BhbnvieVLVHCoyhDWxHK0d4XkNRan7c1s/0R9LIEQOpHMfk1Lw7Q3RLngU8dAfuigPyjzHBci4qxEL9G4DtnfRGaMXxWvaCDFuRpKJusZ4dS9nDIV25nmUraL5t2EwEoj6ocpuOJgzNa20NvpJV2eCXlHlTWGxDbOCUFnxzdy0dknhWz5jCbWlo/ubW+r595ranV9smA+goXlgN+wM+VxGvp9kdPJ7oLeecxoeVqLnpCV7nj6SjPS4ojWyYnFSZMyTs20hJlgwJlWWBUYaDfWNDye1Vmbqo8MzqoGSfwqDj2vohJDZTSCSu1RoyxT3wxkJ7bqfIR+ZTXSdk50/IBPKCXycjGEArAvCRkTwhH1/6DTu2V7VamWhTAN5P/rKtGQd3+kICV4q1srirsa5V9onx9aUbuW1DRRFqmE7CCAiYLg4gHjPRFqb1EQqGyCEAAAAAAAAAAAAAAAEAAAAHdGVzdF9pZAAAAAkAAAAFcGFibG8AAAAAAAAAAP//////////AAAAAAAAAIIAAAAVcGVybWl0LVgxMS1mb3J3YXJkaW5nAAAAAAAAABdwZXJtaXQtYWdlbnQtZm9yd2FyZGluZwAAAAAAAAAWcGVybWl0LXBvcnQtZm9yd2FyZGluZwAAAAAAAAAKcGVybWl0LXB0eQAAAAAAAAAOcGVybWl0LXVzZXItcmMAAAAAAAAAAAAAAZcAAAAHc3NoLXJzYQAAAAMBAAEAAAGBAL31VqlEfmObcccO164mLhjYPzIA0+S4b/fs8KExcu8xL50gI1MZvbUhyEaZMdOqtPyzuqR0mPLMKRy7im9dHzrSLPc9Zz1g5/hI939XtDsysLd9W8TUs153GZOlROtDUs2/Hg754+SzsTVrFHe6iLc4SAwarlSxsTS03vuCr1qIqoSF2aevduq4WfpUXA628MzoFy2ZjhTZVBAqR3eihWwUAssvJ5MOK2gg3I5MyLXFDrZP1+vDQeAJABaSGDujpncYbsVegR2zdUGJRWDnmV57i/rE9I0YpCnCCe/MhxPhpO4sggyXYryZAjMZIpSJEItGPvuuqEFVQ9nL038LslMn4X+zIZdF035o0flA3MgkOs0GtLItRZajKkCrC4DaEZ2VS7A7eR9uMnw32Cq/FAxLP5ZtqF3qGkMFKwfjk5BG3SPhx9tMmxFJ7QJs9uXqhov0jJbFG/4NvPZTm/22oQuam7EC4y930LwwNyXbGQblkSLqYEOe6EaW53GYg0qCFwAAAZQAAAAMcnNhLXNoYTItNTEyAAABgKJinKmehk2OvTE9NyKLobjn0yQfM0cWBibKXG4oyqjAQbkjIp0cgOTJ2/RjTjbJxmAgJMTGxDBe81Q/ttrXg5dYd33PjjrxezcPndfswwoNG64rCgIB2Xoch3ngjB5GB7ZN6QZJ79dxKacFnaldgbisaCx/FCtQ7DkOTN9sBmNIo2liZIfhvxNVAlBo7/mhKtaJXDbSpQB06GFlSLyJTEKEp/aFGwnx7s/3ihincKzm7G0oz8Imn2f+HGdGY5trPlzPLuGp3fihBgqQZ1WshdpX9eaem6wTPF0tAiI1yc/jD+6IFfrxnUjy0ycJKkCUq6Hjg7NkRDhlnoZtu7VfKTT7hAm7nh8V9MQRpQdbYufNFkiU55iDGjKD52ZcwVvfqk/F0YKBEA33COXOYT8/HyKG0FCNDGAxqe0i7n6LWFIQEzdGAZZG9N3VTbcUlUoyi7NveXk6lZeIWmSdHCjS7I8HnlbUQo064cyDHFLwakz2mBRDHL8mL6cUQ3k1iJQ9Uw== root@9556493260ae

I tried to generate the certificate with multiple options, -t ssh-rsa, -t rsa-sha2-512, and the cert is always stored in ssh-rsa-cert-v01@openssh.com format...

So I'm not sure it's possible to generate a certificate in a "sha-2" format with OpenSSH tools, and so I don't know what it should look like.

@HammerZ3it HammerZ3it mentioned this pull request Aug 19, 2022
@tierpod
Copy link
Contributor

tierpod commented Aug 19, 2022

I appreciate your job. As I see, it may be a problem with openssh client:

  • this thread looks similar

  • here is some interesting details, especially

    OpenSSH client uses different signature based on remote server version.

or with openssh server, something about server-sig-algs extension:

I can indirectly confirm this. The same ssh client, the same certificate, 3 different servers:

# Centos 7, enabled PubkeyAcceptedKeyTypes=+ssh-rsa-cert-v01@openssh.com
debug1: kex_input_ext_info: server-sig-algs=<rsa-sha2-256,rsa-sha2-512>
debug3: sign_and_send_pubkey: signing using ssh-rsa-cert-v01@openssh.com SHA256:...

# OL8
debug1: kex_input_ext_info: server-sig-algs=<ssh-ed25519,ssh-rsa,rsa-sha2-256,rsa-sha2-512,ssh-dss,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521>
debug3: sign_and_send_pubkey: signing using rsa-sha2-512-cert-v01@openssh.com SHA256:...

# OL9
debug1: kex_input_ext_info: server-sig-algs=<ssh-ed25519,sk-ssh-ed25519@openssh.com,ssh-rsa,rsa-sha2-256,rsa-sha2-512,ssh-dss,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,sk-ecdsa-sha2-nistp256@openssh.com,webauthn-sk-ecdsa-sha2-nistp256@openssh.com>
debug3: sign_and_send_pubkey: signing using rsa-sha2-512-cert-v01@openssh.com SHA256:...

So, I think, there is nothing we can do about it. The best choice is to generate new ECDSA or ED25519 keys

Even if the CA is an RSA key, you can sign ECDSA or ED25519 keys so you get ECDSA/ED25519 certs which allow you to work around the issue without changing anything server-side

As for ssh-keygen Type output, it looks like it's OK that it is the same for any rsa type.

@tierpod
Copy link
Contributor

tierpod commented Aug 19, 2022

To summarize:

Certificate type ssh-rsa-cert-v01@openssh.com is like a container. Real sign algorithm can be sha1 (deprecated), sha2-256, and sha2-512 (still valid).

The same is for ssh keys: ssh-rsa is like a container. Real algorithm can be sha1 (deprecated), sha2-256, sha2-512

And considering this, we shouldn't show depreciation warning for ssh-rsa-cert-v01@openssh.com type. And my first issue has wrong title 😄

@pablo-ruth
Copy link
Contributor Author

Good finds! It's definitely clearer now :) So the problem arises when we have a "buggy" openssh client/server combination, and it's not a problem with the ssh-rsa cert container, thereby I'll close this PR since it creates a cert file with a bad format.

You're right we shouldn't show a deprecation warning about the container format, but as this problem seems to be more and more frequent, and hard to debug for the end user, I think that replacing it with a warning when signing an "rsa" key should be helpful. Displaying the warning when signmykey signed only "rsa" keys (saying that you should generate a ssh keypair with another algorithm) feels like a good compromise. I'll open a new PR for that.

@pablo-ruth pablo-ruth closed this Aug 21, 2022
@pablo-ruth pablo-ruth deleted the ssh-rsa-cert-v01-deprecation branch August 21, 2022 20:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Certificate type is set to ssh-rsa-cert-v01@openssh.com which is deprecated in new openssh
2 participants