mbedtls: improve SNI for client certs
This commit is contained in:
parent
ad07d95026
commit
b06665b851
7 changed files with 89 additions and 17 deletions
|
@ -2469,8 +2469,7 @@ lws_ssl_get_error_string(int status, int ret, char *buf, size_t len);
|
|||
*/
|
||||
|
||||
LWS_EXTERN int
|
||||
lws_tls_server_client_cert_verify_config(struct lws_context_creation_info *info,
|
||||
struct lws_vhost *vh);
|
||||
lws_tls_server_client_cert_verify_config(struct lws_vhost *vh);
|
||||
LWS_EXTERN int
|
||||
lws_tls_server_vhost_backend_init(struct lws_context_creation_info *info,
|
||||
struct lws_vhost *vhost, struct lws *wsi);
|
||||
|
|
|
@ -86,7 +86,7 @@ lws_context_init_server_ssl(struct lws_context_creation_info *info,
|
|||
if (lws_tls_server_vhost_backend_init(info, vhost, &wsi))
|
||||
return -1;
|
||||
|
||||
lws_tls_server_client_cert_verify_config(info, vhost);
|
||||
lws_tls_server_client_cert_verify_config(vhost);
|
||||
|
||||
vhost->protocols[0].callback(&wsi,
|
||||
LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS,
|
||||
|
|
|
@ -23,20 +23,31 @@
|
|||
#include <mbedtls/x509_csr.h>
|
||||
|
||||
int
|
||||
lws_tls_server_client_cert_verify_config(struct lws_context_creation_info *info,
|
||||
struct lws_vhost *vh)
|
||||
lws_tls_server_client_cert_verify_config(struct lws_vhost *vh)
|
||||
{
|
||||
int verify_options = SSL_VERIFY_PEER;
|
||||
|
||||
/* as a server, are we requiring clients to identify themselves? */
|
||||
|
||||
if (!lws_check_opt(info->options,
|
||||
LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT))
|
||||
if (!lws_check_opt(vh->options,
|
||||
LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT)) {
|
||||
lwsl_notice("no client cert required\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lws_check_opt(info->options, LWS_SERVER_OPTION_PEER_CERT_NOT_REQUIRED))
|
||||
/*
|
||||
* The wrapper has this messed-up mapping:
|
||||
*
|
||||
* else if (ctx->verify_mode == SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
|
||||
* mode = MBEDTLS_SSL_VERIFY_OPTIONAL;
|
||||
*
|
||||
* ie the meaning is inverted. So where we should test for ! we don't
|
||||
*/
|
||||
if (lws_check_opt(vh->options, LWS_SERVER_OPTION_PEER_CERT_NOT_REQUIRED))
|
||||
verify_options = SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
|
||||
|
||||
lwsl_notice("%s: vh %s requires client cert %d\n", __func__, vh->name,
|
||||
verify_options);
|
||||
|
||||
SSL_CTX_set_verify(vh->ssl_ctx, verify_options, NULL);
|
||||
|
||||
return 0;
|
||||
|
@ -78,7 +89,8 @@ lws_mbedtls_sni_cb(void *arg, mbedtls_ssl_context *mbedtls_ctx,
|
|||
return 0;
|
||||
}
|
||||
|
||||
lwsl_info("SNI: Found: %s:%d\n", servername, vh->listen_port);
|
||||
lwsl_info("SNI: Found: %s:%d at vhost '%s'\n", servername,
|
||||
vh->listen_port, vhost->name);
|
||||
|
||||
/* select the ssl ctx from the selected vhost for this conn */
|
||||
SSL_set_SSL_CTX(ssl, vhost->ssl_ctx);
|
||||
|
@ -192,6 +204,8 @@ lws_tls_server_vhost_backend_init(struct lws_context_creation_info *info,
|
|||
struct lws_vhost *vhost, struct lws *wsi)
|
||||
{
|
||||
const SSL_METHOD *method = TLS_server_method();
|
||||
uint8_t *p;
|
||||
lws_filepos_t flen;
|
||||
|
||||
vhost->ssl_ctx = SSL_CTX_new(method); /* create context */
|
||||
if (!vhost->ssl_ctx) {
|
||||
|
@ -202,6 +216,26 @@ lws_tls_server_vhost_backend_init(struct lws_context_creation_info *info,
|
|||
if (!vhost->use_ssl || !info->ssl_cert_filepath)
|
||||
return 0;
|
||||
|
||||
if (info->ssl_ca_filepath) {
|
||||
lwsl_notice("%s: vh %s: loading CA filepath %s\n", __func__,
|
||||
vhost->name, info->ssl_ca_filepath);
|
||||
if (lws_tls_alloc_pem_to_der_file(vhost->context,
|
||||
info->ssl_ca_filepath, NULL, 0, &p, &flen)) {
|
||||
lwsl_err("couldn't find client CA file %s\n",
|
||||
info->ssl_ca_filepath);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (SSL_CTX_add_client_CA_ASN1(vhost->ssl_ctx, (int)flen, p) != 1) {
|
||||
lwsl_err("%s: SSL_CTX_add_client_CA_ASN1 unhappy\n",
|
||||
__func__);
|
||||
free(p);
|
||||
return 1;
|
||||
}
|
||||
free(p);
|
||||
}
|
||||
|
||||
return lws_tls_server_certs_load(vhost, wsi,
|
||||
info->ssl_cert_filepath,
|
||||
info->ssl_private_key_filepath,
|
||||
|
|
|
@ -46,6 +46,9 @@
|
|||
|
||||
void SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx);
|
||||
|
||||
int SSL_CTX_add_client_CA_ASN1(SSL_CTX *ssl, int len,
|
||||
const unsigned char *d);
|
||||
|
||||
SSL *SSL_SSL_from_mbedtls_ssl_context(mbedtls_ssl_context *msc);
|
||||
|
||||
/**
|
||||
|
|
|
@ -166,6 +166,28 @@ int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief add CA client certification into the SSL
|
||||
*/
|
||||
int SSL_CTX_add_client_CA_ASN1(SSL_CTX *ctx, int len,
|
||||
const unsigned char *d)
|
||||
{
|
||||
X509 *x;
|
||||
|
||||
x = d2i_X509(NULL, d, len);
|
||||
if (!x) {
|
||||
SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "d2i_X509() return NULL");
|
||||
return 0;
|
||||
}
|
||||
SSL_ASSERT1(ctx);
|
||||
|
||||
X509_free(ctx->client_CA);
|
||||
|
||||
ctx->client_CA = x;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief add CA client certification into the SSL
|
||||
*/
|
||||
|
|
|
@ -823,17 +823,32 @@ void SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx)
|
|||
{
|
||||
struct ssl_pm *ssl_pm = ssl->ssl_pm;
|
||||
struct x509_pm *x509_pm = (struct x509_pm *)ctx->cert->x509->x509_pm;
|
||||
struct x509_pm *x509_pm_ca = (struct x509_pm *)ctx->client_CA->x509_pm;
|
||||
|
||||
struct pkey_pm *pkey_pm = (struct pkey_pm *)ctx->cert->pkey->pkey_pm;
|
||||
int mode;
|
||||
|
||||
if (ssl->cert)
|
||||
ssl_cert_free(ssl->cert);
|
||||
ssl->ctx = ctx;
|
||||
ssl->cert = __ssl_cert_new(ctx->cert);
|
||||
|
||||
if (ctx->verify_mode == SSL_VERIFY_PEER)
|
||||
mode = MBEDTLS_SSL_VERIFY_REQUIRED;
|
||||
else if (ctx->verify_mode == SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
|
||||
mode = MBEDTLS_SSL_VERIFY_OPTIONAL;
|
||||
else if (ctx->verify_mode == SSL_VERIFY_CLIENT_ONCE)
|
||||
mode = MBEDTLS_SSL_VERIFY_UNSET;
|
||||
else
|
||||
mode = MBEDTLS_SSL_VERIFY_NONE;
|
||||
|
||||
// printf("ssl: %p, client ca x509_crt %p, mbedtls mode %d\n", ssl, x509_pm_ca->x509_crt, mode);
|
||||
|
||||
/* apply new ctx cert to ssl */
|
||||
|
||||
mbedtls_ssl_set_hs_own_cert(&ssl_pm->ssl, x509_pm->x509_crt, pkey_pm->pkey);
|
||||
mbedtls_ssl_set_hs_authmode(&ssl_pm->ssl, MBEDTLS_SSL_VERIFY_NONE);
|
||||
mbedtls_ssl_set_hs_ca_chain(&ssl_pm->ssl, x509_pm->x509_crt, NULL);
|
||||
ssl->verify_mode = ctx->verify_mode;
|
||||
|
||||
mbedtls_ssl_set_hs_ca_chain(&ssl_pm->ssl, x509_pm_ca->x509_crt, NULL);
|
||||
mbedtls_ssl_set_hs_own_cert(&ssl_pm->ssl, x509_pm->x509_crt, pkey_pm->pkey);
|
||||
mbedtls_ssl_set_hs_authmode(&ssl_pm->ssl, mode);
|
||||
}
|
||||
|
|
|
@ -58,18 +58,17 @@ OpenSSL_verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx)
|
|||
}
|
||||
|
||||
int
|
||||
lws_tls_server_client_cert_verify_config(struct lws_context_creation_info *info,
|
||||
struct lws_vhost *vh)
|
||||
lws_tls_server_client_cert_verify_config(struct lws_vhost *vh)
|
||||
{
|
||||
int verify_options = SSL_VERIFY_PEER;
|
||||
|
||||
/* as a server, are we requiring clients to identify themselves? */
|
||||
|
||||
if (!lws_check_opt(info->options,
|
||||
if (!lws_check_opt(vh->options,
|
||||
LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT))
|
||||
return 0;
|
||||
|
||||
if (!lws_check_opt(info->options,
|
||||
if (!lws_check_opt(vh->options,
|
||||
LWS_SERVER_OPTION_PEER_CERT_NOT_REQUIRED))
|
||||
verify_options |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue