extern int lws_ssl_get_error(struct lws *wsi, int n);
-#if defined(LWS_USE_POLARSSL)
-#else
-#if defined(LWS_USE_MBEDTLS)
-#else
-#ifdef USE_WOLFSSL
+#if defined(USE_WOLFSSL)
#else
static int
OpenSSL_client_verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx)
{
+#if defined(LWS_WITH_ESP32)
+// long gvr = ssl_pm_get_verify_result(
+ lwsl_notice("%s\n", __func__);
+
+ return 0;
+#else
SSL *ssl;
int n;
struct lws *wsi;
if ((err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT ||
err == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) &&
wsi->use_ssl & LCCSCF_ALLOW_SELFSIGNED) {
- lwsl_notice("accepting self-signed certificate\n");
+ lwsl_notice("accepting self-signed certificate (verify_callback)\n");
+ X509_STORE_CTX_set_error(x509_ctx, X509_V_OK);
+ return 1; // ok
+ } else if ((err == X509_V_ERR_CERT_NOT_YET_VALID ||
+ err == X509_V_ERR_CERT_HAS_EXPIRED) &&
+ wsi->use_ssl & LCCSCF_ALLOW_EXPIRED) {
+ if (err == X509_V_ERR_CERT_NOT_YET_VALID)
+ lwsl_notice("accepting not yet valid certificate (verify_callback)\n");
+ else if (err == X509_V_ERR_CERT_HAS_EXPIRED)
+ lwsl_notice("accepting expired certificate (verify_callback)\n");
X509_STORE_CTX_set_error(x509_ctx, X509_V_OK);
return 1; // ok
}
}
/* convert callback return code from 0 = OK to verify callback return value 1 = OK */
return !n;
-}
-#endif
#endif
+}
#endif
int
lws_ssl_client_bio_create(struct lws *wsi)
{
-#if defined(LWS_USE_POLARSSL)
- return 0;
-#else
-#if defined(LWS_USE_MBEDTLS)
-#else
char hostname[128], *p;
if (lws_hdr_copy(wsi, hostname, sizeof(hostname),
if (!wsi->ssl) {
lwsl_err("SSL_new failed: %s\n",
ERR_error_string(lws_ssl_get_error(wsi, 0), NULL));
- lws_decode_ssl_error();
+ lws_ssl_elaborate_error();
return -1;
}
}
#endif
+
+#if !defined(USE_WOLFSSL) && !defined(LWS_WITH_ESP32)
+#ifndef USE_OLD_CYASSL
/* OpenSSL_client_verify_callback will be called @ SSL_connect() */
SSL_set_verify(wsi->ssl, SSL_VERIFY_PEER, OpenSSL_client_verify_callback);
+#endif
+#endif
-#ifndef USE_WOLFSSL
+#if !defined(USE_WOLFSSL) && !defined(LWS_WITH_ESP32)
SSL_set_mode(wsi->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
#endif
/*
#endif
#endif
#else
+#if defined(LWS_WITH_ESP32)
+// esp-idf openssl shim does not seem ready for this
+// SSL_set_verify(wsi->ssl, SSL_VERIFY_PEER, OpenSSL_client_verify_callback);
+ SSL_set_verify(wsi->ssl, SSL_VERIFY_NONE, OpenSSL_client_verify_callback);
+
+#else
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
SSL_set_tlsext_host_name(wsi->ssl, hostname);
#endif
#endif
+#endif
#ifdef USE_WOLFSSL
/*
#endif
#endif /* USE_WOLFSSL */
- wsi->client_bio = BIO_new_socket(wsi->sock, BIO_NOCLOSE);
+#if !defined(LWS_WITH_ESP32)
+ wsi->client_bio = BIO_new_socket(wsi->desc.sockfd, BIO_NOCLOSE);
SSL_set_bio(wsi->ssl, wsi->client_bio, wsi->client_bio);
+#else
+ SSL_set_fd(wsi->ssl, wsi->desc.sockfd);
+#endif
#ifdef USE_WOLFSSL
#ifdef USE_OLD_CYASSL
wolfSSL_set_using_nonblock(wsi->ssl, 1);
#endif
#else
+#if !defined(LWS_WITH_ESP32)
BIO_set_nbio(wsi->client_bio, 1); /* nonblocking */
#endif
+#endif
+#if !defined(LWS_WITH_ESP32)
SSL_set_ex_data(wsi->ssl, openssl_websocket_private_data_index,
wsi);
+#endif
return 0;
-#endif
-#endif
}
+#if defined(LWS_WITH_ESP32)
+int ERR_get_error(void)
+{
+ return 0;
+}
+#endif
+
int
lws_ssl_client_connect1(struct lws *wsi)
{
int n = 0;
lws_latency_pre(context, wsi);
-#if defined(LWS_USE_POLARSSL)
-#else
-#if defined(LWS_USE_MBEDTLS)
-#else
+
n = SSL_connect(wsi->ssl);
-#endif
-#endif
lws_latency(context, wsi,
"SSL_connect LWSCM_WSCL_ISSUE_HANDSHAKE", n, n > 0);
* retry if new data comes until we
* run into the connection timeout or win
*/
-#if defined(LWS_USE_POLARSSL)
-#else
-#if defined(LWS_USE_MBEDTLS)
-#else
+
unsigned long error = ERR_get_error();
if (error != SSL_ERROR_NONE) {
error, ERR_error_string(error, sb));
return -1;
}
-#endif
-#endif
}
return 1;
lws_ssl_client_connect2(struct lws *wsi)
{
struct lws_context *context = wsi->context;
-#if defined(LWS_USE_POLARSSL)
-#else
-#if defined(LWS_USE_MBEDTLS)
-#else
struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi];
char *p = (char *)&pt->serv_buf[0];
char *sb = p;
-#endif
-#endif
int n = 0;
if (wsi->mode == LWSCM_WSCL_WAITING_SSL) {
lws_latency_pre(context, wsi);
-#if defined(LWS_USE_POLARSSL)
-#else
-#if defined(LWS_USE_MBEDTLS)
-#else
n = SSL_connect(wsi->ssl);
-#endif
-#endif
- lwsl_notice("%s: SSL_connect says %d\n", __func__, n);
+ lwsl_debug("%s: SSL_connect says %d\n", __func__, n);
lws_latency(context, wsi,
"SSL_connect LWSCM_WSCL_WAITING_SSL", n, n > 0);
* retry if new data comes until we
* run into the connection timeout or win
*/
-#if defined(LWS_USE_POLARSSL)
-#else
-#if defined(LWS_USE_MBEDTLS)
-#else
unsigned long error = ERR_get_error();
if (error != SSL_ERROR_NONE) {
lwsl_err("SSL connect error %lu: %s\n",
error, ERR_error_string(error, sb));
return -1;
}
-#endif
-#endif
}
}
-#if defined(LWS_USE_POLARSSL)
-#else
-#if defined(LWS_USE_MBEDTLS)
-#else
+#if defined(LWS_WITH_ESP32)
+ {
+ X509 *peer = SSL_get_peer_certificate(wsi->ssl);
+
+ if (!peer) {
+ lwsl_notice("peer did not provide cert\n");
+
+ return -1;
+ }
+ lwsl_notice("peer provided cert\n");
+ }
+#endif
+
#ifndef USE_WOLFSSL
/*
* See comment above about wolfSSL certificate
lws_latency(context, wsi,
"SSL_get_verify_result LWS_CONNMODE..HANDSHAKE", n, n > 0);
+ lwsl_debug("get_verify says %d\n", n);
+
if (n != X509_V_OK) {
if ((n == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT ||
n == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) &&
}
#endif /* USE_WOLFSSL */
-#endif
-#endif
return 1;
}
int lws_context_init_client_ssl(struct lws_context_creation_info *info,
struct lws_vhost *vhost)
{
-#if defined(LWS_USE_POLARSSL)
- return 0;
-#else
-#if defined(LWS_USE_MBEDTLS)
-#else
- SSL_METHOD *method;
+ SSL_METHOD *method = NULL;
struct lws wsi;
unsigned long error;
+#if !defined(LWS_WITH_ESP32)
+ const char *cipher_list = info->ssl_cipher_list;
+ const char *ca_filepath = info->ssl_ca_filepath;
+ const char *private_key_filepath = info->ssl_private_key_filepath;
+ const char *cert_filepath = info->ssl_cert_filepath;
+
int n;
+ /*
+ * for backwards-compatibility default to using ssl_... members, but
+ * if the newer client-specific ones are given, use those
+ */
+ if (info->client_ssl_cipher_list)
+ cipher_list = info->client_ssl_cipher_list;
+ if (info->client_ssl_ca_filepath)
+ ca_filepath = info->client_ssl_ca_filepath;
+ if (info->client_ssl_cert_filepath)
+ cert_filepath = info->client_ssl_cert_filepath;
+ if (info->client_ssl_private_key_filepath)
+ private_key_filepath = info->client_ssl_private_key_filepath;
+#endif
+
if (!lws_check_opt(info->options, LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT))
return 0;
/* basic openssl init already happened in context init */
+
+ /* choose the most recent spin of the api */
+#if defined(LWS_HAVE_TLS_CLIENT_METHOD)
+ method = (SSL_METHOD *)TLS_client_method();
+#elif defined(LWS_HAVE_TLSV1_2_CLIENT_METHOD)
+ method = (SSL_METHOD *)TLSv1_2_client_method();
+#else
method = (SSL_METHOD *)SSLv23_client_method();
+#endif
if (!method) {
error = ERR_get_error();
lwsl_err("problem creating ssl method %lu: %s\n",
#ifdef SSL_OP_NO_COMPRESSION
SSL_CTX_set_options(vhost->ssl_client_ctx, SSL_OP_NO_COMPRESSION);
#endif
+
+#if !defined(LWS_WITH_ESP32)
SSL_CTX_set_options(vhost->ssl_client_ctx,
SSL_OP_CIPHER_SERVER_PREFERENCE);
- if (info->ssl_cipher_list)
- SSL_CTX_set_cipher_list(vhost->ssl_client_ctx,
- info->ssl_cipher_list);
+
+ if (cipher_list)
+ SSL_CTX_set_cipher_list(vhost->ssl_client_ctx, cipher_list);
#ifdef LWS_SSL_CLIENT_USE_OS_CA_CERTS
if (!lws_check_opt(info->options, LWS_SERVER_OPTION_DISABLE_OS_CA_CERTS))
#endif
/* openssl init for cert verification (for client sockets) */
- if (!info->ssl_ca_filepath) {
+ if (!ca_filepath) {
if (!SSL_CTX_load_verify_locations(
vhost->ssl_client_ctx, NULL,
LWS_OPENSSL_CLIENT_CERTS))
"Unable to load SSL Client certs from %s "
"(set by --with-client-cert-dir= "
"in configure) -- client ssl isn't "
- "going to work", LWS_OPENSSL_CLIENT_CERTS);
+ "going to work\n", LWS_OPENSSL_CLIENT_CERTS);
} else
if (!SSL_CTX_load_verify_locations(
- vhost->ssl_client_ctx, info->ssl_ca_filepath,
- NULL)) {
+ vhost->ssl_client_ctx, ca_filepath, NULL)) {
lwsl_err(
"Unable to load SSL Client certs "
"file from %s -- client ssl isn't "
- "going to work", info->ssl_ca_filepath);
+ "going to work\n", info->client_ssl_ca_filepath);
lws_ssl_elaborate_error();
}
else
lwsl_info("loaded ssl_ca_filepath\n");
-
+#endif
/*
* callback allowing user code to load extra verification certs
* helping the client to verify server identity
*/
+#if !defined(LWS_WITH_ESP32)
/* support for client-side certificate authentication */
- if (info->ssl_cert_filepath) {
- lwsl_notice("%s: doing cert filepath\n", __func__);
+ if (cert_filepath) {
+ lwsl_notice("%s: doing cert filepath\n", __func__);
n = SSL_CTX_use_certificate_chain_file(vhost->ssl_client_ctx,
- info->ssl_cert_filepath);
+ cert_filepath);
if (n < 1) {
lwsl_err("problem %d getting cert '%s'\n", n,
- info->ssl_cert_filepath);
+ cert_filepath);
lws_ssl_elaborate_error();
return 1;
}
- lwsl_notice("Loaded client cert %s\n", info->ssl_cert_filepath);
+ lwsl_notice("Loaded client cert %s\n", cert_filepath);
}
-
- if (info->ssl_private_key_filepath) {
+ if (private_key_filepath) {
lwsl_notice("%s: doing private key filepath\n", __func__);
lws_ssl_bind_passphrase(vhost->ssl_client_ctx, info);
/* set the private key from KeyFile */
if (SSL_CTX_use_PrivateKey_file(vhost->ssl_client_ctx,
- info->ssl_private_key_filepath, SSL_FILETYPE_PEM) != 1) {
+ private_key_filepath, SSL_FILETYPE_PEM) != 1) {
lwsl_err("use_PrivateKey_file '%s'\n",
- info->ssl_private_key_filepath);
+ private_key_filepath);
lws_ssl_elaborate_error();
return 1;
}
lwsl_notice("Loaded client cert private key %s\n",
- info->ssl_private_key_filepath);
+ private_key_filepath);
/* verify private key */
if (!SSL_CTX_check_private_key(vhost->ssl_client_ctx)) {
return 1;
}
}
-
+#endif
/*
* give him a fake wsi with context set, so he can use
* lws_get_context() in the callback
vhost->ssl_client_ctx, NULL, 0);
return 0;
-#endif
-#endif
}