diff --git a/READMEs/README.build.md b/READMEs/README.build.md index 3ca43205..f06628de 100644 --- a/READMEs/README.build.md +++ b/READMEs/README.build.md @@ -282,6 +282,13 @@ Lws supports both almost the same, so instead of taking my word for it you are invited to try it both ways and see which the results (including, eg, binary size and memory usage as well as speed) suggest you use. +NOTE: one major difference with mbedTLS is it does not load the system trust +store by default. That has advantages and disadvantages, but the disadvantage +is you must provide the CA cert to lws built against mbedTLS for it to be able +to validate it, ie, use -A with the test client. The minimal test clients +have the CA cert for warmcat.com and libwebsockets.org and use it if they see +they were built with mbedTLS. + @section optee Building for OP-TEE OP-TEE is a "Secure World" Trusted Execution Environment. diff --git a/lib/client/client.c b/lib/client/client.c index 4a023043..3b69f387 100644 --- a/lib/client/client.c +++ b/lib/client/client.c @@ -82,7 +82,7 @@ lws_client_socket_service(struct lws_context *context, struct lws *wsi, struct lws_pollfd *pollfd) { struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; - char *p = (char *)&pt->serv_buf[0]; + char *p = (char *)&pt->serv_buf[0], ebuf[128]; const char *cce = NULL; unsigned char c; char *sb = p; @@ -286,11 +286,11 @@ start_ws_handshake: case LWSCM_WSCL_WAITING_SSL: if (wsi->use_ssl) { - n = lws_ssl_client_connect2(wsi); + n = lws_ssl_client_connect2(wsi, ebuf, sizeof(ebuf)); if (!n) return 0; if (n < 0) { - cce = "lws_ssl_client_connect2 failed"; + cce = ebuf; goto bail3; } } else diff --git a/lib/client/ssl-client.c b/lib/client/ssl-client.c index 50f5dd04..fbe7a9b7 100644 --- a/lib/client/ssl-client.c +++ b/lib/client/ssl-client.c @@ -51,7 +51,7 @@ lws_ssl_client_connect1(struct lws *wsi) } int -lws_ssl_client_connect2(struct lws *wsi) +lws_ssl_client_connect2(struct lws *wsi, char *errbuf, int len) { int n = 0; @@ -65,6 +65,7 @@ lws_ssl_client_connect2(struct lws *wsi) switch (n) { case LWS_SSL_CAPABLE_ERROR: + lws_snprintf(errbuf, len, "client connect failed"); return -1; case LWS_SSL_CAPABLE_DONE: break; /* connected */ @@ -79,7 +80,7 @@ lws_ssl_client_connect2(struct lws *wsi) } } - if (lws_tls_client_confirm_peer_cert(wsi)) + if (lws_tls_client_confirm_peer_cert(wsi, errbuf, len)) return -1; return 1; diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h index d6604a9b..4fcc60cd 100644 --- a/lib/private-libwebsockets.h +++ b/lib/private-libwebsockets.h @@ -2373,7 +2373,7 @@ lws_ssl_client_bio_create(struct lws *wsi); LWS_EXTERN int lws_ssl_client_connect1(struct lws *wsi); LWS_EXTERN int -lws_ssl_client_connect2(struct lws *wsi); +lws_ssl_client_connect2(struct lws *wsi, char *errbuf, int len); LWS_EXTERN void lws_ssl_elaborate_error(void); LWS_EXTERN int @@ -2440,7 +2440,7 @@ __lws_tls_shutdown(struct lws *wsi); LWS_EXTERN enum lws_ssl_capable_status lws_tls_client_connect(struct lws *wsi); LWS_EXTERN int -lws_tls_client_confirm_peer_cert(struct lws *wsi); +lws_tls_client_confirm_peer_cert(struct lws *wsi, char *ebuf, int ebuf_len); LWS_EXTERN int lws_tls_client_create_vhost_context(struct lws_vhost *vh, struct lws_context_creation_info *info, diff --git a/lib/tls/mbedtls/mbedtls-client.c b/lib/tls/mbedtls/mbedtls-client.c index 2fbe8a62..990edc63 100644 --- a/lib/tls/mbedtls/mbedtls-client.c +++ b/lib/tls/mbedtls/mbedtls-client.c @@ -72,12 +72,8 @@ lws_ssl_client_bio_create(struct lws *wsi) * use server name indication (SNI), if supported, * when establishing connection */ - if (wsi->vhost->x509_client_CA) - SSL_set_verify(wsi->ssl, SSL_VERIFY_PEER, - OpenSSL_client_verify_callback); - else - SSL_set_verify(wsi->ssl, SSL_VERIFY_NONE, - OpenSSL_client_verify_callback); + SSL_set_verify(wsi->ssl, SSL_VERIFY_PEER, + OpenSSL_client_verify_callback); SSL_set_fd(wsi->ssl, wsi->desc.sockfd); @@ -112,9 +108,12 @@ lws_tls_client_connect(struct lws *wsi) } int -lws_tls_client_confirm_peer_cert(struct lws *wsi) +lws_tls_client_confirm_peer_cert(struct lws *wsi, char *ebuf, int ebuf_len) { + int n; X509 *peer = SSL_get_peer_certificate(wsi->ssl); + struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; + char *sb = (char *)&pt->serv_buf[0]; if (!peer) { lwsl_info("peer did not provide cert\n"); @@ -123,7 +122,41 @@ lws_tls_client_confirm_peer_cert(struct lws *wsi) } lwsl_info("peer provided cert\n"); - return 0; + n = SSL_get_verify_result(wsi->ssl); + lws_latency(wsi->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) + return 0; + + if (n == X509_V_ERR_HOSTNAME_MISMATCH && + (wsi->use_ssl & LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK)) { + lwsl_info("accepting certificate for invalid hostname\n"); + return 0; + } + + if (n == X509_V_ERR_INVALID_CA && + (wsi->use_ssl & LCCSCF_ALLOW_SELFSIGNED)) { + lwsl_info("accepting certificate from untrusted CA\n"); + return 0; + } + + if ((n == X509_V_ERR_CERT_NOT_YET_VALID || + n == X509_V_ERR_CERT_HAS_EXPIRED) && + (wsi->use_ssl & LCCSCF_ALLOW_EXPIRED)) { + lwsl_info("accepting expired or not yet valid certificate\n"); + + return 0; + } + lws_snprintf(ebuf, ebuf_len, + "server's cert didn't look good, X509_V_ERR = %d: %s\n", + n, ERR_error_string(n, sb)); + lwsl_info("%s\n", ebuf); + lws_ssl_elaborate_error(); + + return -1; } int diff --git a/lib/tls/mbedtls/wrapper/library/ssl_lib.c b/lib/tls/mbedtls/wrapper/library/ssl_lib.c index cf553e22..22cc24bb 100644 --- a/lib/tls/mbedtls/wrapper/library/ssl_lib.c +++ b/lib/tls/mbedtls/wrapper/library/ssl_lib.c @@ -1594,11 +1594,34 @@ void ERR_free_strings(void) char *ERR_error_string(unsigned long e, char *buf) { - if (buf) { - strcpy(buf, "unknown"); + if (!buf) + return "unknown"; + + switch(e) { + case X509_V_ERR_INVALID_CA: + strcpy(buf, "CA is not trusted"); + break; + case X509_V_ERR_HOSTNAME_MISMATCH: + strcpy(buf, "Hostname mismatch"); + break; + case X509_V_ERR_CA_KEY_TOO_SMALL: + strcpy(buf, "CA key too small"); + break; + case X509_V_ERR_CA_MD_TOO_WEAK: + strcpy(buf, "MD key too weak"); + break; + case X509_V_ERR_CERT_NOT_YET_VALID: + strcpy(buf, "Cert from the future"); + break; + case X509_V_ERR_CERT_HAS_EXPIRED: + strcpy(buf, "Cert expired"); + break; + default: + strcpy(buf, "unknown"); + break; } - return "unknown"; + return buf; } void *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx) diff --git a/lib/tls/mbedtls/wrapper/platform/ssl_pm.c b/lib/tls/mbedtls/wrapper/platform/ssl_pm.c index 1d7d0932..3d70275e 100755 --- a/lib/tls/mbedtls/wrapper/platform/ssl_pm.c +++ b/lib/tls/mbedtls/wrapper/platform/ssl_pm.c @@ -224,7 +224,7 @@ static int ssl_pm_reload_crt(SSL *ssl) struct x509_pm *crt_pm = (struct x509_pm *)ssl->cert->x509->x509_pm; if (ssl->verify_mode == SSL_VERIFY_PEER) - mode = MBEDTLS_SSL_VERIFY_REQUIRED; + mode = MBEDTLS_SSL_VERIFY_OPTIONAL; else if (ssl->verify_mode == SSL_VERIFY_FAIL_IF_NO_PEER_CERT) mode = MBEDTLS_SSL_VERIFY_OPTIONAL; else if (ssl->verify_mode == SSL_VERIFY_CLIENT_ONCE) @@ -267,7 +267,7 @@ static int mbedtls_handshake( mbedtls_ssl_context *ssl ) while (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) { ret = mbedtls_ssl_handshake_step(ssl); - lwsl_notice("%s: ssl ret -%x state %d\n", __func__, -ret, ssl->state); + lwsl_info("%s: ssl ret -%x state %d\n", __func__, -ret, ssl->state); if (ret != 0) break; @@ -283,8 +283,6 @@ int ssl_pm_handshake(SSL *ssl) int ret; struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; - lwsl_notice("%s\n", __func__); - ssl->err = 0; errno = 0; @@ -761,18 +759,44 @@ void ssl_pm_set_bufflen(SSL *ssl, int len) long ssl_pm_get_verify_result(const SSL *ssl) { - uint32_t ret; - long verify_result; - struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; + uint32_t ret; + long verify_result; + struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; - ret = mbedtls_ssl_get_verify_result(&ssl_pm->ssl); - if (ret) { - SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ssl_get_verify_result() return 0x%x", ret); - verify_result = X509_V_ERR_UNSPECIFIED; - } else - verify_result = X509_V_OK; + ret = mbedtls_ssl_get_verify_result(&ssl_pm->ssl); + if (!ret) + return X509_V_OK; - return verify_result; + if (ret & MBEDTLS_X509_BADCERT_NOT_TRUSTED || + (ret & MBEDTLS_X509_BADCRL_NOT_TRUSTED)) + verify_result = X509_V_ERR_INVALID_CA; + + else if (ret & MBEDTLS_X509_BADCERT_CN_MISMATCH) + verify_result = X509_V_ERR_HOSTNAME_MISMATCH; + + else if ((ret & MBEDTLS_X509_BADCERT_BAD_KEY) || + (ret & MBEDTLS_X509_BADCRL_BAD_KEY)) + verify_result = X509_V_ERR_CA_KEY_TOO_SMALL; + + else if ((ret & MBEDTLS_X509_BADCERT_BAD_MD) || + (ret & MBEDTLS_X509_BADCRL_BAD_MD)) + verify_result = X509_V_ERR_CA_MD_TOO_WEAK; + + else if ((ret & MBEDTLS_X509_BADCERT_FUTURE) || + (ret & MBEDTLS_X509_BADCRL_FUTURE)) + verify_result = X509_V_ERR_CERT_NOT_YET_VALID; + + else if ((ret & MBEDTLS_X509_BADCERT_EXPIRED) || + (ret & MBEDTLS_X509_BADCRL_EXPIRED)) + verify_result = X509_V_ERR_CERT_HAS_EXPIRED; + + else + verify_result = X509_V_ERR_UNSPECIFIED; + + SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, + "mbedtls_ssl_get_verify_result() return 0x%x", ret); + + return verify_result; } /** @@ -856,13 +880,13 @@ void SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx) 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 + if (ctx->verify_mode == SSL_VERIFY_PEER) + mode = MBEDTLS_SSL_VERIFY_OPTIONAL; + 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); diff --git a/lib/tls/openssl/openssl-client.c b/lib/tls/openssl/openssl-client.c index 2f8c8df8..d074ceeb 100644 --- a/lib/tls/openssl/openssl-client.c +++ b/lib/tls/openssl/openssl-client.c @@ -228,9 +228,9 @@ lws_tls_client_connect(struct lws *wsi) } int -lws_tls_client_confirm_peer_cert(struct lws *wsi) +lws_tls_client_confirm_peer_cert(struct lws *wsi, char *ebuf, int ebuf_len) { -#ifndef USE_WOLFSSL +#if !defined(USE_WOLFSSL) struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; char *p = (char *)&pt->serv_buf[0]; char *sb = p; @@ -243,28 +243,38 @@ lws_tls_client_confirm_peer_cert(struct lws *wsi) 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) && - (wsi->use_ssl & LCCSCF_ALLOW_SELFSIGNED)) { - lwsl_notice("accepting self-signed certificate\n"); - } else if ((n == X509_V_ERR_CERT_NOT_YET_VALID || - n == X509_V_ERR_CERT_HAS_EXPIRED) && - (wsi->use_ssl & LCCSCF_ALLOW_EXPIRED)) { - lwsl_notice("accepting expired certificate\n"); - } else if (n == X509_V_ERR_CERT_NOT_YET_VALID) { - lwsl_notice("Cert is from the future... " - "probably our clock... accepting...\n"); - } else { - lwsl_err("server's cert didn't look good, X509_V_ERR = %d: %s\n", - n, ERR_error_string(n, sb)); - lws_ssl_elaborate_error(); - return -1; - } - } -#endif /* USE_WOLFSSL */ + if (n == X509_V_OK) + return 0; + if ((n == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT || + n == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) && + (wsi->use_ssl & LCCSCF_ALLOW_SELFSIGNED)) { + lwsl_info("accepting self-signed certificate\n"); + + return 0; + } + if ((n == X509_V_ERR_CERT_NOT_YET_VALID || + n == X509_V_ERR_CERT_HAS_EXPIRED) && + (wsi->use_ssl & LCCSCF_ALLOW_EXPIRED)) { + lwsl_info("accepting expired certificate\n"); + return 0; + } + if (n == X509_V_ERR_CERT_NOT_YET_VALID) { + lwsl_info("Cert is from the future... " + "probably our clock... accepting...\n"); + return 0; + } + lws_snprintf(ebuf, ebuf_len, + "server's cert didn't look good, X509_V_ERR = %d: %s\n", + n, ERR_error_string(n, sb)); + lwsl_info("%s\n", ebuf); + lws_ssl_elaborate_error(); + + return -1; + +#else /* USE_WOLFSSL */ return 0; +#endif } int diff --git a/minimal-examples/http-client/minimal-http-client/minimal-http-client.c b/minimal-examples/http-client/minimal-http-client/minimal-http-client.c index ad19c0fe..67b00768 100644 --- a/minimal-examples/http-client/minimal-http-client/minimal-http-client.c +++ b/minimal-examples/http-client/minimal-http-client/minimal-http-client.c @@ -110,6 +110,14 @@ int main(int argc, char **argv) info.port = CONTEXT_PORT_NO_LISTEN; /* we do not run any server */ info.protocols = protocols; +#if defined(LWS_WITH_MBEDTLS) + /* + * OpenSSL uses the system trust store. mbedTLS has to be told which + * CA to trust explicitly. + */ + info.client_ssl_ca_filepath = "./warmcat.com.cer"; +#endif + context = lws_create_context(&info); if (!context) { lwsl_err("lws init failed\n"); diff --git a/minimal-examples/http-client/minimal-http-client/warmcat.com.cer b/minimal-examples/http-client/minimal-http-client/warmcat.com.cer new file mode 100644 index 00000000..67de1292 --- /dev/null +++ b/minimal-examples/http-client/minimal-http-client/warmcat.com.cer @@ -0,0 +1,92 @@ +-----BEGIN CERTIFICATE----- +MIIGCDCCA/CgAwIBAgIQKy5u6tl1NmwUim7bo3yMBzANBgkqhkiG9w0BAQwFADCB +hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV +BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTQwMjEy +MDAwMDAwWhcNMjkwMjExMjM1OTU5WjCBkDELMAkGA1UEBhMCR0IxGzAZBgNVBAgT +EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR +Q09NT0RPIENBIExpbWl0ZWQxNjA0BgNVBAMTLUNPTU9ETyBSU0EgRG9tYWluIFZh +bGlkYXRpb24gU2VjdXJlIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAI7CAhnhoFmk6zg1jSz9AdDTScBkxwtiBUUWOqigwAwCfx3M28Sh +bXcDow+G+eMGnD4LgYqbSRutA776S9uMIO3Vzl5ljj4Nr0zCsLdFXlIvNN5IJGS0 +Qa4Al/e+Z96e0HqnU4A7fK31llVvl0cKfIWLIpeNs4TgllfQcBhglo/uLQeTnaG6 +ytHNe+nEKpooIZFNb5JPJaXyejXdJtxGpdCsWTWM/06RQ1A/WZMebFEh7lgUq/51 +UHg+TLAchhP6a5i84DuUHoVS3AOTJBhuyydRReZw3iVDpA3hSqXttn7IzW3uLh0n +c13cRTCAquOyQQuvvUSH2rnlG51/ruWFgqUCAwEAAaOCAWUwggFhMB8GA1UdIwQY +MBaAFLuvfgI9+qbxPISOre44mOzZMjLUMB0GA1UdDgQWBBSQr2o6lFoL2JDqElZz +30O0Oija5zAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNV +HSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGwYDVR0gBBQwEjAGBgRVHSAAMAgG +BmeBDAECATBMBgNVHR8ERTBDMEGgP6A9hjtodHRwOi8vY3JsLmNvbW9kb2NhLmNv +bS9DT01PRE9SU0FDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDBxBggrBgEFBQcB +AQRlMGMwOwYIKwYBBQUHMAKGL2h0dHA6Ly9jcnQuY29tb2RvY2EuY29tL0NPTU9E +T1JTQUFkZFRydXN0Q0EuY3J0MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21v +ZG9jYS5jb20wDQYJKoZIhvcNAQEMBQADggIBAE4rdk+SHGI2ibp3wScF9BzWRJ2p +mj6q1WZmAT7qSeaiNbz69t2Vjpk1mA42GHWx3d1Qcnyu3HeIzg/3kCDKo2cuH1Z/ +e+FE6kKVxF0NAVBGFfKBiVlsit2M8RKhjTpCipj4SzR7JzsItG8kO3KdY3RYPBps +P0/HEZrIqPW1N+8QRcZs2eBelSaz662jue5/DJpmNXMyYE7l3YphLG5SEXdoltMY +dVEVABt0iN3hxzgEQyjpFv3ZBdRdRydg1vs4O2xyopT4Qhrf7W8GjEXCBgCq5Ojc +2bXhc3js9iPc0d1sjhqPpepUfJa3w/5Vjo1JXvxku88+vZbrac2/4EjxYoIQ5QxG +V/Iz2tDIY+3GH5QFlkoakdH368+PUq4NCNk+qKBR6cGHdNXJ93SrLlP7u3r7l+L4 +HyaPs9Kg4DdbKDsx5Q5XLVq4rXmsXiBmGqW5prU5wfWYQ//u+aen/e7KJD2AFsQX +j4rBYKEMrltDR5FL1ZoXX/nUh8HCjLfn4g8wGTeGrODcQgPmlKidrv0PJFGUzpII +0fxQ8ANAe4hZ7Q7drNJ3gjTcBpUC2JD5Leo31Rpg0Gcg19hCC0Wvgmje3WYkN5Ap +lBlGGSW4gNfL1IYoakRwJiNiqZ+Gb7+6kHDSVneFeO/qJakXzlByjAA6quPbYzSf ++AZxAeKCINT+b72x +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFdDCCBFygAwIBAgIQJ2buVutJ846r13Ci/ITeIjANBgkqhkiG9w0BAQwFADBv +MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk +ZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBF +eHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFow +gYUxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO +BgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMSswKQYD +VQQDEyJDT01PRE8gUlNBIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkq +hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAkehUktIKVrGsDSTdxc9EZ3SZKzejfSNw +AHG8U9/E+ioSj0t/EFa9n3Byt2F/yUsPF6c947AEYe7/EZfH9IY+Cvo+XPmT5jR6 +2RRr55yzhaCCenavcZDX7P0N+pxs+t+wgvQUfvm+xKYvT3+Zf7X8Z0NyvQwA1onr +ayzT7Y+YHBSrfuXjbvzYqOSSJNpDa2K4Vf3qwbxstovzDo2a5JtsaZn4eEgwRdWt +4Q08RWD8MpZRJ7xnw8outmvqRsfHIKCxH2XeSAi6pE6p8oNGN4Tr6MyBSENnTnIq +m1y9TBsoilwie7SrmNnu4FGDwwlGTm0+mfqVF9p8M1dBPI1R7Qu2XK8sYxrfV8g/ +vOldxJuvRZnio1oktLqpVj3Pb6r/SVi+8Kj/9Lit6Tf7urj0Czr56ENCHonYhMsT +8dm74YlguIwoVqwUHZwK53Hrzw7dPamWoUi9PPevtQ0iTMARgexWO/bTouJbt7IE +IlKVgJNp6I5MZfGRAy1wdALqi2cVKWlSArvX31BqVUa/oKMoYX9w0MOiqiwhqkfO +KJwGRXa/ghgntNWutMtQ5mv0TIZxMOmm3xaG4Nj/QN370EKIf6MzOi5cHkERgWPO +GHFrK+ymircxXDpqR+DDeVnWIBqv8mqYqnK8V0rSS527EPywTEHl7R09XiidnMy/ +s1Hap0flhFMCAwEAAaOB9DCB8TAfBgNVHSMEGDAWgBStvZh6NLQm9/rEJlTvA73g +JMtUGjAdBgNVHQ4EFgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQD +AgGGMA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0gBAowCDAGBgRVHSAAMEQGA1UdHwQ9 +MDswOaA3oDWGM2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9BZGRUcnVzdEV4dGVy +bmFsQ0FSb290LmNybDA1BggrBgEFBQcBAQQpMCcwJQYIKwYBBQUHMAGGGWh0dHA6 +Ly9vY3NwLnVzZXJ0cnVzdC5jb20wDQYJKoZIhvcNAQEMBQADggEBAGS/g/FfmoXQ +zbihKVcN6Fr30ek+8nYEbvFScLsePP9NDXRqzIGCJdPDoCpdTPW6i6FtxFQJdcfj +Jw5dhHk3QBN39bSsHNA7qxcS1u80GH4r6XnTq1dFDK8o+tDb5VCViLvfhVdpfZLY +Uspzgb8c8+a4bmYRBbMelC1/kZWSWfFMzqORcUx8Rww7Cxn2obFshj5cqsQugsv5 +B5a6SE2Q8pTIqXOi6wZ7I53eovNNVZ96YUWYGGjHXkBrI/V5eu+MtWuLt29G9Hvx +PUsE2JOAWVrgQSQdso8VYFhH2+9uRv0V9dlfmrPb2LjkQLPNlzmuhbsdjrzch5vR +pu/xO28QOG8= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU +MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs +IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290 +MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux +FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h +bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v +dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt +H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9 +uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX +mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX +a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN +E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0 +WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD +VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0 +Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU +cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx +IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN +AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH +YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 +6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC +Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX +c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a +mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= +-----END CERTIFICATE----- diff --git a/minimal-examples/ws-client/minimal-ws-client-rx/libwebsockets.org.cer b/minimal-examples/ws-client/minimal-ws-client-rx/libwebsockets.org.cer new file mode 100644 index 00000000..67de1292 --- /dev/null +++ b/minimal-examples/ws-client/minimal-ws-client-rx/libwebsockets.org.cer @@ -0,0 +1,92 @@ +-----BEGIN CERTIFICATE----- +MIIGCDCCA/CgAwIBAgIQKy5u6tl1NmwUim7bo3yMBzANBgkqhkiG9w0BAQwFADCB +hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV +BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTQwMjEy +MDAwMDAwWhcNMjkwMjExMjM1OTU5WjCBkDELMAkGA1UEBhMCR0IxGzAZBgNVBAgT +EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR +Q09NT0RPIENBIExpbWl0ZWQxNjA0BgNVBAMTLUNPTU9ETyBSU0EgRG9tYWluIFZh +bGlkYXRpb24gU2VjdXJlIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAI7CAhnhoFmk6zg1jSz9AdDTScBkxwtiBUUWOqigwAwCfx3M28Sh +bXcDow+G+eMGnD4LgYqbSRutA776S9uMIO3Vzl5ljj4Nr0zCsLdFXlIvNN5IJGS0 +Qa4Al/e+Z96e0HqnU4A7fK31llVvl0cKfIWLIpeNs4TgllfQcBhglo/uLQeTnaG6 +ytHNe+nEKpooIZFNb5JPJaXyejXdJtxGpdCsWTWM/06RQ1A/WZMebFEh7lgUq/51 +UHg+TLAchhP6a5i84DuUHoVS3AOTJBhuyydRReZw3iVDpA3hSqXttn7IzW3uLh0n +c13cRTCAquOyQQuvvUSH2rnlG51/ruWFgqUCAwEAAaOCAWUwggFhMB8GA1UdIwQY +MBaAFLuvfgI9+qbxPISOre44mOzZMjLUMB0GA1UdDgQWBBSQr2o6lFoL2JDqElZz +30O0Oija5zAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNV +HSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGwYDVR0gBBQwEjAGBgRVHSAAMAgG +BmeBDAECATBMBgNVHR8ERTBDMEGgP6A9hjtodHRwOi8vY3JsLmNvbW9kb2NhLmNv +bS9DT01PRE9SU0FDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDBxBggrBgEFBQcB +AQRlMGMwOwYIKwYBBQUHMAKGL2h0dHA6Ly9jcnQuY29tb2RvY2EuY29tL0NPTU9E +T1JTQUFkZFRydXN0Q0EuY3J0MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21v +ZG9jYS5jb20wDQYJKoZIhvcNAQEMBQADggIBAE4rdk+SHGI2ibp3wScF9BzWRJ2p +mj6q1WZmAT7qSeaiNbz69t2Vjpk1mA42GHWx3d1Qcnyu3HeIzg/3kCDKo2cuH1Z/ +e+FE6kKVxF0NAVBGFfKBiVlsit2M8RKhjTpCipj4SzR7JzsItG8kO3KdY3RYPBps +P0/HEZrIqPW1N+8QRcZs2eBelSaz662jue5/DJpmNXMyYE7l3YphLG5SEXdoltMY +dVEVABt0iN3hxzgEQyjpFv3ZBdRdRydg1vs4O2xyopT4Qhrf7W8GjEXCBgCq5Ojc +2bXhc3js9iPc0d1sjhqPpepUfJa3w/5Vjo1JXvxku88+vZbrac2/4EjxYoIQ5QxG +V/Iz2tDIY+3GH5QFlkoakdH368+PUq4NCNk+qKBR6cGHdNXJ93SrLlP7u3r7l+L4 +HyaPs9Kg4DdbKDsx5Q5XLVq4rXmsXiBmGqW5prU5wfWYQ//u+aen/e7KJD2AFsQX +j4rBYKEMrltDR5FL1ZoXX/nUh8HCjLfn4g8wGTeGrODcQgPmlKidrv0PJFGUzpII +0fxQ8ANAe4hZ7Q7drNJ3gjTcBpUC2JD5Leo31Rpg0Gcg19hCC0Wvgmje3WYkN5Ap +lBlGGSW4gNfL1IYoakRwJiNiqZ+Gb7+6kHDSVneFeO/qJakXzlByjAA6quPbYzSf ++AZxAeKCINT+b72x +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFdDCCBFygAwIBAgIQJ2buVutJ846r13Ci/ITeIjANBgkqhkiG9w0BAQwFADBv +MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk +ZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBF +eHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFow +gYUxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO +BgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMSswKQYD +VQQDEyJDT01PRE8gUlNBIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkq +hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAkehUktIKVrGsDSTdxc9EZ3SZKzejfSNw +AHG8U9/E+ioSj0t/EFa9n3Byt2F/yUsPF6c947AEYe7/EZfH9IY+Cvo+XPmT5jR6 +2RRr55yzhaCCenavcZDX7P0N+pxs+t+wgvQUfvm+xKYvT3+Zf7X8Z0NyvQwA1onr +ayzT7Y+YHBSrfuXjbvzYqOSSJNpDa2K4Vf3qwbxstovzDo2a5JtsaZn4eEgwRdWt +4Q08RWD8MpZRJ7xnw8outmvqRsfHIKCxH2XeSAi6pE6p8oNGN4Tr6MyBSENnTnIq +m1y9TBsoilwie7SrmNnu4FGDwwlGTm0+mfqVF9p8M1dBPI1R7Qu2XK8sYxrfV8g/ +vOldxJuvRZnio1oktLqpVj3Pb6r/SVi+8Kj/9Lit6Tf7urj0Czr56ENCHonYhMsT +8dm74YlguIwoVqwUHZwK53Hrzw7dPamWoUi9PPevtQ0iTMARgexWO/bTouJbt7IE +IlKVgJNp6I5MZfGRAy1wdALqi2cVKWlSArvX31BqVUa/oKMoYX9w0MOiqiwhqkfO +KJwGRXa/ghgntNWutMtQ5mv0TIZxMOmm3xaG4Nj/QN370EKIf6MzOi5cHkERgWPO +GHFrK+ymircxXDpqR+DDeVnWIBqv8mqYqnK8V0rSS527EPywTEHl7R09XiidnMy/ +s1Hap0flhFMCAwEAAaOB9DCB8TAfBgNVHSMEGDAWgBStvZh6NLQm9/rEJlTvA73g +JMtUGjAdBgNVHQ4EFgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQD +AgGGMA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0gBAowCDAGBgRVHSAAMEQGA1UdHwQ9 +MDswOaA3oDWGM2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9BZGRUcnVzdEV4dGVy +bmFsQ0FSb290LmNybDA1BggrBgEFBQcBAQQpMCcwJQYIKwYBBQUHMAGGGWh0dHA6 +Ly9vY3NwLnVzZXJ0cnVzdC5jb20wDQYJKoZIhvcNAQEMBQADggEBAGS/g/FfmoXQ +zbihKVcN6Fr30ek+8nYEbvFScLsePP9NDXRqzIGCJdPDoCpdTPW6i6FtxFQJdcfj +Jw5dhHk3QBN39bSsHNA7qxcS1u80GH4r6XnTq1dFDK8o+tDb5VCViLvfhVdpfZLY +Uspzgb8c8+a4bmYRBbMelC1/kZWSWfFMzqORcUx8Rww7Cxn2obFshj5cqsQugsv5 +B5a6SE2Q8pTIqXOi6wZ7I53eovNNVZ96YUWYGGjHXkBrI/V5eu+MtWuLt29G9Hvx +PUsE2JOAWVrgQSQdso8VYFhH2+9uRv0V9dlfmrPb2LjkQLPNlzmuhbsdjrzch5vR +pu/xO28QOG8= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU +MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs +IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290 +MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux +FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h +bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v +dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt +H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9 +uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX +mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX +a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN +E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0 +WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD +VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0 +Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU +cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx +IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN +AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH +YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 +6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC +Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX +c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a +mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= +-----END CERTIFICATE----- diff --git a/minimal-examples/ws-client/minimal-ws-client-rx/minimal-ws-client.c b/minimal-examples/ws-client/minimal-ws-client-rx/minimal-ws-client.c index 1ae557f4..1892a357 100644 --- a/minimal-examples/ws-client/minimal-ws-client-rx/minimal-ws-client.c +++ b/minimal-examples/ws-client/minimal-ws-client-rx/minimal-ws-client.c @@ -6,7 +6,7 @@ * This file is made available under the Creative Commons CC0 1.0 * Universal Public Domain Dedication. * - * This demonstrates the a minimal http client using lws. + * This demonstrates the a minimal ws client using lws. * * It connects to https://libwebsockets.org/ and makes a * wss connection to the dumb-increment protocol there. While @@ -92,6 +92,13 @@ int main(int argc, char **argv) info.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; info.port = CONTEXT_PORT_NO_LISTEN; /* we do not run any server */ info.protocols = protocols; +#if defined(LWS_WITH_MBEDTLS) + /* + * OpenSSL uses the system trust store. mbedTLS has to be told which + * CA to trust explicitly. + */ + info.client_ssl_ca_filepath = "./libwebsockets.org.cer"; +#endif context = lws_create_context(&info); if (!context) { @@ -102,12 +109,12 @@ int main(int argc, char **argv) memset(&i, 0, sizeof i); /* otherwise uninitialized garbage */ i.context = context; - i.port = 7681; - i.address = "localhost"; + i.port = 443; + i.address = "libwebsockets.org"; i.path = "/"; i.host = i.address; i.origin = i.address; - i.ssl_connection = 0; + i.ssl_connection = 1; i.protocol = protocols[0].name; /* "dumb-increment-protocol" */ i.pwsi = &client_wsi; diff --git a/test-apps/test-client.c b/test-apps/test-client.c index c5acd604..91049eaf 100644 --- a/test-apps/test-client.c +++ b/test-apps/test-client.c @@ -724,8 +724,13 @@ int main(int argc, char **argv) #endif } - if (use_ssl & LCCSCF_USE_SSL) + if (use_ssl & LCCSCF_USE_SSL) { lwsl_notice(" Using SSL\n"); +#if defined(LWS_WITH_MBEDTLS) + lwsl_notice(" (NOTE: mbedtls needs to be given the remote\n"); + lwsl_notice(" CA cert to trust (with -A) to validate it)\n"); +#endif + } else lwsl_notice(" SSL disabled\n"); if (use_ssl & LCCSCF_ALLOW_SELFSIGNED)