diff --git a/src/backend/libpq/be-secure.c b/src/backend/libpq/be-secure.c index ef2db7f174..9456b254b4 100644 --- a/src/backend/libpq/be-secure.c +++ b/src/backend/libpq/be-secure.c @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/libpq/be-secure.c,v 1.92 2009/06/11 14:48:58 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/libpq/be-secure.c,v 1.92.2.1 2009/12/09 06:37:29 mha Exp $ * * Since the server static private key ($DataDir/server.key) * will normally be stored unencrypted so that the database @@ -953,9 +953,29 @@ aloop: 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 c6e6414787..4a12bd1b1d 100644 --- a/src/interfaces/libpq/fe-secure.c +++ b/src/interfaces/libpq/fe-secure.c @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.127 2009/06/23 18:13:23 mha Exp $ + * $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.127.2.1 2009/12/09 06:37:29 mha Exp $ * * NOTES * @@ -1198,9 +1198,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; + } + } if (!verify_peer_name_matches_certificate(conn)) {