#include <sys_defs.h>
#include <fcntl.h>
#include <unistd.h>
#include <limits.h>
#ifdef USE_TLS
#include <openssl/rand.h>
#include <msg.h>
#include <mymalloc.h>
#include <iostuff.h>
#include <myflock.h>
#include <tls_prng.h>
#define TLS_PRNG_EXCH_SIZE 1024
TLS_PRNG_SRC *tls_prng_exch_open(const char *name)
{
const char *myname = "tls_prng_exch_open";
TLS_PRNG_SRC *eh;
int fd;
if ((fd = open(name, O_RDWR | O_CREAT, 0600)) < 0)
msg_fatal("%s: cannot open PRNG exchange file %s: %m", myname, name);
eh = (TLS_PRNG_SRC *) mymalloc(sizeof(*eh));
eh->fd = fd;
eh->name = mystrdup(name);
eh->timeout = 0;
if (msg_verbose)
msg_info("%s: opened PRNG exchange file %s", myname, name);
return (eh);
}
void tls_prng_exch_update(TLS_PRNG_SRC *eh)
{
unsigned char buffer[TLS_PRNG_EXCH_SIZE];
ssize_t count;
if (myflock(eh->fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) != 0)
msg_fatal("cannot lock PRNG exchange file %s: %m", eh->name);
if (lseek(eh->fd, 0, SEEK_SET) < 0)
msg_fatal("cannot seek PRNG exchange file %s: %m", eh->name);
if ((count = read(eh->fd, buffer, sizeof(buffer))) < 0)
msg_fatal("cannot read PRNG exchange file %s: %m", eh->name);
if (count > 0)
RAND_seed(buffer, count);
RAND_bytes(buffer, sizeof(buffer));
if (lseek(eh->fd, 0, SEEK_SET) < 0)
msg_fatal("cannot seek PRNG exchange file %s: %m", eh->name);
if (write(eh->fd, buffer, sizeof(buffer)) != sizeof(buffer))
msg_fatal("cannot write PRNG exchange file %s: %m", eh->name);
if (myflock(eh->fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) != 0)
msg_fatal("cannot unlock PRNG exchange file %s: %m", eh->name);
}
void tls_prng_exch_close(TLS_PRNG_SRC *eh)
{
const char *myname = "tls_prng_exch_close";
if (close(eh->fd) < 0)
msg_fatal("close PRNG exchange file %s: %m", eh->name);
if (msg_verbose)
msg_info("%s: closed PRNG exchange file %s", myname, eh->name);
myfree(eh->name);
myfree((void *) eh);
}
#endif