Move two typedefs from project.h to ssl.c
[privoxy.git] / ssl.c
1 /*********************************************************************
2 *
3 * File        :  $Source: /cvsroot/ijbswa/current/ssl.c,v $
4 *
5 * Purpose     :  File with TLS/SSL extension. Contains methods for
6 *                creating, using and closing TLS/SSL connections.
7 *
8 * Copyright   :  Written by and Copyright (c) 2017 Vaclav Svec. FIT CVUT.
9 *                Copyright (C) 2018-2019 by Fabian Keil <fk@fabiankeil.de>
10 *
11 *                This program is free software; you can redistribute it
12 *                and/or modify it under the terms of the GNU General
13 *                Public License as published by the Free Software
14 *                Foundation; either version 2 of the License, or (at
15 *                your option) any later version.
16 *
17 *                This program is distributed in the hope that it will
18 *                be useful, but WITHOUT ANY WARRANTY; without even the
19 *                implied warranty of MERCHANTABILITY or FITNESS FOR A
20 *                PARTICULAR PURPOSE.  See the GNU General Public
21 *                License for more details.
22 *
23 *                The GNU General Public License should be included with
24 *                this file.  If not, you can view it at
25 *                http://www.gnu.org/copyleft/gpl.html
26 *                or write to the Free Software Foundation, Inc., 59
27 *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
28 *
29 *********************************************************************/
30
31 #include <string.h>
32 #include <unistd.h>
33
34 #if !defined(MBEDTLS_CONFIG_FILE)
35 #  include "mbedtls/config.h"
36 #else
37 #  include MBEDTLS_CONFIG_FILE
38 #endif
39
40 #include "mbedtls/md5.h"
41 #include "mbedtls/pem.h"
42 #include "mbedtls/base64.h"
43 #include "mbedtls/error.h"
44
45 #include "project.h"
46 #include "miscutil.h"
47 #include "errlog.h"
48 #include "jcc.h"
49 #include "config.h"
50 #include "ssl.h"
51
52
53 /*
54  * Macros for searching begin and end of certificates.
55  * Necessary to convert structure mbedtls_x509_crt to crt file.
56  */
57 #define PEM_BEGIN_CRT     "-----BEGIN CERTIFICATE-----\n"
58 #define PEM_END_CRT       "-----END CERTIFICATE-----\n"
59
60 /*
61  * Macros for ssl.c
62  */
63 #define ERROR_BUF_SIZE                   1024              /* Size of buffer for error messages */
64 #define CERTIFICATE_BUF_SIZE             16384             /* Size of buffer to save certificate. Value 4096 is mbedtls library buffer size for certificate in DER form */
65 #define PRIVATE_KEY_BUF_SIZE             16000             /* Size of buffer to save private key. Value 16000 is taken from mbed TLS library examples. */
66 #define RSA_KEY_PUBLIC_EXPONENT          65537             /* Public exponent for RSA private key generating */
67 #define RSA_KEYSIZE                      2048              /* Size of generated RSA keys */
68 #define GENERATED_CERT_VALID_FROM        "20100101000000"  /* Date and time, which will be set in generated certificates as parameter valid from */
69 #define GENERATED_CERT_VALID_TO          "20401231235959"  /* Date and time, which will be setted in generated certificates as parameter valid to */
70 #define CERT_SIGNATURE_ALGORITHM         MBEDTLS_MD_SHA256 /* The MD algorithm to use for the signature */
71 #define CERT_SERIAL_NUM_LENGTH           4                 /* Bytes of hash to be used for creating serial number of certificate. Min=2 and max=16 */
72 #define LIMIT_MUTEX_NUMBER                                 /* If this macro is defined, mutexes count for generating private keys is changed from 65536 to 32 */
73 #define INVALID_CERT_INFO_BUF_SIZE       2048              /* Size of buffer for message with information about reason of certificate invalidity. Data after the end of buffer will not be saved */
74 #define CERT_PARAM_COMMON_NAME           "CN="
75 #define CERT_PARAM_ORGANIZATION          ",O="
76 #define CERT_PARAM_ORG_UNIT              ",OU="
77 #define CERT_PARAM_COUNTRY               ",C=CZ"
78 #define KEY_FILE_TYPE                    ".pem"
79 #define CERT_FILE_TYPE                   ".crt"
80 #define CERT_SUBJECT_PASSWORD            ""
81 #define CERT_INFO_PREFIX                 ""
82
83 /*
84  * Properties of cert for generating
85  */
86 typedef struct {
87    char       *issuer_crt;                         /* filename of the issuer certificate       */
88    char       *subject_key;                        /* filename of the subject key file         */
89    char       *issuer_key;                         /* filename of the issuer key file          */
90    const char *subject_pwd;                        /* password for the subject key file        */
91    const char *issuer_pwd;                         /* password for the issuer key file         */
92    char       *output_file;                        /* where to store the constructed key file  */
93    const char *subject_name;                       /* subject name for certificate             */
94    char       issuer_name[ISSUER_NAME_BUF_SIZE];   /* issuer name for certificate              */
95    const char *not_before;                         /* validity period not before               */
96    const char *not_after;                          /* validity period not after                */
97    const char *serial;                             /* serial number string                     */
98    int        is_ca;                               /* is a CA certificate                      */
99    int        max_pathlen;                         /* maximum CA path length                   */
100 } cert_options;
101
102 /*
103  * Properties of key for generating
104  */
105 typedef struct {
106    mbedtls_pk_type_t type;   /* type of key to generate  */
107    int  rsa_keysize;         /* length of key in bits    */
108    char *key_file_path;      /* filename of the key file */
109 } key_options;
110
111 extern int generate_webpage_certificate(struct client_state * csp);
112 static char * make_certs_path(const char * conf_dir, const char * file_name, const char * suffix);
113 static int file_exists(const char * path);
114 static int host_to_hash(struct client_state *csp);
115 static int ssl_verify_callback(void *data, mbedtls_x509_crt *crt, int depth, uint32_t *flags);
116 static void free_certificate_chain(struct client_state *csp);
117 static unsigned int get_certificate_mutex_id(struct client_state *csp);
118 static unsigned long  get_certificate_serial(struct client_state *csp);
119 static void free_client_ssl_structures(struct client_state *csp);
120 static void free_server_ssl_structures(struct client_state *csp);
121 static int seed_rng(struct client_state *csp);
122
123 /*********************************************************************
124  *
125  * Function    :  client_use_ssl
126  *
127  * Description :  Tests if client in current client state structure
128  *                should use SSL connection or standard connection.
129  *
130  * Parameters  :
131  *          1  :  csp = Current client state (buffers, headers, etc...)
132  *
133  * Returns     :  If client should use TLS/SSL connection, 1 is returned.
134  *                Otherwise 0 is returned.
135  *
136  *********************************************************************/
137 extern int client_use_ssl(const struct client_state *csp)
138 {
139    return csp->http->client_ssl;
140 }
141
142
143 /*********************************************************************
144  *
145  * Function    :  server_use_ssl
146  *
147  * Description :  Tests if server in current client state structure
148  *                should use SSL connection or standard connection.
149  *
150  * Parameters  :
151  *          1  :  csp = Current client state (buffers, headers, etc...)
152  *
153  * Returns     :  If server should use TLS/SSL connection, 1 is returned.
154  *                Otherwise 0 is returned.
155  *
156  *********************************************************************/
157 extern int server_use_ssl(const struct client_state *csp)
158 {
159    return csp->http->server_ssl;
160 }
161
162
163 /*********************************************************************
164 *
165 * Function    :  is_ssl_pending
166 *
167 * Description :  Tests if there are some waitting data on ssl connection
168 *
169 * Parameters  :
170 *          1  :  ssl = SSL context to test
171 *
172 * Returns     :   0 => No data are pending
173 *                >0 => Pending data length
174 *
175 *********************************************************************/
176 extern size_t is_ssl_pending(mbedtls_ssl_context *ssl)
177 {
178    if (ssl == NULL)
179    {
180       return 0;
181    }
182
183    return mbedtls_ssl_get_bytes_avail(ssl);
184 }
185
186
187 /*********************************************************************
188  *
189  * Function    :  ssl_send_data
190  *
191  * Description :  Sends the content of buf (for n bytes) to given SSL
192  *                connection context.
193  *
194  * Parameters  :
195  *          1  :  ssl = SSL context to send data to
196  *          2  :  buf = Pointer to data to be sent
197  *          3  :  len = Length of data to be sent to the SSL context
198  *
199  * Returns     :  Length of sent data or negative value on error.
200  *
201  *********************************************************************/
202 extern int ssl_send_data(mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len)
203 {
204    int ret = 0;
205    size_t max_fragment_size = 0;  /* Maximal length of data in one SSL fragment*/
206    int send_len             = 0;  /* length of one data part to send */
207    int pos                  = 0;  /* Position of unsent part in buffer */
208
209    if (len == 0)
210    {
211       return 0;
212    }
213
214    /* Getting maximal length of data sent in one fragment */
215    max_fragment_size = mbedtls_ssl_get_max_frag_len(ssl);
216
217    /*
218     * Whole buffer must be sent in many fragments, because each fragment
219     * has its maximal length.
220     */
221    while (pos < len)
222    {
223       /* Compute length of data, that can be send in next fragment */
224       if ((pos + (int)max_fragment_size) > len)
225       {
226          send_len = (int)len - pos;
227       }
228       else
229       {
230          send_len = (int)max_fragment_size;
231       }
232
233       /*
234        * Sending one part of the buffer
235        */
236       while ((ret = mbedtls_ssl_write(ssl,
237          (const unsigned char *)(buf + pos),
238          (size_t)send_len)) < 0)
239       {
240          if (ret != MBEDTLS_ERR_SSL_WANT_READ &&
241              ret != MBEDTLS_ERR_SSL_WANT_WRITE)
242          {
243             char err_buf[ERROR_BUF_SIZE];
244
245             memset(err_buf, 0, sizeof(err_buf));
246             mbedtls_strerror(ret, err_buf, sizeof(err_buf));
247             log_error(LOG_LEVEL_ERROR,
248                "Sending data over TLS/SSL failed: %s", err_buf);
249             return -1;
250          }
251       }
252       /* Adding count of sent bytes to position in buffer */
253       pos = pos + send_len;
254    }
255
256    return (int)len;
257 }
258
259
260 /*********************************************************************
261  *
262  * Function    :  ssl_recv_data
263  *
264  * Description :  Receives data from given SSL context and puts
265  *                it into buffer.
266  *
267  * Parameters  :
268  *          1  :  ssl = SSL context to receive data from
269  *          2  :  buf = Pointer to buffer where data will be written
270  *          3  :  max_length = Maximum number of bytes to read
271  *
272  * Returns     :  Number of bytes read, 0 for EOF, or negative
273  *                value on error.
274  *
275  *********************************************************************/
276 extern int ssl_recv_data(mbedtls_ssl_context *ssl, unsigned char *buf, size_t max_length)
277 {
278    int ret = 0;
279    memset(buf, 0, max_length);
280
281    /*
282     * Receiving data from SSL context into buffer
283     */
284    do
285    {
286       ret = mbedtls_ssl_read(ssl, buf, max_length);
287    } while (ret == MBEDTLS_ERR_SSL_WANT_READ
288       || ret == MBEDTLS_ERR_SSL_WANT_WRITE);
289
290    if (ret < 0)
291    {
292       char err_buf[ERROR_BUF_SIZE];
293
294       memset(err_buf, 0, sizeof(err_buf));
295       mbedtls_strerror(ret, err_buf, sizeof(err_buf));
296       log_error(LOG_LEVEL_ERROR,
297          "Receiving data over TLS/SSL failed: %s", err_buf);
298    }
299
300    return ret;
301 }
302
303
304 /*********************************************************************
305  *
306  * Function    :  ssl_flush_socket
307  *
308  * Description :  Send any pending "buffered" content with given
309  *                SSL connection. Alternative to function flush_socket.
310  *
311  * Parameters  :
312  *          1  :  ssl = SSL context to send buffer to
313  *          2  :  iob = The I/O buffer to flush, usually csp->iob.
314  *
315  * Returns     :  On success, the number of bytes send are returned (zero
316  *                indicates nothing was sent).  On error, -1 is returned.
317  *
318  *********************************************************************/
319 extern long ssl_flush_socket(mbedtls_ssl_context *ssl, struct iob *iob)
320 {
321    /* Computing length of buffer part to send */
322    long len = iob->eod - iob->cur;
323
324    if (len <= 0)
325    {
326       return(0);
327    }
328
329    /* Sending data to given SSl context */
330    if (ssl_send_data(ssl, (const unsigned char *)iob->cur, (size_t)len) < 0)
331    {
332       return -1;
333    }
334    iob->eod = iob->cur = iob->buf;
335    return(len);
336 }
337
338
339 /*********************************************************************
340  *
341  * Function    :  ssl_debug_callback
342  *
343  * Description :  Debug callback function for mbedtls library.
344  *                Prints info into log file.
345  *
346  * Parameters  :
347  *          1  :  ctx   = File to save log in
348  *          2  :  level = Debug level
349  *          3  :  file  = File calling debug message
350  *          4  :  line  = Line calling debug message
351  *          5  :  str   = Debug message
352  *
353  * Returns     :  N/A
354  *
355  *********************************************************************/
356 static void ssl_debug_callback(void *ctx, int level, const char *file, int line, const char *str)
357 {
358    /*
359    ((void)level);
360    fprintf((FILE *)ctx, "%s:%04d: %s", file, line, str);
361    fflush((FILE *)ctx);
362    log_error(LOG_LEVEL_INFO, "SSL debug message: %s:%04d: %s", file, line, str);
363    */
364 }
365
366
367 /*********************************************************************
368  *
369  * Function    :  create_client_ssl_connection
370  *
371  * Description :  Creates TLS/SSL secured connection with client
372  *
373  * Parameters  :
374  *          1  :  csp = Current client state (buffers, headers, etc...)
375  *
376  * Returns     :  0 on success, negative value if connection wasn't created
377  *                successfully.
378  *
379  *********************************************************************/
380 extern int create_client_ssl_connection(struct client_state *csp)
381 {
382    /* Paths to certificates file and key file */
383    char *key_file  = NULL;
384    char *ca_file   = NULL;
385    char *cert_file = NULL;
386    int ret = 0;
387    char err_buf[ERROR_BUF_SIZE];
388
389    memset(err_buf, 0, sizeof(err_buf));
390
391    /*
392     * Initializing mbedtls structures for TLS/SSL connection
393     */
394    mbedtls_net_init(&(csp->mbedtls_client_attr.socket_fd));
395    mbedtls_ssl_init(&(csp->mbedtls_client_attr.ssl));
396    mbedtls_ssl_config_init(&(csp->mbedtls_client_attr.conf));
397    mbedtls_x509_crt_init(&(csp->mbedtls_client_attr.server_cert));
398    mbedtls_pk_init(&(csp->mbedtls_client_attr.prim_key));
399 #if defined(MBEDTLS_SSL_CACHE_C)
400    mbedtls_ssl_cache_init(&(csp->mbedtls_client_attr.cache));
401 #endif
402
403    /*
404     * Preparing hash of host for creating certificates
405     */
406    ret = host_to_hash(csp);
407    if (ret != 0)
408    {
409       log_error(LOG_LEVEL_ERROR, "Generating hash of host failed: %d", ret);
410       ret = -1;
411       goto exit;
412    }
413
414    /*
415     * Preparing paths to certificates files and key file
416     */
417    ca_file   = csp->config->ca_cert_file;
418    cert_file = make_certs_path(csp->config->certificate_directory,
419       (const char *)csp->http->hash_of_host_hex, CERT_FILE_TYPE);
420    key_file  = make_certs_path(csp->config->certificate_directory,
421       (const char *)csp->http->hash_of_host_hex, KEY_FILE_TYPE);
422
423    if (cert_file == NULL || key_file == NULL)
424    {
425       ret = -1;
426       goto exit;
427    }
428
429    /*
430     * Generating certificate for requested host. Mutex to prevent
431     * certificate and key inconsistence must be locked.
432     */
433    unsigned int cert_mutex_id = get_certificate_mutex_id(csp);
434    privoxy_mutex_lock(&(certificates_mutexes[cert_mutex_id]));
435
436    ret = generate_webpage_certificate(csp);
437    if (ret < 0)
438    {
439       log_error(LOG_LEVEL_ERROR,
440          "Generate_webpage_certificate failed: %d", ret);
441       privoxy_mutex_unlock(&(certificates_mutexes[cert_mutex_id]));
442       ret = -1;
443       goto exit;
444    }
445    privoxy_mutex_unlock(&(certificates_mutexes[cert_mutex_id]));
446
447    /*
448     * Seed the RNG
449     */
450    ret = seed_rng(csp);
451    if (ret != 0)
452    {
453       ret = -1;
454       goto exit;
455    }
456
457    /*
458     * Loading CA file, webpage certificate and key files
459     */
460    ret = mbedtls_x509_crt_parse_file(&(csp->mbedtls_client_attr.server_cert),
461       cert_file);
462    if (ret != 0)
463    {
464       mbedtls_strerror(ret, err_buf, sizeof(err_buf));
465       log_error(LOG_LEVEL_ERROR,
466          "Loading webpage certificate %s failed: %s", cert_file, err_buf);
467       ret = -1;
468       goto exit;
469    }
470
471    ret = mbedtls_x509_crt_parse_file(&(csp->mbedtls_client_attr.server_cert),
472       ca_file);
473    if (ret != 0)
474    {
475       mbedtls_strerror(ret, err_buf, sizeof(err_buf));
476       log_error(LOG_LEVEL_ERROR,
477          "Loading CA certificate %s failed: %s", ca_file, err_buf);
478       ret = -1;
479       goto exit;
480    }
481
482    ret = mbedtls_pk_parse_keyfile(&(csp->mbedtls_client_attr.prim_key),
483       key_file, NULL);
484    if (ret != 0)
485    {
486       mbedtls_strerror(ret, err_buf, sizeof(err_buf));
487       log_error(LOG_LEVEL_ERROR,
488          "Loading and parsing webpage certificate private key %s failed: %s",
489          key_file, err_buf);
490       ret = -1;
491       goto exit;
492    }
493
494    /*
495     * Setting SSL parameters
496     */
497    ret = mbedtls_ssl_config_defaults(&(csp->mbedtls_client_attr.conf),
498       MBEDTLS_SSL_IS_SERVER, MBEDTLS_SSL_TRANSPORT_STREAM,
499       MBEDTLS_SSL_PRESET_DEFAULT);
500    if (ret != 0)
501    {
502       mbedtls_strerror(ret, err_buf, sizeof(err_buf));
503       log_error(LOG_LEVEL_ERROR,
504          "mbedtls_ssl_config_defaults failed: %s", err_buf);
505       ret = -1;
506       goto exit;
507    }
508
509    mbedtls_ssl_conf_rng(&(csp->mbedtls_client_attr.conf),
510       mbedtls_ctr_drbg_random, &ctr_drbg);
511    mbedtls_ssl_conf_dbg(&(csp->mbedtls_client_attr.conf),
512       ssl_debug_callback, stdout);
513
514 #if defined(MBEDTLS_SSL_CACHE_C)
515    mbedtls_ssl_conf_session_cache(&(csp->mbedtls_client_attr.conf),
516       &(csp->mbedtls_client_attr.cache), mbedtls_ssl_cache_get,
517       mbedtls_ssl_cache_set);
518 #endif
519
520    /*
521     * Setting certificates
522     */
523    ret = mbedtls_ssl_conf_own_cert(&(csp->mbedtls_client_attr.conf),
524       &(csp->mbedtls_client_attr.server_cert),
525       &(csp->mbedtls_client_attr.prim_key));
526    if (ret != 0)
527    {
528       mbedtls_strerror(ret, err_buf, sizeof(err_buf));
529       log_error(LOG_LEVEL_ERROR,
530          "mbedtls_ssl_conf_own_cert failed: %s", err_buf);
531       ret = -1;
532       goto exit;
533    }
534
535    ret = mbedtls_ssl_setup(&(csp->mbedtls_client_attr.ssl),
536       &(csp->mbedtls_client_attr.conf));
537    if (ret != 0)
538    {
539       mbedtls_strerror(ret, err_buf, sizeof(err_buf));
540       log_error(LOG_LEVEL_ERROR, "mbedtls_ssl_setup failed: %s", err_buf);
541       ret = -1;
542       goto exit;
543    }
544
545    mbedtls_ssl_set_bio(&(csp->mbedtls_client_attr.ssl),
546       &(csp->mbedtls_client_attr.socket_fd), mbedtls_net_send,
547       mbedtls_net_recv, NULL);
548    mbedtls_ssl_session_reset(&(csp->mbedtls_client_attr.ssl));
549
550    /*
551     * Setting socket fd in mbedtls_net_context structure. This structure
552     * can't be set by mbedtls functions, because we already have created
553     * a TCP connection when this function is called.
554     */
555    csp->mbedtls_client_attr.socket_fd.fd = csp->cfd;
556
557    /*
558     *  Handshake with client
559     */
560    log_error(LOG_LEVEL_CONNECT,
561       "Performing the TLS/SSL handshake with client. Hash of host: %s",
562       csp->http->hash_of_host_hex);
563    while ((ret = mbedtls_ssl_handshake(&(csp->mbedtls_client_attr.ssl))) != 0)
564    {
565       if (ret != MBEDTLS_ERR_SSL_WANT_READ &&
566           ret != MBEDTLS_ERR_SSL_WANT_WRITE)
567       {
568          mbedtls_strerror(ret, err_buf, sizeof(err_buf));
569          log_error(LOG_LEVEL_ERROR,
570             "medtls_ssl_handshake with client failed: %s", err_buf);
571          ret = -1;
572          goto exit;
573       }
574    }
575
576    log_error(LOG_LEVEL_CONNECT, "Client successfully connected over TLS/SSL");
577    csp->ssl_with_client_is_opened = 1;
578
579 exit:
580    /*
581     * Freeing allocated paths to files
582     */
583    freez(cert_file);
584    freez(key_file);
585
586    /* Freeing structures if connection wasn't created successfully */
587    if (ret < 0)
588    {
589       free_client_ssl_structures(csp);
590    }
591    return ret;
592 }
593
594
595 /*********************************************************************
596  *
597  * Function    :  close_client_ssl_connection
598  *
599  * Description :  Closes TLS/SSL connection with client. This function
600  *                checks if this connection is already created.
601  *
602  * Parameters  :
603  *          1  :  csp = Current client state (buffers, headers, etc...)
604  *
605  * Returns     :  N/A
606  *
607  *********************************************************************/
608 extern void close_client_ssl_connection(struct client_state *csp)
609 {
610    int ret = 0;
611
612    if (csp->ssl_with_client_is_opened == 0)
613    {
614       return;
615    }
616
617    /*
618     * Notifying the peer that the connection is being closed.
619     */
620    do {
621       ret = mbedtls_ssl_close_notify(&(csp->mbedtls_client_attr.ssl));
622    } while (ret == MBEDTLS_ERR_SSL_WANT_WRITE);
623
624    free_client_ssl_structures(csp);
625    csp->ssl_with_client_is_opened = 0;
626 }
627
628
629 /*********************************************************************
630  *
631  * Function    :  free_client_ssl_structures
632  *
633  * Description :  Frees structures used for SSL communication with
634  *                client.
635  *
636  * Parameters  :
637  *          1  :  csp = Current client state (buffers, headers, etc...)
638  *
639  * Returns     :  N/A
640  *
641  *********************************************************************/
642 static void free_client_ssl_structures(struct client_state *csp)
643 {
644    /*
645    * We can't use function mbedtls_net_free, because this function
646    * inter alia close TCP connection on setted fd. Instead of this
647    * function, we change fd to -1, which is the same what does
648    * rest of mbedtls_net_free function.
649    */
650    csp->mbedtls_client_attr.socket_fd.fd = -1;
651
652    /* Freeing mbedtls structures */
653    mbedtls_x509_crt_free(&(csp->mbedtls_client_attr.server_cert));
654    mbedtls_pk_free(&(csp->mbedtls_client_attr.prim_key));
655    mbedtls_ssl_free(&(csp->mbedtls_client_attr.ssl));
656    mbedtls_ssl_config_free(&(csp->mbedtls_client_attr.conf));
657 #if defined(MBEDTLS_SSL_CACHE_C)
658    mbedtls_ssl_cache_free(&(csp->mbedtls_client_attr.cache));
659 #endif
660 }
661
662
663 /*********************************************************************
664  *
665  * Function    :  create_server_ssl_connection
666  *
667  * Description :  Creates TLS/SSL secured connection with server.
668  *
669  * Parameters  :
670  *          1  :  csp = Current client state (buffers, headers, etc...)
671  *
672  * Returns     :  0 on success, negative value if connection wasn't created
673  *                successfully.
674  *
675  *********************************************************************/
676 extern int create_server_ssl_connection(struct client_state *csp)
677 {
678    int ret = 0;
679    char err_buf[ERROR_BUF_SIZE];
680    char *trusted_cas_file = NULL;
681    int auth_mode = MBEDTLS_SSL_VERIFY_REQUIRED;
682
683    memset(err_buf, 0, sizeof(err_buf));
684
685    csp->server_cert_verification_result = SSL_CERT_NOT_VERIFIED;
686    csp->server_certs_chain.next = NULL;
687
688    /* Setting path to file with trusted CAs */
689    trusted_cas_file = csp->config->trusted_cas_file;
690
691    /*
692     * Initializing mbedtls structures for TLS/SSL connection
693     */
694    mbedtls_net_init(&(csp->mbedtls_server_attr.socket_fd));
695    mbedtls_ssl_init(&(csp->mbedtls_server_attr.ssl));
696    mbedtls_ssl_config_init(&(csp->mbedtls_server_attr.conf));
697    mbedtls_x509_crt_init( &(csp->mbedtls_server_attr.ca_cert));
698
699    /*
700    * Setting socket fd in mbedtls_net_context structure. This structure
701    * can't be set by mbedtls functions, because we already have created
702    * TCP connection when calling this function.
703    */
704    csp->mbedtls_server_attr.socket_fd.fd = csp->server_connection.sfd;
705
706    /*
707     * Seed the RNG
708     */
709    ret = seed_rng(csp);
710    if (ret != 0)
711    {
712       ret = -1;
713       goto exit;
714    }
715
716    /*
717     * Loading file with trusted CAs
718     */
719    ret = mbedtls_x509_crt_parse_file(&(csp->mbedtls_server_attr.ca_cert),
720       trusted_cas_file);
721    if (ret < 0)
722    {
723       mbedtls_strerror(ret, err_buf, sizeof(err_buf));
724       log_error(LOG_LEVEL_ERROR, "Loading trusted CAs file %s failed: %s",
725          trusted_cas_file, err_buf);
726       ret = -1;
727       goto exit;
728    }
729
730    /*
731     * Set TLS/SSL options
732     */
733    ret = mbedtls_ssl_config_defaults(&(csp->mbedtls_server_attr.conf),
734       MBEDTLS_SSL_IS_CLIENT,
735       MBEDTLS_SSL_TRANSPORT_STREAM,
736       MBEDTLS_SSL_PRESET_DEFAULT);
737    if (ret != 0)
738    {
739       mbedtls_strerror(ret, err_buf, sizeof(err_buf));
740       log_error(LOG_LEVEL_ERROR, "mbedtls_ssl_config_defaults failed: %s",
741          err_buf);
742       ret = -1;
743       goto exit;
744    }
745
746    /*
747     * Setting how strict should certificate verification be and other
748     * parameters for certificate verification
749     */
750    if (csp->dont_verify_certificate)
751    {
752       auth_mode = MBEDTLS_SSL_VERIFY_NONE;
753    }
754
755    mbedtls_ssl_conf_authmode(&(csp->mbedtls_server_attr.conf), auth_mode);
756    mbedtls_ssl_conf_ca_chain(&(csp->mbedtls_server_attr.conf),
757       &(csp->mbedtls_server_attr.ca_cert), NULL);
758
759    /* Setting callback function for certificates verification */
760    mbedtls_ssl_conf_verify(&(csp->mbedtls_server_attr.conf),
761       ssl_verify_callback, (void *)csp);
762
763    mbedtls_ssl_conf_rng(&(csp->mbedtls_server_attr.conf),
764       mbedtls_ctr_drbg_random, &ctr_drbg);
765    mbedtls_ssl_conf_dbg(&(csp->mbedtls_server_attr.conf),
766       ssl_debug_callback, stdout);
767
768    ret = mbedtls_ssl_setup(&(csp->mbedtls_server_attr.ssl),
769       &(csp->mbedtls_server_attr.conf));
770    if (ret != 0)
771    {
772       mbedtls_strerror(ret, err_buf, sizeof(err_buf));
773       log_error(LOG_LEVEL_ERROR, "mbedtls_ssl_setup failed: %s", err_buf);
774       ret = -1;
775       goto exit;
776    }
777
778    /*
779     * Set the hostname to check against the received server certificate
780     */
781    ret = mbedtls_ssl_set_hostname(&(csp->mbedtls_server_attr.ssl),
782       csp->http->host);
783    if (ret != 0)
784    {
785       mbedtls_strerror(ret, err_buf, sizeof(err_buf));
786       log_error(LOG_LEVEL_ERROR, "mbedtls_ssl_set_hostname failed: %s",
787          err_buf);
788       ret = -1;
789       goto exit;
790    }
791
792    mbedtls_ssl_set_bio(&(csp->mbedtls_server_attr.ssl),
793       &(csp->mbedtls_server_attr.socket_fd), mbedtls_net_send,
794       mbedtls_net_recv, NULL);
795
796    /*
797     * Handshake with server
798     */
799    log_error(LOG_LEVEL_CONNECT,
800       "Performing the TLS/SSL handshake with server");
801
802    while ((ret = mbedtls_ssl_handshake(&(csp->mbedtls_server_attr.ssl))) != 0)
803    {
804       if (ret != MBEDTLS_ERR_SSL_WANT_READ
805        && ret != MBEDTLS_ERR_SSL_WANT_WRITE)
806       {
807          mbedtls_strerror(ret, err_buf, sizeof(err_buf));
808
809          if (ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED)
810          {
811             log_error(LOG_LEVEL_ERROR,
812                "Server certificate verification failed: %s", err_buf);
813             csp->server_cert_verification_result =
814                mbedtls_ssl_get_verify_result(&(csp->mbedtls_server_attr.ssl));
815
816             ret = -1;
817          }
818          else
819          {
820             log_error(LOG_LEVEL_ERROR,
821                "mbedtls_ssl_handshake with server failed: %s", err_buf);
822             ret = -1;
823          }
824          goto exit;
825       }
826    }
827
828    log_error(LOG_LEVEL_CONNECT, "Server successfully connected over TLS/SSL");
829
830    /*
831     * Server certificate chain is valid, so we can clean
832     * chain, because we will not send it to client.
833     */
834    free_certificate_chain(csp);
835
836    csp->ssl_with_server_is_opened = 1;
837    csp->server_cert_verification_result =
838       mbedtls_ssl_get_verify_result(&(csp->mbedtls_server_attr.ssl));
839
840 exit:
841    /* Freeing structures if connection wasn't created successfully */
842    if (ret < 0)
843    {
844       free_server_ssl_structures(csp);
845    }
846
847    return ret;
848 }
849
850
851 /*********************************************************************
852  *
853  * Function    :  close_server_ssl_connection
854  *
855  * Description :  Closes TLS/SSL connection with server. This function
856  *                checks if this connection is already opened.
857  *
858  * Parameters  :
859  *          1  :  csp = Current client state (buffers, headers, etc...)
860  *
861  * Returns     :  N/A
862  *
863  *********************************************************************/
864 static void close_server_ssl_connection(struct client_state *csp)
865 {
866    int ret = 0;
867
868    if (csp->ssl_with_server_is_opened == 0)
869    {
870       return;
871    }
872
873    /*
874    * Notifying the peer that the connection is being closed.
875    */
876    do {
877       ret = mbedtls_ssl_close_notify(&(csp->mbedtls_server_attr.ssl));
878    } while (ret == MBEDTLS_ERR_SSL_WANT_WRITE);
879
880    free_server_ssl_structures(csp);
881    csp->ssl_with_server_is_opened = 0;
882 }
883
884
885 /*********************************************************************
886  *
887  * Function    :  free_server_ssl_structures
888  *
889  * Description :  Frees structures used for SSL communication with server
890  *
891  * Parameters  :
892  *          1  :  csp = Current client state (buffers, headers, etc...)
893  *
894  * Returns     :  N/A
895  *
896  *********************************************************************/
897 static void free_server_ssl_structures(struct client_state *csp)
898 {
899    /*
900    * We can't use function mbedtls_net_free, because this function
901    * inter alia close TCP connection on setted fd. Instead of this
902    * function, we change fd to -1, which is the same what does
903    * rest of mbedtls_net_free function.
904    */
905    csp->mbedtls_client_attr.socket_fd.fd = -1;
906
907    mbedtls_x509_crt_free(&(csp->mbedtls_server_attr.ca_cert));
908    mbedtls_ssl_free(&(csp->mbedtls_server_attr.ssl));
909    mbedtls_ssl_config_free(&(csp->mbedtls_server_attr.conf));
910 }
911
912
913 /*********************************************************************
914  *
915  * Function    :  close_client_and_server_ssl_connections
916  *
917  * Description :  Checks if client or server should use secured
918  *                connection over SSL and if so, closes all of them.
919  *
920  * Parameters  :
921  *          1  :  csp = Current client state (buffers, headers, etc...)
922  *
923  * Returns     :  N/A
924  *
925  *********************************************************************/
926 extern void close_client_and_server_ssl_connections(struct client_state *csp)
927 {
928    if (client_use_ssl(csp) == 1)
929    {
930       close_client_ssl_connection(csp);
931    }
932    if (server_use_ssl(csp) == 1)
933    {
934       close_server_ssl_connection(csp);
935    }
936 }
937
938 /*====================== Certificates ======================*/
939
940 /*********************************************************************
941  *
942  * Function    :  write_certificate
943  *
944  * Description :  Writes certificate into file.
945  *
946  * Parameters  :
947  *          1  :  crt = certificate to write into file
948  *          2  :  output_file = path to save certificate file
949  *          3  :  f_rng = mbedtls_ctr_drbg_random
950  *          4  :  p_rng = mbedtls_ctr_drbg_context
951  *
952  * Returns     :  Length of written certificate on success or negative value
953  *                on error
954  *
955  *********************************************************************/
956 static int write_certificate(mbedtls_x509write_cert *crt, const char *output_file,
957    int(*f_rng)(void *, unsigned char *, size_t), void *p_rng)
958 {
959    FILE *f = NULL;
960    size_t len = 0;
961    unsigned char cert_buf[CERTIFICATE_BUF_SIZE + 1]; /* Buffer for certificate in PEM format + terminating NULL */
962    int ret = 0;
963    char err_buf[ERROR_BUF_SIZE];
964
965    memset(err_buf,  0, sizeof(err_buf));
966    memset(cert_buf, 0, sizeof(cert_buf));
967
968    /*
969     * Writing certificate into PEM string. If buffer is too small, fuction
970     * returns specific error and no buffer overflow can happen.
971     */
972    if ((ret = mbedtls_x509write_crt_pem(crt, cert_buf,
973       sizeof(cert_buf) - 1, f_rng, p_rng)) != 0)
974    {
975       mbedtls_strerror(ret, err_buf, sizeof(err_buf));
976       log_error(LOG_LEVEL_ERROR,
977          "Writing certificate into buffer failed: %s", err_buf);
978       return -1;
979    }
980
981    len = strlen((char *)cert_buf);
982
983    /*
984     * Saving certificate into file
985     */
986    if ((f = fopen(output_file, "w")) == NULL)
987    {
988       log_error(LOG_LEVEL_ERROR, "Opening file %s to save certificate failed",
989          output_file);
990       return -1;
991    }
992
993    if (fwrite(cert_buf, 1, len, f) != len)
994    {
995       log_error(LOG_LEVEL_ERROR,
996          "Writing certificate into file %s failed", output_file);
997       fclose(f);
998       return -1;
999    }
1000
1001    fclose(f);
1002
1003    return (int)len;
1004 }
1005
1006
1007 /*********************************************************************
1008  *
1009  * Function    :  write_private_key
1010  *
1011  * Description :  Writes private key into file and copies saved
1012  *                content into given pointer to string. If function
1013  *                returns 0 for success, this copy must be freed by
1014  *                caller.
1015  *
1016  * Parameters  :
1017  *          1  :  key = key to write into file
1018  *          2  :  ret_buf = pointer to string with created key file content
1019  *          3  :  key_file_path = path where to save key file
1020  *
1021  * Returns     :  Length of written private key on success or negative value
1022  *                on error
1023  *
1024  *********************************************************************/
1025 static int write_private_key(mbedtls_pk_context *key, unsigned char **ret_buf,
1026    const char *key_file_path)
1027 {
1028    size_t len = 0;                /* Length of created key    */
1029    FILE *f = NULL;                /* File to save certificate */
1030    int ret = 0;
1031    char err_buf[ERROR_BUF_SIZE];
1032
1033    memset(err_buf, 0, sizeof(err_buf));
1034
1035    /* Initializing buffer for key file content */
1036    *ret_buf = (unsigned char *)malloc(PRIVATE_KEY_BUF_SIZE + 1);
1037    if (*ret_buf == NULL)
1038    {
1039       log_error(LOG_LEVEL_ERROR,
1040          "Creating buffer for private key failed: malloc fail");
1041       ret = -1;
1042       goto exit;
1043    }
1044    memset(*ret_buf, 0, PRIVATE_KEY_BUF_SIZE + 1);
1045
1046    /*
1047     * Writing private key into PEM string
1048     */
1049    if ((ret = mbedtls_pk_write_key_pem(key, *ret_buf, PRIVATE_KEY_BUF_SIZE)) != 0)
1050    {
1051       mbedtls_strerror(ret, err_buf, sizeof(err_buf));
1052       log_error(LOG_LEVEL_ERROR,
1053          "Writing private key into PEM string failed: %s", err_buf);
1054       ret = -1;
1055       goto exit;
1056    }
1057    len = strlen((char *)*ret_buf);
1058
1059    /*
1060     * Saving key into file
1061     */
1062    if ((f = fopen(key_file_path, "wb")) == NULL)
1063    {
1064       log_error(LOG_LEVEL_ERROR,
1065          "Opening file %s to save private key failed: %E",
1066          key_file_path);
1067       ret = -1;
1068       goto exit;
1069    }
1070
1071    if (fwrite(*ret_buf, 1, len, f) != len)
1072    {
1073       fclose(f);
1074       log_error(LOG_LEVEL_ERROR,
1075          "Writing private key into file %s failed",
1076          key_file_path);
1077       ret = -1;
1078       goto exit;
1079    }
1080
1081    fclose(f);
1082
1083 exit:
1084    if (ret < 0)
1085    {
1086       freez(*ret_buf);
1087       *ret_buf = NULL;
1088       return ret;
1089    }
1090    return (int)len;
1091 }
1092
1093
1094 /*********************************************************************
1095  *
1096  * Function    :  generate_key
1097  *
1098  * Description : Tests if private key for host saved in csp already
1099  *               exists.  If this file doesn't exists, a new key is
1100  *               generated and saved in a file. The generated key is also
1101  *               copied into given parameter key_buf, which must be then
1102  *               freed by caller. If file with key exists, key_buf
1103  *               contain NULL and no private key is generated.
1104  *
1105  * Parameters  :
1106  *          1  :  key_buf = buffer to save new generated key
1107  *          2  :  csp = Current client state (buffers, headers, etc...)
1108  *
1109  * Returns     :  -1 => Error while generating private key
1110  *                 0 => Key already exists
1111  *                >0 => Length of generated private key
1112  *
1113  *********************************************************************/
1114 static int generate_key(unsigned char **key_buf, struct client_state *csp)
1115 {
1116    mbedtls_pk_context key;
1117    key_options key_opt;
1118    int ret = 0;
1119    char err_buf[ERROR_BUF_SIZE];
1120
1121    key_opt.key_file_path = NULL;
1122    memset(err_buf, 0, sizeof(err_buf));
1123
1124    /*
1125     * Initializing structures for key generating
1126     */
1127    mbedtls_pk_init(&key);
1128
1129    /*
1130     * Preparing path for key file and other properties for generating key
1131     */
1132    key_opt.type        = MBEDTLS_PK_RSA;
1133    key_opt.rsa_keysize = RSA_KEYSIZE;
1134
1135    key_opt.key_file_path = make_certs_path(csp->config->certificate_directory,
1136       (char *)csp->http->hash_of_host_hex, KEY_FILE_TYPE);
1137    if (key_opt.key_file_path == NULL)
1138    {
1139       ret = -1;
1140       goto exit;
1141    }
1142
1143    /*
1144     * Test if key already exists. If so, we don't have to create it again.
1145     */
1146    if (file_exists(key_opt.key_file_path) == 1)
1147    {
1148       ret = 0;
1149       goto exit;
1150    }
1151
1152    /*
1153     * Seed the RNG
1154     */
1155    ret = seed_rng(csp);
1156    if (ret != 0)
1157    {
1158       ret = -1;
1159       goto exit;
1160    }
1161
1162    /*
1163     * Setting attributes of private key and generating it
1164     */
1165    if ((ret = mbedtls_pk_setup(&key,
1166       mbedtls_pk_info_from_type(key_opt.type))) != 0)
1167    {
1168       mbedtls_strerror(ret, err_buf, sizeof(err_buf));
1169       log_error(LOG_LEVEL_ERROR, "mbedtls_pk_setup failed: %s", err_buf);
1170       ret = -1;
1171       goto exit;
1172    }
1173
1174    ret = mbedtls_rsa_gen_key(mbedtls_pk_rsa(key), mbedtls_ctr_drbg_random,
1175       &ctr_drbg, (unsigned)key_opt.rsa_keysize, RSA_KEY_PUBLIC_EXPONENT);
1176    if (ret != 0)
1177    {
1178       mbedtls_strerror(ret, err_buf, sizeof(err_buf));
1179       log_error(LOG_LEVEL_ERROR, "Key generating failed: %s", err_buf);
1180       ret = -1;
1181       goto exit;
1182    }
1183
1184    /*
1185     * Exporting private key into file
1186     */
1187    if ((ret = write_private_key(&key, key_buf, key_opt.key_file_path)) < 0)
1188    {
1189       log_error(LOG_LEVEL_ERROR,
1190          "Writing private key into file %s failed", key_opt.key_file_path);
1191       ret = -1;
1192       goto exit;
1193    }
1194
1195 exit:
1196    /*
1197     * Freeing used variables
1198     */
1199    freez(key_opt.key_file_path);
1200
1201    mbedtls_pk_free(&key);
1202
1203    return ret;
1204 }
1205
1206
1207 /*********************************************************************
1208  *
1209  * Function    :  generate_webpage_certificate
1210  *
1211  * Description :  Creates certificate file in presetted directory.
1212  *                If certificate already exists, no other certificate
1213  *                will be created. Subject of certificate is named
1214  *                by csp->http->host from parameter. This function also
1215  *                triggers generating of private key for new certificate.
1216  *
1217  * Parameters  :
1218  *          1  :  csp = Current client state (buffers, headers, etc...)
1219  *
1220  * Returns     :  -1 => Error while creating certificate.
1221  *                 0 => Certificate alreaday exist.
1222  *                >0 => Length of created certificate.
1223  *
1224  *********************************************************************/
1225 extern int generate_webpage_certificate(struct client_state * csp)
1226 {
1227    mbedtls_x509_crt issuer_cert;
1228    mbedtls_pk_context loaded_issuer_key, loaded_subject_key;
1229    mbedtls_pk_context *issuer_key  = &loaded_issuer_key;
1230    mbedtls_pk_context *subject_key = &loaded_subject_key;
1231    mbedtls_x509write_cert cert;
1232    mbedtls_mpi serial;
1233
1234    unsigned char *key_buf = NULL;    /* Buffer for created key */
1235
1236    int ret = 0;
1237    char err_buf[ERROR_BUF_SIZE];
1238    cert_options cert_opt;
1239
1240    memset(err_buf, 0, sizeof(err_buf));
1241
1242    /* Paths to keys and certificates needed to create certificate */
1243    cert_opt.issuer_key  = NULL;
1244    cert_opt.subject_key = NULL;
1245    cert_opt.issuer_crt  = NULL;
1246    cert_opt.output_file = NULL;
1247
1248    /*
1249     * Create key for requested host
1250     */
1251    int subject_key_len = generate_key(&key_buf, csp);
1252    if (subject_key_len < 0)
1253    {
1254       log_error(LOG_LEVEL_ERROR, "Key generating failed");
1255       return -1;
1256    }
1257
1258    /*
1259     * Initializing structures for certificate generating
1260     */
1261    mbedtls_x509write_crt_init(&cert);
1262    mbedtls_x509write_crt_set_md_alg( &cert, CERT_SIGNATURE_ALGORITHM);
1263    mbedtls_pk_init(&loaded_issuer_key);
1264    mbedtls_pk_init(&loaded_subject_key);
1265    mbedtls_mpi_init(&serial);
1266    mbedtls_x509_crt_init(&issuer_cert);
1267
1268    /*
1269     * Presetting parameters for certificate. We must compute total length
1270     * of parameters.
1271     */
1272    size_t cert_params_len = strlen(CERT_PARAM_COMMON_NAME) +
1273       strlen(CERT_PARAM_ORGANIZATION) + strlen(CERT_PARAM_COUNTRY) +
1274       strlen(CERT_PARAM_ORG_UNIT) +
1275       3 * strlen(csp->http->host) + 1;
1276    char cert_params[cert_params_len];
1277    memset(cert_params, 0, cert_params_len);
1278
1279    /*
1280     * Converting unsigned long serial number to char * serial number.
1281     * We must compute length of serial number in string + terminating null.
1282     */
1283    unsigned long certificate_serial = get_certificate_serial(csp);
1284    int serial_num_size = snprintf(NULL, 0, "%lu", certificate_serial) + 1;
1285    if (serial_num_size <= 0)
1286    {
1287       serial_num_size = 1;
1288    }
1289
1290    char serial_num_text[serial_num_size];  /* Buffer for serial number */
1291    ret = snprintf(serial_num_text, (size_t)serial_num_size, "%lu", certificate_serial);
1292    if (ret < 0 || ret >= serial_num_size)
1293    {
1294       log_error(LOG_LEVEL_ERROR,
1295          "Converting certificate serial number into string failed");
1296       ret = -1;
1297       goto exit;
1298    }
1299
1300    /*
1301     * Preparing parameters for certificate
1302     */
1303    strlcpy(cert_params, CERT_PARAM_COMMON_NAME,  cert_params_len);
1304    strlcat(cert_params, csp->http->host,         cert_params_len);
1305    strlcat(cert_params, CERT_PARAM_ORGANIZATION, cert_params_len);
1306    strlcat(cert_params, csp->http->host,         cert_params_len);
1307    strlcat(cert_params, CERT_PARAM_ORG_UNIT,     cert_params_len);
1308    strlcat(cert_params, csp->http->host,         cert_params_len);
1309    strlcat(cert_params, CERT_PARAM_COUNTRY,      cert_params_len);
1310
1311    cert_opt.issuer_crt = csp->config->ca_cert_file;
1312    cert_opt.issuer_key = csp->config->ca_key_file;
1313    cert_opt.subject_key = make_certs_path(csp->config->certificate_directory,
1314       (const char *)csp->http->hash_of_host_hex, KEY_FILE_TYPE);
1315    cert_opt.output_file = make_certs_path(csp->config->certificate_directory,
1316       (const char *)csp->http->hash_of_host_hex, CERT_FILE_TYPE);
1317
1318    if (cert_opt.subject_key == NULL || cert_opt.output_file == NULL)
1319    {
1320       ret = -1;
1321       goto exit;
1322    }
1323
1324    cert_opt.subject_pwd   = CERT_SUBJECT_PASSWORD;
1325    cert_opt.issuer_pwd    = csp->config->ca_password;
1326    cert_opt.subject_name  = cert_params;
1327    cert_opt.not_before    = GENERATED_CERT_VALID_FROM;
1328    cert_opt.not_after     = GENERATED_CERT_VALID_TO;
1329    cert_opt.serial        = serial_num_text;
1330    cert_opt.is_ca         = 0;
1331    cert_opt.max_pathlen   = -1;
1332
1333    /*
1334     * Test if certificate exists and private key was already created
1335     */
1336    if (file_exists(cert_opt.output_file) == 1 && subject_key_len == 0)
1337    {
1338       ret = 0;
1339       goto exit;
1340    }
1341
1342    /*
1343     * Seed the PRNG
1344     */
1345    ret = seed_rng(csp);
1346    if (ret != 0)
1347    {
1348       ret = -1;
1349       goto exit;
1350    }
1351
1352    /*
1353     * Parse serial to MPI
1354     */
1355    ret = mbedtls_mpi_read_string(&serial, 10, cert_opt.serial);
1356    if (ret != 0)
1357    {
1358       mbedtls_strerror(ret, err_buf, sizeof(err_buf));
1359       log_error(LOG_LEVEL_ERROR,
1360          "mbedtls_mpi_read_string failed: %s", err_buf);
1361       ret = -1;
1362       goto exit;
1363    }
1364
1365    /*
1366     * Loading certificates
1367     */
1368    ret = mbedtls_x509_crt_parse_file(&issuer_cert, cert_opt.issuer_crt);
1369    if (ret != 0)
1370    {
1371       mbedtls_strerror(ret, err_buf, sizeof(err_buf));
1372       log_error(LOG_LEVEL_ERROR, "Loading issuer certificate %s failed: %s",
1373          cert_opt.issuer_crt, err_buf);
1374       ret = -1;
1375       goto exit;
1376    }
1377
1378    ret = mbedtls_x509_dn_gets(cert_opt.issuer_name,
1379       sizeof(cert_opt.issuer_name), &issuer_cert.subject);
1380    if (ret < 0)
1381    {
1382       mbedtls_strerror( ret, err_buf, sizeof(err_buf));
1383       log_error(LOG_LEVEL_ERROR, "mbedtls_x509_dn_gets failed: %s", err_buf);
1384       ret = -1;
1385       goto exit;
1386    }
1387
1388    /*
1389     * Loading keys from file or from buffer
1390     */
1391    if (key_buf != NULL && subject_key_len > 0)
1392    {
1393       /* Key was created in this function and is stored in buffer */
1394       ret = mbedtls_pk_parse_key(&loaded_subject_key, key_buf,
1395          (size_t)(subject_key_len + 1), (unsigned const char *)
1396          cert_opt.subject_pwd, strlen(cert_opt.subject_pwd));
1397    }
1398    else
1399    {
1400       /* Key wasn't created in this function, because it already existed */
1401       ret = mbedtls_pk_parse_keyfile(&loaded_subject_key,
1402          cert_opt.subject_key, cert_opt.subject_pwd);
1403    }
1404
1405    if (ret != 0)
1406    {
1407       mbedtls_strerror(ret, err_buf, sizeof(err_buf));
1408       log_error(LOG_LEVEL_ERROR, "Parsing subject key %s failed: %s",
1409          cert_opt.subject_key, err_buf);
1410       ret = -1;
1411       goto exit;
1412    }
1413
1414    ret = mbedtls_pk_parse_keyfile(&loaded_issuer_key, cert_opt.issuer_key,
1415       cert_opt.issuer_pwd);
1416    if (ret != 0)
1417    {
1418       mbedtls_strerror(ret, err_buf, sizeof(err_buf));
1419       log_error(LOG_LEVEL_ERROR,
1420          "Parsing issuer key %s failed: %s", cert_opt.issuer_key, err_buf);
1421       ret = -1;
1422       goto exit;
1423    }
1424
1425    /*
1426     * Check if key and issuer certificate match
1427     */
1428    if (!mbedtls_pk_can_do(&issuer_cert.pk, MBEDTLS_PK_RSA) ||
1429       mbedtls_mpi_cmp_mpi(&mbedtls_pk_rsa(issuer_cert.pk)->N,
1430          &mbedtls_pk_rsa(*issuer_key)->N) != 0 ||
1431       mbedtls_mpi_cmp_mpi( &mbedtls_pk_rsa(issuer_cert.pk)->E,
1432          &mbedtls_pk_rsa(*issuer_key )->E) != 0)
1433    {
1434       log_error(LOG_LEVEL_ERROR,
1435          "Issuer key doesn't match issuer certificate");
1436       ret = -1;
1437       goto exit;
1438    }
1439
1440    mbedtls_x509write_crt_set_subject_key(&cert, subject_key);
1441    mbedtls_x509write_crt_set_issuer_key(&cert, issuer_key);
1442
1443    /*
1444     * Setting parameters of signed certificate
1445     */
1446    ret = mbedtls_x509write_crt_set_subject_name(&cert, cert_opt.subject_name);
1447    if (ret != 0)
1448    {
1449       mbedtls_strerror( ret, err_buf, sizeof(err_buf));
1450       log_error(LOG_LEVEL_ERROR,
1451          "Setting subject name in signed certificate failed: %s", err_buf);
1452       ret = -1;
1453       goto exit;
1454    }
1455
1456    ret = mbedtls_x509write_crt_set_issuer_name(&cert, cert_opt.issuer_name);
1457    if (ret != 0)
1458    {
1459       mbedtls_strerror( ret, err_buf, sizeof(err_buf));
1460       log_error(LOG_LEVEL_ERROR,
1461          "Setting issuer name in signed certificate failed: %s", err_buf);
1462       ret = -1;
1463       goto exit;
1464    }
1465
1466    ret = mbedtls_x509write_crt_set_serial(&cert, &serial);
1467    if (ret != 0)
1468    {
1469       mbedtls_strerror(ret, err_buf, sizeof(err_buf));
1470       log_error(LOG_LEVEL_ERROR,
1471          "Setting serial number in signed certificate failed: %s", err_buf);
1472       ret = -1;
1473       goto exit;
1474    }
1475
1476    ret = mbedtls_x509write_crt_set_validity(&cert, cert_opt.not_before,
1477       cert_opt.not_after);
1478    if (ret != 0)
1479    {
1480       mbedtls_strerror( ret, err_buf, sizeof(err_buf));
1481       log_error(LOG_LEVEL_ERROR,
1482          "Setting validity in signed certificate failed: %s", err_buf);
1483       ret = -1;
1484       goto exit;
1485    }
1486
1487    /*
1488     * Setting the basicConstraints extension for certificate
1489     */
1490    ret = mbedtls_x509write_crt_set_basic_constraints(&cert, cert_opt.is_ca,
1491       cert_opt.max_pathlen);
1492    if (ret != 0)
1493    {
1494       mbedtls_strerror( ret, err_buf, sizeof(err_buf));
1495       log_error(LOG_LEVEL_ERROR, "Setting the basicConstraints extension "
1496          "in signed certificate failed: %s", err_buf);
1497       ret = -1;
1498       goto exit;
1499    }
1500
1501 #if defined(MBEDTLS_SHA1_C)
1502    /* Setting the subjectKeyIdentifier extension for certificate */
1503    ret = mbedtls_x509write_crt_set_subject_key_identifier(&cert);
1504    if (ret != 0)
1505    {
1506       mbedtls_strerror( ret, err_buf, sizeof(err_buf));
1507       log_error(LOG_LEVEL_ERROR, "mbedtls_x509write_crt_set_subject_key_"
1508          "identifier failed: %s", err_buf);
1509       ret = -1;
1510       goto exit;
1511    }
1512
1513    /* Setting the authorityKeyIdentifier extension for certificate */
1514    ret = mbedtls_x509write_crt_set_authority_key_identifier(&cert);
1515    if (ret != 0)
1516    {
1517       mbedtls_strerror( ret, err_buf, sizeof(err_buf));
1518       log_error(LOG_LEVEL_ERROR, "mbedtls_x509write_crt_set_authority_key_"
1519          "identifier failed: %s", err_buf);
1520       ret = -1;
1521       goto exit;
1522    }
1523 #endif /* MBEDTLS_SHA1_C */
1524
1525    /*
1526     * Writing certificate into file
1527     */
1528    ret = write_certificate(&cert, cert_opt.output_file,
1529       mbedtls_ctr_drbg_random, &ctr_drbg);
1530    if (ret < 0)
1531    {
1532       log_error(LOG_LEVEL_ERROR, "Writing certificate into file failed");
1533       goto exit;
1534    }
1535
1536 exit:
1537    /*
1538     * Freeing used structures
1539     */
1540    mbedtls_x509write_crt_free(&cert);
1541    mbedtls_pk_free(&loaded_subject_key);
1542    mbedtls_pk_free(&loaded_issuer_key);
1543    mbedtls_mpi_free(&serial);
1544    mbedtls_x509_crt_free(&issuer_cert);
1545
1546    freez(cert_opt.subject_key);
1547    freez(cert_opt.output_file);
1548    freez(key_buf);
1549
1550    return ret;
1551 }
1552
1553
1554 /*********************************************************************
1555  *
1556  * Function    :  make_certs_path
1557  *
1558  * Description : Creates path to file from three pieces. This fuction
1559  *               takes parameters and puts them in one new mallocated
1560  *               char * in correct order. Returned variable must be freed
1561  *               by caller. This function is mainly used for creating
1562  *               paths of certificates and keys files.
1563  *
1564  * Parameters  :
1565  *          1  :  conf_dir  = Name/path of directory where is the file.
1566  *                            '.' can be used for current directory.
1567  *          2  :  file_name = Name of file in conf_dir without suffix.
1568  *          3  :  suffix    = Suffix of given file_name.
1569  *
1570  * Returns     :  path => Path was built up successfully
1571  *                NULL => Path can't be built up
1572  *
1573  *********************************************************************/
1574 static char *make_certs_path(const char *conf_dir, const char *file_name,
1575    const char *suffix)
1576 {
1577    /* Test if all given parameters are valid */
1578    if (conf_dir == NULL || *conf_dir == '\0' || file_name == NULL ||
1579       *file_name == '\0' || suffix == NULL || *suffix == '\0')
1580    {
1581       log_error(LOG_LEVEL_ERROR,
1582          "make_certs_path failed: bad input parameters");
1583       return NULL;
1584    }
1585
1586    char *path = NULL;
1587    size_t path_size = strlen(conf_dir)
1588       + strlen(file_name) + strlen(suffix) + 2;
1589
1590    /* Setting delimiter and editing path length */
1591 #if defined(_WIN32) || defined(__OS2__)
1592    char delim[] = "\\";
1593    path_size += 1;
1594 #else /* ifndef _WIN32 || __OS2__ */
1595    char delim[] = "/";
1596 #endif /* ifndef _WIN32 || __OS2__ */
1597
1598    /*
1599     * Building up path from many parts
1600     */
1601 #if defined(unix)
1602    if (*conf_dir != '/' && basedir && *basedir)
1603    {
1604       /*
1605        * Replacing conf_dir with basedir. This new variable contains
1606        * absolute path to cwd.
1607        */
1608       path_size += strlen(basedir) + 2;
1609       path = (char *)malloc(path_size);
1610       if (path == NULL)
1611       {
1612          log_error(LOG_LEVEL_ERROR, "make_certs_path failed: malloc fail");
1613          return NULL;
1614       }
1615       memset(path, 0, path_size);
1616
1617       strlcpy(path, basedir,   path_size);
1618       strlcat(path, delim,     path_size);
1619       strlcat(path, conf_dir,  path_size);
1620       strlcat(path, delim,     path_size);
1621       strlcat(path, file_name, path_size);
1622       strlcat(path, suffix,    path_size);
1623    }
1624    else
1625 #endif /* defined unix */
1626    {
1627       path = (char *)malloc(path_size);
1628       if (path == NULL)
1629       {
1630          log_error(LOG_LEVEL_ERROR, "make_certs_path failed: malloc fail");
1631          return NULL;
1632       }
1633       memset(path, 0, path_size);
1634
1635       strlcpy(path, conf_dir,  path_size);
1636       strlcat(path, delim,     path_size);
1637       strlcat(path, file_name, path_size);
1638       strlcat(path, suffix,    path_size);
1639    }
1640
1641    return path;
1642 }
1643
1644
1645 /*********************************************************************
1646  *
1647  * Function    :  get_certificate_mutex_id
1648  *
1649  * Description :  Computes mutex id from host name hash. This hash must
1650  *                be already saved in csp structure
1651  *
1652  * Parameters  :
1653  *          1  :  csp = Current client state (buffers, headers, etc...)
1654  *
1655  * Returns     :  Mutex id for given host name
1656  *
1657  *********************************************************************/
1658 static unsigned int get_certificate_mutex_id(struct client_state *csp) {
1659 #ifdef LIMIT_MUTEX_NUMBER
1660    return (unsigned int)(csp->http->hash_of_host[0] % 32);
1661 #else
1662    return (unsigned int)(csp->http->hash_of_host[1]
1663       + 256 * (int)csp->http->hash_of_host[0]);
1664 #endif /* LIMIT_MUTEX_NUMBER */
1665 }
1666
1667
1668 /*********************************************************************
1669  *
1670  * Function    :  get_certificate_serial
1671  *
1672  * Description :  Computes serial number for new certificate from host
1673  *                name hash. This hash must be already saved in csp
1674  *                structure.
1675  *
1676  * Parameters  :
1677  *          1  :  csp = Current client state (buffers, headers, etc...)
1678  *
1679  * Returns     :  Serial number for new certificate
1680  *
1681  *********************************************************************/
1682 static unsigned long  get_certificate_serial(struct client_state *csp) {
1683    unsigned long exp    = 1;
1684    unsigned long serial = 0;
1685
1686    int i = CERT_SERIAL_NUM_LENGTH;
1687    /* Length of hash is 16 bytes, we must avoid to read next chars */
1688    if (i > 16)
1689    {
1690       i = 16;
1691    }
1692    if (i < 2)
1693    {
1694       i = 2;
1695    }
1696
1697    for (; i >= 0; i--)
1698    {
1699       serial += exp * (unsigned)csp->http->hash_of_host[i];
1700       exp *= 256;
1701    }
1702    return serial;
1703 }
1704
1705
1706 /*********************************************************************
1707  *
1708  * Function    :  ssl_send_certificate_error
1709  *
1710  * Description :  Sends info about invalid server certificate to client.
1711  *                Sent message is including all trusted chain certificates,
1712  *                that can be downloaded in web browser.
1713  *
1714  * Parameters  :
1715  *          1  :  csp = Current client state (buffers, headers, etc...)
1716  *
1717  * Returns     :  N/A
1718  *
1719  *********************************************************************/
1720 extern void ssl_send_certificate_error(struct client_state *csp)
1721 {
1722    size_t message_len = 0;
1723    int ret = 0;
1724    struct certs_chain *cert = NULL;
1725
1726    /* Header of message with certificate informations */
1727    const char message_begin[] =
1728       "HTTP/1.1 200 OK\r\n"
1729       "Content-Type: text/html\r\n"
1730       "Connection: close\r\n\r\n"
1731       "<html><body><h1>Invalid server certificate</h1><p>Reason: ";
1732    const char message_end[] = "</body></html>\r\n\r\n";
1733    char reason[INVALID_CERT_INFO_BUF_SIZE];
1734    memset(reason, 0, sizeof(reason));
1735
1736    /* Get verification message from verification return code */
1737    mbedtls_x509_crt_verify_info(reason, sizeof(reason), " ",
1738       csp->server_cert_verification_result);
1739
1740    /*
1741     * Computing total length of message with all certificates inside
1742     */
1743    message_len = strlen(message_begin) + strlen(message_end)
1744                  + strlen(reason) + strlen("</p>") + 1;
1745
1746    cert = &(csp->server_certs_chain);
1747    while (cert->next != NULL)
1748    {
1749       size_t base64_len = 4 * ((strlen(cert->file_buf) + 2) / 3) + 1;
1750
1751       message_len += strlen(cert->text_buf) + strlen("<pre></pre>\n")
1752                      +  base64_len + strlen("<a href=\"data:application"
1753                         "/x-x509-ca-cert;base64,\">Download certificate</a>");
1754       cert = cert->next;
1755    }
1756
1757    /*
1758     * Joining all blocks in one long message
1759     */
1760    char message[message_len];
1761    memset(message, 0, message_len);
1762
1763    strlcpy(message, message_begin, message_len);
1764    strlcat(message, reason       , message_len);
1765    strlcat(message, "</p>"       , message_len);
1766
1767    cert = &(csp->server_certs_chain);
1768    while (cert->next != NULL)
1769    {
1770       size_t olen = 0;
1771       size_t base64_len = 4 * ((strlen(cert->file_buf) + 2) / 3) + 1; /* +1 for terminating null*/
1772       char base64_buf[base64_len];
1773       memset(base64_buf, 0, base64_len);
1774
1775       /* Encoding certificate into base64 code */
1776       ret = mbedtls_base64_encode((unsigned char*)base64_buf,
1777                base64_len, &olen, (const unsigned char*)cert->file_buf,
1778                strlen(cert->file_buf));
1779       if (ret != 0)
1780       {
1781          log_error(LOG_LEVEL_ERROR,
1782             "Encoding to base64 failed, buffer is to small");
1783       }
1784
1785       strlcat(message, "<pre>",        message_len);
1786       strlcat(message, cert->text_buf, message_len);
1787       strlcat(message, "</pre>\n",     message_len);
1788
1789       if (ret == 0)
1790       {
1791          strlcat(message, "<a href=\"data:application/x-x509-ca-cert;base64,",
1792             message_len);
1793          strlcat(message, base64_buf, message_len);
1794          strlcat(message, "\">Download certificate</a>", message_len);
1795       }
1796
1797       cert = cert->next;
1798    }
1799    strlcat(message, message_end, message_len);
1800
1801    /*
1802     * Sending final message to client
1803     */
1804    ssl_send_data(&(csp->mbedtls_client_attr.ssl),
1805       (const unsigned char *)message, strlen(message));
1806    /*
1807     * Waiting before closing connection. Some browsers doesn't show received
1808     * message if there isn't this delay.
1809     */
1810    sleep(1);
1811
1812    free_certificate_chain(csp);
1813 }
1814
1815
1816 /*********************************************************************
1817  *
1818  * Function    :  ssl_verify_callback
1819  *
1820  * Description :  This is a callback function for certificate verification.
1821  *                It's called for all certificates in server certificate
1822  *                trusted chain and it's preparing information about this
1823  *                certificates. Prepared informations can be used to inform
1824  *                user about invalid certificates.
1825  *
1826  * Parameters  :
1827  *          1  :  csp_void = Current client state (buffers, headers, etc...)
1828  *          2  :  crt   = certificate from trusted chain
1829  *          3  :  depth = depth in trusted chain
1830  *          4  :  flags = certificate flags
1831  *
1832  * Returns     :  0 on success and negative value on error
1833  *
1834  *********************************************************************/
1835 static int ssl_verify_callback(void *csp_void, mbedtls_x509_crt *crt,
1836    int depth, uint32_t *flags)
1837 {
1838    struct client_state *csp  = (struct client_state *)csp_void;
1839    struct certs_chain  *last = &(csp->server_certs_chain);
1840    size_t olen = 0;
1841    int ret = 0;
1842
1843    /*
1844     * Searching for last item in certificates linked list
1845     */
1846    while (last->next != NULL)
1847    {
1848       last = last->next;
1849    }
1850
1851    /*
1852     * Preparing next item in linked list for next certificate
1853     * If malloc fails, we are continuing without this certificate
1854     */
1855    last->next = (struct certs_chain *)malloc(sizeof(struct certs_chain));
1856    if (last->next != NULL)
1857    {
1858       last->next->next = NULL;
1859       memset(last->next->text_buf, 0, sizeof(last->next->text_buf));
1860       memset(last->next->file_buf, 0, sizeof(last->next->file_buf));
1861
1862       /*
1863        * Saving certificate file into buffer
1864        */
1865       if ((ret = mbedtls_pem_write_buffer(PEM_BEGIN_CRT, PEM_END_CRT,
1866          crt->raw.p, crt->raw.len, (unsigned char *)last->file_buf,
1867          sizeof(last->file_buf)-1, &olen)) != 0)
1868       {
1869          return(ret);
1870       }
1871
1872       /*
1873        * Saving certificate information into buffer
1874        */
1875       mbedtls_x509_crt_info(last->text_buf, sizeof(last->text_buf) - 1,
1876          CERT_INFO_PREFIX, crt);
1877    }
1878    else
1879    {
1880       log_error(LOG_LEVEL_ERROR,
1881          "Malloc memory for server certificate informations failed");
1882       return -1;
1883    }
1884
1885    return 0;
1886 }
1887
1888
1889 /*********************************************************************
1890  *
1891  * Function    :  free_certificate_chain
1892  *
1893  * Description :  Frees certificates linked list. This linked list is
1894  *                used to save informations about certificates in
1895  *                trusted chain.
1896  *
1897  * Parameters  :
1898  *          1  :  csp = Current client state (buffers, headers, etc...)
1899  *
1900  * Returns     :  N/A
1901  *
1902  *********************************************************************/
1903 static void free_certificate_chain(struct client_state *csp)
1904 {
1905    struct certs_chain *cert = csp->server_certs_chain.next;
1906
1907    /* Cleaning buffers */
1908    memset(csp->server_certs_chain.text_buf, 0,
1909       sizeof(csp->server_certs_chain.text_buf));
1910    memset(csp->server_certs_chain.text_buf, 0,
1911       sizeof(csp->server_certs_chain.file_buf));
1912    csp->server_certs_chain.next = NULL;
1913
1914    /* Freeing memory in whole linked list */
1915    if (cert != NULL)
1916    {
1917       do
1918       {
1919          struct certs_chain *cert_for_free = cert;
1920          cert = cert->next;
1921          freez(cert_for_free);
1922       } while (cert != NULL);
1923    }
1924 }
1925
1926
1927 /*********************************************************************
1928 *
1929 * Function    :  file_exists
1930 *
1931 * Description :  Tests if file exists and is readable.
1932 *
1933 * Parameters  :
1934 *          1  :  path = Path to tested file.
1935 *
1936 * Returns     :  1 => File exists and is readable.
1937 *                0 => File doesn't exist or is not readable.
1938 *
1939 *********************************************************************/
1940 static int file_exists(const char *path)
1941 {
1942    FILE *f;
1943    if ((f = fopen(path, "r")) != NULL)
1944    {
1945       fclose(f);
1946       return 1;
1947    }
1948
1949    return 0;
1950 }
1951
1952
1953 /*********************************************************************
1954  *
1955  * Function    :  host_to_hash
1956  *
1957  * Description :  Creates MD5 hash from host name. Host name is loaded
1958  *                from structure csp and saved again into it.
1959  *
1960  * Parameters  :
1961  *          1  :  csp = Current client state (buffers, headers, etc...)
1962  *
1963  * Returns     :  1 => Error while creating hash
1964  *                0 => Hash created successfully
1965  *
1966  *********************************************************************/
1967 static int host_to_hash(struct client_state * csp)
1968 {
1969    int ret = 0;
1970
1971 #if !defined(MBEDTLS_MD5_C)
1972    log_error(LOG_LEVEL_ERROR, "MBEDTLS_MD5_C is not defined. Can't create"
1973       "MD5 hash for certificate and key name.");
1974    return -1;
1975 #else
1976    memset(csp->http->hash_of_host, 0, sizeof(csp->http->hash_of_host));
1977    mbedtls_md5((unsigned char *)csp->http->host, strlen(csp->http->host),
1978       csp->http->hash_of_host);
1979
1980    /* Converting hash into string with hex */
1981    size_t i = 0;
1982    for (; i < 16; i++)
1983    {
1984       if ((ret = sprintf((char *)csp->http->hash_of_host_hex + 2 * i, "%02x",
1985          csp->http->hash_of_host[i])) < 0)
1986       {
1987          log_error(LOG_LEVEL_ERROR, "Sprintf return value: %d", ret);
1988          return -1;
1989       }
1990    }
1991
1992    return 0;
1993 #endif /* MBEDTLS_MD5_C */
1994 }
1995
1996
1997 /*********************************************************************
1998  *
1999  * Function    :  tunnel_established_successfully
2000  *
2001  * Description :  Check if parent proxy server response contains
2002  *                informations about successfully created connection with
2003  *                destination server. (HTTP/... 2xx ...)
2004  *
2005  * Parameters  :
2006  *          1  :  server_response = Buffer with parent proxy server response
2007  *          2  :  response_len = Length of server_response
2008  *
2009  * Returns     :  1 => Connection created successfully
2010  *                0 => Connection wasn't created successfully
2011  *
2012  *********************************************************************/
2013 extern int tunnel_established_successfully(const char *server_response,
2014    unsigned int response_len)
2015 {
2016    unsigned int pos = 0;
2017
2018    if (server_response == NULL)
2019    {
2020       return 0;
2021    }
2022
2023    /* Tests if "HTTP/" string is at the begin of received response */
2024    if (strncmp(server_response, "HTTP/", 5) != 0)
2025    {
2026       return 0;
2027    }
2028
2029    for (pos = 0; pos < response_len; pos++)
2030    {
2031       if (server_response[pos] == ' ')
2032       {
2033          break;
2034       }
2035    }
2036
2037    /*
2038     * response_len -3 because of buffer end, response structure and 200 code.
2039     * There must be at least 3 chars after space.
2040     * End of buffer: ... 2xx'\0'
2041     *             pos = |
2042     */
2043    if (pos >= (response_len - 3))
2044    {
2045       return 0;
2046    }
2047
2048    /* Test HTTP status code */
2049    if (server_response[pos + 1] != '2')
2050    {
2051       return 0;
2052    }
2053
2054    return 1;
2055 }
2056
2057
2058 /*********************************************************************
2059  *
2060  * Function    :  seed_rng
2061  *
2062  * Description :  Seeding the RNG for all SSL uses
2063  *
2064  * Parameters  :
2065  *          1  :  csp = Current client state (buffers, headers, etc...)
2066  *
2067  * Returns     : -1 => RNG wasn't seed successfully
2068  *                0 => RNG is seeded successfully
2069  *
2070  *********************************************************************/
2071 static int seed_rng(struct client_state *csp)
2072 {
2073    int ret = 0;
2074    char err_buf[ERROR_BUF_SIZE];
2075
2076    memset(err_buf, 0, sizeof(err_buf));
2077
2078    if (rng_seeded == 0)
2079    {
2080       privoxy_mutex_lock(&rng_mutex);
2081       if (rng_seeded == 0)
2082       {
2083          mbedtls_ctr_drbg_init(&ctr_drbg);
2084          mbedtls_entropy_init(&entropy);
2085          ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func,
2086             &entropy, NULL, 0);
2087          if (ret != 0)
2088          {
2089             mbedtls_strerror(ret, err_buf, sizeof(err_buf));
2090             log_error(LOG_LEVEL_ERROR,
2091                "mbedtls_ctr_drbg_seed failed: %s", err_buf);
2092             privoxy_mutex_unlock(&rng_mutex);
2093             return -1;
2094          }
2095          rng_seeded = 1;
2096       }
2097       privoxy_mutex_unlock(&rng_mutex);
2098    }
2099    return 0;
2100 }