From b5d1505fc81a33aa10d013efd247d00f631fc681 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Tue, 28 Oct 2014 17:41:22 -0400 Subject: Add support for sqlite NSS databases We do a chdir() to the NSS database location so that libnssckbi.so is available when the database is opened. Strip off a sql: prefix if one is available. This allows the new sqlite format to work. Add an additional test pass configuring NSS using the sqlite format. This requires a bit of a hack to pass in the value to python but it will work for now. Resolves: #1057650 --- ChangeLog | 7 +++++-- Makefile.am | 5 +++++ README | 7 +++++++ docs/mod_nss.html | 13 +++++++++++-- gencert.in | 20 +++++++++++--------- nss_engine_init.c | 7 ++++++- test/setup.sh | 10 ++++++---- test/suite1.tmpl | 8 +++----- test/test.py | 3 ++- test/test_config.py | 1 + 10 files changed, 57 insertions(+), 24 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2490d97..07db014 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,12 +1,15 @@ +2014-10-28 Rob Crittenden + * Add support for sqlite NSS databases (#1057650) + 2014-10-22 Stanislav Tokos * Compare subject CN and VS hostname during server start up -2014-10-16 Rob Crittenden * Add support for enabling TLS v1.2 * Don't enable SSL 3 by default (CVE-2014-3566) * Improve protocol testing -2014-02-20 Rob Crittenden * Sync with Fedora builds which were basicaly the defacto upstream. * Add nss_pcache man page * Fix CVE-2013-4566 diff --git a/Makefile.am b/Makefile.am index 986048d..fbfa62d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -98,8 +98,13 @@ EXTRA_DIST = *.h *.8 LICENSE test docs check: cd test; \ + rm -rf work; \ ./setup.sh; \ nosetests -v; \ + sleep 5; \ + rm -rf work; \ + ./setup.sh sql:; \ + DBPREFIX=sql: nosetests -v; \ cd .. .PHONY: all test clean diff --git a/README b/README index 542e114..aee8f55 100644 --- a/README +++ b/README @@ -123,3 +123,10 @@ TESTING From the source tree run: % make check + + The tests are run twice. Once with the old-style database and once + using the sqlite database format. See + https://wiki.mozilla.org/NSS_Shared_DB + + This is controlled by the environment variable DBPREFIX which needs + to be set to sql: when using the newer format for the tests. diff --git a/docs/mod_nss.html b/docs/mod_nss.html index 3d7c121..dea9db9 100644 --- a/docs/mod_nss.html +++ b/docs/mod_nss.html @@ -366,11 +366,13 @@ secmod.db. cert8.db stores certificates and Certificate Revocation Lists (CRLs), key3.db stores keys and secmod.db stores information about available PKCS#11 modules.

-This directive specifies a path, not a filename.
+This directive specifies a path, not a filename. To use a sqlite +NSS database include the prefix sql: in the path.

Example

NSSCertificateDatabase /etc/httpd/conf/nss
+NSSCertificateDatabase sql:/etc/httpd/conf/nss

NSSDBPrefix

@@ -1328,7 +1330,14 @@ NSS stores it's certificates and keys in a set of files referred to as the "certificate database." The files by default (with NSS 3.x) are named cert8.db, key3.db and secmod.db. See the NSS documentation at http://www.mozilla.org/projects/security/pki/nss/ -for more information on these specific files.
+for more information on these specific files.

+By default the NSS databases use the Berkeley Database format (cert8 and +key3). To use the sqlite format (cert9 and key4) either include sql: in +all references to the database (-d sql:/path/to/database) or +export NSS_DEFAULT_DB_TYPE="sql". +

+For more details see +https://wiki.mozilla.org/NSS_Shared_DB

The NSS database also stores any Certificate Revocation Lists (CRLs).

diff --git a/gencert.in b/gencert.in index 1128740..ffccaab 100755 --- a/gencert.in +++ b/gencert.in @@ -75,13 +75,15 @@ then echo "usage: $0 " 1>&2 exit 1 fi -if [ ! -d $1 -o ! -w $1 ] +PREFIX=`echo $1 | cut -d: -f1` +DEST=`echo $1 | cut -d: -f2` +if [ ! -d $DEST -o ! -w $DEST ] then echo "ERROR: $1 must be writable directory." 1>&2 exit 1 fi -DEST=$1 +DBDIR=$1 echo "httptest" > $DEST/pw.txt @@ -90,7 +92,7 @@ echo "#####################################################################" echo "Generating new server certificate and key database. The password" echo "is httptest" echo "#####################################################################" -$CERTUTIL -N -d $DEST -f $DEST/pw.txt +$CERTUTIL -N -d $DBDIR -f $DEST/pw.txt echo "" echo "#####################################################################" @@ -102,7 +104,7 @@ let CERTSERIAL=CERTSERIAL+1 # y 10 y -> basic constraints: CA cert # 5 6 7 9 n -> SSL, S/MIME, Object signing CA echo -e "5\n9\nn\ny\n10\ny\n5\n6\n7\n9\nn\n" | \ -$CERTUTIL -S -d $DEST -n cacert \ +$CERTUTIL -S -d $DBDIR -n cacert \ -s "$CA_CERTDN" \ -x \ -t CTu,CTu,CTu \ @@ -124,7 +126,7 @@ let CERTSERIAL=CERTSERIAL+1 # 0 2 9 n -> Key usage: Key Encipherment, Digital Signature # 0 9 n -> SSL Client echo -e "0\n2\n9\nn\n0\n9\nn\n" | \ -$CERTUTIL -S -d $DEST -n alpha \ +$CERTUTIL -S -d $DBDIR -n alpha \ -s "$ALPHA_CERTDN" \ -c cacert \ -t u,pu,u \ @@ -145,7 +147,7 @@ let CERTSERIAL=CERTSERIAL+1 # 0 2 9 n -> Key usage: Key Encipherment, Digital Signature # 0 9 n -> SSL Client echo -e "0\n2\n9\nn\n0\n9\nn\n" | \ -$CERTUTIL -S -d $DEST -n beta \ +$CERTUTIL -S -d $DBDIR -n beta \ -s "$BETA_CERTDN" \ -c cacert \ -t u,pu,u \ @@ -162,7 +164,7 @@ echo "#####################################################################" echo "Generating server certificate request" echo "#####################################################################" (ps -elf; date; netstat -a) > $DEST/noise -$CERTUTIL -R -d $DEST \ +$CERTUTIL -R -d $DBDIR \ -s "$SERVER_CERTDN" \ -o $DEST/tmpcertreq \ -g $KEYSIZE \ @@ -175,7 +177,7 @@ echo "Generating server certificate" echo "#####################################################################" let CERTSERIAL=CERTSERIAL+1 echo -e "2\n9\nn\n1\n9\nn\n" | \ -$CERTUTIL -C -d $DEST \ +$CERTUTIL -C -d $DBDIR \ -c cacert \ -i $DEST/tmpcertreq \ -o $DEST/tmpcert.der \ @@ -191,7 +193,7 @@ echo "" echo "#####################################################################" echo "Importing server certificate into server cert DB" echo "#####################################################################" -$CERTUTIL -A -d $DEST -n Server-Cert \ +$CERTUTIL -A -d $DBDIR -n Server-Cert \ -t u,u,u \ -i $DEST/tmpcert.der \ -f $DEST/pw.txt diff --git a/nss_engine_init.c b/nss_engine_init.c index 2569c8d..50b623d 100644 --- a/nss_engine_init.c +++ b/nss_engine_init.c @@ -145,6 +145,7 @@ static void nss_init_SSLLibrary(server_rec *base_server) int fipsenabled = FALSE; int ocspenabled = FALSE; int ocspdefault = FALSE; + char *dbdir = NULL; const char * ocspurl = NULL; const char * ocspname = NULL; @@ -186,7 +187,11 @@ static void nss_init_SSLLibrary(server_rec *base_server) else return; } - if (chdir(mc->pCertificateDatabase) != 0) { + if (strncasecmp(mc->pCertificateDatabase, "sql:", 4) == 0) + dbdir = mc->pCertificateDatabase + 4; + else + dbdir = mc->pCertificateDatabase; + if (chdir(dbdir) != 0) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, base_server, "Unable to change directory to %s", mc->pCertificateDatabase); if (mc->nInitCount == 1) diff --git a/test/setup.sh b/test/setup.sh index 2c6819c..b1e3371 100755 --- a/test/setup.sh +++ b/test/setup.sh @@ -5,6 +5,8 @@ server_gid=$USER server_port=8000 server_name=`hostname` +DBPREFIX=$1 + test_root=$currentpath/work/httpd test_root_esc=`echo ${test_root} | sed -e 's/\\//\\\\\\//g'` @@ -22,20 +24,20 @@ fi cp ../.libs/libmodnss.so ${test_root}/lib cp ../nss_pcache ${test_root}/bin -bash ../gencert ${test_root}/alias +bash ../gencert ${DBPREFIX}${test_root}/alias echo internal:httptest > ${test_root}/conf/password.conf # Export the CA cert -certutil -L -d ${test_root}/alias -n cacert -a > ${test_root}/alias/ca.pem +certutil -L -d ${DBPREFIX}${test_root}/alias -n cacert -a > ${test_root}/alias/ca.pem # Export the client cert cd ${test_root} echo password > pw echo httptest > dbpw -pk12util -o alpha.p12 -d alias -n alpha -w pw -k dbpw +pk12util -o alpha.p12 -d ${DBPREFIX}${test_root}/alias -n alpha -w pw -k dbpw openssl pkcs12 -in alpha.p12 -clcerts -nokeys -out alpha.crt -passin pass:`cat pw` openssl pkcs12 -in alpha.p12 -nocerts -nodes -out alpha.key -passin pass:`cat pw` -pk12util -o beta.p12 -d alias -n beta -w pw -k dbpw +pk12util -o beta.p12 -d ${DBPREFIX}${test_root}/alias -n beta -w pw -k dbpw openssl pkcs12 -in beta.p12 -clcerts -nokeys -out beta.crt -passin pass:`cat pw` openssl pkcs12 -in beta.p12 -nocerts -nodes -out beta.key -passin pass:`cat pw` /bin/rm -f pw dbpw diff --git a/test/suite1.tmpl b/test/suite1.tmpl index 8c9e7a3..233894c 100644 --- a/test/suite1.tmpl +++ b/test/suite1.tmpl @@ -12,7 +12,7 @@ Listen 0.0.0.0:8001 LogLevel debug - + NSSEngine on NSSFIPS off @@ -25,7 +25,7 @@ NSSProtocol SSLv3,TLSv1.0 NSSNickname Server-Cert -NSSCertificateDatabase $SERVER_ROOT/alias +NSSCertificateDatabase $DBPREFIX$SERVER_ROOT/alias NSSVerifyClient none @@ -86,7 +86,7 @@ NSSUserName SSL_CLIENT_S_DN_UID # # For testing protocol handling # - + NSSEngine on NSSFIPS off @@ -99,8 +99,6 @@ NSSProtocol TLSv1.2 NSSNickname Server-Cert -NSSCertificateDatabase $SERVER_ROOT/alias - NSSVerifyClient none # A bit redundant since the initial handshake should fail if no TLSv1.2 diff --git a/test/test.py b/test/test.py index 93e8518..75f3b0c 100644 --- a/test/test.py +++ b/test/test.py @@ -2,11 +2,12 @@ from test_config import Declarative, write_template_file, restart_apache from test_config import stop_apache import ssl import requests.exceptions +import os class test_suite1(Declarative): @classmethod def setUpClass(cls): - write_template_file('suite1.tmpl', 'work/httpd/conf/test.conf', {}) + write_template_file('suite1.tmpl', 'work/httpd/conf/test.conf', {'DBPREFIX': os.environ.get('DBPREFIX', '')}) restart_apache() @classmethod diff --git a/test/test_config.py b/test/test_config.py index 838ebd7..24a2f2a 100644 --- a/test/test_config.py +++ b/test/test_config.py @@ -33,6 +33,7 @@ DEF_PORT=8000 FQDN = socket.gethostname() default_vars = dict( + DBPREFIX = '', SERVER_PORT = DEF_PORT, SERVER_NAME = FQDN, TEST_ROOT = '%s/work/httpd' % os.getcwd(), -- cgit