682
687
if (strcmp(conn->sslmode, "verify-full") != 0)
691
* Extract the common name from the certificate.
693
* XXX: Should support alternate names here
695
/* First find out the name's length and allocate a buffer for it. */
696
len = X509_NAME_get_text_by_NID(X509_get_subject_name(conn->peer),
697
NID_commonName, NULL, 0);
700
printfPQExpBuffer(&conn->errorMessage,
701
libpq_gettext("could not get server common name from server certificate\n"));
704
peer_cn = malloc(len + 1);
707
printfPQExpBuffer(&conn->errorMessage,
708
libpq_gettext("out of memory\n"));
712
r = X509_NAME_get_text_by_NID(X509_get_subject_name(conn->peer),
713
NID_commonName, peer_cn, len + 1);
716
/* Got different length than on the first call. Shouldn't happen. */
717
printfPQExpBuffer(&conn->errorMessage,
718
libpq_gettext("could not get server common name from server certificate\n"));
725
* Reject embedded NULLs in certificate common name to prevent attacks
726
* like CVE-2009-4034.
728
if (len != strlen(peer_cn))
730
printfPQExpBuffer(&conn->errorMessage,
731
libpq_gettext("SSL certificate's common name contains embedded null\n"));
737
* We got the peer's common name. Now compare it against the originally
685
740
if (!(conn->pghost && conn->pghost[0] != '\0'))
687
742
printfPQExpBuffer(&conn->errorMessage,
688
743
libpq_gettext("host name must be specified for a verified SSL connection\n"));
694
* Connect by hostname.
696
* XXX: Should support alternate names here
698
if (pg_strcasecmp(conn->peer_cn, conn->pghost) == 0)
748
if (pg_strcasecmp(peer_cn, conn->pghost) == 0)
699
749
/* Exact name match */
701
else if (wildcard_certificate_match(conn->peer_cn, conn->pghost))
751
else if (wildcard_certificate_match(peer_cn, conn->pghost))
702
752
/* Matched wildcard certificate */
706
756
printfPQExpBuffer(&conn->errorMessage,
707
757
libpq_gettext("server common name \"%s\" does not match host name \"%s\"\n"),
708
conn->peer_cn, conn->pghost);
758
peer_cn, conn->pghost);
1351
1404
return PGRES_POLLING_FAILED;
1354
X509_NAME_oneline(X509_get_subject_name(conn->peer),
1355
conn->peer_dn, sizeof(conn->peer_dn));
1356
conn->peer_dn[sizeof(conn->peer_dn) - 1] = '\0';
1358
r = X509_NAME_get_text_by_NID(X509_get_subject_name(conn->peer),
1359
NID_commonName, conn->peer_cn, SM_USER);
1360
conn->peer_cn[SM_USER] = '\0'; /* buffer is SM_USER+1 chars! */
1363
/* Unable to get the CN, set it to blank so it can't be used */
1364
conn->peer_cn[0] = '\0';
1369
* Reject embedded NULLs in certificate common name to prevent attacks like
1372
if (r != strlen(conn->peer_cn))
1374
printfPQExpBuffer(&conn->errorMessage,
1375
libpq_gettext("SSL certificate's common name contains embedded null\n"));
1377
return PGRES_POLLING_FAILED;
1381
1407
if (!verify_peer_name_matches_certificate(conn))
1383
1409
close_SSL(conn);