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