bugzilla-daemon at mindrot.org
2025-Sep-28 14:27 UTC
[Bug 3869] New: Loading "only" an ssh certificate in ssh-agent with ssh-add unnecessarily loads the private key and always exits with an error even when successful
https://bugzilla.mindrot.org/show_bug.cgi?id=3869 Bug ID: 3869 Summary: Loading "only" an ssh certificate in ssh-agent with ssh-add unnecessarily loads the private key and always exits with an error even when successful Product: Portable OpenSSH Version: 10.0p2 Hardware: All OS: All Status: NEW Severity: minor Priority: P5 Component: ssh-agent Assignee: unassigned-bugs at mindrot.org Reporter: brendan at swiftspirit.co.za Technically the solution for this could be in one or both of `ssh-add` and `ssh-agent`. When `ssh-add`ing a key that has an accompanying certificate to the ssh-agent, the certificate is automatically added. When the certificate expires and the certificate *file* is replaced, ssh-agent is not aware of this and thus keeps a cached copy of the old expired certificate. The ssh client seems to automatically read the certificate from disk in this scenario, thus avoiding the issue for most users. I've come across this scenario because I am writing an application in golang that makes use of the ssh agent if it is available but it does not make use of the ssh client binary. I have thus had to write a workaround for this scenario as the agent passes the expired certificate to the application. My application then checks if there is a new non-expired certificate available on disk. In attempting to resolve this on the certificate renewal end, one could run `ssh-add -C ~/.ssh/id_ed25519` to add only the certificate. But, running this first tries to re-add the identity despite what the man page says: `-C When loading keys into or deleting keys from the agent, process certificates only and skip plain keys.` Because it tries to load the identity, it unnecessarily requires the passphrase when the identity is encrypted. The command does at least fail semi-gracefully. It fails to replace the identity and then successfully re-adds the certificate. It also exits with exit code 1, which could be misinterpreted as an error despite that the command technically succeeded. brendan at foo.local ~ % ssh-add -dC ~/.ssh/id_ed25519 Identity removed: /home/brendan/.ssh/id_ed25519-cert.pub ED25519-CERT (brendan at foo.local) brendan at foo.local ~ % ssh-add -C ~/.ssh/id_ed25519 Enter passphrase for /home/brendan/.ssh/id_ed25519: Could not add identity "/home/brendan/.ssh/id_ed25519": success Certificate added: /home/brendan/.ssh/id_ed25519-cert.pub (brendan at foo.local) 1 brendan at foo.local ~ % ssh-add -C ~/.ssh/id_ed25519 Enter passphrase for /home/brendan/.ssh/id_ed25519: Could not add identity "/home/brendan/.ssh/id_ed25519": success Certificate added: /home/brendan/.ssh/id_ed25519-cert.pub (brendan at foo.local) 1 brendan at foo.local ~ % I see three scenarios that would resolve the immediate problem: a) `ssh-add -C ~/.ssh/id_ed25519`, because of the `-C` parameter, should automatically know that the identity should not be loaded. It should skip the private key entirely and load only the renewed certificate. b) An alternative flag to explicitly allow you to "refresh" the certificate (though one could argue that's what `-C` is for) c) A change to ssh-agent that has it watch the certificate file for changes and automatically refresh the certificate when the cached version is expiring/expired. I believe that a) would be fixing a real bug, while c) would be a valuable enhancement. -- You are receiving this mail because: You are watching the assignee of the bug.
bugzilla-daemon at mindrot.org
2025-Sep-29 02:58 UTC
[Bug 3869] Loading "only" an ssh certificate in ssh-agent with ssh-add unnecessarily loads the private key and always exits with an error even when successful
https://bugzilla.mindrot.org/show_bug.cgi?id=3869 Damien Miller <djm at mindrot.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |djm at mindrot.org Status|NEW |RESOLVED Resolution|--- |WONTFIX --- Comment #1 from Damien Miller <djm at mindrot.org> --- Except for this spurious error:> Could not add identity "/home/brendan/.ssh/id_ed25519": successEverything you describe here is intended behaviour. ssh-agent does not monitor files for changes. It only receives keys when the user loads them via ssh-add. It *can't* monitor local files, as the keys being loaded may not even be on the same host as ssh-agent (consider agent forwarding). Sometimes there is no file to monitor, e.g. keys being loaded from standard input, from a PKCS#11 token or from a FIDO device. Likewise, loading a certificate *must* require the private key too. There are two reasons for this. The first reason is practical: ssh-agent is essentially a repository for private keys and, in ssh-agent's view, certificates are just another type of private key. The second reason has to do with security. If it is possible to load a certificate without the private key, then there is no proof that the user loading the certificate has *access* to the private key material that corresponds to that certificate. Relaxing this criteria would allow, for example, an attacker on a machine to which a user had forwarded their agent to load an unexpected certificate that could be used with a previously-loaded private key. Under some circumstances, this could be worse than the attacker having access to the agent at all. Sorry, we don't intend to change any of this. I will fix the spurious error message though. -- You are receiving this mail because: You are watching the assignee of the bug. You are watching someone on the CC list of the bug.
bugzilla-daemon at mindrot.org
2025-Sep-29 07:55 UTC
[Bug 3869] Loading "only" an ssh certificate in ssh-agent with ssh-add unnecessarily loads the private key and always exits with an error even when successful
https://bugzilla.mindrot.org/show_bug.cgi?id=3869 --- Comment #2 from Brendan Hide <brendan at swiftspirit.co.za> ---> If it is possible to load a certificate without the private key, then there is no proof that the user loading the certificate has *access* to the private key material that corresponds to that certificate.Perhaps I don't understand the security model well. If the agent has a certificate and the client tries to load a new one with a matching pubkey+signer/etc (and with a newer expiry date), I'm not sure it really matters that the client doesn't have access to the private key. As a parallel, cert issuers never have access to your private keys, only your public keys. -- You are receiving this mail because: You are watching the assignee of the bug. You are watching someone on the CC list of the bug.