Feature #2692


[PATCH] allow setting explicit SSL server certificate chain

Added by mackyle over 8 years ago. Updated over 6 years ago.

Target version:


To explain why this is needed, consider this comment from the
Apache mod_ssl ssl_engine_init.c source file:

     * Optionally configure extra server certificate chain certificates.
     * This is usually done by OpenSSL automatically when one of the
     * server cert issuers are found under SSLCACertificatePath or in
     * SSLCACertificateFile. But because these are intended for client
     * authentication it can conflict. For instance when you use a
     * Global ID server certificate you've to send out the intermediate
     * CA certificate, too. When you would just configure this with
     * SSLCACertificateFile and also use client authentication mod_ssl
     * would accept all clients also issued by this CA. Obviously this
     * isn't what we want in this situation. So this feature here exists
     * to allow one to explicity configure CA certificates which are
     * used only for the server certificate chain.

Note that SSLCACertificateFile corresponds to lighttpd's

However, lighttpd does not have an explicit directive to set the server's
sertificate chain. It sets only the server's certificate (excluding any
necessary intermediate certificates) using the SSL_CTX_use_certificate
function. The server's certificate chain, if it were to be configured
explicitly, would be set using the SSL_CTX_add_extra_chain_cert function.

However, lighttpd never calls the SSL_CTX_add_extra_chain_cert function.

But consider this information from the man page documentation about the
SSL_CTX_use_certificate function:

       SSL_CTX_use_certificate() loads the certificate x into ctx,
       SSL_use_certificate() loads x into ssl. The rest of the certificates
       needed to form the complete certificate chain can be specified using
       the SSL_CTX_add_extra_chain_cert(3) function.

       SSL_CTX_use_certificate_file() loads the first certificate stored in
       file into ctx. The formatting type of the certificate must be specified
       from the known types SSL_FILETYPE_PEM, SSL_FILETYPE_ASN1.
       SSL_use_certificate_file() loads the certificate from file into ssl.
       See the NOTES section on why SSL_CTX_use_certificate_chain_file()
       should be preferred.

       SSL_CTX_use_certificate_chain_file() loads a certificate chain from
       file into ctx. The certificates must be in PEM format and must be
       sorted starting with the subject's certificate (actual client or server
       certificate), followed by intermediate CA certificates if applicable,
       and ending at the highest level (root) CA.  There is no corresponding
       function working on a single SSL object.

       SSL_CTX_use_certificate_chain_file() is only applicable to PEM
       formatting.  Files of type SSL_FILETYPE_PEM can contain more than one

       SSL_CTX_use_certificate_chain_file() adds the first certificate found
       in the file to the certificate store. The other certificates are added
       to the store of chain certificates using
       SSL_CTX_add_extra_chain_cert(3).  There exists only one extra chain
       store, so that the same chain is appended to both types of
       certificates, RSA and DSA! If it is not intended to use both type of
       certificate at the same time, it is recommended to use the
       SSL_CTX_use_certificate_chain_file() instead of the
       SSL_CTX_use_certificate_file() function in order to allow the use of
       complete certificate chains even when no trusted CA storage is used or
       when the CA issuing the certificate shall not be added to the trusted
       CA storage.

We could switch from using the SSL_CTX_use_certificate function to the
SSL_CTX_use_certificate_chain_file function instead so that an optional
server certificate chain can simply be concatenated onto the end of the
file specified using the ssl.pemfile directive.

This requires only the very simplest change.

The problem with such a change is that the file may not be read until
after lighttpd has dropped privileges. If the file has restricted
privileges because it contains the server certificate's key it may not
be readable at that time.

However, the solution is simple. Just set a separate server certificate
key file with restricted permissions and relax the permissions on the
pemfile that then contains only non-sensitive certificates but no key.

Of course lighttpd has no ssl.keyfile directive making this impossible.

The alternative is to load the entire chain at the time the ssl.pemfile
is originally read and then call SSL_CTX_add_extra_chain_cert for each
extra certificate in the chain.

The final solution requires a bit more code than just using
SSL_CTX_use_certificate_chain_file would, but it's more compatible.

Also, while we we're mucking around with the SSL function calls, we take
the opportunity to correct the error return checking. Most SSL function
calls are documented as returning 1 on success. If it's not 1 then it
cannot be assumed to be successful, so checking for '< 0' for failure
or '!0' for success is simply incorrect. We correct all these checks.

Patch file attached.

See also


Related issues 1 (0 open1 closed)

Related to Bug #2562: SSL + SNI with cyclic CAs/not unique issuers? brokenFixedActions
Actions #1

Updated by gstrauss almost 8 years ago

  • Category changed from core to TLS
Actions #3

Updated by gstrauss almost 8 years ago

mackyle: thanks for rebasing your patches to master. I'd like to try to review them and related tickets in the next couple weeks.

There are a fair number of tickets that I recently categorized into 'TLS', including yours.
I could use some help evaluating all the TLS-related requests/issues so that they can all be addressed coherently.[]=status_id&op[status_id]=o&f[]=category_id&op[category_id]=%3D&v[category_id][]=47&f[]=&c[]=tracker&c[]=status&c[]=priority&c[]=subject&c[]=assigned_to&c[]=updated_on&c[]=category&c[]=fixed_version&group_by=

Actions #4

Updated by gstrauss almost 8 years ago

  • Assignee deleted (stbuehler)
  • Missing in 1.5.x deleted (Yes)
Actions #5

Updated by gstrauss over 7 years ago

  • Related to Bug #2562: SSL + SNI with cyclic CAs/not unique issuers? broken added
Actions #6

Updated by gstrauss over 6 years ago

lighttpd 1.4.46 splits openssl code into mod_openssl, and lighttpd adds a plugin hook to guarantee that mod_openssl config is processed prior to privileges being dropped. Therefore, it might now be possible to go with a simpler patch which uses SSL_CTX_use_certificate_chain_file()


Actions #7

Updated by gstrauss over 6 years ago

  • Status changed from New to Patch Pending
  • Target version changed from 1.4.x to 1.4.48
--- a/src/mod_openssl.c
+++ b/src/mod_openssl.c
@@ -843,7 +843,8 @@ network_init_ssl (server *srv, void *p_d)

-        if (1 != SSL_CTX_use_certificate(s->ssl_ctx, s->ssl_pemfile_x509)) {
+        if (1 != SSL_CTX_use_certificate_chain_file(s->ssl_ctx,
+                                                    s->ssl_pemfile->ptr)) {
             log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
                             ERR_error_string(ERR_get_error(), NULL),
Actions #8

Updated by gstrauss over 6 years ago

  • Status changed from Patch Pending to Fixed
  • % Done changed from 0 to 100

Also available in: Atom