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 : }
|