mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-03 22:56:33 +02:00
gpg: New commands --add-recipients and --change-recipients.
* g10/gpg.c (aAddRecipients, aChangeRecipients): New consts. (opts): Add --add-recipients and --change-recipients. (main): Handle them. * g10/gpg.h (struct server_control_s): Add fields modify_recipients, clear_recipients, and last_read_ctb. * g10/armor.c (was_armored): New. * g10/decrypt.c (decrypt_message): Add optional arg 'remusr'. Handle re-encryption if desired. * g10/encrypt.c (write_pubkey_enc): Factor info printing out to ... (show_encrypted_for_user_info): new. (reencrypt_to_new_recipients): New. * g10/packet.h (struct parse_packet_ctx_s): Add fields only_fookey_enc and last_ctb. (init_parse_packet): Clear them. * g10/parse-packet.c (parse): Store CTB in the context. Early return on pubkey_enc and symkey_enc packets if requested. * g10/mainproc.c (proc_encrypted): Allow for PKT being NULL. Return early in modify-recipients mode. (proc_encryption_packets): Add two optional args 'r_dek' and 'r_list'. Adjust callers. Call do_proc_packets in modify-recipients mode depending on the optional args. (do_proc_packets): Add arg 'keep_dek_and_list'. Adjust callers. Save the last read CTB in CTRL and return after the last fooenc_enc packets. -- This basically works but does not yet handle symmetric encrypted packets (symkey_enc). GnuPG-bug-id: 1825 (Yes, this is an at least 9 year old feature request)
This commit is contained in:
parent
2cc340eca0
commit
d528d0b065
11 changed files with 332 additions and 67 deletions
|
@ -116,7 +116,7 @@ static int literals_seen;
|
|||
|
||||
|
||||
/*** Local prototypes. ***/
|
||||
static int do_proc_packets (CTX c, iobuf_t a);
|
||||
static int do_proc_packets (CTX c, iobuf_t a, int keep_dek_and_list);
|
||||
static void list_node (CTX c, kbnode_t node);
|
||||
static void proc_tree (CTX c, kbnode_t node);
|
||||
|
||||
|
@ -580,10 +580,15 @@ proc_encrypted (CTX c, PACKET *pkt)
|
|||
int early_plaintext = literals_seen;
|
||||
unsigned int compliance_de_vs = 0;
|
||||
|
||||
if (pkt->pkttype == PKT_ENCRYPTED_AEAD)
|
||||
c->seen_pkt_encrypted_aead = 1;
|
||||
if (pkt->pkttype == PKT_ENCRYPTED_MDC)
|
||||
c->seen_pkt_encrypted_mdc = 1;
|
||||
if (pkt)
|
||||
{
|
||||
if (pkt->pkttype == PKT_ENCRYPTED_AEAD)
|
||||
c->seen_pkt_encrypted_aead = 1;
|
||||
if (pkt->pkttype == PKT_ENCRYPTED_MDC)
|
||||
c->seen_pkt_encrypted_mdc = 1;
|
||||
}
|
||||
else /* No PKT indicates the the add-recipients mode. */
|
||||
log_assert (c->ctrl->modify_recipients);
|
||||
|
||||
if (early_plaintext)
|
||||
{
|
||||
|
@ -650,6 +655,22 @@ proc_encrypted (CTX c, PACKET *pkt)
|
|||
if (c->dek && opt.verbose > 1)
|
||||
log_info (_("public key encrypted data: good DEK\n"));
|
||||
|
||||
if (c->ctrl->modify_recipients)
|
||||
{
|
||||
if (c->anchor)
|
||||
{
|
||||
log_error ("command not possible with nested data\n");
|
||||
write_status_errcode ("decryption.mod_recp", GPG_ERR_BAD_DATA);
|
||||
xfree (c->dek);
|
||||
c->dek = NULL;
|
||||
return;
|
||||
}
|
||||
literals_seen++;
|
||||
/* Simply return here. Our caller will then test for DEK and
|
||||
* the PK_list to decide whether decryption worked. */
|
||||
return;
|
||||
}
|
||||
|
||||
if (!opt.show_only_session_key)
|
||||
write_status (STATUS_BEGIN_DECRYPTION);
|
||||
|
||||
|
@ -1112,7 +1133,7 @@ static int
|
|||
proc_encrypt_cb (iobuf_t a, void *info )
|
||||
{
|
||||
CTX c = info;
|
||||
return proc_encryption_packets (c->ctrl, info, a );
|
||||
return proc_encryption_packets (c->ctrl, info, a, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1502,7 +1523,7 @@ proc_packets (ctrl_t ctrl, void *anchor, iobuf_t a )
|
|||
|
||||
c->ctrl = ctrl;
|
||||
c->anchor = anchor;
|
||||
rc = do_proc_packets (c, a);
|
||||
rc = do_proc_packets (c, a, 0);
|
||||
xfree (c);
|
||||
|
||||
return rc;
|
||||
|
@ -1525,7 +1546,7 @@ proc_signature_packets (ctrl_t ctrl, void *anchor, iobuf_t a,
|
|||
c->signed_data.used = !!signedfiles;
|
||||
|
||||
c->sigfilename = sigfilename;
|
||||
rc = do_proc_packets (c, a);
|
||||
rc = do_proc_packets (c, a, 0);
|
||||
|
||||
/* If we have not encountered any signature we print an error
|
||||
messages, send a NODATA status back and return an error code.
|
||||
|
@ -1568,7 +1589,7 @@ proc_signature_packets_by_fd (ctrl_t ctrl, void *anchor, iobuf_t a,
|
|||
c->signed_data.data_names = NULL;
|
||||
c->signed_data.used = (signed_data_fd != GNUPG_INVALID_FD);
|
||||
|
||||
rc = do_proc_packets (c, a);
|
||||
rc = do_proc_packets (c, a, 0);
|
||||
|
||||
/* If we have not encountered any signature we print an error
|
||||
messages, send a NODATA status back and return an error code.
|
||||
|
@ -1592,8 +1613,13 @@ proc_signature_packets_by_fd (ctrl_t ctrl, void *anchor, iobuf_t a,
|
|||
}
|
||||
|
||||
|
||||
int
|
||||
proc_encryption_packets (ctrl_t ctrl, void *anchor, iobuf_t a )
|
||||
/* Handle encryption packets. If called recursively the caller's CTX
|
||||
* should be given for ANCHOR. If R_DEK and R_LIST are not NULL the
|
||||
* DEK (or NULL) is returned there and the list at R_LIST; the caller
|
||||
* needs to release them; even if the function returns an error. */
|
||||
gpg_error_t
|
||||
proc_encryption_packets (ctrl_t ctrl, void *anchor, iobuf_t a,
|
||||
DEK **r_dek, struct pubkey_enc_list **r_list)
|
||||
{
|
||||
CTX c = xmalloc_clear (sizeof *c);
|
||||
int rc;
|
||||
|
@ -1601,7 +1627,16 @@ proc_encryption_packets (ctrl_t ctrl, void *anchor, iobuf_t a )
|
|||
c->ctrl = ctrl;
|
||||
c->anchor = anchor;
|
||||
c->encrypt_only = 1;
|
||||
rc = do_proc_packets (c, a);
|
||||
if (r_dek && r_list)
|
||||
{
|
||||
rc = do_proc_packets (c, a, 1);
|
||||
*r_dek = c->dek;
|
||||
c->dek = NULL;
|
||||
*r_list = c->pkenc_list;
|
||||
c->pkenc_list = NULL;
|
||||
}
|
||||
else
|
||||
rc = do_proc_packets (c, a, 0);
|
||||
xfree (c);
|
||||
return rc;
|
||||
}
|
||||
|
@ -1626,8 +1661,11 @@ check_nesting (CTX c)
|
|||
}
|
||||
|
||||
|
||||
/* Main processing loop. If KEEP_DEK_AND_LIST is set the DEK and
|
||||
* PKENC_LIST of the context C are not released at the end of the
|
||||
* function. The caller is then required to do this. */
|
||||
static int
|
||||
do_proc_packets (CTX c, iobuf_t a)
|
||||
do_proc_packets (CTX c, iobuf_t a, int keep_dek_and_list)
|
||||
{
|
||||
PACKET *pkt;
|
||||
struct parse_packet_ctx_s parsectx;
|
||||
|
@ -1648,6 +1686,18 @@ do_proc_packets (CTX c, iobuf_t a)
|
|||
any_data = 1;
|
||||
if (rc)
|
||||
{
|
||||
if (c->ctrl->modify_recipients && gpg_err_code (rc) == GPG_ERR_TRUE)
|
||||
{
|
||||
/* Save the last read CTB (which was the last byte
|
||||
* actually read from the input) and get out of the
|
||||
* loop. */
|
||||
c->ctrl->last_read_ctb = parsectx.last_ctb;
|
||||
/* We need to call the first part of the encrypted data
|
||||
* handler to get the DEK. */
|
||||
proc_encrypted (c, NULL);
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
free_packet (pkt, &parsectx);
|
||||
/* Stop processing when an invalid packet has been encountered
|
||||
* but don't do so when we are doing a --list-packets. */
|
||||
|
@ -1706,8 +1756,19 @@ do_proc_packets (CTX c, iobuf_t a)
|
|||
goto leave;
|
||||
|
||||
case PKT_SIGNATURE: newpkt = add_signature (c, pkt); break;
|
||||
case PKT_SYMKEY_ENC: proc_symkey_enc (c, pkt); break;
|
||||
case PKT_PUBKEY_ENC: proc_pubkey_enc (c, pkt); break;
|
||||
|
||||
case PKT_SYMKEY_ENC:
|
||||
case PKT_PUBKEY_ENC:
|
||||
/* In --add-recipients mode set the stop flag as soon as
|
||||
* we see the first of these packets. */
|
||||
if (c->ctrl->modify_recipients)
|
||||
parsectx.only_fookey_enc = 1;
|
||||
if (pkt->pkttype == PKT_SYMKEY_ENC)
|
||||
proc_symkey_enc (c, pkt);
|
||||
else
|
||||
proc_pubkey_enc (c, pkt);
|
||||
break;
|
||||
|
||||
case PKT_ENCRYPTED:
|
||||
case PKT_ENCRYPTED_MDC:
|
||||
case PKT_ENCRYPTED_AEAD: proc_encrypted (c, pkt); break;
|
||||
|
@ -1783,8 +1844,8 @@ do_proc_packets (CTX c, iobuf_t a)
|
|||
|
||||
|
||||
leave:
|
||||
release_list (c);
|
||||
xfree(c->dek);
|
||||
if (!keep_dek_and_list)
|
||||
release_list (c);
|
||||
free_packet (pkt, &parsectx);
|
||||
deinit_parse_packet (&parsectx);
|
||||
xfree (pkt);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue