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