Opened 6 years ago

Closed 6 years ago

#9443 closed task (fixed)

Generate and secure pgp keys for bridges.tpo

Reported by: sysrqb Owned by: isis
Priority: High Milestone:
Component: Circumvention/BridgeDB Version:
Severity: Keywords: bridgedb-email
Cc: isis, asn, isis@…, mrphs Actual Points:
Parent ID: #5463 Points:
Reviewer: Sponsor:

Description

We need to start signing the emails we send from bridges.tpo, but we need keys to do this. This means we need to be able to store them in a safe way, too; preferably the long-term keys will be stored in an offline hardware chip of some sort, subkey(s) will be online. Who will generate these, who will control this chip and where will it be stored?

Plus any other important questions I missed.

Child Tickets

Change History (7)

comment:1 Changed 6 years ago by sysrqb

Parent ID: #5463

We need to do this before we can actually sign.

comment:2 Changed 6 years ago by isis

Cc: isis asn isis@… added; isis asn removed
Status: newneeds_information

I can do this, and I have an empty card device which has never been used. My main issue with it is that it won't handle ECC keys, and won't handle keys larger than 3072 bits. But if we want a 3072 certify-only identity key, I can do that.

FWIW, it would be nice to have some sort of shared-secret recovery method for this key, i.e. with k=8 and n=3 (because I really don't think it would be possible to get more than three people to collude to be in the same physical location within a relatively short timeframe).

comment:3 Changed 6 years ago by mrphs

Cc: mrphs added

comment:4 Changed 6 years ago by isis

Keywords: bridgedb-email added
Owner: set to isis
Status: needs_informationassigned

Actually, it turns out that OpenPGP smartcards will only allow keyslot bitlength expansion to 3072 bit if the key is flagged 'S', 'E', or 'A', but not, for some stupid reason, certification-only keys, which is the key we would want to keep offline.

comment:5 Changed 6 years ago by isis

Also, to facilitate getting smartphone users to actually verify the fingerprint, I could put either:

  1. A QR code of the fingerprint as a UID on the primary certification key.
  2. A QR code of a link to some webpage, e.g. https://bridges.torproject.org/verify.html with instructions for what to do and a signed statement containing the fingerprint.

Option #1 is nice because the people making APG and Gibberbot and similar tools have started putting support for scanning QR code to verify fingerprints.

The latter option is nice because it will (hopefully) make our help desk have to deal less with helping people with PGP/GPG (which sounds hellish to me).

Actually, it occurs to me that these things can be combined. Here's what I am going to do:

  1. Long-Term Identity Keypair:
    • RSA 16384-bit
    • Usage: C
    • Storage:
      • Private Key: Offline, probably in pieces, using some variant of Shamir's Secret Sharing Scheme such that some N out of K people are needed to decrypt it. (There actually is an obscure key flag for this. I don't think anyone has implemented it.)
      • Public Key: Well, the keyservers will puke if I try to feed this key to them, so I'm going to put it on https://bridges.torproject.org/key.asc and set the "Preferred Keyserver" for all keys 0-3 to that URL.
    • Lifetime: Indefinite
  2. Primary Keypair:
    • RSA 4096-bit
      • I could make it be an 8192-bit key, though I am not sure how far back GnuPG allows this keysize (it's at least a couple years now), and I have no idea if PGP or APG will handle it correctly.
    • Usage: C
    • Storage:
      • Private Key: Offline. Not on a smartcard, because apparently we can't put it on a smartcard, not even if we reduce it to 3072-bit.
      • Public Key: Online, on ponticum. We have to do this because GnuPG won't allow subkeys to be detached entirely from their primary keypair. (Although there is a neat trick for turning primary keys into subkeys and vice versa, involving bitflipping the bit 3 in the first octet of the Secret Key Packet to modify the packet tag header which says whether it's a subkey or not.
    • Lifetime: 1 year (it should be rotated because it is kept online)
    • UID 1: BridgeDB <bridges@bridges.torproject.org>
    • UID 2: photoID, containing link to https://bridges.torproject.org/verify.html (NOTE: I'm not sure about this one yet.)
    • Certification Notation: bridges@bridges.torproject.org=<primary key fingerprint>
    • Certification Notation: verified@bridges.torproject.org=<fingerprint of the key we're certifying>
    • Certification Notation: certified.count@bridges.torproject.org=<number of certifications>
  3. Signing Subkey:
    • RSA 4096-bit
    • Usage: S
    • Storage:
      • Private Key: Online, on ponticum.
      • Private Key: Online, on ponticum.
    • Lifetime: 1 year
    • Signature notation: bridges@bridges.torproject.org=<primary key fingerprint>
    • Signature notation: sig.count@bridges.torproject.org=<number of signatures thus far>
    • Signature notation: signed.data@bridges.torproject.org=<filename signed>
  4. Encryption Subkey:
    • RSA 4096-bit
    • Usage: E
    • Storage:
      • Private Key: Online, on ponticum.
      • Private Key: Online, on ponticum.
    • Lifetime: 1 year

I have also been considering designating the long-term identity key (0) as a revoker for the signing (2) and encryption (3) keys, and then destroying the private portion of the second certification key (1).

Last edited 6 years ago by isis (previous) (diff)

comment:6 Changed 6 years ago by isis

I created two version of the same key. I haven't uploaded either anywhere yet, because I haven't decided which is better.

Version 1:

16384-bit certification-only primary key with a 4096-bit signing-only subkey and another 4096-bit encryption-only subkey.

pub  16384R/55A22E5EAC57022E  created: 2013-09-11  expires: never       usage: C   
                             trust: ultimate      validity: ultimate
sub  4096R/FD419C960FAC24C5  created: 2013-09-11  expires: 2014-09-11  usage: S   
sub  4096R/15BC38E8CF01816F  created: 2013-09-11  expires: 2014-09-11  usage: E   
[ultimate] (1). BridgeDB <bridges@bridges.torproject.org>

It looks like this:

∃!isisⒶwintermute:(build/2.1.0-beta3-16384b)~/code/sources/gnupg/gnupg2.1.0-b3_2/bin ∴ pgpdump bdb-16kC-SEsub.pub
Old: Public Key Packet(tag 6)(2061 bytes)
        Ver 4 - new
        Public key creation time - Wed Sep 11 08:24:59 UTC 2013
        Pub alg - RSA Encrypt or Sign(pub 1)
        RSA n(16384 bits) - ...
        RSA e(17 bits) - ...
Old: User ID Packet(tag 13)(41 bytes)
        User ID - BridgeDB <bridges@bridges.torproject.org>
Old: Signature Packet(tag 2)(2336 bytes)
        Ver 4 - new
        Sig type - Positive certification of a User ID and Public Key packet(0x13).
        Pub alg - RSA Encrypt or Sign(pub 1)
        Hash alg - SHA512(hash 10)
        Hashed Sub: notation data(sub 20)(71 bytes)
                Flag - Human-readable
                Name - verified@torproject.org
                Value - DB983958F184F3C6F9F348D555A22E5EAC57022E
        Hashed Sub: notation data(sub 20)(78 bytes)
                Flag - Human-readable
                Name - bridges@bridges.torproject.org
                Value - DB983958F184F3C6F9F348D555A22E5EAC57022E
        Hashed Sub: policy URL(sub 26)(41 bytes)
                URL - https://bridges.torproject.org/policy.txt
        Hashed Sub: key flags(sub 27)(1 bytes)
                Flag - This key may be used to certify other keys
        Hashed Sub: features(sub 30)(1 bytes)
                Flag - Modification detection (packets 18 and 19)
        Hashed Sub: key server preferences(sub 23)(1 bytes)
                Flag - No-modify
        Hashed Sub: signature creation time(sub 2)(4 bytes)
                Time - Wed Sep 11 08:58:51 UTC 2013
        Hashed Sub: preferred symmetric algorithms(sub 11)(3 bytes)
                Sym alg - Camellia with 256-bit key(sym 13)
                Sym alg - AES with 256-bit key(sym 9)
                Sym alg - Twofish with 256-bit key(sym 10)
        Hashed Sub: preferred hash algorithms(sub 21)(3 bytes)
                Hash alg - SHA512(hash 10)
                Hash alg - SHA384(hash 9)
                Hash alg - SHA256(hash 8)
        Hashed Sub: preferred compression algorithms(sub 22)(3 bytes)
                Comp alg - ZLIB <RFC1950>(comp 2)
                Comp alg - ZIP <RFC1951>(comp 1)
                Comp alg - Uncompressed(comp 0)
        Hashed Sub: preferred key server(sub 24)(38 bytes)
                URL - https://bridges.torproject.org/key.asc
        Sub: issuer key ID(sub 16)(8 bytes)
                Key ID - 0x55A22E5EAC57022E
        Hash left 2 bytes - 66 bd
        RSA m^d mod n(16384 bits) - ...
                -> PKCS-1
Old: Public Subkey Packet(tag 14)(525 bytes)
        Ver 4 - new
        Public key creation time - Wed Sep 11 08:59:00 UTC 2013
        Pub alg - RSA Encrypt or Sign(pub 1)
        RSA n(4096 bits) - ...
        RSA e(17 bits) - ...
Old: Signature Packet(tag 2)(2947 bytes)
        Ver 4 - new
        Sig type - Subkey Binding Signature(0x18).
        Pub alg - RSA Encrypt or Sign(pub 1)
        Hash alg - SHA512(hash 10)
        Hashed Sub: signature creation time(sub 2)(4 bytes)
                Time - Wed Sep 11 08:59:00 UTC 2013
        Hashed Sub: notation data(sub 20)(71 bytes)
                Flag - Human-readable
                Name - verified@torproject.org
                Value - DB983958F184F3C6F9F348D555A22E5EAC57022E
        Hashed Sub: notation data(sub 20)(78 bytes)
                Flag - Human-readable
                Name - bridges@bridges.torproject.org
                Value - DB983958F184F3C6F9F348D555A22E5EAC57022E
        Hashed Sub: policy URL(sub 26)(41 bytes)
                URL - https://bridges.torproject.org/policy.txt
        Hashed Sub: key flags(sub 27)(1 bytes)
                Flag - This key may be used to sign data
        Hashed Sub: key expiration time(sub 9)(4 bytes)
                Time - Thu Sep 11 08:59:00 UTC 2014
        Sub: issuer key ID(sub 16)(8 bytes)
                Key ID - 0x55A22E5EAC57022E
        Sub: embedded signature(sub 32)(663 bytes)
        Ver 4 - new
        Sig type - Primary Key Binding Signature(0x19).
        Pub alg - RSA Encrypt or Sign(pub 1)
        Hash alg - SHA512(hash 10)
        Hashed Sub: signature creation time(sub 2)(4 bytes)
                Time - Wed Sep 11 08:59:00 UTC 2013
        Hashed Sub: notation data(sub 20)(78 bytes)
                Flag - Human-readable
                Name - bridges@bridges.torproject.org
                Value - B5EEDA1783ACA9D80B4F752EFD419C960FAC24C5
        Hashed Sub: policy URL(sub 26)(41 bytes)
                URL - https://bridges.torproject.org/policy.txt
        Sub: issuer key ID(sub 16)(8 bytes)
                Key ID - 0xFD419C960FAC24C5
        Hash left 2 bytes - 04 a8
        RSA m^d mod n(4096 bits) - ...
                -> PKCS-1
        Hash left 2 bytes - ff a9
        RSA m^d mod n(16384 bits) - ...
                -> PKCS-1
Old: Public Subkey Packet(tag 14)(525 bytes)
        Ver 4 - new
        Public key creation time - Wed Sep 11 09:05:16 UTC 2013
        Pub alg - RSA Encrypt or Sign(pub 1)
        RSA n(4096 bits) - ...
        RSA e(17 bits) - ...
Old: Signature Packet(tag 2)(2281 bytes)
        Ver 4 - new
        Sig type - Subkey Binding Signature(0x18).
        Pub alg - RSA Encrypt or Sign(pub 1)
        Hash alg - SHA512(hash 10)
        Hashed Sub: signature creation time(sub 2)(4 bytes)
                Time - Wed Sep 11 09:05:16 UTC 2013
        Hashed Sub: notation data(sub 20)(71 bytes)
                Flag - Human-readable
                Name - verified@torproject.org
                Value - DB983958F184F3C6F9F348D555A22E5EAC57022E
        Hashed Sub: notation data(sub 20)(78 bytes)
                Flag - Human-readable
                Name - bridges@bridges.torproject.org
                Value - DB983958F184F3C6F9F348D555A22E5EAC57022E
        Hashed Sub: policy URL(sub 26)(41 bytes)
                URL - https://bridges.torproject.org/policy.txt
        Hashed Sub: key flags(sub 27)(1 bytes)
                Flag - This key may be used to encrypt communications
                Flag - This key may be used to encrypt storage
        Hashed Sub: key expiration time(sub 9)(4 bytes)
                Time - Thu Sep 11 09:05:16 UTC 2014
        Sub: issuer key ID(sub 16)(8 bytes)
                Key ID - 0x55A22E5EAC57022E
        Hash left 2 bytes - b4 df
        RSA m^d mod n(16383 bits) - ...
                -> PKCS-1

Version 2:

Same 16384-bit primary key, though with no subkeys. Instead, it signed a totally separate keypair. This second keypair has it's secret primary key removed so that it can live online, and it has the signing and encryption subkeys instead. They look like this:

pub  16384R/68BD0B28290C50A5  created: 2013-09-11  expires: never       usage: C   
                             trust: ultimate      validity: ultimate
[ultimate] (1). BridgeDB (Offline ID Key) <bridges@bridges.torproject.org>

pub  4096R/0C35CEC9FA6FA175  created: 2013-09-11  expires: 2014-09-11  usage: C   
                             trust: unknown       validity: full
sub  4096R/9F07296D8220C992  created: 2013-09-11  expires: 2014-09-11  usage: S   
sub  4096R/3678E38022DC427B  created: 2013-09-11  expires: 2014-09-11  usage: E   
[  full  ] (1). BridgeDB <bridges@bridges.torproject.org>

comment:7 Changed 6 years ago by isis

Resolution: fixed
Status: assignedclosed

I'm going with Version 2. Here are the keyrings which I'm putting on ponticum, they are not capable of certifying further keys without using the secret portion of the 16384-bit offline key:

/home/bridgedb/.gnupg/pubring.gpg
-----------------------------------------------------------------
pub   16384R/CBD97AA24E8E472E 2013-10-12
uid               [ultimate] BridgeDB (Offline ID Key) <bridges@bridges.torproject.org>

pub   4096R/8DC43A2848821E32 2013-09-11 [expires: 2014-09-11]
uid               [  full  ] BridgeDB <bridges@bridges.torproject.org>
sub   4096R/21B554E95938F4D0 2013-09-11 [expires: 2014-09-11]
sub   4096R/E7793047C5B54232 2013-09-11 [expires: 2014-09-11]

/home/bridgedb/.gnupg/secring.gpg
-----------------------------------------------------------------
sec#  4096R/8DC43A2848821E32 2013-09-11 [expires: 2014-09-11]
uid                          BridgeDB <bridges@bridges.torproject.org>
ssb   4096R/21B554E95938F4D0 2013-09-11
ssb   4096R/E7793047C5B54232 2013-09-11
Note: See TracTickets for help on using tickets.