Bug 2550 - ssh can't use an in-memory-only certificate that doesn't also have another in-memory private key
Summary: ssh can't use an in-memory-only certificate that doesn't also have another in...
Status: CLOSED FIXED
Alias: None
Product: Portable OpenSSH
Classification: Unclassified
Component: ssh (show other bugs)
Version: 7.2p1
Hardware: amd64 Linux
: P5 enhancement
Assignee: Damien Miller
URL:
Keywords:
Depends on:
Blocks: V_7_3
  Show dependency treegraph
 
Reported: 2016-03-11 10:12 AEDT by Peter Moody
Modified: 2016-08-02 10:41 AEST (History)
2 users (show)

See Also:


Attachments
don't disregard already-certified keys (447 bytes, patch)
2016-03-12 14:34 AEDT, Damien Miller
no flags Details | Diff
attempt 2: try cert if no separate key matches (545 bytes, patch)
2016-03-13 05:51 AEDT, Damien Miller
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Peter Moody 2016-03-11 10:12:07 AEDT
I have an ssh certificate authority setup where a user can ssh to it (forwarding their agent) and when they authenticate, the CA generates a new ssh cert and adds it directly to their ssh-agent. the cert then shows up on their agent like so

$ ssh-add -l
2048 85:0d:c1:cc:50:6b:24:93:74:33:61:88:00:ab:88:dd [Valid until Fri 11 Mar 2016 18:10 UTC, Version 2] (RSA-CERT)

the cert has the appropriate private key embedded in it, but the private key isn't added separately.

prior to commit 4e44a79a07d4b88b6a4e5e8c1bed5f58c841b1b8, just having the cert on the user's agent process worked as expected. After that commit, the user needs both the private and the cert (also with the private key) loaded together to work.

if I try to use just the cert after this commit, I see:

debug1: Server accepts key: pkalg ssh-rsa-cert-v01@openssh.com blen 2769
debug2: input_userauth_pk_ok: fp SHA256:XiFOO+XzZ0m/aWzkQLgxVFI2HJV3abWpNyuIhcEYKuc
debug3: sign_and_send_pubkey: RSA-CERT SHA256:XiFOO+XzZ0m/aWzkQLgxVFI2HJV3abWpNyuIhcEYKuc
debug1: sign_and_send_pubkey: no private key for certificate "[Valid until Fri 11 Mar 2016 18:10 UTC, Version 2]"

if I modify the ca to add both the cert (with private key) and the private key, so my agent looks like this:

$ ./ssh-add -l
2048 SHA256:nZkpX+sy5o/9r7H5JSilHN6YmQMAipZphtZHgVNA3Gs [Valid until Fri 11 Mar 2016 19:08 UTC, Version 2] (RSA)
2048 SHA256:nZkpX+sy5o/9r7H5JSilHN6YmQMAipZphtZHgVNA3Gs [Valid until Fri 11 Mar 2016 19:08 UTC, Version 2] (RSA-CERT)

and now I can use those creds to ssh

debug1: Server accepts key: pkalg ssh-rsa-cert-v01@openssh.com blen 2769
debug2: input_userauth_pk_ok: fp SHA256:nZkpX+sy5o/9r7H5JSilHN6YmQMAipZphtZHgVNA3Gs
debug3: sign_and_send_pubkey: RSA-CERT SHA256:nZkpX+sy5o/9r7H5JSilHN6YmQMAipZphtZHgVNA3Gs
debug2: sign_and_send_pubkey: using private key "[Valid until Fri 11 Mar 2016 19:08 UTC, Version 2]" from agent for certificate


My c-chops have grown dull in the last 10 months, but I can work up a patch for this. It seems like, unless there's some particular reason not to do this, the 

 if (key_is_cert(id->key)) {
   ...
 }

could also check the private key on the cert .. ? I'm not sure how that works with a remote ssh client accessing a forwarded agent.
Comment 1 Damien Miller 2016-03-12 14:34:57 AEDT
Created attachment 2798 [details]
don't disregard already-certified keys

I think this might fix it.
Comment 2 Peter Moody 2016-03-12 15:40:42 AEDT
nope :(

this works tho:

   if (sshkey_equal_public(id->key, private_id->key) &&
       id == private_id) {
  
I added a 

   debug2("id %p (id %d), private id %p (id %d)", id, id->key->type, private_id, private_id->key->type);

to the match, and this is the -vvv output


debug1: Server accepts key: pkalg ssh-rsa-cert-v01@openssh.com blen 2769
debug2: input_userauth_pk_ok: fp SHA256:5U6bsClkHE1aWyFRkKbynEtiK8QD3/Nf3cxeUSR+BCA
debug3: sign_and_send_pubkey: RSA-CERT SHA256:5U6bsClkHE1aWyFRkKbynEtiK8QD3/Nf3cxeUSR+BCA
debug2: id 0x7fab613164d0 (id 5), private id 0x7fab613164d0 (id 5)
debug2: sign_and_send_pubkey: using private key "[Valid until Sat 12 Mar 2016 11:55 UTC, Version 2]" from agent for certificate
debug3: send packet: type 50
debug3: receive packet: type 52
debug1: Authentication succeeded (publickey).

this is my ssh-agent

pmoody@pmoody (148) 04:39 (.git 7.2p1) /home/pmoody/src/openssh-portable
$ ./ssh-add -l
2048 SHA256:5U6bsClkHE1aWyFRkKbynEtiK8QD3/Nf3cxeUSR+BCA [Valid until Sat 12 Mar 2016 11:55 UTC, Version 2] (RSA-CERT)

pmoody@pmoody (0) 04:39 (.git 7.2p1) /home/pmoody/src/openssh-portable
$
Comment 3 Peter Moody 2016-03-12 15:51:38 AEDT
sorry, I forgot to include this. here was the output with your patch

debug1: Offering RSA-CERT public key: [Valid until Sat 12 Mar 2016 11:55 UTC, Version 2]
debug3: send_pubkey_test
debug3: send packet: type 50
debug2: we sent a publickey packet, wait for reply
debug3: receive packet: type 60
debug1: Server accepts key: pkalg ssh-rsa-cert-v01@openssh.com blen 2769
debug2: input_userauth_pk_ok: fp SHA256:5U6bsClkHE1aWyFRkKbynEtiK8QD3/Nf3cxeUSR+BCA
debug3: sign_and_send_pubkey: RSA-CERT SHA256:5U6bsClkHE1aWyFRkKbynEtiK8QD3/Nf3cxeUSR+BCA
debug1: sign_and_send_pubkey: no private key for certificate "[Valid until Sat 12 Mar 2016 11:55 UTC, Version 2]"
debug1: Trying private key: /home/pmoody/.ssh/id_rsa
debug3: no such identity: /home/pmoody/.ssh/id_rsa: No such file or directory
debug1: Trying private key: /home/pmoody/.ssh/id_dsa
debug3: no such identity: /home/pmoody/.ssh/id_dsa: No such file or directory
debug1: Trying private key: /home/pmoody/.ssh/id_ecdsa
debug3: no such identity: /home/pmoody/.ssh/id_ecdsa: No such file or directory
debug1: Trying private key: /home/pmoody/.ssh/id_ed25519
debug3: no such identity: /home/pmoody/.ssh/id_ed25519: No such file or directory
debug2: we did not send a packet, disable method
debug1: No more authentication methods to try.
Permission denied (publickey).
Comment 4 Damien Miller 2016-03-13 05:51:27 AEDT
Created attachment 2799 [details]
attempt 2: try cert if no separate key matches

Try this one instead - it just falls back to using the certificate directly if no other private key matches.
Comment 5 Peter Moody 2016-03-13 07:03:04 AEDT
that works, thanks!
Comment 6 Damien Miller 2016-03-15 03:24:34 AEDT
Committed, this will be in OpenSSH 7.3 - thanks!

commit c38905ba391434834da86abfc988a2b8b9b62477
Author: djm@openbsd.org <djm@openbsd.org>
Date:   Mon Mar 14 16:20:54 2016 +0000

    upstream commit
    
    unbreak authentication using lone certificate keys in
     ssh-agent: when attempting pubkey auth with a certificate, if no separate
     private key is found among the keys then try with the certificate key itself.
    
    bz#2550 reported by Peter Moody
    
    Upstream-ID: f939cd76d68e6a9a3d1711b5a943d6ed1e623966
Comment 7 Colin Watson 2016-04-28 10:50:25 AEST
It might not hurt to update the comment above that block too, which in master still reads:

        /*
         * If the key is an certificate, try to find a matching private key
         * and use it to complete the signature.
         * If no such private key exists, return failure and continue with
         * other methods of authentication.
         */
Comment 8 Damien Miller 2016-04-29 19:20:50 AEST
Good point, Colin - fixed.
Comment 9 Damien Miller 2016-08-02 10:41:44 AEST
Close all resolved bugs after 7.3p1 release