summaryrefslogtreecommitdiffstats
path: root/tools/gpg-wks-server.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2016-07-12 16:54:55 +0200
committerWerner Koch <wk@gnupg.org>2016-07-12 16:59:20 +0200
commitd3837e0435921bfa5587a50738f5924a5fdf976a (patch)
treed6bb5cb1dca051476651639f45496ec9c0913aed /tools/gpg-wks-server.c
parentdoc: Update import-export description. (diff)
downloadgnupg2-d3837e0435921bfa5587a50738f5924a5fdf976a.tar.xz
gnupg2-d3837e0435921bfa5587a50738f5924a5fdf976a.zip
wks: Also create DANE record.
* tools/gpg-wks-server.c (copy_key_as_dane): New. (check_and_publish): Also publish as DANE record. Signed-off-by: Werner Koch <wk@gnupg.org>
Diffstat (limited to 'tools/gpg-wks-server.c')
-rw-r--r--tools/gpg-wks-server.c98
1 files changed, 91 insertions, 7 deletions
diff --git a/tools/gpg-wks-server.c b/tools/gpg-wks-server.c
index e46eafaeb..88313eca9 100644
--- a/tools/gpg-wks-server.c
+++ b/tools/gpg-wks-server.c
@@ -489,6 +489,55 @@ list_key (server_ctx_t ctx, estream_t key)
}
+/* Take the key in KEYFILE and write it to DANEFILE using the DANE
+ * output format. */
+static gpg_error_t
+copy_key_as_dane (const char *keyfile, const char *danefile)
+{
+ gpg_error_t err;
+ ccparray_t ccp;
+ const char **argv;
+
+ ccparray_init (&ccp, 0);
+
+ ccparray_put (&ccp, "--no-options");
+ if (!opt.verbose)
+ ccparray_put (&ccp, "--quiet");
+ else if (opt.verbose > 1)
+ ccparray_put (&ccp, "--verbose");
+ ccparray_put (&ccp, "--batch");
+ ccparray_put (&ccp, "--yes");
+ ccparray_put (&ccp, "--always-trust");
+ ccparray_put (&ccp, "--no-keyring");
+ ccparray_put (&ccp, "--output");
+ ccparray_put (&ccp, danefile);
+ ccparray_put (&ccp, "--export-options=export-dane");
+ ccparray_put (&ccp, "--import-options=import-export");
+ ccparray_put (&ccp, "--import");
+ ccparray_put (&ccp, "--");
+ ccparray_put (&ccp, keyfile);
+
+ ccparray_put (&ccp, NULL);
+ argv = ccparray_get (&ccp, NULL);
+ if (!argv)
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+ err = gnupg_exec_tool_stream (opt.gpg_program, argv, NULL,
+ NULL, NULL, NULL, NULL);
+ if (err)
+ {
+ log_error ("%s failed: %s\n", __func__, gpg_strerror (err));
+ goto leave;
+ }
+
+ leave:
+ xfree (argv);
+ return err;
+}
+
+
static void
encrypt_stream_status_cb (void *opaque, const char *keyword, char *args)
{
@@ -782,7 +831,7 @@ send_confirmation_request (server_ctx_t ctx,
log_error ("error allocating memory buffer: %s\n", gpg_strerror (err));
goto leave;
}
- /* It is fine to use 8 bit encosind because that is encrypted and
+ /* It is fine to use 8 bit encoding because that is encrypted and
* only our client will see it. */
es_fputs ("Content-Type: application/vnd.gnupg.wks\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -945,6 +994,7 @@ check_and_publish (server_ctx_t ctx, const char *address, const char *nonce)
const char *domain;
const char *s;
strlist_t sl;
+ char shaxbuf[32]; /* Used for SHA-1 and SHA-256 */
/* FIXME: There is a bug in name-value.c which adds white space for
* the last pair and thus we strip the nonce here until this has
@@ -1011,11 +1061,8 @@ check_and_publish (server_ctx_t ctx, const char *address, const char *nonce)
/* Hash user ID and create filename. */
s = strchr (address, '@');
log_assert (s);
- {
- char sha1buf[20];
- gcry_md_hash_buffer (GCRY_MD_SHA1, sha1buf, address, s - address);
- hash = zb32_encode (sha1buf, 8*20);
- }
+ gcry_md_hash_buffer (GCRY_MD_SHA1, shaxbuf, address, s - address);
+ hash = zb32_encode (shaxbuf, 8*20);
if (!hash)
{
err = gpg_error_from_syserror ();
@@ -1032,7 +1079,7 @@ check_and_publish (server_ctx_t ctx, const char *address, const char *nonce)
goto leave;
}
if (!gnupg_mkdir (fnewname, "-rwxr-xr-x"))
- log_info ("directory '%s' created\n", fname);
+ log_info ("directory '%s' created\n", fnewname);
xfree (fnewname);
}
fnewname = make_filename_try (opt.directory, domain, "hu", hash, NULL);
@@ -1053,6 +1100,43 @@ check_and_publish (server_ctx_t ctx, const char *address, const char *nonce)
log_info ("key %s published for '%s'\n", ctx->fpr, address);
+
+ /* Try to publish as DANE record if the DANE directory exists. */
+ xfree (fname);
+ fname = fnewname;
+ fnewname = make_filename_try (opt.directory, domain, "dane", NULL);
+ if (!fnewname)
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+ if (!access (fnewname, W_OK))
+ {
+ /* Yes, we have a dane directory. */
+ s = strchr (address, '@');
+ log_assert (s);
+ gcry_md_hash_buffer (GCRY_MD_SHA256, shaxbuf, address, s - address);
+ xfree (hash);
+ hash = bin2hex (shaxbuf, 28, NULL);
+ if (!hash)
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+ xfree (fnewname);
+ fnewname = make_filename_try (opt.directory, domain, "dane", hash, NULL);
+ if (!fnewname)
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+ err = copy_key_as_dane (fname, fnewname);
+ if (err)
+ goto leave;
+ log_info ("key %s published for '%s' (DANE record)\n", ctx->fpr, address);
+ }
+
+
leave:
es_fclose (key);
xfree (hash);