2 * Copyright (c) 2009-2012 Niels Provos and Nick Mathewson
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 #include <sys/types.h>
34 #include <sys/socket.h>
35 #include <netinet/in.h>
38 #include "event2/util.h"
39 #include "event2/event.h"
40 #include "event2/bufferevent_ssl.h"
41 #include "event2/buffer.h"
42 #include "event2/listener.h"
46 #include "tinytest_macros.h"
48 #include <openssl/ssl.h>
49 #include <openssl/bio.h>
50 #include <openssl/err.h>
51 #include <openssl/pem.h>
55 /* A short pre-generated key, to save the cost of doing an RSA key generation
56 * step during the unit tests. It's only 512 bits long, and it is published
57 * in this file, so you would have to be very foolish to consider using it in
59 static const char KEY
[] =
60 "-----BEGIN RSA PRIVATE KEY-----\n"
61 "MIIBOgIBAAJBAKibTEzXjj+sqpipePX1lEk5BNFuL/dDBbw8QCXgaJWikOiKHeJq\n"
62 "3FQ0OmCnmpkdsPFE4x3ojYmmdgE2i0dJwq0CAwEAAQJAZ08gpUS+qE1IClps/2gG\n"
63 "AAer6Bc31K2AaiIQvCSQcH440cp062QtWMC3V5sEoWmdLsbAHFH26/9ZHn5zAflp\n"
64 "gQIhANWOx/UYeR8HD0WREU5kcuSzgzNLwUErHLzxP7U6aojpAiEAyh2H35CjN/P7\n"
65 "NhcZ4QYw3PeUWpqgJnaE/4i80BSYkSUCIQDLHFhLYLJZ80HwHTADif/ISn9/Ow6b\n"
66 "p6BWh3DbMar/eQIgBPS6azH5vpp983KXkNv9AL4VZi9ac/b+BeINdzC6GP0CIDmB\n"
67 "U6GFEQTZ3IfuiVabG5pummdC4DNbcdI+WKrSFNmQ\n"
68 "-----END RSA PRIVATE KEY-----\n";
76 /* new read-only BIO backed by KEY. */
77 bio
= BIO_new_mem_buf((char*)KEY
, -1);
80 key
= PEM_read_bio_PrivateKey(bio
,NULL
,NULL
,NULL
);
92 /* Dummy code to make a quick-and-dirty valid certificate with
93 OpenSSL. Don't copy this code into your own program! It does a
94 number of things in a stupid and insecure way. */
96 X509_NAME
*name
= NULL
;
97 EVP_PKEY
*key
= getkey();
99 time_t now
= time(NULL
);
105 tt_assert(0 != X509_set_version(x509
, 2));
106 tt_assert(0 != ASN1_INTEGER_set(X509_get_serialNumber(x509
),
109 name
= X509_NAME_new();
111 tt_assert(NID_undef
!= (nid
= OBJ_txt2nid("commonName")));
112 tt_assert(0 != X509_NAME_add_entry_by_NID(
113 name
, nid
, MBSTRING_ASC
, (unsigned char*)"example.com",
116 X509_set_subject_name(x509
, name
);
117 X509_set_issuer_name(x509
, name
);
119 X509_time_adj(X509_get_notBefore(x509
), 0, &now
);
121 X509_time_adj(X509_get_notAfter(x509
), 0, &now
);
122 X509_set_pubkey(x509
, key
);
123 tt_assert(0 != X509_sign(x509
, key
, EVP_sha1()));
131 static SSL_CTX
*the_ssl_ctx
= NULL
;
138 return (the_ssl_ctx
= SSL_CTX_new(SSLv23_method()));
145 ERR_load_crypto_strings();
146 SSL_load_error_strings();
147 OpenSSL_add_all_algorithms();
150 /* ====================
151 Here's a simple test: we read a number from the input, increment it, and
152 reply, until we get to 1001.
155 static int test_is_done
= 0;
156 static int n_connected
= 0;
157 static int got_close
= 0;
158 static int got_error
= 0;
159 static int renegotiate_at
= -1;
160 static int stop_when_connected
= 0;
161 static int pending_connect_events
= 0;
162 static struct event_base
*exit_base
= NULL
;
165 respond_to_number(struct bufferevent
*bev
, void *ctx
)
167 struct evbuffer
*b
= bufferevent_get_input(bev
);
170 line
= evbuffer_readln(b
, NULL
, EVBUFFER_EOL_LF
);
175 TT_FAIL(("Bad number: %s", line
));
176 TT_BLATHER(("The number was %d", n
));
179 bufferevent_free(bev
); /* Should trigger close on other side. */
182 if (!strcmp(ctx
, "client") && n
== renegotiate_at
) {
183 SSL_renegotiate(bufferevent_openssl_get_ssl(bev
));
186 evbuffer_add_printf(bufferevent_get_output(bev
),
188 TT_BLATHER(("Done reading; now writing."));
189 bufferevent_enable(bev
, EV_WRITE
);
190 bufferevent_disable(bev
, EV_READ
);
194 done_writing_cb(struct bufferevent
*bev
, void *ctx
)
196 struct evbuffer
*b
= bufferevent_get_output(bev
);
197 if (evbuffer_get_length(b
))
199 TT_BLATHER(("Done writing."));
200 bufferevent_disable(bev
, EV_WRITE
);
201 bufferevent_enable(bev
, EV_READ
);
205 eventcb(struct bufferevent
*bev
, short what
, void *ctx
)
207 TT_BLATHER(("Got event %d", (int)what
));
208 if (what
& BEV_EVENT_CONNECTED
) {
212 ssl
= bufferevent_openssl_get_ssl(bev
);
214 peer_cert
= SSL_get_peer_certificate(ssl
);
215 if (0==strcmp(ctx
, "server")) {
216 tt_assert(peer_cert
== NULL
);
218 tt_assert(peer_cert
!= NULL
);
220 if (stop_when_connected
) {
221 if (--pending_connect_events
== 0)
222 event_base_loopexit(exit_base
, NULL
);
224 } else if (what
& BEV_EVENT_EOF
) {
225 TT_BLATHER(("Got a good EOF"));
227 bufferevent_free(bev
);
228 } else if (what
& BEV_EVENT_ERROR
) {
229 TT_BLATHER(("Got an error."));
231 bufferevent_free(bev
);
238 open_ssl_bufevs(struct bufferevent
**bev1_out
, struct bufferevent
**bev2_out
,
239 struct event_base
*base
, int is_open
, int flags
, SSL
*ssl1
, SSL
*ssl2
,
240 int *fd_pair
, struct bufferevent
**underlying_pair
)
242 int state1
= is_open
? BUFFEREVENT_SSL_OPEN
:BUFFEREVENT_SSL_CONNECTING
;
243 int state2
= is_open
? BUFFEREVENT_SSL_OPEN
:BUFFEREVENT_SSL_ACCEPTING
;
245 *bev1_out
= bufferevent_openssl_socket_new(
246 base
, fd_pair
[0], ssl1
, state1
, flags
);
247 *bev2_out
= bufferevent_openssl_socket_new(
248 base
, fd_pair
[1], ssl2
, state2
, flags
);
250 *bev1_out
= bufferevent_openssl_filter_new(
251 base
, underlying_pair
[0], ssl1
, state1
, flags
);
252 *bev2_out
= bufferevent_openssl_filter_new(
253 base
, underlying_pair
[1], ssl2
, state2
, flags
);
256 bufferevent_setcb(*bev1_out
, respond_to_number
, done_writing_cb
,
257 eventcb
, (void*)"client");
258 bufferevent_setcb(*bev2_out
, respond_to_number
, done_writing_cb
,
259 eventcb
, (void*)"server");
263 regress_bufferevent_openssl(void *arg
)
265 struct basic_test_data
*data
= arg
;
267 struct bufferevent
*bev1
, *bev2
;
269 X509
*cert
= getcert();
270 EVP_PKEY
*key
= getkey();
271 const int start_open
= strstr((char*)data
->setup_data
, "open")!=NULL
;
272 const int filter
= strstr((char*)data
->setup_data
, "filter")!=NULL
;
273 int flags
= BEV_OPT_DEFER_CALLBACKS
;
274 struct bufferevent
*bev_ll
[2] = { NULL
, NULL
};
282 ssl1
= SSL_new(get_ssl_ctx());
283 ssl2
= SSL_new(get_ssl_ctx());
285 SSL_use_certificate(ssl2
, cert
);
286 SSL_use_PrivateKey(ssl2
, key
);
289 flags
|= BEV_OPT_CLOSE_ON_FREE
;
291 if (strstr((char*)data
->setup_data
, "renegotiate"))
292 renegotiate_at
= 600;
295 tt_assert(strstr((char*)data
->setup_data
, "socketpair"));
296 fd_pair
= data
->pair
;
298 bev_ll
[0] = bufferevent_socket_new(data
->base
, data
->pair
[0],
299 BEV_OPT_CLOSE_ON_FREE
);
300 bev_ll
[1] = bufferevent_socket_new(data
->base
, data
->pair
[1],
301 BEV_OPT_CLOSE_ON_FREE
);
304 open_ssl_bufevs(&bev1
, &bev2
, data
->base
, 0, flags
, ssl1
, ssl2
,
308 tt_int_op(bufferevent_getfd(bev1
), ==, data
->pair
[0]);
310 tt_ptr_op(bufferevent_get_underlying(bev1
), ==, bev_ll
[0]);
314 pending_connect_events
= 2;
315 stop_when_connected
= 1;
316 exit_base
= data
->base
;
317 event_base_dispatch(data
->base
);
318 /* Okay, now the renegotiation is done. Make new
319 * bufferevents to test opening in BUFFEREVENT_SSL_OPEN */
320 flags
|= BEV_OPT_CLOSE_ON_FREE
;
321 bufferevent_free(bev1
);
322 bufferevent_free(bev2
);
324 open_ssl_bufevs(&bev1
, &bev2
, data
->base
, 1, flags
, ssl1
, ssl2
,
328 bufferevent_enable(bev1
, EV_READ
|EV_WRITE
);
329 bufferevent_enable(bev2
, EV_READ
|EV_WRITE
);
331 evbuffer_add_printf(bufferevent_get_output(bev1
), "1\n");
333 event_base_dispatch(data
->base
);
335 tt_assert(test_is_done
== 1);
336 tt_assert(n_connected
== 2);
338 /* We don't handle shutdown properly yet.
339 tt_int_op(got_close, ==, 1);
340 tt_int_op(got_error, ==, 0);
347 acceptcb(struct evconnlistener
*listener
, evutil_socket_t fd
,
348 struct sockaddr
*addr
, int socklen
, void *arg
)
350 struct basic_test_data
*data
= arg
;
351 struct bufferevent
*bev
;
352 SSL
*ssl
= SSL_new(get_ssl_ctx());
354 SSL_use_certificate(ssl
, getcert());
355 SSL_use_PrivateKey(ssl
, getkey());
357 bev
= bufferevent_openssl_socket_new(
361 BUFFEREVENT_SSL_ACCEPTING
,
362 BEV_OPT_CLOSE_ON_FREE
|BEV_OPT_DEFER_CALLBACKS
);
364 bufferevent_setcb(bev
, respond_to_number
, NULL
, eventcb
,
367 bufferevent_enable(bev
, EV_READ
|EV_WRITE
);
369 /* Only accept once, then disable ourself. */
370 evconnlistener_disable(listener
);
374 regress_bufferevent_openssl_connect(void *arg
)
376 struct basic_test_data
*data
= arg
;
378 struct event_base
*base
= data
->base
;
380 struct evconnlistener
*listener
;
381 struct bufferevent
*bev
;
382 struct sockaddr_in sin
;
383 struct sockaddr_storage ss
;
388 memset(&sin
, 0, sizeof(sin
));
389 sin
.sin_family
= AF_INET
;
390 sin
.sin_addr
.s_addr
= htonl(0x7f000001);
392 memset(&ss
, 0, sizeof(ss
));
395 listener
= evconnlistener_new_bind(base
, acceptcb
, data
,
396 LEV_OPT_CLOSE_ON_FREE
|LEV_OPT_REUSEABLE
,
397 -1, (struct sockaddr
*)&sin
, sizeof(sin
));
400 tt_assert(evconnlistener_get_fd(listener
) >= 0);
402 bev
= bufferevent_openssl_socket_new(
403 data
->base
, -1, SSL_new(get_ssl_ctx()),
404 BUFFEREVENT_SSL_CONNECTING
,
405 BEV_OPT_CLOSE_ON_FREE
|BEV_OPT_DEFER_CALLBACKS
);
408 bufferevent_setcb(bev
, respond_to_number
, NULL
, eventcb
,
411 tt_assert(getsockname(evconnlistener_get_fd(listener
),
412 (struct sockaddr
*)&ss
, &slen
) == 0);
413 tt_assert(slen
== sizeof(struct sockaddr_in
));
414 tt_int_op(((struct sockaddr
*)&ss
)->sa_family
, ==, AF_INET
);
415 tt_int_op(((struct sockaddr
*)&ss
)->sa_family
, ==, AF_INET
);
418 bufferevent_socket_connect(bev
, (struct sockaddr
*)&ss
, slen
));
419 evbuffer_add_printf(bufferevent_get_output(bev
), "1\n");
420 bufferevent_enable(bev
, EV_READ
|EV_WRITE
);
422 event_base_dispatch(base
);
427 struct testcase_t ssl_testcases
[] = {
429 { "bufferevent_socketpair", regress_bufferevent_openssl
, TT_ISOLATED
,
430 &basic_setup
, (void*)"socketpair" },
431 { "bufferevent_filter", regress_bufferevent_openssl
,
433 &basic_setup
, (void*)"filter" },
434 { "bufferevent_renegotiate_socketpair", regress_bufferevent_openssl
,
436 &basic_setup
, (void*)"socketpair renegotiate" },
437 { "bufferevent_renegotiate_filter", regress_bufferevent_openssl
,
439 &basic_setup
, (void*)"filter renegotiate" },
440 { "bufferevent_socketpair_startopen", regress_bufferevent_openssl
,
441 TT_ISOLATED
, &basic_setup
, (void*)"socketpair open" },
442 { "bufferevent_filter_startopen", regress_bufferevent_openssl
,
443 TT_ISOLATED
, &basic_setup
, (void*)"filter open" },
445 { "bufferevent_connect", regress_bufferevent_openssl_connect
,
446 TT_FORK
|TT_NEED_BASE
, &basic_setup
, NULL
},