user-manual: Note that FreeBSD and ElectroBSD users can try to install Privoxy
[privoxy.git] / openssl.c
1 /*********************************************************************
2  *
3  * File        :  $Source: /cvsroot/ijbswa/current/openssl.c,v $
4  *
5  * Purpose     :  File with TLS/SSL extension. Contains methods for
6  *                creating, using and closing TLS/SSL connections
7  *                using OpenSSL (or LibreSSL).
8  *
9  * Copyright   :  Written by and Copyright (c) 2020 Maxim Antonov <mantonov@gmail.com>
10  *                Copyright (C) 2017 Vaclav Svec. FIT CVUT.
11  *                Copyright (C) 2018-2022 by Fabian Keil <fk@fabiankeil.de>
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
36 #include <openssl/bn.h>
37 #include <openssl/opensslv.h>
38 #include <openssl/pem.h>
39 #include <openssl/md5.h>
40 #include <openssl/x509v3.h>
41
42 #include "config.h"
43 #include "project.h"
44 #include "miscutil.h"
45 #include "errlog.h"
46 #include "encode.h"
47 #include "jcc.h"
48 #include "ssl.h"
49 #include "ssl_common.h"
50
51 /*
52  * Macros for openssl.c
53  */
54 #define CERTIFICATE_BASIC_CONSTRAINTS            "CA:FALSE"
55 #define CERTIFICATE_SUBJECT_KEY                  "hash"
56 #define CERTIFICATE_AUTHORITY_KEY                "keyid:always"
57 #define CERTIFICATE_ALT_NAME_PREFIX              "DNS:"
58 #define CERTIFICATE_VERSION                      2
59 #define VALID_DATETIME_FMT                       "%y%m%d%H%M%SZ"
60 #define VALID_DATETIME_BUFLEN                    16
61
62 static int generate_host_certificate(struct client_state *csp);
63 static void free_client_ssl_structures(struct client_state *csp);
64 static void free_server_ssl_structures(struct client_state *csp);
65 static int ssl_store_cert(struct client_state *csp, X509 *crt);
66 static void log_ssl_errors(int debuglevel, const char* fmt, ...) __attribute__((format(printf, 2, 3)));
67
68 static int ssl_inited = 0;
69
70 #if OPENSSL_VERSION_NUMBER < 0x10100000L
71 #define X509_set1_notBefore X509_set_notBefore
72 #define X509_set1_notAfter X509_set_notAfter
73 #define X509_get0_serialNumber X509_get_serialNumber
74 #define X509_get0_notBefore X509_get_notBefore
75 #define X509_get0_notAfter X509_get_notAfter
76 #endif
77
78 /*********************************************************************
79  *
80  * Function    :  openssl_init
81  *
82  * Description :  Initializes OpenSSL library once
83  *
84  * Parameters  :  N/A
85  *
86  * Returns     :  N/A
87  *
88  *********************************************************************/
89 static void openssl_init(void)
90 {
91    if (ssl_inited == 0)
92    {
93       privoxy_mutex_lock(&ssl_init_mutex);
94       if (ssl_inited == 0)
95       {
96 #if OPENSSL_VERSION_NUMBER < 0x10100000L
97          SSL_library_init();
98 #else
99          OPENSSL_init_ssl(0, NULL);
100 #endif
101          SSL_load_error_strings();
102          OpenSSL_add_ssl_algorithms();
103          ssl_inited = 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
124  *
125  *********************************************************************/
126 extern size_t is_ssl_pending(struct ssl_attr *ssl_attr)
127 {
128    BIO *bio = ssl_attr->openssl_attr.bio;
129    if (bio == NULL)
130    {
131       return 0;
132    }
133
134    return (size_t)BIO_pending(bio);
135 }
136
137
138 /*********************************************************************
139  *
140  * Function    :  ssl_send_data
141  *
142  * Description :  Sends the content of buf (for n bytes) to given SSL
143  *                connection context.
144  *
145  * Parameters  :
146  *          1  :  ssl_attr = SSL context to send data to
147  *          2  :  buf = Pointer to data to be sent
148  *          3  :  len = Length of data to be sent to the SSL context
149  *
150  * Returns     :  Length of sent data or negative value on error.
151  *
152  *********************************************************************/
153 extern int ssl_send_data(struct ssl_attr *ssl_attr, const unsigned char *buf, size_t len)
154 {
155    BIO *bio = ssl_attr->openssl_attr.bio;
156    SSL *ssl;
157    int ret = 0;
158    int pos = 0; /* Position of unsent part in buffer */
159    int fd = -1;
160
161    if (len == 0)
162    {
163       return 0;
164    }
165
166    if (BIO_get_ssl(bio, &ssl) == 1)
167    {
168       fd = SSL_get_fd(ssl);
169    }
170
171    while (pos < len)
172    {
173       int send_len = (int)len - pos;
174
175       log_error(LOG_LEVEL_WRITING, "TLS on socket %d: %N",
176          fd, send_len, buf+pos);
177
178       /*
179        * Sending one part of the buffer
180        */
181       while ((ret = BIO_write(bio,
182          (const unsigned char *)(buf + pos),
183          send_len)) <= 0)
184       {
185          if (!BIO_should_retry(bio))
186          {
187             log_ssl_errors(LOG_LEVEL_ERROR,
188                "Sending data on socket %d over TLS/SSL failed", fd);
189             return -1;
190          }
191       }
192       /* Adding count of sent bytes to position in buffer */
193       pos = pos + ret;
194    }
195
196    return (int)len;
197 }
198
199
200 /*********************************************************************
201  *
202  * Function    :  ssl_recv_data
203  *
204  * Description :  Receives data from given SSL context and puts
205  *                it into buffer.
206  *
207  * Parameters  :
208  *          1  :  ssl_attr = SSL context to receive data from
209  *          2  :  buf = Pointer to buffer where data will be written
210  *          3  :  max_length = Maximum number of bytes to read
211  *
212  * Returns     :  Number of bytes read, 0 for EOF, or -1
213  *                on error.
214  *
215  *********************************************************************/
216 extern int ssl_recv_data(struct ssl_attr *ssl_attr, unsigned char *buf, size_t max_length)
217 {
218    BIO *bio = ssl_attr->openssl_attr.bio;
219    SSL *ssl;
220    int ret = 0;
221    int fd = -1;
222
223    memset(buf, 0, max_length);
224
225    /*
226     * Receiving data from SSL context into buffer
227     */
228    do
229    {
230       ret = BIO_read(bio, buf, (int)max_length);
231    } while (ret <= 0 && BIO_should_retry(bio));
232
233    if (BIO_get_ssl(bio, &ssl) == 1)
234    {
235       fd = SSL_get_fd(ssl);
236    }
237
238    if (ret < 0)
239    {
240       log_ssl_errors(LOG_LEVEL_ERROR,
241          "Receiving data on socket %d over TLS/SSL failed", fd);
242
243       return -1;
244    }
245
246    log_error(LOG_LEVEL_RECEIVED, "TLS from socket %d: %N",
247       fd, ret, buf);
248
249    return ret;
250 }
251
252
253 /*********************************************************************
254  *
255  * Function    :  ssl_store_cert
256  *
257  * Description : This function is called once for each certificate in the
258  *               server's certificate trusted chain and prepares
259  *               information about the certificate. The information can
260  *               be used to inform the user about invalid certificates.
261  *
262  * Parameters  :
263  *          1  :  csp = Current client state (buffers, headers, etc...)
264  *          2  :  crt = certificate from trusted chain
265  *
266  * Returns     :  0 on success and negative value on error
267  *
268  *********************************************************************/
269 static int ssl_store_cert(struct client_state *csp, X509 *crt)
270 {
271    long len;
272    struct certs_chain  *last = &(csp->server_certs_chain);
273    int ret = 0;
274    BIO *bio = BIO_new(BIO_s_mem());
275    EVP_PKEY *pkey = NULL;
276    char *bio_mem_data = NULL;
277    char *encoded_text;
278    long l;
279    const ASN1_INTEGER *bs;
280 #if OPENSSL_VERSION_NUMBER > 0x10100000L
281    const X509_ALGOR *tsig_alg;
282 #endif
283    int loc;
284
285    if (!bio)
286    {
287       log_ssl_errors(LOG_LEVEL_ERROR, "BIO_new() failed");
288       return -1;
289    }
290
291    /*
292     * Searching for last item in certificates linked list
293     */
294    while (last->next != NULL)
295    {
296       last = last->next;
297    }
298
299    /*
300     * Preparing next item in linked list for next certificate
301     */
302    last->next = malloc_or_die(sizeof(struct certs_chain));
303    last->next->next = NULL;
304    memset(last->next->info_buf, 0, sizeof(last->next->info_buf));
305    last->next->file_buf = NULL;
306
307    /*
308     * Saving certificate file into buffer
309     */
310    if (!PEM_write_bio_X509(bio, crt))
311    {
312       log_ssl_errors(LOG_LEVEL_ERROR, "PEM_write_bio_X509() failed");
313       ret = -1;
314       goto exit;
315    }
316
317    len = BIO_get_mem_data(bio, &bio_mem_data);
318
319    last->file_buf = malloc((size_t)len + 1);
320    if (last->file_buf == NULL)
321    {
322       log_error(LOG_LEVEL_ERROR,
323          "Failed to allocate %lu bytes to store the X509 PEM certificate",
324          len + 1);
325       ret = -1;
326       goto exit;
327    }
328
329    strncpy(last->file_buf, bio_mem_data, (size_t)len);
330    last->file_buf[len] = '\0';
331    BIO_free(bio);
332    bio = BIO_new(BIO_s_mem());
333    if (!bio)
334    {
335       log_ssl_errors(LOG_LEVEL_ERROR, "BIO_new() failed");
336       ret = -1;
337       goto exit;
338    }
339
340    /*
341     * Saving certificate information into buffer
342     */
343    l = X509_get_version(crt);
344    if (l >= 0 && l <= 2)
345    {
346       if (BIO_printf(bio, "cert. version     : %ld\n", l + 1) <= 0)
347       {
348          log_ssl_errors(LOG_LEVEL_ERROR, "BIO_printf() for version failed");
349          ret = -1;
350          goto exit;
351       }
352    }
353    else
354    {
355       if (BIO_printf(bio, "cert. version     : Unknown (%ld)\n", l) <= 0)
356       {
357          log_ssl_errors(LOG_LEVEL_ERROR, "BIO_printf() for version failed");
358          ret = -1;
359          goto exit;
360       }
361    }
362
363    if (BIO_puts(bio, "serial number     : ") <= 0)
364    {
365       log_ssl_errors(LOG_LEVEL_ERROR, "BIO_puts() for serial failed");
366       ret = -1;
367       goto exit;
368    }
369    bs = X509_get0_serialNumber(crt);
370    if (bs->length <= (int)sizeof(long))
371    {
372       ERR_set_mark();
373       l = ASN1_INTEGER_get(bs);
374       ERR_pop_to_mark();
375    }
376    else
377    {
378       l = -1;
379    }
380    if (l != -1)
381    {
382       unsigned long ul;
383       const char *neg;
384       if (bs->type == V_ASN1_NEG_INTEGER)
385       {
386          ul = 0 - (unsigned long)l;
387          neg = "-";
388       }
389       else
390       {
391          ul = (unsigned long)l;
392          neg = "";
393       }
394       if (BIO_printf(bio, "%s%lu (%s0x%lx)\n", neg, ul, neg, ul) <= 0)
395       {
396          log_ssl_errors(LOG_LEVEL_ERROR, "BIO_printf() for serial failed");
397          ret = -1;
398          goto exit;
399       }
400    }
401    else
402    {
403       int i;
404       if (bs->type == V_ASN1_NEG_INTEGER)
405       {
406          if (BIO_puts(bio, " (Negative)") < 0)
407          {
408             log_ssl_errors(LOG_LEVEL_ERROR, "BIO_puts() for serial failed");
409             ret = -1;
410             goto exit;
411          }
412       }
413       for (i = 0; i < bs->length; i++)
414       {
415          if (BIO_printf(bio, "%02x%c", bs->data[i],
416                ((i + 1 == bs->length) ? '\n' : ':')) <= 0)
417          {
418             log_ssl_errors(LOG_LEVEL_ERROR, "BIO_printf() for serial failed");
419             ret = -1;
420             goto exit;
421          }
422       }
423    }
424
425    if (BIO_puts(bio, "issuer name       : ") <= 0)
426    {
427       log_ssl_errors(LOG_LEVEL_ERROR, "BIO_puts() for issuer failed");
428       ret = -1;
429       goto exit;
430    }
431    if (X509_NAME_print_ex(bio, X509_get_issuer_name(crt), 0, 0) < 0)
432    {
433       log_ssl_errors(LOG_LEVEL_ERROR, "X509_NAME_print_ex() for issuer failed");
434       ret = -1;
435       goto exit;
436    }
437
438    if (BIO_puts(bio, "\nsubject name      : ") <= 0)
439    {
440       log_ssl_errors(LOG_LEVEL_ERROR, "BIO_puts() for subject failed");
441       ret = -1;
442       goto exit;
443    }
444    if (X509_NAME_print_ex(bio, X509_get_subject_name(crt), 0, 0) < 0) {
445       log_ssl_errors(LOG_LEVEL_ERROR, "X509_NAME_print_ex() for subject failed");
446       ret = -1;
447       goto exit;
448    }
449
450    if (BIO_puts(bio, "\nissued  on        : ") <= 0)
451    {
452       log_ssl_errors(LOG_LEVEL_ERROR, "BIO_puts() for issued on failed");
453       ret = -1;
454       goto exit;
455    }
456    if (!ASN1_TIME_print(bio, X509_get0_notBefore(crt)))
457    {
458       log_ssl_errors(LOG_LEVEL_ERROR, "ASN1_TIME_print() for issued on failed");
459       ret = -1;
460       goto exit;
461    }
462
463    if (BIO_puts(bio, "\nexpires on        : ") <= 0)
464    {
465       log_ssl_errors(LOG_LEVEL_ERROR, "BIO_puts() for expires on failed");
466       ret = -1;
467       goto exit;
468    }
469    if (!ASN1_TIME_print(bio, X509_get0_notAfter(crt)))
470    {
471       log_ssl_errors(LOG_LEVEL_ERROR, "ASN1_TIME_print() for expires on failed");
472       ret = -1;
473       goto exit;
474    }
475
476 #if OPENSSL_VERSION_NUMBER > 0x10100000L
477    if (BIO_puts(bio, "\nsigned using      : ") <= 0)
478    {
479       log_ssl_errors(LOG_LEVEL_ERROR, "BIO_puts() for signed using failed");
480       ret = -1;
481       goto exit;
482    }
483    tsig_alg = X509_get0_tbs_sigalg(crt);
484    if (!i2a_ASN1_OBJECT(bio, tsig_alg->algorithm))
485    {
486       log_ssl_errors(LOG_LEVEL_ERROR, "i2a_ASN1_OBJECT() for signed using failed");
487       ret = -1;
488       goto exit;
489    }
490 #endif
491    pkey = X509_get_pubkey(crt);
492    if (!pkey)
493    {
494       log_ssl_errors(LOG_LEVEL_ERROR, "X509_get_pubkey() failed");
495       ret = -1;
496       goto exit;
497    }
498 #define BC              "18"
499    switch (EVP_PKEY_base_id(pkey))
500    {
501       case EVP_PKEY_RSA:
502          ret = BIO_printf(bio, "\n%-" BC "s: %d bits", "RSA key size", EVP_PKEY_bits(pkey));
503          break;
504       case EVP_PKEY_DSA:
505          ret = BIO_printf(bio, "\n%-" BC "s: %d bits", "DSA key size", EVP_PKEY_bits(pkey));
506          break;
507       case EVP_PKEY_EC:
508          ret = BIO_printf(bio, "\n%-" BC "s: %d bits", "EC key size", EVP_PKEY_bits(pkey));
509          break;
510       default:
511          ret = BIO_printf(bio, "\n%-" BC "s: %d bits", "non-RSA/DSA/EC key size",
512             EVP_PKEY_bits(pkey));
513          break;
514    }
515    if (ret <= 0)
516    {
517       log_ssl_errors(LOG_LEVEL_ERROR, "BIO_printf() for key size failed");
518       ret = -1;
519       goto exit;
520    }
521
522    loc = X509_get_ext_by_NID(crt, NID_basic_constraints, -1);
523    if (loc != -1)
524    {
525       X509_EXTENSION *ex = X509_get_ext(crt, loc);
526       if (BIO_puts(bio, "\nbasic constraints : ") <= 0)
527       {
528          log_ssl_errors(LOG_LEVEL_ERROR,
529             "BIO_printf() for basic constraints failed");
530          ret = -1;
531          goto exit;
532       }
533       if (!X509V3_EXT_print(bio, ex, 0, 0))
534       {
535          if (!ASN1_STRING_print_ex(bio, X509_EXTENSION_get_data(ex), ASN1_STRFLGS_RFC2253))
536          {
537             log_ssl_errors(LOG_LEVEL_ERROR,
538                "ASN1_STRING_print_ex() for basic constraints failed");
539             ret = -1;
540             goto exit;
541          }
542       }
543    }
544
545    loc = X509_get_ext_by_NID(crt, NID_subject_alt_name, -1);
546    if (loc != -1)
547    {
548       X509_EXTENSION *ex = X509_get_ext(crt, loc);
549       if (BIO_puts(bio, "\nsubject alt name  : ") <= 0)
550       {
551          log_ssl_errors(LOG_LEVEL_ERROR, "BIO_printf() for alt name failed");
552          ret = -1;
553          goto exit;
554       }
555       if (!X509V3_EXT_print(bio, ex, 0, 0))
556       {
557          if (!ASN1_STRING_print_ex(bio, X509_EXTENSION_get_data(ex),
558                ASN1_STRFLGS_RFC2253))
559          {
560             log_ssl_errors(LOG_LEVEL_ERROR,
561                "ASN1_STRING_print_ex() for alt name failed");
562             ret = -1;
563             goto exit;
564          }
565       }
566    }
567
568    loc = X509_get_ext_by_NID(crt, NID_netscape_cert_type, -1);
569    if (loc != -1)
570    {
571       X509_EXTENSION *ex = X509_get_ext(crt, loc);
572       if (BIO_puts(bio, "\ncert. type        : ") <= 0)
573       {
574          log_ssl_errors(LOG_LEVEL_ERROR, "BIO_printf() for cert type failed");
575          ret = -1;
576          goto exit;
577       }
578       if (!X509V3_EXT_print(bio, ex, 0, 0))
579       {
580          if (!ASN1_STRING_print_ex(bio, X509_EXTENSION_get_data(ex),
581                ASN1_STRFLGS_RFC2253))
582          {
583             log_ssl_errors(LOG_LEVEL_ERROR,
584                "ASN1_STRING_print_ex() for cert type failed");
585             ret = -1;
586             goto exit;
587          }
588       }
589    }
590
591    loc = X509_get_ext_by_NID(crt, NID_key_usage, -1);
592    if (loc != -1)
593    {
594       X509_EXTENSION *ex = X509_get_ext(crt, loc);
595       if (BIO_puts(bio, "\nkey usage         : ") <= 0)
596       {
597          log_ssl_errors(LOG_LEVEL_ERROR, "BIO_printf() for key usage failed");
598          ret = -1;
599          goto exit;
600       }
601       if (!X509V3_EXT_print(bio, ex, 0, 0))
602       {
603          if (!ASN1_STRING_print_ex(bio, X509_EXTENSION_get_data(ex),
604                ASN1_STRFLGS_RFC2253))
605          {
606             log_ssl_errors(LOG_LEVEL_ERROR,
607                "ASN1_STRING_print_ex() for key usage failed");
608             ret = -1;
609             goto exit;
610          }
611       }
612    }
613
614    loc = X509_get_ext_by_NID(crt, NID_ext_key_usage, -1);
615    if (loc != -1) {
616       X509_EXTENSION *ex = X509_get_ext(crt, loc);
617       if (BIO_puts(bio, "\next key usage     : ") <= 0)
618       {
619          log_ssl_errors(LOG_LEVEL_ERROR,
620             "BIO_printf() for ext key usage failed");
621          ret = -1;
622          goto exit;
623       }
624       if (!X509V3_EXT_print(bio, ex, 0, 0))
625       {
626          if (!ASN1_STRING_print_ex(bio, X509_EXTENSION_get_data(ex),
627                ASN1_STRFLGS_RFC2253))
628          {
629             log_ssl_errors(LOG_LEVEL_ERROR,
630                "ASN1_STRING_print_ex() for ext key usage failed");
631             ret = -1;
632             goto exit;
633          }
634       }
635    }
636
637    loc = X509_get_ext_by_NID(crt, NID_certificate_policies, -1);
638    if (loc != -1)
639    {
640       X509_EXTENSION *ex = X509_get_ext(crt, loc);
641       if (BIO_puts(bio, "\ncertificate policies : ") <= 0)
642       {
643          log_ssl_errors(LOG_LEVEL_ERROR, "BIO_printf() for certificate policies failed");
644          ret = -1;
645          goto exit;
646       }
647       if (!X509V3_EXT_print(bio, ex, 0, 0))
648       {
649          if (!ASN1_STRING_print_ex(bio, X509_EXTENSION_get_data(ex),
650                ASN1_STRFLGS_RFC2253))
651          {
652             log_ssl_errors(LOG_LEVEL_ERROR,
653                "ASN1_STRING_print_ex() for certificate policies failed");
654             ret = -1;
655             goto exit;
656          }
657       }
658    }
659
660    /* make valgrind happy */
661    static const char zero = 0;
662    BIO_write(bio, &zero, 1);
663
664    len = BIO_get_mem_data(bio, &bio_mem_data);
665    if (len <= 0)
666    {
667       log_error(LOG_LEVEL_ERROR, "BIO_get_mem_data() returned %ld "
668          "while gathering certificate information", len);
669       ret = -1;
670       goto exit;
671    }
672    encoded_text = html_encode(bio_mem_data);
673    if (encoded_text == NULL)
674    {
675       log_error(LOG_LEVEL_ERROR,
676          "Failed to HTML-encode the certificate information");
677       ret = -1;
678       goto exit;
679    }
680
681    strlcpy(last->info_buf, encoded_text, sizeof(last->info_buf));
682    freez(encoded_text);
683    ret = 0;
684
685 exit:
686    if (bio)
687    {
688       BIO_free(bio);
689    }
690    if (pkey)
691    {
692       EVP_PKEY_free(pkey);
693    }
694    return ret;
695 }
696
697
698 /*********************************************************************
699  *
700  * Function    :  host_to_hash
701  *
702  * Description :  Creates MD5 hash from host name. Host name is loaded
703  *                from structure csp and saved again into it.
704  *
705  * Parameters  :
706  *          1  :  csp = Current client state (buffers, headers, etc...)
707  *
708  * Returns     : -1 => Error while creating hash
709  *                0 => Hash created successfully
710  *
711  *********************************************************************/
712 static int host_to_hash(struct client_state *csp)
713 {
714    int ret = 0;
715
716    memset(csp->http->hash_of_host, 0, sizeof(csp->http->hash_of_host));
717    MD5((unsigned char *)csp->http->host, strlen(csp->http->host),
718       csp->http->hash_of_host);
719
720    /* Converting hash into string with hex */
721    size_t i = 0;
722    for (; i < 16; i++)
723    {
724       if ((ret = sprintf((char *)csp->http->hash_of_host_hex + 2 * i, "%02x",
725          csp->http->hash_of_host[i])) < 0)
726       {
727          log_error(LOG_LEVEL_ERROR, "Sprintf return value: %d", ret);
728          return -1;
729       }
730    }
731
732    return 0;
733 }
734
735
736 /*********************************************************************
737  *
738  * Function    :  create_client_ssl_connection
739  *
740  * Description :  Creates TLS/SSL secured connection with client
741  *
742  * Parameters  :
743  *          1  :  csp = Current client state (buffers, headers, etc...)
744  *
745  * Returns     :  0 on success, negative value if connection wasn't created
746  *                successfully.
747  *
748  *********************************************************************/
749 extern int create_client_ssl_connection(struct client_state *csp)
750 {
751    struct ssl_attr *ssl_attr = &csp->ssl_client_attr;
752    /* Paths to certificates file and key file */
753    char *key_file  = NULL;
754    char *cert_file = NULL;
755    int ret = 0;
756    SSL *ssl;
757
758    /*
759     * Initializing OpenSSL structures for TLS/SSL connection
760     */
761    openssl_init();
762
763    /*
764     * Preparing hash of host for creating certificates
765     */
766    ret = host_to_hash(csp);
767    if (ret != 0)
768    {
769       log_error(LOG_LEVEL_ERROR, "Generating hash of host failed: %d", ret);
770       ret = -1;
771       goto exit;
772    }
773
774    /*
775     * Preparing paths to certificates files and key file
776     */
777    cert_file = make_certs_path(csp->config->certificate_directory,
778       (const char *)csp->http->hash_of_host_hex, CERT_FILE_TYPE);
779    key_file  = make_certs_path(csp->config->certificate_directory,
780       (const char *)csp->http->hash_of_host_hex, KEY_FILE_TYPE);
781
782    if (cert_file == NULL || key_file == NULL)
783    {
784       ret = -1;
785       goto exit;
786    }
787
788    /*
789     * Generating certificate for requested host. Mutex to prevent
790     * certificate and key inconsistence must be locked.
791     */
792    privoxy_mutex_lock(&certificate_mutex);
793
794    ret = generate_host_certificate(csp);
795    if (ret < 0)
796    {
797       log_error(LOG_LEVEL_ERROR,
798          "generate_host_certificate failed: %d", ret);
799       privoxy_mutex_unlock(&certificate_mutex);
800       ret = -1;
801       goto exit;
802    }
803    privoxy_mutex_unlock(&certificate_mutex);
804
805    if (!(ssl_attr->openssl_attr.ctx = SSL_CTX_new(SSLv23_server_method())))
806    {
807       log_ssl_errors(LOG_LEVEL_ERROR, "Unable to create SSL context");
808       ret = -1;
809       goto exit;
810    }
811
812    /* Set the key and cert */
813    if (SSL_CTX_use_certificate_file(ssl_attr->openssl_attr.ctx,
814          cert_file, SSL_FILETYPE_PEM) != 1)
815    {
816       log_ssl_errors(LOG_LEVEL_ERROR,
817          "Loading webpage certificate %s failed", cert_file);
818       ret = -1;
819       goto exit;
820    }
821
822    if (SSL_CTX_use_PrivateKey_file(ssl_attr->openssl_attr.ctx,
823          key_file, SSL_FILETYPE_PEM) != 1)
824    {
825       log_ssl_errors(LOG_LEVEL_ERROR,
826          "Loading webpage certificate private key %s failed", key_file);
827       ret = -1;
828       goto exit;
829    }
830
831    SSL_CTX_set_options(ssl_attr->openssl_attr.ctx, SSL_OP_NO_SSLv3);
832
833    if (!(ssl_attr->openssl_attr.bio = BIO_new_ssl(ssl_attr->openssl_attr.ctx, 0)))
834    {
835       log_ssl_errors(LOG_LEVEL_ERROR, "Unable to create BIO structure");
836       ret = -1;
837       goto exit;
838    }
839
840    if (BIO_get_ssl(ssl_attr->openssl_attr.bio, &ssl) != 1)
841    {
842       log_ssl_errors(LOG_LEVEL_ERROR, "BIO_get_ssl failed");
843       ret = -1;
844       goto exit;
845    }
846
847    if (!SSL_set_fd(ssl, csp->cfd))
848    {
849       log_ssl_errors(LOG_LEVEL_ERROR, "SSL_set_fd failed");
850       ret = -1;
851       goto exit;
852    }
853
854    if (csp->config->cipher_list != NULL)
855    {
856       if (!SSL_set_cipher_list(ssl, csp->config->cipher_list))
857       {
858          log_ssl_errors(LOG_LEVEL_ERROR,
859             "Setting the cipher list '%s' for the client connection failed",
860             csp->config->cipher_list);
861          ret = -1;
862          goto exit;
863       }
864    }
865
866    /*
867     *  Handshake with client
868     */
869    log_error(LOG_LEVEL_CONNECT,
870       "Performing the TLS/SSL handshake with client. Hash of host: %s",
871       csp->http->hash_of_host_hex);
872    if (BIO_do_handshake(ssl_attr->openssl_attr.bio) != 1)
873    {
874        log_ssl_errors(LOG_LEVEL_ERROR,
875           "The TLS/SSL handshake with the client failed");
876        ret = -1;
877        goto exit;
878    }
879
880    log_error(LOG_LEVEL_CONNECT, "Client successfully connected over %s (%s).",
881       SSL_get_version(ssl), SSL_get_cipher_name(ssl));
882
883    csp->ssl_with_client_is_opened = 1;
884    ret = 0;
885
886 exit:
887    /*
888     * Freeing allocated paths to files
889     */
890    freez(cert_file);
891    freez(key_file);
892
893    /* Freeing structures if connection wasn't created successfully */
894    if (ret < 0)
895    {
896       free_client_ssl_structures(csp);
897    }
898    return ret;
899 }
900
901
902 /*********************************************************************
903  *
904  * Function    :  close_client_ssl_connection
905  *
906  * Description :  Closes TLS/SSL connection with client. This function
907  *                checks if this connection is already created.
908  *
909  * Parameters  :
910  *          1  :  csp = Current client state (buffers, headers, etc...)
911  *
912  * Returns     :  N/A
913  *
914  *********************************************************************/
915 extern void close_client_ssl_connection(struct client_state *csp)
916 {
917    struct ssl_attr *ssl_attr = &csp->ssl_client_attr;
918    SSL *ssl;
919
920    if (csp->ssl_with_client_is_opened == 0)
921    {
922       return;
923    }
924
925    /*
926     * Notifying the peer that the connection is being closed.
927     */
928    BIO_ssl_shutdown(ssl_attr->openssl_attr.bio);
929    if (BIO_get_ssl(ssl_attr->openssl_attr.bio, &ssl) != 1)
930    {
931       log_ssl_errors(LOG_LEVEL_ERROR,
932          "BIO_get_ssl() failed in close_client_ssl_connection()");
933    }
934    else
935    {
936       /*
937        * Pretend we received a shutdown alert so
938        * the BIO_free_all() call later on returns
939        * quickly.
940        */
941       SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN);
942    }
943    free_client_ssl_structures(csp);
944    csp->ssl_with_client_is_opened = 0;
945 }
946
947
948 /*********************************************************************
949  *
950  * Function    :  free_client_ssl_structures
951  *
952  * Description :  Frees structures used for SSL communication with
953  *                client.
954  *
955  * Parameters  :
956  *          1  :  csp = Current client state (buffers, headers, etc...)
957  *
958  * Returns     :  N/A
959  *
960  *********************************************************************/
961 static void free_client_ssl_structures(struct client_state *csp)
962 {
963    struct ssl_attr *ssl_attr = &csp->ssl_client_attr;
964
965    if (ssl_attr->openssl_attr.bio)
966    {
967       BIO_free_all(ssl_attr->openssl_attr.bio);
968    }
969    if (ssl_attr->openssl_attr.ctx)
970    {
971       SSL_CTX_free(ssl_attr->openssl_attr.ctx);
972    }
973 }
974
975
976 /*********************************************************************
977  *
978  * Function    :  close_server_ssl_connection
979  *
980  * Description :  Closes TLS/SSL connection with server. This function
981  *                checks if this connection is already opened.
982  *
983  * Parameters  :
984  *          1  :  csp = Current client state (buffers, headers, etc...)
985  *
986  * Returns     :  N/A
987  *
988  *********************************************************************/
989 extern void close_server_ssl_connection(struct client_state *csp)
990 {
991    struct ssl_attr *ssl_attr = &csp->ssl_server_attr;
992    SSL *ssl;
993
994    if (csp->ssl_with_server_is_opened == 0)
995    {
996       return;
997    }
998
999    /*
1000    * Notifying the peer that the connection is being closed.
1001    */
1002    BIO_ssl_shutdown(ssl_attr->openssl_attr.bio);
1003    if (BIO_get_ssl(ssl_attr->openssl_attr.bio, &ssl) != 1)
1004    {
1005       log_ssl_errors(LOG_LEVEL_ERROR,
1006          "BIO_get_ssl() failed in close_server_ssl_connection()");
1007    }
1008    else
1009    {
1010       /*
1011        * Pretend we received a shutdown alert so
1012        * the BIO_free_all() call later on returns
1013        * quickly.
1014        */
1015       SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN);
1016    }
1017    free_server_ssl_structures(csp);
1018    csp->ssl_with_server_is_opened = 0;
1019 }
1020
1021
1022 /*********************************************************************
1023  *
1024  * Function    :  create_server_ssl_connection
1025  *
1026  * Description :  Creates TLS/SSL secured connection with server.
1027  *
1028  * Parameters  :
1029  *          1  :  csp = Current client state (buffers, headers, etc...)
1030  *
1031  * Returns     :  0 on success, negative value if connection wasn't created
1032  *                successfully.
1033  *
1034  *********************************************************************/
1035 extern int create_server_ssl_connection(struct client_state *csp)
1036 {
1037    openssl_connection_attr *ssl_attrs = &csp->ssl_server_attr.openssl_attr;
1038    int ret = 0;
1039    char *trusted_cas_file = NULL;
1040    STACK_OF(X509) *chain;
1041    SSL *ssl;
1042
1043    csp->server_cert_verification_result = SSL_CERT_NOT_VERIFIED;
1044    csp->server_certs_chain.next = NULL;
1045
1046    /* Setting path to file with trusted CAs */
1047    trusted_cas_file = csp->config->trusted_cas_file;
1048
1049    ssl_attrs->ctx = SSL_CTX_new(SSLv23_method());
1050    if (!ssl_attrs->ctx)
1051    {
1052       log_ssl_errors(LOG_LEVEL_ERROR, "SSL context creation failed");
1053       ret = -1;
1054       goto exit;
1055    }
1056
1057    /*
1058     * Loading file with trusted CAs
1059     */
1060    if (!SSL_CTX_load_verify_locations(ssl_attrs->ctx, trusted_cas_file, NULL))
1061    {
1062       log_ssl_errors(LOG_LEVEL_ERROR, "Loading trusted CAs file %s failed",
1063          trusted_cas_file);
1064       ret = -1;
1065       goto exit;
1066    }
1067
1068    SSL_CTX_set_verify(ssl_attrs->ctx, SSL_VERIFY_NONE, NULL);
1069    SSL_CTX_set_options(ssl_attrs->ctx, SSL_OP_NO_SSLv3);
1070
1071    if (!(ssl_attrs->bio = BIO_new_ssl(ssl_attrs->ctx, 1)))
1072    {
1073       log_ssl_errors(LOG_LEVEL_ERROR, "Unable to create BIO structure");
1074       ret = -1;
1075       goto exit;
1076    }
1077
1078    if (BIO_get_ssl(ssl_attrs->bio, &ssl) != 1)
1079    {
1080       log_ssl_errors(LOG_LEVEL_ERROR, "BIO_get_ssl failed");
1081       ret = -1;
1082       goto exit;
1083    }
1084
1085    if (!SSL_set_fd(ssl, csp->server_connection.sfd))
1086    {
1087       log_ssl_errors(LOG_LEVEL_ERROR, "SSL_set_fd failed");
1088       ret = -1;
1089       goto exit;
1090    }
1091
1092    if (csp->config->cipher_list != NULL)
1093    {
1094       if (!SSL_set_cipher_list(ssl, csp->config->cipher_list))
1095       {
1096          log_ssl_errors(LOG_LEVEL_ERROR,
1097             "Setting the cipher list '%s' for the server connection failed",
1098             csp->config->cipher_list);
1099          ret = -1;
1100          goto exit;
1101       }
1102    }
1103
1104    /*
1105     * Set the hostname to check against the received server certificate
1106     */
1107 #if OPENSSL_VERSION_NUMBER > 0x10100000L
1108    if (!SSL_set1_host(ssl, csp->http->host))
1109    {
1110       log_ssl_errors(LOG_LEVEL_ERROR, "SSL_set1_host failed");
1111       ret = -1;
1112       goto exit;
1113    }
1114 #else
1115    if (host_is_ip_address(csp->http->host))
1116    {
1117       if (X509_VERIFY_PARAM_set1_ip_asc(ssl->param,  csp->http->host) != 1)
1118       {
1119          log_ssl_errors(LOG_LEVEL_ERROR,
1120             "X509_VERIFY_PARAM_set1_ip_asc() failed");
1121          ret = -1;
1122          goto exit;
1123       }
1124    }
1125    else
1126    {
1127       if (X509_VERIFY_PARAM_set1_host(ssl->param,  csp->http->host, 0) != 1)
1128       {
1129          log_ssl_errors(LOG_LEVEL_ERROR,
1130             "X509_VERIFY_PARAM_set1_host() failed");
1131          ret = -1;
1132          goto exit;
1133       }
1134    }
1135 #endif
1136    /* SNI extension */
1137    if (!SSL_set_tlsext_host_name(ssl, csp->http->host))
1138    {
1139       log_ssl_errors(LOG_LEVEL_ERROR, "SSL_set_tlsext_host_name failed");
1140       ret = -1;
1141       goto exit;
1142    }
1143
1144    /*
1145     * Handshake with server
1146     */
1147    log_error(LOG_LEVEL_CONNECT,
1148       "Performing the TLS/SSL handshake with the server");
1149
1150    if (BIO_do_handshake(ssl_attrs->bio) != 1)
1151    {
1152       log_ssl_errors(LOG_LEVEL_ERROR,
1153          "The TLS/SSL handshake with the server failed");
1154       ret = -1;
1155       goto exit;
1156    }
1157
1158    /*
1159     * XXX: Do we really have to do this always?
1160     *      Probably it's sufficient to do if the verification fails
1161     *      in which case we're sending the certificates to the client.
1162     */
1163    chain = SSL_get_peer_cert_chain(ssl);
1164    if (chain)
1165    {
1166       int i;
1167       for (i = 0; i < sk_X509_num(chain); i++)
1168       {
1169          if (ssl_store_cert(csp, sk_X509_value(chain, i)) != 0)
1170          {
1171             log_error(LOG_LEVEL_ERROR, "ssl_store_cert failed");
1172             ret = -1;
1173             goto exit;
1174          }
1175       }
1176    }
1177
1178    if (!csp->dont_verify_certificate)
1179    {
1180       long verify_result = SSL_get_verify_result(ssl);
1181       if (verify_result == X509_V_OK)
1182       {
1183          ret = 0;
1184          csp->server_cert_verification_result = SSL_CERT_VALID;
1185       }
1186       else
1187       {
1188          csp->server_cert_verification_result = verify_result;
1189          log_error(LOG_LEVEL_ERROR,
1190             "X509 certificate verification for %s failed: %s",
1191             csp->http->hostport, X509_verify_cert_error_string(verify_result));
1192          ret = -1;
1193          goto exit;
1194       }
1195    }
1196
1197    log_error(LOG_LEVEL_CONNECT, "Server successfully connected over %s (%s).",
1198      SSL_get_version(ssl), SSL_get_cipher_name(ssl));
1199
1200    /*
1201     * Server certificate chain is valid, so we can clean
1202     * chain, because we will not send it to client.
1203     */
1204    free_certificate_chain(csp);
1205
1206    csp->ssl_with_server_is_opened = 1;
1207 exit:
1208    /* Freeing structures if connection wasn't created successfully */
1209    if (ret < 0)
1210    {
1211       free_server_ssl_structures(csp);
1212    }
1213
1214    return ret;
1215 }
1216
1217
1218 /*********************************************************************
1219  *
1220  * Function    :  free_server_ssl_structures
1221  *
1222  * Description :  Frees structures used for SSL communication with server
1223  *
1224  * Parameters  :
1225  *          1  :  csp = Current client state (buffers, headers, etc...)
1226  *
1227  * Returns     :  N/A
1228  *
1229  *********************************************************************/
1230 static void free_server_ssl_structures(struct client_state *csp)
1231 {
1232    struct ssl_attr *ssl_attr = &csp->ssl_server_attr;
1233
1234    if (ssl_attr->openssl_attr.bio)
1235    {
1236       BIO_free_all(ssl_attr->openssl_attr.bio);
1237    }
1238    if (ssl_attr->openssl_attr.ctx)
1239    {
1240       SSL_CTX_free(ssl_attr->openssl_attr.ctx);
1241    }
1242 }
1243
1244
1245 /*********************************************************************
1246  *
1247  * Function    :  log_ssl_errors
1248  *
1249  * Description :  Log SSL errors
1250  *
1251  * Parameters  :
1252  *          1  :  debuglevel = Debug level
1253  *          2  :  desc = Error description
1254  *
1255  * Returns     :  N/A
1256  *
1257  *********************************************************************/
1258 static void log_ssl_errors(int debuglevel, const char* fmt, ...)
1259 {
1260    unsigned long err_code;
1261    char prefix[ERROR_BUF_SIZE];
1262    va_list args;
1263    va_start(args, fmt);
1264    vsnprintf(prefix, sizeof(prefix), fmt, args);
1265    int reported = 0;
1266
1267    while ((err_code = ERR_get_error()))
1268    {
1269       char err_buf[ERROR_BUF_SIZE];
1270       reported = 1;
1271       ERR_error_string_n(err_code, err_buf, sizeof(err_buf));
1272       log_error(debuglevel, "%s: %s", prefix, err_buf);
1273    }
1274    va_end(args);
1275    /*
1276     * In case if called by mistake and there were
1277     * no TLS/SSL errors let's report it to the log.
1278     */
1279    if (!reported)
1280    {
1281       log_error(debuglevel, "%s: no TLS/SSL errors detected", prefix);
1282    }
1283 }
1284
1285
1286 /*********************************************************************
1287  *
1288  * Function    :  ssl_base64_encode
1289  *
1290  * Description :  Encode a buffer into base64 format.
1291  *
1292  * Parameters  :
1293  *          1  :  dst = Destination buffer
1294  *          2  :  dlen = Destination buffer length
1295  *          3  :  olen = Number of bytes written
1296  *          4  :  src = Source buffer
1297  *          5  :  slen = Amount of data to be encoded
1298  *
1299  * Returns     :  0 on success, error code othervise
1300  *
1301  *********************************************************************/
1302 extern int ssl_base64_encode(unsigned char *dst, size_t dlen, size_t *olen,
1303                              const unsigned char *src, size_t slen)
1304 {
1305    *olen = 4 * ((slen/3) + ((slen%3) ? 1 : 0)) + 1;
1306    if (*olen > dlen)
1307    {
1308       return ENOBUFS;
1309    }
1310    *olen = (size_t)EVP_EncodeBlock(dst, src, (int)slen) + 1;
1311    return 0;
1312 }
1313
1314
1315 /*********************************************************************
1316  *
1317  * Function    :  close_file_stream
1318  *
1319  * Description :  Close file stream, report error on close error
1320  *
1321  * Parameters  :
1322  *          1  :  f = file stream to close
1323  *          2  :  path = path for error report
1324  *
1325  * Returns     :  N/A
1326  *
1327  *********************************************************************/
1328 static void close_file_stream(FILE *f, const char *path)
1329 {
1330    if (fclose(f) != 0)
1331    {
1332       log_error(LOG_LEVEL_ERROR,
1333          "Error closing file %s: %s", path, strerror(errno));
1334    }
1335 }
1336
1337
1338 /*********************************************************************
1339  *
1340  * Function    :  write_certificate
1341  *
1342  * Description :  Writes certificate into file.
1343  *
1344  * Parameters  :
1345  *          1  :  crt = certificate to write into file
1346  *          2  :  output_file = path to save certificate file
1347  *
1348  *                on error
1349  * Returns     :  1 on success success or negative value
1350  *
1351  *********************************************************************/
1352 static int write_certificate(X509 *crt, const char *output_file)
1353 {
1354    FILE *f = NULL;
1355    int ret = -1;
1356
1357    /*
1358     * Saving certificate into file
1359     */
1360    if ((f = fopen(output_file, "w")) == NULL)
1361    {
1362       log_error(LOG_LEVEL_ERROR, "Opening file %s to save certificate failed",
1363          output_file);
1364       return ret;
1365    }
1366
1367    ret = PEM_write_X509(f, crt);
1368    if (!ret)
1369    {
1370       log_ssl_errors(LOG_LEVEL_ERROR,
1371          "Writing certificate into file %s failed", output_file);
1372       ret = -1;
1373    }
1374
1375    close_file_stream(f, output_file);
1376
1377    return ret;
1378 }
1379
1380 /*********************************************************************
1381  *
1382  * Function    :  write_private_key
1383  *
1384  * Description :  Writes private key into file and copies saved
1385  *                content into given pointer to string. If function
1386  *                returns 0 for success, this copy must be freed by
1387  *                caller.
1388  *
1389  * Parameters  :
1390  *          1  :  key = key to write into file
1391  *          2  :  ret_buf = pointer to string with created key file content
1392  *          3  :  key_file_path = path where to save key file
1393  *
1394  * Returns     :  Length of written private key on success or negative value
1395  *                on error
1396  *
1397  *********************************************************************/
1398 static int write_private_key(EVP_PKEY *key, char **ret_buf,
1399                              const char *key_file_path)
1400 {
1401    size_t len = 0;                /* Length of created key    */
1402    FILE *f = NULL;                /* File to save certificate */
1403    int ret = 0;
1404    BIO *bio_mem = BIO_new(BIO_s_mem());
1405    char *bio_mem_data = 0;
1406
1407    if (bio_mem == NULL)
1408    {
1409       log_ssl_errors(LOG_LEVEL_ERROR, "write_private_key memory allocation failure");
1410       return -1;
1411    }
1412
1413    /*
1414     * Writing private key into PEM string
1415     */
1416    if (!PEM_write_bio_PrivateKey(bio_mem, key, NULL, NULL, 0, NULL, NULL))
1417    {
1418       log_ssl_errors(LOG_LEVEL_ERROR,
1419          "Writing private key into PEM string failed");
1420       ret = -1;
1421       goto exit;
1422    }
1423
1424    len = (size_t)BIO_get_mem_data(bio_mem, &bio_mem_data);
1425
1426    /* Initializing buffer for key file content */
1427    *ret_buf = zalloc_or_die(len + 1);
1428    (*ret_buf)[len] = 0;
1429
1430    strncpy(*ret_buf, bio_mem_data, len);
1431
1432    /*
1433     * Saving key into file
1434     */
1435    if ((f = fopen(key_file_path, "wb")) == NULL)
1436    {
1437       log_error(LOG_LEVEL_ERROR,
1438          "Opening file %s to save private key failed: %E",
1439          key_file_path);
1440       ret = -1;
1441       goto exit;
1442    }
1443
1444    if (fwrite(*ret_buf, 1, len, f) != len)
1445    {
1446       log_error(LOG_LEVEL_ERROR,
1447          "Writing private key into file %s failed",
1448          key_file_path);
1449       close_file_stream(f, key_file_path);
1450       ret = -1;
1451       goto exit;
1452    }
1453
1454    close_file_stream(f, key_file_path);
1455
1456 exit:
1457    BIO_free(bio_mem);
1458    if (ret < 0)
1459    {
1460       freez(*ret_buf);
1461       *ret_buf = NULL;
1462       return ret;
1463    }
1464    return (int)len;
1465 }
1466
1467
1468 /*********************************************************************
1469  *
1470  * Function    :  generate_key
1471  *
1472  * Description : Tests if private key for host saved in csp already
1473  *               exists.  If this file doesn't exists, a new key is
1474  *               generated and saved in a file. The generated key is also
1475  *               copied into given parameter key_buf, which must be then
1476  *               freed by caller. If file with key exists, key_buf
1477  *               contain NULL and no private key is generated.
1478  *
1479  * Parameters  :
1480  *          1  :  csp = Current client state (buffers, headers, etc...)
1481  *          2  :  key_buf = buffer to save new generated key
1482  *
1483  * Returns     :  -1 => Error while generating private key
1484  *                 0 => Key already exists
1485  *                >0 => Length of generated private key
1486  *
1487  *********************************************************************/
1488 static int generate_key(struct client_state *csp, char **key_buf)
1489 {
1490    int ret = 0;
1491    char* key_file_path;
1492    BIGNUM *exp;
1493    RSA *rsa;
1494    EVP_PKEY *key;
1495
1496    key_file_path = make_certs_path(csp->config->certificate_directory,
1497       (char *)csp->http->hash_of_host_hex, KEY_FILE_TYPE);
1498    if (key_file_path == NULL)
1499    {
1500       return -1;
1501    }
1502
1503    /*
1504     * Test if key already exists. If so, we don't have to create it again.
1505     */
1506    if (file_exists(key_file_path) == 1)
1507    {
1508       freez(key_file_path);
1509       return 0;
1510    }
1511
1512    exp = BN_new();
1513    rsa = RSA_new();
1514    key = EVP_PKEY_new();
1515    if (exp == NULL || rsa == NULL || key == NULL)
1516    {
1517       log_ssl_errors(LOG_LEVEL_ERROR, "RSA key memory allocation failure");
1518       ret = -1;
1519       goto exit;
1520    }
1521
1522    if (BN_set_word(exp, RSA_KEY_PUBLIC_EXPONENT) != 1)
1523    {
1524       log_ssl_errors(LOG_LEVEL_ERROR, "Setting RSA key exponent failed");
1525       ret = -1;
1526       goto exit;
1527    }
1528
1529    ret = RSA_generate_key_ex(rsa, RSA_KEYSIZE, exp, NULL);
1530    if (ret == 0)
1531    {
1532       log_ssl_errors(LOG_LEVEL_ERROR, "RSA key generation failure");
1533       ret = -1;
1534       goto exit;
1535    }
1536
1537    if (!EVP_PKEY_set1_RSA(key, rsa))
1538    {
1539       log_ssl_errors(LOG_LEVEL_ERROR,
1540          "Error assigning RSA key pair to PKEY structure");
1541       ret = -1;
1542       goto exit;
1543    }
1544
1545    /*
1546     * Exporting private key into file
1547     */
1548    if ((ret = write_private_key(key, key_buf, key_file_path)) < 0)
1549    {
1550       log_error(LOG_LEVEL_ERROR,
1551          "Writing private key into file %s failed", key_file_path);
1552       ret = -1;
1553       goto exit;
1554    }
1555
1556 exit:
1557    /*
1558     * Freeing used variables
1559     */
1560    if (exp)
1561    {
1562       BN_free(exp);
1563    }
1564    if (rsa)
1565    {
1566       RSA_free(rsa);
1567    }
1568    if (key)
1569    {
1570       EVP_PKEY_free(key);
1571    }
1572    freez(key_file_path);
1573
1574    return ret;
1575 }
1576
1577
1578 /*********************************************************************
1579  *
1580  * Function    :  ssl_certificate_load
1581  *
1582  * Description :  Loads certificate from file.
1583  *
1584  * Parameters  :
1585  *          1  :  cert_path = The certificate path to load
1586  *
1587  * Returns     :   NULL => error loading certificate,
1588  *                   pointer to certificate instance otherwise
1589  *
1590  *********************************************************************/
1591 static X509 *ssl_certificate_load(const char *cert_path)
1592 {
1593    X509 *cert = NULL;
1594    FILE *cert_f = NULL;
1595
1596    if (!(cert_f = fopen(cert_path, "r")))
1597    {
1598       log_error(LOG_LEVEL_ERROR,
1599          "Error opening certificate file %s: %s", cert_path, strerror(errno));
1600       return NULL;
1601    }
1602
1603    if (!(cert = PEM_read_X509(cert_f, NULL, NULL, NULL)))
1604    {
1605       log_ssl_errors(LOG_LEVEL_ERROR,
1606          "Error reading certificate file %s", cert_path);
1607    }
1608
1609    close_file_stream(cert_f, cert_path);
1610    return cert;
1611 }
1612
1613
1614 /*********************************************************************
1615  *
1616  * Function    :  ssl_certificate_is_invalid
1617  *
1618  * Description :  Checks whether or not a certificate is valid.
1619  *                Currently only checks that the certificate can be
1620  *                parsed and that the "valid to" date is in the future.
1621  *
1622  * Parameters  :
1623  *          1  :  cert_file = The certificate to check
1624  *
1625  * Returns     :   0 => The certificate is valid.
1626  *                 1 => The certificate is invalid
1627  *
1628  *********************************************************************/
1629 static int ssl_certificate_is_invalid(const char *cert_file)
1630 {
1631    int ret;
1632
1633    X509 *cert = NULL;
1634
1635    if (!(cert = ssl_certificate_load(cert_file)))
1636    {
1637       return 1;
1638    }
1639
1640    ret = X509_cmp_current_time(X509_get_notAfter(cert));
1641    if (ret == 0)
1642    {
1643       log_ssl_errors(LOG_LEVEL_ERROR,
1644          "Error checking certificate %s validity", cert_file);
1645       ret = -1;
1646    }
1647
1648    X509_free(cert);
1649
1650    return ret == -1 ? 1 : 0;
1651 }
1652
1653
1654 /*********************************************************************
1655  *
1656  * Function    :  set_x509_ext
1657  *
1658  * Description :  Sets the X509V3 extension data
1659  *
1660  * Parameters  :
1661  *          1  :  cert = The certificate to modify
1662  *          2  :  issuer = Issuer certificate
1663  *          3  :  nid = OpenSSL NID
1664  *          4  :  value = extension value
1665  *
1666  * Returns     :   0 => Error while setting extension data
1667  *                 1 => It worked
1668  *
1669  *********************************************************************/
1670 static int set_x509_ext(X509 *cert, X509 *issuer, int nid, char *value)
1671 {
1672    X509_EXTENSION *ext = NULL;
1673    X509V3_CTX ctx;
1674    int ret = 0;
1675
1676    X509V3_set_ctx(&ctx, issuer, cert, NULL, NULL, 0);
1677    ext = X509V3_EXT_conf_nid(NULL, &ctx, nid, value);
1678    if (!ext)
1679    {
1680       log_ssl_errors(LOG_LEVEL_ERROR, "X509V3_EXT_conf_nid failure");
1681       goto exit;
1682    }
1683
1684    if (!X509_add_ext(cert, ext, -1))
1685    {
1686       log_ssl_errors(LOG_LEVEL_ERROR, "X509_add_ext failure");
1687       goto exit;
1688    }
1689
1690    ret = 1;
1691 exit:
1692    if (ext)
1693    {
1694       X509_EXTENSION_free(ext);
1695    }
1696    return ret;
1697 }
1698
1699
1700 /*********************************************************************
1701  *
1702  * Function    :  set_subject_alternative_name
1703  *
1704  * Description :  Sets the Subject Alternative Name extension to a cert
1705  *
1706  * Parameters  :
1707  *          1  :  cert = The certificate to modify
1708  *          2  :  issuer = Issuer certificate
1709  *          3  :  hostname = The hostname to add
1710  *
1711  * Returns     :   0 => Error while creating certificate.
1712  *                 1 => It worked
1713  *
1714  *********************************************************************/
1715 static int set_subject_alternative_name(X509 *cert, X509 *issuer, const char *hostname)
1716 {
1717    size_t altname_len = strlen(hostname) + sizeof(CERTIFICATE_ALT_NAME_PREFIX);
1718    char alt_name_buf[altname_len];
1719
1720    snprintf(alt_name_buf, sizeof(alt_name_buf),
1721       CERTIFICATE_ALT_NAME_PREFIX"%s", hostname);
1722    return set_x509_ext(cert, issuer, NID_subject_alt_name, alt_name_buf);
1723 }
1724
1725
1726 /*********************************************************************
1727  *
1728  * Function    :  generate_host_certificate
1729  *
1730  * Description :  Creates certificate file in presetted directory.
1731  *                If certificate already exists, no other certificate
1732  *                will be created. Subject of certificate is named
1733  *                by csp->http->host from parameter. This function also
1734  *                triggers generating of private key for new certificate.
1735  *
1736  * Parameters  :
1737  *          1  :  csp = Current client state (buffers, headers, etc...)
1738  *
1739  * Returns     :  -1 => Error while creating certificate.
1740  *                 0 => Certificate already exists.
1741  *                 1 => Certificate created
1742  *
1743  *********************************************************************/
1744 static int generate_host_certificate(struct client_state *csp)
1745 {
1746    char *key_buf = NULL;    /* Buffer for created key */
1747    X509 *issuer_cert = NULL;
1748    X509 *cert = NULL;
1749    BIO *pk_bio = NULL;
1750    EVP_PKEY *loaded_subject_key = NULL;
1751    EVP_PKEY *loaded_issuer_key = NULL;
1752    X509_NAME *issuer_name;
1753    X509_NAME *subject_name = NULL;
1754    ASN1_TIME *asn_time = NULL;
1755    ASN1_INTEGER *serial = NULL;
1756    BIGNUM *serial_num = NULL;
1757
1758    int ret = 0;
1759    cert_options cert_opt;
1760    char cert_valid_from[VALID_DATETIME_BUFLEN];
1761    char cert_valid_to[VALID_DATETIME_BUFLEN];
1762    const char *common_name;
1763    enum { CERT_PARAM_COMMON_NAME_MAX = 64 };
1764
1765    /* Paths to keys and certificates needed to create certificate */
1766    cert_opt.issuer_key  = NULL;
1767    cert_opt.subject_key = NULL;
1768    cert_opt.issuer_crt  = NULL;
1769
1770    cert_opt.output_file = make_certs_path(csp->config->certificate_directory,
1771       (const char *)csp->http->hash_of_host_hex, CERT_FILE_TYPE);
1772    if (cert_opt.output_file == NULL)
1773    {
1774       return -1;
1775    }
1776
1777    cert_opt.subject_key = make_certs_path(csp->config->certificate_directory,
1778       (const char *)csp->http->hash_of_host_hex, KEY_FILE_TYPE);
1779    if (cert_opt.subject_key == NULL)
1780    {
1781       freez(cert_opt.output_file);
1782       return -1;
1783    }
1784
1785    if (enforce_sane_certificate_state(cert_opt.output_file,
1786          cert_opt.subject_key))
1787    {
1788       freez(cert_opt.output_file);
1789       freez(cert_opt.subject_key);
1790
1791       return -1;
1792    }
1793
1794    if (file_exists(cert_opt.output_file) == 1)
1795    {
1796       /* The file exists, but is it valid? */
1797       if (ssl_certificate_is_invalid(cert_opt.output_file))
1798       {
1799          log_error(LOG_LEVEL_CONNECT,
1800             "Certificate %s is no longer valid. Removing it.",
1801             cert_opt.output_file);
1802          if (unlink(cert_opt.output_file))
1803          {
1804             log_error(LOG_LEVEL_ERROR, "Failed to unlink %s: %E",
1805                cert_opt.output_file);
1806
1807             freez(cert_opt.output_file);
1808             freez(cert_opt.subject_key);
1809
1810             return -1;
1811          }
1812          if (unlink(cert_opt.subject_key))
1813          {
1814             log_error(LOG_LEVEL_ERROR, "Failed to unlink %s: %E",
1815                cert_opt.subject_key);
1816
1817             freez(cert_opt.output_file);
1818             freez(cert_opt.subject_key);
1819
1820             return -1;
1821          }
1822       }
1823       else
1824       {
1825          freez(cert_opt.output_file);
1826          freez(cert_opt.subject_key);
1827
1828          return 0;
1829       }
1830    }
1831
1832    /*
1833     * Create key for requested host
1834     */
1835    int subject_key_len = generate_key(csp, &key_buf);
1836    if (subject_key_len < 0)
1837    {
1838       freez(cert_opt.output_file);
1839       freez(cert_opt.subject_key);
1840       log_error(LOG_LEVEL_ERROR, "Key generating failed");
1841       return -1;
1842    }
1843
1844    /*
1845     * Converting unsigned long serial number to char * serial number.
1846     * We must compute length of serial number in string + terminating null.
1847     */
1848    unsigned long certificate_serial = get_certificate_serial(csp);
1849    unsigned long certificate_serial_time = (unsigned long)time(NULL);
1850    int serial_num_size = snprintf(NULL, 0, "%lu%lu",
1851       certificate_serial_time, certificate_serial) + 1;
1852    if (serial_num_size <= 0)
1853    {
1854       serial_num_size = 1;
1855    }
1856
1857    char serial_num_text[serial_num_size];  /* Buffer for serial number */
1858    ret = snprintf(serial_num_text, (size_t)serial_num_size, "%lu%lu",
1859       certificate_serial_time, certificate_serial);
1860    if (ret < 0 || ret >= serial_num_size)
1861    {
1862       log_error(LOG_LEVEL_ERROR,
1863          "Converting certificate serial number into string failed");
1864       ret = -1;
1865       goto exit;
1866    }
1867
1868    /*
1869     * Preparing parameters for certificate
1870     */
1871    subject_name = X509_NAME_new();
1872    if (!subject_name)
1873    {
1874       log_ssl_errors(LOG_LEVEL_ERROR, "X509 memory allocation failure");
1875       ret = -1;
1876       goto exit;
1877    }
1878
1879    /*
1880     * Make sure OpenSSL doesn't reject the common name due to its length.
1881     * The clients should only care about the Subject Alternative Name anyway
1882     * and we always use the real host name for that.
1883     */
1884    common_name = (strlen(csp->http->host) > CERT_PARAM_COMMON_NAME_MAX) ?
1885       CGI_SITE_2_HOST : csp->http->host;
1886    if (!X509_NAME_add_entry_by_txt(subject_name, CERT_PARAM_COMMON_NAME_FCODE,
1887          MBSTRING_ASC, (void *)common_name, -1, -1, 0))
1888    {
1889       log_ssl_errors(LOG_LEVEL_ERROR,
1890          "X509 subject name (code: %s, val: %s) error",
1891          CERT_PARAM_COMMON_NAME_FCODE, csp->http->host);
1892       ret = -1;
1893       goto exit;
1894    }
1895    if (!X509_NAME_add_entry_by_txt(subject_name, CERT_PARAM_ORGANIZATION_FCODE,
1896          MBSTRING_ASC, (void *)common_name, -1, -1, 0))
1897    {
1898       log_ssl_errors(LOG_LEVEL_ERROR,
1899          "X509 subject name (code: %s, val: %s) error",
1900          CERT_PARAM_ORGANIZATION_FCODE, csp->http->host);
1901       ret = -1;
1902       goto exit;
1903    }
1904    if (!X509_NAME_add_entry_by_txt(subject_name, CERT_PARAM_ORG_UNIT_FCODE,
1905          MBSTRING_ASC, (void *)common_name, -1, -1, 0))
1906    {
1907       log_ssl_errors(LOG_LEVEL_ERROR,
1908          "X509 subject name (code: %s, val: %s) error",
1909          CERT_PARAM_ORG_UNIT_FCODE, csp->http->host);
1910       ret = -1;
1911       goto exit;
1912    }
1913    if (!X509_NAME_add_entry_by_txt(subject_name, CERT_PARAM_COUNTRY_FCODE,
1914          MBSTRING_ASC, (void *)CERT_PARAM_COUNTRY_CODE, -1, -1, 0))
1915    {
1916       log_ssl_errors(LOG_LEVEL_ERROR,
1917          "X509 subject name (code: %s, val: %s) error",
1918          CERT_PARAM_COUNTRY_FCODE, CERT_PARAM_COUNTRY_CODE);
1919       ret = -1;
1920       goto exit;
1921    }
1922
1923    cert_opt.issuer_crt = csp->config->ca_cert_file;
1924    cert_opt.issuer_key = csp->config->ca_key_file;
1925
1926    if (get_certificate_valid_from_date(cert_valid_from,
1927          sizeof(cert_valid_from), VALID_DATETIME_FMT)
1928     || get_certificate_valid_to_date(cert_valid_to,
1929          sizeof(cert_valid_to), VALID_DATETIME_FMT))
1930    {
1931       log_error(LOG_LEVEL_ERROR, "Generating one of the validity dates failed");
1932       ret = -1;
1933       goto exit;
1934    }
1935
1936    cert_opt.subject_pwd = CERT_SUBJECT_PASSWORD;
1937    cert_opt.issuer_pwd  = csp->config->ca_password;
1938    cert_opt.not_before  = cert_valid_from;
1939    cert_opt.not_after   = cert_valid_to;
1940    cert_opt.serial      = serial_num_text;
1941    cert_opt.max_pathlen = -1;
1942
1943    /*
1944     * Test if the private key was already created.
1945     * XXX: Can this still happen?
1946     */
1947    if (subject_key_len == 0)
1948    {
1949       log_error(LOG_LEVEL_ERROR, "Subject key was already created");
1950       ret = 0;
1951       goto exit;
1952    }
1953
1954    /*
1955     * Parse serial to MPI
1956     */
1957    serial_num = BN_new();
1958    if (!serial_num)
1959    {
1960       log_error(LOG_LEVEL_ERROR, "generate_host_certificate: memory error");
1961       ret = -1;
1962       goto exit;
1963    }
1964    if (!BN_dec2bn(&serial_num, cert_opt.serial))
1965    {
1966       log_ssl_errors(LOG_LEVEL_ERROR, "Failed to parse serial %s", cert_opt.serial);
1967       ret = -1;
1968       goto exit;
1969    }
1970
1971    if (!(serial = BN_to_ASN1_INTEGER(serial_num, NULL)))
1972    {
1973       log_ssl_errors(LOG_LEVEL_ERROR, "Failed to generate serial ASN1 representation");
1974       ret = -1;
1975       goto exit;
1976    }
1977
1978    /*
1979     * Loading certificates
1980     */
1981    if (!(issuer_cert = ssl_certificate_load(cert_opt.issuer_crt)))
1982    {
1983       log_error(LOG_LEVEL_ERROR, "Loading issuer certificate %s failed",
1984          cert_opt.issuer_crt);
1985       ret = -1;
1986       goto exit;
1987    }
1988
1989    issuer_name = X509_get_subject_name(issuer_cert);
1990
1991    /*
1992     * Loading keys from file or from buffer
1993     */
1994    if (key_buf != NULL && subject_key_len > 0)
1995    {
1996       pk_bio = BIO_new_mem_buf(key_buf, subject_key_len);
1997    }
1998    else if (!(pk_bio = BIO_new_file(cert_opt.subject_key, "r")))
1999    {
2000       log_ssl_errors(LOG_LEVEL_ERROR,
2001          "Failure opening subject key %s BIO", cert_opt.subject_key);
2002       ret = -1;
2003       goto exit;
2004    }
2005
2006    loaded_subject_key = PEM_read_bio_PrivateKey(pk_bio, NULL, NULL,
2007       (void *)cert_opt.subject_pwd);
2008    if (!loaded_subject_key)
2009    {
2010       log_ssl_errors(LOG_LEVEL_ERROR, "Parsing subject key %s failed",
2011          cert_opt.subject_key);
2012       ret = -1;
2013       goto exit;
2014    }
2015
2016    if (!BIO_free(pk_bio))
2017    {
2018       log_ssl_errors(LOG_LEVEL_ERROR, "Error closing subject key BIO");
2019    }
2020
2021    if (!(pk_bio = BIO_new_file(cert_opt.issuer_key, "r")))
2022    {
2023       log_ssl_errors(LOG_LEVEL_ERROR, "Failure opening issuer key %s BIO",
2024          cert_opt.issuer_key);
2025       ret = -1;
2026       goto exit;
2027    }
2028
2029    loaded_issuer_key = PEM_read_bio_PrivateKey(pk_bio, NULL, NULL,
2030       (void *)cert_opt.issuer_pwd);
2031    if (!loaded_issuer_key)
2032    {
2033       log_ssl_errors(LOG_LEVEL_ERROR, "Parsing issuer key %s failed",
2034          cert_opt.subject_key);
2035       ret = -1;
2036       goto exit;
2037    }
2038
2039    cert = X509_new();
2040    if (!cert)
2041    {
2042       log_ssl_errors(LOG_LEVEL_ERROR, "Certificate allocation error");
2043       ret = -1;
2044       goto exit;
2045    }
2046
2047    if (!X509_set_version(cert, CERTIFICATE_VERSION))
2048    {
2049       log_ssl_errors(LOG_LEVEL_ERROR, "X509_set_version failed");
2050       ret = -1;
2051       goto exit;
2052    }
2053
2054    /*
2055     * Setting parameters of signed certificate
2056     */
2057    if (!X509_set_pubkey(cert, loaded_subject_key))
2058    {
2059       log_ssl_errors(LOG_LEVEL_ERROR,
2060          "Setting public key in signed certificate failed");
2061       ret = -1;
2062       goto exit;
2063    }
2064
2065    if (!X509_set_subject_name(cert, subject_name))
2066    {
2067       log_ssl_errors(LOG_LEVEL_ERROR,
2068          "Setting subject name in signed certificate failed");
2069       ret = -1;
2070       goto exit;
2071    }
2072
2073    if (!X509_set_issuer_name(cert, issuer_name))
2074    {
2075       log_ssl_errors(LOG_LEVEL_ERROR,
2076          "Setting issuer name in signed certificate failed");
2077       ret = -1;
2078       goto exit;
2079    }
2080
2081    if (!X509_set_serialNumber(cert, serial))
2082    {
2083       log_ssl_errors(LOG_LEVEL_ERROR,
2084          "Setting serial number in signed certificate failed");
2085       ret = -1;
2086       goto exit;
2087    }
2088
2089    asn_time = ASN1_TIME_new();
2090    if (!asn_time)
2091    {
2092       log_ssl_errors(LOG_LEVEL_ERROR, "ASN1 time memory allocation failure");
2093       ret = -1;
2094       goto exit;
2095    }
2096
2097    if (!ASN1_TIME_set_string(asn_time, cert_opt.not_after))
2098    {
2099       log_ssl_errors(LOG_LEVEL_ERROR, "ASN1 time [%s] encode error", cert_opt.not_after);
2100       ret = -1;
2101       goto exit;
2102    }
2103
2104    if (!X509_set1_notAfter(cert, asn_time))
2105    {
2106       log_ssl_errors(LOG_LEVEL_ERROR,
2107          "Setting valid not after in signed certificate failed");
2108       ret = -1;
2109       goto exit;
2110    }
2111
2112    if (!ASN1_TIME_set_string(asn_time, cert_opt.not_before))
2113    {
2114       log_ssl_errors(LOG_LEVEL_ERROR, "ASN1 time encode error");
2115       ret = -1;
2116       goto exit;
2117    }
2118
2119    if (!X509_set1_notBefore(cert, asn_time))
2120    {
2121       log_ssl_errors(LOG_LEVEL_ERROR,
2122          "Setting valid not before in signed certificate failed");
2123       ret = -1;
2124       goto exit;
2125    }
2126
2127    if (!set_x509_ext(cert, issuer_cert, NID_basic_constraints, CERTIFICATE_BASIC_CONSTRAINTS))
2128    {
2129       log_ssl_errors(LOG_LEVEL_ERROR, "Setting the basicConstraints extension "
2130          "in signed certificate failed");
2131       ret = -1;
2132       goto exit;
2133    }
2134
2135    if (!set_x509_ext(cert, issuer_cert, NID_subject_key_identifier, CERTIFICATE_SUBJECT_KEY))
2136    {
2137       log_ssl_errors(LOG_LEVEL_ERROR,
2138          "Setting the Subject Key Identifier extension failed");
2139       ret = -1;
2140       goto exit;
2141    }
2142
2143    if (!set_x509_ext(cert, issuer_cert, NID_authority_key_identifier, CERTIFICATE_AUTHORITY_KEY))
2144    {
2145       log_ssl_errors(LOG_LEVEL_ERROR,
2146          "Setting the Authority Key Identifier extension failed");
2147       ret = -1;
2148       goto exit;
2149    }
2150
2151    if (!host_is_ip_address(csp->http->host) &&
2152        !set_subject_alternative_name(cert, issuer_cert, csp->http->host))
2153    {
2154       log_ssl_errors(LOG_LEVEL_ERROR,
2155          "Setting the Subject Alt Name extension failed");
2156       ret = -1;
2157       goto exit;
2158    }
2159
2160    if (!X509_sign(cert, loaded_issuer_key, EVP_sha256()))
2161    {
2162       log_ssl_errors(LOG_LEVEL_ERROR, "Signing certificate failed");
2163       ret = -1;
2164       goto exit;
2165    }
2166
2167    /*
2168     * Writing certificate into file
2169     */
2170    if (write_certificate(cert, cert_opt.output_file) < 0)
2171    {
2172       log_error(LOG_LEVEL_ERROR, "Writing certificate into file failed");
2173       ret = -1;
2174       goto exit;
2175    }
2176
2177    ret = 1;
2178
2179 exit:
2180    /*
2181     * Freeing used structures
2182     */
2183    if (issuer_cert)
2184    {
2185       X509_free(issuer_cert);
2186    }
2187    if (cert)
2188    {
2189       X509_free(cert);
2190    }
2191    if (pk_bio && !BIO_free(pk_bio))
2192    {
2193       log_ssl_errors(LOG_LEVEL_ERROR, "Error closing pk BIO");
2194    }
2195    if (loaded_subject_key)
2196    {
2197       EVP_PKEY_free(loaded_subject_key);
2198    }
2199    if (loaded_issuer_key)
2200    {
2201       EVP_PKEY_free(loaded_issuer_key);
2202    }
2203    if (subject_name)
2204    {
2205       X509_NAME_free(subject_name);
2206    }
2207    if (asn_time)
2208    {
2209       ASN1_TIME_free(asn_time);
2210    }
2211    if (serial_num)
2212    {
2213       BN_free(serial_num);
2214    }
2215    if (serial)
2216    {
2217       ASN1_INTEGER_free(serial);
2218    }
2219    freez(cert_opt.subject_key);
2220    freez(cert_opt.output_file);
2221    freez(key_buf);
2222
2223    return ret;
2224 }
2225
2226
2227 /*********************************************************************
2228  *
2229  * Function    :  ssl_crt_verify_info
2230  *
2231  * Description :  Returns an informational string about the verification
2232  *                status of a certificate.
2233  *
2234  * Parameters  :
2235  *          1  :  buf = Buffer to write to
2236  *          2  :  size = Maximum size of buffer
2237  *          3  :  csp = client state
2238  *
2239  * Returns     :  N/A
2240  *
2241  *********************************************************************/
2242 extern void ssl_crt_verify_info(char *buf, size_t size, struct client_state *csp)
2243 {
2244    strncpy(buf, X509_verify_cert_error_string(csp->server_cert_verification_result), size);
2245    buf[size - 1] = 0;
2246 }
2247
2248
2249 #ifdef FEATURE_GRACEFUL_TERMINATION
2250 /*********************************************************************
2251  *
2252  * Function    :  ssl_release
2253  *
2254  * Description :  Release all SSL resources
2255  *
2256  * Parameters  :
2257  *
2258  * Returns     :  N/A
2259  *
2260  *********************************************************************/
2261 extern void ssl_release(void)
2262 {
2263    if (ssl_inited == 1)
2264    {
2265 #if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2266 #ifndef LIBRESSL_VERSION_NUMBER
2267 #ifndef OPENSSL_NO_COMP
2268       SSL_COMP_free_compression_methods();
2269 #endif
2270 #endif
2271 #endif
2272       CONF_modules_free();
2273       CONF_modules_unload(1);
2274 #ifndef OPENSSL_NO_COMP
2275       COMP_zlib_cleanup();
2276 #endif
2277
2278       ERR_free_strings();
2279       EVP_cleanup();
2280
2281       CRYPTO_cleanup_all_ex_data();
2282    }
2283 }
2284 #endif /* def FEATURE_GRACEFUL_TERMINATION */