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