aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMagnus Hagander <magnus@hagander.net>2009-12-09 06:37:09 +0000
committerMagnus Hagander <magnus@hagander.net>2009-12-09 06:37:09 +0000
commit5293cc8eb915f5f45ec206d3e770092b50cf445b (patch)
treeac4fba9f5fa9daafb53ddba5cdfa99e61e8f626c
parent32eb4823db6985d81644a249d73e28b7bb9891cd (diff)
downloadpostgresql-5293cc8eb915f5f45ec206d3e770092b50cf445b.tar.gz
postgresql-5293cc8eb915f5f45ec206d3e770092b50cf445b.zip
Reject certificates with embedded NULLs in the commonName field. This stops
attacks where an attacker would put <attack>\0<propername> in the field and trick the validation code that the certificate was for <attack>. This is a very low risk attack since it reuqires the attacker to trick the CA into issuing a certificate with an incorrect field, and the common PostgreSQL deployments are with private CAs, and not external ones. Also, default mode in 8.4 does not do any name validation, and is thus also not vulnerable - but the higher security modes are. Backpatch all the way. Even though versions 8.3.x and before didn't have certificate name validation support, they still exposed this field for the user to perform the validation in the application code, and there is no way to detect this problem through that API. Security: CVE-2009-4034
-rw-r--r--src/backend/libpq/be-secure.c26
-rw-r--r--src/interfaces/libpq/fe-secure.c25
2 files changed, 46 insertions, 5 deletions
diff --git a/src/backend/libpq/be-secure.c b/src/backend/libpq/be-secure.c
index b854d4337c7..589424c6dd4 100644
--- a/src/backend/libpq/be-secure.c
+++ b/src/backend/libpq/be-secure.c
@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/libpq/be-secure.c,v 1.43.2.5 2009/01/28 15:06:48 mha Exp $
+ * $Header: /cvsroot/pgsql/src/backend/libpq/be-secure.c,v 1.43.2.6 2009/12/09 06:37:09 mha Exp $
*
* Since the server static private key ($DataDir/server.key)
* will normally be stored unencrypted so that the database
@@ -801,12 +801,34 @@ open_server_SSL(Port *port)
}
else
{
+ int r;
+
X509_NAME_oneline(X509_get_subject_name(port->peer),
port->peer_dn, sizeof(port->peer_dn));
port->peer_dn[sizeof(port->peer_dn) - 1] = '\0';
- X509_NAME_get_text_by_NID(X509_get_subject_name(port->peer),
+ r = X509_NAME_get_text_by_NID(X509_get_subject_name(port->peer),
NID_commonName, port->peer_cn, sizeof(port->peer_cn));
port->peer_cn[sizeof(port->peer_cn) - 1] = '\0';
+ if (r == -1)
+ {
+ /* Unable to get the CN, set it to blank so it can't be used */
+ port->peer_cn[0] = '\0';
+ }
+ else
+ {
+ /*
+ * Reject embedded NULLs in certificate common name to prevent attacks like
+ * CVE-2009-4034.
+ */
+ if (r != strlen(port->peer_cn))
+ {
+ ereport(COMMERROR,
+ (errcode(ERRCODE_PROTOCOL_VIOLATION),
+ errmsg("SSL certificate's common name contains embedded null")));
+ close_SSL(port);
+ return -1;
+ }
+ }
}
ereport(DEBUG2,
(errmsg("SSL connection from \"%s\"", port->peer_cn)));
diff --git a/src/interfaces/libpq/fe-secure.c b/src/interfaces/libpq/fe-secure.c
index 3a445b780d0..ed85c452d45 100644
--- a/src/interfaces/libpq/fe-secure.c
+++ b/src/interfaces/libpq/fe-secure.c
@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-secure.c,v 1.32.2.2 2009/01/28 15:06:48 mha Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-secure.c,v 1.32.2.3 2009/12/09 06:37:09 mha Exp $
*
* NOTES
* The client *requires* a valid server certificate. Since
@@ -967,9 +967,28 @@ open_client_SSL(PGconn *conn)
conn->peer_dn, sizeof(conn->peer_dn));
conn->peer_dn[sizeof(conn->peer_dn) - 1] = '\0';
- X509_NAME_get_text_by_NID(X509_get_subject_name(conn->peer),
+ r = X509_NAME_get_text_by_NID(X509_get_subject_name(conn->peer),
NID_commonName, conn->peer_cn, SM_USER);
- conn->peer_cn[SM_USER] = '\0';
+ conn->peer_cn[SM_USER] = '\0'; /* buffer is SM_USER+1 chars! */
+ if (r == -1)
+ {
+ /* Unable to get the CN, set it to blank so it can't be used */
+ conn->peer_cn[0] = '\0';
+ }
+ else
+ {
+ /*
+ * Reject embedded NULLs in certificate common name to prevent attacks like
+ * CVE-2009-4034.
+ */
+ if (r != strlen(conn->peer_cn))
+ {
+ printfPQExpBuffer(&conn->errorMessage,
+ libpq_gettext("SSL certificate's common name contains embedded null\n"));
+ close_SSL(conn);
+ return PGRES_POLLING_FAILED;
+ }
+ }
/* verify that the common name resolves to peer */