summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Goldschmidt <[email protected]>2018-11-24 13:41:34 +0100
committerSimon Goldschmidt <[email protected]>2019-02-18 13:12:19 +0100
commit89be04ce7a4feca4db0e6b8a4c18cda18b913bd9 (patch)
tree1a53426d3e324872749f0e19bd985e2e45cf9748
parent4b3c59e4cc98c2c5a6bf801fb83bdff09eaaae6d (diff)
altcp_tls: add functions to create servers with multiple certificates
(cherry picked from commit 3f583a17575f5180d767c9d9eaf5ef3a5aa21501)
-rw-r--r--src/apps/altcp_tls/altcp_tls_mbedtls.c94
-rw-r--r--src/include/lwip/altcp_tls.h17
2 files changed, 82 insertions, 29 deletions
diff --git a/src/apps/altcp_tls/altcp_tls_mbedtls.c b/src/apps/altcp_tls/altcp_tls_mbedtls.c
index ea9303ca..574fcb93 100644
--- a/src/apps/altcp_tls/altcp_tls_mbedtls.c
+++ b/src/apps/altcp_tls/altcp_tls_mbedtls.c
@@ -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;
}
diff --git a/src/include/lwip/altcp_tls.h b/src/include/lwip/altcp_tls.h
index 7b17c608..87b2761e 100644
--- a/src/include/lwip/altcp_tls.h
+++ b/src/include/lwip/altcp_tls.h
@@ -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,