blob: 5e802b38f60824d82d4d4134af2eb37b88caaaaf [file] [log] [blame]
Adam Langleyb70cd922016-04-25 10:48:19 -07001/* Copyright (c) 2016, 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
Adam Langley9a4beb82015-11-09 13:57:26 -080015#include <assert.h>
David Benjaminfef78b02017-03-29 16:12:47 -050016#include <stdlib.h>
Adam Langley9a4beb82015-11-09 13:57:26 -080017
David Benjamin25f44222016-09-22 10:14:35 -040018#include <openssl/bio.h>
David Benjamin0fde2eb2017-06-30 19:11:22 -040019#include <openssl/bytestring.h>
David Benjamin4c0e6c62016-10-13 19:03:17 -040020#include <openssl/err.h>
David Benjamin25f44222016-09-22 10:14:35 -040021#include <openssl/evp.h>
David Benjaminbc5b2a22016-03-01 22:57:32 -050022#include <openssl/rand.h>
David Benjamin25f44222016-09-22 10:14:35 -040023#include <openssl/rsa.h>
Adam Langley9a4beb82015-11-09 13:57:26 -080024#include <openssl/ssl.h>
David Benjamin25f44222016-09-22 10:14:35 -040025#include <openssl/x509.h>
Adam Langley9a4beb82015-11-09 13:57:26 -080026
David Benjamin0fde2eb2017-06-30 19:11:22 -040027#include "../ssl/test/fuzzer.h"
Adam Langley9a4beb82015-11-09 13:57:26 -080028
Adam Langley9a4beb82015-11-09 13:57:26 -080029
David Benjamin25f44222016-09-22 10:14:35 -040030static const uint8_t kOCSPResponse[] = {0x01, 0x02, 0x03, 0x04};
David Benjaminfef78b02017-03-29 16:12:47 -050031static const uint8_t kSCT[] = {0x00, 0x06, 0x00, 0x04, 0x05, 0x06, 0x07, 0x08};
David Benjamin25f44222016-09-22 10:14:35 -040032
33static int ALPNSelectCallback(SSL *ssl, const uint8_t **out, uint8_t *out_len,
34 const uint8_t *in, unsigned in_len, void *arg) {
35 static const uint8_t kProtocol[] = {'a', 'a'};
36 *out = kProtocol;
37 *out_len = sizeof(kProtocol);
38 return SSL_TLSEXT_ERR_OK;
39}
40
41static int NPNAdvertiseCallback(SSL *ssl, const uint8_t **out,
42 unsigned *out_len, void *arg) {
43 static const uint8_t kProtocols[] = {
44 0x01, 'a', 0x02, 'a', 'a', 0x03, 'a', 'a', 'a',
45 };
46 *out = kProtocols;
47 *out_len = sizeof(kProtocols);
48 return SSL_TLSEXT_ERR_OK;
49}
50
Adam Langley9a4beb82015-11-09 13:57:26 -080051struct GlobalState {
52 GlobalState()
53 : ctx(SSL_CTX_new(SSLv23_method())) {
David Benjamin0fde2eb2017-06-30 19:11:22 -040054 debug = getenv("BORINGSSL_FUZZER_DEBUG") != nullptr;
55
Adam Langley9a4beb82015-11-09 13:57:26 -080056 const uint8_t *bufp = kRSAPrivateKeyDER;
57 RSA *privkey = d2i_RSAPrivateKey(NULL, &bufp, sizeof(kRSAPrivateKeyDER));
58 assert(privkey != nullptr);
59
60 EVP_PKEY *pkey = EVP_PKEY_new();
61 EVP_PKEY_assign_RSA(pkey, privkey);
62
63 SSL_CTX_use_PrivateKey(ctx, pkey);
64 EVP_PKEY_free(pkey);
65
66 bufp = kCertificateDER;
67 X509 *cert = d2i_X509(NULL, &bufp, sizeof(kCertificateDER));
68 assert(cert != nullptr);
69
70 SSL_CTX_use_certificate(ctx, cert);
71 X509_free(cert);
David Benjamin25f44222016-09-22 10:14:35 -040072
David Benjaminfef78b02017-03-29 16:12:47 -050073 if (!SSL_CTX_set_ocsp_response(ctx, kOCSPResponse, sizeof(kOCSPResponse)) ||
74 !SSL_CTX_set_signed_cert_timestamp_list(ctx, kSCT, sizeof(kSCT))) {
75 abort();
76 }
David Benjamin25f44222016-09-22 10:14:35 -040077
78 SSL_CTX_set_alpn_select_cb(ctx, ALPNSelectCallback, nullptr);
79 SSL_CTX_set_next_protos_advertised_cb(ctx, NPNAdvertiseCallback, nullptr);
Steven Valdeza5076172017-03-29 17:09:09 -040080 SSL_CTX_set_early_data_enabled(ctx, 1);
David Benjamin0fde2eb2017-06-30 19:11:22 -040081
82 // If accepting client certificates, allow any certificate.
83 SSL_CTX_set_cert_verify_callback(
84 ctx, [](X509_STORE_CTX *store_ctx, void *arg) -> int { return 1; },
85 nullptr);
Adam Langley9a4beb82015-11-09 13:57:26 -080086 }
87
88 ~GlobalState() {
89 SSL_CTX_free(ctx);
90 }
91
David Benjamin0fde2eb2017-06-30 19:11:22 -040092 bool debug;
Adam Langley9a4beb82015-11-09 13:57:26 -080093 SSL_CTX *const ctx;
94};
95
96static GlobalState g_state;
97
David Benjamin0939f802016-10-12 10:35:18 -040098extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
David Benjaminbc5b2a22016-03-01 22:57:32 -050099 RAND_reset_for_fuzzing();
100
David Benjamin0fde2eb2017-06-30 19:11:22 -0400101 CBS cbs;
102 CBS_init(&cbs, buf, len);
103 bssl::UniquePtr<SSL> server = SetupTest(&cbs, g_state.ctx, true);
104 if (!server) {
105 if (g_state.debug) {
106 fprintf(stderr, "Error parsing parameters.\n");
107 }
108 return 0;
109 }
David Benjamin25f44222016-09-22 10:14:35 -0400110
David Benjamin0fde2eb2017-06-30 19:11:22 -0400111 SSL_set_max_proto_version(server.get(), TLS1_3_VERSION);
David Benjamin09114ae2017-07-01 00:39:14 -0400112 SSL_set_min_proto_version(server.get(), SSL3_VERSION);
David Benjamin0fde2eb2017-06-30 19:11:22 -0400113 SSL_set_tls_channel_id_enabled(server.get(), 1);
David Benjamin25f44222016-09-22 10:14:35 -0400114
115 // Enable ciphers that are off by default.
David Benjamin0fde2eb2017-06-30 19:11:22 -0400116 SSL_set_strict_cipher_list(server.get(), "ALL:NULL-SHA");
David Benjamin25f44222016-09-22 10:14:35 -0400117
David Benjamin0fde2eb2017-06-30 19:11:22 -0400118 BIO *in = BIO_new(BIO_s_mem());
119 BIO *out = BIO_new(BIO_s_mem());
120 SSL_set_bio(server.get(), in, out); // Takes ownership of |in| and |out|.
121
122 BIO_write(in, CBS_data(&cbs), CBS_len(&cbs));
123 if (SSL_do_handshake(server.get()) == 1) {
David Benjamind86c8a42016-03-02 14:53:11 -0500124 // Keep reading application data until error or EOF.
125 uint8_t tmp[1024];
126 for (;;) {
David Benjamin0fde2eb2017-06-30 19:11:22 -0400127 if (SSL_read(server.get(), tmp, sizeof(tmp)) <= 0) {
David Benjamind86c8a42016-03-02 14:53:11 -0500128 break;
129 }
130 }
David Benjamin0fde2eb2017-06-30 19:11:22 -0400131 } else if (g_state.debug) {
132 fprintf(stderr, "Handshake failed.\n");
David Benjamind86c8a42016-03-02 14:53:11 -0500133 }
Adam Langley9a4beb82015-11-09 13:57:26 -0800134
David Benjamin0fde2eb2017-06-30 19:11:22 -0400135 if (g_state.debug) {
136 ERR_print_errors_fp(stderr);
137 }
David Benjamin4c0e6c62016-10-13 19:03:17 -0400138 ERR_clear_error();
Adam Langley9a4beb82015-11-09 13:57:26 -0800139 return 0;
140}