Home | History | Annotate | Line # | Download | only in test
      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