|
|
|
|
@ -100,6 +100,10 @@ struct altcp_tls_config {
|
|
|
|
|
mbedtls_ctr_drbg_context ctr_drbg; |
|
|
|
|
mbedtls_x509_crt *cert; |
|
|
|
|
mbedtls_pk_context *pkey; |
|
|
|
|
uint8_t cert_count; |
|
|
|
|
uint8_t cert_max; |
|
|
|
|
uint8_t pkey_count; |
|
|
|
|
uint8_t pkey_max; |
|
|
|
|
mbedtls_x509_crt *ca; |
|
|
|
|
#if defined(MBEDTLS_SSL_CACHE_C) && ALTCP_MBEDTLS_USE_SESSION_CACHE |
|
|
|
|
/** Inter-connection cache for fast connection startup */ |
|
|
|
|
@ -657,7 +661,7 @@ altcp_mbedtls_debug(void *ctx, int level, const char *file, int line, const char
|
|
|
|
|
* ATTENTION: Server certificate and private key have to be added outside this function! |
|
|
|
|
*/ |
|
|
|
|
static struct altcp_tls_config * |
|
|
|
|
altcp_tls_create_config(int is_server, int have_cert, int have_pkey, int have_ca) |
|
|
|
|
altcp_tls_create_config(int is_server, uint8_t cert_count, uint8_t pkey_count, int have_ca) |
|
|
|
|
{ |
|
|
|
|
size_t sz; |
|
|
|
|
int ret; |
|
|
|
|
@ -672,30 +676,32 @@ altcp_tls_create_config(int is_server, int have_cert, int have_pkey, int have_ca
|
|
|
|
|
altcp_mbedtls_mem_init(); |
|
|
|
|
|
|
|
|
|
sz = sizeof(struct altcp_tls_config); |
|
|
|
|
if (have_cert) { |
|
|
|
|
sz += sizeof(mbedtls_x509_crt); |
|
|
|
|
if (cert_count > 0) { |
|
|
|
|
sz += (cert_count * sizeof(mbedtls_x509_crt)); |
|
|
|
|
} |
|
|
|
|
if (have_ca) { |
|
|
|
|
sz += sizeof(mbedtls_x509_crt); |
|
|
|
|
} |
|
|
|
|
if (have_pkey) { |
|
|
|
|
sz += sizeof(mbedtls_pk_context); |
|
|
|
|
if (pkey_count > 0) { |
|
|
|
|
sz += (pkey_count * sizeof(mbedtls_pk_context)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
conf = (struct altcp_tls_config *)altcp_mbedtls_alloc_config(sz); |
|
|
|
|
if (conf == NULL) { |
|
|
|
|
return NULL; |
|
|
|
|
} |
|
|
|
|
conf->cert_max = cert_count; |
|
|
|
|
mem = (mbedtls_x509_crt *)(conf + 1); |
|
|
|
|
if (have_cert) { |
|
|
|
|
if (cert_count > 0) { |
|
|
|
|
conf->cert = mem; |
|
|
|
|
mem++; |
|
|
|
|
mem += cert_count; |
|
|
|
|
} |
|
|
|
|
if (have_ca) { |
|
|
|
|
conf->ca = mem; |
|
|
|
|
mem++; |
|
|
|
|
} |
|
|
|
|
if (have_pkey) { |
|
|
|
|
conf->pkey_max = pkey_count; |
|
|
|
|
if (pkey_count > 0) { |
|
|
|
|
conf->pkey = (mbedtls_pk_context *)mem; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -750,54 +756,86 @@ altcp_tls_create_config(int is_server, int have_cert, int have_pkey, int have_ca
|
|
|
|
|
return conf; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** Create new TLS configuration
|
|
|
|
|
* This is a suboptimal version that gets the encrypted private key and its password, |
|
|
|
|
* as well as the server certificate. |
|
|
|
|
*/ |
|
|
|
|
struct altcp_tls_config * |
|
|
|
|
altcp_tls_create_config_server_privkey_cert(const u8_t *privkey, size_t privkey_len, |
|
|
|
|
const u8_t *privkey_pass, size_t privkey_pass_len, |
|
|
|
|
const u8_t *cert, size_t cert_len) |
|
|
|
|
struct altcp_tls_config *altcp_tls_create_config_server(uint8_t cert_count) |
|
|
|
|
{ |
|
|
|
|
struct altcp_tls_config *conf = altcp_tls_create_config(1, cert_count, cert_count, 0); |
|
|
|
|
if (conf == NULL) { |
|
|
|
|
return NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
mbedtls_ssl_conf_ca_chain(&conf->conf, NULL, NULL); |
|
|
|
|
return conf; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
err_t altcp_tls_config_server_add_privkey_cert(struct altcp_tls_config *config, |
|
|
|
|
const u8_t *privkey, size_t privkey_len, |
|
|
|
|
const u8_t *privkey_pass, size_t privkey_pass_len, |
|
|
|
|
const u8_t *cert, size_t cert_len) |
|
|
|
|
{ |
|
|
|
|
int ret; |
|
|
|
|
mbedtls_x509_crt *srvcert; |
|
|
|
|
mbedtls_pk_context *pkey; |
|
|
|
|
struct altcp_tls_config *conf = altcp_tls_create_config(1, 1, 1, 0); |
|
|
|
|
if (conf == NULL) { |
|
|
|
|
return NULL; |
|
|
|
|
|
|
|
|
|
if (config->cert_count >= config->cert_max) { |
|
|
|
|
return ERR_MEM; |
|
|
|
|
} |
|
|
|
|
if (config->pkey_count >= config->pkey_max) { |
|
|
|
|
return ERR_MEM; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
srvcert = conf->cert; |
|
|
|
|
srvcert = config->cert + config->cert_count; |
|
|
|
|
mbedtls_x509_crt_init(srvcert); |
|
|
|
|
|
|
|
|
|
pkey = conf->pkey; |
|
|
|
|
pkey = config->pkey + config->pkey_count; |
|
|
|
|
mbedtls_pk_init(pkey); |
|
|
|
|
|
|
|
|
|
/* Load the certificates and private key */ |
|
|
|
|
ret = mbedtls_x509_crt_parse(srvcert, cert, cert_len); |
|
|
|
|
if (ret != 0) { |
|
|
|
|
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_x509_crt_parse failed: %d\n", ret)); |
|
|
|
|
altcp_mbedtls_free_config(conf); |
|
|
|
|
return NULL; |
|
|
|
|
return ERR_VAL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ret = mbedtls_pk_parse_key(pkey, (const unsigned char *) privkey, privkey_len, privkey_pass, privkey_pass_len); |
|
|
|
|
if (ret != 0) { |
|
|
|
|
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_pk_parse_public_key failed: %d\n", ret)); |
|
|
|
|
mbedtls_x509_crt_free(srvcert); |
|
|
|
|
altcp_mbedtls_free_config(conf); |
|
|
|
|
return NULL; |
|
|
|
|
return ERR_VAL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
mbedtls_ssl_conf_ca_chain(&conf->conf, srvcert->next, NULL); |
|
|
|
|
ret = mbedtls_ssl_conf_own_cert(&conf->conf, srvcert, pkey); |
|
|
|
|
ret = mbedtls_ssl_conf_own_cert(&config->conf, srvcert, pkey); |
|
|
|
|
if (ret != 0) { |
|
|
|
|
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_conf_own_cert failed: %d\n", ret)); |
|
|
|
|
mbedtls_x509_crt_free(srvcert); |
|
|
|
|
mbedtls_pk_free(pkey); |
|
|
|
|
return ERR_VAL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
config->cert_count++; |
|
|
|
|
config->pkey_count++; |
|
|
|
|
return ERR_OK; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** Create new TLS configuration
|
|
|
|
|
* This is a suboptimal version that gets the encrypted private key and its password, |
|
|
|
|
* as well as the server certificate. |
|
|
|
|
*/ |
|
|
|
|
struct altcp_tls_config * |
|
|
|
|
altcp_tls_create_config_server_privkey_cert(const u8_t *privkey, size_t privkey_len, |
|
|
|
|
const u8_t *privkey_pass, size_t privkey_pass_len, |
|
|
|
|
const u8_t *cert, size_t cert_len) |
|
|
|
|
{ |
|
|
|
|
struct altcp_tls_config *conf = altcp_tls_create_config_server(1); |
|
|
|
|
if (conf == NULL) { |
|
|
|
|
return NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (altcp_tls_config_server_add_privkey_cert(conf, privkey, privkey_len, |
|
|
|
|
privkey_pass, privkey_pass_len, cert, cert_len) != ERR_OK) { |
|
|
|
|
altcp_mbedtls_free_config(conf); |
|
|
|
|
return NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return conf; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -805,7 +843,7 @@ static struct altcp_tls_config *
|
|
|
|
|
altcp_tls_create_config_client_common(const u8_t *ca, size_t ca_len, int is_2wayauth) |
|
|
|
|
{ |
|
|
|
|
int ret; |
|
|
|
|
struct altcp_tls_config *conf = altcp_tls_create_config(0, is_2wayauth, is_2wayauth, ca != NULL); |
|
|
|
|
struct altcp_tls_config *conf = altcp_tls_create_config(0, (is_2wayauth) ? 1 : 0, (is_2wayauth) ? 1 : 0, ca != NULL); |
|
|
|
|
if (conf == NULL) { |
|
|
|
|
return NULL; |
|
|
|
|
} |
|
|
|
|
|