foxboron / ssh-tpm-agent Goto Github PK
View Code? Open in Web Editor NEW:computer: :key: ssh-agent for TPMs
License: MIT License
:computer: :key: ssh-agent for TPMs
License: MIT License
ssh-tpm-keygen
fails to import a nistp384 key (created using ssh-keygen -t ecdsa -b 384
).
$ ssh-tpm-keygen --import ~/.ssh/id_ecdsa
Sealing an existing public/private ecdsa key pair.
/home/username/.ssh/id_ecdsa.pub already exists.
Overwrite (y/n)?y
Enter pin (empty for no pin):
Confirm pin:
panic: math/big: buffer too small to fit value
goroutine 1 [running]:
math/big.nat.bytes(...)
/usr/lib/go/src/math/big/nat.go:1318
math/big.(*Int).FillBytes(0xc00002e860?, {0xc000022360?, 0x20?, 0x20?})
/usr/lib/go/src/math/big/int.go:540 +0xec
github.com/foxboron/ssh-tpm-agent/key.ImportKey({0x5647fc58cbc8?, 0xc00002c200}, {0x5647fc577440?, 0xc00011fd58?}, {0x0, 0x0, 0x0}, {0xc000014520, 0xd, 0x10})
/build/ssh-tpm-agent-git/src/ssh-tpm-agent.git/key/key.go:392 +0x165
main.main()
/build/ssh-tpm-agent-git/src/ssh-tpm-agent.git/cmd/ssh-tpm-keygen/main.go:309 +0xd55
Using ssh-tpm-agent-git 0.2.0.r0.25e8edb-1 from AUR.
everything seems to work ok but when I restart sshd:
Dec 10 01:08:32 host systemd[1]: Starting OpenBSD Secure Shell server...
Dec 10 01:08:32 host sshd[24703]: Unable to load host key "/etc/ssh/ssh_tpm_host_ecdsa_key.pub": error in libcrypto
Dec 10 01:08:32 host sshd[24703]: Unable to load host key "/etc/ssh/ssh_tpm_host_rsa_key.pub": error in libcrypto
Dec 10 01:08:32 host sshd[24704]: Unable to load host key "/etc/ssh/ssh_tpm_host_ecdsa_key.pub": error in libcrypto
Dec 10 01:08:32 host sshd[24704]: Unable to load host key "/etc/ssh/ssh_tpm_host_rsa_key.pub": error in libcrypto
Dec 10 01:08:32 host sshd[24704]: Server listening on 0.0.0.0 port 22.
Dec 10 01:08:32 host sshd[24704]: Server listening on :: port 22.
Dec 10 01:08:32 host systemd[1]: Started OpenBSD Secure Shell server.
Went overtime and ran out of time to get ssh-tpm-agent working.
Mentioned this in #24:
... level=DEBUG msg="%s not a TPM sealed key: %v\n" /r/c/ssh/hh-8192_ecdsa.tpm="tpm-ssh: unsupported key type \"TPM EC PRIVATE KEY\"
^ fixed this by generating a key using trunk, not v0.1.0
Now:
$ ssh-tpm-keygen
[---]
ssh config:
Match OriginalHost github.com
IdentityAgent /run/user/1000/ssh-tpm-agent.sock
IdentityFile /r/c/ssh/hh-8192_ecdsa.tpm
IdentitiesOnly yes
$ ssh [email protected]
...
Load key "/r/c/ssh/hh-8192_ecdsa.tpm": error in libcrypto
Oct 14 17:03:20 hh-8192 ssh-tpm-agent[1984892]: time=2023-10-14T17:03:20.844+03:00 level=INFO msg="agent 25: agent: not implemented: \"[email protected]\""
This happens with RSA key as well.
If an absolute path is specified for ssh-tpm-keygen -f
, it becomes a relative path under ~/.ssh/
:
$ ssh-tpm-keygen -b 256 -f /tmp/ec
Generating a sealed public/private ecdsa key pair.
Enter file in which to save the key (/home/grawity/.ssh/tmp/ec):
Docs say that ECDSA P-256 is the default if neither -t
nor -b
is not specified, but that doesn't seem to be the case:
$ ssh-tpm-keygen
2024/02/26 11:12:10 invalid ecdsa key length: TPM does not support 0 bits
$ ssh-tpm-keygen -t ecdsa
2024/02/26 11:16:39 invalid ecdsa key length: TPM does not support 0 bits
Specifying -t rsa
without -b
seems to correctly generate a 2048-bit RSA key.
It could be nice to support binding a key to the state of user-selectable PCRs at creation time, e.g. to restrict keys to be used only with some sort of verified boot. This can indirectly be achieved by storing the .tpm
file on a filesystem backed by a LUKS partition which itself is then bound to PCR state, but for unencrypted systems it might still be nice to directly support this. Also, the .tpm
files could theoretically be leaked into an unverified boot session and then used with incorrect PCR state, natively binding the key within the TPM would mitigate this.
I have an ansible playbook that adds an ssh key to the agent via stdin that fails with the ssh tpm agent. The ssh tpm agent is running with forwarding to another ssh agent, changing SSH_AUTH_SOCK
to that agent and the ansible playbook works.
The playbook looks like this
- name: Add ssh key to ssh agent
hosts: all
serial: 1
gather_facts: false
tasks:
- name: Read ansible ssh key
community.hashi_vault.vault_read:
url: "{{ vault.url }}"
path: secret/SOME_PATH
register: vault_ansible_data
no_log: true
delegate_to: localhost
- name: Add ssh key to ssh agent
ansible.builtin.command:
cmd: "ssh-add -"
stdin: '{{ vault_ansible_data["data"]["data"]["ssh_private_key"] }}'
no_log: true
changed_when: false
delegate_to: localhost
Error message from ansible is
Could not add identity \"(stdin)\": agent refused operation"
Symptom: agent 13: failed getting handle: TPM_RC_INTEGRITY (parameter 1): integrity check failed
Cause: Generated key on another machine, can't use it on this machine. OR TPM state got flushed by an update.
I'm struggling to picture the UX on how we should handle multiple keys.
ssh-agent
is not really made for key creating this way, so there needs to be a secondary control thing for this.
Running Arch Linux, installed ssh-tpm-agent via pacman
I am able to use this successfully without PIN.
However, with a ssh key with a PIN, I try to clone a private, git repo, ssh-tpm-agent throws this error:
agent 13: pinentry: unexpected response: \"S ERROR curses.isatty 83918950 \"
This problem occured (after a while):
2023/08/11 17:43:44 failed getting list from agent: agent: client error: write unix @->/run/user/1000/gnupg/S.gpg-agent.ssh: write: broken pipe
2023/08/11 17:43:44 failed getting Signers from agent: &{%!f(string=agent: client error: write unix @->/run/user/1000/gnupg/S.gpg-agent.ssh: write: broken pipe)}
2023/08/11 18:32:04 failed getting list from agent: agent: client error: write unix @->/run/user/1000/gnupg/S.gpg-agent.ssh: write: broken pipe
2023/08/11 18:32:47 failed getting list from agent: agent: client error: write unix @->/run/user/1000/gnupg/S.gpg-agent.ssh: write: broken pipe
systemctl --user restart ssh-tpm-agent
, the problem was resolvedUser systemd-unit:
[Unit]
Description=A ssh-agent compatible agent that support TPM keys
Documentation=https://github.com/Foxboron/ssh-tpm-agent
[Service]
ExecStart=/home/user/bin/ssh-tpm-agent -A /run/user/1000/gnupg/S.gpg-agent.ssh
ExecReload=/bin/kill -HUP $MAINPID
IPAddressDeny=any
RestrictAddressFamilies=AF_UNIX
RestrictNamespaces=yes
RestrictRealtime=yes
RestrictSUIDSGID=yes
LockPersonality=yes
SystemCallFilter=@system-service
SystemCallFilter=~@privileged @resources
SystemCallErrorNumber=EPERM
SystemCallArchitectures=native
NoNewPrivileges=yes
KeyringMode=private
UMask=0177
RuntimeDirectory=ssh-tpm-agent
[Install]
WantedBy=default.target
I try to use ssh-tpm-keygen
to import a ed25519 key, but this key type isn't support.
$ sudo ssh-tpm-keygen --import ~/.ssh/id_ed25519
Sealing an existing public/private ecdsa key pair.
Enter existing password (empty for no pin):
2023/12/26 15:46:10 unsupported key type
Is it possible to support ed25519?
Hi Morten,
I just installed the archlinux package extra/ssh-tpm-agent
which correctly copies the files to /usr/bin
but doesn't set the executable bit, thus throwing this error:
$ ssh-tpm-keygen
zsh: permission denied: ssh-tpm-keygen
setting the executable bit fixes this.
A maybe common use-case is that you have one or more ssh-agent
running. One key here, one key there.
ssh-tpm-agent
can only support TPM sealed keys, but it could proxy requests to other ssh-agent sockets. This would allow you to rely on one socket for all of the key handling.
Clearly this should be an opt-in feature, but might make it a more valueable ssh-agent
replacement.
From agent:
2023/07/30 03:37:29 agent 13: failed to sign: initializing session 1: TPM_RC_VALUE (parameter 2): value is out of range or is not correct for the context
From ssh -v ...
sign_and_send_pubkey: signing failed for ECDSA "/home/sgo/.ssh/id_ecdsa.pub" from agent: agent refused operation
this flag should show us all the identities loaded into our agent, useful for troubleshooting problems
Hi, while setting this up I found that
ssh-tpm-agent --print-socket
does not return the correct value of /run/user/1000/ssh-tpm-agent.sock
but rather the current value of $SSH_AUTH_SOCK
,
which in my case pointed to the gpg-agent.sock
.
I believe this should be fixed to correctly reflect the ssh-tpm-agent socket, so export SSH_AUTH_SOCK=$(tpm-ssh-agent --print-socket)
works as expected.
$ ssh-tpm-keygen
Generating a sealed public/private ecdsa key pair.
Enter file in which to save the key (/home/jc/.ssh/id_ecdsa): /home/jc/.ssh/hh-8192_ecdsa.tpm
Enter pin (empty for no pin):
Confirm pin:
Your identification has been saved in /home/jc/.ssh/hh-8192_ecdsa.tpm.tpm
Expected. Your identification has been saved in /home/jc/.ssh/hh-8192_ecdsa.tpm
turns out I was wrong about host keys failing and I hope this is another one of those situations.
I followed the instructions for user keys and can't find any evidence that the key is being used, plus I get the libcrypto error again:
ssh host.local
Load key "/home/user/.ssh/id_ecdsa.pub": error in libcrypto
[email protected]'s password:
Hello, when I try to run the ssh-tpm-keygen
command, I get the following error: open /dev/tpmrm0: permission denied
. Is the user executing the command expected to have some special permissions and / or is the user expected to belong to some group (e.g. tss
group)?
Thank you very much and have a nice day!
it will take me a few hours to get to the bottom of it, but it looks like when you use this agent with an ssh pki, agent forwarding appears to cause the pubkey itself, not the certificate to get forwarded.
here is a scenario.
I have User machine A, and hosts B and C
user A has tpm user keys while B and C trust the CA which has signed A's tpm pubkey
from my user on machine A I will ssh -Av B.local
i can confirm from the output that my certificate is approved and I login without a password. within this session I now
ssh -v C.local
this authorization fails. If I move the pubkey to machine C as an authorized_key, then the forwarded agent works.
so it seems to me that ssh-tpm-agent needs to be modified to correctly forward the certificate, as this scheme works as intended when not using the tpm agent.
I would be nice if $SSH_ASKPASS
could be used for TPM key PIN entry in place of pinentry
.
Most ssh users are likely to be familial with ssh askpass programs, but may not be so familiar with pinentry from the GnuPG world.
The description of the pinentry prompt is not descriptive enough.
ssh-tpm-agent/pinentry/pinentry.go
Line 19 in 65d5a50
Without differing it per-key, it is not possible to save multiple key PINs in a password manager.
Is it possible to change the PIN for a key, similar to ssh-keygen's -p
? I don't see an option in ssh-tpm-keygen for this.
I am trying to delete a key, but it does not work.
Key was added with ssh-tpm-keygen, and it shows up when I do ssh-add -L.
I tried ssh-add placeholder.tpm, which returns:
Bad key file tpm_hellesvik_gitlab.tpm: No such file or directory
And ssh-tpm-add -d placeholder.tpm, which returns:
2024/05/24 17:39:06 open -d: no such file or directory
ssh-tpm-agent.service gives me
agent 17: operation unsupported
With EvictControl
implemented in go-tpm
we could in theory support RSA keys, but default to NISP P256 keys.
It will be super slow, but we can atleast persist the RSA key which should be there on systems running systemd
.
The default should always be the most sane ECC thing we have available.
Since upgrading to version 0.3.0-1 from the archlinux repo, ssh-tpm-agent complains about the key being in an old format:
[2024-03-06T17:59:11+0100] [ALPM] upgraded ssh-tpm-agent (0.2.0-2 -> 0.3.0-1)
$ journalctl --user -u ssh-tpm-agent
Mar 09 09:18:06 sunny systemd[838]: Started ssh-tpm-agent service.
Mar 09 09:18:06 sunny ssh-tpm-agent[13577]: time=2024-03-09T09:18:06.309+01:00 level=INFO msg="Activated agent by socket"
Mar 09 09:18:06 sunny ssh-tpm-agent[13577]: time=2024-03-09T09:18:06.312+01:00 level=INFO msg="TPM key is in an old format. Will not load it." key_path=/home/knightshrub/.ssh/id_ecdsa.tpm error="old format on key"
The release notes for 0.3.0
mention this breaking change.
Is there a way to upgrade the key format or do I have to generate a new key?
There is something weird happening with the session encryption when used together with the signing. Inconsistent attributes apparently?
Need to figure out that one.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.