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