sslcorrupttest.c (1.1.1.3) | sslcorrupttest.c (1.1.1.1) |
---|---|
1/* | 1/* |
2 * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. | 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 | 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 |
10#include <string.h> | |
11#include "ssltestlib.h" 12#include "testutil.h" 13 | 10#include "ssltestlib.h" 11#include "testutil.h" 12 |
14static int docorrupt = 0; 15 | |
16static void copy_flags(BIO *bio) 17{ 18 int flags; 19 BIO *next = BIO_next(bio); 20 21 flags = BIO_test_flags(next, BIO_FLAGS_SHOULD_RETRY | BIO_FLAGS_RWS); 22 BIO_clear_flags(bio, BIO_FLAGS_SHOULD_RETRY | BIO_FLAGS_RWS); 23 BIO_set_flags(bio, flags); --- 11 unchanged lines hidden (view full) --- 35} 36 37static int tls_corrupt_write(BIO *bio, const char *in, int inl) 38{ 39 int ret; 40 BIO *next = BIO_next(bio); 41 char *copy; 42 | 13static void copy_flags(BIO *bio) 14{ 15 int flags; 16 BIO *next = BIO_next(bio); 17 18 flags = BIO_test_flags(next, BIO_FLAGS_SHOULD_RETRY | BIO_FLAGS_RWS); 19 BIO_clear_flags(bio, BIO_FLAGS_SHOULD_RETRY | BIO_FLAGS_RWS); 20 BIO_set_flags(bio, flags); --- 11 unchanged lines hidden (view full) --- 32} 33 34static int tls_corrupt_write(BIO *bio, const char *in, int inl) 35{ 36 int ret; 37 BIO *next = BIO_next(bio); 38 char *copy; 39 |
43 if (docorrupt) { 44 if (!TEST_ptr(copy = BUF_memdup(in, inl))) 45 return 0; | 40 if (in[0] == SSL3_RT_APPLICATION_DATA) { 41 copy = BUF_memdup(in, inl); 42 TEST_check(copy != NULL); |
46 /* corrupt last bit of application data */ 47 copy[inl-1] ^= 1; 48 ret = BIO_write(next, copy, inl); 49 OPENSSL_free(copy); 50 } else { 51 ret = BIO_write(next, in, inl); 52 } 53 copy_flags(bio); --- 78 unchanged lines hidden (view full) --- 132 * The test is supposed to be executed with RSA key, customarily 133 * with apps/server.pem used even in other tests. For this reason 134 * |cipher_list| is initialized with RSA ciphers' names. This 135 * naturally means that if test is to be re-purposed for other 136 * type of key, then NID_auth_* filter below would need adjustment. 137 */ 138static const char **cipher_list = NULL; 139 | 43 /* corrupt last bit of application data */ 44 copy[inl-1] ^= 1; 45 ret = BIO_write(next, copy, inl); 46 OPENSSL_free(copy); 47 } else { 48 ret = BIO_write(next, in, inl); 49 } 50 copy_flags(bio); --- 78 unchanged lines hidden (view full) --- 129 * The test is supposed to be executed with RSA key, customarily 130 * with apps/server.pem used even in other tests. For this reason 131 * |cipher_list| is initialized with RSA ciphers' names. This 132 * naturally means that if test is to be re-purposed for other 133 * type of key, then NID_auth_* filter below would need adjustment. 134 */ 135static const char **cipher_list = NULL; 136 |
140static int setup_cipher_list(void) | 137static int setup_cipher_list() |
141{ 142 SSL_CTX *ctx = NULL; 143 SSL *ssl = NULL; | 138{ 139 SSL_CTX *ctx = NULL; 140 SSL *ssl = NULL; |
144 STACK_OF(SSL_CIPHER) *sk_ciphers = NULL; 145 int i, j, numciphers = 0; | 141 static STACK_OF(SSL_CIPHER) *sk_ciphers = NULL; 142 int i, numciphers; |
146 | 143 |
147 if (!TEST_ptr(ctx = SSL_CTX_new(TLS_server_method())) 148 || !TEST_ptr(ssl = SSL_new(ctx)) 149 || !TEST_ptr(sk_ciphers = SSL_get1_supported_ciphers(ssl))) 150 goto err; | 144 ctx = SSL_CTX_new(TLS_server_method()); 145 TEST_check(ctx != NULL); 146 ssl = SSL_new(ctx); 147 TEST_check(ssl != NULL); 148 sk_ciphers = SSL_get1_supported_ciphers(ssl); 149 TEST_check(sk_ciphers != NULL); |
151 152 /* 153 * The |cipher_list| will be filled only with names of RSA ciphers, 154 * so that some of the allocated space will be wasted, but the loss 155 * is deemed acceptable... 156 */ 157 cipher_list = OPENSSL_malloc(sk_SSL_CIPHER_num(sk_ciphers) * 158 sizeof(cipher_list[0])); | 150 151 /* 152 * The |cipher_list| will be filled only with names of RSA ciphers, 153 * so that some of the allocated space will be wasted, but the loss 154 * is deemed acceptable... 155 */ 156 cipher_list = OPENSSL_malloc(sk_SSL_CIPHER_num(sk_ciphers) * 157 sizeof(cipher_list[0])); |
159 if (!TEST_ptr(cipher_list)) 160 goto err; | 158 TEST_check(cipher_list != NULL); |
161 | 159 |
162 for (j = 0, i = 0; i < sk_SSL_CIPHER_num(sk_ciphers); i++) { | 160 for (numciphers = 0, i = 0; i < sk_SSL_CIPHER_num(sk_ciphers); i++) { |
163 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(sk_ciphers, i); 164 165 if (SSL_CIPHER_get_auth_nid(cipher) == NID_auth_rsa) | 161 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(sk_ciphers, i); 162 163 if (SSL_CIPHER_get_auth_nid(cipher) == NID_auth_rsa) |
166 cipher_list[j++] = SSL_CIPHER_get_name(cipher); | 164 cipher_list[numciphers++] = SSL_CIPHER_get_name(cipher); |
167 } | 165 } |
168 if (TEST_int_ne(j, 0)) 169 numciphers = j; | 166 TEST_check(numciphers != 0); |
170 | 167 |
171err: | |
172 sk_SSL_CIPHER_free(sk_ciphers); 173 SSL_free(ssl); 174 SSL_CTX_free(ctx); 175 176 return numciphers; 177} 178 179static char *cert = NULL; 180static char *privkey = NULL; 181 182static int test_ssl_corrupt(int testidx) 183{ | 168 sk_SSL_CIPHER_free(sk_ciphers); 169 SSL_free(ssl); 170 SSL_CTX_free(ctx); 171 172 return numciphers; 173} 174 175static char *cert = NULL; 176static char *privkey = NULL; 177 178static int test_ssl_corrupt(int testidx) 179{ |
184 static unsigned char junk[16000] = { 0 }; | |
185 SSL_CTX *sctx = NULL, *cctx = NULL; 186 SSL *server = NULL, *client = NULL; 187 BIO *c_to_s_fbio; 188 int testresult = 0; | 180 SSL_CTX *sctx = NULL, *cctx = NULL; 181 SSL *server = NULL, *client = NULL; 182 BIO *c_to_s_fbio; 183 int testresult = 0; |
189 STACK_OF(SSL_CIPHER) *ciphers; 190 const SSL_CIPHER *currcipher; | 184 static unsigned char junk[16000] = { 0 }; |
191 | 185 |
192 docorrupt = 0; | 186 printf("Starting Test %d, %s\n", testidx, cipher_list[testidx]); |
193 | 187 |
194 TEST_info("Starting #%d, %s", testidx, cipher_list[testidx]); 195 196 if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(), 197 TLS1_VERSION, TLS_MAX_VERSION, 198 &sctx, &cctx, cert, privkey))) | 188 if (!create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(), &sctx, 189 &cctx, cert, privkey)) { 190 printf("Unable to create SSL_CTX pair\n"); |
199 return 0; | 191 return 0; |
192 } |
|
200 | 193 |
201 if (!TEST_true(SSL_CTX_set_cipher_list(cctx, cipher_list[testidx])) 202 || !TEST_true(SSL_CTX_set_ciphersuites(cctx, "")) 203 || !TEST_ptr(ciphers = SSL_CTX_get_ciphers(cctx)) 204 || !TEST_int_eq(sk_SSL_CIPHER_num(ciphers), 1) 205 || !TEST_ptr(currcipher = sk_SSL_CIPHER_value(ciphers, 0))) | 194 if (!SSL_CTX_set_cipher_list(cctx, cipher_list[testidx])) { 195 printf("Failed setting cipher list\n"); |
206 goto end; | 196 goto end; |
197 } |
|
207 | 198 |
208 /* 209 * No ciphers we are using are TLSv1.3 compatible so we should not attempt 210 * to negotiate TLSv1.3 211 */ 212 if (!TEST_true(SSL_CTX_set_max_proto_version(cctx, TLS1_2_VERSION))) | 199 c_to_s_fbio = BIO_new(bio_f_tls_corrupt_filter()); 200 if (c_to_s_fbio == NULL) { 201 printf("Failed to create filter BIO\n"); |
213 goto end; | 202 goto end; |
203 } |
|
214 | 204 |
215 if (!TEST_ptr(c_to_s_fbio = BIO_new(bio_f_tls_corrupt_filter()))) 216 goto end; 217 | |
218 /* BIO is freed by create_ssl_connection on error */ | 205 /* BIO is freed by create_ssl_connection on error */ |
219 if (!TEST_true(create_ssl_objects(sctx, cctx, &server, &client, NULL, 220 c_to_s_fbio))) | 206 if (!create_ssl_objects(sctx, cctx, &server, &client, NULL, 207 c_to_s_fbio)) { 208 printf("Unable to create SSL objects\n"); 209 ERR_print_errors_fp(stdout); |
221 goto end; | 210 goto end; |
211 } |
|
222 | 212 |
223 if (!TEST_true(create_ssl_connection(server, client, SSL_ERROR_NONE))) | 213 if (!create_ssl_connection(server, client)) { 214 printf("Unable to create SSL connection\n"); 215 ERR_print_errors_fp(stdout); |
224 goto end; | 216 goto end; |
217 } |
|
225 | 218 |
226 docorrupt = 1; 227 228 if (!TEST_int_ge(SSL_write(client, junk, sizeof(junk)), 0)) | 219 if (SSL_write(client, junk, sizeof(junk)) < 0) { 220 printf("Unable to SSL_write\n"); 221 ERR_print_errors_fp(stdout); |
229 goto end; | 222 goto end; |
223 } |
|
230 | 224 |
231 if (!TEST_int_lt(SSL_read(server, junk, sizeof(junk)), 0)) | 225 if (SSL_read(server, junk, sizeof(junk)) >= 0) { 226 printf("Read should have failed with \"bad record mac\"\n"); |
232 goto end; | 227 goto end; |
228 } |
|
233 | 229 |
234 if (!TEST_int_eq(ERR_GET_REASON(ERR_peek_error()), 235 SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC)) | 230 if (ERR_GET_REASON(ERR_peek_error()) != 231 SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC) { 232 ERR_print_errors_fp(stdout); |
236 goto end; | 233 goto end; |
234 } |
|
237 238 testresult = 1; 239 end: 240 SSL_free(server); 241 SSL_free(client); 242 SSL_CTX_free(sctx); 243 SSL_CTX_free(cctx); | 235 236 testresult = 1; 237 end: 238 SSL_free(server); 239 SSL_free(client); 240 SSL_CTX_free(sctx); 241 SSL_CTX_free(cctx); |
242 |
|
244 return testresult; 245} 246 | 243 return testresult; 244} 245 |
247int setup_tests(void) | 246int main(int argc, char *argv[]) |
248{ | 247{ |
249 int n; | 248 BIO *err = NULL; 249 int testresult = 1; |
250 | 250 |
251 if (!TEST_ptr(cert = test_get_argument(0)) 252 || !TEST_ptr(privkey = test_get_argument(1))) { 253 TEST_note("Usage error: require cert and private key files"); 254 return 0; | 251 if (argc != 3) { 252 printf("Invalid argument count\n"); 253 return 1; |
255 } 256 | 254 } 255 |
257 n = setup_cipher_list(); 258 if (n > 0) 259 ADD_ALL_TESTS(test_ssl_corrupt, n); 260 return 1; 261} | 256 cert = argv[1]; 257 privkey = argv[2]; |
262 | 258 |
263void cleanup_tests(void) 264{ | 259 err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT); 260 261 CRYPTO_set_mem_debug(1); 262 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); 263 264 ADD_ALL_TESTS(test_ssl_corrupt, setup_cipher_list()); 265 266 testresult = run_tests(argv[0]); 267 |
265 bio_f_tls_corrupt_filter_free(); | 268 bio_f_tls_corrupt_filter_free(); |
269 |
|
266 OPENSSL_free(cipher_list); | 270 OPENSSL_free(cipher_list); |
271 272#ifndef OPENSSL_NO_CRYPTO_MDEBUG 273 if (CRYPTO_mem_leaks(err) <= 0) 274 testresult = 1; 275#endif 276 BIO_free(err); 277 278 if (!testresult) 279 printf("PASS\n"); 280 281 return testresult; |
|
267} | 282} |