summaryrefslogtreecommitdiffstats
path: root/src/tls/tls_prng_file.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tls/tls_prng_file.c')
-rw-r--r--src/tls/tls_prng_file.c155
1 files changed, 155 insertions, 0 deletions
diff --git a/src/tls/tls_prng_file.c b/src/tls/tls_prng_file.c
new file mode 100644
index 0000000..23865be
--- /dev/null
+++ b/src/tls/tls_prng_file.c
@@ -0,0 +1,155 @@
+/*++
+/* NAME
+/* tls_prng_file 3
+/* SUMMARY
+/* seed OpenSSL PRNG from entropy file
+/* SYNOPSIS
+/* #include <tls_prng_src.h>
+/*
+/* TLS_PRNG_SRC *tls_prng_file_open(name, timeout)
+/* const char *name;
+/* int timeout;
+/*
+/* ssize_t tls_prng_file_read(fh, length)
+/* TLS_PRNG_SRC *fh;
+/* size_t length;
+/*
+/* int tls_prng_file_close(fh)
+/* TLS_PRNG_SRC *fh;
+/* DESCRIPTION
+/* tls_prng_file_open() open the specified file and returns
+/* a handle that should be used with all subsequent access.
+/*
+/* tls_prng_file_read() reads the requested number of bytes from
+/* the entropy file and updates the OpenSSL PRNG. The file is not
+/* locked for shared or exclusive access.
+/*
+/* tls_prng_file_close() closes the specified entropy file
+/* and releases memory that was allocated for the handle.
+/*
+/* Arguments:
+/* .IP name
+/* The pathname of the entropy file.
+/* .IP length
+/* The number of bytes to read from the entropy file.
+/* .IP timeout
+/* Time limit on individual I/O operations.
+/* DIAGNOSTICS
+/* tls_prng_file_open() returns a null pointer on error.
+/*
+/* tls_prng_file_read() returns -1 on error, the number
+/* of bytes received on success.
+/*
+/* tls_prng_file_close() returns -1 on error, 0 on success.
+/*
+/* In all cases the errno variable indicates the type of error.
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Wietse Venema
+/* IBM T.J. Watson Research
+/* P.O. Box 704
+/* Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <limits.h>
+#include <errno.h>
+
+/* OpenSSL library. */
+
+#ifdef USE_TLS
+#include <openssl/rand.h> /* For the PRNG */
+
+/* Utility library. */
+
+#include <msg.h>
+#include <mymalloc.h>
+#include <connect.h>
+#include <iostuff.h>
+
+/* TLS library. */
+
+#include <tls_prng.h>
+
+/* tls_prng_file_open - open entropy file */
+
+TLS_PRNG_SRC *tls_prng_file_open(const char *name, int timeout)
+{
+ const char *myname = "tls_prng_file_open";
+ TLS_PRNG_SRC *fh;
+ int fd;
+
+ if ((fd = open(name, O_RDONLY, 0)) < 0) {
+ if (msg_verbose)
+ msg_info("%s: cannot open entropy file %s: %m", myname, name);
+ return (0);
+ } else {
+ fh = (TLS_PRNG_SRC *) mymalloc(sizeof(*fh));
+ fh->fd = fd;
+ fh->name = mystrdup(name);
+ fh->timeout = timeout;
+ if (msg_verbose)
+ msg_info("%s: opened entropy file %s", myname, name);
+ return (fh);
+ }
+}
+
+/* tls_prng_file_read - update internal PRNG from entropy file */
+
+ssize_t tls_prng_file_read(TLS_PRNG_SRC *fh, size_t len)
+{
+ const char *myname = "tls_prng_file_read";
+ char buffer[8192];
+ ssize_t to_read;
+ ssize_t count;
+
+ if (msg_verbose)
+ msg_info("%s: seed internal pool from file %s", myname, fh->name);
+
+ if (lseek(fh->fd, 0, SEEK_SET) < 0) {
+ if (msg_verbose)
+ msg_info("cannot seek entropy file %s: %m", fh->name);
+ return (-1);
+ }
+ errno = 0;
+ for (to_read = len; to_read > 0; to_read -= count) {
+ if ((count = timed_read(fh->fd, buffer, to_read > sizeof(buffer) ?
+ sizeof(buffer) : to_read,
+ fh->timeout, (void *) 0)) < 0) {
+ if (msg_verbose)
+ msg_info("cannot read entropy file %s: %m", fh->name);
+ return (-1);
+ }
+ if (count == 0)
+ break;
+ RAND_seed(buffer, count);
+ }
+ if (msg_verbose)
+ msg_info("read %ld bytes from entropy file %s: %m",
+ (long) (len - to_read), fh->name);
+ return (len - to_read);
+}
+
+/* tls_prng_file_close - close entropy file */
+
+int tls_prng_file_close(TLS_PRNG_SRC *fh)
+{
+ const char *myname = "tls_prng_file_close";
+ int err;
+
+ if (msg_verbose)
+ msg_info("%s: close entropy file %s", myname, fh->name);
+ err = close(fh->fd);
+ myfree(fh->name);
+ myfree((void *) fh);
+ return (err);
+}
+
+#endif