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