libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

fuzz_tls.c (97391B)


      1 /*
      2   This file is part of libmicrohttpd
      3   Copyright (C) 2026 Christian Grothoff
      4 
      5   This library is free software; you can redistribute it and/or
      6   modify it under the terms of the GNU Lesser General Public
      7   License as published by the Free Software Foundation; either
      8   version 2.1 of the License, or (at your option) any later version.
      9 
     10   This library is distributed in the hope that it will be useful,
     11   but WITHOUT ANY WARRANTY; without even the implied warranty of
     12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13   Lesser General Public License for more details.
     14 
     15   You should have received a copy of the GNU Lesser General Public
     16   License along with this library.
     17   If not, see <http://www.gnu.org/licenses/>.
     18 */
     19 
     20 /**
     21  * @file fuzz/fuzz_tls.c
     22  * @brief In-process fuzzer for MHD's HTTPS/TLS integration layer.
     23  * @author Christian Grothoff
     24  *
     25  * The target is **MHD's own TLS plumbing**, not GnuTLS.  GnuTLS has its
     26  * own OSS-Fuzz project and its record parser is not our bug surface, so
     27  * only a small part of the input budget is spent throwing raw bytes at a
     28  * TLS socket.  What this harness really exercises is
     29  *
     30  *  - the @c MHD_USE_TLS daemon option surface: #MHD_OPTION_HTTPS_MEM_KEY,
     31  *    #MHD_OPTION_HTTPS_MEM_CERT, #MHD_OPTION_HTTPS_MEM_TRUST,
     32  *    #MHD_OPTION_HTTPS_MEM_DHPARAMS, #MHD_OPTION_HTTPS_PRIORITIES,
     33  *    #MHD_OPTION_HTTPS_PRIORITIES_APPEND, #MHD_OPTION_HTTPS_CRED_TYPE,
     34  *    #MHD_OPTION_HTTPS_KEY_PASSWORD, #MHD_OPTION_TLS_NO_ALPN and the SNI
     35  *    callback #MHD_OPTION_HTTPS_CERT_CALLBACK -- with malformed PEM
     36  *    blobs, mismatched key/certificate pairs, bogus priority strings,
     37  *    credential types MHD does not support, and an SNI callback that
     38  *    fails or answers with garbage;
     39  *  - the pre-shared key path: #MHD_OPTION_GNUTLS_PSK_CRED_HANDLER and
     40  *    @c psk_gnutls_adapter(), which is the one place where MHD takes a
     41  *    buffer straight from an application callback and hands it to
     42  *    GnuTLS.  See the "TLS-PSK" note below for why one input bit turns
     43  *    the whole scenario on rather than four independent ones;
     44  *  - the handshake state machine of connection_https.c
     45  *    (#MHD_TLS_CONN_INIT -> HANDSHAKING -> CONNECTED / TLS_FAILED) and
     46  *    what MHD does when the handshake fails, is abandoned half way, or
     47  *    the peer disappears while MHD is still in it;
     48  *  - the transition from the handshake to the ordinary HTTP parser, and
     49  *    the TLS receive/send adapters and @c gnutls_bye() shutdown path that
     50  *    the connection uses afterwards.
     51  *
     52  * To reach that last group the harness contains a real, in-process GnuTLS
     53  * *client*.  Both ends of an @c AF_UNIX @c socketpair() are non-blocking
     54  * and everything runs in one thread: the client's @c gnutls_handshake()
     55  * is called until it answers @c GNUTLS_E_AGAIN, then the daemon is pumped
     56  * with MHD_run(), and so on.  No threads, no ports, no TCP stack, and --
     57  * because the client's handshake timeout is set to
     58  * @c GNUTLS_INDEFINITE_TIMEOUT -- no wall clock either.
     59  *
     60  * Input format (see README):
     61  *
     62  *   byte 0   certificate/key pair selector (valid, mismatched, truncated,
     63  *            garbage, absent, or built from the fuzzer's own bytes)
     64  *   byte 1   which TLS daemon options to pass at all (bitmask)
     65  *              0x01 MHD_OPTION_HTTPS_MEM_TRUST
     66  *              0x02 MHD_OPTION_HTTPS_MEM_DHPARAMS
     67  *              0x04 MHD_OPTION_HTTPS_CERT_CALLBACK (the SNI callback)
     68  *              0x08 MHD_OPTION_HTTPS_PRIORITIES[_APPEND]
     69  *              0x10 MHD_OPTION_HTTPS_CRED_TYPE
     70  *              0x20 MHD_OPTION_TLS_NO_ALPN
     71  *              0x40 MHD_OPTION_HTTPS_KEY_PASSWORD
     72  *              0x80 use _PRIORITIES_APPEND instead of _PRIORITIES
     73  *   byte 2   priority string selector
     74  *   byte 3   bits 0-2 credential type (certificate, PSK, anon, SRP, IA,
     75  *                     and two values GnuTLS does not define)
     76  *            bits 3-5 SNI callback behaviour
     77  *            bit  6   trust blob: CA certificate or garbage
     78  *            bit  7   DH parameters: valid or garbage
     79  *   byte 4   bits 0-1 client mode
     80  *                     0 raw bytes, 1 real TLS client,
     81  *                     2 real client, handshake abandoned half way,
     82  *                     3 raw bytes shaped like TLS records
     83  *            bit  2   client sends a server name (SNI)
     84  *            bit  3   client presents a client certificate
     85  *            bits 4-5 client priority string selector
     86  *            bit  6   gnutls_bye() before closing
     87  *            bit  7   shutdown(SHUT_WR) before closing
     88  *   byte 5   bits 0-3 MHD_OPTION_CONNECTION_MEMORY_LIMIT selector
     89  *            bits 4-5 event loop: MHD_run() vs MHD_get_fdset*() +
     90  *                     MHD_run_from_select*()
     91  *            bit  6   hand the daemon one more connection at the very
     92  *                     end and stop it without running the loop again,
     93  *                     so that a TLS session is torn down for a
     94  *                     connection MHD never started
     95  *            bit  7   unused
     96  *   byte 6   handler behaviour and introspection
     97  *              bits 0-1 response constructor
     98  *              bit  2   MHD_get_connection_info() for the TLS members
     99  *              bit  3   MHD_get_daemon_info()
    100  *              bit  4   MHD_set_connection_option()
    101  *              bit  5   answer 403 instead of 200
    102  *              bit  6   add a response header
    103  *              bit  7   MHD_quiesce_daemon() before stopping
    104  *   byte 7   bits 0-2 handshake round budget (client mode 2)
    105  *            bit  3   pass the HTTPS options to a daemon started *without*
    106  *                     MHD_USE_TLS
    107  *            bit  4   MHD_ALLOW_UPGRADE
    108  *            bits 5-7 extra pump rounds
    109  *   byte 8   how many bytes of the segment stream are spliced into the
    110  *            fuzzer-built PEM blobs (see cred_tbl entries 12 and 13)
    111  *   byte 9   bits 0-2 the server name the client presents, as an index
    112  *            into a small built-in table; an op 1 segment overrides it.
    113  *            In the TLS-PSK scenario that same string is also the PSK
    114  *            identity the client sends, so an op 1 segment gives byte
    115  *            level control over the @a username that reaches
    116  *            psk_gnutls_adapter()
    117  *            bits 3-5 behaviour of the PSK credentials callback
    118  *            bit  6   the client offers PSK credentials
    119  *            bit  7   run the TLS-PSK scenario (see below)
    120  *   byte 10. a sequence of segments, each introduced by a little-endian
    121  *            16 bit header  (op << 14) | length
    122  *              op 0  send the payload
    123  *              op 1  the payload is the server name the *next* client
    124  *                    connection presents; nothing is sent
    125  *              op 2  send the payload and pump the daemon extra rounds
    126  *              op 3  close the connection, open a fresh one (which means
    127  *                    a fresh handshake), then send
    128  *
    129  * All ten configuration bytes are mandatory; a shorter input is
    130  * rejected.
    131  *
    132  * The segment encoding is byte-for-byte the one fuzz_request uses, and
    133  * `corpus/` is shared by every harness in this directory (see README
    134  * section 3), so the seeds below deliberately contain **no op 1
    135  * segment**: fuzz_request reads op 1 as the declared decoded request
    136  * body of its own body oracle, and would report a spurious finding when
    137  * it replays a fuzz_tls seed.  That is what byte 9 is for.  Inputs the
    138  * generator or a mutator produces may use op 1 freely -- they never end
    139  * up in `corpus/`.
    140  *
    141  * TLS-PSK.  Reaching psk_gnutls_adapter() needs four unrelated things to
    142  * be true at the same time: the daemon's credential type has to be
    143  * #GNUTLS_CRD_PSK, both ends need a priority string that actually has a
    144  * PSK key exchange in it ("NORMAL" does not), the daemon needs
    145  * #MHD_OPTION_GNUTLS_PSK_CRED_HANDLER, and the client has to offer a PSK
    146  * identity.  Spread over four independent input bits that combination
    147  * comes up once in a few hundred thousand inputs, and an 8 hour campaign
    148  * duly left the function at zero coverage.  Bit 7 of byte 9 therefore
    149  * switches the whole scenario on at once and the remaining PSK bits only
    150  * choose between its variants.
    151  *
    152  * The variants are the branches of psk_gnutls_adapter() itself: the
    153  * callback is missing, fails, or answers 0 with a key of a workable
    154  * size, of 4 KiB, of zero size, of one byte less than the
    155  * @c MHD_PSK_MIN_SIZE the adapter enforces, and of a size that exceeds
    156  * @c UINT_MAX.  The two undersized ones and #PSK_OK bracket that
    157  * minimum from both sides -- #PSK_OK is exactly @c MHD_PSK_MIN_SIZE
    158  * bytes -- which is what makes an off-by-one in the check visible.
    159  *
    160  * One behaviour is deliberately *not* offered: answering 0 without
    161  * writing the two output parameters.  MHD would then read uninitialised
    162  * memory, but the application has broken the documented contract, so a
    163  * report from that would be a harness bug rather than an MHD bug.
    164  *
    165  * The certificates and keys are the ones from
    166  * `src/testcurl/https/tls_test_keys.h` (the CA certificate, the
    167  * CA-signed server certificate with its key, and the self-signed server
    168  * certificate with its key), reproduced verbatim so that this harness
    169  * stays a single translation unit.  The DH parameters are RFC 3526
    170  * group 14, as emitted by `certtool --get-dh-params --sec-param medium`.
    171  *
    172  * The whole harness is guarded by #HTTPS_SUPPORT: `contrib/oss-fuzz/
    173  * build.sh` configures `--disable-https` (that is what makes the
    174  * MemorySanitizer build possible), and in such a build this file must
    175  * still compile to a valid, trivially passing fuzz target.
    176  */
    177 
    178 #define FUZZ_HARNESS_NAME "fuzz_tls"
    179 #include "fuzz_common.h"
    180 
    181 /* Pulls in MHD_config.h, which is where HTTPS_SUPPORT is defined.  It
    182    must come before <microhttpd.h>: it also settles FD_SETSIZE. */
    183 #include "mhd_options.h"
    184 
    185 #ifdef HTTPS_SUPPORT
    186 
    187 #include <microhttpd.h>
    188 #include <gnutls/gnutls.h>
    189 #include <gnutls/abstract.h>
    190 #include <sys/socket.h>
    191 #include <netinet/in.h>
    192 #include <sys/select.h>
    193 #include <arpa/inet.h>
    194 
    195 /**
    196  * LeakSanitizer suppressions, compiled into the harness so that they
    197  * cannot be forgotten on the command line.
    198  *
    199  * There is exactly one entry and it is *not* about MHD.  GnuTLS 3.8.9
    200  * leaks the partially parsed certificate when a PEM certificate blob
    201  * ends before its "-----END CERTIFICATE-----" line:
    202  *
    203  *     gnutls_certificate_allocate_credentials (&cred);
    204  *     gnutls_certificate_set_x509_key_mem (cred, &truncated_cert,
    205  *                                          &good_key,
    206  *                                          GNUTLS_X509_FMT_PEM);
    207  *        -> GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR (-207)
    208  *     gnutls_certificate_free_credentials (cred);
    209  *
    210  * leaks 9672 bytes in 57 allocations with no libmicrohttpd in the
    211  * picture at all (reproduced with a 40 line program).  MHD passes the
    212  * blob straight through and frees the credentials on every path, so
    213  * there is nothing for MHD to fix and nothing for this harness to find;
    214  * GnuTLS is fuzzed separately by its own OSS-Fuzz project.
    215  *
    216  * The suppression matches only allocations made *inside* GnuTLS's
    217  * certificate parser.  A credential object leaked by MHD itself is a
    218  * direct leak from gnutls_certificate_allocate_credentials() and is
    219  * still reported, as is every other MHD allocation.
    220  */
    221 const char *
    222 __lsan_default_suppressions (void);
    223 
    224 const char *
    225 __lsan_default_suppressions (void)
    226 {
    227   return "leak:gnutls_x509_crt_init\n";
    228 }
    229 
    230 
    231 #define MAX_SEGMENTS 48
    232 #define MAX_CONNECTIONS 3
    233 #define RESP_BUF_SIZE 16384
    234 #define GEN_BUF_SIZE 4096
    235 #define MAX_SNI_LEN 255
    236 #define FUZZ_PEM_BODY_MAX 1024
    237 
    238 /** Number of client priority strings offered to the input. */
    239 #define CLIENT_PRIO_COUNT 4
    240 
    241 /**
    242  * Upper bound on the number of client/server round trips spent on one
    243  * handshake.  A TLS 1.3 handshake over a socketpair needs a handful; the
    244  * cap only has to guarantee termination.
    245  */
    246 #define HANDSHAKE_ROUNDS 64
    247 
    248 
    249 /* ------------------------------------------------------------------ */
    250 /* Test credentials                                                    */
    251 /* ------------------------------------------------------------------ */
    252 
    253 /*
    254  * Taken verbatim from src/testcurl/https/tls_test_keys.h (the CA
    255  * certificate, the CA-signed server certificate and its key, and the
    256  * self-signed server certificate and its key), so that this harness
    257  * stays a single translation unit.  dh_params_pem is RFC 3526 group 14,
    258  * as emitted by "certtool --get-dh-params --sec-param medium".
    259  */
    260 
    261 static const char ca_cert_pem[] =
    262   "-----BEGIN CERTIFICATE-----\n"
    263   "MIIGITCCBAmgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgTELMAkGA1UEBhMCUlUx\n"
    264   "DzANBgNVBAgMBk1vc2NvdzEPMA0GA1UEBwwGTW9zY293MRswGQYDVQQKDBJ0ZXN0\n"
    265   "LWxpYm1pY3JvaHR0cGQxITAfBgkqhkiG9w0BCQEWEm5vYm9keUBleGFtcGxlLm9y\n"
    266   "ZzEQMA4GA1UEAwwHdGVzdC1DQTAgFw0yMTA0MDcxNzM2MThaGA8yMTIxMDMxNDE3\n"
    267   "MzYxOFowgYExCzAJBgNVBAYTAlJVMQ8wDQYDVQQIDAZNb3Njb3cxDzANBgNVBAcM\n"
    268   "Bk1vc2NvdzEbMBkGA1UECgwSdGVzdC1saWJtaWNyb2h0dHBkMSEwHwYJKoZIhvcN\n"
    269   "AQkBFhJub2JvZHlAZXhhbXBsZS5vcmcxEDAOBgNVBAMMB3Rlc3QtQ0EwggIiMA0G\n"
    270   "CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDdaWupA4qZjCBNkJoJOm5xnCaizl36\n"
    271   "ZLUwp4xBL/YfXPWE3LkmAREiVI/YnAb8l6G7CJnz8dTsOJWkNXG6T1KVP5/2RvBI\n"
    272   "IaaaufRIAl7hEnj1j9E2hQlV2fxF2ZNhz+nqi0LqKV4LJSpclkXADf2FA9HsVRP/\n"
    273   "B7zYh+DP0fSU8V6bsu8XCeRGshroAPrc8rH8lFEEXpNLNIqQr8yKx6SmdB6hfja6\n"
    274   "6SQ0++qBhl0aJtn4LHWZohgjBmkIaGFPYIJLgxQ/xyp2Grz2q7lGKJ+zBkBF8iOP\n"
    275   "t3x+F1hSCBnr/DGYWmjEm5tYm+7pyuriPddXdCc8+qa2LxMZo3EXxLo5YISpPCyw\n"
    276   "Z7V3YAOZTr3m1C24LiYvPehCq1CTIkhhmqtlVJXU7ISD48cx9y+5Pi34wtbTI/gN\n"
    277   "x4voyTLAfyavKMmIpxxIRsWldiF2n06HdvCRVdihDQUad10ygTmWf1J/s2ZETAtH\n"
    278   "QaSd7MD389t6nQFtTIXigsNKnnDPlrtxt7rOLvLQeR0K04Gzrf/scheOanRAfOXH\n"
    279   "KNBFU7YkDFG8rqizlC65rx9qeXFYXQcHZTuqxK7tgZnSgJat3E70VbTSCsEEG7eR\n"
    280   "bNX/fChUKAIIpWaiW6HDlKLl6m2y+BzM91umBsKOqTvntMVFBSF9pVYlXK854aIR\n"
    281   "q8A2Xujd012seQIDAQABo4GfMIGcMAsGA1UdDwQEAwICpDASBgNVHRMBAf8ECDAG\n"
    282   "AQH/AgEBMB0GA1UdDgQWBBRYdUPApWoxw4U13Rqsjf9AHdbpLDATBgNVHSUEDDAK\n"
    283   "BggrBgEFBQcDATAkBglghkgBhvhCAQ0EFxYVVGVzdCBsaWJtaWNyb2h0dHBkIENB\n"
    284   "MB8GA1UdIwQYMBaAFFh1Q8ClajHDhTXdGqyN/0Ad1uksMA0GCSqGSIb3DQEBCwUA\n"
    285   "A4ICAQBvrrcTKVeI1EYnXo4BQD4oCvf9z1fYQmL21EbHwgjg1nmaPkvStgWAc5p1\n"
    286   "kKwySrpEMKXfu68X76RccXZyWWIamEjz2OCWYZgjX6d6FpjhLphL8WxXDy5C9eay\n"
    287   "ixN7+URz2XQoi22wqR+tCPDhrIzcMPyMkx/6gRgcYeDnaFrkdSeSsKsID4plfcIj\n"
    288   "ISWJDvv+IAgrtsG1NVHnGwpAv0od3A8/4/fR6PPyewaU3aydvjZ7Au8O9DGDjlU9\n"
    289   "9HdlOkkY6GVJ1pfGZib7cV7lhy0D2kj1g9xZh97YjpoUfppPl9r+6A8gDm0hXlAD\n"
    290   "TlzNYlwTb681ZEoSd9PiLEY8HETssHlays2dYXdcNwAEp69iIHz8q1Q98Be9LScl\n"
    291   "WEzgaOT9U7lpIw/MWbELoMsC+Ecs1cVWBIuiIq8aSG2kRr1x3S8yVXbAohAXif2s\n"
    292   "E6puieM/VJ25iaNhkbLmDkk58QVVmn9NZNv6ETxuSQMp9e0EwbVlj68vzClQ91Y/\n"
    293   "nmAiGcLFUEwB9G0szv9+vR+oDW4IkvdFZSUbcICd2cnynnwAD395onqS4hEZO1xM\n"
    294   "Gy5ZldbTMTjgn7fChNopz15ChPBnwFIjhm+S0CyiLRQAowfknRVq2IBkj7/5kOWg\n"
    295   "4mcxcq76HoQWK/8X/8RFL1eFVAvY7TNHYJ0RS51DMuwCNQictA==\n"
    296   "-----END CERTIFICATE-----\n";
    297 
    298 
    299 static const char srv_signed_key_pem[] =
    300   "-----BEGIN PRIVATE KEY-----\n"
    301   "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCff7amw9zNSE+h\n"
    302   "rOMhBrzbbsJluUP3gmd8nOKY5MUimoPkxmAXfp2L0il+MPZT/ZEmo11q0k6J2jfG\n"
    303   "UBQ+oZW9ahNZ9gCDjbYlBblo/mqTai+LdeLO3qk53d0zrZKXvCO6sA3uKpG2WR+g\n"
    304   "+sNKxfYpIHCpanqBU6O+degIV/+WKy3nQ2Fwp7K5HUNj1u0pg0QQ18yf68LTnKFU\n"
    305   "HFjZmmaaopWki5wKSBieHivzQy6w+04HSTogHHRK/y/UcoJNSG7xnHmoPPo1vLT8\n"
    306   "CMRIYnSSgU3wJ43XBJ80WxrC2dcoZjV2XZz+XdQwCD4ZrC1ihykcAmiQA+sauNm7\n"
    307   "dztOMkGzAgMBAAECggEAIbKDzlvXDG/YkxnJqrKXt+yAmak4mNQuNP+YSCEdHSBz\n"
    308   "+SOILa6MbnvqVETX5grOXdFp7SWdfjZiTj2g6VKOJkSA7iKxHRoVf2DkOTB3J8np\n"
    309   "XZd8YaRdMGKVV1O2guQ20Dxd1RGdU18k9YfFNsj4Jtw5sTFTzHr1P0n9ybV9xCXp\n"
    310   "znSxVfRg8U6TcMHoRDJR9EMKQMO4W3OQEmreEPoGt2/+kMuiHjclxLtbwDxKXTLP\n"
    311   "pD0gdg3ibvlufk/ccKl/yAglDmd0dfW22oS7NgvRKUve7tzDxY1Q6O5v8BCnLFSW\n"
    312   "D+z4hS1PzooYRXRkM0xYudvPkryPyu+1kEpw3fNsoQKBgQDRfXJo82XQvlX8WPdZ\n"
    313   "Ts3PfBKKMVu3Wf8J3SYpuvYT816qR3ot6e4Ivv5ZCQkdDwzzBKe2jAv6JddMJIhx\n"
    314   "pkGHc0KKOodd9HoBewOd8Td++hapJAGaGblhL5beIidLKjXDjLqtgoHRGlv5Cojo\n"
    315   "zHa7Viel1eOPPcBumhp83oJ+mQKBgQDC6PmdETZdrW3QPm7ZXxRzF1vvpC55wmPg\n"
    316   "pRfTRM059jzRzAk0QiBgVp3yk2a6Ob3mB2MLfQVDgzGf37h2oO07s5nspSFZTFnM\n"
    317   "KgSjFy0xVOAVDLe+0VpbmLp1YUTYvdCNowaoTE7++5rpePUDu3BjAifx07/yaSB+\n"
    318   "W+YPOfOuKwKBgQCGK6g5G5qcJSuBIaHZ6yTZvIdLRu2M8vDral5k3793a6m3uWvB\n"
    319   "OFAh/eF9ONJDcD5E7zhTLEMHhXDs7YEN+QODMwjs6yuDu27gv97DK5j1lEsrLUpx\n"
    320   "XgRjAE3KG2m7NF+WzO1K74khWZaKXHrvTvTEaxudlO3X8h7rN3u7ee9uEQKBgQC2\n"
    321   "wI1zeTUZhsiFTlTPWfgppchdHPs6zUqq0wFQ5Zzr8Pa72+zxY+NJkU2NqinTCNsG\n"
    322   "ePykQ/gQgk2gUrt595AYv2De40IuoYk9BlTMuql0LNniwsbykwd/BOgnsSlFdEy8\n"
    323   "0RQn70zOhgmNSg2qDzDklJvxghLi7zE5aV9//V1/ewKBgFRHHZN1a8q/v8AAOeoB\n"
    324   "ROuXfgDDpxNNUKbzLL5MO5odgZGi61PBZlxffrSOqyZoJkzawXycNtoBP47tcVzT\n"
    325   "QPq5ZOB3kjHTcN7dRLmPWjji9h4O3eHCX67XaPVMSWiMuNtOZIg2an06+jxGFhLE\n"
    326   "qdJNJ1DkyUc9dN2cliX4R+rG\n"
    327   "-----END PRIVATE KEY-----\n";
    328 
    329 
    330 static const char srv_signed_cert_pem[] =
    331   "-----BEGIN CERTIFICATE-----\n"
    332   "MIIFSzCCAzOgAwIBAgIBBDANBgkqhkiG9w0BAQsFADCBgTELMAkGA1UEBhMCUlUx\n"
    333   "DzANBgNVBAgMBk1vc2NvdzEPMA0GA1UEBwwGTW9zY293MRswGQYDVQQKDBJ0ZXN0\n"
    334   "LWxpYm1pY3JvaHR0cGQxITAfBgkqhkiG9w0BCQEWEm5vYm9keUBleGFtcGxlLm9y\n"
    335   "ZzEQMA4GA1UEAwwHdGVzdC1DQTAgFw0yMjA0MjAxODQzMDJaGA8yMTIyMDMyNjE4\n"
    336   "NDMwMlowZTELMAkGA1UEBhMCUlUxDzANBgNVBAgMBk1vc2NvdzEPMA0GA1UEBwwG\n"
    337   "TW9zY293MRswGQYDVQQKDBJ0ZXN0LWxpYm1pY3JvaHR0cGQxFzAVBgNVBAMMDnRl\n"
    338   "c3QtbWhkc2VydmVyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn3+2\n"
    339   "psPczUhPoazjIQa8227CZblD94JnfJzimOTFIpqD5MZgF36di9IpfjD2U/2RJqNd\n"
    340   "atJOido3xlAUPqGVvWoTWfYAg422JQW5aP5qk2ovi3Xizt6pOd3dM62Sl7wjurAN\n"
    341   "7iqRtlkfoPrDSsX2KSBwqWp6gVOjvnXoCFf/list50NhcKeyuR1DY9btKYNEENfM\n"
    342   "n+vC05yhVBxY2ZpmmqKVpIucCkgYnh4r80MusPtOB0k6IBx0Sv8v1HKCTUhu8Zx5\n"
    343   "qDz6Nby0/AjESGJ0koFN8CeN1wSfNFsawtnXKGY1dl2c/l3UMAg+GawtYocpHAJo\n"
    344   "kAPrGrjZu3c7TjJBswIDAQABo4HmMIHjMAsGA1UdDwQEAwIFoDAMBgNVHRMBAf8E\n"
    345   "AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMBMDEGA1UdEQQqMCiCDnRlc3QtbWhk\n"
    346   "c2VydmVyhwR/AAABhxAAAAAAAAAAAAAAAAAAAAABMB0GA1UdDgQWBBQ57Z06WJae\n"
    347   "8fJIHId4QGx/HsRgDDAoBglghkgBhvhCAQ0EGxYZVGVzdCBsaWJtaWNyb2h0dHBk\n"
    348   "IHNlcnZlcjARBglghkgBhvhCAQEEBAMCBkAwHwYDVR0jBBgwFoAUWHVDwKVqMcOF\n"
    349   "Nd0arI3/QB3W6SwwDQYJKoZIhvcNAQELBQADggIBAI7Lggm/XzpugV93H5+KV48x\n"
    350   "X+Ct8unNmPCSzCaI5hAHGeBBJpvD0KME5oiJ5p2wfCtK5Dt9zzf0S0xYdRKqU8+N\n"
    351   "aKIvPoU1hFixXLwTte1qOp6TviGvA9Xn2Fc4n36dLt6e9aiqDnqPbJgBwcVO82ll\n"
    352   "HJxVr3WbrAcQTB3irFUMqgAke/Cva9Bw79VZgX4ghb5EnejDzuyup4pHGzV10Myv\n"
    353   "hdg+VWZbAxpCe0S4eKmstZC7mWsFCLeoRTf/9Pk1kQ6+azbTuV/9QOBNfFi8QNyb\n"
    354   "18jUjmm8sc2HKo8miCGqb2sFqaGD918hfkWmR+fFkzQ3DZQrT+eYbKq2un3k0pMy\n"
    355   "UySy8SRn1eadfab+GwBVb68I9TrPRMrJsIzysNXMX4iKYl2fFE/RSNnaHtPw0C8y\n"
    356   "B7memyxPRl+H2xg6UjpoKYh3+8e44/XKm0rNIzXjrwA8f8gnw2TbqmMDkj1YqGnC\n"
    357   "SCj5A27zUzaf2pT/YsnQXIWOJjVvbEI+YKj34wKWyTrXA093y8YI8T3mal7Kr9YM\n"
    358   "WiIyPts0/aVeziM0Gunglz+8Rj1VesL52FTurobqusPgM/AME82+qb/qnxuPaCKj\n"
    359   "OT1qAbIblaRuWqCsid8BzP7ZQiAnAWgMRSUg1gzDwSwRhrYQRRWAyn/Qipzec+27\n"
    360   "/w0gW9EVWzFhsFeGEssi\n"
    361   "-----END CERTIFICATE-----\n";
    362 
    363 
    364 static const char srv_self_signed_cert_pem[] =
    365   "-----BEGIN CERTIFICATE-----\n"
    366   "MIIDJzCCAg+gAwIBAgIUOKf6e6Heee2XA+yF5St3t+fVM40wDQYJKoZIhvcNAQEF\n"
    367   "BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MCAXDTIyMTAxMDA4MzQ0N1oYDzIxMjIw\n"
    368   "OTE2MDgzNDQ3WjAUMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB\n"
    369   "AQUAA4IBDwAwggEKAoIBAQClivgF8Xq0ekQli++0l7Q5JFwJCuLf04Cb1UKIS80U\n"
    370   "CfphFd1ILJepNw4bWR3OV1sRI1vFiw6LnCz53vOwVNyiZ+sMGi4bDX4AV9Xd+F83\n"
    371   "xhG8AjOmKTayW0TxSIvt47Qd5S/4fgraxMtvqrRRBen30iKOwX7uNF/4dYb9vdin\n"
    372   "OldV/e8uzbqSurMGkNDznOeSaNBmdO/7x0VMFZM2hwmHyiiw75/j4BhUlLCcMEvK\n"
    373   "oN+YHNCNcTt3Qm1vVuiGXmh9QreOV09Gc1SzAltxF2gmI0jzw8r/duz18QXMNsMw\n"
    374   "El/Ah4+02gR70L7qlgttN1NPU3RJpK/L34J7yg649wHTAgMBAAGjbzBtMB0GA1Ud\n"
    375   "DgQWBBROVferD+YYcV1YEnFgC0jYm5X9BjAfBgNVHSMEGDAWgBROVferD+YYcV1Y\n"
    376   "EnFgC0jYm5X9BjAPBgNVHRMBAf8EBTADAQH/MBoGA1UdEQQTMBGCCWxvY2FsaG9z\n"
    377   "dIcEfwAAATANBgkqhkiG9w0BAQUFAAOCAQEAoRbozsm5xXdNX3VO++s2LMzw5KM9\n"
    378   "RpIInHNkMJbnyLJFKJ8DF7nTxSGCA38YMkX3tphPNKZXbg+V64Dqr/XpzOVyiinU\n"
    379   "7hIwyUdSSKKyErZxIWR97lY6Q3SOyPAg8ZElbtvSsSzmd772VE23VTXGDi7AW0PQ\n"
    380   "hag9N2EEnHURMvID15O+UXyFpDdyUyQIbx3HuswsGDH9xBTm4irLyrZwO0KwKg5a\n"
    381   "JBeUiPs0SYRRfn9/MoE6VwAnmOCg3LLR6ZPU3hQtTPLHj2Op1g5fey3X3X6lC+JC\n"
    382   "K6dNZc1zBFPz8KANGUsFYbmoP2bvAAA+6KwCnZZEflUgE7/HFEmQhVOezw==\n"
    383   "-----END CERTIFICATE-----\n";
    384 
    385 
    386 static const char srv_self_signed_key_pem[] =
    387   "-----BEGIN PRIVATE KEY-----\n"
    388   "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQClivgF8Xq0ekQl\n"
    389   "i++0l7Q5JFwJCuLf04Cb1UKIS80UCfphFd1ILJepNw4bWR3OV1sRI1vFiw6LnCz5\n"
    390   "3vOwVNyiZ+sMGi4bDX4AV9Xd+F83xhG8AjOmKTayW0TxSIvt47Qd5S/4fgraxMtv\n"
    391   "qrRRBen30iKOwX7uNF/4dYb9vdinOldV/e8uzbqSurMGkNDznOeSaNBmdO/7x0VM\n"
    392   "FZM2hwmHyiiw75/j4BhUlLCcMEvKoN+YHNCNcTt3Qm1vVuiGXmh9QreOV09Gc1Sz\n"
    393   "AltxF2gmI0jzw8r/duz18QXMNsMwEl/Ah4+02gR70L7qlgttN1NPU3RJpK/L34J7\n"
    394   "yg649wHTAgMBAAECggEAERbbCtYGakoy7cNX8Ac3Kiz4OVC/4gZWAQBPeX2FwrtS\n"
    395   "9yHIMbK0x1mxIZ6eBpabBpZlW2vDCSOKuxLKiloAWt2qdJnhR5apesSWhe8leT7/\n"
    396   "xq5dgZpAlMH6SIRKObknd2yY+qicW0A0licDrVeUcypkueL8xP9wJtiPInOuQXkI\n"
    397   "QROhB13eStRuRKYwOn5gtwAHJ+J1DFKKiqpBOkrSYf4625StGegJO9+bjK0ei+0W\n"
    398   "tp6unpiwA/lXTgz6Xim1Z3fzWs4XjFgVKzK5s/6yBJjr8spHX6lv7QsahP4w6HZ/\n"
    399   "VcRxP6cJNd/otiTEtJXpbxiiyccwXm/AOcOn22P1cQKBgQDAnY/0G/ap/G98pneE\n"
    400   "suzNXhWOQ8JoL8d66Io8vwTvfiJggfgUcwblI7pPCrSlaZMR7/q6JImE53lZtPk8\n"
    401   "eI3c9lN0ocr8E7+huDpYdk7cMYj9SuxySsXoMLiMqzHFi+NcIhKMF56kk6a5CFCt\n"
    402   "yP1Ofy76LVweGE3XvTwpwE7wUQKBgQDcBLyH1cC71s0I0Gz28AyELV9hPhasjAKO\n"
    403   "12CVbeBVTPd+28uk/3o80wSrTksc6H5ehAA2aTvrb4OhwssWNL+D0fS8YK2cJ3V0\n"
    404   "FJxGAM266+vC4d/8jRTHJnc+6PP3ix5t6vAt+K2Y0fePtefLqf4ebgXx/ODAj3J2\n"
    405   "aZKBldjK4wKBgGIRFpTLk/eR/dUyEBHw4x3gdAsdtqJDCUYrlQ4+ly20Q55tLbiD\n"
    406   "pBQP77CEm9rH+MgeLcKODbIsBB3HRUojet7wTydHpMhY6a1V1ebqPVZgpgWIGwBJ\n"
    407   "z59bBusf0lRo15Y2Bslq0SurvSvh7um8NjO8D1fytj7gUumvgC0lq0sxAoGBAI1+\n"
    408   "kkx9IBTtIDER8XGhkTsT/uoHxwcyh5abVmbjIclZ1TUFX2L+Vft17ePJVy8BKfvY\n"
    409   "wlY7uShBMBNAteDTDXNV/CGFv0DUc4myk4nFjIkwng9XufeuN3WX/Eo+AF/rXSdt\n"
    410   "VwcJjYLhTWdjoe1tppqlQTeN3HCaEA+s92ZVGvXnAoGAMCXGS6WZl1e5wsHRq0Yy\n"
    411   "8Ef2Wrk620bBjKHolkTfvgfhlvxeZM1sv1ioZGsOeQ0z7O7wdJhvL0M/WAG+3yQj\n"
    412   "HSXp81T1vOICPwNYZf8xcvbLKmvj7rHFt6ZAZF2o4EK8ReZTRyA3DUpBCDY+s3FN\n"
    413   "GmBv0D7N3QP0CT3SzfQrPkc=\n"
    414   "-----END PRIVATE KEY-----\n";
    415 
    416 
    417 static const char dh_params_pem[] =
    418   "-----BEGIN DH PARAMETERS-----\n"
    419   "MIIBDAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz\n"
    420   "+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a\n"
    421   "87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7\n"
    422   "YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi\n"
    423   "7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD\n"
    424   "ssbzSibBsu/6iGtCOGEoXJf//////////wIBAgICAQA=\n"
    425   "-----END DH PARAMETERS-----\n";
    426 
    427 /** A PEM blob whose armour is fine but whose payload is not base64. */
    428 static const char garbage_cert_pem[] =
    429   "-----BEGIN CERTIFICATE-----\n"
    430   "this is not base64 at all, not even close !!!! ????\n"
    431   "-----END CERTIFICATE-----\n";
    432 
    433 static const char garbage_key_pem[] =
    434   "-----BEGIN PRIVATE KEY-----\n"
    435   "@@@@ neither is this @@@@\n"
    436   "-----END PRIVATE KEY-----\n";
    437 
    438 /** Correct base64, but the armour never ends. */
    439 static const char truncated_cert_pem[] =
    440   "-----BEGIN CERTIFICATE-----\n"
    441   "MIIFSzCCAzOgAwIBAgIBBDANBgkqhkiG9w0BAQsFADCBgTELMAkGA1UEBhMCUlUx\n"
    442   "DzANBgNVBAgMBk1vc2NvdzEPMA0GA1UEBwwGTW9zY293MRswGQYDVQQKDBJ0ZXN0\n";
    443 
    444 static const char truncated_key_pem[] =
    445   "-----BEGIN PRIVATE KEY-----\n"
    446   "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCff7amw9zNSE+h\n";
    447 
    448 /** Base64 of a certificate, but with no PEM armour at all. */
    449 static const char no_armour_pem[] =
    450   "MIIFSzCCAzOgAwIBAgIBBDANBgkqhkiG9w0BAQsFADCBgTELMAkGA1UEBhMCUlUx\n"
    451   "DzANBgNVBAgMBk1vc2NvdzEPMA0GA1UEBwwGTW9zY293MRswGQYDVQQKDBJ0ZXN0\n";
    452 
    453 static const char garbage_dh_pem[] =
    454   "-----BEGIN DH PARAMETERS-----\n"
    455   "not-dh-parameters\n"
    456   "-----END DH PARAMETERS-----\n";
    457 
    458 /**
    459  * PEM blobs assembled from the fuzzer's own bytes, see cred_tbl entries
    460  * 12 and 13.  Static so that the pointer handed to MHD stays valid for
    461  * the whole lifetime of the daemon.
    462  */
    463 static char fuzz_cert_pem[FUZZ_PEM_BODY_MAX + 128];
    464 static char fuzz_key_pem[FUZZ_PEM_BODY_MAX + 128];
    465 
    466 
    467 /**
    468  * A certificate/key pair for #MHD_OPTION_HTTPS_MEM_CERT and
    469  * #MHD_OPTION_HTTPS_MEM_KEY.  A NULL member means "do not pass the
    470  * option at all", which is a configuration MHD has to reject cleanly.
    471  */
    472 struct cred_pair
    473 {
    474   const char *cert;
    475   const char *key;
    476 };
    477 
    478 static const struct cred_pair cred_tbl[] = {
    479   { srv_signed_cert_pem, srv_signed_key_pem },        /*  0 valid, CA signed */
    480   { srv_self_signed_cert_pem, srv_self_signed_key_pem }, /* 1 valid, self signed */
    481   { srv_signed_cert_pem, srv_self_signed_key_pem },   /*  2 key does not match */
    482   { srv_self_signed_cert_pem, srv_signed_key_pem },   /*  3 key does not match */
    483   { srv_signed_cert_pem, NULL },                      /*  4 certificate only */
    484   { NULL, srv_signed_key_pem },                       /*  5 key only */
    485   { NULL, NULL },                                     /*  6 neither */
    486   { "", "" },                                         /*  7 empty strings */
    487   { truncated_cert_pem, srv_signed_key_pem },         /*  8 truncated armour */
    488   { srv_signed_cert_pem, truncated_key_pem },         /*  9 truncated armour */
    489   { garbage_cert_pem, garbage_key_pem },              /* 10 armour, no base64 */
    490   { no_armour_pem, srv_signed_key_pem },              /* 11 base64, no armour */
    491   { fuzz_cert_pem, srv_signed_key_pem },              /* 12 PEM from the input */
    492   { srv_signed_cert_pem, fuzz_key_pem },              /* 13 PEM from the input */
    493   { fuzz_cert_pem, fuzz_key_pem },                    /* 14 PEM from the input */
    494   { srv_signed_cert_pem, srv_signed_key_pem }         /* 15 valid (bias) */
    495 };
    496 
    497 #define CRED_COUNT (sizeof (cred_tbl) / sizeof (cred_tbl[0]))
    498 
    499 /**
    500  * Priority strings.  The first entries are the ones a real server would
    501  * use, the rest are what MHD has to reject without falling over.  MHD
    502  * hands these to gnutls_priority_init() (or appends them to its own
    503  * base string) and fails daemon startup if GnuTLS does not like them.
    504  */
    505 static const char *const prio_tbl[] = {
    506   "NORMAL",
    507   "NORMAL:-VERS-ALL:+VERS-TLS1.3",
    508   "NORMAL:-VERS-ALL:+VERS-TLS1.2",
    509   "SECURE128",
    510   "PERFORMANCE",
    511   "@LIBMICROHTTPD",
    512   "@SYSTEM",
    513   "NONE",
    514   "",
    515   "BOGUS-PRIORITY-STRING",
    516   "NORMAL:!!!",
    517   "NORMAL:-VERS-ALL",
    518   "NORMAL:+ANON-ECDH",
    519   "NORMAL:%SERVER_PRECEDENCE",
    520   "SECURE256:-CIPHER-ALL",
    521   ":::::"
    522 };
    523 
    524 #define PRIO_COUNT (sizeof (prio_tbl) / sizeof (prio_tbl[0]))
    525 
    526 /** Priority strings offered to the *client* side. */
    527 static const char *const client_prio_tbl[CLIENT_PRIO_COUNT] = {
    528   "NORMAL",
    529   "NORMAL:-VERS-ALL:+VERS-TLS1.3",
    530   "NORMAL:-VERS-ALL:+VERS-TLS1.2",
    531   "PERFORMANCE"
    532 };
    533 
    534 /**
    535  * Priority strings for the TLS-PSK scenario, used on both ends.
    536  * "NORMAL" carries no PSK key exchange, so without one of these the
    537  * ciphersuite is never negotiated, GnuTLS never asks the server for a
    538  * key, and psk_gnutls_adapter() is never called.  Index is the client
    539  * priority selector (byte 4, bits 4-5), which the ordinary tables no
    540  * longer use once the scenario is on.
    541  *
    542  * The TLS 1.2 entry has to remove the other key exchanges explicitly.
    543  * A daemon with #GNUTLS_CRD_PSK has no certificate credentials, so with
    544  * the certificate key exchanges still in the list the TLS 1.2 handshake
    545  * dies with "received handshake message out of context" before GnuTLS
    546  * ever asks for a key.  Under TLS 1.3 the same list is fine, which is
    547  * what entries 0 and 2 cover.
    548  */
    549 static const char *const psk_prio_tbl[CLIENT_PRIO_COUNT] = {
    550   "NORMAL:+ECDHE-PSK:+DHE-PSK:+PSK",
    551   "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-PSK:+DHE-PSK:+PSK",
    552   "NORMAL:-VERS-ALL:+VERS-TLS1.3:+ECDHE-PSK:+DHE-PSK:+PSK",
    553   "NORMAL:-KX-ALL:+ECDHE-PSK:+DHE-PSK:+PSK"
    554 };
    555 
    556 /**
    557  * Credential types.  Only GNUTLS_CRD_CERTIFICATE and GNUTLS_CRD_PSK are
    558  * accepted by MHD_TLS_init(); everything else must make daemon startup
    559  * fail rather than reach the MHD_PANIC() in new_connection_prepare_().
    560  */
    561 static const int cred_type_tbl[] = {
    562   (int) GNUTLS_CRD_CERTIFICATE,
    563   (int) GNUTLS_CRD_PSK,
    564   (int) GNUTLS_CRD_ANON,
    565   (int) GNUTLS_CRD_SRP,
    566   (int) GNUTLS_CRD_IA,
    567   (int) GNUTLS_CRD_CERTIFICATE,
    568   99,
    569   -1
    570 };
    571 
    572 #define CRED_TYPE_COUNT (sizeof (cred_type_tbl) / sizeof (cred_type_tbl[0]))
    573 
    574 /** Index of #GNUTLS_CRD_PSK in #cred_type_tbl. */
    575 #define PSK_CRED_TYPE_IDX 1u
    576 
    577 /**
    578  * The pre-shared key the client uses, and the one #PSK_OK hands back.
    579  * They match, so that variant completes the handshake and MHD goes on to
    580  * serve ordinary HTTP over a session with no certificate at all -- which
    581  * is a different shape again for the connection introspection calls.
    582  *
    583  * Its length is exactly the @c MHD_PSK_MIN_SIZE that psk_gnutls_adapter()
    584  * enforces (16, RFC 4279 section 7.1).  That is not a coincidence and
    585  * the two have to be kept in step: #PSK_OK and #PSK_ONE_SHORT bracket
    586  * the check from both sides, and #PSK_ONE_SHORT derives its length from
    587  * this array.  The minimum is private to daemon.c, so this is a mirror
    588  * rather than a shared constant; if daemon.c changes, so must this.
    589  */
    590 static const unsigned char psk_key_bytes[16] = {
    591   0x9e, 0x1d, 0x4c, 0x7b, 0x30, 0xa5, 0xf2, 0x68,
    592   0x11, 0xc3, 0x54, 0xd9, 0x87, 0x2a, 0x6f, 0xb0
    593 };
    594 
    595 static const size_t mem_limit_tbl[] = {
    596   0 /* MHD default */, 256, 512, 1024, 1400, 1500, 2048, 4096, 8192, 32768,
    597   0, 1024, 2048, 4096, 16384, 0
    598 };
    599 
    600 #define MEM_LIMIT_COUNT (sizeof (mem_limit_tbl) / sizeof (mem_limit_tbl[0]))
    601 
    602 static const char https_key_password[] = "not-the-password";
    603 
    604 
    605 /* ------------------------------------------------------------------ */
    606 /* Per-iteration configuration                                         */
    607 /* ------------------------------------------------------------------ */
    608 
    609 /** Behaviour of the SNI callback, selected by bits 3-5 of byte 3. */
    610 enum sni_behaviour
    611 {
    612   SNI_ALWAYS_OK = 0,      /**< always answer with the signed pair */
    613   SNI_FAIL,               /**< always answer -1 */
    614   SNI_EMPTY,              /**< answer 0 with an empty certificate list */
    615   SNI_BY_NAME,            /**< look the server name up, -1 if unknown */
    616   SNI_MISMATCH,           /**< answer with a key that is not the cert's */
    617   SNI_NO_KEY,             /**< answer 0, certificate but no key */
    618   SNI_SELF_SIGNED,        /**< always answer with the self-signed pair */
    619   SNI_BEHAVIOUR_COUNT
    620 };
    621 
    622 /**
    623  * Behaviour of the PSK credentials callback, selected by bits 3-5 of
    624  * byte 9.  Each entry corresponds to one branch of psk_gnutls_adapter().
    625  */
    626 enum psk_behaviour
    627 {
    628   PSK_OK = 0,             /**< the key the client expects; handshake works */
    629   PSK_FAIL,               /**< the callback answers -1 */
    630   PSK_EMPTY,              /**< a zero length key: rejected as too short */
    631   PSK_LONG,               /**< a 4 KiB key */
    632   PSK_FROM_ID,            /**< key built from the identity the client sent,
    633                                so its length is attacker-chosen and lands
    634                                on either side of MHD_PSK_MIN_SIZE */
    635   PSK_HUGE,               /**< a size above UINT_MAX */
    636   PSK_NO_HANDLER,         /**< the option is not passed at all */
    637   /* Appended rather than grouped with PSK_EMPTY on purpose: the seeds
    638      below encode the behaviour as a literal index, so inserting in the
    639      middle would silently re-point every one of them. */
    640   PSK_ONE_SHORT,          /**< MHD_PSK_MIN_SIZE - 1 bytes: the boundary */
    641   PSK_BEHAVIOUR_COUNT
    642 };
    643 
    644 /** Client behaviour, selected by bits 0-1 of byte 4. */
    645 enum client_mode
    646 {
    647   CLIENT_RAW = 0,         /**< raw bytes straight at the TLS socket */
    648   CLIENT_TLS,             /**< a real GnuTLS client */
    649   CLIENT_TLS_ABANDON,     /**< a real client that stops mid-handshake */
    650   CLIENT_RECORDS          /**< raw bytes shaped like TLS records */
    651 };
    652 
    653 struct fuzz_cfg
    654 {
    655   /* ---- daemon ---- */
    656   const char *cert;
    657   const char *key;
    658   int use_tls;                 /**< set MHD_USE_TLS at all */
    659   int use_trust;
    660   int trust_garbage;
    661   int use_dhparams;
    662   int dh_garbage;
    663   int use_sni;
    664   int use_prio;
    665   int prio_append;
    666   unsigned int prio_idx;
    667   const char *prio_str;        /**< what use_prio actually passes */
    668   int use_cred_type;
    669   unsigned int cred_type_idx;
    670   int no_alpn;
    671   int key_password;
    672   int allow_upgrade;
    673   size_t mem_limit;
    674   unsigned int loop_mode;
    675 
    676   /* ---- SNI callback ---- */
    677   enum sni_behaviour sni_mode;
    678 
    679   /* ---- TLS-PSK ---- */
    680   int psk_scenario;            /**< the whole PSK bundle is on */
    681   enum psk_behaviour psk_mode;
    682 
    683   /* ---- client ---- */
    684   enum client_mode mode;
    685   int client_sni;
    686   int client_cert;
    687   int client_psk;              /**< offer PSK credentials */
    688   unsigned int client_prio_idx;
    689   int client_bye;
    690   int client_shut_wr;
    691   unsigned int hs_budget;      /**< handshake rounds in CLIENT_TLS_ABANDON */
    692   unsigned int extra_pump;
    693 
    694   /* ---- handler ---- */
    695   unsigned int resp_kind;
    696   int conn_info;
    697   int daemon_info;
    698   int conn_option;
    699   int error_reply;
    700   int resp_header;
    701   int quiesce;
    702   int stop_with_queued;        /**< stop with a connection still queued */
    703 };
    704 
    705 static struct fuzz_cfg cfg;
    706 
    707 /**
    708  * Server names the client can present.  Which one is used comes from
    709  * byte 9 of the input; an op 1 segment overrides it.  MHD itself never
    710  * looks at the name -- GnuTLS parses the extension and the application
    711  * callback reads it back -- so a fixed table costs no MHD coverage.
    712  */
    713 static const char *const sni_name_tbl[] = {
    714   "test-mhdserver",
    715   "localhost",
    716   "mhdhost1",
    717   "nobody.example.org",
    718   "",
    719   "example.org",
    720   "TEST-MHDSERVER",
    721   "a.very.long.name.that.nobody.has.a.certificate.for.example.org"
    722 };
    723 
    724 #define SNI_NAME_COUNT (sizeof (sni_name_tbl) / sizeof (sni_name_tbl[0]))
    725 
    726 /** Server name the next client connection presents. */
    727 static char sni_name[MAX_SNI_LEN + 1];
    728 static size_t sni_name_len;
    729 
    730 /** Bytes received from the daemon during the current iteration. */
    731 static char resp_buf[RESP_BUF_SIZE];
    732 static size_t resp_len;
    733 
    734 /** Statistics, printed at exit with --verbose. */
    735 static unsigned long stat_daemons;
    736 static unsigned long stat_daemons_failed;
    737 static unsigned long stat_connections;
    738 static unsigned long stat_handshakes_ok;
    739 static unsigned long stat_handshakes_failed;
    740 static unsigned long stat_handler_calls;
    741 static unsigned long stat_sni_calls;
    742 static unsigned long stat_psk_calls;
    743 static int stats_registered;
    744 
    745 
    746 static void
    747 print_stats (void)
    748 {
    749   if (! fuzz_verbose)
    750     return;
    751   fprintf (stderr,
    752            "%s: daemons=%lu (start failed=%lu) connections=%lu "
    753            "handshakes ok=%lu failed=%lu handler calls=%lu SNI calls=%lu "
    754            "PSK calls=%lu\n",
    755            FUZZ_HARNESS_NAME,
    756            stat_daemons, stat_daemons_failed, stat_connections,
    757            stat_handshakes_ok, stat_handshakes_failed, stat_handler_calls,
    758            stat_sni_calls, stat_psk_calls);
    759 }
    760 
    761 
    762 /* ------------------------------------------------------------------ */
    763 /* The SNI (certificate retrieve) callback                             */
    764 /* ------------------------------------------------------------------ */
    765 
    766 /**
    767  * Certificates for the SNI callback, parsed once and then kept in these
    768  * statics for the whole life of the process: they are configuration, not
    769  * per-iteration state, and re-parsing them on every execution would cost
    770  * more than everything else the harness does.  They are reachable from
    771  * globals, so LeakSanitizer does not count them.
    772  */
    773 struct sni_host
    774 {
    775   const char *name;
    776   const char *cert_pem;
    777   const char *key_pem;
    778   gnutls_pcert_st pcrt;
    779   gnutls_privkey_t key;
    780   int loaded;
    781 };
    782 
    783 static struct sni_host sni_hosts[2] = {
    784   { "test-mhdserver", NULL, NULL, { 0, { NULL, 0 }, 0 }, NULL, 0 },
    785   { "localhost", NULL, NULL, { 0, { NULL, 0 }, 0 }, NULL, 0 }
    786 };
    787 
    788 static int sni_hosts_ready;
    789 
    790 
    791 /**
    792  * @return 0 if the certificates are usable
    793  */
    794 static int
    795 sni_hosts_init (void)
    796 {
    797   unsigned int i;
    798 
    799   if (0 != sni_hosts_ready)
    800     return (1 == sni_hosts_ready) ? 0 : -1;
    801   sni_hosts[0].cert_pem = srv_signed_cert_pem;
    802   sni_hosts[0].key_pem = srv_signed_key_pem;
    803   sni_hosts[1].cert_pem = srv_self_signed_cert_pem;
    804   sni_hosts[1].key_pem = srv_self_signed_key_pem;
    805   sni_hosts_ready = 1;
    806   for (i = 0; i < sizeof (sni_hosts) / sizeof (sni_hosts[0]); i++)
    807   {
    808     struct sni_host *h = &sni_hosts[i];
    809     gnutls_datum_t d;
    810 
    811     d.data = (unsigned char *) (intptr_t) h->cert_pem;
    812     d.size = (unsigned int) strlen (h->cert_pem);
    813     if (GNUTLS_E_SUCCESS !=
    814         gnutls_pcert_import_x509_raw (&h->pcrt, &d, GNUTLS_X509_FMT_PEM, 0))
    815     {
    816       sni_hosts_ready = -1;
    817       continue;
    818     }
    819     if (GNUTLS_E_SUCCESS != gnutls_privkey_init (&h->key))
    820     {
    821       gnutls_pcert_deinit (&h->pcrt);
    822       sni_hosts_ready = -1;
    823       continue;
    824     }
    825     d.data = (unsigned char *) (intptr_t) h->key_pem;
    826     d.size = (unsigned int) strlen (h->key_pem);
    827     if (GNUTLS_E_SUCCESS !=
    828         gnutls_privkey_import_x509_raw (h->key, &d, GNUTLS_X509_FMT_PEM,
    829                                         NULL, 0))
    830     {
    831       gnutls_privkey_deinit (h->key);
    832       h->key = NULL;
    833       gnutls_pcert_deinit (&h->pcrt);
    834       sni_hosts_ready = -1;
    835       continue;
    836     }
    837     h->loaded = 1;
    838   }
    839   return (1 == sni_hosts_ready) ? 0 : -1;
    840 }
    841 
    842 
    843 /**
    844  * #MHD_OPTION_HTTPS_CERT_CALLBACK.  Deliberately badly behaved for most
    845  * of the settings of @e cfg.sni_mode: an application callback that fails
    846  * or answers with nothing is exactly the case MHD has to survive.
    847  */
    848 static int
    849 sni_callback (gnutls_session_t session,
    850               const gnutls_datum_t *req_ca_dn,
    851               int nreqs,
    852               const gnutls_pk_algorithm_t *pk_algos,
    853               int pk_algos_length,
    854               gnutls_pcert_st **pcert,
    855               unsigned int *pcert_length,
    856               gnutls_privkey_t *pkey)
    857 {
    858   char name[MAX_SNI_LEN + 1];
    859   size_t name_len = sizeof (name);
    860   unsigned int type;
    861   unsigned int i;
    862 
    863   (void) req_ca_dn;
    864   (void) nreqs;
    865   (void) pk_algos;
    866   (void) pk_algos_length;
    867   stat_sni_calls++;
    868   if (! sni_hosts[0].loaded)
    869     return -1;
    870   switch (cfg.sni_mode)
    871   {
    872   case SNI_FAIL:
    873     return -1;
    874   case SNI_EMPTY:
    875     *pcert = NULL;
    876     *pcert_length = 0;
    877     *pkey = NULL;
    878     return 0;
    879   case SNI_NO_KEY:
    880     *pcert = &sni_hosts[0].pcrt;
    881     *pcert_length = 1;
    882     *pkey = NULL;
    883     return 0;
    884   case SNI_MISMATCH:
    885     if (! sni_hosts[1].loaded)
    886       return -1;
    887     *pcert = &sni_hosts[0].pcrt;
    888     *pcert_length = 1;
    889     *pkey = sni_hosts[1].key;
    890     return 0;
    891   case SNI_SELF_SIGNED:
    892     if (! sni_hosts[1].loaded)
    893       return -1;
    894     *pcert = &sni_hosts[1].pcrt;
    895     *pcert_length = 1;
    896     *pkey = sni_hosts[1].key;
    897     return 0;
    898   case SNI_BY_NAME:
    899     if (GNUTLS_E_SUCCESS !=
    900         gnutls_server_name_get (session, name, &name_len, &type, 0))
    901       return -1;
    902     for (i = 0; i < sizeof (sni_hosts) / sizeof (sni_hosts[0]); i++)
    903       if ( (sni_hosts[i].loaded) &&
    904            (0 == strncmp (name, sni_hosts[i].name, name_len)) )
    905       {
    906         *pcert = &sni_hosts[i].pcrt;
    907         *pcert_length = 1;
    908         *pkey = sni_hosts[i].key;
    909         return 0;
    910       }
    911     return -1;
    912   case SNI_ALWAYS_OK:
    913   case SNI_BEHAVIOUR_COUNT:
    914   default:
    915     break;
    916   }
    917   *pcert = &sni_hosts[0].pcrt;
    918   *pcert_length = 1;
    919   *pkey = sni_hosts[0].key;
    920   return 0;
    921 }
    922 
    923 
    924 /* ------------------------------------------------------------------ */
    925 /* The application                                                     */
    926 /* ------------------------------------------------------------------ */
    927 
    928 static const char resp_body[] = "hello world over TLS";
    929 
    930 
    931 static enum MHD_Result
    932 ahc (void *cls,
    933      struct MHD_Connection *connection,
    934      const char *url,
    935      const char *method,
    936      const char *version,
    937      const char *upload_data,
    938      size_t *upload_data_size,
    939      void **req_cls)
    940 {
    941   static int marker;
    942   struct MHD_Response *r;
    943   enum MHD_Result ret;
    944 
    945   (void) cls;
    946   (void) url;
    947   (void) method;
    948   (void) version;
    949   (void) upload_data;
    950   stat_handler_calls++;
    951   if (NULL == *req_cls)
    952   {
    953     /* first call: MHD only wants to know that we are interested */
    954     *req_cls = &marker;
    955     return MHD_YES;
    956   }
    957   if (0 != *upload_data_size)
    958   {
    959     /* discard the request body */
    960     *upload_data_size = 0;
    961     return MHD_YES;
    962   }
    963   if (cfg.conn_info)
    964   {
    965     /* The TLS-specific members of MHD_ConnectionInfo; all three answer
    966        NULL on a connection without a session, which is a state this
    967        harness can produce. */
    968     (void) MHD_get_connection_info (connection,
    969                                     MHD_CONNECTION_INFO_CIPHER_ALGO);
    970     (void) MHD_get_connection_info (connection,
    971                                     MHD_CONNECTION_INFO_PROTOCOL);
    972     (void) MHD_get_connection_info (connection,
    973                                     MHD_CONNECTION_INFO_GNUTLS_SESSION);
    974     (void) MHD_get_connection_info (connection,
    975                                     MHD_CONNECTION_INFO_GNUTLS_CLIENT_CERT);
    976     (void) MHD_get_connection_info (connection,
    977                                     MHD_CONNECTION_INFO_CLIENT_ADDRESS);
    978     (void) MHD_get_connection_info (connection,
    979                                     MHD_CONNECTION_INFO_CONNECTION_FD);
    980   }
    981   if (cfg.conn_option)
    982     (void) MHD_set_connection_option (connection,
    983                                       MHD_CONNECTION_OPTION_TIMEOUT,
    984                                       (unsigned int) 0);
    985   switch (cfg.resp_kind)
    986   {
    987   case 1:
    988     r = MHD_create_response_from_buffer_copy (sizeof (resp_body) - 1,
    989                                               resp_body);
    990     break;
    991   case 2:
    992     r = MHD_create_response_empty (MHD_RF_NONE);
    993     break;
    994   case 3:
    995     r = MHD_create_response_from_buffer_static (0, "");
    996     break;
    997   case 0:
    998   default:
    999     r = MHD_create_response_from_buffer_static (sizeof (resp_body) - 1,
   1000                                                 resp_body);
   1001     break;
   1002   }
   1003   if (NULL == r)
   1004     return MHD_NO;
   1005   if (cfg.resp_header)
   1006     (void) MHD_add_response_header (r, "X-Fuzz", "tls");
   1007   ret = MHD_queue_response (connection,
   1008                             cfg.error_reply
   1009                             ? MHD_HTTP_FORBIDDEN
   1010                             : MHD_HTTP_OK,
   1011                             r);
   1012   MHD_destroy_response (r);
   1013   return ret;
   1014 }
   1015 
   1016 
   1017 static void
   1018 panic_cb (void *cls,
   1019           const char *file,
   1020           unsigned int line,
   1021           const char *reason)
   1022 {
   1023   char msg[512];
   1024 
   1025   (void) cls;
   1026   (void) snprintf (msg, sizeof (msg),
   1027                    "MHD_PANIC() reached at %s:%u: %s",
   1028                    (NULL != file) ? file : "?",
   1029                    line,
   1030                    (NULL != reason) ? reason : "?");
   1031   fuzz_report_finding (msg);
   1032 }
   1033 
   1034 
   1035 /* ------------------------------------------------------------------ */
   1036 /* Driving the daemon                                                  */
   1037 /* ------------------------------------------------------------------ */
   1038 
   1039 /**
   1040  * Advance the daemon by one cycle, through the event-loop API selected
   1041  * by byte 5 of the input.  The select() timeout is always zero: the
   1042  * harness is single threaded, whatever the daemon is waiting for has
   1043  * already been written into the socketpair, and blocking would only burn
   1044  * wall clock.
   1045  */
   1046 static void
   1047 run_once (struct MHD_Daemon *d)
   1048 {
   1049   fd_set rs;
   1050   fd_set ws;
   1051   fd_set es;
   1052   MHD_socket max_fd = MHD_INVALID_SOCKET;
   1053   struct timeval tv;
   1054 
   1055   if (0 == cfg.loop_mode)
   1056   {
   1057     (void) MHD_run (d);
   1058     return;
   1059   }
   1060   FD_ZERO (&rs);
   1061   FD_ZERO (&ws);
   1062   FD_ZERO (&es);
   1063   if (1 == cfg.loop_mode)
   1064   {
   1065     /* Parenthesised so that the real v1 function is called: microhttpd.h
   1066        also defines MHD_get_fdset as a macro forwarding to
   1067        MHD_get_fdset2.  Same trick for MHD_run_from_select below. */
   1068     if (MHD_YES != (MHD_get_fdset) (d, &rs, &ws, &es, &max_fd))
   1069     {
   1070       (void) MHD_run (d);
   1071       return;
   1072     }
   1073   }
   1074   else
   1075   {
   1076     if (MHD_YES != MHD_get_fdset2 (d, &rs, &ws, &es, &max_fd,
   1077                                    (unsigned int) FD_SETSIZE))
   1078     {
   1079       (void) MHD_run (d);
   1080       return;
   1081     }
   1082   }
   1083   tv.tv_sec = 0;
   1084   tv.tv_usec = 0;
   1085   if (MHD_INVALID_SOCKET != max_fd)
   1086     (void) select ((int) max_fd + 1, &rs, &ws, &es, &tv);
   1087   if (1 == cfg.loop_mode)
   1088     (void) (MHD_run_from_select) (d, &rs, &ws, &es);
   1089   else
   1090     (void) MHD_run_from_select2 (d, &rs, &ws, &es, (unsigned int) FD_SETSIZE);
   1091 }
   1092 
   1093 
   1094 /* ------------------------------------------------------------------ */
   1095 /* The PSK credentials callback                                        */
   1096 /* ------------------------------------------------------------------ */
   1097 
   1098 #if GNUTLS_VERSION_MAJOR >= 3
   1099 
   1100 /**
   1101  * #MHD_OPTION_GNUTLS_PSK_CRED_HANDLER.  GnuTLS calls
   1102  * psk_gnutls_adapter() with the identity the client sent, and that
   1103  * function calls this; whatever comes back is copied into a
   1104  * gnutls_malloc()ed buffer and handed to GnuTLS, with @a psk freed by
   1105  * MHD on every path.  The buffer therefore has to come from plain
   1106  * malloc() -- see the doxygen on #MHD_PskServerCredentialsCallback.
   1107  *
   1108  * @param cls unused
   1109  * @param connection the connection GnuTLS is handshaking
   1110  * @param username the identity claimed by the client
   1111  * @param[out] psk the key
   1112  * @param[out] psk_size its length
   1113  * @return 0 on success, -1 on error
   1114  */
   1115 static int
   1116 psk_cred_cb (void *cls,
   1117              const struct MHD_Connection *connection,
   1118              const char *username,
   1119              void **psk,
   1120              size_t *psk_size)
   1121 {
   1122   unsigned char *buf;
   1123   size_t len;
   1124 
   1125   (void) cls;
   1126   (void) connection;
   1127   stat_psk_calls++;
   1128 
   1129   switch (cfg.psk_mode)
   1130   {
   1131   case PSK_FAIL:
   1132     return -1;
   1133   case PSK_EMPTY:
   1134     len = 0;
   1135     break;
   1136   case PSK_ONE_SHORT:
   1137     /* One byte below the minimum the adapter enforces.  Deliberately
   1138        written in terms of sizeof (psk_key_bytes), which is exactly that
   1139        minimum, so this stays on the boundary if the minimum changes. */
   1140     len = sizeof (psk_key_bytes) - 1;
   1141     break;
   1142   case PSK_LONG:
   1143     len = 4096;
   1144     break;
   1145   case PSK_FROM_ID:
   1146     len = (NULL != username) ? strlen (username) : 0;
   1147     if (len > 1024)
   1148       len = 1024;
   1149     break;
   1150   case PSK_HUGE:
   1151 #if SIZE_MAX > UINT_MAX
   1152     /* The size MHD is told about, not the size allocated: the point is
   1153        the "PSK too long" branch, which rejects before reading @a psk.
   1154        MHD still free()s the pointer, so it has to be a real one. */
   1155     buf = (unsigned char *) malloc (1);
   1156     if (NULL == buf)
   1157       return -1;
   1158     buf[0] = 0;
   1159     *psk = buf;
   1160     *psk_size = (size_t) UINT_MAX + 1u;
   1161     return 0;
   1162 #else
   1163     len = sizeof (psk_key_bytes);
   1164     break;
   1165 #endif
   1166   case PSK_OK:
   1167   case PSK_NO_HANDLER:  /* not reached: the option is not passed at all */
   1168   case PSK_BEHAVIOUR_COUNT:
   1169   default:
   1170     len = sizeof (psk_key_bytes);
   1171     break;
   1172   }
   1173 
   1174   /* malloc(0) may answer NULL, which would be indistinguishable from
   1175      failure here; always ask for at least one byte and report the length
   1176      separately. */
   1177   buf = (unsigned char *) malloc (0 != len ? len : 1);
   1178   if (NULL == buf)
   1179     return -1;
   1180   if (0 != len)
   1181   {
   1182     size_t i;
   1183 
   1184     for (i = 0; i < len; i++)
   1185       buf[i] = psk_key_bytes[i % sizeof (psk_key_bytes)];
   1186   }
   1187   else
   1188     buf[0] = 0;
   1189   *psk = buf;
   1190   *psk_size = len;
   1191   return 0;
   1192 }
   1193 
   1194 
   1195 #endif /* GNUTLS_VERSION_MAJOR >= 3 */
   1196 
   1197 
   1198 /* ------------------------------------------------------------------ */
   1199 /* The in-process TLS client                                           */
   1200 /* ------------------------------------------------------------------ */
   1201 
   1202 struct tls_client
   1203 {
   1204   gnutls_session_t sess;                    /**< NULL in the raw modes */
   1205   gnutls_certificate_credentials_t cred;
   1206   gnutls_psk_client_credentials_t psk;      /**< only in the PSK scenario */
   1207   int fd;                                   /**< our end of the socketpair */
   1208   int hs_done;
   1209   int dead;
   1210 };
   1211 
   1212 
   1213 static void
   1214 pump (struct MHD_Daemon *d,
   1215       unsigned int rounds)
   1216 {
   1217   unsigned int i;
   1218 
   1219   for (i = 0; i < rounds; i++)
   1220     run_once (d);
   1221 }
   1222 
   1223 
   1224 /**
   1225  * Read whatever the daemon has produced so far.  In the raw modes this
   1226  * is a plain recv(); with a real client it goes through GnuTLS, which is
   1227  * what actually drives MHD's send path and its TLS shutdown handling.
   1228  */
   1229 static void
   1230 tc_drain (struct tls_client *tc)
   1231 {
   1232   unsigned int i;
   1233   char tmp[4096];
   1234 
   1235   if (0 > tc->fd)
   1236     return;
   1237   if (NULL == tc->sess)
   1238   {
   1239     for (;;)
   1240     {
   1241       ssize_t n = recv (tc->fd, tmp, sizeof (tmp), MSG_DONTWAIT);
   1242 
   1243       if (0 >= n)
   1244         break;
   1245       if (resp_len + (size_t) n < RESP_BUF_SIZE)
   1246       {
   1247         memcpy (resp_buf + resp_len, tmp, (size_t) n);
   1248         resp_len += (size_t) n;
   1249       }
   1250     }
   1251     return;
   1252   }
   1253   if (tc->dead || (! tc->hs_done))
   1254     return;
   1255   for (i = 0; i < 8; i++)
   1256   {
   1257     ssize_t n = gnutls_record_recv (tc->sess, tmp, sizeof (tmp));
   1258 
   1259     if (0 < n)
   1260     {
   1261       if (resp_len + (size_t) n < RESP_BUF_SIZE)
   1262       {
   1263         memcpy (resp_buf + resp_len, tmp, (size_t) n);
   1264         resp_len += (size_t) n;
   1265       }
   1266       continue;
   1267     }
   1268     if (0 == n)
   1269       break;                    /* peer closed the TLS connection */
   1270     if ( (GNUTLS_E_AGAIN == n) ||
   1271          (GNUTLS_E_INTERRUPTED == n) )
   1272       break;
   1273     if (0 != gnutls_error_is_fatal ((int) n))
   1274       tc->dead = 1;
   1275     break;
   1276   }
   1277 }
   1278 
   1279 
   1280 static void
   1281 pump_and_drain (struct MHD_Daemon *d,
   1282                 struct tls_client *tc,
   1283                 unsigned int rounds)
   1284 {
   1285   unsigned int i;
   1286 
   1287   for (i = 0; i < rounds; i++)
   1288   {
   1289     run_once (d);
   1290     tc_drain (tc);
   1291   }
   1292 }
   1293 
   1294 
   1295 /**
   1296  * Let the client and the daemon take turns at the handshake until it
   1297  * completes, fails, or @a rounds is exhausted.  Exhausting @a rounds on
   1298  * purpose (client mode 2) is what leaves MHD's connection parked in
   1299  * #MHD_TLS_CONN_HANDSHAKING.
   1300  */
   1301 static void
   1302 tc_handshake (struct MHD_Daemon *d,
   1303               struct tls_client *tc,
   1304               unsigned int rounds)
   1305 {
   1306   unsigned int i;
   1307 
   1308   if ( (NULL == tc->sess) ||
   1309        (0 != tc->dead) ||
   1310        (0 != tc->hs_done) )
   1311     return;
   1312   for (i = 0; i < rounds; i++)
   1313   {
   1314     int ret = gnutls_handshake (tc->sess);
   1315 
   1316     if (GNUTLS_E_SUCCESS == ret)
   1317     {
   1318       tc->hs_done = 1;
   1319       stat_handshakes_ok++;
   1320       return;
   1321     }
   1322     if (0 != gnutls_error_is_fatal (ret))
   1323     {
   1324       tc->dead = 1;
   1325       stat_handshakes_failed++;
   1326       return;
   1327     }
   1328     /* GNUTLS_E_AGAIN / GNUTLS_E_INTERRUPTED / a warning alert: give the
   1329        daemon a chance to answer. */
   1330     run_once (d);
   1331   }
   1332 }
   1333 
   1334 
   1335 /**
   1336  * Open a fresh connection: a socketpair, one end handed to MHD with
   1337  * MHD_add_connection(), the other end ours.  With a real client the
   1338  * GnuTLS session is set up here too, but the handshake itself is driven
   1339  * by tc_handshake().
   1340  *
   1341  * @return 0 on success
   1342  */
   1343 static int
   1344 tc_open (struct MHD_Daemon *d,
   1345          struct tls_client *tc)
   1346 {
   1347   int sv[2];
   1348   struct sockaddr_in sa;
   1349   int fl;
   1350 #if GNUTLS_VERSION_NUMBER >= 0x030500
   1351   gnutls_init_flags_t flags;
   1352 #else
   1353   unsigned int flags;
   1354 #endif
   1355 
   1356   memset (tc, 0, sizeof (*tc));
   1357   tc->fd = -1;
   1358   if (0 != socketpair (AF_UNIX, SOCK_STREAM, 0, sv))
   1359     return -1;
   1360   memset (&sa, 0, sizeof (sa));
   1361   sa.sin_family = AF_INET;
   1362   sa.sin_port = htons (44444);
   1363   sa.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
   1364   if (MHD_YES != MHD_add_connection (d,
   1365                                      (MHD_socket) sv[1],
   1366                                      (const struct sockaddr *) &sa,
   1367                                      (socklen_t) sizeof (sa)))
   1368   {
   1369     /* MHD has already closed sv[1] in that case */
   1370     (void) close (sv[0]);
   1371     return -1;
   1372   }
   1373   tc->fd = sv[0];
   1374   stat_connections++;
   1375   /* Our end must never block: the daemon is pumped from this very
   1376      thread, so a blocking write would deadlock the process. */
   1377   fl = fcntl (tc->fd, F_GETFL, 0);
   1378   if (0 <= fl)
   1379     (void) fcntl (tc->fd, F_SETFL, fl | O_NONBLOCK);
   1380   if ( (CLIENT_TLS != cfg.mode) &&
   1381        (CLIENT_TLS_ABANDON != cfg.mode) )
   1382     return 0;
   1383 
   1384   if (GNUTLS_E_SUCCESS !=
   1385       gnutls_certificate_allocate_credentials (&tc->cred))
   1386   {
   1387     tc->cred = NULL;
   1388     tc->dead = 1;
   1389     return 0;
   1390   }
   1391   if (cfg.client_cert)
   1392   {
   1393     gnutls_datum_t c;
   1394     gnutls_datum_t k;
   1395 
   1396     c.data = (unsigned char *) (intptr_t) srv_self_signed_cert_pem;
   1397     c.size = (unsigned int) strlen (srv_self_signed_cert_pem);
   1398     k.data = (unsigned char *) (intptr_t) srv_self_signed_key_pem;
   1399     k.size = (unsigned int) strlen (srv_self_signed_key_pem);
   1400     (void) gnutls_certificate_set_x509_key_mem (tc->cred, &c, &k,
   1401                                                 GNUTLS_X509_FMT_PEM);
   1402   }
   1403   flags = GNUTLS_CLIENT;
   1404 #if GNUTLS_VERSION_MAJOR >= 3
   1405   flags |= GNUTLS_NONBLOCK;
   1406 #endif
   1407 #if GNUTLS_VERSION_NUMBER >= 0x030402
   1408   flags |= GNUTLS_NO_SIGNAL;
   1409 #endif
   1410   if (GNUTLS_E_SUCCESS != gnutls_init (&tc->sess, flags))
   1411   {
   1412     tc->sess = NULL;
   1413     tc->dead = 1;
   1414     return 0;
   1415   }
   1416   if (GNUTLS_E_SUCCESS !=
   1417       gnutls_priority_set_direct (tc->sess,
   1418                                   cfg.psk_scenario
   1419                                   ? psk_prio_tbl[cfg.client_prio_idx]
   1420                                   : client_prio_tbl[cfg.client_prio_idx],
   1421                                   NULL))
   1422     (void) gnutls_priority_set_direct (tc->sess, "NORMAL", NULL);
   1423   if (GNUTLS_E_SUCCESS !=
   1424       gnutls_credentials_set (tc->sess, GNUTLS_CRD_CERTIFICATE, tc->cred))
   1425     tc->dead = 1;
   1426   if (cfg.client_psk)
   1427   {
   1428     /* The identity is the same string byte 9 (or an op 1 segment) picked
   1429        for SNI; it is what arrives as @a username in psk_gnutls_adapter().
   1430        A client that offers no PSK credentials at all against a PSK-only
   1431        server is the other half of this: the handshake then fails without
   1432        the adapter ever being asked. */
   1433     gnutls_datum_t k;
   1434 
   1435     k.data = (unsigned char *) (intptr_t) psk_key_bytes;
   1436     k.size = (unsigned int) sizeof (psk_key_bytes);
   1437     if (GNUTLS_E_SUCCESS !=
   1438         gnutls_psk_allocate_client_credentials (&tc->psk))
   1439       tc->psk = NULL;
   1440     else
   1441     {
   1442       if (GNUTLS_E_SUCCESS !=
   1443           gnutls_psk_set_client_credentials (tc->psk,
   1444                                              sni_name,
   1445                                              &k,
   1446                                              GNUTLS_PSK_KEY_RAW))
   1447         tc->dead = 1;
   1448       else if (GNUTLS_E_SUCCESS !=
   1449                gnutls_credentials_set (tc->sess, GNUTLS_CRD_PSK, tc->psk))
   1450         tc->dead = 1;
   1451     }
   1452   }
   1453   if ( (cfg.client_sni) &&
   1454        (0 != sni_name_len) )
   1455     (void) gnutls_server_name_set (tc->sess,
   1456                                    GNUTLS_NAME_DNS,
   1457                                    sni_name,
   1458                                    sni_name_len);
   1459   gnutls_transport_set_int (tc->sess, tc->fd);
   1460   /* GNUTLS_INDEFINITE_TIMEOUT: the default handshake timeout is a wall
   1461      clock deadline, and this harness must not depend on the clock. */
   1462   gnutls_handshake_set_timeout (tc->sess, 0);
   1463   return 0;
   1464 }
   1465 
   1466 
   1467 static void
   1468 tc_send (struct MHD_Daemon *d,
   1469          struct tls_client *tc,
   1470          const uint8_t *buf,
   1471          size_t len)
   1472 {
   1473   size_t off = 0;
   1474   unsigned int stall = 0;
   1475 
   1476   if ( (0 > tc->fd) ||
   1477        (0 == len) )
   1478     return;
   1479   if (NULL == tc->sess)
   1480   {
   1481     while ( (off < len) &&
   1482             (stall < 64) )
   1483     {
   1484       ssize_t s = send (tc->fd, buf + off, len - off, MSG_DONTWAIT);
   1485 
   1486       if (0 < s)
   1487       {
   1488         off += (size_t) s;
   1489         stall = 0;
   1490         continue;
   1491       }
   1492       stall++;
   1493       pump_and_drain (d, tc, 2);
   1494       if ( (0 > s) &&
   1495            (EAGAIN != errno) &&
   1496            (EWOULDBLOCK != errno) &&
   1497            (EINTR != errno) )
   1498         break;
   1499     }
   1500     return;
   1501   }
   1502   if ( (0 != tc->dead) ||
   1503        (0 == tc->hs_done) )
   1504     return;
   1505   while ( (off < len) &&
   1506           (stall < 64) )
   1507   {
   1508     /* On GNUTLS_E_AGAIN the call has to be repeated with exactly the
   1509        same arguments, which is why @a off is only advanced on success. */
   1510     ssize_t s = gnutls_record_send (tc->sess, buf + off, len - off);
   1511 
   1512     if (0 < s)
   1513     {
   1514       off += (size_t) s;
   1515       stall = 0;
   1516       continue;
   1517     }
   1518     if ( (GNUTLS_E_AGAIN == s) ||
   1519          (GNUTLS_E_INTERRUPTED == s) )
   1520     {
   1521       stall++;
   1522       pump_and_drain (d, tc, 2);
   1523       continue;
   1524     }
   1525     if (0 != gnutls_error_is_fatal ((int) s))
   1526       tc->dead = 1;
   1527     break;
   1528   }
   1529 }
   1530 
   1531 
   1532 /**
   1533  * Tear the client end down.  Every GnuTLS object is released on every
   1534  * path, including the ones where the session never got off the ground.
   1535  */
   1536 static void
   1537 tc_close (struct MHD_Daemon *d,
   1538           struct tls_client *tc)
   1539 {
   1540   if (NULL != tc->sess)
   1541   {
   1542     if ( (cfg.client_bye) &&
   1543          (0 == tc->dead) &&
   1544          (0 != tc->hs_done) )
   1545     {
   1546       unsigned int i;
   1547 
   1548       for (i = 0; i < 8; i++)
   1549       {
   1550         int ret = gnutls_bye (tc->sess, GNUTLS_SHUT_WR);
   1551 
   1552         if ( (GNUTLS_E_AGAIN != ret) &&
   1553              (GNUTLS_E_INTERRUPTED != ret) )
   1554           break;
   1555         run_once (d);
   1556       }
   1557     }
   1558     gnutls_deinit (tc->sess);
   1559     tc->sess = NULL;
   1560   }
   1561   if (NULL != tc->cred)
   1562   {
   1563     gnutls_certificate_free_credentials (tc->cred);
   1564     tc->cred = NULL;
   1565   }
   1566   if (NULL != tc->psk)
   1567   {
   1568     gnutls_psk_free_client_credentials (tc->psk);
   1569     tc->psk = NULL;
   1570   }
   1571   if (0 <= tc->fd)
   1572   {
   1573     if (cfg.client_shut_wr)
   1574       (void) shutdown (tc->fd, SHUT_WR);
   1575     pump (d, 2);
   1576     (void) close (tc->fd);
   1577     tc->fd = -1;
   1578   }
   1579   tc->hs_done = 0;
   1580   tc->dead = 1;
   1581   pump (d, 4);
   1582 }
   1583 
   1584 
   1585 /**
   1586  * Hand the daemon one more connection and do not run the loop again.
   1587  *
   1588  * See the comment at the call site: this is what leaves a fully prepared
   1589  * connection -- GnuTLS session and all -- on the daemon's
   1590  * new_connections list when MHD_stop_daemon() runs.
   1591  *
   1592  * @param d the daemon, about to be stopped
   1593  * @return our end of the socket pair, or -1 if nothing was queued
   1594  */
   1595 static int
   1596 queue_unprocessed_conn (struct MHD_Daemon *d)
   1597 {
   1598   int sv[2];
   1599   struct sockaddr_in sa;
   1600 
   1601   if (0 != socketpair (AF_UNIX, SOCK_STREAM, 0, sv))
   1602     return -1;
   1603   memset (&sa, 0, sizeof (sa));
   1604   sa.sin_family = AF_INET;
   1605   sa.sin_port = htons (44444);
   1606   sa.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
   1607   if (MHD_YES != MHD_add_connection (d,
   1608                                      (MHD_socket) sv[1],
   1609                                      (const struct sockaddr *) &sa,
   1610                                      (socklen_t) sizeof (sa)))
   1611   {
   1612     /* MHD has closed sv[1] already. */
   1613     (void) close (sv[0]);
   1614     return -1;
   1615   }
   1616   return sv[0];
   1617 }
   1618 
   1619 
   1620 /**
   1621  * Bring a fresh connection up to the point where payload can be sent.
   1622  */
   1623 static void
   1624 tc_start (struct MHD_Daemon *d,
   1625           struct tls_client *tc)
   1626 {
   1627   if (0 != tc_open (d, tc))
   1628   {
   1629     tc->fd = -1;
   1630     return;
   1631   }
   1632   if (CLIENT_TLS == cfg.mode)
   1633     tc_handshake (d, tc, HANDSHAKE_ROUNDS);
   1634   else if (CLIENT_TLS_ABANDON == cfg.mode)
   1635     tc_handshake (d, tc, cfg.hs_budget);
   1636   else
   1637     pump (d, 1);
   1638 }
   1639 
   1640 
   1641 /* ------------------------------------------------------------------ */
   1642 /* PEM blobs assembled from the input                                  */
   1643 /* ------------------------------------------------------------------ */
   1644 
   1645 /**
   1646  * Build @a out as "-----BEGIN @a label-----\n<body>\n-----END @a
   1647  * label-----\n", with @a body_len bytes of @a body as the payload.  The
   1648  * result is always NUL terminated, because MHD calls strlen() on it.
   1649  */
   1650 static void
   1651 build_fuzz_pem (char *out,
   1652                 size_t out_size,
   1653                 const char *label,
   1654                 const uint8_t *body,
   1655                 size_t body_len)
   1656 {
   1657   size_t o = 0;
   1658   size_t i;
   1659   int n;
   1660 
   1661   n = snprintf (out, out_size, "-----BEGIN %s-----\n", label);
   1662   if ( (0 > n) ||
   1663        ((size_t) n >= out_size) )
   1664   {
   1665     out[0] = '\0';
   1666     return;
   1667   }
   1668   o = (size_t) n;
   1669   if (body_len > FUZZ_PEM_BODY_MAX)
   1670     body_len = FUZZ_PEM_BODY_MAX;
   1671   for (i = 0; (i < body_len) && (o + 32 < out_size); i++)
   1672   {
   1673     /* Keep the blob a C string; a NUL inside would simply truncate it
   1674        for MHD's strlen(), which is a less interesting shape. */
   1675     out[o++] = (char) ((0 == body[i]) ? 'A' : body[i]);
   1676   }
   1677   n = snprintf (out + o, out_size - o, "\n-----END %s-----\n", label);
   1678   if (0 > n)
   1679     out[o] = '\0';
   1680 }
   1681 
   1682 
   1683 /* ------------------------------------------------------------------ */
   1684 /* The fuzz target                                                     */
   1685 /* ------------------------------------------------------------------ */
   1686 
   1687 int
   1688 LLVMFuzzerTestOneInput (const uint8_t *data,
   1689                         size_t size)
   1690 {
   1691   struct MHD_Daemon *d;
   1692   struct MHD_OptionItem opts[12];
   1693   unsigned int nopt = 0;
   1694   unsigned int flags;
   1695   struct tls_client tc;
   1696   size_t pos;
   1697   unsigned int nseg = 0;
   1698   unsigned int nconn = 1;
   1699   int queued_fd = -1;          /**< see queue_unprocessed_conn() */
   1700 
   1701   /* Must happen before the first write() into the socketpair; see
   1702      fuzz_ignore_sigpipe() in fuzz_common.h for why the process dies
   1703      without it.  Idempotent. */
   1704   fuzz_ignore_sigpipe ();
   1705 
   1706   /* The ten configuration bytes are mandatory. */
   1707   if (size < 10)
   1708     return 0;
   1709 
   1710   resp_len = 0;
   1711   memset (&cfg, 0, sizeof (cfg));
   1712 
   1713   {
   1714     const char *nm = sni_name_tbl[(data[9] & 0x07) % SNI_NAME_COUNT];
   1715 
   1716     sni_name_len = strlen (nm);
   1717     memcpy (sni_name, nm, sni_name_len + 1);
   1718   }
   1719 
   1720   cfg.cert = cred_tbl[data[0] % CRED_COUNT].cert;
   1721   cfg.key = cred_tbl[data[0] % CRED_COUNT].key;
   1722 
   1723   cfg.use_trust = (0 != (data[1] & 0x01));
   1724   cfg.use_dhparams = (0 != (data[1] & 0x02));
   1725   cfg.use_sni = (0 != (data[1] & 0x04));
   1726   cfg.use_prio = (0 != (data[1] & 0x08));
   1727   cfg.use_cred_type = (0 != (data[1] & 0x10));
   1728   cfg.no_alpn = (0 != (data[1] & 0x20));
   1729   cfg.key_password = (0 != (data[1] & 0x40));
   1730   cfg.prio_append = (0 != (data[1] & 0x80));
   1731 
   1732   cfg.prio_idx = (unsigned int) (data[2] % PRIO_COUNT);
   1733 
   1734   cfg.cred_type_idx = (unsigned int) (data[3] & 0x07) % CRED_TYPE_COUNT;
   1735   cfg.sni_mode =
   1736     (enum sni_behaviour) (((unsigned int) (data[3] >> 3) & 0x07)
   1737                           % (unsigned int) SNI_BEHAVIOUR_COUNT);
   1738   cfg.trust_garbage = (0 != (data[3] & 0x40));
   1739   cfg.dh_garbage = (0 != (data[3] & 0x80));
   1740 
   1741   cfg.prio_str = prio_tbl[cfg.prio_idx];
   1742 
   1743   cfg.mode = (enum client_mode) (data[4] & 0x03);
   1744   cfg.client_sni = (0 != (data[4] & 0x04));
   1745   cfg.client_cert = (0 != (data[4] & 0x08));
   1746   cfg.client_prio_idx = (unsigned int) ((data[4] >> 4) & 0x03);
   1747   cfg.client_bye = (0 != (data[4] & 0x40));
   1748   cfg.client_shut_wr = (0 != (data[4] & 0x80));
   1749 
   1750   cfg.mem_limit = mem_limit_tbl[(data[5] & 0x0F) % MEM_LIMIT_COUNT];
   1751   cfg.loop_mode = (unsigned int) ((data[5] >> 4) & 0x03);
   1752   cfg.stop_with_queued = (0 != (data[5] & 0x40));
   1753 
   1754   cfg.resp_kind = (unsigned int) (data[6] & 0x03);
   1755   cfg.conn_info = (0 != (data[6] & 0x04));
   1756   cfg.daemon_info = (0 != (data[6] & 0x08));
   1757   cfg.conn_option = (0 != (data[6] & 0x10));
   1758   cfg.error_reply = (0 != (data[6] & 0x20));
   1759   cfg.resp_header = (0 != (data[6] & 0x40));
   1760   cfg.quiesce = (0 != (data[6] & 0x80));
   1761 
   1762   cfg.hs_budget = 1u + (unsigned int) (data[7] & 0x07);
   1763   cfg.use_tls = (0 == (data[7] & 0x08));
   1764   cfg.allow_upgrade =
   1765     (0 != (data[7] & 0x10)) &&
   1766     (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_UPGRADE));
   1767   cfg.extra_pump = (unsigned int) ((data[7] >> 5) & 0x07);
   1768 
   1769   cfg.psk_mode =
   1770     (enum psk_behaviour) (((unsigned int) (data[9] >> 3) & 0x07)
   1771                           % (unsigned int) PSK_BEHAVIOUR_COUNT);
   1772   cfg.client_psk = (0 != (data[9] & 0x40));
   1773 #if GNUTLS_VERSION_MAJOR >= 3
   1774   cfg.psk_scenario = (0 != (data[9] & 0x80));
   1775 #else
   1776   /* MHD refuses MHD_OPTION_GNUTLS_PSK_CRED_HANDLER outright when it was
   1777      built against GnuTLS 2, so there is nothing to reach there. */
   1778   cfg.psk_scenario = 0;
   1779 #endif
   1780 
   1781   /* The PSK bundle.  Four things have to line up before GnuTLS asks the
   1782      server for a key at all; see the TLS-PSK note at the top of this
   1783      file for why they are not four independent input bits. */
   1784   if (cfg.psk_scenario)
   1785   {
   1786     cfg.use_tls = 1;
   1787     cfg.use_cred_type = 1;
   1788     cfg.cred_type_idx = PSK_CRED_TYPE_IDX;
   1789     cfg.use_prio = 1;
   1790     cfg.prio_append = 0;
   1791     cfg.prio_str = psk_prio_tbl[cfg.client_prio_idx];
   1792     /* Raw bytes never negotiate anything; the abandoning client is kept
   1793        because stopping half way through a PSK handshake is its own
   1794        shape. */
   1795     if ( (CLIENT_TLS != cfg.mode) &&
   1796          (CLIENT_TLS_ABANDON != cfg.mode) )
   1797       cfg.mode = CLIENT_TLS;
   1798   }
   1799   else
   1800     cfg.client_psk = 0;
   1801 
   1802   /* A real handshake is pointless without a working credential setup on
   1803      our own side; fall back to the raw modes if the SNI certificates
   1804      could not be parsed. */
   1805   if ( (cfg.use_sni) &&
   1806        (0 != sni_hosts_init ()) )
   1807     cfg.use_sni = 0;
   1808 
   1809   /* The PEM blobs built from the input.  They are only referenced by
   1810      cred_tbl entries 12-14, but filling them unconditionally keeps this
   1811      out of the option assembly below. */
   1812   {
   1813     size_t body = (size_t) data[8] * 4u;
   1814 
   1815     if (body > size - 10)
   1816       body = size - 10;
   1817     build_fuzz_pem (fuzz_cert_pem, sizeof (fuzz_cert_pem),
   1818                     "CERTIFICATE", data + 10, body);
   1819     build_fuzz_pem (fuzz_key_pem, sizeof (fuzz_key_pem),
   1820                     "PRIVATE KEY", data + 10, body);
   1821   }
   1822 
   1823   if (0 != cfg.mem_limit)
   1824   {
   1825     opts[nopt].option = MHD_OPTION_CONNECTION_MEMORY_LIMIT;
   1826     opts[nopt].value = (intptr_t) cfg.mem_limit;
   1827     opts[nopt].ptr_value = NULL;
   1828     nopt++;
   1829   }
   1830   if (NULL != cfg.key)
   1831   {
   1832     opts[nopt].option = MHD_OPTION_HTTPS_MEM_KEY;
   1833     opts[nopt].value = 0;
   1834     opts[nopt].ptr_value = (void *) (intptr_t) cfg.key;
   1835     nopt++;
   1836   }
   1837   if (NULL != cfg.cert)
   1838   {
   1839     opts[nopt].option = MHD_OPTION_HTTPS_MEM_CERT;
   1840     opts[nopt].value = 0;
   1841     opts[nopt].ptr_value = (void *) (intptr_t) cfg.cert;
   1842     nopt++;
   1843   }
   1844   if (cfg.key_password)
   1845   {
   1846     opts[nopt].option = MHD_OPTION_HTTPS_KEY_PASSWORD;
   1847     opts[nopt].value = 0;
   1848     opts[nopt].ptr_value = (void *) (intptr_t) https_key_password;
   1849     nopt++;
   1850   }
   1851   if (cfg.use_trust)
   1852   {
   1853     opts[nopt].option = MHD_OPTION_HTTPS_MEM_TRUST;
   1854     opts[nopt].value = 0;
   1855     opts[nopt].ptr_value = (void *) (intptr_t)
   1856                            (cfg.trust_garbage ? garbage_cert_pem
   1857                             : ca_cert_pem);
   1858     nopt++;
   1859   }
   1860   if (cfg.use_dhparams)
   1861   {
   1862     opts[nopt].option = MHD_OPTION_HTTPS_MEM_DHPARAMS;
   1863     opts[nopt].value = 0;
   1864     opts[nopt].ptr_value = (void *) (intptr_t)
   1865                            (cfg.dh_garbage ? garbage_dh_pem : dh_params_pem);
   1866     nopt++;
   1867   }
   1868   if (cfg.use_prio)
   1869   {
   1870     opts[nopt].option = cfg.prio_append
   1871                         ? MHD_OPTION_HTTPS_PRIORITIES_APPEND
   1872                         : MHD_OPTION_HTTPS_PRIORITIES;
   1873     opts[nopt].value = 0;
   1874     opts[nopt].ptr_value = (void *) (intptr_t) cfg.prio_str;
   1875     nopt++;
   1876   }
   1877   if (cfg.use_cred_type)
   1878   {
   1879     opts[nopt].option = MHD_OPTION_HTTPS_CRED_TYPE;
   1880     opts[nopt].value = (intptr_t) cred_type_tbl[cfg.cred_type_idx];
   1881     opts[nopt].ptr_value = NULL;
   1882     nopt++;
   1883   }
   1884   if (cfg.no_alpn)
   1885   {
   1886     opts[nopt].option = MHD_OPTION_TLS_NO_ALPN;
   1887     opts[nopt].value = 1;
   1888     opts[nopt].ptr_value = NULL;
   1889     nopt++;
   1890   }
   1891   opts[nopt].option = MHD_OPTION_END;
   1892   opts[nopt].value = 0;
   1893   opts[nopt].ptr_value = NULL;
   1894 
   1895   flags = MHD_USE_NO_LISTEN_SOCKET;
   1896   if (cfg.use_tls)
   1897     flags |= MHD_USE_TLS;
   1898   if (fuzz_verbose)
   1899     flags |= MHD_USE_ERROR_LOG;
   1900   if (cfg.allow_upgrade)
   1901     flags |= MHD_ALLOW_UPGRADE;
   1902 
   1903   MHD_set_panic_func (&panic_cb, NULL);
   1904   /* The callback options go through the varargs rather than through the
   1905      option array: the array's ptr_value is a void *, and a function
   1906      pointer does not portably fit in one.  A NULL callback is exactly
   1907      equivalent to not passing the option -- which is what makes
   1908      PSK_NO_HANDLER (the "PSK not supported by this server" arm of
   1909      psk_gnutls_adapter()) reachable without a second call site.
   1910 
   1911      MHD_OPTION_GNUTLS_PSK_CRED_HANDLER is the exception: an MHD built
   1912      against GnuTLS 2 rejects it whatever the callback is, and rejecting
   1913      an option fails the whole MHD_start_daemon(), so on such a build the
   1914      option must not be passed at all. */
   1915 #if GNUTLS_VERSION_MAJOR >= 3
   1916   d = MHD_start_daemon (flags,
   1917                         0,
   1918                         NULL, NULL,
   1919                         &ahc, NULL,
   1920                         MHD_OPTION_ARRAY, opts,
   1921                         MHD_OPTION_HTTPS_CERT_CALLBACK,
   1922                         cfg.use_sni ? &sni_callback : NULL,
   1923                         MHD_OPTION_GNUTLS_PSK_CRED_HANDLER,
   1924                         (cfg.psk_scenario &&
   1925                          (PSK_NO_HANDLER != cfg.psk_mode))
   1926                         ? &psk_cred_cb : NULL,
   1927                         NULL,
   1928                         MHD_OPTION_END);
   1929 #else
   1930   d = MHD_start_daemon (flags,
   1931                         0,
   1932                         NULL, NULL,
   1933                         &ahc, NULL,
   1934                         MHD_OPTION_ARRAY, opts,
   1935                         MHD_OPTION_HTTPS_CERT_CALLBACK,
   1936                         cfg.use_sni ? &sni_callback : NULL,
   1937                         MHD_OPTION_END);
   1938 #endif
   1939   if (NULL == d)
   1940   {
   1941     stat_daemons_failed++;
   1942     return 0;
   1943   }
   1944   stat_daemons++;
   1945   if (! stats_registered)
   1946   {
   1947     stats_registered = 1;
   1948     (void) atexit (&print_stats);
   1949   }
   1950   if (cfg.daemon_info)
   1951   {
   1952     (void) MHD_get_daemon_info (d, MHD_DAEMON_INFO_LISTEN_FD);
   1953     (void) MHD_get_daemon_info (d, MHD_DAEMON_INFO_FLAGS);
   1954     (void) MHD_get_daemon_info (d, MHD_DAEMON_INFO_CURRENT_CONNECTIONS);
   1955     (void) MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
   1956   }
   1957 
   1958   /* The connection is opened lazily, when the first segment that carries
   1959      wire data is reached, so that a leading op 1 segment can still
   1960      override the server name byte 9 selected. */
   1961   tc.sess = NULL;
   1962   tc.cred = NULL;
   1963   tc.psk = NULL;
   1964   tc.fd = -1;
   1965   tc.hs_done = 0;
   1966   tc.dead = 1;
   1967 
   1968   pos = 10u;
   1969   while ( (pos + 2 <= size) &&
   1970           (nseg < MAX_SEGMENTS) )
   1971   {
   1972     unsigned int hdr = (unsigned int) data[pos]
   1973                        | ((unsigned int) data[pos + 1] << 8);
   1974     unsigned int op = hdr >> 14;
   1975     size_t slen = (size_t) (hdr & 0x3FFF);
   1976 
   1977     pos += 2;
   1978     nseg++;
   1979     if (slen > size - pos)
   1980       slen = size - pos;
   1981 
   1982     if (1 == op)
   1983     {
   1984       /* Server name declaration for the next connection, not wire data. */
   1985       size_t n = slen;
   1986 
   1987       if (n > MAX_SNI_LEN)
   1988         n = MAX_SNI_LEN;
   1989       memcpy (sni_name, data + pos, n);
   1990       /* GnuTLS wants a plain host name, and an embedded NUL would only
   1991          shorten it behind our back. */
   1992       while ( (0 != n) &&
   1993               ('\0' == sni_name[n - 1]) )
   1994         n--;
   1995       sni_name[n] = '\0';
   1996       sni_name_len = n;
   1997       pos += slen;
   1998       continue;
   1999     }
   2000     if (0 > tc.fd)
   2001     {
   2002       tc_start (d, &tc);
   2003       if (0 > tc.fd)
   2004         break;
   2005     }
   2006     else if ( (3 == op) &&
   2007               (nconn < MAX_CONNECTIONS) )
   2008     {
   2009       tc_close (d, &tc);
   2010       tc_start (d, &tc);
   2011       nconn++;
   2012       if (0 > tc.fd)
   2013         break;
   2014     }
   2015     if (0 != slen)
   2016       tc_send (d, &tc, data + pos, slen);
   2017     pos += slen;
   2018     pump_and_drain (d, &tc, (2 == op) ? (6u + cfg.extra_pump) : 3u);
   2019   }
   2020   if (0 > tc.fd)
   2021     tc_start (d, &tc);
   2022   pump_and_drain (d, &tc, 2u + cfg.extra_pump);
   2023   tc_close (d, &tc);
   2024 
   2025   if (cfg.quiesce)
   2026     (void) MHD_quiesce_daemon (d);
   2027   /* Last, so that no run can drain the list again.  MHD_add_connection()
   2028      on a thread-safe daemon (the default) only queues the socket, but
   2029      new_connection_prepare_() has already built the GnuTLS session for
   2030      it; stopping before the next run is what makes MHD free that session
   2031      from new_connection_close_() rather than from the ordinary
   2032      connection teardown.  fuzz_eventloop covers the same shape without
   2033      TLS -- see its byte 3 bit 4. */
   2034   if (cfg.stop_with_queued)
   2035     queued_fd = queue_unprocessed_conn (d);
   2036   MHD_stop_daemon (d);
   2037   if (0 <= queued_fd)
   2038     (void) close (queued_fd);
   2039   return 0;
   2040 }
   2041 
   2042 
   2043 /* ------------------------------------------------------------------ */
   2044 /* Structure-aware generator                                           */
   2045 /* ------------------------------------------------------------------ */
   2046 
   2047 struct sbuf
   2048 {
   2049   uint8_t *p;
   2050   size_t len;
   2051   size_t cap;
   2052 };
   2053 
   2054 
   2055 static void
   2056 sb_raw (struct sbuf *b,
   2057         const void *v,
   2058         size_t n)
   2059 {
   2060   if (b->len + n > b->cap)
   2061     n = b->cap - b->len;
   2062   memcpy (b->p + b->len, v, n);
   2063   b->len += n;
   2064 }
   2065 
   2066 
   2067 static void
   2068 sb_str (struct sbuf *b,
   2069         const char *s)
   2070 {
   2071   sb_raw (b, s, strlen (s));
   2072 }
   2073 
   2074 
   2075 static void
   2076 sb_u32 (struct sbuf *b,
   2077         uint32_t v)
   2078 {
   2079   char tmp[16];
   2080   unsigned int n = 0;
   2081 
   2082   do
   2083   {
   2084     tmp[n++] = (char) ('0' + (v % 10u));
   2085     v /= 10u;
   2086   }
   2087   while ( (0 != v) &&
   2088           (n < sizeof (tmp)) );
   2089   while (0 != n)
   2090   {
   2091     char c = tmp[--n];
   2092 
   2093     sb_raw (b, &c, 1);
   2094   }
   2095 }
   2096 
   2097 
   2098 enum gen_shape
   2099 {
   2100   SHAPE_TLS_HTTP = 0,   /**< good credentials, real handshake, HTTP over TLS */
   2101   SHAPE_RAW_BYTES,      /**< good credentials, junk at the TLS socket */
   2102   SHAPE_ABANDON,        /**< a real client that walks away mid-handshake */
   2103   SHAPE_BAD_CREDS,      /**< mismatched/garbage/absent key or certificate */
   2104   SHAPE_BAD_OPTIONS,    /**< bogus priorities, credential types, no MHD_USE_TLS */
   2105   SHAPE_SNI,            /**< the certificate callback, all behaviours */
   2106   SHAPE_PEM_FUZZ,       /**< PEM blobs built from the generator's own bytes */
   2107   SHAPE_RECORDS,        /**< hand-built TLS records */
   2108   SHAPE_PSK,            /**< the pre-shared key credentials path */
   2109   SHAPE_COUNT
   2110 };
   2111 
   2112 static int forced_shape = -1;
   2113 static int forced_shape_read;
   2114 
   2115 static const char *const gen_methods[] = {
   2116   "GET", "POST", "HEAD", "PUT", "OPTIONS", "BREW"
   2117 };
   2118 
   2119 static const char *const gen_targets[] = {
   2120   "/", "/a", "/index.html", "/a?b=c", "/%41%42", "*", "//"
   2121 };
   2122 
   2123 static const char *const gen_versions[] = {
   2124   "HTTP/1.1", "HTTP/1.0", "HTTP/1.2", "HTTP/9.9"
   2125 };
   2126 
   2127 static const char *const gen_hdr_names[] = {
   2128   "Host", "User-Agent", "Accept", "Connection", "X-Fuzz", "Cookie",
   2129   "Content-Type", "Expect"
   2130 };
   2131 
   2132 static const char *const gen_hdr_values[] = {
   2133   "x", "localhost", "*/*", "keep-alive", "close", "100-continue",
   2134   "text/plain", "a=b"
   2135 };
   2136 
   2137 
   2138 /**
   2139  * A plain HTTP request; over TLS this is what makes MHD leave the
   2140  * handshake state machine and enter the ordinary parser.
   2141  */
   2142 static void
   2143 gen_http_request (struct fuzz_rng *rng,
   2144                   struct sbuf *b)
   2145 {
   2146   unsigned int nh;
   2147   unsigned int i;
   2148   int with_body;
   2149 
   2150   sb_str (b, gen_methods[fuzz_below (rng, (uint32_t)
   2151                                      (sizeof (gen_methods)
   2152                                       / sizeof (gen_methods[0])))]);
   2153   sb_str (b, " ");
   2154   sb_str (b, gen_targets[fuzz_below (rng, (uint32_t)
   2155                                      (sizeof (gen_targets)
   2156                                       / sizeof (gen_targets[0])))]);
   2157   sb_str (b, " ");
   2158   sb_str (b, gen_versions[fuzz_below (rng, (uint32_t)
   2159                                       (sizeof (gen_versions)
   2160                                        / sizeof (gen_versions[0])))]);
   2161   sb_str (b, "\r\n");
   2162   with_body = fuzz_chance (rng, 3);
   2163   nh = fuzz_below (rng, 4);
   2164   for (i = 0; i < nh; i++)
   2165   {
   2166     sb_str (b, gen_hdr_names[fuzz_below (rng, (uint32_t)
   2167                                          (sizeof (gen_hdr_names)
   2168                                           / sizeof (gen_hdr_names[0])))]);
   2169     sb_str (b, ": ");
   2170     sb_str (b, gen_hdr_values[fuzz_below (rng, (uint32_t)
   2171                                           (sizeof (gen_hdr_values)
   2172                                            / sizeof (gen_hdr_values[0])))]);
   2173     sb_str (b, "\r\n");
   2174   }
   2175   if (with_body)
   2176   {
   2177     unsigned int blen = fuzz_below (rng, 64);
   2178 
   2179     sb_str (b, "Content-Length: ");
   2180     sb_u32 (b, blen);
   2181     sb_str (b, "\r\n\r\n");
   2182     for (i = 0; i < blen; i++)
   2183     {
   2184       char c = (char) ('a' + (int) fuzz_below (rng, 26));
   2185 
   2186       sb_raw (b, &c, 1);
   2187     }
   2188     return;
   2189   }
   2190   sb_str (b, "\r\n");
   2191 }
   2192 
   2193 
   2194 /**
   2195  * Something that looks like a TLS record: a content type, a version, a
   2196  * length and a payload.  Most of this lands in GnuTLS's record parser
   2197  * rather than in MHD, which is why the generator spends only one shape
   2198  * on it.
   2199  */
   2200 static void
   2201 gen_tls_records (struct fuzz_rng *rng,
   2202                  struct sbuf *b)
   2203 {
   2204   unsigned int n = 1 + fuzz_below (rng, 4);
   2205   unsigned int i;
   2206   unsigned int j;
   2207 
   2208   for (i = 0; i < n; i++)
   2209   {
   2210     uint8_t hdr[5];
   2211     unsigned int plen = fuzz_below (rng, 96);
   2212     unsigned int declared = fuzz_chance (rng, 3)
   2213                             ? fuzz_below (rng, 0x4000)
   2214                             : plen;
   2215 
   2216     hdr[0] = fuzz_chance (rng, 4)
   2217              ? fuzz_byte (rng)
   2218              : (uint8_t) (20 + fuzz_below (rng, 4));
   2219     hdr[1] = 0x03;
   2220     hdr[2] = (uint8_t) fuzz_below (rng, 5);
   2221     hdr[3] = (uint8_t) ((declared >> 8) & 0xFF);
   2222     hdr[4] = (uint8_t) (declared & 0xFF);
   2223     sb_raw (b, hdr, sizeof (hdr));
   2224     for (j = 0; j < plen; j++)
   2225     {
   2226       uint8_t v = fuzz_byte (rng);
   2227 
   2228       sb_raw (b, &v, 1);
   2229     }
   2230   }
   2231 }
   2232 
   2233 
   2234 /**
   2235  * Number of leading entries of #prio_tbl that GnuTLS accepts.  Beyond
   2236  * that the daemon refuses to start, which is a fine thing to fuzz but a
   2237  * poor way to reach the handshake.
   2238  */
   2239 #define PRIO_VALID_COUNT 7
   2240 
   2241 
   2242 /**
   2243  * Constrain the configuration bytes so that MHD_start_daemon() actually
   2244  * succeeds.  Used by the shapes whose point is what happens *after* the
   2245  * daemon is up; the option surface itself is fuzzed by the shapes that
   2246  * do not call this.
   2247  */
   2248 static void
   2249 make_daemon_startable (struct fuzz_rng *rng,
   2250                        uint8_t *cfg_bytes)
   2251 {
   2252   cfg_bytes[1] &= (uint8_t) ~0x10u;      /* no credential type override */
   2253   cfg_bytes[3] &= (uint8_t) ~0xC0u;      /* valid trust store, valid DH */
   2254   if (0 != (cfg_bytes[1] & 0x08u))
   2255     cfg_bytes[2] = (uint8_t) fuzz_below (rng, PRIO_VALID_COUNT);
   2256   cfg_bytes[7] &= (uint8_t) ~0x08u;      /* keep MHD_USE_TLS */
   2257 }
   2258 
   2259 
   2260 /**
   2261  * Emit one segment with the given op code.
   2262  */
   2263 static void
   2264 emit_segment (struct sbuf *out,
   2265               unsigned int op,
   2266               const uint8_t *payload,
   2267               size_t len)
   2268 {
   2269   unsigned int hv;
   2270   uint8_t hdr[2];
   2271 
   2272   if (len > 0x3FFF)
   2273     len = 0x3FFF;
   2274   hv = (op << 14) | (unsigned int) len;
   2275   hdr[0] = (uint8_t) (hv & 0xFF);
   2276   hdr[1] = (uint8_t) (hv >> 8);
   2277   sb_raw (out, hdr, 2);
   2278   sb_raw (out, payload, len);
   2279 }
   2280 
   2281 
   2282 static size_t
   2283 fuzz_generate (struct fuzz_rng *rng,
   2284                uint8_t *buf,
   2285                size_t cap)
   2286 {
   2287   struct sbuf out;
   2288   struct sbuf rb;
   2289   uint8_t req[GEN_BUF_SIZE];
   2290   uint8_t cfg_bytes[10];
   2291   enum gen_shape shape;
   2292   unsigned int nreq;
   2293   unsigned int i;
   2294 
   2295   out.p = buf;
   2296   out.len = 0;
   2297   out.cap = cap;
   2298 
   2299   if (! forced_shape_read)
   2300   {
   2301     const char *e = getenv ("MHD_FUZZ_SHAPE");
   2302 
   2303     forced_shape_read = 1;
   2304     if (NULL != e)
   2305       forced_shape = atoi (e);
   2306   }
   2307   if (0 <= forced_shape)
   2308     shape = (enum gen_shape) (forced_shape % (int) SHAPE_COUNT);
   2309   else
   2310     shape = (enum gen_shape) fuzz_below (rng, (uint32_t) SHAPE_COUNT);
   2311 
   2312   for (i = 0; i < sizeof (cfg_bytes); i++)
   2313     cfg_bytes[i] = fuzz_byte (rng);
   2314 
   2315   /* Byte 0 picks the credentials, byte 4 (bits 0-1) the client, and byte
   2316      1 which options are passed at all; every shape below narrows exactly
   2317      those and leaves the rest of the configuration space random. */
   2318   cfg_bytes[7] &= (uint8_t) ~0x08u;      /* keep MHD_USE_TLS by default */
   2319   switch (shape)
   2320   {
   2321   case SHAPE_TLS_HTTP:
   2322     cfg_bytes[0] = (uint8_t) (fuzz_chance (rng, 2) ? 0 : 1);
   2323     cfg_bytes[4] = (uint8_t) ((cfg_bytes[4] & ~0x03u) | CLIENT_TLS);
   2324     cfg_bytes[1] &= (uint8_t) ~0x04u;    /* no SNI callback */
   2325     make_daemon_startable (rng, cfg_bytes);
   2326     break;
   2327   case SHAPE_RAW_BYTES:
   2328     cfg_bytes[0] = 0;
   2329     cfg_bytes[4] = (uint8_t) ((cfg_bytes[4] & ~0x03u) | CLIENT_RAW);
   2330     make_daemon_startable (rng, cfg_bytes);
   2331     break;
   2332   case SHAPE_ABANDON:
   2333     cfg_bytes[0] = (uint8_t) (fuzz_chance (rng, 2) ? 0 : 1);
   2334     cfg_bytes[4] = (uint8_t) ((cfg_bytes[4] & ~0x03u) | CLIENT_TLS_ABANDON);
   2335     cfg_bytes[7] = (uint8_t) ((cfg_bytes[7] & ~0x07u)
   2336                               + fuzz_below (rng, 6));
   2337     make_daemon_startable (rng, cfg_bytes);
   2338     break;
   2339   case SHAPE_BAD_CREDS:
   2340     /* entries 2-11 of cred_tbl are the broken ones */
   2341     cfg_bytes[0] = (uint8_t) (2 + fuzz_below (rng, 10));
   2342     cfg_bytes[4] = (uint8_t) ((cfg_bytes[4] & ~0x03u)
   2343                               | (fuzz_chance (rng, 2) ? CLIENT_TLS
   2344                                  : CLIENT_RAW));
   2345     break;
   2346   case SHAPE_BAD_OPTIONS:
   2347     cfg_bytes[1] |= 0x18u;               /* priorities + credential type */
   2348     cfg_bytes[2] = (uint8_t) fuzz_below (rng, (uint32_t) PRIO_COUNT);
   2349     cfg_bytes[3] = fuzz_byte (rng);
   2350     if (fuzz_chance (rng, 4))
   2351       cfg_bytes[7] |= 0x08u;             /* HTTPS options, but no MHD_USE_TLS */
   2352     cfg_bytes[4] = (uint8_t) ((cfg_bytes[4] & ~0x03u)
   2353                               | (fuzz_chance (rng, 2) ? CLIENT_TLS
   2354                                  : CLIENT_RAW));
   2355     break;
   2356   case SHAPE_SNI:
   2357     cfg_bytes[0] = (uint8_t) (fuzz_chance (rng, 3) ? 6 : 0);
   2358     cfg_bytes[3] = (uint8_t)
   2359                    ((cfg_bytes[3] & ~0x38u)
   2360                     | (fuzz_below (rng, (uint32_t) SNI_BEHAVIOUR_COUNT) << 3));
   2361     cfg_bytes[4] = (uint8_t) ((cfg_bytes[4] & ~0x03u) | CLIENT_TLS | 0x04u);
   2362     cfg_bytes[9] = (uint8_t) fuzz_below (rng, (uint32_t) SNI_NAME_COUNT);
   2363     make_daemon_startable (rng, cfg_bytes);
   2364     cfg_bytes[1] |= 0x04u;               /* the certificate callback */
   2365     break;
   2366   case SHAPE_PEM_FUZZ:
   2367     cfg_bytes[0] = (uint8_t) (12 + fuzz_below (rng, 3));
   2368     cfg_bytes[8] = (uint8_t) (1 + fuzz_below (rng, 64));
   2369     cfg_bytes[4] = (uint8_t) ((cfg_bytes[4] & ~0x03u)
   2370                               | (fuzz_chance (rng, 2) ? CLIENT_TLS
   2371                                  : CLIENT_RAW));
   2372     break;
   2373   case SHAPE_RECORDS:
   2374     cfg_bytes[0] = 0;
   2375     cfg_bytes[4] = (uint8_t) ((cfg_bytes[4] & ~0x03u) | CLIENT_RECORDS);
   2376     make_daemon_startable (rng, cfg_bytes);
   2377     break;
   2378   case SHAPE_PSK:
   2379     /* The certificate is irrelevant to a PSK handshake but still has to
   2380        let the daemon start, so keep the valid pair. */
   2381     cfg_bytes[0] = 0;
   2382     cfg_bytes[4] = (uint8_t) ((cfg_bytes[4] & ~0x03u)
   2383                               | (fuzz_chance (rng, 5) ? CLIENT_TLS_ABANDON
   2384                                  : CLIENT_TLS));
   2385     cfg_bytes[1] &= (uint8_t) ~0x04u;    /* no SNI callback */
   2386     make_daemon_startable (rng, cfg_bytes);
   2387     cfg_bytes[9] = (uint8_t)
   2388                    (0x80u                                 /* the scenario itself */
   2389                     | (fuzz_chance (rng, 6) ? 0u : 0x40u) /* client PSK */
   2390                     | (uint8_t) (fuzz_below (rng,
   2391                                              (uint32_t) PSK_BEHAVIOUR_COUNT)
   2392                                  << 3)
   2393                     | (uint8_t) fuzz_below (rng, (uint32_t) SNI_NAME_COUNT));
   2394     break;
   2395   case SHAPE_COUNT:
   2396   default:
   2397     break;
   2398   }
   2399   /* Byte 9 already carries a server name; now and then hand the same
   2400      one over as an op 1 segment instead, so that the segment form is
   2401      exercised too.  Generated inputs are never written to corpus/, so
   2402      unlike the seeds they may use op 1 (see the note at the top). */
   2403   sb_raw (&out, cfg_bytes, sizeof (cfg_bytes));
   2404   if (fuzz_chance (rng, 4))
   2405   {
   2406     const char *nm = sni_name_tbl[cfg_bytes[9] & 0x07];
   2407 
   2408     emit_segment (&out, 1u, (const uint8_t *) nm, strlen (nm));
   2409   }
   2410 
   2411   nreq = 1u + (fuzz_chance (rng, 4) ? 1u : 0u);
   2412   for (i = 0; i < nreq; i++)
   2413   {
   2414     unsigned int op;
   2415 
   2416     rb.p = req;
   2417     rb.len = 0;
   2418     rb.cap = sizeof (req);
   2419     switch (shape)
   2420     {
   2421     case SHAPE_RECORDS:
   2422       gen_tls_records (rng, &rb);
   2423       break;
   2424     case SHAPE_RAW_BYTES:
   2425       {
   2426         unsigned int n = 1 + fuzz_below (rng, 256);
   2427         unsigned int j;
   2428 
   2429         for (j = 0; j < n; j++)
   2430         {
   2431           uint8_t v = fuzz_byte (rng);
   2432 
   2433           sb_raw (&rb, &v, 1);
   2434         }
   2435         break;
   2436       }
   2437     default:
   2438       gen_http_request (rng, &rb);
   2439       break;
   2440     }
   2441     if (0 != i)
   2442       op = 3u;                           /* a fresh connection */
   2443     else
   2444       op = fuzz_chance (rng, 3) ? 2u : 0u;
   2445     /* Split the payload now and then: MHD's parser is incremental and
   2446        the TLS record boundaries move with the split. */
   2447     if ( (rb.len > 8) &&
   2448          fuzz_chance (rng, 3) )
   2449     {
   2450       size_t cut = 1 + fuzz_below (rng, (uint32_t) (rb.len - 1));
   2451 
   2452       emit_segment (&out, op, req, cut);
   2453       emit_segment (&out, 2u, req + cut, rb.len - cut);
   2454     }
   2455     else
   2456     {
   2457       emit_segment (&out, op, req, rb.len);
   2458     }
   2459   }
   2460   return out.len;
   2461 }
   2462 
   2463 
   2464 /* ------------------------------------------------------------------ */
   2465 /* Built-in seed corpus                                                */
   2466 /* ------------------------------------------------------------------ */
   2467 
   2468 struct seed_part
   2469 {
   2470   unsigned int op;              /**< 0 send, 1 server name, 2 send+pump, 3 new */
   2471   const char *txt;              /**< NUL terminated payload */
   2472 };
   2473 
   2474 struct seed_def
   2475 {
   2476   const char *name;
   2477   unsigned char cfg[10];
   2478   struct seed_part parts[4];
   2479 };
   2480 
   2481 #define P_END { 0, NULL }
   2482 
   2483 /* The configuration bytes are written out in full so that a seed can be
   2484    read without decoding: see the input format at the top of this file. */
   2485 static const struct seed_def seeds[] = {
   2486   /* A complete TLS 1.3 handshake followed by an ordinary request: the
   2487      only shape that reaches the handshake -> HTTP parser transition. */
   2488   { "tls-handshake-get",
   2489     { 0, 0x00, 0, 0, 0x41, 0x00, 0x04, 0x00, 0, 0 },
   2490     { { 0, "GET / HTTP/1.1\r\nHost: x\r\n\r\n" }, P_END, P_END, P_END } },
   2491 
   2492   /* The same, but the request arrives in two TLS records. */
   2493   { "tls-handshake-split",
   2494     { 0, 0x00, 0, 0, 0x41, 0x00, 0x04, 0x00, 0, 0 },
   2495     { { 0, "GET / HTTP/1.1\r\nHo" },
   2496       { 2, "st: x\r\n\r\n" }, P_END, P_END } },
   2497 
   2498   /* Keep-alive over TLS: two requests on one session, then gnutls_bye(). */
   2499   { "tls-keepalive",
   2500     { 0, 0x00, 0, 0, 0x41, 0x00, 0x00, 0x00, 0, 0 },
   2501     { { 0, "GET /a HTTP/1.1\r\nHost: x\r\n\r\n" },
   2502       { 2, "GET /b HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n" },
   2503       P_END, P_END } },
   2504 
   2505   /* A second connection, i.e. a second handshake on the same daemon. */
   2506   { "tls-second-connection",
   2507     { 0, 0x00, 0, 0, 0x41, 0x00, 0x00, 0x00, 0, 0 },
   2508     { { 0, "GET /a HTTP/1.1\r\nHost: x\r\n\r\n" },
   2509       { 3, "GET /b HTTP/1.1\r\nHost: x\r\n\r\n" },
   2510       P_END, P_END } },
   2511 
   2512   /* Plain HTTP at a TLS port: the record layer sees "GET ..." and the
   2513      handshake fails, which is MHD_run_tls_handshake_()'s error arm. */
   2514   { "plain-http-at-tls-port",
   2515     { 0, 0x00, 0, 0, 0x00, 0x00, 0x00, 0x00, 0, 0 },
   2516     { { 0, "GET / HTTP/1.1\r\nHost: x\r\n\r\n" }, P_END, P_END, P_END } },
   2517 
   2518   /* Nothing at all, then EOF: the connection dies in MHD_TLS_CONN_INIT. */
   2519   { "eof-in-init",
   2520     { 0, 0x00, 0, 0, 0x80, 0x00, 0x00, 0x00, 0, 0 },
   2521     { { 0, "" }, P_END, P_END, P_END } },
   2522 
   2523   /* A real client that walks away after a single handshake round: MHD is
   2524      left in MHD_TLS_CONN_HANDSHAKING when the socket closes. */
   2525   { "abandon-handshake",
   2526     { 0, 0x00, 0, 0, 0x02, 0x00, 0x00, 0x00, 0, 0 },
   2527     { { 0, "" }, P_END, P_END, P_END } },
   2528 
   2529   /* Certificate and key do not belong together. */
   2530   { "mismatched-key",
   2531     { 2, 0x00, 0, 0, 0x01, 0x00, 0x00, 0x00, 0, 0 },
   2532     { { 0, "GET / HTTP/1.1\r\nHost: x\r\n\r\n" }, P_END, P_END, P_END } },
   2533 
   2534   /* No certificate at all: MHD_start_daemon() has to fail cleanly. */
   2535   { "no-certificate",
   2536     { 6, 0x00, 0, 0, 0x01, 0x00, 0x00, 0x00, 0, 0 },
   2537     { { 0, "GET / HTTP/1.1\r\nHost: x\r\n\r\n" }, P_END, P_END, P_END } },
   2538 
   2539   /* PEM armour with a payload that is not base64. */
   2540   { "garbage-pem",
   2541     { 10, 0x00, 0, 0, 0x01, 0x00, 0x00, 0x00, 0, 0 },
   2542     { { 0, "GET / HTTP/1.1\r\nHost: x\r\n\r\n" }, P_END, P_END, P_END } },
   2543 
   2544   /* A priority string GnuTLS rejects (index 9 of prio_tbl). */
   2545   { "bogus-priorities",
   2546     { 0, 0x08, 9, 0, 0x01, 0x00, 0x00, 0x00, 0, 0 },
   2547     { { 0, "GET / HTTP/1.1\r\nHost: x\r\n\r\n" }, P_END, P_END, P_END } },
   2548 
   2549   /* The same string through MHD_OPTION_HTTPS_PRIORITIES_APPEND. */
   2550   { "bogus-priorities-append",
   2551     { 0, 0x88, 10, 0, 0x01, 0x00, 0x00, 0x00, 0, 0 },
   2552     { { 0, "GET / HTTP/1.1\r\nHost: x\r\n\r\n" }, P_END, P_END, P_END } },
   2553 
   2554   /* TLS 1.2 only on both ends, with the trust store and a client
   2555      certificate request. */
   2556   { "tls12-with-trust",
   2557     { 0, 0x01, 2, 0, 0x29, 0x00, 0x04, 0x00, 0, 0 },
   2558     { { 0, "GET / HTTP/1.1\r\nHost: x\r\n\r\n" }, P_END, P_END, P_END } },
   2559 
   2560   /* Valid Diffie-Hellman parameters (RFC 3526 group 14). */
   2561   { "valid-dhparams",
   2562     { 0, 0x02, 0, 0, 0x21, 0x00, 0x00, 0x00, 0, 0 },
   2563     { { 0, "GET / HTTP/1.1\r\nHost: x\r\n\r\n" }, P_END, P_END, P_END } },
   2564 
   2565   /* Malformed Diffie-Hellman parameters: MHD_start_daemon() must fail. */
   2566   { "garbage-dhparams",
   2567     { 0, 0x02, 0, 0x80, 0x01, 0x00, 0x00, 0x00, 0, 0 },
   2568     { { 0, "GET / HTTP/1.1\r\nHost: x\r\n\r\n" }, P_END, P_END, P_END } },
   2569 
   2570   /* A credential type MHD does not support (GNUTLS_CRD_ANON). */
   2571   { "cred-type-anon",
   2572     { 0, 0x10, 0, 0x02, 0x01, 0x00, 0x00, 0x00, 0, 0 },
   2573     { { 0, "GET / HTTP/1.1\r\nHost: x\r\n\r\n" }, P_END, P_END, P_END } },
   2574 
   2575   /* GNUTLS_CRD_PSK without a PSK callback: the daemon starts, the
   2576      handshake cannot. */
   2577   { "cred-type-psk",
   2578     { 0, 0x10, 0, 0x01, 0x01, 0x00, 0x00, 0x00, 0, 0 },
   2579     { { 0, "GET / HTTP/1.1\r\nHost: x\r\n\r\n" }, P_END, P_END, P_END } },
   2580 
   2581   /* The TLS-PSK scenario (byte 9 bit 7), one seed per branch of
   2582      psk_gnutls_adapter().  Byte 9 is
   2583        0x80 scenario | 0x40 client offers PSK | behaviour << 3 | identity.
   2584      Byte 4 bits 4-5 pick the PSK priority string, which is what decides
   2585      the protocol version the PSK key exchange runs under. */
   2586 
   2587   /* The whole path end to end: identity accepted, key matches, handshake
   2588      completes, and MHD then serves plain HTTP over a session that has no
   2589      certificate at all (byte 6 bit 2 reads the TLS members back). */
   2590   { "psk-handshake",
   2591     { 0, 0x00, 0, 0, 0x11, 0x00, 0x04, 0x00, 0, 0xC0 },
   2592     { { 0, "GET / HTTP/1.1\r\nHost: x\r\n\r\n" }, P_END, P_END, P_END } },
   2593 
   2594   /* The same over TLS 1.3, where GnuTLS treats the key as an external
   2595      PSK and the exchange has a different shape. */
   2596   { "psk-handshake-tls13",
   2597     { 0, 0x00, 0, 0, 0x21, 0x00, 0x00, 0x00, 0, 0xC0 },
   2598     { { 0, "GET / HTTP/1.1\r\nHost: x\r\n\r\n" }, P_END, P_END, P_END } },
   2599 
   2600   /* The application refuses the identity: the adapter's -1 arm. */
   2601   { "psk-callback-fails",
   2602     { 0, 0x00, 0, 0, 0x11, 0x00, 0x00, 0x00, 0, 0xC8 },
   2603     { { 0, "GET / HTTP/1.1\r\nHost: x\r\n\r\n" }, P_END, P_END, P_END } },
   2604 
   2605   /* Zero length key: the "PSK too short" arm, and the reason MHD never
   2606      reaches gnutls_malloc(0). */
   2607   { "psk-empty-key",
   2608     { 0, 0x00, 0, 0, 0x11, 0x00, 0x00, 0x00, 0, 0xD0 },
   2609     { { 0, "GET / HTTP/1.1\r\nHost: x\r\n\r\n" }, P_END, P_END, P_END } },
   2610 
   2611   /* One byte below the minimum -- the other side of the boundary that
   2612      psk-handshake (exactly the minimum) sits on. */
   2613   { "psk-one-byte-short",
   2614     { 0, 0x00, 0, 0, 0x11, 0x00, 0x00, 0x00, 0, 0xF8 },
   2615     { { 0, "GET / HTTP/1.1\r\nHost: x\r\n\r\n" }, P_END, P_END, P_END } },
   2616 
   2617   /* 4 KiB key: the copy into the gnutls_malloc()ed buffer, at a size no
   2618      ciphersuite expects. */
   2619   { "psk-long-key",
   2620     { 0, 0x00, 0, 0, 0x11, 0x00, 0x00, 0x00, 0, 0xD8 },
   2621     { { 0, "GET / HTTP/1.1\r\nHost: x\r\n\r\n" }, P_END, P_END, P_END } },
   2622 
   2623   /* Key length taken from the identity, with the longest identity in the
   2624      table (sni_name_tbl entry 7, 62 characters): the callback then hands
   2625      back a 62 byte key, which no PSK ciphersuite expects. */
   2626   { "psk-key-from-identity",
   2627     { 0, 0x00, 0, 0, 0x11, 0x00, 0x00, 0x00, 0, 0xE7 },
   2628     { { 0, "GET / HTTP/1.1\r\nHost: x\r\n\r\n" }, P_END, P_END, P_END } },
   2629 
   2630   /* A key size above UINT_MAX: the "PSK too long" arm, which has to
   2631      free the application's buffer and fail. */
   2632   { "psk-oversized-key",
   2633     { 0, 0x00, 0, 0, 0x11, 0x00, 0x00, 0x00, 0, 0xE8 },
   2634     { { 0, "GET / HTTP/1.1\r\nHost: x\r\n\r\n" }, P_END, P_END, P_END } },
   2635 
   2636   /* PSK credential type, PSK ciphersuite, but no credentials callback:
   2637      the "PSK not supported by this server" arm. */
   2638   { "psk-no-handler",
   2639     { 0, 0x00, 0, 0, 0x11, 0x00, 0x00, 0x00, 0, 0xF0 },
   2640     { { 0, "GET / HTTP/1.1\r\nHost: x\r\n\r\n" }, P_END, P_END, P_END } },
   2641 
   2642   /* A PSK-only server against a client that offers no PSK identity: the
   2643      handshake fails before the adapter is ever asked. */
   2644   { "psk-client-no-creds",
   2645     { 0, 0x00, 0, 0, 0x11, 0x00, 0x00, 0x00, 0, 0x80 },
   2646     { { 0, "GET / HTTP/1.1\r\nHost: x\r\n\r\n" }, P_END, P_END, P_END } },
   2647 
   2648   /* Byte 5 bit 6: stop the daemon with a connection queued but never
   2649      started, so that its GnuTLS session is freed by
   2650      new_connection_close_() instead of by the ordinary teardown. */
   2651   { "stop-with-queued-connection",
   2652     { 0, 0x00, 0, 0, 0x01, 0x40, 0x00, 0x00, 0, 0 },
   2653     { { 0, "GET / HTTP/1.1\r\nHost: x\r\n\r\n" }, P_END, P_END, P_END } },
   2654 
   2655   /* The SNI callback, answering for the presented name (byte 9 = 0,
   2656      "test-mhdserver").  No op 1 segment here or below: see the note on
   2657      the shared corpus at the top of this file. */
   2658   { "sni-by-name",
   2659     { 6, 0x04, 0, 0x18, 0x05, 0x00, 0x04, 0x00, 0, 0 },
   2660     { { 0, "GET / HTTP/1.1\r\nHost: test-mhdserver\r\n\r\n" },
   2661       P_END, P_END, P_END } },
   2662 
   2663   /* The SNI callback failing outright. */
   2664   { "sni-callback-fails",
   2665     { 6, 0x04, 0, 0x08, 0x05, 0x00, 0x00, 0x00, 0, 0 },
   2666     { { 0, "GET / HTTP/1.1\r\nHost: x\r\n\r\n" },
   2667       P_END, P_END, P_END } },
   2668 
   2669   /* The SNI callback answering with an empty certificate list. */
   2670   { "sni-callback-empty",
   2671     { 6, 0x04, 0, 0x10, 0x05, 0x00, 0x00, 0x00, 0, 0 },
   2672     { { 0, "GET / HTTP/1.1\r\nHost: x\r\n\r\n" },
   2673       P_END, P_END, P_END } },
   2674 
   2675   /* The SNI callback answering with a key that is not the certificate's
   2676      (byte 9 = 1, "localhost"). */
   2677   { "sni-callback-mismatch",
   2678     { 6, 0x04, 0, 0x20, 0x05, 0x00, 0x00, 0x00, 0, 1 },
   2679     { { 0, "GET / HTTP/1.1\r\nHost: x\r\n\r\n" },
   2680       P_END, P_END, P_END } },
   2681 
   2682   /* The SNI callback answering with a certificate but no key. */
   2683   { "sni-callback-no-key",
   2684     { 6, 0x04, 0, 0x28, 0x05, 0x00, 0x00, 0x00, 0, 0 },
   2685     { { 0, "GET / HTTP/1.1\r\nHost: x\r\n\r\n" },
   2686       P_END, P_END, P_END } },
   2687 
   2688   /* An unknown server name with the by-name callback (byte 9 = 3,
   2689      "nobody.example.org"): no certificate. */
   2690   { "sni-unknown-name",
   2691     { 6, 0x04, 0, 0x18, 0x05, 0x00, 0x00, 0x00, 0, 3 },
   2692     { { 0, "GET / HTTP/1.1\r\nHost: x\r\n\r\n" },
   2693       P_END, P_END, P_END } },
   2694 
   2695   /* A PEM blob assembled from the payload below (cred_tbl entry 14). */
   2696   { "fuzzed-pem",
   2697     { 14, 0x00, 0, 0, 0x01, 0x00, 0x00, 0x00, 32, 0 },
   2698     { { 0, "MIIFSzCCAzOgAwIBAgIBBDANBgkqhkiG9w0BAQsFADCBgTELMAkGA1UEBhMCUlUx" },
   2699       P_END, P_END, P_END } },
   2700 
   2701   /* A truncated TLS record header, then EOF. */
   2702   { "short-record",
   2703     { 0, 0x00, 0, 0, 0x00, 0x00, 0x00, 0x00, 0, 0 },
   2704     { { 0, "\x16\x03\x01" }, P_END, P_END, P_END } },
   2705 
   2706   /* A record that promises far more data than it delivers. */
   2707   { "record-length-lie",
   2708     { 0, 0x00, 0, 0, 0x00, 0x00, 0x00, 0x00, 0, 0 },
   2709     { { 0, "\x16\x03\x01\x3f\xff\x01\x02\x03\x04" }, P_END, P_END, P_END } },
   2710 
   2711   /* The HTTPS options on a daemon started without MHD_USE_TLS. */
   2712   { "no-use-tls-flag",
   2713     { 0, 0x0F, 0, 0, 0x00, 0x00, 0x00, 0x08, 0, 0 },
   2714     { { 0, "GET / HTTP/1.1\r\nHost: x\r\n\r\n" }, P_END, P_END, P_END } },
   2715 
   2716   /* A tiny connection memory pool with a real TLS session. */
   2717   { "small-pool-tls",
   2718     { 0, 0x00, 0, 0, 0x41, 0x01, 0x00, 0x00, 0, 0 },
   2719     { { 0, "GET /aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa HTTP/1.1\r\n"
   2720         "Host: x\r\nX-Long: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n\r\n" },
   2721       P_END, P_END, P_END } },
   2722 
   2723   /* A request body over TLS, so that the receive adapter is used for
   2724      more than the request line. */
   2725   { "tls-request-body",
   2726     { 0, 0x00, 0, 0, 0x41, 0x00, 0x00, 0x00, 0, 0 },
   2727     { { 0, "POST /a HTTP/1.1\r\nHost: x\r\nContent-Length: 11\r\n\r\n"
   2728         "hello world" },
   2729       P_END, P_END, P_END } },
   2730 
   2731   /* The external event loop (MHD_get_fdset() + MHD_run_from_select()). */
   2732   { "tls-external-loop",
   2733     { 0, 0x00, 0, 0, 0x41, 0x10, 0x04, 0x00, 0, 0 },
   2734     { { 0, "GET / HTTP/1.1\r\nHost: x\r\n\r\n" }, P_END, P_END, P_END } },
   2735 
   2736   /* MHD_quiesce_daemon() with a live TLS connection. */
   2737   { "tls-quiesce",
   2738     { 0, 0x00, 0, 0, 0x41, 0x00, 0x80, 0x00, 0, 0 },
   2739     { { 0, "GET / HTTP/1.1\r\nHost: x\r\n\r\n" }, P_END, P_END, P_END } }
   2740 };
   2741 
   2742 static uint8_t seed_render_buf[2048];
   2743 
   2744 
   2745 static size_t
   2746 fuzz_seed_count (void)
   2747 {
   2748   return sizeof (seeds) / sizeof (seeds[0]);
   2749 }
   2750 
   2751 
   2752 static const uint8_t *
   2753 fuzz_seed_get (size_t idx,
   2754                size_t *len)
   2755 {
   2756   const struct seed_def *sd = &seeds[idx];
   2757   struct sbuf b;
   2758   unsigned int i;
   2759 
   2760   b.p = seed_render_buf;
   2761   b.len = 0;
   2762   b.cap = sizeof (seed_render_buf);
   2763   sb_raw (&b, sd->cfg, sizeof (sd->cfg));
   2764   for (i = 0; i < sizeof (sd->parts) / sizeof (sd->parts[0]); i++)
   2765   {
   2766     if (NULL == sd->parts[i].txt)
   2767       break;
   2768     emit_segment (&b, sd->parts[i].op,
   2769                   (const uint8_t *) sd->parts[i].txt,
   2770                   strlen (sd->parts[i].txt));
   2771   }
   2772   *len = b.len;
   2773   return seed_render_buf;
   2774 }
   2775 
   2776 
   2777 #else  /* ! HTTPS_SUPPORT */
   2778 
   2779 /*
   2780  * MHD was configured without HTTPS (which is what
   2781  * contrib/oss-fuzz/build.sh does for the MemorySanitizer build), so
   2782  * there is no TLS layer to fuzz.  The file still has to produce a valid
   2783  * fuzz target: LLVMFuzzerTestOneInput() must exist unconditionally, or
   2784  * an OSS-Fuzz build of this harness would silently be an empty binary.
   2785  */
   2786 
   2787 int
   2788 LLVMFuzzerTestOneInput (const uint8_t *data,
   2789                         size_t size)
   2790 {
   2791   fuzz_ignore_sigpipe ();
   2792   (void) data;
   2793   (void) size;
   2794   return 0;
   2795 }
   2796 
   2797 
   2798 static size_t
   2799 fuzz_generate (struct fuzz_rng *rng,
   2800                uint8_t *buf,
   2801                size_t cap)
   2802 {
   2803   (void) rng;
   2804   if (0 == cap)
   2805     return 0;
   2806   buf[0] = 0;
   2807   return 1;
   2808 }
   2809 
   2810 
   2811 static const uint8_t no_https_seed[] = { 0 };
   2812 
   2813 
   2814 static size_t
   2815 fuzz_seed_count (void)
   2816 {
   2817   return 1;
   2818 }
   2819 
   2820 
   2821 static const uint8_t *
   2822 fuzz_seed_get (size_t idx,
   2823                size_t *len)
   2824 {
   2825   (void) idx;
   2826   *len = sizeof (no_https_seed);
   2827   return no_https_seed;
   2828 }
   2829 
   2830 
   2831 #endif /* ! HTTPS_SUPPORT */
   2832 
   2833 /* end of fuzz_tls.c */