ssl_common.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
  1. /*********************************************************************
  2. *
  3. * File : $Source: /cvsroot/ijbswa/current/ssl_common.c,v $
  4. *
  5. * Purpose : File with TLS/SSL extension. Contains methods for
  6. * creating, using and closing TLS/SSL connections that do
  7. * not depend on particular TLS/SSL library.
  8. *
  9. * Copyright : Written by and Copyright (c) 2017 Vaclav Svec. FIT CVUT.
  10. * Copyright (C) 2018-2020 by Fabian Keil <fk@fabiankeil.de>
  11. *
  12. * This program is free software; you can redistribute it
  13. * and/or modify it under the terms of the GNU General
  14. * Public License as published by the Free Software
  15. * Foundation; either version 2 of the License, or (at
  16. * your option) any later version.
  17. *
  18. * This program is distributed in the hope that it will
  19. * be useful, but WITHOUT ANY WARRANTY; without even the
  20. * implied warranty of MERCHANTABILITY or FITNESS FOR A
  21. * PARTICULAR PURPOSE. See the GNU General Public
  22. * License for more details.
  23. *
  24. * The GNU General Public License should be included with
  25. * this file. If not, you can view it at
  26. * http://www.gnu.org/copyleft/gpl.html
  27. * or write to the Free Software Foundation, Inc., 59
  28. * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  29. *
  30. *********************************************************************/
  31. #include <string.h>
  32. #include <ctype.h>
  33. #include "config.h"
  34. #include "project.h"
  35. #include "miscutil.h"
  36. #include "errlog.h"
  37. #include "ssl.h"
  38. #include "ssl_common.h"
  39. /*
  40. * Macros for ssl_common.c
  41. */
  42. #define CERT_SERIAL_NUM_LENGTH 4 /* Bytes of hash to be used for creating serial number of certificate. Min=2 and max=16 */
  43. /*********************************************************************
  44. *
  45. * Function : client_use_ssl
  46. *
  47. * Description : Tests if client in current client state structure
  48. * should use SSL connection or standard connection.
  49. *
  50. * Parameters :
  51. * 1 : csp = Current client state (buffers, headers, etc...)
  52. *
  53. * Returns : If client should use TLS/SSL connection, 1 is returned.
  54. * Otherwise 0 is returned.
  55. *
  56. *********************************************************************/
  57. extern int client_use_ssl(const struct client_state *csp)
  58. {
  59. return csp->http->client_ssl;
  60. }
  61. /*********************************************************************
  62. *
  63. * Function : server_use_ssl
  64. *
  65. * Description : Tests if server in current client state structure
  66. * should use SSL connection or standard connection.
  67. *
  68. * Parameters :
  69. * 1 : csp = Current client state (buffers, headers, etc...)
  70. *
  71. * Returns : If server should use TLS/SSL connection, 1 is returned.
  72. * Otherwise 0 is returned.
  73. *
  74. *********************************************************************/
  75. extern int server_use_ssl(const struct client_state *csp)
  76. {
  77. return csp->http->server_ssl;
  78. }
  79. /*********************************************************************
  80. *
  81. * Function : ssl_send_data_delayed
  82. *
  83. * Description : Sends the contents of buf (for n bytes) to given SSL
  84. * connection, optionally delaying the operation.
  85. *
  86. * Parameters :
  87. * 1 : ssl_attr = SSL context to send data to
  88. * 2 : buf = Pointer to data to be sent
  89. * 3 : len = Length of data to be sent to the SSL context
  90. * 4 : delay = Delay in milliseconds.
  91. *
  92. * Returns : 0 on success (entire buffer sent).
  93. * nonzero on error.
  94. *
  95. *********************************************************************/
  96. extern int ssl_send_data_delayed(struct ssl_attr* ssl_attr,
  97. const unsigned char *buf, size_t len,
  98. unsigned int delay)
  99. {
  100. size_t i = 0;
  101. if (delay == 0)
  102. {
  103. if (ssl_send_data(ssl_attr, buf, len) < 0)
  104. {
  105. return -1;
  106. }
  107. else
  108. {
  109. return 0;
  110. }
  111. }
  112. while (i < len)
  113. {
  114. size_t write_length;
  115. enum { MAX_WRITE_LENGTH = 10 };
  116. if ((i + MAX_WRITE_LENGTH) > len)
  117. {
  118. write_length = len - i;
  119. }
  120. else
  121. {
  122. write_length = MAX_WRITE_LENGTH;
  123. }
  124. privoxy_millisleep(delay);
  125. if (ssl_send_data(ssl_attr, buf + i, write_length) < 0)
  126. {
  127. return -1;
  128. }
  129. i += write_length;
  130. }
  131. return 0;
  132. }
  133. /*********************************************************************
  134. *
  135. * Function : ssl_flush_socket
  136. *
  137. * Description : Send any pending "buffered" content with given
  138. * SSL connection. Alternative to function flush_socket.
  139. *
  140. * Parameters :
  141. * 1 : ssl_attr = SSL context to send buffer to
  142. * 2 : iob = The I/O buffer to flush, usually csp->iob.
  143. *
  144. * Returns : On success, the number of bytes send are returned (zero
  145. * indicates nothing was sent). On error, -1 is returned.
  146. *
  147. *********************************************************************/
  148. extern long ssl_flush_socket(struct ssl_attr *ssl_attr, struct iob *iob)
  149. {
  150. /* Computing length of buffer part to send */
  151. long len = iob->eod - iob->cur;
  152. if (len <= 0)
  153. {
  154. return(0);
  155. }
  156. /* Sending data to given SSl context */
  157. if (ssl_send_data(ssl_attr, (const unsigned char *)iob->cur, (size_t)len) < 0)
  158. {
  159. return -1;
  160. }
  161. iob->eod = iob->cur = iob->buf;
  162. return(len);
  163. }
  164. /*********************************************************************
  165. *
  166. * Function : close_client_and_server_ssl_connections
  167. *
  168. * Description : Checks if client or server should use secured
  169. * connection over SSL and if so, closes all of them.
  170. *
  171. * Parameters :
  172. * 1 : csp = Current client state (buffers, headers, etc...)
  173. *
  174. * Returns : N/A
  175. *
  176. *********************************************************************/
  177. extern void close_client_and_server_ssl_connections(struct client_state *csp)
  178. {
  179. if (client_use_ssl(csp) == 1)
  180. {
  181. close_client_ssl_connection(csp);
  182. }
  183. if (server_use_ssl(csp) == 1)
  184. {
  185. close_server_ssl_connection(csp);
  186. }
  187. }
  188. /*********************************************************************
  189. *
  190. * Function : tunnel_established_successfully
  191. *
  192. * Description : Check if parent proxy server response contains
  193. * information about successfully created connection with
  194. * destination server. (HTTP/... 2xx ...)
  195. *
  196. * Parameters :
  197. * 1 : server_response = Buffer with parent proxy server response
  198. * 2 : response_len = Length of server_response
  199. *
  200. * Returns : 1 => Connection created successfully
  201. * 0 => Connection wasn't created successfully
  202. *
  203. *********************************************************************/
  204. extern int tunnel_established_successfully(const char *server_response,
  205. unsigned int response_len)
  206. {
  207. unsigned int pos = 0;
  208. if (server_response == NULL)
  209. {
  210. return 0;
  211. }
  212. /* Tests if "HTTP/" string is at the begin of received response */
  213. if (strncmp(server_response, "HTTP/", 5) != 0)
  214. {
  215. return 0;
  216. }
  217. for (pos = 0; pos < response_len; pos++)
  218. {
  219. if (server_response[pos] == ' ')
  220. {
  221. break;
  222. }
  223. }
  224. /*
  225. * response_len -3 because of buffer end, response structure and 200 code.
  226. * There must be at least 3 chars after space.
  227. * End of buffer: ... 2xx'\0'
  228. * pos = |
  229. */
  230. if (pos >= (response_len - 3))
  231. {
  232. return 0;
  233. }
  234. /* Test HTTP status code */
  235. if (server_response[pos + 1] != '2')
  236. {
  237. return 0;
  238. }
  239. return 1;
  240. }
  241. /*********************************************************************
  242. *
  243. * Function : free_certificate_chain
  244. *
  245. * Description : Frees certificates linked list. This linked list is
  246. * used to save information about certificates in
  247. * trusted chain.
  248. *
  249. * Parameters :
  250. * 1 : csp = Current client state (buffers, headers, etc...)
  251. *
  252. * Returns : N/A
  253. *
  254. *********************************************************************/
  255. extern void free_certificate_chain(struct client_state *csp)
  256. {
  257. struct certs_chain *cert = csp->server_certs_chain.next;
  258. /* Cleaning buffers */
  259. memset(csp->server_certs_chain.info_buf, 0,
  260. sizeof(csp->server_certs_chain.info_buf));
  261. memset(csp->server_certs_chain.file_buf, 0,
  262. sizeof(csp->server_certs_chain.file_buf));
  263. csp->server_certs_chain.next = NULL;
  264. /* Freeing memory in whole linked list */
  265. while (cert != NULL)
  266. {
  267. struct certs_chain *cert_for_free = cert;
  268. cert = cert->next;
  269. freez(cert_for_free);
  270. }
  271. }
  272. /*********************************************************************
  273. *
  274. * Function : ssl_send_certificate_error
  275. *
  276. * Description : Sends info about invalid server certificate to client.
  277. * Sent message is including all trusted chain certificates,
  278. * that can be downloaded in web browser.
  279. *
  280. * Parameters :
  281. * 1 : csp = Current client state (buffers, headers, etc...)
  282. *
  283. * Returns : N/A
  284. *
  285. *********************************************************************/
  286. extern void ssl_send_certificate_error(struct client_state *csp)
  287. {
  288. struct ssl_attr *ssl_attr = &csp->ssl_client_attr;
  289. size_t message_len = 0;
  290. int ret = 0;
  291. struct certs_chain *cert = NULL;
  292. const size_t head_length = 63;
  293. /* Header of message with certificate information */
  294. const char message_begin[] =
  295. "HTTP/1.1 200 OK\r\n"
  296. "Content-Type: text/html\r\n"
  297. "Connection: close\r\n\r\n"
  298. "<!DOCTYPE html>\n"
  299. "<html><head><title>Server certificate verification failed</title></head>\n"
  300. "<body><h1>Server certificate verification failed</h1>\n"
  301. "<p><a href=\"https://" CGI_SITE_2_HOST "/\">Privoxy</a> was unable "
  302. "to securely connect to the destination server.</p>"
  303. "<p>Reason: ";
  304. const char message_end[] = "</body></html>\r\n\r\n";
  305. char reason[INVALID_CERT_INFO_BUF_SIZE];
  306. memset(reason, 0, sizeof(reason));
  307. /* Get verification message from verification return code */
  308. ssl_crt_verify_info(reason, sizeof(reason), csp);
  309. /*
  310. * Computing total length of message with all certificates inside
  311. */
  312. message_len = strlen(message_begin) + strlen(message_end)
  313. + strlen(reason) + strlen("</p>") + 1;
  314. cert = &(csp->server_certs_chain);
  315. while (cert->next != NULL)
  316. {
  317. size_t base64_len = 4 * ((strlen(cert->file_buf) + 2) / 3) + 1;
  318. message_len += strlen(cert->info_buf) + strlen("<pre></pre>\n")
  319. + base64_len + strlen("<a href=\"data:application"
  320. "/x-x509-ca-cert;base64,\">Download certificate</a>");
  321. cert = cert->next;
  322. }
  323. /*
  324. * Joining all blocks in one long message
  325. */
  326. char message[message_len];
  327. memset(message, 0, message_len);
  328. strlcpy(message, message_begin, message_len);
  329. strlcat(message, reason , message_len);
  330. strlcat(message, "</p>" , message_len);
  331. cert = &(csp->server_certs_chain);
  332. while (cert->next != NULL)
  333. {
  334. size_t olen = 0;
  335. size_t base64_len = 4 * ((strlen(cert->file_buf) + 2) / 3) + 1; /* +1 for terminating null*/
  336. char base64_buf[base64_len];
  337. memset(base64_buf, 0, base64_len);
  338. /* Encoding certificate into base64 code */
  339. ret = ssl_base64_encode((unsigned char*)base64_buf,
  340. base64_len, &olen, (const unsigned char*)cert->file_buf,
  341. strlen(cert->file_buf));
  342. if (ret != 0)
  343. {
  344. log_error(LOG_LEVEL_ERROR,
  345. "Encoding to base64 failed, buffer is to small");
  346. }
  347. strlcat(message, "<pre>", message_len);
  348. strlcat(message, cert->info_buf, message_len);
  349. strlcat(message, "</pre>\n", message_len);
  350. if (ret == 0)
  351. {
  352. strlcat(message, "<a href=\"data:application/x-x509-ca-cert;base64,",
  353. message_len);
  354. strlcat(message, base64_buf, message_len);
  355. strlcat(message, "\">Download certificate</a>", message_len);
  356. }
  357. cert = cert->next;
  358. }
  359. strlcat(message, message_end, message_len);
  360. /*
  361. * Sending final message to client
  362. */
  363. (void)ssl_send_data(ssl_attr, (const unsigned char *)message, strlen(message));
  364. free_certificate_chain(csp);
  365. log_error(LOG_LEVEL_CRUNCH, "Certificate error: %s: https://%s%s",
  366. reason, csp->http->hostport, csp->http->path);
  367. log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s https://%s%s %s\" 200 %lu",
  368. csp->ip_addr_str, csp->http->gpc, csp->http->hostport, csp->http->path,
  369. csp->http->version, message_len-head_length);
  370. #ifdef FEATURE_CONNECTION_KEEP_ALIVE
  371. csp->flags &= ~CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE;
  372. csp->flags |= CSP_FLAG_SERVER_SOCKET_TAINTED;
  373. #endif
  374. }
  375. /*********************************************************************
  376. *
  377. * Function : file_exists
  378. *
  379. * Description : Tests if file exists and is readable.
  380. *
  381. * Parameters :
  382. * 1 : path = Path to tested file.
  383. *
  384. * Returns : 1 => File exists and is readable.
  385. * 0 => File doesn't exist or is not readable.
  386. *
  387. *********************************************************************/
  388. extern int file_exists(const char *path)
  389. {
  390. FILE *f;
  391. if ((f = fopen(path, "r")) != NULL)
  392. {
  393. fclose(f);
  394. return 1;
  395. }
  396. return 0;
  397. }
  398. /*********************************************************************
  399. *
  400. * Function : make_certs_path
  401. *
  402. * Description : Creates path to file from three pieces. This function
  403. * takes parameters and puts them in one new mallocated
  404. * char * in correct order. Returned variable must be freed
  405. * by caller. This function is mainly used for creating
  406. * paths of certificates and keys files.
  407. *
  408. * Parameters :
  409. * 1 : conf_dir = Name/path of directory where is the file.
  410. * '.' can be used for current directory.
  411. * 2 : file_name = Name of file in conf_dir without suffix.
  412. * 3 : suffix = Suffix of given file_name.
  413. *
  414. * Returns : path => Path was built up successfully
  415. * NULL => Path can't be built up
  416. *
  417. *********************************************************************/
  418. extern char *make_certs_path(const char *conf_dir, const char *file_name,
  419. const char *suffix)
  420. {
  421. /* Test if all given parameters are valid */
  422. if (conf_dir == NULL || *conf_dir == '\0' || file_name == NULL ||
  423. *file_name == '\0' || suffix == NULL || *suffix == '\0')
  424. {
  425. log_error(LOG_LEVEL_ERROR,
  426. "make_certs_path failed: bad input parameters");
  427. return NULL;
  428. }
  429. char *path = NULL;
  430. size_t path_size = strlen(conf_dir)
  431. + strlen(file_name) + strlen(suffix) + 2;
  432. /* Setting delimiter and editing path length */
  433. #if defined(_WIN32)
  434. char delim[] = "\\";
  435. path_size += 1;
  436. #else /* ifndef _WIN32 */
  437. char delim[] = "/";
  438. #endif /* ifndef _WIN32 */
  439. /*
  440. * Building up path from many parts
  441. */
  442. #if defined(unix)
  443. if (*conf_dir != '/' && basedir && *basedir)
  444. {
  445. /*
  446. * Replacing conf_dir with basedir. This new variable contains
  447. * absolute path to cwd.
  448. */
  449. path_size += strlen(basedir) + 2;
  450. path = zalloc_or_die(path_size);
  451. strlcpy(path, basedir, path_size);
  452. strlcat(path, delim, path_size);
  453. strlcat(path, conf_dir, path_size);
  454. strlcat(path, delim, path_size);
  455. strlcat(path, file_name, path_size);
  456. strlcat(path, suffix, path_size);
  457. }
  458. else
  459. #endif /* defined unix */
  460. {
  461. path = zalloc_or_die(path_size);
  462. strlcpy(path, conf_dir, path_size);
  463. strlcat(path, delim, path_size);
  464. strlcat(path, file_name, path_size);
  465. strlcat(path, suffix, path_size);
  466. }
  467. return path;
  468. }
  469. /*********************************************************************
  470. *
  471. * Function : get_certificate_serial
  472. *
  473. * Description : Computes serial number for new certificate from host
  474. * name hash. This hash must be already saved in csp
  475. * structure.
  476. *
  477. * Parameters :
  478. * 1 : csp = Current client state (buffers, headers, etc...)
  479. *
  480. * Returns : Serial number for new certificate
  481. *
  482. *********************************************************************/
  483. extern unsigned long get_certificate_serial(struct client_state *csp)
  484. {
  485. unsigned long exp = 1;
  486. unsigned long serial = 0;
  487. int i = CERT_SERIAL_NUM_LENGTH;
  488. for (; i >= 0; i--)
  489. {
  490. serial += exp * (unsigned)csp->http->hash_of_host[i];
  491. exp *= 256;
  492. }
  493. return serial;
  494. }
  495. /*********************************************************************
  496. *
  497. * Function : generate_certificate_valid_date
  498. *
  499. * Description : Turns a time_t into the format expected by mbedTLS.
  500. *
  501. * Parameters :
  502. * 1 : time_spec = The timestamp to convert
  503. * 2 : buffer = The buffer to write the date to
  504. * 3 : buffer_size = The size of the buffer
  505. * 4 : fmt = format
  506. *
  507. * Returns : 0 => The conversion worked
  508. * 1 => The conversion failed
  509. *
  510. *********************************************************************/
  511. static int generate_certificate_valid_date(time_t time_spec, char *buffer,
  512. size_t buffer_size, const char *fmt)
  513. {
  514. struct tm valid_date;
  515. struct tm *timeptr;
  516. size_t ret;
  517. timeptr = privoxy_gmtime_r(&time_spec, &valid_date);
  518. if (NULL == timeptr)
  519. {
  520. return 1;
  521. }
  522. ret = strftime(buffer, buffer_size, fmt, timeptr);
  523. if (ret <= 0)
  524. {
  525. return 1;
  526. }
  527. return 0;
  528. }
  529. /*********************************************************************
  530. *
  531. * Function : get_certificate_valid_from_date
  532. *
  533. * Description : Generates a "valid from" date in the format
  534. * expected by mbedTLS.
  535. *
  536. * Parameters :
  537. * 1 : buffer = The buffer to write the date to
  538. * 2 : buffer_size = The size of the buffer
  539. * 3 : fmt = format
  540. *
  541. * Returns : 0 => The generation worked
  542. * 1 => The generation failed
  543. *
  544. *********************************************************************/
  545. extern int get_certificate_valid_from_date(char *buffer, size_t buffer_size, const char *fmt)
  546. {
  547. time_t time_spec;
  548. time_spec = time(NULL);
  549. /* 1 month in the past */
  550. time_spec -= 30 * 24 * 60 * 60;
  551. return generate_certificate_valid_date(time_spec, buffer, buffer_size, fmt);
  552. }
  553. /*********************************************************************
  554. *
  555. * Function : get_certificate_valid_to_date
  556. *
  557. * Description : Generates a "valid to" date in the format
  558. * expected by mbedTLS.
  559. *
  560. * Parameters :
  561. * 1 : buffer = The buffer to write the date to
  562. * 2 : buffer_size = The size of the buffer
  563. * 3 : fmt = format
  564. *
  565. * Returns : 0 => The generation worked
  566. * 1 => The generation failed
  567. *
  568. *********************************************************************/
  569. extern int get_certificate_valid_to_date(char *buffer, size_t buffer_size, const char *fmt)
  570. {
  571. time_t time_spec;
  572. time_spec = time(NULL);
  573. /* Three months in the future */
  574. time_spec += 90 * 24 * 60 * 60;
  575. return generate_certificate_valid_date(time_spec, buffer, buffer_size, fmt);
  576. }
  577. /*********************************************************************
  578. *
  579. * Function : host_is_ip_address
  580. *
  581. * Description : Checks whether or not a host is specified by
  582. * IP address. Does not actually validate the
  583. * address.
  584. *
  585. * Parameters :
  586. * 1 : host = The host name to check
  587. *
  588. * Returns : 1 => Yes
  589. * 0 => No
  590. *
  591. *********************************************************************/
  592. extern int host_is_ip_address(const char *host)
  593. {
  594. const char *p;
  595. if (NULL != strstr(host, ":"))
  596. {
  597. /* Assume an IPv6 address. */
  598. return 1;
  599. }
  600. for (p = host; *p; p++)
  601. {
  602. if ((*p != '.') && !privoxy_isdigit(*p))
  603. {
  604. /* Not a dot or digit so it can't be an IPv4 address. */
  605. return 0;
  606. }
  607. }
  608. /*
  609. * Host only consists of dots and digits so
  610. * assume that is an IPv4 address.
  611. */
  612. return 1;
  613. }