• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
get_sni_from_client_hello(BIO * bio,char ** sni)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 
client_setup_sni_before_state(void)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 
client_setup_sni_after_state(void)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 
server_setup_sni(void)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 
test_servername(int test)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 
setup_tests(void)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