[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
Robert Crittenden (rcritten)
fedora-directory-commits at redhat.com
Mon Oct 3 14:59:28 UTC 2005
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
More information about the Fedora-directory-commits
mailing list