From b2f4eaf48301259a7c6626150204e43c411b01214f2137c5a4525b4d81a2e077 Mon Sep 17 00:00:00 2001 From: Wolfgang Rosenauer Date: Thu, 30 Oct 2014 11:16:30 +0000 Subject: [PATCH] Accepting request 258819 from home:kstreitova:branches:mozilla:Factory - bnc#897712: added mod_nss-compare_subject_CN_and_VS_hostname.patch that compare CN and VS hostname (use NSS library). Removed following patches: * mod_nss-SNI-checks.patch * mod_nss-SNI-callback.patch OBS-URL: https://build.opensuse.org/request/show/258819 OBS-URL: https://build.opensuse.org/package/show/mozilla:Factory/apache2-mod_nss?expand=0&rev=14 --- apache2-mod_nss.changes | 9 + apache2-mod_nss.spec | 8 +- mod_nss-SNI-callback.patch | 241 ------------------ mod_nss-SNI-checks.patch | 155 ----------- ...s-compare_subject_CN_and_VS_hostname.patch | 42 +++ 5 files changed, 55 insertions(+), 400 deletions(-) delete mode 100644 mod_nss-SNI-callback.patch delete mode 100644 mod_nss-SNI-checks.patch create mode 100644 mod_nss-compare_subject_CN_and_VS_hostname.patch diff --git a/apache2-mod_nss.changes b/apache2-mod_nss.changes index ed15adc..18ea48e 100644 --- a/apache2-mod_nss.changes +++ b/apache2-mod_nss.changes @@ -1,3 +1,12 @@ +------------------------------------------------------------------- +Wed Oct 29 14:59:06 UTC 2014 - kstreitova@suse.com + +- bnc#897712: added mod_nss-compare_subject_CN_and_VS_hostname.patch + that compare CN and VS hostname (use NSS library). Removed + following patches: + * mod_nss-SNI-checks.patch + * mod_nss-SNI-callback.patch + ------------------------------------------------------------------- Thu Aug 21 07:50:57 UTC 2014 - meissner@suse.com diff --git a/apache2-mod_nss.spec b/apache2-mod_nss.spec index adfb60a..4a69190 100644 --- a/apache2-mod_nss.spec +++ b/apache2-mod_nss.spec @@ -69,9 +69,10 @@ Patch17: mod_nss-overlapping_memcpy.patch Patch18: mod_nss-CVE-2013-4566-NSSVerifyClient.diff Patch19: mod_nss-cipherlist_update_for_tls12.diff Patch20: mod_nss-cipherlist_update_for_tls12-doc.diff -Patch21: mod_nss-SNI-callback.patch -Patch22: mod_nss-SNI-checks.patch Patch23: mod_nss-bnc863518-reopen_dev_tty.diff +# PATCH-FIX-UPSTREAM bnc#897712 kstreitova@suse.com -- check for the misconfiguration of certificate's CN and virtual name +Patch24: mod_nss-compare_subject_CN_and_VS_hostname.patch + BuildRoot: %{_tmppath}/%{name}-%{version}-build %define apxs /usr/sbin/apxs2 %define apache apache2 @@ -109,9 +110,8 @@ security library. %patch18 -p0 -b .CVE-2013-4566.rpmpatch %patch19 -p0 -b .ciphers.rpmpatch %patch20 -p0 -b .ciphers.doc.rpmpatch -%patch21 -p0 -b .mod_nss-SNI-callback.rpmpatch -%patch22 -p0 -b .mod_nss-SNI-checks.patch.rpmpatch %patch23 -p0 -b .mod_nss-bnc863518-reopen_dev_tty.rpmpatch +%patch24 -p1 -b .mod_nss-compare_subject_CN_and_VS_hostname.rpmpatch # keep this last, otherwise we get fuzzyness from above %if 0%{?suse_version} >= 1300 diff --git a/mod_nss-SNI-callback.patch b/mod_nss-SNI-callback.patch deleted file mode 100644 index e009906..0000000 --- a/mod_nss-SNI-callback.patch +++ /dev/null @@ -1,241 +0,0 @@ -diff -rNU 30 ../mod_nss-1.0.8-o/mod_nss.h ./mod_nss.h ---- ../mod_nss-1.0.8-o/mod_nss.h 2014-06-23 12:23:17.000000000 +0200 -+++ ./mod_nss.h 2014-06-25 15:43:14.000000000 +0200 -@@ -459,31 +459,37 @@ - APR_DECLARE_OPTIONAL_FN(int, nss_engine_disable, (conn_rec *)); - - /* I/O */ - PRFileDesc * nss_io_new_fd(); - int nss_io_layer_init(); - void nss_io_filter_init(conn_rec *c, PRFileDesc *ssl); - void nss_io_filter_register(apr_pool_t *p); - - /* Utility Functions */ - char *nss_util_vhostid(apr_pool_t *, server_rec *); - apr_file_t *nss_util_ppopen(server_rec *, apr_pool_t *, const char *, - const char * const *); - void nss_util_ppclose(server_rec *, apr_pool_t *, apr_file_t *); - char *nss_util_readfilter(server_rec *, apr_pool_t *, const char *, - const char * const *); - /* ssl_io_buffer_fill fills the setaside buffering of the HTTP request - * to allow an SSL renegotiation to take place. */ - int nss_io_buffer_fill(request_rec *r); - - int nss_rand_seed(server_rec *s, apr_pool_t *p, ssl_rsctx_t nCtx, char *prefix); - - /* Pass Phrase Handling */ - SECStatus nss_Init_Tokens(server_rec *s); - - /* Logging */ - void nss_log_nss_error(const char *file, int line, int level, server_rec *s); - void nss_die(void); - - /* NSS callback */ - SECStatus nss_AuthCertificate(void *arg, PRFileDesc *socket, PRBool checksig, PRBool isServer); -+ -+ -+#define SNIMAXNAMELEN 100 -+PRInt32 mod_nss_SSLSNISocketConfig(PRFileDesc *, const SECItem *, PRUint32, void *); -+ -+ - #endif /* __MOD_NSS_H__ */ -diff -rNU 30 ../mod_nss-1.0.8-o/nss_engine_init.c ./nss_engine_init.c ---- ../mod_nss-1.0.8-o/nss_engine_init.c 2014-06-23 12:23:17.000000000 +0200 -+++ ./nss_engine_init.c 2014-06-25 18:33:19.000000000 +0200 -@@ -5,60 +5,62 @@ - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - #include "mod_nss.h" - #include "apr_thread_proc.h" - #include "ap_mpm.h" - #include "secmod.h" - #include "sslerr.h" - #include "pk11func.h" - #include "ocsp.h" - #include "keyhi.h" - #include "cert.h" - - static SECStatus ownBadCertHandler(void *arg, PRFileDesc * socket); - static SECStatus ownHandshakeCallback(PRFileDesc * socket, void *arg); - static SECStatus NSSHandshakeCallback(PRFileDesc *socket, void *arg); - static CERTCertificate* FindServerCertFromNickname(const char* name, const CERTCertList* clist); - SECStatus nss_AuthCertificate(void *arg, PRFileDesc *socket, PRBool checksig, PRBool isServer); - - /* - * Global variables defined in this file. - */ -+void * sni_callback_arg; -+ - char* INTERNAL_TOKEN_NAME = "internal "; - - cipher_properties ciphers_def[ciphernum] = - { - /* SSL2 cipher suites */ - {"rc4", SSL_EN_RC4_128_WITH_MD5, 0, SSL2}, - {"rc4export", SSL_EN_RC4_128_EXPORT40_WITH_MD5, 0, SSL2}, - {"rc2", SSL_EN_RC2_128_CBC_WITH_MD5, 0, SSL2}, - {"rc2export", SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5, 0, SSL2}, - {"des", SSL_EN_DES_64_CBC_WITH_MD5, 0, SSL2}, - {"desede3", SSL_EN_DES_192_EDE3_CBC_WITH_MD5, 0, SSL2}, - /* SSL3/TLS cipher suites */ - {"rsa_rc4_128_md5", SSL_RSA_WITH_RC4_128_MD5, 0, SSL3 | TLS}, - {"rsa_rc4_128_sha", SSL_RSA_WITH_RC4_128_SHA, 0, SSL3 | TLS}, - {"rsa_3des_sha", SSL_RSA_WITH_3DES_EDE_CBC_SHA, 0, SSL3 | TLS}, - {"rsa_des_sha", SSL_RSA_WITH_DES_CBC_SHA, 0, SSL3 | TLS}, - {"rsa_rc4_40_md5", SSL_RSA_EXPORT_WITH_RC4_40_MD5, 0, SSL3 | TLS}, - {"rsa_rc2_40_md5", SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, 0, SSL3 | TLS}, - {"rsa_null_md5", SSL_RSA_WITH_NULL_MD5, 0, SSL3 | TLS}, - {"rsa_null_sha", SSL_RSA_WITH_NULL_SHA, 0, SSL3 | TLS}, - {"fips_3des_sha", SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, 0, SSL3 | TLS}, - {"fips_des_sha", SSL_RSA_FIPS_WITH_DES_CBC_SHA, 0, SSL3 | TLS}, - {"fortezza", SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, 1, SSL3 | TLS}, - {"fortezza_rc4_128_sha", SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, 1, SSL3 | TLS}, - {"fortezza_null", SSL_FORTEZZA_DMS_WITH_NULL_SHA, 1, SSL3 | TLS}, - /* TLS 1.0: Exportable 56-bit Cipher Suites. */ - {"rsa_des_56_sha", TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA, 0, SSL3 | TLS}, - {"rsa_rc4_56_sha", TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, 0, SSL3 | TLS}, - /* AES ciphers.*/ - {"rsa_aes_128_sha", TLS_RSA_WITH_AES_128_CBC_SHA, 0, SSL3 | TLS}, -@@ -850,60 +852,78 @@ - - static void nss_init_ctx_callbacks(server_rec *s, - apr_pool_t *p, - apr_pool_t *ptemp, - modnss_ctx_t *mctx) - { - if (SSL_AuthCertificateHook(mctx->model, nss_AuthCertificate, (void *)CERT_GetDefaultCertDB()) != SECSuccess) { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, - "SSL_AuthCertificateHook failed."); - nss_log_nss_error(APLOG_MARK, APLOG_ERR, s); - nss_die(); - } - if (SSL_BadCertHook(mctx->model, (SSLBadCertHandler) ownBadCertHandler, NULL) != SECSuccess) { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, - "SSL_BadCertHook failed"); - nss_log_nss_error(APLOG_MARK, APLOG_ERR, s); - nss_die(); - } - if (SSL_HandshakeCallback(mctx->model, (SSLHandshakeCallback) ownHandshakeCallback, NULL) != SECSuccess) { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, - "SSL_HandshakeCallback failed"); - nss_log_nss_error(APLOG_MARK, APLOG_ERR, s); - nss_die(); - } - if (SSL_GetClientAuthDataHook(mctx->model, NSS_GetClientAuthData, (void *)mctx->nickname) != SECSuccess) { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, - "SSL_GetClientAuthDataHook failed"); - nss_log_nss_error(APLOG_MARK, APLOG_ERR, s); - nss_die(); - } -+ -+ sni_callback_arg = apr_pcalloc(p, SNIMAXNAMELEN + 1); -+ if(sni_callback_arg) { -+ if(SSL_SNISocketConfigHook(mctx->model, mod_nss_SSLSNISocketConfig, -+ sni_callback_arg)) { -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -+ "SSL_SNISocketConfigHook failed"); -+ nss_log_nss_error(APLOG_MARK, APLOG_ERR, s); -+ nss_die(); -+ } -+ } else { -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -+ "apr_palloc returned NULL for sni_callback_arg"); -+ nss_log_nss_error(APLOG_MARK, APLOG_ERR, s); -+ nss_die(); -+ } -+ -+ - } - - static void nss_init_ctx_verify(server_rec *s, - apr_pool_t *p, - apr_pool_t *ptemp, - modnss_ctx_t *mctx) - { - if (mctx->auth.verify_mode == SSL_CVERIFY_REQUIRE) { - SSL_OptionSet(mctx->model, SSL_REQUEST_CERTIFICATE, PR_TRUE); - SSL_OptionSet(mctx->model, SSL_REQUIRE_CERTIFICATE, SSL_REQUIRE_ALWAYS); - } else if (mctx->auth.verify_mode == SSL_CVERIFY_OPTIONAL) { - SSL_OptionSet(mctx->model, SSL_REQUEST_CERTIFICATE, PR_TRUE); - SSL_OptionSet(mctx->model, SSL_REQUIRE_CERTIFICATE, SSL_REQUIRE_NEVER); - } else { - SSL_OptionSet(mctx->model, SSL_REQUEST_CERTIFICATE, PR_FALSE); - SSL_OptionSet(mctx->model, SSL_REQUIRE_CERTIFICATE, SSL_REQUIRE_NEVER); - } - } - - static int countciphers(PRBool cipher_state[ciphernum], int version) { - int ciphercount = 0; - int i; - - for (i = 0; i < ciphernum; i++) - { - if ((cipher_state[i] == PR_TRUE) && - (ciphers_def[i].version & version)) { - ciphercount++; - } - } -@@ -1702,30 +1722,54 @@ - return -1; - } - - if ((ciphers = strchr(cipher, ','))) { - *ciphers++ = '\0'; - } - - found = PR_FALSE; - - for (i = 0; i < ciphernum; i++) - { - if (!strcasecmp(cipher, ciphers_def[i].name)) { - cipher_list[i] = active; - found = PR_TRUE; - break; - } - } - - if (found == PR_FALSE) { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, - "Unknown cipher %s", cipher); - } - - if (ciphers) { - cipher = ciphers; - } - } - - return 0; - } -+ -+ -+ -+ -+PRInt32 mod_nss_SSLSNISocketConfig(PRFileDesc *fd, const SECItem *sniNameArr, -+ PRUint32 sniNameArrSize, void *arg) -+{ -+ /* -+ arg is apr pool memory from apr_palloc(), SNIMAXNAMELEN+1 bytes long. -+ initialized zero. -+ */ -+ -+ char * retptr = NULL; -+ const SECItem *mysni = sniNameArr; -+ -+ if(mysni) { -+ retptr = apr_cpystrn(arg, mysni[0].data, -+ ( mysni[0].len + 1 < SNIMAXNAMELEN ) ? mysni[0].len + 1 : SNIMAXNAMELEN ); -+ return 0; -+ } else { -+ /* no SNI provided... Well. */ -+ return SSL_SNI_CURRENT_CONFIG_IS_USED; -+ } -+} diff --git a/mod_nss-SNI-checks.patch b/mod_nss-SNI-checks.patch deleted file mode 100644 index d879292..0000000 --- a/mod_nss-SNI-checks.patch +++ /dev/null @@ -1,155 +0,0 @@ -diff -rNU 30 ../mod_nss-1.0.8-o/nss_engine_kernel.c ./nss_engine_kernel.c ---- ../mod_nss-1.0.8-o/nss_engine_kernel.c 2014-06-25 19:13:26.000000000 +0200 -+++ ./nss_engine_kernel.c 2014-06-27 13:57:40.000000000 +0200 -@@ -1,102 +1,151 @@ - /* Copyright 2001-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - #include "mod_nss.h" - #include "secerr.h" - - static void HandshakeDone(PRFileDesc *fd, void *doneflag); - -+extern void * sni_callback_arg; -+ - /* - * Post Read Request Handler - */ - int nss_hook_ReadReq(request_rec *r) - { - SSLConnRec *sslconn = myConnConfig(r->connection); - PRFileDesc *ssl = sslconn ? sslconn->ssl : NULL; - - if (!sslconn) { - return DECLINED; - } - - if (sslconn->non_nss_request) { - const char *errmsg; - char *thisurl; - char *thisport = ""; - int port = ap_get_server_port(r); - - if (!ap_is_default_port(port, r)) { - thisport = apr_psprintf(r->pool, ":%u", port); - } - - thisurl = ap_escape_html(r->pool, - apr_psprintf(r->pool, "https://%s%s/", - ap_get_server_name(r), - thisport)); - - errmsg = apr_psprintf(r->pool, - "Reason: You're speaking plain HTTP " - "to an SSL-enabled server port.
\n" - "Instead use the HTTPS scheme to access " - "this URL, please.
\n" - "
Hint: " - "%s
", - thisurl, thisurl); - - apr_table_setn(r->notes, "error-notes", errmsg); - /* Now that we have caught this error, forget it. we are done - * with using SSL on this request. - */ - sslconn->non_nss_request = 0; - - - return HTTP_BAD_REQUEST; - } - - /* Get the SSL connection structure and perform the - * delayed interlinking from SSL back to request_rec - */ - if (!ssl) { - return DECLINED; - } - -+ -+ /* -+ * SNI. -+ * -+ * global pool-allocated char * sni_callback_arg contains SNI name -+ * coming from mod_nss_SSLSNISocketConfig() callback by nss as soon as -+ * SNI extension information was supplied by the client. -+ * -+ * With the SNI provided servername, this is now widely analogous -+ * to mod_ssl; the same checks apply. -+ * -+ */ -+ -+ -+ -+ char *servername; -+ servername = (char *) sni_callback_arg; -+ -+ if(servername[0] != '\0') { -+ char *host, *scope_id; -+ apr_port_t port; -+ apr_status_t rv; -+ -+ if (!r->hostname) { -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, -+ "Hostname %s provided via SNI, but no hostname" -+ " provided in HTTP request", servername); -+ return HTTP_BAD_REQUEST; -+ } -+ -+ rv = apr_parse_addr_port(&host, &scope_id, &port, r->hostname, r->pool); -+ if (rv != APR_SUCCESS || scope_id) { -+ return HTTP_BAD_REQUEST; -+ } -+ -+ if (strcasecmp(host, servername)) { -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, -+ "Hostname %s provided via SNI and hostname %s provided" -+ " via HTTP are different", servername, host); -+ return HTTP_BAD_REQUEST; -+ } -+ -+ -+ } -+ -+ -+ - /* - * Log information about incoming HTTPS requests - */ - if (r->server->loglevel >= APLOG_INFO && ap_is_initial_req(r)) { - ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, - "%s HTTPS request received for child %ld (server %s)", - (r->connection->keepalives <= 0 ? - "Initial (No.1)" : - apr_psprintf(r->pool, "Subsequent (No.%d)", - r->connection->keepalives+1)), - r->connection->id, - nss_util_vhostid(r->pool, r->server)); - } - - if (sslconn->client_cert != NULL) - CERT_DestroyCertificate(sslconn->client_cert); - sslconn->client_cert = SSL_PeerCertificate(ssl); - sslconn->client_dn = NULL; - - return DECLINED; - } - - /* - * Access Handler - */ - int nss_hook_Access(request_rec *r) - { - SSLDirConfigRec *dc = myDirConfig(r); - SSLSrvConfigRec *sc = mySrvConfig(r->server); - SSLConnRec *sslconn = myConnConfig(r->connection); diff --git a/mod_nss-compare_subject_CN_and_VS_hostname.patch b/mod_nss-compare_subject_CN_and_VS_hostname.patch new file mode 100644 index 0000000..4bfb530 --- /dev/null +++ b/mod_nss-compare_subject_CN_and_VS_hostname.patch @@ -0,0 +1,42 @@ +From c027af16af4975bbb0aa7bc509ea059944028481 Mon Sep 17 00:00:00 2001 +From: standa +Date: Wed, 22 Oct 2014 16:14:29 +0200 +Subject: [PATCH] Compare subject CN and VS hostname during server start up + +--- + nss_engine_init.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +diff --git a/nss_engine_init.c b/nss_engine_init.c +index d74f002..2569c8d 100644 +--- a/nss_engine_init.c ++++ b/nss_engine_init.c +@@ -1179,12 +1179,20 @@ static void nss_init_certificate(server_rec *s, const char *nickname, + + *KEAtype = NSS_FindCertKEAType(*servercert); + ++ /* Subject/hostname check */ ++ secstatus = CERT_VerifyCertName(*servercert, s->server_hostname); ++ if (secstatus != SECSuccess) { ++ char *cert_dns = CERT_GetCommonName(&(*servercert)->subject); ++ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, ++ "Misconfiguration of certificate's CN and virtual name." ++ " The certificate CN has %s. We expected %s as virtual" ++ " name.", cert_dns, s->server_hostname); ++ PORT_Free(cert_dns); ++ } ++ + /* +- * Check for certs that are expired or not yet valid and WARN about it +- * no need to refuse working - the client gets a warning, but can work +- * with the server we could also verify if the certificate is made out +- * for the correct hostname but that would require a reverse DNS lookup +- * for every virtual server - too expensive? ++ * Check for certs that are expired or not yet valid and WARN about it. ++ * No need to refuse working - the client gets a warning. + */ + + certtimestatus = CERT_CheckCertValidTimes(*servercert, PR_Now(), PR_FALSE); +-- +1.9.3 +