After a failed checksum: What options remain?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

After a failed checksum: What options remain?

Charlie Eddy
Hello,

Privateinternetaccess.org supplies secure VPNs. Their Windows installer
(v75) has a SHA256 result that does not match what is supplied on their
website.

Fucking terrible "security" solution, is it not?

As a prospective user of OpenBSD, I would hope that this never occurs, and
that free software would fulfill its promises. I am considering switching
to OpenBSD, but am afraid that I will be overcome by the difficulty of
learning Linux commands. I am not incompetent and willing to read code and
manpages, just timid, about this "big change."

As part of considering OpenBSD adoption, I am extremely focused on
security. However, trivial and fundamental issues are difficult to work
around.

My conclusion that the privateinternetaccess.org security solution is
terrible is not necessarily well-founded. The checksum could be modified
for these reasons:

- file was messed with in transit to me
- incompetent administrators did not update the checksum when they updated
the file

I suspect the latter, and unless my support ticket currently opened with
Private Internet Access is resolved to my satisfaction I will be forced to
use a free software solution. I am patient, but intolerant of stupidity.
The determination remains to be made.

GNUPG is my first step towards a cryptographically secure future. However,
in downloading it, I am confronted by a serious problem. They state the
following:

Comparing Checksums
If you are not able to use an old version of GnuPG, you can still verify
the file's SHA-1 checksum. This is less secure, because if someone modified
the files as they were transferred to you, it would not be much more effort
to modify the checksums that you see on this webpage. As such, if you use
this method, you should compare the checksums with those in release
announcement. This is sent to the gnupg-announce mailing list (among
others), which is widely mirrored. Don't use the mailing list archive on
this website, but find the announcement on several other websites and make
sure the checksum is consistent. This makes it more difficult for an
attacker to trick you into installing a modified version of the software.

As a result, I obtained an SSL/TLS server test to determine whether they
would be exposed to MITM despite their https:// prefix due to no
implementation of HSTS.

GNUPG is HSTSecure. Private Internet Access is not, another flaw in their
system.

However, the classic Orwellian security problem cannot be solved in this
case. The serious problem is that HSTS does not prevent a first-time user
from being MitM'd when they visit the site, and I may have been attacked
every single time. I have not yet verified the SHA1 sum in the archives --
are they correctly in stating that this is the best method?

How can I positively verify an OpenBSD install is secure? How can
implementing secure processes begin? Do I need to write my own checker from
scratch to know that things are operating properly? That's a joke, but it's
not that funny, is it?

If a user on a compromised device installs an operating system with
privilege separation, pledges could still be meaningless. What is the
correct way to wear a tinfoil hat?

Regards
Reply | Threaded
Open this post in threaded view
|

Re: After a failed checksum: What options remain?

Martijn van Duren-6
Hello Charlie,

There is no correct way to wear a tinfoil hat. Do you trust your current
installation of Windows? And why? Do you trust your computer hardware?
Intel has proven something along those lines a couple of times in recent
history. Based on what premise do you trust OpenBSD?

Suspicion can be a good thing, but you need to balance your security
with other factors in life like usability, stability, compatibility and
probably some other ity's.

I love OpenBSD. Both for its security, but also its simplicity and
usability. But I'm also aware that even OpenBSD isn't without its quirks
and bugs. It's also still based on the premises that you trust other
components on which OpenBSD was build around. Even the mathematical
principles behind signature verification.

In other words choose something that works for you and where you feel
confident enough that it won't try to kill your kittens.

As for the checking a signature you can start by downloading OpenBSD 6.2
and verifying its signature:
$ cat /etc/signify/openbsd-62-base.pub
untrusted comment: openbsd 6.2 base public key
RWRVWzAMgtyg7g27STK1h1xA6RIwtjex6Vr5Y9q5SC5q5+b0GN4lLhfu
You can compare that string to any other sources, among others:
- https://www.openbsd.org/62.html
- https://twitter.com/phessler/status/914414877539803136
- ...
If you need signify I found a Windows port here[0], but since I don't
run Windows, so I haven't tested any of it (nor checked the diff). I
found that it is an older release, so the diff (against my personal
OpenBSD cvs account checkout) below also includes changes in OpenBSD's
current signify. But I guess this release will still work and the diff
is still small enough to manually verify if something funky has been
done with this port (still a pain though).
Nevertheless, it runs on Windows, so you have to trust your Windows
installation, which runs on ....
Once OpenBSD is installed it'll automatically install the keys for the
next release and which will be verified with the current key.

Finally your usability question. I find it easy to use, but that's a
combination of years of experience and liking the minimal footprint.
A lot of people seem to be unable to work with the removal of a lot
of abstraction layers, I find it liberating and it gives me more
peace of mind that not a lot more happens than I request of the system.
If it works for you, is for you to find out. Just install it and take it
for a test run. OpenBSD's FAQ[1] is quite good and covers quite a lot of
subjects. You can use the FAQ to guide you to the man pages and if that
doesn't satisfy you, you can always turn to the source. Feel free to
send in some patches if you find something quirky in the source. :-)

Hope this helps.

martijn@

[0] https://github.com/stoeckmann/signify-windows
[1] https://www.openbsd.org/faq/

Only in /home/martijn/src/OpenBSD/usr.bin/signify: CVS
Only in /home/martijn/src/OpenBSD/usr.bin/signify: Makefile
Only in /tmp/signify-windows/patched-src: base64.c
diff -ru /home/martijn/src/OpenBSD/usr.bin/signify/crypto_api.c /tmp/signify-windows/patched-src/crypto_api.c
--- /home/martijn/src/OpenBSD/usr.bin/signify/crypto_api.c Wed Jan  8 04:59:46 2014
+++ /tmp/signify-windows/patched-src/crypto_api.c Fri Jan 12 11:07:34 2018
@@ -3,6 +3,8 @@
  * Public domain. Author: Ted Unangst <[hidden email]>
  * API compatible reimplementation of functions from nacl
  */
+#include "mingw.h"
+
 #include <sys/types.h>
 
 #include <string.h>
Only in /tmp/signify-windows/patched-src: err.c
Only in /tmp/signify-windows/patched-src: errx.c
Only in /tmp/signify-windows/patched-src: explicit_bzero.c
Only in /tmp/signify-windows/patched-src: sha2.c
Only in /tmp/signify-windows/patched-src: sha2.h
Only in /home/martijn/src/OpenBSD/usr.bin/signify: signify.1
diff -ru /home/martijn/src/OpenBSD/usr.bin/signify/signify.c /tmp/signify-windows/patched-src/signify.c
--- /home/martijn/src/OpenBSD/usr.bin/signify/signify.c Wed Jul 12 01:27:13 2017
+++ /tmp/signify-windows/patched-src/signify.c Fri Jan 12 11:07:34 2018
@@ -1,4 +1,4 @@
-/* $OpenBSD: signify.c,v 1.128 2017/07/11 23:27:13 tedu Exp $ */
+/* $OpenBSD: signify.c,v 1.100 2015/01/16 06:16:12 tedu Exp $ */
 /*
  * Copyright (c) 2013 Ted Unangst <[hidden email]>
  *
@@ -14,11 +14,10 @@
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
+#include "mingw.h"
+
 #include <sys/stat.h>
 
-#include <netinet/in.h>
-#include <resolv.h>
-
 #include <limits.h>
 #include <stdint.h>
 #include <fcntl.h>
@@ -26,15 +25,10 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <stddef.h>
-#include <ohash.h>
-#include <err.h>
 #include <unistd.h>
-#include <readpassphrase.h>
-#include <util.h>
 #include <sha2.h>
 
 #include "crypto_api.h"
-#include "signify.h"
 
 #define SIGBYTES crypto_sign_ed25519_BYTES
 #define SECRETBYTES crypto_sign_ed25519_SECRETKEYBYTES
@@ -71,7 +65,9 @@
  uint8_t sig[SIGBYTES];
 };
 
-static void __dead
+char *__progname = "signify";
+
+static void
 usage(const char *error)
 {
  if (error)
@@ -80,14 +76,13 @@
 #ifndef VERIFYONLY
     "\t%1$s -C [-q] -p pubkey -x sigfile [file ...]\n"
     "\t%1$s -G [-n] [-c comment] -p pubkey -s seckey\n"
-    "\t%1$s -S [-ez] [-x sigfile] -s seckey -m message\n"
+    "\t%1$s -S [-e] [-x sigfile] -s seckey -m message\n"
 #endif
-    "\t%1$s -V [-eqz] [-p pubkey] [-t keytype] [-x sigfile] -m message\n",
-    getprogname());
+    "\tsignify -V [-eq] [-x sigfile] -p pubkey -m message\n");
  exit(1);
 }
 
-int
+static int
 xopen(const char *fname, int oflags, mode_t mode)
 {
  struct stat sb;
@@ -111,7 +106,7 @@
  return fd;
 }
 
-void *
+static void *
 xmalloc(size_t len)
 {
  void *p;
@@ -189,7 +184,7 @@
  errx(1, "msg too large in %s", filename);
  space = msglen;
  if (!(msg = realloc(msg, msglen + space + 1)))
- err(1, "realloc");
+ errx(1, "realloc");
  }
  if ((x = read(fd, msg + msglen, space)) == -1)
  err(1, "read from %s", filename);
@@ -206,7 +201,7 @@
  return msg;
 }
 
-void
+static void
 writeall(int fd, const void *buf, size_t buflen, const char *filename)
 {
  ssize_t x;
@@ -220,31 +215,26 @@
 }
 
 #ifndef VERIFYONLY
-static char *
-createheader(const char *comment, const void *buf, size_t buflen)
+static void
+writeb64file(const char *filename, const char *comment, const void *buf,
+    size_t buflen, const void *msg, size_t msglen, int oflags, mode_t mode)
 {
- char *header;
+ char header[1024];
  char b64[1024];
+ int fd, rv, nr;
 
- if (b64_ntop(buf, buflen, b64, sizeof(b64)) == -1)
- errx(1, "base64 encode failed");
- if (asprintf(&header, "%s%s\n%s\n", COMMENTHDR, comment, b64) == -1)
- err(1, "asprintf failed");
- explicit_bzero(b64, sizeof(b64));
- return header;
-}
-
-static void
-writekeyfile(const char *filename, const char *comment, const void *buf,
-    size_t buflen, int oflags, mode_t mode)
-{
- char *header;
- int fd;
-
  fd = xopen(filename, O_CREAT|oflags|O_NOFOLLOW|O_WRONLY, mode);
- header = createheader(comment, buf, buflen);
+ if ((nr = snprintf(header, sizeof(header), "%s%s\n",
+    COMMENTHDR, comment)) == -1 || nr >= sizeof(header))
+ errx(1, "comment too long");
  writeall(fd, header, strlen(header), filename);
- freezero(header, strlen(header));
+ if ((rv = b64_ntop(buf, buflen, b64, sizeof(b64))) == -1)
+ errx(1, "base64 encode failed");
+ b64[rv++] = '\n';
+ writeall(fd, b64, rv, filename);
+ explicit_bzero(b64, sizeof(b64));
+ if (msg)
+ writeall(fd, msg, msglen, filename);
  close(fd);
 }
 
@@ -326,83 +316,39 @@
  explicit_bzero(digest, sizeof(digest));
  explicit_bzero(xorkey, sizeof(xorkey));
 
- nr = snprintf(commentbuf, sizeof(commentbuf), "%s secret key", comment);
- if (nr == -1 || nr >= sizeof(commentbuf))
+ if ((nr = snprintf(commentbuf, sizeof(commentbuf), "%s secret key",
+    comment)) == -1 || nr >= sizeof(commentbuf))
  errx(1, "comment too long");
- writekeyfile(seckeyfile, commentbuf, &enckey,
-    sizeof(enckey), O_EXCL, 0600);
+ writeb64file(seckeyfile, commentbuf, &enckey,
+    sizeof(enckey), NULL, 0, O_EXCL, 0600);
  explicit_bzero(&enckey, sizeof(enckey));
 
  memcpy(pubkey.pkalg, PKALG, 2);
  memcpy(pubkey.keynum, keynum, KEYNUMLEN);
- nr = snprintf(commentbuf, sizeof(commentbuf), "%s public key", comment);
- if (nr == -1 || nr >= sizeof(commentbuf))
+ if ((nr = snprintf(commentbuf, sizeof(commentbuf), "%s public key",
+    comment)) == -1 || nr >= sizeof(commentbuf))
  errx(1, "comment too long");
- writekeyfile(pubkeyfile, commentbuf, &pubkey,
-    sizeof(pubkey), O_EXCL, 0666);
+ writeb64file(pubkeyfile, commentbuf, &pubkey,
+    sizeof(pubkey), NULL, 0, O_EXCL, 0666);
 }
 
-static const char *
-check_keyname_compliance(const char *pubkeyfile, const char *seckeyfile)
+static void
+sign(const char *seckeyfile, const char *msgfile, const char *sigfile,
+    int embedded)
 {
- const char *pos;
- size_t len;
-
- /* basename may or may not modify input */
- pos = strrchr(seckeyfile, '/');
- if (pos != NULL)
- seckeyfile = pos + 1;
-
- len = strlen(seckeyfile);
- if (len < 5) /* ?.key */
- goto bad;
- if (strcmp(seckeyfile + len - 4, ".sec") != 0)
- goto bad;
- if (pubkeyfile != NULL) {
- pos = strrchr(pubkeyfile, '/');
- if (pos != NULL)
- pubkeyfile = pos + 1;
-
- if (strlen(pubkeyfile) != len)
- goto bad;
- if (strcmp(pubkeyfile + len - 4, ".pub") != 0)
- goto bad;
- if (strncmp(pubkeyfile, seckeyfile, len - 4) != 0)
- goto bad;
- }
-
- return seckeyfile;
-bad:
- errx(1, "please use naming scheme of keyname.pub and keyname.sec");
-}
-
-uint8_t *
-createsig(const char *seckeyfile, const char *msgfile, uint8_t *msg,
-    unsigned long long msglen)
-{
- struct enckey enckey;
- uint8_t xorkey[sizeof(enckey.seckey)];
  struct sig sig;
- char *sighdr;
  uint8_t digest[SHA512_DIGEST_LENGTH];
- int i, nr, rounds;
- SHA2_CTX ctx;
+ struct enckey enckey;
+ uint8_t xorkey[sizeof(enckey.seckey)];
+ uint8_t *msg;
  char comment[COMMENTMAXLEN], sigcomment[COMMENTMAXLEN];
+ char *secname;
+ unsigned long long msglen;
+ int i, rounds, nr;
+ SHA2_CTX ctx;
 
  readb64file(seckeyfile, &enckey, sizeof(enckey), comment);
 
- if (strcmp(seckeyfile, "-") == 0) {
- nr = snprintf(sigcomment, sizeof(sigcomment),
-    "signature from %s", comment);
- } else {
- const char *keyname = check_keyname_compliance(NULL,
-    seckeyfile);
- nr = snprintf(sigcomment, sizeof(sigcomment),
-    VERIFYWITH "%.*s.pub", (int)strlen(keyname) - 4, keyname);
- }
- if (nr == -1 || nr >= sizeof(sigcomment))
- errx(1, "comment too long");
-
  if (memcmp(enckey.kdfalg, KDFALG, 2) != 0)
  errx(1, "unsupported KDF");
  rounds = ntohl(enckey.kdfrounds);
@@ -415,38 +361,32 @@
  SHA512Update(&ctx, enckey.seckey, sizeof(enckey.seckey));
  SHA512Final(digest, &ctx);
  if (memcmp(enckey.checksum, digest, sizeof(enckey.checksum)) != 0)
- errx(1, "incorrect passphrase");
+    errx(1, "incorrect passphrase");
  explicit_bzero(digest, sizeof(digest));
 
+ msg = readmsg(msgfile, &msglen);
+
  signmsg(enckey.seckey, msg, msglen, sig.sig);
  memcpy(sig.keynum, enckey.keynum, KEYNUMLEN);
  explicit_bzero(&enckey, sizeof(enckey));
 
  memcpy(sig.pkalg, PKALG, 2);
-
- sighdr = createheader(sigcomment, &sig, sizeof(sig));
- return sighdr;
-}
-
-static void
-sign(const char *seckeyfile, const char *msgfile, const char *sigfile,
-    int embedded)
-{
- uint8_t *msg;
- char *sighdr;
- int fd;
- unsigned long long msglen;
-
- msg = readmsg(msgfile, &msglen);
-
- sighdr = createsig(seckeyfile, msgfile, msg, msglen);
-
- fd = xopen(sigfile, O_CREAT|O_TRUNC|O_NOFOLLOW|O_WRONLY, 0666);
- writeall(fd, sighdr, strlen(sighdr), sigfile);
- free(sighdr);
+ secname = strstr(seckeyfile, ".sec");
+ if (secname && strlen(secname) == 4) {
+ if ((nr = snprintf(sigcomment, sizeof(sigcomment), VERIFYWITH "%.*s.pub",
+    (int)strlen(seckeyfile) - 4, seckeyfile)) == -1 || nr >= sizeof(sigcomment))
+ errx(1, "comment too long");
+ } else {
+ if ((nr = snprintf(sigcomment, sizeof(sigcomment), "signature from %s",
+    comment)) == -1 || nr >= sizeof(sigcomment))
+ errx(1, "comment too long");
+ }
  if (embedded)
- writeall(fd, msg, msglen, sigfile);
- close(fd);
+ writeb64file(sigfile, sigcomment, &sig, sizeof(sig), msg,
+    msglen, O_TRUNC, 0666);
+ else
+ writeb64file(sigfile, sigcomment, &sig, sizeof(sig), NULL,
+    0, O_TRUNC, 0666);
 
  free(msg);
 }
@@ -477,42 +417,18 @@
 }
 
 static void
-check_keytype(const char *pubkeyfile, const char *keytype)
-{
- const char *p;
- size_t typelen;
-
- if (!(p = strrchr(pubkeyfile, '-')))
- goto bad;
- p++;
- typelen = strlen(keytype);
- if (strncmp(p, keytype, typelen) != 0)
- goto bad;
- if (strcmp(p + typelen, ".pub") != 0)
- goto bad;
- return;
-
-bad:
- errx(1, "incorrect keytype: %s is not %s", pubkeyfile, keytype);
-}
-
-static void
 readpubkey(const char *pubkeyfile, struct pubkey *pubkey,
-    const char *sigcomment, const char *keytype)
+    const char *sigcomment)
 {
- const char *safepath = "/etc/signify";
- char keypath[1024];
+ const char *safepath = "/etc/signify/";
 
  if (!pubkeyfile) {
  pubkeyfile = strstr(sigcomment, VERIFYWITH);
- if (pubkeyfile && strchr(pubkeyfile, '/') == NULL) {
+ if (pubkeyfile) {
  pubkeyfile += strlen(VERIFYWITH);
- if (keytype)
- check_keytype(pubkeyfile, keytype);
- if (snprintf(keypath, sizeof(keypath), "%s/%s",
-    safepath, pubkeyfile) >= sizeof(keypath))
- errx(1, "name too long %s", pubkeyfile);
- pubkeyfile = keypath;
+ if (strncmp(pubkeyfile, safepath, strlen(safepath)) != 0 ||
+    strstr(pubkeyfile, "/../") != NULL)
+ errx(1, "untrusted path %s", pubkeyfile);
  } else
  usage("must specify pubkey");
  }
@@ -521,7 +437,7 @@
 
 static void
 verifysimple(const char *pubkeyfile, const char *msgfile, const char *sigfile,
-    int quiet, const char *keytype)
+    int quiet)
 {
  char sigcomment[COMMENTMAXLEN];
  struct sig sig;
@@ -532,7 +448,7 @@
  msg = readmsg(msgfile, &msglen);
 
  readb64file(sigfile, &sig, sizeof(sig), sigcomment);
- readpubkey(pubkeyfile, &pubkey, sigcomment, keytype);
+ readpubkey(pubkeyfile, &pubkey, sigcomment);
 
  verifymsg(&pubkey, msg, msglen, &sig, quiet);
 
@@ -541,7 +457,7 @@
 
 static uint8_t *
 verifyembedded(const char *pubkeyfile, const char *sigfile,
-    int quiet, unsigned long long *msglenp, const char *keytype)
+    int quiet, unsigned long long *msglenp)
 {
  char sigcomment[COMMENTMAXLEN];
  struct sig sig;
@@ -552,7 +468,7 @@
  msg = readmsg(sigfile, &msglen);
 
  siglen = parseb64file(sigfile, msg, &sig, sizeof(sig), sigcomment);
- readpubkey(pubkeyfile, &pubkey, sigcomment, keytype);
+ readpubkey(pubkeyfile, &pubkey, sigcomment);
 
  msglen -= siglen;
  memmove(msg, msg + siglen, msglen);
@@ -566,21 +482,20 @@
 
 static void
 verify(const char *pubkeyfile, const char *msgfile, const char *sigfile,
-    int embedded, int quiet, const char *keytype)
+    int embedded, int quiet)
 {
  unsigned long long msglen;
  uint8_t *msg;
  int fd;
 
  if (embedded) {
- msg = verifyembedded(pubkeyfile, sigfile, quiet, &msglen,
-    keytype);
+ msg = verifyembedded(pubkeyfile, sigfile, quiet, &msglen);
  fd = xopen(msgfile, O_CREAT|O_TRUNC|O_NOFOLLOW|O_WRONLY, 0666);
  writeall(fd, msg, msglen, msgfile);
  free(msg);
  close(fd);
  } else {
- verifysimple(pubkeyfile, msgfile, sigfile, quiet, keytype);
+ verifysimple(pubkeyfile, msgfile, sigfile, quiet);
  }
 }
 
@@ -592,7 +507,7 @@
  char algo[32];
 };
 
-static void *
+static void *
 ecalloc(size_t s1, size_t s2, void *data)
 {
  void *p;
@@ -638,8 +553,9 @@
  } else {
  errx(1, "can't handle algorithm %s", c->algo);
  }
- if (strcmp(c->hash, buf) != 0)
+ if (strcmp(c->hash, buf) != 0) {
  return 0;
+ }
  if (!quiet)
  printf("%s: OK\n", c->file);
  return 1;
@@ -716,31 +632,11 @@
  unsigned long long msglen;
  uint8_t *msg;
 
- msg = verifyembedded(pubkeyfile, sigfile, quiet, &msglen, NULL);
+ msg = verifyembedded(pubkeyfile, sigfile, quiet, &msglen);
  verifychecksums((char *)msg, argc, argv, quiet);
 
  free(msg);
 }
-
-void *
-verifyzdata(uint8_t *zdata, unsigned long long zdatalen,
-    const char *filename, const char *pubkeyfile, const char *keytype)
-{
- struct sig sig;
- char sigcomment[COMMENTMAXLEN];
- unsigned long long siglen;
- struct pubkey pubkey;
-
- if (zdatalen < sizeof(sig))
- errx(1, "signature too short in %s", filename);
- siglen = parseb64file(filename, zdata, &sig, sizeof(sig),
-    sigcomment);
- readpubkey(pubkeyfile, &pubkey, sigcomment, keytype);
- zdata += siglen;
- zdatalen -= siglen;
- verifymsg(&pubkey, zdata, zdatalen, &sig, 1);
- return zdata;
-}
 #endif
 
 int
@@ -750,11 +646,9 @@
     *sigfile = NULL;
  char sigfilebuf[PATH_MAX];
  const char *comment = "signify";
- char *keytype = NULL;
  int ch, rounds;
  int embedded = 0;
  int quiet = 0;
- int gzip = 0;
  enum {
  NONE,
  CHECK,
@@ -763,12 +657,10 @@
  VERIFY
  } verb = NONE;
 
- if (pledge("stdio rpath wpath cpath tty", NULL) == -1)
- err(1, "pledge");
 
  rounds = 42;
 
- while ((ch = getopt(argc, argv, "CGSVzc:em:np:qs:t:x:")) != -1) {
+ while ((ch = getopt(argc, argv, "CGSVc:em:np:qs:x:")) != -1) {
  switch (ch) {
 #ifndef VERIFYONLY
  case 'C':
@@ -786,9 +678,6 @@
  usage(NULL);
  verb = SIGN;
  break;
- case 'z':
- gzip = 1;
- break;
 #endif
  case 'V':
  if (verb)
@@ -816,9 +705,6 @@
  case 's':
  seckeyfile = optarg;
  break;
- case 't':
- keytype = optarg;
- break;
  case 'x':
  sigfile = optarg;
  break;
@@ -830,16 +716,8 @@
  argc -= optind;
  argv += optind;
 
- if (embedded && gzip)
- errx(1, "can't combine -e and -z options");
-
- if (setvbuf(stdout, NULL, _IOLBF, 0) != 0)
- err(1, "setvbuf");
-
 #ifndef VERIFYONLY
  if (verb == CHECK) {
- if (pledge("stdio rpath", NULL) == -1)
- err(1, "pledge");
  if (!sigfile)
  usage("must specify sigfile");
  check(pubkeyfile, sigfile, quiet, argc, argv);
@@ -854,9 +732,8 @@
  int nr;
  if (strcmp(msgfile, "-") == 0)
  usage("must specify sigfile with - message");
- nr = snprintf(sigfilebuf, sizeof(sigfilebuf),
-    "%s.sig", msgfile);
- if (nr == -1 || nr >= sizeof(sigfilebuf))
+ if ((nr = snprintf(sigfilebuf, sizeof(sigfilebuf), "%s.sig",
+    msgfile)) == -1 || nr >= sizeof(sigfilebuf))
  errx(1, "path too long");
  sigfile = sigfilebuf;
  }
@@ -864,47 +741,22 @@
  switch (verb) {
 #ifndef VERIFYONLY
  case GENERATE:
- /* no pledge */
  if (!pubkeyfile || !seckeyfile)
  usage("must specify pubkey and seckey");
- check_keyname_compliance(pubkeyfile, seckeyfile);
  generate(pubkeyfile, seckeyfile, rounds, comment);
  break;
  case SIGN:
- /* no pledge */
- if (gzip) {
- if (!msgfile || !seckeyfile || !sigfile)
- usage("must specify message sigfile seckey");
- zsign(seckeyfile, msgfile, sigfile);
- } else {
- if (!msgfile || !seckeyfile)
- usage("must specify message and seckey");
- sign(seckeyfile, msgfile, sigfile, embedded);
- }
+ if (!msgfile || !seckeyfile)
+ usage("must specify message and seckey");
+ sign(seckeyfile, msgfile, sigfile, embedded);
  break;
 #endif
  case VERIFY:
- if ((embedded || gzip) &&
-    (msgfile && strcmp(msgfile, "-") != 0)) {
- /* will need to create output file */
- if (pledge("stdio rpath wpath cpath", NULL) == -1)
- err(1, "pledge");
- } else {
- if (pledge("stdio rpath", NULL) == -1)
- err(1, "pledge");
- }
- if (gzip) {
- zverify(pubkeyfile, msgfile, sigfile, keytype);
- } else {
- if (!msgfile)
- usage("must specify message");
- verify(pubkeyfile, msgfile, sigfile, embedded,
-    quiet, keytype);
- }
+ if (!msgfile)
+ usage("must specify message");
+ verify(pubkeyfile, msgfile, sigfile, embedded, quiet);
  break;
  default:
- if (pledge("stdio", NULL) == -1)
- err(1, "pledge");
  usage(NULL);
  break;
  }
Only in /home/martijn/src/OpenBSD/usr.bin/signify: signify.h
Only in /tmp/signify-windows/patched-src: smult_curve25519_ref.c
Only in /tmp/signify-windows/patched-src: strlcpy.c
Only in /tmp/signify-windows/patched-src: timingsafe_bcmp.c
Only in /tmp/signify-windows/patched-src: verr.c
Only in /tmp/signify-windows/patched-src: verrx.c
Only in /home/martijn/src/OpenBSD/usr.bin/signify: zsig.c


On 01/12/18 02:28, Charlie Eddy wrote:

> Hello,
>
> Privateinternetaccess.org supplies secure VPNs. Their Windows installer
> (v75) has a SHA256 result that does not match what is supplied on their
> website.
>
> Fucking terrible "security" solution, is it not?
>
> As a prospective user of OpenBSD, I would hope that this never occurs, and
> that free software would fulfill its promises. I am considering switching
> to OpenBSD, but am afraid that I will be overcome by the difficulty of
> learning Linux commands. I am not incompetent and willing to read code and
> manpages, just timid, about this "big change."
>
> As part of considering OpenBSD adoption, I am extremely focused on
> security. However, trivial and fundamental issues are difficult to work
> around.
>
> My conclusion that the privateinternetaccess.org security solution is
> terrible is not necessarily well-founded. The checksum could be modified
> for these reasons:
>
> - file was messed with in transit to me
> - incompetent administrators did not update the checksum when they updated
> the file
>
> I suspect the latter, and unless my support ticket currently opened with
> Private Internet Access is resolved to my satisfaction I will be forced to
> use a free software solution. I am patient, but intolerant of stupidity.
> The determination remains to be made.
>
> GNUPG is my first step towards a cryptographically secure future. However,
> in downloading it, I am confronted by a serious problem. They state the
> following:
>
> Comparing Checksums
> If you are not able to use an old version of GnuPG, you can still verify
> the file's SHA-1 checksum. This is less secure, because if someone modified
> the files as they were transferred to you, it would not be much more effort
> to modify the checksums that you see on this webpage. As such, if you use
> this method, you should compare the checksums with those in release
> announcement. This is sent to the gnupg-announce mailing list (among
> others), which is widely mirrored. Don't use the mailing list archive on
> this website, but find the announcement on several other websites and make
> sure the checksum is consistent. This makes it more difficult for an
> attacker to trick you into installing a modified version of the software.
>
> As a result, I obtained an SSL/TLS server test to determine whether they
> would be exposed to MITM despite their https:// prefix due to no
> implementation of HSTS.
>
> GNUPG is HSTSecure. Private Internet Access is not, another flaw in their
> system.
>
> However, the classic Orwellian security problem cannot be solved in this
> case. The serious problem is that HSTS does not prevent a first-time user
> from being MitM'd when they visit the site, and I may have been attacked
> every single time. I have not yet verified the SHA1 sum in the archives --
> are they correctly in stating that this is the best method?
>
> How can I positively verify an OpenBSD install is secure? How can
> implementing secure processes begin? Do I need to write my own checker from
> scratch to know that things are operating properly? That's a joke, but it's
> not that funny, is it?
>
> If a user on a compromised device installs an operating system with
> privilege separation, pledges could still be meaningless. What is the
> correct way to wear a tinfoil hat?
>
> Regards
>