diff options
author | Ingo Klöcker <[email protected]> | 2024-05-15 08:31:46 +0000 |
---|---|---|
committer | Ingo Klöcker <[email protected]> | 2024-05-21 14:38:59 +0000 |
commit | adadfac997a812699049cd9a5f484cbcabff5bfd (patch) | |
tree | 41b5c964ed1396b20ede6968379708cc21802faf /src | |
parent | tests: Fix segv in t-json.c (diff) | |
download | gpgme-adadfac997a812699049cd9a5f484cbcabff5bfd.tar.gz gpgme-adadfac997a812699049cd9a5f484cbcabff5bfd.zip |
core: Add information about revocation keys to keys
* src/gpgme.h.in (struct _gpgme_revocation_key,
gpgme_revocation_key_t): New.
(struct _gpgme_key): Add fields 'revkeys', '_last_revkey'.
* src/key.c (_gpgme_key_add_rev_key): New.
(gpgme_key_unref): Free revkeys.
* src/keylist.c (keylist_colon_handler): Parse rvk lines.
* src/ops.h (_gpgme_key_add_rev_key): New.
* tests/run-keylist.c (main): Print revocation key info.
--
GnuPG-bug-id: 7118
Diffstat (limited to 'src')
-rw-r--r-- | src/gpgme.h.in | 28 | ||||
-rw-r--r-- | src/key.c | 38 | ||||
-rw-r--r-- | src/keylist.c | 37 | ||||
-rw-r--r-- | src/ops.h | 1 |
4 files changed, 103 insertions, 1 deletions
diff --git a/src/gpgme.h.in b/src/gpgme.h.in index c8eba0a5..eaeb22aa 100644 --- a/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -763,6 +763,28 @@ struct _gpgme_user_id typedef struct _gpgme_user_id *gpgme_user_id_t; +/* A designated revocation key for a key. + * This structure shall be considered read-only and an application + * must not allocate such a structure on its own. */ +struct _gpgme_revocation_key +{ + struct _gpgme_revocation_key *next; + + /* The public key algorithm of the revocation key. */ + gpgme_pubkey_algo_t pubkey_algo; + + /* The fingerprint of the revocation_key in hex digit form. */ + char *fpr; + + /* The class of the revocation key. */ + unsigned int key_class; + + /* True if the revocation key should not be exported. */ + unsigned int sensitive : 1; +}; +typedef struct _gpgme_revocation_key *gpgme_revocation_key_t; + + /* A key from the keyring. * This structure shall be considered read-only and an application * must not allocate such a structure on its own. */ @@ -860,6 +882,12 @@ struct _gpgme_key /* Time of the last refresh of the entire key. 0 if unknown. */ unsigned long last_update; + + /* The revocation keys of the key. */ + gpgme_revocation_key_t revocation_keys; + + /* Internal to GPGME, do not use. */ + gpgme_revocation_key_t _last_revkey; }; typedef struct _gpgme_key *gpgme_key_t; @@ -304,6 +304,35 @@ _gpgme_key_add_sig (gpgme_key_t key, char *src) } +gpgme_error_t +_gpgme_key_add_rev_key (gpgme_key_t key, const char *src) +{ + gpgme_revocation_key_t revkey; + int src_len = src ? strlen (src) : 0; + + assert (key); + /* malloc a buffer for the revocation key and the fingerprint. */ + revkey = malloc (sizeof (*revkey) + src_len + 1); + if (!revkey) + return gpg_error_from_syserror (); + memset (revkey, 0, sizeof *revkey); + + revkey->fpr = ((char *) revkey) + sizeof (*revkey); + if (src) + memcpy (revkey->fpr, src, src_len + 1); + else + revkey->fpr[0] = '\0'; + + if (!key->revocation_keys) + key->revocation_keys = revkey; + if (key->_last_revkey) + key->_last_revkey->next = revkey; + key->_last_revkey = revkey; + + return 0; +} + + /* Acquire a reference to KEY. */ void gpgme_key_ref (gpgme_key_t key) @@ -324,6 +353,7 @@ gpgme_key_unref (gpgme_key_t key) { gpgme_user_id_t uid; gpgme_subkey_t subkey; + gpgme_revocation_key_t revkey; if (!key) return; @@ -392,6 +422,14 @@ gpgme_key_unref (gpgme_key_t key) uid = next_uid; } + revkey = key->revocation_keys; + while (revkey) + { + gpgme_revocation_key_t next = revkey->next; + free (revkey); + revkey = next; + } + free (key->issuer_serial); free (key->issuer_name); free (key->chain_id); diff --git a/src/keylist.c b/src/keylist.c index 1d8c8184..f8dd2962 100644 --- a/src/keylist.c +++ b/src/keylist.c @@ -603,7 +603,7 @@ keylist_colon_handler (void *priv, char *line) enum { RT_NONE, RT_SIG, RT_UID, RT_TFS, RT_SUB, RT_PUB, RT_FPR, RT_FP2, RT_GRP, - RT_SSB, RT_SEC, RT_CRT, RT_CRS, RT_REV, RT_SPK + RT_SSB, RT_SEC, RT_CRT, RT_CRS, RT_REV, RT_SPK, RT_RVK } rectype = RT_NONE; #define NR_FIELDS 20 @@ -669,6 +669,8 @@ keylist_colon_handler (void *priv, char *line) rectype = RT_SSB; else if (!strcmp (field[0], "spk") && key) rectype = RT_SPK; + else if (!strcmp (field[0], "rvk") && key) + rectype = RT_RVK; else rectype = RT_NONE; @@ -1124,6 +1126,39 @@ keylist_colon_handler (void *priv, char *line) keysig->_last_notation = notation; } } + break; + + case RT_RVK: + /* Ignore revocation keys without fingerprint */ + if (fields >= 10 && *field[9]) + { + gpgme_revocation_key_t revkey = NULL; + + err = _gpgme_key_add_rev_key (key, field[9]); + if (err) + return err; + + revkey = key->_last_revkey; + assert (revkey); + + /* Field 4 has the public key algorithm. */ + { + int i = atoi (field[3]); + if (i >= 1 && i < 128) + revkey->pubkey_algo = _gpgme_map_pk_algo (i, ctx->protocol); + } + + /* Field 11 has the class (eg, 0x40 means sensitive). */ + if (fields >= 11 && field[10][0] && field[10][1]) + { + int key_class = _gpgme_hextobyte (field[10]); + if (key_class >= 0) + revkey->key_class = key_class; + if (field[10][2] == 's') + revkey->sensitive = 1; + } + } + break; case RT_NONE: /* Unknown record. */ @@ -145,6 +145,7 @@ gpgme_error_t _gpgme_key_add_subkey (gpgme_key_t key, gpgme_error_t _gpgme_key_append_name (gpgme_key_t key, const char *src, int convert); gpgme_key_sig_t _gpgme_key_add_sig (gpgme_key_t key, char *src); +gpgme_error_t _gpgme_key_add_rev_key (gpgme_key_t key, const char *src); |