12

I am trying to establish a SSL connection with my MySQL database in Java using MySQL Connector/J (version 5.1.45) and this AWS RDS certificate here: https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem

But I am getting the following Exception:

java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors

I could trace this Exception down to the MySQL Connector/J class ExportControlled.java on line 297:

CertPathValidatorResult result = this.validator.validate(certPath, this.validatorParams);

Then I can't go further down since this goes into the JRE security classes, like CertPathValidator.

Since I am using MySQL Connector/J to do the whole SSL magic, my hands are tied and I don't know what's going on or how to fix this. The certificate works fine on MySQL Workbench and on Intelli J IDEA Database, so I have no clue why it's being rejected now.

How do I fix this?

Michel Feinstein
  • 13,416
  • 16
  • 91
  • 173

4 Answers4

21

I fixed this after A LOT of headaches. The truststore needs to have ALL the certificates of the chain, I was using https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem, which IN THEORY has all the certificates, but when you import it to a keystore file, keytool ignores all but the first certificate, so I only had the root certificate on my keystore and not the root and the AWS Region certificate that I actually needed.

For now, there's no way to bach import all the certificates, I tried several methods, including converting to PKCS7 (which supports certificates chains), but keytool needs one alias for each certificate so you need to import each certificate and give it an alias, one at the time.

You could make a program to call keytool and load one certificate at a time or you could be a bit more lazy as I was and use KeyStore Explorer. You will need to select to create a new keystore file and open the bundled pem certificate using the Examine File option and for each certificate on it, select import, this will import the selected certificate to the new keystore. At the end you just have to define a password for your keystore file and save it.

Michel Feinstein
  • 13,416
  • 16
  • 91
  • 173
  • I'm still getting the error: "Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors". /n – NOTiFY Jan 26 '18 at 14:28
  • 1
    Be sure ALL the certificates in the chain are in your trustore. From the root certificate to the lowest. There's a keytool command for seeing all the certificates inside it. – Michel Feinstein Jan 26 '18 at 14:31
  • Was in the process of editing and your comment popped up. I think I had missed the root certificate, I now have the three certificates in my 'truststore.pks'. I'm trying to connect to my AWS RDS MySQ instance from JBoss WildFly 11. standalone-full.xml useSSL=true&verifyServerCertificate=true&trustCertificateKeyStorePassword=mypassword&trustStore=file:///home/ec2-user/truststore/truststore.jks I'm still getting the error - "Path does not chain with any of the trust anchors". Any other suggestions? TIA – NOTiFY Jan 26 '18 at 14:44
  • 1
    Why do you need 3 certificates? You just need 2, the AWS Root and the Region certificate. – Michel Feinstein Jan 26 '18 at 15:09
  • Download the KeyStore Explorer that I pointed out on my Answer and see what's inside the truststore.jks, be SURE to confirm the Root and the Region certificate is there. Be sure the Region is your RDS region, some names are too similar and can be confused. – Michel Feinstein Jan 26 '18 at 15:12
  • My mistake and misunderstanding. Imported root and the region certificate for my location eu-2. Saved as PKS. Opened using KS and both there ..... same error – NOTiFY Jan 26 '18 at 15:23
  • I only used JKS. Well, I am sorry, all the problems I had were solved with adding all the certificates. Maybe you are using the wrong version of the certificates? There are new ones, try the ones in the bundle I referenced in my answer. – Michel Feinstein Jan 26 '18 at 15:53
  • I did use JKS. The error was in the JBoss WildFly DS had the wrong parameter name for the location of my JKS file. Changed to 'trustCertificateKeyStoreUrl' and WildFly started fine I could deploy my EAR. Thanks for your suggestions, got looking closer and couldn't have done it without KeyStore Explorer. Excellent. – NOTiFY Jan 26 '18 at 16:33
  • It was my pleasure :) – Michel Feinstein Jan 26 '18 at 16:54
  • Rather than add another tool, use the bash script here for importing multiple certificates at once: https://stackoverflow.com/questions/14660767/keytool-importing-multiple-certificates-in-single-file – Erica Kane Nov 18 '18 at 23:26
6

AWS now provides separate certificates and not just the bundle, which has extra stuff you won't need. See Using SSL to Encrypt a Connection to a DB Instance.

You will need to download two certificates: the root certificate, and the intermediate certificate for your region. As stated in the link above,

A root certificate that works for all regions can be downloaded at https://s3.amazonaws.com/rds-downloads/rds-ca-2019-root.pem

and the intermediate cerificates can be found further down the page. You must use the one appropriate for your region, the region where your database instance is located.

You must use keytool to import both of these into a new keystore, and tell MySQL to use that keystore via the trustCertificateKeyStoreUrl and trustCertificateKeyStorePassword parameters.

I had the further task of getting all of this to work with Tomcat. I had poor luck setting things via the connection URL; what worked was setting the connectionProperties in the connection pool to useSSL=true;requireSSL=true;verifyServerCertificate=true;trustCertificateKeyStoreUrl=file://[absolute path to keystore file];trustCertificateKeyStorePassword=[keystore password]

Erica Kane
  • 3,137
  • 26
  • 36
5

One additional issue is that the MySQL documentation appears to be incorrect.

It describes the following connection properties:

clientCertificateKeyStoreUrl=file:path_to_truststore_file 
clientCertificateKeyStorePassword=mypassword

The correct connection parameters are:

trustCertificateKeyStoreUrl
trustCertificateKeyStorePassword

There is a note to this effect in the "User Comments" section of the page.

kdgregory
  • 38,754
  • 10
  • 77
  • 102
1

I got the exact same error a couple of hours ago when I moved to 5.1.45.

Trying now with 5.1.42 to see if the problem disappears.

  • My error just changed to: `sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target` – Michel Feinstein Jan 16 '18 at 20:02