From d7f1a6dd6814bc657a1fa9fc9821d8e7f3b65d00 Mon Sep 17 00:00:00 2001 From: bluhm <> Date: Tue, 15 Sep 2020 01:45:16 +0000 Subject: Test botan TLS client with libressl, openssl, openssl11 server. --- src/regress/lib/libssl/interop/Makefile | 3 +- src/regress/lib/libssl/interop/Makefile.inc | 10 +- src/regress/lib/libssl/interop/botan/Makefile | 70 ++++++++ src/regress/lib/libssl/interop/botan/client.cpp | 228 ++++++++++++++++++++++++ 4 files changed, 305 insertions(+), 6 deletions(-) create mode 100644 src/regress/lib/libssl/interop/botan/Makefile create mode 100644 src/regress/lib/libssl/interop/botan/client.cpp (limited to 'src') diff --git a/src/regress/lib/libssl/interop/Makefile b/src/regress/lib/libssl/interop/Makefile index cf06d8c022..0bd1195d39 100644 --- a/src/regress/lib/libssl/interop/Makefile +++ b/src/regress/lib/libssl/interop/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.11 2020/09/14 00:51:04 bluhm Exp $ +# $OpenBSD: Makefile,v 1.12 2020/09/15 01:45:16 bluhm Exp $ SUBDIR = libressl openssl openssl11 @@ -8,5 +8,6 @@ SUBDIR += cipher SUBDIR += version SUBDIR += netcat SUBDIR += session +SUBDIR += botan .include diff --git a/src/regress/lib/libssl/interop/Makefile.inc b/src/regress/lib/libssl/interop/Makefile.inc index dfe1424949..91f88e2b0b 100644 --- a/src/regress/lib/libssl/interop/Makefile.inc +++ b/src/regress/lib/libssl/interop/Makefile.inc @@ -1,9 +1,9 @@ -# $OpenBSD: Makefile.inc,v 1.6 2019/02/21 23:06:33 bluhm Exp $ +# $OpenBSD: Makefile.inc,v 1.7 2020/09/15 01:45:16 bluhm Exp $ .PATH: ${.CURDIR}/.. -SRCS_client = client.c util.c -SRCS_server = server.c util.c +SRCS_client ?= client.c util.c +SRCS_server ?= server.c util.c WARNINGS = yes CLEANFILES += *.out *.fstat @@ -43,8 +43,8 @@ CLEANFILES += 127.0.0.1.{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 $@ + -subj /L=OpenBSD/O=tls-regress/OU=server/CN=${@:R}/ \ + -nodes -newkey rsa -keyout ${@:R}.key -x509 -out $@ ca.crt fake-ca.crt: openssl req -batch -new \ diff --git a/src/regress/lib/libssl/interop/botan/Makefile b/src/regress/lib/libssl/interop/botan/Makefile new file mode 100644 index 0000000000..f6a87dd6d7 --- /dev/null +++ b/src/regress/lib/libssl/interop/botan/Makefile @@ -0,0 +1,70 @@ +# $OpenBSD: Makefile,v 1.1 2020/09/15 01:45:16 bluhm Exp $ + +.if ! exists(/usr/local/bin/botan) +regress: + # install botan2 from ports for interop tests + @echo SKIPPED +.endif + +LIBRARIES = libressl +.if exists(/usr/local/bin/eopenssl) +LIBRARIES += openssl +.endif +.if exists(/usr/local/bin/eopenssl11) +LIBRARIES += openssl11 +.endif + +PROGS = client +SRCS_client = client.cpp +CXXFLAGS = -I/usr/local/include/botan-2 -Wall +LDFLAGS = -L/usr/local/lib +LDADD = -lbotan-2 +DPADD = /usr/local/lib/libbotan-2.a + +.for lib in ${LIBRARIES} + +REGRESS_TARGETS += run-client-botan-server-${lib} + +run-client-botan-server-${lib}: client server.crt + @echo '\n======== $@ ========' + LD_LIBRARY_PATH=/usr/local/lib/e${lib} \ + ../${lib}/server >server-${lib}.out \ + -c server.crt -k server.key \ + 127.0.0.1 0 + ./client >client-botan.out \ + -C ca.crt \ + 127.0.0.1 \ + `sed -n 's/listen sock: 127.0.0.1 //p' server-${lib}.out` + # check that the server child run successfully to the end + grep -q '^success$$' server-${lib}.out || \ + { sleep 1; grep -q '^success$$' server-${lib}.out; } + # server must have read client hello + grep -q '^<<< hello$$' server-${lib}.out + # check that the client run successfully to the end + grep -q '^success$$' client-botan.out + # client must have read server greeting + grep -q '^<<< greeting$$' client-botan.out + # currently botan supports TLS 1.2, adapt later + grep -q ' Protocol *: TLSv1.2$$' server-${lib}.out + +.endfor + +server.key ca.key: + /usr/local/bin/botan keygen >$@.tmp + mv $@.tmp $@ + +ca.crt: ${@:R}.key + /usr/local/bin/botan gen_self_signed ${@:R}.key ${@:R} >$@.tmp \ + --organization=tls-regress --ca + mv $@.tmp $@ + +server.req: ${@:R}.key + /usr/local/bin/botan gen_pkcs10 ${@:R}.key localhost >$@.tmp \ + --organization=tls-regress --dns=127.0.0.1 + mv $@.tmp $@ + +server.crt: ca.crt ${@:R}.req + /usr/local/bin/botan sign_cert ca.crt ca.key ${@:R}.req >$@.tmp + mv $@.tmp $@ + +.include diff --git a/src/regress/lib/libssl/interop/botan/client.cpp b/src/regress/lib/libssl/interop/botan/client.cpp new file mode 100644 index 0000000000..2352d7bba2 --- /dev/null +++ b/src/regress/lib/libssl/interop/botan/client.cpp @@ -0,0 +1,228 @@ +/* $OpenBSD: client.cpp,v 1.1 2020/09/15 01:45:16 bluhm Exp $ */ +/* + * Copyright (c) 2019-2020 Alexander Bluhm + * + * 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 +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +using namespace std; + +class Callbacks : public Botan::TLS::Callbacks { +public: + Callbacks(int socket) : + m_socket(socket) + {} + + void print_sockname() + { + struct sockaddr_storage ss; + char host[NI_MAXHOST], port[NI_MAXSERV]; + socklen_t slen; + + slen = sizeof(ss); + if (getsockname(m_socket, (struct sockaddr *)&ss, &slen) == -1) + err(1, "getsockname"); + if (getnameinfo((struct sockaddr *)&ss, ss.ss_len, host, + sizeof(host), port, sizeof(port), + NI_NUMERICHOST | NI_NUMERICSERV)) + errx(1, "getnameinfo"); + cout <<"sock: " < 0) { + ssize_t n; + + n = send(m_socket, data + off, len, 0); + if (n < 0) + err(1, "send"); + off += n; + len -= n; + } + } + + void tls_record_received(uint64_t seq_no, const uint8_t data[], + size_t size) override + { + cout <<"<<< " <>> " <send(str); + m_channel->close(); + } + + void tls_alert(Botan::TLS::Alert alert) override + { + errx(1, "alert: %s", alert.type_string().c_str()); + } + + bool tls_session_established(const Botan::TLS::Session& session) + override + { + cout <<"established" < trusted_certificate_authorities( + const std::string &type, const std::string &context) + override + { + std::vector cs { &m_ca }; + return cs; + } + + void add_certificate_file(const std::string &file) { + Botan::X509_Certificate cert(file); + m_ca.add_certificate(cert); + } +private: + Botan::Certificate_Store_In_Memory m_ca; +}; + +class Policy : public Botan::TLS::Strict_Policy { +public: + bool require_cert_revocation_info() const override { + return false; + } +}; + +void __dead +usage(void) +{ + fprintf(stderr, "usage: client [-C CA] host port\n"); + exit(2); +} + +int +main(int argc, char *argv[]) +{ + struct addrinfo hints, *res; + int ch, s, error; + char buf[256]; + char *cafile = NULL; + char *host, *port; + + while ((ch = getopt(argc, argv, "C:")) != -1) { + switch (ch) { + case 'C': + cafile = optarg; + break; + default: + usage(); + } + } + argc -= optind; + argv += optind; + if (argc == 2) { + host = argv[0]; + port = argv[1]; + } else { + usage(); + } + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + error = getaddrinfo(host, port, &hints, &res); + if (error) + errx(1, "getaddrinfo: %s", gai_strerror(error)); + if (res == NULL) + errx(1, "getaddrinfo empty"); + s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (s == -1) + err(1, "socket"); + if (connect(s, res->ai_addr, res->ai_addrlen) == -1) + err(1, "connect"); + freeaddrinfo(res); + + { + Callbacks callbacks(s); + Botan::AutoSeeded_RNG rng; + Botan::TLS::Session_Manager_In_Memory session_mgr(rng); + Credentials creds; + if (cafile != NULL) + creds.add_certificate_file(cafile); + Policy policy; + + callbacks.print_sockname(); + callbacks.print_peername(); + Botan::TLS::Client client(callbacks, session_mgr, creds, + policy, rng); + callbacks.set_channel(client); + + while (!client.is_closed()) { + ssize_t n; + + n = recv(s, buf, sizeof(buf), 0); + if (n < 0) + err(1, "recv"); + if (n == 0) + errx(1, "eof"); + client.received_data((uint8_t *)&buf, n); + } + } + + if (close(s) == -1) + err(1, "close"); + + cout <<"success" <