[mbedtls] Various fixes and improvements
* Move certificate, key, DH parameters and configuration to heap (Documentation states that setting new configuration, e.g. during a rehash, is unsupported while connections using that configuration are active) This is the same approach as the fix for #186 Refcount these structures so as to not introduce a memory leak On rehash, it will use new structures only if there are no errors in constructing them * Make fingerprint generation work for TLS connections See the comments in the newly created file for an explanation * Fix memory leak when generating a fingerprint from a file * Add better error-reporting (strings in addition to numbers) where possible * Coalesce several connection memory allocations into one function * Reduce boilerplate where possible (Charybdis targets C99) * Support private key being in certificate file, and having no DH parameters file * Correct erroneous closing comment
This commit is contained in:
parent
c40eede13b
commit
1e7342d0f4
2 changed files with 430 additions and 231 deletions
|
@ -1,10 +1,11 @@
|
|||
/*
|
||||
* librb: a library used by ircd-ratbox and other things
|
||||
* mbedtls.c: mbedtls related code
|
||||
* mbedtls.c: ARM mbedTLS backend
|
||||
*
|
||||
* 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>
|
||||
* Copyright (C) 2016 Aaron Jones <aaronmdjones@gmail.com>
|
||||
*
|
||||
* 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
|
||||
|
@ -42,29 +43,149 @@
|
|||
#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;
|
||||
#include "mbedtls_embedded_data.h"
|
||||
|
||||
#define SSL_P(x) ((mbedtls_ssl_context *)F->ssl)
|
||||
typedef struct
|
||||
{
|
||||
mbedtls_x509_crt crt;
|
||||
mbedtls_pk_context key;
|
||||
mbedtls_dhm_context dhp;
|
||||
mbedtls_ssl_config server_cfg;
|
||||
mbedtls_ssl_config client_cfg;
|
||||
size_t refcount;
|
||||
} rb_mbedtls_cfg_context;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
rb_mbedtls_cfg_context *cfg;
|
||||
mbedtls_ssl_context ssl;
|
||||
} rb_mbedtls_ssl_context;
|
||||
|
||||
#define SSL_C(x) ((rb_mbedtls_ssl_context *) (x)->ssl)->cfg
|
||||
#define SSL_P(x) &((rb_mbedtls_ssl_context *) (x)->ssl)->ssl
|
||||
|
||||
static mbedtls_ctr_drbg_context ctr_drbg_ctx;
|
||||
static mbedtls_entropy_context entropy_ctx;
|
||||
|
||||
static mbedtls_x509_crt dummy_ca_ctx;
|
||||
static rb_mbedtls_cfg_context *rb_mbedtls_cfg = NULL;
|
||||
|
||||
static const char *
|
||||
rb_get_ssl_strerror_internal(int err)
|
||||
{
|
||||
static char errbuf[512];
|
||||
|
||||
#ifdef MBEDTLS_ERROR_C
|
||||
char mbed_errbuf[512];
|
||||
mbedtls_strerror(err, mbed_errbuf, sizeof mbed_errbuf);
|
||||
snprintf(errbuf, sizeof errbuf, "(-0x%x) %s", -err, mbed_errbuf);
|
||||
#else
|
||||
snprintf(errbuf, sizeof errbuf, "-0x%x", -err);
|
||||
#endif
|
||||
|
||||
return errbuf;
|
||||
}
|
||||
|
||||
const char *
|
||||
rb_get_ssl_strerror(rb_fde_t *F)
|
||||
{
|
||||
return rb_get_ssl_strerror_internal(F->ssl_errno);
|
||||
}
|
||||
|
||||
static void rb_mbedtls_cfg_incref(rb_mbedtls_cfg_context *cfg)
|
||||
{
|
||||
lrb_assert(cfg->refcount > 0);
|
||||
|
||||
cfg->refcount++;
|
||||
}
|
||||
|
||||
static void rb_mbedtls_cfg_decref(rb_mbedtls_cfg_context *cfg)
|
||||
{
|
||||
if(cfg == NULL)
|
||||
return;
|
||||
|
||||
lrb_assert(cfg->refcount > 0);
|
||||
|
||||
if((--cfg->refcount) > 0)
|
||||
return;
|
||||
|
||||
mbedtls_ssl_config_free(&cfg->client_cfg);
|
||||
mbedtls_ssl_config_free(&cfg->server_cfg);
|
||||
mbedtls_dhm_free(&cfg->dhp);
|
||||
mbedtls_pk_free(&cfg->key);
|
||||
mbedtls_x509_crt_free(&cfg->crt);
|
||||
|
||||
rb_free(cfg);
|
||||
}
|
||||
|
||||
static rb_mbedtls_cfg_context *rb_mbedtls_cfg_new(void)
|
||||
{
|
||||
rb_mbedtls_cfg_context *cfg;
|
||||
int ret;
|
||||
|
||||
if((cfg = rb_malloc(sizeof(rb_mbedtls_cfg_context))) == NULL)
|
||||
return NULL;
|
||||
|
||||
mbedtls_x509_crt_init(&cfg->crt);
|
||||
mbedtls_pk_init(&cfg->key);
|
||||
mbedtls_dhm_init(&cfg->dhp);
|
||||
mbedtls_ssl_config_init(&cfg->server_cfg);
|
||||
mbedtls_ssl_config_init(&cfg->client_cfg);
|
||||
|
||||
cfg->refcount = 1;
|
||||
|
||||
if((ret = mbedtls_ssl_config_defaults(&cfg->server_cfg,
|
||||
MBEDTLS_SSL_IS_SERVER, MBEDTLS_SSL_TRANSPORT_STREAM,
|
||||
MBEDTLS_SSL_PRESET_DEFAULT)) != 0)
|
||||
{
|
||||
rb_lib_log("rb_mbedtls_cfg_new: ssl_config_defaults (server): %s",
|
||||
rb_get_ssl_strerror_internal(ret));
|
||||
rb_mbedtls_cfg_decref(cfg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if((ret = mbedtls_ssl_config_defaults(&cfg->client_cfg,
|
||||
MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM,
|
||||
MBEDTLS_SSL_PRESET_DEFAULT)) != 0)
|
||||
{
|
||||
rb_lib_log("rb_mbedtls_cfg_new: ssl_config_defaults (client): %s",
|
||||
rb_get_ssl_strerror_internal(ret));
|
||||
rb_mbedtls_cfg_decref(cfg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mbedtls_ssl_conf_rng(&cfg->server_cfg, mbedtls_ctr_drbg_random, &ctr_drbg_ctx);
|
||||
mbedtls_ssl_conf_rng(&cfg->client_cfg, mbedtls_ctr_drbg_random, &ctr_drbg_ctx);
|
||||
|
||||
mbedtls_ssl_conf_ca_chain(&cfg->server_cfg, &dummy_ca_ctx, NULL);
|
||||
mbedtls_ssl_conf_ca_chain(&cfg->client_cfg, &dummy_ca_ctx, NULL);
|
||||
|
||||
mbedtls_ssl_conf_authmode(&cfg->server_cfg, MBEDTLS_SSL_VERIFY_OPTIONAL);
|
||||
mbedtls_ssl_conf_authmode(&cfg->client_cfg, MBEDTLS_SSL_VERIFY_NONE);
|
||||
|
||||
return cfg;
|
||||
}
|
||||
|
||||
void
|
||||
rb_ssl_shutdown(rb_fde_t *F)
|
||||
{
|
||||
int i;
|
||||
if(F == NULL || F->ssl == NULL)
|
||||
return;
|
||||
for(i = 0; i < 4; i++)
|
||||
|
||||
if(SSL_P(F) != NULL)
|
||||
{
|
||||
for(int 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));
|
||||
}
|
||||
|
||||
if(SSL_C(F) != NULL)
|
||||
rb_mbedtls_cfg_decref(SSL_C(F));
|
||||
|
||||
rb_free(F->ssl);
|
||||
}
|
||||
|
||||
|
@ -87,50 +208,46 @@ rb_ssl_timeout(rb_fde_t *F, void *notused)
|
|||
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;
|
||||
int ret = mbedtls_ssl_handshake(SSL_P(F));
|
||||
|
||||
ret = mbedtls_ssl_handshake(SSL_P(F));
|
||||
if(ret < 0)
|
||||
if(ret == 0)
|
||||
{
|
||||
F->handshake_count++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(ret == -1 && rb_ignore_errno(errno))
|
||||
ret = MBEDTLS_ERR_SSL_WANT_READ;
|
||||
|
||||
if((ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE))
|
||||
switch(ret)
|
||||
{
|
||||
if(ret == MBEDTLS_ERR_SSL_WANT_READ)
|
||||
flags = RB_SELECT_READ;
|
||||
else
|
||||
flags = RB_SELECT_WRITE;
|
||||
rb_setselect(F, flags, callback, data);
|
||||
case MBEDTLS_ERR_SSL_WANT_READ:
|
||||
rb_setselect(F, RB_SELECT_READ, callback, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
case MBEDTLS_ERR_SSL_WANT_WRITE:
|
||||
rb_setselect(F, RB_SELECT_WRITE, callback, data);
|
||||
return 0;
|
||||
default:
|
||||
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);
|
||||
int ret = do_ssl_handshake(F, rb_ssl_tryaccept, NULL);
|
||||
|
||||
/* do_ssl_handshake does the rb_setselect */
|
||||
if(ret == 0)
|
||||
return;
|
||||
|
||||
ad = F->accept;
|
||||
struct acceptdata *ad = F->accept;
|
||||
F->accept = NULL;
|
||||
rb_settimeout(F, 0, NULL, NULL);
|
||||
rb_setselect(F, RB_SELECT_READ | RB_SELECT_WRITE, NULL, NULL);
|
||||
|
@ -146,10 +263,9 @@ rb_ssl_tryaccept(rb_fde_t *F, void *data)
|
|||
static int
|
||||
rb_ssl_read_cb(void *opaque, unsigned char *buf, size_t size)
|
||||
{
|
||||
int ret;
|
||||
rb_fde_t *F = opaque;
|
||||
|
||||
ret = read(F->fd, buf, size);
|
||||
int ret = (int) read(F->fd, buf, size);
|
||||
if(ret < 0 && rb_ignore_errno(errno))
|
||||
return MBEDTLS_ERR_SSL_WANT_READ;
|
||||
|
||||
|
@ -160,9 +276,8 @@ static int
|
|||
rb_ssl_write_cb(void *opaque, const unsigned char *buf, size_t size)
|
||||
{
|
||||
rb_fde_t *F = opaque;
|
||||
int ret;
|
||||
|
||||
ret = write(F->fd, buf, size);
|
||||
int ret = (int) write(F->fd, buf, size);
|
||||
if(ret < 0 && rb_ignore_errno(errno))
|
||||
return MBEDTLS_ERR_SSL_WANT_WRITE;
|
||||
|
||||
|
@ -170,42 +285,60 @@ rb_ssl_write_cb(void *opaque, const unsigned char *buf, size_t size)
|
|||
}
|
||||
|
||||
static void
|
||||
rb_ssl_setup_srv_context(rb_fde_t *F, mbedtls_ssl_context *ssl)
|
||||
rb_ssl_setup_mbed_context(rb_fde_t *F, bool is_server)
|
||||
{
|
||||
rb_mbedtls_ssl_context *mbed_ssl_ctx;
|
||||
mbedtls_ssl_config *mbed_config;
|
||||
int ret;
|
||||
|
||||
mbedtls_ssl_init(ssl);
|
||||
if ((ret = mbedtls_ssl_setup(ssl, &serv_config)) != 0)
|
||||
if((mbed_ssl_ctx = rb_malloc(sizeof(rb_mbedtls_ssl_context))) == NULL)
|
||||
{
|
||||
rb_lib_log("rb_ssl_setup_srv_context: failed to set up ssl context: -0x%x", -ret);
|
||||
rb_lib_log("rb_ssl_setup_mbed_context: rb_malloc: allocation failure");
|
||||
rb_close(F);
|
||||
return;
|
||||
}
|
||||
|
||||
mbedtls_ssl_set_bio(ssl, F, rb_ssl_write_cb, rb_ssl_read_cb, NULL);
|
||||
if(is_server)
|
||||
mbed_config = &rb_mbedtls_cfg->server_cfg;
|
||||
else
|
||||
mbed_config = &rb_mbedtls_cfg->client_cfg;
|
||||
|
||||
mbedtls_ssl_init(&mbed_ssl_ctx->ssl);
|
||||
mbedtls_ssl_set_bio(&mbed_ssl_ctx->ssl, F, rb_ssl_write_cb, rb_ssl_read_cb, NULL);
|
||||
|
||||
if((ret = mbedtls_ssl_setup(&mbed_ssl_ctx->ssl, mbed_config)) != 0)
|
||||
{
|
||||
rb_lib_log("rb_ssl_setup_mbed_context: ssl_setup: %s",
|
||||
rb_get_ssl_strerror_internal(ret));
|
||||
mbedtls_ssl_free(&mbed_ssl_ctx->ssl);
|
||||
rb_free(mbed_ssl_ctx);
|
||||
rb_close(F);
|
||||
return;
|
||||
}
|
||||
|
||||
mbed_ssl_ctx->cfg = rb_mbedtls_cfg;
|
||||
rb_mbedtls_cfg_incref(mbed_ssl_ctx->cfg);
|
||||
F->ssl = mbed_ssl_ctx;
|
||||
}
|
||||
|
||||
void
|
||||
rb_ssl_start_accepted(rb_fde_t *new_F, ACCB * cb, void *data, int timeout)
|
||||
rb_ssl_start_accepted(rb_fde_t *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));
|
||||
F->type |= RB_FD_SSL;
|
||||
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);
|
||||
F->accept->callback = cb;
|
||||
F->accept->data = data;
|
||||
rb_settimeout(F, timeout, rb_ssl_timeout, NULL);
|
||||
|
||||
new_F->accept->addrlen = 0;
|
||||
F->accept->addrlen = 0;
|
||||
|
||||
rb_ssl_setup_srv_context(new_F, ssl);
|
||||
if(do_ssl_handshake(new_F, rb_ssl_tryaccept, NULL))
|
||||
rb_ssl_setup_mbed_context(F, true);
|
||||
if(do_ssl_handshake(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);
|
||||
struct acceptdata *ad = F->accept;
|
||||
F->accept = NULL;
|
||||
ad->callback(F, RB_OK, (struct sockaddr *)&ad->S, ad->addrlen, ad->data);
|
||||
rb_free(ad);
|
||||
}
|
||||
}
|
||||
|
@ -214,35 +347,34 @@ 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);
|
||||
rb_ssl_setup_mbed_context(new_F, true);
|
||||
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)
|
||||
rb_ssl_read_or_write(bool do_read, 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);
|
||||
if(do_read)
|
||||
ret = mbedtls_ssl_read(SSL_P(F), rbuf, count);
|
||||
else
|
||||
ret = mbedtls_ssl_write(F->ssl, wbuf, count);
|
||||
ret = mbedtls_ssl_write(SSL_P(F), wbuf, count);
|
||||
|
||||
if(ret < 0)
|
||||
{
|
||||
|
@ -265,13 +397,13 @@ rb_ssl_read_or_write(int r_or_w, rb_fde_t *F, void *rbuf, const void *wbuf, size
|
|||
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);
|
||||
return rb_ssl_read_or_write(true, 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);
|
||||
return rb_ssl_read_or_write(false, F, NULL, buf, count);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -279,112 +411,112 @@ rb_init_ssl(void)
|
|||
{
|
||||
int ret;
|
||||
|
||||
mbedtls_entropy_init(&entropy);
|
||||
mbedtls_ctr_drbg_init(&ctr_drbg);
|
||||
mbedtls_ctr_drbg_init(&ctr_drbg_ctx);
|
||||
mbedtls_entropy_init(&entropy_ctx);
|
||||
|
||||
if((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0)) != 0)
|
||||
if((ret = mbedtls_ctr_drbg_seed(&ctr_drbg_ctx, mbedtls_entropy_func, &entropy_ctx,
|
||||
(const unsigned char *)rb_mbedtls_personal_str, sizeof(rb_mbedtls_personal_str))) != 0)
|
||||
{
|
||||
rb_lib_log("rb_init_prng: unable to initialize PRNG, mbedtls_ctr_drbg_seed() returned -0x%x", -ret);
|
||||
rb_lib_log("rb_init_ssl: ctr_drbg_seed: %s",
|
||||
rb_get_ssl_strerror_internal(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)
|
||||
if((ret = mbedtls_x509_crt_parse_der(&dummy_ca_ctx, rb_mbedtls_dummy_ca_certificate,
|
||||
sizeof(rb_mbedtls_dummy_ca_certificate))) != 0)
|
||||
{
|
||||
rb_lib_log("rb_init_ssl: unable to initialize default SSL parameters for server context: -0x%x", -ret);
|
||||
rb_lib_log("rb_init_ssl: x509_crt_parse_der (Dummy CA): %s",
|
||||
rb_get_ssl_strerror_internal(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(&client_config, mbedtls_ctr_drbg_random, &ctr_drbg);
|
||||
mbedtls_ssl_conf_authmode(&client_config, MBEDTLS_SSL_VERIFY_NONE);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile, const char *cipher_list)
|
||||
rb_setup_ssl_server(const char *certfile, const char *keyfile, const char *dhfile, const char *cipher_list)
|
||||
{
|
||||
rb_mbedtls_cfg_context *newcfg;
|
||||
int ret;
|
||||
|
||||
mbedtls_x509_crt_init(&x509);
|
||||
ret = mbedtls_x509_crt_parse_file(&x509, cert);
|
||||
if (ret != 0)
|
||||
if(certfile == NULL)
|
||||
{
|
||||
rb_lib_log("rb_setup_ssl_server: failed to parse certificate '%s': -0x%x", cert, -ret);
|
||||
rb_lib_log("rb_setup_ssl_server: no certificate file specified");
|
||||
return 0;
|
||||
}
|
||||
|
||||
mbedtls_pk_init(&serv_pk);
|
||||
ret = mbedtls_pk_parse_keyfile(&serv_pk, keyfile, NULL);
|
||||
if (ret != 0)
|
||||
if(keyfile == NULL)
|
||||
keyfile = certfile;
|
||||
|
||||
if((newcfg = rb_mbedtls_cfg_new()) == NULL)
|
||||
{
|
||||
rb_lib_log("rb_setup_ssl_server: failed to parse private key '%s': -0x%x", keyfile, -ret);
|
||||
rb_lib_log("rb_setup_ssl_server: rb_mbedtls_cfg_new: allocation failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
mbedtls_dhm_init(&dh_params);
|
||||
ret = mbedtls_dhm_parse_dhmfile(&dh_params, dhfile);
|
||||
if (ret != 0)
|
||||
if((ret = mbedtls_x509_crt_parse_file(&newcfg->crt, certfile)) != 0)
|
||||
{
|
||||
rb_lib_log("rb_setup_ssl_server: failed to parse DH parameters '%s': -0x%x", dhfile, -ret);
|
||||
rb_lib_log("rb_setup_ssl_server: x509_crt_parse_file ('%s'): %s",
|
||||
certfile, rb_get_ssl_strerror_internal(ret));
|
||||
rb_mbedtls_cfg_decref(newcfg);
|
||||
return 0;
|
||||
}
|
||||
if((ret = mbedtls_pk_parse_keyfile(&newcfg->key, keyfile, NULL)) != 0)
|
||||
{
|
||||
rb_lib_log("rb_setup_ssl_server: pk_parse_keyfile ('%s'): %s",
|
||||
keyfile, rb_get_ssl_strerror_internal(ret));
|
||||
rb_mbedtls_cfg_decref(newcfg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = mbedtls_ssl_conf_dh_param_ctx(&serv_config, &dh_params);
|
||||
if (ret != 0)
|
||||
/* Absense of DH parameters does not matter with mbedTLS, as it comes with its own defaults
|
||||
Thus, clients can still use DHE- ciphersuites, just over a weaker, common DH group
|
||||
So, we do not consider failure to parse DH parameters as fatal */
|
||||
if(dhfile == NULL)
|
||||
{
|
||||
rb_lib_log("rb_setup_ssl_server: failed to set DH parameters on SSL config context: -0x%x", -ret);
|
||||
rb_lib_log("rb_setup_ssl_server: no DH parameters file specified");
|
||||
}
|
||||
else
|
||||
{
|
||||
if((ret = mbedtls_dhm_parse_dhmfile(&newcfg->dhp, dhfile)) != 0)
|
||||
{
|
||||
rb_lib_log("rb_setup_ssl_server: dhm_parse_dhmfile ('%s'): %s",
|
||||
dhfile, rb_get_ssl_strerror_internal(ret));
|
||||
}
|
||||
else if((ret = mbedtls_ssl_conf_dh_param_ctx(&newcfg->server_cfg, &newcfg->dhp)) != 0)
|
||||
{
|
||||
rb_lib_log("rb_setup_ssl_server: ssl_conf_dh_param_ctx: %s",
|
||||
rb_get_ssl_strerror_internal(ret));
|
||||
}
|
||||
}
|
||||
|
||||
if((ret = mbedtls_ssl_conf_own_cert(&newcfg->server_cfg, &newcfg->crt, &newcfg->key)) != 0)
|
||||
{
|
||||
rb_lib_log("rb_setup_ssl_server: ssl_conf_own_cert (server): %s",
|
||||
rb_get_ssl_strerror_internal(ret));
|
||||
rb_mbedtls_cfg_decref(newcfg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (x509.next)
|
||||
if((ret = mbedtls_ssl_conf_own_cert(&newcfg->client_cfg, &newcfg->crt, &newcfg->key)) != 0)
|
||||
{
|
||||
mbedtls_ssl_conf_ca_chain(&serv_config, x509.next, NULL);
|
||||
mbedtls_ssl_conf_ca_chain(&client_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;
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_ssl_conf_own_cert(&client_config, &x509, &serv_pk)) != 0)
|
||||
{
|
||||
rb_lib_log("rb_setup_ssl_server: failed to set up own certificate: -0x%x", -ret);
|
||||
rb_lib_log("rb_setup_ssl_server: ssl_conf_own_cert (client): %s",
|
||||
rb_get_ssl_strerror_internal(ret));
|
||||
rb_mbedtls_cfg_decref(newcfg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* XXX support cipher lists when added to mbedtls */
|
||||
|
||||
rb_mbedtls_cfg_decref(rb_mbedtls_cfg);
|
||||
rb_mbedtls_cfg = newcfg;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
rb_ssl_listen(rb_fde_t *F, int backlog, int defer_accept)
|
||||
{
|
||||
int result;
|
||||
|
||||
result = rb_listen(F, backlog, defer_accept);
|
||||
int result = rb_listen(F, backlog, defer_accept);
|
||||
F->type = RB_FD_SOCKET | RB_FD_LISTEN | RB_FD_SSL;
|
||||
|
||||
return result;
|
||||
|
@ -415,99 +547,72 @@ rb_ssl_tryconn_timeout_cb(rb_fde_t *F, void *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);
|
||||
int ret = do_ssl_handshake(F, rb_ssl_tryconn_cb, data);
|
||||
|
||||
switch(ret)
|
||||
{
|
||||
case -1:
|
||||
rb_ssl_connect_realcb(F, RB_ERROR_SSL, sconn);
|
||||
rb_ssl_connect_realcb(F, RB_ERROR_SSL, data);
|
||||
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);
|
||||
rb_ssl_connect_realcb(F, RB_OK, data);
|
||||
}
|
||||
|
||||
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);
|
||||
rb_ssl_connect_realcb(F, status, data);
|
||||
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);
|
||||
rb_ssl_setup_mbed_context(F, false);
|
||||
rb_settimeout(F, ((struct ssl_connect *)data)->timeout, rb_ssl_tryconn_timeout_cb, data);
|
||||
do_ssl_handshake(F, rb_ssl_tryconn_cb, data);
|
||||
}
|
||||
|
||||
void
|
||||
rb_connect_tcp_ssl(rb_fde_t *F, struct sockaddr *dest,
|
||||
struct sockaddr *clocal, CNCB * callback, void *data, int timeout)
|
||||
{
|
||||
struct ssl_connect *sconn;
|
||||
if(F == NULL)
|
||||
return;
|
||||
|
||||
sconn = rb_malloc(sizeof(struct ssl_connect));
|
||||
struct ssl_connect *sconn = rb_malloc(sizeof(struct ssl_connect));
|
||||
sconn->data = data;
|
||||
sconn->callback = callback;
|
||||
sconn->timeout = timeout;
|
||||
|
||||
rb_connect_tcp(F, dest, clocal, 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));
|
||||
struct ssl_connect *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_ssl_setup_mbed_context(F, false);
|
||||
rb_settimeout(F, sconn->timeout, rb_ssl_tryconn_timeout_cb, sconn);
|
||||
|
||||
do_ssl_handshake(F, rb_ssl_tryconn_cb, (void *)sconn);
|
||||
do_ssl_handshake(F, rb_ssl_tryconn_cb, sconn);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -519,89 +624,74 @@ rb_init_prng(const char *path, prng_seed_t seed_type)
|
|||
int
|
||||
rb_get_random(void *buf, size_t length)
|
||||
{
|
||||
if (mbedtls_ctr_drbg_random(&ctr_drbg, buf, length))
|
||||
if(mbedtls_ctr_drbg_random(&ctr_drbg_ctx, 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
|
||||
}
|
||||
|
||||
static size_t
|
||||
make_certfp(const mbedtls_x509_crt *peer_cert, uint8_t certfp[RB_SSL_CERTFP_LEN], int method)
|
||||
rb_make_certfp(const mbedtls_x509_crt *peer_cert, uint8_t certfp[RB_SSL_CERTFP_LEN], int method)
|
||||
{
|
||||
const mbedtls_md_info_t *md_info;
|
||||
mbedtls_md_type_t md_type;
|
||||
bool spki = false;
|
||||
size_t hashlen;
|
||||
int ret;
|
||||
int len;
|
||||
|
||||
uint8_t der_pubkey[8192];
|
||||
void* data = peer_cert->raw.p;
|
||||
size_t datalen = peer_cert->raw.len;
|
||||
|
||||
switch(method)
|
||||
{
|
||||
case RB_SSL_CERTFP_METH_CERT_SHA1:
|
||||
md_type = MBEDTLS_MD_SHA1;
|
||||
len = RB_SSL_CERTFP_LEN_SHA1;
|
||||
hashlen = RB_SSL_CERTFP_LEN_SHA1;
|
||||
break;
|
||||
|
||||
case RB_SSL_CERTFP_METH_SPKI_SHA256:
|
||||
spki = true;
|
||||
case RB_SSL_CERTFP_METH_CERT_SHA256:
|
||||
md_type = MBEDTLS_MD_SHA256;
|
||||
len = RB_SSL_CERTFP_LEN_SHA256;
|
||||
hashlen = RB_SSL_CERTFP_LEN_SHA256;
|
||||
break;
|
||||
|
||||
case RB_SSL_CERTFP_METH_SPKI_SHA512:
|
||||
spki = true;
|
||||
case RB_SSL_CERTFP_METH_CERT_SHA512:
|
||||
md_type = MBEDTLS_MD_SHA512;
|
||||
len = RB_SSL_CERTFP_LEN_SHA512;
|
||||
hashlen = RB_SSL_CERTFP_LEN_SHA512;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
md_info = mbedtls_md_info_from_type(md_type);
|
||||
if (md_info == NULL)
|
||||
if((md_info = mbedtls_md_info_from_type(md_type)) == NULL)
|
||||
return 0;
|
||||
|
||||
if (!spki)
|
||||
if(spki)
|
||||
{
|
||||
if ((ret = mbedtls_md(md_info, peer_cert->raw.p, peer_cert->raw.len, certfp)) != 0)
|
||||
if ((ret = mbedtls_pk_write_pubkey_der((mbedtls_pk_context *)&peer_cert->pk,
|
||||
der_pubkey, sizeof(der_pubkey))) < 0)
|
||||
{
|
||||
rb_lib_log("rb_get_ssl_certfp: unable to calculate certfp: -0x%x", -ret);
|
||||
len = 0;
|
||||
rb_lib_log("rb_get_ssl_certfp: pk_write_pubkey_der: %s",
|
||||
rb_get_ssl_strerror_internal(ret));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const size_t der_pubkey_bufsz = 4096;
|
||||
void *der_pubkey = rb_malloc(der_pubkey_bufsz);
|
||||
int der_pubkey_len;
|
||||
|
||||
der_pubkey_len = mbedtls_pk_write_pubkey_der((mbedtls_pk_context *)&peer_cert->pk, der_pubkey, der_pubkey_bufsz);
|
||||
if (der_pubkey_len < 0)
|
||||
{
|
||||
rb_lib_log("rb_get_ssl_certfp: unable to retrieve pubkey: -0x%x", -der_pubkey_len);
|
||||
len = 0;
|
||||
}
|
||||
else if ((ret = mbedtls_md(md_info, der_pubkey+(der_pubkey_bufsz-der_pubkey_len), der_pubkey_len, certfp)) != 0)
|
||||
{
|
||||
rb_lib_log("rb_get_ssl_certfp: unable to calculate certfp: -0x%x", -ret);
|
||||
len = 0;
|
||||
data = der_pubkey + (sizeof(der_pubkey) - ret);
|
||||
datalen = ret;
|
||||
}
|
||||
|
||||
rb_free(der_pubkey);
|
||||
if((ret = mbedtls_md(md_info, data, datalen, certfp)) != 0)
|
||||
{
|
||||
rb_lib_log("rb_get_ssl_certfp: mbedtls_md: %s",
|
||||
rb_get_ssl_strerror_internal(ret));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return len;
|
||||
return hashlen;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -609,11 +699,10 @@ rb_get_ssl_certfp(rb_fde_t *F, uint8_t certfp[RB_SSL_CERTFP_LEN], int method)
|
|||
{
|
||||
const mbedtls_x509_crt *peer_cert;
|
||||
|
||||
peer_cert = mbedtls_ssl_get_peer_cert(SSL_P(F));
|
||||
if (peer_cert == NULL)
|
||||
if ((peer_cert = mbedtls_ssl_get_peer_cert(SSL_P(F))) == NULL)
|
||||
return 0;
|
||||
|
||||
return make_certfp(peer_cert, certfp, method);
|
||||
return (int) rb_make_certfp(peer_cert, certfp, method);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -624,11 +713,14 @@ rb_get_ssl_certfp_file(const char *filename, uint8_t certfp[RB_SSL_CERTFP_LEN],
|
|||
|
||||
mbedtls_x509_crt_init(&cert);
|
||||
|
||||
ret = mbedtls_x509_crt_parse_file(&cert, filename);
|
||||
if (ret != 0)
|
||||
if ((ret = mbedtls_x509_crt_parse_file(&cert, filename)) != 0)
|
||||
return -1;
|
||||
|
||||
return make_certfp(&cert, certfp, method);
|
||||
size_t len = rb_make_certfp(&cert, certfp, method);
|
||||
|
||||
mbedtls_x509_crt_free(&cert);
|
||||
|
||||
return (int) len;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -650,9 +742,9 @@ rb_get_ssl_info(char *buf, size_t len)
|
|||
const char *
|
||||
rb_ssl_get_cipher(rb_fde_t *F)
|
||||
{
|
||||
if(F == NULL || F->ssl == NULL)
|
||||
if(F == NULL || F->ssl == NULL || SSL_P(F) == NULL)
|
||||
return NULL;
|
||||
return mbedtls_ssl_get_ciphersuite(SSL_P(F));
|
||||
}
|
||||
|
||||
#endif /* HAVE_GNUTLS */
|
||||
#endif /* HAVE_MBEDTLS */
|
||||
|
|
107
librb/src/mbedtls_embedded_data.h
Normal file
107
librb/src/mbedtls_embedded_data.h
Normal file
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* libratbox: a library used by ircd-ratbox and other things
|
||||
* mbedtls.h: embedded data for ARM mbedTLS backend
|
||||
*
|
||||
* Copyright (C) 2016 Aaron Jones <aaronmdjones@gmail.com>
|
||||
*
|
||||
* 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$
|
||||
*/
|
||||
|
||||
#ifndef RB_MBEDTLS_EMBEDDED_DATA_H
|
||||
#define RB_MBEDTLS_EMBEDDED_DATA_H
|
||||
|
||||
/*
|
||||
* Personalization string for CTR-DRBG initialization
|
||||
*/
|
||||
static const char rb_mbedtls_personal_str[] = "charybdis/librb personalization string";
|
||||
|
||||
/*
|
||||
* YES, this is a hardcoded CA certificate.
|
||||
*
|
||||
* BEFORE YOU THROW YOUR ARMS UP IN A PANIC ABOUT A BACKDOOR, READ THIS TEXT!
|
||||
*
|
||||
* ARM mbedTLS requires a CA certificate to be set in its configuration before it will
|
||||
* request a client certificate from peers. Since we want to do that, and not all
|
||||
* installations will have a CA certificate to hand, we have this.
|
||||
*
|
||||
* Its key was securely destroyed after being generated, but even if it wasn't, that
|
||||
* doesn't matter; the IRCd will accept ALL certificates, whether signed by this CA
|
||||
* certificate or not!
|
||||
*
|
||||
* After all, it only cares about certificates in as far as to generate a fingerprint
|
||||
* for them.
|
||||
*
|
||||
* Yes, this is a massive hack, but there is no alternative.
|
||||
*/
|
||||
|
||||
static const unsigned char rb_mbedtls_dummy_ca_certificate[825] = {
|
||||
0x30, 0x82, 0x03, 0x35, 0x30, 0x82, 0x02, 0x1D, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00,
|
||||
0x86, 0xC5, 0x1F, 0x62, 0xBE, 0xFC, 0x0B, 0xA8, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86,
|
||||
0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x30, 0x31, 0x31, 0x2F, 0x30, 0x2D, 0x06, 0x03, 0x55,
|
||||
0x04, 0x03, 0x0C, 0x26, 0x43, 0x68, 0x61, 0x72, 0x79, 0x62, 0x64, 0x69, 0x73, 0x20, 0x6D, 0x62,
|
||||
0x65, 0x64, 0x54, 0x4C, 0x53, 0x20, 0x44, 0x75, 0x6D, 0x6D, 0x79, 0x20, 0x43, 0x41, 0x20, 0x43,
|
||||
0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x36,
|
||||
0x30, 0x35, 0x30, 0x34, 0x30, 0x38, 0x35, 0x32, 0x35, 0x33, 0x5A, 0x17, 0x0D, 0x34, 0x33, 0x30,
|
||||
0x39, 0x32, 0x30, 0x30, 0x38, 0x35, 0x32, 0x35, 0x33, 0x5A, 0x30, 0x31, 0x31, 0x2F, 0x30, 0x2D,
|
||||
0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x26, 0x43, 0x68, 0x61, 0x72, 0x79, 0x62, 0x64, 0x69, 0x73,
|
||||
0x20, 0x6D, 0x62, 0x65, 0x64, 0x54, 0x4C, 0x53, 0x20, 0x44, 0x75, 0x6D, 0x6D, 0x79, 0x20, 0x43,
|
||||
0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x30, 0x82, 0x01,
|
||||
0x22, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00,
|
||||
0x03, 0x82, 0x01, 0x0F, 0x00, 0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01, 0x00, 0xCA, 0x4B,
|
||||
0xA6, 0xA1, 0x82, 0x5B, 0x06, 0xC6, 0x82, 0x76, 0x8E, 0xB2, 0x22, 0x37, 0x83, 0x91, 0x4B, 0xD0,
|
||||
0xAE, 0x2F, 0xEE, 0x8E, 0x60, 0x04, 0xBA, 0x77, 0x8C, 0xD0, 0xCF, 0x5E, 0xA4, 0xFD, 0x80, 0xA1,
|
||||
0x2E, 0xDC, 0x1F, 0xD9, 0x72, 0x2C, 0x28, 0x03, 0x27, 0x48, 0x23, 0x6E, 0x41, 0x49, 0x62, 0x09,
|
||||
0x2D, 0xCF, 0x87, 0xA1, 0x45, 0x9D, 0x2B, 0x43, 0x6F, 0xBB, 0xDB, 0x23, 0xD8, 0xD9, 0x6D, 0x36,
|
||||
0x4E, 0xA3, 0x85, 0x40, 0x4D, 0x72, 0xEC, 0x7B, 0xEF, 0x2B, 0x13, 0xE4, 0x6F, 0xDA, 0x23, 0x4F,
|
||||
0x1C, 0xE7, 0xEA, 0xD9, 0x17, 0x2B, 0xD6, 0x67, 0x79, 0x42, 0xC3, 0x81, 0x9A, 0x77, 0x64, 0xC7,
|
||||
0xC5, 0x44, 0xE1, 0xA4, 0xA3, 0x50, 0x8C, 0x1F, 0xCA, 0xD3, 0x6F, 0xC7, 0xFF, 0x2C, 0xBA, 0x7B,
|
||||
0x21, 0x0C, 0xF3, 0xA9, 0x6A, 0x89, 0x74, 0x33, 0x60, 0xA1, 0xF8, 0x9F, 0xAA, 0x39, 0xA9, 0x45,
|
||||
0x7E, 0x3D, 0x41, 0x67, 0x04, 0xF5, 0x9F, 0x47, 0x62, 0xAC, 0x65, 0xE0, 0x8D, 0x46, 0x9E, 0xD9,
|
||||
0xE5, 0x77, 0xD5, 0x8C, 0x47, 0xA2, 0xFB, 0x7D, 0x94, 0x27, 0xC9, 0xB9, 0x3F, 0x4D, 0xF4, 0xFD,
|
||||
0x19, 0x3C, 0xF6, 0x24, 0xAE, 0x70, 0xD7, 0x23, 0xE4, 0x64, 0x0A, 0xFC, 0x63, 0x89, 0x8A, 0xFE,
|
||||
0xD0, 0x8E, 0x48, 0x1A, 0xD8, 0xC3, 0xA9, 0xEC, 0x9D, 0x0F, 0xC7, 0xC5, 0x22, 0xBC, 0x45, 0x4A,
|
||||
0x2F, 0x4D, 0xF5, 0x0E, 0x4F, 0xFF, 0xAC, 0xE0, 0x55, 0xF4, 0x86, 0x04, 0x1B, 0x60, 0xDF, 0x4C,
|
||||
0x25, 0xB9, 0xEC, 0x10, 0x0C, 0x54, 0x16, 0xDF, 0x42, 0xF0, 0x07, 0x00, 0x28, 0x81, 0x7C, 0x95,
|
||||
0xAA, 0xC1, 0x01, 0xA3, 0xB8, 0xDF, 0x68, 0xCB, 0x55, 0xA7, 0x80, 0xCC, 0xE5, 0x3D, 0xE1, 0x68,
|
||||
0x10, 0x27, 0x56, 0x94, 0x67, 0xEC, 0x82, 0x66, 0x3D, 0x96, 0x76, 0xC3, 0xEE, 0x23, 0x02, 0x03,
|
||||
0x01, 0x00, 0x01, 0xA3, 0x50, 0x30, 0x4E, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16,
|
||||
0x04, 0x14, 0xFF, 0xC8, 0xBA, 0x56, 0x74, 0xB1, 0x03, 0xA9, 0x79, 0x55, 0xFA, 0x58, 0x86, 0x13,
|
||||
0xDE, 0xC0, 0xFA, 0xF2, 0x94, 0x62, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x1D, 0x23, 0x04, 0x18, 0x30,
|
||||
0x16, 0x80, 0x14, 0xFF, 0xC8, 0xBA, 0x56, 0x74, 0xB1, 0x03, 0xA9, 0x79, 0x55, 0xFA, 0x58, 0x86,
|
||||
0x13, 0xDE, 0xC0, 0xFA, 0xF2, 0x94, 0x62, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x04, 0x05,
|
||||
0x30, 0x03, 0x01, 0x01, 0xFF, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01,
|
||||
0x01, 0x0B, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x3D, 0x35, 0x69, 0x87, 0xEB, 0x41, 0xA9,
|
||||
0x2A, 0x51, 0xF3, 0x28, 0x71, 0xB4, 0x06, 0x7F, 0x15, 0x5A, 0x6D, 0x88, 0x5B, 0xC8, 0x4C, 0xE1,
|
||||
0x6C, 0xC7, 0xCB, 0x93, 0x63, 0x69, 0xFB, 0xA6, 0x6D, 0xC7, 0x44, 0x6B, 0xD6, 0x39, 0x46, 0x34,
|
||||
0xFC, 0x45, 0x23, 0xD2, 0x29, 0x1B, 0xCC, 0x1C, 0x13, 0xD7, 0x63, 0x10, 0x81, 0xF5, 0x82, 0x45,
|
||||
0xEC, 0xDC, 0x20, 0x5F, 0xBB, 0xC3, 0xE6, 0x4A, 0x07, 0xA7, 0xBD, 0x9E, 0xFC, 0x5D, 0xFE, 0xC5,
|
||||
0x43, 0x3A, 0xC6, 0xA4, 0x6C, 0x5B, 0xF9, 0x63, 0x8F, 0xF9, 0xEB, 0xC2, 0xF4, 0xA7, 0xE4, 0x1B,
|
||||
0x23, 0xFA, 0xE1, 0x5A, 0x79, 0xC5, 0x1D, 0x1D, 0xFC, 0xAA, 0x81, 0xF7, 0x21, 0x52, 0xC9, 0x46,
|
||||
0x17, 0x1B, 0x24, 0x4B, 0x14, 0x5C, 0xF9, 0xB5, 0x86, 0x04, 0x80, 0x51, 0x95, 0xCF, 0x4E, 0x47,
|
||||
0x32, 0x8A, 0x1E, 0x52, 0x2E, 0xBF, 0x08, 0x8E, 0x9E, 0xE3, 0x88, 0x45, 0xC3, 0x75, 0xD7, 0xAE,
|
||||
0xC3, 0x7E, 0x7E, 0xE9, 0xC9, 0x5B, 0xD8, 0x58, 0x3B, 0x25, 0x53, 0x0C, 0x00, 0x21, 0x1A, 0x71,
|
||||
0x12, 0x23, 0xA0, 0x35, 0x6E, 0xC9, 0x7D, 0x83, 0x5C, 0x19, 0xE4, 0x05, 0x84, 0x46, 0x4E, 0x50,
|
||||
0xE2, 0x9E, 0x70, 0x2E, 0x74, 0x05, 0xEA, 0x31, 0x04, 0x55, 0xA7, 0xF4, 0x67, 0x95, 0xDC, 0x86,
|
||||
0x1F, 0x9D, 0xA0, 0x5D, 0x7F, 0x29, 0x48, 0x84, 0xEF, 0x13, 0xB8, 0xB3, 0xBF, 0x65, 0xD4, 0x52,
|
||||
0x98, 0x06, 0xE6, 0x8A, 0xB1, 0x36, 0xEA, 0x39, 0xB3, 0x04, 0x2B, 0x6E, 0x64, 0x6E, 0xF3, 0x20,
|
||||
0x74, 0xB6, 0x6E, 0x21, 0x3B, 0x99, 0xFE, 0x6E, 0x70, 0x48, 0x78, 0xEA, 0x31, 0x95, 0xB3, 0xB0,
|
||||
0x0E, 0x48, 0x83, 0x35, 0xA9, 0x74, 0xBF, 0x45, 0x07, 0xC8, 0x5A, 0x12, 0xA2, 0x4D, 0x16, 0xDB,
|
||||
0xB3, 0x1F, 0x72, 0xDE, 0x2A, 0x28, 0xFE, 0x7C, 0x2D
|
||||
};
|
||||
|
||||
#endif /* RB_MBEDTLS_EMBEDDED_DATA_H */
|
Loading…
Reference in a new issue