Understanding SSH Certificate signatures

Damien Miller djm at mindrot.org
Wed Feb 10 10:38:29 AEDT 2021

On Mon, 8 Feb 2021, Digant Kasundra wrote:

> Hello OpenSSH community,
> I haven't found a good Rust library to verify that a presented OpenSSH
> public certificate is valid.  My plan is to compare the signature_key to my
> trusted CA certs and verify the signature in the user's public certificate.
> Here is what I tried but it isn't working:
> * create an openssl RSA public key using the n and e from the signature_key
> * decrypt the signature with that key to get the hash
> * create a hash from all the base64 bytes up to but not including the
> signature using SHA1

Current versions of OpenSSH use sha-256 for certificate signatures by
default, so that's one possile problem.

> * compare the hashes, but they do not match

Your approach seems reasonable. The certificate signature is made using
exactly the same rules and structure as other SSH signatures. Are you
following these? If so, then the only other possibility is that you are
including the wrong bytes in the hash :)

> To create my own hash, I'm skipping the opening text identifier in the
> cert, but using the "ssh-rsa-cert-v01 at openssh.com" string as part of the
> octet string.

The signed hash definitely includes this (and the four byte length before it)

> Am I on the right track?  If so, I'll give some details of what I'm doing
> so we can hopefully pinpoint where I'm going wrong.  (Or if someone knows a
> rust crate that actually verifies a certificate instead of just parsing it,
> that would be awesome!)

My advice is to take a copy of OpenSSH, insert a
sshbuf_dump_data(sshbuf_ptr(key->cert->certblob), signed_len, stderr)
in sshkey.c:cert_parse() right before the sshkey_verify() call and
compare what is you are including in your hash to what OpenSSH is.
I've never solved a signature verification bug without printf debugging :)


More information about the openssh-unix-dev mailing list