gpg: Try to use the passphrase from the primary for --quick-addkey.
[gnupg.git] / agent / keyformat.txt
index 7bdb94c..c1a59ce 100644 (file)
@@ -1,11 +1,11 @@
-keyformat.txt (wk 2001-12-18)
------------------------------
+keyformat.txt               emacs, please switch to -*- org -*- mode
+-------------
 
 
 Some notes on the format of the secret keys used with gpg-agent.
 
-Location of keys
-================
+Location of keys
+
 The secret keys[1] are stored on a per file basis in a directory below
 the ~/.gnupg home directory.  This directory is named
 
@@ -14,10 +14,74 @@ the ~/.gnupg home directory.  This directory is named
 and should have permissions 700.
 
 The secret keys are stored in files with a name matching the
-hexadecimal representation of the keygrip[2].
+hexadecimal representation of the keygrip[2] and suffixed with ".key".
+
+* Extended Private Key Format
+
+GnuPG 2.3+ will use a new format to store private keys that is both
+more flexible and easier to read and edit by human beings.  The new
+format stores name,value-pairs using the common mail and http header
+convention.  Example (here indented with two spaces):
+
+  Description: Key to sign all GnuPG released tarballs.
+    The key is actually stored on a smart card.
+  Use-for-ssh: yes
+  OpenSSH-cert: long base64 encoded string wrapped so that this
+    key file can be easily edited with a standard editor.
+  Key: (shadowed-private-key
+    (rsa
+    (n #00AA1AD2A55FD8C8FDE9E1941772D9CC903FA43B268CB1B5A1BAFDC900
+    2961D8AEA153424DC851EF13B83AC64FBE365C59DC1BD3E83017C90D4365B4
+    83E02859FC13DB5842A00E969480DB96CE6F7D1C03600392B8E08EF0C01FC7
+    19F9F9086B25AD39B4F1C2A2DF3E2BE317110CFFF21D4A11455508FE407997
+    601260816C8422297C0637BB291C3A079B9CB38A92CE9E551F80AA0EBF4F0E
+    72C3F250461E4D31F23A7087857FC8438324A013634563D34EFDDCBF2EA80D
+    F9662C9CCD4BEF2522D8BDFED24CEF78DC6B309317407EAC576D889F88ADA0
+    8C4FFB480981FB68C5C6CA27503381D41018E6CDC52AAAE46B166BDC10637A
+    E186A02BA2497FDC5D1221#)
+    (e #00010001#)
+    (shadowed t1-v1
+     (#D2760001240102000005000011730000# OPENPGP.1)
+    )))
+
+GnuPG 2.2 is able to read and update keys using the new format, but
+will not create new files using the new format.  Furthermore, it only
+makes use of the value stored under the name 'Key:'.
+
+Keys in the extended format can be recognized by looking at the first
+byte of the file.  If it starts with a '(' it is a naked S-expression,
+otherwise it is a key in extended format.
+
+** Names
+
+A name must start with a letter and end with a colon.  Valid
+characters are all ASCII letters, numbers and the hyphen.  Comparison
+of names is done case insensitively.  Names may be used several times
+to represent an array of values.
+
+The name "Key:" is special in that it may occur only once and the
+associated value holds the actual S-expression with the cryptographic
+key.  The S-expression is formatted using the 'Advanced Format'
+(GCRYSEXP_FMT_ADVANCED) that avoids non-printable characters so that
+the file can be easily inspected and edited.  See section 'Private Key
+Format' below for details.
+
+** Values
+
+Values are UTF-8 encoded strings.  Values can be wrapped at any point,
+and continued in the next line indicated by leading whitespace.  A
+continuation line with one leading space does not introduce a blank so
+that the lines can be effectively concatenated.  A blank line as part
+of a continuation line encodes a newline.
+
+** Comments
+
+Lines containing only whitespace, and lines starting with whitespace
+followed by '#' are considered to be comments and are ignored.
+
+* Private Key Format
+** Unprotected Private Key Format
 
-Unprotected Private Key Format
-==============================
 The content of the file is an S-Expression like the ones used with
 Libgcrypt.  Here is an example of an unprotected file:
 
@@ -30,33 +94,20 @@ Libgcrypt.  Here is an example of an unprotected file:
   (q #00f7a7c..[some bytes not shown]..61#)
   (u #304559a..[some bytes not shown]..9b#)
  )
+ (created-at timestamp)
  (uri http://foo.bar x-foo:whatever_you_want)
  (comment whatever)
 )
 
-"comment" and "uri" are optional.  "comment" is currently used to keep
-track of ssh key comments.
+"comment", "created-at" and "uri" are optional.  "comment" is
+currently used to keep track of ssh key comments. "created-at" is used
+to keep track of the creation time stamp used with OpenPGP keys; it is
+optional but required for some operations to calculate the fingerprint
+of the key.  This timestamp should be a string with the number of
+seconds since Epoch or an ISO time string (yyyymmddThhmmss).
 
-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[3]:
+** Protected Private Key Format
 
-(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#)
-   )
-   (uri http://foo.bar x-foo:whatever_you_want)
-)  
-
-
-Protected Private Key Format
-==============================
 A protected key is like this:
 
 (protected-private-key
@@ -64,70 +115,148 @@ A protected key is like this:
     (n #00e0ce9..[some bytes not shown]..51#)
     (e #010001#)
     (protected mode (parms) encrypted_octet_string)
+    (protected-at <isotimestamp>)
    )
    (uri http://foo.bar x-foo:whatever_you_want)
    (comment whatever)
-)  
+)
 
 
 In this scheme the encrypted_octet_string is encrypted according to
 the algorithm described after the keyword protected; 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.
+list of the secret key parameters.  The protected-at expression is
+optional; the isotimestamp is 15 bytes long (e.g. "19610711T172000").
 
-The only available protection mode for now is
+The currently defined protection modes are:
 
-  openpgp-s2k3-sha1-aes-cbc
+*** openpgp-s2k3-sha1-aes-cbc
 
-which describes an algorithm using using AES in CBC mode for
-encryption, SHA-1 for integrity protection and the String to Key
-algorithm 3 from OpenPGP (rfc2440).
+  This describes an algorithm using using AES in CBC mode for
+  encryption, SHA-1 for integrity protection and the String to Key
+  algorithm 3 from OpenPGP (rfc4880).
 
-Example:
+  Example:
 
-(protected openpgp-s2k3-sha1-aes-cbc
-  ((sha1 16byte_salt no_of_iterations) 16byte_iv)
-  encrypted_octet_string
-)
+  (protected openpgp-s2k3-sha1-aes-cbc
+    ((sha1 16byte_salt no_of_iterations) 16byte_iv)
+    encrypted_octet_string
+  )
 
-The encrypted_octet string should yield this S-Exp (in canonical
-representation) after decryption:
+  The encrypted_octet string should yield this S-Exp (in canonical
+  representation) after decryption:
 
-(
- (
-  (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#) 
- ) 
- (hash sha1 #...[hashvalue]...#)
-)
+  (
+   (
+    (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#)
+   )
+   (hash sha1 #...[hashvalue]...#)
+  )
+
+  For padding reasons, random bytes are appended to this list - they can
+  easily be stripped by looking for the end of the list.
+
+  The hash is calculated on the concatenation of the public key and
+  secret key parameter lists: i.e. it is required to hash the
+  concatenation of these 6 canonical encoded lists for RSA, including
+  the parenthesis, the algorithm keyword and (if used) the protected-at
+  list.
+
+  (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#)
+   (protected-at "18950523T000000")
+  )
+
+  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.
+
+*** openpgp-s2k3-ocb-aes
+
+  This describes an algorithm using using AES-128 in OCB mode, a nonce
+  of 96 bit, a taglen of 128 bit, and the String to Key algorithm 3
+  from OpenPGP (rfc4880).
+
+  Example:
+
+  (protected openpgp-s2k3-ocb-aes
+    ((sha1 16byte_salt no_of_iterations) 12byte_nonce)
+    encrypted_octet_string
+  )
+
+  The encrypted_octet string should yield this S-Exp (in canonical
+  representation) after decryption:
+
+  (
+   (
+    (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 hash is calculated on the concatenation of the public key and
-secret key parameter lists: i.e it is required to hash the
-concatenation of these 6 canonical encoded lists for RSA, including
-the parenthesis and the algorithm keyword.
-
-(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#)
-)
+  For padding reasons, random bytes may be appended to this list -
+  they can easily be stripped by looking for the end of the list.
+
+  The associated data required for this protection mode is the list
+  formiing the public key parameters.  For the above example this is
+  is this canonical encoded S-expression:
+
+  (rsa
+   (n #00e0ce9..[some bytes not shown]..51#)
+   (e #010001#)
+   (protected-at "18950523T000000")
+  )
+
+*** openpgp-native
 
-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.
+  This is a wrapper around the OpenPGP Private Key Transport format
+  which resembles the standard OpenPGP format and allows the use of an
+  existing key without re-encrypting to the default protection format.
 
+  Example:
+
+  (protected openpgp-native
+    (openpgp-private-key
+     (version V)
+     (algo PUBKEYALGO)
+     (skey _ P1 _ P2 _ P3 ... e PN)
+     (csum n)
+     (protection PROTTYPE PROTALGO IV S2KMODE S2KHASH S2KSALT S2KCOUNT)))
+
+  Note that the public key paramaters in SKEY are duplicated and
+  should be identical to their copies in the standard parameter
+  elements.  Here is an example of an entire protected private key
+  using this format:
+
+  (protected-private-key
+   (rsa
+    (n #00e0ce9..[some bytes not shown]..51#)
+    (e #010001#)
+    (protected openpgp-native
+     (openpgp-private-key
+      (version 4)
+      (algo rsa)
+      (skey _ #00e0ce9..[some bytes not shown]..51#
+            _ #010001#
+            e #.........................#)
+      (protection sha1 aes #aabbccddeeff00112233445566778899#
+                  3 sha1 #2596f93e85f41e53# 3:190))))
+   (uri http://foo.bar x-foo:whatever_you_want)
+   (comment whatever))
+
+** Shadowed Private Key Format
 
-Shadowed Private Key Format
-============================
 To keep track of keys stored on IC cards we use a third format for
 private kyes which are called shadow keys as they are only a reference
 to keys stored on a token:
@@ -140,22 +269,149 @@ to keys stored on a token:
    )
    (uri http://foo.bar x-foo:whatever_you_want)
    (comment whatever)
-)  
+)
 
 The currently used protocol is "ti-v1" (token info version 1).  The
 second list with the information has this layout:
 
-(card_serial_number id_string_of_key)
+(card_serial_number id_string_of_key fixed_pin_length)
+
+FIXED_PIN_LENGTH is optional.  It can be used to store the length of
+the PIN; a value of 0 indicates that this information is not
+available.  The rationale for this field is that some pinpad equipped
+readers don't allow passing a variable length PIN.
 
 More items may be added to the list.
 
+** OpenPGP Private Key Transfer Format
+
+This format is used to transfer keys between gpg and gpg-agent.
+
+(openpgp-private-key
+  (version V)
+  (algo PUBKEYALGO)
+  (curve CURVENAME)
+  (skey _ P1 _ P2 _ P3 ... e PN)
+  (csum n)
+  (protection PROTTYPE PROTALGO IV S2KMODE S2KHASH S2KSALT S2KCOUNT))
+
+
+ * V is the packet version number (3 or 4).
+ * PUBKEYALGO is a Libgcrypt algo name
+ * CURVENAME is the name of the curve - only used with ECC.
+ * P1 .. PN are the parameters; the public parameters are never encrypted
+   the secrect key parameters are encrypted if the "protection" list is
+   given.  To make this more explicit each parameter is preceded by a
+   flag "_" for cleartext or "e" for encrypted text.
+ * CSUM is the deprecated 16 bit checksum as defined by OpenPGP.  This
+   is an optional element.
+ * If PROTTYPE is "sha1" the new style SHA1 checksum is used if it is "sum"
+   the old 16 bit checksum (above) is used and if it is "none" no
+   protection at all is used.
+ * PROTALGO is a Libgcrypt style cipher algorithm name
+ * IV is the initialization verctor.
+ * S2KMODE is the value from RFC-4880.
+ * S2KHASH is a a libgcrypt style hash algorithm identifier.
+ * S2KSALT is the 8 byte salt
+ * S2KCOUNT is the count value from RFC-4880.
+
+** Persistent Passphrase Format
+
+Note: That this has not yet been implemented.
+
+To allow persistent storage of cached passphrases we use a scheme
+similar to the private-key storage format.  This is a master
+passphrase format where each file may protect several secrets under
+one master passphrase.  It is possible to have several of those files
+each protected by a dedicated master passphrase.  Clear text keywords
+allow to list the available protected passphrases.
+
+The name of the files with these protected secrets have this form:
+pw-<string>.dat.  STRING may be an arbitrary string, as a default name
+for the passphrase storage the name "pw-default.dat" is suggested.
+
+
+(protected-shared-secret
+   ((desc descriptive_text)
+    (key [key_1] (keyword_1 keyword_2 keyword_n))
+    (key [key_2] (keyword_21 keyword_22 keyword_2n))
+    (key [key_n] (keyword_n1 keyword_n2 keyword_nn))
+    (protected mode (parms) encrypted_octet_string)
+    (protected-at <isotimestamp>)
+   )
+)
+
+After decryption the encrypted_octet_string yields this S-expression:
+
+(
+ (
+  (value key_1 value_1)
+  (value key_2 value_2)
+  (value key_n value_n)
+ )
+ (hash sha1 #...[hashvalue]...#)
+)
+
+The "descriptive_text" is displayed with the prompt to enter the
+unprotection passphrase.
+
+KEY_1 to KEY_N are unique identifiers for the shared secret, for
+example an URI.  In case this information should be kept confidential
+as well, they may not appear in the unprotected part; however they are
+mandatory in the encrypted_octet_string.  The list of keywords is
+optional.  The oder of the "key" lists and the order of the "value"
+lists mut match, that is the first "key"-list is associated with the
+first "value" list in the encrypted_octet_string.
+
+The protection mode etc. is indentical to the protection mode as
+decribed for the private key format.
+
+list of the secret key parameters.  The protected-at expression is
+optional; the isotimestamp is 15 bytes long (e.g. "19610711T172000").
+
+The "hash" in the encrypted_octet_string is calculated on the
+concatenation of the key list and value lists: i.e it is required to
+hash the concatenation of all these lists, including the
+parenthesis and (if used) the protected-at list.
+
+Example:
+
+(protected-shared-secret
+   ((desc "List of system passphrases")
+    (key "uid-1002" ("Knuth" "Donald Ervin Knuth"))
+    (key "uid-1001" ("Dijkstra" "Edsgar Wybe Dijkstra"))
+    (key)
+    (protected mode (parms) encrypted_octet_string)
+    (protected-at "20100915T111722")
+   )
+)
 
+with "encrypted_octet_string" decoding to:
 
+(
+ (
+  (value 4:1002 "signal flags at the lock")
+  (value 4:1001 "taocp")
+  (value 1:0    "premature optimization is the root of all evil")
+ )
+ (hash sha1 #0102030405060708091011121314151617181920#)
+)
 
+To compute the hash this S-expression (in canoncical format) was
+hashed:
+
+   ((desc "List of system passphrases")
+    (key "uid-1002" ("Knuth" "Donald Ervin Knuth"))
+    (key "uid-1001" ("Dijkstra" "Edsgar Wybe Dijkstra"))
+    (key)
+    (value 4:1002 "signal flags at the lock")
+    (value 4:1001 "taocp")
+    (value 1:0    "premature optimization is the root of all evil")
+    (protected-at "20100915T111722")
+   )
 
+* Notes
 
-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.