How should SSHSIG/ssh-keygen handle signatures by a Certificate

Brian Candler b.candler at pobox.com
Fri Feb 10 20:10:04 AEDT 2023


On 10/02/2023 04:14, Paul Tagliamonte wrote:
> My questions going in:
>
>   1. Will it accept an SSH certificate at all?
>   2. If it does, will it accept the underlying Public Key too?
>   3. What happens if my principals in the SSHSIG principals file don't
>      match in the ssh certificate
>   4. What happens if the certificate is expired? SSHSIG has no
>      'time of signature', so how do we even know? Now?
>
> The answers according to OpenSSH 9.1 / git
>
>   1.   Yes!
>   2.   No!
>   3/4. No validation on the Certificate is done

You didn't provide the "-Y sign" commands that you used, but let me 
demonstrate using OpenSSH_9.2p1.  For testing I have:

~/.ssh/id_rsa
~/.ssh/id_rsa.pub
~/.ssh/id_rsa-cert.pub    # an expired certificate containing various 
principals, one of them is "brian at +nsrc"

I do not have the CA private key available locally - the certificate was 
signed using Hashicorp Vault - but I do have its public key.

As you described, plain signing works:

$ echo "hello" >hello
$ ssh-keygen -Y sign -f ~/.ssh/id_rsa.pub -n file hello
Signing file hello
Write signature to hello.sig
$ mv hello.sig hello.sig1
$ echo "dontcare $(cat ~/.ssh/id_rsa.pub)" >hello.allowed1
$ ssh-keygen -Y verify -f hello.allowed1 -n file -s hello.sig1 -I 
dontcare <hello
Good "file" signature for dontcare with RSA key 
SHA256:mVV81jWVCP/SDRFA7vRM/SDQniylCAcBoSERWyhAXEo

I think you probably tried to do a certificate signature creation and 
verification like this:

$ ssh-keygen -Y sign -f ~/.ssh/id_rsa-cert.pub -n file hello
Signing file hello
Write signature to hello.sig
$ mv hello.sig hello.sig2
$ echo "brian at +nsrc $(cat ~/.ssh/id_rsa.pub)" >hello.allowed2
$ ssh-keygen -Y verify -f hello.allowed2 -n file -s hello.sig2 -I 
brian at +nsrc <hello
Could not verify signature.

Note that the *signing* process was successful.  This implies that it 
was using the private key id_rsa to make the signature (since the CA's 
private key is nowhere).

Note also that the second signature is about twice the size of the 
first, although both have a single "BEGIN SSH SIGNATURE" block:

$ ls -l hello.sig1 hello.sig2
-rw-r--r--  1 brian  staff   866 10 Feb 08:30 hello.sig1
-rw-r--r--  1 brian  staff  1653 10 Feb 08:42 hello.sig2

In other words, it's a chain. You need to verify it using the CA's 
public key:

$ echo "brian at +nsrc *cert-authority $(cat ca.pub)*" >hello.allowed3
$ ssh-keygen -Y verify -f hello.allowed3 -n file -s hello.sig2 -I 
brian at +nsrc <hello
hello.allowed3:1: certificate not authorized: Certificate invalid: expired
Could not verify signature.
$ ssh-keygen -Y match-principals -f hello.allowed3 -n file -s hello.sig2 
-I brian at +nsrc <hello
brian at +nsrc

To summarize, I believe the following is true:

- to verify a detached signature made using a certificate, you must 
provide the public key of the certificate authority which originally 
signed that certificate
- the time validity of the parent certificate is already being verified, 
without any code patches required

I guess it might be more user friendly not to allow signing with an 
expired or not-yet-valid certificate, or at least to warn if you do this.

Regarding your other question:

  "3. What happens if my principals in the SSHSIG principals file don't match in the ssh certificate"

The answer is the manpage under "ALLOWED SIGNERS":

      When verifying signatures made by certificates, the expected 
principal name must match
      both the principals pattern in the allowed signers file and the 
principals embedded in
      the certificate itself.

Regards,

Brian.


More information about the openssh-unix-dev mailing list