kore

An easy to use, scalable and secure web application framework for writing web APIs in C.
Commits | Files | Refs | README | LICENSE | git clone https://git.kore.io/kore.git

commit f57ca7dcc2e208badea229cc05ab4f90bb22d013
parent 60a3f60a92f53113d58d6509fc442df2c089a894
Author: Joris Vink <joris@coders.se>
Date:   Mon, 27 Feb 2017 21:28:35 -0800

Let workers fetch entropy from keymgr.

At bootup and every 1800 seconds after that the worker processes will
ask the keymgr for new entropy that they will seed into their PRNG.

Additionally once received the worker calls RAND_poll() to grab
more entropy from the system to be mixed in.

Diffstat:
includes/kore.h | 4++++
src/keymgr.c | 18++++++++++++++++++
src/worker.c | 32++++++++++++++++++++++++++++++++
3 files changed, 54 insertions(+), 0 deletions(-)

diff --git a/includes/kore.h b/includes/kore.h @@ -66,6 +66,8 @@ extern int daemon(int, int); #define KORE_TLS_VERSION_1_0 1 #define KORE_TLS_VERSION_BOTH 2 +#define KORE_RESEED_TIME (1800 * 1000) + #define errno_s strerror(errno) #define ssl_errno_s ERR_error_string(ERR_get_error(), NULL) @@ -418,6 +420,8 @@ struct kore_timer { #define KORE_MSG_KEYMGR_REQ 3 #define KORE_MSG_KEYMGR_RESP 4 #define KORE_MSG_SHUTDOWN 5 +#define KORE_MSG_ENTROPY_REQ 6 +#define KORE_MSG_ENTROPY_RESP 7 /* Predefined message targets. */ #define KORE_MSG_PARENT 1000 diff --git a/src/keymgr.c b/src/keymgr.c @@ -51,6 +51,7 @@ static void keymgr_save_randfile(void); static void keymgr_load_privatekey(struct kore_domain *); static void keymgr_msg_recv(struct kore_msg *, const void *); +static void keymgr_entropy_request(struct kore_msg *, const void *); static void keymgr_rsa_encrypt(struct kore_msg *, const void *, struct key *); @@ -85,6 +86,7 @@ kore_keymgr_run(void) kore_msg_worker_init(); kore_msg_register(KORE_MSG_KEYMGR_REQ, keymgr_msg_recv); + kore_msg_register(KORE_MSG_ENTROPY_REQ, keymgr_entropy_request); last_seed = 0; kore_log(LOG_NOTICE, "key manager started"); @@ -264,6 +266,22 @@ keymgr_load_privatekey(struct kore_domain *dom) } static void +keymgr_entropy_request(struct kore_msg *msg, const void *data) +{ + u_int8_t buf[RAND_FILE_SIZE]; + + if (RAND_bytes(buf, sizeof(buf)) != 1) { + kore_log(LOG_WARNING, + "failed to generate entropy for worker %u: %s", + msg->src, ssl_errno_s); + return; + } + + /* No cleanse, this stuff is leaked in the kernel path anyway. */ + kore_msg_send(msg->src, KORE_MSG_ENTROPY_RESP, buf, sizeof(buf)); +} + +static void keymgr_msg_recv(struct kore_msg *msg, const void *data) { const struct kore_keyreq *req; diff --git a/src/worker.c b/src/worker.c @@ -21,6 +21,10 @@ #include <sys/resource.h> #include <sys/socket.h> +#if !defined(KORE_NO_TLS) +#include <openssl/rand.h> +#endif + #include <fcntl.h> #include <grp.h> #include <pwd.h> @@ -71,6 +75,10 @@ static void worker_unlock(void); static inline int kore_worker_acceptlock_obtain(void); static inline void kore_worker_acceptlock_release(void); +#if !defined(KORE_NO_TLS) +static void worker_entropy_recv(struct kore_msg *, const void *); +#endif + static struct kore_worker *kore_workers; static int shm_accept_key; static struct wlock *accept_lock; @@ -270,6 +278,9 @@ kore_worker_entry(struct kore_worker *kw) char buf[16]; int quit, had_lock, r; u_int64_t now, next_lock, netwait; +#if !defined(KORE_NO_TLS) + u_int64_t last_seed; +#endif worker = kw; @@ -331,6 +342,11 @@ kore_worker_entry(struct kore_worker *kw) kore_task_init(); #endif +#if !defined(KORE_NO_TLS) + last_seed = 0; + kore_msg_register(KORE_MSG_ENTROPY_RESP, worker_entropy_recv); +#endif + kore_log(LOG_NOTICE, "worker %d started (cpu#%d)", kw->id, kw->cpu); rcall = kore_runtime_getcall("kore_worker_configure"); @@ -364,6 +380,14 @@ kore_worker_entry(struct kore_worker *kw) if (netwait > 100) netwait = 100; +#if !defined(KORE_NO_TLS) + if ((now - last_seed) > KORE_RESEED_TIME) { + kore_msg_send(KORE_WORKER_KEYMGR, + KORE_MSG_ENTROPY_REQ, NULL, 0); + last_seed = now; + } +#endif + if (now > next_lock) { if (kore_worker_acceptlock_obtain()) { if (had_lock == 0) { @@ -557,3 +581,11 @@ worker_unlock(void) if (!__sync_bool_compare_and_swap(&(accept_lock->lock), 1, 0)) kore_log(LOG_NOTICE, "worker_unlock(): wasnt locked"); } + +#if !defined(KORE_NO_TLS) +static void +worker_entropy_recv(struct kore_msg *msg, const void *data) +{ + RAND_seed(data, msg->length); +} +#endif