1/* Copyright (c) 2014, Google Inc.
2 *
3 * Permission to use, copy, modify, and/or distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
15#include <openssl/base.h>
16
17#if !defined(OPENSSL_WINDOWS)
18#include <arpa/inet.h>
19#include <netinet/in.h>
20#include <signal.h>
21#include <sys/socket.h>
22#include <unistd.h>
23#endif
24
25#include <sys/types.h>
26
27#include <openssl/bio.h>
28#include <openssl/bytestring.h>
29#include <openssl/ssl.h>
30
31#include "async_bio.h"
32#include "packeted_bio.h"
33#include "test_config.h"
34
35static int usage(const char *program) {
36  fprintf(stderr, "Usage: %s [flags...]\n",
37          program);
38  return 1;
39}
40
41static int g_ex_data_index = 0;
42
43static void SetConfigPtr(SSL *ssl, const TestConfig *config) {
44  SSL_set_ex_data(ssl, g_ex_data_index, (void *)config);
45}
46
47static const TestConfig *GetConfigPtr(SSL *ssl) {
48  return (const TestConfig *)SSL_get_ex_data(ssl, g_ex_data_index);
49}
50
51static EVP_PKEY *LoadPrivateKey(const std::string &file) {
52  BIO *bio = BIO_new(BIO_s_file());
53  if (bio == NULL) {
54    return NULL;
55  }
56  if (!BIO_read_filename(bio, file.c_str())) {
57    BIO_free(bio);
58    return NULL;
59  }
60  EVP_PKEY *pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
61  BIO_free(bio);
62  return pkey;
63}
64
65static int early_callback_called = 0;
66
67static int select_certificate_callback(const struct ssl_early_callback_ctx *ctx) {
68  early_callback_called = 1;
69
70  const TestConfig *config = GetConfigPtr(ctx->ssl);
71
72  if (config->expected_server_name.empty()) {
73    return 1;
74  }
75
76  const uint8_t *extension_data;
77  size_t extension_len;
78  CBS extension, server_name_list, host_name;
79  uint8_t name_type;
80
81  if (!SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_server_name,
82                                            &extension_data,
83                                            &extension_len)) {
84    fprintf(stderr, "Could not find server_name extension.\n");
85    return -1;
86  }
87
88  CBS_init(&extension, extension_data, extension_len);
89  if (!CBS_get_u16_length_prefixed(&extension, &server_name_list) ||
90      CBS_len(&extension) != 0 ||
91      !CBS_get_u8(&server_name_list, &name_type) ||
92      name_type != TLSEXT_NAMETYPE_host_name ||
93      !CBS_get_u16_length_prefixed(&server_name_list, &host_name) ||
94      CBS_len(&server_name_list) != 0) {
95    fprintf(stderr, "Could not decode server_name extension.\n");
96    return -1;
97  }
98
99  if (!CBS_mem_equal(&host_name,
100                     (const uint8_t*)config->expected_server_name.data(),
101                     config->expected_server_name.size())) {
102    fprintf(stderr, "Server name mismatch.\n");
103  }
104
105  return 1;
106}
107
108static int skip_verify(int preverify_ok, X509_STORE_CTX *store_ctx) {
109  return 1;
110}
111
112static int next_protos_advertised_callback(SSL *ssl,
113                                           const uint8_t **out,
114                                           unsigned int *out_len,
115                                           void *arg) {
116  const TestConfig *config = GetConfigPtr(ssl);
117  if (config->advertise_npn.empty())
118    return SSL_TLSEXT_ERR_NOACK;
119
120  // TODO(davidben): Support passing byte strings with NULs to the
121  // test shim.
122  *out = (const uint8_t*)config->advertise_npn.data();
123  *out_len = config->advertise_npn.size();
124  return SSL_TLSEXT_ERR_OK;
125}
126
127static int next_proto_select_callback(SSL* ssl,
128                                      uint8_t** out,
129                                      uint8_t* outlen,
130                                      const uint8_t* in,
131                                      unsigned inlen,
132                                      void* arg) {
133  const TestConfig *config = GetConfigPtr(ssl);
134  if (config->select_next_proto.empty())
135    return SSL_TLSEXT_ERR_NOACK;
136
137  *out = (uint8_t*)config->select_next_proto.data();
138  *outlen = config->select_next_proto.size();
139  return SSL_TLSEXT_ERR_OK;
140}
141
142static int alpn_select_callback(SSL* ssl,
143                                const uint8_t** out,
144                                uint8_t* outlen,
145                                const uint8_t* in,
146                                unsigned inlen,
147                                void* arg) {
148  const TestConfig *config = GetConfigPtr(ssl);
149  if (config->select_alpn.empty())
150    return SSL_TLSEXT_ERR_NOACK;
151
152  if (!config->expected_advertised_alpn.empty() &&
153      (config->expected_advertised_alpn.size() != inlen ||
154       memcmp(config->expected_advertised_alpn.data(),
155              in, inlen) != 0)) {
156    fprintf(stderr, "bad ALPN select callback inputs\n");
157    exit(1);
158  }
159
160  *out = (const uint8_t*)config->select_alpn.data();
161  *outlen = config->select_alpn.size();
162  return SSL_TLSEXT_ERR_OK;
163}
164
165static int cookie_generate_callback(SSL *ssl, uint8_t *cookie, size_t *cookie_len) {
166  *cookie_len = 32;
167  memset(cookie, 42, *cookie_len);
168  return 1;
169}
170
171static int cookie_verify_callback(SSL *ssl, const uint8_t *cookie, size_t cookie_len) {
172  if (cookie_len != 32) {
173    fprintf(stderr, "Cookie length mismatch.\n");
174    return 0;
175  }
176  for (size_t i = 0; i < cookie_len; i++) {
177    if (cookie[i] != 42) {
178      fprintf(stderr, "Cookie mismatch.\n");
179      return 0;
180    }
181  }
182  return 1;
183}
184
185static SSL_CTX *setup_ctx(const TestConfig *config) {
186  SSL_CTX *ssl_ctx = NULL;
187  DH *dh = NULL;
188
189  const SSL_METHOD *method;
190  if (config->is_dtls) {
191    // TODO(davidben): Get DTLS 1.2 working and test the version negotiation
192    // codepath. This doesn't currently work because
193    // - Session resumption is broken: https://crbug.com/403378
194    // - DTLS hasn't been updated for EVP_AEAD.
195    if (config->is_server) {
196      method = DTLSv1_server_method();
197    } else {
198      method = DTLSv1_client_method();
199    }
200  } else {
201    if (config->is_server) {
202      method = SSLv23_server_method();
203    } else {
204      method = SSLv23_client_method();
205    }
206  }
207  ssl_ctx = SSL_CTX_new(method);
208  if (ssl_ctx == NULL) {
209    goto err;
210  }
211
212  if (config->is_dtls) {
213    // DTLS needs read-ahead to function on a datagram BIO.
214    //
215    // TODO(davidben): this should not be necessary. DTLS code should only
216    // expect a datagram BIO.
217    SSL_CTX_set_read_ahead(ssl_ctx, 1);
218  }
219
220  if (!SSL_CTX_set_ecdh_auto(ssl_ctx, 1)) {
221    goto err;
222  }
223
224  if (!SSL_CTX_set_cipher_list(ssl_ctx, "ALL")) {
225    goto err;
226  }
227
228  dh = DH_get_2048_256(NULL);
229  if (!SSL_CTX_set_tmp_dh(ssl_ctx, dh)) {
230    goto err;
231  }
232
233  SSL_CTX_set_session_cache_mode(ssl_ctx, SSL_SESS_CACHE_BOTH);
234
235  ssl_ctx->select_certificate_cb = select_certificate_callback;
236
237  SSL_CTX_set_next_protos_advertised_cb(
238      ssl_ctx, next_protos_advertised_callback, NULL);
239  if (!config->select_next_proto.empty()) {
240    SSL_CTX_set_next_proto_select_cb(ssl_ctx, next_proto_select_callback, NULL);
241  }
242
243  if (!config->select_alpn.empty()) {
244    SSL_CTX_set_alpn_select_cb(ssl_ctx, alpn_select_callback, NULL);
245  }
246
247  SSL_CTX_set_cookie_generate_cb(ssl_ctx, cookie_generate_callback);
248  SSL_CTX_set_cookie_verify_cb(ssl_ctx, cookie_verify_callback);
249
250  ssl_ctx->tlsext_channel_id_enabled_new = 1;
251
252  DH_free(dh);
253  return ssl_ctx;
254
255 err:
256  if (dh != NULL) {
257    DH_free(dh);
258  }
259  if (ssl_ctx != NULL) {
260    SSL_CTX_free(ssl_ctx);
261  }
262  return NULL;
263}
264
265static int retry_async(SSL *ssl, int ret, BIO *bio) {
266  // No error; don't retry.
267  if (ret >= 0) {
268    return 0;
269  }
270  // See if we needed to read or write more. If so, allow one byte through on
271  // the appropriate end to maximally stress the state machine.
272  int err = SSL_get_error(ssl, ret);
273  if (err == SSL_ERROR_WANT_READ) {
274    async_bio_allow_read(bio, 1);
275    return 1;
276  } else if (err == SSL_ERROR_WANT_WRITE) {
277    async_bio_allow_write(bio, 1);
278    return 1;
279  }
280  return 0;
281}
282
283static int do_exchange(SSL_SESSION **out_session,
284                       SSL_CTX *ssl_ctx,
285                       const TestConfig *config,
286                       bool is_resume,
287                       int fd,
288                       SSL_SESSION *session) {
289  early_callback_called = 0;
290
291  SSL *ssl = SSL_new(ssl_ctx);
292  if (ssl == NULL) {
293    BIO_print_errors_fp(stdout);
294    return 1;
295  }
296
297  SetConfigPtr(ssl, config);
298
299  if (config->fallback_scsv) {
300    if (!SSL_enable_fallback_scsv(ssl)) {
301      BIO_print_errors_fp(stdout);
302      return 1;
303    }
304  }
305  if (!config->key_file.empty()) {
306    if (!SSL_use_PrivateKey_file(ssl, config->key_file.c_str(),
307                                 SSL_FILETYPE_PEM)) {
308      BIO_print_errors_fp(stdout);
309      return 1;
310    }
311  }
312  if (!config->cert_file.empty()) {
313    if (!SSL_use_certificate_file(ssl, config->cert_file.c_str(),
314                                  SSL_FILETYPE_PEM)) {
315      BIO_print_errors_fp(stdout);
316      return 1;
317    }
318  }
319  if (config->require_any_client_certificate) {
320    SSL_set_verify(ssl, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
321                   skip_verify);
322  }
323  if (config->false_start) {
324    SSL_set_mode(ssl, SSL_MODE_HANDSHAKE_CUTTHROUGH);
325  }
326  if (config->cbc_record_splitting) {
327    SSL_set_mode(ssl, SSL_MODE_CBC_RECORD_SPLITTING);
328  }
329  if (config->partial_write) {
330    SSL_set_mode(ssl, SSL_MODE_ENABLE_PARTIAL_WRITE);
331  }
332  if (config->no_tls12) {
333    SSL_set_options(ssl, SSL_OP_NO_TLSv1_2);
334  }
335  if (config->no_tls11) {
336    SSL_set_options(ssl, SSL_OP_NO_TLSv1_1);
337  }
338  if (config->no_tls1) {
339    SSL_set_options(ssl, SSL_OP_NO_TLSv1);
340  }
341  if (config->no_ssl3) {
342    SSL_set_options(ssl, SSL_OP_NO_SSLv3);
343  }
344  if (config->cookie_exchange) {
345    SSL_set_options(ssl, SSL_OP_COOKIE_EXCHANGE);
346  }
347  if (config->tls_d5_bug) {
348    SSL_set_options(ssl, SSL_OP_TLS_D5_BUG);
349  }
350  if (!config->expected_channel_id.empty()) {
351    SSL_enable_tls_channel_id(ssl);
352  }
353  if (!config->send_channel_id.empty()) {
354    EVP_PKEY *pkey = LoadPrivateKey(config->send_channel_id);
355    if (pkey == NULL) {
356      BIO_print_errors_fp(stdout);
357      return 1;
358    }
359    SSL_enable_tls_channel_id(ssl);
360    if (!SSL_set1_tls_channel_id(ssl, pkey)) {
361      EVP_PKEY_free(pkey);
362      BIO_print_errors_fp(stdout);
363      return 1;
364    }
365    EVP_PKEY_free(pkey);
366  }
367  if (!config->host_name.empty()) {
368    SSL_set_tlsext_host_name(ssl, config->host_name.c_str());
369  }
370  if (!config->advertise_alpn.empty()) {
371    SSL_set_alpn_protos(ssl, (const uint8_t *)config->advertise_alpn.data(),
372                        config->advertise_alpn.size());
373  }
374
375  BIO *bio = BIO_new_fd(fd, 1 /* take ownership */);
376  if (bio == NULL) {
377    BIO_print_errors_fp(stdout);
378    return 1;
379  }
380  if (config->is_dtls) {
381    BIO *packeted = packeted_bio_create();
382    BIO_push(packeted, bio);
383    bio = packeted;
384  }
385  if (config->async) {
386    BIO *async =
387        config->is_dtls ? async_bio_create_datagram() : async_bio_create();
388    BIO_push(async, bio);
389    bio = async;
390  }
391  SSL_set_bio(ssl, bio, bio);
392
393  if (session != NULL) {
394    if (SSL_set_session(ssl, session) != 1) {
395      fprintf(stderr, "failed to set session\n");
396      return 2;
397    }
398  }
399
400  int ret;
401  do {
402    if (config->is_server) {
403      ret = SSL_accept(ssl);
404    } else {
405      ret = SSL_connect(ssl);
406    }
407  } while (config->async && retry_async(ssl, ret, bio));
408  if (ret != 1) {
409    SSL_free(ssl);
410    BIO_print_errors_fp(stdout);
411    return 2;
412  }
413
414  if (is_resume && (SSL_session_reused(ssl) == config->expect_session_miss)) {
415    fprintf(stderr, "session was%s reused\n",
416            SSL_session_reused(ssl) ? "" : " not");
417    return 2;
418  }
419
420  if (!config->expected_server_name.empty()) {
421    const char *server_name =
422        SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
423    if (server_name != config->expected_server_name) {
424      fprintf(stderr, "servername mismatch (got %s; want %s)\n",
425              server_name, config->expected_server_name.c_str());
426      return 2;
427    }
428
429    if (!early_callback_called) {
430      fprintf(stderr, "early callback not called\n");
431      return 2;
432    }
433  }
434
435  if (!config->expected_certificate_types.empty()) {
436    uint8_t *certificate_types;
437    int num_certificate_types =
438        SSL_get0_certificate_types(ssl, &certificate_types);
439    if (num_certificate_types !=
440        (int)config->expected_certificate_types.size() ||
441        memcmp(certificate_types,
442               config->expected_certificate_types.data(),
443               num_certificate_types) != 0) {
444      fprintf(stderr, "certificate types mismatch\n");
445      return 2;
446    }
447  }
448
449  if (!config->expected_next_proto.empty()) {
450    const uint8_t *next_proto;
451    unsigned next_proto_len;
452    SSL_get0_next_proto_negotiated(ssl, &next_proto, &next_proto_len);
453    if (next_proto_len != config->expected_next_proto.size() ||
454        memcmp(next_proto, config->expected_next_proto.data(),
455               next_proto_len) != 0) {
456      fprintf(stderr, "negotiated next proto mismatch\n");
457      return 2;
458    }
459  }
460
461  if (!config->expected_alpn.empty()) {
462    const uint8_t *alpn_proto;
463    unsigned alpn_proto_len;
464    SSL_get0_alpn_selected(ssl, &alpn_proto, &alpn_proto_len);
465    if (alpn_proto_len != config->expected_alpn.size() ||
466        memcmp(alpn_proto, config->expected_alpn.data(),
467               alpn_proto_len) != 0) {
468      fprintf(stderr, "negotiated alpn proto mismatch\n");
469      return 2;
470    }
471  }
472
473  if (!config->expected_channel_id.empty()) {
474    uint8_t channel_id[64];
475    if (!SSL_get_tls_channel_id(ssl, channel_id, sizeof(channel_id))) {
476      fprintf(stderr, "no channel id negotiated\n");
477      return 2;
478    }
479    if (config->expected_channel_id.size() != 64 ||
480        memcmp(config->expected_channel_id.data(),
481               channel_id, 64) != 0) {
482      fprintf(stderr, "channel id mismatch\n");
483      return 2;
484    }
485  }
486
487  if (config->write_different_record_sizes) {
488    if (config->is_dtls) {
489      fprintf(stderr, "write_different_record_sizes not supported for DTLS\n");
490      return 6;
491    }
492    // This mode writes a number of different record sizes in an attempt to
493    // trip up the CBC record splitting code.
494    uint8_t buf[32769];
495    memset(buf, 0x42, sizeof(buf));
496    static const size_t kRecordSizes[] = {
497        0, 1, 255, 256, 257, 16383, 16384, 16385, 32767, 32768, 32769};
498    for (size_t i = 0; i < sizeof(kRecordSizes) / sizeof(kRecordSizes[0]);
499         i++) {
500      int w;
501      const size_t len = kRecordSizes[i];
502      size_t off = 0;
503
504      if (len > sizeof(buf)) {
505        fprintf(stderr, "Bad kRecordSizes value.\n");
506        return 5;
507      }
508
509      do {
510        w = SSL_write(ssl, buf + off, len - off);
511        if (w > 0) {
512          off += (size_t) w;
513        }
514      } while ((config->async && retry_async(ssl, w, bio)) ||
515               (w > 0 && off < len));
516
517      if (w < 0 || off != len) {
518        SSL_free(ssl);
519        BIO_print_errors_fp(stdout);
520        return 4;
521      }
522    }
523  } else {
524    if (config->shim_writes_first) {
525      int w;
526      do {
527        w = SSL_write(ssl, "hello", 5);
528      } while (config->async && retry_async(ssl, w, bio));
529    }
530    for (;;) {
531      uint8_t buf[512];
532      int n;
533      do {
534        n = SSL_read(ssl, buf, sizeof(buf));
535      } while (config->async && retry_async(ssl, n, bio));
536      if (n < 0) {
537        SSL_free(ssl);
538        BIO_print_errors_fp(stdout);
539        return 3;
540      } else if (n == 0) {
541        break;
542      } else {
543        for (int i = 0; i < n; i++) {
544          buf[i] ^= 0xff;
545        }
546        int w;
547        do {
548          w = SSL_write(ssl, buf, n);
549        } while (config->async && retry_async(ssl, w, bio));
550        if (w != n) {
551          SSL_free(ssl);
552          BIO_print_errors_fp(stdout);
553          return 4;
554        }
555      }
556    }
557  }
558
559  if (out_session) {
560    *out_session = SSL_get1_session(ssl);
561  }
562
563  SSL_shutdown(ssl);
564  SSL_free(ssl);
565  return 0;
566}
567
568int main(int argc, char **argv) {
569#if !defined(OPENSSL_WINDOWS)
570  signal(SIGPIPE, SIG_IGN);
571#endif
572
573  if (!SSL_library_init()) {
574    return 1;
575  }
576  g_ex_data_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
577
578  TestConfig config;
579  if (!ParseConfig(argc - 1, argv + 1, &config)) {
580    return usage(argv[0]);
581  }
582
583  SSL_CTX *ssl_ctx = setup_ctx(&config);
584  if (ssl_ctx == NULL) {
585    BIO_print_errors_fp(stdout);
586    return 1;
587  }
588
589  SSL_SESSION *session = NULL;
590  int ret = do_exchange(&session,
591                        ssl_ctx, &config,
592                        false /* is_resume */,
593                        3 /* fd */, NULL /* session */);
594  if (ret != 0) {
595    goto out;
596  }
597
598  if (config.resume) {
599    ret = do_exchange(NULL,
600                      ssl_ctx, &config,
601                      true /* is_resume */,
602                      4 /* fd */,
603                      config.is_server ? NULL : session);
604    if (ret != 0) {
605      goto out;
606    }
607  }
608
609  ret = 0;
610
611out:
612  SSL_SESSION_free(session);
613  SSL_CTX_free(ssl_ctx);
614  return ret;
615}
616