diff options
Diffstat (limited to 'g10/mainproc.c')
-rw-r--r-- | g10/mainproc.c | 102 |
1 files changed, 94 insertions, 8 deletions
diff --git a/g10/mainproc.c b/g10/mainproc.c index 11e73cc62..eb876799d 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -71,6 +71,7 @@ struct mainproc_context int encrypt_only; /* Process only encryption messages. */ int symkey_only; /* Just process a SK-ESK packet. */ int pubkey_only; /* Just process a PK-ESK packet. */ + int encrypted_data_only; /* Just process encrypted data packets. */ /* Name of the file with the complete signature or the file with the detached signature. This is currently only used to deduce the @@ -98,6 +99,8 @@ struct mainproc_context int trustletter; /* Temporary usage in list_node. */ ulong symkeys; struct kidlist_item *pkenc_list; /* List of encryption packets. */ + estream_t outputfp; /* Overrides where to send the contents of the message. */ + u32 timestamp; /* Timestamp stored in the last literal packet. */ struct { unsigned int sig_seen:1; /* Set to true if a signature packet has been seen. */ @@ -142,7 +145,7 @@ release_list( CTX c ) c->any.data = 0; c->any.uncompress_failed = 0; c->last_was_session_key = 0; - if (! (c->symkey_only || c->pubkey_only)) + if (! (c->symkey_only || c->pubkey_only || c->encrypted_data_only)) { xfree (c->dek); c->dek = NULL; @@ -663,8 +666,11 @@ proc_encrypted (CTX c, PACKET *pkt) * ways to specify the session key (symmmetric and PK). */ } - xfree (c->dek); - c->dek = NULL; + if (! c->encrypted_data_only) + { + xfree (c->dek); + c->dek = NULL; + } free_packet (pkt); c->last_was_session_key = 0; write_status (STATUS_END_DECRYPTION); @@ -765,12 +771,25 @@ proc_plaintext( CTX c, PACKET *pkt ) if (!rc) { - rc = handle_plaintext (pt, &c->mfx, c->sigs_only, clearsig); + estream_t outputfp = NULL; + CTX ci; + for (ci = c; ci && ! outputfp; ci = ci->anchor) + outputfp = ci->outputfp; + + rc = handle_plaintext (pt, &c->mfx, c->sigs_only, outputfp, clearsig); if (gpg_err_code (rc) == GPG_ERR_EACCES && !c->sigs_only) { /* Can't write output but we hash it anyway to check the signature. */ - rc = handle_plaintext( pt, &c->mfx, 1, clearsig ); + rc = handle_plaintext( pt, &c->mfx, 1, NULL, clearsig); + } + + if (! rc) + { + /* Save the time stamp in the root. */ + for (ci = c; ci->anchor; ci = ci->anchor) + ; + ci->timestamp = pt->timestamp; } } @@ -1292,6 +1311,30 @@ proc_pubkey_packet (ctrl_t ctrl, iobuf_t a, DEK *dek) } int +proc_encrypted_data (ctrl_t ctrl, iobuf_t input, DEK *dek, + estream_t outputfp, u32 *timestamp) +{ + CTX c = xmalloc_clear (sizeof *c); + int rc; + + c->ctrl = ctrl; + c->encrypted_data_only = 1; + c->dek = dek; + c->outputfp = outputfp; + + reset_literals_seen(); + rc = do_proc_packets (ctrl, c, input); + reset_literals_seen(); + + if (timestamp) + *timestamp = c->timestamp; + + xfree (c); + + return rc; +} + +int proc_signature_packets_by_fd (ctrl_t ctrl, void *anchor, iobuf_t a, int signed_data_fd ) { @@ -1416,9 +1459,10 @@ do_proc_packets (ctrl_t ctrl, CTX c, iobuf_t a) case PKT_PUBLIC_KEY: case PKT_SECRET_KEY: case PKT_USER_ID: - case PKT_SIGNATURE: case PKT_PUBKEY_ENC: + case PKT_ENCRYPTED: case PKT_ENCRYPTED_MDC: + case PKT_SIGNATURE: case PKT_PLAINTEXT: case PKT_COMPRESSED: case PKT_ONEPASS_SIG: @@ -1438,9 +1482,10 @@ do_proc_packets (ctrl_t ctrl, CTX c, iobuf_t a) case PKT_PUBLIC_KEY: case PKT_SECRET_KEY: case PKT_USER_ID: - case PKT_SIGNATURE: case PKT_SYMKEY_ENC: + case PKT_ENCRYPTED: case PKT_ENCRYPTED_MDC: + case PKT_SIGNATURE: case PKT_PLAINTEXT: case PKT_COMPRESSED: case PKT_ONEPASS_SIG: @@ -1453,6 +1498,30 @@ do_proc_packets (ctrl_t ctrl, CTX c, iobuf_t a) default: newpkt = 0; break; } } + else if (c->encrypted_data_only) + { + switch (pkt->pkttype) + { + case PKT_PUBLIC_KEY: + case PKT_SECRET_KEY: + case PKT_USER_ID: + case PKT_SYMKEY_ENC: + case PKT_PUBKEY_ENC: + case PKT_SIGNATURE: + case PKT_PLAINTEXT: + case PKT_COMPRESSED: + case PKT_ONEPASS_SIG: + case PKT_GPG_CONTROL: + write_status_text (STATUS_UNEXPECTED, "0"); + rc = GPG_ERR_UNEXPECTED; + goto leave; + + case PKT_ENCRYPTED: + case PKT_ENCRYPTED_MDC: + proc_encrypted (c, pkt); break; + default: newpkt = 0; break; + } + } else if (c->sigs_only) { switch (pkt->pkttype) @@ -1563,8 +1632,25 @@ do_proc_packets (ctrl_t ctrl, CTX c, iobuf_t a) leave: + if (opt.show_session_key && c->dek) + { + char numbuf[25]; + char *hexbuf; + + snprintf (numbuf, sizeof numbuf, "%d:", c->dek->algo); + hexbuf = bin2hex (c->dek->key, c->dek->keylen, NULL); + if (!hexbuf) + { + rc = gpg_error_from_syserror (); + goto leave; + } + log_info ("session key: '%s%s'\n", numbuf, hexbuf); + write_status_strings (STATUS_SESSION_KEY, numbuf, hexbuf, NULL); + xfree (hexbuf); + } + release_list (c); - if (! (c->symkey_only || c->pubkey_only)) + if (! (c->symkey_only || c->pubkey_only || c->encrypted_data_only)) xfree(c->dek); free_packet (pkt); xfree (pkt); |