Skip to content

fix: update bundled trust store to Google's current root certificates - #2636

Open
blakeli0 wants to merge 1 commit into
mainfrom
fix/update-bundled-truststore
Open

blakeli0 wants to merge 1 commit into
mainfrom
fix/update-bundled-truststore

Conversation

@blakeli0

Copy link
Copy Markdown
Contributor

GoogleUtils#getCertificateTrustStore() falls back to the bundled google.p12 when the JDK cacerts file can't be loaded, for example on Android and in GraalVM native images. GoogleNetHttpTransport.newTrustedTransport() uses it in that case. Before 2.9.0, the bundle was always used.

The bundle is a 2013 snapshot of roots. It was re-encoded to PKCS#12 in #1738, and DigiCert Global Root G2 was added in #2582.

  • Mostly stale. It has 71 roots. 26 have expired, and only 5 are in Google's published root list (https://pki.goog/roots.pem) or the Chrome Root Store.
  • Distrusted roots. It still trusts roots that root programs have since removed or distrusted, such as AAA Certificate Services, StartCom, and the legacy VeriSign/thawte/GeoTrust roots.
  • No Google Trust Services roots. Google APIs currently validate against it only through the GTS Root R1/R4 cross-certificates issued by GlobalSign Root CA. Those expire on 2028-01-28, after which every connection that relies on the bundle would fail.

Changes

  • Regenerate google.p12 from https://pki.goog/roots.pem. That's the set of roots Google publishes for clients that connect to Google services: 21 roots, including GTS Root R1–R4. The file keeps the same password and the same PKCS#12 algorithms as before (pbeWithSHA1And40BitRC2-CBC with a SHA-1 MAC), so it stays loadable on Android and Java 8.
  • Remove google.jks. The library hasn't read it since it switched to google.p12 in fix: re-encode public keys from google.jks into p12 format for android #1738.
  • Document and test the bundle. A comment on BUNDLED_KEYSTORE documents the bundle's source. New tests check that the bundle contains only trusted CA certificates, includes the GTS roots, and no longer includes AAA Certificate Services.

Compatibility

  • No API changes. When the JDK cacerts file can be loaded (the common JVM case), behavior is unchanged.
  • Google APIs keep working in the fallback case. The GTS roots are now trust anchors, so the GlobalSign cross-certificate is no longer needed.
  • Non-Google hosts may be affected in the fallback case. If such a host chains to a removed root, the fallback no longer trusts it. The bundle is documented as the roots "to use for Google APIs", and NetHttpTransport (platform trust) remains the recommended transport.

How the keystore was generated

curl -sSfO https://pki.goog/roots.pem
# sha256 at generation time: ec989df46c8f4419ef2ee2517cad7619d555e4973f3307be697662aa2497e480
# Split roots.pem into one PEM file per certificate, then for each certificate:
keytool -J-Dkeystore.pkcs12.legacy -importcert -noprompt \
  -alias <name> -file <cert>.pem \
  -keystore google.p12 -storetype PKCS12 -storepass notasecret
  • -J-Dkeystore.pkcs12.legacy keeps the previous PKCS#12 algorithms. Current keytool defaults (AES-256/PBKDF2/HmacSHA256) may not load on older Android versions.
  • Use keytool, not openssl pkcs12 -export -nokeys. Java ignores certificates without its trusted-certificate attribute, so an openssl-built file loads with 0 entries.

Testing

  • Unit tests: mvn test -pl google-api-client on Java 11. All 224 tests pass, including the new GoogleUtilsTest cases.
  • Load check: loaded the new keystore on Java 11, 21 and 26. Each shows 21 trusted certificate entries, and the fingerprints match pki.goog/roots.pem exactly.
  • Live TLS check: used the new keystore as the only trust store to connect to storage, oauth2, www, datastore and bigquery.googleapis.com on Java 11 and 26, with both ECDSA and RSA certificate chains. All connections succeeded.
  • Why not a smaller edit: removing GlobalSign Root CA from the old bundle without adding the GTS roots makes the same live check fail. Just deleting stale roots from the old file isn't safe; the bundle needs the GTS roots.

GoogleUtils#getCertificateTrustStore falls back to the bundled google.p12
when the JDK cacerts file can't be loaded (for example on Android and in
GraalVM native images). The bundle was a 2013 snapshot: 26 of its 71 roots
had expired, it still included roots that root programs have since removed
or distrusted (such as AAA Certificate Services), and it had no Google Trust
Services roots, so Google APIs only validated through cross-certificates
that expire on 2028-01-28.

Regenerate google.p12 from https://pki.goog/roots.pem, the roots Google
publishes for clients connecting to Google services, keeping the same
password and PKCS#12 algorithms for Android compatibility. Remove
google.jks, which the library no longer reads.
@blakeli0
blakeli0 requested a review from a team as a code owner October 21, 2026 02:12
@product-auto-label product-auto-label Bot added the size: m Pull request size is medium. label Oct 21, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size: m Pull request size is medium.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant