aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorIngo Klöcker <[email protected]>2024-05-15 08:31:46 +0000
committerIngo Klöcker <[email protected]>2024-05-21 14:38:59 +0000
commitadadfac997a812699049cd9a5f484cbcabff5bfd (patch)
tree41b5c964ed1396b20ede6968379708cc21802faf /src
parenttests: Fix segv in t-json.c (diff)
downloadgpgme-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.in28
-rw-r--r--src/key.c38
-rw-r--r--src/keylist.c37
-rw-r--r--src/ops.h1
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;
diff --git a/src/key.c b/src/key.c
index 93cdc1c8..fec9eb16 100644
--- a/src/key.c
+++ b/src/key.c
@@ -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. */
diff --git a/src/ops.h b/src/ops.h
index cde63a4e..aa8d9c94 100644
--- a/src/ops.h
+++ b/src/ops.h
@@ -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);