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

wks: Make sure that the draft 2 request is correctly detected.

* tools/gpg-wks.h (WKS_DRAFT_VERSION): New.
* tools/wks-receive.c (new_part): Move test wks draft version to ...
(t2body): new callback.
(wks_receive): Register this callback.
* tools/gpg-wks-server.c (send_confirmation_request): Emit draft
version header.
(send_congratulation_message): Ditto.
* tools/gpg-wks-client.c (decrypt_stream_parm_s): New.
(decrypt_stream_status_cb): Check DECRYTPION_KEY status.
(decrypt_stream): Get infor from new callback.
(process_confirmation_request): New arg 'mainfpr'.  Check that it
matches the decryption key.
(read_confirmation_request): Check that the decryption key has been
generated by us.
(command_send): Use macro from draft version header.
(send_confirmation_response): Emit draft version header.
--

This patch also adds a check to only send a confirmation when the
decryption has been done by an ultimately trusted (self-generated)
key.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2017-02-23 20:10:59 +01:00
parent a209025082
commit d30e17ac62
No known key found for this signature in database
GPG key ID: E3FDFF218E45B72B
4 changed files with 119 additions and 35 deletions

View file

@ -373,6 +373,7 @@ get_key (estream_t *r_key, const char *fingerprint, const char *addrspec)
log_error ("error allocating memory buffer: %s\n", gpg_strerror (err));
goto leave;
}
/* Prefix the key with the MIME content type. */
es_fputs ("Content-Type: application/pgp-keys\n"
"\n", key);
@ -437,20 +438,38 @@ get_key (estream_t *r_key, const char *fingerprint, const char *addrspec)
struct decrypt_stream_parm_s
{
char *fpr;
char *mainfpr;
int otrust;
};
static void
decrypt_stream_status_cb (void *opaque, const char *keyword, char *args)
{
(void)opaque;
struct decrypt_stream_parm_s *decinfo = opaque;
if (DBG_CRYPTO)
log_debug ("gpg status: %s %s\n", keyword, args);
}
if (!strcmp (keyword, "DECRYPTION_KEY") && !decinfo->fpr)
{
char *fields[3];
if (split_fields (args, fields, DIM (fields)) >= 3)
{
decinfo->fpr = xstrdup (fields[0]);
decinfo->mainfpr = xstrdup (fields[1]);
decinfo->otrust = *fields[2];
}
}
}
/* Decrypt the INPUT stream to a new stream which is stored at success
* at R_OUTPUT. */
static gpg_error_t
decrypt_stream (estream_t *r_output, estream_t input)
decrypt_stream (estream_t *r_output, struct decrypt_stream_parm_s *decinfo,
estream_t input)
{
gpg_error_t err;
ccparray_t ccp;
@ -458,6 +477,7 @@ decrypt_stream (estream_t *r_output, estream_t input)
estream_t output;
*r_output = NULL;
memset (decinfo, 0, sizeof *decinfo);
output = es_fopenmem (0, "w+b");
if (!output)
@ -492,7 +512,9 @@ decrypt_stream (estream_t *r_output, estream_t input)
}
err = gnupg_exec_tool_stream (opt.gpg_program, argv, input,
NULL, output,
decrypt_stream_status_cb, NULL);
decrypt_stream_status_cb, decinfo);
if (!err && (!decinfo->fpr || !decinfo->mainfpr || !decinfo->otrust))
err = gpg_error (GPG_ERR_INV_ENGINE);
if (err)
{
log_error ("decryption failed: %s\n", gpg_strerror (err));
@ -506,6 +528,12 @@ decrypt_stream (estream_t *r_output, estream_t input)
output = NULL;
leave:
if (err)
{
xfree (decinfo->fpr);
xfree (decinfo->mainfpr);
memset (decinfo, 0, sizeof *decinfo);
}
es_fclose (output);
xfree (argv);
return err;
@ -749,8 +777,9 @@ command_send (const char *fingerprint, char *userid)
if (err)
goto leave;
/* Tell server that we support draft version 3. */
err = mime_maker_add_header (mime, "Wks-Draft-Version", "3");
/* Tell server which draft we support. */
err = mime_maker_add_header (mime, "Wks-Draft-Version",
STR2(WKS_DRAFT_VERSION));
if (err)
goto leave;
@ -948,6 +977,10 @@ send_confirmation_response (const char *sender, const char *address,
err = mime_maker_add_header (mime, "Subject", "Key publication confirmation");
if (err)
goto leave;
err = mime_maker_add_header (mime, "Wks-Draft-Version",
STR2(WKS_DRAFT_VERSION));
if (err)
goto leave;
if (encrypt)
{
@ -998,9 +1031,11 @@ send_confirmation_response (const char *sender, const char *address,
/* Reply to a confirmation request. The MSG has already been
* decrypted and we only need to send the nonce back. */
* decrypted and we only need to send the nonce back. MAINFPR is
* either NULL or the primary key fingerprint of the key used to
* decrypt the request. */
static gpg_error_t
process_confirmation_request (estream_t msg)
process_confirmation_request (estream_t msg, const char *mainfpr)
{
gpg_error_t err;
nvc_t nvc;
@ -1044,8 +1079,20 @@ process_confirmation_request (estream_t msg)
}
fingerprint = value;
/* FIXME: Check that the fingerprint matches the key used to decrypt the
* message. */
/* Check that the fingerprint matches the key used to decrypt the
* message. In --read mode or with the old format we don't have the
* decryption key; thus we can't bail out. */
if (!mainfpr || ascii_strcasecmp (mainfpr, fingerprint))
{
log_info ("target fingerprint: %s\n", fingerprint);
log_info ("but decrypted with: %s\n", mainfpr);
log_error ("confirmation request not decrypted with target key\n");
if (mainfpr)
{
err = gpg_error (GPG_ERR_INV_DATA);
goto leave;
}
}
/* Get the address. */
if (!((item = nvc_lookup (nvc, "address:")) && (value = nve_value (item))
@ -1058,10 +1105,7 @@ process_confirmation_request (estream_t msg)
}
address = value;
/* FIXME: Check that the "address" matches the User ID we want to
* publish. Also get the "fingerprint" and compare that to our to
* be published key. Further we should make sure that we actually
* decrypted using that fingerprint (which is a bit problematic if
* --read is used). */
* publish. */
/* Get the sender. */
if (!((item = nvc_lookup (nvc, "sender:")) && (value = nve_value (item))
@ -1130,14 +1174,24 @@ read_confirmation_request (estream_t msg)
}
if (c != '-')
err = process_confirmation_request (msg);
err = process_confirmation_request (msg, NULL);
else
{
err = decrypt_stream (&plaintext, msg);
struct decrypt_stream_parm_s decinfo;
err = decrypt_stream (&plaintext, &decinfo, msg);
if (err)
log_error ("decryption failed: %s\n", gpg_strerror (err));
else if (decinfo.otrust != 'u')
{
err = gpg_error (GPG_ERR_WRONG_SECKEY);
log_error ("key used to decrypt the confirmation request"
" was not generated by us\n");
}
else
err = process_confirmation_request (plaintext);
err = process_confirmation_request (plaintext, decinfo.mainfpr);
xfree (decinfo.fpr);
xfree (decinfo.mainfpr);
}
es_fclose (plaintext);