A Creative Approach to Revoking OpenPGP Subkeys

I was sitting down with my devices this evening to check how my OpenPGP keys were set up to make sure all of them are functioning okay and will do what I need whenever I would need them. Save for the fact that I took a plunge a month back and began a transition to using ECC (its compatibility isn’t like RSA’s across OpenPGP implementations, plus I’m using Curve25519 for encryption, which GnuPG provides but isn’t in OpenPGP’s RFC) everything looked fine, until I thought about what would happen if I lose my device.

Just Revoke The Subkeys?

The roleplay in my head, because I travel quite a bit and go through various security checkpoints, is “What do I do if I must surrender one of my devices on-hand?” The Guardian Project‘s Ripple app, in Beta, would let me wipe OpenKeychain while I’m waiting in line for my turn, but that support isn’t implemented yet. In addition, while deleting something off my phone would be easy and inconspicuous enough to do while waiting in line, rummaging through my bags for my tablet or other technology would certainly mark me as Interesting–possibly Interesting enough to be expedited through the process.

In any case, pondering this situation made me wonder if it’s possible to generate revocation certificates for my OpenPGP keys that revoke only the subkeys of a compromised device. Unfortunately, the answer is no; generated revocation certificates will revoke the entire key. Revoking the entire key seems too much like throwing the baby out with the bathwater in my situation, especially since I do not carry the secret material of my primary key on me.

In addition, since I don’t carry the secret material of my primary key on me, I would have no method of revoking the subkeys after I’ve surrendered any of my devices. I could just wait until I get to a trusted system to revoke the subkeys properly, but from the moment I surrender a device to the moment I get to a trusted computer, someone may have utilized my key material. I’m not particularly fond of that prospect.

I began thinking of solutions for this theoretical problem.

Changes to Public Keys are Merged

It occurred to me that the public key material exported from gpg --export contains the public information about your key, along with signatures that certify certain things like your current and revoked user IDs and subkeys. The important thing I remembered is that when someone updates a public key, any additions–like self-signatures stating that a subkey is revoked–are merged with the current information in the key ring.

Based on that knowledge, I booted up my trusted system and, for each of my devices:

  1. Exported my current public and secret keys to a respective file.
  2. Used gpg --edit-key to revoke the subkeys that would be on the device.
  3. Exported the public key material with the revocations to a new file.
  4. Deleted my public and secret keys from the key ring.
  5. Imported my public and secret files I created in step one.

What I’ve basically made are ‘per-device revocation certificates’ masquerading as a public key file. Publishing the files I’ve made to a key server will merge the self-signatures that revoked the subkeys into my public key stored on the key server. People who already have my key will be able to note the revocation after they do an update (e.g. gpg --refresh-keys) on their key ring. The best benefit? I won’t need to revoke my entire key using an actual revocation certificate, and I won’t need to carry my secret key material to revoke any compromised subkeys.

It Works, But It’s Not Pretty

The biggest problem I foresee utilizing this process is those subkeys are marked revoked on the date I self-signed the revocation–not on the day that I, say, published the change on a key server.

For example, let’s say I created the revocations today using the process I outlined, used my keys for a month, and then had to surrender a device. I have no way to properly revoke the subkeys because I don’t have my secret key material available for revocations. I publish the file I made for the particular device that was compromised to a key server, marking the subkeys as revoked on the date of the self signature. Even though I put PREEMPTIVE STOPGAP: A device has been compromised. as a description during the subkey revocation process, thus letting people know that this revocation was done pre-emptively, gnupg will still complain that a signature, ciphertext, or authentication was done during a time when a subkey should’ve been invalid because it was revoked–even if said operations were done before I published the file to a key server.

I’d consider that consequence unacceptable, but more acceptable than revoking an entire key via revocation certificate just because of a few compromised subkeys (again, throwing baby out with the bathwater), or carrying the secret key material with me to accomplish correct revocations (if I can help it, I won’t carry the secret key material of my primary key). It gives me a way to notify people not to trust operations done by a compromised subkey when I can’t revoke in the correct manner.

If a better solution exists to this problem, I’d be very glad to know it. But thus far, I can’t think of a better solution.

Update: Because I’ve transitioned to a new key based on ECC, I revoked my old primary key using a Revocation Certificate I made for the purpose (key has been superseded). A prepared certificate was used because I knew, during the time, that I will not have access to my trusted computer.

Turns out, using a revocation certificate issues a revocation based on the time I created the revocation certificate, and not the time that I used it. Ergo, the process I outlined above functions the exact same way as a revocation certificate, which is what I want to happen.

As An Aside

This just further confirms my opinion that OpenPGP can get far too hard.