Re: HTTPS trust anchors in sysinst
Taylor R Campbell <[email protected]> Sun, 27 Aug 2023 21:49:12 +0000
| Newsgroups | gmane.os.netbsd.devel.installation |
|---|---|
| Message-ID | <[email protected]> |
This is a multi-part message in MIME format. --=_jDV1puCPoyAVzskxaSdfIVlbKCEreG6G Content-Transfer-Encoding: quoted-printable (Please keep me cc'd -- otherwise I may miss your replies.) > Date: Sat, 26 Aug 2023 09:21:49 -0400 > From: Mouse <[email protected]> >=20 > > [*] We should _also_ bake a public signature verification key into > > the installers that can verify a signature on the sets which can > > in turn be made only by TNF -- not by any of the public HTTPS > > CAs. But that's a separate issue that requires more key > > management and software verifier setup than we have settled now. >=20 > Once you have that, it seems to me that the use of SSL on either HTTP > or FTP becomes pointless CPU cycle wasting. This then leads me to > wonder two things: (1) is doing SSL a case of the good being the enemy > of the best (because people will fall into the trap of thinking that > SSL means "it's secure" without asking "...against what?"[%])? and (2) > is all this kerfuffle about CA trust anchors effort that would better > be put into designing and building the right answer? Enabling HTTPS validation is low-hanging fruit for modern systems in a modern world to defend against a large class of plausible threats -- namely, MITM on the network between you and cdn.netbsd.org. The [*] part _also_ defends against a compromised CDN, or against MITM on the network _combined with_ a compromised root CA. But the [*] part takes even more care to make sure we seriously consider other classes of threats, and don't ship a system that will silently get permanently wedged on automatic updates. I am planning to the [*] part but it is not going to be ready for netbsd-10, whereas HTTPS validation will be -- in base, at least. So I'm probing to see how much engineering effort will be needed to make HTTPS validation happen in the installer too. See also: Or maybe we can decide this isn't worthwhile, and the effort is better spent on a lighter-weight signing system for NetBSD distributions... (https://mail-index.netbsd.org/tech-install/2023/08/26/msg000698.html) > Also, if you're doing public-key crypto - for anything - in the > installers, this will drastically, I am tempted to say > catastrophically, slow down installation on low-end machines, like a > MicroVAX-II or Sun-3. (Of course, NetBSD might be fine with that. I > just think it should be at least thought about.) Can you please do the following tests on any low-end machines of interest? 1. Run `openssl speed' and share the output. Running it will take several minutes but the time is largely independent of the speed of the CPU; it measures how many operations it can do in a fixed time. 2. Build the attached rwverify.c with make rwverify DBG=3D-g\ -O2 LDLIBS=3D-lcrypto Then run it and share the output. You can also cross-build it on a more capable machine if you have a NetBSD `build.sh release' cross-build handy already, of course: make rwverify CC=3D$TOOLDIR/bin/vax--netbsdelf-gcc \ DBG=3D-g\ -O2\ --sysroot=3D$OBJDIR/destdir.vax \ LDLIBS=3D-lcrypto Running it will take approximately ten seconds. 3. Download https://falcon-sign.info/Falcon-impl-20211101.zip (or http://www.NetBSD.org/~riastradh/tmp/20230827/Falcon-impl-20211101.zip if you insist on avoiding https), build it with make, run `./speed', and share the output. To build for VAX, you'll need to make sure that -DFALCON_FPEMU=3D1 -DFALCON_FPNATIVE=3D0 is set in CFLAGS. So to cross-build for VAX, you'll need to do this: make CC=3D$TOOLDIR/bin/vax--netbsdelf-gcc \ CFLAGS=3D-g\ -O2\ --sysroot=3D$OBJDIR/destdir.vax\ -DFALCON_FPEMU=3D1\ -D= FALCON_FPNATIVE=3D0 \ LD=3D$TOOLDIR/bin/vax--netbsdelf-gcc \ LDFLAGS=3D--sysroot=3D$OBJDIR/destdir.vax --=_jDV1puCPoyAVzskxaSdfIVlbKCEreG6G Content-Type: text/plain; charset="ISO-8859-1"; name="rwverify" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="rwverify.c" #include <assert.h> #include <err.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <time.h> #include <unistd.h> #include <openssl/bn.h> #include <openssl/err.h> static void oerr(int status, const char *fmt, ...) { va_list va; fprintf(stderr, "%s: ", getprogname()); va_start(va, fmt); vfprintf(stderr, fmt, va); va_end(va); fprintf(stderr, ": %s\n", ERR_error_string(ERR_get_error(), NULL)); exit(status); } /* * openssl prime -generate -hex -bits 1024 | fold -w 64 | sed -e 's,^, "= ,' -e 's,$,",' * * repeat until: * - lsbyte of p is 3 * - lsbyte of q is 7 * - p*q > 2^2047 */ static const char p_hex[] =3D "E29BC82D77D0A11610FAF5CEC23A1FEB05C5274FDBB9C548DCC4460B306C2ABE" "99B9287C7AC53FF9DC041C722D9F7288D73AD49495A98DA5255D93B9ADF3DCB0" "60FFB8D9ADA3499BA8782BC4B77B25CE0CDF6A47D2F3410BEB5FFC26775DE6A7" "0CD74FA2C98667932A9663E29284880F36D6F94E14102D321A4B9D209E1E49C3"; static const char q_hex[] =3D "E8A6EE70C1F10DA317CF5B2B5EB7B5388BD5013C2A4D078C0ADB3CB1B64A87C3" "1E9F1B06301E3A288FC0869FD3727604C408AC4D21E941E4B45910B02A3FFB2C" "B608C3790994965AC8EA49802A00D40D242E701543117F8B220F6BDF47B2BCEE" "371DD93047C35EA734BA66AF94A6E94AC5230C323A9F435073FC73DCA68FF4E7"; /* * n =3D p*q */ static const char n_hex[] =3D "cdf0f17da5ff6f30d64bd37863b27bcd0ba20e0b014597517d8ddb7035059959" "93f2df5d937a2c8e861047cc8777ff82ade5f0337895466d7855dbdae07f4d9e" "79cc85a6479f96989c32ca0571b87df85eb26ca6d88a19522d65adc2de164276" "420b1297cd2d448b38f978b837f6139aa0387547cd2c8a2942a6f9650b00e071" "c3fa2e9041123969a2e3fca77704bac7874fb56c5c4577cf4406fd0df840fc00" "c735bf766d899962e5f1e433bd85ee235676429ebb06b80ed129eb3ff21964e8" "cf799c89b6d744e12d422e5ef488caa69b155821ae79967eaa97d5c8c8179c9f" "5c8659401975d2579122decd9a80493b356d86fd7a4c475869dbd277318f6af5"; /* * openssl rand -hex 32 */ static const char z_hex[] =3D "7715296787e5fa6f33a383dece71f421de100ef755da8d4785566d927a621ae6"; /* * r =3D KangarooTwelve(z || * 'The Magic Words are Squeamish Ossifrage')[0:4), */ static const int r =3D 0x3; /* * h =3D KangarooTwelve('\0'*32 || * 'The Magic Words are Squeamish Ossifrage')[0:2047), * * (note: 2047-bit integer, not 2048-bit integer) */ static const char h_hex[] =3D "5bf14befd0c7c1646f66ba6fd75f464b9fe769439f4816a20d8d8d92ea00327f" "862f1c7f87250c02c0d2dffdaefd4f5fdeb28fbd97cd86e7da2af4eaabff9087" "eade2f5d88e6628fddcc9439d505c6c339db315609509873b40f4504e2c3ef6c" "ce96df7fede8a24403566a7d6d0644cb486cf05d3943c74cfc8ec23efc338b21" "acbf5fc6261eaa4e1446c5da4350987f9f8e9f1d8fba92744411d04e0ddf6e2e" "37a555f3d51865ea2f4e43c6739605757af6880b1d261e02d7bb5ad22b31ff04" "1f602166314e360e2d166362e71aa06320b26d10a51e3c2cc6add5dcb2daf3f8" "e45bdc5456694adfca42373058d7978a98e068046437dd016efaa80fd75e3515"; /* * Standard signature components -- tweaked square root of h modulo n. */ static const int e =3D 1; /* 1 or -1 */ static const int f =3D 1; /* 1 or 2 */ static const char s_hex[] =3D "1ebbb89fcb46a93c951bee64efb1aeb47cf604404d907b36193e9525c13a7a66" "87e280b8cd0f134b9de31722fb5ad8f15a22039017effdd948d5cd592a0ba1d4" "280589f8242e0891b014dcad060f8721359522fcc874c08ba175645a4784f71c" "ba4c91919d578528bde19113aeed301e8b7f009accd2315b0bc360eb8910e864" "c627b594316e8b705a84d8c78aebe7eec7d25e8d7def08a5296c7b2d246abb1f" "db3cca82463f8dcfad4863ea7ef4b2f8f8cfa318182643b36893659094a7a66b" "db3433884cfbacf119231abe15090d966516da47de2fde4a3a972835525487c7" "792594d09b6058d8d53262e881d07c44ae0c2415621efebdef99aee51bde520f"; /* * Multiplier for reduction-free verification. */ static const char t_hex[] =3D "049620497c78b2f064d5a1bfffe5da819d733c976c63c5b3a8e0d65c33d598ab" "12664e220c61f53a1031933a40e91cb39ac81aa22f5a4e9d2c5983d27170d853" "c35de0cbb99081b039aee92da2e194ac258a0fa95577e6531c9b9aaa55c540e5" "88a1b9c976331de6d1353f15ec6b75a31fbc482f6df29393946d217af9362684" "fe73c7ef8380ba4aee66af6ca8ad7b5a76e56b6cb3a9806326cebca37bb0db9d" "6da5cc48075222ff6da8240bf9a68574456a5fcc8e3c7738a2fadda699f310b0" "bb0905f19e05c6a258e0faed653681b87a6cc5991fbe2efcdd37d66a9c6165b0" "0bf5ff50d3a3872240a7718b20be0b53cdf940c3d7105e07d9a1e6e9d27dc11c"; static sig_atomic_t alarmed =3D 0; static void sigalrm(int signo) { alarmed =3D 1; } int main(int argc, char **argv) { BIGNUM *n, *h, *s, *t; int n_len, h_len, s_len, t_len; int n_off, h_off, s_off, t_off; unsigned char *n_bin, *h_bin, *s_bin, *t_bin; unsigned timelimit_sec =3D 10; unsigned i =3D 0; struct timespec t0, t1, dt; setprogname(argv[0]); /* Parse the hex representations once -- slow, unrealistic. */ n =3D NULL; if (BN_hex2bn(&n, n_hex) =3D=3D 0) oerr(1, "BN_hex2bn n"); assert(n); h =3D NULL; if (BN_hex2bn(&h, h_hex) =3D=3D 0) oerr(1, "BN_hex2bn h"); assert(h); s =3D NULL; if (BN_hex2bn(&s, s_hex) =3D=3D 0) oerr(1, "BN_hex2bn s"); assert(s); t =3D NULL; if (BN_hex2bn(&t, t_hex) =3D=3D 0) oerr(1, "BN_hex2bn t"); assert(t); /* Convert to binary representations -- realistic. */ n_len =3D 256; assert(n_len >=3D BN_num_bytes(n)); n_off =3D n_len - BN_num_bytes(n); if ((n_bin =3D calloc(1, n_len)) =3D=3D NULL) err(1, "malloc n_bin"); h_len =3D 256; assert(h_len >=3D BN_num_bytes(h)); h_off =3D h_len - BN_num_bytes(h); if ((h_bin =3D calloc(1, h_len)) =3D=3D NULL) err(1, "malloc h_bin"); s_len =3D 256; assert(s_len >=3D BN_num_bytes(s)); s_off =3D s_len - BN_num_bytes(s); if ((s_bin =3D calloc(1, s_len)) =3D=3D NULL) err(1, "malloc s_bin"); t_len =3D 256; assert(t_len >=3D BN_num_bytes(t)); t_off =3D t_len - BN_num_bytes(t); if ((t_bin =3D calloc(1, t_len)) =3D=3D NULL) err(1, "malloc t_bin"); if (BN_bn2binpad(n, n_bin + n_off, n_len - n_off) =3D=3D -1) oerr(1, "BN_bn2binpad n"); if (BN_bn2binpad(h, h_bin + h_off, h_len - h_off) =3D=3D -1) oerr(1, "BN_bn2binpad h"); if (BN_bn2binpad(s, s_bin + s_off, s_len - s_off) =3D=3D -1) oerr(1, "BN_bn2binpad s"); if (BN_bn2binpad(t, t_bin + t_off, t_len - t_off) =3D=3D -1) oerr(1, "BN_bn2binpad t"); BN_free(t); t =3D NULL; BN_free(s); s =3D NULL; BN_free(h); h =3D NULL; BN_free(n); n =3D NULL; /* Start a timer going. */ if (signal(SIGALRM, sigalrm) =3D=3D SIG_ERR) err(1, "signal"); alarm(timelimit_sec); if (clock_gettime(CLOCK_MONOTONIC, &t0) =3D=3D -1) err(1, "clock_gettime(CLOCK_MONOTONIC)"); for (i =3D 0; !alarmed; i++) { BN_CTX *ctx; BIGNUM *f_bn, *s2, *fs2, *nt, *fs2_nt; /* Allocate a bignum context. */ if ((ctx =3D BN_CTX_new()) =3D=3D NULL) oerr(1, "BN_CTX_new"); /* Push an intermediate bignum frame. */ BN_CTX_start(ctx); if ((n =3D BN_CTX_get(ctx)) =3D=3D NULL) oerr(1, "BN_CTX_get n"); if ((h =3D BN_CTX_get(ctx)) =3D=3D NULL) oerr(1, "BN_CTX_get h"); if ((s =3D BN_CTX_get(ctx)) =3D=3D NULL) oerr(1, "BN_CTX_get s"); if ((t =3D BN_CTX_get(ctx)) =3D=3D NULL) oerr(1, "BN_CTX_get t"); if ((f_bn =3D BN_CTX_get(ctx)) =3D=3D NULL) oerr(1, "BN_CTX_get f"); if ((s2 =3D BN_CTX_get(ctx)) =3D=3D NULL) oerr(1, "BN_CTX_get s2"); if ((fs2 =3D BN_CTX_get(ctx)) =3D=3D NULL) oerr(1, "BN_CTX_get fs2"); if ((nt =3D BN_CTX_get(ctx)) =3D=3D NULL) oerr(1, "BN_CTX_get nt"); if ((fs2_nt =3D BN_CTX_get(ctx)) =3D=3D NULL) oerr(1, "BN_CTX_get fs2_nt"); /* Parse the signature. */ if (BN_bin2bn(n_bin, n_len, n) =3D=3D NULL) oerr(1, "BN_bin2bn n"); if (BN_bin2bn(h_bin, h_len, h) =3D=3D NULL) oerr(1, "BN_bin2bn h"); if (BN_bin2bn(s_bin, s_len, s) =3D=3D NULL) oerr(1, "BN_bin2bn s"); if (BN_bin2bn(t_bin, t_len, t) =3D=3D NULL) oerr(1, "BN_bin2bn t"); if (!BN_set_word(f_bn, f)) oerr(1, "BN_set_word f"); /* Verify the signature. */ if (!BN_sqr(s2, s, ctx)) oerr(1, "BN_sqr s"); if (!BN_mul(fs2, f_bn, s2, ctx)) oerr(1, "BN_mul f, s2"); if (!BN_mul(nt, n, t, ctx)) oerr(1, "BN_mul n, t"); switch (e) { case 1: if (!BN_sub(fs2_nt, fs2, nt)) oerr(1, "BN_sub fs2, nt"); if (BN_cmp(h, fs2_nt) !=3D 0) errx(42, "verification failure"); break; case -1: if (!BN_sub(fs2_nt, nt, fs2)) oerr(1, "BN_sub nt, fs2"); if (BN_cmp(h, fs2_nt) !=3D 0) errx(42, "verification failure"); break; default: err(1, "bad e: %d", e); } /* Free intermediate bignums. */ BN_CTX_end(ctx); /* Free the bignum context. */ BN_CTX_free(ctx); } if (clock_gettime(CLOCK_MONOTONIC, &t1) =3D=3D -1) err(1, "clock_gettime(CLOCK_MONOTONIC)"); timespecsub(&t1, &t0, &dt); /* Print results of the timer. */ printf("%d verifications in %f sec\n", i, dt.tv_sec + 1e-9*dt.tv_nsec); printf("%f v/s\n", i/(dt.tv_sec + 1e-9*dt.tv_nsec)); fflush(stdout); return ferror(stdout); } --=_jDV1puCPoyAVzskxaSdfIVlbKCEreG6G--