mirror of
https://github.com/matrix-construct/construct
synced 2024-12-28 00:14:07 +01:00
libratbox: initial cut at an mbedtls implementation, which will replace openssl and gnutls backends in charybdis 3.6
notably, it presently is lacking CertFP support, but everything else is implemented
This commit is contained in:
parent
6f57a957b0
commit
cd492e44b5
6 changed files with 604 additions and 11 deletions
|
@ -282,6 +282,8 @@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
|
|||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MANIFEST_TOOL = @MANIFEST_TOOL@
|
||||
MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@
|
||||
MBEDTLS_LIBS = @MBEDTLS_LIBS@
|
||||
MKDIR_P = @MKDIR_P@
|
||||
MV = @MV@
|
||||
NM = @NM@
|
||||
|
|
4
libratbox/configure
vendored
4
libratbox/configure
vendored
|
@ -637,6 +637,8 @@ am__EXEEXT_TRUE
|
|||
LTLIBOBJS
|
||||
LIBOBJS
|
||||
RB_PREFIX
|
||||
MBEDTLS_LIBS
|
||||
MBEDTLS_CFLAGS
|
||||
SSL_LIBS
|
||||
SSL_CFLAGS
|
||||
SEDOBJ
|
||||
|
@ -15358,6 +15360,8 @@ fi
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
if test "$prefix" = "NONE"; then
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
|
|
|
@ -466,6 +466,8 @@ AC_SUBST(SSL_CFLAGS)
|
|||
AC_SUBST(SSL_LIBS)
|
||||
AC_SUBST(GNUTLS_CFLAGS)
|
||||
AC_SUBST(GNUTLS_LIBS)
|
||||
AC_SUBST(MBEDTLS_CFLAGS)
|
||||
AC_SUBST(MBEDTLS_LIBS)
|
||||
|
||||
if test "$prefix" = "NONE"; then
|
||||
AC_DEFINE_UNQUOTED(RB_PREFIX, "$ac_default_prefix", [Prefix where libratbox is installed.])
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
|
||||
INCLUDES = -I. -I../include @SSL_CFLAGS@ @GNUTLS_CFLAGS@
|
||||
INCLUDES = -I. -I../include @SSL_CFLAGS@ @GNUTLS_CFLAGS@ @MBEDTLS_CFLAGS@
|
||||
|
||||
BUILT_SOURCES = version.c
|
||||
|
||||
|
@ -19,6 +19,7 @@ libratbox_la_SOURCES = \
|
|||
crypt.c \
|
||||
balloc.c \
|
||||
commio.c \
|
||||
mbedtls.c \
|
||||
openssl.c \
|
||||
gnutls.c \
|
||||
nossl.c \
|
||||
|
@ -41,8 +42,7 @@ libratbox_la_SOURCES = \
|
|||
arc4random.c \
|
||||
version.c
|
||||
|
||||
|
||||
libratbox_la_LDFLAGS = @SSL_LIBS@ @GNUTLS_LIBS@ -avoid-version -no-undefined -export-symbols export-syms.txt
|
||||
libratbox_la_LIBADD = @SSL_LIBS@ @GNUTLS_LIBS@
|
||||
libratbox_la_LDFLAGS = @SSL_LIBS@ @GNUTLS_LIBS@ @MBEDTLS_LIBS@ -avoid-version -no-undefined -export-symbols export-syms.txt
|
||||
libratbox_la_LIBADD = @SSL_LIBS@ @GNUTLS_LIBS@ @MBEDTLS_LIBS@
|
||||
lib_LTLIBRARIES = libratbox.la
|
||||
|
||||
|
|
|
@ -132,10 +132,11 @@ am__installdirs = "$(DESTDIR)$(libdir)"
|
|||
LTLIBRARIES = $(lib_LTLIBRARIES)
|
||||
libratbox_la_DEPENDENCIES =
|
||||
am_libratbox_la_OBJECTS = unix.lo win32.lo crypt.lo balloc.lo \
|
||||
commio.lo openssl.lo gnutls.lo nossl.lo event.lo ratbox_lib.lo \
|
||||
rb_memory.lo linebuf.lo snprintf.lo tools.lo helper.lo \
|
||||
devpoll.lo epoll.lo poll.lo ports.lo sigio.lo select.lo \
|
||||
kqueue.lo rawbuf.lo patricia.lo arc4random.lo version.lo
|
||||
commio.lo mbedtls.lo openssl.lo gnutls.lo nossl.lo event.lo \
|
||||
ratbox_lib.lo rb_memory.lo linebuf.lo snprintf.lo tools.lo \
|
||||
helper.lo devpoll.lo epoll.lo poll.lo ports.lo sigio.lo \
|
||||
select.lo kqueue.lo rawbuf.lo patricia.lo arc4random.lo \
|
||||
version.lo
|
||||
libratbox_la_OBJECTS = $(am_libratbox_la_OBJECTS)
|
||||
AM_V_lt = $(am__v_lt_@AM_V@)
|
||||
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
|
||||
|
@ -255,6 +256,8 @@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
|
|||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MANIFEST_TOOL = @MANIFEST_TOOL@
|
||||
MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@
|
||||
MBEDTLS_LIBS = @MBEDTLS_LIBS@
|
||||
MKDIR_P = @MKDIR_P@
|
||||
MV = @MV@
|
||||
NM = @NM@
|
||||
|
@ -340,7 +343,7 @@ top_build_prefix = @top_build_prefix@
|
|||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
INCLUDES = -I. -I../include @SSL_CFLAGS@ @GNUTLS_CFLAGS@
|
||||
INCLUDES = -I. -I../include @SSL_CFLAGS@ @GNUTLS_CFLAGS@ @MBEDTLS_CFLAGS@
|
||||
BUILT_SOURCES = version.c
|
||||
libratbox_la_SOURCES = \
|
||||
unix.c \
|
||||
|
@ -348,6 +351,7 @@ libratbox_la_SOURCES = \
|
|||
crypt.c \
|
||||
balloc.c \
|
||||
commio.c \
|
||||
mbedtls.c \
|
||||
openssl.c \
|
||||
gnutls.c \
|
||||
nossl.c \
|
||||
|
@ -370,8 +374,8 @@ libratbox_la_SOURCES = \
|
|||
arc4random.c \
|
||||
version.c
|
||||
|
||||
libratbox_la_LDFLAGS = @SSL_LIBS@ @GNUTLS_LIBS@ -avoid-version -no-undefined -export-symbols export-syms.txt
|
||||
libratbox_la_LIBADD = @SSL_LIBS@ @GNUTLS_LIBS@
|
||||
libratbox_la_LDFLAGS = @SSL_LIBS@ @GNUTLS_LIBS@ @MBEDTLS_LIBS@ -avoid-version -no-undefined -export-symbols export-syms.txt
|
||||
libratbox_la_LIBADD = @SSL_LIBS@ @GNUTLS_LIBS@ @MBEDTLS_LIBS@
|
||||
lib_LTLIBRARIES = libratbox.la
|
||||
all: $(BUILT_SOURCES)
|
||||
$(MAKE) $(AM_MAKEFLAGS) all-am
|
||||
|
@ -463,6 +467,7 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/helper.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kqueue.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linebuf.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mbedtls.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nossl.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/patricia.Plo@am__quote@
|
||||
|
|
580
libratbox/src/mbedtls.c
Normal file
580
libratbox/src/mbedtls.c
Normal file
|
@ -0,0 +1,580 @@
|
|||
/*
|
||||
* libratbox: a library used by ircd-ratbox and other things
|
||||
* mbedtls.c: mbedtls related code
|
||||
*
|
||||
* Copyright (C) 2007-2008 ircd-ratbox development team
|
||||
* Copyright (C) 2007-2008 Aaron Sethman <androsyn@ratbox.org>
|
||||
* Copyright (C) 2015 William Pitcock <nenolod@dereferenced.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
* USA
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <libratbox_config.h>
|
||||
#include <ratbox_lib.h>
|
||||
#include <commio-int.h>
|
||||
#include <commio-ssl.h>
|
||||
|
||||
#ifdef HAVE_MBEDTLS
|
||||
|
||||
#include "mbedtls/entropy.h"
|
||||
#include "mbedtls/ctr_drbg.h"
|
||||
#include "mbedtls/certs.h"
|
||||
#include "mbedtls/x509.h"
|
||||
#include "mbedtls/ssl.h"
|
||||
#include "mbedtls/net.h"
|
||||
#include "mbedtls/error.h"
|
||||
#include "mbedtls/debug.h"
|
||||
#include "mbedtls/dhm.h"
|
||||
#include "mbedtls/version.h"
|
||||
|
||||
static mbedtls_x509_crt x509;
|
||||
static mbedtls_pk_context serv_pk;
|
||||
static mbedtls_dhm_context dh_params;
|
||||
static mbedtls_ctr_drbg_context ctr_drbg;
|
||||
static mbedtls_entropy_context entropy;
|
||||
static mbedtls_ssl_config serv_config;
|
||||
static mbedtls_ssl_config client_config;
|
||||
|
||||
#define SSL_P(x) ((mbedtls_ssl_context *)F->ssl)
|
||||
|
||||
void
|
||||
rb_ssl_shutdown(rb_fde_t *F)
|
||||
{
|
||||
int i;
|
||||
if(F == NULL || F->ssl == NULL)
|
||||
return;
|
||||
for(i = 0; i < 4; i++)
|
||||
{
|
||||
int r = mbedtls_ssl_close_notify(SSL_P(F));
|
||||
if(r != MBEDTLS_ERR_SSL_WANT_READ && r != MBEDTLS_ERR_SSL_WANT_WRITE)
|
||||
break;
|
||||
}
|
||||
mbedtls_ssl_free(SSL_P(F));
|
||||
rb_free(F->ssl);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
rb_ssl_handshake_count(rb_fde_t *F)
|
||||
{
|
||||
return F->handshake_count;
|
||||
}
|
||||
|
||||
void
|
||||
rb_ssl_clear_handshake_count(rb_fde_t *F)
|
||||
{
|
||||
F->handshake_count = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
rb_ssl_timeout(rb_fde_t *F, void *notused)
|
||||
{
|
||||
lrb_assert(F->accept != NULL);
|
||||
F->accept->callback(F, RB_ERR_TIMEOUT, NULL, 0, F->accept->data);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
do_ssl_handshake(rb_fde_t *F, PF * callback, void *data)
|
||||
{
|
||||
int ret;
|
||||
int flags;
|
||||
|
||||
ret = mbedtls_ssl_handshake(SSL_P(F));
|
||||
if(ret < 0)
|
||||
{
|
||||
if((ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE))
|
||||
{
|
||||
if(ret == MBEDTLS_ERR_SSL_WANT_READ)
|
||||
flags = RB_SELECT_READ;
|
||||
else
|
||||
flags = RB_SELECT_WRITE;
|
||||
rb_setselect(F, flags, callback, data);
|
||||
return 0;
|
||||
}
|
||||
F->ssl_errno = ret;
|
||||
return -1;
|
||||
}
|
||||
return 1; /* handshake is finished..go about life */
|
||||
}
|
||||
|
||||
static void
|
||||
rb_ssl_tryaccept(rb_fde_t *F, void *data)
|
||||
{
|
||||
int ret;
|
||||
struct acceptdata *ad;
|
||||
|
||||
lrb_assert(F->accept != NULL);
|
||||
|
||||
ret = do_ssl_handshake(F, rb_ssl_tryaccept, NULL);
|
||||
|
||||
/* do_ssl_handshake does the rb_setselect */
|
||||
if(ret == 0)
|
||||
return;
|
||||
|
||||
ad = F->accept;
|
||||
F->accept = NULL;
|
||||
rb_settimeout(F, 0, NULL, NULL);
|
||||
rb_setselect(F, RB_SELECT_READ | RB_SELECT_WRITE, NULL, NULL);
|
||||
|
||||
if(ret > 0)
|
||||
ad->callback(F, RB_OK, (struct sockaddr *)&ad->S, ad->addrlen, ad->data);
|
||||
else
|
||||
ad->callback(F, RB_ERROR_SSL, NULL, 0, ad->data);
|
||||
|
||||
rb_free(ad);
|
||||
}
|
||||
|
||||
static int
|
||||
rb_ssl_read_cb(void *opaque, unsigned char *buf, size_t size)
|
||||
{
|
||||
rb_fde_t *F = opaque;
|
||||
|
||||
return read(F->fd, buf, size);
|
||||
}
|
||||
|
||||
static int
|
||||
rb_ssl_write_cb(void *opaque, const unsigned char *buf, size_t size)
|
||||
{
|
||||
rb_fde_t *F = opaque;
|
||||
|
||||
return write(F->fd, buf, size);
|
||||
}
|
||||
|
||||
static void
|
||||
rb_ssl_setup_srv_context(rb_fde_t *F, mbedtls_ssl_context *ssl)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mbedtls_ssl_init(ssl);
|
||||
if ((ret = mbedtls_ssl_setup(ssl, &serv_config)) != 0)
|
||||
{
|
||||
rb_lib_log("rb_ssl_setup_srv_context: failed to set up ssl context: -0x%x", -ret);
|
||||
rb_close(F);
|
||||
return;
|
||||
}
|
||||
|
||||
mbedtls_ssl_set_bio(ssl, F, rb_ssl_write_cb, rb_ssl_read_cb, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
rb_ssl_start_accepted(rb_fde_t *new_F, ACCB * cb, void *data, int timeout)
|
||||
{
|
||||
mbedtls_ssl_context *ssl;
|
||||
new_F->type |= RB_FD_SSL;
|
||||
ssl = new_F->ssl = rb_malloc(sizeof(mbedtls_ssl_context));
|
||||
new_F->accept = rb_malloc(sizeof(struct acceptdata));
|
||||
|
||||
new_F->accept->callback = cb;
|
||||
new_F->accept->data = data;
|
||||
rb_settimeout(new_F, timeout, rb_ssl_timeout, NULL);
|
||||
|
||||
new_F->accept->addrlen = 0;
|
||||
|
||||
rb_ssl_setup_srv_context(new_F, ssl);
|
||||
if(do_ssl_handshake(new_F, rb_ssl_tryaccept, NULL))
|
||||
{
|
||||
struct acceptdata *ad = new_F->accept;
|
||||
new_F->accept = NULL;
|
||||
ad->callback(new_F, RB_OK, (struct sockaddr *)&ad->S, ad->addrlen, ad->data);
|
||||
rb_free(ad);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rb_ssl_accept_setup(rb_fde_t *F, rb_fde_t *new_F, struct sockaddr *st, int addrlen)
|
||||
{
|
||||
new_F->type |= RB_FD_SSL;
|
||||
new_F->ssl = rb_malloc(sizeof(mbedtls_ssl_context));
|
||||
new_F->accept = rb_malloc(sizeof(struct acceptdata));
|
||||
|
||||
new_F->accept->callback = F->accept->callback;
|
||||
new_F->accept->data = F->accept->data;
|
||||
rb_settimeout(new_F, 10, rb_ssl_timeout, NULL);
|
||||
memcpy(&new_F->accept->S, st, addrlen);
|
||||
new_F->accept->addrlen = addrlen;
|
||||
|
||||
rb_ssl_setup_srv_context(new_F, new_F->ssl);
|
||||
if(do_ssl_handshake(F, rb_ssl_tryaccept, NULL))
|
||||
{
|
||||
struct acceptdata *ad = F->accept;
|
||||
F->accept = NULL;
|
||||
ad->callback(F, RB_OK, (struct sockaddr *)&ad->S, ad->addrlen, ad->data);
|
||||
rb_free(ad);
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
rb_ssl_read_or_write(int r_or_w, rb_fde_t *F, void *rbuf, const void *wbuf, size_t count)
|
||||
{
|
||||
ssize_t ret;
|
||||
|
||||
if(r_or_w == 0)
|
||||
ret = mbedtls_ssl_read(F->ssl, rbuf, count);
|
||||
else
|
||||
ret = mbedtls_ssl_write(F->ssl, wbuf, count);
|
||||
|
||||
if(ret < 0)
|
||||
{
|
||||
switch (ret)
|
||||
{
|
||||
case MBEDTLS_ERR_SSL_WANT_READ:
|
||||
return RB_RW_SSL_NEED_READ;
|
||||
case MBEDTLS_ERR_SSL_WANT_WRITE:
|
||||
return RB_RW_SSL_NEED_WRITE;
|
||||
default:
|
||||
F->ssl_errno = ret;
|
||||
errno = EIO;
|
||||
return RB_RW_IO_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
rb_ssl_read(rb_fde_t *F, void *buf, size_t count)
|
||||
{
|
||||
return rb_ssl_read_or_write(0, F, buf, NULL, count);
|
||||
}
|
||||
|
||||
ssize_t
|
||||
rb_ssl_write(rb_fde_t *F, const void *buf, size_t count)
|
||||
{
|
||||
return rb_ssl_read_or_write(1, F, NULL, buf, count);
|
||||
}
|
||||
|
||||
int
|
||||
rb_init_ssl(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mbedtls_entropy_init(&entropy);
|
||||
mbedtls_ctr_drbg_init(&ctr_drbg);
|
||||
|
||||
if((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0)) != 0)
|
||||
{
|
||||
rb_lib_log("rb_init_prng: unable to initialize PRNG, mbedtls_ctr_drbg_seed() returned -0x%x", -ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
mbedtls_ssl_config_init(&serv_config);
|
||||
|
||||
if ((ret = mbedtls_ssl_config_defaults(&serv_config,
|
||||
MBEDTLS_SSL_IS_SERVER,
|
||||
MBEDTLS_SSL_TRANSPORT_STREAM,
|
||||
MBEDTLS_SSL_PRESET_DEFAULT)) != 0)
|
||||
{
|
||||
rb_lib_log("rb_init_ssl: unable to initialize default SSL parameters for server context: -0x%x", -ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
mbedtls_ssl_conf_rng(&serv_config, mbedtls_ctr_drbg_random, &ctr_drbg);
|
||||
|
||||
/***************************************************************************************************************/
|
||||
|
||||
mbedtls_ssl_config_init(&client_config);
|
||||
|
||||
if ((ret = mbedtls_ssl_config_defaults(&client_config,
|
||||
MBEDTLS_SSL_IS_CLIENT,
|
||||
MBEDTLS_SSL_TRANSPORT_STREAM,
|
||||
MBEDTLS_SSL_PRESET_DEFAULT)) != 0)
|
||||
{
|
||||
rb_lib_log("rb_init_ssl: unable to initialize default SSL parameters for client context: -0x%x", -ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
mbedtls_ssl_conf_rng(&serv_config, mbedtls_ctr_drbg_random, &ctr_drbg);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mbedtls_x509_crt_init(&x509);
|
||||
ret = mbedtls_x509_crt_parse_file(&x509, cert);
|
||||
if (ret != 0)
|
||||
{
|
||||
rb_lib_log("rb_setup_ssl_server: failed to parse certificate '%s': -0x%x", -ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
mbedtls_pk_init(&serv_pk);
|
||||
ret = mbedtls_pk_parse_keyfile(&serv_pk, keyfile, NULL);
|
||||
if (ret != 0)
|
||||
{
|
||||
rb_lib_log("rb_setup_ssl_server: failed to parse private key '%s': -0x%x", -ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
mbedtls_dhm_init(&dh_params);
|
||||
ret = mbedtls_dhm_parse_dhmfile(&dh_params, dhfile);
|
||||
if (ret != 0)
|
||||
{
|
||||
rb_lib_log("rb_setup_ssl_server: failed to parse DH parameters '%s': -0x%x", -ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = mbedtls_ssl_conf_dh_param_ctx(&serv_config, &dh_params);
|
||||
if (ret != 0)
|
||||
{
|
||||
rb_lib_log("rb_setup_ssl_server: failed to set DH parameters on SSL config context: -0x%x", -ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (x509.next)
|
||||
mbedtls_ssl_conf_ca_chain(&serv_config, x509.next, NULL);
|
||||
|
||||
if ((ret = mbedtls_ssl_conf_own_cert(&serv_config, &x509, &serv_pk)) != 0)
|
||||
{
|
||||
rb_lib_log("rb_setup_ssl_server: failed to set up own certificate: -0x%x", -ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
rb_ssl_listen(rb_fde_t *F, int backlog, int defer_accept)
|
||||
{
|
||||
int result;
|
||||
|
||||
result = rb_listen(F, backlog, defer_accept);
|
||||
F->type = RB_FD_SOCKET | RB_FD_LISTEN | RB_FD_SSL;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
struct ssl_connect
|
||||
{
|
||||
CNCB *callback;
|
||||
void *data;
|
||||
int timeout;
|
||||
};
|
||||
|
||||
static void
|
||||
rb_ssl_connect_realcb(rb_fde_t *F, int status, struct ssl_connect *sconn)
|
||||
{
|
||||
F->connect->callback = sconn->callback;
|
||||
F->connect->data = sconn->data;
|
||||
rb_free(sconn);
|
||||
rb_connect_callback(F, status);
|
||||
}
|
||||
|
||||
static void
|
||||
rb_ssl_tryconn_timeout_cb(rb_fde_t *F, void *data)
|
||||
{
|
||||
rb_ssl_connect_realcb(F, RB_ERR_TIMEOUT, data);
|
||||
}
|
||||
|
||||
static void
|
||||
rb_ssl_tryconn_cb(rb_fde_t *F, void *data)
|
||||
{
|
||||
struct ssl_connect *sconn = data;
|
||||
int ret;
|
||||
|
||||
ret = do_ssl_handshake(F, rb_ssl_tryconn_cb, (void *)sconn);
|
||||
|
||||
switch (ret)
|
||||
{
|
||||
case -1:
|
||||
rb_ssl_connect_realcb(F, RB_ERROR_SSL, sconn);
|
||||
break;
|
||||
case 0:
|
||||
/* do_ssl_handshake does the rb_setselect stuff */
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
rb_ssl_connect_realcb(F, RB_OK, sconn);
|
||||
}
|
||||
|
||||
static void
|
||||
rb_ssl_setup_client_context(rb_fde_t *F, mbedtls_ssl_context *ssl)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mbedtls_ssl_init(ssl);
|
||||
if ((ret = mbedtls_ssl_setup(ssl, &client_config)) != 0)
|
||||
{
|
||||
rb_lib_log("rb_ssl_setup_client_context: failed to set up ssl context: -0x%x", -ret);
|
||||
rb_close(F);
|
||||
return;
|
||||
}
|
||||
|
||||
mbedtls_ssl_set_bio(ssl, F, rb_ssl_write_cb, rb_ssl_read_cb, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
rb_ssl_tryconn(rb_fde_t *F, int status, void *data)
|
||||
{
|
||||
struct ssl_connect *sconn = data;
|
||||
if(status != RB_OK)
|
||||
{
|
||||
rb_ssl_connect_realcb(F, status, sconn);
|
||||
return;
|
||||
}
|
||||
|
||||
F->type |= RB_FD_SSL;
|
||||
|
||||
|
||||
rb_settimeout(F, sconn->timeout, rb_ssl_tryconn_timeout_cb, sconn);
|
||||
F->ssl = rb_malloc(sizeof(mbedtls_ssl_context));
|
||||
rb_ssl_setup_client_context(F, F->ssl);
|
||||
|
||||
do_ssl_handshake(F, rb_ssl_tryconn_cb, (void *)sconn);
|
||||
}
|
||||
|
||||
void
|
||||
rb_connect_tcp_ssl(rb_fde_t *F, struct sockaddr *dest,
|
||||
struct sockaddr *clocal, int socklen, CNCB * callback, void *data, int timeout)
|
||||
{
|
||||
struct ssl_connect *sconn;
|
||||
if(F == NULL)
|
||||
return;
|
||||
|
||||
sconn = rb_malloc(sizeof(struct ssl_connect));
|
||||
sconn->data = data;
|
||||
sconn->callback = callback;
|
||||
sconn->timeout = timeout;
|
||||
rb_connect_tcp(F, dest, clocal, socklen, rb_ssl_tryconn, sconn, timeout);
|
||||
}
|
||||
|
||||
void
|
||||
rb_ssl_start_connected(rb_fde_t *F, CNCB * callback, void *data, int timeout)
|
||||
{
|
||||
struct ssl_connect *sconn;
|
||||
if(F == NULL)
|
||||
return;
|
||||
|
||||
sconn = rb_malloc(sizeof(struct ssl_connect));
|
||||
sconn->data = data;
|
||||
sconn->callback = callback;
|
||||
sconn->timeout = timeout;
|
||||
F->connect = rb_malloc(sizeof(struct conndata));
|
||||
F->connect->callback = callback;
|
||||
F->connect->data = data;
|
||||
F->type |= RB_FD_SSL;
|
||||
F->ssl = rb_malloc(sizeof(mbedtls_ssl_context));
|
||||
|
||||
rb_ssl_setup_client_context(F, F->ssl);
|
||||
rb_settimeout(F, sconn->timeout, rb_ssl_tryconn_timeout_cb, sconn);
|
||||
|
||||
do_ssl_handshake(F, rb_ssl_tryconn_cb, (void *)sconn);
|
||||
}
|
||||
|
||||
int
|
||||
rb_init_prng(const char *path, prng_seed_t seed_type)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
rb_get_random(void *buf, size_t length)
|
||||
{
|
||||
if (mbedtls_ctr_drbg_random(&ctr_drbg, buf, length))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *
|
||||
rb_get_ssl_strerror(rb_fde_t *F)
|
||||
{
|
||||
#ifdef MBEDTLS_ERROR_C
|
||||
static char errbuf[512];
|
||||
mbedtls_strerror(F->ssl_errno, errbuf, sizeof errbuf);
|
||||
return errbuf;
|
||||
#else
|
||||
return "???";
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
rb_get_ssl_certfp(rb_fde_t *F, uint8_t certfp[RB_SSL_CERTFP_LEN])
|
||||
{
|
||||
const mbedtls_x509_crt *peer_cert;
|
||||
|
||||
peer_cert = mbedtls_ssl_get_peer_cert(SSL_P(F));
|
||||
if (peer_cert == NULL)
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
#if 0
|
||||
gnutls_x509_crt_t cert;
|
||||
unsigned int cert_list_size;
|
||||
const gnutls_datum_t *cert_list;
|
||||
uint8_t digest[RB_SSL_CERTFP_LEN * 2];
|
||||
size_t digest_size;
|
||||
|
||||
if (gnutls_certificate_type_get(SSL_P(F)) != GNUTLS_CRT_X509)
|
||||
return 0;
|
||||
|
||||
if (gnutls_x509_crt_init(&cert) < 0)
|
||||
return 0;
|
||||
|
||||
cert_list_size = 0;
|
||||
cert_list = gnutls_certificate_get_peers(SSL_P(F), &cert_list_size);
|
||||
if (cert_list == NULL)
|
||||
{
|
||||
gnutls_x509_crt_deinit(cert);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER) < 0)
|
||||
{
|
||||
gnutls_x509_crt_deinit(cert);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_SHA1, digest, &digest_size) < 0)
|
||||
{
|
||||
gnutls_x509_crt_deinit(cert);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(certfp, digest, RB_SSL_CERTFP_LEN);
|
||||
|
||||
gnutls_x509_crt_deinit(cert);
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
rb_supports_ssl(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
rb_get_ssl_info(char *buf, size_t len)
|
||||
{
|
||||
char version_str[512];
|
||||
mbedtls_version_get_string(version_str);
|
||||
|
||||
rb_snprintf(buf, len, "MBEDTLS: compiled (%s), library(%s)",
|
||||
MBEDTLS_VERSION_STRING, version_str);
|
||||
}
|
||||
|
||||
|
||||
#endif /* HAVE_GNUTLS */
|
Loading…
Reference in a new issue