In August, I wrote about replacing security/pam-ssh-agent-auth with security/pam_ssh_agent. The old module is abandoned and deprecated. The new one, pam-ssh-agent, was a drop-in replacement in /usr/local/etc/pam.d/sudo:
auth sufficient /usr/local/lib/pam_ssh_agent.so file=~/.ssh/authorized_keys
I saw no problems with it, except when this one case.
The symptom
With an ssh-rsa key, sudo fell through to the next PAM entry, and this showed up in the logs:
pam_ssh_agent(sudo:auth): authorized keys from '/usr/home/foo/.ssh/authorized_keys' pam_ssh_agent(sudo:auth): signature error: cryptographic error pam_ssh_agent(sudo:auth): pam_ssh_agent(sudo:auth): Caused by: pam_ssh_agent(sudo:auth): cryptographic error
I changed to an ssh-ed25519 key. No problems.
I wasn’t asking for a fix, merely confirmation that RSA was supported. I opened an issue and asked.
The investigation
nresare, the maintainer, confirmed RSA is expected to work, and showed a passing test with a freshly generated key. They also pointed me at the authenticator example, which tests the core of the crate without building and installing a PAM module:
cargo run --example authenticator test.pub
ssr-zna first found a separate bug with RSA certificates, and submitted a fix for it. They then reproduced my exact error with a plain 1024-bit key: the ssh-key crate has a minimum RSA key size of 2048 bits, and anything smaller fails with that same unhelpful cryptographic error.
That got me checking my own key:
# ssh-keygen -l -f id_rsa.pub 4098 SHA256:WNCkh3Ssk58Gs/idsblOkRnKokENzR581bIuphhR+oc foo@myhost (RSA)
4098. Not 4096.
I have been here before
Back in 2013, I wrote about one StartCOM cert that worked, and the other that did not. That too was key size:
Server public key is 4098 bit
The cause was simple: I thought 4098 was a power of 2. It isn’t. 212 is 4096. For a while, I used 4098 everywhere I meant 4096. This key’s public half is dated December 2013, right in the middle of that period, and it has been quietly working ever since.
Why 4098 fails
So small keys fail. Why would a bigger key fail?
pam-ssh-agent uses the ssh-key crate (0.6), which uses the rsa crate (0.9) to validate RSA public keys. That version of rsa has a maximum:
pub const MAX_SIZE: usize = 4096;
Any modulus larger than 4096 bits is rejected, and ssh-key turns that into the same generic Error::Crypto used for keys under 2048 bits. For pam-ssh-agent, an RSA key must be between 2048 and 4096 bits. Mine was 2 bits too big.
The fix
I created a standard 4096-bit key, under a new name so I could keep the old one around:
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa_4096 ssh-add ~/.ssh/id_rsa_4096
I added id_rsa_4096.pub to ~/.ssh/authorized_keys, and sudo worked as advertised.
pam-ssh-agent 1.0.0
nresare has just released pam-ssh-agent 1.0.0 (which got me back onto this topic to track down the cause). Among other things, it includes the fix for RSA certificates. It still builds against the same rsa 0.9 series, so a 4098-bit key will still fail. I’m going to migrate this user from that odd-sizes RSA key.
Lessons
- Check your key sizes. ssh-keygen -l -f shows the bit count first. An odd number like 4098 means trouble is waiting.
- cryptographic error can mean "I don't like the size of this key", in either direction.
- The authenticator example in pam-ssh-agent is a quick way to test a key without involving PAM.
- Or use ed25519. That key worked the whole time.
Thanks to nresare and ssr-zna for working through this with me.