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