178#define FUZZ_HARNESS_NAME "fuzz_tls"
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>
222__lsan_default_suppressions (
void);
225__lsan_default_suppressions (
void)
227 return "leak:gnutls_x509_crt_init\n";
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
239#define CLIENT_PRIO_COUNT 4
246#define HANDSHAKE_ROUNDS 64
261static 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";
299static 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";
330static 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";
364static 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";
386static 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";
417static 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";
428static const char garbage_cert_pem[] =
429 "-----BEGIN CERTIFICATE-----\n"
430 "this is not base64 at all, not even close !!!! ????\n"
431 "-----END CERTIFICATE-----\n";
433static const char garbage_key_pem[] =
434 "-----BEGIN PRIVATE KEY-----\n"
435 "@@@@ neither is this @@@@\n"
436 "-----END PRIVATE KEY-----\n";
439static const char truncated_cert_pem[] =
440 "-----BEGIN CERTIFICATE-----\n"
441 "MIIFSzCCAzOgAwIBAgIBBDANBgkqhkiG9w0BAQsFADCBgTELMAkGA1UEBhMCUlUx\n"
442 "DzANBgNVBAgMBk1vc2NvdzEPMA0GA1UEBwwGTW9zY293MRswGQYDVQQKDBJ0ZXN0\n";
444static const char truncated_key_pem[] =
445 "-----BEGIN PRIVATE KEY-----\n"
446 "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCff7amw9zNSE+h\n";
449static const char no_armour_pem[] =
450 "MIIFSzCCAzOgAwIBAgIBBDANBgkqhkiG9w0BAQsFADCBgTELMAkGA1UEBhMCUlUx\n"
451 "DzANBgNVBAgMBk1vc2NvdzEPMA0GA1UEBwwGTW9zY293MRswGQYDVQQKDBJ0ZXN0\n";
453static const char garbage_dh_pem[] =
454 "-----BEGIN DH PARAMETERS-----\n"
455 "not-dh-parameters\n"
456 "-----END DH PARAMETERS-----\n";
463static char fuzz_cert_pem[FUZZ_PEM_BODY_MAX + 128];
464static char fuzz_key_pem[FUZZ_PEM_BODY_MAX + 128];
478static const struct cred_pair cred_tbl[] = {
479 { srv_signed_cert_pem, srv_signed_key_pem },
480 { srv_self_signed_cert_pem, srv_self_signed_key_pem },
481 { srv_signed_cert_pem, srv_self_signed_key_pem },
482 { srv_self_signed_cert_pem, srv_signed_key_pem },
483 { srv_signed_cert_pem,
NULL },
484 {
NULL, srv_signed_key_pem },
487 { truncated_cert_pem, srv_signed_key_pem },
488 { srv_signed_cert_pem, truncated_key_pem },
489 { garbage_cert_pem, garbage_key_pem },
490 { no_armour_pem, srv_signed_key_pem },
491 { fuzz_cert_pem, srv_signed_key_pem },
492 { srv_signed_cert_pem, fuzz_key_pem },
493 { fuzz_cert_pem, fuzz_key_pem },
494 { srv_signed_cert_pem, srv_signed_key_pem }
497#define CRED_COUNT (sizeof (cred_tbl) / sizeof (cred_tbl[0]))
505static const char *
const prio_tbl[] = {
507 "NORMAL:-VERS-ALL:+VERS-TLS1.3",
508 "NORMAL:-VERS-ALL:+VERS-TLS1.2",
515 "BOGUS-PRIORITY-STRING",
519 "NORMAL:%SERVER_PRECEDENCE",
520 "SECURE256:-CIPHER-ALL",
524#define PRIO_COUNT (sizeof (prio_tbl) / sizeof (prio_tbl[0]))
527static const char *
const client_prio_tbl[CLIENT_PRIO_COUNT] = {
529 "NORMAL:-VERS-ALL:+VERS-TLS1.3",
530 "NORMAL:-VERS-ALL:+VERS-TLS1.2",
549static 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"
561static 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,
567 (
int) GNUTLS_CRD_CERTIFICATE,
572#define CRED_TYPE_COUNT (sizeof (cred_type_tbl) / sizeof (cred_type_tbl[0]))
575#define PSK_CRED_TYPE_IDX 1u
590static 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
596 0 , 256, 512, 1024, 1400, 1500, 2048, 4096, 8192, 32768,
597 0, 1024, 2048, 4096, 16384, 0
600#define MEM_LIMIT_COUNT (sizeof (mem_limit_tbl) / sizeof (mem_limit_tbl[0]))
602static const char https_key_password[] =
"not-the-password";
666 unsigned int prio_idx;
667 const char *prio_str;
669 unsigned int cred_type_idx;
674 unsigned int loop_mode;
677 enum sni_behaviour sni_mode;
681 enum psk_behaviour psk_mode;
684 enum client_mode mode;
688 unsigned int client_prio_idx;
691 unsigned int hs_budget;
692 unsigned int extra_pump;
695 unsigned int resp_kind;
702 int stop_with_queued;
705static struct fuzz_cfg
cfg;
713static const char *
const sni_name_tbl[] = {
717 "nobody.example.org",
721 "a.very.long.name.that.nobody.has.a.certificate.for.example.org"
724#define SNI_NAME_COUNT (sizeof (sni_name_tbl) / sizeof (sni_name_tbl[0]))
727static char sni_name[MAX_SNI_LEN + 1];
728static size_t sni_name_len;
737static unsigned long stat_connections;
738static unsigned long stat_handshakes_ok;
739static unsigned long stat_handshakes_failed;
741static unsigned long stat_sni_calls;
742static unsigned long stat_psk_calls;
752 "%s: daemons=%lu (start failed=%lu) connections=%lu "
753 "handshakes ok=%lu failed=%lu handler calls=%lu SNI calls=%lu "
758 stat_sni_calls, stat_psk_calls);
776 const char *cert_pem;
778 gnutls_pcert_st pcrt;
779 gnutls_privkey_t key;
783static struct sni_host sni_hosts[2] = {
788static int sni_hosts_ready;
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;
806 for (i = 0; i <
sizeof (sni_hosts) /
sizeof (sni_hosts[0]); i++)
808 struct sni_host *h = &sni_hosts[i];
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))
816 sni_hosts_ready = -1;
819 if (GNUTLS_E_SUCCESS != gnutls_privkey_init (&h->key))
821 gnutls_pcert_deinit (&h->pcrt);
822 sni_hosts_ready = -1;
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,
831 gnutls_privkey_deinit (h->key);
833 gnutls_pcert_deinit (&h->pcrt);
834 sni_hosts_ready = -1;
839 return (1 == sni_hosts_ready) ? 0 : -1;
849sni_callback (gnutls_session_t session,
850 const gnutls_datum_t *req_ca_dn,
852 const gnutls_pk_algorithm_t *pk_algos,
854 gnutls_pcert_st **pcert,
855 unsigned int *pcert_length,
856 gnutls_privkey_t *pkey)
858 char name[MAX_SNI_LEN + 1];
859 size_t name_len =
sizeof (name);
866 (void) pk_algos_length;
868 if (! sni_hosts[0].loaded)
870 switch (
cfg.sni_mode)
880 *pcert = &sni_hosts[0].pcrt;
885 if (! sni_hosts[1].loaded)
887 *pcert = &sni_hosts[0].pcrt;
889 *pkey = sni_hosts[1].key;
891 case SNI_SELF_SIGNED:
892 if (! sni_hosts[1].loaded)
894 *pcert = &sni_hosts[1].pcrt;
896 *pkey = sni_hosts[1].key;
899 if (GNUTLS_E_SUCCESS !=
900 gnutls_server_name_get (session, name, &name_len, &type, 0))
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)) )
906 *pcert = &sni_hosts[i].pcrt;
908 *pkey = sni_hosts[i].key;
913 case SNI_BEHAVIOUR_COUNT:
917 *pcert = &sni_hosts[0].pcrt;
919 *pkey = sni_hosts[0].key;
928static const char resp_body[] =
"hello world over TLS";
937 const char *upload_data,
938 size_t *upload_data_size,
951 if (
NULL == *req_cls)
957 if (0 != *upload_data_size)
960 *upload_data_size = 0;
985 switch (
cfg.resp_kind)
1005 if (
cfg.resp_header)
1026 (void) snprintf (msg,
sizeof (msg),
1027 "MHD_PANIC() reached at %s:%u: %s",
1028 (
NULL != file) ? file :
"?",
1030 (
NULL != reason) ? reason :
"?");
1055 if (0 ==
cfg.loop_mode)
1063 if (1 ==
cfg.loop_mode)
1077 (
unsigned int) FD_SETSIZE))
1086 (void) select ((
int) max_fd + 1, &rs, &ws, &es, &tv);
1087 if (1 ==
cfg.loop_mode)
1098#if GNUTLS_VERSION_MAJOR >= 3
1116psk_cred_cb (
void *cls,
1118 const char *username,
1129 switch (
cfg.psk_mode)
1140 len =
sizeof (psk_key_bytes) - 1;
1146 len = (
NULL != username) ? strlen (username) : 0;
1151#if SIZE_MAX > UINT_MAX
1155 buf = (
unsigned char *) malloc (1);
1160 *psk_size = (size_t)
UINT_MAX + 1u;
1163 len =
sizeof (psk_key_bytes);
1167 case PSK_NO_HANDLER:
1168 case PSK_BEHAVIOUR_COUNT:
1170 len =
sizeof (psk_key_bytes);
1177 buf = (
unsigned char *) malloc (0 != len ? len : 1);
1184 for (i = 0; i < len; i++)
1185 buf[i] = psk_key_bytes[i %
sizeof (psk_key_bytes)];
1204 gnutls_session_t sess;
1205 gnutls_certificate_credentials_t cred;
1206 gnutls_psk_client_credentials_t psk;
1215 unsigned int rounds)
1219 for (i = 0; i < rounds; i++)
1230tc_drain (
struct tls_client *tc)
1237 if (
NULL == tc->sess)
1241 ssize_t n = recv (tc->fd, tmp, sizeof (tmp), MSG_DONTWAIT);
1253 if (tc->dead || (! tc->hs_done))
1255 for (i = 0; i < 8; i++)
1257 ssize_t n = gnutls_record_recv (tc->sess, tmp, sizeof (tmp));
1270 if ( (GNUTLS_E_AGAIN == n) ||
1271 (GNUTLS_E_INTERRUPTED == n) )
1273 if (0 != gnutls_error_is_fatal ((
int) n))
1282 struct tls_client *tc,
1283 unsigned int rounds)
1287 for (i = 0; i < rounds; i++)
1303 struct tls_client *tc,
1304 unsigned int rounds)
1308 if ( (
NULL == tc->sess) ||
1310 (0 != tc->hs_done) )
1312 for (i = 0; i < rounds; i++)
1314 int ret = gnutls_handshake (tc->sess);
1316 if (GNUTLS_E_SUCCESS == ret)
1319 stat_handshakes_ok++;
1322 if (0 != gnutls_error_is_fatal (ret))
1325 stat_handshakes_failed++;
1345 struct tls_client *tc)
1348 struct sockaddr_in sa;
1350#if GNUTLS_VERSION_NUMBER >= 0x030500
1351 gnutls_init_flags_t flags;
1356 memset (tc, 0,
sizeof (*tc));
1358 if (0 != socketpair (AF_UNIX, SOCK_STREAM, 0, sv))
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);
1366 (
const struct sockaddr *) &sa,
1367 (socklen_t)
sizeof (sa)))
1370 (void) close (sv[0]);
1377 fl = fcntl (tc->fd, F_GETFL, 0);
1379 (void) fcntl (tc->fd, F_SETFL, fl | O_NONBLOCK);
1380 if ( (CLIENT_TLS !=
cfg.mode) &&
1381 (CLIENT_TLS_ABANDON !=
cfg.mode) )
1384 if (GNUTLS_E_SUCCESS !=
1385 gnutls_certificate_allocate_credentials (&tc->cred))
1391 if (
cfg.client_cert)
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);
1403 flags = GNUTLS_CLIENT;
1404#if GNUTLS_VERSION_MAJOR >= 3
1405 flags |= GNUTLS_NONBLOCK;
1407#if GNUTLS_VERSION_NUMBER >= 0x030402
1408 flags |= GNUTLS_NO_SIGNAL;
1410 if (GNUTLS_E_SUCCESS != gnutls_init (&tc->sess, flags))
1416 if (GNUTLS_E_SUCCESS !=
1417 gnutls_priority_set_direct (tc->sess,
1419 ? psk_prio_tbl[
cfg.client_prio_idx]
1420 : client_prio_tbl[
cfg.client_prio_idx],
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))
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))
1442 if (GNUTLS_E_SUCCESS !=
1443 gnutls_psk_set_client_credentials (tc->psk,
1446 GNUTLS_PSK_KEY_RAW))
1448 else if (GNUTLS_E_SUCCESS !=
1449 gnutls_credentials_set (tc->sess, GNUTLS_CRD_PSK, tc->psk))
1453 if ( (
cfg.client_sni) &&
1454 (0 != sni_name_len) )
1455 (void) gnutls_server_name_set (tc->sess,
1459 gnutls_transport_set_int (tc->sess, tc->fd);
1462 gnutls_handshake_set_timeout (tc->sess, 0);
1469 struct tls_client *tc,
1474 unsigned int stall = 0;
1476 if ( (0 > tc->fd) ||
1479 if (
NULL == tc->sess)
1481 while ( (off < len) &&
1484 ssize_t s = send (tc->fd, buf + off, len - off, MSG_DONTWAIT);
1493 pump_and_drain (d, tc, 2);
1495 (EAGAIN != errno) &&
1496 (EWOULDBLOCK != errno) &&
1502 if ( (0 != tc->dead) ||
1503 (0 == tc->hs_done) )
1505 while ( (off < len) &&
1510 ssize_t s = gnutls_record_send (tc->sess, buf + off, len - off);
1518 if ( (GNUTLS_E_AGAIN == s) ||
1519 (GNUTLS_E_INTERRUPTED == s) )
1522 pump_and_drain (d, tc, 2);
1525 if (0 != gnutls_error_is_fatal ((
int) s))
1538 struct tls_client *tc)
1540 if (
NULL != tc->sess)
1542 if ( (
cfg.client_bye) &&
1544 (0 != tc->hs_done) )
1548 for (i = 0; i < 8; i++)
1550 int ret = gnutls_bye (tc->sess, GNUTLS_SHUT_WR);
1552 if ( (GNUTLS_E_AGAIN != ret) &&
1553 (GNUTLS_E_INTERRUPTED != ret) )
1558 gnutls_deinit (tc->sess);
1561 if (
NULL != tc->cred)
1563 gnutls_certificate_free_credentials (tc->cred);
1566 if (
NULL != tc->psk)
1568 gnutls_psk_free_client_credentials (tc->psk);
1573 if (
cfg.client_shut_wr)
1574 (void) shutdown (tc->fd, SHUT_WR);
1576 (void) close (tc->fd);
1599 struct sockaddr_in sa;
1601 if (0 != socketpair (AF_UNIX, SOCK_STREAM, 0, sv))
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);
1609 (
const struct sockaddr *) &sa,
1610 (socklen_t)
sizeof (sa)))
1613 (void) close (sv[0]);
1625 struct tls_client *tc)
1627 if (0 != tc_open (d, tc))
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);
1651build_fuzz_pem (
char *out,
1654 const uint8_t *body,
1661 n = snprintf (out, out_size,
"-----BEGIN %s-----\n", label);
1663 ((
size_t) n >= out_size) )
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++)
1675 out[o++] = (char) ((0 == body[i]) ?
'A' : body[i]);
1677 n = snprintf (out + o, out_size - o,
"\n-----END %s-----\n", label);
1693 unsigned int nopt = 0;
1695 struct tls_client tc;
1697 unsigned int nseg = 0;
1698 unsigned int nconn = 1;
1711 memset (&
cfg, 0,
sizeof (
cfg));
1714 const char *nm = sni_name_tbl[(
data[9] & 0x07) % SNI_NAME_COUNT];
1716 sni_name_len = strlen (nm);
1717 memcpy (sni_name, nm, sni_name_len + 1);
1720 cfg.cert = cred_tbl[
data[0] % CRED_COUNT].cert;
1721 cfg.key = cred_tbl[
data[0] % CRED_COUNT].key;
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));
1732 cfg.prio_idx = (
unsigned int) (
data[2] % PRIO_COUNT);
1734 cfg.cred_type_idx = (
unsigned int) (
data[3] & 0x07) % CRED_TYPE_COUNT;
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));
1741 cfg.prio_str = prio_tbl[
cfg.prio_idx];
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));
1751 cfg.loop_mode = (
unsigned int) ((
data[5] >> 4) & 0x03);
1752 cfg.stop_with_queued = (0 != (
data[5] & 0x40));
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));
1762 cfg.hs_budget = 1u + (
unsigned int) (
data[7] & 0x07);
1763 cfg.use_tls = (0 == (
data[7] & 0x08));
1765 (0 != (
data[7] & 0x10)) &&
1767 cfg.extra_pump = (
unsigned int) ((
data[7] >> 5) & 0x07);
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));
1778 cfg.psk_scenario = 0;
1784 if (
cfg.psk_scenario)
1787 cfg.use_cred_type = 1;
1788 cfg.cred_type_idx = PSK_CRED_TYPE_IDX;
1790 cfg.prio_append = 0;
1791 cfg.prio_str = psk_prio_tbl[
cfg.client_prio_idx];
1795 if ( (CLIENT_TLS !=
cfg.mode) &&
1796 (CLIENT_TLS_ABANDON !=
cfg.mode) )
1797 cfg.mode = CLIENT_TLS;
1805 if ( (
cfg.use_sni) &&
1806 (0 != sni_hosts_init ()) )
1813 size_t body = (size_t)
data[8] * 4u;
1815 if (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);
1823 if (0 !=
cfg.mem_limit)
1826 opts[nopt].value = (intptr_t)
cfg.mem_limit;
1827 opts[nopt].ptr_value =
NULL;
1833 opts[nopt].value = 0;
1834 opts[nopt].ptr_value = (
void *) (intptr_t)
cfg.key;
1840 opts[nopt].value = 0;
1841 opts[nopt].ptr_value = (
void *) (intptr_t)
cfg.cert;
1844 if (
cfg.key_password)
1847 opts[nopt].value = 0;
1848 opts[nopt].ptr_value = (
void *) (intptr_t) https_key_password;
1854 opts[nopt].value = 0;
1855 opts[nopt].ptr_value = (
void *) (intptr_t)
1856 (
cfg.trust_garbage ? garbage_cert_pem
1860 if (
cfg.use_dhparams)
1863 opts[nopt].value = 0;
1864 opts[nopt].ptr_value = (
void *) (intptr_t)
1865 (
cfg.dh_garbage ? garbage_dh_pem : dh_params_pem);
1870 opts[nopt].option =
cfg.prio_append
1873 opts[nopt].value = 0;
1874 opts[nopt].ptr_value = (
void *) (intptr_t)
cfg.prio_str;
1877 if (
cfg.use_cred_type)
1880 opts[nopt].value = (intptr_t) cred_type_tbl[
cfg.cred_type_idx];
1881 opts[nopt].ptr_value =
NULL;
1887 opts[nopt].value = 1;
1888 opts[nopt].ptr_value =
NULL;
1892 opts[nopt].value = 0;
1893 opts[nopt].ptr_value =
NULL;
1900 if (
cfg.allow_upgrade)
1915#if GNUTLS_VERSION_MAJOR >= 3
1922 cfg.use_sni ? &sni_callback :
NULL,
1924 (
cfg.psk_scenario &&
1925 (PSK_NO_HANDLER !=
cfg.psk_mode))
1926 ? &psk_cred_cb :
NULL,
1936 cfg.use_sni ? &sni_callback :
NULL,
1950 if (
cfg.daemon_info)
1969 while ( (pos + 2 <= size) &&
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);
1979 if (slen > size - pos)
1987 if (n > MAX_SNI_LEN)
1989 memcpy (sni_name,
data + pos, n);
1993 (
'\0' == sni_name[n - 1]) )
2006 else if ( (3 ==
op) &&
2016 tc_send (d, &tc,
data + pos, slen);
2018 pump_and_drain (d, &tc, (2 ==
op) ? (6u +
cfg.extra_pump) : 3u);
2022 pump_and_drain (d, &tc, 2u +
cfg.extra_pump);
2034 if (
cfg.stop_with_queued)
2038 (void) close (queued_fd);
2060 if (b->len + n > b->cap)
2061 n = b->cap - b->len;
2062 memcpy (b->p + b->len, v, n);
2071 sb_raw (b, s, strlen (s));
2076sb_u32 (
struct sbuf *b,
2084 tmp[n++] = (char) (
'0' + (v % 10u));
2088 (n <
sizeof (tmp)) );
2116 "GET",
"POST",
"HEAD",
"PUT",
"OPTIONS",
"BREW"
2120 "/",
"/a",
"/index.html",
"/a?b=c",
"/%41%42",
"*",
"//"
2124 "HTTP/1.1",
"HTTP/1.0",
"HTTP/1.2",
"HTTP/9.9"
2128 "Host",
"User-Agent",
"Accept",
"Connection",
"X-Fuzz",
"Cookie",
2129 "Content-Type",
"Expect"
2133 "x",
"localhost",
"*/*",
"keep-alive",
"close",
"100-continue",
2143gen_http_request (
struct fuzz_rng *rng,
2164 for (i = 0; i < nh; i++)
2179 sb_str (b,
"Content-Length: ");
2182 for (i = 0; i < blen; i++)
2184 char c = (char) (
'a' + (
int)
fuzz_below (rng, 26));
2201gen_tls_records (
struct fuzz_rng *rng,
2208 for (i = 0; i < n; i++)
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++)
2239#define PRIO_VALID_COUNT 7
2249make_daemon_startable (
struct fuzz_rng *rng,
2252 cfg_bytes[1] &= (uint8_t) ~0x10u;
2253 cfg_bytes[3] &= (uint8_t) ~0xC0u;
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;
2264emit_segment (
struct sbuf *out,
2266 const uint8_t *payload,
2274 hv = (
op << 14) | (
unsigned int) len;
2275 hdr[0] = (uint8_t) (hv & 0xFF);
2276 hdr[1] = (uint8_t) (hv >> 8);
2278 sb_raw (out, payload, len);
2290 uint8_t cfg_bytes[10];
2301 const char *e = getenv (
"MHD_FUZZ_SHAPE");
2312 for (i = 0; i <
sizeof (cfg_bytes); i++)
2318 cfg_bytes[7] &= (uint8_t) ~0x08u;
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;
2325 make_daemon_startable (rng, cfg_bytes);
2327 case SHAPE_RAW_BYTES:
2329 cfg_bytes[4] = (uint8_t) ((cfg_bytes[4] & ~0x03u) | CLIENT_RAW);
2330 make_daemon_startable (rng, cfg_bytes);
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)
2337 make_daemon_startable (rng, cfg_bytes);
2339 case SHAPE_BAD_CREDS:
2341 cfg_bytes[0] = (uint8_t) (2 +
fuzz_below (rng, 10));
2342 cfg_bytes[4] = (uint8_t) ((cfg_bytes[4] & ~0x03u)
2346 case SHAPE_BAD_OPTIONS:
2347 cfg_bytes[1] |= 0x18u;
2348 cfg_bytes[2] = (uint8_t)
fuzz_below (rng, (uint32_t) PRIO_COUNT);
2351 cfg_bytes[7] |= 0x08u;
2352 cfg_bytes[4] = (uint8_t) ((cfg_bytes[4] & ~0x03u)
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;
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)
2375 cfg_bytes[4] = (uint8_t) ((cfg_bytes[4] & ~0x03u) | CLIENT_RECORDS);
2376 make_daemon_startable (rng, cfg_bytes);
2382 cfg_bytes[4] = (uint8_t) ((cfg_bytes[4] & ~0x03u)
2385 cfg_bytes[1] &= (uint8_t) ~0x04u;
2386 make_daemon_startable (rng, cfg_bytes);
2387 cfg_bytes[9] = (uint8_t)
2391 (uint32_t) PSK_BEHAVIOUR_COUNT)
2393 | (uint8_t)
fuzz_below (rng, (uint32_t) SNI_NAME_COUNT));
2403 sb_raw (&out, cfg_bytes,
sizeof (cfg_bytes));
2406 const char *nm = sni_name_tbl[cfg_bytes[9] & 0x07];
2408 emit_segment (&out, 1u, (
const uint8_t *) nm, strlen (nm));
2412 for (i = 0; i < nreq; i++)
2418 rb.cap =
sizeof (req);
2422 gen_tls_records (rng, &rb);
2424 case SHAPE_RAW_BYTES:
2429 for (j = 0; j < n; j++)
2438 gen_http_request (rng, &rb);
2447 if ( (rb.len > 8) &&
2450 size_t cut = 1 +
fuzz_below (rng, (uint32_t) (rb.len - 1));
2452 emit_segment (&out,
op, req, cut);
2453 emit_segment (&out, 2u, req + cut, rb.len - cut);
2457 emit_segment (&out,
op, req, rb.len);
2477 unsigned char cfg[10];
2478 struct seed_part parts[4];
2481#define P_END { 0, NULL }
2485static const struct seed_def
seeds[] = {
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 } },
2493 {
"tls-handshake-split",
2494 { 0, 0x00, 0, 0, 0x41, 0x00, 0x04, 0x00, 0, 0 },
2495 { { 0,
"GET / HTTP/1.1\r\nHo" },
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" },
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" },
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 } },
2520 { 0, 0x00, 0, 0, 0x80, 0x00, 0x00, 0x00, 0, 0 },
2525 {
"abandon-handshake",
2526 { 0, 0x00, 0, 0, 0x02, 0x00, 0x00, 0x00, 0, 0 },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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" },
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" },
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" },
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" },
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" },
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" },
2697 { 14, 0x00, 0, 0, 0x01, 0x00, 0x00, 0x00, 32, 0 },
2698 { { 0,
"MIIFSzCCAzOgAwIBAgIBBDANBgkqhkiG9w0BAQsFADCBgTELMAkGA1UEBhMCUlUx" },
2703 { 0, 0x00, 0, 0, 0x00, 0x00, 0x00, 0x00, 0, 0 },
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 } },
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 } },
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" },
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"
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 } },
2738 { 0, 0x00, 0, 0, 0x41, 0x00, 0x80, 0x00, 0, 0 },
2752static const uint8_t *
2756 const struct seed_def *sd = &
seeds[idx];
2763 sb_raw (&b, sd->cfg, sizeof (sd->cfg));
2764 for (i = 0; i <
sizeof (sd->parts) /
sizeof (sd->parts[0]); i++)
2766 if (
NULL == sd->parts[i].txt)
2768 emit_segment (&b, sd->parts[i].op,
2769 (
const uint8_t *) sd->parts[i].txt,
2770 strlen (sd->parts[i].txt));
2821static const uint8_t *
Shared, header-only fuzzing driver for the MHD in-process fuzzers.
static FUZZ_UNUSED void fuzz_ignore_sigpipe(void)
static FUZZ_UNUSED int fuzz_verbose
static FUZZ_UNUSED uint32_t fuzz_below(struct fuzz_rng *r, uint32_t n)
static FUZZ_UNUSED uint8_t fuzz_byte(struct fuzz_rng *r)
static FUZZ_UNUSED void fuzz_report_finding(const char *what)
static FUZZ_UNUSED int fuzz_chance(struct fuzz_rng *r, uint32_t n)
static const struct seed_def seeds[]
static int stats_registered
static unsigned long stat_daemons
static void panic_cb(void *cls, const char *file, unsigned int line, const char *reason)
static uint8_t seed_render_buf[64]
static enum MHD_Result ahc(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **req_cls)
static unsigned long stat_handler_calls
static int queue_unprocessed_conn(struct MHD_Daemon *d)
static const size_t mem_limit_tbl[]
static const char *const gen_hdr_values[]
static void pump(struct MHD_Daemon *d, int sock, unsigned int rounds)
static void run_once(struct MHD_Daemon *d)
static const char *const gen_targets[]
static void sb_raw(struct sbuf *b, const void *s, size_t n)
static void sb_str(struct sbuf *b, const char *s)
static const char *const gen_methods[]
static const char *const gen_hdr_names[]
static unsigned long stat_daemons_failed
static const char resp_body[]
static const char *const gen_versions[]
static char resp_buf[RESP_BUF_SIZE]
static int forced_shape_read
static size_t fuzz_seed_count(void)
#define FUZZ_HARNESS_NAME
static const uint8_t * fuzz_seed_get(size_t idx, size_t *len)
static const uint8_t no_https_seed[]
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
static size_t fuzz_generate(struct fuzz_rng *rng, uint8_t *buf, size_t cap)
#define MHD_run_from_select(d, r, w, e)
_MHD_EXTERN void MHD_stop_daemon(struct MHD_Daemon *daemon)
_MHD_EXTERN enum MHD_Result MHD_run(struct MHD_Daemon *daemon)
_MHD_EXTERN enum MHD_Result MHD_get_fdset2(struct MHD_Daemon *daemon, fd_set *read_fd_set, fd_set *write_fd_set, fd_set *except_fd_set, MHD_socket *max_fd, unsigned int fd_setsize)
#define MHD_get_fdset(daemon, read_fd_set, write_fd_set, except_fd_set, max_fd)
_MHD_EXTERN enum MHD_Result MHD_run_from_select2(struct MHD_Daemon *daemon, const fd_set *read_fd_set, const fd_set *write_fd_set, const fd_set *except_fd_set, unsigned int fd_setsize)
_MHD_EXTERN struct MHD_Daemon * MHD_start_daemon(unsigned int flags, uint16_t port, MHD_AcceptPolicyCallback apc, void *apc_cls, MHD_AccessHandlerCallback dh, void *dh_cls,...)
#define MHD_HTTP_FORBIDDEN
_MHD_EXTERN void MHD_set_panic_func(MHD_PanicCallback cb, void *cls)
@ MHD_CONNECTION_INFO_GNUTLS_SESSION
@ MHD_CONNECTION_INFO_CIPHER_ALGO
@ MHD_CONNECTION_INFO_CLIENT_ADDRESS
@ MHD_CONNECTION_INFO_GNUTLS_CLIENT_CERT
@ MHD_CONNECTION_INFO_CONNECTION_FD
@ MHD_CONNECTION_INFO_PROTOCOL
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_buffer_copy(size_t size, const void *buffer)
_MHD_EXTERN enum MHD_Result MHD_queue_response(struct MHD_Connection *connection, unsigned int status_code, struct MHD_Response *response)
_MHD_EXTERN void MHD_destroy_response(struct MHD_Response *response)
_MHD_EXTERN struct MHD_Response * MHD_create_response_empty(enum MHD_ResponseFlags flags)
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_buffer_static(size_t size, const void *buffer)
_MHD_EXTERN enum MHD_Result MHD_add_response_header(struct MHD_Response *response, const char *header, const char *content)
_MHD_EXTERN enum MHD_Result MHD_add_connection(struct MHD_Daemon *daemon, MHD_socket client_socket, const struct sockaddr *addr, socklen_t addrlen)
_MHD_EXTERN enum MHD_Result MHD_is_feature_supported(enum MHD_FEATURE feature)
_MHD_EXTERN enum MHD_Result MHD_set_connection_option(struct MHD_Connection *connection, enum MHD_CONNECTION_OPTION option,...)
_MHD_EXTERN MHD_socket MHD_quiesce_daemon(struct MHD_Daemon *daemon)
_MHD_EXTERN const union MHD_DaemonInfo * MHD_get_daemon_info(struct MHD_Daemon *daemon, enum MHD_DaemonInfoType info_type,...)
_MHD_EXTERN const union MHD_ConnectionInfo * MHD_get_connection_info(struct MHD_Connection *connection, enum MHD_ConnectionInfoType info_type,...)
additional automatic macros for MHD_config.h
public interface to libmicrohttpd
@ MHD_OPTION_HTTPS_PRIORITIES_APPEND
@ MHD_OPTION_HTTPS_CRED_TYPE
@ MHD_OPTION_HTTPS_PRIORITIES
@ MHD_OPTION_HTTPS_MEM_DHPARAMS
@ MHD_OPTION_HTTPS_MEM_CERT
@ MHD_OPTION_HTTPS_MEM_KEY
@ MHD_OPTION_HTTPS_KEY_PASSWORD
@ MHD_OPTION_CONNECTION_MEMORY_LIMIT
@ MHD_OPTION_GNUTLS_PSK_CRED_HANDLER
@ MHD_OPTION_HTTPS_MEM_TRUST
@ MHD_OPTION_HTTPS_CERT_CALLBACK
#define MHD_INVALID_SOCKET
@ MHD_DAEMON_INFO_BIND_PORT
@ MHD_DAEMON_INFO_CURRENT_CONNECTIONS
@ MHD_DAEMON_INFO_LISTEN_FD
@ MHD_USE_NO_LISTEN_SOCKET
@ MHD_CONNECTION_OPTION_TIMEOUT