1*e7be843bSPierre Pronchery /*
2*e7be843bSPierre Pronchery * Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved.
3*e7be843bSPierre Pronchery *
4*e7be843bSPierre Pronchery * Licensed under the Apache License 2.0 (the "License");
5*e7be843bSPierre Pronchery * you may not use this file except in compliance with the License.
6*e7be843bSPierre Pronchery * You may obtain a copy of the License at
7*e7be843bSPierre Pronchery * https://www.openssl.org/source/license.html
8*e7be843bSPierre Pronchery * or in the file LICENSE in the source distribution.
9*e7be843bSPierre Pronchery */
10*e7be843bSPierre Pronchery
11*e7be843bSPierre Pronchery #include <time.h>
12*e7be843bSPierre Pronchery #include <openssl/rand.h>
13*e7be843bSPierre Pronchery #include <openssl/ssl.h>
14*e7be843bSPierre Pronchery #include <openssl/rsa.h>
15*e7be843bSPierre Pronchery #include <openssl/dsa.h>
16*e7be843bSPierre Pronchery #include <openssl/ec.h>
17*e7be843bSPierre Pronchery #include <openssl/dh.h>
18*e7be843bSPierre Pronchery #include <openssl/err.h>
19*e7be843bSPierre Pronchery #include "fuzzer.h"
20*e7be843bSPierre Pronchery
21*e7be843bSPierre Pronchery /* unused, to avoid warning. */
22*e7be843bSPierre Pronchery static int idx;
23*e7be843bSPierre Pronchery
24*e7be843bSPierre Pronchery #define FUZZTIME 1485898104
25*e7be843bSPierre Pronchery
26*e7be843bSPierre Pronchery #define TIME_IMPL(t) { if (t != NULL) *t = FUZZTIME; return FUZZTIME; }
27*e7be843bSPierre Pronchery
28*e7be843bSPierre Pronchery /*
29*e7be843bSPierre Pronchery * This might not work in all cases (and definitely not on Windows
30*e7be843bSPierre Pronchery * because of the way linkers are) and callees can still get the
31*e7be843bSPierre Pronchery * current time instead of the fixed time. This will just result
32*e7be843bSPierre Pronchery * in things not being fully reproducible and have a slightly
33*e7be843bSPierre Pronchery * different coverage.
34*e7be843bSPierre Pronchery */
35*e7be843bSPierre Pronchery #if !defined(_WIN32)
time(time_t * t)36*e7be843bSPierre Pronchery time_t time(time_t *t) TIME_IMPL(t)
37*e7be843bSPierre Pronchery #endif
38*e7be843bSPierre Pronchery
39*e7be843bSPierre Pronchery int FuzzerInitialize(int *argc, char ***argv)
40*e7be843bSPierre Pronchery {
41*e7be843bSPierre Pronchery STACK_OF(SSL_COMP) *comp_methods;
42*e7be843bSPierre Pronchery
43*e7be843bSPierre Pronchery FuzzerSetRand();
44*e7be843bSPierre Pronchery OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS | OPENSSL_INIT_ASYNC, NULL);
45*e7be843bSPierre Pronchery OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
46*e7be843bSPierre Pronchery ERR_clear_error();
47*e7be843bSPierre Pronchery CRYPTO_free_ex_index(0, -1);
48*e7be843bSPierre Pronchery idx = SSL_get_ex_data_X509_STORE_CTX_idx();
49*e7be843bSPierre Pronchery comp_methods = SSL_COMP_get_compression_methods();
50*e7be843bSPierre Pronchery if (comp_methods != NULL)
51*e7be843bSPierre Pronchery sk_SSL_COMP_sort(comp_methods);
52*e7be843bSPierre Pronchery
53*e7be843bSPierre Pronchery return 1;
54*e7be843bSPierre Pronchery }
55*e7be843bSPierre Pronchery
FuzzerTestOneInput(const uint8_t * buf,size_t len)56*e7be843bSPierre Pronchery int FuzzerTestOneInput(const uint8_t *buf, size_t len)
57*e7be843bSPierre Pronchery {
58*e7be843bSPierre Pronchery SSL *client = NULL;
59*e7be843bSPierre Pronchery BIO *in;
60*e7be843bSPierre Pronchery BIO *out;
61*e7be843bSPierre Pronchery SSL_CTX *ctx;
62*e7be843bSPierre Pronchery
63*e7be843bSPierre Pronchery if (len == 0)
64*e7be843bSPierre Pronchery return 0;
65*e7be843bSPierre Pronchery
66*e7be843bSPierre Pronchery /* This only fuzzes the initial flow from the client so far. */
67*e7be843bSPierre Pronchery ctx = SSL_CTX_new(DTLS_client_method());
68*e7be843bSPierre Pronchery if (ctx == NULL)
69*e7be843bSPierre Pronchery goto end;
70*e7be843bSPierre Pronchery
71*e7be843bSPierre Pronchery client = SSL_new(ctx);
72*e7be843bSPierre Pronchery if (client == NULL)
73*e7be843bSPierre Pronchery goto end;
74*e7be843bSPierre Pronchery OPENSSL_assert(SSL_set_min_proto_version(client, 0) == 1);
75*e7be843bSPierre Pronchery OPENSSL_assert(SSL_set_cipher_list(client, "ALL:eNULL:@SECLEVEL=0") == 1);
76*e7be843bSPierre Pronchery SSL_set_tlsext_host_name(client, "localhost");
77*e7be843bSPierre Pronchery in = BIO_new(BIO_s_mem());
78*e7be843bSPierre Pronchery if (in == NULL)
79*e7be843bSPierre Pronchery goto end;
80*e7be843bSPierre Pronchery out = BIO_new(BIO_s_mem());
81*e7be843bSPierre Pronchery if (out == NULL) {
82*e7be843bSPierre Pronchery BIO_free(in);
83*e7be843bSPierre Pronchery goto end;
84*e7be843bSPierre Pronchery }
85*e7be843bSPierre Pronchery SSL_set_bio(client, in, out);
86*e7be843bSPierre Pronchery SSL_set_connect_state(client);
87*e7be843bSPierre Pronchery OPENSSL_assert((size_t)BIO_write(in, buf, len) == len);
88*e7be843bSPierre Pronchery if (SSL_do_handshake(client) == 1) {
89*e7be843bSPierre Pronchery /* Keep reading application data until error or EOF. */
90*e7be843bSPierre Pronchery uint8_t tmp[1024];
91*e7be843bSPierre Pronchery for (;;) {
92*e7be843bSPierre Pronchery if (SSL_read(client, tmp, sizeof(tmp)) <= 0) {
93*e7be843bSPierre Pronchery break;
94*e7be843bSPierre Pronchery }
95*e7be843bSPierre Pronchery }
96*e7be843bSPierre Pronchery }
97*e7be843bSPierre Pronchery end:
98*e7be843bSPierre Pronchery SSL_free(client);
99*e7be843bSPierre Pronchery ERR_clear_error();
100*e7be843bSPierre Pronchery SSL_CTX_free(ctx);
101*e7be843bSPierre Pronchery
102*e7be843bSPierre Pronchery return 0;
103*e7be843bSPierre Pronchery }
104*e7be843bSPierre Pronchery
FuzzerCleanup(void)105*e7be843bSPierre Pronchery void FuzzerCleanup(void)
106*e7be843bSPierre Pronchery {
107*e7be843bSPierre Pronchery FuzzerClearRand();
108*e7be843bSPierre Pronchery }
109