mirror of
git://git.gnupg.org/gnupg.git
synced 2025-04-17 15:44:34 +02:00
dirmngr: Fix signature checking.
* dirmngr/server.c: Include cpparray.h. (verify_swdb_parm_s): New. (verify_swdb_status_cb): New. (cmd_versioncheck): Use gpgv to correclty verify the signature. Rename some variable to comply with GNU standards. -- Relying on the return code of gpg is not a robust way to check signatures. We better use our dedicated tool. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
8fced66be3
commit
5a1f6a0062
@ -54,6 +54,7 @@
|
|||||||
#include "mbox-util.h"
|
#include "mbox-util.h"
|
||||||
#include "zb32.h"
|
#include "zb32.h"
|
||||||
#include "server-help.h"
|
#include "server-help.h"
|
||||||
|
#include "ccparray.h"
|
||||||
#include "../common/exectool.h"
|
#include "../common/exectool.h"
|
||||||
|
|
||||||
/* To avoid DoS attacks we limit the size of a certificate to
|
/* To avoid DoS attacks we limit the size of a certificate to
|
||||||
@ -2546,6 +2547,29 @@ fetch_into_tmpdir (ctrl_t ctrl, const char *url, estream_t *strm_out,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct verify_swdb_parm_s
|
||||||
|
{
|
||||||
|
time_t sigtime;
|
||||||
|
int anyvalid;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
verify_swdb_status_cb (void *opaque, const char *keyword, char *args)
|
||||||
|
{
|
||||||
|
struct verify_swdb_parm_s *parm = opaque;
|
||||||
|
|
||||||
|
/* We care only about the first valid signature. */
|
||||||
|
if (!strcmp (keyword, "VALIDSIG") && !parm->anyvalid)
|
||||||
|
{
|
||||||
|
char *fields[3];
|
||||||
|
|
||||||
|
parm->anyvalid = 1;
|
||||||
|
if (split_fields (args, fields, DIM (fields)) >= 3)
|
||||||
|
parm->sigtime = parse_timestamp (fields[2], NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static const char hlp_versioncheck[] =
|
static const char hlp_versioncheck[] =
|
||||||
"VERSIONCHECK <name> <version>"
|
"VERSIONCHECK <name> <version>"
|
||||||
"\n"
|
"\n"
|
||||||
@ -2570,13 +2594,17 @@ cmd_versioncheck (assuan_context_t ctx, char *line)
|
|||||||
char* swdb_sig_dir = NULL;
|
char* swdb_sig_dir = NULL;
|
||||||
char* buf = NULL;
|
char* buf = NULL;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
const char *argv[8];
|
ccparray_t ccp;
|
||||||
char keyring_path[128];
|
const char **argv = NULL;
|
||||||
char swdb_path[128];
|
char keyring_name[128];
|
||||||
char swdb_sig_path[128];
|
char swdb_name[128];
|
||||||
|
char swdb_sig_name[128];
|
||||||
|
|
||||||
swdb_path[0] = 0;
|
struct verify_swdb_parm_s verify_swdb_parm = { (time_t)(-1), 0 };
|
||||||
swdb_sig_path[0] = 0;
|
|
||||||
|
|
||||||
|
swdb_name[0] = 0;
|
||||||
|
swdb_sig_name[0] = 0;
|
||||||
ctrl = assuan_get_pointer (ctx);
|
ctrl = assuan_get_pointer (ctx);
|
||||||
|
|
||||||
if (split_fields (line, cmd_fields, 2) != 2)
|
if (split_fields (line, cmd_fields, 2) != 2)
|
||||||
@ -2594,29 +2622,51 @@ cmd_versioncheck (assuan_context_t ctx, char *line)
|
|||||||
&swdb, &swdb_dir)))
|
&swdb, &swdb_dir)))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
snprintf (swdb_path, sizeof swdb_path, "%s%s%s", swdb_dir, DIRSEP_S, "file");
|
snprintf (swdb_name, sizeof swdb_name, "%s%s%s", swdb_dir, DIRSEP_S, "file");
|
||||||
|
|
||||||
if ((err = fetch_into_tmpdir (ctrl, "https://versions.gnupg.org/swdb.lst.sig",
|
if ((err = fetch_into_tmpdir (ctrl, "https://versions.gnupg.org/swdb.lst.sig",
|
||||||
&swdb_sig, &swdb_sig_dir)))
|
&swdb_sig, &swdb_sig_dir)))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
snprintf (keyring_path, sizeof keyring_path, "%s%s%s", gnupg_datadir (),
|
snprintf (keyring_name, sizeof keyring_name, "%s%s%s", gnupg_datadir (),
|
||||||
DIRSEP_S, "distsigkey.gpg");
|
DIRSEP_S, "distsigkey.gpg");
|
||||||
snprintf (swdb_sig_path, sizeof swdb_sig_path, "%s%s%s", swdb_sig_dir,
|
snprintf (swdb_sig_name, sizeof swdb_sig_name, "%s%s%s", swdb_sig_dir,
|
||||||
DIRSEP_S, "file");
|
DIRSEP_S, "file");
|
||||||
|
|
||||||
argv[0] = "--batch";
|
ccparray_init (&ccp, 0);
|
||||||
argv[1] = "--no-default-keyring";
|
ccparray_put (&ccp, "--status-fd=2");
|
||||||
argv[2] = "--keyring";
|
ccparray_put (&ccp, "--keyring");
|
||||||
argv[3] = keyring_path;
|
ccparray_put (&ccp, keyring_name);
|
||||||
argv[4] = "--verify";
|
ccparray_put (&ccp, "--");
|
||||||
argv[5] = swdb_sig_path;
|
ccparray_put (&ccp, swdb_sig_name);
|
||||||
argv[6] = "-";
|
ccparray_put (&ccp, "-");
|
||||||
argv[7] = NULL;
|
ccparray_put (&ccp, NULL);
|
||||||
|
argv = ccparray_get (&ccp, NULL);
|
||||||
|
if (!argv)
|
||||||
|
{
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if ((err = gnupg_exec_tool_stream (gnupg_module_name (GNUPG_MODULE_NAME_GPG),
|
if ((err = gnupg_exec_tool_stream (gnupg_module_name (GNUPG_MODULE_NAME_GPGV),
|
||||||
argv, swdb, NULL, NULL, NULL, NULL)))
|
argv, swdb, NULL, NULL,
|
||||||
|
verify_swdb_status_cb, &verify_swdb_parm)))
|
||||||
goto out;
|
goto out;
|
||||||
|
if (verify_swdb_parm.sigtime == (time_t)(-1))
|
||||||
|
{
|
||||||
|
if (verify_swdb_parm.anyvalid)
|
||||||
|
err = gpg_error (GPG_ERR_BAD_SIGNATURE);
|
||||||
|
else
|
||||||
|
err = gpg_error (GPG_ERR_INV_TIME);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
gnupg_isotime_t tbuf;
|
||||||
|
|
||||||
|
epoch2isotime (tbuf, verify_swdb_parm.sigtime);
|
||||||
|
log_debug ("swdb created: %s\n", tbuf);
|
||||||
|
}
|
||||||
|
|
||||||
es_fseek (swdb, 0, SEEK_SET);
|
es_fseek (swdb, 0, SEEK_SET);
|
||||||
|
|
||||||
@ -2652,22 +2702,23 @@ cmd_versioncheck (assuan_context_t ctx, char *line)
|
|||||||
|
|
||||||
err = assuan_send_data (ctx, "NOT_FOUND", strlen ("NOT_FOUND"));
|
err = assuan_send_data (ctx, "NOT_FOUND", strlen ("NOT_FOUND"));
|
||||||
|
|
||||||
out:
|
out:
|
||||||
es_fclose (swdb);
|
es_fclose (swdb);
|
||||||
es_fclose (swdb_sig);
|
es_fclose (swdb_sig);
|
||||||
xfree (buf);
|
xfree (buf);
|
||||||
|
|
||||||
if (strlen (swdb_path) > 0)
|
if (strlen (swdb_name) > 0)
|
||||||
unlink (swdb_path);
|
remove (swdb_name);
|
||||||
if (swdb_dir)
|
if (swdb_dir)
|
||||||
rmdir (swdb_dir);
|
rmdir (swdb_dir);
|
||||||
xfree (swdb_dir);
|
xfree (swdb_dir);
|
||||||
|
|
||||||
if (strlen (swdb_sig_path) > 0)
|
if (strlen (swdb_sig_name) > 0)
|
||||||
unlink (swdb_sig_path);
|
remove (swdb_sig_name);
|
||||||
if (swdb_sig_dir)
|
if (swdb_sig_dir)
|
||||||
rmdir (swdb_sig_dir);
|
rmdir (swdb_sig_dir);
|
||||||
xfree (swdb_sig_dir);
|
xfree (swdb_sig_dir);
|
||||||
|
xfree (argv);
|
||||||
|
|
||||||
return leave_cmd (ctx, err);
|
return leave_cmd (ctx, err);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user