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