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