privoxy-log-parser: Highlight 'Keeping chunk offset at 0 despite flushing 31 bytes.'
[privoxy.git] / wolfssl.c
1 /*********************************************************************
2  *
3  * File        :  $Source: /cvsroot/ijbswa/current/wolfssl.c,v $
4  *
5  * Purpose     :  File with TLS/SSL extension. Contains methods for
6  *                creating, using and closing TLS/SSL connections
7  *                using wolfSSL.
8  *
9  * Copyright   :  Copyright (C) 2018-2021 by Fabian Keil <fk@fabiankeil.de>
10  *                Copyright (C) 2020 Maxim Antonov <mantonov@gmail.com>
11  *                Copyright (C) 2017 Vaclav Svec. FIT CVUT.
12  *
13  *                This program is free software; you can redistribute it
14  *                and/or modify it under the terms of the GNU General
15  *                Public License as published by the Free Software
16  *                Foundation; either version 2 of the License, or (at
17  *                your option) any later version.
18  *
19  *                This program is distributed in the hope that it will
20  *                be useful, but WITHOUT ANY WARRANTY; without even the
21  *                implied warranty of MERCHANTABILITY or FITNESS FOR A
22  *                PARTICULAR PURPOSE.  See the GNU General Public
23  *                License for more details.
24  *
25  *                The GNU General Public License should be included with
26  *                this file.  If not, you can view it at
27  *                http://www.gnu.org/copyleft/gpl.html
28  *                or write to the Free Software Foundation, Inc., 59
29  *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
30  *
31  *********************************************************************/
32
33 #include <string.h>
34 #include <unistd.h>
35 #include <assert.h>
36 #include "config.h"
37
38 #include <wolfssl/options.h>
39 #include <wolfssl/openssl/x509v3.h>
40 #include <wolfssl/ssl.h>
41 #include <wolfssl/wolfcrypt/coding.h>
42 #include <wolfssl/wolfcrypt/rsa.h>
43
44 #include "project.h"
45 #include "miscutil.h"
46 #include "errlog.h"
47 #include "encode.h"
48 #include "jcc.h"
49 #include "jbsockets.h"
50 #include "ssl.h"
51 #include "ssl_common.h"
52
53 static int ssl_certificate_is_invalid(const char *cert_file);
54 static int generate_host_certificate(struct client_state *csp,
55    const char *certificate_path, const char *key_path);
56 static void free_client_ssl_structures(struct client_state *csp);
57 static void free_server_ssl_structures(struct client_state *csp);
58 static int ssl_store_cert(struct client_state *csp, X509 *crt);
59 static void log_ssl_errors(int debuglevel, const char* fmt, ...) __attribute__((format(printf, 2, 3)));
60
61 static int wolfssl_initialized = 0;
62
63 /*
64  * Whether or not sharing the RNG is thread-safe
65  * doesn't matter because we only use it with
66  * the certificate_mutex locked.
67  */
68 static RNG wolfssl_rng;
69
70 #ifndef WOLFSSL_ALT_CERT_CHAINS
71 /*
72  * Without WOLFSSL_ALT_CERT_CHAINS wolfSSL will reject valid
73  * certificates if the certificate chain contains CA certificates
74  * that are "only" signed by trusted CA certificates but aren't
75  * trusted CAs themselves.
76  */
77 #warning wolfSSL has been compiled without WOLFSSL_ALT_CERT_CHAINS
78 #endif
79
80 /*********************************************************************
81  *
82  * Function    :  wolfssl_init
83  *
84  * Description :  Initializes wolfSSL library once
85  *
86  * Parameters  :  N/A
87  *
88  * Returns     :  N/A
89  *
90  *********************************************************************/
91 static void wolfssl_init(void)
92 {
93    if (wolfssl_initialized == 0)
94    {
95       privoxy_mutex_lock(&ssl_init_mutex);
96       if (wolfssl_initialized == 0)
97       {
98          if (wolfSSL_Init() != WOLFSSL_SUCCESS)
99          {
100             log_error(LOG_LEVEL_FATAL, "Failed to initialize wolfSSL");
101          }
102          wc_InitRng(&wolfssl_rng);
103          wolfssl_initialized = 1;
104       }
105       privoxy_mutex_unlock(&ssl_init_mutex);
106    }
107 }
108
109
110 /*********************************************************************
111  *
112  * Function    :  is_ssl_pending
113  *
114  * Description :  Tests if there are some waiting data on ssl connection.
115  *                Only considers data that has actually been received
116  *                locally and ignores data that is still on the fly
117  *                or has not yet been sent by the remote end.
118  *
119  * Parameters  :
120  *          1  :  ssl_attr = SSL context to test
121  *
122  * Returns     :   0 => No data are pending
123  *                >0 => Pending data length. XXX: really?
124  *
125  *********************************************************************/
126 extern size_t is_ssl_pending(struct ssl_attr *ssl_attr)
127 {
128    return (size_t)wolfSSL_pending(ssl_attr->wolfssl_attr.ssl);
129 }
130
131
132 /*********************************************************************
133  *
134  * Function    :  ssl_send_data
135  *
136  * Description :  Sends the content of buf (for n bytes) to given SSL
137  *                connection context.
138  *
139  * Parameters  :
140  *          1  :  ssl_attr = SSL context to send data to
141  *          2  :  buf = Pointer to data to be sent
142  *          3  :  len = Length of data to be sent to the SSL context
143  *
144  * Returns     :  Length of sent data or negative value on error.
145  *
146  *********************************************************************/
147 extern int ssl_send_data(struct ssl_attr *ssl_attr, const unsigned char *buf, size_t len)
148 {
149    WOLFSSL *ssl;
150    int ret = 0;
151    int pos = 0; /* Position of unsent part in buffer */
152    int fd = -1;
153
154    if (len == 0)
155    {
156       return 0;
157    }
158
159    ssl = ssl_attr->wolfssl_attr.ssl;
160    fd = wolfSSL_get_fd(ssl);
161
162    while (pos < len)
163    {
164       int send_len = (int)len - pos;
165
166       log_error(LOG_LEVEL_WRITING, "TLS on socket %d: %N",
167          fd, send_len, buf+pos);
168
169       ret = wolfSSL_write(ssl, buf+pos, send_len);
170       if (ret <= 0)
171       {
172          log_ssl_errors(LOG_LEVEL_ERROR,
173             "Sending data on socket %d over TLS failed", fd);
174          return -1;
175       }
176
177       /* Adding count of sent bytes to position in buffer */
178       pos = pos + ret;
179    }
180
181    return (int)len;
182 }
183
184
185 /*********************************************************************
186  *
187  * Function    :  ssl_recv_data
188  *
189  * Description :  Receives data from given SSL context and puts
190  *                it into buffer.
191  *
192  * Parameters  :
193  *          1  :  ssl_attr = SSL context to receive data from
194  *          2  :  buf = Pointer to buffer where data will be written
195  *          3  :  max_length = Maximum number of bytes to read
196  *
197  * Returns     :  Number of bytes read, 0 for EOF, or -1
198  *                on error.
199  *
200  *********************************************************************/
201 extern int ssl_recv_data(struct ssl_attr *ssl_attr, unsigned char *buf, size_t max_length)
202 {
203    WOLFSSL *ssl;
204    int ret = 0;
205    int fd = -1;
206
207    memset(buf, 0, max_length);
208
209    /*
210     * Receiving data from SSL context into buffer
211     */
212    ssl = ssl_attr->wolfssl_attr.ssl;
213    ret = wolfSSL_read(ssl, buf, (int)max_length);
214    fd = wolfSSL_get_fd(ssl);
215
216    if (ret < 0)
217    {
218       log_ssl_errors(LOG_LEVEL_ERROR,
219          "Receiving data on socket %d over TLS failed", fd);
220
221       return -1;
222    }
223
224    log_error(LOG_LEVEL_RECEIVED, "TLS from socket %d: %N",
225       fd, ret, buf);
226
227    return ret;
228 }
229
230
231 /*********************************************************************
232  *
233  * Function    :  get_public_key_size_string
234  *
235  * Description : Translates a public key type to a string.
236  *
237  * Parameters  :
238  *          1  :  key_type = The public key type.
239  *
240  * Returns     :  String containing the translated key size.
241  *
242  *********************************************************************/
243 static const char *get_public_key_size_string(int key_type)
244 {
245    switch (key_type)
246    {
247       case EVP_PKEY_RSA:
248          return "RSA key size";
249       case EVP_PKEY_DSA:
250          return "DSA key size";
251       case EVP_PKEY_EC:
252          return "EC key size";
253       default:
254          return "non-RSA/DSA/EC key size";
255    }
256 }
257
258
259 /*********************************************************************
260  *
261  * Function    :  ssl_store_cert
262  *
263  * Description : This function is called once for each certificate in the
264  *               server's certificate trusted chain and prepares
265  *               information about the certificate. The information can
266  *               be used to inform the user about invalid certificates.
267  *
268  * Parameters  :
269  *          1  :  csp = Current client state (buffers, headers, etc...)
270  *          2  :  cert = certificate from trusted chain
271  *
272  * Returns     :  0 on success and negative value on error
273  *
274  *********************************************************************/
275 static int ssl_store_cert(struct client_state *csp, X509 *cert)
276 {
277    long len;
278    struct certs_chain *last = &(csp->server_certs_chain);
279    int ret = 0;
280    WOLFSSL_BIO *bio = BIO_new(BIO_s_mem());
281    WOLFSSL_EVP_PKEY *pkey = NULL;
282    char *bio_mem_data = NULL;
283    char *encoded_text;
284    long l;
285    unsigned char serial_number[32];
286    int  serial_number_size = sizeof(serial_number);
287    WOLFSSL_X509_NAME *issuer_name;
288    WOLFSSL_X509_NAME *subject_name;
289    char *subject_alternative_name;
290    int loc;
291    int san_prefix_printed = 0;
292
293    if (!bio)
294    {
295       log_ssl_errors(LOG_LEVEL_ERROR, "BIO_new() failed");
296       return -1;
297    }
298
299    /*
300     * Searching for last item in certificates linked list
301     */
302    while (last->next != NULL)
303    {
304       last = last->next;
305    }
306
307    /*
308     * Preparing next item in linked list for next certificate
309     */
310    last->next = zalloc_or_die(sizeof(struct certs_chain));
311
312    /*
313     * Saving certificate file into buffer
314     */
315    if (wolfSSL_PEM_write_bio_X509(bio, cert) != WOLFSSL_SUCCESS)
316    {
317       log_ssl_errors(LOG_LEVEL_ERROR, "wolfSSL_PEM_write_bio_X509() failed");
318       ret = -1;
319       goto exit;
320    }
321
322    len = wolfSSL_BIO_get_mem_data(bio, &bio_mem_data);
323    last->file_buf = malloc((size_t)len + 1);
324    if (last->file_buf == NULL)
325    {
326       log_error(LOG_LEVEL_ERROR,
327          "Failed to allocate %lu bytes to store the X509 PEM certificate",
328          len + 1);
329       ret = -1;
330       goto exit;
331    }
332
333    strncpy(last->file_buf, bio_mem_data, (size_t)len);
334    last->file_buf[len] = '\0';
335    wolfSSL_BIO_free(bio);
336    bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem());
337    if (!bio)
338    {
339       log_ssl_errors(LOG_LEVEL_ERROR, "wolfSSL_BIO_new() failed");
340       ret = -1;
341       goto exit;
342    }
343
344    /*
345     * Saving certificate information into buffer
346     */
347    l = wolfSSL_X509_get_version(cert);
348    if (l >= 0 && l <= 2)
349    {
350       if (wolfSSL_BIO_printf(bio, "cert. version     : %ld\n", l + 1) <= 0)
351       {
352          log_ssl_errors(LOG_LEVEL_ERROR,
353             "wolfSSL_BIO_printf() for version failed");
354          ret = -1;
355          goto exit;
356       }
357    }
358    else
359    {
360       if (wolfSSL_BIO_printf(bio, "cert. version     : Unknown (%ld)\n", l) <= 0)
361       {
362          log_ssl_errors(LOG_LEVEL_ERROR,
363             "wolfSSL_BIO_printf() for version failed");
364          ret = -1;
365          goto exit;
366       }
367    }
368
369    if (wolfSSL_BIO_puts(bio, "serial number     : ") <= 0)
370    {
371       log_ssl_errors(LOG_LEVEL_ERROR,
372          "wolfSSL_BIO_puts() for serial number failed");
373       ret = -1;
374       goto exit;
375    }
376    if (wolfSSL_X509_get_serial_number(cert, serial_number, &serial_number_size)
377       != WOLFSSL_SUCCESS)
378    {
379       log_error(LOG_LEVEL_ERROR, "wolfSSL_X509_get_serial_number() failed");
380       ret = -1;
381       goto exit;
382    }
383
384    if (serial_number_size <= (int)sizeof(char))
385    {
386       if (wolfSSL_BIO_printf(bio, "%lu (0x%lx)\n", serial_number[0],
387             serial_number[0]) <= 0)
388       {
389          log_ssl_errors(LOG_LEVEL_ERROR,
390             "wolfSSL_BIO_printf() for serial number as single byte failed");
391          ret = -1;
392          goto exit;
393       }
394    }
395    else
396    {
397       int i;
398       for (i = 0; i < serial_number_size; i++)
399       {
400          if (wolfSSL_BIO_printf(bio, "%02x%c", serial_number[i],
401                ((i + 1 == serial_number_size) ? '\n' : ':')) <= 0)
402          {
403             log_ssl_errors(LOG_LEVEL_ERROR,
404                "wolfSSL_BIO_printf() for serial number bytes failed");
405             ret = -1;
406             goto exit;
407          }
408       }
409    }
410
411    if (wolfSSL_BIO_puts(bio, "issuer name       : ") <= 0)
412    {
413       log_ssl_errors(LOG_LEVEL_ERROR, "wolfSSL_BIO_puts() for issuer failed");
414       ret = -1;
415       goto exit;
416    }
417    issuer_name = wolfSSL_X509_get_issuer_name(cert);
418    if (wolfSSL_X509_NAME_get_sz(issuer_name) <= 0)
419    {
420       if (wolfSSL_BIO_puts(bio, "none") <= 0)
421       {
422          log_ssl_errors(LOG_LEVEL_ERROR,
423             "wolfSSL_BIO_puts() for issuer name failed");
424          ret = -1;
425          goto exit;
426       }
427    }
428    else if (wolfSSL_X509_NAME_print_ex(bio, issuer_name, 0, 0) < 0)
429    {
430       log_ssl_errors(LOG_LEVEL_ERROR,
431          "wolfSSL_X509_NAME_print_ex() for issuer failed");
432       ret = -1;
433       goto exit;
434    }
435
436    if (wolfSSL_BIO_puts(bio, "\nsubject name      : ") <= 0)
437    {
438       log_ssl_errors(LOG_LEVEL_ERROR,
439          "wolfSSL_BIO_puts() for subject name failed");
440       ret = -1;
441       goto exit;
442    }
443    subject_name = wolfSSL_X509_get_subject_name(cert);
444    if (wolfSSL_X509_NAME_get_sz(subject_name) <= 0)
445    {
446       if (wolfSSL_BIO_puts(bio, "none") <= 0)
447       {
448          log_ssl_errors(LOG_LEVEL_ERROR,
449             "wolfSSL_BIO_puts() for subject name failed");
450          ret = -1;
451          goto exit;
452       }
453    }
454    else if (wolfSSL_X509_NAME_print_ex(bio, subject_name, 0, 0) < 0)
455    {
456       log_ssl_errors(LOG_LEVEL_ERROR,
457          "wolfSSL_X509_NAME_print_ex() for subject name failed");
458       ret = -1;
459       goto exit;
460    }
461
462    if (wolfSSL_BIO_puts(bio, "\nissued  on        : ") <= 0)
463    {
464       log_ssl_errors(LOG_LEVEL_ERROR,
465          "wolfSSL_BIO_puts() for issued on failed");
466       ret = -1;
467       goto exit;
468    }
469    if (!wolfSSL_ASN1_TIME_print(bio, wolfSSL_X509_get_notBefore(cert)))
470    {
471       log_ssl_errors(LOG_LEVEL_ERROR,
472          "wolfSSL_ASN1_TIME_print() for issued on failed");
473       ret = -1;
474       goto exit;
475    }
476
477    if (wolfSSL_BIO_puts(bio, "\nexpires on        : ") <= 0)
478    {
479       log_ssl_errors(LOG_LEVEL_ERROR,
480          "wolfSSL_BIO_puts() for expires on failed");
481       ret = -1;
482       goto exit;
483    }
484    if (!wolfSSL_ASN1_TIME_print(bio, wolfSSL_X509_get_notAfter(cert)))
485    {
486       log_ssl_errors(LOG_LEVEL_ERROR,
487          "wolfSSL_ASN1_TIME_print() for expires on failed");
488       ret = -1;
489       goto exit;
490    }
491
492    /* XXX: Show signature algorithm */
493
494    pkey = wolfSSL_X509_get_pubkey(cert);
495    if (!pkey)
496    {
497       log_ssl_errors(LOG_LEVEL_ERROR, "wolfSSL_X509_get_pubkey() failed");
498       ret = -1;
499       goto exit;
500    }
501    ret = wolfSSL_BIO_printf(bio, "\n%-18s: %d bits",
502       get_public_key_size_string(wolfSSL_EVP_PKEY_base_id(pkey)),
503       wolfSSL_EVP_PKEY_bits(pkey));
504    if (ret <= 0)
505    {
506       log_ssl_errors(LOG_LEVEL_ERROR,
507          "wolfSSL_BIO_printf() for key size failed");
508       ret = -1;
509       goto exit;
510    }
511
512    /*
513     * XXX: Show cert usage, etc.
514     */
515    loc = wolfSSL_X509_get_ext_by_NID(cert, NID_basic_constraints, -1);
516    if (loc != -1)
517    {
518       WOLFSSL_X509_EXTENSION *ex = wolfSSL_X509_get_ext(cert, loc);
519       if (BIO_puts(bio, "\nbasic constraints : ") <= 0)
520       {
521          log_ssl_errors(LOG_LEVEL_ERROR,
522             "BIO_printf() for basic constraints failed");
523          ret = -1;
524          goto exit;
525       }
526       if (!wolfSSL_X509V3_EXT_print(bio, ex, 0, 0))
527       {
528          if (!wolfSSL_ASN1_STRING_print_ex(bio,
529                wolfSSL_X509_EXTENSION_get_data(ex),
530                ASN1_STRFLGS_RFC2253))
531          {
532             log_ssl_errors(LOG_LEVEL_ERROR,
533                "wolfSSL_ASN1_STRING_print_ex() for basic constraints failed");
534             ret = -1;
535             goto exit;
536          }
537       }
538    }
539
540    while ((subject_alternative_name = wolfSSL_X509_get_next_altname(cert))
541       != NULL)
542    {
543       if (san_prefix_printed == 0)
544       {
545          ret = wolfSSL_BIO_printf(bio, "\nsubject alt name  : ");
546          san_prefix_printed = 1;
547       }
548       if (ret > 0)
549       {
550          ret = wolfSSL_BIO_printf(bio, "%s ", subject_alternative_name);
551       }
552       if (ret <= 0)
553       {
554          log_ssl_errors(LOG_LEVEL_ERROR,
555             "wolfSSL_BIO_printf() for Subject Alternative Name failed");
556          ret = -1;
557          goto exit;
558       }
559    }
560
561 #if 0
562    /*
563     * This code compiles but does not work because wolfSSL
564     * sets NID_netscape_cert_type to NID_undef.
565     */
566    loc = wolfSSL_X509_get_ext_by_NID(cert, NID_netscape_cert_type, -1);
567    if (loc != -1)
568    {
569       WOLFSSL_X509_EXTENSION *ex = wolfSSL_X509_get_ext(cert, loc);
570       if (wolfSSL_BIO_puts(bio, "\ncert. type        : ") <= 0)
571       {
572          log_ssl_errors(LOG_LEVEL_ERROR,
573             "wolfSSL_BIO_printf() for cert type failed");
574          ret = -1;
575          goto exit;
576       }
577       if (!wolfSSL_X509V3_EXT_print(bio, ex, 0, 0))
578       {
579          if (!wolfSSL_ASN1_STRING_print_ex(bio,
580                wolfSSL_X509_EXTENSION_get_data(ex),
581                ASN1_STRFLGS_RFC2253))
582          {
583             log_ssl_errors(LOG_LEVEL_ERROR,
584                "wolfSSL_ASN1_STRING_print_ex() for cert type failed");
585             ret = -1;
586             goto exit;
587          }
588       }
589    }
590 #endif
591
592 #if 0
593    /*
594     * This code compiles but does not work. wolfSSL_OBJ_obj2nid()
595     * triggers a 'X509V3_EXT_print not yet implemented for ext type' message.
596      */
597    loc = wolfSSL_X509_get_ext_by_NID(cert, NID_key_usage, -1);
598    if (loc != -1)
599    {
600       WOLFSSL_X509_EXTENSION *extension = wolfSSL_X509_get_ext(cert, loc);
601       if (BIO_puts(bio, "\nkey usage         : ") <= 0)
602       {
603          log_ssl_errors(LOG_LEVEL_ERROR,
604             "wolfSSL_BIO_printf() for key usage failed");
605          ret = -1;
606          goto exit;
607       }
608       if (!wolfSSL_X509V3_EXT_print(bio, extension, 0, 0))
609       {
610          if (!wolfSSL_ASN1_STRING_print_ex(bio,
611                wolfSSL_X509_EXTENSION_get_data(extension),
612                ASN1_STRFLGS_RFC2253))
613          {
614             log_ssl_errors(LOG_LEVEL_ERROR,
615                "wolfSSL_ASN1_STRING_print_ex() for key usage failed");
616             ret = -1;
617             goto exit;
618          }
619       }
620    }
621 #endif
622
623 #if 0
624    /*
625     * This compiles but doesn't work. wolfSSL_X509_ext_isSet_by_NID()
626     * complains about "NID not in table".
627     */
628    loc = wolfSSL_X509_get_ext_by_NID(cert, NID_ext_key_usage, -1);
629    if (loc != -1) {
630       WOLFSSL_X509_EXTENSION *ex = wolfSSL_X509_get_ext(cert, loc);
631       if (wolfSSL_BIO_puts(bio, "\next key usage     : ") <= 0)
632       {
633          log_ssl_errors(LOG_LEVEL_ERROR,
634             "wolfSSL_BIO_printf() for ext key usage failed");
635          ret = -1;
636          goto exit;
637       }
638       if (!wolfSSL_X509V3_EXT_print(bio, ex, 0, 0))
639       {
640          if (!wolfSSL_ASN1_STRING_print_ex(bio,
641                wolfSSL_X509_EXTENSION_get_data(ex),
642                ASN1_STRFLGS_RFC2253))
643          {
644             log_ssl_errors(LOG_LEVEL_ERROR,
645                "wolfSSL_ASN1_STRING_print_ex() for ext key usage failed");
646             ret = -1;
647             goto exit;
648          }
649       }
650    }
651 #endif
652
653 #if 0
654    /*
655     * This compiles but doesn't work. wolfSSL_X509_ext_isSet_by_NID()
656     * complains about "NID not in table". XXX: again?
657     */
658    loc = wolfSSL_X509_get_ext_by_NID(cert, NID_certificate_policies, -1);
659    if (loc != -1)
660    {
661       WOLFSSL_X509_EXTENSION *ex = wolfSSL_X509_get_ext(cert, loc);
662       if (wolfSSL_BIO_puts(bio, "\ncertificate policies : ") <= 0)
663       {
664          log_ssl_errors(LOG_LEVEL_ERROR,
665             "wolfSSL_BIO_printf() for certificate policies failed");
666          ret = -1;
667          goto exit;
668       }
669       if (!wolfSSL_X509V3_EXT_print(bio, ex, 0, 0))
670       {
671          if (!wolfSSL_ASN1_STRING_print_ex(bio,
672                wolfSSL_X509_EXTENSION_get_data(ex),
673                ASN1_STRFLGS_RFC2253))
674          {
675             log_ssl_errors(LOG_LEVEL_ERROR,
676                "wolfSSL_ASN1_STRING_print_ex() for certificate policies failed");
677             ret = -1;
678             goto exit;
679          }
680       }
681    }
682 #endif
683
684    /* make valgrind happy */
685    static const char zero = 0;
686    wolfSSL_BIO_write(bio, &zero, 1);
687
688    len = wolfSSL_BIO_get_mem_data(bio, &bio_mem_data);
689    if (len <= 0)
690    {
691       log_error(LOG_LEVEL_ERROR, "BIO_get_mem_data() returned %ld "
692          "while gathering certificate information", len);
693       ret = -1;
694       goto exit;
695    }
696    encoded_text = html_encode(bio_mem_data);
697    if (encoded_text == NULL)
698    {
699       log_error(LOG_LEVEL_ERROR,
700          "Failed to HTML-encode the certificate information");
701       ret = -1;
702       goto exit;
703    }
704
705    strlcpy(last->info_buf, encoded_text, sizeof(last->info_buf));
706    freez(encoded_text);
707    ret = 0;
708
709 exit:
710    if (bio)
711    {
712       wolfSSL_BIO_free(bio);
713    }
714    if (pkey)
715    {
716       wolfSSL_EVP_PKEY_free(pkey);
717    }
718    return ret;
719 }
720
721
722 /*********************************************************************
723  *
724  * Function    :  host_to_hash
725  *
726  * Description :  Creates MD5 hash from host name. Host name is loaded
727  *                from structure csp and saved again into it.
728  *
729  * Parameters  :
730  *          1  :  csp = Current client state (buffers, headers, etc...)
731  *
732  * Returns     : -1 => Error while creating hash
733  *                0 => Hash created successfully
734  *
735  *********************************************************************/
736 static int host_to_hash(struct client_state *csp)
737 {
738    Md5 md5;
739    int ret;
740    size_t i;
741
742    ret = wc_InitMd5(&md5);
743    if (ret != 0)
744    {
745       return -1;
746    }
747
748    ret = wc_Md5Update(&md5, (const byte *)csp->http->host,
749       (word32)strlen(csp->http->host));
750    if (ret != 0)
751    {
752       return -1;
753    }
754
755    ret = wc_Md5Final(&md5, csp->http->hash_of_host);
756    if (ret != 0)
757    {
758       return -1;
759    }
760
761    wc_Md5Free(&md5);
762
763    /* Converting hash into string with hex */
764    for (i = 0; i < 16; i++)
765    {
766       ret = snprintf((char *)csp->http->hash_of_host_hex + 2 * i,
767          sizeof(csp->http->hash_of_host_hex) - 2 * i,
768          "%02x", csp->http->hash_of_host[i]);
769       if (ret < 0)
770       {
771          log_error(LOG_LEVEL_ERROR, "sprintf() failed. Return value: %d", ret);
772          return -1;
773       }
774    }
775
776    return 0;
777 }
778
779
780 /*********************************************************************
781  *
782  * Function    :  create_client_ssl_connection
783  *
784  * Description :  Creates a TLS-secured connection with the client.
785  *
786  * Parameters  :
787  *          1  :  csp = Current client state (buffers, headers, etc...)
788  *
789  * Returns     :  0 on success, negative value if connection wasn't created
790  *                successfully.
791  *
792  *********************************************************************/
793 extern int create_client_ssl_connection(struct client_state *csp)
794 {
795    struct ssl_attr *ssl_attr = &csp->ssl_client_attr;
796    /* Paths to certificates file and key file */
797    char *key_file  = NULL;
798    char *cert_file = NULL;
799    int ret = 0;
800    WOLFSSL *ssl;
801
802    /* Should probably be called from somewhere else. */
803    wolfssl_init();
804
805    /*
806     * Preparing hash of host for creating certificates
807     */
808    ret = host_to_hash(csp);
809    if (ret != 0)
810    {
811       log_error(LOG_LEVEL_ERROR, "Generating hash of host failed: %d", ret);
812       ret = -1;
813       goto exit;
814    }
815
816    /*
817     * Preparing paths to certificates files and key file
818     */
819    cert_file = make_certs_path(csp->config->certificate_directory,
820       (const char *)csp->http->hash_of_host_hex, CERT_FILE_TYPE);
821    key_file  = make_certs_path(csp->config->certificate_directory,
822       (const char *)csp->http->hash_of_host_hex, KEY_FILE_TYPE);
823
824    if (cert_file == NULL || key_file == NULL)
825    {
826       ret = -1;
827       goto exit;
828    }
829
830    /* Do we need to generate a new host certificate and key? */
831    if (!file_exists(cert_file) || !file_exists(key_file) ||
832        ssl_certificate_is_invalid(cert_file))
833    {
834       /*
835        * Yes we do. Lock mutex to prevent certificate and
836        * key inconsistencies.
837        */
838       privoxy_mutex_lock(&certificate_mutex);
839       ret = generate_host_certificate(csp, cert_file, key_file);
840       privoxy_mutex_unlock(&certificate_mutex);
841       if (ret < 0)
842       {
843          /*
844           * No need to log something, generate_host_certificate()
845           * took care of it.
846           */
847          ret = -1;
848          goto exit;
849       }
850    }
851    ssl_attr->wolfssl_attr.ctx = wolfSSL_CTX_new(wolfSSLv23_method());
852    if (ssl_attr->wolfssl_attr.ctx == NULL)
853    {
854       log_ssl_errors(LOG_LEVEL_ERROR, "Unable to create TLS context");
855       ret = -1;
856       goto exit;
857    }
858
859    /* Set the key and cert */
860    if (wolfSSL_CTX_use_certificate_file(ssl_attr->wolfssl_attr.ctx,
861          cert_file, SSL_FILETYPE_PEM) != WOLFSSL_SUCCESS)
862    {
863       log_ssl_errors(LOG_LEVEL_ERROR,
864          "Loading host certificate %s failed", cert_file);
865       ret = -1;
866       goto exit;
867    }
868
869    if (wolfSSL_CTX_use_PrivateKey_file(ssl_attr->wolfssl_attr.ctx,
870          key_file, SSL_FILETYPE_PEM) != WOLFSSL_SUCCESS)
871    {
872       log_ssl_errors(LOG_LEVEL_ERROR,
873          "Loading host certificate private key %s failed", key_file);
874       ret = -1;
875       goto exit;
876    }
877
878    wolfSSL_CTX_set_options(ssl_attr->wolfssl_attr.ctx, WOLFSSL_OP_NO_SSLv3);
879
880    ssl = ssl_attr->wolfssl_attr.ssl = wolfSSL_new(ssl_attr->wolfssl_attr.ctx);
881
882    if (wolfSSL_set_fd(ssl, csp->cfd) != WOLFSSL_SUCCESS)
883    {
884       log_ssl_errors(LOG_LEVEL_ERROR,
885          "wolfSSL_set_fd() failed to set the client socket");
886       ret = -1;
887       goto exit;
888    }
889
890    if (csp->config->cipher_list != NULL)
891    {
892       if (!wolfSSL_set_cipher_list(ssl, csp->config->cipher_list))
893       {
894          log_ssl_errors(LOG_LEVEL_ERROR,
895             "Setting the cipher list '%s' for the client connection failed",
896             csp->config->cipher_list);
897          ret = -1;
898          goto exit;
899       }
900    }
901
902    /*
903     *  Handshake with client
904     */
905    log_error(LOG_LEVEL_CONNECT,
906       "Performing the TLS/SSL handshake with client. Hash of host: %s",
907       csp->http->hash_of_host_hex);
908
909    ret = wolfSSL_accept(ssl);
910    if (ret == WOLFSSL_SUCCESS)
911    {
912       log_error(LOG_LEVEL_CONNECT,
913          "Client successfully connected over %s (%s).",
914          wolfSSL_get_version(ssl), wolfSSL_get_cipher_name(ssl));
915       csp->ssl_with_client_is_opened = 1;
916       ret = 0;
917    }
918    else
919    {
920       char buffer[80];
921       int error = wolfSSL_get_error(ssl, ret);
922       log_error(LOG_LEVEL_ERROR,
923          "The TLS handshake with the client failed. error = %d, %s",
924          error, wolfSSL_ERR_error_string((unsigned long)error, buffer));
925       ret = -1;
926    }
927
928 exit:
929    /*
930     * Freeing allocated paths to files
931     */
932    freez(cert_file);
933    freez(key_file);
934
935    /* Freeing structures if connection wasn't created successfully */
936    if (ret < 0)
937    {
938       free_client_ssl_structures(csp);
939    }
940    return ret;
941 }
942
943
944 /*********************************************************************
945  *
946  * Function    :  shutdown_connection
947  *
948  * Description :  Shuts down a TLS connection if the socket is still
949  *                alive.
950  *
951  * Parameters  :
952  *          1  :  csp = Current client state (buffers, headers, etc...)
953  *
954  * Returns     :  N/A
955  *
956  *********************************************************************/
957 static void shutdown_connection(WOLFSSL *ssl, const char *type)
958 {
959    int shutdown_attempts = 0;
960    int ret;
961    int fd;
962    enum { MAX_SHUTDOWN_ATTEMPTS = 2 };
963
964    fd = wolfSSL_get_fd(ssl);
965
966    do
967    {
968       if (!socket_is_still_alive(fd))
969       {
970          log_error(LOG_LEVEL_CONNECT, "Not shutting down %s connection "
971             "on socket %d. The socket is no longer alive.", type, fd);
972          return;
973       }
974       ret = wolfSSL_shutdown(ssl);
975       if (WOLFSSL_SUCCESS != ret)
976       {
977          shutdown_attempts++;
978          log_error(LOG_LEVEL_CONNECT, "Failed to shutdown %s connection "
979             "on socket %d. Attempts so far: %d, ret: %d", type, fd,
980             shutdown_attempts, ret);
981       }
982    } while (ret == WOLFSSL_SHUTDOWN_NOT_DONE &&
983       shutdown_attempts < MAX_SHUTDOWN_ATTEMPTS);
984    if (WOLFSSL_SUCCESS != ret)
985    {
986       char buffer[80];
987       int error = wolfSSL_get_error(ssl, ret);
988       log_error(LOG_LEVEL_ERROR, "Failed to shutdown %s connection "
989          "on socket %d after %d attempts. ret: %d, error: %d, %s",
990          type, fd, shutdown_attempts, ret, error,
991          wolfSSL_ERR_error_string((unsigned long)error, buffer));
992    }
993 }
994
995
996 /*********************************************************************
997  *
998  * Function    :  close_client_ssl_connection
999  *
1000  * Description :  Closes TLS connection with client. This function
1001  *                checks if this connection is already created.
1002  *
1003  * Parameters  :
1004  *          1  :  csp = Current client state (buffers, headers, etc...)
1005  *
1006  * Returns     :  N/A
1007  *
1008  *********************************************************************/
1009 extern void close_client_ssl_connection(struct client_state *csp)
1010 {
1011    struct ssl_attr *ssl_attr = &csp->ssl_client_attr;
1012
1013    if (csp->ssl_with_client_is_opened == 0)
1014    {
1015       return;
1016    }
1017
1018    /*
1019     * Notify the peer that the connection is being closed.
1020     */
1021    shutdown_connection(ssl_attr->wolfssl_attr.ssl, "client");
1022
1023    free_client_ssl_structures(csp);
1024    csp->ssl_with_client_is_opened = 0;
1025 }
1026
1027
1028 /*********************************************************************
1029  *
1030  * Function    :  free_client_ssl_structures
1031  *
1032  * Description :  Frees structures used for SSL communication with
1033  *                client.
1034  *
1035  * Parameters  :
1036  *          1  :  csp = Current client state (buffers, headers, etc...)
1037  *
1038  * Returns     :  N/A
1039  *
1040  *********************************************************************/
1041 static void free_client_ssl_structures(struct client_state *csp)
1042 {
1043    struct ssl_attr *ssl_attr = &csp->ssl_client_attr;
1044
1045    if (ssl_attr->wolfssl_attr.ssl)
1046    {
1047       wolfSSL_free(ssl_attr->wolfssl_attr.ssl);
1048    }
1049    if (ssl_attr->wolfssl_attr.ctx)
1050    {
1051       wolfSSL_CTX_free(ssl_attr->wolfssl_attr.ctx);
1052    }
1053 }
1054
1055
1056 /*********************************************************************
1057  *
1058  * Function    :  close_server_ssl_connection
1059  *
1060  * Description :  Closes TLS connection with server. This function
1061  *                checks if this connection is already opened.
1062  *
1063  * Parameters  :
1064  *          1  :  csp = Current client state (buffers, headers, etc...)
1065  *
1066  * Returns     :  N/A
1067  *
1068  *********************************************************************/
1069 extern void close_server_ssl_connection(struct client_state *csp)
1070 {
1071    struct ssl_attr *ssl_attr = &csp->ssl_server_attr;
1072
1073    if (csp->ssl_with_server_is_opened == 0)
1074    {
1075       return;
1076    }
1077
1078    /*
1079    * Notify the peer that the connection is being closed.
1080    */
1081    shutdown_connection(ssl_attr->wolfssl_attr.ssl, "server");
1082
1083    free_server_ssl_structures(csp);
1084    csp->ssl_with_server_is_opened = 0;
1085 }
1086
1087
1088 /*********************************************************************
1089  *
1090  * Function    :  create_server_ssl_connection
1091  *
1092  * Description :  Creates TLS-secured connection with the server.
1093  *
1094  * Parameters  :
1095  *          1  :  csp = Current client state (buffers, headers, etc...)
1096  *
1097  * Returns     :  0 on success, negative value if connection wasn't created
1098  *                successfully.
1099  *
1100  *********************************************************************/
1101 extern int create_server_ssl_connection(struct client_state *csp)
1102 {
1103    wolfssl_connection_attr *ssl_attrs = &csp->ssl_server_attr.wolfssl_attr;
1104    int ret = 0;
1105    WOLFSSL *ssl;
1106    int connect_ret = 0;
1107
1108    csp->server_cert_verification_result = SSL_CERT_NOT_VERIFIED;
1109    csp->server_certs_chain.next = NULL;
1110
1111    ssl_attrs->ctx = wolfSSL_CTX_new(wolfSSLv23_method());
1112    if (ssl_attrs->ctx == NULL)
1113    {
1114       log_ssl_errors(LOG_LEVEL_ERROR, "TLS context creation failed");
1115       ret = -1;
1116       goto exit;
1117    }
1118
1119    if (csp->dont_verify_certificate)
1120    {
1121       wolfSSL_CTX_set_verify(ssl_attrs->ctx, WOLFSSL_VERIFY_NONE, NULL);
1122    }
1123    else if (wolfSSL_CTX_load_verify_locations(ssl_attrs->ctx,
1124       csp->config->trusted_cas_file, NULL) != WOLFSSL_SUCCESS)
1125    {
1126       log_ssl_errors(LOG_LEVEL_ERROR, "Loading trusted CAs file %s failed",
1127          csp->config->trusted_cas_file);
1128       ret = -1;
1129       goto exit;
1130    }
1131
1132    wolfSSL_CTX_set_options(ssl_attrs->ctx, WOLFSSL_OP_NO_SSLv3);
1133
1134    ssl = ssl_attrs->ssl = wolfSSL_new(ssl_attrs->ctx);
1135
1136    if (wolfSSL_set_fd(ssl, csp->server_connection.sfd) != WOLFSSL_SUCCESS)
1137    {
1138       log_ssl_errors(LOG_LEVEL_ERROR,
1139          "wolfSSL_set_fd() failed to set the server socket");
1140       ret = -1;
1141       goto exit;
1142    }
1143
1144    if (csp->config->cipher_list != NULL)
1145    {
1146       if (wolfSSL_set_cipher_list(ssl, csp->config->cipher_list) != WOLFSSL_SUCCESS)
1147       {
1148          log_ssl_errors(LOG_LEVEL_ERROR,
1149             "Setting the cipher list '%s' for the server connection failed",
1150             csp->config->cipher_list);
1151          ret = -1;
1152          goto exit;
1153       }
1154    }
1155
1156    ret = wolfSSL_UseSNI(ssl, WOLFSSL_SNI_HOST_NAME,
1157       csp->http->host, (unsigned short)strlen(csp->http->host));
1158    if (ret != WOLFSSL_SUCCESS)
1159    {
1160       log_ssl_errors(LOG_LEVEL_ERROR, "Failed to set use of SNI");
1161       ret = -1;
1162       goto exit;
1163    }
1164
1165    ret = wolfSSL_check_domain_name(ssl, csp->http->host);
1166    if (ret != WOLFSSL_SUCCESS)
1167    {
1168       char buffer[80];
1169       int error = wolfSSL_get_error(ssl, ret);
1170       log_error(LOG_LEVEL_FATAL,
1171          "Failed to set check domain name. error = %d, %s",
1172          error, wolfSSL_ERR_error_string((unsigned long)error, buffer));
1173       ret = -1;
1174       goto exit;
1175    }
1176
1177 #ifdef HAVE_SECURE_RENEGOTIATION
1178 #warning wolfssl has been compiled with HAVE_SECURE_RENEGOTIATION while you probably want HAVE_RENEGOTIATION_INDICATION
1179    if(wolfSSL_UseSecureRenegotiation(ssl) != WOLFSSL_SUCCESS)
1180    {
1181       log_ssl_errors(LOG_LEVEL_ERROR,
1182          "Failed to enable 'Secure' Renegotiation. Continuing anyway.");
1183    }
1184 #endif
1185 #ifndef HAVE_RENEGOTIATION_INDICATION
1186 #warning Looks like wolfssl has been compiled without HAVE_RENEGOTIATION_INDICATION
1187 #endif
1188
1189    log_error(LOG_LEVEL_CONNECT,
1190       "Performing the TLS/SSL handshake with the server");
1191
1192    /* wolfSSL_Debugging_ON(); */
1193    connect_ret = wolfSSL_connect(ssl);
1194    /* wolfSSL_Debugging_OFF(); */
1195
1196    /*
1197    wolfSSL_Debugging_ON();
1198    */
1199    if (!csp->dont_verify_certificate)
1200    {
1201       long verify_result = wolfSSL_get_error(ssl, connect_ret);
1202
1203       if (verify_result == X509_V_OK)
1204       {
1205          ret = 0;
1206          csp->server_cert_verification_result = SSL_CERT_VALID;
1207       }
1208       else
1209       {
1210          WOLF_STACK_OF(WOLFSSL_X509) *chain;
1211
1212          csp->server_cert_verification_result = verify_result;
1213          log_error(LOG_LEVEL_ERROR,
1214             "X509 certificate verification for %s failed with error %ld: %s",
1215             csp->http->hostport, verify_result,
1216             wolfSSL_X509_verify_cert_error_string(verify_result));
1217
1218          chain = wolfSSL_get_peer_cert_chain(ssl);
1219          if (chain != NULL)
1220          {
1221             int i;
1222             for (i = 0; i < wolfSSL_sk_X509_num(chain); i++)
1223             {
1224                if (ssl_store_cert(csp, wolfSSL_sk_X509_value(chain, i)) != 0)
1225                {
1226                   log_error(LOG_LEVEL_ERROR,
1227                      "ssl_store_cert() failed for cert %d", i);
1228                   /*
1229                    * ssl_send_certificate_error() wil not be able to show
1230                    * the certificate but the user will stil get the error
1231                    * description.
1232                    */
1233                }
1234             }
1235          }
1236
1237          ret = -1;
1238          goto exit;
1239       }
1240    }
1241    /*
1242    wolfSSL_Debugging_OFF();
1243    */
1244    if (connect_ret == WOLFSSL_SUCCESS)
1245    {
1246       log_error(LOG_LEVEL_CONNECT,
1247          "Server successfully connected over %s (%s).",
1248          wolfSSL_get_version(ssl), wolfSSL_get_cipher_name(ssl));
1249       csp->ssl_with_server_is_opened = 1;
1250       ret = 0;
1251    }
1252    else
1253    {
1254       char buffer[80];
1255       int error = wolfSSL_get_error(ssl, ret);
1256       log_error(LOG_LEVEL_ERROR,
1257          "The TLS handshake with the server %s failed. error = %d, %s",
1258          csp->http->hostport,
1259          error, wolfSSL_ERR_error_string((unsigned long)error, buffer));
1260       ret = -1;
1261    }
1262
1263 exit:
1264    /* Freeing structures if connection wasn't created successfully */
1265    if (ret < 0)
1266    {
1267       free_server_ssl_structures(csp);
1268    }
1269
1270    return ret;
1271 }
1272
1273
1274 /*********************************************************************
1275  *
1276  * Function    :  free_server_ssl_structures
1277  *
1278  * Description :  Frees structures used for SSL communication with server
1279  *
1280  * Parameters  :
1281  *          1  :  csp = Current client state (buffers, headers, etc...)
1282  *
1283  * Returns     :  N/A
1284  *
1285  *********************************************************************/
1286 static void free_server_ssl_structures(struct client_state *csp)
1287 {
1288    struct ssl_attr *ssl_attr = &csp->ssl_server_attr;
1289
1290    if (ssl_attr->wolfssl_attr.ssl)
1291    {
1292       wolfSSL_free(ssl_attr->wolfssl_attr.ssl);
1293    }
1294    if (ssl_attr->wolfssl_attr.ctx)
1295    {
1296       wolfSSL_CTX_free(ssl_attr->wolfssl_attr.ctx);
1297    }
1298 }
1299
1300
1301 /*********************************************************************
1302  *
1303  * Function    :  log_ssl_errors
1304  *
1305  * Description :  Log SSL errors
1306  *
1307  * Parameters  :
1308  *          1  :  debuglevel = Debug level
1309  *          2  :  desc = Error description
1310  *
1311  * Returns     :  N/A
1312  *
1313  *********************************************************************/
1314 static void log_ssl_errors(int debuglevel, const char* fmt, ...)
1315 {
1316    unsigned long err_code;
1317    char prefix[ERROR_BUF_SIZE];
1318    va_list args;
1319    va_start(args, fmt);
1320    vsnprintf(prefix, sizeof(prefix), fmt, args);
1321    int reported = 0;
1322
1323    while ((err_code = wolfSSL_ERR_get_error()))
1324    {
1325       char err_buf[ERROR_BUF_SIZE];
1326       reported = 1;
1327       wolfSSL_ERR_error_string_n(err_code, err_buf, sizeof(err_buf));
1328       log_error(debuglevel, "%s: %s", prefix, err_buf);
1329    }
1330    va_end(args);
1331    /*
1332     * In case if called by mistake and there were
1333     * no TLS errors let's report it to the log.
1334     */
1335    if (!reported)
1336    {
1337       log_error(debuglevel, "%s: no TLS errors detected", prefix);
1338    }
1339 }
1340
1341
1342 /*********************************************************************
1343  *
1344  * Function    :  ssl_base64_encode
1345  *
1346  * Description :  Encode a buffer into base64 format.
1347  *
1348  * Parameters  :
1349  *          1  :  dst = Destination buffer
1350  *          2  :  dlen = Destination buffer length
1351  *          3  :  olen = Number of bytes written
1352  *          4  :  src = Source buffer
1353  *          5  :  slen = Amount of data to be encoded
1354  *
1355  * Returns     :  0 on success, error code othervise
1356  *
1357  *********************************************************************/
1358 extern int ssl_base64_encode(unsigned char *dst, size_t dlen, size_t *olen,
1359                              const unsigned char *src, size_t slen)
1360 {
1361    word32 output_length;
1362    int ret;
1363
1364    *olen = 4 * ((slen/3) + ((slen%3) ? 1 : 0)) + 1;
1365    if (*olen > dlen)
1366    {
1367       return ENOBUFS;
1368    }
1369
1370    output_length = (word32)dlen;
1371    ret = Base64_Encode_NoNl(src, (word32)slen, dst, &output_length);
1372    if (ret != 0)
1373    {
1374       log_error(LOG_LEVEL_ERROR, "base64 encoding failed with %d", ret);
1375       return ret;
1376    }
1377    *olen = output_length;
1378
1379    return 0;
1380
1381 }
1382
1383
1384 /*********************************************************************
1385  *
1386  * Function    :  close_file_stream
1387  *
1388  * Description :  Close file stream, report error on close error
1389  *
1390  * Parameters  :
1391  *          1  :  f = file stream to close
1392  *          2  :  path = path for error report
1393  *
1394  * Returns     :  N/A
1395  *
1396  *********************************************************************/
1397 static void close_file_stream(FILE *f, const char *path)
1398 {
1399    if (fclose(f) != 0)
1400    {
1401       log_error(LOG_LEVEL_ERROR,
1402          "Error closing file %s: %s", path, strerror(errno));
1403    }
1404 }
1405
1406
1407 /*********************************************************************
1408  *
1409  * Function    :  write_certificate
1410  *
1411  * Description :  Writes a PEM-encoded certificate to a file.
1412  *
1413  * Parameters  :
1414  *          1  :  certificate_path = Path to the file to create
1415  *          2  :  certificate = PEM-encoded certificate to write.
1416  *
1417  * Returns     :  NULL => Error. Otherwise a key;
1418  *
1419  *********************************************************************/
1420 static int write_certificate(const char *certificate_path, const char *certificate)
1421 {
1422    FILE *fp;
1423
1424    assert(certificate_path != NULL);
1425    assert(certificate != NULL);
1426
1427    fp = fopen(certificate_path, "wb");
1428    if (NULL == fp)
1429    {
1430       log_error(LOG_LEVEL_ERROR,
1431          "Failed to open %s to write the certificate: %E",
1432          certificate_path);
1433       return -1;
1434    }
1435    if (fputs(certificate, fp) < 0)
1436    {
1437       log_error(LOG_LEVEL_ERROR, "Failed to write certificate to %s: %E",
1438          certificate_path);
1439       fclose(fp);
1440       return -1;
1441    }
1442    fclose(fp);
1443
1444    return 0;
1445
1446 }
1447
1448
1449 /*********************************************************************
1450  *
1451  * Function    :  generate_rsa_key
1452  *
1453  * Description : Generates a new RSA key and saves it in a file.
1454  *
1455  * Parameters  :
1456  *          1  :  rsa_key_path = Path to the key that should be written.
1457  *
1458  * Returns     :  -1 => Error while generating private key
1459  *                 0 => Success.
1460  *
1461  *********************************************************************/
1462 static int generate_rsa_key(const char *rsa_key_path)
1463 {
1464    RsaKey rsa_key;
1465    byte rsa_key_der[4096];
1466    int ret;
1467    byte key_pem[4096];
1468    int der_key_size;
1469    int pem_key_size;
1470    FILE *f = NULL;
1471
1472    assert(file_exists(rsa_key_path) != 1);
1473
1474    wc_InitRsaKey(&rsa_key, NULL);
1475
1476    log_error(LOG_LEVEL_CONNECT, "Making RSA key %s ...", rsa_key_path);
1477    ret = wc_MakeRsaKey(&rsa_key, RSA_KEYSIZE, RSA_KEY_PUBLIC_EXPONENT,
1478       &wolfssl_rng);
1479    if (ret != 0)
1480    {
1481       log_error(LOG_LEVEL_ERROR, "RSA key generation failed");
1482       ret = -1;
1483       goto exit;
1484    }
1485    log_error(LOG_LEVEL_CONNECT, "Done making RSA key %s", rsa_key_path);
1486
1487    der_key_size = wc_RsaKeyToDer(&rsa_key, rsa_key_der, sizeof(rsa_key_der));
1488    wc_FreeRsaKey(&rsa_key);
1489    if (der_key_size < 0)
1490    {
1491       log_error(LOG_LEVEL_ERROR, "RSA key conversion to DER format failed");
1492       ret = -1;
1493       goto exit;
1494    }
1495    pem_key_size = wc_DerToPem(rsa_key_der, (word32)der_key_size,
1496       key_pem, sizeof(key_pem), PRIVATEKEY_TYPE);
1497    if (pem_key_size < 0)
1498    {
1499       log_error(LOG_LEVEL_ERROR, "RSA key conversion to PEM format failed");
1500       ret = -1;
1501       goto exit;
1502    }
1503
1504    /*
1505     * Saving key into file
1506     */
1507    if ((f = fopen(rsa_key_path, "wb")) == NULL)
1508    {
1509       log_error(LOG_LEVEL_ERROR,
1510          "Opening file %s to save private key failed: %E",
1511          rsa_key_path);
1512       ret = -1;
1513       goto exit;
1514    }
1515
1516    if (fwrite(key_pem, 1, (size_t)pem_key_size, f) != pem_key_size)
1517    {
1518       log_error(LOG_LEVEL_ERROR,
1519          "Writing private key into file %s failed",
1520          rsa_key_path);
1521       close_file_stream(f, rsa_key_path);
1522       ret = -1;
1523       goto exit;
1524    }
1525
1526    close_file_stream(f, rsa_key_path);
1527
1528 exit:
1529
1530    return ret;
1531
1532 }
1533
1534
1535 /*********************************************************************
1536  *
1537  * Function    :  ssl_certificate_load
1538  *
1539  * Description :  Loads certificate from file.
1540  *
1541  * Parameters  :
1542  *          1  :  cert_path = The certificate path to load
1543  *
1544  * Returns     :   NULL => error loading certificate,
1545  *                   pointer to certificate instance otherwise
1546  *
1547  *********************************************************************/
1548 static X509 *ssl_certificate_load(const char *cert_path)
1549 {
1550    X509 *cert = NULL;
1551    FILE *cert_f = NULL;
1552
1553    if (!(cert_f = fopen(cert_path, "r")))
1554    {
1555       log_error(LOG_LEVEL_ERROR,
1556          "Error opening certificate file %s: %s", cert_path, strerror(errno));
1557       return NULL;
1558    }
1559
1560    if (!(cert = PEM_read_X509(cert_f, NULL, NULL, NULL)))
1561    {
1562       log_ssl_errors(LOG_LEVEL_ERROR,
1563          "Error reading certificate file %s", cert_path);
1564    }
1565
1566    close_file_stream(cert_f, cert_path);
1567    return cert;
1568 }
1569
1570
1571 /*********************************************************************
1572  *
1573  * Function    :  ssl_certificate_is_invalid
1574  *
1575  * Description :  Checks whether or not a certificate is valid.
1576  *                Currently only checks that the certificate can be
1577  *                parsed and that the "valid to" date is in the future.
1578  *
1579  * Parameters  :
1580  *          1  :  cert_file = The certificate to check
1581  *
1582  * Returns     :   0 => The certificate is valid.
1583  *                 1 => The certificate is invalid
1584  *
1585  *********************************************************************/
1586 static int ssl_certificate_is_invalid(const char *cert_file)
1587 {
1588    int ret;
1589
1590    X509 *cert = NULL;
1591
1592    if (!(cert = ssl_certificate_load(cert_file)))
1593    {
1594       return 1;
1595    }
1596
1597    ret = wolfSSL_X509_cmp_current_time(wolfSSL_X509_get_notAfter(cert));
1598    if (ret == 0)
1599    {
1600       log_ssl_errors(LOG_LEVEL_ERROR,
1601          "Error checking certificate %s validity", cert_file);
1602       ret = -1;
1603    }
1604
1605    wolfSSL_X509_free(cert);
1606
1607    return ret == -1 ? 1 : 0;
1608 }
1609
1610
1611 /*********************************************************************
1612  *
1613  * Function    :  load_rsa_key
1614  *
1615  * Description :  Load a PEM-encoded RSA file into memory.
1616  *
1617  * Parameters  :
1618  *          1  :  rsa_key_path = Path to the file that holds the key.
1619  *          2  :  password = Password to unlock the key. NULL if no
1620  *                           password is required.
1621  *          3  :  rsa_key = Initialized RSA key storage.
1622  *
1623  * Returns     :   0 => Error while creating the key.
1624  *                 1 => It worked
1625  *
1626  *********************************************************************/
1627 static int load_rsa_key(const char *rsa_key_path, const char *password, RsaKey *rsa_key)
1628 {
1629    FILE *fp;
1630    size_t length;
1631    long ret;
1632    unsigned char *key_pem;
1633    DerBuffer *der_buffer;
1634    word32 der_index = 0;
1635    DerBuffer decrypted_der_buffer;
1636    unsigned char der_data[4096];
1637
1638    fp = fopen(rsa_key_path, "rb");
1639    if (NULL == fp)
1640    {
1641       log_error(LOG_LEVEL_ERROR, "Failed to open %s: %E", rsa_key_path);
1642       return 0;
1643    }
1644
1645    /* Get file length */
1646    if (fseek(fp, 0, SEEK_END))
1647    {
1648       log_error(LOG_LEVEL_ERROR,
1649          "Unexpected error while fseek()ing to the end of %s: %E",
1650          rsa_key_path);
1651       fclose(fp);
1652       return 0;
1653    }
1654    ret = ftell(fp);
1655    if (-1 == ret)
1656    {
1657       log_error(LOG_LEVEL_ERROR,
1658          "Unexpected ftell() error while loading %s: %E",
1659          rsa_key_path);
1660       fclose(fp);
1661       return 0;
1662    }
1663    length = (size_t)ret;
1664
1665    /* Go back to the beginning. */
1666    if (fseek(fp, 0, SEEK_SET))
1667    {
1668       log_error(LOG_LEVEL_ERROR,
1669          "Unexpected error while fseek()ing to the beginning of %s: %E",
1670          rsa_key_path);
1671       fclose(fp);
1672       return 0;
1673    }
1674
1675    key_pem = malloc_or_die(length);
1676
1677    if (1 != fread(key_pem, length, 1, fp))
1678    {
1679       log_error(LOG_LEVEL_ERROR,
1680          "Couldn't completely read file %s.", rsa_key_path);
1681       fclose(fp);
1682       freez(key_pem);
1683       return 0;
1684    }
1685
1686    fclose(fp);
1687
1688    if (password == NULL)
1689    {
1690       ret = wc_PemToDer(key_pem, (long)length, PRIVATEKEY_TYPE,
1691          &der_buffer, NULL, NULL, NULL);
1692    }
1693    else
1694    {
1695       der_buffer = &decrypted_der_buffer;
1696       der_buffer->buffer = der_data;
1697       ret = wc_KeyPemToDer(key_pem, (int)length, der_buffer->buffer,
1698          sizeof(der_data), password);
1699       if (ret < 0)
1700       {
1701          log_error(LOG_LEVEL_ERROR,
1702             "Failed to convert PEM key %s into DER format. Error: %ld",
1703             rsa_key_path, ret);
1704          freez(key_pem);
1705          return 0;
1706       }
1707       der_buffer->length = (word32)ret;
1708    }
1709
1710    freez(key_pem);
1711
1712    if (ret < 0)
1713    {
1714       log_error(LOG_LEVEL_ERROR,
1715          "Failed to convert buffer into DER format for file %s. Error = %ld",
1716          rsa_key_path, ret);
1717       return 0;
1718    }
1719
1720    ret = wc_RsaPrivateKeyDecode(der_buffer->buffer, &der_index, rsa_key,
1721       der_buffer->length);
1722    if (password == NULL)
1723    {
1724       freez(der_buffer);
1725    }
1726    if (ret < 0)
1727    {
1728       log_error(LOG_LEVEL_ERROR,
1729          "Failed to decode DER buffer into RSA key structure for %s",
1730          rsa_key_path);
1731       return 0;
1732    }
1733
1734    return 1;
1735 }
1736
1737 #ifndef WOLFSSL_ALT_NAMES
1738 #error wolfSSL lacks Subject Alternative Name support
1739 #endif
1740 /*********************************************************************
1741  *
1742  * Function    :  set_subject_alternative_name
1743  *
1744  * Description :  Sets the Subject Alternative Name extension to
1745  *                a cert using the awesome "API" provided by wolfSSL.
1746  *
1747  * Parameters  :
1748  *          1  :  cert = The certificate to modify
1749  *          2  :  hostname = The hostname to add
1750  *
1751  * Returns     :  <0 => Error.
1752  *                 0 => It worked
1753  *
1754  *********************************************************************/
1755 static int set_subject_alternative_name(struct Cert *certificate, const char *hostname)
1756 {
1757    const size_t hostname_length = strlen(hostname);
1758
1759    if (hostname_length >= 253)
1760    {
1761       /*
1762        * We apparently only have a byte to represent the length
1763        * of the sequence.
1764        */
1765       log_error(LOG_LEVEL_ERROR,
1766          "Hostname '%s' is too long to set Subject Alternative Name",
1767          hostname);
1768       return -1;
1769    }
1770    certificate->altNames[0] = 0x30; /* Sequence */
1771    certificate->altNames[1] = (unsigned char)hostname_length + 2;
1772
1773    certificate->altNames[2] = 0x82; /* DNS name */
1774    certificate->altNames[3] = (unsigned char)hostname_length;
1775    memcpy(&certificate->altNames[4], hostname, hostname_length);
1776
1777    certificate->altNamesSz = (int)hostname_length + 4;
1778
1779    return 0;
1780 }
1781
1782
1783 /*********************************************************************
1784  *
1785  * Function    :  generate_host_certificate
1786  *
1787  * Description :  Creates certificate file in presetted directory.
1788  *                If certificate already exists, no other certificate
1789  *                will be created. Subject of certificate is named
1790  *                by csp->http->host from parameter. This function also
1791  *                triggers generating of private key for new certificate.
1792  *
1793  * Parameters  :
1794  *          1  :  csp = Current client state (buffers, headers, etc...)
1795  *          2  :  certificate_path = Path to the certficate to generate.
1796  *          3  :  rsa_key_path = Path to the key to generate for the
1797  *                               certificate.
1798  *
1799  * Returns     :  -1 => Error while creating certificate.
1800  *                 0 => Certificate already exists.
1801  *                 1 => Certificate created
1802  *
1803  *********************************************************************/
1804 static int generate_host_certificate(struct client_state *csp,
1805    const char *certificate_path, const char *rsa_key_path)
1806 {
1807    struct Cert certificate;
1808    RsaKey ca_key;
1809    RsaKey rsa_key;
1810    int ret;
1811    byte certificate_der[4096];
1812    int der_certificate_length;
1813    byte certificate_pem[4096];
1814    int pem_certificate_length;
1815
1816    if (file_exists(certificate_path) == 1)
1817    {
1818       /* The file exists, but is it valid? */
1819       if (ssl_certificate_is_invalid(certificate_path))
1820       {
1821          log_error(LOG_LEVEL_CONNECT,
1822             "Certificate %s is no longer valid. Removing it.",
1823             certificate_path);
1824          if (unlink(certificate_path))
1825          {
1826             log_error(LOG_LEVEL_ERROR, "Failed to unlink %s: %E",
1827                certificate_path);
1828             return -1;
1829          }
1830          if (unlink(rsa_key_path))
1831          {
1832             log_error(LOG_LEVEL_ERROR, "Failed to unlink %s: %E",
1833                rsa_key_path);
1834             return -1;
1835          }
1836       }
1837       else
1838       {
1839          return 0;
1840       }
1841    }
1842    else
1843    {
1844       log_error(LOG_LEVEL_CONNECT, "Creating new certificate %s",
1845          certificate_path);
1846    }
1847    if (enforce_sane_certificate_state(certificate_path, rsa_key_path))
1848    {
1849       return -1;
1850    }
1851
1852    wc_InitRsaKey(&rsa_key, NULL);
1853    wc_InitRsaKey(&ca_key, NULL);
1854
1855    if (generate_rsa_key(rsa_key_path) == -1)
1856    {
1857       return -1;
1858    }
1859
1860    wc_InitCert(&certificate);
1861
1862    strncpy(certificate.subject.country, CERT_PARAM_COUNTRY_CODE, CTC_NAME_SIZE);
1863    strncpy(certificate.subject.org, "Privoxy", CTC_NAME_SIZE);
1864    strncpy(certificate.subject.unit, "Development", CTC_NAME_SIZE);
1865    strncpy(certificate.subject.commonName, csp->http->host, CTC_NAME_SIZE);
1866    certificate.daysValid = 90;
1867    certificate.selfSigned = 0;
1868    certificate.sigType = CTC_SHA256wRSA;
1869    if (!host_is_ip_address(csp->http->host) &&
1870        set_subject_alternative_name(&certificate, csp->http->host))
1871    {
1872       ret = -1;
1873       goto exit;
1874    }
1875
1876    ret = wc_SetIssuer(&certificate, csp->config->ca_cert_file);
1877    if (ret < 0)
1878    {
1879       log_error(LOG_LEVEL_ERROR,
1880          "Failed to set Issuer file %s", csp->config->ca_cert_file);
1881       ret = -1;
1882       goto exit;
1883    }
1884
1885    if (load_rsa_key(rsa_key_path, NULL, &rsa_key) != 1)
1886    {
1887       log_error(LOG_LEVEL_ERROR,
1888          "Failed to load RSA key %s", rsa_key_path);
1889       ret = -1;
1890       goto exit;
1891    }
1892
1893    /* wolfSSL_Debugging_ON(); */
1894    der_certificate_length = wc_MakeCert(&certificate, certificate_der,
1895       sizeof(certificate_der), &rsa_key, NULL, &wolfssl_rng);
1896    /* wolfSSL_Debugging_OFF(); */
1897
1898    if (der_certificate_length < 0)
1899    {
1900       log_error(LOG_LEVEL_ERROR, "Failed to make certificate");
1901       ret = -1;
1902       goto exit;
1903    }
1904
1905    if (load_rsa_key(csp->config->ca_key_file, csp->config->ca_password,
1906       &ca_key) != 1)
1907    {
1908       log_error(LOG_LEVEL_ERROR,
1909          "Failed to load CA key %s", csp->config->ca_key_file);
1910       ret = -1;
1911       goto exit;
1912    }
1913
1914    der_certificate_length = wc_SignCert(certificate.bodySz, certificate.sigType,
1915       certificate_der, sizeof(certificate_der), &ca_key, NULL, &wolfssl_rng);
1916    wc_FreeRsaKey(&ca_key);
1917    if (der_certificate_length < 0)
1918    {
1919       log_error(LOG_LEVEL_ERROR, "Failed to sign certificate");
1920       ret = -1;
1921       goto exit;
1922    }
1923
1924    pem_certificate_length = wc_DerToPem(certificate_der,
1925       (word32)der_certificate_length, certificate_pem,
1926       sizeof(certificate_pem), CERT_TYPE);
1927    if (pem_certificate_length < 0)
1928    {
1929       log_error(LOG_LEVEL_ERROR,
1930          "Failed to convert certificate from DER to PEM");
1931       ret = -1;
1932       goto exit;
1933    }
1934    certificate_pem[pem_certificate_length] = '\0';
1935
1936    if (write_certificate(certificate_path, (const char*)certificate_pem))
1937    {
1938       ret = -1;
1939       goto exit;
1940    }
1941
1942    ret = 1;
1943
1944 exit:
1945    wc_FreeRsaKey(&rsa_key);
1946    wc_FreeRsaKey(&ca_key);
1947
1948    return 1;
1949
1950 }
1951
1952
1953 /*********************************************************************
1954  *
1955  * Function    :  ssl_crt_verify_info
1956  *
1957  * Description :  Returns an informational string about the verification
1958  *                status of a certificate.
1959  *
1960  * Parameters  :
1961  *          1  :  buf = Buffer to write to
1962  *          2  :  size = Maximum size of buffer
1963  *          3  :  csp = client state
1964  *
1965  * Returns     :  N/A
1966  *
1967  *********************************************************************/
1968 extern void ssl_crt_verify_info(char *buf, size_t size, struct client_state *csp)
1969 {
1970    strncpy(buf, wolfSSL_X509_verify_cert_error_string(
1971       csp->server_cert_verification_result), size);
1972    buf[size - 1] = 0;
1973 }
1974
1975
1976 #ifdef FEATURE_GRACEFUL_TERMINATION
1977 /*********************************************************************
1978  *
1979  * Function    :  ssl_release
1980  *
1981  * Description :  Release all SSL resources
1982  *
1983  * Parameters  :
1984  *
1985  * Returns     :  N/A
1986  *
1987  *********************************************************************/
1988 extern void ssl_release(void)
1989 {
1990    if (wolfssl_initialized == 1)
1991    {
1992       wc_FreeRng(&wolfssl_rng);
1993       wolfSSL_Cleanup();
1994    }
1995 }
1996 #endif /* def FEATURE_GRACEFUL_TERMINATION */