openssl-client.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903
  1. /*
  2. * libwebsockets - small server side websockets and web server implementation
  3. *
  4. * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
  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. #include "lws_config.h"
  25. #ifdef LWS_HAVE_X509_VERIFY_PARAM_set1_host
  26. /* Before glibc 2.10, strnlen required _GNU_SOURCE */
  27. #define _GNU_SOURCE
  28. #endif
  29. #include <string.h>
  30. #include "private-lib-core.h"
  31. #include "private-lib-tls-openssl.h"
  32. /*
  33. * Care: many openssl apis return 1 for success. These are translated to the
  34. * lws convention of 0 for success.
  35. */
  36. int lws_openssl_describe_cipher(struct lws *wsi);
  37. extern int openssl_websocket_private_data_index,
  38. openssl_SSL_CTX_private_data_index;
  39. #if !defined(USE_WOLFSSL)
  40. static int
  41. OpenSSL_client_verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx)
  42. {
  43. SSL *ssl;
  44. int n;
  45. struct lws *wsi;
  46. /* keep old behaviour accepting self-signed server certs */
  47. if (!preverify_ok) {
  48. int err = X509_STORE_CTX_get_error(x509_ctx);
  49. if (err != X509_V_OK) {
  50. ssl = X509_STORE_CTX_get_ex_data(x509_ctx,
  51. SSL_get_ex_data_X509_STORE_CTX_idx());
  52. wsi = SSL_get_ex_data(ssl,
  53. openssl_websocket_private_data_index);
  54. if (!wsi) {
  55. lwsl_err("%s: can't get wsi from ssl privdata\n",
  56. __func__);
  57. return 0;
  58. }
  59. if ((err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT ||
  60. err == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) &&
  61. wsi->tls.use_ssl & LCCSCF_ALLOW_SELFSIGNED) {
  62. lwsl_notice("accepting self-signed "
  63. "certificate (verify_callback)\n");
  64. X509_STORE_CTX_set_error(x509_ctx, X509_V_OK);
  65. return 1; // ok
  66. } else if ((err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY ||
  67. err == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE) &&
  68. wsi->tls.use_ssl & LCCSCF_ALLOW_INSECURE) {
  69. lwsl_notice("accepting non-trusted certificate\n");
  70. X509_STORE_CTX_set_error(x509_ctx, X509_V_OK);
  71. return 1; /* ok */
  72. } else if ((err == X509_V_ERR_CERT_NOT_YET_VALID ||
  73. err == X509_V_ERR_CERT_HAS_EXPIRED) &&
  74. wsi->tls.use_ssl & LCCSCF_ALLOW_EXPIRED) {
  75. if (err == X509_V_ERR_CERT_NOT_YET_VALID)
  76. lwsl_notice("accepting not yet valid "
  77. "certificate (verify_"
  78. "callback)\n");
  79. else if (err == X509_V_ERR_CERT_HAS_EXPIRED)
  80. lwsl_notice("accepting expired "
  81. "certificate (verify_"
  82. "callback)\n");
  83. X509_STORE_CTX_set_error(x509_ctx, X509_V_OK);
  84. return 1; // ok
  85. }
  86. }
  87. }
  88. ssl = X509_STORE_CTX_get_ex_data(x509_ctx,
  89. SSL_get_ex_data_X509_STORE_CTX_idx());
  90. wsi = SSL_get_ex_data(ssl, openssl_websocket_private_data_index);
  91. if (!wsi) {
  92. lwsl_err("%s: can't get wsi from ssl privdata\n", __func__);
  93. return 0;
  94. }
  95. n = lws_get_context_protocol(wsi->a.context, 0).callback(wsi,
  96. LWS_CALLBACK_OPENSSL_PERFORM_SERVER_CERT_VERIFICATION,
  97. x509_ctx, ssl, preverify_ok);
  98. /* keep old behaviour if something wrong with server certs */
  99. /* if ssl error is overruled in callback and cert is ok,
  100. * X509_STORE_CTX_set_error(x509_ctx, X509_V_OK); must be set and
  101. * return value is 0 from callback */
  102. if (!preverify_ok) {
  103. int err = X509_STORE_CTX_get_error(x509_ctx);
  104. if (err != X509_V_OK) {
  105. /* cert validation error was not handled in callback */
  106. int depth = X509_STORE_CTX_get_error_depth(x509_ctx);
  107. const char *msg = X509_verify_cert_error_string(err);
  108. lwsl_err("SSL error: %s (preverify_ok=%d;err=%d;"
  109. "depth=%d)\n", msg, preverify_ok, err, depth);
  110. return preverify_ok; // not ok
  111. }
  112. }
  113. /*
  114. * convert callback return code from 0 = OK to verify callback
  115. * return value 1 = OK
  116. */
  117. return !n;
  118. }
  119. #endif
  120. int
  121. lws_ssl_client_bio_create(struct lws *wsi)
  122. {
  123. char hostname[128], *p;
  124. #if defined(LWS_HAVE_SSL_set_alpn_protos) && \
  125. defined(LWS_HAVE_SSL_get0_alpn_selected)
  126. uint8_t openssl_alpn[40];
  127. const char *alpn_comma = wsi->a.context->tls.alpn_default;
  128. int n;
  129. #endif
  130. if (wsi->stash) {
  131. lws_strncpy(hostname, wsi->stash->cis[CIS_HOST], sizeof(hostname));
  132. #if defined(LWS_HAVE_SSL_set_alpn_protos) && \
  133. defined(LWS_HAVE_SSL_get0_alpn_selected)
  134. alpn_comma = wsi->stash->cis[CIS_ALPN];
  135. #endif
  136. } else {
  137. #if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
  138. if (lws_hdr_copy(wsi, hostname, sizeof(hostname),
  139. _WSI_TOKEN_CLIENT_HOST) <= 0)
  140. #endif
  141. {
  142. lwsl_err("%s: Unable to get hostname\n", __func__);
  143. return -1;
  144. }
  145. }
  146. /*
  147. * remove any :port part on the hostname... necessary for network
  148. * connection but typical certificates do not contain it
  149. */
  150. p = hostname;
  151. while (*p) {
  152. if (*p == ':') {
  153. *p = '\0';
  154. break;
  155. }
  156. p++;
  157. }
  158. wsi->tls.ssl = SSL_new(wsi->a.vhost->tls.ssl_client_ctx);
  159. if (!wsi->tls.ssl) {
  160. lwsl_err("SSL_new failed: %s\n",
  161. ERR_error_string(lws_ssl_get_error(wsi, 0), NULL));
  162. lws_tls_err_describe_clear();
  163. return -1;
  164. }
  165. #if defined (LWS_HAVE_SSL_SET_INFO_CALLBACK)
  166. if (wsi->a.vhost->tls.ssl_info_event_mask)
  167. SSL_set_info_callback(wsi->tls.ssl, lws_ssl_info_callback);
  168. #endif
  169. #if defined(LWS_HAVE_X509_VERIFY_PARAM_set1_host)
  170. if (!(wsi->tls.use_ssl & LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK)) {
  171. #if !defined(USE_WOLFSSL)
  172. X509_VERIFY_PARAM *param = SSL_get0_param(wsi->tls.ssl);
  173. /* Enable automatic hostname checks */
  174. X509_VERIFY_PARAM_set_hostflags(param,
  175. X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
  176. /* Handle the case where the hostname is an IP address */
  177. if (!X509_VERIFY_PARAM_set1_ip_asc(param, hostname))
  178. X509_VERIFY_PARAM_set1_host(param, hostname,
  179. strnlen(hostname, sizeof(hostname)));
  180. #endif
  181. }
  182. #else
  183. if (!(wsi->tls.use_ssl & LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK)) {
  184. lwsl_err("%s: your tls lib is too old to have "
  185. "X509_VERIFY_PARAM_set1_host, failing all client tls\n",
  186. __func__);
  187. return -1;
  188. }
  189. #endif
  190. #if !defined(USE_WOLFSSL)
  191. #ifndef USE_OLD_CYASSL
  192. /* OpenSSL_client_verify_callback will be called @ SSL_connect() */
  193. SSL_set_verify(wsi->tls.ssl, SSL_VERIFY_PEER,
  194. OpenSSL_client_verify_callback);
  195. #endif
  196. #endif
  197. #if !defined(USE_WOLFSSL)
  198. SSL_set_mode(wsi->tls.ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
  199. #endif
  200. /*
  201. * use server name indication (SNI), if supported,
  202. * when establishing connection
  203. */
  204. #ifdef USE_WOLFSSL
  205. #ifdef USE_OLD_CYASSL
  206. #ifdef CYASSL_SNI_HOST_NAME
  207. CyaSSL_UseSNI(wsi->tls.ssl, CYASSL_SNI_HOST_NAME, hostname,
  208. strlen(hostname));
  209. #endif
  210. #else
  211. #ifdef WOLFSSL_SNI_HOST_NAME
  212. wolfSSL_UseSNI(wsi->tls.ssl, WOLFSSL_SNI_HOST_NAME, hostname,
  213. strlen(hostname));
  214. #endif
  215. #endif
  216. #else
  217. #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
  218. SSL_set_tlsext_host_name(wsi->tls.ssl, hostname);
  219. #endif
  220. #endif
  221. #ifdef USE_WOLFSSL
  222. /*
  223. * wolfSSL/CyaSSL does certificate verification differently
  224. * from OpenSSL.
  225. * If we should ignore the certificate, we need to set
  226. * this before SSL_new and SSL_connect is called.
  227. * Otherwise the connect will simply fail with error code -155
  228. */
  229. #ifdef USE_OLD_CYASSL
  230. if (wsi->tls.use_ssl & LCCSCF_ALLOW_SELFSIGNED)
  231. CyaSSL_set_verify(wsi->tls.ssl, SSL_VERIFY_NONE, NULL);
  232. #else
  233. if (wsi->tls.use_ssl & LCCSCF_ALLOW_SELFSIGNED)
  234. wolfSSL_set_verify(wsi->tls.ssl, SSL_VERIFY_NONE, NULL);
  235. #endif
  236. #endif /* USE_WOLFSSL */
  237. wsi->tls.client_bio = BIO_new_socket((int)(lws_intptr_t)wsi->desc.sockfd,
  238. BIO_NOCLOSE);
  239. SSL_set_bio(wsi->tls.ssl, wsi->tls.client_bio, wsi->tls.client_bio);
  240. #ifdef USE_WOLFSSL
  241. #ifdef USE_OLD_CYASSL
  242. CyaSSL_set_using_nonblock(wsi->tls.ssl, 1);
  243. #else
  244. wolfSSL_set_using_nonblock(wsi->tls.ssl, 1);
  245. #endif
  246. #else
  247. BIO_set_nbio(wsi->tls.client_bio, 1); /* nonblocking */
  248. #endif
  249. #if defined(LWS_HAVE_SSL_set_alpn_protos) && \
  250. defined(LWS_HAVE_SSL_get0_alpn_selected)
  251. if (wsi->a.vhost->tls.alpn)
  252. alpn_comma = wsi->a.vhost->tls.alpn;
  253. if (wsi->stash)
  254. alpn_comma = wsi->stash->cis[CIS_ALPN];
  255. #if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
  256. if (lws_hdr_copy(wsi, hostname, sizeof(hostname),
  257. _WSI_TOKEN_CLIENT_ALPN) > 0)
  258. alpn_comma = hostname;
  259. #endif
  260. lwsl_info("%s client conn using alpn list '%s'\n", wsi->role_ops->name, alpn_comma);
  261. n = lws_alpn_comma_to_openssl(alpn_comma, openssl_alpn,
  262. sizeof(openssl_alpn) - 1);
  263. SSL_set_alpn_protos(wsi->tls.ssl, openssl_alpn, n);
  264. #endif
  265. SSL_set_ex_data(wsi->tls.ssl, openssl_websocket_private_data_index,
  266. wsi);
  267. if (wsi->sys_tls_client_cert) {
  268. lws_system_blob_t *b = lws_system_get_blob(wsi->a.context,
  269. LWS_SYSBLOB_TYPE_CLIENT_CERT_DER,
  270. wsi->sys_tls_client_cert - 1);
  271. const uint8_t *data;
  272. size_t size;
  273. if (!b)
  274. goto no_client_cert;
  275. /*
  276. * Set up the per-connection client cert
  277. */
  278. size = lws_system_blob_get_size(b);
  279. if (!size)
  280. goto no_client_cert;
  281. if (lws_system_blob_get_single_ptr(b, &data))
  282. goto no_client_cert;
  283. if (SSL_use_certificate_ASN1(wsi->tls.ssl,
  284. #if defined(USE_WOLFSSL)
  285. (unsigned char *)
  286. #endif
  287. data, (int)size) != 1) {
  288. lwsl_err("%s: use_certificate failed\n", __func__);
  289. lws_tls_err_describe_clear();
  290. goto no_client_cert;
  291. }
  292. b = lws_system_get_blob(wsi->a.context,
  293. LWS_SYSBLOB_TYPE_CLIENT_KEY_DER,
  294. wsi->sys_tls_client_cert - 1);
  295. if (!b)
  296. goto no_client_cert;
  297. size = lws_system_blob_get_size(b);
  298. if (!size)
  299. goto no_client_cert;
  300. if (lws_system_blob_get_single_ptr(b, &data))
  301. goto no_client_cert;
  302. if (SSL_use_PrivateKey_ASN1(EVP_PKEY_RSA, wsi->tls.ssl,
  303. #if defined(USE_WOLFSSL)
  304. (unsigned char *)
  305. #endif
  306. data, (int)size) != 1 &&
  307. SSL_use_PrivateKey_ASN1(EVP_PKEY_EC, wsi->tls.ssl,
  308. #if defined(USE_WOLFSSL)
  309. (unsigned char *)
  310. #endif
  311. data, (int)size) != 1) {
  312. lwsl_err("%s: use_privkey failed\n", __func__);
  313. lws_tls_err_describe_clear();
  314. goto no_client_cert;
  315. }
  316. if (SSL_check_private_key(wsi->tls.ssl) != 1) {
  317. lwsl_err("Private SSL key doesn't match cert\n");
  318. lws_tls_err_describe_clear();
  319. return 1;
  320. }
  321. lwsl_notice("%s: set system client cert %u\n", __func__,
  322. wsi->sys_tls_client_cert - 1);
  323. }
  324. return 0;
  325. no_client_cert:
  326. lwsl_err("%s: unable to set up system client cert %d\n", __func__,
  327. wsi->sys_tls_client_cert - 1);
  328. return 1;
  329. }
  330. enum lws_ssl_capable_status
  331. lws_tls_client_connect(struct lws *wsi, char *errbuf, int elen)
  332. {
  333. #if defined(LWS_HAVE_SSL_set_alpn_protos) && \
  334. defined(LWS_HAVE_SSL_get0_alpn_selected)
  335. const unsigned char *prot;
  336. char a[32];
  337. unsigned int len;
  338. #endif
  339. int m, n, en;
  340. errno = 0;
  341. ERR_clear_error();
  342. n = SSL_connect(wsi->tls.ssl);
  343. en = errno;
  344. m = lws_ssl_get_error(wsi, n);
  345. if (m == SSL_ERROR_SYSCALL
  346. #if defined(WIN32)
  347. && en
  348. #endif
  349. ) {
  350. #if defined(WIN32) || (_LWS_ENABLED_LOGS & LLL_INFO)
  351. lwsl_info("%s: n %d, m %d, errno %d\n", __func__, n, m, en);
  352. #endif
  353. lws_snprintf(errbuf, elen, "connect SYSCALL %d", en);
  354. return LWS_SSL_CAPABLE_ERROR;
  355. }
  356. if (m == SSL_ERROR_SSL) {
  357. n = lws_snprintf(errbuf, elen, "connect SSL err %d: ", m);
  358. ERR_error_string_n(m, errbuf + n, elen - n);
  359. return LWS_SSL_CAPABLE_ERROR;
  360. }
  361. if (m == SSL_ERROR_WANT_READ || SSL_want_read(wsi->tls.ssl))
  362. return LWS_SSL_CAPABLE_MORE_SERVICE_READ;
  363. if (m == SSL_ERROR_WANT_WRITE || SSL_want_write(wsi->tls.ssl))
  364. return LWS_SSL_CAPABLE_MORE_SERVICE_WRITE;
  365. if (n == 1 || m == SSL_ERROR_SYSCALL) {
  366. #if defined(LWS_HAVE_SSL_set_alpn_protos) && \
  367. defined(LWS_HAVE_SSL_get0_alpn_selected)
  368. SSL_get0_alpn_selected(wsi->tls.ssl, &prot, &len);
  369. if (len >= sizeof(a))
  370. len = sizeof(a) - 1;
  371. memcpy(a, (const char *)prot, len);
  372. a[len] = '\0';
  373. lws_role_call_alpn_negotiated(wsi, (const char *)a);
  374. #endif
  375. lwsl_info("client connect OK\n");
  376. lws_openssl_describe_cipher(wsi);
  377. return LWS_SSL_CAPABLE_DONE;
  378. }
  379. if (!n) /* we don't know what he wants, but he says to retry */
  380. return LWS_SSL_CAPABLE_MORE_SERVICE;
  381. lws_snprintf(errbuf, elen, "connect unk %d", m);
  382. return LWS_SSL_CAPABLE_ERROR;
  383. }
  384. int
  385. lws_tls_client_confirm_peer_cert(struct lws *wsi, char *ebuf, int ebuf_len)
  386. {
  387. #if !defined(USE_WOLFSSL)
  388. struct lws_context_per_thread *pt = &wsi->a.context->pt[(int)wsi->tsi];
  389. char *p = (char *)&pt->serv_buf[0];
  390. char *sb = p;
  391. int n;
  392. errno = 0;
  393. ERR_clear_error();
  394. n = SSL_get_verify_result(wsi->tls.ssl);
  395. lwsl_debug("get_verify says %d\n", n);
  396. if (n == X509_V_OK)
  397. return 0;
  398. if ((n == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT ||
  399. n == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) &&
  400. (wsi->tls.use_ssl & LCCSCF_ALLOW_SELFSIGNED)) {
  401. lwsl_info("accepting self-signed certificate\n");
  402. return 0;
  403. }
  404. if ((n == X509_V_ERR_CERT_NOT_YET_VALID ||
  405. n == X509_V_ERR_CERT_HAS_EXPIRED) &&
  406. (wsi->tls.use_ssl & LCCSCF_ALLOW_EXPIRED)) {
  407. lwsl_info("accepting expired certificate\n");
  408. return 0;
  409. }
  410. if (n == X509_V_ERR_CERT_NOT_YET_VALID) {
  411. lwsl_info("Cert is from the future... "
  412. "probably our clock... accepting...\n");
  413. return 0;
  414. }
  415. lws_snprintf(ebuf, ebuf_len,
  416. "server's cert didn't look good, X509_V_ERR = %d: %s\n",
  417. n, ERR_error_string(n, sb));
  418. lwsl_info("%s\n", ebuf);
  419. lws_tls_err_describe_clear();
  420. return -1;
  421. #else /* USE_WOLFSSL */
  422. return 0;
  423. #endif
  424. }
  425. int
  426. lws_tls_client_vhost_extra_cert_mem(struct lws_vhost *vh,
  427. const uint8_t *der, size_t der_len)
  428. {
  429. X509_STORE *st;
  430. X509 *x = d2i_X509(NULL, &der, (long)der_len);
  431. int n;
  432. if (!x) {
  433. lwsl_err("%s: Failed to load DER\n", __func__);
  434. lws_tls_err_describe_clear();
  435. return 1;
  436. }
  437. st = SSL_CTX_get_cert_store(vh->tls.ssl_client_ctx);
  438. if (!st) {
  439. lwsl_err("%s: failed to get cert store\n", __func__);
  440. X509_free(x);
  441. return 1;
  442. }
  443. n = X509_STORE_add_cert(st, x);
  444. if (n != 1)
  445. lwsl_err("%s: failed to add cert\n", __func__);
  446. X509_free(x);
  447. return n != 1;
  448. }
  449. int
  450. lws_tls_client_create_vhost_context(struct lws_vhost *vh,
  451. const struct lws_context_creation_info *info,
  452. const char *cipher_list,
  453. const char *ca_filepath,
  454. const void *ca_mem,
  455. unsigned int ca_mem_len,
  456. const char *cert_filepath,
  457. const void *cert_mem,
  458. unsigned int cert_mem_len,
  459. const char *private_key_filepath,
  460. const void *key_mem,
  461. unsigned int key_mem_len
  462. )
  463. {
  464. struct lws_tls_client_reuse *tcr;
  465. X509_STORE *x509_store;
  466. unsigned long error;
  467. SSL_METHOD *method;
  468. EVP_MD_CTX *mdctx;
  469. unsigned int len;
  470. uint8_t hash[32];
  471. X509 *client_CA;
  472. char c;
  473. int n;
  474. /* basic openssl init already happened in context init */
  475. /* choose the most recent spin of the api */
  476. #if defined(LWS_HAVE_TLS_CLIENT_METHOD)
  477. method = (SSL_METHOD *)TLS_client_method();
  478. #elif defined(LWS_HAVE_TLSV1_2_CLIENT_METHOD)
  479. method = (SSL_METHOD *)TLSv1_2_client_method();
  480. #else
  481. method = (SSL_METHOD *)SSLv23_client_method();
  482. #endif
  483. if (!method) {
  484. error = ERR_get_error();
  485. lwsl_err("problem creating ssl method %lu: %s\n",
  486. error, ERR_error_string(error,
  487. (char *)vh->context->pt[0].serv_buf));
  488. return 1;
  489. }
  490. /*
  491. * OpenSSL client contexts are quite expensive, because they bring in
  492. * the system certificate bundle for each one. So if you have multiple
  493. * vhosts, each with a client context, it can add up to several
  494. * megabytes of heap. In the case the client contexts are configured
  495. * identically, they could perfectly well have shared just the one.
  496. *
  497. * For that reason, use a hash to fingerprint the context configuration
  498. * and prefer to reuse an existing one with the same fingerprint if
  499. * possible.
  500. */
  501. mdctx = EVP_MD_CTX_create();
  502. if (!mdctx)
  503. return 1;
  504. if (EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL) != 1) {
  505. EVP_MD_CTX_destroy(mdctx);
  506. return 1;
  507. }
  508. if (info->ssl_client_options_set)
  509. EVP_DigestUpdate(mdctx, &info->ssl_client_options_set,
  510. sizeof(info->ssl_client_options_set));
  511. #if (OPENSSL_VERSION_NUMBER >= 0x009080df) && !defined(USE_WOLFSSL)
  512. if (info->ssl_client_options_clear)
  513. EVP_DigestUpdate(mdctx, &info->ssl_client_options_clear,
  514. sizeof(info->ssl_client_options_clear));
  515. #endif
  516. if (cipher_list)
  517. EVP_DigestUpdate(mdctx, cipher_list, strlen(cipher_list));
  518. #if defined(LWS_HAVE_SSL_CTX_set_ciphersuites)
  519. if (info->client_tls_1_3_plus_cipher_list)
  520. EVP_DigestUpdate(mdctx, info->client_tls_1_3_plus_cipher_list,
  521. strlen(info->client_tls_1_3_plus_cipher_list));
  522. #endif
  523. if (!lws_check_opt(vh->options, LWS_SERVER_OPTION_DISABLE_OS_CA_CERTS)) {
  524. c = 1;
  525. EVP_DigestUpdate(mdctx, &c, 1);
  526. }
  527. if (ca_filepath)
  528. EVP_DigestUpdate(mdctx, ca_filepath, strlen(ca_filepath));
  529. if (cert_filepath)
  530. EVP_DigestUpdate(mdctx, cert_filepath, strlen(cert_filepath));
  531. if (private_key_filepath)
  532. EVP_DigestUpdate(mdctx, private_key_filepath,
  533. strlen(private_key_filepath));
  534. if (ca_mem && ca_mem_len)
  535. EVP_DigestUpdate(mdctx, ca_mem, ca_mem_len);
  536. if (cert_mem && cert_mem_len)
  537. EVP_DigestUpdate(mdctx, cert_mem, cert_mem_len);
  538. len = sizeof(hash);
  539. EVP_DigestFinal_ex(mdctx, hash, &len);
  540. EVP_MD_CTX_destroy(mdctx);
  541. /* look for existing client context with same config already */
  542. lws_start_foreach_dll_safe(struct lws_dll2 *, p, tp,
  543. lws_dll2_get_head(&vh->context->tls.cc_owner)) {
  544. tcr = lws_container_of(p, struct lws_tls_client_reuse, cc_list);
  545. if (!memcmp(hash, tcr->hash, len)) {
  546. /* it's a match */
  547. tcr->refcount++;
  548. vh->tls.ssl_client_ctx = tcr->ssl_client_ctx;
  549. lwsl_info("%s: vh %s: reusing client ctx %d: use %d\n",
  550. __func__, vh->name, tcr->index,
  551. tcr->refcount);
  552. return 0;
  553. }
  554. } lws_end_foreach_dll_safe(p, tp);
  555. /* no existing one the same... create new client SSL_CTX */
  556. errno = 0;
  557. ERR_clear_error();
  558. vh->tls.ssl_client_ctx = SSL_CTX_new(method);
  559. if (!vh->tls.ssl_client_ctx) {
  560. error = ERR_get_error();
  561. lwsl_err("problem creating ssl context %lu: %s\n",
  562. error, ERR_error_string(error,
  563. (char *)vh->context->pt[0].serv_buf));
  564. return 1;
  565. }
  566. tcr = lws_zalloc(sizeof(*tcr), "client ctx tcr");
  567. if (!tcr) {
  568. SSL_CTX_free(vh->tls.ssl_client_ctx);
  569. return 1;
  570. }
  571. tcr->ssl_client_ctx = vh->tls.ssl_client_ctx;
  572. tcr->refcount = 1;
  573. memcpy(tcr->hash, hash, len);
  574. tcr->index = vh->context->tls.count_client_contexts++;
  575. lws_dll2_add_head(&tcr->cc_list, &vh->context->tls.cc_owner);
  576. lwsl_info("%s: vh %s: created new client ctx %d\n", __func__,
  577. vh->name, tcr->index);
  578. /* bind the tcr to the client context */
  579. SSL_CTX_set_ex_data(vh->tls.ssl_client_ctx,
  580. openssl_SSL_CTX_private_data_index,
  581. (char *)tcr);
  582. #ifdef SSL_OP_NO_COMPRESSION
  583. SSL_CTX_set_options(vh->tls.ssl_client_ctx, SSL_OP_NO_COMPRESSION);
  584. #endif
  585. SSL_CTX_set_options(vh->tls.ssl_client_ctx,
  586. SSL_OP_CIPHER_SERVER_PREFERENCE);
  587. SSL_CTX_set_mode(vh->tls.ssl_client_ctx,
  588. SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
  589. SSL_MODE_RELEASE_BUFFERS);
  590. if (info->ssl_client_options_set)
  591. SSL_CTX_set_options(vh->tls.ssl_client_ctx,
  592. info->ssl_client_options_set);
  593. /* SSL_clear_options introduced in 0.9.8m */
  594. #if (OPENSSL_VERSION_NUMBER >= 0x009080df) && !defined(USE_WOLFSSL)
  595. if (info->ssl_client_options_clear)
  596. SSL_CTX_clear_options(vh->tls.ssl_client_ctx,
  597. info->ssl_client_options_clear);
  598. #endif
  599. if (cipher_list)
  600. SSL_CTX_set_cipher_list(vh->tls.ssl_client_ctx, cipher_list);
  601. #if defined(LWS_HAVE_SSL_CTX_set_ciphersuites)
  602. if (info->client_tls_1_3_plus_cipher_list)
  603. SSL_CTX_set_ciphersuites(vh->tls.ssl_client_ctx,
  604. info->client_tls_1_3_plus_cipher_list);
  605. #endif
  606. #ifdef LWS_SSL_CLIENT_USE_OS_CA_CERTS
  607. if (!lws_check_opt(vh->options, LWS_SERVER_OPTION_DISABLE_OS_CA_CERTS))
  608. /* loads OS default CA certs */
  609. SSL_CTX_set_default_verify_paths(vh->tls.ssl_client_ctx);
  610. #endif
  611. /* openssl init for cert verification (for client sockets) */
  612. if (!ca_filepath && (!ca_mem || !ca_mem_len)) {
  613. #if defined(LWS_HAVE_SSL_CTX_load_verify_dir)
  614. if (!SSL_CTX_load_verify_dir(
  615. vh->tls.ssl_client_ctx, LWS_OPENSSL_CLIENT_CERTS))
  616. #else
  617. if (!SSL_CTX_load_verify_locations(
  618. vh->tls.ssl_client_ctx, NULL, LWS_OPENSSL_CLIENT_CERTS))
  619. #endif
  620. lwsl_err("Unable to load SSL Client certs from %s "
  621. "(set by LWS_OPENSSL_CLIENT_CERTS) -- "
  622. "client ssl isn't going to work\n",
  623. LWS_OPENSSL_CLIENT_CERTS);
  624. } else if (ca_filepath) {
  625. #if defined(LWS_HAVE_SSL_CTX_load_verify_file)
  626. if (!SSL_CTX_load_verify_file(
  627. vh->tls.ssl_client_ctx, ca_filepath)) {
  628. #else
  629. if (!SSL_CTX_load_verify_locations(
  630. vh->tls.ssl_client_ctx, ca_filepath, NULL)) {
  631. #endif
  632. lwsl_err(
  633. "Unable to load SSL Client certs "
  634. "file from %s -- client ssl isn't "
  635. "going to work\n", ca_filepath);
  636. lws_tls_err_describe_clear();
  637. }
  638. else
  639. lwsl_info("loaded ssl_ca_filepath\n");
  640. } else {
  641. lws_filepos_t amount = 0;
  642. const uint8_t *up;
  643. uint8_t *up1;
  644. if (lws_tls_alloc_pem_to_der_file(vh->context, NULL, ca_mem,
  645. ca_mem_len, &up1, &amount)) {
  646. lwsl_err("%s: Unable to decode x.509 mem\n", __func__);
  647. lwsl_hexdump_notice(ca_mem, ca_mem_len);
  648. return 1;
  649. }
  650. up = up1;
  651. client_CA = d2i_X509(NULL, &up, (long)amount);
  652. if (!client_CA) {
  653. lwsl_err("%s: d2i_X509 failed\n", __func__);
  654. lwsl_hexdump_notice(up1, (size_t)amount);
  655. lws_tls_err_describe_clear();
  656. } else {
  657. x509_store = X509_STORE_new();
  658. if (!X509_STORE_add_cert(x509_store, client_CA)) {
  659. X509_STORE_free(x509_store);
  660. lwsl_err("Unable to load SSL Client certs from "
  661. "ssl_ca_mem -- client ssl isn't going to "
  662. "work\n");
  663. lws_tls_err_describe_clear();
  664. } else {
  665. /* it doesn't increment x509_store ref counter */
  666. SSL_CTX_set_cert_store(vh->tls.ssl_client_ctx,
  667. x509_store);
  668. lwsl_info("loaded ssl_ca_mem\n");
  669. }
  670. }
  671. if (client_CA)
  672. X509_free(client_CA);
  673. lws_free(up1);
  674. // lws_tls_client_vhost_extra_cert_mem(vh, ca_mem, ca_mem_len);
  675. }
  676. /*
  677. * callback allowing user code to load extra verification certs
  678. * helping the client to verify server identity
  679. */
  680. /* support for client-side certificate authentication */
  681. if (cert_filepath) {
  682. if (lws_tls_use_any_upgrade_check_extant(cert_filepath) !=
  683. LWS_TLS_EXTANT_YES &&
  684. (info->options & LWS_SERVER_OPTION_IGNORE_MISSING_CERT))
  685. return 0;
  686. lwsl_notice("%s: doing cert filepath %s\n", __func__,
  687. cert_filepath);
  688. n = SSL_CTX_use_certificate_chain_file(vh->tls.ssl_client_ctx,
  689. cert_filepath);
  690. if (n < 1) {
  691. lwsl_err("problem %d getting cert '%s'\n", n,
  692. cert_filepath);
  693. lws_tls_err_describe_clear();
  694. return 1;
  695. }
  696. lwsl_notice("Loaded client cert %s\n", cert_filepath);
  697. } else if (cert_mem && cert_mem_len) {
  698. lws_filepos_t flen;
  699. uint8_t *p;
  700. if (lws_tls_alloc_pem_to_der_file(vh->context, NULL, cert_mem,
  701. cert_mem_len, &p, &flen)) {
  702. lwsl_err("%s: couldn't read cert file\n", __func__);
  703. return 1;
  704. }
  705. n = SSL_CTX_use_certificate_ASN1(vh->tls.ssl_client_ctx, (int)flen, p);
  706. if (n < 1) {
  707. lwsl_err("%s: problem interpreting client cert\n", __func__);
  708. lws_tls_err_describe_clear();
  709. }
  710. lws_free_set_NULL(p);
  711. if (n != 1)
  712. return 1;
  713. }
  714. if (private_key_filepath) {
  715. lwsl_info("%s: using private key filepath\n", __func__);
  716. lws_ssl_bind_passphrase(vh->tls.ssl_client_ctx, 1, info);
  717. /* set the private key from KeyFile */
  718. if (SSL_CTX_use_PrivateKey_file(vh->tls.ssl_client_ctx,
  719. private_key_filepath, SSL_FILETYPE_PEM) != 1) {
  720. lwsl_err("use_PrivateKey_file '%s'\n",
  721. private_key_filepath);
  722. lws_tls_err_describe_clear();
  723. return 1;
  724. }
  725. lwsl_info("Loaded client cert private key %s\n",
  726. private_key_filepath);
  727. /* verify private key */
  728. if (!SSL_CTX_check_private_key(vh->tls.ssl_client_ctx)) {
  729. lwsl_err("Private SSL key doesn't match cert\n");
  730. return 1;
  731. }
  732. }
  733. else if (key_mem && key_mem_len) {
  734. lws_filepos_t flen;
  735. uint8_t *p;
  736. if (lws_tls_alloc_pem_to_der_file(vh->context, NULL, key_mem,
  737. key_mem_len, &p, &flen)) {
  738. lwsl_err("%s: couldn't use mem cert\n", __func__);
  739. return 1;
  740. }
  741. n = SSL_CTX_use_PrivateKey_ASN1(EVP_PKEY_RSA, vh->tls.ssl_client_ctx, p,
  742. (long)(lws_intptr_t)flen);
  743. if (n != 1)
  744. n = SSL_CTX_use_PrivateKey_ASN1(EVP_PKEY_EC,
  745. vh->tls.ssl_client_ctx, p,
  746. (long)(lws_intptr_t)flen);
  747. lws_free_set_NULL(p);
  748. if (n != 1) {
  749. lwsl_err("%s: unable to use key_mem\n", __func__);
  750. return 1;
  751. }
  752. }
  753. return 0;
  754. }