Thread: SSL certificates issue

SSL certificates issue

From
Asia
Date:
Recently I have been working on implementation of mutual SSL authentication between our application and PostgreSQL
database.
I managed to make it work wih "ssl=true" connection option and "clientcert=1" flags in pg_hba.conf. Moreover I managed
tomake it work with C++ application using libpq and Java application using postgresql JDBC driver. 

The only concern I have is some discrepancy between the way libpq and JDBC works. It seems that libpq is less
restrictivethan JDBC with standard 
built-in SSLSocketFactory.
The following schema describes some information about my certs:

    Client                                  Server
    postgresql.crt                       server.crt
    postgresql.key                      server.key
    root.crt                               root.crt

where postgresql.crt is singed by Intermediate CA 1
         server.crt is signed     by Intermediate CA 2
 Intermediate CA 1 and Intermediate CA 2 are chain certs both singed by the same root certificate
         root.crt - root certificate that signed Intermediate CA1 and Intermediate CA 2 (which was enough for libpq but
notenough for JDBC) 

Now the issue is then when using libpq it was enough to have only root certificate in server's root.crt and it worked
fine.
But when I tried using the same with JDBC it turned out that I need to put whole chain (2 certs) of Intermediate CA 1
inserver's root.crt. 

All I need is the confirmation whether this is working as designed or this is possibly libpq bug?

Kind Regards,
Joanna


Re: SSL certificates issue

From
Tom Lane
Date:
Asia <asia123321@op.pl> writes:
> Now the issue is then when using libpq it was enough to have only root certificate in server's root.crt and it worked
fine.
> But when I tried using the same with JDBC it turned out that I need to put whole chain (2 certs) of Intermediate CA 1
inserver's root.crt. 

This is poor configuration, because every certificate listed in root.crt
is considered fully trusted for every purpose.  It's best to keep only
top-level root certs in root.crt.  Instead, put the full chain of
certificates into the client's postgresql.crt, as per the manual:

: In some cases, the client certificate might be signed by an
: "intermediate" certificate authority, rather than one that is directly
: trusted by the server. To use such a certificate, append the certificate
: of the signing authority to the postgresql.crt file, then its parent
: authority's certificate, and so on up to a "root" authority that is
: trusted by the server. The root certificate should be included in every
: case where postgresql.crt contains more than one certificate.

In the JDBC case you'd need to put all those certs into the client's
keystore, which I'm afraid I don't know the details of doing.  Possibly
somebody on pgsql-jdbc could help you with that.

            regards, tom lane

Re: SSL certificates issue

From
Asia
Date:
Thank you for your reply. I agree that this configuration could be better and this is why I sent my post.

There is still one concern remaining. As I said I have working configuration with libpq and jdbc. For jdbc I created
keystore,that is properly used with connection ssl=on parameter and clientcert=1 in og_hba.conf, everything works fine. 

The issue is why for libpq it is enough to have only one lowest level root certificate matched besides the fact that
certificatepostgresql.crt that is presented to server contains actually 3 certs (2 from Intermediate authority with
lowestlevel root).  
For JDBC it was not enough, I had to put whole CA chain to be able to create succesfull connection. It seems lipqg does
notsupport chained CA's. 

I need to confirm that this is working as designed (I will be able to adjust my solution depending on the answer).

Thank you.

Kind regards,
Joanna

W dniu 2011-08-22 15:37:28 użytkownik Tom Lane <tgl@sss.pgh.pa.us> napisał:
> Asia <asia123321@op.pl> writes:
> > Now the issue is then when using libpq it was enough to have only root certificate in server's root.crt and it
workedfine. 
> > But when I tried using the same with JDBC it turned out that I need to put whole chain (2 certs) of Intermediate CA
1in server's root.crt. 
>
> This is poor configuration, because every certificate listed in root.crt
> is considered fully trusted for every purpose.  It's best to keep only
> top-level root certs in root.crt.  Instead, put the full chain of
> certificates into the client's postgresql.crt, as per the manual:
>
> : In some cases, the client certificate might be signed by an
> : "intermediate" certificate authority, rather than one that is directly
> : trusted by the server. To use such a certificate, append the certificate
> : of the signing authority to the postgresql.crt file, then its parent
> : authority's certificate, and so on up to a "root" authority that is
> : trusted by the server. The root certificate should be included in every
> : case where postgresql.crt contains more than one certificate.
>
> In the JDBC case you'd need to put all those certs into the client's
> keystore, which I'm afraid I don't know the details of doing.  Possibly
> somebody on pgsql-jdbc could help you with that.
>
>             regards, tom lane
>




Re: SSL certificates issue

From
Giuseppe Sacco
Date:
Il giorno lun, 22/08/2011 alle 09.37 -0400, Tom Lane ha scritto:
> Asia <asia123321@op.pl> writes:
> > Now the issue is then when using libpq it was enough to have only root certificate in server's root.crt and it
workedfine. 
> > But when I tried using the same with JDBC it turned out that I need to put whole chain (2 certs) of Intermediate CA
1in server's root.crt. 
[...]
> In the JDBC case you'd need to put all those certs into the client's
> keystore, which I'm afraid I don't know the details of doing.  Possibly
> somebody on pgsql-jdbc could help you with that.

you should import CA certificate in your JRE ca certstore with commands:

cd $JAVA_HOME/jre/lib/security
keytool -import -trustcacerts -alias $YOURCAALIAS \
    -file $YOURCACERTFILE -keystore cacerts

I usually store in client and server certificates the whole chain from
primary CA.

Bye,
Giuseppe


Re: SSL certificates issue

From
Asia
Date:
> Asia <asia123321@op.pl> writes:
> > Now the issue is then when using libpq it was enough to have only root certificate in server's root.crt and it
workedfine. 
> > But when I tried using the same with JDBC it turned out that I need to put whole chain (2 certs) of Intermediate CA
1in server's root.crt. 
>
> This is poor configuration, because every certificate listed in root.crt
> is considered fully trusted for every purpose.  It's best to keep only
> top-level root certs in root.crt.  Instead, put the full chain of
> certificates into the client's postgresql.crt, as per the manual:
>
> : In some cases, the client certificate might be signed by an
> : "intermediate" certificate authority, rather than one that is directly
> : trusted by the server. To use such a certificate, append the certificate
> : of the signing authority to the postgresql.crt file, then its parent
> : authority's certificate, and so on up to a "root" authority that is
> : trusted by the server. The root certificate should be included in every
> : case where postgresql.crt contains more than one certificate.
>
> In the JDBC case you'd need to put all those certs into the client's
> keystore, which I'm afraid I don't know the details of doing.  Possibly
> somebody on pgsql-jdbc could help you with that.
>
>             regards, tom lane
>

Hi Tom,

I have analyzed your reply thoroughly in my implementation, but unfortunately either I make something wrong with the
configurationor it does not work like described in the doc. 

When I put top-level CA (just to remind intermediate CA is a 2 certs chain) certificate in root.crt on client I receive
followingerror when connecting: 

SSL error: tlsv1 alert unknown ca

When I do the same on server (with original root.crt on client) I receive following error when connecting with server's
root.crtcontaining only top level CA: 

SSL error: certificate verify failed

I was not actually asking for the details ho to do it with JDBC, since I got it working with proper keystore and
truststoreand "clientcert=1". I was asking why jdbc works differently than libpq - it should have similar behavior
(JDBCuses standard ssl implementation from Java, I did not find custom implementation from Postgres). JDBC requires
clientsfull CA chain in server's root.crt while libpq does not. The question is why and is it right ? 

Would you please let me know what possibly I am doing wrong and confirm that chained CA's are supported?

I would expect to have only one top-level CA cert in server's and client's root.crt and it was not possible to
configurewith 2-level intermediate CA.  

Please advise.

Kind regards,
Joanna



Re: SSL certificates issue

From
Tom Lane
Date:
Asia <asia123321@op.pl> writes:
> I would expect to have only one top-level CA cert in server's and client's root.crt and it was not possible to
configurewith 2-level intermediate CA.  

This seems a little confused, since in your previous message you stated
that libpq worked correctly and JDBC did not, and now you seem to be
saying the opposite.

As far as libpq goes, I would expect it to function correctly in 9.0 and
up (and it did function correctly, last I tested it).  Previous releases
will not do this nicely, for lack of this patch:
http://git.postgresql.org/gitweb/?p=postgresql.git&a=commitdiff&h=4ed4b6c54

            regards, tom lane

Re: SSL certificates issue

From
Asia
Date:
> Asia <asia123321@op.pl> writes:
> > I would expect to have only one top-level CA cert in server's and client's root.crt and it was not possible to
configurewith 2-level intermediate CA.  
>
> This seems a little confused, since in your previous message you stated
> that libpq worked correctly and JDBC did not, and now you seem to be
> saying the opposite.
>
> As far as libpq goes, I would expect it to function correctly in 9.0 and
> up (and it did function correctly, last I tested it).  Previous releases
> will not do this nicely, for lack of this patch:
> http://git.postgresql.org/gitweb/?p=postgresql.git&a=commitdiff&h=4ed4b6c54
>
>             regards, tom lane
>


I apologise then, it seems I was not clear enough when explaining my issue.

I am using PostgreSQL, version 9.0.

I have all of it (libpq and jdbc) working, however I have some doubts about the correctness of my configuration.

The situation is more or less like following:

Client intermediate CA (root.crt): C1 -> C2, Client cert: C1 -> C2 ->C3

Server intermediate CA (root.crt): C1 -> S1, Server Cert: C1 -> S1 -> S2

I always use clientcert=1 in pg_hba to force mutual SSL.

Now with the above configuration libpq connects fine. But when I tried to use jdbc it requires me to append client's
intermediateCA - "C1 -> C2"  
to server's root.crt. So server's root.crt content looks like follows:

C1 -> S1  ->  C1 -> C2

Then jdbc conenction works fine and the change does not affect libpq - it works fine like before.

So my point was general why the behavior for libpq and jdbc driver is not common (probably we would need some custom
implementationof Java SSL facory  
for PostgreSQL) - both types of connection have different cert configuration what I believe could be better when it was
common.

And the second issue is that you wrote that it should be enough to put to-level CA certs. So I left only C1 in server's
root.crt,restarted server 
and received following error during connection:

SSL error: certificate verify failed

The question is how to do it correctly?

Please advise.

Kind regards,
Joanna

Re: SSL certificates issue

From
Radosław Smogura
Date:
On Wed, 07 Sep 2011 12:03:45 +0200, Asia wrote:
>> Asia <asia123321@op.pl> writes:
>> > I would expect to have only one top-level CA cert in server's and
>> client's root.crt and it was not possible to configure with 2-level
>> intermediate CA.
>>
>> This seems a little confused, since in your previous message you
>> stated
>> that libpq worked correctly and JDBC did not, and now you seem to be
>> saying the opposite.
>>
>> As far as libpq goes, I would expect it to function correctly in 9.0
>> and
>> up (and it did function correctly, last I tested it).  Previous
>> releases
>> will not do this nicely, for lack of this patch:
>>
>> http://git.postgresql.org/gitweb/?p=postgresql.git&a=commitdiff&h=4ed4b6c54
>>
>>             regards, tom lane
>>
>
>
> I apologise then, it seems I was not clear enough when explaining my
> issue.
>
> I am using PostgreSQL, version 9.0.
>
> I have all of it (libpq and jdbc) working, however I have some doubts
> about the correctness of my configuration.
>
> The situation is more or less like following:
>
> Client intermediate CA (root.crt): C1 -> C2, Client cert: C1 -> C2
> ->C3
>
> Server intermediate CA (root.crt): C1 -> S1, Server Cert: C1 -> S1 ->
> S2
>
> I always use clientcert=1 in pg_hba to force mutual SSL.
>
> Now with the above configuration libpq connects fine. But when I
> tried to use jdbc it requires me to append client's intermediate CA -
> "C1 -> C2"
> to server's root.crt. So server's root.crt content looks like
> follows:
>
> C1 -> S1  ->  C1 -> C2
>
> Then jdbc conenction works fine and the change does not affect libpq
> - it works fine like before.
>
> So my point was general why the behavior for libpq and jdbc driver is
> not common (probably we would need some custom implementation of Java
> SSL facory
> for PostgreSQL) - both types of connection have different cert
> configuration what I believe could be better when it was common.
>
> And the second issue is that you wrote that it should be enough to
> put to-level CA certs. So I left only C1 in server's root.crt,
> restarted server
> and received following error during connection:
>
> SSL error: certificate verify failed
>
> The question is how to do it correctly?
>
> Please advise.
>
> Kind regards,
> Joanna

I think problem is as follows, server sends to client certificates it
can accept (as accepted parents), without intermediate CA, Java sees
only top-level cert and tries to find client cert issued directly by
top-level CA, I may only assume, that without intermediate CA you will
be able to auth against any cert signed by top-level CA (this may cause
small security hole as well).

I think this is not needed, but I suggest You too check cert "policies"
with v3 extensions.

Java is really pedantic, about security.

Regards,
Radek

Re: SSL certificates issue

From
Asia
Date:
>
> I think problem is as follows, server sends to client certificates it
> can accept (as accepted parents), without intermediate CA, Java sees
> only top-level cert and tries to find client cert issued directly by
> top-level CA, I may only assume, that without intermediate CA you will
> be able to auth against any cert signed by top-level CA (this may cause
> small security hole as well).
>
> I think this is not needed, but I suggest You too check cert "policies"
> with v3 extensions.
>
> Java is really pedantic, about security.
>
> Regards,
> Radek
>


The problem is that I believe that this configuration could be better but I cannot put part
of CA chain in root.crt as it was advised.
For Java it all depends on current SSL Factory implementation, I was using the default one.
If I wrote my own implementation I would probably be able to have common with libpq,
requiring the least info, configuration (but actually I would prefer to avoid it).

Kind regards,
Joanna


Re: SSL certificates issue

From
Radosław Smogura
Date:
On Wed, 07 Sep 2011 13:49:30 +0200, Asia wrote:
>>
>> I think problem is as follows, server sends to client certificates
>> it
>> can accept (as accepted parents), without intermediate CA, Java sees
>> only top-level cert and tries to find client cert issued directly by
>> top-level CA, I may only assume, that without intermediate CA you
>> will
>> be able to auth against any cert signed by top-level CA (this may
>> cause
>> small security hole as well).
>>
>> I think this is not needed, but I suggest You too check cert
>> "policies"
>> with v3 extensions.
>>
>> Java is really pedantic, about security.
>>
>> Regards,
>> Radek
>>
>
>
> The problem is that I believe that this configuration could be better
> but I cannot put part
> of CA chain in root.crt as it was advised.
> For Java it all depends on current SSL Factory implementation, I was
> using the default one.
> If I wrote my own implementation I would probably be able to have
> common with libpq,
> requiring the least info, configuration (but actually I would prefer
> to avoid it).
>
> Kind regards,
> Joanna

I personally haven't tired SSL for PostgreSQL but, I think, You should
put in root.crt only intermediate certificate (C1 - from prev post), so
all and only all "sub-certs" of intermediate CA will be able to
establish connection (paranoic security).

Putting intermediate CAs as trusted in Java keystore may be solution,
but I'm not sure if in situation of cert invalidation, such cert will be
rejected.

If you want to write SSL Factory, you should re-implement KeyManager
only, to give ability of extended search.

Regards,
Radek

Re: SSL certificates issue

From
Adrian Klaver
Date:
On Wednesday, September 07, 2011 4:49:30 am Asia wrote:

>
> The problem is that I believe that this configuration could be better but I
> cannot put part of CA chain in root.crt as it was advised.
> For Java it all depends on current SSL Factory implementation, I was using
> the default one. If I wrote my own implementation I would probably be able
> to have common with libpq, requiring the least info, configuration (but
> actually I would prefer to avoid it).

You might want to take a look at the below and see if it helps:

http://jdbc.postgresql.org/documentation/head/ssl-client.html

>
> Kind regards,
> Joanna

--
Adrian Klaver
adrian.klaver@gmail.com

Re: SSL certificates issue

From
Asia
Date:
>
> I personally haven't tired SSL for PostgreSQL but, I think, You should
> put in root.crt only intermediate certificate (C1 - from prev post), so
> all and only all "sub-certs" of intermediate CA will be able to
> establish connection (paranoic security).
>
> Putting intermediate CAs as trusted in Java keystore may be solution,
> but I'm not sure if in situation of cert invalidation, such cert will be
> rejected.
>
> If you want to write SSL Factory, you should re-implement KeyManager
> only, to give ability of extended search.
>
> Regards,
> Radek
>

I  have already tried with only C1 in root.crt but unfortunately it does not work. I get error message that cert is
invalid.It seems that chained CA's are not supported in a way we would like to have it done. I would prefer to have
numberof trusted certs in root.crt limited as much as possible, but as I said it does not work. 

About Java, I would need to analyze the libpq code and implement KeyManager in a similar way - this is surely possible
butnot necessarily preferred solution ;-) 

Kind regards,
Joanna


Re: SSL certificates issue

From
Tom Lane
Date:
Asia <asia123321@op.pl> writes:
> The problem is that I believe that this configuration could be better but I cannot put part
> of CA chain in root.crt as it was advised.
> For Java it all depends on current SSL Factory implementation, I was using the default one.
> If I wrote my own implementation I would probably be able to have common with libpq,
> requiring the least info, configuration (but actually I would prefer to avoid it).

You would be better off to ask about this on the pgsql-jdbc list; the
people who actually work with JDBC tend to hang out there.  I'm not sure
how carefully any of them follow pgsql-general.

            regards, tom lane

Re: SSL certificates issue

From
Asia
Date:
I have a feeling that jdbc list is not the right list to ask why libpq does not work when I
put top-level CA cert from CA having two certs in root.crt while you stated it would be
proper configuration.

There are 2 related threads here: one with consistency between libpq and jdbc driver and the other about
how libpq works with chained CA's.

Kind regards,
Joanna

W dniu 2011-09-07 16:06:10 użytkownik Tom Lane <tgl@sss.pgh.pa.us> napisał:
> Asia <asia123321@op.pl> writes:
> > The problem is that I believe that this configuration could be better but I cannot put part
> > of CA chain in root.crt as it was advised.
> > For Java it all depends on current SSL Factory implementation, I was using the default one.
> > If I wrote my own implementation I would probably be able to have common with libpq,
> > requiring the least info, configuration (but actually I would prefer to avoid it).
>
> You would be better off to ask about this on the pgsql-jdbc list; the
> people who actually work with JDBC tend to hang out there.  I'm not sure
> how carefully any of them follow pgsql-general.
>
>             regards, tom lane
>




Re: SSL certificates issue

From
Tom Lane
Date:
Asia <asia123321@op.pl> writes:
> I have a feeling that jdbc list is not the right list to ask why libpq does not work when I
> put top-level CA cert from CA having two certs in root.crt while you stated it would be
> proper configuration.

What is a "CA having two certs"?  AFAIK, there is no such animal.

            regards, tom lane

Re: SSL certificates issue

From
Radosław Smogura
Date:
Asia <asia123321@op.pl> Wednesday 07 of September 2011 16:00:39
> > I personally haven't tired SSL for PostgreSQL but, I think, You should
> > put in root.crt only intermediate certificate (C1 - from prev post), so
> > all and only all "sub-certs" of intermediate CA will be able to
> > establish connection (paranoic security).
> >
> > Putting intermediate CAs as trusted in Java keystore may be solution,
> > but I'm not sure if in situation of cert invalidation, such cert will be
> > rejected.
> >
> > If you want to write SSL Factory, you should re-implement KeyManager
> > only, to give ability of extended search.
> >
> > Regards,
> > Radek
>
> I  have already tried with only C1 in root.crt but unfortunately it does
> not work. I get error message that cert is invalid. It seems that chained
> CA's are not supported in a way we would like to have it done. I would
> prefer to have number of trusted certs in root.crt limited as much as
> possible, but as I said it does not work.
>
> About Java, I would need to analyze the libpq code and implement KeyManager
> in a similar way - this is surely possible but not necessarily preferred
> solution ;-)
>
> Kind regards,
> Joanna
I bearly looked at Javav SSL implementation, and it should support certificate
chain, even if intermediate cert isn't presented by server (not in root.crt),
until You have valid chain in key/trust store. I found, and You may try to
turn it on, "javax.net.debug=all" to see debug info of cert matching.

Only one thing comes to me, why it doesn't works, Your intermediate cert may
have no issuer DN

Regards,
Radek

Re: SSL certificates issue

From
Andrew Sullivan
Date:
On Wed, Sep 07, 2011 at 04:37:24PM +0200, Asia wrote:

> put top-level CA cert from CA having two certs in root.crt

[. . .]

> how libpq works with chained CA's.

"Two certs" and "chained CAs" are completely different problems.  What
are you trying to do, exactly?

A

--
Andrew Sullivan
ajs@crankycanuck.ca