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