• Stan Hu's avatar
    Fix auto-renew of LetsEncrypt domains for Pages · b3a7e0d5
    Stan Hu authored
    As described in
    https://community.letsencrypt.org/t/production-chain-changes/150739, the
    LetsEncrypt DST Root CA X3 expired on September 30, 2021. Domains that
    needed to be renewed via PagesDomainSslWorker would fail with the error,
    "Certificate misses intermediates".
    
    Newly-issued certificates would come with this chain of trust:
    
    End-entity certificate (A) ← R3 (B) ← ISRG Root X1 (C) ← DST Root CA X3
    
    Previously, this is what was happening:
    
    1. LetsEncrypt returned a bundle containing A, B, and C.
    2. `PagesDomain#has_intermediates?` took B and C and added them to the
    OpenSSL certificate store.
    3. `OpenSSL::X509::Store#verify` returned `false` because C was a
    trusted certificate, but DST Root CA X3 had expired.
    
    The crux of the problem is that we aren't using `verify` properly: we
    should be passing in an untrusted chain and allow OpenSSL to verify that
    C is indeed trusted from the system store. This emulates the behavior of
    the `-untrusted` parameter in the `openssl` command-line:
    
    ```
    All certificates (typically of intermediate CAs) are considered
    untrusted and may be used to construct a certificate chain from the
    target certificate to a trust anchor.
    ```
    
    Relates to https://gitlab.com/gitlab-org/gitlab/-/issues/342326
    
    Changelog: fixed
    b3a7e0d5
letsencrypt_expired_x3.pem 5.8 KB