Re: what can go in root.crt ? - Mailing list pgsql-hackers
From | Chapman Flack |
---|---|
Subject | Re: what can go in root.crt ? |
Date | |
Msg-id | 5ECC8A5A.6080008@anastigmatix.net Whole thread Raw |
In response to | Re: what can go in root.crt ? (Bruce Momjian <bruce@momjian.us>) |
List | pgsql-hackers |
On 05/25/20 22:03, Bruce Momjian wrote: > Did you review the PG documentation about intermediate certificates? > > https://www.postgresql.org/docs/13/ssl-tcp.html#SSL-CERTIFICATE-CREATION AFAICT, there isn't much in that section to apply to my question. > Is there a specific question you have? I'm pretty sure there is. :) Let me try to clarify it. The doc section you linked has an example showing how to be my own CA, and generate a chain of certs including a self-signed one to serve as the root. It suggests putting that self-signed one in root.crt on the client. That means the client will happily connect to any server wearing a certificate signed by that root (or by intermediates that can be followed up to that root). For the example that's fine, because that root signer is me, and there aren't a lot of other certs around that chain back to it. At $work we have Ways Of Doing Things. Generating our own self-signed certs generally isn't among those. If I want a certificate so I can stand up a server, I generate a key and a CSR, I send the CSR to our Bureau of Making Certificates Happen, and they send me back a signed cert with a chain of external authorities, ending in the self-signed certificate of a prominent commercial root CA. Sure, I can put that self-signed root cert into root.crt on the client, and my client will happily connect to my server. But in this case the world is teeming with other certificates and even other whole sub-CAs that chain back to that prominent root issuer. Granted, you might have to be a bit enterprising to find a sub-CA out there that will sign a cert for you with the name of my server in it, but if you can, my client will follow the chain back to that same root, and therefore trust it. So I would like to be able to do one of two things: 1. I would like to put my server's end-entity (leaf) certificate in the root.crt file, and have my client only accept a server with that exact cert. Or, 2. I would like to put one of the lower intermediates from the chain into the root.crt file, to at least limit my client to trusting only certs signed by that particular sub-CA. What seems to be happening (for the libpq and libssl versions in 18.04 anyway) is that the certificate that I put in root.crt is found, but because it isn't a literal "root", as in signer-of-itself, the library declares a verification failure because it hasn't been able to continue climbing the chain to find a "root" cert. Whereas I would like it to say "but I don't have to do that, because I have already verified as far as this certificate that the administrator deliberately placed in this file here to tell me to trust it." In Java, for example, the analogous file is called trustStore, which may be a better name. You populate the trustStore with certificates you consider trusted. They can be root certs, intermediate certs, or flat-out leaf certs of individual servers. Whenever Java is verifying a connection, as soon as its chain-following brings it to a cert that you placed in the trustStore, it stops and says "yes, I trust this, because you have told me to." I have also encountered web browsers that work in both of these ways. The last time I was standing up a temporary web service to test something, I did make a self-signed cert and then use it to sign a leaf cert for the service. I was testing with Chrome and Firefox and they both have spiffy UIs for managing a list of trusted certs, but one of them (I have forgotten which) allowed me to simply load the leaf cert that I wanted to trust, while the other insisted I give it the self-signed root that I had signed the leaf cert with. I think the former behavior, which is like Java's, is strictly more useful. What puzzled me today, and why I began this thread, is that I hadn't (and still haven't) found a clear discussion in the doc of these two approaches and which one libpq is intended to supply. I know that my attempts to use root.crt like a trustStore have so far been met with failure, but between the terse error message and the sparse doc, it is hard to know whether that's a "you can't do that, dummy!" or a "you just haven't guessed the right way yet." If there is a way to get a trustStore-like behavior and have the client trust an intermediate or leaf cert that I explicitly tell it to, but I just haven't pronounced the magic words right, this email may be read as "oh good, how do I do it?" If the current implementation really is stuck accepting only self-signed certs in that file and therefore can't offer trustStore-like behavior, this email may be read as "it could be made more useful by changing that." And in either case, there seems to be room in the docs for some discussion of the difference between those two models and which one libpq is meant to offer. I would not be unwilling to try my hand at such a doc patch one day, but for now I'm still hoping to learn the answers myself. Regards, -Chap
pgsql-hackers by date: