| 
									
										
										
										
											2017-03-07 00:56:42 +08:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2018-03-20 21:00:17 +08:00
										 |  |  |  * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. | 
					
						
							| 
									
										
										
										
											2017-03-07 00:56:42 +08:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2018-12-06 20:05:25 +08:00
										 |  |  |  * Licensed under the Apache License 2.0 (the "License").  You may not use | 
					
						
							| 
									
										
										
										
											2017-03-07 00:56:42 +08:00
										 |  |  |  * this file except in compliance with the License.  You can obtain a copy | 
					
						
							|  |  |  |  * in the file LICENSE in the source distribution or at | 
					
						
							|  |  |  |  * https://www.openssl.org/source/license.html
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "ssltestlib.h"
 | 
					
						
							|  |  |  | #include "testutil.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char *cert = NULL; | 
					
						
							|  |  |  | static char *privkey = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define TEST_PLAINTEXT_OVERFLOW_OK      0
 | 
					
						
							|  |  |  | #define TEST_PLAINTEXT_OVERFLOW_NOT_OK  1
 | 
					
						
							|  |  |  | #define TEST_ENCRYPTED_OVERFLOW_TLS1_3_OK       2
 | 
					
						
							|  |  |  | #define TEST_ENCRYPTED_OVERFLOW_TLS1_3_NOT_OK   3
 | 
					
						
							|  |  |  | #define TEST_ENCRYPTED_OVERFLOW_TLS1_2_OK       4
 | 
					
						
							|  |  |  | #define TEST_ENCRYPTED_OVERFLOW_TLS1_2_NOT_OK   5
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define TOTAL_RECORD_OVERFLOW_TESTS 6
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int write_record(BIO *b, size_t len, int rectype, int recversion) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     unsigned char header[SSL3_RT_HEADER_LENGTH]; | 
					
						
							|  |  |  |     size_t written; | 
					
						
							|  |  |  |     unsigned char buf[256]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     memset(buf, 0, sizeof(buf)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     header[0] = rectype; | 
					
						
							|  |  |  |     header[1] = (recversion >> 8) & 0xff; | 
					
						
							|  |  |  |     header[2] = recversion & 0xff; | 
					
						
							|  |  |  |     header[3] = (len >> 8) & 0xff; | 
					
						
							|  |  |  |     header[4] = len & 0xff; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!BIO_write_ex(b, header, SSL3_RT_HEADER_LENGTH, &written) | 
					
						
							|  |  |  |             || written != SSL3_RT_HEADER_LENGTH) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     while (len > 0) { | 
					
						
							|  |  |  |         size_t outlen; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (len > sizeof(buf)) | 
					
						
							|  |  |  |             outlen = sizeof(buf); | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             outlen = len; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!BIO_write_ex(b, buf, outlen, &written) | 
					
						
							|  |  |  |                 || written != outlen) | 
					
						
							|  |  |  |             return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         len -= outlen; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int fail_due_to_record_overflow(int enc) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     long err = ERR_peek_error(); | 
					
						
							|  |  |  |     int reason; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (enc) | 
					
						
							|  |  |  |         reason = SSL_R_ENCRYPTED_LENGTH_TOO_LONG; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         reason = SSL_R_DATA_LENGTH_TOO_LONG; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ERR_GET_LIB(err) == ERR_LIB_SSL | 
					
						
							|  |  |  |             && ERR_GET_REASON(err) == reason) | 
					
						
							|  |  |  |         return 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-07 17:58:27 +08:00
										 |  |  | static int test_record_overflow(int idx) | 
					
						
							| 
									
										
										
										
											2017-03-07 00:56:42 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     SSL_CTX *cctx = NULL, *sctx = NULL; | 
					
						
							|  |  |  |     SSL *clientssl = NULL, *serverssl = NULL; | 
					
						
							|  |  |  |     int testresult = 0; | 
					
						
							|  |  |  |     size_t len = 0; | 
					
						
							|  |  |  |     size_t written; | 
					
						
							|  |  |  |     int overf_expected; | 
					
						
							|  |  |  |     unsigned char buf; | 
					
						
							|  |  |  |     BIO *serverbio; | 
					
						
							|  |  |  |     int recversion; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef OPENSSL_NO_TLS1_2
 | 
					
						
							|  |  |  |     if (idx == TEST_ENCRYPTED_OVERFLOW_TLS1_2_OK | 
					
						
							|  |  |  |             || idx == TEST_ENCRYPTED_OVERFLOW_TLS1_2_NOT_OK) | 
					
						
							|  |  |  |         return 1; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef OPENSSL_NO_TLS1_3
 | 
					
						
							|  |  |  |     if (idx == TEST_ENCRYPTED_OVERFLOW_TLS1_3_OK | 
					
						
							|  |  |  |             || idx == TEST_ENCRYPTED_OVERFLOW_TLS1_3_NOT_OK) | 
					
						
							|  |  |  |         return 1; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ERR_clear_error(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-19 02:34:43 +08:00
										 |  |  |     if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(), | 
					
						
							| 
									
										
										
										
											2018-12-10 03:53:05 +08:00
										 |  |  |                                        TLS1_VERSION, 0, | 
					
						
							| 
									
										
										
										
											2017-04-19 02:34:43 +08:00
										 |  |  |                                        &sctx, &cctx, cert, privkey))) | 
					
						
							| 
									
										
										
										
											2017-03-07 00:56:42 +08:00
										 |  |  |         goto end; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (idx == TEST_ENCRYPTED_OVERFLOW_TLS1_2_OK | 
					
						
							|  |  |  |             || idx == TEST_ENCRYPTED_OVERFLOW_TLS1_2_NOT_OK) { | 
					
						
							| 
									
										
										
										
											2017-03-07 17:58:27 +08:00
										 |  |  |         len = SSL3_RT_MAX_ENCRYPTED_LENGTH; | 
					
						
							|  |  |  | #ifndef OPENSSL_NO_COMP
 | 
					
						
							|  |  |  |         len -= SSL3_RT_MAX_COMPRESSED_OVERHEAD; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2017-03-07 00:56:42 +08:00
										 |  |  |         SSL_CTX_set_max_proto_version(sctx, TLS1_2_VERSION); | 
					
						
							|  |  |  |     } else if (idx == TEST_ENCRYPTED_OVERFLOW_TLS1_3_OK | 
					
						
							|  |  |  |                || idx == TEST_ENCRYPTED_OVERFLOW_TLS1_3_NOT_OK) { | 
					
						
							|  |  |  |         len = SSL3_RT_MAX_TLS13_ENCRYPTED_LENGTH; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-19 02:34:43 +08:00
										 |  |  |     if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, | 
					
						
							|  |  |  |                                       NULL, NULL))) | 
					
						
							| 
									
										
										
										
											2017-03-07 00:56:42 +08:00
										 |  |  |         goto end; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     serverbio = SSL_get_rbio(serverssl); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (idx == TEST_PLAINTEXT_OVERFLOW_OK | 
					
						
							|  |  |  |             || idx == TEST_PLAINTEXT_OVERFLOW_NOT_OK) { | 
					
						
							|  |  |  |         len = SSL3_RT_MAX_PLAIN_LENGTH; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (idx == TEST_PLAINTEXT_OVERFLOW_NOT_OK) | 
					
						
							|  |  |  |             len++; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-19 02:34:43 +08:00
										 |  |  |         if (!TEST_true(write_record(serverbio, len, | 
					
						
							|  |  |  |                                     SSL3_RT_HANDSHAKE, TLS1_VERSION))) | 
					
						
							| 
									
										
										
										
											2017-03-07 00:56:42 +08:00
										 |  |  |             goto end; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-19 02:34:43 +08:00
										 |  |  |         if (!TEST_int_le(SSL_accept(serverssl), 0)) | 
					
						
							| 
									
										
										
										
											2017-03-07 00:56:42 +08:00
										 |  |  |             goto end; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         overf_expected = (idx == TEST_PLAINTEXT_OVERFLOW_OK) ? 0 : 1; | 
					
						
							| 
									
										
										
										
											2017-04-19 02:34:43 +08:00
										 |  |  |         if (!TEST_int_eq(fail_due_to_record_overflow(0), overf_expected)) | 
					
						
							| 
									
										
										
										
											2017-03-07 00:56:42 +08:00
										 |  |  |             goto end; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         goto success; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-19 02:34:43 +08:00
										 |  |  |     if (!TEST_true(create_ssl_connection(serverssl, clientssl, | 
					
						
							|  |  |  |                                          SSL_ERROR_NONE))) | 
					
						
							| 
									
										
										
										
											2017-03-07 00:56:42 +08:00
										 |  |  |         goto end; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (idx == TEST_ENCRYPTED_OVERFLOW_TLS1_2_NOT_OK | 
					
						
							|  |  |  |             || idx == TEST_ENCRYPTED_OVERFLOW_TLS1_3_NOT_OK) { | 
					
						
							|  |  |  |         overf_expected = 1; | 
					
						
							|  |  |  |         len++; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         overf_expected = 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-26 20:26:14 +08:00
										 |  |  |     recversion = TLS1_2_VERSION; | 
					
						
							| 
									
										
										
										
											2017-03-07 00:56:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-19 02:34:43 +08:00
										 |  |  |     if (!TEST_true(write_record(serverbio, len, SSL3_RT_APPLICATION_DATA, | 
					
						
							|  |  |  |                                 recversion))) | 
					
						
							| 
									
										
										
										
											2017-03-07 00:56:42 +08:00
										 |  |  |         goto end; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-19 02:34:43 +08:00
										 |  |  |     if (!TEST_false(SSL_read_ex(serverssl, &buf, sizeof(buf), &written))) | 
					
						
							| 
									
										
										
										
											2017-03-07 00:56:42 +08:00
										 |  |  |         goto end; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-19 02:34:43 +08:00
										 |  |  |     if (!TEST_int_eq(fail_due_to_record_overflow(1), overf_expected)) | 
					
						
							| 
									
										
										
										
											2017-03-07 00:56:42 +08:00
										 |  |  |         goto end; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  success: | 
					
						
							|  |  |  |     testresult = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  end: | 
					
						
							|  |  |  |     SSL_free(serverssl); | 
					
						
							|  |  |  |     SSL_free(clientssl); | 
					
						
							|  |  |  |     SSL_CTX_free(sctx); | 
					
						
							|  |  |  |     SSL_CTX_free(cctx); | 
					
						
							|  |  |  |     return testresult; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-16 10:36:01 +08:00
										 |  |  | OPT_TEST_DECLARE_USAGE("certfile privkeyfile\n") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-18 09:48:27 +08:00
										 |  |  | int setup_tests(void) | 
					
						
							| 
									
										
										
										
											2017-03-07 00:56:42 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-01-30 23:30:17 +08:00
										 |  |  |     if (!test_skip_common_options()) { | 
					
						
							|  |  |  |         TEST_error("Error parsing test options\n"); | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-18 09:48:27 +08:00
										 |  |  |     if (!TEST_ptr(cert = test_get_argument(0)) | 
					
						
							|  |  |  |             || !TEST_ptr(privkey = test_get_argument(1))) | 
					
						
							|  |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2017-03-07 00:56:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-07 17:58:27 +08:00
										 |  |  |     ADD_ALL_TESTS(test_record_overflow, TOTAL_RECORD_OVERFLOW_TESTS); | 
					
						
							| 
									
										
										
										
											2017-07-18 09:48:27 +08:00
										 |  |  |     return 1; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-03-07 00:56:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-18 09:48:27 +08:00
										 |  |  | void cleanup_tests(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-03-07 00:56:42 +08:00
										 |  |  |     bio_s_mempacket_test_free(); | 
					
						
							|  |  |  | } |