1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/chromium/src/third_party/libevent/test/regress_ssl.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,472 @@ 1.4 +/* 1.5 + * Copyright (c) 2009-2012 Niels Provos and Nick Mathewson 1.6 + * 1.7 + * Redistribution and use in source and binary forms, with or without 1.8 + * modification, are permitted provided that the following conditions 1.9 + * are met: 1.10 + * 1. Redistributions of source code must retain the above copyright 1.11 + * notice, this list of conditions and the following disclaimer. 1.12 + * 2. Redistributions in binary form must reproduce the above copyright 1.13 + * notice, this list of conditions and the following disclaimer in the 1.14 + * documentation and/or other materials provided with the distribution. 1.15 + * 3. The name of the author may not be used to endorse or promote products 1.16 + * derived from this software without specific prior written permission. 1.17 + * 1.18 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1.19 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1.20 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1.21 + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 1.22 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 1.23 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.24 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.25 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.26 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 1.27 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.28 + */ 1.29 + 1.30 +#ifdef WIN32 1.31 +#include <winsock2.h> 1.32 +#include <windows.h> 1.33 +#endif 1.34 + 1.35 +#ifndef WIN32 1.36 +#include <sys/types.h> 1.37 +#include <sys/socket.h> 1.38 +#include <netinet/in.h> 1.39 +#endif 1.40 + 1.41 +#include "event2/util.h" 1.42 +#include "event2/event.h" 1.43 +#include "event2/bufferevent_ssl.h" 1.44 +#include "event2/buffer.h" 1.45 +#include "event2/listener.h" 1.46 + 1.47 +#include "regress.h" 1.48 +#include "tinytest.h" 1.49 +#include "tinytest_macros.h" 1.50 + 1.51 +#include <openssl/ssl.h> 1.52 +#include <openssl/bio.h> 1.53 +#include <openssl/err.h> 1.54 +#include <openssl/pem.h> 1.55 + 1.56 +#include <string.h> 1.57 + 1.58 +/* A short pre-generated key, to save the cost of doing an RSA key generation 1.59 + * step during the unit tests. It's only 512 bits long, and it is published 1.60 + * in this file, so you would have to be very foolish to consider using it in 1.61 + * your own code. */ 1.62 +static const char KEY[] = 1.63 + "-----BEGIN RSA PRIVATE KEY-----\n" 1.64 + "MIIBOgIBAAJBAKibTEzXjj+sqpipePX1lEk5BNFuL/dDBbw8QCXgaJWikOiKHeJq\n" 1.65 + "3FQ0OmCnmpkdsPFE4x3ojYmmdgE2i0dJwq0CAwEAAQJAZ08gpUS+qE1IClps/2gG\n" 1.66 + "AAer6Bc31K2AaiIQvCSQcH440cp062QtWMC3V5sEoWmdLsbAHFH26/9ZHn5zAflp\n" 1.67 + "gQIhANWOx/UYeR8HD0WREU5kcuSzgzNLwUErHLzxP7U6aojpAiEAyh2H35CjN/P7\n" 1.68 + "NhcZ4QYw3PeUWpqgJnaE/4i80BSYkSUCIQDLHFhLYLJZ80HwHTADif/ISn9/Ow6b\n" 1.69 + "p6BWh3DbMar/eQIgBPS6azH5vpp983KXkNv9AL4VZi9ac/b+BeINdzC6GP0CIDmB\n" 1.70 + "U6GFEQTZ3IfuiVabG5pummdC4DNbcdI+WKrSFNmQ\n" 1.71 + "-----END RSA PRIVATE KEY-----\n"; 1.72 + 1.73 +static EVP_PKEY * 1.74 +getkey(void) 1.75 +{ 1.76 + EVP_PKEY *key; 1.77 + BIO *bio; 1.78 + 1.79 + /* new read-only BIO backed by KEY. */ 1.80 + bio = BIO_new_mem_buf((char*)KEY, -1); 1.81 + tt_assert(bio); 1.82 + 1.83 + key = PEM_read_bio_PrivateKey(bio,NULL,NULL,NULL); 1.84 + BIO_free(bio); 1.85 + tt_assert(key); 1.86 + 1.87 + return key; 1.88 +end: 1.89 + return NULL; 1.90 +} 1.91 + 1.92 +static X509 * 1.93 +getcert(void) 1.94 +{ 1.95 + /* Dummy code to make a quick-and-dirty valid certificate with 1.96 + OpenSSL. Don't copy this code into your own program! It does a 1.97 + number of things in a stupid and insecure way. */ 1.98 + X509 *x509 = NULL; 1.99 + X509_NAME *name = NULL; 1.100 + EVP_PKEY *key = getkey(); 1.101 + int nid; 1.102 + time_t now = time(NULL); 1.103 + 1.104 + tt_assert(key); 1.105 + 1.106 + x509 = X509_new(); 1.107 + tt_assert(x509); 1.108 + tt_assert(0 != X509_set_version(x509, 2)); 1.109 + tt_assert(0 != ASN1_INTEGER_set(X509_get_serialNumber(x509), 1.110 + (long)now)); 1.111 + 1.112 + name = X509_NAME_new(); 1.113 + tt_assert(name); 1.114 + nid = OBJ_txt2nid("commonName"); 1.115 + tt_assert(NID_undef != nid); 1.116 + tt_assert(0 != X509_NAME_add_entry_by_NID( 1.117 + name, nid, MBSTRING_ASC, (unsigned char*)"example.com", 1.118 + -1, -1, 0)); 1.119 + 1.120 + X509_set_subject_name(x509, name); 1.121 + X509_set_issuer_name(x509, name); 1.122 + 1.123 + X509_time_adj(X509_get_notBefore(x509), 0, &now); 1.124 + now += 3600; 1.125 + X509_time_adj(X509_get_notAfter(x509), 0, &now); 1.126 + X509_set_pubkey(x509, key); 1.127 + tt_assert(0 != X509_sign(x509, key, EVP_sha1())); 1.128 + 1.129 + return x509; 1.130 +end: 1.131 + X509_free(x509); 1.132 + return NULL; 1.133 +} 1.134 + 1.135 +static int disable_tls_11_and_12 = 0; 1.136 +static SSL_CTX *the_ssl_ctx = NULL; 1.137 + 1.138 +static SSL_CTX * 1.139 +get_ssl_ctx(void) 1.140 +{ 1.141 + if (the_ssl_ctx) 1.142 + return the_ssl_ctx; 1.143 + the_ssl_ctx = SSL_CTX_new(SSLv23_method()); 1.144 + if (!the_ssl_ctx) 1.145 + return NULL; 1.146 + if (disable_tls_11_and_12) { 1.147 +#ifdef SSL_OP_NO_TLSv1_2 1.148 + SSL_CTX_set_options(the_ssl_ctx, SSL_OP_NO_TLSv1_2); 1.149 +#endif 1.150 +#ifdef SSL_OP_NO_TLSv1_1 1.151 + SSL_CTX_set_options(the_ssl_ctx, SSL_OP_NO_TLSv1_1); 1.152 +#endif 1.153 + } 1.154 + return the_ssl_ctx; 1.155 +} 1.156 + 1.157 +static void 1.158 +init_ssl(void) 1.159 +{ 1.160 + SSL_library_init(); 1.161 + ERR_load_crypto_strings(); 1.162 + SSL_load_error_strings(); 1.163 + OpenSSL_add_all_algorithms(); 1.164 + if (SSLeay() != OPENSSL_VERSION_NUMBER) { 1.165 + TT_DECLARE("WARN", ("Version mismatch for openssl: compiled with %lx but running with %lx", (unsigned long)OPENSSL_VERSION_NUMBER, (unsigned long)SSLeay())); 1.166 + } 1.167 +} 1.168 + 1.169 +/* ==================== 1.170 + Here's a simple test: we read a number from the input, increment it, and 1.171 + reply, until we get to 1001. 1.172 +*/ 1.173 + 1.174 +static int test_is_done = 0; 1.175 +static int n_connected = 0; 1.176 +static int got_close = 0; 1.177 +static int got_error = 0; 1.178 +static int renegotiate_at = -1; 1.179 +static int stop_when_connected = 0; 1.180 +static int pending_connect_events = 0; 1.181 +static struct event_base *exit_base = NULL; 1.182 + 1.183 +static void 1.184 +respond_to_number(struct bufferevent *bev, void *ctx) 1.185 +{ 1.186 + struct evbuffer *b = bufferevent_get_input(bev); 1.187 + char *line; 1.188 + int n; 1.189 + line = evbuffer_readln(b, NULL, EVBUFFER_EOL_LF); 1.190 + if (! line) 1.191 + return; 1.192 + n = atoi(line); 1.193 + if (n <= 0) 1.194 + TT_FAIL(("Bad number: %s", line)); 1.195 + TT_BLATHER(("The number was %d", n)); 1.196 + if (n == 1001) { 1.197 + ++test_is_done; 1.198 + bufferevent_free(bev); /* Should trigger close on other side. */ 1.199 + return; 1.200 + } 1.201 + if (!strcmp(ctx, "client") && n == renegotiate_at) { 1.202 + SSL_renegotiate(bufferevent_openssl_get_ssl(bev)); 1.203 + } 1.204 + ++n; 1.205 + evbuffer_add_printf(bufferevent_get_output(bev), 1.206 + "%d\n", n); 1.207 + TT_BLATHER(("Done reading; now writing.")); 1.208 + bufferevent_enable(bev, EV_WRITE); 1.209 + bufferevent_disable(bev, EV_READ); 1.210 +} 1.211 + 1.212 +static void 1.213 +done_writing_cb(struct bufferevent *bev, void *ctx) 1.214 +{ 1.215 + struct evbuffer *b = bufferevent_get_output(bev); 1.216 + if (evbuffer_get_length(b)) 1.217 + return; 1.218 + TT_BLATHER(("Done writing.")); 1.219 + bufferevent_disable(bev, EV_WRITE); 1.220 + bufferevent_enable(bev, EV_READ); 1.221 +} 1.222 + 1.223 +static void 1.224 +eventcb(struct bufferevent *bev, short what, void *ctx) 1.225 +{ 1.226 + TT_BLATHER(("Got event %d", (int)what)); 1.227 + if (what & BEV_EVENT_CONNECTED) { 1.228 + SSL *ssl; 1.229 + X509 *peer_cert; 1.230 + ++n_connected; 1.231 + ssl = bufferevent_openssl_get_ssl(bev); 1.232 + tt_assert(ssl); 1.233 + peer_cert = SSL_get_peer_certificate(ssl); 1.234 + if (0==strcmp(ctx, "server")) { 1.235 + tt_assert(peer_cert == NULL); 1.236 + } else { 1.237 + tt_assert(peer_cert != NULL); 1.238 + } 1.239 + if (stop_when_connected) { 1.240 + if (--pending_connect_events == 0) 1.241 + event_base_loopexit(exit_base, NULL); 1.242 + } 1.243 + } else if (what & BEV_EVENT_EOF) { 1.244 + TT_BLATHER(("Got a good EOF")); 1.245 + ++got_close; 1.246 + bufferevent_free(bev); 1.247 + } else if (what & BEV_EVENT_ERROR) { 1.248 + TT_BLATHER(("Got an error.")); 1.249 + ++got_error; 1.250 + bufferevent_free(bev); 1.251 + } 1.252 +end: 1.253 + ; 1.254 +} 1.255 + 1.256 +static void 1.257 +open_ssl_bufevs(struct bufferevent **bev1_out, struct bufferevent **bev2_out, 1.258 + struct event_base *base, int is_open, int flags, SSL *ssl1, SSL *ssl2, 1.259 + evutil_socket_t *fd_pair, struct bufferevent **underlying_pair) 1.260 +{ 1.261 + int state1 = is_open ? BUFFEREVENT_SSL_OPEN :BUFFEREVENT_SSL_CONNECTING; 1.262 + int state2 = is_open ? BUFFEREVENT_SSL_OPEN :BUFFEREVENT_SSL_ACCEPTING; 1.263 + if (fd_pair) { 1.264 + *bev1_out = bufferevent_openssl_socket_new( 1.265 + base, fd_pair[0], ssl1, state1, flags); 1.266 + *bev2_out = bufferevent_openssl_socket_new( 1.267 + base, fd_pair[1], ssl2, state2, flags); 1.268 + } else { 1.269 + *bev1_out = bufferevent_openssl_filter_new( 1.270 + base, underlying_pair[0], ssl1, state1, flags); 1.271 + *bev2_out = bufferevent_openssl_filter_new( 1.272 + base, underlying_pair[1], ssl2, state2, flags); 1.273 + 1.274 + } 1.275 + bufferevent_setcb(*bev1_out, respond_to_number, done_writing_cb, 1.276 + eventcb, (void*)"client"); 1.277 + bufferevent_setcb(*bev2_out, respond_to_number, done_writing_cb, 1.278 + eventcb, (void*)"server"); 1.279 +} 1.280 + 1.281 +static void 1.282 +regress_bufferevent_openssl(void *arg) 1.283 +{ 1.284 + struct basic_test_data *data = arg; 1.285 + 1.286 + struct bufferevent *bev1, *bev2; 1.287 + SSL *ssl1, *ssl2; 1.288 + X509 *cert = getcert(); 1.289 + EVP_PKEY *key = getkey(); 1.290 + const int start_open = strstr((char*)data->setup_data, "open")!=NULL; 1.291 + const int filter = strstr((char*)data->setup_data, "filter")!=NULL; 1.292 + int flags = BEV_OPT_DEFER_CALLBACKS; 1.293 + struct bufferevent *bev_ll[2] = { NULL, NULL }; 1.294 + evutil_socket_t *fd_pair = NULL; 1.295 + 1.296 + tt_assert(cert); 1.297 + tt_assert(key); 1.298 + 1.299 + init_ssl(); 1.300 + 1.301 + if (strstr((char*)data->setup_data, "renegotiate")) { 1.302 + if (SSLeay() >= 0x10001000 && 1.303 + SSLeay() < 0x1000104f) { 1.304 + /* 1.0.1 up to 1.0.1c has a bug where TLS1.1 and 1.2 1.305 + * can't renegotiate with themselves. Disable. */ 1.306 + disable_tls_11_and_12 = 1; 1.307 + } 1.308 + renegotiate_at = 600; 1.309 + } 1.310 + 1.311 + ssl1 = SSL_new(get_ssl_ctx()); 1.312 + ssl2 = SSL_new(get_ssl_ctx()); 1.313 + 1.314 + SSL_use_certificate(ssl2, cert); 1.315 + SSL_use_PrivateKey(ssl2, key); 1.316 + 1.317 + if (! start_open) 1.318 + flags |= BEV_OPT_CLOSE_ON_FREE; 1.319 + 1.320 + if (!filter) { 1.321 + tt_assert(strstr((char*)data->setup_data, "socketpair")); 1.322 + fd_pair = data->pair; 1.323 + } else { 1.324 + bev_ll[0] = bufferevent_socket_new(data->base, data->pair[0], 1.325 + BEV_OPT_CLOSE_ON_FREE); 1.326 + bev_ll[1] = bufferevent_socket_new(data->base, data->pair[1], 1.327 + BEV_OPT_CLOSE_ON_FREE); 1.328 + } 1.329 + 1.330 + open_ssl_bufevs(&bev1, &bev2, data->base, 0, flags, ssl1, ssl2, 1.331 + fd_pair, bev_ll); 1.332 + 1.333 + if (!filter) { 1.334 + tt_int_op(bufferevent_getfd(bev1), ==, data->pair[0]); 1.335 + } else { 1.336 + tt_ptr_op(bufferevent_get_underlying(bev1), ==, bev_ll[0]); 1.337 + } 1.338 + 1.339 + if (start_open) { 1.340 + pending_connect_events = 2; 1.341 + stop_when_connected = 1; 1.342 + exit_base = data->base; 1.343 + event_base_dispatch(data->base); 1.344 + /* Okay, now the renegotiation is done. Make new 1.345 + * bufferevents to test opening in BUFFEREVENT_SSL_OPEN */ 1.346 + flags |= BEV_OPT_CLOSE_ON_FREE; 1.347 + bufferevent_free(bev1); 1.348 + bufferevent_free(bev2); 1.349 + bev1 = bev2 = NULL; 1.350 + open_ssl_bufevs(&bev1, &bev2, data->base, 1, flags, ssl1, ssl2, 1.351 + fd_pair, bev_ll); 1.352 + } 1.353 + 1.354 + bufferevent_enable(bev1, EV_READ|EV_WRITE); 1.355 + bufferevent_enable(bev2, EV_READ|EV_WRITE); 1.356 + 1.357 + evbuffer_add_printf(bufferevent_get_output(bev1), "1\n"); 1.358 + 1.359 + event_base_dispatch(data->base); 1.360 + 1.361 + tt_assert(test_is_done == 1); 1.362 + tt_assert(n_connected == 2); 1.363 + 1.364 + /* We don't handle shutdown properly yet. 1.365 + tt_int_op(got_close, ==, 1); 1.366 + tt_int_op(got_error, ==, 0); 1.367 + */ 1.368 +end: 1.369 + return; 1.370 +} 1.371 + 1.372 +static void 1.373 +acceptcb(struct evconnlistener *listener, evutil_socket_t fd, 1.374 + struct sockaddr *addr, int socklen, void *arg) 1.375 +{ 1.376 + struct basic_test_data *data = arg; 1.377 + struct bufferevent *bev; 1.378 + SSL *ssl = SSL_new(get_ssl_ctx()); 1.379 + 1.380 + SSL_use_certificate(ssl, getcert()); 1.381 + SSL_use_PrivateKey(ssl, getkey()); 1.382 + 1.383 + bev = bufferevent_openssl_socket_new( 1.384 + data->base, 1.385 + fd, 1.386 + ssl, 1.387 + BUFFEREVENT_SSL_ACCEPTING, 1.388 + BEV_OPT_CLOSE_ON_FREE|BEV_OPT_DEFER_CALLBACKS); 1.389 + 1.390 + bufferevent_setcb(bev, respond_to_number, NULL, eventcb, 1.391 + (void*)"server"); 1.392 + 1.393 + bufferevent_enable(bev, EV_READ|EV_WRITE); 1.394 + 1.395 + /* Only accept once, then disable ourself. */ 1.396 + evconnlistener_disable(listener); 1.397 +} 1.398 + 1.399 +static void 1.400 +regress_bufferevent_openssl_connect(void *arg) 1.401 +{ 1.402 + struct basic_test_data *data = arg; 1.403 + 1.404 + struct event_base *base = data->base; 1.405 + 1.406 + struct evconnlistener *listener; 1.407 + struct bufferevent *bev; 1.408 + struct sockaddr_in sin; 1.409 + struct sockaddr_storage ss; 1.410 + ev_socklen_t slen; 1.411 + 1.412 + init_ssl(); 1.413 + 1.414 + memset(&sin, 0, sizeof(sin)); 1.415 + sin.sin_family = AF_INET; 1.416 + sin.sin_addr.s_addr = htonl(0x7f000001); 1.417 + 1.418 + memset(&ss, 0, sizeof(ss)); 1.419 + slen = sizeof(ss); 1.420 + 1.421 + listener = evconnlistener_new_bind(base, acceptcb, data, 1.422 + LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, 1.423 + -1, (struct sockaddr *)&sin, sizeof(sin)); 1.424 + 1.425 + tt_assert(listener); 1.426 + tt_assert(evconnlistener_get_fd(listener) >= 0); 1.427 + 1.428 + bev = bufferevent_openssl_socket_new( 1.429 + data->base, -1, SSL_new(get_ssl_ctx()), 1.430 + BUFFEREVENT_SSL_CONNECTING, 1.431 + BEV_OPT_CLOSE_ON_FREE|BEV_OPT_DEFER_CALLBACKS); 1.432 + tt_assert(bev); 1.433 + 1.434 + bufferevent_setcb(bev, respond_to_number, NULL, eventcb, 1.435 + (void*)"client"); 1.436 + 1.437 + tt_assert(getsockname(evconnlistener_get_fd(listener), 1.438 + (struct sockaddr*)&ss, &slen) == 0); 1.439 + tt_assert(slen == sizeof(struct sockaddr_in)); 1.440 + tt_int_op(((struct sockaddr*)&ss)->sa_family, ==, AF_INET); 1.441 + tt_int_op(((struct sockaddr*)&ss)->sa_family, ==, AF_INET); 1.442 + 1.443 + tt_assert(0 == 1.444 + bufferevent_socket_connect(bev, (struct sockaddr*)&ss, slen)); 1.445 + evbuffer_add_printf(bufferevent_get_output(bev), "1\n"); 1.446 + bufferevent_enable(bev, EV_READ|EV_WRITE); 1.447 + 1.448 + event_base_dispatch(base); 1.449 +end: 1.450 + ; 1.451 +} 1.452 + 1.453 +struct testcase_t ssl_testcases[] = { 1.454 + 1.455 + { "bufferevent_socketpair", regress_bufferevent_openssl, TT_ISOLATED, 1.456 + &basic_setup, (void*)"socketpair" }, 1.457 + { "bufferevent_filter", regress_bufferevent_openssl, 1.458 + TT_ISOLATED, 1.459 + &basic_setup, (void*)"filter" }, 1.460 + { "bufferevent_renegotiate_socketpair", regress_bufferevent_openssl, 1.461 + TT_ISOLATED, 1.462 + &basic_setup, (void*)"socketpair renegotiate" }, 1.463 + { "bufferevent_renegotiate_filter", regress_bufferevent_openssl, 1.464 + TT_ISOLATED, 1.465 + &basic_setup, (void*)"filter renegotiate" }, 1.466 + { "bufferevent_socketpair_startopen", regress_bufferevent_openssl, 1.467 + TT_ISOLATED, &basic_setup, (void*)"socketpair open" }, 1.468 + { "bufferevent_filter_startopen", regress_bufferevent_openssl, 1.469 + TT_ISOLATED, &basic_setup, (void*)"filter open" }, 1.470 + 1.471 + { "bufferevent_connect", regress_bufferevent_openssl_connect, 1.472 + TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, 1.473 + 1.474 + END_OF_TESTCASES, 1.475 +};