An option that seems the closest in spirit to what I want is to set up a gpg-agent
program that would delegate the actual cryptography to a human.
When you use GPG to sign things, it talks to the gpg-agent
to actually perform the operations with the private key. That way, the gpg-agent
can remember the password for a while, interact with smartcards, and figure out which pinentry program to show to the user. Importantly, it listens on a Unix domain socket, so it can be forwarded over connections like SSH with the -R
remote listening setup.
The original motivation for my question was in the context of remote working: you get a computer somewhere, you can only work on the code via a remote connection, and you can't (as in, not supposed to) bring the code away from the remote connection. It is for these setups that gpg-agent
forwarding works best: a hidden channel is established in addition to your session, and over that channel the remote gpg
program talks to your local gpg-agent
, and the gpg-agent
retains the private keys while only providing the result to the remote computer.
But this could also work for air-gapped setups. I've tried opening two terminal panes, one on the remote computer with a nc -Ul
listening on the Unix socket where the gpg-agent
would normally live, and one on my local computer with gpg-connect-agent
, and copying the commands back and forth between the two windows. I almost went through the entire signature transaction, and the only reason it failed is at the very last step, when executing PKSIGN
, it produced a bunch of binary data that did not get copied over correctly in the clipboard.
So, the plan is:
- On the untrusted computer, replace the standard
gpg-agent
program with one that responds withOK
s until thePKSIGN
command. When a signature operation is requested, the program pops up an alert containing the previous commands in a compressed text-only form. - A human copies the data on the screen into the trusted computer that holds the keys. There, a program replays the commands into the real
gpg-agent
, which performs the signature operation, and then returns a compressed text-only response. - The human then copies this data back into the untrusted computer. The pretend
gpg-agent
returns the response to the callinggpg
program, which completes the signature.
This is basically similar to gpg-agent
forwarding over SSH, except that the protocol is modified to require less back-and-forth interactions (since those require the attention of the human now).
This is of course very theoretical and very paranoid: the computer I'm working on is obviously not airgapped because I'd be remoting into it. A realistic solution for my problem is to use normal gpg-agent
forwarding, and/or generate a new key to keep on the untrusted computer (perhaps signed by my main key, perhaps not).