mirror of
https://gitee.com/acl-dev/acl.git
synced 2024-12-01 03:17:37 +08:00
145 lines
4.2 KiB
C
145 lines
4.2 KiB
C
/*++
|
|
* NAME
|
|
* tls_prng_exch 3
|
|
* SUMMARY
|
|
* maintain PRNG exchange file
|
|
* SYNOPSIS
|
|
* #include <tls_prng_src.h>
|
|
*
|
|
* TLS_PRNG_SRC *tls_prng_exch_open(name, timeout)
|
|
* const char *name;
|
|
* int timeout;
|
|
*
|
|
* void tls_prng_exch_update(fh, length)
|
|
* TLS_PRNG_SRC *fh;
|
|
* size_t length;
|
|
*
|
|
* void tls_prng_exch_close(fh)
|
|
* TLS_PRNG_SRC *fh;
|
|
* DESCRIPTION
|
|
* tls_prng_exch_open() opens the specified PRNG exchange file
|
|
* and returns a handle that should be used with all subsequent
|
|
* access.
|
|
*
|
|
* tls_prng_exch_update() reads the requested number of bytes
|
|
* from the PRNG exchange file, updates the OpenSSL PRNG, and
|
|
* writes the requested number of bytes to the exchange file.
|
|
* The file is locked for exclusive access.
|
|
*
|
|
* tls_prng_exch_close() closes the specified PRNG exchange
|
|
* file and releases memory that was allocated for the handle.
|
|
*
|
|
* Arguments:
|
|
* .IP name
|
|
* The name of the PRNG exchange file.
|
|
* .IP length
|
|
* The number of bytes to read from/write to the entropy file.
|
|
* .IP timeout
|
|
* Time limit on individual I/O operations.
|
|
* DIAGNOSTICS
|
|
* All errors are fatal.
|
|
* 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
|
|
*--*/
|
|
|
|
#include "StdAfx.h"
|
|
#include <fcntl.h>
|
|
#ifdef ACL_UNIX
|
|
#include <unistd.h>
|
|
#endif
|
|
#include <limits.h>
|
|
|
|
/* OpenSSL library. */
|
|
|
|
#ifdef USE_TLS
|
|
#include <openssl/rand.h> /* For the PRNG */
|
|
|
|
/* TLS library. */
|
|
|
|
#include "tls_prng.h"
|
|
|
|
/* Application specific. */
|
|
|
|
#define TLS_PRNG_EXCH_SIZE 1024 /* XXX Why not configurable? */
|
|
|
|
/* tls_prng_exch_open - open PRNG exchange file */
|
|
|
|
TLS_PRNG_SRC *tls_prng_exch_open(const char *name)
|
|
{
|
|
const char *myname = "tls_prng_exch_open";
|
|
TLS_PRNG_SRC *eh;
|
|
ACL_FILE_HANDLE fd;
|
|
|
|
if ((fd = acl_file_open(name, O_RDWR | O_CREAT, 0600)) < 0)
|
|
acl_msg_fatal("%s: cannot open PRNG exchange file %s: %s",
|
|
myname, name, acl_last_serror());
|
|
eh = (TLS_PRNG_SRC *) acl_mymalloc(sizeof(*eh));
|
|
eh->fd.file = fd;
|
|
eh->name = acl_mystrdup(name);
|
|
eh->timeout = 0;
|
|
if (acl_msg_verbose)
|
|
acl_msg_info("%s: opened PRNG exchange file %s", myname, name);
|
|
return (eh);
|
|
}
|
|
|
|
/* tls_prng_exch_update - update PRNG exchange file */
|
|
|
|
void tls_prng_exch_update(TLS_PRNG_SRC *eh)
|
|
{
|
|
const char *myname = "tls_prng_exch_update";
|
|
unsigned char buffer[TLS_PRNG_EXCH_SIZE];
|
|
ssize_t count;
|
|
|
|
/*
|
|
* Update the PRNG exchange file. Since other processes may have added
|
|
* entropy, we use a read-stir-write cycle.
|
|
*/
|
|
if (acl_myflock(eh->fd.file, ACL_INTERNAL_LOCK, ACL_FLOCK_OP_EXCLUSIVE) != 0)
|
|
acl_msg_fatal("%s: cannot lock PRNG exchange file %s: %s",
|
|
myname, eh->name, acl_last_serror());
|
|
if (acl_lseek(eh->fd.file, 0, SEEK_SET) < 0)
|
|
acl_msg_fatal("%s: cannot seek PRNG exchange file %s: %s",
|
|
myname, eh->name, acl_last_serror());
|
|
if ((count = acl_file_read(eh->fd.file, buffer, sizeof(buffer), 0, NULL, NULL)) < 0)
|
|
acl_msg_fatal("%s: cannot read PRNG exchange file %s: %s",
|
|
myname, eh->name, acl_last_serror());
|
|
|
|
if (count > 0)
|
|
RAND_seed(buffer, count);
|
|
RAND_bytes(buffer, sizeof(buffer));
|
|
|
|
if (acl_lseek(eh->fd.file, 0, SEEK_SET) < 0)
|
|
acl_msg_fatal("%s: cannot seek PRNG exchange file %s: %s",
|
|
myname, eh->name, acl_last_serror());
|
|
if (acl_file_write(eh->fd.file, buffer, sizeof(buffer), 0, NULL, NULL) != sizeof(buffer))
|
|
acl_msg_fatal("%s: cannot write PRNG exchange file %s: %s",
|
|
myname, eh->name, acl_last_serror());
|
|
if (acl_myflock(eh->fd.file, ACL_INTERNAL_LOCK, ACL_FLOCK_OP_NONE) != 0)
|
|
acl_msg_fatal("%s: cannot unlock PRNG exchange file %s: %s",
|
|
myname, eh->name, acl_last_serror());
|
|
}
|
|
|
|
/* tls_prng_exch_close - close PRNG exchange file */
|
|
|
|
void tls_prng_exch_close(TLS_PRNG_SRC *eh)
|
|
{
|
|
const char *myname = "tls_prng_exch_close";
|
|
|
|
if (acl_file_close(eh->fd.file) < 0)
|
|
acl_msg_fatal("%s: close PRNG exchange file %s: %s",
|
|
myname, eh->name, acl_last_serror());
|
|
if (acl_msg_verbose)
|
|
acl_msg_info("%s: closed PRNG exchange file %s", myname, eh->name);
|
|
acl_myfree(eh->name);
|
|
acl_myfree(eh);
|
|
}
|
|
|
|
#endif
|