LCOV - code coverage report
Current view: top level - fuzz - ssl.c (source / functions) Hit Total Coverage
Test: trace.lcov_info_final Lines: 59 584 10.1 %
Date: 2021-02-22 04:51:02 Functions: 8 21 38.1 %

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

Generated by: LCOV version 1.14