#2705·folly

folly does not build against OpenSSL 4.0 (opaque ASN1_STRING, const X509 accessors); fizz and wangle affected too

Author: michel-slmCreated Sep 17, 2026Updated Sep 17, 2026

Summary

folly does not compile against OpenSSL 4.0 (released 2026-04-14). Two kinds of change bite: ASN1_STRING is now opaque, and a set of X509_* accessors now return const pointers. folly fails in two files; fizz and wangle use the same accessors and will need the same treatment. The fixes are mechanical and the corrected forms are valid on OpenSSL 1.1 and 3.x too, so no version conditionals should be needed.

Filed from packaging cachelib for Fedora: Fedora 45 and Rawhide ship OpenSSL 4.0.2, so the whole folly stack is currently unbuildable there. RHEL 9/10 and Fedora 44 are still on 3.5.

Build failure

folly at 594a1f3161c64f67e8653ce6df46641b16fb38bb (the revision the cachelib snapshot pins), GCC 16, OpenSSL 4.0.2, Fedora Rawhide aarch64:

folly/io/async/ssl/OpenSSLUtils.cpp:126:62: error: invalid use of incomplete type ‘ASN1_OCTET_STRING’ {aka ‘struct asn1_string_st’}
folly/io/async/ssl/OpenSSLUtils.cpp:127:53: error: invalid use of incomplete type ‘ASN1_OCTET_STRING’ {aka ‘struct asn1_string_st’}
folly/io/async/ssl/OpenSSLUtils.cpp:288:45: error: invalid conversion from ‘const X509_NAME*’ {aka ‘const X509_name_st*’} to ‘X509_NAME*’ {aka ‘X509_name_st*’} [-fpermissive]
folly/ssl/OpenSSLCertUtils.cpp:113:34: error: invalid conversion from ‘const asn1_string_st*’ to ‘ASN1_STRING*’ {aka ‘asn1_string_st*’} [-fpermissive]
folly/ssl/OpenSSLCertUtils.cpp:148:42: error: invalid conversion from ‘const X509_NAME*’ {aka ‘const X509_name_st*’} to ‘X509_NAME*’ {aka ‘X509_name_st*’} [-fpermissive]
folly/ssl/OpenSSLCertUtils.cpp:152:41: error: invalid conversion from ‘const X509_NAME*’ {aka ‘const X509_name_st*’} to ‘X509_NAME*’ {aka ‘X509_name_st*’} [-fpermissive]
folly/ssl/OpenSSLCertUtils.cpp:279:45: error: invalid conversion from ‘const X509_EXTENSION*’ {aka ‘const X509_extension_st*’} to ‘X509_EXTENSION*’ {aka ‘X509_extension_st*’} [-fpermissive]
folly/ssl/OpenSSLCertUtils.cpp:292:45: error: invalid conversion from ‘const X509_EXTENSION*’ {aka ‘const X509_extension_st*’} to ‘X509_EXTENSION*’ {aka ‘X509_extension_st*’} [-fpermissive]
folly/ssl/OpenSSLCertUtils.cpp:95:50: error: invalid conversion from ‘const ASN1_OBJECT*’ {aka ‘const asn1_object_st*’} to ‘ASN1_OBJECT*’ {aka ‘asn1_object_st*’} [-fpermissive]

What changed in OpenSSL 4.0

From the OpenSSL CHANGES for 4.0.0: "ASN1_STRING has been made opaque. Access to values from ASN1_STRING and related types should be done with the appropriate accessor functions." and "* const-corrected various function return values, particularly in X509 and related areas, and when functions were returning non-const objects owned by a const parameter. Bob Beck * Many functions accepting X509 * arguments, or returning values from a const X509 * have been changed to take/return const "

Prototypes, 3.5 vs 4.0 (include/openssl/x509.h.in):

function 3.5 returns 4.0 returns
X509_get_subject_name X509_NAME * const X509_NAME *
X509_get_issuer_name X509_NAME * const X509_NAME *
X509_get_ext X509_EXTENSION * const X509_EXTENSION *
X509_NAME_get_entry X509_NAME_ENTRY * const X509_NAME_ENTRY *
X509_NAME_ENTRY_get_object ASN1_OBJECT * const ASN1_OBJECT *
X509_NAME_ENTRY_get_data ASN1_STRING * const ASN1_STRING *
X509_EXTENSION_get_object ASN1_OBJECT * const ASN1_OBJECT *
X509_EXTENSION_get_data ASN1_OCTET_STRING * const ASN1_OCTET_STRING *
X509_get0_notBefore / X509_get0_notAfter const ASN1_TIME * unchanged
X509_get_X509_PUBKEY X509_PUBKEY * const X509_PUBKEY *
X509_get_serialNumber ASN1_INTEGER * unchanged

Plus the opaque ASN1_STRING: ->data / ->length on any ASN1_STRING-derived value (ASN1_OCTET_STRING, ASN1_IA5STRING, the GENERAL_NAME union members such as d.iPAddress and d.dNSName) must become ASN1_STRING_get0_data() / ASN1_STRING_length(), both available since 1.1.0.

Where the stack uses these

Call sites found by grepping the folly, fizz and wangle trees the cachelib snapshot pins (test files included, since they build with -Werror when tests are on):

function files
X509_get_subject_name folly io/async/ssl/OpenSSLUtils.cpp, ssl/OpenSSLCertUtils.cpp, io/async/ssl/test/OpenSSLUtilsTest.cpp; fizz protocol/OpenSSLCertificateVerifier.cpp, protocol/CertUtil.h; wangle ssl/SSLUtil.cpp
X509_get_issuer_name, X509_get_ext, X509_EXTENSION_get_data, X509_EXTENSION_get_object folly ssl/OpenSSLCertUtils.cpp
X509_NAME_get_entry, X509_NAME_ENTRY_get_data folly ssl/OpenSSLCertUtils.cpp, io/async/test/SSLContextTest.cpp; wangle ssl/test/SSLContextManagerTest.cpp
X509_get_serialNumber fizz protocol/CertUtil.h
X509_get0_notBefore / notAfter folly ssl/OpenSSLCertUtils.cpp; fizz extensions/delegatedcred/DelegatedCredentialUtils.cpp and its test
direct ->data / ->length on GENERAL_NAME.d.iPAddress folly io/async/ssl/OpenSSLUtils.cpp:126-127
sk_GENERAL_NAME_value results treated as mutable folly io/async/ssl/OpenSSLUtils.cpp, ssl/OpenSSLCertUtils.cpp; wangle ssl/SSLUtil.cpp

mvfst and fbthrift have no direct uses. Only the folly failures are confirmed by a compiler; fizz and wangle were not reached, and there may be further sites this grep misses (anything else assigning an X509_* getter result to a non-const pointer, or poking into an ASN1_STRING).

Suggested fix

Take the results as const on the receiving side and use the ASN1_STRING_get0_data() / ASN1_STRING_length() accessors, which compile unchanged against 1.1, 3.x and 4.0. folly/portability/OpenSSL.h currently only models FOLLY_OPENSSL_IS_3X; a 4.x notion may be useful if anything genuinely needs to differ.

Generated with Claude Code