xref: /openbsd-src/regress/lib/libssl/interop/server.c (revision 188261f971cd38befa1c7c6b2989c3590d80f354)
1 /*	$OpenBSD: server.c,v 1.3 2018/11/07 19:09:01 bluhm Exp $	*/
2 /*
3  * Copyright (c) 2018 Alexander Bluhm <bluhm@openbsd.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <sys/types.h>
19 #include <sys/socket.h>
20 
21 #include <err.h>
22 #include <netdb.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <unistd.h>
26 
27 #include <openssl/err.h>
28 #include <openssl/ssl.h>
29 
30 #include "util.h"
31 
32 void __dead usage(void);
33 
34 void __dead
35 usage(void)
36 {
37 	fprintf(stderr, "usage: server [host port]");
38 	exit(2);
39 }
40 
41 int
42 main(int argc, char *argv[])
43 {
44 	const SSL_METHOD *method;
45 	SSL_CTX *ctx;
46 	SSL *ssl;
47 	BIO *bio;
48 	SSL_SESSION *session;
49 	int error;
50 	char buf[256];
51 	char *crt, *key, *host_port, *host = "127.0.0.1", *port = "0";
52 
53 	if (argc == 3) {
54 		host = argv[1];
55 		port = argv[2];
56 	} else if (argc != 1) {
57 		usage();
58 	}
59 	if (asprintf(&host_port, strchr(host, ':') ? "[%s]:%s" : "%s:%s",
60 	    host, port) == -1)
61 		err(1, "asprintf host port");
62 	if (asprintf(&crt, "%s.crt", host) == -1)
63 		err(1, "asprintf crt");
64 	if (asprintf(&key, "%s.key", host) == -1)
65 		err(1, "asprintf key");
66 
67 	SSL_library_init();
68 	SSL_load_error_strings();
69 	print_version();
70 
71 	/* setup method and context */
72 #if OPENSSL_VERSION_NUMBER >= 0x1010000f
73 	method = TLS_server_method();
74 	if (method == NULL)
75 		err_ssl(1, "TLS_server_method");
76 #else
77 	method = SSLv23_server_method();
78 	if (method == NULL)
79 		err_ssl(1, "SSLv23_server_method");
80 #endif
81 	ctx = SSL_CTX_new(method);
82 	if (ctx == NULL)
83 		err_ssl(1, "SSL_CTX_new");
84 
85 	/* needed when linking with OpenSSL 1.0.2p */
86 	if (SSL_CTX_set_ecdh_auto(ctx, 1) <= 0)
87 		err_ssl(1, "SSL_CTX_set_ecdh_auto");
88 
89 	/* load server certificate */
90 	if (SSL_CTX_use_certificate_file(ctx, crt, SSL_FILETYPE_PEM) <= 0)
91 		err_ssl(1, "SSL_CTX_use_certificate_file");
92 	if (SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM) <= 0)
93 		err_ssl(1, "SSL_CTX_use_PrivateKey_file");
94 	if (SSL_CTX_check_private_key(ctx) <= 0)
95 		err_ssl(1, "SSL_CTX_check_private_key");
96 
97 	/* setup ssl and bio for socket operations */
98 	ssl = SSL_new(ctx);
99 	if (ssl == NULL)
100 		err_ssl(1, "SSL_new");
101 	bio = BIO_new_accept(host_port);
102 	if (bio == NULL)
103 		err_ssl(1, "BIO_new_accept");
104 	print_ciphers(SSL_get_ciphers(ssl));
105 
106 	/* bind, listen */
107 	if (BIO_do_accept(bio) <= 0)
108 		err_ssl(1, "BIO_do_accept setup");
109 	printf("listen ");
110 	print_sockname(bio);
111 
112 	/* fork to background and accept */
113 	if (daemon(1, 1) == -1)
114 		err(1, "daemon");
115 	if (BIO_do_accept(bio) <= 0)
116 		err_ssl(1, "BIO_do_accept wait");
117 	bio = BIO_pop(bio);
118 	printf("accept ");
119 	print_sockname(bio);
120 	printf("accept ");
121 	print_peername(bio);
122 
123 	/* do ssl server handshake */
124 	SSL_set_bio(ssl, bio, bio);
125 	if ((error = SSL_accept(ssl)) <= 0)
126 		err_ssl(1, "SSL_accept %d", error);
127 
128 	/* print session statistics */
129 	session = SSL_get_session(ssl);
130 	if (session == NULL)
131 		err_ssl(1, "SSL_get_session");
132 	if (SSL_SESSION_print_fp(stdout, session) <= 0)
133 		err_ssl(1, "SSL_SESSION_print_fp");
134 
135 	/* write server greeting and read client hello over TLS connection */
136 	strlcpy(buf, "greeting\n", sizeof(buf));
137 	printf(">>> %s", buf);
138 	if (fflush(stdout) != 0)
139 		err(1, "fflush stdout");
140 	if ((error = SSL_write(ssl, buf, 9)) <= 0)
141 		err_ssl(1, "SSL_write %d", error);
142 	if (error != 9)
143 		errx(1, "write not 9 bytes greeting: %d", error);
144 	if ((error = SSL_read(ssl, buf, 6)) <= 0)
145 		err_ssl(1, "SSL_read %d", error);
146 	if (error != 6)
147 		errx(1, "read not 6 bytes hello: %d", error);
148 	buf[6] = '\0';
149 	printf("<<< %s", buf);
150 	if (fflush(stdout) != 0)
151 		err(1, "fflush stdout");
152 
153 	/* shutdown connection */
154 	if ((error = SSL_shutdown(ssl)) < 0)
155 		err_ssl(1, "SSL_shutdown unidirectional %d", error);
156 	if (error <= 0) {
157 		if ((error = SSL_shutdown(ssl)) <= 0)
158 			err_ssl(1, "SSL_shutdown bidirectional %d", error);
159 	}
160 
161 	/* cleanup and free resources */
162 	SSL_free(ssl);
163 	SSL_CTX_free(ctx);
164 
165 	printf("success\n");
166 
167 	return 0;
168 }
169