1 /* 2 * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. 3 * Copyright 2017 BaishanCloud. All rights reserved. 4 * 5 * Licensed under the Apache License 2.0 (the "License"). You may not use 6 * this file except in compliance with the License. You can obtain a copy 7 * in the file LICENSE in the source distribution or at 8 * https://www.openssl.org/source/license.html 9 */ 10 11 #include <string.h> 12 13 #include <openssl/opensslconf.h> 14 #include <openssl/bio.h> 15 #include <openssl/crypto.h> 16 #include <openssl/evp.h> 17 #include <openssl/ssl.h> 18 #include <openssl/err.h> 19 #include <time.h> 20 21 #include "internal/packet.h" 22 23 #include "testutil.h" 24 #include "internal/nelem.h" 25 #include "helpers/ssltestlib.h" 26 27 #define CLIENT_VERSION_LEN 2 28 29 static const char *host = "dummy-host"; 30 31 static char *cert = NULL; 32 static char *privkey = NULL; 33 34 #if defined(OPENSSL_NO_TLS1_3) || (defined(OPENSSL_NO_EC) && defined(OPENSSL_NO_DH)) 35 static int maxversion = TLS1_2_VERSION; 36 #else 37 static int maxversion = 0; 38 #endif 39 40 static int get_sni_from_client_hello(BIO *bio, char **sni) 41 { 42 long len; 43 unsigned char *data; 44 PACKET pkt, pkt2, pkt3, pkt4, pkt5; 45 unsigned int servname_type = 0, type = 0; 46 int ret = 0; 47 48 memset(&pkt, 0, sizeof(pkt)); 49 memset(&pkt2, 0, sizeof(pkt2)); 50 memset(&pkt3, 0, sizeof(pkt3)); 51 memset(&pkt4, 0, sizeof(pkt4)); 52 memset(&pkt5, 0, sizeof(pkt5)); 53 54 if (!TEST_long_ge(len = BIO_get_mem_data(bio, (char **)&data), 0) 55 || !TEST_true(PACKET_buf_init(&pkt, data, len)) 56 /* Skip the record header */ 57 || !PACKET_forward(&pkt, SSL3_RT_HEADER_LENGTH) 58 /* Skip the handshake message header */ 59 || !TEST_true(PACKET_forward(&pkt, SSL3_HM_HEADER_LENGTH)) 60 /* Skip client version and random */ 61 || !TEST_true(PACKET_forward(&pkt, CLIENT_VERSION_LEN + SSL3_RANDOM_SIZE)) 62 /* Skip session id */ 63 || !TEST_true(PACKET_get_length_prefixed_1(&pkt, &pkt2)) 64 /* Skip ciphers */ 65 || !TEST_true(PACKET_get_length_prefixed_2(&pkt, &pkt2)) 66 /* Skip compression */ 67 || !TEST_true(PACKET_get_length_prefixed_1(&pkt, &pkt2)) 68 /* Extensions len */ 69 || !TEST_true(PACKET_as_length_prefixed_2(&pkt, &pkt2))) 70 goto end; 71 72 /* Loop through all extensions for SNI */ 73 while (PACKET_remaining(&pkt2)) { 74 if (!TEST_true(PACKET_get_net_2(&pkt2, &type)) 75 || !TEST_true(PACKET_get_length_prefixed_2(&pkt2, &pkt3))) 76 goto end; 77 if (type == TLSEXT_TYPE_server_name) { 78 if (!TEST_true(PACKET_get_length_prefixed_2(&pkt3, &pkt4)) 79 || !TEST_uint_ne(PACKET_remaining(&pkt4), 0) 80 || !TEST_true(PACKET_get_1(&pkt4, &servname_type)) 81 || !TEST_uint_eq(servname_type, TLSEXT_NAMETYPE_host_name) 82 || !TEST_true(PACKET_get_length_prefixed_2(&pkt4, &pkt5)) 83 || !TEST_uint_le(PACKET_remaining(&pkt5), TLSEXT_MAXLEN_host_name) 84 || !TEST_false(PACKET_contains_zero_byte(&pkt5)) 85 || !TEST_true(PACKET_strndup(&pkt5, sni))) 86 goto end; 87 ret = 1; 88 goto end; 89 } 90 } 91 end: 92 return ret; 93 } 94 95 static int client_setup_sni_before_state(void) 96 { 97 SSL_CTX *ctx; 98 SSL *con = NULL; 99 BIO *rbio; 100 BIO *wbio; 101 char *hostname = NULL; 102 int ret = 0; 103 104 /* use TLS_method to blur 'side' */ 105 ctx = SSL_CTX_new(TLS_method()); 106 if (!TEST_ptr(ctx)) 107 goto end; 108 109 if (maxversion > 0 110 && !TEST_true(SSL_CTX_set_max_proto_version(ctx, maxversion))) 111 goto end; 112 113 con = SSL_new(ctx); 114 if (!TEST_ptr(con)) 115 goto end; 116 117 /* set SNI before 'client side' is set */ 118 SSL_set_tlsext_host_name(con, host); 119 120 rbio = BIO_new(BIO_s_mem()); 121 wbio = BIO_new(BIO_s_mem()); 122 if (!TEST_ptr(rbio) || !TEST_ptr(wbio)) { 123 BIO_free(rbio); 124 BIO_free(wbio); 125 goto end; 126 } 127 128 SSL_set_bio(con, rbio, wbio); 129 130 if (!TEST_int_le(SSL_connect(con), 0)) 131 /* This shouldn't succeed because we don't have a server! */ 132 goto end; 133 if (!TEST_true(get_sni_from_client_hello(wbio, &hostname))) 134 /* no SNI in client hello */ 135 goto end; 136 if (!TEST_str_eq(hostname, host)) 137 /* incorrect SNI value */ 138 goto end; 139 ret = 1; 140 end: 141 OPENSSL_free(hostname); 142 SSL_free(con); 143 SSL_CTX_free(ctx); 144 return ret; 145 } 146 147 static int client_setup_sni_after_state(void) 148 { 149 SSL_CTX *ctx; 150 SSL *con = NULL; 151 BIO *rbio; 152 BIO *wbio; 153 char *hostname = NULL; 154 int ret = 0; 155 156 /* use TLS_method to blur 'side' */ 157 ctx = SSL_CTX_new(TLS_method()); 158 if (!TEST_ptr(ctx)) 159 goto end; 160 161 if (maxversion > 0 162 && !TEST_true(SSL_CTX_set_max_proto_version(ctx, maxversion))) 163 goto end; 164 165 con = SSL_new(ctx); 166 if (!TEST_ptr(con)) 167 goto end; 168 169 rbio = BIO_new(BIO_s_mem()); 170 wbio = BIO_new(BIO_s_mem()); 171 if (!TEST_ptr(rbio) || !TEST_ptr(wbio)) { 172 BIO_free(rbio); 173 BIO_free(wbio); 174 goto end; 175 } 176 177 SSL_set_bio(con, rbio, wbio); 178 SSL_set_connect_state(con); 179 180 /* set SNI after 'client side' is set */ 181 SSL_set_tlsext_host_name(con, host); 182 183 if (!TEST_int_le(SSL_connect(con), 0)) 184 /* This shouldn't succeed because we don't have a server! */ 185 goto end; 186 if (!TEST_true(get_sni_from_client_hello(wbio, &hostname))) 187 /* no SNI in client hello */ 188 goto end; 189 if (!TEST_str_eq(hostname, host)) 190 /* incorrect SNI value */ 191 goto end; 192 ret = 1; 193 end: 194 OPENSSL_free(hostname); 195 SSL_free(con); 196 SSL_CTX_free(ctx); 197 return ret; 198 } 199 200 static int server_setup_sni(void) 201 { 202 SSL_CTX *cctx = NULL, *sctx = NULL; 203 SSL *clientssl = NULL, *serverssl = NULL; 204 int testresult = 0; 205 206 if (!TEST_true(create_ssl_ctx_pair(NULL, TLS_server_method(), 207 TLS_client_method(), 208 TLS1_VERSION, 0, 209 &sctx, &cctx, cert, privkey)) 210 || !TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, 211 NULL, NULL))) 212 goto end; 213 214 /* set SNI at server side */ 215 SSL_set_tlsext_host_name(serverssl, host); 216 217 if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) 218 goto end; 219 220 if (!TEST_ptr_null(SSL_get_servername(serverssl, 221 TLSEXT_NAMETYPE_host_name))) { 222 /* SNI should have been cleared during handshake */ 223 goto end; 224 } 225 226 testresult = 1; 227 end: 228 SSL_free(serverssl); 229 SSL_free(clientssl); 230 SSL_CTX_free(sctx); 231 SSL_CTX_free(cctx); 232 233 return testresult; 234 } 235 236 typedef int (*sni_test_fn)(void); 237 238 static sni_test_fn sni_test_fns[3] = { 239 client_setup_sni_before_state, 240 client_setup_sni_after_state, 241 server_setup_sni 242 }; 243 244 static int test_servername(int test) 245 { 246 /* 247 * For each test set up an SSL_CTX and SSL and see 248 * what SNI behaves. 249 */ 250 return sni_test_fns[test](); 251 } 252 253 int setup_tests(void) 254 { 255 if (!test_skip_common_options()) { 256 TEST_error("Error parsing test options\n"); 257 return 0; 258 } 259 260 if (!TEST_ptr(cert = test_get_argument(0)) 261 || !TEST_ptr(privkey = test_get_argument(1))) 262 return 0; 263 264 ADD_ALL_TESTS(test_servername, OSSL_NELEM(sni_test_fns)); 265 return 1; 266 } 267