On Wed, Nov 03, 2021 at 12:38:51PM +0000, Jason Schultz wrote: > In any case, things appear to be working now, but I'm hitting an issue > later on when calling SSL_CTX_build_cert_chain(). I working on > debugging that, I may have to start yet another thread later.
Your mistake is probably in loading a certificate file, rather than a certificate chain file. With the latter, you'd also pick up any associated intermediate issuer certificates (e.g. from certbot's "fullchain.pem"). With the intermediate certificates thus obtained, you're far more likely to be able to verify the completely server's chain relative to some trust store with exclusively or mostly just a bunch of root CAs. I'd in fact recommend not rebuilding the provided chain, but just observing whether it is complete, the user may have good reasons for going with some alternative sequence of issuer CAs (e.g. to support old Android devices, as with e.g. current Let's Encrypt redundant cross cert). Therefore, per: SSL_CTX_build_cert_chain() builds the certificate chain for ctx. Normally this uses the chain store or the verify store if the chain store is not set. If the function is successful the built chain will replace any existing chain. The flags parameter can be set to SSL_BUILD_CHAIN_FLAG_UNTRUSTED to use existing chain certificates as untrusted CAs, SSL_BUILD_CHAIN_FLAG_NO_ROOT to omit the root CA from the built chain, SSL_BUILD_CHAIN_FLAG_CHECK to use all existing chain certificates only to build the chain (effectively sanity checking and rearranging them if necessary), the flag SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR ignores any errors during verification: if flag SSL_BUILD_CHAIN_FLAG_CLEAR_ERROR is also set verification errors are cleared from the error queue. Details of the chain building process are described in "Certification Path Building" in openssl-verification-options(1). I'd set the flags to: SSL_BUILD_CHAIN_FLAG_UNTRUSTED | SSL_BUILD_CHAIN_FLAG_CHECK if you're sure the service is not DANE TLSA enabled, and there's definitely good reason to omit the root CA from the chain, or you provide a configuration to let the user make the choice, you can also add: SSL_BUILD_CHAIN_FLAG_NO_ROOT which is often, but not always appropriate, and should ideally not be unconditionally hardcoded. Be sure to clear the error queue before starting, and after reporting any errors observed. -- Viktor.