Download raw body.
if worthy, can someone complete this?
i think it's unlikely that anything weakening signify's pledge would be
accepted. iirc there was also an agreed limit on code size of signify.
(there are also numerous style(9) issues but probably not worth looking
at those assuming i'm right with the above).
On 2024/12/31 07:33, Peter Philipp wrote:
> Dear Community,
>
> Happy New Year 2025! I have had some time to work on my own tree, doing a contribution to OpenBSD signify.
> This is something I want to share, but it exposed a bug on my nameserver which will take some time to fix.
> So in order to speed this up, If wanted in OpenBSD, I ask you to look into this with a non-broken nameserver,
> other than that I will have some time in perhaps February 2025 to commit this. Not looking for OK's right
> now, but rather someone to finish this work and test. Very minute changes needed as well as some experience
> with DNSSEC.
>
> This patch checks against a DNSSEC TLSA resource record for the signify signature, it must be used in
> conjunction with unwind(8) otherwise that mode doesn't work. It adds one flag to the signify -V mode.
>
> There is two areas that this patch needs cleanup. 1. The offsets of the DNSSEC packet returned into the main()
> at signify, may need to be adjusted. 2. the temporary file holding a dummy signify public key (which should
> get deleted at end of program) needs work (3 line fix). The latter is a little awkward since mkstemp() which
> I would prefer does not return a fileame in any way, so mktemp() has to be used somehow.
>
> Anyhow, I would have liked to give you a full patch myself, but priorities for the new year have shifted this
> on the backburner, and maybe it's liked (even though it's unfinished).
>
> Please any replies CC'ed to me as I'm not on the tech@ list right now.
>
> -pjp
>
> PS: T_TLSA (52 decimal) RR needs to be added to the system headers I believe.
>
> diff /usr/src
> commit - c3d0badf2f2115528d40d041f1a0e7094bf568e2
> path + /usr/src
> blob - de945715d4c1428c079f724fca4471d7223f2e62
> file + usr.bin/signify/Makefile
> --- usr.bin/signify/Makefile
> +++ usr.bin/signify/Makefile
> @@ -5,6 +5,7 @@ SRCS+= zsig.c
> SRCS+= fe25519.c sc25519.c
> SRCS+= mod_ed25519.c mod_ge25519.c
> SRCS+= crypto_api.c
> +SRCS+= dnssec.c
>
> PROG= signify
>
> blob - /dev/null
> file + usr.bin/signify/dnssec.c (mode 644)
> --- /dev/null
> +++ usr.bin/signify/dnssec.c
> @@ -0,0 +1,124 @@
> +/*
> + * Copyright (c) 2024 Peter Philipp <pjp@delphinusdns.org>
> + *
> + * Permission to use, copy, modify, and distribute this software for any
> + * purpose with or without fee is hereby granted, provided that the above
> + * copyright notice and this permission notice appear in all copies.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> + */
> +
> +#include <sys/types.h>
> +#include <netinet/in.h>
> +#include <arpa/nameser.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <resolv.h>
> +#include <ctype.h>
> +#include <err.h>
> +
> +#define _RES_CONF_NAMESERVER "nameserver " /* the nameserver entry */
> +#define _RES_CONF_NAMESERVER_LEN 11
> +#define _RES_CONF_UNWIND "# resolvd: unwind" /* set with unwind usage */
> +
> +#define MAXANSWERSZ 65535 /* RFC 1035 limit of a DNS packet */
> +#define T_TLSA 52 /* RFC 6698, sec. 7.1, XXX add to arpa/nameser.h later */
> +
> +extern struct __res_state _res;
> +
> +char * tlsa_query(const char *, int, int *);
> +int using_unwind(void);
> +
> +/*
> + * check if using unwind, if yes return true
> + */
> +
> +int
> +using_unwind(void)
> +{
> + int res = 0;
> + char *p;
> + char buf[512];
> + FILE *f;
> +
> + f = fopen(_PATH_RESCONF, "r");
> + if (f == NULL)
> + return(res);
> +
> + while (fgets(buf, sizeof(buf), f) != NULL) {
> + p = &buf[0];
> + while (isspace(*p))
> + p++;
> +
> + if (strncmp(p, _RES_CONF_NAMESERVER, _RES_CONF_NAMESERVER_LEN) == 0) {
> + if (strstr(buf, "# resolvd: unwind") != NULL)
> + res = 1;
> + else
> + res = 0;
> + }
> + }
> +
> + fclose(f);
> +
> + return (res);
> +}
> +
> +
> +/*
> + * returns zero if a public key file has been created with valid data, otherwise -1 on error
> + * creates the pubkeyfile only on success.
> + */
> +
> +char *
> +tlsa_query(const char *dname, int pubkeysize, int *retlen)
> +{
> + HEADER dheader;
> + char *answer = NULL, *ret = NULL;
> + int len;
> +
> +
> +
> + /* res_init(); not needed it's internally in res_query() */
> + //_res.options |= RES_USE_DNSSEC;
> +
> + answer = calloc(MAXANSWERSZ, 1);
> + if (answer == NULL) {
> + warn("cannot allocate %d bytes", MAXANSWERSZ);
> + return(NULL);
> + }
> +
> + if ((len = res_query(dname, C_IN, T_TLSA, answer, MAXANSWERSZ)) == -1) {
> + return(NULL);
> + }
> +
> + if (len >= HFIXEDSZ) {
> + memcpy((char *)&dheader, answer, HFIXEDSZ);
> +
> + if (((len - HFIXEDSZ) < (pubkeysize)) || (dheader.ad != 1) || (ntohs(dheader.ancount) != 1))
> + goto err;
> +
> + len -= (pubkeysize);
> + if (len < HFIXEDSZ) /* make sure that there is an offset past header */
> + goto err;
> +
> + ret = malloc(pubkeysize);
> + if (ret == NULL) {
> + warn("cannot allocate %d bytes", pubkeysize);
> + goto err;
> + }
> +
> + memcpy(ret, &answer[len], pubkeysize);
> + *retlen = pubkeysize;
> + }
> +
> +err:
> + freezero(answer, MAXANSWERSZ);
> + return(ret);
> +}
> blob - 2d1a29ec3218fdbd84a506edf1489615b95db8fa
> file + usr.bin/signify/signify.1
> --- usr.bin/signify/signify.1
> +++ usr.bin/signify/signify.1
> @@ -24,6 +24,7 @@
> .Nm signify
> .Fl C
> .Op Fl q
> +.Op Fl d Ar name
> .Op Fl p Ar pubkey
> .Op Fl t Ar keytype
> .Fl x Ar sigfile
> @@ -101,6 +102,14 @@ When signing with
> store a zero time stamp in the
> .Xr gzip 1
> header.
> +.It Fl d Ar name
> +Public key used by
> +.Fl V
> +to check a signature distributed by secure DNS. Used on a system utilizing
> +.Xr unwind 8
> +for DNSSEC validation, where
> +.Ar name
> +is the domain name queried with type TLSA RR.
> .It Fl p Ar pubkey
> Public key produced by
> .Fl G ,
> @@ -156,6 +165,10 @@ Entered passphrase is incorrect.
> The message file was corrupted and its signature does not match.
> .It
> The message file is too large.
> +.It
> +In case of
> +.Fl d
> +a secure DNS lookup fails.
> .El
> .Sh EXAMPLES
> Create a new key pair:
> @@ -193,7 +206,8 @@ $ ftp url | signify -Vz -t arc | tar ztf -
> .Xr pkg_add 1 ,
> .Xr sha256 1 ,
> .Xr fw_update 8 ,
> -.Xr sysupgrade 8
> +.Xr sysupgrade 8 ,
> +.Xr unwind 8
> .Sh HISTORY
> The
> .Nm
> blob - 1ab609ae5dd74b929b240ba5f196951df93018bb
> file + usr.bin/signify/signify.c
> --- usr.bin/signify/signify.c
> +++ usr.bin/signify/signify.c
> @@ -76,9 +76,10 @@ usage(const char *error)
> {
> if (error)
> fprintf(stderr, "%s\n", error);
> + /* -C line fits in exactly 80 character column terminals, hope that's okay */
> fprintf(stderr, "usage:"
> #ifndef VERIFYONLY
> - "\t%1$s -C [-q] [-p pubkey] [-t keytype] -x sigfile [file ...]\n"
> + "\t%1$s -C [-q] [-d name] [-p pubkey] [-t keytype] -x sigfile [file ...]\n"
> "\t%1$s -G [-n] [-c comment] -p pubkey -s seckey\n"
> "\t%1$s -S [-enz] [-x sigfile] -s seckey -m message\n"
> #endif
> @@ -752,13 +753,14 @@ int
> main(int argc, char **argv)
> {
> const char *pubkeyfile = NULL, *msgfile = NULL, *sigfile = NULL;
> + const char *dname = NULL;
> char sigfilebuf[PATH_MAX];
> - char *keytype = NULL;
> + char *keytype = NULL, *pubkey = NULL;
> #ifndef VERIFYONLY
> const char *seckeyfile = NULL, *comment = "signify";
> int none = 0;
> #endif
> - int ch;
> + int ch, len;
> int embedded = 0;
> int quiet = 0;
> int gzip = 0;
> @@ -770,10 +772,10 @@ main(int argc, char **argv)
> VERIFY
> } verb = NONE;
>
> - if (pledge("stdio rpath wpath cpath tty", NULL) == -1)
> + if (pledge("stdio rpath wpath cpath tty dns", NULL) == -1)
> err(1, "pledge");
>
> - while ((ch = getopt(argc, argv, "CGSVzc:em:np:qs:t:x:")) != -1) {
> + while ((ch = getopt(argc, argv, "CGSVzc:d:em:np:qs:t:x:")) != -1) {
> switch (ch) {
> #ifndef VERIFYONLY
> case 'C':
> @@ -794,6 +796,12 @@ main(int argc, char **argv)
> case 'c':
> comment = optarg;
> break;
> + case 'd':
> + /* XXX the mktemp is the only call returning a filename which is needed at unlink */
> + //pubkeyfile = mktemp("/tmp/signify.XXXXXXXX");
> + pubkeyfile = "/tmp/signify.XXXXXXXX";
> + dname = optarg;
> + break;
> case 'n':
> none = 1;
> break;
> @@ -835,19 +843,36 @@ main(int argc, char **argv)
> argc -= optind;
> argv += optind;
>
> + if (dname != NULL) {
> + if (using_unwind()) {
> + if ((pubkey = tlsa_query(dname, sizeof(struct pubkey), &len)) == NULL)
> + errx(1, "unable to get secure DNS TLSA public key data");
> +
> + writekeyfile(pubkeyfile, dname, pubkey, sizeof(struct pubkey), O_EXCL, 0644);
> + freezero(pubkey, len);
> + } else {
> + errx(1, "system is not using unwind(8) for validated DNS");
> + }
> + }
> +
> if (embedded && gzip)
> errx(1, "can't combine -e and -z options");
>
> if (setvbuf(stdout, NULL, _IOLBF, 0) != 0)
> err(1, "setvbuf");
>
> + if (pledge("stdio rpath wpath cpath tty", NULL) == -1)
> + err(1, "pledge");
> +
> #ifndef VERIFYONLY
> if (verb == CHECK) {
> - if (pledge("stdio rpath", NULL) == -1)
> + if (pledge("stdio rpath cpath", NULL) == -1)
> err(1, "pledge");
> if (!sigfile)
> usage("must specify sigfile");
> check(pubkeyfile, sigfile, keytype, quiet, argc, argv);
> + if (dname != NULL)
> + unlink(pubkeyfile);
> return 0;
> }
> #endif
> @@ -895,7 +920,7 @@ main(int argc, char **argv)
> if (pledge("stdio rpath wpath cpath", NULL) == -1)
> err(1, "pledge");
> } else {
> - if (pledge("stdio rpath", NULL) == -1)
> + if (pledge("stdio rpath cpath", NULL) == -1)
> err(1, "pledge");
> }
> if (gzip) {
> @@ -914,5 +939,8 @@ main(int argc, char **argv)
> break;
> }
>
> + if (dname != NULL)
> + unlink(pubkeyfile);
> +
> return 0;
> }
> blob - db7df8f07141ad4f31e92173f375d6e2a914f550
> file + usr.bin/signify/signify.h
> --- usr.bin/signify/signify.h
> +++ usr.bin/signify/signify.h
> @@ -29,5 +29,7 @@ extern void *verifyzdata(uint8_t *, unsigned long long
> extern uint8_t *createsig(const char *, const char *, uint8_t *,
> unsigned long long);
>
> +extern char *tlsa_query(const char *, int, int *);
> +extern int using_unwind(void);
>
> #endif
> --
>
> -
> I remember when google, youtube, facebook, etc were open access
>
if worthy, can someone complete this?