summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortb <>2020-01-23 03:53:39 +0000
committertb <>2020-01-23 03:53:39 +0000
commit130f32cc7004f9434c10db4fc8a7e8b1db9082a5 (patch)
tree4d9d69b009f469def034872876e1caec106f28a1
parent61fedc0310a1ba6f15f2242f24fbba7b3b8d3d8f (diff)
downloadopenbsd-130f32cc7004f9434c10db4fc8a7e8b1db9082a5.tar.gz
openbsd-130f32cc7004f9434c10db4fc8a7e8b1db9082a5.tar.bz2
openbsd-130f32cc7004f9434c10db4fc8a7e8b1db9082a5.zip
The X509_LOOKUP code tries to grope around in /etc/ssl/cert/ to find
CA certs it couldn't find otherwise. This may lead to a pledge rpath violation reported by Kor, son of Rynar. Unfortunately, providing certs inside a directory is common in linuxes, so we need to keep this functionality for portable. Check if /etc/ssl/cert.pem and /etc/ssl/cert exist and pledge accordingly. Add unveils to restrict this program further on a default OpenBSD install. Fix -C to look only inside the provided root bundle. Input from jsing and sthen, tests by sthen and Kor ok beck, jsing, sthen (after much back and forth)
-rw-r--r--src/usr.sbin/ocspcheck/ocspcheck.c97
1 files changed, 67 insertions, 30 deletions
diff --git a/src/usr.sbin/ocspcheck/ocspcheck.c b/src/usr.sbin/ocspcheck/ocspcheck.c
index 41700f91a0..ea06c128c4 100644
--- a/src/usr.sbin/ocspcheck/ocspcheck.c
+++ b/src/usr.sbin/ocspcheck/ocspcheck.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ocspcheck.c,v 1.25 2019/05/15 13:44:18 bcook Exp $ */ 1/* $OpenBSD: ocspcheck.c,v 1.26 2020/01/23 03:53:39 tb Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2017 Bob Beck <beck@openbsd.org> 4 * Copyright (c) 2017 Bob Beck <beck@openbsd.org>
@@ -184,35 +184,41 @@ parse_ocsp_time(ASN1_GENERALIZEDTIME *gt)
184} 184}
185 185
186static X509_STORE * 186static X509_STORE *
187read_cacerts(char *file) 187read_cacerts(const char *file, const char *dir)
188{ 188{
189 X509_STORE *store; 189 X509_STORE *store = NULL;
190 X509_LOOKUP *lookup; 190 X509_LOOKUP *lookup;
191 191
192 if ((store = X509_STORE_new()) == NULL) { 192 if (file == NULL && dir == NULL) {
193 warnx("Malloc failed"); 193 warnx("No CA certs to load");
194 goto end; 194 goto end;
195 } 195 }
196 if ((lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file())) == 196 if ((store = X509_STORE_new()) == NULL) {
197 NULL) { 197 warnx("Malloc failed");
198 warnx("Unable to load CA certs from file %s", file);
199 goto end; 198 goto end;
200 } 199 }
201 if (file) { 200 if (file != NULL) {
201 if ((lookup = X509_STORE_add_lookup(store,
202 X509_LOOKUP_file())) == NULL) {
203 warnx("Unable to load CA cert file");
204 goto end;
205 }
202 if (!X509_LOOKUP_load_file(lookup, file, X509_FILETYPE_PEM)) { 206 if (!X509_LOOKUP_load_file(lookup, file, X509_FILETYPE_PEM)) {
203 warnx("Unable to load CA certs from file %s", file); 207 warnx("Unable to load CA certs from file %s", file);
204 goto end; 208 goto end;
205 } 209 }
206 } else
207 X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT);
208
209 if ((lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir())) ==
210 NULL) {
211 warnx("Unable to load CA certs from file %s", file);
212 goto end;
213 } 210 }
214 X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT); 211 if (dir != NULL) {
215 ERR_clear_error(); 212 if ((lookup = X509_STORE_add_lookup(store,
213 X509_LOOKUP_hash_dir())) == NULL) {
214 warnx("Unable to load CA cert directory");
215 goto end;
216 }
217 if (!X509_LOOKUP_add_dir(lookup, dir, X509_FILETYPE_PEM)) {
218 warnx("Unable to load CA certs from directory %s", dir);
219 goto end;
220 }
221 }
216 return store; 222 return store;
217 223
218end: 224end:
@@ -289,7 +295,7 @@ issuer_from_chain(STACK_OF(X509) *fullchain)
289} 295}
290 296
291static ocsp_request * 297static ocsp_request *
292ocsp_request_new_from_cert(char *file, int nonce) 298ocsp_request_new_from_cert(const char *cadir, char *file, int nonce)
293{ 299{
294 X509 *cert = NULL; 300 X509 *cert = NULL;
295 int count = 0; 301 int count = 0;
@@ -308,10 +314,11 @@ ocsp_request_new_from_cert(char *file, int nonce)
308 return NULL; 314 return NULL;
309 315
310 request->fullchain = read_fullchain(file, &count); 316 request->fullchain = read_fullchain(file, &count);
311 /* Drop rpath from pledge, we don't need to read anymore */ 317 if (cadir == NULL) {
312 if (pledge("stdio inet dns", NULL) == -1) 318 /* Drop rpath from pledge, we don't need to read anymore */
313 err(1, "pledge"); 319 if (pledge("stdio inet dns", NULL) == -1)
314 320 err(1, "pledge");
321 }
315 if (request->fullchain == NULL) 322 if (request->fullchain == NULL)
316 return NULL; 323 return NULL;
317 if (count <= 1) { 324 if (count <= 1) {
@@ -506,8 +513,9 @@ usage(void)
506int 513int
507main(int argc, char **argv) 514main(int argc, char **argv)
508{ 515{
516 const char *cafile = NULL, *cadir = NULL;
509 char *host = NULL, *path = "/", *certfile = NULL, *outfile = NULL, 517 char *host = NULL, *path = "/", *certfile = NULL, *outfile = NULL,
510 *cafile = NULL, *instaple = NULL, *infile = NULL; 518 *instaple = NULL, *infile = NULL;
511 struct addr addrs[MAX_SERVERS_DNS] = {{0}}; 519 struct addr addrs[MAX_SERVERS_DNS] = {{0}};
512 struct source sources[MAX_SERVERS_DNS]; 520 struct source sources[MAX_SERVERS_DNS];
513 int i, ch, staplefd = -1, infd = -1, nonce = 1; 521 int i, ch, staplefd = -1, infd = -1, nonce = 1;
@@ -566,6 +574,24 @@ main(int argc, char **argv)
566 nonce = 0; /* Can't validate a nonce on a saved reply */ 574 nonce = 0; /* Can't validate a nonce on a saved reply */
567 } 575 }
568 576
577 if (cafile == NULL) {
578 if (access(X509_get_default_cert_file(), R_OK) == 0)
579 cafile = X509_get_default_cert_file();
580 if (access(X509_get_default_cert_dir(), F_OK) == 0)
581 cadir = X509_get_default_cert_dir();
582 }
583
584 if (cafile != NULL) {
585 if (unveil(cafile, "r") == -1)
586 err(1, "unveil");
587 }
588 if (cadir != NULL) {
589 if (unveil(cadir, "r") == -1)
590 err(1, "unveil");
591 }
592 if (unveil(certfile, "r") == -1)
593 err(1, "unveil");
594
569 if (pledge("stdio inet rpath dns", NULL) == -1) 595 if (pledge("stdio inet rpath dns", NULL) == -1)
570 err(1, "pledge"); 596 err(1, "pledge");
571 597
@@ -574,9 +600,10 @@ main(int argc, char **argv)
574 * OCSP request based on the full certificate chain 600 * OCSP request based on the full certificate chain
575 * we have been given to check. 601 * we have been given to check.
576 */ 602 */
577 if ((castore = read_cacerts(cafile)) == NULL) 603 if ((castore = read_cacerts(cafile, cadir)) == NULL)
578 exit(1); 604 exit(1);
579 if ((request = ocsp_request_new_from_cert(certfile, nonce)) == NULL) 605 if ((request = ocsp_request_new_from_cert(cadir, certfile, nonce))
606 == NULL)
580 exit(1); 607 exit(1);
581 608
582 dspew("Built an %zu byte ocsp request\n", request->size); 609 dspew("Built an %zu byte ocsp request\n", request->size);
@@ -612,8 +639,13 @@ main(int argc, char **argv)
612 * routines and parsing untrusted input from someone's OCSP 639 * routines and parsing untrusted input from someone's OCSP
613 * server. 640 * server.
614 */ 641 */
615 if (pledge("stdio", NULL) == -1) 642 if (cadir == NULL) {
616 err(1, "pledge"); 643 if (pledge("stdio", NULL) == -1)
644 err(1, "pledge");
645 } else {
646 if (pledge("stdio rpath", NULL) == -1)
647 err(1, "pledge");
648 }
617 649
618 dspew("Server at %s returns:\n", host); 650 dspew("Server at %s returns:\n", host);
619 for (i = 0; i < httphsz; i++) 651 for (i = 0; i < httphsz; i++)
@@ -641,8 +673,13 @@ main(int argc, char **argv)
641 /* 673 /*
642 * Pledge minimally before fiddling with libcrypto init 674 * Pledge minimally before fiddling with libcrypto init
643 */ 675 */
644 if (pledge("stdio", NULL) == -1) 676 if (cadir == NULL) {
645 err(1, "pledge"); 677 if (pledge("stdio", NULL) == -1)
678 err(1, "pledge");
679 } else {
680 if (pledge("stdio rpath", NULL) == -1)
681 err(1, "pledge");
682 }
646 683
647 dspew("Using ocsp response saved in %s:\n", infile); 684 dspew("Using ocsp response saved in %s:\n", infile);
648 685