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