Best way to determine a certificate comes from Let’s Encrypt?

What is the best way to determine (algorithmically) whether a given certificate comes from Let’s Encrypt?

Depends on what OS you are on and language you like I guess.

I'd generally use openssl, the command

echo | openssl s_client -servername "example.com" -connect "example.com:443" | openssl x509 -noout -issuer

would provide information about the issuer.

algorithmically, that's "obtain a copy of the certificate"

echo | openssl s_client -servername "example.com" -connect "example.com:443"

Then "obtain the issuer info from the certificate" which there are a number of ways;

openssl x509 -noout -issuer

or

openssl x509 -noout -text | grep Issuer:

Does that give you an answer ?

1 Like

I can parse the cert just fine; what I need to know is which part of the cert I can reliably tell a piece of code to check.

The two ways that occur to me are:

  1. regexp on some part of the issuer’s DN (commonName? organizationName?)

  2. Look for OID 1.3.6.1.4.1.44947.1.1.1 in the certificate policies extension.

Option 1 makes me concerned that “Let’s Encrypt” may become “Let’s Encrypt” or “Lets Encrypt” (i.e., switch out straight-quote for UTF-8 rsquo, or get rid of it entirely).

Options 2 … well, I don’t know how permanent that OID is.

Thoughts?

Personally I use option 1. I don’t think the organizationName is likely to change ( although not impossible I guess).

Option 1 is inconsistent with their branding, which makes me a bit uneasy about it. (I also just try to avoid text-parsing in general when possible.)

I don’t have first hand experience of what you’re trying to achieve, but wouldn’t it make sense to aim for the ‘Certificate Authority Key Identifier’? That should hopefully bring you to the ‘X3’ certificate.

Then, how to verify the ‘X3’ certificate?

You’d have to somehow hard code what that identifier is supposed to be, but that’s part of the TLS certificate’s top-down model. In the end you must trust someone. You’ll have to learn who is the ‘top’ identifier, and trust it.

Anybody can make a certificate with an arbitrary issuer DN in it. If you’re definitely not doing this for any security-related reason, you could just hard-code the textual check described by serverco and it’s no worse than anything else, but it would treat a fake “Let’s Encrypt” cert the same as a genuine one.

Security-wise, you need to do this in terms of signatures, and right now today the “Let’s Encrypt” intermediates in active use aren’t actually signed by the ISRG root (because ISRG hasn’t held a “ceremony” in which all the people necessary to authorise that are in one place doing it). Eventually you’ll be able to chain back from an end-user certificate to an intermediate, and find a certificate joining that intermediate back to ISRG’s root. Right now, the intermediates X3 and X4 only chain back to another public CA, IdenTrust.

If you need a solution right now today, and it is to have any security meaning at all, you should check explicitly for the four Let’s Encrypt intermediates, X1, X2, X3 and X4, probably by hard coding their public keys into your software.

1 Like

We’re reasonably sure that what we have is ok from a security standpoint; we have other logic in place to verify the trust chain.

So, it sounds like the textual check is it? OK …

Just for curiosity, what is the “permanence” (or lack thereof) of the CPS OID that I mentioned above?

That OID has been self-issued by Let’s Encrypt, and in their policies represents Domain Validation (DV). So you could expect that OID to appear in all the certificates they issue since currently they have no plans to do anything except DV. On the other hand, they could of course create new OIDs to represent some other policy, whether it’s a minor variation of the existing policy or something more radical. So, it’s probably not safer than the textual check. It might work forever, it might break in six months. Plan to have the ability to upgrade / fix anything that depends on these checks or else to accept that they might fail. Don’t put yourself in the trap the Payment companies made for themselves baking obsolete public CA keys into devices with a ten year service contract and no way to upgrade them…

1 Like

Of course; still, it would seem a good feature to have some identifier that clearly identifies these certificates as LE DV certs—since the 90-day validity period builds in an expectation that they’ll be replaced frequently.

In our particular application, we expect there to be a desire to upsell paid certificates. How we handle the near-expired state will thus depend on what’s installed: if it’s LE, we’ll just renew automatically; if it’s not, we’ll alert the user to allow them to renew manually.

There is also the case of additional domains being added to an Apache vhost: if we’re LE-secured, then we’ll just grab a new cert; if it’s another CA, we’ll just let them know that the new domain isn’t secured.

But, so, as a final proposal:

for my $dn_part (@issuer_list) {
    if ($dn_part->{'value'} matches /Let(?:'|’)?s Encrypt)/)
        $is_letsencrypt = true;
    }
}

??

Seems good. Maybe restrict the DN check to just look in the Organisation (O) part of the DN? Hard to imagine why any legit certificate issuer would say O=Let’s Encrypt if they weren’t er, Let’s Encrypt.

Ongoing work at Mozilla is trying to get the public CAs (a few dozen organisations, controlling a couple of hundred CA keys, enshrined in Mozilla’s NSS trust store as self-signed “certificates” because that’s just traditionally how everybody does this) to disclose every unconstrained intermediate certificate issued under their CA.

All of those intermediates could appear as issuers of publicly trusted certificates on the public Internet. Most aren’t “supposed” to be used that way, but no actual technical mechanism prevents it so Mozilla wants to make sure we know they exist. In practice a couple dozen or so issue the vast majority of certificates in use today, but your customers (I guess you’re a service provider? Web hosting maybe?) could in theory show up with a certificate from any of them. So once disclosure is complete (in theory 2014, but in practice maybe later this summer) we can check that to see if any of them other than the actual Let’s Encrypt certificates claim to be from “Let’s Encrypt”.

I don’t expect any shenanigans though. Some of them are super vague like they’ll say “CA Root” as if that’s going to distinguish them from anybody else, or there was even once just named “tarquin” but none so far involve outright fraudulent deceit.

1 Like