From fedora-directory-commits at redhat.com Mon Oct 3 14:59:28 2005 From: fedora-directory-commits at redhat.com (Robert Crittenden (rcritten)) Date: Mon, 3 Oct 2005 10:59:28 -0400 Subject: [Fedora-directory-commits] mod_nss nss_engine_rand.c, NONE, 1.1 Makefile.am, 1.6, 1.7 Makefile.in, 1.9, 1.10 mod_nss.c, 1.8, 1.9 mod_nss.h, 1.7, 1.8 nss.conf.in, 1.6, 1.7 nss_engine_config.c, 1.8, 1.9 nss_engine_init.c, 1.13, 1.14 Message-ID: <200510031459.j93ExSrg011496@cvs-int.fedora.redhat.com> Author: rcritten Update of /cvs/dirsec/mod_nss In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv11437 Modified Files: Makefile.am Makefile.in mod_nss.c mod_nss.h nss.conf.in nss_engine_config.c nss_engine_init.c Added Files: nss_engine_rand.c Log Message: Add support for seeding the NSS Random Number Generator. This adds a new directive, NSSRandomSeed based on the mod_ssl SSLRandomSeed directive. --- NEW FILE nss_engine_rand.c --- /* Copyright 2001-2005 The Apache Software Foundation or its licensors, as * applicable. * * 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" /* _________________________________________________________________ ** ** Support for better seeding of SSL library's RNG ** _________________________________________________________________ */ static int nss_rand_choosenum(int, int); static int nss_rand_feedfp(apr_pool_t *, apr_file_t *, int); int nss_rand_seed(server_rec *s, apr_pool_t *p, ssl_rsctx_t nCtx, char *prefix) { SSLModConfigRec *mc; apr_array_header_t *apRandSeed; ssl_randseed_t *pRandSeeds; ssl_randseed_t *pRandSeed; unsigned char stackdata[256]; int nReq, nDone; apr_file_t *fp; int i, n, l; mc = myModConfig(s); nReq = 0; nDone = 0; apRandSeed = mc->aRandSeed; pRandSeeds = (ssl_randseed_t *)apRandSeed->elts; for (i = 0; i < apRandSeed->nelts; i++) { pRandSeed = &pRandSeeds[i]; if (pRandSeed->nCtx == nCtx) { nReq += pRandSeed->nBytes; if (pRandSeed->nSrc == SSL_RSSRC_FILE) { /* * seed in contents of an external file */ if (apr_file_open(&fp, pRandSeed->cpPath, APR_READ, APR_OS_DEFAULT, p) != APR_SUCCESS) continue; nDone += nss_rand_feedfp(p, fp, pRandSeed->nBytes); apr_file_close(fp); } else if (pRandSeed->nSrc == SSL_RSSRC_EXEC) { const char *cmd = pRandSeed->cpPath; const char **argv = apr_palloc(p, sizeof(char *) * 3); /* * seed in contents generated by an external program */ argv[0] = cmd; argv[1] = apr_itoa(p, pRandSeed->nBytes); argv[2] = NULL; if ((fp = nss_util_ppopen(s, p, cmd, argv)) == NULL) continue; nDone += nss_rand_feedfp(p, fp, pRandSeed->nBytes); nss_util_ppclose(s, p, fp); } else if (pRandSeed->nSrc == SSL_RSSRC_BUILTIN) { struct { time_t t; pid_t pid; } my_seed; /* * seed in the current time (usually just 4 bytes) */ my_seed.t = time(NULL); /* * seed in the current process id (usually just 4 bytes) */ my_seed.pid = mc->pid; l = sizeof(my_seed); PK11_RandomUpdate((unsigned char *)&my_seed, l); nDone += l; /* * seed in some current state of the run-time stack (128 bytes) */ n = nss_rand_choosenum(0, sizeof(stackdata)-128-1); PK11_RandomUpdate(stackdata+n, 128); nDone += 128; } } } if (nDone > 0) ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, "%sSeeding PRNG with %d bytes of entropy", prefix, nDone); return nDone; } #define BUFSIZE 8192 static int nss_rand_feedfp(apr_pool_t *p, apr_file_t *fp, int nReq) { apr_size_t nDone; unsigned char caBuf[BUFSIZE]; apr_size_t nBuf; apr_size_t nRead; apr_size_t nTodo; nDone = 0; nRead = BUFSIZE; nTodo = nReq; while (1) { if (nReq > 0) nRead = (nTodo < BUFSIZE ? nTodo : BUFSIZE); nBuf = nRead; if (apr_file_read(fp, caBuf, &nBuf) != APR_SUCCESS) break; PK11_RandomUpdate(caBuf, nBuf); nDone += nBuf; if (nReq > 0) { nTodo -= nBuf; if (nTodo <= 0) break; } } return nDone; } static int nss_rand_choosenum(int l, int h) { int i; char buf[50]; apr_snprintf(buf, sizeof(buf), "%.0f", (((double)(rand()%RAND_MAX)/RAND_MAX)*(h-l))); i = atoi(buf)+1; if (i < l) i = l; if (i > h) i = h; return i; } Index: Makefile.am =================================================================== RCS file: /cvs/dirsec/mod_nss/Makefile.am,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- Makefile.am 13 Sep 2005 19:34:39 -0000 1.6 +++ Makefile.am 3 Oct 2005 14:59:26 -0000 1.7 @@ -6,7 +6,7 @@ nss_pcache_SOURCES = nss_pcache.c ## Define the source file for the module -libmodnss_la_SOURCES = mod_nss.c nss_engine_config.c nss_engine_init.c nss_engine_io.c nss_engine_kernel.c nss_engine_log.c nss_engine_pphrase.c nss_engine_vars.c nss_expr.c nss_expr_eval.c nss_expr_parse.y nss_expr_scan.l nss_util.c +libmodnss_la_SOURCES = mod_nss.c nss_engine_config.c nss_engine_init.c nss_engine_io.c nss_engine_kernel.c nss_engine_log.c nss_engine_pphrase.c nss_engine_vars.c nss_expr.c nss_expr_eval.c nss_expr_parse.y nss_expr_scan.l nss_util.c nss_engine_rand.c ## Set the includes and libraries needed INCLUDES = -I at apache_inc@ @nspr_inc@ @nss_inc@ @apr_inc@ Index: Makefile.in =================================================================== RCS file: /cvs/dirsec/mod_nss/Makefile.in,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- Makefile.in 26 Sep 2005 20:01:24 -0000 1.9 +++ Makefile.in 3 Oct 2005 14:59:26 -0000 1.10 @@ -107,7 +107,7 @@ nss_pcache_SOURCES = nss_pcache.c -libmodnss_la_SOURCES = mod_nss.c nss_engine_config.c nss_engine_init.c nss_engine_io.c nss_engine_kernel.c nss_engine_log.c nss_engine_pphrase.c nss_engine_vars.c nss_expr.c nss_expr_eval.c nss_expr_parse.y nss_expr_scan.l nss_util.c +libmodnss_la_SOURCES = mod_nss.c nss_engine_config.c nss_engine_init.c nss_engine_io.c nss_engine_kernel.c nss_engine_log.c nss_engine_pphrase.c nss_engine_vars.c nss_expr.c nss_expr_eval.c nss_expr_parse.y nss_expr_scan.l nss_util.c nss_engine_rand.c INCLUDES = -I at apache_inc@ @nspr_inc@ @nss_inc@ @apr_inc@ LIBS = @nspr_lib@ @nss_lib@ -lssl3 -lsmime3 -lnss3 -lsoftokn3 -lplc4 -lplds4 -lnspr4 @@ -133,7 +133,7 @@ nss_engine_init.lo nss_engine_io.lo nss_engine_kernel.lo \ nss_engine_log.lo nss_engine_pphrase.lo nss_engine_vars.lo \ nss_expr.lo nss_expr_eval.lo nss_expr_parse.lo nss_expr_scan.lo \ - nss_util.lo + nss_util.lo nss_engine_rand.lo libmodnss_la_OBJECTS = $(am_libmodnss_la_OBJECTS) bin_PROGRAMS = nss_pcache$(EXEEXT) PROGRAMS = $(bin_PROGRAMS) @@ -157,6 +157,7 @@ @AMDEP_TRUE@ ./$(DEPDIR)/nss_engine_kernel.Plo \ @AMDEP_TRUE@ ./$(DEPDIR)/nss_engine_log.Plo \ @AMDEP_TRUE@ ./$(DEPDIR)/nss_engine_pphrase.Plo \ + at AMDEP_TRUE@ ./$(DEPDIR)/nss_engine_rand.Plo \ @AMDEP_TRUE@ ./$(DEPDIR)/nss_engine_vars.Plo \ @AMDEP_TRUE@ ./$(DEPDIR)/nss_expr.Plo \ @AMDEP_TRUE@ ./$(DEPDIR)/nss_expr_eval.Plo \ @@ -256,6 +257,7 @@ @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/nss_engine_kernel.Plo at am__quote@ @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/nss_engine_log.Plo at am__quote@ @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/nss_engine_pphrase.Plo at am__quote@ + at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/nss_engine_rand.Plo at am__quote@ @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/nss_engine_vars.Plo at am__quote@ @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/nss_expr.Plo at am__quote@ @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/nss_expr_eval.Plo at am__quote@ Index: mod_nss.c =================================================================== RCS file: /cvs/dirsec/mod_nss/mod_nss.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- mod_nss.c 29 Sep 2005 19:35:43 -0000 1.8 +++ mod_nss.c 3 Oct 2005 14:59:26 -0000 1.9 @@ -63,6 +63,9 @@ SSL_CMD_SRV(OCSP, FLAG, "OCSP (Online Certificate Status Protocol)" "(`on', `off')") + SSL_CMD_SRV(RandomSeed, TAKE23, + "SSL Pseudo Random Number Generator (PRNG) seeding source " + "(`startup builtin|file:/path|exec:/path [bytes]')") /* * Per-server context configuration directives Index: mod_nss.h =================================================================== RCS file: /cvs/dirsec/mod_nss/mod_nss.h,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- mod_nss.h 29 Sep 2005 19:35:43 -0000 1.7 +++ mod_nss.h 3 Oct 2005 14:59:26 -0000 1.8 @@ -163,6 +163,26 @@ } nss_require_t; /* + * Define the SSL random number generator seeding source. The CONNECT + * method is not currently used. + */ +typedef enum { + SSL_RSCTX_STARTUP = 1, + SSL_RSCTX_CONNECT = 2 +} ssl_rsctx_t; +typedef enum { + SSL_RSSRC_BUILTIN = 1, + SSL_RSSRC_FILE = 2, + SSL_RSSRC_EXEC = 3 +} ssl_rssrc_t; +typedef struct { + ssl_rsctx_t nCtx; + ssl_rssrc_t nSrc; + char *cpPath; + int nBytes; +} ssl_randseed_t; + +/* * Define the SSL verify levels */ typedef enum { @@ -217,6 +237,8 @@ apr_proc_t proc; apr_procattr_t *procattr; + apr_array_header_t *aRandSeed; + struct { void *pV1, *pV2, *pV3, *pV4, *pV5, *pV6, *pV7, *pV8, *pV9, *pV10; } rCtx; @@ -328,6 +350,7 @@ const char *nss_cmd_NSSSessionCacheSize(cmd_parms *cmd, void *dcfg, const char *arg); const char *nss_cmd_NSSPassPhraseDialog(cmd_parms *cmd, void *dcfg, const char *arg); const char *nss_cmd_NSSPassPhraseHelper(cmd_parms *cmd, void *dcfg, const char *arg); +const char *nss_cmd_NSSRandomSeed(cmd_parms *, void *, const char *, const char *, const char *); const char *nss_cmd_NSSUserName(cmd_parms *cmd, void *dcfg, const char *arg); const char *nss_cmd_NSSOptions(cmd_parms *, void *, const char *); const char *nss_cmd_NSSRequireSSL(cmd_parms *cmd, void *dcfg); Index: nss.conf.in =================================================================== RCS file: /cvs/dirsec/mod_nss/nss.conf.in,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- nss.conf.in 13 Sep 2005 19:34:39 -0000 1.6 +++ nss.conf.in 3 Oct 2005 14:59:26 -0000 1.7 @@ -50,6 +50,20 @@ NSSSessionCacheTimeout 100 NSSSession3CacheTimeout 86400 +# +# Pseudo Random Number Generator (PRNG): +# Configure one or more sources to seed the PRNG of the SSL library. +# The seed data should be of good random quality. +# WARNING! On some platforms /dev/random blocks if not enough entropy +# is available. Those platforms usually also provide a non-blocking +# device, /dev/urandom, which may be used instead. +# +# This does not support seeding the RNG with each connection. + +NSSRandomSeed startup builtin +#NSSRandomSeed startup file:/dev/random 512 +#NSSRandomSeed startup file:/dev/urandom 512 + ## ## SSL Virtual Host Context ## Index: nss_engine_config.c =================================================================== RCS file: /cvs/dirsec/mod_nss/nss_engine_config.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- nss_engine_config.c 29 Sep 2005 19:35:43 -0000 1.8 +++ nss_engine_config.c 3 Oct 2005 14:59:26 -0000 1.9 @@ -51,6 +51,8 @@ mc->ssl3_session_cache_timeout = UNSET; mc->pphrase_dialog_helper = NULL; mc->pphrase_dialog_path = NULL; + mc->aRandSeed = apr_array_make(pool, 4, + sizeof(ssl_randseed_t)); apr_pool_userdata_set(mc, SSL_MOD_CONFIG_KEY, apr_pool_cleanup_null, @@ -561,6 +563,93 @@ return NULL; } +const char *nss_cmd_NSSRandomSeed(cmd_parms *cmd, + void *dcfg, + const char *arg1, + const char *arg2, + const char *arg3) +{ + SSLModConfigRec *mc = myModConfig(cmd->server); + const char *err; + ssl_randseed_t *seed; + int arg2len = strlen(arg2); + + if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) { + return err; + } + + /* Only run through this once. Otherwise the random seed sources are + * pushed into the array for each server start (and we are guaranteed 2) */ + if (mc->nInitCount >= 1) { + return NULL; + } + + seed = apr_array_push(mc->aRandSeed); + + if (strcEQ(arg1, "startup")) { + seed->nCtx = SSL_RSCTX_STARTUP; + } + else if (strcEQ(arg1, "connect")) { + return apr_pstrcat(cmd->pool, "NSSRandomSeed: " + "mod_nss doesn't do per-connection random seeding", + NULL); + } + else { + return apr_pstrcat(cmd->pool, "NSSRandomSeed: " + "invalid context: `", arg1, "'", + NULL); + } + + if ((arg2len > 5) && strEQn(arg2, "file:", 5)) { + seed->nSrc = SSL_RSSRC_FILE; + seed->cpPath = ap_server_root_relative(mc->pPool, arg2+5); + } + else if ((arg2len > 5) && strEQn(arg2, "exec:", 5)) { + seed->nSrc = SSL_RSSRC_EXEC; + seed->cpPath = ap_server_root_relative(mc->pPool, arg2+5); + } + else if (strcEQ(arg2, "builtin")) { + seed->nSrc = SSL_RSSRC_BUILTIN; + seed->cpPath = NULL; + } + else { + seed->nSrc = SSL_RSSRC_FILE; + seed->cpPath = ap_server_root_relative(mc->pPool, arg2); + } + + if (seed->nSrc != SSL_RSSRC_BUILTIN) { + apr_finfo_t finfo; + if (!seed->cpPath) { + return apr_pstrcat(cmd->pool, + "Invalid NSSRandomSeed path ", + arg2, NULL); + } + if (apr_stat(&finfo, seed->cpPath, APR_FINFO_TYPE|APR_FINFO_SIZE, cmd->pool) != 0) { + return apr_pstrcat(cmd->pool, + "NSSRandomSeed: source path '", + seed->cpPath, "' does not exist", NULL); + } + } + + if (!arg3) { + seed->nBytes = 0; /* read whole file */ + } + else { + if (seed->nSrc == SSL_RSSRC_BUILTIN) { + return "NSSRandomSeed: byte specification not " + "allowed for builtin seed source"; + } + + seed->nBytes = atoi(arg3); + + if (seed->nBytes < 0) { + return "NSSRandomSeed: invalid number of bytes specified"; + } + } + + return NULL; +} + const char *nss_cmd_NSSUserName(cmd_parms *cmd, void *dcfg, const char *arg) { Index: nss_engine_init.c =================================================================== RCS file: /cvs/dirsec/mod_nss/nss_engine_init.c,v retrieving revision 1.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- nss_engine_init.c 29 Sep 2005 19:35:43 -0000 1.13 +++ nss_engine_init.c 3 Oct 2005 14:59:26 -0000 1.14 @@ -348,8 +348,14 @@ /* Load our layer */ nss_io_layer_init(); - ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, - "done layer"); + + /* + * Seed the Pseudo Random Number Generator (PRNG) + * only need ptemp here; nothing inside allocated from the pool + * needs to live once we return from nss_rand_seed(). + */ + if (mc->nInitCount > 1) + nss_rand_seed(base_server, ptemp, SSL_RSCTX_STARTUP, "Init: "); /* * initialize servers From fedora-directory-commits at redhat.com Mon Oct 3 14:59:29 2005 From: fedora-directory-commits at redhat.com (Robert Crittenden (rcritten)) Date: Mon, 3 Oct 2005 10:59:29 -0400 Subject: [Fedora-directory-commits] mod_nss/docs mod_nss.html,1.9,1.10 Message-ID: <200510031459.j93ExTqZ011508@cvs-int.fedora.redhat.com> Author: rcritten Update of /cvs/dirsec/mod_nss/docs In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv11437/docs Modified Files: mod_nss.html Log Message: Add support for seeding the NSS Random Number Generator. This adds a new directive, NSSRandomSeed based on the mod_ssl SSLRandomSeed directive. Index: mod_nss.html =================================================================== RCS file: /cvs/dirsec/mod_nss/docs/mod_nss.html,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- mod_nss.html 29 Sep 2005 19:35:44 -0000 1.9 +++ mod_nss.html 3 Oct 2005 14:59:26 -0000 1.10 @@ -249,7 +249,6 @@

Configuration Directives

The following mod_ssl Directives are not applicable to mod_nss: