1 /*
2  * libwebsockets - small server side websockets and web server implementation
3  *
4  * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22  * IN THE SOFTWARE.
23  */
24 
25 #include "lws_config.h"
26 #ifdef LWS_HAVE_X509_VERIFY_PARAM_set1_host
27 /* Before glibc 2.10, strnlen required _GNU_SOURCE */
28 #if !defined(_GNU_SOURCE)
29 #define _GNU_SOURCE
30 #endif
31 #endif
32 #include <string.h>
33 
34 #include "private-lib-core.h"
35 #include "private-lib-tls-openssl.h"
36 
37 static const int MAX_CLIENT_SSL_CA_NUMBER = 10;
38 
39 /*
40  * Care: many openssl apis return 1 for success.  These are translated to the
41  * lws convention of 0 for success.
42  */
43 
44 int lws_openssl_describe_cipher(struct lws *wsi);
45 
46 extern int openssl_websocket_private_data_index,
47     openssl_SSL_CTX_private_data_index;
48 
49 #if !defined(USE_WOLFSSL)
50 
51 #if 0
52 #if defined(LWS_WITH_TLS_JIT_TRUST)
53 
54 /*
55  * Completion of sync or async JIT trust lookup
56  */
57 
58 int
59 lws_tls_jit_trust_got_cert_cb(void *got_opaque, const uint8_t *der,
60 			      size_t der_len)
61 {
62 	X509 *x = d2i_X509(NULL, &der, (long)der_len);
63 	/** !!! this is not safe for async atm */
64 	struct lws *wsi = (struct lws *)got_opaque;
65 	X509_STORE *xs;
66 	int ret = 0;
67 
68 	if (!x) {
69 		lwsl_err("%s: failed\n", __func__);
70 		return 1;
71 	}
72 
73 	xs = SSL_CTX_get_cert_store(SSL_get_SSL_CTX(wsi->tls.ssl));
74 	if (xs) {
75 		if (X509_STORE_add_cert(xs, x) != 1) {
76 			lwsl_warn("%s: unable to set trusted CA\n", __func__);
77 			ret = 1;
78 		} else
79 			lwsl_notice("%s: added trusted CA to CTX for next time\n",
80 					__func__);
81 	} else
82 		lwsl_warn("%s: couldn't get cert store\n", __func__);
83 
84 	X509_free(x);
85 
86 	return ret;
87 }
88 #endif
89 #endif
90 
91 static int
OpenSSL_client_verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx)92 OpenSSL_client_verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx)
93 {
94 	SSL *ssl;
95 	int n, err = 0;
96 	struct lws *wsi;
97 
98 	/* keep old behaviour accepting self-signed server certs */
99 	if (!preverify_ok) {
100 		err = X509_STORE_CTX_get_error(x509_ctx);
101 
102 		if (err != X509_V_OK) {
103 			ssl = X509_STORE_CTX_get_ex_data(x509_ctx,
104 					SSL_get_ex_data_X509_STORE_CTX_idx());
105 			wsi = SSL_get_ex_data(ssl,
106 					openssl_websocket_private_data_index);
107 			if (!wsi) {
108 				lwsl_err("%s: can't get wsi from ssl privdata\n",
109 					 __func__);
110 
111 				return 0;
112 			}
113 
114 			if ((err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT ||
115 			     err == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) &&
116 			     wsi->tls.use_ssl & LCCSCF_ALLOW_SELFSIGNED) {
117 				lwsl_notice("accepting self-signed "
118 					    "certificate (verify_callback)\n");
119 				X509_STORE_CTX_set_error(x509_ctx, X509_V_OK);
120 				return 1;	// ok
121 		} else if ((err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY ||
122 			    err == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE) &&
123 			    wsi->tls.use_ssl & LCCSCF_ALLOW_INSECURE) {
124 				lwsl_notice("accepting non-trusted certificate\n");
125 				X509_STORE_CTX_set_error(x509_ctx, X509_V_OK);
126 				return 1;  /* ok */
127 			} else if ((err == X509_V_ERR_CERT_NOT_YET_VALID ||
128 				    err == X509_V_ERR_CERT_HAS_EXPIRED) &&
129 				    wsi->tls.use_ssl & LCCSCF_ALLOW_EXPIRED) {
130 				if (err == X509_V_ERR_CERT_NOT_YET_VALID)
131 					lwsl_notice("accepting not yet valid "
132 						    "certificate (verify_"
133 						    "callback)\n");
134 				else if (err == X509_V_ERR_CERT_HAS_EXPIRED)
135 					lwsl_notice("accepting expired "
136 						    "certificate (verify_"
137 						    "callback)\n");
138 				X509_STORE_CTX_set_error(x509_ctx, X509_V_OK);
139 				return 1;	// ok
140 			}
141 		}
142 	}
143 
144 	ssl = X509_STORE_CTX_get_ex_data(x509_ctx,
145 					 SSL_get_ex_data_X509_STORE_CTX_idx());
146 	wsi = SSL_get_ex_data(ssl, openssl_websocket_private_data_index);
147 	if (!wsi) {
148 		lwsl_err("%s: can't get wsi from ssl privdata\n",  __func__);
149 
150 		return 0;
151 	}
152 
153 #if defined(LWS_WITH_TLS_JIT_TRUST)
154 	if (err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY) {
155 		union lws_tls_cert_info_results ci;
156 		STACK_OF(X509) *x509_stack;
157 
158 		x509_stack = X509_STORE_CTX_get1_chain(x509_ctx);
159 		if (x509_stack) {
160 
161 			for (n = 0; n < OPENSSL_sk_num((const OPENSSL_STACK *)x509_stack) &&
162 				    wsi->tls.kid_chain.count !=
163 				     LWS_ARRAY_SIZE(wsi->tls.kid_chain.akid); n++) {
164 				X509 *x509 = OPENSSL_sk_value((const OPENSSL_STACK *)x509_stack, n);
165 
166 				if (!lws_tls_openssl_cert_info(x509,
167 					    LWS_TLS_CERT_INFO_SUBJECT_KEY_ID,
168 					    &ci, 0))
169 					lws_tls_kid_copy(&ci,
170 						&wsi->tls.kid_chain.skid[
171 						     wsi->tls.kid_chain.count]);
172 
173 				if (!lws_tls_openssl_cert_info(x509,
174 					     LWS_TLS_CERT_INFO_AUTHORITY_KEY_ID,
175 					     &ci, 0))
176 					lws_tls_kid_copy(&ci,
177 						 &wsi->tls.kid_chain.akid[
178 						     wsi->tls.kid_chain.count]);
179 
180 				wsi->tls.kid_chain.count++;
181 			}
182 
183 			sk_X509_pop_free(x509_stack, X509_free);
184 		}
185 
186 		lws_tls_jit_trust_sort_kids(wsi, &wsi->tls.kid_chain);
187 	}
188 #endif
189 
190 	n = lws_get_context_protocol(wsi->a.context, 0).callback(wsi,
191 			LWS_CALLBACK_OPENSSL_PERFORM_SERVER_CERT_VERIFICATION,
192 			x509_ctx, ssl, (unsigned int)preverify_ok);
193 
194 	/* keep old behaviour if something wrong with server certs */
195 	/* if ssl error is overruled in callback and cert is ok,
196 	 * X509_STORE_CTX_set_error(x509_ctx, X509_V_OK); must be set and
197 	 * return value is 0 from callback */
198 	if (!preverify_ok) {
199 		int err = X509_STORE_CTX_get_error(x509_ctx);
200 
201 		if (err != X509_V_OK) {
202 			/* cert validation error was not handled in callback */
203 			int depth = X509_STORE_CTX_get_error_depth(x509_ctx);
204 			const char *msg = X509_verify_cert_error_string(err);
205 
206 			lws_strncpy(wsi->tls.err_helper, msg,
207 				    sizeof(wsi->tls.err_helper));
208 
209 			lwsl_err("SSL error: %s (preverify_ok=%d;err=%d;"
210 				 "depth=%d)\n", msg, preverify_ok, err, depth);
211 
212 #if defined(LWS_WITH_SYS_METRICS)
213 			{
214 				char buckname[64];
215 
216 				lws_snprintf(buckname, sizeof(buckname),
217 					     "tls=\"%s\"", msg);
218 				lws_metrics_hist_bump_describe_wsi(wsi,
219 					lws_metrics_priv_to_pub(wsi->a.context->mth_conn_failures),
220 					buckname);
221 			}
222 #endif
223 
224 			return preverify_ok;	// not ok
225 		}
226 	}
227 	/*
228 	 * convert callback return code from 0 = OK to verify callback
229 	 * return value 1 = OK
230 	 */
231 	return !n;
232 }
233 #endif
234 
235 int
lws_ssl_client_bio_create(struct lws *wsi)236 lws_ssl_client_bio_create(struct lws *wsi)
237 {
238 	char hostname[128], *p;
239 #if defined(LWS_HAVE_SSL_set_alpn_protos) && \
240     defined(LWS_HAVE_SSL_get0_alpn_selected)
241 	uint8_t openssl_alpn[40];
242 	const char *alpn_comma = wsi->a.context->tls.alpn_default;
243 	int n;
244 #endif
245 
246 	if (wsi->stash) {
247 		lws_strncpy(hostname, wsi->stash->cis[CIS_HOST], sizeof(hostname));
248 #if defined(LWS_HAVE_SSL_set_alpn_protos) && \
249     defined(LWS_HAVE_SSL_get0_alpn_selected)
250 		alpn_comma = wsi->stash->cis[CIS_ALPN];
251 #endif
252 	} else {
253 #if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
254 		if (lws_hdr_copy(wsi, hostname, sizeof(hostname),
255 				 _WSI_TOKEN_CLIENT_HOST) <= 0)
256 #endif
257 		{
258 			lwsl_err("%s: Unable to get hostname\n", __func__);
259 
260 			return -1;
261 		}
262 	}
263 
264 	/*
265 	 * remove any :port part on the hostname... necessary for network
266 	 * connection but typical certificates do not contain it
267 	 */
268 	p = hostname;
269 	while (*p) {
270 		if (*p == ':') {
271 			*p = '\0';
272 			break;
273 		}
274 		p++;
275 	}
276 
277 	wsi->tls.ssl = SSL_new(wsi->a.vhost->tls.ssl_client_ctx);
278 	if (!wsi->tls.ssl) {
279 		const char *es = ERR_error_string(
280 #if defined(LWS_WITH_BORINGSSL)
281 	(uint32_t)
282 #else
283 	(unsigned long)
284 #endif
285 	lws_ssl_get_error(wsi, 0), NULL);
286 		lwsl_err("SSL_new failed: %s\n", es);
287 		lws_tls_err_describe_clear();
288 		return -1;
289 	}
290 
291 #if defined(LWS_WITH_TLS_SESSIONS)
292 	if (!(wsi->a.vhost->options & LWS_SERVER_OPTION_DISABLE_TLS_SESSION_CACHE))
293 		lws_tls_reuse_session(wsi);
294 #endif
295 
296 #if defined (LWS_HAVE_SSL_SET_INFO_CALLBACK)
297 	if (wsi->a.vhost->tls.ssl_info_event_mask)
298 		SSL_set_info_callback(wsi->tls.ssl, lws_ssl_info_callback);
299 #endif
300 
301 #if defined(LWS_HAVE_X509_VERIFY_PARAM_set1_host)
302 	if (!(wsi->tls.use_ssl & LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK)) {
303 #if !defined(USE_WOLFSSL)
304 
305 		X509_VERIFY_PARAM *param = SSL_get0_param(wsi->tls.ssl);
306 
307 		/* Enable automatic hostname checks */
308 		X509_VERIFY_PARAM_set_hostflags(param,
309 					X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
310 		/* Handle the case where the hostname is an IP address */
311 		if (!X509_VERIFY_PARAM_set1_ip_asc(param, hostname))
312 			X509_VERIFY_PARAM_set1_host(param, hostname,
313 					strnlen(hostname, sizeof(hostname)));
314 #endif
315 
316 	}
317 #else
318 	if (!(wsi->tls.use_ssl & LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK)) {
319 		lwsl_err("%s: your tls lib is too old to have "
320 			 "X509_VERIFY_PARAM_set1_host, failing all client tls\n",
321 			 __func__);
322 		return -1;
323 	}
324 #endif
325 
326 #if !defined(USE_WOLFSSL)
327 #ifndef USE_OLD_CYASSL
328 	/* OpenSSL_client_verify_callback will be called @ SSL_connect() */
329 	SSL_set_verify(wsi->tls.ssl, SSL_VERIFY_PEER,
330 		       OpenSSL_client_verify_callback);
331 #endif
332 #endif
333 
334 #if !defined(USE_WOLFSSL)
335 	SSL_set_mode(wsi->tls.ssl,  SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
336 #endif
337 	/*
338 	 * use server name indication (SNI), if supported,
339 	 * when establishing connection
340 	 */
341 #ifdef USE_WOLFSSL
342 #ifdef USE_OLD_CYASSL
343 #ifdef CYASSL_SNI_HOST_NAME
344 	CyaSSL_UseSNI(wsi->tls.ssl, CYASSL_SNI_HOST_NAME, hostname,
345 		      strlen(hostname));
346 #endif
347 #else
348 #if defined(WOLFSSL_SNI_HOST_NAME) || defined(HAVE_SNI)
349 	wolfSSL_UseSNI(wsi->tls.ssl, WOLFSSL_SNI_HOST_NAME, hostname,
350 		       (unsigned short)strlen(hostname));
351 #endif
352 #endif
353 #else
354 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
355 	SSL_set_tlsext_host_name(wsi->tls.ssl, hostname);
356 #endif
357 #endif
358 
359 #ifdef USE_WOLFSSL
360 	/*
361 	 * wolfSSL/CyaSSL does certificate verification differently
362 	 * from OpenSSL.
363 	 * If we should ignore the certificate, we need to set
364 	 * this before SSL_new and SSL_connect is called.
365 	 * Otherwise the connect will simply fail with error code -155
366 	 */
367 #ifdef USE_OLD_CYASSL
368 	if (wsi->tls.use_ssl & LCCSCF_ALLOW_SELFSIGNED)
369 		CyaSSL_set_verify(wsi->tls.ssl, SSL_VERIFY_NONE, NULL);
370 #else
371 	if (wsi->tls.use_ssl & LCCSCF_ALLOW_SELFSIGNED)
372 		wolfSSL_set_verify(wsi->tls.ssl, SSL_VERIFY_NONE, NULL);
373 #endif
374 #endif /* USE_WOLFSSL */
375 
376 	wsi->tls.client_bio = BIO_new_socket((int)(lws_intptr_t)wsi->desc.sockfd,
377 					     BIO_NOCLOSE);
378 	SSL_set_bio(wsi->tls.ssl, wsi->tls.client_bio, wsi->tls.client_bio);
379 
380 #ifdef USE_WOLFSSL
381 #ifdef USE_OLD_CYASSL
382 	CyaSSL_set_using_nonblock(wsi->tls.ssl, 1);
383 #else
384 	wolfSSL_set_using_nonblock(wsi->tls.ssl, 1);
385 #endif
386 #else
387 	BIO_set_nbio(wsi->tls.client_bio, 1); /* nonblocking */
388 #endif
389 
390 #if defined(LWS_HAVE_SSL_set_alpn_protos) && \
391     defined(LWS_HAVE_SSL_get0_alpn_selected)
392 	if (wsi->a.vhost->tls.alpn)
393 		alpn_comma = wsi->a.vhost->tls.alpn;
394 	if (wsi->stash)
395 		alpn_comma = wsi->stash->cis[CIS_ALPN];
396 #if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
397 	if (lws_hdr_copy(wsi, hostname, sizeof(hostname),
398 			 _WSI_TOKEN_CLIENT_ALPN) > 0)
399 		alpn_comma = hostname;
400 #endif
401 
402 	lwsl_info("%s client conn using alpn list '%s'\n", wsi->role_ops->name, alpn_comma);
403 
404 	n = lws_alpn_comma_to_openssl(alpn_comma, openssl_alpn,
405 				      sizeof(openssl_alpn) - 1);
406 
407 	SSL_set_alpn_protos(wsi->tls.ssl, openssl_alpn, (unsigned int)n);
408 #endif
409 
410 	SSL_set_ex_data(wsi->tls.ssl, openssl_websocket_private_data_index,
411 			wsi);
412 
413 	if (wsi->sys_tls_client_cert) {
414 		lws_system_blob_t *b = lws_system_get_blob(wsi->a.context,
415 					LWS_SYSBLOB_TYPE_CLIENT_CERT_DER,
416 					wsi->sys_tls_client_cert - 1);
417 		const uint8_t *data;
418 		size_t size;
419 
420 		if (!b)
421 			goto no_client_cert;
422 
423 		/*
424 		 * Set up the per-connection client cert
425 		 */
426 
427 		size = lws_system_blob_get_size(b);
428 		if (!size)
429 			goto no_client_cert;
430 
431 		if (lws_system_blob_get_single_ptr(b, &data))
432 			goto no_client_cert;
433 
434 		if (SSL_use_certificate_ASN1(wsi->tls.ssl,
435 #if defined(USE_WOLFSSL)
436 			(unsigned char *)
437 #endif
438 					data,
439 #if defined(LWS_WITH_BORINGSSL)
440 					(size_t)
441 #else
442 					(int)
443 #endif
444 					size) != 1) {
445 			lwsl_err("%s: use_certificate failed\n", __func__);
446 			lws_tls_err_describe_clear();
447 			goto no_client_cert;
448 		}
449 
450 		b = lws_system_get_blob(wsi->a.context,
451 					LWS_SYSBLOB_TYPE_CLIENT_KEY_DER,
452 					wsi->sys_tls_client_cert - 1);
453 		if (!b)
454 			goto no_client_cert;
455 
456 		size = lws_system_blob_get_size(b);
457 		if (!size)
458 			goto no_client_cert;
459 
460 		if (lws_system_blob_get_single_ptr(b, &data))
461 			goto no_client_cert;
462 
463 		if (SSL_use_PrivateKey_ASN1(EVP_PKEY_RSA, wsi->tls.ssl,
464 #if defined(USE_WOLFSSL)
465 			(unsigned char *)
466 #endif
467 
468 					    data,
469 #if defined(LWS_WITH_BORINGSSL)
470 					(size_t)
471 #else
472 					(int)
473 #endif
474 					    size) != 1 &&
475 		    SSL_use_PrivateKey_ASN1(EVP_PKEY_EC, wsi->tls.ssl,
476 #if defined(USE_WOLFSSL)
477 			(unsigned char *)
478 #endif
479 					    data,
480 #if defined(LWS_WITH_BORINGSSL)
481 					(size_t)
482 #else
483 					(int)
484 #endif
485 					    size) != 1) {
486 			lwsl_err("%s: use_privkey failed\n", __func__);
487 			lws_tls_err_describe_clear();
488 			goto no_client_cert;
489 		}
490 
491 		if (SSL_check_private_key(wsi->tls.ssl) != 1) {
492 			lwsl_err("Private SSL key doesn't match cert\n");
493 			lws_tls_err_describe_clear();
494 			return 1;
495 		}
496 
497 		lwsl_notice("%s: set system client cert %u\n", __func__,
498 				wsi->sys_tls_client_cert - 1);
499 	}
500 
501 	return 0;
502 
503 no_client_cert:
504 	lwsl_err("%s: unable to set up system client cert %d\n", __func__,
505 			wsi->sys_tls_client_cert - 1);
506 
507 	return 1;
508 }
509 
510 enum lws_ssl_capable_status
lws_tls_client_connect(struct lws *wsi, char *errbuf, size_t elen)511 lws_tls_client_connect(struct lws *wsi, char *errbuf, size_t elen)
512 {
513 #if defined(LWS_HAVE_SSL_set_alpn_protos) && \
514     defined(LWS_HAVE_SSL_get0_alpn_selected)
515 	const unsigned char *prot;
516 	char a[32];
517 	unsigned int len;
518 #endif
519 	int m, n, en;
520 	unsigned long l;
521 #if defined(LWS_WITH_TLS_SESSIONS) && defined(LWS_HAVE_SSL_SESSION_set_time)
522 	SSL_SESSION *sess;
523 #endif
524 	errno = 0;
525 	ERR_clear_error();
526 	wsi->tls.err_helper[0] = '\0';
527 	n = SSL_connect(wsi->tls.ssl);
528 	en = errno;
529 
530 	m = lws_ssl_get_error(wsi, n);
531 
532 	if (m == SSL_ERROR_SYSCALL
533 #if defined(WIN32)
534 			&& en
535 #endif
536 	) {
537 #if defined(WIN32) || (_LWS_ENABLED_LOGS & LLL_INFO)
538 		lwsl_info("%s: n %d, m %d, errno %d\n", __func__, n, m, en);
539 #endif
540 		lws_snprintf(errbuf, elen, "connect SYSCALL %d", en);
541 		return LWS_SSL_CAPABLE_ERROR;
542 	}
543 
544 	if (m == SSL_ERROR_SSL) {
545 		l = ERR_get_error();
546 		n = lws_snprintf(errbuf, elen, "tls: %s", wsi->tls.err_helper);
547 		if (!wsi->tls.err_helper[0])
548 			ERR_error_string_n((unsigned int)l, errbuf + n, (elen - (unsigned int)n));
549 		return LWS_SSL_CAPABLE_ERROR;
550 	}
551 
552 #if defined(LWS_WITH_TLS_SESSIONS)
553 	if (SSL_session_reused(wsi->tls.ssl)) {
554 #if defined(LWS_HAVE_SSL_SESSION_set_time)
555 		sess = SSL_get_session(wsi->tls.ssl);
556 		if (sess) /* should always be true */
557 #if defined(OPENSSL_IS_BORINGSSL)
558 			SSL_SESSION_set_time(sess, (uint64_t)time(NULL)); /* extend session lifetime */
559 #else
560 			SSL_SESSION_set_time(sess, (long)time(NULL)); /* extend session lifetime */
561 #endif
562 #endif
563 	}
564 #endif
565 
566 	if (m == SSL_ERROR_WANT_READ || SSL_want_read(wsi->tls.ssl))
567 		return LWS_SSL_CAPABLE_MORE_SERVICE_READ;
568 
569 	if (m == SSL_ERROR_WANT_WRITE || SSL_want_write(wsi->tls.ssl))
570 		return LWS_SSL_CAPABLE_MORE_SERVICE_WRITE;
571 
572 	if (n == 1 || m == SSL_ERROR_SYSCALL) {
573 #if defined(LWS_HAVE_SSL_set_alpn_protos) && \
574     defined(LWS_HAVE_SSL_get0_alpn_selected)
575 		SSL_get0_alpn_selected(wsi->tls.ssl, &prot, &len);
576 
577 		if (len >= sizeof(a))
578 			len = sizeof(a) - 1;
579 		memcpy(a, (const char *)prot, len);
580 		a[len] = '\0';
581 
582 		lws_role_call_alpn_negotiated(wsi, (const char *)a);
583 #endif
584 #if defined(LWS_TLS_SYNTHESIZE_CB)
585 		lws_sul_schedule(wsi->a.context, wsi->tsi,
586 				 &wsi->tls.sul_cb_synth,
587 				 lws_sess_cache_synth_cb, 500 * LWS_US_PER_MS);
588 #endif
589 
590 		lwsl_info("client connect OK\n");
591 		lws_openssl_describe_cipher(wsi);
592 		return LWS_SSL_CAPABLE_DONE;
593 	}
594 
595 	if (!n) /* we don't know what he wants, but he says to retry */
596 		return LWS_SSL_CAPABLE_MORE_SERVICE;
597 
598 	lws_snprintf(errbuf, elen, "connect unk %d", m);
599 
600 	return LWS_SSL_CAPABLE_ERROR;
601 }
602 
603 int
lws_tls_client_confirm_peer_cert(struct lws *wsi, char *ebuf, size_t ebuf_len)604 lws_tls_client_confirm_peer_cert(struct lws *wsi, char *ebuf, size_t ebuf_len)
605 {
606 #if !defined(USE_WOLFSSL)
607 	struct lws_context_per_thread *pt = &wsi->a.context->pt[(int)wsi->tsi];
608 	char *p = (char *)&pt->serv_buf[0];
609 	const char *es, *type = "";
610 	unsigned int avoid = 0;
611 	char *sb = p;
612 	long n;
613 
614 	errno = 0;
615 	ERR_clear_error();
616 	n = SSL_get_verify_result(wsi->tls.ssl);
617 
618 	switch (n) {
619 	case X509_V_OK:
620 		return 0;
621 
622 	case X509_V_ERR_HOSTNAME_MISMATCH:
623 		type = "tls=hostname";
624 		avoid = LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK;
625 		break;
626 
627 	case X509_V_ERR_INVALID_CA:
628 	case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
629 	case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
630 		type = "tls=invalidca";
631 		avoid = LCCSCF_ALLOW_SELFSIGNED;
632 		break;
633 
634 	case X509_V_ERR_CERT_NOT_YET_VALID:
635 		type = "tls=notyetvalid";
636 		avoid = LCCSCF_ALLOW_EXPIRED;
637 		break;
638 
639 	case X509_V_ERR_CERT_HAS_EXPIRED:
640 		type = "tls=expired";
641 		avoid = LCCSCF_ALLOW_EXPIRED;
642 		break;
643 	}
644 
645 	lwsl_info("%s: cert problem: %s\n", __func__, type);
646 
647 #if defined(LWS_WITH_SYS_METRICS)
648 	lws_metrics_hist_bump_describe_wsi(wsi,
649 			lws_metrics_priv_to_pub(wsi->a.context->mth_conn_failures), type);
650 #endif
651 
652 	if (wsi->tls.use_ssl & avoid) {
653 		lwsl_info("%s: allowing anyway\n", __func__);
654 
655 		return 0;
656 	}
657 
658 	es = ERR_error_string(
659 	#if defined(LWS_WITH_BORINGSSL)
660 					 (uint32_t)
661 	#else
662 					 (unsigned long)
663 	#endif
664 					 n, sb);
665 	lws_snprintf(ebuf, ebuf_len,
666 		"server's cert didn't look good, %s X509_V_ERR = %ld: %s\n",
667 		 type, n, es);
668 	lwsl_info("%s\n", ebuf);
669 	lws_tls_err_describe_clear();
670 
671 	return -1;
672 
673 #else /* USE_WOLFSSL */
674 	return 0;
675 #endif
676 }
677 
678 int
lws_tls_client_vhost_extra_cert_mem(struct lws_vhost *vh, const uint8_t *der, size_t der_len)679 lws_tls_client_vhost_extra_cert_mem(struct lws_vhost *vh,
680                 const uint8_t *der, size_t der_len)
681 {
682 	X509_STORE *st;
683 #if defined(USE_WOLFSSL)
684 	X509 *x  = d2i_X509(NULL, &der, (int)der_len);
685 #else
686 	X509 *x  = d2i_X509(NULL, &der, (long)der_len);
687 #endif
688 	int n;
689 
690 	if (!x) {
691 		lwsl_err("%s: Failed to load DER\n", __func__);
692 		lws_tls_err_describe_clear();
693 		return 1;
694 	}
695 
696 	st = SSL_CTX_get_cert_store(vh->tls.ssl_client_ctx);
697 	if (!st) {
698 		lwsl_err("%s: failed to get cert store\n", __func__);
699 		X509_free(x);
700 		return 1;
701 	}
702 
703 	n = X509_STORE_add_cert(st, x);
704 	if (n != 1)
705 		lwsl_err("%s: failed to add cert\n", __func__);
706 
707 	X509_free(x);
708 
709 	return n != 1;
710 }
711 
712 int
lws_tls_client_create_vhost_context(struct lws_vhost *vh, const struct lws_context_creation_info *info, const char *cipher_list, const char *ca_filepath, const void *ca_mem, unsigned int ca_mem_len, const char *cert_filepath, const void *cert_mem, unsigned int cert_mem_len, const char *private_key_filepath, const void *key_mem, unsigned int key_mem_len )713 lws_tls_client_create_vhost_context(struct lws_vhost *vh,
714 				    const struct lws_context_creation_info *info,
715 				    const char *cipher_list,
716 				    const char *ca_filepath,
717 				    const void *ca_mem,
718 				    unsigned int ca_mem_len,
719 				    const char *cert_filepath,
720 				    const void *cert_mem,
721 				    unsigned int cert_mem_len,
722 				    const char *private_key_filepath,
723 					const void *key_mem,
724 				    unsigned int key_mem_len
725 					)
726 {
727 	struct lws_tls_client_reuse *tcr;
728 	X509_STORE *x509_store;
729 	unsigned long error;
730 	SSL_METHOD *method;
731 	EVP_MD_CTX *mdctx;
732 	unsigned int len;
733 	uint8_t hash[32];
734 	X509 *client_CA;
735 	char c;
736 	int n;
737 
738 	/* basic openssl init already happened in context init */
739 
740 	/* choose the most recent spin of the api */
741 #if defined(LWS_HAVE_TLS_CLIENT_METHOD)
742 	method = (SSL_METHOD *)TLS_client_method();
743 #elif defined(LWS_HAVE_TLSV1_2_CLIENT_METHOD)
744 	method = (SSL_METHOD *)TLSv1_2_client_method();
745 #else
746 	method = (SSL_METHOD *)SSLv23_client_method();
747 #endif
748 
749 	if (!method) {
750 		const char *es;
751 
752 		error = ERR_get_error();
753 		es = ERR_error_string(
754 		#if defined(LWS_WITH_BORINGSSL)
755 			(uint32_t)
756 		#else
757 			(unsigned long)
758 		#endif
759 			 error, (char *)vh->context->pt[0].serv_buf);
760 		lwsl_err("problem creating ssl method %lu: %s\n",
761 			error, es);
762 		return 1;
763 	}
764 
765 	/*
766 	 * OpenSSL client contexts are quite expensive, because they bring in
767 	 * the system certificate bundle for each one.  So if you have multiple
768 	 * vhosts, each with a client context, it can add up to several
769 	 * megabytes of heap.  In the case the client contexts are configured
770 	 * identically, they could perfectly well have shared just the one.
771 	 *
772 	 * For that reason, use a hash to fingerprint the context configuration
773 	 * and prefer to reuse an existing one with the same fingerprint if
774 	 * possible.
775 	 */
776 
777 	 mdctx = EVP_MD_CTX_create();
778 	 if (!mdctx)
779 		 return 1;
780 
781 	if (EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL) != 1) {
782 		EVP_MD_CTX_destroy(mdctx);
783 
784 		return 1;
785 	}
786 
787 	if (info->ssl_client_options_set)
788 		EVP_DigestUpdate(mdctx, &info->ssl_client_options_set,
789 				 sizeof(info->ssl_client_options_set));
790 
791 #if (OPENSSL_VERSION_NUMBER >= 0x009080df) && !defined(USE_WOLFSSL)
792 	if (info->ssl_client_options_clear)
793 		EVP_DigestUpdate(mdctx, &info->ssl_client_options_clear,
794 				 sizeof(info->ssl_client_options_clear));
795 #endif
796 
797 	if (cipher_list)
798 		EVP_DigestUpdate(mdctx, cipher_list, strlen(cipher_list));
799 
800 #if defined(LWS_HAVE_SSL_CTX_set_ciphersuites)
801 	if (info->client_tls_1_3_plus_cipher_list)
802 		EVP_DigestUpdate(mdctx, info->client_tls_1_3_plus_cipher_list,
803 				 strlen(info->client_tls_1_3_plus_cipher_list));
804 #endif
805 
806 	if (!lws_check_opt(vh->options, LWS_SERVER_OPTION_DISABLE_OS_CA_CERTS)) {
807 		c = 1;
808 		EVP_DigestUpdate(mdctx, &c, 1);
809 	}
810 
811 	if (ca_filepath)
812 		EVP_DigestUpdate(mdctx, ca_filepath, strlen(ca_filepath));
813 
814 	if (cert_filepath)
815 		EVP_DigestUpdate(mdctx, cert_filepath, strlen(cert_filepath));
816 
817 	if (private_key_filepath)
818 		EVP_DigestUpdate(mdctx, private_key_filepath,
819 				 strlen(private_key_filepath));
820 	if (ca_mem && ca_mem_len)
821 		EVP_DigestUpdate(mdctx, ca_mem, ca_mem_len);
822 
823 	if (cert_mem && cert_mem_len)
824 		EVP_DigestUpdate(mdctx, cert_mem, cert_mem_len);
825 
826 	len = sizeof(hash);
827 	EVP_DigestFinal_ex(mdctx, hash, &len);
828 	EVP_MD_CTX_destroy(mdctx);
829 
830 	/* look for existing client context with same config already */
831 
832 	lws_start_foreach_dll_safe(struct lws_dll2 *, p, tp,
833 			 lws_dll2_get_head(&vh->context->tls.cc_owner)) {
834 		tcr = lws_container_of(p, struct lws_tls_client_reuse, cc_list);
835 
836 		if (!memcmp(hash, tcr->hash, len)) {
837 
838 			/* it's a match */
839 
840 			tcr->refcount++;
841 			vh->tls.ssl_client_ctx = tcr->ssl_client_ctx;
842 			vh->tls.tcr = tcr;
843 
844 			lwsl_info("%s: vh %s: reusing client ctx %d: use %d\n",
845 				   __func__, vh->name, tcr->index,
846 				   tcr->refcount);
847 
848 			return 0;
849 		}
850 	} lws_end_foreach_dll_safe(p, tp);
851 
852 	/* no existing one the same... create new client SSL_CTX */
853 
854 	errno = 0;
855 	ERR_clear_error();
856 	vh->tls.ssl_client_ctx = SSL_CTX_new(method);
857 	if (!vh->tls.ssl_client_ctx) {
858 		const char *es;
859 
860 		error = ERR_get_error();
861 		es = ERR_error_string(
862 		#if defined(LWS_WITH_BORINGSSL)
863 			(uint32_t)
864 		#else
865 			(unsigned long)
866 		#endif
867 			 error, (char *)vh->context->pt[0].serv_buf);
868 		lwsl_err("problem creating ssl context %lu: %s\n",
869 			error, es);
870 		return 1;
871 	}
872 
873 	SSL_CTX_set_ex_data(vh->tls.ssl_client_ctx,
874 				openssl_SSL_CTX_private_data_index,
875 				(char *)vh->context);
876 
877 	lws_plat_vhost_tls_client_ctx_init(vh);
878 
879 	tcr = lws_zalloc(sizeof(*tcr), "client ctx tcr");
880 	if (!tcr) {
881 		SSL_CTX_free(vh->tls.ssl_client_ctx);
882 		return 1;
883 	}
884 
885 	tcr->ssl_client_ctx = vh->tls.ssl_client_ctx;
886 	tcr->refcount = 1;
887 	memcpy(tcr->hash, hash, len);
888 	tcr->index = vh->context->tls.count_client_contexts++;
889 	lws_dll2_add_head(&tcr->cc_list, &vh->context->tls.cc_owner);
890 
891 	lwsl_info("%s: vh %s: created new client ctx %d\n", __func__,
892 			vh->name, tcr->index);
893 
894 	/* bind the tcr to the client context */
895 
896 	vh->tls.tcr = tcr;
897 
898 #if defined(LWS_WITH_TLS_SESSIONS)
899 	vh->tls_session_cache_max = info->tls_session_cache_max ?
900 				    info->tls_session_cache_max : 10;
901 	lws_tls_session_cache(vh, info->tls_session_timeout);
902 #endif
903 
904 #ifdef SSL_OP_NO_COMPRESSION
905 	SSL_CTX_set_options(vh->tls.ssl_client_ctx, SSL_OP_NO_COMPRESSION);
906 #endif
907 
908 	SSL_CTX_set_options(vh->tls.ssl_client_ctx,
909 			    SSL_OP_CIPHER_SERVER_PREFERENCE);
910 
911 	SSL_CTX_set_mode(vh->tls.ssl_client_ctx,
912 			 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
913 			 SSL_MODE_RELEASE_BUFFERS);
914 
915 #if !defined(USE_WOLFSSL)
916 #if defined(LWS_WITH_BORINGSSL)
917 				uint32_t
918 #else
919 #if (OPENSSL_VERSION_NUMBER >= 0x10003000l) && \
920 	!defined(LIBRESSL_VERSION_NUMBER) /* not documented by openssl */
921 		unsigned long
922 #else
923 		long
924 #endif
925 #endif
926 #else
927 		long
928 #endif
929 			ssl_client_options_set_value =
930 #if !defined(USE_WOLFSSL)
931 #if defined(LWS_WITH_BORINGSSL)
932 				(uint32_t)
933 #else
934 #if (OPENSSL_VERSION_NUMBER >= 0x10003000l) && \
935 	!defined(LIBRESSL_VERSION_NUMBER) /* not documented by openssl */
936 				(unsigned long)
937 #else
938 				(long)
939 #endif
940 #endif
941 #endif
942 			info->ssl_client_options_set;
943 
944 	if (info->ssl_client_options_set)
945 		SSL_CTX_set_options(vh->tls.ssl_client_ctx, ssl_client_options_set_value);
946 
947 #if (OPENSSL_VERSION_NUMBER >= 0x009080df) && !defined(USE_WOLFSSL)
948 
949 	/* SSL_clear_options introduced in 0.9.8m */
950 #if defined(LWS_WITH_BORINGSSL)
951                 uint32_t
952 #else
953 #if (OPENSSL_VERSION_NUMBER >= 0x10003000l) && \
954 	!defined(LIBRESSL_VERSION_NUMBER) /* not documented by openssl */
955 		unsigned long
956 #else
957 		long
958 #endif
959 #endif
960 
961 			ssl_client_options_clear_value =
962 #if defined(LWS_WITH_BORINGSSL)
963 				(uint32_t)
964 #else
965 #if (OPENSSL_VERSION_NUMBER >= 0x10003000l) && \
966 	!defined(LIBRESSL_VERSION_NUMBER) /* not documented by openssl */
967 				(unsigned long)
968 #else
969 				(long)
970 #endif
971 #endif
972 			info->ssl_client_options_clear;
973 
974 	if (info->ssl_client_options_clear)
975 		SSL_CTX_clear_options(vh->tls.ssl_client_ctx, ssl_client_options_clear_value);
976 #endif
977 
978 	if (cipher_list)
979 		SSL_CTX_set_cipher_list(vh->tls.ssl_client_ctx, cipher_list);
980 
981 #if defined(LWS_HAVE_SSL_CTX_set_ciphersuites)
982 	if (info->client_tls_1_3_plus_cipher_list)
983 		SSL_CTX_set_ciphersuites(vh->tls.ssl_client_ctx,
984 					 info->client_tls_1_3_plus_cipher_list);
985 #endif
986 
987 #ifdef LWS_SSL_CLIENT_USE_OS_CA_CERTS
988 	if (!lws_check_opt(vh->options, LWS_SERVER_OPTION_DISABLE_OS_CA_CERTS))
989 		/* loads OS default CA certs */
990 		SSL_CTX_set_default_verify_paths(vh->tls.ssl_client_ctx);
991 #endif
992 
993 	/* openssl init for cert verification (for client sockets) */
994     if (!ca_mem || !ca_mem_len) {
995         for (int i = 0; i < MAX_CLIENT_SSL_CA_NUMBER; i++) {
996             if ((info->client_ssl_ca_dirs[i] != NULL) &&
997                 (!SSL_CTX_load_verify_locations(vh->tls.ssl_client_ctx, NULL, info->client_ssl_ca_dirs[i]))) {
998                 lwsl_err(
999                     "Unable to load SSL Client certs from %s "
1000                     "(set by info->client_ssl_ca_dirs[%d]) -- "
1001                     "client ssl isn't going to work\n",
1002                     info->client_ssl_ca_dirs[i], i);
1003             }
1004         }
1005     }
1006 
1007 	if (!ca_filepath && (!ca_mem || !ca_mem_len)) {
1008 #if defined(LWS_HAVE_SSL_CTX_load_verify_dir)
1009 		if (!SSL_CTX_load_verify_dir(
1010 			vh->tls.ssl_client_ctx, LWS_OPENSSL_CLIENT_CERTS))
1011 #else
1012 		if (!SSL_CTX_load_verify_locations(
1013 			vh->tls.ssl_client_ctx, NULL, LWS_OPENSSL_CLIENT_CERTS))
1014 #endif
1015 			lwsl_err("Unable to load SSL Client certs from %s "
1016 			    "(set by LWS_OPENSSL_CLIENT_CERTS) -- "
1017 			    "client ssl isn't going to work\n",
1018 			    LWS_OPENSSL_CLIENT_CERTS);
1019 	} else if (ca_filepath) {
1020 #if defined(LWS_HAVE_SSL_CTX_load_verify_file)
1021 		if (!SSL_CTX_load_verify_file(
1022 			vh->tls.ssl_client_ctx, ca_filepath)) {
1023 #else
1024 		if (!SSL_CTX_load_verify_locations(
1025 			vh->tls.ssl_client_ctx, ca_filepath, NULL)) {
1026 #endif
1027 			lwsl_err(
1028 				"Unable to load SSL Client certs "
1029 				"file from %s -- client ssl isn't "
1030 				"going to work\n", ca_filepath);
1031 			lws_tls_err_describe_clear();
1032 		}
1033 		else
1034 			lwsl_info("loaded ssl_ca_filepath\n");
1035 	} else {
1036 
1037 		lws_filepos_t amount = 0;
1038 		const uint8_t *up;
1039 		uint8_t *up1;
1040 
1041 		if (lws_tls_alloc_pem_to_der_file(vh->context, NULL, ca_mem,
1042 						  ca_mem_len, &up1, &amount)) {
1043 			lwsl_err("%s: Unable to decode x.509 mem\n", __func__);
1044 			lwsl_hexdump_notice(ca_mem, ca_mem_len);
1045 			return 1;
1046 		}
1047 
1048 		up = up1;
1049 #if defined(USE_WOLFSSL)
1050 		client_CA = d2i_X509(NULL, &up, (int)amount);
1051 #else
1052 		client_CA = d2i_X509(NULL, &up, (long)amount);
1053 #endif
1054 		if (!client_CA) {
1055 			lwsl_err("%s: d2i_X509 failed\n", __func__);
1056 			lwsl_hexdump_notice(up1, (size_t)amount);
1057 			lws_tls_err_describe_clear();
1058 		} else {
1059 			x509_store = X509_STORE_new();
1060 			if (!X509_STORE_add_cert(x509_store, client_CA)) {
1061 				X509_STORE_free(x509_store);
1062 				lwsl_err("Unable to load SSL Client certs from "
1063 					 "ssl_ca_mem -- client ssl isn't going to "
1064 					 "work\n");
1065 				lws_tls_err_describe_clear();
1066 			} else {
1067 				/* it doesn't increment x509_store ref counter */
1068 				SSL_CTX_set_cert_store(vh->tls.ssl_client_ctx,
1069 						       x509_store);
1070 				lwsl_info("loaded ssl_ca_mem\n");
1071 			}
1072 		}
1073 		if (client_CA)
1074 			X509_free(client_CA);
1075 		lws_free(up1);
1076 	//	lws_tls_client_vhost_extra_cert_mem(vh, ca_mem, ca_mem_len);
1077 	}
1078 
1079 	/*
1080 	 * callback allowing user code to load extra verification certs
1081 	 * helping the client to verify server identity
1082 	 */
1083 
1084 	/* support for client-side certificate authentication */
1085 
1086 	if (cert_filepath) {
1087 		if (lws_tls_use_any_upgrade_check_extant(cert_filepath) !=
1088 				LWS_TLS_EXTANT_YES &&
1089 		    (info->options & LWS_SERVER_OPTION_IGNORE_MISSING_CERT))
1090 			return 0;
1091 
1092 		lwsl_notice("%s: doing cert filepath %s\n", __func__,
1093 				cert_filepath);
1094 		n = SSL_CTX_use_certificate_chain_file(vh->tls.ssl_client_ctx,
1095 						       cert_filepath);
1096 		if (n < 1) {
1097 			lwsl_err("problem %d getting cert '%s'\n", n,
1098 				 cert_filepath);
1099 			lws_tls_err_describe_clear();
1100 			return 1;
1101 		}
1102 		lwsl_info("Loaded client cert %s\n", cert_filepath);
1103 
1104 	} else if (cert_mem && cert_mem_len) {
1105 		lws_filepos_t flen;
1106 		uint8_t *p;
1107 
1108 		if (lws_tls_alloc_pem_to_der_file(vh->context, NULL, cert_mem,
1109 						  cert_mem_len, &p, &flen)) {
1110 			lwsl_err("%s: couldn't read cert file\n", __func__);
1111 
1112 			return 1;
1113 		}
1114 
1115 		n = SSL_CTX_use_certificate_ASN1(vh->tls.ssl_client_ctx,
1116 #if defined(LWS_WITH_BORINGSSL)
1117 				(size_t)
1118 #else
1119 				(int)
1120 #endif
1121 				flen, p);
1122 
1123 		if (n < 1) {
1124 			lwsl_err("%s: problem interpreting client cert\n",  __func__);
1125 			lws_tls_err_describe_clear();
1126 		}
1127 
1128 		lws_free_set_NULL(p);
1129 
1130 		if (n != 1)
1131 			return 1;
1132 
1133 	}
1134 	if (private_key_filepath) {
1135 		lwsl_info("%s: using private key filepath\n", __func__);
1136 		lws_ssl_bind_passphrase(vh->tls.ssl_client_ctx, 1, info);
1137 		/* set the private key from KeyFile */
1138 		if (SSL_CTX_use_PrivateKey_file(vh->tls.ssl_client_ctx,
1139 		    private_key_filepath, SSL_FILETYPE_PEM) != 1) {
1140 			lwsl_err("use_PrivateKey_file '%s'\n",
1141 				 private_key_filepath);
1142 			lws_tls_err_describe_clear();
1143 			return 1;
1144 		}
1145 		lwsl_info("Loaded client cert private key %s\n",
1146 			    private_key_filepath);
1147 
1148 		/* verify private key */
1149 		if (!SSL_CTX_check_private_key(vh->tls.ssl_client_ctx)) {
1150 			lwsl_err("Private SSL key doesn't match cert\n");
1151 			return 1;
1152 		}
1153 	}
1154 	else if (key_mem && key_mem_len) {
1155 
1156 		lws_filepos_t flen;
1157 		uint8_t *p;
1158 
1159 		if (lws_tls_alloc_pem_to_der_file(vh->context, NULL, key_mem,
1160 						  key_mem_len, &p, &flen)) {
1161 			lwsl_err("%s: couldn't use mem cert\n", __func__);
1162 
1163 			return 1;
1164 		}
1165 
1166 		n = SSL_CTX_use_PrivateKey_ASN1(EVP_PKEY_RSA, vh->tls.ssl_client_ctx, p,
1167 #if defined(LWS_WITH_BORINGSSL)
1168 				(size_t)
1169 #else
1170 				(long)(lws_intptr_t)
1171 #endif
1172 						flen);
1173 		if (n != 1)
1174 			n = SSL_CTX_use_PrivateKey_ASN1(EVP_PKEY_EC,
1175 							vh->tls.ssl_client_ctx, p,
1176 #if defined(LWS_WITH_BORINGSSL)
1177 				(size_t)
1178 #else
1179 				(long)(lws_intptr_t)
1180 #endif
1181 						flen);
1182 
1183 		lws_free_set_NULL(p);
1184 
1185 		if (n != 1)  {
1186 			lwsl_err("%s: unable to use key_mem\n", __func__);
1187 
1188 			return 1;
1189 		}
1190 	}
1191 
1192 	return 0;
1193 }
1194 
1195 
1196