Skip to content

Commit

Permalink
Improve initialisation of OpenSSL PRNG.
Browse files Browse the repository at this point in the history
Basic idea taken from Tor.
  • Loading branch information
Linus Nordberg committed Dec 20, 2013
1 parent da72e14 commit 11570f6
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 25 deletions.
2 changes: 1 addition & 1 deletion lib/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ event_init_bufferevent (struct rs_connection *conn, struct rs_peer *peer)
#if defined (RS_ENABLE_TLS)
else if (conn->realm->type == RS_CONN_TYPE_TLS)
{
if (rs_tls_init (conn))
if (tls_init_conn (conn))
return -1;
/* Would be convenient to pass BEV_OPT_CLOSE_ON_FREE but things
seem to break when be_openssl_ctrl() (in libevent) calls
Expand Down
3 changes: 1 addition & 2 deletions lib/examples/client-blocking.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ blocking_client (const char *config_fn, const char *configuration,
r = rs_context_create (&h);
if (r)
{
assert(r == RSE_NOMEM);
assert (!"out of RAM -- unable to create libradsec context");
assert (!"unable to create libradsec context");
}

#if !defined (USE_CONFIG_FILE)
Expand Down
10 changes: 6 additions & 4 deletions lib/radsec.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "debug.h"
#include "radsecproxy/debug.h"
#if defined (RS_ENABLE_TLS)
#include "tls.h"
#include <regex.h>
#include "radsecproxy/list.h"
#include "radsecproxy/radsecproxy.h"
Expand All @@ -32,14 +33,15 @@ rs_context_create (struct rs_context **ctx)
{
struct rs_context *h;

#if defined (RS_ENABLE_TLS)
if (tls_init ())
return RSE_SSLERR;
#endif

h = calloc (1, sizeof(*h));
if (h == NULL)
return RSE_NOMEM;

#if defined (RS_ENABLE_TLS)
ssl_init ();
#endif

debug_init ("libradsec"); /* radsecproxy compat, FIXME: remove */

if (ctx != NULL)
Expand Down
15 changes: 0 additions & 15 deletions lib/radsecproxy/tlscommon.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,21 +39,6 @@

static struct hash *tlsconfs = NULL;

void ssl_init(void) {
time_t t;
pid_t pid;

SSL_load_error_strings();
SSL_library_init();

while (!RAND_status()) {
t = time(NULL);
pid = getpid();
RAND_seed((unsigned char *)&t, sizeof(time_t));
RAND_seed((unsigned char *)&pid, sizeof(pid));
}
}

static int pem_passwd_cb(char *buf, int size, int rwflag, void *userdata) {
int pwdlen = strlen(userdata);
if (rwflag != 0 || pwdlen > size) /* not for decryption or too large */
Expand Down
1 change: 0 additions & 1 deletion lib/radsecproxy/tlscommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ struct tls {
};

#if defined(RADPROT_TLS) || defined(RADPROT_DTLS)
void ssl_init();
struct tls *tlsgettls(char *alt1, char *alt2);
SSL_CTX *tlsgetctx(uint8_t type, struct tls *t);
X509 *verifytlscert(SSL *ssl);
Expand Down
81 changes: 80 additions & 1 deletion lib/tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,24 @@
#endif

#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <fcntl.h>
#include <limits.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/bn.h>
#include <openssl/x509v3.h>
#include <openssl/rand.h>
#include <radsec/radsec.h>
#include <radsec/radsec-impl.h>

#include <regex.h>
#include "radsecproxy/list.h"
#include "radsecproxy/radsecproxy.h"

#include "tls.h"

static struct tls *
_get_tlsconf (struct rs_connection *conn, const struct rs_realm *realm)
{
Expand Down Expand Up @@ -112,8 +118,81 @@ psk_client_cb (SSL *ssl,
}
#endif /* RS_ENABLE_TLS_PSK */

/** Read \a buf_len bytes from one of the random devices into \a
buf. Return 0 on success and -1 on failure. */
static int
load_rand_ (uint8_t *buf, size_t buf_len)
{
static const char *fns[] = {"/dev/urandom", "/dev/random", NULL};
int i;

if (buf_len > SSIZE_MAX)
return -1;

for (i = 0; fns[i] != NULL; i++)
{
size_t nread = 0;
int fd = open (fns[i], O_RDONLY);
if (fd < 0)
continue;
while (nread != buf_len)
{
ssize_t r = read (fd, buf + nread, buf_len - nread);
if (r < 0)
return -1;
if (r == 0)
break;
nread += r;
}
close (fd);
if (nread != buf_len)
return -1;
return 0;
}
return -1;
}

/** Initialise OpenSSL's PRNG by possibly invoking RAND_poll() and by
feeding RAND_seed() data from one of the random devices. If either
succeeds, we're happy and return 0. */
static int
init_openssl_rand_ (void)
{
long openssl_version = 0;
int openssl_random_init_flag = 0;
int our_random_init_flag = 0;
uint8_t buf[32];

/* Older OpenSSL has a crash bug in RAND_poll (when a file it opens
gets a file descriptor with a number higher than FD_SETSIZE) so
use it only for newer versions. */
openssl_version = SSLeay ();
if (openssl_version >= OPENSSL_V (0,9,8,'c'))
openssl_random_init_flag = RAND_poll ();

our_random_init_flag = !load_rand_ (buf, sizeof(buf));
if (our_random_init_flag)
RAND_seed (buf, sizeof(buf));
memset (buf, 0, sizeof(buf)); /* FIXME: What if memset() is optimised out? */

if (!openssl_random_init_flag && !our_random_init_flag)
return -1;
if (!RAND_bytes (buf, sizeof(buf)))
return -1;
return 0;
}

/** Initialise the TLS library. Return 0 on success, -1 on failure. */
int
tls_init (void)
{
SSL_load_error_strings ();
SSL_library_init ();
return init_openssl_rand_ ();
}

int
rs_tls_init (struct rs_connection *conn)
tls_init_conn (struct rs_connection *conn)
{
struct rs_context *ctx = NULL;
struct tls *tlsconf = NULL;
Expand Down
12 changes: 11 additions & 1 deletion lib/tls.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,19 @@
extern "C" {
#endif

int rs_tls_init (struct rs_connection *conn);
int tls_init (void);
int tls_init_conn (struct rs_connection *conn);
int tls_verify_cert (struct rs_connection *conn);

#define OPENSSL_VER(a,b,c,d,e) \
(((a)<<28) | \
((b)<<20) | \
((c)<<12) | \
((d)<< 4) | \
(e))
#define OPENSSL_V(a,b,c,d) \
OPENSSL_VER((a),(b),(c),(d)-'a'+1,0xf)

#if defined (__cplusplus)
}
#endif

0 comments on commit 11570f6

Please sign in to comment.