|
2 | 2 | use warnings;
|
3 | 3 | use PostgresNode;
|
4 | 4 | use TestLib;
|
5 |
| -use Test::More tests => 40; |
| 5 | +use Test::More tests => 62; |
6 | 6 | use ServerSetup;
|
7 | 7 | use File::Copy;
|
8 | 8 |
|
|
20 | 20 | # of the key stored in the code tree and update its permissions.
|
21 | 21 | copy("ssl/client.key", "ssl/client_tmp.key");
|
22 | 22 | chmod 0600, "ssl/client_tmp.key";
|
| 23 | +copy("ssl/client-revoked.key", "ssl/client-revoked_tmp.key"); |
| 24 | +chmod 0600, "ssl/client-revoked_tmp.key"; |
| 25 | + |
| 26 | +# Also make a copy of that explicitly world-readable. We can't |
| 27 | +# necessarily rely on the file in the source tree having those |
| 28 | +# permissions. |
| 29 | +copy("ssl/client.key", "ssl/client_wrongperms_tmp.key"); |
| 30 | +chmod 0644, "ssl/client_wrongperms_tmp.key"; |
23 | 31 |
|
24 | 32 | #### Part 0. Set up the server.
|
25 | 33 |
|
|
48 | 56 |
|
49 | 57 | # The server should not accept non-SSL connections.
|
50 | 58 | test_connect_fails($common_connstr, "sslmode=disable",
|
| 59 | + qr/\Qno pg_hba.conf entry\E/, |
51 | 60 | "server doesn't accept non-SSL connections");
|
52 | 61 |
|
53 | 62 | # Try without a root cert. In sslmode=require, this should work. In verify-ca
|
54 | 63 | # or verify-full mode it should fail.
|
55 | 64 | test_connect_ok($common_connstr, "sslrootcert=invalid sslmode=require",
|
56 | 65 | "connect without server root cert sslmode=require");
|
57 | 66 | test_connect_fails($common_connstr, "sslrootcert=invalid sslmode=verify-ca",
|
| 67 | + qr/root certificate file "invalid" does not exist/, |
58 | 68 | "connect without server root cert sslmode=verify-ca");
|
59 | 69 | test_connect_fails($common_connstr, "sslrootcert=invalid sslmode=verify-full",
|
| 70 | + qr/root certificate file "invalid" does not exist/, |
60 | 71 | "connect without server root cert sslmode=verify-full");
|
61 | 72 |
|
62 | 73 | # Try with wrong root cert, should fail. (We're using the client CA as the
|
63 | 74 | # root, but the server's key is signed by the server CA.)
|
64 | 75 | test_connect_fails($common_connstr,
|
65 | 76 | "sslrootcert=ssl/client_ca.crt sslmode=require",
|
| 77 | + qr/SSL error/, |
66 | 78 | "connect with wrong server root cert sslmode=require");
|
67 | 79 | test_connect_fails($common_connstr,
|
68 | 80 | "sslrootcert=ssl/client_ca.crt sslmode=verify-ca",
|
| 81 | + qr/SSL error/, |
69 | 82 | "connect with wrong server root cert sslmode=verify-ca");
|
70 | 83 | test_connect_fails($common_connstr,
|
71 | 84 | "sslrootcert=ssl/client_ca.crt sslmode=verify-full",
|
| 85 | + qr/SSL error/, |
72 | 86 | "connect with wrong server root cert sslmode=verify-full");
|
73 | 87 |
|
74 | 88 | # Try with just the server CA's cert. This fails because the root file
|
75 | 89 | # must contain the whole chain up to the root CA.
|
76 | 90 | test_connect_fails($common_connstr,
|
77 | 91 | "sslrootcert=ssl/server_ca.crt sslmode=verify-ca",
|
| 92 | + qr/SSL error/, |
78 | 93 | "connect with server CA cert, without root CA");
|
79 | 94 |
|
80 | 95 | # And finally, with the correct root cert.
|
|
107 | 122 | # A CRL belonging to a different CA is not accepted, fails
|
108 | 123 | test_connect_fails($common_connstr,
|
109 | 124 | "sslrootcert=ssl/root+server_ca.crt sslmode=verify-ca sslcrl=ssl/client.crl",
|
| 125 | + qr/SSL error/, |
110 | 126 | "CRL belonging to a different CA");
|
111 | 127 |
|
112 | 128 | # With the correct CRL, succeeds (this cert is not revoked)
|
|
124 | 140 | test_connect_ok($common_connstr, "sslmode=verify-ca host=wronghost.test",
|
125 | 141 | "mismatch between host name and server certificate sslmode=verify-ca");
|
126 | 142 | test_connect_fails($common_connstr, "sslmode=verify-full host=wronghost.test",
|
| 143 | + qr/\Qserver certificate for "common-name.pg-ssltest.test" does not match host name "wronghost.test"\E/, |
127 | 144 | "mismatch between host name and server certificate sslmode=verify-full");
|
128 | 145 |
|
129 |
| - |
130 | 146 | # Test Subject Alternative Names.
|
131 | 147 | switch_server_cert($node, 'server-multiple-alt-names');
|
132 | 148 |
|
|
141 | 157 | "host name matching with X.509 Subject Alternative Names wildcard");
|
142 | 158 |
|
143 | 159 | test_connect_fails($common_connstr, "host=wronghost.alt-name.pg-ssltest.test",
|
| 160 | + qr/\Qserver certificate for "dns1.alt-name.pg-ssltest.test" (and 2 other names) does not match host name "wronghost.alt-name.pg-ssltest.test"\E/, |
144 | 161 | "host name not matching with X.509 Subject Alternative Names");
|
145 | 162 | test_connect_fails($common_connstr,
|
146 | 163 | "host=deep.subdomain.wildcard.pg-ssltest.test",
|
| 164 | + qr/\Qserver certificate for "dns1.alt-name.pg-ssltest.test" (and 2 other names) does not match host name "deep.subdomain.wildcard.pg-ssltest.test"\E/, |
147 | 165 | "host name not matching with X.509 Subject Alternative Names wildcard");
|
148 | 166 |
|
149 | 167 | # Test certificate with a single Subject Alternative Name. (this gives a
|
|
157 | 175 | "host name matching with a single X.509 Subject Alternative Name");
|
158 | 176 |
|
159 | 177 | test_connect_fails($common_connstr, "host=wronghost.alt-name.pg-ssltest.test",
|
| 178 | + qr/\Qserver certificate for "single.alt-name.pg-ssltest.test" does not match host name "wronghost.alt-name.pg-ssltest.test"\E/, |
160 | 179 | "host name not matching with a single X.509 Subject Alternative Name");
|
161 | 180 | test_connect_fails($common_connstr,
|
162 | 181 | "host=deep.subdomain.wildcard.pg-ssltest.test",
|
| 182 | + qr/\Qserver certificate for "single.alt-name.pg-ssltest.test" does not match host name "deep.subdomain.wildcard.pg-ssltest.test"\E/, |
163 | 183 | "host name not matching with a single X.509 Subject Alternative Name wildcard");
|
164 | 184 |
|
165 | 185 | # Test server certificate with a CN and SANs. Per RFCs 2818 and 6125, the CN
|
|
174 | 194 | test_connect_ok($common_connstr, "host=dns2.alt-name.pg-ssltest.test",
|
175 | 195 | "certificate with both a CN and SANs 2");
|
176 | 196 | test_connect_fails($common_connstr, "host=common-name.pg-ssltest.test",
|
| 197 | + qr/\Qserver certificate for "dns1.alt-name.pg-ssltest.test" (and 1 other name) does not match host name "common-name.pg-ssltest.test"\E/, |
177 | 198 | "certificate with both a CN and SANs ignores CN");
|
178 | 199 |
|
179 | 200 | # Finally, test a server certificate that has no CN or SANs. Of course, that's
|
|
187 | 208 | "server certificate without CN or SANs sslmode=verify-ca");
|
188 | 209 | test_connect_fails($common_connstr,
|
189 | 210 | "sslmode=verify-full host=common-name.pg-ssltest.test",
|
| 211 | + qr/could not get server's host name from server certificate/, |
190 | 212 | "server certificate without CN or SANs sslmode=verify-full");
|
191 | 213 |
|
192 | 214 | # Test that the CRL works
|
|
201 | 223 | "connects without client-side CRL");
|
202 | 224 | test_connect_fails($common_connstr,
|
203 | 225 | "sslrootcert=ssl/root+server_ca.crt sslmode=verify-ca sslcrl=ssl/root+server.crl",
|
| 226 | + qr/SSL error/, |
204 | 227 | "does not connect with client-side CRL");
|
205 | 228 |
|
206 | 229 | ### Part 2. Server-side tests.
|
|
215 | 238 | # no client cert
|
216 | 239 | test_connect_fails($common_connstr,
|
217 | 240 | "user=ssltestuser sslcert=invalid",
|
| 241 | + qr/connection requires a valid client certificate/, |
218 | 242 | "certificate authorization fails without client cert");
|
219 | 243 |
|
220 | 244 | # correct client cert
|
221 | 245 | test_connect_ok($common_connstr,
|
222 | 246 | "user=ssltestuser sslcert=ssl/client.crt sslkey=ssl/client_tmp.key",
|
223 | 247 | "certificate authorization succeeds with correct client cert");
|
224 | 248 |
|
| 249 | +# client key with wrong permissions |
| 250 | +test_connect_fails($common_connstr, |
| 251 | + "user=ssltestuser sslcert=ssl/client.crt sslkey=ssl/client_wrongperms_tmp.key", |
| 252 | + qr!\Qprivate key file "ssl/client_wrongperms_tmp.key" has group or world access\E!, |
| 253 | + "certificate authorization fails because of file permissions"); |
| 254 | + |
225 | 255 | # client cert belonging to another user
|
226 | 256 | test_connect_fails($common_connstr,
|
227 | 257 | "user=anotheruser sslcert=ssl/client.crt sslkey=ssl/client_tmp.key",
|
| 258 | + qr/certificate authentication failed for user "anotheruser"/, |
228 | 259 | "certificate authorization fails with client cert belonging to another user");
|
229 | 260 |
|
230 | 261 | # revoked client cert
|
231 | 262 | test_connect_fails($common_connstr,
|
232 |
| - "user=ssltestuser sslcert=ssl/client-revoked.crt sslkey=ssl/client-revoked.key", |
| 263 | + "user=ssltestuser sslcert=ssl/client-revoked.crt sslkey=ssl/client-revoked_tmp.key", |
| 264 | + qr/SSL error/, |
233 | 265 | "certificate authorization fails with revoked client cert");
|
234 | 266 |
|
235 | 267 | # intermediate client_ca.crt is provided by client, and isn't in server's ssl_ca_file
|
|
241 | 273 | "sslmode=require sslcert=ssl/client+client_ca.crt",
|
242 | 274 | "intermediate client certificate is provided by client");
|
243 | 275 | test_connect_fails($common_connstr, "sslmode=require sslcert=ssl/client.crt",
|
| 276 | + qr/SSL error/, |
244 | 277 | "intermediate client certificate is missing");
|
245 | 278 |
|
246 | 279 | # clean up
|
247 |
| -unlink "ssl/client_tmp.key"; |
| 280 | +unlink("ssl/client_tmp.key", |
| 281 | + "ssl/client_wrongperms_tmp.key", |
| 282 | + "ssl/client-revoked_tmp.key"); |
0 commit comments