Add secret key parsing to PGPPacket
authorW. Trevor King <wking@tremily.us>
Fri, 20 Dec 2013 18:25:59 +0000 (10:25 -0800)
committerW. Trevor King <wking@tremily.us>
Fri, 20 Dec 2013 19:46:31 +0000 (11:46 -0800)
commitac2696b9c7688e1c7efef7ad13455d732d596fbb
tree9fdf0bd74fd66b16e76d89feacb5ed6392e31c4f
parentfdc688a4e3b58bad40a49ae03d116d681bc04b75
Add secret key parsing to PGPPacket

Use the same parser for public-key and public-subkey packets.  From
RFC 4880 [1]:

  A Secret-Subkey packet (tag 7) is the subkey analog of the Secret
  Key packet and has exactly the same format.

The generic (sub)key parsing is specified in section 5.5.3 [2]:

  The Secret-Key and Secret-Subkey packets contain all the data of the
  Public-Key and Public-Subkey packets, with additional algorithm-
  specific secret-key data appended, usually in encrypted form.

  The packet contains:

  - A Public-Key or Public-Subkey packet, as described above.
  - One octet indicating string-to-key usage conventions.  Zero
    indicates that the secret-key data is not encrypted.  255 or 254
    indicates that a string-to-key specifier is being given.  Any
    other value is a symmetric-key encryption algorithm identifier.
  - [Optional] If string-to-key usage octet was 255 or 254, a one-
    octet symmetric encryption algorithm.
  - [Optional] If string-to-key usage octet was 255 or 254, a
    string-to-key specifier.  The length of the string-to-key
    specifier is implied by its type, as described above.
  - [Optional] If secret data is encrypted (string-to-key usage octet
    not zero), an Initial Vector (IV) of the same length as the
    cipher's block size.
  - Plain or encrypted multiprecision integers comprising the secret
    key data.  These algorithm-specific fields are as described below.
  - If the string-to-key usage octet is zero or 255, then a two-octet
    checksum of the plaintext of the algorithm-specific portion (sum
    of all octets, mod 65536).  If the string-to-key usage octet was
    254, then a 20-octet SHA-1 hash of the plaintext of the
    algorithm-specific portion.  This checksum or hash is encrypted
    together with the algorithm-specific fields (if string-to-key
    usage octet is not zero).  Note that for all other values, a
    two-octet checksum is required.

RFC 4880 claims to list block sizes (needed for the IV length) [3]:

  OpenPGP specifies a number of symmetric-key algorithms.  This
  specification creates a registry of symmetric-key algorithm
  identifiers.  The registry includes the algorithm name, its key
  sizes and block size, and a reference to the defining specification.
  The initial values for this registry can be found in Section 9.

But in section 9.2 [4], they just list key size.  It looks like the
block size is usually equal to the key size, but not always.  From
section one of the AES spec [5]:

  This standard specifies the Rijndael algorithm (...), a symmetric
  block cipher that can process data blocks of 128 bits, using cipher
  keys with lengths of 128, 192, and 256 bits.

So it looks like the block size for each cipher needs research beyond
RFC 4880.

[1]: http://tools.ietf.org/search/rfc4880#section-5.5.1.4
[2]: http://tools.ietf.org/search/rfc4880#section-5.5.3
[3]: http://tools.ietf.org/search/rfc4880#section-10.3.2
[4]: http://tools.ietf.org/search/rfc4880#section-9.2
[5]: http://csrc.nist.gov/publications/fips/fips197/fips-197.{ps,pdf}
gpg-migrate.py