1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-03 22:56:33 +02:00

gpg: New option --include-key-block.

* common/openpgpdefs.h (SIGSUBPKT_KEY_BLOCK): New.
* g10/gpg.c (oIncludeKeyBlock): New.
(opts): New option --include-key-block.
(main): Implement.
* g10/options.h (opt): New flag include_key_block.
* g10/parse-packet.c (dump_sig_subpkt): Support SIGSUBPKT_KEY_BLOCK.
(parse_one_sig_subpkt): Ditto.
(can_handle_critical): Ditto.
* g10/sign.c (mk_sig_subpkt_key_block): New.
(write_signature_packets): Call it for data signatures.
--

This patch adds support for a to be proposed OpenPGP ferature:

  Introduce the Key Block subpacket to align OpenPGP with CMS.

  This new subpacket may be used similar to the CertificateSet of
  CMS (RFC-5652) and thus allows to start encrypted communication
  after having received a signed message.  In practice a stripped down
  version of the key should be including having only the key material
  and the self-signatures which are really useful and shall be used by
  the recipient to reply encrypted.

  #### Key Block

  (1 octet with value 0, N octets of key data)

  This subpacket MAY be used to convey key data along with a signature
  of class 0x00, 0x01, or 0x02.  It MUST contain the key used to create
  the signature; either as the primary key or as a subkey.  The key
  SHOULD contain a primary or subkey capable of encryption and the
  entire key must be a valid OpenPGP key including at least one User ID
  packet and the corresponding self-signatures.

  Implementations MUST ignore this subpacket if the first octet does not
  have a value of zero or if the key data does not represent a valid
  transferable public key.

GnuPG-bug-id: 4856
Signed-off-by: Werner Koch <wk@gnupg.org>

Backported from master.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2020-03-13 13:28:35 +01:00
parent 2baa00ea18
commit d79ebee64e
No known key found for this signature in database
GPG key ID: E3FDFF218E45B72B
6 changed files with 147 additions and 11 deletions

View file

@ -185,6 +185,91 @@ mk_notation_policy_etc (PKT_signature *sig,
}
/*
* Put the Key Block subpakcet into SIG for key PKSK. Returns an
* error code on failure.
*/
static gpg_error_t
mk_sig_subpkt_key_block (ctrl_t ctrl, PKT_signature *sig, PKT_public_key *pksk)
{
gpg_error_t err;
char *mbox;
char *filterexp = NULL;
int save_opt_armor = opt.armor;
int save_opt_verbose = opt.verbose;
char hexfpr[2*MAX_FINGERPRINT_LEN + 1];
void *data = NULL;
size_t datalen;
kbnode_t keyblock = NULL;
push_export_filters ();
opt.armor = 0;
hexfingerprint (pksk, hexfpr, sizeof hexfpr);
/* Get the user id so that we know which one to insert into the
* key. */
if (pksk->user_id
&& (mbox = mailbox_from_userid (pksk->user_id->name)))
{
if (DBG_LOOKUP)
log_debug ("including key with UID '%s' (specified)\n", mbox);
filterexp = xasprintf ("keep-uid= -- mbox = %s", mbox);
xfree (mbox);
}
else if (opt.sender_list)
{
/* If --sender was given we use the first one from that list. */
if (DBG_LOOKUP)
log_debug ("including key with UID '%s' (--sender)\n",
opt.sender_list->d);
filterexp = xasprintf ("keep-uid= -- mbox = %s", opt.sender_list->d);
}
else /* Use the primary user id. */
{
if (DBG_LOOKUP)
log_debug ("including key with primary UID\n");
filterexp = xstrdup ("keep-uid= primary -t");
}
if (DBG_LOOKUP)
log_debug ("export filter expression: %s\n", filterexp);
err = parse_and_set_export_filter (filterexp);
if (err)
goto leave;
xfree (filterexp);
filterexp = xasprintf ("drop-subkey= fpr <> %s && usage !~ e", hexfpr);
if (DBG_LOOKUP)
log_debug ("export filter expression: %s\n", filterexp);
err = parse_and_set_export_filter (filterexp);
if (err)
goto leave;
opt.verbose = 0;
err = export_pubkey_buffer (ctrl, hexfpr, EXPORT_MINIMAL|EXPORT_CLEAN,
"", 1, /* Prefix with the reserved byte. */
NULL, &keyblock, &data, &datalen);
opt.verbose = save_opt_verbose;
if (err)
{
log_error ("failed to get to be included key: %s\n", gpg_strerror (err));
goto leave;
}
build_sig_subpkt (sig, SIGSUBPKT_KEY_BLOCK, data, datalen);
leave:
xfree (data);
release_kbnode (keyblock);
xfree (filterexp);
opt.armor = save_opt_armor;
pop_export_filters ();
return err;
}
/*
* Helper to hash a user ID packet.
*/
@ -737,7 +822,7 @@ write_signature_packets (ctrl_t ctrl,
PKT_public_key *pk;
PKT_signature *sig;
gcry_md_hd_t md;
int rc;
gpg_error_t err;
pk = sk_rover->pk;
@ -770,14 +855,18 @@ write_signature_packets (ctrl_t ctrl,
{
build_sig_subpkt_from_sig (sig, pk);
mk_notation_policy_etc (sig, NULL, pk);
if (opt.flags.include_key_block && IS_SIG (sig))
err = mk_sig_subpkt_key_block (ctrl, sig, pk);
else
err = 0;
}
hash_sigversion_to_magic (md, sig);
gcry_md_final (md);
rc = do_sign (ctrl, pk, sig, md, hash_for (pk), cache_nonce, 0);
if (!err)
err = do_sign (ctrl, pk, sig, md, hash_for (pk), cache_nonce, 0);
gcry_md_close (md);
if (!rc)
if (!err)
{
/* Write the packet. */
PACKET pkt;
@ -785,19 +874,19 @@ write_signature_packets (ctrl_t ctrl,
init_packet (&pkt);
pkt.pkttype = PKT_SIGNATURE;
pkt.pkt.signature = sig;
rc = build_packet (out, &pkt);
if (!rc && is_status_enabled())
err = build_packet (out, &pkt);
if (!err && is_status_enabled())
print_status_sig_created (pk, sig, status_letter);
free_packet (&pkt, NULL);
if (rc)
if (err)
log_error ("build signature packet failed: %s\n",
gpg_strerror (rc));
gpg_strerror (err));
}
else
free_seckey_enc (sig);
if (rc)
return rc;
if (err)
return err;
}
return 0;