'How many HTTPS certificates have the google reCaptcha endpoint? And where can I download them?

We have a Java web application that implements reCaptcha validation against URL https://www.google.com/recaptcha/api/siteverify in a microservice in Docker. This has been working for almost 2 years, but this Tuesday 8/06/2021, the app started throwing this exception:

Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:439)
        at java.base/sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:306)
        at java.base/sun.security.validator.Validator.validate(Validator.java:264)
        at java.base/sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:313)
        at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:222)
        at java.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:129)
        at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.checkServerCerts(CertificateMessage.java:1340)
        ... 89 common frames omitted
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at java.base/sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
        at java.base/sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
        at java.base/java.security.cert.CertPathBuilder.build(CertPathBuilder.java:297)
        at java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:434)
        ... 95 common frames omitted

We find that the certificate that we have in Java 11 was one of GlobalSign but with name ending in "R2":

Certificate R2 in truststore

However, in some cases the same Google endpoint returns one with name ending in "R1":

Certificate R1 not in Truststore

After we add this certificate R1, the app started to work fine, but is it normal that the same endpoint returns two different certificates? And how can I obtain or add all the possible certificates in my truststore? Is there a pool of certificates that we need to add?



Solution 1:[1]

Not an answer (yet?) to the real problem, only to "is it normal", but also much too long for comments.

It is possible for one SSL/TLS server to have more than one certificate, and provide different ones on connection requests, although it would be odd to so for the same domainname; this is more common on servers that support multiple domains -- either for different parts or services of one entity, or a CDN or frontend like Cloudflare or Fastly(!) that handles connections for multiple entities. However, in the specific case of www.google.com that is not a single server but hundreds or thousands, all over the world, and it is quite possible that different servers have different certificates, either intentionally (perhaps for testing) or because they are making a change which does not happen instantly everywhere.

According to my notes recently www.google.com as accessed from my location was using certs under GTS CA 1O1 with this intermediate cert under GlobalSign Root CA - R2 as shown in your first image. Note that intermediate cert expires in 6 months, as does the root it is under, which is a good reason to stop using it. (https://crt.sh/?caid=10 does show two 'cross' certs for R2 under GlobalSign Root CA (see below) with longer expiration, but they are both revoked.)

As of today I get a cert under GTS CA 1C3 under GTS Root R1 -- so far like your second figure -- but then crossed under GlobalSign Root CA WITHOUT R1. Specifically I get this intermediate cert for GTS CA 1C3 and this cross cert for GTS Root R1, which are valid until 2027 and 2028 and appear here on the GTS website as GTS CA 1C3 and GTS Root R1 Cross respectively. And this cert for that GlobalSign root -- which in effect is R1, since the other currently known GlobalSign roots are R2-6, but is not named R1 -- has been in at least Java and Mozilla/Firefox truststores for long time; I can't easily check history on others. crt.sh doesn't know of ANY cert named with R1. I'd note that Firefox does have in its truststore a root cert for GTS Root R1 (and also R2-R4) which means it could shorten the chain, but doesn't; AFAICS no Java has any of these GTS roots.

Moreover the leaf certs I get have both CommonName and SubjectAltName www.google.com NOT *.google.com. This pretty much confirms you are getting a different server than I am.

It might help if you can extract the "GlobalSign R1" cert you apparently have in some truststore, and post it to be looked at or searched for, and the rest of the chain which you can get with keytool -printcert -rfc -sslserver www.google.com and/or if you can identify which google address(es?) you are getting this cert chain from so others (like me) can try it -- although even one address might anycast to multiple physical servers.

Solution 2:[2]

You can refer to Google's PKI Repository which lists 5 CAs.

As per the FAQ, they actually list 36 different CAs in the roots.pem file (as of 28th April, 2022).

Ideally you will need to add all those CAs to your trust store to cover all bases.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 dave_thompson_085
Solution 2 vivek241