Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error validating client certificate: PostgreSQL reports "ccs received early" error #1364

Closed
1 of 2 tasks
Mrk-Nguyen opened this issue Dec 6, 2018 · 40 comments
Closed
1 of 2 tasks

Comments

@Mrk-Nguyen
Copy link
Contributor

**I'm submitting a **

  • bug report
  • feature request

Describe the issue

I'm passing in a client certificate, client key, and certificate authorities using properties sslrootcert, sslcert, and sslkey in the JDBC driver and am receiving the SSL error:

could not accept SSL connection: ccs received early

This occurs at the client - Change Cipher Spec record during the SSL handshake.

Passing the same certificates into psql:

psql "host=localhost dbname=training user=mule password=mule sslmode=verify-ca sslrootcert=root-client.crt sslcert=client.crt sslkey=client.key"

works. This means I know the certificates themselves are not the issue.

Driver Version?
42.2.5

Java Version?
Oracle JDK 1.8.0_191

OS Version?
Mac OS 10.13.6

PostgreSQL Version?
10.6

To Reproduce

  1. Create self-signed certificates for both server and client using openssl.
  2. Install server certificates, key, and client certificate into CA authority certificate.
  3. Configure pg_hba.conf for hostssl:
hostssl    all             all             127.0.0.1/32           md5
hostssl    all             all             ::1/128                    md5
  1. Setup a database, a table, and a user account with permissions to the table in the PostgreSQL.
  2. Confirm psql works with provided client certificate, key and server certificate as the sslrootcert:
psql "host=localhost dbname=training user=mule password=mule sslmode=verify-ca sslrootcert=root-client.crt sslcert=client.crt sslkey=client.key"
  1. Use the JDBC driver in a Java program to access the same table with the same credentials and certificates:
import java.sql.*;
import java.util.Properties;

public class CCS {
    //Test for ccs received early bug
    public static void main(String[] args) throws java.sql.SQLException {
        String url = "jdbc:postgresql://localhost:5432/training";

        Properties props = new Properties();
        props.setProperty("user","mule");
        props.setProperty("password","mule");
        props.setProperty("sslmode","verify-ca");
        props.setProperty("sslrootcert","/Users/mark/certs/root-client.crt");
        props.setProperty("sslcert","/Users/mark/certs/client.crt");
        props.setProperty("sslkey","/Users/mark/certs/client.key");
        props.setProperty("loggerLevel","TRACE");
        props.setProperty("loggerFile","pgjdbc-trace.log");

        Connection conn = DriverManager.getConnection(url,props);
        Statement st = conn.createStatement();
        ResultSet rs = st.executeQuery("SELECT username FROM test_accounts");

        System.out.println("Column: username");
        while (rs.next()) {
            System.out.println(rs.getString(1));
        }

        rs.close();
        st.close();
        conn.close();
    }
}
  1. javax.net.ssl.SSLException: Received fatal alert: unexpected_message gets thrown when running the Java program.

Expected behaviour
The SSL handshake should complete successfully and application data gets transferred to the Java program.

And what actually happens:

Exception gets thrown: javax.net.ssl.SSLException: Received fatal alert: unexpected_message

Logs

JDBC Driver Logs

Dec 06, 2018 10:14:30 AM org.postgresql.Driver connect
FINE: Connecting with URL: jdbc:postgresql://localhost:5432/training
Dec 06, 2018 10:14:30 AM org.postgresql.jdbc.PgConnection <init>
FINE: PostgreSQL JDBC Driver 42.2.5
Dec 06, 2018 10:14:30 AM org.postgresql.jdbc.PgConnection setDefaultFetchSize
FINE:   setDefaultFetchSize = 0
Dec 06, 2018 10:14:30 AM org.postgresql.jdbc.PgConnection setPrepareThreshold
FINE:   setPrepareThreshold = 5
Dec 06, 2018 10:14:30 AM org.postgresql.core.v3.ConnectionFactoryImpl openConnectionImpl
FINE: Trying to establish a protocol version 3 connection to localhost:5432
Dec 06, 2018 10:14:30 AM org.postgresql.core.Encoding <init>
FINEST: Creating new Encoding UTF-8 with fastASCIINumbers true
Dec 06, 2018 10:14:30 AM org.postgresql.core.Encoding <init>
FINEST: Creating new Encoding UTF-8 with fastASCIINumbers true
Dec 06, 2018 10:14:30 AM org.postgresql.core.Encoding <init>
FINEST: Creating new Encoding UTF-8 with fastASCIINumbers true
Dec 06, 2018 10:14:30 AM org.postgresql.core.v3.ConnectionFactoryImpl enableSSL
FINEST:  FE=> SSLRequest
Dec 06, 2018 10:14:30 AM org.postgresql.core.v3.ConnectionFactoryImpl enableSSL
FINEST:  <=BE SSLOk
Dec 06, 2018 10:14:30 AM org.postgresql.ssl.MakeSSL convert
FINE: converting regular socket connection to ssl
Dec 06, 2018 10:14:30 AM org.postgresql.Driver connect
FINE: Connection error: 
org.postgresql.util.PSQLException: SSL error: Received fatal alert: unexpected_message
	at org.postgresql.ssl.MakeSSL.convert(MakeSSL.java:42)
	at org.postgresql.core.v3.ConnectionFactoryImpl.enableSSL(ConnectionFactoryImpl.java:435)
	at org.postgresql.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:94)
	at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:192)
	at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:49)
	at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:195)
	at org.postgresql.Driver.makeConnection(Driver.java:454)
	at org.postgresql.Driver.connect(Driver.java:256)
	at java.sql.DriverManager.getConnection(DriverManager.java:664)
	at java.sql.DriverManager.getConnection(DriverManager.java:208)
	at CCS.main(CCS.java:19)
Caused by: javax.net.ssl.SSLException: Received fatal alert: unexpected_message
	at sun.security.ssl.Alerts.getSSLException(Alerts.java:208)
	at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)
	at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:2020)
	at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1127)
	at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1367)
	at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1395)
	at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1379)
	at org.postgresql.ssl.MakeSSL.convert(MakeSSL.java:40)
	... 10 more

PostGres Log

2018-12-06 18:14:30.661 UTC [89527] LOG:  could not accept SSL connection: ccs received early

javax.net.debug = ssl:handshake Log

For brevity, I'm only including the step before Client Change Cipher Spec.

main, WRITE: TLSv1.2 Handshake, length = 1057
SESSION KEYGEN:
PreMaster Secret:
0000: 91 BB 64 B1 F8 D5 93 91   81 04 43 3D 15 BD 5A 5C  ..d.......C=..Z\
0010: 21 2D 6E 93 E3 1C F1 65   EF 3D 6D 52 15 BA FC 42  !-n....e.=mR...B
CONNECTION KEYGEN:
Client Nonce:
0000: 5C 09 68 10 D8 A3 D6 70   FF 90 2D 04 7B C0 E1 DC  \.h....p..-.....
0010: C8 87 D6 25 72 F2 BD B0   8C 78 73 1A 72 C1 49 16  ...%r....xs.r.I.
Server Nonce:
0000: 7B 88 53 D6 85 3F 3F 9F   FE 90 2C E2 1A C6 22 11  ..S..??...,...".
0010: 43 B6 1B A0 D8 FE 58 B6   31 83 DE 81 60 F5 29 92  C.....X.1...`.).
Master Secret:
0000: E2 42 BD 0E 8B AF 14 63   75 35 FA 25 FA BF 22 8D  .B.....cu5.%..".
0010: 03 A1 A7 6F 3B 24 68 49   91 FA D3 5B 46 98 C6 CC  ...o;$hI...[F...
0020: C5 CE 0D C4 98 4F 6F 22   50 ED E5 62 3D E1 F2 EC  .....Oo"P..b=...
... no MAC keys used for this cipher
Client write key:
0000: EA 49 03 97 1E B4 2B 53   E7 81 9A 66 7D 5A 59 E5  .I....+S...f.ZY.
0010: A8 D3 29 57 2E A0 AD A1   4F FB 56 61 BD D4 F9 3D  ..)W....O.Va...=
Server write key:
0000: 3E 55 BD 58 C1 06 06 64   A3 9D 59 25 3D D3 37 95  >U.X...d..Y%=.7.
0010: 3D 92 B3 89 AB E9 5E 30   CF 64 D4 B3 2E 85 C5 94  =.....^0.d......
Client write IV:
0000: A4 BE 2B 6D                                        ..+m
Server write IV:
0000: 4C 84 3A 66                                        L.:f
update handshake state: change_cipher_spec
upcoming handshake states: client finished[20]
upcoming handshake states: server change_cipher_spec[-1]
upcoming handshake states: server finished[20]
main, WRITE: TLSv1.2 Change Cipher Spec, length = 1
*** Finished
verify_data:  { 51, 47, 253, 85, 108, 121, 204, 99, 206, 252, 63, 253 }
***
update handshake state: finished[20]
upcoming handshake states: server change_cipher_spec[-1]
upcoming handshake states: server finished[20]
main, WRITE: TLSv1.2 Handshake, length = 40
main, READ: TLSv1.2 Alert, length = 2
main, RECV TLSv1.2 ALERT:  fatal, unexpected_message
%% Invalidated:  [Session-1, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384]
main, called closeSocket()
main, handling exception: javax.net.ssl.SSLException: Received fatal alert: unexpected_message
Exception in thread "main" org.postgresql.util.PSQLException: SSL error: Received fatal alert: unexpected_message

Thanks.

@davecramer
Copy link
Member

Yes, I've seen this before, now I have to recall how I fixed it.

@davecramer
Copy link
Member

@Mrk-Nguyen try setting properties.setProperty(SSL_PASSWORD.getName(),"");

@Mrk-Nguyen
Copy link
Contributor Author

Thanks for the response Dave. Adding:

props.setProperty("sslpassword","");

into my Java code still gives me the same error.

@davecramer
Copy link
Member

In my case it was failing to open the ssl keystore if thst helps

@Mrk-Nguyen
Copy link
Contributor Author

I see, the certificates I created have no password. I'll try to add passwords and see if that's the issue.

@davecramer
Copy link
Member

Mine didn't have password either, but the code needed something other than null for the password IIRC

@Mrk-Nguyen
Copy link
Contributor Author

Well I created a new client certificate with an encrypted key and the sslpassword property doesn't do anything in the Java code. I still get the same error.

@msqr
Copy link

msqr commented Dec 14, 2018

I am facing this same problem, on slightly different software:

Driver Version?
42.2.5

Java Version?
Oracle JDK 1.8.0_181

OS Version?
Mac OS 10.14.2

PostgreSQL Version?
9.6.11 on FreeBSD 11.2

OpenSSL Version?
OpenSSL 1.0.2o-freebsd 27 Mar 2018

I am using similar SSL connection attributes, but with the addition of sslfactory=org.postgresql.ssl.LibPQFactory. The certificate and key do not have passwords. psql is able to connect using these same certificate settings.

I have not found a work-around yet!

@davecramer
Copy link
Member

davecramer commented Dec 14, 2018

hmmm ok, I'll spend some time on this.
That said travis is able to do this.

Can either one of you provide me a step by step how you are creating the certs/keys and I'll try to figure it out ?

@msqr
Copy link

msqr commented Dec 14, 2018

I think I found the problem, after stepping through the SSL code... the private key was not loading from an "invalid format" exception. My key was in PEM format. I converted it to DER format with

openssl pkcs8 -topk8 -inform PEM -in my.key -outform DER -nocrypt -out my.key.der

and then re-configured the connection to use the my.key.der version... and then it works!

@davecramer
Copy link
Member

@msqr thanks for the update

@Mrk-Nguyen
Copy link
Contributor Author

Mrk-Nguyen commented Dec 14, 2018

@msqr Confirmed it now works! Thanks for looking into this.

@davecramer should the JDBC driver support PEM format as well? psql accepts the key in PEM format, so I don't see why the JDBC driver should not accept PEM as well.

@davecramer
Copy link
Member

@Mrk-Nguyen pull requests are welcome. I'm ambivalent, although if either of you wanted to fix the docs so that nobody else wastes this much time I'd be grateful

@Mrk-Nguyen
Copy link
Contributor Author

I'll submit a PR on docs this weekend to save everyone headaches.

I'll see if I can submit a PR on supporting PEM format.

davecramer pushed a commit that referenced this issue Dec 16, 2018
Add DEM format details and instructions on how to convert from PEM to DER format as discussed in issue #1364
@dtitov
Copy link

dtitov commented May 23, 2019

Not sure if anyone will read it, but we've faced the same problem: our key was PEM-encoded and had to be converted to DER. Would be really nice if pgjdbc could read PEM files...

@davecramer
Copy link
Member

davecramer commented May 23, 2019

my understanding is that this is a java problem? see https://stackoverflow.com/questions/11787571/how-to-read-pem-file-to-get-private-and-public-key

@dtitov
Copy link

dtitov commented May 23, 2019

Let me elaborate a bit. The problem comes from this line: props.setProperty("sslkey","/Users/mark/certs/client.key"); (taken from OP's post).

If the file is in DER format, everything works, but if it's in PEM format, you'll get the Caused by: javax.net.ssl.SSLException: Received fatal alert: unexpected_message error.

Of course, it is quite simple to convert PEM to DER - that's what I've done. And this can be done both ways: statically (before launching of the application) and even dynamically (in the code).

What I'm trying to say here is that it would be really nice if, whoever reads this file under the hood, could read it not only in DER format but in PEM format as well. That would allow as to avoid such conversion at all.

@davecramer
Copy link
Member

PR's are more than welcome!

@changetoblow
Copy link

changetoblow commented Aug 26, 2019

Hello, guys, I have the same problem

public static void main(String[] args){
    String url = "jdbc:postgresql://192.168.1.202:5432/herodb";
    Properties props = new Properties();
    props.setProperty("user","sysadmin");
    props.setProperty("sslmode","verify-ca");
    props.setProperty("sslcert","E:\\certificate\\sysadmin.crt");
    props.setProperty("sslkey","E:\\certificate\\sysadmin.key.der");
    props.setProperty("sslrootcert","E:\\certificate\\ca.crt.der");
    props.setProperty("loggerLevel","TRACE");

    Connection conn = null;
    try {
      Class.forName("org.postgresql.Driver");
      conn = DriverManager.getConnection(url, props);
    } catch (Exception e1) {
      e1.printStackTrace();
    }
    System.out.println(conn);
    conn.close();
  }
Error log:
八月 26, 2019 4:26:49 下午 org.postgresql.Driver connect
详细: Connecting with URL: jdbc:postgresql://192.168.1.202:5432/herodb
八月 26, 2019 4:26:49 下午 org.postgresql.jdbc.PgConnection <init>
详细: PostgreSQL JDBC Driver /*$mvn.project.property.parsedversion.osgiversion$*/
八月 26, 2019 4:26:49 下午 org.postgresql.jdbc.PgConnection setDefaultFetchSize
详细:   setDefaultFetchSize = 0
八月 26, 2019 4:26:49 下午 org.postgresql.jdbc.PgConnection setPrepareThreshold
详细:   setPrepareThreshold = 5
八月 26, 2019 4:26:49 下午 org.postgresql.core.v3.ConnectionFactoryImpl 
openConnectionImpl
详细: Trying to establish a protocol version 3 connection to 192.168.1.202:5432
八月 26, 2019 4:26:49 下午 org.postgresql.core.v3.ConnectionFactoryImpl 
openConnectionImpl
信息: Try connection 192.168.1.202:5432
八月 26, 2019 4:26:49 下午 org.postgresql.core.Encoding <init>
非常详细: Creating new Encoding UTF-8 with fastASCIINumbers true
八月 26, 2019 4:26:49 下午 org.postgresql.core.Encoding <init>
非常详细: Creating new Encoding UTF-8 with fastASCIINumbers true
八月 26, 2019 4:26:49 下午 org.postgresql.core.Encoding <init>
非常详细: Creating new Encoding UTF-8 with fastASCIINumbers true
八月 26, 2019 4:26:49 下午 org.postgresql.core.v3.ConnectionFactoryImpl enableSSL
非常详细:  FE=> SSLRequest
八月 26, 2019 4:26:49 下午 org.postgresql.core.v3.ConnectionFactoryImpl enableSSL
非常详细:  <=BE SSLOk
八月 26, 2019 4:26:49 下午 org.postgresql.ssl.MakeSSL convert
详细: converting regular socket connection to ssl
八月 26, 2019 4:26:50 下午 org.postgresql.Driver connect
详细: Connection error: 
org.postgresql.util.PSQLException: SSL error: Received fatal alert: unexpected_message
	at org.postgresql.ssl.MakeSSL.convert(MakeSSL.java:42)
	at org.postgresql.core.v3.ConnectionFactoryImpl.enableSSL(ConnectionFactoryImpl.java:453)
	at org.postgresql.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:76)
	at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:175)
	at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:49)
	at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:195)
	at org.postgresql.Driver.makeConnection(Driver.java:458)
	at org.postgresql.Driver.connect(Driver.java:260)
	at java.sql.DriverManager.getConnection(DriverManager.java:664)
	at java.sql.DriverManager.getConnection(DriverManager.java:208)
	at org.postgresql.test.ssl.jdbcTest.main(jdbcTest.java:35)
Caused by: javax.net.ssl.SSLException: Received fatal alert: unexpected_message
	at sun.security.ssl.Alerts.getSSLException(Alerts.java:208)
	at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)
	at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:2038)
	at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1135)
	at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385)
	at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413)
	at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1397)
	at org.postgresql.ssl.MakeSSL.convert(MakeSSL.java:40)
	... 10 more

Driver version?
42.2.7
Java version?
Oracle JDK 1.8.0_192

postgresql version?
11.4

I tried setting it up
SetProperty (ssl_password.getname (),");
And convert statements using openssl
Openssl pkcs8-topk8-inform pem-in my. key-outform der-nocrypt-out my.key. DER
but I did not solve the problem.

@davecramer
Copy link
Member

@changetoblow are you able to connect with psql with these certs ?

@changetoblow
Copy link

changetoblow commented Aug 26, 2019

@davecramer Yes, I use psql command to verify the certificate, it is no problem.

@changetoblow
Copy link

@davecramer I repeated yesterday's steps with the openssl command to do a certificate format conversion, this problem inexplicably solved.Thank you very much for your help.

@pip25
Copy link
Contributor

pip25 commented Sep 4, 2019

@changetoblow I think I know what your problem was. The documentation of the JDBC driver suggests the following command for the conversion:
openssl pkcs8 -topk8 -inform PEM -in my.key -outform DER -out my.key.der
The above suggested command is:
openssl pkcs8 -topk8 -inform PEM -in my.key -outform DER -nocrypt -out my.key.der

The former lacks the "nocrypt" option. Apparently, even without specifying a password during conversion, if you use the first command, the connection will fail. (Except if you specify the "sslpassword" option with an empty string value perhaps? I haven't tested that.)

@davecramer
Copy link
Member

@pip25 I'm pretty sure I tested this. the sslpassword you are referring to is the password used to encrypt the der key ?

@pip25
Copy link
Contributor

pip25 commented Sep 4, 2019

@davecramer Yes, that one. It seems like giving an empty password during the conversion is not the same as disabling encryption from the command line (which makes sense I guess, but since many key/keystore/cert generation methods simply skip the password if you give an empty one, it's not necessarily what you'd expect).

@davecramer
Copy link
Member

davecramer commented Sep 4, 2019 via email

@changetoblow
Copy link

changetoblow commented Sep 5, 2019

@pip25 You're right. At first I didn't notice the difference between the two commands. The first time I used the commands suggested by the JDBC driver's documentation to convert them.It needs to specify a password.
openssl pkcs8 -topk8 -inform PEM -in my.key -outform DER -out my.key.der
But it still makes a mistake.
Received fatal alert: unexpected_message
Use the above suggested command conversion to solve the problem eventually
openssl pkcs8 -topk8 -inform PEM -in my.key -outform DER -nocrypt -out my.key.der

@pip25
Copy link
Contributor

pip25 commented Sep 5, 2019

@davecramer I've been trying to test the other cases (empty password, normal password, both passed using "sslpassword") to clarify the docs, but it turns out none of these work for me, the error message "Received fatal alert: unexpected_message" appears in either case. Could someone else retest these as well? Currently, I'm not sure what I should be writing, other than "always use -nocrypt", which does not sound very encouraging in terms of security.

@pritammobisoft
Copy link

Hi Guys,

I am facing a similar problem. The connection with SSL using the following psql command works:

psql "sslmode=require sslrootcert=/home/ansiuser/Pritam/pgtest/pg/files/ssl/root.crt host=10.0.15.10 dbname=postgres user=pgman sslkey=/home/ansiuser/Pritam/pgtest/pg/files/ssl/pgman.key sslcert=/home/ansiuser/Pritam/pgtest/pg/files/ssl/pgman.crt"

the line for the pgman user in pg_hba.conf is like the following:

hostssl all pgman 0.0.0.0/0 cert clientcert=1

The crt files are in PEM format.

But for some reason, JDBC connection doesn't work.

I tried various combinations of passing the certificate files in DER and PEM formats but I keep getting "FATAL: connection requires a valid client certificate" error.

Here is my JDBC connection string:

'jdbc:postgresql://10.0.15.10:5432/postgres?ssl=true&sslmode=require&sslkey=/home/ansiuser/Pritam/pgtest/pg/files/ssl/pgman.key.pk8&sslcert=/home/ansiuser/Pritam/pgtest/pg/files/ssl/pgman.crt.der&sslrootcert=/home/ansiuser/Pritam/pgtest/pg/files/ssl/root.crt.der&sslfactory=org.postgresql.ssl.jdbc4.LibPQFactory'

Driver Version?
42.2.10

PostgreSQL Version
10.12

Java Version
openjdk version "11" 2018-09-25

Now I am clueless about what to do next. Any hint will be much appreciated.

@dtitov
Copy link

dtitov commented Feb 27, 2020

In my case it was only the key that should have been in DER format: sslcert and sslrootcert should still be PEM. Try this out, maybe it will work.

@pritammobisoft
Copy link

@dtitov Thanks for the reply. I tried that also once again just to be sure. Still no luck.

@davecramer
Copy link
Member

https://github.com/pgjdbc/pgjdbc/blob/master/certdir/Makefile was just added to the repo. We are able to make this work in travis.

@pritammobisoft
Copy link

Summary: I found that the SSL connection works with JDK 8 but not with Open JDK 11.

JDK Verison (That works):

openjdk version "1.8.0_242"
OpenJDK Runtime Environment (build 1.8.0_242-8u242-b08-0ubuntu3~16.04-b08)
OpenJDK 64-Bit Server VM (build 25.242-b08, mixed mode)

JDK Version (That didn't work):

openjdk version "11" 2018-09-25
OpenJDK Runtime Environment (build 11+24-Ubuntu-116.04.1)
OpenJDK 64-Bit Server VM (build 11+24-Ubuntu-116.04.1, mixed mode, sharing)

Here are details of what I did:

To confirm I changed the certificate generated by me with the certificates from the certdir of the pgjdbc repo. Then I tested it with JDK 11. It didn't work. So just to give it a try I recompiled my test program with JDK 8 and ran it. This time it worked!

Then I changed the settings of PostgreSQL server to use my original certificates and tried to connect with JDK 8. It worked with JDK 8 this time too.

Has any of you guys tried to use SSL connection with JDK 11 with Postgres?

@pritammobisoft
Copy link

Checked this further. The SSL connection doesn't work till JDK version OpenJDK version 11.0.4. It starts working from OpenJDK version 11.0.5. Looks like there is some bug in SSL implementation in Open JDK 11 till version 11.0.4.

I also tested it with the current version of Amazon Corretto 11. It also works.

I hope this helps someone who stumbles on this post later.

@dtitov
Copy link

dtitov commented Feb 28, 2020

I'm using:

openjdk 13.0.1 2019-10-15
OpenJDK Runtime Environment AdoptOpenJDK (build 13.0.1+9)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 13.0.1+9, mixed mode, sharing)

Everything works fine. Just FYI.

@davecramer
Copy link
Member

@pritammobisoft thanks for the update!

@gdibernardo8
Copy link

gdibernardo8 commented Apr 7, 2020

Hi everyone! I was wondering if you can help me with this. I ended up here because I'm struggling connecting Mulesoft and postgresql in GoogleCloud via JDBC.
I enabled SSL GoogleCloud-side, downloaded client-cert.pem and client-key.pem, tested with the following:

  1. psql: OK!
    with command:
    psql "sslmode=require sslcert=client-cert.pem sslkey=client-key.pem hostaddr= user=admin1 dbname=myname"
  2. DBeaver: OK!
    To make it work I needed to convert the key from PEM to DER ( with ocmmand: penssl pkcs8 -topk8 -inform PEM -outform DER -in client-key.key -out client-key.pk8)
  3. Tested the JDBC connector using the java class mentioned in the description at point by @Mrk-Nguyen 4): OK!
    I indeed needed to convert the certificate

Now, I'm having some challenges in trying to make it work in Mulesoft, basically I need to create a keystore JKS and import client-cert.pem and client-key.pem. I'm trying to do that with "Keystore Explorer" --> create JKS trustore, import key pair:
It works with the original PEM files, but I I get this error in Mulesoft:
org.postgresql.util.PSQLException: FATAL: connection requires a valid client certificate
I guess that it is due to the JDBC connector issue, therefore i tried with the converted client-key: it doesn't really like the format of the key nor the DER, none of them :(

image

I tried a lot of different formats, but nothing worked.
The client-key.pem downloaded from Google Cloud SQL looks like:
image

Next step should to pass this truststore to JVM via command:

-Djavax.net.ssl.trustStore=path_to_keystore_file
-Djavax.net.ssl.trustStorePassword=password

(as mentioned in: https://help.mulesoft.com/s/question/0D52T00004mXW0MSAW/how-to-access-tls-enabled-mysql-database-using-database-connector)

@bvanderveen
Copy link
Contributor

I eventually got this to work by:

  • Upgrading from a super ancient version of the JDBC driver to org.postgresql:postgresql:42.2.12 (the old version didn't have org.postgresql.ssl.LibPQFactory in it)
  • Using a connection string with format jdbc:postgresql://%s:%s/%s?user=%s&password=%s&ssl=true&sslmode=require
  • Converting my PEM key file using openssl pkcs8 -topk8 -inform PEM -in postgresql.key -outform DER -out postgresql.pk8 -v1 PBE-MD5-DES -nocrypt. The nocrypt flag was required. Without this, I was getting the message "Could not read password for SSL key file, console is not available.".

It would be nice if someone could update the openssl command in docs (https://github.com/pgjdbc/pgjdbc/pull/1376/files) to:

  • update -out my.key.dir to -out postgresql.pk8, since, right above the command, that's what it says is expected by default.
  • add the -nocrypt flag, since this was necessary.

Bonus points if someone could make LibPQFactory work with the PEM format, since… that's how libpq works, and arguably the point of this class is to make the JDBC driver, well, work like libpq.

The struggle continues, comrades.

@davecramer
Copy link
Member

#1762 work for you?

@bvanderveen
Copy link
Contributor

Oh you beat me to it: #1763.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants