Since I got interested in starting to use OpenPGP for my email, I thought the fact that the Gnome desktop comes with a graphical application for generating a new key with GnuPG was wicked awesome. Unfortunately, when I started to switch between the GUI frontend and the command-line interface to see how things worked, I noticed a couple inconsistencies. This is one of them.
Since I read about this year's recommendation against the DSA algorithm (and yes, I'm coming down with a touch of RAS syndrome there), I generated an RSA key using Seahorse (or "Passwords and Encryption Keys," as
Ubuntu all user-facing text calls it).
The bug showed its face when I examined the key up-close in terminal:
gpg --edit-key 01234567gpg (GnuPG) 1.4.6; Copyright (C) 2006 Free Software Foundation, Inc. This program comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. See the file COPYING for details. Secret key is available. pub 2048R/01234567 created: 2009-08-24 expires: never usage: SCEA trust: ultimate validity: ultimate
I looked up what "Usage: SCEA" meant. What those letters are are key usage flags, telling GnuPG what cryptographic job the key is meant to be used for. This key has all of them: a flag for Signing, Certifying, Encrypting, and Authenticating. From what little I've read, you're really, really REALLY not supposed to make it even possible to use the same RSA key for signing and encryption. See here for why. It's why the usage flags are extra important for the sanity of RSA. (Though that hasn't always been the case, back when OpenPGP codified RSA-for-encryption and RSA-for-signatures as two entirely different key types.)
It turns out this mistake is a long-standing bug that's really hard to search for. Gnome bug 555205 from late 2008, to be exact. (Okay, it was reported months earlier as bug 539532, but the dupe triagers gave the bug report written in super-precise tech-speak deference.)
git clone git://git.gnome.org/seahorse
I looked into the seahorse/pgp/ folder and grep'd aroundseahorse-gpgme-key-op.c -- and looked at what functions it called that looked likely to lead to actual key-generation, and checked out those. Eventually that trail led to a function I couldn't grep for. That forced me to remember the actual GnuPG-touching code isn't supposed to be in Seahorse in the first place; it's in Seahorse's dependency package, GPGME ("GPG Made Easy," or as named in Ubuntu 8.04, libgpgme11).. I found what looked like the function for generating a new key -- seahorse_gpgme_key_op_generate in
After running apt-get source libgpgme11, I grep -rn'd through GPGME's source to find the function hook Seahorse had called, and ended up digging through more and more functions. It got extremely confusing. I kept tracking the XML data that the Seahorse source code seemed to be giving as input into the variable parms, which then went into the variable help_data, which went... um... straight onto gpg's command-line arguments? Or possibly into stdin right after gpg started. I wasn't quite sure. The code itself openly admitted it was a pile of kludges when I reached that point.
Eventually I gave up and went back to the beginning: I Googled for the XML fields individually instead of en-quoted (starting with Key-Type: and Name-Comment:, etc).
The first thing I found useful was this:
A Key-Usage: field, holy crap! That's just what I need. I could've inserted that line into the XML all this time. I thought I'd better Google for more details just in case, though:
Aha, now that explains why the usage flags were all shitty in the first place. A "default to all technical capabilities" feature, regardless of the security recommendations for RSA in particular.
Once I found out what the standard syntax was, the patch was dead-simple. It was just all that finding out that was hard. (Which probably says more about me than about the documentation.)
--- a/pgp/seahorse-gpgme-key-op.c Sat Sep 05 12:58:59 2009 -0400 +++ b/pgp/seahorse-gpgme-key-op.c Sat Sep 05 16:08:28 2009 -0400 @@ -135,9 +135,9 @@ common = g_strdup_printf ("Name-Comment: %s\n%s", comment, common); if (type == RSA_SIGN)
- key_type = "Key-Type: RSA";else - key_type = "Key-Type: DSA";start = g_strdup_printf (" \n%s\nKey-Length: ", key_type);
Now to get a Bugzilla account...