mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2025-01-28 14:54:05 +00:00
altcp_tls: add functions to create servers with multiple certificates
This commit is contained in:
parent
6f232b7c3f
commit
3f583a1757
@ -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,6 +756,66 @@ altcp_tls_create_config(int is_server, int have_cert, int have_pkey, int have_ca
|
||||
return conf;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (config->cert_count >= config->cert_max) {
|
||||
return ERR_MEM;
|
||||
}
|
||||
if (config->pkey_count >= config->pkey_max) {
|
||||
return ERR_MEM;
|
||||
}
|
||||
|
||||
srvcert = config->cert + config->cert_count;
|
||||
mbedtls_x509_crt_init(srvcert);
|
||||
|
||||
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));
|
||||
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);
|
||||
return ERR_VAL;
|
||||
}
|
||||
|
||||
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.
|
||||
@ -759,45 +825,17 @@ altcp_tls_create_config_server_privkey_cert(const u8_t *privkey, size_t privkey_
|
||||
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);
|
||||
struct altcp_tls_config *conf = altcp_tls_create_config_server(1);
|
||||
if (conf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
srvcert = conf->cert;
|
||||
mbedtls_x509_crt_init(srvcert);
|
||||
|
||||
pkey = conf->pkey;
|
||||
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));
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
mbedtls_ssl_conf_ca_chain(&conf->conf, srvcert->next, NULL);
|
||||
ret = mbedtls_ssl_conf_own_cert(&conf->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);
|
||||
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;
|
||||
}
|
||||
|
@ -61,7 +61,22 @@ extern "C" {
|
||||
struct altcp_tls_config;
|
||||
|
||||
/** @ingroup altcp_tls
|
||||
* Create an ALTCP_TLS server configuration handle
|
||||
* Create an ALTCP_TLS server configuration handle prepared for multiple certificates
|
||||
*/
|
||||
struct altcp_tls_config *altcp_tls_create_config_server(uint8_t cert_count);
|
||||
|
||||
/** @ingroup altcp_tls
|
||||
* Add a certificate to an ALTCP_TLS server configuration handle
|
||||
*/
|
||||
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);
|
||||
|
||||
/** @ingroup altcp_tls
|
||||
* Create an ALTCP_TLS server configuration handle with one certificate
|
||||
* (short version of calling @ref altcp_tls_create_config_server and
|
||||
* @ref altcp_tls_config_server_add_privkey_cert)
|
||||
*/
|
||||
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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user