From 0988e49c45d0fb73d0b536aa027bd114f9dc65a7 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 7 Sep 2022 10:34:05 +0200 Subject: [PATCH] gpg: Support key flags for RENC, TIME, and GROUP. * g10/packet.h (PUBKEY_USAGE_RENC): New. (PUBKEY_USAGE_TIME): New. (PUBKEY_USAGE_GROUP): New. * g10/getkey.c (parse_key_usage): Set the new key flags. * g10/keyedit.c (show_key_with_all_names_colon): Show the new key flags. * g10/keyid.c (usagestr_from_pk): Ditto * g10/keylist.c (print_capabilities): Ditto. * g10/keygen.c (parse_usagestr): Parse line and set new flags. (quickgen_set_para): Show flags. -- See draft-koch-openpgp-2015-rfc4880bis-00 for the current version. Actually these flags have been in the draft for years now. This patch is a first step to make use of them. --- doc/DETAILS | 17 +++++++++++++++++ g10/getkey.c | 18 ++++++++++++++++++ g10/keyedit.c | 6 ++++++ g10/keygen.c | 15 ++++++++++++--- g10/keyid.c | 7 +++++++ g10/keylist.c | 7 +++++++ g10/packet.h | 3 +++ 7 files changed, 70 insertions(+), 3 deletions(-) diff --git a/doc/DETAILS b/doc/DETAILS index 028e68ba9..378387934 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -193,6 +193,9 @@ described here. - s :: Sign - c :: Certify - a :: Authentication + - r :: Restricted encryption (subkey only use) + - t :: Timestamping + - g :: Group key - ? :: Unknown capability A key may have any combination of them in any order. In addition @@ -1688,6 +1691,20 @@ Description of some debug flags: calculate a RMD160 hash value from it. This is used as the fingerprint and the low 64 bits are the keyid. +** gnupg.org notations + + - adsk@gnupg.org :: Additional decryption subkey. This notation + gives a list of keys an implementation SHOULD + also encrypt to. The data consists of an array + of eight-octet numbers holding the Key ID of an + encryption subkey. This notation is only valid + on an encryption subkey (i.e. with first octet + of the key flags 0x04 or 0x08). Subkeys not on + the same keyblock MUST NOT be considered. For + interoperability this notation SHOULD NOT be + marked as criticial. Due to its nature it MUST + NOT be marked as human readable. + ** Simplified revocation certificates Revocation certificates consist only of the signature packet; "--import" knows how to handle this. The rationale behind it is to diff --git a/g10/getkey.c b/g10/getkey.c index e49718e68..3772a8505 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -2457,11 +2457,29 @@ parse_key_usage (PKT_signature * sig) flags &= ~0x20; } + if ((flags & 0x80)) + { + key_usage |= PUBKEY_USAGE_GROUP; + flags &= ~0x80; + } + if (flags) key_usage |= PUBKEY_USAGE_UNKNOWN; + n--; + p++; + if (n) + { + flags = *p; + if ((flags & 0x04)) + key_usage |= PUBKEY_USAGE_RENC; + if ((flags & 0x08)) + key_usage |= PUBKEY_USAGE_TIME; + } + if (!key_usage) key_usage |= PUBKEY_USAGE_NONE; + } else if (p) /* Key flags of length zero. */ key_usage |= PUBKEY_USAGE_NONE; diff --git a/g10/keyedit.c b/g10/keyedit.c index e4c754fae..2f7263ec6 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -3610,6 +3610,12 @@ show_key_with_all_names_colon (ctrl_t ctrl, estream_t fp, kbnode_t keyblock) es_putc ('c', fp); if ((pk->pubkey_usage & PUBKEY_USAGE_AUTH)) es_putc ('a', fp); + if ((pk->pubkey_usage & PUBKEY_USAGE_RENC)) + es_putc ('r', fp); + if ((pk->pubkey_usage & PUBKEY_USAGE_TIME)) + es_putc ('t', fp); + if ((pk->pubkey_usage & PUBKEY_USAGE_GROUP)) + es_putc ('g', fp); es_putc ('\n', fp); print_fingerprint (ctrl, fp, pk, 0); diff --git a/g10/keygen.c b/g10/keygen.c index 7f3ed8ccb..4bf0995eb 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -3929,6 +3929,12 @@ parse_usagestr (const char *usagestr) use |= PUBKEY_USAGE_AUTH; else if (!ascii_strcasecmp (s, "cert")) use |= PUBKEY_USAGE_CERT; + else if (!ascii_strcasecmp (s, "renc")) + use |= PUBKEY_USAGE_RENC; + else if (!ascii_strcasecmp (s, "time")) + use |= PUBKEY_USAGE_TIME; + else if (!ascii_strcasecmp (s, "group")) + use |= PUBKEY_USAGE_GROUP; else { xfree (tokens); @@ -4499,14 +4505,17 @@ quickgen_set_para (struct para_data_s *para, int for_subkey, { struct para_data_s *r; - r = xmalloc_clear (sizeof *r + 30); + r = xmalloc_clear (sizeof *r + 50); r->key = for_subkey? pSUBKEYUSAGE : pKEYUSAGE; if (use) - snprintf (r->u.value, 30, "%s%s%s%s", + snprintf (r->u.value, 30, "%s%s%s%s%s%s%s", (use & PUBKEY_USAGE_ENC)? "encr " : "", (use & PUBKEY_USAGE_SIG)? "sign " : "", (use & PUBKEY_USAGE_AUTH)? "auth " : "", - (use & PUBKEY_USAGE_CERT)? "cert " : ""); + (use & PUBKEY_USAGE_CERT)? "cert " : "", + (use & PUBKEY_USAGE_RENC)? "renc " : "", + (use & PUBKEY_USAGE_TIME)? "time " : "", + (use & PUBKEY_USAGE_GROUP)?"group ": ""); else strcpy (r->u.value, for_subkey ? "encr" : "sign"); r->next = para; diff --git a/g10/keyid.c b/g10/keyid.c index cf459a192..ca6564c5c 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -808,6 +808,13 @@ usagestr_from_pk (PKT_public_key *pk, int fill) if ( (use & PUBKEY_USAGE_AUTH) ) buffer[i++] = 'A'; + if ( (use & PUBKEY_USAGE_RENC) ) + buffer[i++] = 'R'; + if ( (use & PUBKEY_USAGE_TIME) ) + buffer[i++] = 'T'; + if ( (use & PUBKEY_USAGE_GROUP) ) + buffer[i++] = 'G'; + while (fill && i < 4) buffer[i++] = ' '; diff --git a/g10/keylist.c b/g10/keylist.c index 76eed6a78..e785aa0b9 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -802,6 +802,13 @@ print_capabilities (ctrl_t ctrl, PKT_public_key *pk, KBNODE keyblock) if ((use & PUBKEY_USAGE_AUTH)) es_putc ('a', es_stdout); + if (use & PUBKEY_USAGE_RENC) + es_putc ('r', es_stdout); + if ((use & PUBKEY_USAGE_TIME)) + es_putc ('t', es_stdout); + if ((use & PUBKEY_USAGE_GROUP)) + es_putc ('g', es_stdout); + if ((use & PUBKEY_USAGE_UNKNOWN)) es_putc ('?', es_stdout); diff --git a/g10/packet.h b/g10/packet.h index 5a14015a1..eeea9b450 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -56,6 +56,9 @@ | GCRY_PK_USAGE_AUTH | GCRY_PK_USAGE_UNKN) >= 256 # error Please choose another value for PUBKEY_USAGE_NONE #endif +#define PUBKEY_USAGE_RENC 512 /* Restricted encryption. */ +#define PUBKEY_USAGE_TIME 1024 /* Timestamp use. */ +#define PUBKEY_USAGE_GROUP 512 /* Group flag. */ /* Helper macros. */ #define is_RSA(a) ((a)==PUBKEY_ALGO_RSA || (a)==PUBKEY_ALGO_RSA_E \