1 /* $NetBSD: regress_ssl.c,v 1.2 2013/04/11 16:56:42 christos Exp $ */
3 * Copyright (c) 2009-2012 Niels Provos and Nick Mathewson
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
34 #include <sys/types.h>
35 #include <sys/socket.h>
36 #include <netinet/in.h>
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"
47 #include "tinytest_macros.h"
49 #include <openssl/ssl.h>
50 #include <openssl/bio.h>
51 #include <openssl/err.h>
52 #include <openssl/pem.h>
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
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
);
78 /* new read-only BIO backed by KEY. */
79 bio
= BIO_new_mem_buf(xkey
, -1);
82 key
= PEM_read_bio_PrivateKey(bio
,NULL
,NULL
,NULL
);
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. */
98 X509_NAME
*name
= NULL
;
99 EVP_PKEY
*key
= getkey();
101 time_t now
= time(NULL
);
107 tt_assert(0 != X509_set_version(x509
, 2));
108 tt_assert(0 != ASN1_INTEGER_set(X509_get_serialNumber(x509
),
111 name
= X509_NAME_new();
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"),
119 X509_set_subject_name(x509
, name
);
120 X509_set_issuer_name(x509
, name
);
122 X509_time_adj(X509_get_notBefore(x509
), 0, &now
);
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()));
134 static int disable_tls_11_and_12
= 0;
135 static SSL_CTX
*the_ssl_ctx
= NULL
;
142 the_ssl_ctx
= SSL_CTX_new(SSLv23_method());
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
);
149 #ifdef SSL_OP_NO_TLSv1_1
150 SSL_CTX_set_options(the_ssl_ctx
, SSL_OP_NO_TLSv1_1
);
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()));
168 /* ====================
169 Here's a simple test: we read a number from the input, increment it, and
170 reply, until we get to 1001.
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
;
183 respond_to_number(struct bufferevent
*bev
, void *ctx
)
185 struct evbuffer
*b
= bufferevent_get_input(bev
);
188 line
= evbuffer_readln(b
, NULL
, EVBUFFER_EOL_LF
);
193 TT_FAIL(("Bad number: %s", line
));
194 TT_BLATHER(("The number was %d", n
));
197 bufferevent_free(bev
); /* Should trigger close on other side. */
200 if (!strcmp(ctx
, "client") && n
== renegotiate_at
) {
201 SSL_renegotiate(bufferevent_openssl_get_ssl(bev
));
204 evbuffer_add_printf(bufferevent_get_output(bev
),
206 TT_BLATHER(("Done reading; now writing."));
207 bufferevent_enable(bev
, EV_WRITE
);
208 bufferevent_disable(bev
, EV_READ
);
212 done_writing_cb(struct bufferevent
*bev
, void *ctx
)
214 struct evbuffer
*b
= bufferevent_get_output(bev
);
215 if (evbuffer_get_length(b
))
217 TT_BLATHER(("Done writing."));
218 bufferevent_disable(bev
, EV_WRITE
);
219 bufferevent_enable(bev
, EV_READ
);
223 eventcb(struct bufferevent
*bev
, short what
, void *ctx
)
225 TT_BLATHER(("Got event %d", (int)what
));
226 if (what
& BEV_EVENT_CONNECTED
) {
230 ssl
= bufferevent_openssl_get_ssl(bev
);
232 peer_cert
= SSL_get_peer_certificate(ssl
);
233 if (0==strcmp(ctx
, "server")) {
234 tt_assert(peer_cert
== NULL
);
236 tt_assert(peer_cert
!= NULL
);
238 if (stop_when_connected
) {
239 if (--pending_connect_events
== 0)
240 event_base_loopexit(exit_base
, NULL
);
242 } else if (what
& BEV_EVENT_EOF
) {
243 TT_BLATHER(("Got a good EOF"));
245 bufferevent_free(bev
);
246 } else if (what
& BEV_EVENT_ERROR
) {
247 TT_BLATHER(("Got an error."));
249 bufferevent_free(bev
);
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
)
260 int state1
= is_open
? BUFFEREVENT_SSL_OPEN
:BUFFEREVENT_SSL_CONNECTING
;
261 int state2
= is_open
? BUFFEREVENT_SSL_OPEN
:BUFFEREVENT_SSL_ACCEPTING
;
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
);
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
);
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"));
281 regress_bufferevent_openssl(void *arg
)
283 struct basic_test_data
*data
= arg
;
285 struct bufferevent
*bev1
, *bev2
;
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
;
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;
307 renegotiate_at
= 600;
310 ssl1
= SSL_new(get_ssl_ctx());
311 ssl2
= SSL_new(get_ssl_ctx());
313 SSL_use_certificate(ssl2
, cert
);
314 SSL_use_PrivateKey(ssl2
, key
);
317 flags
|= BEV_OPT_CLOSE_ON_FREE
;
320 tt_assert(strstr((char*)data
->setup_data
, "socketpair"));
321 fd_pair
= data
->pair
;
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
);
329 open_ssl_bufevs(&bev1
, &bev2
, data
->base
, 0, flags
, ssl1
, ssl2
,
333 tt_int_op(bufferevent_getfd(bev1
), ==, data
->pair
[0]);
335 tt_ptr_op(bufferevent_get_underlying(bev1
), ==, bev_ll
[0]);
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
);
349 open_ssl_bufevs(&bev1
, &bev2
, data
->base
, 1, flags
, ssl1
, ssl2
,
353 bufferevent_enable(bev1
, EV_READ
|EV_WRITE
);
354 bufferevent_enable(bev2
, EV_READ
|EV_WRITE
);
356 evbuffer_add_printf(bufferevent_get_output(bev1
), "1\n");
358 event_base_dispatch(data
->base
);
360 tt_assert(test_is_done
== 1);
361 tt_assert(n_connected
== 2);
363 /* We don't handle shutdown properly yet.
364 tt_int_op(got_close, ==, 1);
365 tt_int_op(got_error, ==, 0);
372 acceptcb(struct evconnlistener
*listener
, evutil_socket_t fd
,
373 struct sockaddr
*addr
, int socklen
, void *arg
)
375 struct basic_test_data
*data
= arg
;
376 struct bufferevent
*bev
;
377 SSL
*ssl
= SSL_new(get_ssl_ctx());
379 SSL_use_certificate(ssl
, getcert());
380 SSL_use_PrivateKey(ssl
, getkey());
382 bev
= bufferevent_openssl_socket_new(
386 BUFFEREVENT_SSL_ACCEPTING
,
387 BEV_OPT_CLOSE_ON_FREE
|BEV_OPT_DEFER_CALLBACKS
);
389 bufferevent_setcb(bev
, respond_to_number
, NULL
, eventcb
,
390 __UNCONST("server"));
392 bufferevent_enable(bev
, EV_READ
|EV_WRITE
);
394 /* Only accept once, then disable ourself. */
395 evconnlistener_disable(listener
);
399 regress_bufferevent_openssl_connect(void *arg
)
401 struct basic_test_data
*data
= arg
;
403 struct event_base
*base
= data
->base
;
405 struct evconnlistener
*listener
;
406 struct bufferevent
*bev
;
407 struct sockaddr_in sin
;
408 struct sockaddr_storage ss
;
413 memset(&sin
, 0, sizeof(sin
));
414 sin
.sin_family
= AF_INET
;
415 sin
.sin_addr
.s_addr
= htonl(0x7f000001);
417 memset(&ss
, 0, sizeof(ss
));
420 listener
= evconnlistener_new_bind(base
, acceptcb
, data
,
421 LEV_OPT_CLOSE_ON_FREE
|LEV_OPT_REUSEABLE
,
422 -1, (struct sockaddr
*)&sin
, sizeof(sin
));
425 tt_assert(evconnlistener_get_fd(listener
) >= 0);
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
);
433 bufferevent_setcb(bev
, respond_to_number
, NULL
, eventcb
,
434 __UNCONST("client"));
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
);
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
);
447 event_base_dispatch(base
);
452 struct testcase_t ssl_testcases
[] = {
454 { "bufferevent_socketpair", regress_bufferevent_openssl
, TT_ISOLATED
,
455 &basic_setup
, __UNCONST("socketpair") },
456 { "bufferevent_filter", regress_bufferevent_openssl
,
458 &basic_setup
, __UNCONST("filter") },
459 { "bufferevent_renegotiate_socketpair", regress_bufferevent_openssl
,
461 &basic_setup
, __UNCONST("socketpair renegotiate") },
462 { "bufferevent_renegotiate_filter", regress_bufferevent_openssl
,
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") },
470 { "bufferevent_connect", regress_bufferevent_openssl_connect
,
471 TT_FORK
|TT_NEED_BASE
, &basic_setup
, NULL
},