diff options
author | 2018-11-09 06:30:41 +0000 | |
---|---|---|
committer | 2018-11-09 06:30:41 +0000 | |
commit | a8d85e88ed9b5d655d229d3ed8828f64afac8a9f (patch) | |
tree | 3fbdf5a18051540eac9aacb8628711b3d2764a75 | |
parent | Delete superfluous libc reacharounds. (diff) | |
download | wireguard-openbsd-a8d85e88ed9b5d655d229d3ed8828f64afac8a9f.tar.xz wireguard-openbsd-a8d85e88ed9b5d655d229d3ed8828f64afac8a9f.zip |
The cert subdir is testing all combinations of certificate validation.
Having the three libraries, client and server certificates, missing
or invalid CA or certificates, and enforcing peer certificate results
in 1944 new test cases.
-rw-r--r-- | regress/lib/libssl/interop/Makefile | 4 | ||||
-rw-r--r-- | regress/lib/libssl/interop/Makefile.inc | 43 | ||||
-rw-r--r-- | regress/lib/libssl/interop/README | 5 | ||||
-rw-r--r-- | regress/lib/libssl/interop/cert/Makefile | 70 | ||||
-rw-r--r-- | regress/lib/libssl/interop/client.c | 58 | ||||
-rw-r--r-- | regress/lib/libssl/interop/libressl/Makefile | 9 | ||||
-rw-r--r-- | regress/lib/libssl/interop/openssl/Makefile | 9 | ||||
-rw-r--r-- | regress/lib/libssl/interop/openssl11/Makefile | 9 | ||||
-rw-r--r-- | regress/lib/libssl/interop/server.c | 70 | ||||
-rw-r--r-- | regress/lib/libssl/interop/util.c | 12 | ||||
-rw-r--r-- | regress/lib/libssl/interop/util.h | 3 |
11 files changed, 244 insertions, 48 deletions
diff --git a/regress/lib/libssl/interop/Makefile b/regress/lib/libssl/interop/Makefile index d89376aaf61..0226cae4abe 100644 --- a/regress/lib/libssl/interop/Makefile +++ b/regress/lib/libssl/interop/Makefile @@ -1,5 +1,5 @@ -# $OpenBSD: Makefile,v 1.2 2018/11/07 19:09:01 bluhm Exp $ +# $OpenBSD: Makefile,v 1.3 2018/11/09 06:30:41 bluhm Exp $ -SUBDIR = libressl openssl openssl11 +SUBDIR = libressl openssl openssl11 cert .include <bsd.subdir.mk> diff --git a/regress/lib/libssl/interop/Makefile.inc b/regress/lib/libssl/interop/Makefile.inc index 1a1ef30ca68..9daae79e57a 100644 --- a/regress/lib/libssl/interop/Makefile.inc +++ b/regress/lib/libssl/interop/Makefile.inc @@ -1,17 +1,15 @@ -# $OpenBSD: Makefile.inc,v 1.3 2018/11/07 20:46:28 bluhm Exp $ +# $OpenBSD: Makefile.inc,v 1.4 2018/11/09 06:30:41 bluhm Exp $ .PATH: ${.CURDIR}/.. SRCS_client = client.c util.c SRCS_server = server.c util.c WARNINGS = yes -REGRESS_TARGETS = # check that program is linked with correct libraries .for p in ${PROGS} CLEANFILES += ldd-$p.out -REGRESS_TARGETS += run-ldd-$p ldd-$p.out: $p LD_LIBRARY_PATH=${LD_LIBRARY_PATH} ldd $p >$@ .endfor @@ -19,12 +17,13 @@ ldd-$p.out: $p # run netcat server and connect with test client CLEANFILES += nc-client.out netcat-l.out netcat-l.fstat -REGRESS_TARGETS += run-client nc-client.out run-client: client 127.0.0.1.crt @echo '\n======== $@ ========' echo "greeting" | nc -l -c -C 127.0.0.1.crt -K 127.0.0.1.key \ 127.0.0.1 0 >netcat-l.out & \ - sleep 1; fstat -p $$! >netcat-l.fstat + for i in `jot 1000`; do fstat -p $$! >netcat-l.fstat; \ + grep -q ' stream tcp .*:[1-9][0-9]*$$' netcat-l.fstat && exit 0; \ + done; exit 1 LD_LIBRARY_PATH=${LD_LIBRARY_PATH} ./client \ `sed -n 's/.* stream tcp .*:/127.0.0.1 /p' netcat-l.fstat` \ >nc-client.out @@ -38,12 +37,11 @@ nc-client.out run-client: client 127.0.0.1.crt # run test server and connect with netcat client CLEANFILES += nc-server.out netcat.out -REGRESS_TARGETS += run-server nc-server.out run-server: server 127.0.0.1.crt @echo '\n======== $@ ========' LD_LIBRARY_PATH=${LD_LIBRARY_PATH} ./server 127.0.0.1 0 \ >nc-server.out - echo "hello" | nc -c -T noverify \ + echo "hello" | nc -c -R 127.0.0.1.crt \ `sed -n 's/listen sock: //p' nc-server.out` \ >netcat.out # check that the server child run successfully to the end @@ -56,7 +54,6 @@ nc-server.out run-server: server 127.0.0.1.crt # run test server and with test client, self test the ssl library CLEANFILES += self-client.out self-server.out -REGRESS_TARGETS += run-self self-client.out self-server.out run-self: client server 127.0.0.1.crt @echo '\n======== $@ ========' LD_LIBRARY_PATH=${LD_LIBRARY_PATH} ./server 127.0.0.1 0 \ @@ -73,23 +70,27 @@ self-client.out self-server.out run-self: client server 127.0.0.1.crt # server must have read client hello grep -q '^<<< hello$$' self-server.out -.for o in nc-client nc-server self-client self-server - -# check that client and server have used correct runtime library - -REGRESS_TARGETS += run-version-$o - -# check that client and server have used correct TLS protocol - -REGRESS_TARGETS += run-protocol-$o - -.endfor - # create certificates for TLS -CLEANFILES += 127.0.0.1.crt 127.0.0.1.key +CLEANFILES += 127.0.0.1.{crt,key} \ + ca.{crt,key,srl} fake-ca.{crt,key} \ + {client,server}.{req,crt,key} 127.0.0.1.crt: openssl req -batch -new \ -subj /L=OpenBSD/O=tls-regress/OU=server/CN=127.0.0.1/ \ -nodes -newkey rsa -keyout 127.0.0.1.key -x509 -out $@ + +ca.crt fake-ca.crt: + openssl req -batch -new \ + -subj /L=OpenBSD/O=tls-regress/OU=ca/CN=root/ \ + -nodes -newkey rsa -keyout ${@:R}.key -x509 -out $@ + +client.req server.req: + openssl req -batch -new \ + -subj /L=OpenBSD/O=tls-regress/OU=${@:R}/CN=localhost/ \ + -nodes -newkey rsa -keyout ${@:R}.key -out $@ + +client.crt server.crt: ca.crt ${@:R}.req + openssl x509 -CAcreateserial -CAkey ca.key -CA ca.crt \ + -req -in ${@:R}.req -out $@ diff --git a/regress/lib/libssl/interop/README b/regress/lib/libssl/interop/README index 1bd418c9cc2..b53b47b878a 100644 --- a/regress/lib/libssl/interop/README +++ b/regress/lib/libssl/interop/README @@ -12,3 +12,8 @@ that the highest available TLS version is selected. LibreSSL TLS Currently OpenSSL 1.0.2p and OpenSSL 1.1.1 from ports are used. As soon as LibreSSL supports TLS 1.3, it should be used automatically when netcat is communicating with OpenSSL 1.1. + +The cert subdir is testing all combinations of certificate validation. +Having the three libraries, client and server certificates, missing +or invalid CA or certificates, and enforcing peer certificate results +in 1944 test cases. diff --git a/regress/lib/libssl/interop/cert/Makefile b/regress/lib/libssl/interop/cert/Makefile new file mode 100644 index 00000000000..dabc0441f0d --- /dev/null +++ b/regress/lib/libssl/interop/cert/Makefile @@ -0,0 +1,70 @@ +# $OpenBSD: Makefile,v 1.1 2018/11/09 06:30:41 bluhm Exp $ + +.if ! exists(/usr/local/bin/eopenssl) || ! exists(/usr/local/bin/eopenssl11) +regress: + # install openssl-1.0.2p and openssl-1.1.1 from ports + @echo SKIPPED +.endif + +CLEANFILES += client.out server.out + +.for cca in noca ca fakeca +.for sca in noca ca fakeca +.for ccert in nocert cert +.for scert in nocert cert +.for cv in noverify verify +.for sv in noverify verify certverify + +# remember when certificate verification should fail +.if (("${cv}" == verify && "${cca}" == ca && "${scert}" == cert) || \ + "${cv}" == noverify) && \ + (("${sv}" == verify && "${ccert}" == nocert) || \ + ("${sv}" == verify && "${sca}" == ca && "${ccert}" == cert) || \ + ("${sv}" == certverify && "${sca}" == ca && "${ccert}" == cert) || \ + "${sv}" == noverify) +FAIL_${cca}_${sca}_${ccert}_${scert}_${cv}_${sv} = +.else +FAIL_${cca}_${sca}_${ccert}_${scert}_${cv}_${sv} = ! +.endif + +.for clib in libressl openssl openssl11 +.for slib in libressl openssl openssl11 + +REGRESS_TARGETS += \ +run-client-${clib}-${cca}-${ccert}-${cv}-server-${slib}-${sca}-${scert}-${sv} + +run-client-${clib}-${cca}-${ccert}-${cv}-server-${slib}-${sca}-${scert}-${sv}:\ + 127.0.0.1.crt ca.crt fake-ca.crt client.crt server.crt \ + ../${clib}/client ../${slib}/server + @echo '\n======== $@ ========' + LD_LIBRARY_PATH=/usr/local/lib/e${slib} \ + ../${slib}/server >server.out \ + ${sca:S/^noca//:S/^fakeca/-C fake-ca.crt/:S/^ca/-C ca.crt/} \ + ${scert:S/^nocert//:S/^cert/-c server.crt -k server.key/} \ + ${sv:S/^noverify//:S/^verify/-v/:S/^certverify/-vv/} \ + 127.0.0.1 0 + ${FAIL_${cca}_${sca}_${ccert}_${scert}_${cv}_${sv}} \ + LD_LIBRARY_PATH=/usr/local/lib/e${clib} \ + ../${clib}/client >client.out \ + ${cca:S/^noca//:S/^fakeca/-C fake-ca.crt/:S/^ca/-C ca.crt/} \ + ${ccert:S/^nocert//:S/^cert/-c server.crt -k server.key/} \ + ${cv:S/^noverify//:S/^verify/-v/} \ + `sed -n 's/listen sock: //p' server.out` +.if empty(${FAIL_${cca}_${sca}_${ccert}_${scert}_${cv}_${sv}}) + grep '^success$$' server.out + grep '^success$$' client.out +.elif ! ("${sv}" == certverify && "${ccert}" == nocert) || \ + ("${cv}" == verify && "${scert}" != cert) + grep '^verify: fail' client.out server.out +.endif + +.endfor +.endfor +.endfor +.endfor +.endfor +.endfor +.endfor +.endfor + +.include <bsd.regress.mk> diff --git a/regress/lib/libssl/interop/client.c b/regress/lib/libssl/interop/client.c index 60fb718fdb4..c312d7ae8ad 100644 --- a/regress/lib/libssl/interop/client.c +++ b/regress/lib/libssl/interop/client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: client.c,v 1.3 2018/11/07 19:09:01 bluhm Exp $ */ +/* $OpenBSD: client.c,v 1.4 2018/11/09 06:30:41 bluhm Exp $ */ /* * Copyright (c) 2018 Alexander Bluhm <bluhm@openbsd.org> * @@ -34,7 +34,8 @@ void __dead usage(void); void __dead usage(void) { - fprintf(stderr, "usage: client host port"); + fprintf(stderr, + "usage: client [-c] [-C CA] [-c crt -k key] host port"); exit(2); } @@ -46,19 +47,42 @@ main(int argc, char *argv[]) SSL *ssl; BIO *bio; SSL_SESSION *session; - int error; - char buf[256]; + int error, verify = 0; + char buf[256], ch; + char *ca = NULL, *crt = NULL, *key = NULL; char *host_port, *host, *port; - if (argc == 3) { - host = argv[1]; - port = argv[2]; + while ((ch = getopt(argc, argv, "C:c:k:v")) != -1) { + switch (ch) { + case 'C': + ca = optarg; + break; + case 'c': + crt = optarg; + break; + case 'k': + key = optarg; + break; + case 'v': + verify = 1; + break; + default: + usage(); + } + } + argc -= optind; + argv += optind; + if (argc == 2) { + host = argv[0]; + port = argv[1]; } else { usage(); } if (asprintf(&host_port, strchr(host, ':') ? "[%s]:%s" : "%s:%s", host, port) == -1) err(1, "asprintf host port"); + if ((crt == NULL && key != NULL) || (crt != NULL && key == NULL)) + errx(1, "certificate and private key must be used together"); SSL_library_init(); SSL_load_error_strings(); @@ -78,6 +102,26 @@ main(int argc, char *argv[]) if (ctx == NULL) err_ssl(1, "SSL_CTX_new"); + /* load client certificate */ + if (crt != NULL) { + if (SSL_CTX_use_certificate_file(ctx, crt, + SSL_FILETYPE_PEM) <= 0) + err_ssl(1, "SSL_CTX_use_certificate_file"); + if (SSL_CTX_use_PrivateKey_file(ctx, key, + SSL_FILETYPE_PEM) <= 0) + err_ssl(1, "SSL_CTX_use_PrivateKey_file"); + if (SSL_CTX_check_private_key(ctx) <= 0) + err_ssl(1, "SSL_CTX_check_private_key"); + } + + /* verify server certificate */ + if (ca != NULL) { + if (SSL_CTX_load_verify_locations(ctx, ca, NULL) <= 0) + err_ssl(1, "SSL_CTX_load_verify_locations"); + } + SSL_CTX_set_verify(ctx, verify ? SSL_VERIFY_PEER : SSL_VERIFY_NONE, + verify_callback); + /* setup ssl and bio for socket operations */ ssl = SSL_new(ctx); if (ssl == NULL) diff --git a/regress/lib/libssl/interop/libressl/Makefile b/regress/lib/libssl/interop/libressl/Makefile index 19557ffbc1c..6923e124695 100644 --- a/regress/lib/libssl/interop/libressl/Makefile +++ b/regress/lib/libssl/interop/libressl/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.3 2018/11/07 20:46:28 bluhm Exp $ +# $OpenBSD: Makefile,v 1.4 2018/11/09 06:30:41 bluhm Exp $ PROGS = client server CPPFLAGS = @@ -6,6 +6,13 @@ LDFLAGS = LDADD = -lssl -lcrypto DPADD = ${LIBSSL} ${LIBCRYPTO} LD_LIBRARY_PATH = +REGRESS_TARGETS = run-self +.for p in ${PROGS} +REGRESS_TARGETS += run-ldd-$p run-$p +.for x in nc self +REGRESS_TARGETS += run-version-$x-$p run-protocol-$x-$p +.endfor +.endfor run-protocol-self-client run-protocol-self-server \ run-protocol-nc-client run-protocol-nc-server: diff --git a/regress/lib/libssl/interop/openssl/Makefile b/regress/lib/libssl/interop/openssl/Makefile index ad0c7288cab..5c51c029cea 100644 --- a/regress/lib/libssl/interop/openssl/Makefile +++ b/regress/lib/libssl/interop/openssl/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.3 2018/11/07 20:46:28 bluhm Exp $ +# $OpenBSD: Makefile,v 1.4 2018/11/09 06:30:41 bluhm Exp $ .if ! exists(/usr/local/bin/eopenssl) regress: @@ -13,6 +13,13 @@ LDADD = -lssl -lcrypto DPADD = /usr/local/lib/eopenssl/libssl.a \ /usr/local/lib/eopenssl/libcrypto.a LD_LIBRARY_PATH = /usr/local/lib/eopenssl +REGRESS_TARGETS = run-self +.for p in ${PROGS} +REGRESS_TARGETS += run-ldd-$p run-$p +.for x in nc self +REGRESS_TARGETS += run-version-$x-$p run-protocol-$x-$p +.endfor +.endfor .for p in ${PROGS} run-ldd-$p: ldd-$p.out diff --git a/regress/lib/libssl/interop/openssl11/Makefile b/regress/lib/libssl/interop/openssl11/Makefile index e7257a3976f..ec6f6db7ec6 100644 --- a/regress/lib/libssl/interop/openssl11/Makefile +++ b/regress/lib/libssl/interop/openssl11/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.2 2018/11/07 20:46:28 bluhm Exp $ +# $OpenBSD: Makefile,v 1.3 2018/11/09 06:30:41 bluhm Exp $ .if ! exists(/usr/local/bin/eopenssl11) regress: @@ -13,6 +13,13 @@ LDADD = -lssl -lcrypto DPADD = /usr/local/lib/eopenssl11/libssl.a \ /usr/local/lib/eopenssl11/libcrypto.a LD_LIBRARY_PATH = /usr/local/lib/eopenssl11 +REGRESS_TARGETS = run-self +.for p in ${PROGS} +REGRESS_TARGETS += run-ldd-$p run-$p +.for x in nc self +REGRESS_TARGETS += run-version-$x-$p run-protocol-$x-$p +.endfor +.endfor run-protocol-nc-client run-protocol-nc-server: @echo '\n======== $@ ========' diff --git a/regress/lib/libssl/interop/server.c b/regress/lib/libssl/interop/server.c index 0aece87583c..6c0c720dfec 100644 --- a/regress/lib/libssl/interop/server.c +++ b/regress/lib/libssl/interop/server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server.c,v 1.3 2018/11/07 19:09:01 bluhm Exp $ */ +/* $OpenBSD: server.c,v 1.4 2018/11/09 06:30:41 bluhm Exp $ */ /* * Copyright (c) 2018 Alexander Bluhm <bluhm@openbsd.org> * @@ -34,7 +34,8 @@ void __dead usage(void); void __dead usage(void) { - fprintf(stderr, "usage: server [host port]"); + fprintf(stderr, + "usage: server [-vv] [-C CA] [-c crt -k key] [host port]"); exit(2); } @@ -46,22 +47,46 @@ main(int argc, char *argv[]) SSL *ssl; BIO *bio; SSL_SESSION *session; - int error; - char buf[256]; - char *crt, *key, *host_port, *host = "127.0.0.1", *port = "0"; - - if (argc == 3) { - host = argv[1]; - port = argv[2]; - } else if (argc != 1) { + int error, verify = 0; + char buf[256], ch; + char *ca = NULL, *crt = NULL, *key = NULL; + char *host_port, *host = "127.0.0.1", *port = "0"; + + while ((ch = getopt(argc, argv, "C:c:k:v")) != -1) { + switch (ch) { + case 'C': + ca = optarg; + break; + case 'c': + crt = optarg; + break; + case 'k': + key = optarg; + break; + case 'v': + /* use twice to force client cert */ + verify++; + break; + default: + usage(); + } + } + argc -= optind; + argv += optind; + if (argc == 2) { + host = argv[0]; + port = argv[1]; + } else if (argc != 0) { usage(); } if (asprintf(&host_port, strchr(host, ':') ? "[%s]:%s" : "%s:%s", host, port) == -1) err(1, "asprintf host port"); - if (asprintf(&crt, "%s.crt", host) == -1) + if ((crt == NULL && key != NULL) || (crt != NULL && key == NULL)) + errx(1, "certificate and private key must be used together"); + if (crt == NULL && asprintf(&crt, "%s.crt", host) == -1) err(1, "asprintf crt"); - if (asprintf(&key, "%s.key", host) == -1) + if (key == NULL && asprintf(&key, "%s.key", host) == -1) err(1, "asprintf key"); SSL_library_init(); @@ -94,6 +119,23 @@ main(int argc, char *argv[]) if (SSL_CTX_check_private_key(ctx) <= 0) err_ssl(1, "SSL_CTX_check_private_key"); + /* request client certificate and verify it */ + if (ca != NULL) { + STACK_OF(X509_NAME) *x509stack; + + x509stack = SSL_load_client_CA_file(ca); + if (x509stack == NULL) + err_ssl(1, "SSL_load_client_CA_file"); + SSL_CTX_set_client_CA_list(ctx, x509stack); + if (SSL_CTX_load_verify_locations(ctx, ca, NULL) <= 0) + err_ssl(1, "SSL_CTX_load_verify_locations"); + } + SSL_CTX_set_verify(ctx, + verify == 0 ? SSL_VERIFY_NONE : + verify == 1 ? SSL_VERIFY_PEER : + SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, + verify_callback); + /* setup ssl and bio for socket operations */ ssl = SSL_new(ctx); if (ssl == NULL) @@ -109,9 +151,11 @@ main(int argc, char *argv[]) printf("listen "); print_sockname(bio); - /* fork to background and accept */ + /* fork to background, set timeout, and accept */ if (daemon(1, 1) == -1) err(1, "daemon"); + if ((int)alarm(60) == -1) + err(1, "alarm"); if (BIO_do_accept(bio) <= 0) err_ssl(1, "BIO_do_accept wait"); bio = BIO_pop(bio); diff --git a/regress/lib/libssl/interop/util.c b/regress/lib/libssl/interop/util.c index b012d731932..5190e81828e 100644 --- a/regress/lib/libssl/interop/util.c +++ b/regress/lib/libssl/interop/util.c @@ -1,4 +1,4 @@ -/* $OpenBSD: util.c,v 1.2 2018/11/07 06:29:26 bluhm Exp $ */ +/* $OpenBSD: util.c,v 1.3 2018/11/09 06:30:41 bluhm Exp $ */ /* * Copyright (c) 2018 Alexander Bluhm <bluhm@openbsd.org> * @@ -133,3 +133,13 @@ err_ssl(int eval, const char *fmt, ...) verrx(eval, fmt, ap); va_end(ap); } + +int +verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx) +{ + printf("verify: %s\n", preverify_ok ? "pass" : "fail"); + if (fflush(stdout) != 0) + err(1, "fflush stdout"); + + return preverify_ok; +} diff --git a/regress/lib/libssl/interop/util.h b/regress/lib/libssl/interop/util.h index 78f7bb63b6d..7414a037d70 100644 --- a/regress/lib/libssl/interop/util.h +++ b/regress/lib/libssl/interop/util.h @@ -1,4 +1,4 @@ -/* $OpenBSD: util.h,v 1.2 2018/11/07 06:29:26 bluhm Exp $ */ +/* $OpenBSD: util.h,v 1.3 2018/11/09 06:30:41 bluhm Exp $ */ /* * Copyright (c) 2018 Alexander Bluhm <bluhm@openbsd.org> * @@ -20,3 +20,4 @@ void print_ciphers(STACK_OF(SSL_CIPHER) *); void print_sockname(BIO *); void print_peername(BIO *); void err_ssl(int, const char *, ...); +int verify_callback(int, X509_STORE_CTX *); |