← All libraries
Crypto · C
How to fuzz OpenSSL
Heartbleed proved that a single OOB read in OpenSSL breaks the entire internet.
OpenSSL's ASN.1 DER decoder, X.509 certificate parser, and TLS state machine are among the most security-critical C code on the internet. Its complexity — over 500 KLOC — means subtle length-field mismatches can survive years of code review, as Heartbleed demonstrated.
Common bug classes
- •Heap buffer over-read in ASN.1 DER length field (cf. Heartbleed)
- •Out-of-bounds write in BN bignum arithmetic on crafted parameters
- •Use-after-free in X.509 certificate chain verification
- •Integer overflow in EVP_EncryptUpdate buffer sizing
- •Null dereference in TLS session ticket extension parsing
Recommended setup
Fuzzers
- → AFL++
- → libFuzzer
- → Honggfuzz
- → Centipede
Sanitizers
- → ASan
- → UBSan
- → MSan
Harness scaffold
#include <stdint.h>
#include <stddef.h>
#include <openssl/x509.h>
#include <openssl/bio.h>
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
const uint8_t *p = data;
X509 *cert = d2i_X509(NULL, &p, (long)size);
if (cert) {
X509_verify_cert_error_string(X509_V_ERR_UNSPECIFIED);
X509_free(cert);
}
/* Also fuzz PEM path */
BIO *bio = BIO_new_mem_buf(data, (int)size);
if (bio) {
X509 *pem_cert = PEM_read_bio_X509(bio, NULL, NULL, NULL);
if (pem_cert) X509_free(pem_cert);
BIO_free(bio);
}
return 0;
}Save this as fuzz_target.cc, build with your compiler + sanitizer flags, and you have a working starting point.
Notable CVEs found by fuzzing
- → CVE-2014-0160
- → CVE-2022-0778
- → CVE-2022-3602
Push the harness above + a Dockerfile. First month 50% off.