From 6737e07a9b04064947ae37abd28b845a09abee22 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 11 Apr 2024 08:27:53 +0200 Subject: doc: Move keyformat.txt to here. -- --- agent/keyformat.txt | 520 ---------------------------------------------------- doc/Makefile.am | 2 +- doc/keyformat.txt | 520 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 521 insertions(+), 521 deletions(-) delete mode 100644 agent/keyformat.txt create mode 100644 doc/keyformat.txt diff --git a/agent/keyformat.txt b/agent/keyformat.txt deleted file mode 100644 index dadfed4eb..000000000 --- a/agent/keyformat.txt +++ /dev/null @@ -1,520 +0,0 @@ -keyformat.txt emacs, please switch to -*- org -*- mode -------------- - - -Some notes on the format of the secret keys used with gpg-agent. - -* 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 - - 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] and suffixed with ".key". - -* Extended Private Key Format - -** Overview -GnuPG 2.3+ uses 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. - Token: D2760001240102000005000011730000 OPENPGP.1 - - Token: FF020001008A77C1 PIV.9C - - 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 also able to read and write keys using the new format -However, it only makes use of some of the values. - -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. Note that the name "Key" is special -in that it is mandatory and must occur only once. - -*** 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. - -** Well known names -*** Description -This is a human readable string describing the key. - -*** Key -The name "Key" is special in that it is mandatory and must occur only -once. 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. - -*** Created -The UTC time the key was created in ISO compressed format -(yyyymmddThhmmss). This information can be used to re-create an -OpenPGP key. - -*** Label -This is a short human readable description for the key which can be -used by the software to describe the key in a user interface. For -example as part of the description in a prompt for a PIN or -passphrase. It is often used instead of a comment element as present -in the S-expression of the "Key" item. - -*** OpenSSH-cert -This takes a base64 encoded string wrapped so that this -key file can be easily edited with a standard editor. Several of such -items can be used. - -*** Token -If such an item exists it overrides the info given by the "shadow" -parameter in the S-expression. Using this item makes it possible to -describe a key which is stored on several tokens and also makes it -easy to update this info using a standard editor. The syntax is -similar to the "shadow" parameter: - -- Serialnumber of the token. -- Key reference from the token in full format (e.g. "OpenPGP.2"). -- An optional fixed length of the PIN or "-". -- The human readable serial number of a card. This is usually what is - printed on the actual card. This value is taken directly from the - card but when asking to insert a card it is useful to have this - value available. GnuPG takes care of creating and possibly updating - this entry. This is percent-plus-escaped. - - -*** Use-for-ssh -If given and the value is "yes" or "1" the key is allowed for use by -gpg-agent's ssh-agent implementation. This is thus the same as -putting the keygrip into the 'sshcontrol' file. Only one such item -should exist. If another non-zero value between 1 and 99999 is used, -this is taken to establish the order in which the keys are returned to -ssh; lower numbers are returned first. If a negative value is used -this overrides currently active (inserted) cards and thus allows to -prefer on-disk keys over inserted cards. A value of -1 has the -highest priority; values are capped at -999 and have a lower priority -but still above the positive values, inserted cards or the order in -sshcontrol. - - -*** Use-for-p11 -If given and the value is "yes" or "1" the key is allowed for use by -GnuPG's PKCS#11 interface (Scute). Note that Scute needs to be -configured to use this optimization. - -*** Remote-list -Allow to list the key with the KEYINFO command from a remote machine -via the extra socket. A boolean value is expected; the default is -"no". Note that KEYINFO will anyway provide information if the -keygrip is specified. - -*** Confirm -If given and the value is "yes", a user will be asked confirmation by -a dialog window when the key is about to be used for -PKSIGN/PKAUTH/PKDECRYPT operation. If the value is "restricted", it -is only asked for the access through extra/browser socket. - -*** Prompt -This field is for card key. If given and the value is "yes" -(default), a user will be prompted about insertion of the card by a -dialog window when card is not available. When the value is "no", a -card operation is refused with GPG_ERR_UNUSABLE_SECKEY error. - -*** Backup-info -This gives information for a backup of the key. The following fields -are space delimited: - -- Hexified keygrip (uppercase) to make it easy to identify the - filename. When restoring software should make sure that the keygrip - matches the one derived from the "Key" field. -- Backup time in as ISO string. -- Name of the backup software. -- Arbitrary information. - -* 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: - -(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#) - ) - (created-at timestamp) - (uri http://foo.bar x-foo:whatever_you_want) - (comment whatever) -) - -"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). - -** Protected Private Key Format - -A protected key is like this: - -(protected-private-key - (rsa - (n #00e0ce9..[some bytes not shown]..51#) - (e #010001#) - (protected mode (parms) encrypted_octet_string) - (protected-at ) - ) - (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. The protected-at expression is -optional; the isotimestamp is 15 bytes long (e.g. "19610711T172000"). - -The currently defined protection modes are: - -*** openpgp-s2k3-sha1-aes-cbc - - This describes an algorithm using AES in CBC mode for - encryption, SHA-1 for integrity protection and the String to Key - algorithm 3 from OpenPGP (rfc4880). - - Example: - - (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: - - ( - ( - (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 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 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 - forming 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 - - 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 parameters 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 - -To keep track of keys stored on IC cards we use a third format for -private keys which are called shadow keys as they are only a reference -to keys stored on a token: - -(shadowed-private-key - (rsa - (n #00e0ce9..[some bytes not shown]..51#) - (e #010001#) - (shadowed protocol (info)) - ) - (uri http://foo.bar x-foo:whatever_you_want) - (comment whatever) -) - -The currently used protocols are "t1-v1" (token info version 1) and -"tpm2-v1" (TPM format key information). The second list with the -information has this layout for "t1-v1": - -(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. - -This is the (info) layout for "tpm2-v1": - -(parent tpm_private_string tpm_public_string) - -Although this precise format is encapsulated inside the tpm2daemon -itself and nothing in gpg ever uses this. - -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 secret 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 vector. - * S2KMODE is the value from RFC-4880. - * S2KHASH is 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 listing the available protected passphrases. - -The name of the files with these protected secrets have this form: -pw-.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 ) - ) -) - -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 order of the "key" lists and the order of the "value" -lists must match, that is the first "key"-list is associated with the -first "value" list in the encrypted_octet_string. - -The protection mode etc. is identical to the protection mode as -described 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" "Edsger 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 canonical format) was -hashed: - - ((desc "List of system passphrases") - (key "uid-1002" ("Knuth" "Donald Ervin Knuth")) - (key "uid-1001" ("Dijkstra" "Edsger 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 - -[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 used with -different protocols. PKCS-15 calls this a subjectKeyHash; it can be -calculated using Libgcrypt's gcry_pk_get_keygrip (). - -[3] Even when canonical representation are required we will show the -S-expression here in a more readable representation. diff --git a/doc/Makefile.am b/doc/Makefile.am index 390153c76..66a934cef 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -42,7 +42,7 @@ EXTRA_DIST = samplekeys.asc mksamplekeys com-certs.pem \ FAQ gnupg7.texi mkdefsinc.c defsincdate \ opt-homedir.texi see-also-note.texi specify-user-id.texi \ gpgv.texi yat2m.c ChangeLog-2011 whats-new-in-2.1.txt \ - trust-values.texi + trust-values.texi keyformat.txt BUILT_SOURCES = gnupg-module-overview.png gnupg-module-overview.pdf \ gnupg-card-architecture.png gnupg-card-architecture.pdf \ diff --git a/doc/keyformat.txt b/doc/keyformat.txt new file mode 100644 index 000000000..dadfed4eb --- /dev/null +++ b/doc/keyformat.txt @@ -0,0 +1,520 @@ +keyformat.txt emacs, please switch to -*- org -*- mode +------------- + + +Some notes on the format of the secret keys used with gpg-agent. + +* 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 + + 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] and suffixed with ".key". + +* Extended Private Key Format + +** Overview +GnuPG 2.3+ uses 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. + Token: D2760001240102000005000011730000 OPENPGP.1 - + Token: FF020001008A77C1 PIV.9C - + 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 also able to read and write keys using the new format +However, it only makes use of some of the values. + +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. Note that the name "Key" is special +in that it is mandatory and must occur only once. + +*** 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. + +** Well known names +*** Description +This is a human readable string describing the key. + +*** Key +The name "Key" is special in that it is mandatory and must occur only +once. 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. + +*** Created +The UTC time the key was created in ISO compressed format +(yyyymmddThhmmss). This information can be used to re-create an +OpenPGP key. + +*** Label +This is a short human readable description for the key which can be +used by the software to describe the key in a user interface. For +example as part of the description in a prompt for a PIN or +passphrase. It is often used instead of a comment element as present +in the S-expression of the "Key" item. + +*** OpenSSH-cert +This takes a base64 encoded string wrapped so that this +key file can be easily edited with a standard editor. Several of such +items can be used. + +*** Token +If such an item exists it overrides the info given by the "shadow" +parameter in the S-expression. Using this item makes it possible to +describe a key which is stored on several tokens and also makes it +easy to update this info using a standard editor. The syntax is +similar to the "shadow" parameter: + +- Serialnumber of the token. +- Key reference from the token in full format (e.g. "OpenPGP.2"). +- An optional fixed length of the PIN or "-". +- The human readable serial number of a card. This is usually what is + printed on the actual card. This value is taken directly from the + card but when asking to insert a card it is useful to have this + value available. GnuPG takes care of creating and possibly updating + this entry. This is percent-plus-escaped. + + +*** Use-for-ssh +If given and the value is "yes" or "1" the key is allowed for use by +gpg-agent's ssh-agent implementation. This is thus the same as +putting the keygrip into the 'sshcontrol' file. Only one such item +should exist. If another non-zero value between 1 and 99999 is used, +this is taken to establish the order in which the keys are returned to +ssh; lower numbers are returned first. If a negative value is used +this overrides currently active (inserted) cards and thus allows to +prefer on-disk keys over inserted cards. A value of -1 has the +highest priority; values are capped at -999 and have a lower priority +but still above the positive values, inserted cards or the order in +sshcontrol. + + +*** Use-for-p11 +If given and the value is "yes" or "1" the key is allowed for use by +GnuPG's PKCS#11 interface (Scute). Note that Scute needs to be +configured to use this optimization. + +*** Remote-list +Allow to list the key with the KEYINFO command from a remote machine +via the extra socket. A boolean value is expected; the default is +"no". Note that KEYINFO will anyway provide information if the +keygrip is specified. + +*** Confirm +If given and the value is "yes", a user will be asked confirmation by +a dialog window when the key is about to be used for +PKSIGN/PKAUTH/PKDECRYPT operation. If the value is "restricted", it +is only asked for the access through extra/browser socket. + +*** Prompt +This field is for card key. If given and the value is "yes" +(default), a user will be prompted about insertion of the card by a +dialog window when card is not available. When the value is "no", a +card operation is refused with GPG_ERR_UNUSABLE_SECKEY error. + +*** Backup-info +This gives information for a backup of the key. The following fields +are space delimited: + +- Hexified keygrip (uppercase) to make it easy to identify the + filename. When restoring software should make sure that the keygrip + matches the one derived from the "Key" field. +- Backup time in as ISO string. +- Name of the backup software. +- Arbitrary information. + +* 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: + +(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#) + ) + (created-at timestamp) + (uri http://foo.bar x-foo:whatever_you_want) + (comment whatever) +) + +"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). + +** Protected Private Key Format + +A protected key is like this: + +(protected-private-key + (rsa + (n #00e0ce9..[some bytes not shown]..51#) + (e #010001#) + (protected mode (parms) encrypted_octet_string) + (protected-at ) + ) + (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. The protected-at expression is +optional; the isotimestamp is 15 bytes long (e.g. "19610711T172000"). + +The currently defined protection modes are: + +*** openpgp-s2k3-sha1-aes-cbc + + This describes an algorithm using AES in CBC mode for + encryption, SHA-1 for integrity protection and the String to Key + algorithm 3 from OpenPGP (rfc4880). + + Example: + + (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: + + ( + ( + (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 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 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 + forming 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 + + 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 parameters 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 + +To keep track of keys stored on IC cards we use a third format for +private keys which are called shadow keys as they are only a reference +to keys stored on a token: + +(shadowed-private-key + (rsa + (n #00e0ce9..[some bytes not shown]..51#) + (e #010001#) + (shadowed protocol (info)) + ) + (uri http://foo.bar x-foo:whatever_you_want) + (comment whatever) +) + +The currently used protocols are "t1-v1" (token info version 1) and +"tpm2-v1" (TPM format key information). The second list with the +information has this layout for "t1-v1": + +(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. + +This is the (info) layout for "tpm2-v1": + +(parent tpm_private_string tpm_public_string) + +Although this precise format is encapsulated inside the tpm2daemon +itself and nothing in gpg ever uses this. + +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 secret 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 vector. + * S2KMODE is the value from RFC-4880. + * S2KHASH is 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 listing the available protected passphrases. + +The name of the files with these protected secrets have this form: +pw-.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 ) + ) +) + +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 order of the "key" lists and the order of the "value" +lists must match, that is the first "key"-list is associated with the +first "value" list in the encrypted_octet_string. + +The protection mode etc. is identical to the protection mode as +described 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" "Edsger 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 canonical format) was +hashed: + + ((desc "List of system passphrases") + (key "uid-1002" ("Knuth" "Donald Ervin Knuth")) + (key "uid-1001" ("Dijkstra" "Edsger 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 + +[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 used with +different protocols. PKCS-15 calls this a subjectKeyHash; it can be +calculated using Libgcrypt's gcry_pk_get_keygrip (). + +[3] Even when canonical representation are required we will show the +S-expression here in a more readable representation. -- cgit v1.2.3