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