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