2 * Copyright (c) 2009-2010 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/socket.h>
34 #include <netinet/in.h>
37 #include "event2/util.h"
38 #include "event2/event.h"
39 #include "event2/bufferevent_ssl.h"
40 #include "event2/buffer.h"
41 #include "event2/listener.h"
45 #include "tinytest_macros.h"
47 #include <openssl/ssl.h>
48 #include <openssl/bio.h>
49 #include <openssl/err.h>
50 #include <openssl/pem.h>
54 /* A short pre-generated key, to save the cost of doing an RSA key generation
55 * step during the unit tests. It's only 512 bits long, and it is published
56 * in this file, so you would have to be very foolish to consider using it in
58 static const char KEY
[] =
59 "-----BEGIN RSA PRIVATE KEY-----\n"
60 "MIIBOgIBAAJBAKibTEzXjj+sqpipePX1lEk5BNFuL/dDBbw8QCXgaJWikOiKHeJq\n"
61 "3FQ0OmCnmpkdsPFE4x3ojYmmdgE2i0dJwq0CAwEAAQJAZ08gpUS+qE1IClps/2gG\n"
62 "AAer6Bc31K2AaiIQvCSQcH440cp062QtWMC3V5sEoWmdLsbAHFH26/9ZHn5zAflp\n"
63 "gQIhANWOx/UYeR8HD0WREU5kcuSzgzNLwUErHLzxP7U6aojpAiEAyh2H35CjN/P7\n"
64 "NhcZ4QYw3PeUWpqgJnaE/4i80BSYkSUCIQDLHFhLYLJZ80HwHTADif/ISn9/Ow6b\n"
65 "p6BWh3DbMar/eQIgBPS6azH5vpp983KXkNv9AL4VZi9ac/b+BeINdzC6GP0CIDmB\n"
66 "U6GFEQTZ3IfuiVabG5pummdC4DNbcdI+WKrSFNmQ\n"
67 "-----END RSA PRIVATE KEY-----\n";
75 /* new read-only BIO backed by KEY. */
76 bio
= BIO_new_mem_buf((char*)KEY
, -1);
79 key
= PEM_read_bio_PrivateKey(bio
,NULL
,NULL
,NULL
);
91 /* Dummy code to make a quick-and-dirty valid certificate with
92 OpenSSL. Don't copy this code into your own program! It does a
93 number of things in a stupid and insecure way. */
95 X509_NAME
*name
= NULL
;
96 EVP_PKEY
*key
= getkey();
98 time_t now
= time(NULL
);
104 tt_assert(0 != X509_set_version(x509
, 2));
105 tt_assert(0 != ASN1_INTEGER_set(X509_get_serialNumber(x509
),
108 name
= X509_NAME_new();
110 tt_assert(NID_undef
!= (nid
= OBJ_txt2nid("commonName")));
111 tt_assert(0 != X509_NAME_add_entry_by_NID(
112 name
, nid
, MBSTRING_ASC
, (unsigned char*)"example.com",
115 X509_set_subject_name(x509
, name
);
116 X509_set_issuer_name(x509
, name
);
118 X509_time_adj(X509_get_notBefore(x509
), 0, &now
);
120 X509_time_adj(X509_get_notAfter(x509
), 0, &now
);
121 X509_set_pubkey(x509
, key
);
122 tt_assert(0 != X509_sign(x509
, key
, EVP_sha1()));
130 static SSL_CTX
*the_ssl_ctx
= NULL
;
137 return (the_ssl_ctx
= SSL_CTX_new(SSLv23_method()));
144 ERR_load_crypto_strings();
145 SSL_load_error_strings();
146 OpenSSL_add_all_algorithms();
149 /* ====================
150 Here's a simple test: we read a number from the input, increment it, and
151 reply, until we get to 1001.
154 static int test_is_done
= 0;
155 static int n_connected
= 0;
156 static int got_close
= 0;
157 static int got_error
= 0;
158 static int renegotiate_at
= -1;
159 static int stop_when_connected
= 0;
160 static int pending_connect_events
= 0;
161 static struct event_base
*exit_base
= NULL
;
164 respond_to_number(struct bufferevent
*bev
, void *ctx
)
166 struct evbuffer
*b
= bufferevent_get_input(bev
);
169 line
= evbuffer_readln(b
, NULL
, EVBUFFER_EOL_LF
);
174 TT_FAIL(("Bad number: %s", line
));
175 TT_BLATHER(("The number was %d", n
));
178 bufferevent_free(bev
); /* Should trigger close on other side. */
181 if (!strcmp(ctx
, "client") && n
== renegotiate_at
) {
182 SSL_renegotiate(bufferevent_openssl_get_ssl(bev
));
185 evbuffer_add_printf(bufferevent_get_output(bev
),
187 TT_BLATHER(("Done reading; now writing."));
188 bufferevent_enable(bev
, EV_WRITE
);
189 bufferevent_disable(bev
, EV_READ
);
193 done_writing_cb(struct bufferevent
*bev
, void *ctx
)
195 struct evbuffer
*b
= bufferevent_get_output(bev
);
196 if (evbuffer_get_length(b
))
198 TT_BLATHER(("Done writing."));
199 bufferevent_disable(bev
, EV_WRITE
);
200 bufferevent_enable(bev
, EV_READ
);
204 eventcb(struct bufferevent
*bev
, short what
, void *ctx
)
206 TT_BLATHER(("Got event %d", (int)what
));
207 if (what
& BEV_EVENT_CONNECTED
) {
211 ssl
= bufferevent_openssl_get_ssl(bev
);
213 peer_cert
= SSL_get_peer_certificate(ssl
);
214 if (0==strcmp(ctx
, "server")) {
215 tt_assert(peer_cert
== NULL
);
217 tt_assert(peer_cert
!= NULL
);
219 if (stop_when_connected
) {
220 if (--pending_connect_events
== 0)
221 event_base_loopexit(exit_base
, NULL
);
223 } else if (what
& BEV_EVENT_EOF
) {
224 TT_BLATHER(("Got a good EOF"));
226 bufferevent_free(bev
);
227 } else if (what
& BEV_EVENT_ERROR
) {
228 TT_BLATHER(("Got an error."));
230 bufferevent_free(bev
);
237 open_ssl_bufevs(struct bufferevent
**bev1_out
, struct bufferevent
**bev2_out
,
238 struct event_base
*base
, int is_open
, int flags
, SSL
*ssl1
, SSL
*ssl2
,
239 int *fd_pair
, struct bufferevent
**underlying_pair
)
241 int state1
= is_open
? BUFFEREVENT_SSL_OPEN
:BUFFEREVENT_SSL_CONNECTING
;
242 int state2
= is_open
? BUFFEREVENT_SSL_OPEN
:BUFFEREVENT_SSL_ACCEPTING
;
244 *bev1_out
= bufferevent_openssl_socket_new(
245 base
, fd_pair
[0], ssl1
, state1
, flags
);
246 *bev2_out
= bufferevent_openssl_socket_new(
247 base
, fd_pair
[1], ssl2
, state2
, flags
);
249 *bev1_out
= bufferevent_openssl_filter_new(
250 base
, underlying_pair
[0], ssl1
, state1
, flags
);
251 *bev2_out
= bufferevent_openssl_filter_new(
252 base
, underlying_pair
[1], ssl2
, state2
, flags
);
255 bufferevent_setcb(*bev1_out
, respond_to_number
, done_writing_cb
,
256 eventcb
, (void*)"client");
257 bufferevent_setcb(*bev2_out
, respond_to_number
, done_writing_cb
,
258 eventcb
, (void*)"server");
262 regress_bufferevent_openssl(void *arg
)
264 struct basic_test_data
*data
= arg
;
266 struct bufferevent
*bev1
, *bev2
;
268 X509
*cert
= getcert();
269 EVP_PKEY
*key
= getkey();
270 const int start_open
= strstr((char*)data
->setup_data
, "open")!=NULL
;
271 const int filter
= strstr((char*)data
->setup_data
, "filter")!=NULL
;
272 int flags
= BEV_OPT_DEFER_CALLBACKS
;
273 struct bufferevent
*bev_ll
[2] = { NULL
, NULL
};
281 ssl1
= SSL_new(get_ssl_ctx());
282 ssl2
= SSL_new(get_ssl_ctx());
284 SSL_use_certificate(ssl2
, cert
);
285 SSL_use_PrivateKey(ssl2
, key
);
288 flags
|= BEV_OPT_CLOSE_ON_FREE
;
290 if (strstr((char*)data
->setup_data
, "renegotiate"))
291 renegotiate_at
= 600;
294 tt_assert(strstr((char*)data
->setup_data
, "socketpair"));
295 fd_pair
= data
->pair
;
297 bev_ll
[0] = bufferevent_socket_new(data
->base
, data
->pair
[0],
298 BEV_OPT_CLOSE_ON_FREE
);
299 bev_ll
[1] = bufferevent_socket_new(data
->base
, data
->pair
[1],
300 BEV_OPT_CLOSE_ON_FREE
);
303 open_ssl_bufevs(&bev1
, &bev2
, data
->base
, 0, flags
, ssl1
, ssl2
,
307 tt_int_op(bufferevent_getfd(bev1
), ==, data
->pair
[0]);
309 tt_ptr_op(bufferevent_get_underlying(bev1
), ==, bev_ll
[0]);
313 pending_connect_events
= 2;
314 stop_when_connected
= 1;
315 exit_base
= data
->base
;
316 event_base_dispatch(data
->base
);
317 /* Okay, now the renegotiation is done. Make new
318 * bufferevents to test opening in BUFFEREVENT_SSL_OPEN */
319 flags
|= BEV_OPT_CLOSE_ON_FREE
;
320 bufferevent_free(bev1
);
321 bufferevent_free(bev2
);
323 open_ssl_bufevs(&bev1
, &bev2
, data
->base
, 1, flags
, ssl1
, ssl2
,
327 bufferevent_enable(bev1
, EV_READ
|EV_WRITE
);
328 bufferevent_enable(bev2
, EV_READ
|EV_WRITE
);
330 evbuffer_add_printf(bufferevent_get_output(bev1
), "1\n");
332 event_base_dispatch(data
->base
);
334 tt_assert(test_is_done
== 1);
335 tt_assert(n_connected
== 2);
337 /* We don't handle shutdown properly yet.
338 tt_int_op(got_close, ==, 1);
339 tt_int_op(got_error, ==, 0);
346 acceptcb(struct evconnlistener
*listener
, evutil_socket_t fd
,
347 struct sockaddr
*addr
, int socklen
, void *arg
)
349 struct basic_test_data
*data
= arg
;
350 struct bufferevent
*bev
;
351 SSL
*ssl
= SSL_new(get_ssl_ctx());
353 SSL_use_certificate(ssl
, getcert());
354 SSL_use_PrivateKey(ssl
, getkey());
356 bev
= bufferevent_openssl_socket_new(
360 BUFFEREVENT_SSL_ACCEPTING
,
361 BEV_OPT_CLOSE_ON_FREE
|BEV_OPT_DEFER_CALLBACKS
);
363 bufferevent_setcb(bev
, respond_to_number
, NULL
, eventcb
,
366 bufferevent_enable(bev
, EV_READ
|EV_WRITE
);
368 /* Only accept once, then disable ourself. */
369 evconnlistener_disable(listener
);
373 regress_bufferevent_openssl_connect(void *arg
)
375 struct basic_test_data
*data
= arg
;
377 struct event_base
*base
= data
->base
;
379 struct evconnlistener
*listener
;
380 struct bufferevent
*bev
;
381 struct sockaddr_in sin
;
382 struct sockaddr_storage ss
;
387 memset(&sin
, 0, sizeof(sin
));
388 sin
.sin_family
= AF_INET
;
389 sin
.sin_addr
.s_addr
= htonl(0x7f000001);
391 memset(&ss
, 0, sizeof(ss
));
394 listener
= evconnlistener_new_bind(base
, acceptcb
, data
,
395 LEV_OPT_CLOSE_ON_FREE
|LEV_OPT_REUSEABLE
,
396 -1, (struct sockaddr
*)&sin
, sizeof(sin
));
399 tt_assert(evconnlistener_get_fd(listener
) >= 0);
401 bev
= bufferevent_openssl_socket_new(
402 data
->base
, -1, SSL_new(get_ssl_ctx()),
403 BUFFEREVENT_SSL_CONNECTING
,
404 BEV_OPT_CLOSE_ON_FREE
|BEV_OPT_DEFER_CALLBACKS
);
407 bufferevent_setcb(bev
, respond_to_number
, NULL
, eventcb
,
410 tt_assert(getsockname(evconnlistener_get_fd(listener
),
411 (struct sockaddr
*)&ss
, &slen
) == 0);
412 tt_assert(slen
== sizeof(struct sockaddr_in
));
413 tt_int_op(((struct sockaddr
*)&ss
)->sa_family
, ==, AF_INET
);
414 tt_int_op(((struct sockaddr
*)&ss
)->sa_family
, ==, AF_INET
);
417 bufferevent_socket_connect(bev
, (struct sockaddr
*)&ss
, slen
));
418 evbuffer_add_printf(bufferevent_get_output(bev
), "1\n");
419 bufferevent_enable(bev
, EV_READ
|EV_WRITE
);
421 event_base_dispatch(base
);
426 struct testcase_t ssl_testcases
[] = {
428 { "bufferevent_socketpair", regress_bufferevent_openssl
, TT_ISOLATED
,
429 &basic_setup
, (void*)"socketpair" },
430 { "bufferevent_filter", regress_bufferevent_openssl
,
432 &basic_setup
, (void*)"filter" },
433 { "bufferevent_renegotiate_socketpair", regress_bufferevent_openssl
,
435 &basic_setup
, (void*)"socketpair renegotiate" },
436 { "bufferevent_renegotiate_filter", regress_bufferevent_openssl
,
438 &basic_setup
, (void*)"filter renegotiate" },
439 { "bufferevent_socketpair_startopen", regress_bufferevent_openssl
,
440 TT_ISOLATED
, &basic_setup
, (void*)"socketpair open" },
441 { "bufferevent_filter_startopen", regress_bufferevent_openssl
,
442 TT_ISOLATED
, &basic_setup
, (void*)"filter open" },
444 { "bufferevent_connect", regress_bufferevent_openssl_connect
,
445 TT_FORK
|TT_NEED_BASE
, &basic_setup
, NULL
},