Hello community,

here is the log from the commit of package apache2-mod_nss for openSUSE:Factory 
checked in at 2015-03-09 10:09:27
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/apache2-mod_nss (Old)
 and      /work/SRC/openSUSE:Factory/.apache2-mod_nss.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "apache2-mod_nss"

Changes:
--------
--- /work/SRC/openSUSE:Factory/apache2-mod_nss/apache2-mod_nss.changes  
2014-11-06 16:50:56.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.apache2-mod_nss.new/apache2-mod_nss.changes     
2015-03-09 10:09:39.000000000 +0100
@@ -1,0 +2,8 @@
+Tue Mar  3 10:25:27 UTC 2015 - [email protected]
+
+- add mod_nss-SNI_support.patch that brings Server Name Indication
+  support that allows to have multiple HTTPS websites with multiple
+  certificates on the same IP address and port.
+  [fate#318331], [bnc#897712]
+
+-------------------------------------------------------------------

New:
----
  mod_nss-SNI_support.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ apache2-mod_nss.spec ++++++
--- /var/tmp/diff_new_pack.xkC1d8/_old  2015-03-09 10:09:40.000000000 +0100
+++ /var/tmp/diff_new_pack.xkC1d8/_new  2015-03-09 10:09:40.000000000 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package apache2-mod_nss
 #
-# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -74,6 +74,8 @@
 Patch24:        mod_nss-compare_subject_CN_and_VS_hostname.patch
 # PATCH-FIX-UPSTREAM bnc#902068 [email protected] -- small fixes for TLS-v1.2
 Patch25:        mod_nss-add_support_for_enabling_TLS_v1.2.patch
+# PATCH-FEATURE-UPSTREAM bnc#897712 fate#318331 [email protected] -- add 
Server Name Indication support
+Patch26:        mod_nss-SNI_support.patch
 
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 %define    apxs /usr/sbin/apxs2
@@ -115,6 +117,7 @@
 %patch23 -p0 -b .mod_nss-bnc863518-reopen_dev_tty.rpmpatch
 %patch24 -p1 -b .mod_nss-compare_subject_CN_and_VS_hostname.rpmpatch
 %patch25 -p1 -b .mod_nss-add_support_for_enabling_TLS_v1.2.rpmpatch
+%patch26 -p1 -b .mod_nss-SNI_support.rpmpatch
 
 # keep this last, otherwise we get fuzzyness from above
 %if 0%{?suse_version} >= 1300

++++++ mod_nss-SNI_support.patch ++++++
>From 07405e4dbd1e2df6583bb571a6230da78788c19b Mon Sep 17 00:00:00 2001
From: standa <[email protected]>
Date: Thu, 26 Feb 2015 15:23:50 +0100
Subject: [PATCH] SNI check with NameVirtualHosts

---
 docs/mod_nss.html   | 10 ++++++
 mod_nss.c           |  3 ++
 mod_nss.h           | 18 ++++++++++
 nss_engine_config.c | 11 +++++++
 nss_engine_init.c   | 95 ++++++++++++++++++++++++++++++++++++++++++++++++-----
 nss_engine_kernel.c | 51 ++++++++++++++++++++++++++++
 nss_util.c          | 19 +++++++++++
 7 files changed, 199 insertions(+), 8 deletions(-)

Index: mod_nss-1.0.8/docs/mod_nss.html
===================================================================
--- mod_nss-1.0.8.orig/docs/mod_nss.html
+++ mod_nss-1.0.8/docs/mod_nss.html
@@ -1079,6 +1079,16 @@ components of the client certificate, th
 <br>
 <code>NSSRequire<br>
 </code><br>
+<big><big>NSSSNI</big></big><br>
+<br>
+Enables or disables Server Name Identification(SNI) extension check for
+SSL. This option is turn on by default. SNI vhost_id gets from HTTPS header.
+<br>
+<br>
+<span style="font-weight: bold;">Example</span><br>
+<br>
+<code>NSSSNI off</code><br>
+<br>
 <big><big>NSSProxyEngine</big></big><br>
 <br>
 Enables or disables mod_nss HTTPS support for mod_proxy.<br>
Index: mod_nss-1.0.8/mod_nss.c
===================================================================
--- mod_nss-1.0.8.orig/mod_nss.c
+++ mod_nss-1.0.8/mod_nss.c
@@ -85,6 +85,9 @@ static const command_rec nss_config_cmds
     SSL_CMD_SRV(FIPS, FLAG,
                 "FIPS 140-1 mode "
                 "(`on', `off')")
+    SSL_CMD_SRV(SNI, FLAG,
+                "SNI"
+                "(`on', `off')")
     SSL_CMD_ALL(CipherSuite, TAKE1,
                 "Comma-delimited list of permitted SSL Ciphers, + to enable, - 
to disable "
                 "(`[+-]XXX,...,[+-]XXX' - see manual)")
Index: mod_nss-1.0.8/mod_nss.h
===================================================================
--- mod_nss-1.0.8.orig/mod_nss.h
+++ mod_nss-1.0.8/mod_nss.h
@@ -308,6 +308,7 @@ struct SSLSrvConfigRec {
     const char      *ocsp_name;
     BOOL             ocsp;
     BOOL             enabled;
+    BOOL             sni;
     BOOL             proxy_enabled;
     const char      *vhost_id;
     int              vhost_id_len;
@@ -343,6 +344,20 @@ typedef struct
     PRInt32 version; /* protocol version valid for this cipher */
 } cipher_properties;
 
+typedef struct {
+  const char *vhost_id[70];
+  const char *nick[30];
+} vhostNick[500];
+
+typedef struct {
+  enum {
+        PW_NONE = 0,
+       PW_FROMFILE = 1,
+       PW_PLAINTEXT = 2,
+       PW_EXTERNAL = 3
+      } source;
+      char *data;
+} secuPWData;
 /* Compatibility between Apache 2.0.x and 2.2.x. The numeric version of
  * the version first appeared in Apache 2.0.56-dev. I picked 2.0.55 as it
  * is the last version without this define. This is used for more than just
@@ -384,6 +399,7 @@ void *nss_config_perdir_merge(apr_pool_t
 void *nss_config_server_create(apr_pool_t *p, server_rec *s);
 void *nss_config_server_merge(apr_pool_t *p, void *basev, void *addv);
 const char *nss_cmd_NSSFIPS(cmd_parms *, void *, int);
+const char *nss_cmd_NSSSNI(cmd_parms *, void *, int);
 const char *nss_cmd_NSSEngine(cmd_parms *, void *, int);
 const char *nss_cmd_NSSOCSP(cmd_parms *, void *, int);
 const char *nss_cmd_NSSOCSPDefaultResponder(cmd_parms *, void *, int);
@@ -471,6 +487,8 @@ apr_file_t  *nss_util_ppopen(server_rec
 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 *);
+char *getSECItemData(char *data, int len);
+char *getSplitURL(char *url);
 /* 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);
Index: mod_nss-1.0.8/nss_engine_config.c
===================================================================
--- mod_nss-1.0.8.orig/nss_engine_config.c
+++ mod_nss-1.0.8/nss_engine_config.c
@@ -135,6 +135,7 @@ static SSLSrvConfigRec *nss_config_serve
     sc->ocsp_name                   = NULL;
     sc->fips                        = UNSET;
     sc->enabled                     = UNSET;
+    sc->sni                         = TRUE;
     sc->proxy_enabled               = UNSET;
     sc->vhost_id                    = NULL;  /* set during module init */
     sc->vhost_id_len                = 0;     /* set during module init */
@@ -214,6 +215,7 @@ void *nss_config_server_merge(apr_pool_t
     cfgMerge(ocsp_name, NULL);
     cfgMergeBool(fips);
     cfgMergeBool(enabled);
+    cfgMergeBool(sni);
     cfgMergeBool(proxy_enabled);
     cfgMergeBool(proxy_ssl_check_peer_cn);
 
@@ -320,6 +322,15 @@ const char *nss_cmd_NSSFIPS(cmd_parms *c
  
     return NULL;
 }
+
+const char *nss_cmd_NSSSNI(cmd_parms *cmd, void *dcfg, int flag)
+{
+    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+
+    sc->sni = flag ? TRUE : FALSE;
+
+    return NULL;
+}
 
 const char *nss_cmd_NSSOCSP(cmd_parms *cmd, void *dcfg, int flag)
 {
Index: mod_nss-1.0.8/nss_engine_init.c
===================================================================
--- mod_nss-1.0.8.orig/nss_engine_init.c
+++ mod_nss-1.0.8/nss_engine_init.c
@@ -28,12 +28,17 @@ static SECStatus ownHandshakeCallback(PR
 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);
+PRInt32 ownSSLSNISocketConfig(PRFileDesc *fd, const SECItem *sniNameArr,
+                             PRUint32 sniNameArrSize, void *arg);
 
 /*
  * Global variables defined in this file.
  */
 char* INTERNAL_TOKEN_NAME = "internal                         ";
 
+vhostNick vhostNickSNI;
+int vhostNickSize = 0;
+
 cipher_properties ciphers_def[ciphernum] =
 {
     /* SSL2 cipher suites */
@@ -382,6 +387,11 @@ int nss_init_Module(apr_pool_t *p, apr_p
         sc->vhost_id = nss_util_vhostid(p, s);
         sc->vhost_id_len = strlen(sc->vhost_id);
 
+       if (sc->server->nickname != NULL && sc->vhost_id != NULL) {
+         strcpy(vhostNickSNI[vhostNickSize].vhost_id, sc->vhost_id);
+         strcpy(vhostNickSNI[vhostNickSize].nick, sc->server->nickname);
+         vhostNickSize++;
+       }
         /* Fix up stuff that may not have been set */
         if (sc->fips == UNSET) {
             sc->fips = FALSE;
@@ -534,7 +544,7 @@ int nss_init_Module(apr_pool_t *p, apr_p
         ap_log_error(APLOG_MARK, APLOG_INFO, 0, base_server,
                      "Init: Initializing (virtual) servers for SSL");
 
-        CERTCertList* clist = PK11_ListCerts(PK11CertListUser, NULL);
+        CERTCertList* clist = PK11_ListCerts(PK11CertListUserUnique, NULL);
 
         for (s = base_server; s; s = s->next) {
             sc = mySrvConfig(s);
@@ -547,7 +557,7 @@ int nss_init_Module(apr_pool_t *p, apr_p
             /*
              * Read the server certificate and key
              */
-            nss_init_ConfigureServer(s, p, ptemp, sc, clist);
+           nss_init_ConfigureServer(s, p, ptemp, sc, clist);
         }
 
         if (clist) {
@@ -1233,13 +1243,21 @@ static void nss_init_certificate(server_
             break;
     }
 
-    secstatus = SSL_ConfigSecureServer(model, *servercert, *serverkey, 
*KEAtype);
+   secstatus = SSL_ConfigSecureServer(model, *servercert, *serverkey, 
*KEAtype);
     if (secstatus != SECSuccess) {
         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
             "SSL error configuring server: '%s'", nickname);
         nss_log_nss_error(APLOG_MARK, APLOG_ERR, s);
         nss_die();
-    }
+       }
+
+    /* SNI */
+    if (SSL_SNISocketConfigHook(model, (SSLSNISocketConfig) 
ownSSLSNISocketConfig, (void*) s) != SECSuccess) {
+           ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+               "SSL_SNISocketConfigHook failed");
+           nss_log_nss_error(APLOG_MARK, APLOG_ERR, s);
+           nss_die();
+           }
 }
 
 
@@ -1308,6 +1326,7 @@ static void nss_init_server_certs(server
         nss_log_nss_error(APLOG_MARK, APLOG_ERR, s);
         nss_die();
     }
+
 }
 
 static void nss_init_proxy_ctx(server_rec *s,
@@ -1374,7 +1393,6 @@ void nss_init_Child(apr_pool_t *p, serve
         /* If any servers have SSL, we want sslenabled set so we
          * can perform further initialization
          */
-
         if (sc->enabled == UNSET) {
             sc->enabled = FALSE;
         }
@@ -1404,11 +1422,12 @@ void nss_init_Child(apr_pool_t *p, serve
     nss_init_SSLLibrary(base_server);
 
     /* Configure all virtual servers */
-    CERTCertList* clist = PK11_ListCerts(PK11CertListUser, NULL);
+    CERTCertList* clist = PK11_ListCerts(PK11CertListUserUnique, NULL);
     for (s = base_server; s; s = s->next) {
         sc = mySrvConfig(s);
-        if (sc->server->servercert == NULL && NSS_IsInitialized())
-            nss_init_ConfigureServer(s, p, mc->ptemp, sc, clist);
+        if (sc->server->servercert == NULL && NSS_IsInitialized()) {
+          nss_init_ConfigureServer(s, p, mc->ptemp, sc, clist);
+       }
     }
     if (clist) {
         CERT_DestroyCertList(clist);
@@ -1741,3 +1760,63 @@ int nss_parse_ciphers(server_rec *s, cha
 
     return 0;
 }
+
+PRInt32 ownSSLSNISocketConfig(PRFileDesc *fd, const SECItem *sniNameArr,
+           PRUint32 sniNameArrSize, void *arg)
+{
+    server_rec  *s = (server_rec *)arg;
+
+    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+                "start function ownSSLSNISocketConfig for SNI");
+
+    secuPWData *pwdata;
+    CERTCertificate *    cert = NULL;
+    SECKEYPrivateKey *   privKey = NULL;
+    char *nickName = NULL;
+    char *vhost = NULL;
+    int i;
+
+    PORT_Assert(fd && sniNameArr);
+    if (!fd || !sniNameArr) {
+       return SSL_SNI_SEND_ALERT;
+    }
+    vhost = getSECItemData((char *) sniNameArr->data, sniNameArr->len);
+
+    for(i = 0; i<vhostNickSize; i++) {
+      if (strcmp(getSplitURL(vhostNickSNI[i].vhost_id), vhost) == 0) {
+       nickName = vhostNickSNI[i].nick;
+       pwdata = SSL_RevealPinArg(fd);
+
+        /* if pwdata is NULL, then we would not get the key and
+         * return an error status. */
+       cert = PK11_FindCertFromNickname(nickName, &pwdata);
+       if (cert == NULL) {
+         goto loser; /* Send alert */
+       }
+       privKey = PK11_FindKeyByAnyCert(cert, &pwdata);
+       if (privKey == NULL) {
+         goto loser; /* Send alert */
+       }
+        SSLKEAType  certKEA = NSS_FindCertKEAType(cert);
+       ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+                    "start configure vhost:%s", vhostNickSNI[i].vhost_id);
+       if (SSL_ConfigSecureServer(fd, cert, privKey, certKEA) != SECSuccess) {
+         goto loser; /* Send alert */
+       }
+       ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+                    "successfull setting vhost with nick:%s", 
vhostNickSNI[i].nick);
+       SECKEY_DestroyPrivateKey(privKey);
+       CERT_DestroyCertificate(cert);
+       return 0;
+      }
+    }
+loser:
+    if (privKey) {
+        SECKEY_DestroyPrivateKey(privKey);
+    }
+    if (cert) {
+        CERT_DestroyCertificate(cert);
+    }
+    return SSL_SNI_SEND_ALERT;
+
+}
Index: mod_nss-1.0.8/nss_engine_kernel.c
===================================================================
--- mod_nss-1.0.8.orig/nss_engine_kernel.c
+++ mod_nss-1.0.8/nss_engine_kernel.c
@@ -71,6 +71,57 @@ int nss_hook_ReadReq(request_rec *r)
     }
 
     /*
+     * SNI check is default on. In same cases you switch of by NSSSNI off
+     * sc->sni parameter gets vhost from HTTPS header
+     */
+    SSLSrvConfigRec *sc = mySrvConfig(r->server);
+
+    SECItem *hostInfo = NULL;
+    hostInfo = SSL_GetNegotiatedHostInfo(ssl);
+    if (hostInfo != NULL && sc->sni) {
+      if (ap_is_initial_req(r) && (hostInfo->len != 0)) {
+        char *servername = NULL;
+       char *host, *scope_id;
+       apr_port_t port;
+       apr_status_t rv;
+
+       ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+                "SNI hostInfo  hostInfo->data:%s and hostInfo->len:%d"
+                    , hostInfo->data, hostInfo->len);
+
+       servername = getSECItemData((char *) hostInfo->data, hostInfo->len);
+
+       ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+                "SNI hostInfo  servername:%s, lenght:%d"
+                    , servername, (unsigned)strlen(servername));
+
+         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);
+
+           SECITEM_FreeItem(hostInfo, PR_TRUE);
+           servername = NULL;
+           return HTTP_BAD_REQUEST;
+         } else {
+           SECITEM_FreeItem(hostInfo, PR_TRUE);
+           servername = NULL;
+         }
+      }
+    }
+    /*
      * Log information about incoming HTTPS requests
      */
     if (r->server->loglevel >= APLOG_INFO && ap_is_initial_req(r)) {
Index: mod_nss-1.0.8/nss_util.c
===================================================================
--- mod_nss-1.0.8.orig/nss_util.c
+++ mod_nss-1.0.8/nss_util.c
@@ -100,3 +100,22 @@ char *nss_util_readfilter(server_rec *s,
 
     return buf;
 }
+
+char *getSECItemData(char *data, int len) {
+
+    data[len]='\0';
+
+    return data;
+}
+
+char *getSplitURL(char *url) {
+
+    int iter = 0;
+
+    while(url[iter] != '\0' && url[iter] != ':'){
+      url[iter++];
+    }
+    url[iter]='\0';
+
+    return url;
+}
-- 
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to