diff options
| author | Werner Koch <[email protected]> | 2020-03-13 16:14:34 +0000 |
|---|---|---|
| committer | Werner Koch <[email protected]> | 2020-03-13 16:14:34 +0000 |
| commit | 6a4443c8425fd548020553b22d5a16ffad98371f (patch) | |
| tree | 75da2b6c4ce956ef3923abef180ba079a40d770e /g10/getkey.c | |
| parent | gpg: New option --include-key-block. (diff) | |
| download | gnupg-6a4443c8425fd548020553b22d5a16ffad98371f.tar.gz gnupg-6a4443c8425fd548020553b22d5a16ffad98371f.zip | |
gpg: Make use of the included key block in a signature.
* g10/import.c (read_key_from_file): Rename to ...
(read_key_from_file_or_buffer): this and add new parameters. Adjust
callers.
(import_included_key_block): New.
* g10/packet.h (PKT_signature): Add field flags.key_block.
* g10/parse-packet.c (parse_signature): Set that flags.
* g10/sig-check.c (check_signature2): Add parm forced_pk and change
all callers.
* g10/mainproc.c (do_check_sig): Ditto.
(check_sig_and_print): Try the included key block if no key is
available.
--
This is is the second part to support the new Key Block subpacket.
The idea is that after having received a signed mail, it is instantly
possible to reply encrypted - without the need for any centralized
infrastructure.
There is one case where this does not work: A signed mail is received
using a specified signer ID (e.g. using gpg --sender option) and the
key block with only that user ID is thus imported. The next time a
mail is received using the same key but with a different user ID; the
signatures checks out using the key imported the last time. However,
the new user id is not imported. Now when trying to reply to that
last mail, no key will be found. We need to see whether we can update
a key in such a case.
GnuPG-bug-id: 4856
Signed-off-by: Werner Koch <[email protected]>
Diffstat (limited to 'g10/getkey.c')
| -rw-r--r-- | g10/getkey.c | 64 |
1 files changed, 61 insertions, 3 deletions
diff --git a/g10/getkey.c b/g10/getkey.c index 0349a3858..4b31b8468 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -309,13 +309,21 @@ pk_from_block (PKT_public_key *pk, kbnode_t keyblock, kbnode_t found_key) /* Specialized version of get_pubkey which retrieves the key based on - * information in SIG. In contrast to get_pubkey PK is required. */ + * information in SIG. In contrast to get_pubkey PK is required. IF + * FORCED_PK is not NULL, this public key is used and copied to PK. */ gpg_error_t -get_pubkey_for_sig (ctrl_t ctrl, PKT_public_key *pk, PKT_signature *sig) +get_pubkey_for_sig (ctrl_t ctrl, PKT_public_key *pk, PKT_signature *sig, + PKT_public_key *forced_pk) { const byte *fpr; size_t fprlen; + if (forced_pk) + { + copy_public_key (pk, forced_pk); + return 0; + } + /* First try the new ISSUER_FPR info. */ fpr = issuer_fpr_raw (sig, &fprlen); if (fpr && !get_pubkey_byfprint (ctrl, pk, NULL, fpr, fprlen)) @@ -1594,7 +1602,7 @@ get_pubkey_fromfile (ctrl_t ctrl, PKT_public_key *pk, const char *fname) kbnode_t found_key; unsigned int infoflags; - err = read_key_from_file (ctrl, fname, &keyblock); + err = read_key_from_file_or_buffer (ctrl, fname, NULL, 0, &keyblock); if (!err) { /* Warning: node flag bits 0 and 1 should be preserved by @@ -1613,6 +1621,56 @@ get_pubkey_fromfile (ctrl_t ctrl, PKT_public_key *pk, const char *fname) } +/* Return a public key from the buffer (BUFFER, BUFLEN). The key is + * onlyretruned if it matches the keyid given in WANT_KEYID. On + * success the key is stored at the caller provided PKBUF structure. + * The caller must release the content of PK by calling + * release_public_key_parts (or, if PKBUF was malloced, using + * free_public_key). If R_KEYBLOCK is not NULL the full keyblock is + * also stored there. */ +gpg_error_t +get_pubkey_from_buffer (ctrl_t ctrl, PKT_public_key *pkbuf, + const void *buffer, size_t buflen, u32 *want_keyid, + kbnode_t *r_keyblock) +{ + gpg_error_t err; + kbnode_t keyblock; + kbnode_t node; + PKT_public_key *pk; + + if (r_keyblock) + *r_keyblock = NULL; + + err = read_key_from_file_or_buffer (ctrl, NULL, buffer, buflen, &keyblock); + if (!err) + { + merge_selfsigs (ctrl, keyblock); + for (node = keyblock; node; node = node->next) + { + if (node->pkt->pkttype == PKT_PUBLIC_KEY + || node->pkt->pkttype == PKT_PUBLIC_SUBKEY) + { + pk = node->pkt->pkt.public_key; + keyid_from_pk (pk, NULL); + if (pk->keyid[0] == want_keyid[0] + && pk->keyid[1] == want_keyid[1]) + break; + } + } + if (node) + copy_public_key (pkbuf, pk); + else + err = gpg_error (GPG_ERR_NO_PUBKEY); + } + + if (!err && r_keyblock) + *r_keyblock = keyblock; + else + release_kbnode (keyblock); + return err; +} + + /* Lookup a key with the specified fingerprint. * * If PK is not NULL, the public key of the first result is returned |
