keyformat.txt (wk 2001-12-18)
-----------------------------


Some notes on the format of the secret keys used with gpg-agent.


The secret keys[1] are stored on a per file basis in a directory below
the .gnupg home directory.  This directory is named

   private-keys-v1.d

and should have permissions 700.

The secret keys are stored in files with a name matching the
hexadecimal representation of the keygrip[2].  The content of the file
is an S-Expression like the ones used with Libgcrypt.  Here is an
example of an unprotected file:

(private-key
 (rsa
  (n #00e0ce9..[some bytes not shown]..51#)
  (e #010001#)
  (d #046129F..[some bytes not shown]..81#)
  (p #00e861b..[some bytes not shown]..f1#)
  (q #00f7a7c..[some bytes not shown]..61#)
  (u #304559a..[some bytes not shown]..9b#)
 )
)

Actually this form should not be used for regular purposes and only
accepted by gpg-agent with the configuration option:
--allow-non-canonical-key-format.  

The regular way to represent the keys is in canonical representation
with the additional requirement of an extra object container around
it[3]:

(oid.1.3.6.1.4.1.11591.2.2.2
 (keyinfo human_readable_information_to_decribe_this_key)
 (private-key
   (rsa
    (n #00e0ce9..[some bytes not shown]..51#)
    (e #010001#)
    (d #046129F..[some bytes not shown]..81#)
    (p #00e861b..[some bytes not shown]..f1#)
    (q #00f7a7c..[some bytes not shown]..61#)
    (u #304559a..[some bytes not shown]..9b#)
   )
 )  
)


This describes an unprotected key; a protected key is like this:

(oid.1.3.6.1.4.1.11591.2.2.3
 (keyinfo human_readable_information_to_decribe_this_key)
 (private-key
   (rsa
    (n #00e0ce9..[some bytes not shown]..51#)
    (e #010001#)
    (oid.1.3.6.1.4.1.11591.2.1.1.1 (parms) encrypted_octet_string)
   )
 )  
)

In this scheme the encrypted_octet_string is encrypted according to
the scheme identifier by the OID,  most protection algorithms need
some parameters, which are given in a list before the
encrypted_octet_string.  The result of the decryption process is a
list of the secret key parameters.

Defined protection methods are:

1.3.6.1.4.1.gnu(11591).aegypten(2)
.algorithms(1).keyprotection(1).s2k3-sha1-aes-cbc(1)

This uses AES in CBC mode for encryption, SHA-1 for integrity
protection and the String to Key algorithm 3 from OpenPGP (rfc2440).

Example:

(oid.1.3.6.1.4.1.11591.2.1.1.1 
  ((salt iterations) iv)
  encrypted_octet_string
)

The encrypted_octet string should yield this S-Exp (in canonical
representation) after decryption:

(sha1_hash
 (d #046129F..[some bytes not shown]..81#)
 (p #00e861b..[some bytes not shown]..f1#)
 (q #00f7a7c..[some bytes not shown]..61#)
 (u #304559a..[some bytes not shown]..9b#)
)

For padding reasons, random bytes are appended to this list - they can
easily be stripped by looking for the end of the list.

The first element is the SHA-1 hash calculated on the concatenation of the
public key and secret key parameter lists: i.e one has to hash the
concatenatiohn of these 6 canonical encoded lists for RSA, including
the parenthesis.

 (n #00e0ce9..[some bytes not shown]..51#)
 (e #010001#)
 (d #046129F..[some bytes not shown]..81#)
 (p #00e861b..[some bytes not shown]..f1#)
 (q #00f7a7c..[some bytes not shown]..61#)
 (u #304559a..[some bytes not shown]..9b#)


After decryption the hash must be recalculated and compared against
the stored one - If they don't match the integrity of the key is not
given.


TODO: write a more elaborated version.




Notes:

[1] I usually use the terms private and secret key exchangeable but prefer the
term secret key because it can be visually be better distinguished
from the term public key.

[2] The keygrip is a unique identifier for a key pair, it is
independent of any protocol, so that the same key can be ised with
different protocols.  PKCS-15 calls this a subjectKeyHash; it can be
calculate using Libgcrypt's gcry_pk_get_keygrip().

[3] Even when canonical representation is required we will show the
S-expression here in a more readable representation.
