Discovering/Identifying Roots

First, thanks for your reply.

I guess I am not clear about my need. I am not trying to validate "Trust" nor assume any amount of "Trust". The concept of "Trust" is irrelevant to me. My client could be used within the realms of "Public Computing" (default browser and trust stores) and "Private Computing" (internal/privately managed stores). The public trust stores also change frequently. Within the realms of CI tests, servers like Boulder and Pebble will generate ad-hoc Root certificates. A Trusted certificate could also be revoked and untrusted, eventually removed from a "Trust Store". So there is no guarantee or assumption that a utilized root will appear in the browser/os Trust Store. Sorry to harp on these points, but I want to make this clear: dealing with the concept of "Trust" is completely irrelevant to my concerns and needs. I am not looking to develop code that is concerned with "Trust".

Within the concerns of my usage, a conventional "Trust Store" does not exist to provide "Trust", but functions as a black box that may or may-not contain a terminal certificate. That causes a lot of problems for my usage, so I am actively looking to remove it from the equation.

What I do wish to accomplish, is validating a downloaded certificate against it's downloaded chain. Let's call this the "self-referential integrity of a certificate chain", as I can't think of a better name for it right now. The vast majority of SSL libraries and toolkits do not easily support this without being provided with the terminal root(s) (more than one root is indeed possible) involved -- and that terminal root must be self-signed. (If only we could treat the last intermediate as the root...)

I am not alone in this -- mailing lists, github, stack overflow, and discussion forums are filled with engineers and computer scientists going through extreme workarounds trying to do the same thing (in just about every situation) for CI/Unit Tests. In these cases, no one cares if the end certificate is "Trusted" or not - that is not our call to make, what matters is identifying and obtaining the terminal certificate(s), so the entire chain can be verified.

I would be fine doing this entirely based on signatures, as all I really care about is "Did the first intermediate sign the cert?", "Did the upchain intermediate sign the downchain intermediate?" - but that started getting absurdly complex and is hard to do with the basic OpenSSL commands. To keep installation requirements minimal for the emergency debugging features, we support them as a fallback if python's crypto tools are not installed.

So my problem is better stated that OpenSSL/etc requires a self-signed Root to validate the referential integrity of a certificate chain, but - as @felixf stated - the ACME spec does not provide for identifying and procuring a root, only the intermediates. Again, to be clear, I am not trying to test if a Chain is trusted - I am trying to test if a Chain is well-formed with it's own self-referential integrity.

My interim solution is probing Pebble for tests, and we already hardcode the ISRG roots, but this is far from ideal and essentially does a lock-in to LetsEncrypt for something that should work against any ACME server.

3 Likes