1 /* $NetBSD: regress_ssl.c,v 1.2 2013/04/11 16:56:42 christos Exp $ */ 2 /* 3 * Copyright (c) 2009-2012 Niels Provos and Nick Mathewson 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #ifdef WIN32 29 #include <winsock2.h> 30 #include <windows.h> 31 #endif 32 33 #ifndef WIN32 34 #include <sys/types.h> 35 #include <sys/socket.h> 36 #include <netinet/in.h> 37 #endif 38 39 #include "event2/util.h" 40 #include "event2/event.h" 41 #include "event2/bufferevent_ssl.h" 42 #include "event2/buffer.h" 43 #include "event2/listener.h" 44 45 #include "regress.h" 46 #include "tinytest.h" 47 #include "tinytest_macros.h" 48 49 #include <openssl/ssl.h> 50 #include <openssl/bio.h> 51 #include <openssl/err.h> 52 #include <openssl/pem.h> 53 54 #include <string.h> 55 56 /* A short pre-generated key, to save the cost of doing an RSA key generation 57 * step during the unit tests. It's only 512 bits long, and it is published 58 * in this file, so you would have to be very foolish to consider using it in 59 * your own code. */ 60 static const char KEY[] = 61 "-----BEGIN RSA PRIVATE KEY-----\n" 62 "MIIBOgIBAAJBAKibTEzXjj+sqpipePX1lEk5BNFuL/dDBbw8QCXgaJWikOiKHeJq\n" 63 "3FQ0OmCnmpkdsPFE4x3ojYmmdgE2i0dJwq0CAwEAAQJAZ08gpUS+qE1IClps/2gG\n" 64 "AAer6Bc31K2AaiIQvCSQcH440cp062QtWMC3V5sEoWmdLsbAHFH26/9ZHn5zAflp\n" 65 "gQIhANWOx/UYeR8HD0WREU5kcuSzgzNLwUErHLzxP7U6aojpAiEAyh2H35CjN/P7\n" 66 "NhcZ4QYw3PeUWpqgJnaE/4i80BSYkSUCIQDLHFhLYLJZ80HwHTADif/ISn9/Ow6b\n" 67 "p6BWh3DbMar/eQIgBPS6azH5vpp983KXkNv9AL4VZi9ac/b+BeINdzC6GP0CIDmB\n" 68 "U6GFEQTZ3IfuiVabG5pummdC4DNbcdI+WKrSFNmQ\n" 69 "-----END RSA PRIVATE KEY-----\n"; 70 static void *xkey = __UNCONST(KEY); 71 72 static EVP_PKEY * 73 getkey(void) 74 { 75 EVP_PKEY *key; 76 BIO *bio; 77 78 /* new read-only BIO backed by KEY. */ 79 bio = BIO_new_mem_buf(xkey, -1); 80 tt_assert(bio); 81 82 key = PEM_read_bio_PrivateKey(bio,NULL,NULL,NULL); 83 BIO_free(bio); 84 tt_assert(key); 85 86 return key; 87 end: 88 return NULL; 89 } 90 91 static X509 * 92 getcert(void) 93 { 94 /* Dummy code to make a quick-and-dirty valid certificate with 95 OpenSSL. Don't copy this code into your own program! It does a 96 number of things in a stupid and insecure way. */ 97 X509 *x509 = NULL; 98 X509_NAME *name = NULL; 99 EVP_PKEY *key = getkey(); 100 int nid; 101 time_t now = time(NULL); 102 103 tt_assert(key); 104 105 x509 = X509_new(); 106 tt_assert(x509); 107 tt_assert(0 != X509_set_version(x509, 2)); 108 tt_assert(0 != ASN1_INTEGER_set(X509_get_serialNumber(x509), 109 (long)now)); 110 111 name = X509_NAME_new(); 112 tt_assert(name); 113 nid = OBJ_txt2nid("commonName"); 114 tt_assert(NID_undef != nid); 115 tt_assert(0 != X509_NAME_add_entry_by_NID( 116 name, nid, MBSTRING_ASC, __UNCONST("example.com"), 117 -1, -1, 0)); 118 119 X509_set_subject_name(x509, name); 120 X509_set_issuer_name(x509, name); 121 122 X509_time_adj(X509_get_notBefore(x509), 0, &now); 123 now += 3600; 124 X509_time_adj(X509_get_notAfter(x509), 0, &now); 125 X509_set_pubkey(x509, key); 126 tt_assert(0 != X509_sign(x509, key, EVP_sha1())); 127 128 return x509; 129 end: 130 X509_free(x509); 131 return NULL; 132 } 133 134 static int disable_tls_11_and_12 = 0; 135 static SSL_CTX *the_ssl_ctx = NULL; 136 137 static SSL_CTX * 138 get_ssl_ctx(void) 139 { 140 if (the_ssl_ctx) 141 return the_ssl_ctx; 142 the_ssl_ctx = SSL_CTX_new(SSLv23_method()); 143 if (!the_ssl_ctx) 144 return NULL; 145 if (disable_tls_11_and_12) { 146 #ifdef SSL_OP_NO_TLSv1_2 147 SSL_CTX_set_options(the_ssl_ctx, SSL_OP_NO_TLSv1_2); 148 #endif 149 #ifdef SSL_OP_NO_TLSv1_1 150 SSL_CTX_set_options(the_ssl_ctx, SSL_OP_NO_TLSv1_1); 151 #endif 152 } 153 return the_ssl_ctx; 154 } 155 156 static void 157 init_ssl(void) 158 { 159 SSL_library_init(); 160 ERR_load_crypto_strings(); 161 SSL_load_error_strings(); 162 OpenSSL_add_all_algorithms(); 163 if (SSLeay() != OPENSSL_VERSION_NUMBER) { 164 TT_DECLARE("WARN", ("Version mismatch for openssl: compiled with %lx but running with %lx", (unsigned long)OPENSSL_VERSION_NUMBER, (unsigned long)SSLeay())); 165 } 166 } 167 168 /* ==================== 169 Here's a simple test: we read a number from the input, increment it, and 170 reply, until we get to 1001. 171 */ 172 173 static int test_is_done = 0; 174 static int n_connected = 0; 175 static int got_close = 0; 176 static int got_error = 0; 177 static int renegotiate_at = -1; 178 static int stop_when_connected = 0; 179 static int pending_connect_events = 0; 180 static struct event_base *exit_base = NULL; 181 182 static void 183 respond_to_number(struct bufferevent *bev, void *ctx) 184 { 185 struct evbuffer *b = bufferevent_get_input(bev); 186 char *line; 187 int n; 188 line = evbuffer_readln(b, NULL, EVBUFFER_EOL_LF); 189 if (! line) 190 return; 191 n = atoi(line); 192 if (n <= 0) 193 TT_FAIL(("Bad number: %s", line)); 194 TT_BLATHER(("The number was %d", n)); 195 if (n == 1001) { 196 ++test_is_done; 197 bufferevent_free(bev); /* Should trigger close on other side. */ 198 return; 199 } 200 if (!strcmp(ctx, "client") && n == renegotiate_at) { 201 SSL_renegotiate(bufferevent_openssl_get_ssl(bev)); 202 } 203 ++n; 204 evbuffer_add_printf(bufferevent_get_output(bev), 205 "%d\n", n); 206 TT_BLATHER(("Done reading; now writing.")); 207 bufferevent_enable(bev, EV_WRITE); 208 bufferevent_disable(bev, EV_READ); 209 } 210 211 static void 212 done_writing_cb(struct bufferevent *bev, void *ctx) 213 { 214 struct evbuffer *b = bufferevent_get_output(bev); 215 if (evbuffer_get_length(b)) 216 return; 217 TT_BLATHER(("Done writing.")); 218 bufferevent_disable(bev, EV_WRITE); 219 bufferevent_enable(bev, EV_READ); 220 } 221 222 static void 223 eventcb(struct bufferevent *bev, short what, void *ctx) 224 { 225 TT_BLATHER(("Got event %d", (int)what)); 226 if (what & BEV_EVENT_CONNECTED) { 227 SSL *ssl; 228 X509 *peer_cert; 229 ++n_connected; 230 ssl = bufferevent_openssl_get_ssl(bev); 231 tt_assert(ssl); 232 peer_cert = SSL_get_peer_certificate(ssl); 233 if (0==strcmp(ctx, "server")) { 234 tt_assert(peer_cert == NULL); 235 } else { 236 tt_assert(peer_cert != NULL); 237 } 238 if (stop_when_connected) { 239 if (--pending_connect_events == 0) 240 event_base_loopexit(exit_base, NULL); 241 } 242 } else if (what & BEV_EVENT_EOF) { 243 TT_BLATHER(("Got a good EOF")); 244 ++got_close; 245 bufferevent_free(bev); 246 } else if (what & BEV_EVENT_ERROR) { 247 TT_BLATHER(("Got an error.")); 248 ++got_error; 249 bufferevent_free(bev); 250 } 251 end: 252 ; 253 } 254 255 static void 256 open_ssl_bufevs(struct bufferevent **bev1_out, struct bufferevent **bev2_out, 257 struct event_base *base, int is_open, int flags, SSL *ssl1, SSL *ssl2, 258 evutil_socket_t *fd_pair, struct bufferevent **underlying_pair) 259 { 260 int state1 = is_open ? BUFFEREVENT_SSL_OPEN :BUFFEREVENT_SSL_CONNECTING; 261 int state2 = is_open ? BUFFEREVENT_SSL_OPEN :BUFFEREVENT_SSL_ACCEPTING; 262 if (fd_pair) { 263 *bev1_out = bufferevent_openssl_socket_new( 264 base, fd_pair[0], ssl1, state1, flags); 265 *bev2_out = bufferevent_openssl_socket_new( 266 base, fd_pair[1], ssl2, state2, flags); 267 } else { 268 *bev1_out = bufferevent_openssl_filter_new( 269 base, underlying_pair[0], ssl1, state1, flags); 270 *bev2_out = bufferevent_openssl_filter_new( 271 base, underlying_pair[1], ssl2, state2, flags); 272 273 } 274 bufferevent_setcb(*bev1_out, respond_to_number, done_writing_cb, 275 eventcb, __UNCONST("client")); 276 bufferevent_setcb(*bev2_out, respond_to_number, done_writing_cb, 277 eventcb, __UNCONST("server")); 278 } 279 280 static void 281 regress_bufferevent_openssl(void *arg) 282 { 283 struct basic_test_data *data = arg; 284 285 struct bufferevent *bev1, *bev2; 286 SSL *ssl1, *ssl2; 287 X509 *cert = getcert(); 288 EVP_PKEY *key = getkey(); 289 const int start_open = strstr((char*)data->setup_data, "open")!=NULL; 290 const int filter = strstr((char*)data->setup_data, "filter")!=NULL; 291 int flags = BEV_OPT_DEFER_CALLBACKS; 292 struct bufferevent *bev_ll[2] = { NULL, NULL }; 293 evutil_socket_t *fd_pair = NULL; 294 295 tt_assert(cert); 296 tt_assert(key); 297 298 init_ssl(); 299 300 if (strstr((char*)data->setup_data, "renegotiate")) { 301 if (SSLeay() >= 0x10001000 && 302 SSLeay() < 0x1000104f) { 303 /* 1.0.1 up to 1.0.1c has a bug where TLS1.1 and 1.2 304 * can't renegotiate with themselves. Disable. */ 305 disable_tls_11_and_12 = 1; 306 } 307 renegotiate_at = 600; 308 } 309 310 ssl1 = SSL_new(get_ssl_ctx()); 311 ssl2 = SSL_new(get_ssl_ctx()); 312 313 SSL_use_certificate(ssl2, cert); 314 SSL_use_PrivateKey(ssl2, key); 315 316 if (! start_open) 317 flags |= BEV_OPT_CLOSE_ON_FREE; 318 319 if (!filter) { 320 tt_assert(strstr((char*)data->setup_data, "socketpair")); 321 fd_pair = data->pair; 322 } else { 323 bev_ll[0] = bufferevent_socket_new(data->base, data->pair[0], 324 BEV_OPT_CLOSE_ON_FREE); 325 bev_ll[1] = bufferevent_socket_new(data->base, data->pair[1], 326 BEV_OPT_CLOSE_ON_FREE); 327 } 328 329 open_ssl_bufevs(&bev1, &bev2, data->base, 0, flags, ssl1, ssl2, 330 fd_pair, bev_ll); 331 332 if (!filter) { 333 tt_int_op(bufferevent_getfd(bev1), ==, data->pair[0]); 334 } else { 335 tt_ptr_op(bufferevent_get_underlying(bev1), ==, bev_ll[0]); 336 } 337 338 if (start_open) { 339 pending_connect_events = 2; 340 stop_when_connected = 1; 341 exit_base = data->base; 342 event_base_dispatch(data->base); 343 /* Okay, now the renegotiation is done. Make new 344 * bufferevents to test opening in BUFFEREVENT_SSL_OPEN */ 345 flags |= BEV_OPT_CLOSE_ON_FREE; 346 bufferevent_free(bev1); 347 bufferevent_free(bev2); 348 bev1 = bev2 = NULL; 349 open_ssl_bufevs(&bev1, &bev2, data->base, 1, flags, ssl1, ssl2, 350 fd_pair, bev_ll); 351 } 352 353 bufferevent_enable(bev1, EV_READ|EV_WRITE); 354 bufferevent_enable(bev2, EV_READ|EV_WRITE); 355 356 evbuffer_add_printf(bufferevent_get_output(bev1), "1\n"); 357 358 event_base_dispatch(data->base); 359 360 tt_assert(test_is_done == 1); 361 tt_assert(n_connected == 2); 362 363 /* We don't handle shutdown properly yet. 364 tt_int_op(got_close, ==, 1); 365 tt_int_op(got_error, ==, 0); 366 */ 367 end: 368 return; 369 } 370 371 static void 372 acceptcb(struct evconnlistener *listener, evutil_socket_t fd, 373 struct sockaddr *addr, int socklen, void *arg) 374 { 375 struct basic_test_data *data = arg; 376 struct bufferevent *bev; 377 SSL *ssl = SSL_new(get_ssl_ctx()); 378 379 SSL_use_certificate(ssl, getcert()); 380 SSL_use_PrivateKey(ssl, getkey()); 381 382 bev = bufferevent_openssl_socket_new( 383 data->base, 384 fd, 385 ssl, 386 BUFFEREVENT_SSL_ACCEPTING, 387 BEV_OPT_CLOSE_ON_FREE|BEV_OPT_DEFER_CALLBACKS); 388 389 bufferevent_setcb(bev, respond_to_number, NULL, eventcb, 390 __UNCONST("server")); 391 392 bufferevent_enable(bev, EV_READ|EV_WRITE); 393 394 /* Only accept once, then disable ourself. */ 395 evconnlistener_disable(listener); 396 } 397 398 static void 399 regress_bufferevent_openssl_connect(void *arg) 400 { 401 struct basic_test_data *data = arg; 402 403 struct event_base *base = data->base; 404 405 struct evconnlistener *listener; 406 struct bufferevent *bev; 407 struct sockaddr_in sin; 408 struct sockaddr_storage ss; 409 ev_socklen_t slen; 410 411 init_ssl(); 412 413 memset(&sin, 0, sizeof(sin)); 414 sin.sin_family = AF_INET; 415 sin.sin_addr.s_addr = htonl(0x7f000001); 416 417 memset(&ss, 0, sizeof(ss)); 418 slen = sizeof(ss); 419 420 listener = evconnlistener_new_bind(base, acceptcb, data, 421 LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, 422 -1, (struct sockaddr *)&sin, sizeof(sin)); 423 424 tt_assert(listener); 425 tt_assert(evconnlistener_get_fd(listener) >= 0); 426 427 bev = bufferevent_openssl_socket_new( 428 data->base, -1, SSL_new(get_ssl_ctx()), 429 BUFFEREVENT_SSL_CONNECTING, 430 BEV_OPT_CLOSE_ON_FREE|BEV_OPT_DEFER_CALLBACKS); 431 tt_assert(bev); 432 433 bufferevent_setcb(bev, respond_to_number, NULL, eventcb, 434 __UNCONST("client")); 435 436 tt_assert(getsockname(evconnlistener_get_fd(listener), 437 (struct sockaddr*)&ss, &slen) == 0); 438 tt_assert(slen == sizeof(struct sockaddr_in)); 439 tt_int_op(((struct sockaddr*)&ss)->sa_family, ==, AF_INET); 440 tt_int_op(((struct sockaddr*)&ss)->sa_family, ==, AF_INET); 441 442 tt_assert(0 == 443 bufferevent_socket_connect(bev, (struct sockaddr*)&ss, slen)); 444 evbuffer_add_printf(bufferevent_get_output(bev), "1\n"); 445 bufferevent_enable(bev, EV_READ|EV_WRITE); 446 447 event_base_dispatch(base); 448 end: 449 ; 450 } 451 452 struct testcase_t ssl_testcases[] = { 453 454 { "bufferevent_socketpair", regress_bufferevent_openssl, TT_ISOLATED, 455 &basic_setup, __UNCONST("socketpair") }, 456 { "bufferevent_filter", regress_bufferevent_openssl, 457 TT_ISOLATED, 458 &basic_setup, __UNCONST("filter") }, 459 { "bufferevent_renegotiate_socketpair", regress_bufferevent_openssl, 460 TT_ISOLATED, 461 &basic_setup, __UNCONST("socketpair renegotiate") }, 462 { "bufferevent_renegotiate_filter", regress_bufferevent_openssl, 463 TT_ISOLATED, 464 &basic_setup, __UNCONST("filter renegotiate") }, 465 { "bufferevent_socketpair_startopen", regress_bufferevent_openssl, 466 TT_ISOLATED, &basic_setup, __UNCONST("socketpair open") }, 467 { "bufferevent_filter_startopen", regress_bufferevent_openssl, 468 TT_ISOLATED, &basic_setup, __UNCONST("filter open") }, 469 470 { "bufferevent_connect", regress_bufferevent_openssl_connect, 471 TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, 472 473 END_OF_TESTCASES, 474 }; 475