# Use of short/alternate trust chain

**URL:** <https://community.letsencrypt.org/t/use-of-short-alternate-trust-chain/161215>\
**Category:** Client dev\
**Created:** [October 1, 2021, 2:56am UTC](https://community.letsencrypt.org/t/use-of-short-alternate-trust-chain/161215 "2021-10-01T02:56:19Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![FGasper](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/fgasper/32/18787_2.png) [@FGasper](https://community.letsencrypt.org/u/FGasper)\
**Post date:** [October 1, 2021, 2:56am UTC](https://community.letsencrypt.org/t/use-of-short-alternate-trust-chain/161215/1 "2021-10-01T02:56:19Z")

</div>

Hello,

How can I most easily, when interacting with Let’s Encrypt’s API (not certbot or some other client application), use LE’s alternative trust chain? (The one that doesn’t refer back to the now-expired DST root.)

What _works_ is to fetch the “normal” one then look at the Link headers to find the `rel="alternate"` link; I wonder if there’s a way I could cut out that “throwaway” initial fetch and just _always_ retrieve the trust chain that doesn’t go back to an expired root?

Thank you!

---

<div class="post-metadata">

**Author:** ![rmbolger](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/rmbolger/32/27474_2.png) [@rmbolger](https://community.letsencrypt.org/u/rmbolger)\
**Post date:** [October 1, 2021, 4:28am UTC](https://community.letsencrypt.org/t/use-of-short-alternate-trust-chain/161215/2 "2021-10-01T04:28:19Z")

</div>

I don't think there's any way to avoid the initial download of the default cert+chain. No other endpoint I'm aware of provides the URL you'd need from that `rel="alternate"` header. However, for your particular use-case it's probably also fine to just hard code the alternate chain details in your integration.

Keep in mind that what is currently "default" and what is currently "alternate" may change in the future as the global need for the old-android-compatible chain becomes less. So in that sense, it's another reason you specifically may want to hard-code the chain you care about so it doesn't get switched out from under you unexpectedly later...with the understanding that you (or someone) will need to pay closer attention to things like the API Announcements category for things like the inevitable replacement of R3 with whatever comes next.

---

<div class="post-metadata">

**Author:** ![Osiris](https://avatars.discourse-cdn.com/v4/letter/o/839c29/32.png) [@Osiris](https://community.letsencrypt.org/u/Osiris)\
**Post date:** [October 1, 2021, 4:39am UTC](https://community.letsencrypt.org/t/use-of-short-alternate-trust-chain/161215/3 "2021-10-01T04:39:15Z")

</div>

Hardcoding an intermediate is NEVER a good idea!

The signing intermediate may change from R3 to the backup intermediate R4 at any notice and, more importantly perhaps, _without_ timely notice, breaking any hardcoded chain with it.

Unfortunately, the ACME protocol doesn't have a "please use this alternative chain by default" option. The protocol only leaves room for those Link headers and the rest has to be done client side.

---

<div class="post-metadata">

**Author:** ![FGasper](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/fgasper/32/18787_2.png) [@FGasper](https://community.letsencrypt.org/u/FGasper)\
**Post date:** [October 1, 2021, 1:21pm UTC](https://community.letsencrypt.org/t/use-of-short-alternate-trust-chain/161215/4 "2021-10-01T13:21:07Z")

</div>

Part of what complicates this is OpenSSL’s inconsistent verification: old/new versions, connection vs. verify, CLI vs. API, and all the varied configuration options.

Does anyone have a way, when using OpenSSL’s API, of reliably _failing_ the verification? I need to build a heuristic that will fail LE’s default cert, ideally without hard-coding the specific intermediates I need to avoid.

---

<div class="post-metadata">

**Author:** ![jvanasco](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/jvanasco/32/55900_2.png) [@jvanasco](https://community.letsencrypt.org/u/jvanasco)\
**Post date:** [October 1, 2021, 1:42pm UTC](https://community.letsencrypt.org/t/use-of-short-alternate-trust-chain/161215/5 "2021-10-01T13:42:29Z")

</div>

The only proper way to do this, right now, is to download and inspect all chains.

Some clients will have a “preferred chain” option, but that must download and inspect the chains to properly work.

IMHO, and I’ve brought this up with LetsEncrypt, the links should contain a fingerprint for each chain — which would allow for a client to discern previously encountered chains without downloading them.

No such features currently exist, and the LetsEncrypt service does not / can not guarantee any particular chain for a request. So the only correct way to handle this is downloading and inspecting each chain until you find your match. Personally, I download all chains.

There is one workaround though - if you have your own client, you can just inspect keypair for the chain (you can pull enough data off the cert too) and maintain a database of compatible key pairs. I.e. R3 old, R3 new, and R3 cross sign all have the same keys, and therefore certs signed by them are interoperable with one another. This still causes issues if a new compatible intermediate is released, but it gives you a decent framework to work with.

---

<div class="post-metadata">

**Author:** ![FGasper](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/fgasper/32/18787_2.png) [@FGasper](https://community.letsencrypt.org/u/FGasper)\
**Post date:** [October 1, 2021, 1:57pm UTC](https://community.letsencrypt.org/t/use-of-short-alternate-trust-chain/161215/6 "2021-10-01T13:57:24Z")

</div>

@jvanasco Downloading all the chains isn’t a problem; I’m wondering about how to implement the “inspection”. Keeping a “deny-list” of chains seems a decidedly hacky approach.

It seems like OpenSSL 1.1.1 does its best to _pass_ verification with the Android chain. I’d like to configure OpenSSL instead such that it highlights the _problem_ that it goes back to an expired root, rather than ignoring the expired root because there’s another root in the local store that matches one of the chain’s intermediates.

---

<div class="post-metadata">

**Author:** ![jvanasco](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/jvanasco/32/55900_2.png) [@jvanasco](https://community.letsencrypt.org/u/jvanasco)\
**Post date:** [October 1, 2021, 2:28pm UTC](https://community.letsencrypt.org/t/use-of-short-alternate-trust-chain/161215/7 "2021-10-01T14:28:19Z")

</div>

If I understand you’re comment correctly, this may help. If not, I hope I don’t confuse you:

The canonical way to verify a chain is to build a container and verify upwards from the end entity to the root, one certificate at a time. I do not believe that approach can utilize the shortcircuit behavior, because you pass in an explicit root.

I’m away from a computer and can’t test, but you can see the OpenSSL and Python implementations on ensure-chain and ensure-chain-order in this file; this may help.

> <https://github.com/aptise/peter_sslers/blob/main/peter_sslers/lib/cert_utils.py#L2587>

---

<div class="post-metadata">

**Author:** ![FGasper](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/fgasper/32/18787_2.png) [@FGasper](https://community.letsencrypt.org/u/FGasper)\
**Post date:** [October 1, 2021, 2:51pm UTC](https://community.letsencrypt.org/t/use-of-short-alternate-trust-chain/161215/8 "2021-10-01T14:51:16Z")

</div>

I’m not sure the order matters in that case; you’re just adding certs to the internal X509\_STORE?

This is, I think, similar to what we do: create the X509\_STORE, do X509\_STORE\_load\_locations($root\_certs\_file), then create an X509\_STORE\_CTX and call X509\_STORE\_CTX\_init($x509\_store, $cert, $untrusted\_certs).

We _could_, I suppose, do that verification with 1 intermediates, 2 intermediates, 3, etc. until we either get a success or run out of intermediates. That would be more like a “normalization” of a given chain rather than something we could use to _compare_ two different chains … I _guess_ that’d be OK.

---

<div class="post-metadata">

**Author:** ![FGasper](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/fgasper/32/18787_2.png) [@FGasper](https://community.letsencrypt.org/u/FGasper)\
**Post date:** [October 1, 2021, 4:10pm UTC](https://community.letsencrypt.org/t/use-of-short-alternate-trust-chain/161215/9 "2021-10-01T16:10:23Z")

</div>

Our temporary fix will be just to download the CA Issuers chain and use that. We cache these, so it’ll be faster than fetching the “alternate” link from the ACME server.

With the “fire” put out we can then look to a more robust solution.

---

<div class="post-metadata">

**Author:** ![system](https://global.discourse-cdn.com/letsencrypt/original/3X/c/a/ca6c06ea1ea201324bba7048c6841ce60236468d.png) [@system](https://community.letsencrypt.org/u/system)\
**Post date:** [October 31, 2021, 4:11pm UTC](https://community.letsencrypt.org/t/use-of-short-alternate-trust-chain/161215/10 "2021-10-31T16:11:01Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
