]>
Commit | Line | Data |
---|---|---|
2cb4b5f6 MC |
1 | /* |
2 | * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. | |
3 | * | |
4 | * Licensed under the OpenSSL license (the "License"). You may not use | |
5 | * this file except in compliance with the License. You can obtain a copy | |
6 | * in the file LICENSE in the source distribution or at | |
7 | * https://www.openssl.org/source/license.html | |
8 | */ | |
9 | ||
ba881d3b MC |
10 | #include <string.h> |
11 | ||
2cb4b5f6 MC |
12 | #include <openssl/opensslconf.h> |
13 | #include <openssl/bio.h> | |
14 | #include <openssl/crypto.h> | |
15 | #include <openssl/ssl.h> | |
ba881d3b | 16 | #include <openssl/ocsp.h> |
2cb4b5f6 MC |
17 | |
18 | #include "ssltestlib.h" | |
c887104f | 19 | #include "testutil.h" |
e364c3b2 | 20 | #include "test_main_custom.h" |
2cb4b5f6 MC |
21 | |
22 | static char *cert = NULL; | |
23 | static char *privkey = NULL; | |
24 | ||
ba881d3b MC |
25 | static const unsigned char orespder[] = "Dummy OCSP Response"; |
26 | static int ocsp_server_called = 0; | |
27 | static int ocsp_client_called = 0; | |
28 | ||
29 | static int cdummyarg = 1; | |
30 | static X509 *ocspcert = NULL; | |
31 | ||
84d5549e MC |
32 | #define NUM_EXTRA_CERTS 40 |
33 | ||
34 | static int execute_test_large_message(const SSL_METHOD *smeth, | |
7856332e | 35 | const SSL_METHOD *cmeth, int read_ahead) |
84d5549e MC |
36 | { |
37 | SSL_CTX *cctx = NULL, *sctx = NULL; | |
38 | SSL *clientssl = NULL, *serverssl = NULL; | |
39 | int testresult = 0; | |
40 | int i; | |
41 | BIO *certbio = BIO_new_file(cert, "r"); | |
42 | X509 *chaincert = NULL; | |
43 | int certlen; | |
44 | ||
45 | if (certbio == NULL) { | |
46 | printf("Can't load the certficate file\n"); | |
47 | goto end; | |
48 | } | |
49 | chaincert = PEM_read_bio_X509(certbio, NULL, NULL, NULL); | |
fa454945 MC |
50 | BIO_free(certbio); |
51 | certbio = NULL; | |
52 | if (chaincert == NULL) { | |
53 | printf("Unable to load certificate for chain\n"); | |
54 | goto end; | |
55 | } | |
84d5549e MC |
56 | |
57 | if (!create_ssl_ctx_pair(smeth, cmeth, &sctx, | |
58 | &cctx, cert, privkey)) { | |
59 | printf("Unable to create SSL_CTX pair\n"); | |
60 | goto end; | |
61 | } | |
84d5549e | 62 | |
7856332e MC |
63 | if(read_ahead) { |
64 | /* | |
65 | * Test that read_ahead works correctly when dealing with large | |
66 | * records | |
67 | */ | |
68 | SSL_CTX_set_read_ahead(cctx, 1); | |
69 | } | |
70 | ||
84d5549e MC |
71 | /* |
72 | * We assume the supplied certificate is big enough so that if we add | |
73 | * NUM_EXTRA_CERTS it will make the overall message large enough. The | |
74 | * default buffer size is requested to be 16k, but due to the way BUF_MEM | |
75 | * works, it ends up allocing a little over 21k (16 * 4/3). So, in this test | |
76 | * we need to have a message larger than that. | |
77 | */ | |
78 | certlen = i2d_X509(chaincert, NULL); | |
79 | OPENSSL_assert((certlen * NUM_EXTRA_CERTS) | |
80 | > ((SSL3_RT_MAX_PLAIN_LENGTH * 4) / 3)); | |
81 | for (i = 0; i < NUM_EXTRA_CERTS; i++) { | |
82 | if (!X509_up_ref(chaincert)) { | |
83 | printf("Unable to up ref cert\n"); | |
84 | goto end; | |
85 | } | |
86 | if (!SSL_CTX_add_extra_chain_cert(sctx, chaincert)) { | |
87 | printf("Unable to add extra chain cert %d\n", i); | |
88 | X509_free(chaincert); | |
89 | goto end; | |
90 | } | |
91 | } | |
92 | ||
93 | if (!create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL)) { | |
94 | printf("Unable to create SSL objects\n"); | |
95 | goto end; | |
96 | } | |
97 | ||
98 | if (!create_ssl_connection(serverssl, clientssl)) { | |
99 | printf("Unable to create SSL connection\n"); | |
100 | goto end; | |
101 | } | |
102 | ||
103 | testresult = 1; | |
104 | ||
105 | end: | |
106 | X509_free(chaincert); | |
107 | SSL_free(serverssl); | |
108 | SSL_free(clientssl); | |
109 | SSL_CTX_free(sctx); | |
110 | SSL_CTX_free(cctx); | |
111 | ||
112 | return testresult; | |
113 | } | |
114 | ||
115 | static int test_large_message_tls(void) | |
116 | { | |
7856332e MC |
117 | return execute_test_large_message(TLS_server_method(), TLS_client_method(), |
118 | 0); | |
119 | } | |
120 | ||
121 | static int test_large_message_tls_read_ahead(void) | |
122 | { | |
123 | return execute_test_large_message(TLS_server_method(), TLS_client_method(), | |
124 | 1); | |
84d5549e MC |
125 | } |
126 | ||
55386bef | 127 | #ifndef OPENSSL_NO_DTLS |
84d5549e MC |
128 | static int test_large_message_dtls(void) |
129 | { | |
7856332e MC |
130 | /* |
131 | * read_ahead is not relevant to DTLS because DTLS always acts as if | |
132 | * read_ahead is set. | |
133 | */ | |
84d5549e | 134 | return execute_test_large_message(DTLS_server_method(), |
7856332e | 135 | DTLS_client_method(), 0); |
84d5549e | 136 | } |
55386bef | 137 | #endif |
84d5549e | 138 | |
ba881d3b MC |
139 | static int ocsp_server_cb(SSL *s, void *arg) |
140 | { | |
141 | int *argi = (int *)arg; | |
142 | unsigned char *orespdercopy = NULL; | |
143 | STACK_OF(OCSP_RESPID) *ids = NULL; | |
144 | OCSP_RESPID *id = NULL; | |
145 | ||
146 | if (*argi == 2) { | |
147 | /* In this test we are expecting exactly 1 OCSP_RESPID */ | |
148 | SSL_get_tlsext_status_ids(s, &ids); | |
149 | if (ids == NULL || sk_OCSP_RESPID_num(ids) != 1) | |
150 | return SSL_TLSEXT_ERR_ALERT_FATAL; | |
151 | ||
152 | id = sk_OCSP_RESPID_value(ids, 0); | |
153 | if (id == NULL || !OCSP_RESPID_match(id, ocspcert)) | |
154 | return SSL_TLSEXT_ERR_ALERT_FATAL; | |
155 | } else if (*argi != 1) { | |
156 | return SSL_TLSEXT_ERR_ALERT_FATAL; | |
157 | } | |
158 | ||
159 | ||
160 | orespdercopy = OPENSSL_memdup(orespder, sizeof(orespder)); | |
161 | if (orespdercopy == NULL) | |
162 | return SSL_TLSEXT_ERR_ALERT_FATAL; | |
163 | ||
164 | SSL_set_tlsext_status_ocsp_resp(s, orespdercopy, sizeof(orespder)); | |
165 | ||
166 | ocsp_server_called = 1; | |
167 | ||
168 | return SSL_TLSEXT_ERR_OK; | |
169 | } | |
170 | ||
171 | static int ocsp_client_cb(SSL *s, void *arg) | |
172 | { | |
173 | int *argi = (int *)arg; | |
174 | const unsigned char *respderin; | |
175 | size_t len; | |
176 | ||
177 | if (*argi != 1 && *argi != 2) | |
178 | return 0; | |
179 | ||
180 | len = SSL_get_tlsext_status_ocsp_resp(s, &respderin); | |
181 | ||
182 | if (memcmp(orespder, respderin, len) != 0) | |
183 | return 0; | |
184 | ||
185 | ocsp_client_called = 1; | |
186 | ||
187 | return 1; | |
188 | } | |
189 | ||
2cb4b5f6 MC |
190 | static int test_tlsext_status_type(void) |
191 | { | |
ba881d3b MC |
192 | SSL_CTX *cctx = NULL, *sctx = NULL; |
193 | SSL *clientssl = NULL, *serverssl = NULL; | |
2cb4b5f6 | 194 | int testresult = 0; |
ba881d3b MC |
195 | STACK_OF(OCSP_RESPID) *ids = NULL; |
196 | OCSP_RESPID *id = NULL; | |
197 | BIO *certbio = NULL; | |
2cb4b5f6 | 198 | |
ba881d3b MC |
199 | if (!create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(), &sctx, |
200 | &cctx, cert, privkey)) { | |
201 | printf("Unable to create SSL_CTX pair\n"); | |
202 | return 0; | |
203 | } | |
2cb4b5f6 | 204 | |
ba881d3b | 205 | if (SSL_CTX_get_tlsext_status_type(cctx) != -1) { |
2cb4b5f6 MC |
206 | printf("Unexpected initial value for " |
207 | "SSL_CTX_get_tlsext_status_type()\n"); | |
208 | goto end; | |
209 | } | |
210 | ||
ba881d3b | 211 | /* First just do various checks getting and setting tlsext_status_type */ |
2cb4b5f6 | 212 | |
ba881d3b MC |
213 | clientssl = SSL_new(cctx); |
214 | if (SSL_get_tlsext_status_type(clientssl) != -1) { | |
2cb4b5f6 MC |
215 | printf("Unexpected initial value for SSL_get_tlsext_status_type()\n"); |
216 | goto end; | |
217 | } | |
218 | ||
ba881d3b | 219 | if (!SSL_set_tlsext_status_type(clientssl, TLSEXT_STATUSTYPE_ocsp)) { |
2cb4b5f6 MC |
220 | printf("Unexpected fail for SSL_set_tlsext_status_type()\n"); |
221 | goto end; | |
222 | } | |
223 | ||
ba881d3b | 224 | if (SSL_get_tlsext_status_type(clientssl) != TLSEXT_STATUSTYPE_ocsp) { |
2cb4b5f6 MC |
225 | printf("Unexpected result for SSL_get_tlsext_status_type()\n"); |
226 | goto end; | |
227 | } | |
228 | ||
ba881d3b MC |
229 | SSL_free(clientssl); |
230 | clientssl = NULL; | |
2cb4b5f6 | 231 | |
ba881d3b | 232 | if (!SSL_CTX_set_tlsext_status_type(cctx, TLSEXT_STATUSTYPE_ocsp)) { |
2cb4b5f6 MC |
233 | printf("Unexpected fail for SSL_CTX_set_tlsext_status_type()\n"); |
234 | goto end; | |
235 | } | |
236 | ||
ba881d3b | 237 | if (SSL_CTX_get_tlsext_status_type(cctx) != TLSEXT_STATUSTYPE_ocsp) { |
2cb4b5f6 MC |
238 | printf("Unexpected result for SSL_CTX_get_tlsext_status_type()\n"); |
239 | goto end; | |
240 | } | |
241 | ||
ba881d3b | 242 | clientssl = SSL_new(cctx); |
2cb4b5f6 | 243 | |
ba881d3b | 244 | if (SSL_get_tlsext_status_type(clientssl) != TLSEXT_STATUSTYPE_ocsp) { |
2cb4b5f6 MC |
245 | printf("Unexpected result for SSL_get_tlsext_status_type() (test 2)\n"); |
246 | goto end; | |
247 | } | |
248 | ||
ba881d3b MC |
249 | SSL_free(clientssl); |
250 | clientssl = NULL; | |
251 | ||
252 | /* | |
253 | * Now actually do a handshake and check OCSP information is exchanged and | |
254 | * the callbacks get called | |
255 | */ | |
256 | ||
257 | SSL_CTX_set_tlsext_status_cb(cctx, ocsp_client_cb); | |
258 | SSL_CTX_set_tlsext_status_arg(cctx, &cdummyarg); | |
259 | SSL_CTX_set_tlsext_status_cb(sctx, ocsp_server_cb); | |
260 | SSL_CTX_set_tlsext_status_arg(sctx, &cdummyarg); | |
261 | ||
262 | if (!create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL)) { | |
263 | printf("Unable to create SSL objects\n"); | |
264 | goto end; | |
265 | } | |
266 | ||
267 | if (!create_ssl_connection(serverssl, clientssl)) { | |
268 | printf("Unable to create SSL connection\n"); | |
269 | goto end; | |
270 | } | |
271 | ||
272 | if (!ocsp_client_called || !ocsp_server_called) { | |
273 | printf("OCSP callbacks not called\n"); | |
274 | goto end; | |
275 | } | |
276 | ||
277 | SSL_free(serverssl); | |
278 | SSL_free(clientssl); | |
279 | serverssl = NULL; | |
280 | clientssl = NULL; | |
281 | ||
282 | /* Try again but this time force the server side callback to fail */ | |
283 | ocsp_client_called = 0; | |
284 | ocsp_server_called = 0; | |
285 | cdummyarg = 0; | |
286 | ||
287 | if (!create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL)) { | |
288 | printf("Unable to create SSL objects\n"); | |
289 | goto end; | |
290 | } | |
291 | ||
292 | /* This should fail because the callback will fail */ | |
293 | if (create_ssl_connection(serverssl, clientssl)) { | |
294 | printf("Unexpected success creating the connection\n"); | |
295 | goto end; | |
296 | } | |
297 | ||
298 | if (ocsp_client_called || ocsp_server_called) { | |
299 | printf("OCSP callbacks successfully called unexpectedly\n"); | |
300 | goto end; | |
301 | } | |
302 | ||
303 | SSL_free(serverssl); | |
304 | SSL_free(clientssl); | |
305 | serverssl = NULL; | |
306 | clientssl = NULL; | |
307 | ||
308 | /* | |
309 | * This time we'll get the client to send an OCSP_RESPID that it will | |
310 | * accept. | |
311 | */ | |
312 | ocsp_client_called = 0; | |
313 | ocsp_server_called = 0; | |
314 | cdummyarg = 2; | |
315 | ||
316 | if (!create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL)) { | |
317 | printf("Unable to create SSL objects\n"); | |
318 | goto end; | |
319 | } | |
320 | ||
321 | /* | |
322 | * We'll just use any old cert for this test - it doesn't have to be an OCSP | |
323 | * specifc one. We'll use the server cert. | |
324 | */ | |
325 | certbio = BIO_new_file(cert, "r"); | |
326 | if (certbio == NULL) { | |
327 | printf("Can't load the certficate file\n"); | |
328 | goto end; | |
329 | } | |
330 | id = OCSP_RESPID_new(); | |
331 | ids = sk_OCSP_RESPID_new_null(); | |
332 | ocspcert = PEM_read_bio_X509(certbio, NULL, NULL, NULL); | |
333 | if (id == NULL || ids == NULL || ocspcert == NULL | |
334 | || !OCSP_RESPID_set_by_key(id, ocspcert) | |
335 | || !sk_OCSP_RESPID_push(ids, id)) { | |
336 | printf("Unable to set OCSP_RESPIDs\n"); | |
337 | goto end; | |
338 | } | |
339 | id = NULL; | |
340 | SSL_set_tlsext_status_ids(clientssl, ids); | |
341 | /* Control has been transferred */ | |
342 | ids = NULL; | |
343 | ||
344 | BIO_free(certbio); | |
345 | certbio = NULL; | |
346 | ||
347 | if (!create_ssl_connection(serverssl, clientssl)) { | |
348 | printf("Unable to create SSL connection\n"); | |
349 | goto end; | |
350 | } | |
351 | ||
352 | if (!ocsp_client_called || !ocsp_server_called) { | |
353 | printf("OCSP callbacks not called\n"); | |
354 | goto end; | |
355 | } | |
356 | ||
2cb4b5f6 MC |
357 | testresult = 1; |
358 | ||
359 | end: | |
ba881d3b MC |
360 | SSL_free(serverssl); |
361 | SSL_free(clientssl); | |
362 | SSL_CTX_free(sctx); | |
363 | SSL_CTX_free(cctx); | |
364 | sk_OCSP_RESPID_pop_free(ids, OCSP_RESPID_free); | |
365 | OCSP_RESPID_free(id); | |
366 | BIO_free(certbio); | |
367 | X509_free(ocspcert); | |
368 | ocspcert = NULL; | |
2cb4b5f6 MC |
369 | |
370 | return testresult; | |
371 | } | |
372 | ||
eaa776da MC |
373 | typedef struct ssl_session_test_fixture { |
374 | const char *test_case_name; | |
375 | int use_ext_cache; | |
376 | int use_int_cache; | |
377 | } SSL_SESSION_TEST_FIXTURE; | |
378 | ||
379 | static int new_called = 0, remove_called = 0; | |
380 | ||
381 | static SSL_SESSION_TEST_FIXTURE | |
382 | ssl_session_set_up(const char *const test_case_name) | |
383 | { | |
384 | SSL_SESSION_TEST_FIXTURE fixture; | |
385 | ||
386 | fixture.test_case_name = test_case_name; | |
387 | fixture.use_ext_cache = 1; | |
388 | fixture.use_int_cache = 1; | |
389 | ||
390 | new_called = remove_called = 0; | |
391 | ||
392 | return fixture; | |
393 | } | |
394 | ||
395 | static void ssl_session_tear_down(SSL_SESSION_TEST_FIXTURE fixture) | |
396 | { | |
397 | } | |
398 | ||
399 | static int new_session_cb(SSL *ssl, SSL_SESSION *sess) | |
400 | { | |
401 | new_called++; | |
402 | ||
403 | return 1; | |
404 | } | |
405 | ||
406 | static void remove_session_cb(SSL_CTX *ctx, SSL_SESSION *sess) | |
407 | { | |
408 | remove_called++; | |
409 | } | |
410 | ||
411 | static int execute_test_session(SSL_SESSION_TEST_FIXTURE fix) | |
2cb4b5f6 MC |
412 | { |
413 | SSL_CTX *sctx = NULL, *cctx = NULL; | |
414 | SSL *serverssl1 = NULL, *clientssl1 = NULL; | |
415 | SSL *serverssl2 = NULL, *clientssl2 = NULL; | |
b4982125 | 416 | #ifndef OPENSSL_NO_TLS1_1 |
eaa776da | 417 | SSL *serverssl3 = NULL, *clientssl3 = NULL; |
b4982125 | 418 | #endif |
2cb4b5f6 MC |
419 | SSL_SESSION *sess1 = NULL, *sess2 = NULL; |
420 | int testresult = 0; | |
421 | ||
422 | if (!create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(), &sctx, | |
423 | &cctx, cert, privkey)) { | |
424 | printf("Unable to create SSL_CTX pair\n"); | |
425 | return 0; | |
426 | } | |
427 | ||
eaa776da MC |
428 | #ifndef OPENSSL_NO_TLS1_2 |
429 | /* Only allow TLS1.2 so we can force a connection failure later */ | |
430 | SSL_CTX_set_min_proto_version(cctx, TLS1_2_VERSION); | |
431 | #endif | |
432 | ||
433 | /* Set up session cache */ | |
434 | if (fix.use_ext_cache) { | |
435 | SSL_CTX_sess_set_new_cb(cctx, new_session_cb); | |
436 | SSL_CTX_sess_set_remove_cb(cctx, remove_session_cb); | |
437 | } | |
438 | if (fix.use_int_cache) { | |
439 | /* Also covers instance where both are set */ | |
440 | SSL_CTX_set_session_cache_mode(cctx, SSL_SESS_CACHE_CLIENT); | |
441 | } else { | |
442 | SSL_CTX_set_session_cache_mode(cctx, | |
443 | SSL_SESS_CACHE_CLIENT | |
444 | | SSL_SESS_CACHE_NO_INTERNAL_STORE); | |
445 | } | |
2cb4b5f6 | 446 | |
b4982125 | 447 | if (!create_ssl_objects(sctx, cctx, &serverssl1, &clientssl1, NULL, |
2cb4b5f6 | 448 | NULL)) { |
b4982125 MC |
449 | printf("Unable to create SSL objects\n"); |
450 | goto end; | |
451 | } | |
452 | ||
453 | if (!create_ssl_connection(serverssl1, clientssl1)) { | |
2cb4b5f6 MC |
454 | printf("Unable to create SSL connection\n"); |
455 | goto end; | |
456 | } | |
2cb4b5f6 MC |
457 | sess1 = SSL_get1_session(clientssl1); |
458 | if (sess1 == NULL) { | |
459 | printf("Unexpected NULL session\n"); | |
460 | goto end; | |
461 | } | |
462 | ||
eaa776da | 463 | if (fix.use_int_cache && SSL_CTX_add_session(cctx, sess1)) { |
2cb4b5f6 MC |
464 | /* Should have failed because it should already be in the cache */ |
465 | printf("Unexpected success adding session to cache\n"); | |
466 | goto end; | |
467 | } | |
468 | ||
eaa776da MC |
469 | if (fix.use_ext_cache && (new_called != 1 || remove_called != 0)) { |
470 | printf("Session not added to cache\n"); | |
471 | goto end; | |
472 | } | |
473 | ||
b4982125 MC |
474 | if (!create_ssl_objects(sctx, cctx, &serverssl2, &clientssl2, NULL, NULL)) { |
475 | printf("Unable to create second SSL objects\n"); | |
476 | goto end; | |
477 | } | |
478 | ||
479 | if (!create_ssl_connection(serverssl2, clientssl2)) { | |
2cb4b5f6 MC |
480 | printf("Unable to create second SSL connection\n"); |
481 | goto end; | |
482 | } | |
483 | ||
484 | sess2 = SSL_get1_session(clientssl2); | |
485 | if (sess2 == NULL) { | |
486 | printf("Unexpected NULL session from clientssl2\n"); | |
487 | goto end; | |
488 | } | |
489 | ||
eaa776da MC |
490 | if (fix.use_ext_cache && (new_called != 2 || remove_called != 0)) { |
491 | printf("Remove session callback unexpectedly called\n"); | |
492 | goto end; | |
493 | } | |
494 | ||
2cb4b5f6 MC |
495 | /* |
496 | * This should clear sess2 from the cache because it is a "bad" session. See | |
497 | * SSL_set_session() documentation. | |
498 | */ | |
499 | if (!SSL_set_session(clientssl2, sess1)) { | |
500 | printf("Unexpected failure setting session\n"); | |
501 | goto end; | |
502 | } | |
503 | ||
eaa776da MC |
504 | if (fix.use_ext_cache && (new_called != 2 || remove_called != 1)) { |
505 | printf("Failed to call callback to remove session\n"); | |
506 | goto end; | |
507 | } | |
508 | ||
509 | ||
2cb4b5f6 MC |
510 | if (SSL_get_session(clientssl2) != sess1) { |
511 | printf("Unexpected session found\n"); | |
512 | goto end; | |
513 | } | |
514 | ||
eaa776da MC |
515 | if (fix.use_int_cache) { |
516 | if (!SSL_CTX_add_session(cctx, sess2)) { | |
517 | /* | |
518 | * Should have succeeded because it should not already be in the cache | |
519 | */ | |
520 | printf("Unexpected failure adding session to cache\n"); | |
521 | goto end; | |
522 | } | |
523 | ||
524 | if (!SSL_CTX_remove_session(cctx, sess2)) { | |
525 | printf("Unexpected failure removing session from cache\n"); | |
526 | goto end; | |
527 | } | |
528 | ||
529 | /* This is for the purposes of internal cache testing...ignore the | |
530 | * counter for external cache | |
2cb4b5f6 | 531 | */ |
eaa776da MC |
532 | if (fix.use_ext_cache) |
533 | remove_called--; | |
534 | } | |
535 | ||
536 | /* This shouldn't be in the cache so should fail */ | |
537 | if (SSL_CTX_remove_session(cctx, sess2)) { | |
538 | printf("Unexpected success removing session from cache\n"); | |
2cb4b5f6 MC |
539 | goto end; |
540 | } | |
541 | ||
eaa776da MC |
542 | if (fix.use_ext_cache && (new_called != 2 || remove_called != 2)) { |
543 | printf("Failed to call callback to remove session #2\n"); | |
2cb4b5f6 MC |
544 | goto end; |
545 | } | |
546 | ||
80f397e2 | 547 | #if !defined(OPENSSL_NO_TLS1_1) && !defined(OPENSSL_NO_TLS1_2) |
eaa776da MC |
548 | /* Force a connection failure */ |
549 | SSL_CTX_set_max_proto_version(sctx, TLS1_1_VERSION); | |
b4982125 MC |
550 | |
551 | if (!create_ssl_objects(sctx, cctx, &serverssl3, &clientssl3, NULL, NULL)) { | |
552 | printf("Unable to create third SSL objects\n"); | |
eaa776da MC |
553 | goto end; |
554 | } | |
b4982125 | 555 | |
eaa776da MC |
556 | if (!SSL_set_session(clientssl3, sess1)) { |
557 | printf("Unable to set session for third connection\n"); | |
558 | goto end; | |
559 | } | |
560 | ||
561 | /* This should fail because of the mismatched protocol versions */ | |
b4982125 MC |
562 | if (create_ssl_connection(serverssl3, clientssl3)) { |
563 | printf("Unable to create third SSL connection\n"); | |
eaa776da MC |
564 | goto end; |
565 | } | |
566 | ||
b4982125 | 567 | |
eaa776da MC |
568 | /* We should have automatically removed the session from the cache */ |
569 | if (fix.use_ext_cache && (new_called != 2 || remove_called != 3)) { | |
570 | printf("Failed to call callback to remove session #2\n"); | |
2cb4b5f6 MC |
571 | goto end; |
572 | } | |
573 | ||
eaa776da MC |
574 | if (fix.use_int_cache && !SSL_CTX_add_session(cctx, sess2)) { |
575 | /* | |
576 | * Should have succeeded because it should not already be in the cache | |
577 | */ | |
578 | printf("Unexpected failure adding session to cache #2\n"); | |
579 | goto end; | |
580 | } | |
581 | #endif | |
582 | ||
2cb4b5f6 | 583 | testresult = 1; |
eaa776da | 584 | |
2cb4b5f6 MC |
585 | end: |
586 | SSL_free(serverssl1); | |
587 | SSL_free(clientssl1); | |
588 | SSL_free(serverssl2); | |
589 | SSL_free(clientssl2); | |
b4982125 | 590 | #ifndef OPENSSL_NO_TLS1_1 |
eaa776da MC |
591 | SSL_free(serverssl3); |
592 | SSL_free(clientssl3); | |
b4982125 | 593 | #endif |
2cb4b5f6 MC |
594 | SSL_SESSION_free(sess1); |
595 | SSL_SESSION_free(sess2); | |
eaa776da MC |
596 | /* |
597 | * Check if we need to remove any sessions up-refed for the external cache | |
598 | */ | |
599 | if (new_called >= 1) | |
600 | SSL_SESSION_free(sess1); | |
601 | if (new_called >= 2) | |
602 | SSL_SESSION_free(sess2); | |
2cb4b5f6 MC |
603 | SSL_CTX_free(sctx); |
604 | SSL_CTX_free(cctx); | |
605 | ||
606 | return testresult; | |
607 | } | |
608 | ||
7fb4c820 MC |
609 | static int test_session_with_only_int_cache(void) |
610 | { | |
eaa776da MC |
611 | SETUP_TEST_FIXTURE(SSL_SESSION_TEST_FIXTURE, ssl_session_set_up); |
612 | ||
613 | fixture.use_ext_cache = 0; | |
614 | ||
615 | EXECUTE_TEST(execute_test_session, ssl_session_tear_down); | |
616 | } | |
617 | ||
7fb4c820 MC |
618 | static int test_session_with_only_ext_cache(void) |
619 | { | |
eaa776da MC |
620 | SETUP_TEST_FIXTURE(SSL_SESSION_TEST_FIXTURE, ssl_session_set_up); |
621 | ||
622 | fixture.use_int_cache = 0; | |
623 | ||
624 | EXECUTE_TEST(execute_test_session, ssl_session_tear_down); | |
625 | } | |
626 | ||
7fb4c820 MC |
627 | static int test_session_with_both_cache(void) |
628 | { | |
eaa776da MC |
629 | SETUP_TEST_FIXTURE(SSL_SESSION_TEST_FIXTURE, ssl_session_set_up); |
630 | ||
631 | EXECUTE_TEST(execute_test_session, ssl_session_tear_down); | |
632 | } | |
633 | ||
7fb4c820 MC |
634 | #define USE_NULL 0 |
635 | #define USE_BIO_1 1 | |
636 | #define USE_BIO_2 2 | |
637 | ||
638 | #define TOTAL_SSL_SET_BIO_TESTS (3 * 3 * 3 * 3) | |
639 | ||
640 | static void setupbio(BIO **res, BIO *bio1, BIO *bio2, int type) | |
641 | { | |
642 | switch (type) { | |
643 | case USE_NULL: | |
644 | *res = NULL; | |
645 | break; | |
646 | case USE_BIO_1: | |
647 | *res = bio1; | |
648 | break; | |
649 | case USE_BIO_2: | |
650 | *res = bio2; | |
651 | break; | |
652 | } | |
653 | } | |
654 | ||
655 | static int test_ssl_set_bio(int idx) | |
656 | { | |
657 | SSL_CTX *ctx = SSL_CTX_new(TLS_method()); | |
658 | BIO *bio1 = NULL; | |
659 | BIO *bio2 = NULL; | |
0fae8150 | 660 | BIO *irbio = NULL, *iwbio = NULL, *nrbio = NULL, *nwbio = NULL; |
7fb4c820 MC |
661 | SSL *ssl = NULL; |
662 | int initrbio, initwbio, newrbio, newwbio; | |
663 | int testresult = 0; | |
664 | ||
665 | if (ctx == NULL) { | |
666 | printf("Failed to allocate SSL_CTX\n"); | |
667 | goto end; | |
668 | } | |
669 | ||
670 | ssl = SSL_new(ctx); | |
671 | if (ssl == NULL) { | |
672 | printf("Failed to allocate SSL object\n"); | |
673 | goto end; | |
674 | } | |
675 | ||
676 | initrbio = idx % 3; | |
677 | idx /= 3; | |
678 | initwbio = idx % 3; | |
679 | idx /= 3; | |
680 | newrbio = idx % 3; | |
681 | idx /= 3; | |
682 | newwbio = idx; | |
683 | OPENSSL_assert(newwbio <= 2); | |
684 | ||
685 | if (initrbio == USE_BIO_1 || initwbio == USE_BIO_1 || newrbio == USE_BIO_1 | |
686 | || newwbio == USE_BIO_1) { | |
687 | bio1 = BIO_new(BIO_s_mem()); | |
688 | if (bio1 == NULL) { | |
689 | printf("Failed to allocate bio1\n"); | |
690 | goto end; | |
691 | } | |
692 | } | |
693 | ||
694 | if (initrbio == USE_BIO_2 || initwbio == USE_BIO_2 || newrbio == USE_BIO_2 | |
695 | || newwbio == USE_BIO_2) { | |
696 | bio2 = BIO_new(BIO_s_mem()); | |
697 | if (bio2 == NULL) { | |
698 | printf("Failed to allocate bio2\n"); | |
699 | goto end; | |
700 | } | |
701 | } | |
702 | ||
703 | setupbio(&irbio, bio1, bio2, initrbio); | |
704 | setupbio(&iwbio, bio1, bio2, initwbio); | |
705 | ||
706 | /* | |
707 | * We want to maintain our own refs to these BIO, so do an up ref for each | |
708 | * BIO that will have ownersip transferred in the SSL_set_bio() call | |
709 | */ | |
710 | if (irbio != NULL) | |
711 | BIO_up_ref(irbio); | |
712 | if (iwbio != NULL && iwbio != irbio) | |
713 | BIO_up_ref(iwbio); | |
714 | ||
715 | SSL_set_bio(ssl, irbio, iwbio); | |
716 | ||
717 | setupbio(&nrbio, bio1, bio2, newrbio); | |
718 | setupbio(&nwbio, bio1, bio2, newwbio); | |
719 | ||
720 | /* | |
721 | * We will (maybe) transfer ownership again so do more up refs. | |
722 | * SSL_set_bio() has some really complicated ownership rules where BIOs have | |
723 | * already been set! | |
724 | */ | |
725 | if (nrbio != NULL && nrbio != irbio && (nwbio != iwbio || nrbio != nwbio)) | |
726 | BIO_up_ref(nrbio); | |
727 | if (nwbio != NULL && nwbio != nrbio && (nwbio != iwbio || (nwbio == iwbio && irbio == iwbio))) | |
728 | BIO_up_ref(nwbio); | |
729 | ||
730 | SSL_set_bio(ssl, nrbio, nwbio); | |
731 | ||
732 | testresult = 1; | |
733 | ||
734 | end: | |
735 | SSL_free(ssl); | |
736 | BIO_free(bio1); | |
737 | BIO_free(bio2); | |
738 | /* | |
739 | * This test is checking that the ref counting for SSL_set_bio is correct. | |
740 | * If we get here and we did too many frees then we will fail in the above | |
741 | * functions. If we haven't done enough then this will only be detected in | |
742 | * a crypto-mdebug build | |
743 | */ | |
744 | SSL_CTX_free(ctx); | |
745 | ||
746 | return testresult; | |
747 | } | |
748 | ||
9a716987 MC |
749 | typedef struct ssl_bio_test_fixture { |
750 | const char *test_case_name; | |
751 | int pop_ssl; | |
752 | enum { NO_BIO_CHANGE, CHANGE_RBIO, CHANGE_WBIO } change_bio; | |
753 | } SSL_BIO_TEST_FIXTURE; | |
754 | ||
755 | static SSL_BIO_TEST_FIXTURE ssl_bio_set_up(const char *const test_case_name) | |
756 | { | |
757 | SSL_BIO_TEST_FIXTURE fixture; | |
758 | ||
759 | fixture.test_case_name = test_case_name; | |
760 | fixture.pop_ssl = 0; | |
bee5ee5f | 761 | fixture.change_bio = NO_BIO_CHANGE; |
9a716987 MC |
762 | |
763 | return fixture; | |
764 | } | |
765 | ||
766 | static void ssl_bio_tear_down(SSL_BIO_TEST_FIXTURE fixture) | |
767 | { | |
768 | } | |
769 | ||
770 | static int execute_test_ssl_bio(SSL_BIO_TEST_FIXTURE fix) | |
771 | { | |
772 | BIO *sslbio = NULL, *membio1 = NULL, *membio2 = NULL; | |
773 | SSL_CTX *ctx = SSL_CTX_new(TLS_method()); | |
774 | SSL *ssl = NULL; | |
775 | int testresult = 0; | |
776 | ||
777 | if (ctx == NULL) { | |
778 | printf("Failed to allocate SSL_CTX\n"); | |
779 | return 0; | |
780 | } | |
781 | ||
782 | ssl = SSL_new(ctx); | |
783 | if (ssl == NULL) { | |
784 | printf("Failed to allocate SSL object\n"); | |
785 | goto end; | |
786 | } | |
787 | ||
788 | sslbio = BIO_new(BIO_f_ssl()); | |
789 | membio1 = BIO_new(BIO_s_mem()); | |
790 | ||
791 | if (sslbio == NULL || membio1 == NULL) { | |
792 | printf("Malloc failure creating BIOs\n"); | |
793 | goto end; | |
794 | } | |
795 | ||
796 | BIO_set_ssl(sslbio, ssl, BIO_CLOSE); | |
797 | ||
798 | /* | |
799 | * If anything goes wrong here then we could leak memory, so this will | |
800 | * be caught in a crypto-mdebug build | |
801 | */ | |
802 | BIO_push(sslbio, membio1); | |
803 | ||
804 | /* Verify chaning the rbio/wbio directly does not cause leaks */ | |
805 | if (fix.change_bio != NO_BIO_CHANGE) { | |
806 | membio2 = BIO_new(BIO_s_mem()); | |
807 | if (membio2 == NULL) { | |
808 | printf("Malloc failure creating membio2\n"); | |
809 | goto end; | |
810 | } | |
811 | if (fix.change_bio == CHANGE_RBIO) | |
65e2d672 | 812 | SSL_set0_rbio(ssl, membio2); |
9a716987 | 813 | else |
65e2d672 | 814 | SSL_set0_wbio(ssl, membio2); |
9a716987 MC |
815 | } |
816 | ssl = NULL; | |
817 | ||
818 | if (fix.pop_ssl) | |
819 | BIO_pop(sslbio); | |
820 | else | |
821 | BIO_pop(membio1); | |
822 | ||
823 | testresult = 1; | |
824 | end: | |
825 | BIO_free(membio1); | |
826 | BIO_free(sslbio); | |
827 | SSL_free(ssl); | |
828 | SSL_CTX_free(ctx); | |
829 | ||
830 | return testresult; | |
831 | } | |
832 | ||
833 | static int test_ssl_bio_pop_next_bio(void) | |
834 | { | |
835 | SETUP_TEST_FIXTURE(SSL_BIO_TEST_FIXTURE, ssl_bio_set_up); | |
836 | ||
837 | EXECUTE_TEST(execute_test_ssl_bio, ssl_bio_tear_down); | |
838 | } | |
839 | ||
840 | static int test_ssl_bio_pop_ssl_bio(void) | |
841 | { | |
842 | SETUP_TEST_FIXTURE(SSL_BIO_TEST_FIXTURE, ssl_bio_set_up); | |
843 | ||
844 | fixture.pop_ssl = 1; | |
845 | ||
846 | EXECUTE_TEST(execute_test_ssl_bio, ssl_bio_tear_down); | |
847 | } | |
848 | ||
849 | static int test_ssl_bio_change_rbio(void) | |
850 | { | |
851 | SETUP_TEST_FIXTURE(SSL_BIO_TEST_FIXTURE, ssl_bio_set_up); | |
852 | ||
853 | fixture.change_bio = CHANGE_RBIO; | |
854 | ||
855 | EXECUTE_TEST(execute_test_ssl_bio, ssl_bio_tear_down); | |
856 | } | |
857 | ||
858 | static int test_ssl_bio_change_wbio(void) | |
859 | { | |
860 | SETUP_TEST_FIXTURE(SSL_BIO_TEST_FIXTURE, ssl_bio_set_up); | |
861 | ||
862 | fixture.change_bio = CHANGE_WBIO; | |
863 | ||
864 | EXECUTE_TEST(execute_test_ssl_bio, ssl_bio_tear_down); | |
865 | } | |
866 | ||
e364c3b2 | 867 | int test_main(int argc, char *argv[]) |
2cb4b5f6 | 868 | { |
c887104f | 869 | int testresult = 1; |
2cb4b5f6 MC |
870 | |
871 | if (argc != 3) { | |
872 | printf("Invalid argument count\n"); | |
c887104f | 873 | return 1; |
2cb4b5f6 MC |
874 | } |
875 | ||
876 | cert = argv[1]; | |
877 | privkey = argv[2]; | |
878 | ||
84d5549e | 879 | ADD_TEST(test_large_message_tls); |
7856332e | 880 | ADD_TEST(test_large_message_tls_read_ahead); |
55386bef | 881 | #ifndef OPENSSL_NO_DTLS |
84d5549e | 882 | ADD_TEST(test_large_message_dtls); |
55386bef | 883 | #endif |
c887104f | 884 | ADD_TEST(test_tlsext_status_type); |
eaa776da MC |
885 | ADD_TEST(test_session_with_only_int_cache); |
886 | ADD_TEST(test_session_with_only_ext_cache); | |
887 | ADD_TEST(test_session_with_both_cache); | |
7fb4c820 | 888 | ADD_ALL_TESTS(test_ssl_set_bio, TOTAL_SSL_SET_BIO_TESTS); |
9a716987 MC |
889 | ADD_TEST(test_ssl_bio_pop_next_bio); |
890 | ADD_TEST(test_ssl_bio_pop_ssl_bio); | |
891 | ADD_TEST(test_ssl_bio_change_rbio); | |
892 | ADD_TEST(test_ssl_bio_change_wbio); | |
2cb4b5f6 | 893 | |
c887104f | 894 | testresult = run_tests(argv[0]); |
2cb4b5f6 | 895 | |
fa454945 MC |
896 | bio_s_mempacket_test_free(); |
897 | ||
c887104f | 898 | return testresult; |
2cb4b5f6 | 899 | } |