1 /* $OpenBSD: server.c,v 1.4 2018/11/09 06:30:41 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, 38 "usage: server [-vv] [-C CA] [-c crt -k key] [host port]"); 39 exit(2); 40 } 41 42 int 43 main(int argc, char *argv[]) 44 { 45 const SSL_METHOD *method; 46 SSL_CTX *ctx; 47 SSL *ssl; 48 BIO *bio; 49 SSL_SESSION *session; 50 int error, verify = 0; 51 char buf[256], ch; 52 char *ca = NULL, *crt = NULL, *key = NULL; 53 char *host_port, *host = "127.0.0.1", *port = "0"; 54 55 while ((ch = getopt(argc, argv, "C:c:k:v")) != -1) { 56 switch (ch) { 57 case 'C': 58 ca = optarg; 59 break; 60 case 'c': 61 crt = optarg; 62 break; 63 case 'k': 64 key = optarg; 65 break; 66 case 'v': 67 /* use twice to force client cert */ 68 verify++; 69 break; 70 default: 71 usage(); 72 } 73 } 74 argc -= optind; 75 argv += optind; 76 if (argc == 2) { 77 host = argv[0]; 78 port = argv[1]; 79 } else if (argc != 0) { 80 usage(); 81 } 82 if (asprintf(&host_port, strchr(host, ':') ? "[%s]:%s" : "%s:%s", 83 host, port) == -1) 84 err(1, "asprintf host port"); 85 if ((crt == NULL && key != NULL) || (crt != NULL && key == NULL)) 86 errx(1, "certificate and private key must be used together"); 87 if (crt == NULL && asprintf(&crt, "%s.crt", host) == -1) 88 err(1, "asprintf crt"); 89 if (key == NULL && asprintf(&key, "%s.key", host) == -1) 90 err(1, "asprintf key"); 91 92 SSL_library_init(); 93 SSL_load_error_strings(); 94 print_version(); 95 96 /* setup method and context */ 97 #if OPENSSL_VERSION_NUMBER >= 0x1010000f 98 method = TLS_server_method(); 99 if (method == NULL) 100 err_ssl(1, "TLS_server_method"); 101 #else 102 method = SSLv23_server_method(); 103 if (method == NULL) 104 err_ssl(1, "SSLv23_server_method"); 105 #endif 106 ctx = SSL_CTX_new(method); 107 if (ctx == NULL) 108 err_ssl(1, "SSL_CTX_new"); 109 110 /* needed when linking with OpenSSL 1.0.2p */ 111 if (SSL_CTX_set_ecdh_auto(ctx, 1) <= 0) 112 err_ssl(1, "SSL_CTX_set_ecdh_auto"); 113 114 /* load server certificate */ 115 if (SSL_CTX_use_certificate_file(ctx, crt, SSL_FILETYPE_PEM) <= 0) 116 err_ssl(1, "SSL_CTX_use_certificate_file"); 117 if (SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM) <= 0) 118 err_ssl(1, "SSL_CTX_use_PrivateKey_file"); 119 if (SSL_CTX_check_private_key(ctx) <= 0) 120 err_ssl(1, "SSL_CTX_check_private_key"); 121 122 /* request client certificate and verify it */ 123 if (ca != NULL) { 124 STACK_OF(X509_NAME) *x509stack; 125 126 x509stack = SSL_load_client_CA_file(ca); 127 if (x509stack == NULL) 128 err_ssl(1, "SSL_load_client_CA_file"); 129 SSL_CTX_set_client_CA_list(ctx, x509stack); 130 if (SSL_CTX_load_verify_locations(ctx, ca, NULL) <= 0) 131 err_ssl(1, "SSL_CTX_load_verify_locations"); 132 } 133 SSL_CTX_set_verify(ctx, 134 verify == 0 ? SSL_VERIFY_NONE : 135 verify == 1 ? SSL_VERIFY_PEER : 136 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 137 verify_callback); 138 139 /* setup ssl and bio for socket operations */ 140 ssl = SSL_new(ctx); 141 if (ssl == NULL) 142 err_ssl(1, "SSL_new"); 143 bio = BIO_new_accept(host_port); 144 if (bio == NULL) 145 err_ssl(1, "BIO_new_accept"); 146 print_ciphers(SSL_get_ciphers(ssl)); 147 148 /* bind, listen */ 149 if (BIO_do_accept(bio) <= 0) 150 err_ssl(1, "BIO_do_accept setup"); 151 printf("listen "); 152 print_sockname(bio); 153 154 /* fork to background, set timeout, and accept */ 155 if (daemon(1, 1) == -1) 156 err(1, "daemon"); 157 if ((int)alarm(60) == -1) 158 err(1, "alarm"); 159 if (BIO_do_accept(bio) <= 0) 160 err_ssl(1, "BIO_do_accept wait"); 161 bio = BIO_pop(bio); 162 printf("accept "); 163 print_sockname(bio); 164 printf("accept "); 165 print_peername(bio); 166 167 /* do ssl server handshake */ 168 SSL_set_bio(ssl, bio, bio); 169 if ((error = SSL_accept(ssl)) <= 0) 170 err_ssl(1, "SSL_accept %d", error); 171 172 /* print session statistics */ 173 session = SSL_get_session(ssl); 174 if (session == NULL) 175 err_ssl(1, "SSL_get_session"); 176 if (SSL_SESSION_print_fp(stdout, session) <= 0) 177 err_ssl(1, "SSL_SESSION_print_fp"); 178 179 /* write server greeting and read client hello over TLS connection */ 180 strlcpy(buf, "greeting\n", sizeof(buf)); 181 printf(">>> %s", buf); 182 if (fflush(stdout) != 0) 183 err(1, "fflush stdout"); 184 if ((error = SSL_write(ssl, buf, 9)) <= 0) 185 err_ssl(1, "SSL_write %d", error); 186 if (error != 9) 187 errx(1, "write not 9 bytes greeting: %d", error); 188 if ((error = SSL_read(ssl, buf, 6)) <= 0) 189 err_ssl(1, "SSL_read %d", error); 190 if (error != 6) 191 errx(1, "read not 6 bytes hello: %d", error); 192 buf[6] = '\0'; 193 printf("<<< %s", buf); 194 if (fflush(stdout) != 0) 195 err(1, "fflush stdout"); 196 197 /* shutdown connection */ 198 if ((error = SSL_shutdown(ssl)) < 0) 199 err_ssl(1, "SSL_shutdown unidirectional %d", error); 200 if (error <= 0) { 201 if ((error = SSL_shutdown(ssl)) <= 0) 202 err_ssl(1, "SSL_shutdown bidirectional %d", error); 203 } 204 205 /* cleanup and free resources */ 206 SSL_free(ssl); 207 SSL_CTX_free(ctx); 208 209 printf("success\n"); 210 211 return 0; 212 } 213