Question is simple:
What are the (private) key types and (their specification – format, syntax) accepted by current openSSH?
The vague answer "the keys generated by ssh-keygen
" is not accepted – I know it. They are called PEM with such headers (RSA, DSA, ECDSA variations):
-----BEGIN RSA PRIVATE KEY-----
The other format is described in PROTOCOL.key and is extension by openssh
. It is also used as a default for Ed25519
keys, as stated in manual and (regardless passphrase) marked with header:
-----BEGIN OPENSSH PRIVATE KEY-----
There are also legacy RSA1
keys that should be gone today with SSHv1 protocol, but can be identified by the header:
SSH PRIVATE KEY FILE FORMAT 1.1
Are there any others? I am searching for more verbose description of other keys. I didn't find it (so far) explicitly specified in any manual page nor in any RFC for SSH.
The bonus question (not needed to answer, but I would appreciate the insight):
What is the reason behind (
openssh
) decoding every dummy file and asking for a passphrase, even if it does not have the proper header?
Footnote: Question was originally posted on openssh-unix-dev list, but so far without any answer so I am trying this awesome community, if there is somebody able to answer it.
Best Answer
TL;DR
The most helpful comments from @forcefsck. Unfortunately he didn't fill the answer so I was unable to award the bounty. In short, the answer is PEM + RSA1 + new openSSH format which is described in the question and the main problem was with PEM.
The long one & Bonus
OpenSSH is using parser from openSSL (
PEM_read_bio_PrivateKey()
), which has the only return value for all the failures (NULL
) and if it fails, openSSH expects it was because of wrong passphrase.Without OpenSSL
I just tried to build OpenSSH without OpenSSL support (
--without-openssl
configure option) and the behaviour is "correct":Fix with OpenSSL
The other thing is how to fix it. The poke comes from
ERR_get_error()
function and their friends which should allow us to distinguish between different errors.Wrong passphrase errors
Reasons:
PEM_R_BAD_PASSWORD_READ
,PEM_R_BAD_BASE64_DECODE
,PEM_R_BAD_DECRYPT
.Parse error codes
or this:
Reason:
PEM_R_NO_START_LINE
,PEM_R_BAD_END_LINE
, but there might be more possibilities.Solution?
Adding some more checks for OpenSSL errors should give us an option to choose which error we want to mark as "format" error and which is "bad passphrase". This is located in function
sshkey_parse_private_pem_fileblob()
insshkey.c
on line around 3800.