On 06/03/20 08:07, Ants Aasma wrote: > I think the "why" the org cert is not root was already made clear, that is > the copmany policy.
Thank you, yes, that was what I had intended to convey, and you have saved me finishing a weedsier follow-up message hoping to convey it better. > I don't think postgres should take a stance ... > whether the > certificate designated as the root of trust is self-signed or claims to get > its power from somewhere else. On 06/03/20 16:34, Bruce Momjian wrote: > Uh, we sure can. We disallow many configurations that we consider > unsafe. Ok, so a person in the situation described here, who is not in a position to demand changes in an organizational policy (whether or not it seems ill-conceived to you or even to him/her), is facing this question: What are the "safest" things I /can/ do, under the existing constraints, and /which of those will work in PostgreSQL/? For example, we might agree that it is safe to trust nothing but the end-entity cert of my server itself. I made a server, here is its cert, here is a root.crt file for libpq containing only this exact cert, I want libpq to connect only ever to this server with this cert and nothing else. It's a pain because I have to roll out new root.crt files to everybody whenever the cert changes, but it would be hard to call it unsafe. Great! Can I do that? I think the answer is no. I haven't found it documented, but I think libpq will fail such a connection, because the cert it has found in root.crt is not self-signed. Or, vary the scenario just enough that my organization, or even my department in my organization, now has its own CA, as the first intermediate, the issuer of the end-entity cert. It might be entirely reasonable to put that CA cert into root.crt, so libpq would only connect to things whose certs were issued in my department, or at least my org. I trust the person who would be issuing my department's certs (in all likelihood, me). I would more-or-less trust my org to issue certs for my org. Great! Can I do that? I think that answer is also no, for the same reason. My department's or org's CA cert isn't going to be self-signed, it's going to be vouched for by a chain of more certs leading to a globally recognized one. Why? Short answer, our org also has web sites. We like for people's browsers to be able to see those. We have one group that makes server certs and they follow one procedure, and the certs they make come out the same way. That shouldn't be a problem for PostgreSQL, so it's hard to argue they should have to use a different procedure just for my cert. > I don't think postgres should take a stance whether the > certificate designated as the root of trust is self-signed or claims > to get its power from somewhere else. I'm inclined to agree but I would change the wording a bit for clarity. *Any* certificate we are going to trust gets its power from somewhere else. Being self-signed is not an exception to that rule (if it were, every Snake Oil, Ltd. self-signed cert generated by every student in every network security class ever would be a root of trust). For us to trust a cert, it must be vouched for in some way. The most important vouching that happens, as far as libpq is concerned, is vouching by the administrator who controls the file system where root.crt is found and the contents of that file. If libpq is looking at a cert and finds it in that file, I have vouched for it. That's why it's there. If it is self-signed, then I'm the only person vouching for it, and that's ok. If it is not self-signed, that just means somebody else also has vouched for it. Maybe for the same use, maybe for some other use. In any event, the fact that somebody else has also vouched for it does not in any way negate that I vouched for it, by putting it there in that file I control. > It's pretty easy to conceive of certificate management procedures that make > use of this chain to implement certificate replacement securely. For > example one might trust the global issuer to verify that a CSR is coming > from the O= value that it's claiming to come from to automate replacement > of intermediate certificates, but not trust that every other sub-CA signed > by root and their sub-sub-CA-s are completely honest and secure. That's an example of the kind of policy design I think ought to be possible, but a first step to getting there would be to just better document what does and doesn't work in libpq now. There seem to be some possible configurations that aren't available, not because of principled arguments for disallowing them, but because they fail unstated assumptions. In an ideal world, I think libpq would be using this algorithm: I'm looking at the server's certificate, s. Is s unexpired and in the trust file? If so, SUCCEED. otherwise, loop: get issuer certificate i from s (if s is self-signed, FAIL). does i have CA:TRUE and Certificate Sign bits? If not, FAIL. does i's Domain Constraint allow it to sign s? If not, FAIL. is i unexpired, or has s a Signed Certificate Timestamp made while i was unexpired? If not, FAIL. is i in the trust file? If so, SUCCEED. s := i, continue. (I left out steps like verify signature, check revocation, etc.) What it seems to be doing, though, is just: I'm looking at s Follow chain all the way to a self-signed cert is that in the file? which seems too simplistic. Regards, -Chap