Patrick Welche <prlw1@cam.ac.uk>
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / tls / tls_prng_exch.c
blob0248a5f37423543f5cae41216d40fd495248b5a4
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* tls_prng_exch 3
6 /* SUMMARY
7 /* maintain PRNG exchange file
8 /* SYNOPSIS
9 /* #include <tls_prng_src.h>
11 /* TLS_PRNG_SRC *tls_prng_exch_open(name, timeout)
12 /* const char *name;
13 /* int timeout;
15 /* void tls_prng_exch_update(fh, length)
16 /* TLS_PRNG_SRC *fh;
17 /* size_t length;
19 /* void tls_prng_exch_close(fh)
20 /* TLS_PRNG_SRC *fh;
21 /* DESCRIPTION
22 /* tls_prng_exch_open() opens the specified PRNG exchange file
23 /* and returns a handle that should be used with all subsequent
24 /* access.
26 /* tls_prng_exch_update() reads the requested number of bytes
27 /* from the PRNG exchange file, updates the OpenSSL PRNG, and
28 /* writes the requested number of bytes to the exchange file.
29 /* The file is locked for exclusive access.
31 /* tls_prng_exch_close() closes the specified PRNG exchange
32 /* file and releases memory that was allocated for the handle.
34 /* Arguments:
35 /* .IP name
36 /* The name of the PRNG exchange file.
37 /* .IP length
38 /* The number of bytes to read from/write to the entropy file.
39 /* .IP timeout
40 /* Time limit on individual I/O operations.
41 /* DIAGNOSTICS
42 /* All errors are fatal.
43 /* LICENSE
44 /* .ad
45 /* .fi
46 /* The Secure Mailer license must be distributed with this software.
47 /* AUTHOR(S)
48 /* Wietse Venema
49 /* IBM T.J. Watson Research
50 /* P.O. Box 704
51 /* Yorktown Heights, NY 10598, USA
52 /*--*/
54 /* System library. */
56 #include <sys_defs.h>
57 #include <fcntl.h>
58 #include <unistd.h>
59 #include <limits.h>
61 /* OpenSSL library. */
63 #ifdef USE_TLS
64 #include <openssl/rand.h> /* For the PRNG */
66 /* Utility library. */
68 #include <msg.h>
69 #include <mymalloc.h>
70 #include <iostuff.h>
71 #include <myflock.h>
73 /* TLS library. */
75 #include <tls_prng.h>
77 /* Application specific. */
79 #define TLS_PRNG_EXCH_SIZE 1024 /* XXX Why not configurable? */
81 /* tls_prng_exch_open - open PRNG exchange file */
83 TLS_PRNG_SRC *tls_prng_exch_open(const char *name)
85 const char *myname = "tls_prng_exch_open";
86 TLS_PRNG_SRC *eh;
87 int fd;
89 if ((fd = open(name, O_RDWR | O_CREAT, 0600)) < 0)
90 msg_fatal("%s: cannot open PRNG exchange file %s: %m", myname, name);
91 eh = (TLS_PRNG_SRC *) mymalloc(sizeof(*eh));
92 eh->fd = fd;
93 eh->name = mystrdup(name);
94 eh->timeout = 0;
95 if (msg_verbose)
96 msg_info("%s: opened PRNG exchange file %s", myname, name);
97 return (eh);
100 /* tls_prng_exch_update - update PRNG exchange file */
102 void tls_prng_exch_update(TLS_PRNG_SRC *eh)
104 unsigned char buffer[TLS_PRNG_EXCH_SIZE];
105 ssize_t count;
108 * Update the PRNG exchange file. Since other processes may have added
109 * entropy, we use a read-stir-write cycle.
111 if (myflock(eh->fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) != 0)
112 msg_fatal("cannot lock PRNG exchange file %s: %m", eh->name);
113 if (lseek(eh->fd, 0, SEEK_SET) < 0)
114 msg_fatal("cannot seek PRNG exchange file %s: %m", eh->name);
115 if ((count = read(eh->fd, buffer, sizeof(buffer))) < 0)
116 msg_fatal("cannot read PRNG exchange file %s: %m", eh->name);
118 if (count > 0)
119 RAND_seed(buffer, count);
120 RAND_bytes(buffer, sizeof(buffer));
122 if (lseek(eh->fd, 0, SEEK_SET) < 0)
123 msg_fatal("cannot seek PRNG exchange file %s: %m", eh->name);
124 if (write(eh->fd, buffer, sizeof(buffer)) != sizeof(buffer))
125 msg_fatal("cannot write PRNG exchange file %s: %m", eh->name);
126 if (myflock(eh->fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) != 0)
127 msg_fatal("cannot unlock PRNG exchange file %s: %m", eh->name);
130 /* tls_prng_exch_close - close PRNG exchange file */
132 void tls_prng_exch_close(TLS_PRNG_SRC *eh)
134 const char *myname = "tls_prng_exch_close";
136 if (close(eh->fd) < 0)
137 msg_fatal("close PRNG exchange file %s: %m", eh->name);
138 if (msg_verbose)
139 msg_info("%s: closed PRNG exchange file %s", myname, eh->name);
140 myfree(eh->name);
141 myfree((char *) eh);
144 #endif