Create a GPG key that uses separate subkeys for signing and certification.
Submit a message with this key.
Sigbin redirects you to the homepage with a flashed error notification: "Failed to import signing key from key server"
Wait a few seconds, then try again with the same message.
This time, verifying the signature succeeds, and you are redirected to /update/1. This indicates that the signing key was successfully imported from the key server after all.
Cause
I have a key with the following subkeys:
$ gpg --edit-key 0xAB85B8259D8CEFF1
gpg (GnuPG/MacGPG2) 2.0.28; Copyright (C) 2015 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Secret key is available.
pub 4096R/0xAB85B8259D8CEFF1 created: 2015-05-15 expires: 2020-05-13 usage: C
trust: ultimate validity: ultimate
sub 4096R/0xE0AF3051294E1E5B created: 2015-05-15 expires: never usage: S
sub 4096R/0xA6F916DB5C00B5D9 created: 2015-05-15 expires: never usage: E
sub 4096R/0x440912775128B241 created: 2015-05-15 expires: never usage: A
[ultimate] (1). Garrett Robinson <garrett@freedom.press>
[ultimate] (2) Garrett Robinson <garrett.f.robinson@gmail.com>
[ultimate] (3) Garrett Robinson <garrettr@riseup.net>
Note that I have separate subkeys for Certification and Signing. This is valid and common among those that use a smartcard setup that separates their primary key from their subkeys. However, it is not the default subkey layout that is created by gpg --gen-key or any of the GUI key generation tools (e.g. Enigmail, GPGTools) that I know of. Most of these tools use the same subkey for signing and certification, e.g my old GPG key:
$ gpg --edit-key 0x464F0A89D3EF9CAE
gpg (GnuPG/MacGPG2) 2.0.28; Copyright (C) 2015 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Secret key is available.
pub 4096R/0x464F0A89D3EF9CAE created: 2013-09-04 expires: 2018-09-03 usage: SCA
trust: ultimate validity: ultimate
*** This key has been disabled
sub 4096R/0x0C2CC50511AD9BEC created: 2013-09-04 expires: 2018-09-03 usage: E
[ultimate] (1). Garrett Robinson <garrett@freedom.press>
[ultimate] (2) Garrett Robinson <garrettr@riseup.net>
[ revoked] (3) Garrett Robinson (Work) <grobinson@mozilla.com>
[ultimate] (4) Garrett Robinson (FPF) <garrett@pressfreedomfoundation.org>
The problematic code here is:
# Do we have the signing key?
if "Can't check signature: No public key" in err or "Can't check signature: public key not found" in err:
keyid = ''
for line in err.split('\n'):
if line.startswith('gpg: Signature made'):
keyid = line.split()[-1]
if re.match(r'^[a-fA-F\d]{8}$', keyid):
# Try to fetch the signing key from key server
out, err = self._gpg(['--recv-keys', keyid])
if "key {} not found on keyserver".format(keyid) in err:
return ("The signing key was not found on key servers", None)
else:
import_success = False
for line in err.split('\n'):
if line.startswith('gpg: key {}: public key "'.format(keyid)) and line.endswith('" imported'):
import_success = True
if not import_success:
return ('Failed to import signing key from key server', None)
Specifically, trying to verify that the imported keyid is the same as the signing subkey keyid. This is a valid assumption for many but not all GPG keys.
Here are some logs from an example STR:
127.0.0.1 - - [22/Sep/2015 12:34:40] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [22/Sep/2015 12:34:40] "GET /favicon.ico HTTP/1.1" 200 -
stderr gpg: keyring `/Users/garrett/code/github.com/firstlook/sigbin/homedir/pubring.gpg' created
gpg: Signature made Tue Sep 22 12:35:06 2015 PDT using RSA key ID 294E1E5B
gpg: Can't check signature: No public key
stderr gpg: keyring `/Users/garrett/code/github.com/firstlook/sigbin/homedir/secring.gpg' created
gpg: requesting key 294E1E5B from hkp server pool.sks-keyservers.net
gpg: /Users/garrett/code/github.com/firstlook/sigbin/homedir/trustdb.gpg: trustdb created
gpg: key 9D8CEFF1: public key "Garrett Robinson <garrett@freedom.press>" imported
gpg: no ultimately trusted keys found
gpg: Total number processed: 1
gpg: imported: 1 (RSA: 1)
As you can see, the keyid that made the signature (the S subkey) is not the same as the keyid of the key itself (the C subkey). This causes the check of the imported keyid to fail, even though the key was successfully imported. This check should be modified to work even if the signing subkey and the certifying subkey are not the same.
STR
/update/1
. This indicates that the signing key was successfully imported from the key server after all.Cause
I have a key with the following subkeys:
Note that I have separate subkeys for Certification and Signing. This is valid and common among those that use a smartcard setup that separates their primary key from their subkeys. However, it is not the default subkey layout that is created by
gpg --gen-key
or any of the GUI key generation tools (e.g. Enigmail, GPGTools) that I know of. Most of these tools use the same subkey for signing and certification, e.g my old GPG key:The problematic code here is:
Specifically, trying to verify that the imported keyid is the same as the signing subkey keyid. This is a valid assumption for many but not all GPG keys.
Here are some logs from an example STR:
As you can see, the keyid that made the signature (the S subkey) is not the same as the keyid of the key itself (the C subkey). This causes the check of the imported keyid to fail, even though the key was successfully imported. This check should be modified to work even if the signing subkey and the certifying subkey are not the same.