mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-08-24 07:05:56 +00:00
Fix 2way-auth connections for TLS clients
TLS clients that need 2-way authentication (e.g. Amazon AWS IoT cloud mqtt) need to pass a certificate and private key when creating the tls altcp_pcb. Added a new function altcp_tls_create_config_client_2wayauth() for this that replaces altcp_tls_create_config_client() for such clients. See bug #54601.
This commit is contained in:
parent
24fc93e12f
commit
7749088a83
|
@ -85,6 +85,10 @@
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#if TCP_WND < MBEDTLS_SSL_MAX_CONTENT_LEN
|
||||||
|
#error TCP_WND < MBEDTLS_SSL_MAX_CONTENT_LEN, cannot receive a full decryption buffer
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef ALTCP_MBEDTLS_ENTROPY_PTR
|
#ifndef ALTCP_MBEDTLS_ENTROPY_PTR
|
||||||
#define ALTCP_MBEDTLS_ENTROPY_PTR NULL
|
#define ALTCP_MBEDTLS_ENTROPY_PTR NULL
|
||||||
#endif
|
#endif
|
||||||
|
@ -103,6 +107,7 @@ struct altcp_tls_config {
|
||||||
mbedtls_ctr_drbg_context ctr_drbg;
|
mbedtls_ctr_drbg_context ctr_drbg;
|
||||||
mbedtls_x509_crt *cert;
|
mbedtls_x509_crt *cert;
|
||||||
mbedtls_pk_context *pkey;
|
mbedtls_pk_context *pkey;
|
||||||
|
mbedtls_x509_crt *ca;
|
||||||
#if defined(MBEDTLS_SSL_CACHE_C) && ALTCP_MBEDTLS_SESSION_CACHE_TIMEOUT_SECONDS
|
#if defined(MBEDTLS_SSL_CACHE_C) && ALTCP_MBEDTLS_SESSION_CACHE_TIMEOUT_SECONDS
|
||||||
/** Inter-connection cache for fast connection startup */
|
/** Inter-connection cache for fast connection startup */
|
||||||
struct mbedtls_ssl_cache_context cache;
|
struct mbedtls_ssl_cache_context cache;
|
||||||
|
@ -663,16 +668,23 @@ dummy_rng(void *ctx, unsigned char *buffer, size_t len)
|
||||||
* ATTENTION: Server certificate and private key have to be added outside this function!
|
* ATTENTION: Server certificate and private key have to be added outside this function!
|
||||||
*/
|
*/
|
||||||
static struct altcp_tls_config *
|
static struct altcp_tls_config *
|
||||||
altcp_tls_create_config(int is_server)
|
altcp_tls_create_config(int is_server, int have_cert, int have_pkey, int have_ca)
|
||||||
{
|
{
|
||||||
size_t sz;
|
size_t sz;
|
||||||
int ret;
|
int ret;
|
||||||
struct altcp_tls_config *conf;
|
struct altcp_tls_config *conf;
|
||||||
|
mbedtls_x509_crt *mem;
|
||||||
|
|
||||||
altcp_mbedtls_mem_init();
|
altcp_mbedtls_mem_init();
|
||||||
|
|
||||||
sz = sizeof(struct altcp_tls_config) + sizeof(mbedtls_x509_crt);
|
sz = sizeof(struct altcp_tls_config);
|
||||||
if (is_server) {
|
if (have_cert) {
|
||||||
|
sz += sizeof(mbedtls_x509_crt);
|
||||||
|
}
|
||||||
|
if (have_ca) {
|
||||||
|
sz += sizeof(mbedtls_x509_crt);
|
||||||
|
}
|
||||||
|
if (have_pkey) {
|
||||||
sz += sizeof(mbedtls_pk_context);
|
sz += sizeof(mbedtls_pk_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -680,9 +692,17 @@ altcp_tls_create_config(int is_server)
|
||||||
if (conf == NULL) {
|
if (conf == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
conf->cert = (mbedtls_x509_crt *)(conf + 1);
|
mem = (mbedtls_x509_crt *)(conf + 1);
|
||||||
if (is_server) {
|
if (have_cert) {
|
||||||
conf->pkey = (mbedtls_pk_context *)((conf->cert) + 1);
|
conf->cert = mem;
|
||||||
|
mem++;
|
||||||
|
}
|
||||||
|
if (have_ca) {
|
||||||
|
conf->ca = mem;
|
||||||
|
mem++;
|
||||||
|
}
|
||||||
|
if (have_pkey) {
|
||||||
|
conf->pkey = (mbedtls_pk_context *)mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
mbedtls_ssl_config_init(&conf->conf);
|
mbedtls_ssl_config_init(&conf->conf);
|
||||||
|
@ -732,7 +752,7 @@ altcp_tls_create_config_server_privkey_cert(const u8_t *privkey, size_t privkey_
|
||||||
int ret;
|
int ret;
|
||||||
mbedtls_x509_crt *srvcert;
|
mbedtls_x509_crt *srvcert;
|
||||||
mbedtls_pk_context *pkey;
|
mbedtls_pk_context *pkey;
|
||||||
struct altcp_tls_config *conf = altcp_tls_create_config(1);
|
struct altcp_tls_config *conf = altcp_tls_create_config(1, 1, 1, 0);
|
||||||
if (conf == NULL) {
|
if (conf == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -771,29 +791,80 @@ altcp_tls_create_config_server_privkey_cert(const u8_t *privkey, size_t privkey_
|
||||||
return conf;
|
return conf;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct altcp_tls_config *
|
static struct altcp_tls_config *
|
||||||
altcp_tls_create_config_client(const u8_t *cert, size_t cert_len)
|
altcp_tls_create_config_client_common(const u8_t *ca, size_t ca_len, int is_2wayauth)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
mbedtls_x509_crt *acc_cert;
|
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);
|
|
||||||
if (conf == NULL) {
|
if (conf == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialise certificates, allocated with conf */
|
/* Initialize the CA certificate if provided
|
||||||
acc_cert = conf->cert;
|
* CA certificate is optional (to save memory) but recommended for production environment
|
||||||
mbedtls_x509_crt_init(acc_cert);
|
* Without CA certificate, connection will be prone to man-in-the-middle attacks */
|
||||||
|
if (ca) {
|
||||||
|
mbedtls_x509_crt_init(conf->ca);
|
||||||
|
ret = mbedtls_x509_crt_parse(conf->ca, ca, ca_len);
|
||||||
|
if (ret != 0) {
|
||||||
|
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_x509_crt_parse ca failed: %d 0x%x", ret, -1*ret));
|
||||||
|
altcp_mbedtls_free_config(conf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Load the certificates */
|
mbedtls_ssl_conf_ca_chain(&conf->conf, conf->ca, NULL);
|
||||||
ret = mbedtls_x509_crt_parse(acc_cert, cert, cert_len);
|
}
|
||||||
|
return conf;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct altcp_tls_config *
|
||||||
|
altcp_tls_create_config_client(const u8_t *ca, size_t ca_len)
|
||||||
|
{
|
||||||
|
return altcp_tls_create_config_client_common(ca, ca_len, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct altcp_tls_config *
|
||||||
|
altcp_tls_create_config_client_2wayauth(const u8_t *ca, size_t ca_len, 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;
|
||||||
|
struct altcp_tls_config *conf;
|
||||||
|
|
||||||
|
if (!cert || !privkey) {
|
||||||
|
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("altcp_tls_create_config_client_2wayauth: certificate and priv key required"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
conf = altcp_tls_create_config_client_common(ca, ca_len, 1);
|
||||||
|
if (conf == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the client certificate and corresponding private key */
|
||||||
|
mbedtls_x509_crt_init(conf->cert);
|
||||||
|
ret = mbedtls_x509_crt_parse(conf->cert, cert, cert_len);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_x509_crt_parse failed: %d", ret));
|
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_x509_crt_parse cert failed: %d 0x%x", ret, -1*ret));
|
||||||
|
altcp_mbedtls_free_config(conf->cert);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mbedtls_pk_init(conf->pkey);
|
||||||
|
ret = mbedtls_pk_parse_key(conf->pkey, privkey, privkey_len, privkey_pass, privkey_pass_len);
|
||||||
|
if (ret != 0) {
|
||||||
|
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_pk_parse_key failed: %d 0x%x", ret, -1*ret));
|
||||||
|
altcp_mbedtls_free_config(conf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = mbedtls_ssl_conf_own_cert(&conf->conf, conf->cert, conf->pkey);
|
||||||
|
if (ret != 0) {
|
||||||
|
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_conf_own_cert failed: %d 0x%x", ret, -1*ret));
|
||||||
altcp_mbedtls_free_config(conf);
|
altcp_mbedtls_free_config(conf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
mbedtls_ssl_conf_ca_chain(&conf->conf, acc_cert, NULL);
|
|
||||||
return conf;
|
return conf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -803,7 +874,12 @@ altcp_tls_free_config(struct altcp_tls_config *conf)
|
||||||
if (conf->pkey) {
|
if (conf->pkey) {
|
||||||
mbedtls_pk_free(conf->pkey);
|
mbedtls_pk_free(conf->pkey);
|
||||||
}
|
}
|
||||||
mbedtls_x509_crt_free(conf->cert);
|
if (conf->cert) {
|
||||||
|
mbedtls_x509_crt_free(conf->cert);
|
||||||
|
}
|
||||||
|
if (conf->ca) {
|
||||||
|
mbedtls_x509_crt_free(conf->ca);
|
||||||
|
}
|
||||||
altcp_mbedtls_free_config(conf);
|
altcp_mbedtls_free_config(conf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,6 +72,13 @@ struct altcp_tls_config *altcp_tls_create_config_server_privkey_cert(const u8_t
|
||||||
*/
|
*/
|
||||||
struct altcp_tls_config *altcp_tls_create_config_client(const u8_t *cert, size_t cert_len);
|
struct altcp_tls_config *altcp_tls_create_config_client(const u8_t *cert, size_t cert_len);
|
||||||
|
|
||||||
|
/** @ingroup altcp_tls
|
||||||
|
* Create an ALTCP_TLS client configuration handle with two-way server/client authentication
|
||||||
|
*/
|
||||||
|
struct altcp_tls_config *altcp_tls_create_config_client_2wayauth(const u8_t *ca, size_t ca_len, 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
|
/** @ingroup altcp_tls
|
||||||
* Free an ALTCP_TLS configuration handle
|
* Free an ALTCP_TLS configuration handle
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue
Block a user