├── .gitignore ├── .travis.yml ├── Makefile ├── README.md ├── atomic.c ├── atomic.h ├── certforgery.c ├── certforgery.h ├── daemonize.c ├── daemonize.h ├── datafilter.c ├── datafilter.h ├── datafilter_bytewise.c ├── datafilter_bytewise.h ├── datafilter_hexdump.c ├── datafilter_hexdump.h ├── datafilter_http.c ├── datafilter_http.h ├── errstack.c ├── errstack.h ├── getoptgen ├── Patcher.py └── getoptgen.py ├── hexdump.c ├── hexdump.h ├── hostname_ids.c ├── hostname_ids.h ├── intercept_config.c ├── intercept_config.h ├── interceptdb.c ├── interceptdb.h ├── ipfwd.c ├── ipfwd.h ├── itests ├── SubprocessWrapper.py ├── demo_ca │ ├── client_intermediate.crt │ ├── client_intermediate.key │ ├── client_intermediate.srl │ ├── client_joe.crt │ ├── client_joe.key │ ├── client_julaia.crt │ ├── client_julaia.key │ ├── intermediate.crt │ ├── intermediate.key │ ├── intermediate.srl │ ├── root.crt │ ├── root.key │ ├── root.srl │ ├── server_bar.crt │ ├── server_bar.key │ ├── server_foo.crt │ ├── server_foo.key │ ├── server_moo.crt │ └── server_moo.key ├── ratched_ca │ ├── client.key │ ├── root.crt │ ├── root.key │ └── server.key └── run_itests.py ├── keyvaluelist.c ├── keyvaluelist.h ├── logging.c ├── logging.h ├── map.c ├── map.h ├── mkca ├── PKICreator.py └── create_demo_ca.py ├── ocsp_response.c ├── ocsp_response.h ├── openssl.c ├── openssl.h ├── openssl_certs.c ├── openssl_certs.h ├── openssl_clienthello.c ├── openssl_clienthello.h ├── openssl_filtered_fwd.c ├── openssl_filtered_fwd.h ├── openssl_tls.c ├── openssl_tls.h ├── parse.c ├── parse.h ├── pcapng.c ├── pcapng.h ├── pgmopts.c ├── pgmopts.h ├── ratched.c ├── server.c ├── server.h ├── server ├── client_koo.crt ├── client_koo.key ├── client_moo.crt ├── client_moo.key ├── server_bar.crt ├── server_bar.key ├── server_foo.crt ├── server_foo.key ├── start_server └── test_client ├── sighandler.c ├── sighandler.h ├── stringlist.c ├── stringlist.h ├── tcpip.c ├── tcpip.h ├── tests ├── .gitignore ├── Makefile ├── helper_logging.c ├── local.crt ├── local.key ├── mantest_openssl_sclient.c ├── mantest_openssl_sserver.c ├── test_filter.c ├── test_header_inclusion ├── test_hostname_ids.c ├── test_keyvaluelist.c ├── test_map.c ├── test_ocsp.c ├── test_openssl_certs.c ├── test_openssl_clienthello.c ├── test_openssl_tls.c ├── test_parse.c ├── test_pcapng.c ├── test_stringlist.c ├── test_tcpip.c ├── test_tools.c ├── testbed.c └── testbed.h ├── thread.c ├── thread.h ├── tools.c └── tools.h /.gitignore: -------------------------------------------------------------------------------- 1 | ratched 2 | *.o 3 | __pycache__ 4 | 5 | .*.swp 6 | hexdump_????.bin 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | dist: trusty 2 | language: c 3 | 4 | before_install: 5 | - sudo apt-get install -y build-essential git 6 | - git clone -b OpenSSL_1_1_1k --depth 1 https://github.com/openssl/openssl.git && cd openssl && ./config && make -j2 && sudo make install >/dev/null 2>&1 && cd .. 7 | - sudo ldconfig 8 | 9 | script: 10 | - make all 11 | - make tests 12 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all clean test simpletest tests install 2 | 3 | OBJS := \ 4 | atomic.o \ 5 | certforgery.o \ 6 | daemonize.o \ 7 | datafilter_bytewise.o \ 8 | datafilter_hexdump.o \ 9 | datafilter_http.o \ 10 | datafilter.o \ 11 | errstack.o \ 12 | hexdump.o \ 13 | hostname_ids.o \ 14 | intercept_config.o \ 15 | interceptdb.o \ 16 | ipfwd.o \ 17 | keyvaluelist.o \ 18 | logging.o \ 19 | map.o \ 20 | ocsp_response.o \ 21 | openssl_certs.o \ 22 | openssl_clienthello.o \ 23 | openssl_filtered_fwd.o \ 24 | openssl.o \ 25 | openssl_tls.o \ 26 | parse.o \ 27 | pcapng.o \ 28 | pgmopts.o \ 29 | ratched.o \ 30 | server.o \ 31 | sighandler.o \ 32 | stringlist.o \ 33 | tcpip.o \ 34 | thread.o \ 35 | tools.o 36 | 37 | BUILD_TIMESTAMP_UTC := $(shell /bin/date +'%Y-%m-%d %H:%M:%S') 38 | BUILD_REVISION := $(shell git describe --abbrev=10 --dirty --always) 39 | DEBUG := 0 40 | 41 | CFLAGS := -O3 -Wall -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=500 -Wno-unused-parameter -Wmissing-prototypes -Wstrict-prototypes -Werror=implicit-function-declaration -Werror=format -Wshadow -Wmaybe-uninitialized -Wuninitialized -std=c11 -pthread 42 | CFLAGS += -DBUILD_TIMESTAMP_UTC='"$(BUILD_TIMESTAMP_UTC)"' -DBUILD_REVISION='"$(BUILD_REVISION)"' 43 | LDFLAGS := -L/usr/local/lib -lssl -lcrypto 44 | 45 | ifeq ($(DEBUG),1) 46 | CFLAGS += -g3 47 | 48 | ifneq ($(USER),travis) 49 | # On Travis-CI, gcc does not support "undefined" and "leak" sanitizers. 50 | # Furthermore (and worse, actually), there seems to be a kernel < 4.12.8 51 | # installed which causes the address sanitizer to cause spurious fails ("Shadow 52 | # memory range interleaves with an existing memory mapping. ASan cannot proceed 53 | # correctly. ABORTING."), leading to a broken build. Therefore we do not run 54 | # sanitizers on Travis. 55 | CFLAGS += -pie -fPIE -fsanitize=address -fsanitize=undefined -fsanitize=leak -fno-omit-frame-pointer 56 | endif 57 | endif 58 | 59 | all: ratched 60 | 61 | clean: 62 | rm -f $(OBJS) ratched 63 | 64 | ratched: $(OBJS) 65 | $(CC) $(CFLAGS) -o $@ $(OBJS) $(LDFLAGS) 66 | 67 | test: ratched 68 | ASAN_OPTIONS=fast_unwind_on_malloc=0 ./ratched -o output.pcapng -f 127.0.0.1:9000 -vvv --dump-certs --keyspec ecc:secp256r1 --pcap-comment "foo bar" -i moo,c_certfile=server/client_moo.crt,c_keyfile=server/client_moo.key,s_ciphers=AES128+HIGH+ECDHE -i koo,s_reqclientcert=true --mark-forged-certificates --crl-uri http://foo.com --ocsp-uri http://bar.com --use-ipv6-encapsulation --defaults s_tlsversions=tls10 69 | 70 | simpletest: ratched 71 | ./ratched -o output.pcapng -f 127.0.0.1:9000 -vvv --dump-certs 72 | 73 | tests: 74 | make -C tests test 75 | 76 | install: all 77 | strip ratched 78 | chown root:root ratched 79 | chmod 755 ratched 80 | mv ratched /usr/local/bin 81 | -------------------------------------------------------------------------------- /atomic.c: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #include 25 | #include 26 | #include "atomic.h" 27 | #include "errstack.h" 28 | 29 | void atomic_init(struct atomic_t *atomic) { 30 | memset(atomic, 0, sizeof(*atomic)); 31 | pthread_mutex_init(&atomic->mutex, NULL); 32 | pthread_cond_init(&atomic->cond, NULL); 33 | } 34 | 35 | void atomic_add(struct atomic_t *atomic, int value) { 36 | pthread_mutex_lock(&atomic->mutex); 37 | atomic->value += value; 38 | pthread_cond_broadcast(&atomic->cond); 39 | pthread_mutex_unlock(&atomic->mutex); 40 | } 41 | 42 | void atomic_set(struct atomic_t *atomic, int value) { 43 | pthread_mutex_lock(&atomic->mutex); 44 | atomic->value = value; 45 | pthread_cond_broadcast(&atomic->cond); 46 | pthread_mutex_unlock(&atomic->mutex); 47 | } 48 | 49 | #include 50 | bool atomic_test_and_set(struct atomic_t *atomic) { 51 | bool result = false; 52 | pthread_mutex_lock(&atomic->mutex); 53 | if (atomic->value == 0) { 54 | result = true; 55 | atomic->value = 1; 56 | } 57 | pthread_mutex_unlock(&atomic->mutex); 58 | return result; 59 | } 60 | 61 | void atomic_inc(struct atomic_t *atomic) { 62 | return atomic_add(atomic, 1); 63 | } 64 | 65 | void atomic_dec(struct atomic_t *atomic) { 66 | return atomic_add(atomic, -1); 67 | } 68 | 69 | void atomic_wait_until_value(struct atomic_t *atomic, int value) { 70 | pthread_mutex_lock(&atomic->mutex); 71 | while (atomic->value != value) { 72 | pthread_cond_wait(&atomic->cond, &atomic->mutex); 73 | } 74 | pthread_mutex_unlock(&atomic->mutex); 75 | } 76 | 77 | static void errstack_atomic_dec(struct errstack_element_t *element) { 78 | atomic_dec((struct atomic_t*)element->ptrvalue); 79 | } 80 | 81 | void errstack_push_atomic_dec(struct errstack_t *errstack, struct atomic_t *element) { 82 | errstack_push_generic_nonnull_ptr(errstack, errstack_atomic_dec, element); 83 | } 84 | -------------------------------------------------------------------------------- /atomic.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #ifndef __ATOMIC_H__ 25 | #define __ATOMIC_H__ 26 | 27 | #include 28 | #include 29 | #include "errstack.h" 30 | 31 | struct atomic_t { 32 | pthread_mutex_t mutex; 33 | pthread_cond_t cond; 34 | int value; 35 | }; 36 | 37 | /*************** AUTO GENERATED SECTION FOLLOWS ***************/ 38 | void atomic_init(struct atomic_t *atomic); 39 | void atomic_add(struct atomic_t *atomic, int value); 40 | void atomic_set(struct atomic_t *atomic, int value); 41 | bool atomic_test_and_set(struct atomic_t *atomic); 42 | void atomic_inc(struct atomic_t *atomic); 43 | void atomic_dec(struct atomic_t *atomic); 44 | void atomic_wait_until_value(struct atomic_t *atomic, int value); 45 | void errstack_push_atomic_dec(struct errstack_t *errstack, struct atomic_t *element); 46 | /*************** AUTO GENERATED SECTION ENDS ***************/ 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /certforgery.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #ifndef __CERTFORGERY_H__ 25 | #define __CERTFORGERY_H__ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | /*************** AUTO GENERATED SECTION FOLLOWS ***************/ 33 | struct server_certificate_t; 34 | bool certforgery_init(void); 35 | X509 *get_forged_root_certificate(void); 36 | EVP_PKEY *get_forged_root_key(void); 37 | EVP_PKEY *get_tls_server_key(void); 38 | EVP_PKEY *get_tls_client_key(void); 39 | X509 *forge_certificate_for_server(const char *hostname, uint32_t ipv4_nbo); 40 | void certforgery_deinit(void); 41 | /*************** AUTO GENERATED SECTION ENDS ***************/ 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /daemonize.c: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include "daemonize.h" 29 | #include "logging.h" 30 | 31 | bool daemonize(void) { 32 | pid_t pid = fork(); 33 | if (pid == -1) { 34 | logmsg(LLVL_FATAL, "First fork(3) failed: %s", strerror(errno)); 35 | return false; 36 | } else if (pid != 0) { 37 | /* Parent process, exit. */ 38 | exit(EXIT_SUCCESS); 39 | } 40 | 41 | /* Child process survives */ 42 | pid = fork(); 43 | if (pid == -1) { 44 | logmsg(LLVL_FATAL, "Second fork(3) failed: %s", strerror(errno)); 45 | return false; 46 | } else if (pid != 0) { 47 | /* Parent process, exit. */ 48 | exit(EXIT_SUCCESS); 49 | } 50 | 51 | /* Again, child process survives */ 52 | if (chdir("/") == -1) { 53 | logmsg(LLVL_FATAL, "chdir(3) to root directory failed: %s", strerror(errno)); 54 | return false; 55 | } 56 | 57 | return true; 58 | } 59 | -------------------------------------------------------------------------------- /daemonize.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #ifndef __DAEMONIZE_H__ 25 | #define __DAEMONIZE_H__ 26 | 27 | #include 28 | 29 | /*************** AUTO GENERATED SECTION FOLLOWS ***************/ 30 | bool daemonize(void); 31 | /*************** AUTO GENERATED SECTION ENDS ***************/ 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /datafilter.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "logging.h" 6 | #include "datafilter.h" 7 | 8 | struct filterdata_sink_t { 9 | filter_sink_fnc_t sink_fnc; 10 | void *sink_fnc_arg; 11 | }; 12 | 13 | static bool filterfnc_sink_new(void *data, void *init_attrs) { 14 | struct filterdata_sink_t *ctx = (struct filterdata_sink_t*)data; 15 | struct filterdata_sink_t *attr = (struct filterdata_sink_t*)init_attrs; 16 | *ctx = *attr; 17 | return true; 18 | } 19 | 20 | static void filterfnc_sink_put(struct datafilter_t *filter, const uint8_t *data, unsigned int length) { 21 | struct filterdata_sink_t *ctx = (struct filterdata_sink_t *)filter->data; 22 | ctx->sink_fnc(ctx->sink_fnc_arg, data, length); 23 | } 24 | 25 | static const struct filterclass_t filterclass_sink = { 26 | .name = "sink", 27 | .datasize = sizeof(struct filterdata_sink_t), 28 | .flt_new = filterfnc_sink_new, 29 | .flt_put = filterfnc_sink_put, 30 | }; 31 | 32 | struct datafilter_t *datafilter_new(const struct filterclass_t *flt_class, void *flt_init_args, struct datafilter_t *next) { 33 | struct datafilter_t *filter = calloc(sizeof(struct datafilter_t), 1); 34 | if (!filter) { 35 | logmsg(LLVL_FATAL, "Failed to calloc(3) memory for data filter: %s", strerror(errno)); 36 | return NULL; 37 | } 38 | filter->flt_class = flt_class; 39 | filter->next = next; 40 | if (filter->flt_class->datasize) { 41 | filter->data = calloc(1, filter->flt_class->datasize); 42 | if (!filter->data) { 43 | logmsg(LLVL_FATAL, "Failed to calloc(3) %d bytes of data memory for '%s' type data filter: %s", filter->flt_class->datasize, filter->flt_class->name, strerror(errno)); 44 | free(filter); 45 | return NULL; 46 | } 47 | } 48 | if (filter->flt_class->flt_new) { 49 | if (!filter->flt_class->flt_new(filter->data, flt_init_args)) { 50 | logmsg(LLVL_FATAL, "Failed to calloc(3) internal memory for '%s' type data filter: %s", filter->flt_class->name, strerror(errno)); 51 | free(filter->data); 52 | free(filter); 53 | return NULL; 54 | } 55 | } 56 | return filter; 57 | } 58 | 59 | struct datafilter_t *datafilter_new_sink(filter_sink_fnc_t sink_fnc, void *sink_fnc_arg) { 60 | struct filterdata_sink_t flt_init_arg = { 61 | .sink_fnc = sink_fnc, 62 | .sink_fnc_arg = sink_fnc_arg, 63 | }; 64 | return datafilter_new(&filterclass_sink, &flt_init_arg, NULL); 65 | } 66 | 67 | void datafilter_put(struct datafilter_t *filter, const void *data, unsigned int length) { 68 | filter->flt_class->flt_put(filter, data, length); 69 | } 70 | 71 | static void datafilter_free(struct datafilter_t *filter) { 72 | if (filter->flt_class->flt_free) { 73 | filter->flt_class->flt_free(filter->data); 74 | } 75 | free(filter->data); 76 | free(filter); 77 | } 78 | 79 | void datafilter_free_chain(struct datafilter_t *filter) { 80 | while (filter) { 81 | struct datafilter_t *next_filter = filter->next; 82 | datafilter_free(filter); 83 | filter = next_filter; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /datafilter.h: -------------------------------------------------------------------------------- 1 | #ifndef __DATAFILTER_H__ 2 | #define __DATAFILTER_H__ 3 | 4 | #include 5 | #include 6 | 7 | struct datafilter_t; 8 | 9 | struct filterclass_t { 10 | const char *name; 11 | unsigned int datasize; 12 | bool (*flt_new)(void *data, void *init_attrs); 13 | void (*flt_flush)(struct datafilter_t *filter); 14 | void (*flt_put)(struct datafilter_t *filter, const uint8_t *data, unsigned int length); 15 | void (*flt_free)(void *data); 16 | }; 17 | 18 | typedef void (*filter_sink_fnc_t)(void *arg, const uint8_t *data, unsigned int length); 19 | 20 | struct datafilter_t { 21 | const struct filterclass_t *flt_class; 22 | struct datafilter_t *next; 23 | void *data; 24 | }; 25 | 26 | /*************** AUTO GENERATED SECTION FOLLOWS ***************/ 27 | struct datafilter_t *datafilter_new(const struct filterclass_t *flt_class, void *flt_init_args, struct datafilter_t *next); 28 | struct datafilter_t *datafilter_new_sink(filter_sink_fnc_t sink_fnc, void *sink_fnc_arg); 29 | void datafilter_put(struct datafilter_t *filter, const void *data, unsigned int length); 30 | void datafilter_free_chain(struct datafilter_t *filter); 31 | /*************** AUTO GENERATED SECTION ENDS ***************/ 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /datafilter_bytewise.c: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #include 25 | #include 26 | #include 27 | #include "datafilter_bytewise.h" 28 | 29 | static void filterfnc_bytewise_put(struct datafilter_t *filter, const uint8_t *data, unsigned int length) { 30 | for (unsigned int i = 0; i < length; i++) { 31 | datafilter_put(filter->next, data + i, 1); 32 | } 33 | } 34 | 35 | const struct filterclass_t filterclass_bytewise = { 36 | .name = "bytewise", 37 | .flt_put = filterfnc_bytewise_put, 38 | }; 39 | -------------------------------------------------------------------------------- /datafilter_bytewise.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #ifndef __DATAFILTER_BYTEWISE_H__ 25 | #define __DATAFILTER_BYTEWISE_H__ 26 | 27 | #include "datafilter.h" 28 | 29 | extern const struct filterclass_t filterclass_bytewise; 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /datafilter_hexdump.c: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #include 25 | #include 26 | #include 27 | #include "datafilter_hexdump.h" 28 | #include "hexdump.h" 29 | 30 | static void filterfnc_hexdump_put(struct datafilter_t *filter, const uint8_t *data, unsigned int length) { 31 | hexdump_data(stderr, data, length); 32 | datafilter_put(filter->next, data, length); 33 | } 34 | 35 | const struct filterclass_t filterclass_hexdump = { 36 | .name = "hexdump", 37 | .flt_put = filterfnc_hexdump_put, 38 | }; 39 | -------------------------------------------------------------------------------- /datafilter_hexdump.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #ifndef __DATAFILTER_HEXDUMP_H__ 25 | #define __DATAFILTER_HEXDUMP_H__ 26 | 27 | #include "datafilter.h" 28 | 29 | extern const struct filterclass_t filterclass_hexdump; 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /datafilter_http.c: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #include 25 | #include 26 | #include 27 | #include "datafilter_http.h" 28 | 29 | struct filterdata_http_t { 30 | bool passthrough; 31 | uint8_t *buffer; 32 | unsigned int fill; 33 | }; 34 | 35 | static bool filterfnc_http_new(void *data, void *init_attrs) { 36 | struct filterdata_http_t *ctx = (struct filterdata_http_t*)data; 37 | ctx->buffer = malloc(4096); 38 | if (!ctx->buffer) { 39 | return false; 40 | } 41 | return true; 42 | } 43 | 44 | static void filterfnc_http_put(struct datafilter_t *filter, const uint8_t *data, unsigned int length) { 45 | struct filterdata_http_t *ctx = (struct filterdata_http_t *)filter->data; 46 | if (ctx->passthrough) { 47 | datafilter_put(filter->next, data, length); 48 | } 49 | } 50 | 51 | static void filterfnc_http_free(void *data) { 52 | struct filterdata_http_t *ctx = (struct filterdata_http_t*)data; 53 | free(ctx->buffer); 54 | } 55 | 56 | const struct filterclass_t filterclass_http = { 57 | .name = "http", 58 | .datasize = sizeof(struct filterdata_http_t), 59 | .flt_new = filterfnc_http_new, 60 | .flt_put = filterfnc_http_put, 61 | .flt_free = filterfnc_http_free, 62 | }; 63 | -------------------------------------------------------------------------------- /datafilter_http.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #ifndef __DATAFILTER_HTTP_H__ 25 | #define __DATAFILTER_HTTP_H__ 26 | 27 | #include "datafilter.h" 28 | 29 | extern const struct filterclass_t filterclass_http; 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /errstack.c: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #include 25 | 26 | #include "atomic.h" 27 | #include "errstack.h" 28 | #include "logging.h" 29 | 30 | static void errstack_post_push(const struct errstack_t *errstack) { 31 | //fprintf(stderr, "-> %p %d\n", errstack, errstack->count); 32 | } 33 | 34 | static void errstack_post_pop(const struct errstack_t *errstack) { 35 | //fprintf(stderr, "<- %p %d\n", errstack, errstack->count); 36 | } 37 | 38 | void* errstack_push_generic_ptr(struct errstack_t *errstack, errstack_free_callback_t free_callback, void *element) { 39 | if (errstack->count >= MAX_ERRSTACK_DEPTH) { 40 | logmsg(LLVL_FATAL, "Error stack capacity exceeded (%d elements). Will leak memory.", errstack->count); 41 | return element; 42 | } 43 | errstack->element[errstack->count].free_callback = free_callback; 44 | errstack->element[errstack->count].ptrvalue = element; 45 | errstack->count++; 46 | errstack_post_push(errstack); 47 | return element; 48 | } 49 | 50 | void* errstack_push_generic_nonnull_ptr(struct errstack_t *errstack, errstack_free_callback_t free_callback, void *element) { 51 | if (!element) { 52 | return NULL; 53 | } 54 | return errstack_push_generic_ptr(errstack, free_callback, element); 55 | } 56 | 57 | int errstack_push_int(struct errstack_t *errstack, errstack_free_callback_t free_callback, int element) { 58 | if (errstack->count >= MAX_ERRSTACK_DEPTH) { 59 | logmsg(LLVL_FATAL, "Error stack capacity exceeded (%d elements). Will leak memory.", errstack->count); 60 | return element; 61 | } 62 | errstack->element[errstack->count].free_callback = free_callback; 63 | errstack->element[errstack->count].intvalue = element; 64 | errstack->count++; 65 | errstack_post_push(errstack); 66 | return element; 67 | } 68 | 69 | static void errstack_free_malloc(struct errstack_element_t *element) { 70 | free(element->ptrvalue); 71 | } 72 | 73 | void* errstack_push_malloc(struct errstack_t *errstack, void *element) { 74 | return errstack_push_generic_nonnull_ptr(errstack, errstack_free_malloc, element); 75 | } 76 | 77 | static void errstack_free_fd(struct errstack_element_t *element) { 78 | close(element->intvalue); 79 | } 80 | 81 | int errstack_push_fd(struct errstack_t *errstack, int fd) { 82 | if (fd >= 0) { 83 | return errstack_push_int(errstack, errstack_free_fd, fd); 84 | } else { 85 | return fd; 86 | } 87 | } 88 | 89 | void *errstack_pop_until(struct errstack_t *errstack, int keep_on_stack_cnt) { 90 | for (int i = errstack->count - 1; i >= keep_on_stack_cnt; i--) { 91 | errstack->element[i].free_callback(&errstack->element[i]); 92 | errstack->count--; 93 | errstack_post_pop(errstack); 94 | } 95 | return NULL; 96 | } 97 | 98 | void *errstack_pop_all(struct errstack_t *errstack) { 99 | return errstack_pop_until(errstack, 0); 100 | } 101 | -------------------------------------------------------------------------------- /errstack.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #ifndef __ERRSTACK_H__ 25 | #define __ERRSTACK_H__ 26 | 27 | #define MAX_ERRSTACK_DEPTH 16 28 | 29 | struct errstack_element_t; 30 | typedef void (*errstack_free_callback_t)(struct errstack_element_t *); 31 | 32 | struct errstack_element_t { 33 | errstack_free_callback_t free_callback; 34 | union { 35 | void *ptrvalue; 36 | int intvalue; 37 | }; 38 | }; 39 | 40 | struct errstack_t { 41 | int count; 42 | struct errstack_element_t element[MAX_ERRSTACK_DEPTH]; 43 | }; 44 | 45 | #define ERRSTACK_INIT { .count = 0 } 46 | 47 | /*************** AUTO GENERATED SECTION FOLLOWS ***************/ 48 | void* errstack_push_generic_ptr(struct errstack_t *errstack, errstack_free_callback_t free_callback, void *element); 49 | void* errstack_push_generic_nonnull_ptr(struct errstack_t *errstack, errstack_free_callback_t free_callback, void *element); 50 | int errstack_push_int(struct errstack_t *errstack, errstack_free_callback_t free_callback, int element); 51 | void* errstack_push_malloc(struct errstack_t *errstack, void *element); 52 | int errstack_push_fd(struct errstack_t *errstack, int fd); 53 | void *errstack_pop_until(struct errstack_t *errstack, int keep_on_stack_cnt); 54 | void *errstack_pop_all(struct errstack_t *errstack); 55 | /*************** AUTO GENERATED SECTION ENDS ***************/ 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /getoptgen/Patcher.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # ratched - TLS connection router that performs a man-in-the-middle attack 3 | # Copyright (C) 2017-2017 Johannes Bauer 4 | # 5 | # This file is part of ratched. 6 | # 7 | # ratched is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; this program is ONLY licensed under 10 | # version 3 of the License, later versions are explicitly excluded. 11 | # 12 | # ratched is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with ratched; if not, write to the Free Software 19 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | # 21 | # Johannes Bauer 22 | import re 23 | 24 | class Patcher(object): 25 | def __init__(self, filename, filetype = "c"): 26 | assert(filetype in [ "c", "markdown" ]) 27 | self._filename = filename 28 | self._filetype = filetype 29 | 30 | def _begin_re_str(self, key): 31 | return { 32 | "c": r"/\* Begin of %s -- auto-generated, do not edit! \*/\n" % (key), 33 | "markdown": r"\[//\]: # \(Begin of %s -- auto-generated, do not edit!\)" % (key), 34 | }[self._filetype] 35 | 36 | def _end_re_str(self, key): 37 | return { 38 | "c": r"[\t ]*/\* End of %s -- auto-generated, do not edit! \*/" % (key), 39 | "markdown": r"\[//\]: # \(End of %s -- auto-generated, do not edit!\)" % (key), 40 | }[self._filetype] 41 | 42 | def regex(self, key): 43 | regex = re.compile("(?P" + self._begin_re_str(key) + ")(?P.*?)(?P" + self._end_re_str(key) + ")", flags = re.DOTALL) 44 | return regex 45 | 46 | def patch(self, key, value): 47 | with open(self._filename) as f: 48 | text = f.read() 49 | regex = self.regex(key) 50 | def substitute(match): 51 | groups = match.groupdict() 52 | return groups["begin"] + value + groups["end"] 53 | text = regex.sub(lambda match: substitute(match), text) 54 | with open(self._filename, "w") as f: 55 | f.write(text) 56 | 57 | -------------------------------------------------------------------------------- /hexdump.c: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #include 25 | #include 26 | #include "hexdump.h" 27 | 28 | static const struct hexdump_fmt_t default_format = { 29 | .bytes_per_line = 16, 30 | .short_break = 4, 31 | .long_break = 8, 32 | }; 33 | 34 | static void hexdump_data_left_col(FILE *f, const struct hexdump_fmt_t *fmt, const uint8_t *data, unsigned int length) { 35 | for (int i = 0; i < fmt->bytes_per_line; i++) { 36 | if (i) { 37 | if ((i % fmt->long_break) == 0) { 38 | fprintf(f, " "); 39 | } else if ((i % fmt->short_break) == 0) { 40 | fprintf(f, " "); 41 | } 42 | } 43 | if (i < length) { 44 | fprintf(f, "%02x ", data[i]); 45 | } else { 46 | fprintf(f, " "); 47 | } 48 | } 49 | } 50 | 51 | static void hexdump_data_right_col(FILE *f, const struct hexdump_fmt_t *fmt, const uint8_t *data, unsigned int length) { 52 | for (int i = 0; i < fmt->bytes_per_line; i++) { 53 | if (i < length) { 54 | char c = data[i]; 55 | if ((c > 32) && (c < 127)) { 56 | fprintf(f, "%c", c); 57 | } else { 58 | fprintf(f, "."); 59 | } 60 | } else { 61 | fprintf(f, " "); 62 | } 63 | } 64 | } 65 | 66 | void hexdump_data_fmt(FILE *f, const struct hexdump_fmt_t *fmt, const void *data, unsigned int length) { 67 | int line_count = (length + fmt->bytes_per_line - 1) / fmt->bytes_per_line; 68 | for (int lineno = 0; lineno < line_count; lineno++) { 69 | unsigned int offset = fmt->bytes_per_line * lineno; 70 | const uint8_t *linedata = (const uint8_t*)data + offset; 71 | unsigned int bytes_in_line = length - offset; 72 | if (bytes_in_line > fmt->bytes_per_line) { 73 | bytes_in_line = fmt->bytes_per_line; 74 | } 75 | fprintf(f, "%6x ", offset); 76 | hexdump_data_left_col(f, fmt, linedata, bytes_in_line); 77 | fprintf(f, " | "); 78 | hexdump_data_right_col(f, fmt, linedata, bytes_in_line); 79 | fprintf(f, " |\n"); 80 | } 81 | } 82 | 83 | void hexdump_data(FILE *f, const void *data, unsigned int length) { 84 | hexdump_data_fmt(f, &default_format, data, length); 85 | } 86 | -------------------------------------------------------------------------------- /hexdump.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #ifndef __HEXDUMP_H__ 25 | #define __HEXDUMP_H__ 26 | 27 | #include 28 | 29 | struct hexdump_fmt_t { 30 | unsigned int bytes_per_line; 31 | unsigned int short_break; 32 | unsigned int long_break; 33 | }; 34 | 35 | /*************** AUTO GENERATED SECTION FOLLOWS ***************/ 36 | void hexdump_data_fmt(FILE *f, const struct hexdump_fmt_t *fmt, const void *data, unsigned int length); 37 | void hexdump_data(FILE *f, const void *data, unsigned int length); 38 | /*************** AUTO GENERATED SECTION ENDS ***************/ 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /hostname_ids.c: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #include 25 | #include 26 | #include 27 | #include "logging.h" 28 | #include "hostname_ids.h" 29 | #include "map.h" 30 | 31 | static struct map_t *ip_to_hostnames; 32 | /* ip_to_hostnames = { 33 | * 0x11223344: { 34 | * "foobar": 1, 35 | * "barfoo": 2, 36 | * "mookoo": 3, 37 | * }, 38 | * 0x22334455: { 39 | * "moo.com": 1, 40 | * "bar.de": 2, 41 | * }, 42 | * } 43 | */ 44 | 45 | unsigned int resolve_hostname_id(uint32_t ipv4_nbo, const char *hostname) { 46 | if (!hostname) { 47 | return 0; 48 | } 49 | 50 | struct map_t *map = map_get(ip_to_hostnames, &ipv4_nbo, sizeof(uint32_t)); 51 | if (!map) { 52 | /* No entry for that IP address so far */ 53 | map = map_new(); 54 | if (!map) { 55 | logmsg(LLVL_FATAL, "Unable to create inner map for hostname entry for \"%s\", returning 0.", hostname); 56 | return 0; 57 | } 58 | if (!map_set_ptr(ip_to_hostnames, &ipv4_nbo, sizeof(uint32_t), map)) { 59 | logmsg(LLVL_FATAL, "Unable to register inner map for hostname entry for \"%s\", returning 0.", hostname); 60 | map_free(map); 61 | return 0; 62 | } 63 | } 64 | 65 | int hostname_id = strmap_get_int(map, hostname); 66 | if (hostname_id == -1) { 67 | hostname_id = map->element_count + 1; 68 | strmap_set_int(map, hostname, hostname_id); 69 | } 70 | 71 | return hostname_id; 72 | } 73 | 74 | void init_hostname_ids(void) { 75 | ip_to_hostnames = map_new(); 76 | } 77 | 78 | static void free_inner_map(void *inner_map) { 79 | map_free((struct map_t*)inner_map); 80 | } 81 | 82 | void deinit_hostname_ids(void) { 83 | map_foreach_ptrvalue(ip_to_hostnames, free_inner_map); 84 | map_free(ip_to_hostnames); 85 | } 86 | -------------------------------------------------------------------------------- /hostname_ids.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #ifndef __HOSTNAME_IDS_H__ 25 | #define __HOSTNAME_IDS_H__ 26 | 27 | #include 28 | 29 | /*************** AUTO GENERATED SECTION FOLLOWS ***************/ 30 | unsigned int resolve_hostname_id(uint32_t ipv4_nbo, const char *hostname); 31 | void init_hostname_ids(void); 32 | void deinit_hostname_ids(void); 33 | /*************** AUTO GENERATED SECTION ENDS ***************/ 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /intercept_config.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #ifndef __INTERCEPT_CONFIG_H__ 25 | #define __INTERCEPT_CONFIG_H__ 26 | 27 | #include 28 | #include 29 | 30 | enum interception_mode_t { 31 | INTERCEPTION_MODE_UNDEFINED = 0, 32 | OPPORTUNISTIC_TLS_INTERCEPTION, 33 | MANDATORY_TLS_INTERCEPTION, 34 | TRAFFIC_FORWARDING, 35 | REJECT_CONNECTION, 36 | }; 37 | 38 | enum tls_version_t { 39 | TLS_VERSION_UNDEFINED = 0, 40 | TLS_VERSION_SSL2 = (1 << 0), 41 | TLS_VERSION_SSL3 = (1 << 1), 42 | TLS_VERSION_TLS10 = (1 << 2), 43 | TLS_VERSION_TLS11 = (1 << 3), 44 | TLS_VERSION_TLS12 = (1 << 4), 45 | TLS_VERSION_TLS13 = (1 << 5), 46 | }; 47 | 48 | struct intercept_side_config_t { 49 | // Makes only sense for 'server', but easier this way. 50 | bool request_client_cert; 51 | bool ocsp_status; 52 | bool include_root_ca_cert; 53 | uint32_t tls_versions; 54 | 55 | char *cert_filename; 56 | char *key_filename; 57 | char *chain_filename; 58 | 59 | char *ca_cert_filename; 60 | char *ca_key_filename; 61 | 62 | char *ciphersuites; 63 | char *supported_groups; 64 | char *signature_algorithms; 65 | }; 66 | 67 | struct intercept_config_t { 68 | char *hostname; 69 | uint32_t ipv4_nbo; 70 | enum interception_mode_t interception_mode; 71 | struct intercept_side_config_t server; 72 | struct intercept_side_config_t client; 73 | }; 74 | 75 | 76 | /*************** AUTO GENERATED SECTION FOLLOWS ***************/ 77 | const char *interception_mode_to_str(enum interception_mode_t value); 78 | struct intercept_config_t* intercept_config_new(const char *connection_params, bool contains_hostname); 79 | void intercept_config_free(struct intercept_config_t *config); 80 | /*************** AUTO GENERATED SECTION ENDS ***************/ 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /interceptdb.c: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include "interceptdb.h" 29 | #include "pgmopts.h" 30 | #include "intercept_config.h" 31 | #include "certforgery.h" 32 | #include "map.h" 33 | 34 | static struct intercept_entry_t default_entry; 35 | static struct map_t *intercept_entry_by_hostname; 36 | 37 | struct intercept_entry_t* interceptdb_find_entry(const char *hostname, uint32_t ipv4_nbo) { 38 | struct intercept_entry_t *entry = (struct intercept_entry_t*)strmap_get(intercept_entry_by_hostname, hostname); 39 | if (!entry) { 40 | return &default_entry; 41 | } else { 42 | return entry; 43 | } 44 | } 45 | 46 | static void initialize_default_intercept_entry(struct intercept_entry_t *new_entry) { 47 | new_entry->interception_mode = OPPORTUNISTIC_TLS_INTERCEPTION; 48 | new_entry->server_template.ocsp_status = true; 49 | new_entry->client_template.ocsp_status = true; 50 | new_entry->server_template.tls_versions = TLS_VERSION_TLS10 | TLS_VERSION_TLS11 | TLS_VERSION_TLS12 | TLS_VERSION_TLS13; 51 | new_entry->client_template.tls_versions = TLS_VERSION_TLS10 | TLS_VERSION_TLS11 | TLS_VERSION_TLS12 | TLS_VERSION_TLS13; 52 | } 53 | 54 | static bool init_tls_intercept_entry(struct tls_endpoint_config_t *config, const struct intercept_side_config_t *side_config, const char *description) { 55 | struct tls_endpoint_cert_source_t certsrc = { 56 | .cert_filename = side_config->cert_filename, 57 | .key_filename = side_config->key_filename, 58 | .chain_filename = side_config->chain_filename, 59 | .certificate_authority = { 60 | .cert_filename = side_config->ca_cert_filename, 61 | .key_filename = side_config->ca_key_filename, 62 | }, 63 | }; 64 | if (!init_tls_endpoint_config(config, description, &certsrc)) { 65 | return false; 66 | } 67 | if (config->certificate_authority.cert && config->certificate_authority.key) { 68 | /* Use CA server and key as OCSP responder */ 69 | config->ocsp_responder.cert = config->certificate_authority.cert; 70 | config->ocsp_responder.key = config->certificate_authority.key; 71 | X509_up_ref(config->ocsp_responder.cert); 72 | EVP_PKEY_up_ref(config->ocsp_responder.key); 73 | } 74 | config->request_cert_from_peer = side_config->request_client_cert; 75 | config->ocsp_status = side_config->ocsp_status; 76 | config->include_root_ca_cert = side_config->include_root_ca_cert; 77 | if (side_config->tls_versions != TLS_VERSION_UNDEFINED) { 78 | config->tls_versions = side_config->tls_versions; 79 | } 80 | config->ciphersuites = side_config->ciphersuites; 81 | config->supported_groups = side_config->supported_groups; 82 | config->signature_algorithms = side_config->signature_algorithms; 83 | return true; 84 | } 85 | 86 | static bool initialize_intercept_entry_from_pgm_config(struct intercept_entry_t *new_entry, const struct intercept_config_t *pgm_config) { 87 | memset(new_entry, 0, sizeof(struct intercept_entry_t)); 88 | initialize_default_intercept_entry(new_entry); 89 | if (pgm_config) { 90 | if (pgm_config->interception_mode != INTERCEPTION_MODE_UNDEFINED) { 91 | new_entry->interception_mode = pgm_config->interception_mode; 92 | } 93 | new_entry->hostname = pgm_config->hostname; 94 | new_entry->ipv4_nbo = pgm_config->ipv4_nbo; 95 | 96 | char text[128]; 97 | snprintf(text, sizeof(text), "%s client", pgm_config->hostname); 98 | if (!init_tls_intercept_entry(&new_entry->client_template, &pgm_config->client, text)) { 99 | return false; 100 | } 101 | snprintf(text, sizeof(text), "%s server", pgm_config->hostname); 102 | if (!init_tls_intercept_entry(&new_entry->server_template, &pgm_config->server, text)) { 103 | return false; 104 | } 105 | } 106 | 107 | /* Defaults that apply even when options are specified -- for example, if 108 | * only client cert is specified, the internal server cert should still be 109 | * used instead of throwing an error that it hasn't been specified. */ 110 | if (!new_entry->server_template.key) { 111 | new_entry->server_template.key = get_tls_server_key(); 112 | } 113 | if (!new_entry->server_template.certificate_authority.key && !new_entry->server_template.certificate_authority.cert) { 114 | new_entry->server_template.certificate_authority.cert = get_forged_root_certificate(); 115 | new_entry->server_template.certificate_authority.key = get_forged_root_key(); 116 | } 117 | if (!new_entry->server_template.ocsp_responder.key && !new_entry->server_template.ocsp_responder.cert) { 118 | new_entry->server_template.ocsp_responder.cert = get_forged_root_certificate(); 119 | new_entry->server_template.ocsp_responder.key = get_forged_root_key(); 120 | } 121 | return true; 122 | } 123 | 124 | bool init_interceptdb(void) { 125 | if (!initialize_intercept_entry_from_pgm_config(&default_entry, pgm_options->default_config)) { 126 | return false; 127 | } 128 | 129 | intercept_entry_by_hostname = map_new(); 130 | for (int i = 0; i < pgm_options->custom_configs->element_count; i++) { 131 | struct intercept_config_t *pgm_config = (struct intercept_config_t *)pgm_options->custom_configs->elements[i]->value.pointer; 132 | struct map_element_t *new_map_entry = strmap_set_mem(intercept_entry_by_hostname, pgm_config->hostname, NULL, sizeof(struct intercept_entry_t)); 133 | if (!new_map_entry) { 134 | return false; 135 | } 136 | struct intercept_entry_t *new_entry = (struct intercept_entry_t*)new_map_entry->value.pointer; 137 | initialize_intercept_entry_from_pgm_config(new_entry, pgm_config); 138 | } 139 | return true; 140 | } 141 | 142 | static void free_entry(void *vintercept_entry) { 143 | struct intercept_entry_t *intercept_entry = (struct intercept_entry_t*)vintercept_entry; 144 | free_tls_endpoint_config(&intercept_entry->client_template); 145 | free_tls_endpoint_config(&intercept_entry->server_template); 146 | } 147 | 148 | void deinit_interceptdb(void) { 149 | free_entry(&default_entry); 150 | map_foreach_ptrvalue(intercept_entry_by_hostname, free_entry); 151 | map_free(intercept_entry_by_hostname); 152 | } 153 | 154 | -------------------------------------------------------------------------------- /interceptdb.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #ifndef __INTERCEPTDB_H__ 25 | #define __INTERCEPTDB_H__ 26 | 27 | #include "openssl_certs.h" 28 | #include "intercept_config.h" 29 | 30 | struct intercept_entry_t { 31 | const char *hostname; 32 | uint32_t ipv4_nbo; 33 | enum interception_mode_t interception_mode; 34 | struct tls_endpoint_config_t server_template; 35 | struct tls_endpoint_config_t client_template; 36 | }; 37 | 38 | /*************** AUTO GENERATED SECTION FOLLOWS ***************/ 39 | struct intercept_entry_t* interceptdb_find_entry(const char *hostname, uint32_t ipv4_nbo); 40 | bool init_interceptdb(void); 41 | void deinit_interceptdb(void); 42 | /*************** AUTO GENERATED SECTION ENDS ***************/ 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /ipfwd.c: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include "logging.h" 34 | #include "ipfwd.h" 35 | 36 | int tcp_accept(uint16_t port_nbo) { 37 | int sd = socket(AF_INET, SOCK_STREAM, 0); 38 | if (sd == -1) { 39 | return -1; 40 | } 41 | 42 | { 43 | int enable = 1; 44 | if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable)) < 0) { 45 | logmsg(LLVL_ERROR, "setsockopt(SO_REUSEADDR) failed: %s", strerror(errno)); 46 | close(sd); 47 | return -1; 48 | } 49 | } 50 | 51 | struct sockaddr_in serv_addr; 52 | memset(&serv_addr, 0, sizeof(serv_addr)); 53 | serv_addr.sin_family = AF_INET; 54 | serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); 55 | serv_addr.sin_port = port_nbo; 56 | 57 | if (bind(sd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1) { 58 | logmsg(LLVL_ERROR, "Binding socket on " PRI_IPv4_PORT " failed: %s", FMT_IPv4_PORT(serv_addr), strerror(errno)); 59 | close(sd); 60 | return -1; 61 | } 62 | 63 | if (listen(sd, 1) == -1) { 64 | logmsg(LLVL_ERROR, "Listening on bound socket failed: %s", strerror(errno)); 65 | close(sd); 66 | return -1; 67 | } 68 | 69 | int peer_sd = accept(sd, NULL, NULL); 70 | if (peer_sd == -1) { 71 | logmsg(LLVL_ERROR, "Accepting on bound socket failed: %s", strerror(errno)); 72 | close(sd); 73 | return -1; 74 | } 75 | 76 | close(sd); 77 | return peer_sd; 78 | } 79 | 80 | int tcp_connect(uint32_t ip_nbo, uint16_t port_nbo) { 81 | int sd = socket(AF_INET, SOCK_STREAM, 0); 82 | if (sd == -1) { 83 | return -1; 84 | } 85 | 86 | struct sockaddr_in peer; 87 | memset(&peer, 0, sizeof(peer)); 88 | peer.sin_family = AF_INET; 89 | peer.sin_addr.s_addr = ip_nbo; 90 | peer.sin_port = port_nbo; 91 | 92 | logmsg(LLVL_DEBUG, "Connecting to " PRI_IPv4 ":%d for SD %d", FMT_IPv4(ip_nbo), ntohs(port_nbo), sd); 93 | if (connect(sd, (struct sockaddr*)&peer, sizeof(peer)) == -1) { 94 | int saved_errno = errno; 95 | close(sd); 96 | errno = saved_errno; 97 | return -1; 98 | } 99 | 100 | return sd; 101 | } 102 | -------------------------------------------------------------------------------- /ipfwd.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #ifndef __IPFWD_H__ 25 | #define __IPFWD_H__ 26 | 27 | #define IPv4ADDR(a, b, c, d) ((((a) & 0xff) << 24) | (((b) & 0xff) << 16) | (((c) & 0xff) << 8) | (((d) & 0xff) << 0)) 28 | 29 | #define PRI_IPv4 "%d.%d.%d.%d" 30 | #define FMT_IPv4(x) ((x) >> 0) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, ((x) >> 24) & 0xff 31 | 32 | #define PRI_IPv4_PORT PRI_IPv4 ":%d" 33 | #define FMT_IPv4_PORT_TUPLE(ip, port) FMT_IPv4(ip), ntohs(port) 34 | #define FMT_IPv4_PORT(saddr_in) FMT_IPv4_PORT_TUPLE((saddr_in).sin_addr.s_addr, (saddr_in).sin_port) 35 | 36 | #include 37 | 38 | /*************** AUTO GENERATED SECTION FOLLOWS ***************/ 39 | int tcp_accept(uint16_t port_nbo); 40 | int tcp_connect(uint32_t ip_nbo, uint16_t port_nbo); 41 | /*************** AUTO GENERATED SECTION ENDS ***************/ 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /itests/demo_ca/client_intermediate.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIB/DCCAaKgAwIBAgIUduMXkFj36egQyYl7jMizpUluEVkwCgYIKoZIzj0EAwIw 3 | IzEhMB8GA1UEAwwYVmVyeSB0cnVzdHdvcnRoeSByb290IENBMB4XDTE3MTIwOTA5 4 | MDIyM1oXDTIyMTIwODA5MDIyM1owMzExMC8GA1UEAwwoU3VwZXIgdHJ1c3R3b3J0 5 | aHkgY2xpZW50IGludGVybWVkaWF0ZSBDQTBZMBMGByqGSM49AgEGCCqGSM49AwEH 6 | A0IABEdV96rYkMuRb7WbRv63rzO1oaw4kDC2JCgIlrLVg5gN3BjjiSX03yzGVyiL 7 | C8bqw9uF49XGB1CimhT5P1IeFwqjgaMwgaAwDwYDVR0TAQH/BAUwAwEB/zAdBgNV 8 | HQ4EFgQUk2REoyghyrAIeSSjHIsWDVKAj+8wDgYDVR0PAQH/BAQDAgGGMF4GA1Ud 9 | IwRXMFWAFER4sxj5mna5xxMlewo0RwWLqLAYoSekJTAjMSEwHwYDVQQDDBhWZXJ5 10 | IHRydXN0d29ydGh5IHJvb3QgQ0GCFHXGWR/O0ynXwnb7yfPgfF9OXPKJMAoGCCqG 11 | SM49BAMCA0gAMEUCIQDkNb++AGhTedRJZVkrNiIB7D++yoxs0IIS9lBo1PyhLQIg 12 | F5CAUaxq+Ngc35DCTWMUWqsEAsNGWVw9ELl+Ez2/ltI= 13 | -----END CERTIFICATE----- 14 | -------------------------------------------------------------------------------- /itests/demo_ca/client_intermediate.key: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PARAMETERS----- 2 | BggqhkjOPQMBBw== 3 | -----END EC PARAMETERS----- 4 | -----BEGIN EC PRIVATE KEY----- 5 | MHcCAQEEIF1NoKRZb4o7bikvlwgAnVaM7ddxRQ0+TlN1UhdmF13xoAoGCCqGSM49 6 | AwEHoUQDQgAER1X3qtiQy5FvtZtG/revM7WhrDiQMLYkKAiWstWDmA3cGOOJJfTf 7 | LMZXKIsLxurD24Xj1cYHUKKaFPk/Uh4XCg== 8 | -----END EC PRIVATE KEY----- 9 | -------------------------------------------------------------------------------- /itests/demo_ca/client_intermediate.srl: -------------------------------------------------------------------------------- 1 | 772DD275B6DB2CD08135543635B8F6318C8EDED4 2 | -------------------------------------------------------------------------------- /itests/demo_ca/client_joe.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICIjCCAcigAwIBAgIUdy3SdbbbLNCBNVQ2Nbj2MYyO3tMwCgYIKoZIzj0EAwIw 3 | MzExMC8GA1UEAwwoU3VwZXIgdHJ1c3R3b3J0aHkgY2xpZW50IGludGVybWVkaWF0 4 | ZSBDQTAeFw0xNzEyMDkwOTAyMjNaFw0yMjEyMDgwOTAyMjNaMCQxDDAKBgNVBAMM 5 | A2pvZTEUMBIGA1UECwwLQ2xpZW50IGNlcnQwWTATBgcqhkjOPQIBBggqhkjOPQMB 6 | BwNCAATKZHN0/cEPd5M3xQEGHBY4T8AxuNmNpaxXs/DCpa45fWDnBgeIhIeIMdZz 7 | dSV2P6+d8j2Yw4qYycpYJaWNe+Nwo4HIMIHFMBMGA1UdJQQMMAoGCCsGAQUFBwMC 8 | MBEGCWCGSAGG+EIBAQQEAwIHgDAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBRMQJaP 9 | Rq1c0qi+Yeeg9iP5/DW8yTAOBgNVHQ8BAf8EBAMCA6gwXgYDVR0jBFcwVYAUk2RE 10 | oyghyrAIeSSjHIsWDVKAj++hJ6QlMCMxITAfBgNVBAMMGFZlcnkgdHJ1c3R3b3J0 11 | aHkgcm9vdCBDQYIUduMXkFj36egQyYl7jMizpUluEVkwCgYIKoZIzj0EAwIDSAAw 12 | RQIhAO1N7+xOqQcrx3zep2hS4/9G4/nZKOoAAoKwBB+nhqInAiBzKmoC0jEISmR8 13 | /60QKYY31SLdwHoG/FvFChCb+mm77g== 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /itests/demo_ca/client_joe.key: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PARAMETERS----- 2 | BggqhkjOPQMBBw== 3 | -----END EC PARAMETERS----- 4 | -----BEGIN EC PRIVATE KEY----- 5 | MHcCAQEEIIQcB+ZyT7r5ZhZ10aztAZRhn+v+T8wGMim08XWAzW4KoAoGCCqGSM49 6 | AwEHoUQDQgAEymRzdP3BD3eTN8UBBhwWOE/AMbjZjaWsV7PwwqWuOX1g5wYHiISH 7 | iDHWc3Uldj+vnfI9mMOKmMnKWCWljXvjcA== 8 | -----END EC PRIVATE KEY----- 9 | -------------------------------------------------------------------------------- /itests/demo_ca/client_julaia.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICJTCCAcugAwIBAgIUdy3SdbbbLNCBNVQ2Nbj2MYyO3tQwCgYIKoZIzj0EAwIw 3 | MzExMC8GA1UEAwwoU3VwZXIgdHJ1c3R3b3J0aHkgY2xpZW50IGludGVybWVkaWF0 4 | ZSBDQTAeFw0xNzEyMDkwOTAyMjNaFw0yMjEyMDgwOTAyMjNaMCcxDzANBgNVBAMM 5 | Bmp1bGFpYTEUMBIGA1UECwwLQ2xpZW50IGNlcnQwWTATBgcqhkjOPQIBBggqhkjO 6 | PQMBBwNCAATRC2OYI8O0f5bbM+QQh44AvZQSe03szgNGP9nisANY96JVBd1lDckL 7 | XsKfXGgktwZZjb9L0rK3iMbK/1iajrV2o4HIMIHFMBMGA1UdJQQMMAoGCCsGAQUF 8 | BwMCMBEGCWCGSAGG+EIBAQQEAwIHgDAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBSj 9 | gTcijfnbcwSXaG263rf0kKdAsjAOBgNVHQ8BAf8EBAMCA6gwXgYDVR0jBFcwVYAU 10 | k2REoyghyrAIeSSjHIsWDVKAj++hJ6QlMCMxITAfBgNVBAMMGFZlcnkgdHJ1c3R3 11 | b3J0aHkgcm9vdCBDQYIUduMXkFj36egQyYl7jMizpUluEVkwCgYIKoZIzj0EAwID 12 | SAAwRQIgYt3/AkjwgNveAjeTniyFksm8vu4u2wSAQ6rChgMmsBQCIQDNbDCN35tE 13 | 9nzCCyjl0IOicKJREe7vAg2K3GDyj+2LRg== 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /itests/demo_ca/client_julaia.key: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PARAMETERS----- 2 | BggqhkjOPQMBBw== 3 | -----END EC PARAMETERS----- 4 | -----BEGIN EC PRIVATE KEY----- 5 | MHcCAQEEII3k5BRqFR5TKJLL9wg50buaouY+lFlLyf61og/3jxVSoAoGCCqGSM49 6 | AwEHoUQDQgAE0QtjmCPDtH+W2zPkEIeOAL2UEntN7M4DRj/Z4rADWPeiVQXdZQ3J 7 | C17Cn1xoJLcGWY2/S9Kyt4jGyv9Ymo61dg== 8 | -----END EC PRIVATE KEY----- 9 | -------------------------------------------------------------------------------- /itests/demo_ca/intermediate.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIB9TCCAZugAwIBAgIUduMXkFj36egQyYl7jMizpUluEVgwCgYIKoZIzj0EAwIw 3 | IzEhMB8GA1UEAwwYVmVyeSB0cnVzdHdvcnRoeSByb290IENBMB4XDTE3MTIwMjE4 4 | MjMyMloXDTIyMTIwMTE4MjMyMlowLDEqMCgGA1UEAwwhU3VwZXIgdHJ1c3R3b3J0 5 | aHkgaW50ZXJtZWRpYXRlIENBMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE3g+n 6 | Rgxx3jlEM5nTV3uSnThTn6F9XrIIq691oG8Yw/UZiCcSE8s8o4pHikQLMDmUJaX3 7 | 0M6Pg30x+A7CEpSJbqOBozCBoDBeBgNVHSMEVzBVgBREeLMY+Zp2uccTJXsKNEcF 8 | i6iwGKEnpCUwIzEhMB8GA1UEAwwYVmVyeSB0cnVzdHdvcnRoeSByb290IENBghR1 9 | xlkfztMp18J2+8nz4HxfTlzyiTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE 10 | AwIBhjAdBgNVHQ4EFgQUJZD2TVy0YI2iTvUonfqAiklWEzkwCgYIKoZIzj0EAwID 11 | SAAwRQIgObF+gJ9jADkf4yBM82rxewJ+sBI+25J8ujpXjQ/D+VcCIQD7PfoMPTFC 12 | T4M/XjSynVYAcQb90dB6ngS1Etz3mxEPkw== 13 | -----END CERTIFICATE----- 14 | -------------------------------------------------------------------------------- /itests/demo_ca/intermediate.key: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PARAMETERS----- 2 | BggqhkjOPQMBBw== 3 | -----END EC PARAMETERS----- 4 | -----BEGIN EC PRIVATE KEY----- 5 | MHcCAQEEIDh1SfO3tDjfCCPItJiQ2foas279MuqMpDesE3QKGA0UoAoGCCqGSM49 6 | AwEHoUQDQgAE3g+nRgxx3jlEM5nTV3uSnThTn6F9XrIIq691oG8Yw/UZiCcSE8s8 7 | o4pHikQLMDmUJaX30M6Pg30x+A7CEpSJbg== 8 | -----END EC PRIVATE KEY----- 9 | -------------------------------------------------------------------------------- /itests/demo_ca/intermediate.srl: -------------------------------------------------------------------------------- 1 | 1F93B99A9B654A3D4E524EF9D2B2EE972DDB5AC1 2 | -------------------------------------------------------------------------------- /itests/demo_ca/root.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIB1TCCAXygAwIBAgIUdcZZH87TKdfCdvvJ8+B8X05c8okwCgYIKoZIzj0EAwIw 3 | IzEhMB8GA1UEAwwYVmVyeSB0cnVzdHdvcnRoeSByb290IENBMB4XDTE3MTIwMjE4 4 | MjMyMloXDTIyMTIwMTE4MjMyMlowIzEhMB8GA1UEAwwYVmVyeSB0cnVzdHdvcnRo 5 | eSByb290IENBMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE/2iZoxmfBaCEl3tg 6 | cd9Ya2NCn02OTryNrLci+FO0aRPnTUSmtlABCA2N81yp1k06NLlhMLsjjI9fpG6H 7 | Yv/3sqOBjTCBijBIBgNVHSMEQTA/oSekJTAjMSEwHwYDVQQDDBhWZXJ5IHRydXN0 8 | d29ydGh5IHJvb3QgQ0GCFHXGWR/O0ynXwnb7yfPgfF9OXPKJMA8GA1UdEwEB/wQF 9 | MAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBREeLMY+Zp2uccTJXsKNEcF 10 | i6iwGDAKBggqhkjOPQQDAgNHADBEAiAiI/osG79FV9DxNCOcmfbeRFy3iaAgITKj 11 | bAv7ZxfaSQIgBsvGoRGDJ9o4qvMuF0rC0otrBXAK6RA+sElrCEldusM= 12 | -----END CERTIFICATE----- 13 | -------------------------------------------------------------------------------- /itests/demo_ca/root.key: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PARAMETERS----- 2 | BggqhkjOPQMBBw== 3 | -----END EC PARAMETERS----- 4 | -----BEGIN EC PRIVATE KEY----- 5 | MHcCAQEEINR/QYFC9h12fIPh/4ncXLfBe6gAiAUOh4Qw4utpQTJpoAoGCCqGSM49 6 | AwEHoUQDQgAE/2iZoxmfBaCEl3tgcd9Ya2NCn02OTryNrLci+FO0aRPnTUSmtlAB 7 | CA2N81yp1k06NLlhMLsjjI9fpG6HYv/3sg== 8 | -----END EC PRIVATE KEY----- 9 | -------------------------------------------------------------------------------- /itests/demo_ca/root.srl: -------------------------------------------------------------------------------- 1 | 76E3179058F7E9E810C9897B8CC8B3A5496E1159 2 | -------------------------------------------------------------------------------- /itests/demo_ca/server_bar.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICMDCCAdegAwIBAgIUH5O5mptlSj1OUk750rLuly3bWsAwCgYIKoZIzj0EAwIw 3 | LDEqMCgGA1UEAwwhU3VwZXIgdHJ1c3R3b3J0aHkgaW50ZXJtZWRpYXRlIENBMB4X 4 | DTE3MTIxMTA5MTQ0MFoXDTIyMTIxMDA5MTQ0MFowJDEMMAoGA1UEAwwDYmFyMRQw 5 | EgYDVQQLDAtTZXJ2ZXIgY2VydDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABP56 6 | +PYEBNi61Xn7uy6BBUwDg7pysHQZybEuIWqYhfRF0BYlIyvVhUh/KdHecHncSBMO 7 | e0HJML7rQLjR+tIuJt+jgd4wgdswEQYJYIZIAYb4QgEBBAQDAgZAMAwGA1UdEwEB 8 | /wQCMAAwHQYDVR0OBBYEFH7g/nJ/KK/LLULaBof5ZOR8ffTOMF4GA1UdIwRXMFWA 9 | FCWQ9k1ctGCNok71KJ36gIpJVhM5oSekJTAjMSEwHwYDVQQDDBhWZXJ5IHRydXN0 10 | d29ydGh5IHJvb3QgQ0GCFHbjF5BY9+noEMmJe4zIs6VJbhFYMA4GA1UdDwEB/wQE 11 | AwIDqDATBgNVHSUEDDAKBggrBgEFBQcDATAUBgNVHREEDTALggNiYXKHBH8AAAEw 12 | CgYIKoZIzj0EAwIDRwAwRAIgaVIMjJkbSHa/8jII/MEl5kGC1kcnKrNQrYPMl30s 13 | 7kECIH2Xkbr+i7uO9XEw6HNXGwOghxLOLmGSiZ1T9jx8v9n8 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /itests/demo_ca/server_bar.key: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PARAMETERS----- 2 | BggqhkjOPQMBBw== 3 | -----END EC PARAMETERS----- 4 | -----BEGIN EC PRIVATE KEY----- 5 | MHcCAQEEIKuXVW2Mn4cUBbVQUM7ktU9Z7kRtH5qPkrzJbJsXRC1koAoGCCqGSM49 6 | AwEHoUQDQgAE/nr49gQE2LrVefu7LoEFTAODunKwdBnJsS4hapiF9EXQFiUjK9WF 7 | SH8p0d5wedxIEw57QckwvutAuNH60i4m3w== 8 | -----END EC PRIVATE KEY----- 9 | -------------------------------------------------------------------------------- /itests/demo_ca/server_foo.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICMDCCAdegAwIBAgIUH5O5mptlSj1OUk750rLuly3bWr8wCgYIKoZIzj0EAwIw 3 | LDEqMCgGA1UEAwwhU3VwZXIgdHJ1c3R3b3J0aHkgaW50ZXJtZWRpYXRlIENBMB4X 4 | DTE3MTIxMTA5MTQ0MFoXDTIyMTIxMDA5MTQ0MFowJDEMMAoGA1UEAwwDZm9vMRQw 5 | EgYDVQQLDAtTZXJ2ZXIgY2VydDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDLw 6 | gomsiwU76dt58XdZ14XE3Ez2jVDURHUQl6a3fnFIgFDUOEbKf6TL05RmDm6rAtHS 7 | CKwWoFxeKtf/B17bQoejgd4wgdswEQYJYIZIAYb4QgEBBAQDAgZAMAwGA1UdEwEB 8 | /wQCMAAwHQYDVR0OBBYEFL6/6ocDOoAO6MJcVwxHdyHOyIjvMF4GA1UdIwRXMFWA 9 | FCWQ9k1ctGCNok71KJ36gIpJVhM5oSekJTAjMSEwHwYDVQQDDBhWZXJ5IHRydXN0 10 | d29ydGh5IHJvb3QgQ0GCFHbjF5BY9+noEMmJe4zIs6VJbhFYMA4GA1UdDwEB/wQE 11 | AwIDqDATBgNVHSUEDDAKBggrBgEFBQcDATAUBgNVHREEDTALggNmb2+HBH8AAAEw 12 | CgYIKoZIzj0EAwIDRwAwRAIgMEIgJuq2XFVWqsh3nMPWtvWvyN6bYN+6LqMdxLtj 13 | TooCIBesHx1qQ9AGOtoQRPWrA/LvX4Lo8SOyJxDQN1ead16R 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /itests/demo_ca/server_foo.key: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PARAMETERS----- 2 | BggqhkjOPQMBBw== 3 | -----END EC PARAMETERS----- 4 | -----BEGIN EC PRIVATE KEY----- 5 | MHcCAQEEICVLKLrnMYdbUC9nBxhlLsU1E9xZmDgFV8cPCqjx7wWzoAoGCCqGSM49 6 | AwEHoUQDQgAEMvCCiayLBTvp23nxd1nXhcTcTPaNUNREdRCXprd+cUiAUNQ4Rsp/ 7 | pMvTlGYObqsC0dIIrBagXF4q1/8HXttChw== 8 | -----END EC PRIVATE KEY----- 9 | -------------------------------------------------------------------------------- /itests/demo_ca/server_moo.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICMTCCAdegAwIBAgIUH5O5mptlSj1OUk750rLuly3bWsEwCgYIKoZIzj0EAwIw 3 | LDEqMCgGA1UEAwwhU3VwZXIgdHJ1c3R3b3J0aHkgaW50ZXJtZWRpYXRlIENBMB4X 4 | DTE3MTIxMTA5MTQ0MFoXDTIyMTIxMDA5MTQ0MFowJDEMMAoGA1UEAwwDbW9vMRQw 5 | EgYDVQQLDAtTZXJ2ZXIgY2VydDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABExC 6 | vDShKK/lpdiEY/hMAchHq5B067oC72N3Bi+7Ldmx2apg/D1lIzlGIpQNYhqMOSIA 7 | 2jGYo5F4NKPnoqKT2Bmjgd4wgdswEQYJYIZIAYb4QgEBBAQDAgZAMAwGA1UdEwEB 8 | /wQCMAAwHQYDVR0OBBYEFPWR/nFn2vR07eBMgimp606CdIivMF4GA1UdIwRXMFWA 9 | FCWQ9k1ctGCNok71KJ36gIpJVhM5oSekJTAjMSEwHwYDVQQDDBhWZXJ5IHRydXN0 10 | d29ydGh5IHJvb3QgQ0GCFHbjF5BY9+noEMmJe4zIs6VJbhFYMA4GA1UdDwEB/wQE 11 | AwIDqDATBgNVHSUEDDAKBggrBgEFBQcDATAUBgNVHREEDTALggNtb2+HBH8AAAEw 12 | CgYIKoZIzj0EAwIDSAAwRQIhAKmuYRZGqBO2VEdh/uReMLmuWSHRAEKhrRkpOt5H 13 | NGQ8AiBseOP1FETRj2bNokTxrn8kOEP/QWwGbwONlmp4/E8mcg== 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /itests/demo_ca/server_moo.key: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PARAMETERS----- 2 | BggqhkjOPQMBBw== 3 | -----END EC PARAMETERS----- 4 | -----BEGIN EC PRIVATE KEY----- 5 | MHcCAQEEIAd0MIRTQ8hL0OqfFwfYeFYAJ1XKZCXCLzG1Q65BiDNIoAoGCCqGSM49 6 | AwEHoUQDQgAETEK8NKEor+Wl2IRj+EwByEerkHTrugLvY3cGL7st2bHZqmD8PWUj 7 | OUYilA1iGow5IgDaMZijkXg0o+eiopPYGQ== 8 | -----END EC PRIVATE KEY----- 9 | -------------------------------------------------------------------------------- /itests/ratched_ca/client.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgVPdmiAEDoqOQ8MD/ 3 | 9Tz+2Vy/G8TriSzy0FW6xUrGINahRANCAAQHV+C/+8mgyhfnI7TofCpx8BZGwmKs 4 | Y5ioawOSxpNG90vzIKCLW6DP3+k1+FbcWKzMDFXdgxO9FhukzvZRSLcf 5 | -----END PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /itests/ratched_ca/root.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBnjCCAUSgAwIBAgIQfrWGH0ITKi6ElBZqk/vM7TAKBggqhkjOPQQDAjAgMR4w 3 | HAYDVQQDDBVFdmlsIHJvb3QgY2VydGlmaWNhdGUwHhcNMTcxMjAyMjAxODM1WhcN 4 | MjIxMjAyMjAxODM1WjAgMR4wHAYDVQQDDBVFdmlsIHJvb3QgY2VydGlmaWNhdGUw 5 | WTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAT6dLJNkDwmhnESehbaDPTpUXoGL2S0 6 | 30WaWnMcUaZnG2hf647Y8mFrOR6BnVyyQCvl2LIe1lNN2VCvNjbeSROEo2AwXjAP 7 | BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRKqQ8WALMzrjo2DPTleg0IVQYWVDAf 8 | BgNVHSMEGDAWgBRKqQ8WALMzrjo2DPTleg0IVQYWVDALBgNVHQ8EBAMCAYYwCgYI 9 | KoZIzj0EAwIDSAAwRQIhAMGBKmM8I2kBUJZfSh+/BZqIRWhIo4ERh6Nsj+vUt1Zu 10 | AiB5YuP+2Nv7Knm0LV8aiLzqltnk1NtVveswg+G+vAxaXA== 11 | -----END CERTIFICATE----- 12 | -------------------------------------------------------------------------------- /itests/ratched_ca/root.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgnznN3oVOviAWVElG 3 | Cg6Bmy8hgULH2fruw4Pix1hDrRahRANCAAT6dLJNkDwmhnESehbaDPTpUXoGL2S0 4 | 30WaWnMcUaZnG2hf647Y8mFrOR6BnVyyQCvl2LIe1lNN2VCvNjbeSROE 5 | -----END PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /itests/ratched_ca/server.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgirVJnlLyk2ih6IMP 3 | aSws0msoDJ5iIVipfO2dSfcvlEShRANCAATm7FciV/X04RyALppByTUPs0ZftXHo 4 | WWJF6ovfVZSUzI0ZfEts2v9UsqHQ9UxZdcuXYr2cNtp3iU56xT14l84a 5 | -----END PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /keyvaluelist.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #ifndef __KEYVALUELIST_H__ 25 | #define __KEYVALUELIST_H__ 26 | 27 | #include 28 | #include "stringlist.h" 29 | 30 | typedef bool (*keyvalue_parser_fnc)(char *element, void *arg, void *result); 31 | 32 | struct lookup_entry_t { 33 | const char *key; 34 | int value; 35 | }; 36 | 37 | struct keyvaluelist_t { 38 | struct stringlist_t list; 39 | }; 40 | 41 | struct keyvaluelist_def_t { 42 | const char *key; 43 | keyvalue_parser_fnc parser; 44 | void *target; 45 | void *argument; 46 | bool parsed; 47 | }; 48 | 49 | /*************** AUTO GENERATED SECTION FOLLOWS ***************/ 50 | bool keyvalue_string(char *element, void *argument, void *vresult); 51 | bool keyvalue_longint(char *element, void *argument, void *vresult); 52 | bool keyvalue_ipv4_nbo(char *element, void *argument, void *vresult); 53 | bool keyvalue_bool(char *element, void *argument, void *vresult); 54 | bool keyvalue_lookup(char *element, void *argument, void *vresult); 55 | bool keyvalue_flags(char *element, void *argument, void *vresult); 56 | int parse_keyvalues_from_list(struct stringlist_t *list, unsigned int startindex, struct keyvaluelist_def_t *elements); 57 | int parse_keyvalue_list(const char *string, unsigned int startindex, struct keyvaluelist_def_t *elements, char **positional_args); 58 | /*************** AUTO GENERATED SECTION ENDS ***************/ 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /logging.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #ifndef __LOGGING_H__ 25 | #define __LOGGING_H__ 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | enum loglvl_t { 32 | LLVL_FATAL, 33 | LLVL_ERROR, 34 | LLVL_WARN, 35 | LLVL_INFO, 36 | LLVL_DEBUG, 37 | LLVL_TRACE, 38 | LLVL_LAST, // Invalid 39 | }; 40 | 41 | enum logflag_t { 42 | FLAG_LOG_SAMELINE = (1 << 0), 43 | FLAG_LOG_AFTERLINE = (1 << 1), 44 | FLAG_OPENSSL_ERROR = (1 << 2), 45 | FLAG_OPENSSL_DUMP_X509_CERT_SUBJECT = (1 << 3), 46 | FLAG_OPENSSL_DUMP_X509_CERT_PEM = (1 << 4), 47 | FLAG_OPENSSL_DUMP_X509_CERT_TEXT = (1 << 5), 48 | FLAG_OPENSSL_DUMP_OCSP_RESPONSE_PEM = (1 << 6), 49 | }; 50 | 51 | #define logmsg(lvl, msg, ...) logmsg_src((lvl), __FILE__, __LINE__, (msg), ##__VA_ARGS__) 52 | #define logmsgext(lvl, flags, msg, ...) logmsgext_src((lvl), __FILE__, __LINE__, (flags), (msg), ##__VA_ARGS__) 53 | #define logmsgarg(lvl, flags, arg, msg, ...) logmsgext_src((lvl), __FILE__, __LINE__, (flags), (arg), (msg), ##__VA_ARGS__) 54 | #define log_cert(lvl, crt, msg) log_cert_src((lvl), __FILE__, __LINE__, (crt), (msg)) 55 | #define log_ocsp_response(lvl, orsp, msg) log_ocsp_response_src((lvl), __FILE__, __LINE__, (orsp), (msg)) 56 | #define log_memory(lvl, data, length, msg, ...) log_memory_src((lvl), __FILE__, __LINE__, (data), (length), (msg), ##__VA_ARGS__) 57 | 58 | /*************** AUTO GENERATED SECTION FOLLOWS ***************/ 59 | bool open_logfile(const char *filename); 60 | bool loglevel_at_least(enum loglvl_t lvl); 61 | void __attribute__ ((format (printf, 4, 5))) logmsg_src(enum loglvl_t lvl, const char *src_file, unsigned int src_lineno, const char *msg, ...); 62 | void __attribute__ ((format (printf, 5, 6))) logmsgext_src(enum loglvl_t lvl, const char *src_file, unsigned int src_lineno, unsigned int flags, const char *msg, ...); 63 | void __attribute__ ((format (printf, 6, 7))) logmsgarg_src(enum loglvl_t lvl, const char *src_file, unsigned int src_lineno, unsigned int flags, void *arg, const char *msg, ...); 64 | void __attribute__ ((format (printf, 6, 7))) log_memory_src(enum loglvl_t lvl, const char *src_file, unsigned int src_lineno, const void *data, unsigned int length, const char *msg, ...); 65 | void log_cert_src(enum loglvl_t lvl, const char *src_file, unsigned int src_lineno, X509 *crt, const char *msg); 66 | void log_ocsp_response_src(enum loglvl_t lvl, const char *src_file, unsigned int src_lineno, OCSP_RESPONSE *ocsp_response, const char *msg); 67 | /*************** AUTO GENERATED SECTION ENDS ***************/ 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /map.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #ifndef __MAP_H__ 25 | #define __MAP_H__ 26 | 27 | #include 28 | 29 | enum map_element_type_t { 30 | UNDEFINED, 31 | ALLOCED_MEMORY, 32 | VOID_PTR, 33 | INTEGER, 34 | }; 35 | 36 | union value_t { 37 | void *pointer; 38 | int integer; 39 | }; 40 | 41 | struct map_element_t { 42 | unsigned int key_len; 43 | const void *key; 44 | enum map_element_type_t value_type; 45 | unsigned int value_len; 46 | union value_t value; 47 | }; 48 | 49 | struct map_t { 50 | unsigned int element_count; 51 | struct map_element_t **elements; 52 | }; 53 | 54 | /*************** AUTO GENERATED SECTION FOLLOWS ***************/ 55 | bool map_set_value(struct map_element_t *element, const enum map_element_type_t value_type, const union value_t new_value, const unsigned int new_value_len); 56 | struct map_element_t *map_getitem(struct map_t *map, const void *key, unsigned int key_len); 57 | void *map_get(struct map_t *map, const void *key, unsigned int key_len); 58 | int map_get_int(struct map_t *map, const void *key, unsigned int key_len); 59 | struct map_element_t* map_set(struct map_t *map, const void *key, const unsigned int key_len, enum map_element_type_t value_type, const union value_t value, const unsigned int value_len); 60 | struct map_element_t* map_set_mem(struct map_t *map, const void *key, const unsigned int key_len, const void *value, const unsigned int value_len); 61 | struct map_element_t* map_set_ptr(struct map_t *map, const void *key, const unsigned int key_len, const void *value); 62 | struct map_element_t* map_set_int(struct map_t *map, const void *key, const unsigned int key_len, int value); 63 | void map_del_key(struct map_t *map, const void *key, unsigned int key_len); 64 | struct map_element_t *strmap_set_mem(struct map_t *map, const char *strkey, const void *value, const unsigned int value_len); 65 | struct map_element_t *strmap_set_ptr(struct map_t *map, const char *strkey, void *value); 66 | struct map_element_t *strmap_set_str(struct map_t *map, const char *strkey, const char *strvalue); 67 | struct map_element_t *strmap_set_int(struct map_t *map, const char *strkey, int value); 68 | bool strmap_has(struct map_t *map, const char *strkey); 69 | void* strmap_get(struct map_t *map, const char *strkey); 70 | const char* strmap_get_str(struct map_t *map, const char *strkey); 71 | int strmap_get_int(struct map_t *map, const char *strkey); 72 | void strmap_del(struct map_t *map, const char *strkey); 73 | void map_dump(const struct map_t *map); 74 | void map_foreach(struct map_t *map, void (*callback_fnc)(struct map_element_t *element)); 75 | void map_foreach_ptrvalue(struct map_t *map, void (*callback_fnc)(void *value)); 76 | void map_free(struct map_t *map); 77 | struct map_t *map_new(void); 78 | /*************** AUTO GENERATED SECTION ENDS ***************/ 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /mkca/create_demo_ca.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # ratched - TLS connection router that performs a man-in-the-middle attack 3 | # Copyright (C) 2017-2017 Johannes Bauer 4 | # 5 | # This file is part of ratched. 6 | # 7 | # ratched is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; this program is ONLY licensed under 10 | # version 3 of the License, later versions are explicitly excluded. 11 | # 12 | # ratched is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with ratched; if not, write to the Free Software 19 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | # 21 | # Johannes Bauer 22 | 23 | import os 24 | from PKICreator import PKICreator 25 | 26 | try: 27 | os.mkdir("output") 28 | except FileExistsError: 29 | pass 30 | pki = PKICreator(path_prefix = "output/", default_key = { 31 | "keytype": "ecc", 32 | "curve": "secp256r1", 33 | }) 34 | pki.create_root_ca_cert("root.key", "root.crt", "/CN=Very trustworthy root CA", validity_days = 365 * 5) 35 | pki.create_intermediate_ca_cert("intermediate.key", "intermediate.crt", "root.key", "root.crt", "/CN=Super trustworthy intermediate CA", validity_days = 365 * 5) 36 | pki.create_server_cert("server_foo.key","server_foo.crt", "intermediate.key", "intermediate.crt", "/CN=foo/OU=Server cert", validity_days = 365 * 5, alt_names = [ "foo", "IP:127.0.0.1" ]) 37 | pki.create_server_cert("server_bar.key","server_bar.crt", "intermediate.key", "intermediate.crt", "/CN=bar/OU=Server cert", validity_days = 365 * 5, alt_names = [ "bar", "IP:127.0.0.1" ]) 38 | pki.create_server_cert("server_moo.key","server_moo.crt", "intermediate.key", "intermediate.crt", "/CN=moo/OU=Server cert", validity_days = 365 * 5, alt_names = [ "moo", "IP:127.0.0.1" ]) 39 | 40 | pki.create_intermediate_ca_cert("client_intermediate.key", "client_intermediate.crt", "root.key", "root.crt", "/CN=Super trustworthy client intermediate CA", validity_days = 365 * 5) 41 | pki.create_client_cert("client_joe.key","client_joe.crt", "client_intermediate.key", "client_intermediate.crt", "/CN=joe/OU=Client cert", validity_days = 365 * 5) 42 | pki.create_client_cert("client_julaia.key","client_julaia.crt", "client_intermediate.key", "client_intermediate.crt", "/CN=julaia/OU=Client cert", validity_days = 365 * 5) 43 | -------------------------------------------------------------------------------- /ocsp_response.c: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #include 25 | #include "ocsp_response.h" 26 | #include "logging.h" 27 | #include "openssl.h" 28 | 29 | OCSP_RESPONSE *create_ocsp_response(X509 *subject_crt, X509 *issuer_crt, EVP_PKEY *issuer_key, unsigned int ocsp_ticket_lifetime_days) { 30 | struct errstack_t es = ERRSTACK_INIT; 31 | OCSP_BASICRESP *basic_resp = errstack_push_OCSP_BASICRESP(&es, OCSP_BASICRESP_new()); 32 | if (!basic_resp) { 33 | logmsgext(LLVL_ERROR, FLAG_OPENSSL_ERROR, "Unable to create OCSP basic response."); 34 | return errstack_pop_all(&es); 35 | } 36 | 37 | time_t now = time(NULL); 38 | ASN1_TIME *thisupd = errstack_push_ASN1_TIME(&es, ASN1_TIME_adj(NULL, now, 0, -(3600 * 3))); 39 | if (!thisupd) { 40 | logmsgext(LLVL_ERROR, FLAG_OPENSSL_ERROR, "Unable to create OCSP thisupd timestamp."); 41 | return errstack_pop_all(&es); 42 | } 43 | 44 | ASN1_TIME *nextupd = errstack_push_ASN1_TIME(&es, ASN1_TIME_adj(NULL, now, ocsp_ticket_lifetime_days, 0)); 45 | if (!thisupd) { 46 | logmsgext(LLVL_ERROR, FLAG_OPENSSL_ERROR, "Unable to create OCSP nextupd timestamp."); 47 | return errstack_pop_all(&es); 48 | } 49 | 50 | const EVP_MD *keyid_hash = EVP_sha1(); 51 | if (!keyid_hash) { 52 | logmsgext(LLVL_ERROR, FLAG_OPENSSL_ERROR, "Unable to get SHA-1 for hashing of key IDs."); 53 | return errstack_pop_all(&es); 54 | } 55 | 56 | OCSP_CERTID *cid = errstack_push_OCSP_CERTID(&es, OCSP_cert_to_id(keyid_hash, subject_crt, issuer_crt)); 57 | if (!cid) { 58 | logmsgext(LLVL_ERROR, FLAG_OPENSSL_ERROR, "Unable to get OCSP certificate ID."); 59 | return errstack_pop_all(&es); 60 | } 61 | 62 | OCSP_basic_add1_status(basic_resp, cid, V_OCSP_CERTSTATUS_GOOD, OCSP_RESPONSE_STATUS_SUCCESSFUL, NULL, thisupd, nextupd); 63 | errstack_pop_until(&es, 1); 64 | 65 | const EVP_MD *signing_hash = EVP_sha256(); 66 | long flags = OCSP_NOCERTS | OCSP_RESPID_KEY; 67 | if (!OCSP_basic_sign(basic_resp, issuer_crt, issuer_key, signing_hash, NULL, flags)) { 68 | logmsgext(LLVL_ERROR, FLAG_OPENSSL_ERROR, "Signing of OCSP request failed."); 69 | return errstack_pop_all(&es); 70 | } 71 | 72 | OCSP_RESPONSE *response = OCSP_response_create(OCSP_RESPONSE_STATUS_SUCCESSFUL, basic_resp); 73 | if (!response) { 74 | logmsgext(LLVL_ERROR, FLAG_OPENSSL_ERROR, "Unable to create OCSP response."); 75 | return errstack_pop_all(&es); 76 | } 77 | OCSP_BASICRESP_free(basic_resp); 78 | 79 | return response; 80 | } 81 | 82 | bool serialize_ocsp_response(OCSP_RESPONSE *ocsp_response, uint8_t **data, int *length) { 83 | *data = NULL; 84 | *length = 0; 85 | 86 | BIO* ocsp_bio = BIO_new(BIO_s_mem()); 87 | if (!ocsp_bio) { 88 | logmsgext(LLVL_ERROR, FLAG_OPENSSL_ERROR, "Failed to create OCSP serialization BIO."); 89 | return false; 90 | } 91 | 92 | i2d_OCSP_RESPONSE_bio(ocsp_bio, ocsp_response); 93 | int pending_length = BIO_pending(ocsp_bio); 94 | if (pending_length <= 0) { 95 | logmsgext(LLVL_ERROR, FLAG_OPENSSL_ERROR, "OCSP serialization failed, returned %d bytes length.", pending_length); 96 | BIO_free(ocsp_bio); 97 | return false; 98 | } 99 | 100 | uint8_t *response_data = OPENSSL_malloc(pending_length); 101 | if (!response_data) { 102 | logmsgext(LLVL_ERROR, FLAG_OPENSSL_ERROR, "Allocation of %d bytes for OCSP response failed.", pending_length); 103 | BIO_free(ocsp_bio); 104 | return false; 105 | } 106 | 107 | int response_len = BIO_read(ocsp_bio, response_data, pending_length); 108 | if (response_len != pending_length) { 109 | logmsgext(LLVL_ERROR, FLAG_OPENSSL_ERROR, "Expected %d bytes in OCSP response, but only read %d from BIO.", pending_length, response_len); 110 | OPENSSL_free(response_data); 111 | BIO_free(ocsp_bio); 112 | return false; 113 | } 114 | 115 | BIO_free(ocsp_bio); 116 | 117 | log_memory(LLVL_TRACE, response_data, response_len, "Serialized positive OCSP response (%d bytes).", response_len); 118 | *data = response_data; 119 | *length = response_len; 120 | return true; 121 | } 122 | -------------------------------------------------------------------------------- /ocsp_response.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #ifndef __OCSP_RESPONSE_H__ 25 | #define __OCSP_RESPONSE_H__ 26 | 27 | #include 28 | #include 29 | 30 | /*************** AUTO GENERATED SECTION FOLLOWS ***************/ 31 | OCSP_RESPONSE *create_ocsp_response(X509 *subject_crt, X509 *issuer_crt, EVP_PKEY *issuer_key, unsigned int ocsp_ticket_lifetime_days); 32 | bool serialize_ocsp_response(OCSP_RESPONSE *ocsp_response, uint8_t **data, int *length); 33 | /*************** AUTO GENERATED SECTION ENDS ***************/ 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /openssl.c: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #include 25 | #include 26 | 27 | #include "openssl.h" 28 | #include "errstack.h" 29 | 30 | void openssl_init(void) { 31 | SSL_load_error_strings(); 32 | OpenSSL_add_ssl_algorithms(); 33 | } 34 | 35 | void openssl_deinit(void) { 36 | EVP_cleanup(); 37 | CRYPTO_cleanup_all_ex_data(); 38 | SSL_COMP_free_compression_methods(); 39 | ERR_free_strings(); 40 | } 41 | 42 | static void errstack_free_X509(struct errstack_element_t *element) { 43 | X509_free((X509*)element->ptrvalue); 44 | } 45 | 46 | X509* errstack_push_X509(struct errstack_t *errstack, X509 *element) { 47 | return (X509*)errstack_push_generic_nonnull_ptr(errstack, errstack_free_X509, element); 48 | } 49 | 50 | static void errstack_free_EVP_PKEY(struct errstack_element_t *element) { 51 | EVP_PKEY_free((EVP_PKEY*)element->ptrvalue); 52 | } 53 | 54 | EVP_PKEY* errstack_push_EVP_PKEY(struct errstack_t *errstack, EVP_PKEY *element) { 55 | return (EVP_PKEY*)errstack_push_generic_nonnull_ptr(errstack, errstack_free_EVP_PKEY, element); 56 | } 57 | static void errstack_free_sk_X509(struct errstack_element_t *element) { 58 | sk_X509_pop_free((STACK_OF(X509)*)element->ptrvalue, X509_free); 59 | } 60 | 61 | STACK_OF(X509)* errstack_push_sk_X509(struct errstack_t *errstack, STACK_OF(X509) *element) { 62 | return (STACK_OF(X509)*)errstack_push_generic_nonnull_ptr(errstack, errstack_free_sk_X509, element); 63 | } 64 | 65 | static void errstack_free_OCSP_BASICRESP(struct errstack_element_t *element) { 66 | OCSP_BASICRESP_free((OCSP_BASICRESP*)element->ptrvalue); 67 | } 68 | 69 | OCSP_BASICRESP* errstack_push_OCSP_BASICRESP(struct errstack_t *errstack, OCSP_BASICRESP *element) { 70 | return (OCSP_BASICRESP*)errstack_push_generic_nonnull_ptr(errstack, errstack_free_OCSP_BASICRESP, element); 71 | } 72 | 73 | static void errstack_free_OCSP_CERTID(struct errstack_element_t *element) { 74 | OCSP_CERTID_free((OCSP_CERTID*)element->ptrvalue); 75 | } 76 | 77 | OCSP_CERTID* errstack_push_OCSP_CERTID(struct errstack_t *errstack, OCSP_CERTID *element) { 78 | return (OCSP_CERTID*)errstack_push_generic_nonnull_ptr(errstack, errstack_free_OCSP_CERTID, element); 79 | } 80 | 81 | static void errstack_free_ASN1_TIME(struct errstack_element_t *element) { 82 | ASN1_TIME_free((ASN1_TIME*)element->ptrvalue); 83 | } 84 | 85 | ASN1_TIME* errstack_push_ASN1_TIME(struct errstack_t *errstack, ASN1_TIME *element) { 86 | return (ASN1_TIME*)errstack_push_generic_nonnull_ptr(errstack, errstack_free_ASN1_TIME, element); 87 | } 88 | 89 | static void errstack_free_BIGNUM(struct errstack_element_t *element) { 90 | BN_free((BIGNUM*)element->ptrvalue); 91 | } 92 | 93 | BIGNUM* errstack_push_BIGNUM(struct errstack_t *errstack, BIGNUM *element) { 94 | return (BIGNUM*)errstack_push_generic_nonnull_ptr(errstack, errstack_free_BIGNUM, element); 95 | } 96 | 97 | static void errstack_free_RSA(struct errstack_element_t *element) { 98 | RSA_free((RSA*)element->ptrvalue); 99 | } 100 | 101 | RSA* errstack_push_RSA(struct errstack_t *errstack, RSA *element) { 102 | return (RSA*)errstack_push_generic_nonnull_ptr(errstack, errstack_free_RSA, element); 103 | } 104 | 105 | static void errstack_free_EC_KEY(struct errstack_element_t *element) { 106 | EC_KEY_free((EC_KEY*)element->ptrvalue); 107 | } 108 | 109 | EC_KEY* errstack_push_EC_KEY(struct errstack_t *errstack, EC_KEY *element) { 110 | return (EC_KEY*)errstack_push_generic_nonnull_ptr(errstack, errstack_free_EC_KEY, element); 111 | } 112 | 113 | static void errstack_free_SSL(struct errstack_element_t *element) { 114 | SSL_free((SSL*)element->ptrvalue); 115 | } 116 | 117 | SSL* errstack_push_SSL(struct errstack_t *errstack, SSL *element) { 118 | return (SSL*)errstack_push_generic_nonnull_ptr(errstack, errstack_free_SSL, element); 119 | } 120 | -------------------------------------------------------------------------------- /openssl.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #ifndef __OPENSSL_H__ 25 | #define __OPENSSL_H__ 26 | 27 | #include "errstack.h" 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #if OPENSSL_VERSION_NUMBER < 0x010100000 35 | #error "Ratched requires at least OpenSSL v1.1 to work." 36 | #endif 37 | 38 | /*************** AUTO GENERATED SECTION FOLLOWS ***************/ 39 | void openssl_init(void); 40 | void openssl_deinit(void); 41 | X509* errstack_push_X509(struct errstack_t *errstack, X509 *element); 42 | EVP_PKEY* errstack_push_EVP_PKEY(struct errstack_t *errstack, EVP_PKEY *element); 43 | STACK_OF(X509)* errstack_push_sk_X509(struct errstack_t *errstack, STACK_OF(X509) *element); 44 | OCSP_BASICRESP* errstack_push_OCSP_BASICRESP(struct errstack_t *errstack, OCSP_BASICRESP *element); 45 | OCSP_CERTID* errstack_push_OCSP_CERTID(struct errstack_t *errstack, OCSP_CERTID *element); 46 | ASN1_TIME* errstack_push_ASN1_TIME(struct errstack_t *errstack, ASN1_TIME *element); 47 | BIGNUM* errstack_push_BIGNUM(struct errstack_t *errstack, BIGNUM *element); 48 | RSA* errstack_push_RSA(struct errstack_t *errstack, RSA *element); 49 | EC_KEY* errstack_push_EC_KEY(struct errstack_t *errstack, EC_KEY *element); 50 | SSL* errstack_push_SSL(struct errstack_t *errstack, SSL *element); 51 | /*************** AUTO GENERATED SECTION ENDS ***************/ 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /openssl_certs.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #ifndef __OPENSSL_CERTS_H__ 25 | #define __OPENSSL_CERTS_H__ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | enum cryptosystem_t { 33 | CRYPTOSYSTEM_RSA, 34 | CRYPTOSYSTEM_ECC_FP, 35 | CRYPTOSYSTEM_ECC_F2M, 36 | }; 37 | 38 | struct keyspec_t { 39 | const char *description; 40 | enum cryptosystem_t cryptosystem; 41 | union { 42 | struct { 43 | unsigned int bitlength; 44 | } rsa; 45 | struct { 46 | const char *curve_name; 47 | } ecc_fp; 48 | struct { 49 | const char *curve_name; 50 | } ecc_f2m; 51 | }; 52 | }; 53 | 54 | struct tls_endpoint_config_t { 55 | bool request_cert_from_peer; 56 | bool ocsp_status; 57 | bool include_root_ca_cert; 58 | uint32_t tls_versions; 59 | const char *ciphersuites; 60 | const char *supported_groups; 61 | const char *signature_algorithms; 62 | X509 *cert; 63 | EVP_PKEY *key; 64 | STACK_OF(X509) *chain; 65 | struct { 66 | X509 *cert; 67 | EVP_PKEY *key; 68 | } certificate_authority; 69 | struct { 70 | X509 *cert; 71 | EVP_PKEY *key; 72 | } ocsp_responder; 73 | }; 74 | 75 | struct tls_endpoint_cert_source_t { 76 | const char *cert_filename; 77 | const char *key_filename; 78 | const char *chain_filename; 79 | struct { 80 | const char *cert_filename; 81 | const char *key_filename; 82 | } certificate_authority; 83 | }; 84 | 85 | struct certificatespec_t { 86 | const char *description; 87 | EVP_PKEY *subject_pubkey; 88 | EVP_PKEY *issuer_privkey; 89 | X509 *issuer_certificate; 90 | const char *common_name; 91 | bool mark_certificate; 92 | const char *subject_alternative_dns_hostname; 93 | const char *crl_uri; 94 | const char *ocsp_responder_uri; 95 | uint32_t subject_alternative_ipv4_address; 96 | bool full_authority_keyid; 97 | bool is_ca_certificate; 98 | int validity_predate_seconds; 99 | uint64_t validity_seconds; 100 | }; 101 | 102 | /*************** AUTO GENERATED SECTION FOLLOWS ***************/ 103 | EVP_PKEY* openssl_create_key(const struct keyspec_t *keyspec); 104 | EVP_PKEY *openssl_load_key(const char *filename, const char *description, bool silent); 105 | X509 *openssl_load_cert(const char *filename, const char *description, bool silent); 106 | STACK_OF(X509) *openssl_load_cert_chain(const char *filename, const char *description, bool silent); 107 | bool openssl_store_key(const char *filename, const char *description, bool silent, EVP_PKEY *key); 108 | bool openssl_store_cert(const char *filename, const char *description, bool silent, X509 *cert); 109 | EVP_PKEY* openssl_load_stored_key(const struct keyspec_t *keyspec, const char *filename); 110 | bool add_extension_rawstr(X509 *cert, bool critical, int nid, const char *text); 111 | X509* openssl_create_certificate(const struct certificatespec_t *spec); 112 | X509* openssl_load_stored_certificate(const struct certificatespec_t *certspec, const char *filename, bool recreate_when_expired, bool recreate_when_key_mismatch); 113 | X509 *forge_client_certificate(X509 *original_client_cert, EVP_PKEY *new_subject_pubkey, X509 *new_issuer_cert, EVP_PKEY *new_issuer_privkey, bool recalculate_key_identifiers, bool mark_certificate); 114 | void dump_tls_endpoint_config(char *text, int text_maxlen, const struct tls_endpoint_config_t *config); 115 | bool init_tls_endpoint_config(struct tls_endpoint_config_t *config, const char *description, const struct tls_endpoint_cert_source_t *certsrc); 116 | bool get_certificate_hash(uint8_t hash_value[static 32], X509 *cert); 117 | bool get_public_key_hash(uint8_t hash_value[static 32], EVP_PKEY *pubkey); 118 | bool get_certificate_public_key_hash(uint8_t hash_value[static 32], X509 *cert); 119 | void free_tls_endpoint_config(struct tls_endpoint_config_t *config); 120 | /*************** AUTO GENERATED SECTION ENDS ***************/ 121 | 122 | #endif 123 | -------------------------------------------------------------------------------- /openssl_clienthello.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #ifndef __OPENSSL_CLIENTHELLO_H__ 25 | #define __OPENSSL_CLIENTHELLO_H__ 26 | 27 | #include 28 | #include 29 | #include "errstack.h" 30 | 31 | struct chello_t { 32 | char *server_name_indication; 33 | struct { 34 | bool status_request; 35 | bool encrypt_then_mac; 36 | bool extended_master_secret; 37 | bool session_ticket; 38 | } present_extensions; 39 | }; 40 | 41 | /*************** AUTO GENERATED SECTION FOLLOWS ***************/ 42 | bool parse_client_hello(struct chello_t *result, const uint8_t *data, int length); 43 | void free_client_hello(struct chello_t *chello); 44 | void errstack_push_client_hello(struct errstack_t *errstack, struct chello_t *element); 45 | void client_hello_dump_options(void); 46 | /*************** AUTO GENERATED SECTION ENDS ***************/ 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /openssl_filtered_fwd.c: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include "openssl_filtered_fwd.h" 31 | #include "logging.h" 32 | #include "atomic.h" 33 | #include "openssl.h" 34 | 35 | static void* forwarding_thread_fnc(void *vctx) { 36 | struct forwarding_thread_data_t *ctx = (struct forwarding_thread_data_t*)vctx; 37 | BIO *read_bio, *write_bio; 38 | struct connection_side_stats_t *stats; 39 | bool tcpip_direction; 40 | if (ctx->direction == READ_1_WRITE_2) { 41 | read_bio = ctx->fwd_data->side1; 42 | write_bio = ctx->fwd_data->side2; 43 | stats = &ctx->fwd_data->stats->dir1; 44 | tcpip_direction = true; 45 | } else { 46 | read_bio = ctx->fwd_data->side2; 47 | write_bio = ctx->fwd_data->side1; 48 | stats = &ctx->fwd_data->stats->dir2; 49 | tcpip_direction = false; 50 | } 51 | while (true) { 52 | uint8_t data[4096]; 53 | 54 | ssize_t length_read = BIO_read(read_bio, data, sizeof(data)); 55 | if (length_read == 0) { 56 | /* Peer closed connection */ 57 | break; 58 | } 59 | if (length_read <= 0) { 60 | logmsg(LLVL_ERROR, "%zd bytes read when forwarding %p -> %p.", length_read, read_bio, write_bio); 61 | break; 62 | } 63 | stats->bytes_read += length_read; 64 | 65 | if (ctx->fwd_data->conn) { 66 | append_tcp_ip_data(ctx->fwd_data->conn, tcpip_direction, data, length_read); 67 | } 68 | ssize_t length_written = BIO_write(write_bio, data, length_read); 69 | if (length_written != length_read) { 70 | logmsg(LLVL_ERROR, "%zd bytes written when TLS forwarding %p -> %p, %zd bytes expected.", length_written, read_bio, write_bio, length_read); 71 | break; 72 | } 73 | stats->bytes_written += length_written; 74 | } 75 | ctx->fwd_data->connection_shutdown_callback(ctx); 76 | logmsg(LLVL_TRACE, "Thread %p -> %p (dir %d) finished.", read_bio, write_bio, ctx->direction); 77 | return NULL; 78 | } 79 | 80 | static void filtered_BIO_forward_data(struct forwarding_data_t *fwd_data, struct connection_stats_t *stats, struct connection_t *conn) { 81 | memset(stats, 0, sizeof(struct connection_stats_t)); 82 | fwd_data->stats = stats; 83 | fwd_data->conn = conn; 84 | struct forwarding_thread_data_t dir1 = { 85 | .direction = READ_1_WRITE_2, 86 | .fwd_data = fwd_data, 87 | }; 88 | struct forwarding_thread_data_t dir2 = { 89 | .direction = READ_2_WRITE_1, 90 | .fwd_data = fwd_data, 91 | }; 92 | atomic_init(&fwd_data->shutdown); 93 | 94 | pthread_t dir1_thread, dir2_thread; 95 | if (pthread_create(&dir1_thread, NULL, forwarding_thread_fnc, &dir1)) { 96 | logmsg(LLVL_ERROR, "Failed to create forwarding thread 1: %s", strerror(errno)); 97 | return; 98 | } 99 | if (pthread_create(&dir2_thread, NULL, forwarding_thread_fnc, &dir2)) { 100 | logmsg(LLVL_ERROR, "Failed to create forwarding thread 2: %s", strerror(errno)); 101 | return; 102 | } 103 | 104 | /* Wait for both threads to finish */ 105 | pthread_join(dir1_thread, NULL); 106 | pthread_join(dir2_thread, NULL); 107 | 108 | logmsg(LLVL_INFO, "Closed TLS forwarding %p <-> %p (forwarded %u bytes written to server, %u bytes written to client)", fwd_data->side1, fwd_data->side2, stats->dir1.bytes_written, stats->dir2.bytes_written); 109 | } 110 | 111 | static void fd_shutdown_callback(struct forwarding_thread_data_t *fwddata) { 112 | if (atomic_test_and_set(&fwddata->fwd_data->shutdown)) { 113 | shutdown(fwddata->fwd_data->raw_connection_info.fd.side1, SHUT_RDWR); 114 | shutdown(fwddata->fwd_data->raw_connection_info.fd.side2, SHUT_RDWR); 115 | } 116 | } 117 | 118 | void filtered_fd_forward_data(int fd1, int fd2, struct connection_stats_t *stats, struct connection_t *conn) { 119 | struct forwarding_data_t fwd_data = { 120 | .connection_shutdown_callback = fd_shutdown_callback, 121 | .raw_connection_info = { 122 | .fd = { 123 | .side1 = fd1, 124 | .side2 = fd2, 125 | }, 126 | }, 127 | }; 128 | fwd_data.side1 = BIO_new_fd(fd1, BIO_NOCLOSE); 129 | if (!fwd_data.side1) { 130 | logmsgext(LLVL_ERROR, FLAG_OPENSSL_ERROR, "Failed to create BIO from fd1 %d.", fd1); 131 | return; 132 | } 133 | 134 | fwd_data.side2 = BIO_new_fd(fd2, BIO_NOCLOSE); 135 | if (!fwd_data.side2) { 136 | BIO_free_all(fwd_data.side1); 137 | logmsgext(LLVL_ERROR, FLAG_OPENSSL_ERROR, "Failed to create BIO from fd2 %d.", fd2); 138 | return; 139 | } 140 | 141 | filtered_BIO_forward_data(&fwd_data, stats, conn); 142 | 143 | BIO_free_all(fwd_data.side2); 144 | BIO_free_all(fwd_data.side1); 145 | } 146 | 147 | static void ssl_shutdown_callback(struct forwarding_thread_data_t *fwddata) { 148 | if (atomic_test_and_set(&fwddata->fwd_data->shutdown)) { 149 | SSL_shutdown(fwddata->fwd_data->raw_connection_info.tls.side1); 150 | SSL_shutdown(fwddata->fwd_data->raw_connection_info.tls.side2); 151 | } 152 | } 153 | 154 | void filtered_tls_forward_data(SSL *ssl1, SSL *ssl2, struct connection_stats_t *stats, struct connection_t *conn) { 155 | struct forwarding_data_t fwd_data = { 156 | .connection_shutdown_callback = ssl_shutdown_callback, 157 | .raw_connection_info = { 158 | .tls = { 159 | .side1 = ssl1, 160 | .side2 = ssl2, 161 | }, 162 | }, 163 | }; 164 | fwd_data.side1 = BIO_new(BIO_f_ssl()); 165 | if (!fwd_data.side1) { 166 | logmsgext(LLVL_ERROR, FLAG_OPENSSL_ERROR, "Failed to create BIO from SSL object 1 at %p.", ssl1); 167 | return; 168 | } 169 | BIO_set_ssl(fwd_data.side1, ssl1, BIO_NOCLOSE); 170 | 171 | fwd_data.side2 = BIO_new(BIO_f_ssl()); 172 | if (!fwd_data.side2) { 173 | BIO_free_all(fwd_data.side1); 174 | logmsgext(LLVL_ERROR, FLAG_OPENSSL_ERROR, "Failed to create BIO from SSL object 2 at %p.", ssl2); 175 | return; 176 | } 177 | BIO_set_ssl(fwd_data.side2, ssl2, BIO_NOCLOSE); 178 | 179 | filtered_BIO_forward_data(&fwd_data, stats, conn); 180 | 181 | BIO_free_all(fwd_data.side2); 182 | BIO_free_all(fwd_data.side1); 183 | } 184 | -------------------------------------------------------------------------------- /openssl_filtered_fwd.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #ifndef __OPENSSL_FILTERED_FWD_H__ 25 | #define __OPENSSL_FILTERED_FWD_H__ 26 | 27 | #include 28 | #include "tcpip.h" 29 | #include "atomic.h" 30 | 31 | struct connection_side_stats_t { 32 | unsigned int bytes_read; 33 | unsigned int bytes_written; 34 | }; 35 | 36 | struct connection_stats_t { 37 | struct connection_side_stats_t dir1; 38 | struct connection_side_stats_t dir2; 39 | }; 40 | 41 | enum fwd_direction_t { 42 | READ_1_WRITE_2, 43 | READ_2_WRITE_1, 44 | }; 45 | 46 | union raw_connection_info_t { 47 | struct { 48 | SSL *side1, *side2; 49 | } tls; 50 | struct { 51 | int side1, side2; 52 | } fd; 53 | }; 54 | 55 | struct forwarding_thread_data_t; 56 | 57 | struct forwarding_data_t { 58 | BIO *side1, *side2; 59 | struct connection_stats_t *stats; 60 | struct connection_t *conn; 61 | struct atomic_t shutdown; 62 | union raw_connection_info_t raw_connection_info; 63 | void (*connection_shutdown_callback)(struct forwarding_thread_data_t*); 64 | }; 65 | 66 | struct forwarding_thread_data_t { 67 | enum fwd_direction_t direction; 68 | struct forwarding_data_t *fwd_data; 69 | }; 70 | 71 | /*************** AUTO GENERATED SECTION FOLLOWS ***************/ 72 | void filtered_fd_forward_data(int fd1, int fd2, struct connection_stats_t *stats, struct connection_t *conn); 73 | void filtered_tls_forward_data(SSL *ssl1, SSL *ssl2, struct connection_stats_t *stats, struct connection_t *conn); 74 | /*************** AUTO GENERATED SECTION ENDS ***************/ 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /openssl_tls.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #ifndef __OPENSSL_TLS_H__ 25 | #define __OPENSSL_TLS_H__ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include "openssl_certs.h" 32 | 33 | struct tls_connection_t { 34 | SSL *ssl; 35 | X509 *peer_certificate; 36 | }; 37 | 38 | struct tls_connection_request_t { 39 | int peer_fd; 40 | bool is_server; 41 | const uint8_t *initial_peer_data; 42 | unsigned int initial_peer_data_length; 43 | struct tls_endpoint_config_t *config; 44 | const char *server_name_indication; 45 | }; 46 | 47 | /*************** AUTO GENERATED SECTION FOLLOWS ***************/ 48 | struct tls_connection_t openssl_tls_connect(const struct tls_connection_request_t *request); 49 | /*************** AUTO GENERATED SECTION ENDS ***************/ 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /parse.c: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include "parse.h" 33 | #include "stringlist.h" 34 | #include "logging.h" 35 | 36 | bool safe_strtol(const char **string, long int *result, bool trailing_data_allowed) { 37 | char *end; 38 | errno = 0; 39 | long int value = strtol(*string, &end, 10); 40 | bool did_conversion = (*string != end); 41 | bool success = did_conversion && (errno == 0); 42 | if (!trailing_data_allowed) { 43 | success = success && (*end == 0); 44 | } 45 | if (success) { 46 | *result = value; 47 | *string = end; 48 | } 49 | return success; 50 | } 51 | 52 | static bool next_char_is(const char **string, char c) { 53 | bool success = (**string == c); 54 | if (success) { 55 | *string = *string + 1; 56 | } 57 | return success; 58 | } 59 | 60 | static bool internal_parse_ipv4(const char **ipv4, uint32_t *ip_nbo, bool trailing_data_allowed) { 61 | long int ip[4]; 62 | 63 | if ( 64 | safe_strtol(ipv4, &ip[0], true) 65 | && (next_char_is(ipv4, '.')) 66 | && safe_strtol(ipv4, &ip[1], true) 67 | && (next_char_is(ipv4, '.')) 68 | && safe_strtol(ipv4, &ip[2], true) 69 | && (next_char_is(ipv4, '.')) 70 | && safe_strtol(ipv4, &ip[3], trailing_data_allowed) 71 | ) { 72 | if (!trailing_data_allowed && (**ipv4 != 0)) { 73 | /* No trailing data allowed, but present. */ 74 | return false; 75 | } 76 | 77 | for (int i = 0; i < 4; i++) { 78 | if ((ip[i] < 0) || (ip[i] > 255)) { 79 | return false; 80 | } 81 | } 82 | uint32_t ip_hbo = (ip[0] << 24) | (ip[1] << 16) | (ip[2] << 8) | (ip[3] << 0); 83 | *ip_nbo = htonl(ip_hbo); 84 | return true; 85 | } 86 | return false; 87 | } 88 | 89 | bool parse_ipv4(const char *ipv4, uint32_t *ip_nbo) { 90 | return internal_parse_ipv4(&ipv4, ip_nbo, false); 91 | } 92 | 93 | bool parse_ipv4_port(const char *ipv4_port, uint32_t *ip_nbo, uint16_t *port_nbo) { 94 | long int port; 95 | if ( 96 | internal_parse_ipv4(&ipv4_port, ip_nbo, true) 97 | && (next_char_is(&ipv4_port, ':')) 98 | && safe_strtol(&ipv4_port, &port, false)) { 99 | if ((port > 0) && (port <= 65535)) { 100 | *port_nbo = htons(port); 101 | return true; 102 | } 103 | } 104 | return false; 105 | } 106 | 107 | bool parse_hostname_port(const char *hostname_port, uint32_t *ip_nbo, uint16_t *port_nbo) { 108 | struct stringlist_t list; 109 | parse_stringlist(&list, hostname_port, ":"); 110 | if (list.token_cnt != 2) { 111 | logmsg(LLVL_ERROR, "Expected two arguments for hostname:port combination, but got %d: \"%s\"", list.token_cnt, hostname_port); 112 | free_stringlist(&list); 113 | return false; 114 | } 115 | 116 | /* First try to parse hostname as an IPv4 address */ 117 | if (!parse_ipv4(list.tokens[0], ip_nbo)) { 118 | /* If this doesn't work, try DNS lookup */ 119 | struct addrinfo addrinfo = { 120 | .ai_family = AF_INET, 121 | .ai_flags = AI_PASSIVE, 122 | }; 123 | struct addrinfo *result; 124 | int returnvalue = getaddrinfo(list.tokens[0], NULL, &addrinfo, &result); 125 | if (returnvalue) { 126 | logmsg(LLVL_ERROR, "DNS lookup of %s failed: %s", list.tokens[0], gai_strerror(returnvalue)); 127 | free_stringlist(&list); 128 | return false; 129 | } 130 | 131 | *ip_nbo = ((struct sockaddr_in*)result->ai_addr)->sin_addr.s_addr; 132 | freeaddrinfo(result); 133 | } 134 | 135 | /* Then parse the port number */ 136 | long int port; 137 | const char *port_str = list.tokens[1]; 138 | if (!safe_strtol(&port_str, &port, false)) { 139 | logmsg(LLVL_ERROR, "Could not pase port number \"%s\" as a valid integer.", list.tokens[1]); 140 | free_stringlist(&list); 141 | return false; 142 | } 143 | 144 | if ((port <= 0) || (port >= 65535)) { 145 | logmsg(LLVL_ERROR, "%ld is not a valid port number.", port); 146 | free_stringlist(&list); 147 | return false; 148 | } 149 | *port_nbo = htons(port); 150 | 151 | free_stringlist(&list); 152 | return true; 153 | } 154 | -------------------------------------------------------------------------------- /parse.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #ifndef __PARSE_H__ 25 | #define __PARSE_H__ 26 | 27 | #include 28 | #include 29 | 30 | /*************** AUTO GENERATED SECTION FOLLOWS ***************/ 31 | bool safe_strtol(const char **string, long int *result, bool trailing_data_allowed); 32 | bool parse_ipv4(const char *ipv4, uint32_t *ip_nbo); 33 | bool parse_ipv4_port(const char *ipv4_port, uint32_t *ip_nbo, uint16_t *port_nbo); 34 | bool parse_hostname_port(const char *hostname_port, uint32_t *ip_nbo, uint16_t *port_nbo); 35 | /*************** AUTO GENERATED SECTION ENDS ***************/ 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /pcapng.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #ifndef __PCAPNG_H__ 25 | #define __PCAPNG_H__ 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | #define LINKTYPE_RAW 101 32 | 33 | /*************** AUTO GENERATED SECTION FOLLOWS ***************/ 34 | bool pcapng_write_shb(FILE *f, const char *comment); 35 | bool pcapng_write_idb(FILE *f, uint16_t linktype, uint32_t snaplen, const char *ifname, const char *ifdesc); 36 | bool pcapng_write_nrb(FILE *f, const void *address, const char *hostname, bool is_ipv4); 37 | bool pcapng_write_epb(FILE *f, const uint8_t *payload, unsigned int payload_length, const char *comment); 38 | FILE *pcapng_open(const char *filename, uint16_t linktype, uint32_t snaplen, const char *comment); 39 | /*************** AUTO GENERATED SECTION ENDS ***************/ 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /pgmopts.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #ifndef __PGMOPTS_H__ 25 | #define __PGMOPTS_H__ 26 | 27 | #include 28 | #include 29 | #include "map.h" 30 | #include "logging.h" 31 | 32 | enum keytype_t { 33 | KEYTYPE_RSA, 34 | KEYTYPE_ECC, 35 | }; 36 | 37 | struct pgmopts_t { 38 | char *config_dir; 39 | 40 | struct { 41 | const char *filename; 42 | const char *comment; 43 | bool use_ipv6_encapsulation; 44 | } pcapng; 45 | 46 | struct { 47 | enum loglvl_t level; 48 | const char *logfilename; 49 | bool flush; 50 | bool dump_certificates; 51 | bool write_memdumps_into_files; 52 | } log; 53 | 54 | struct { 55 | bool daemonize; 56 | bool singleshot; 57 | } operation; 58 | 59 | struct { 60 | struct { 61 | uint32_t ipv4_nbo; 62 | uint16_t port_nbo; 63 | unsigned int listen; 64 | } server_socket; 65 | struct { 66 | uint32_t ipv4_nbo; 67 | uint16_t port_nbo; 68 | } local_forwarding; 69 | double initial_read_timeout; 70 | } network; 71 | 72 | struct { 73 | const char *crl_uri, *ocsp_responder_uri; 74 | bool mark_forged_certificates; 75 | bool recalculate_key_identifiers; 76 | } forged_certs; 77 | 78 | struct intercept_config_t *default_config; 79 | struct map_t *custom_configs; 80 | 81 | struct { 82 | enum keytype_t keytype; 83 | union { 84 | struct { 85 | unsigned int modulus_length_bits; 86 | } rsa; 87 | struct { 88 | char *curvename; 89 | } ecc; 90 | }; 91 | } keyspec; 92 | }; 93 | 94 | extern const struct pgmopts_t *pgm_options; 95 | 96 | /*************** AUTO GENERATED SECTION FOLLOWS ***************/ 97 | void show_syntax(const char *pgmbinary); 98 | const struct intercept_config_t* pgmopts_get_intercept_config(const char *hostname); 99 | struct certificate_runtime_parameters_t **pgmopts_get_default_client_parameters(void); 100 | struct certificate_runtime_parameters_t **pgmopts_get_specific_client_parameters(int index); 101 | bool parse_options(int argc, char **argv); 102 | void free_pgm_options(void); 103 | /*************** AUTO GENERATED SECTION ENDS ***************/ 104 | 105 | #endif 106 | -------------------------------------------------------------------------------- /ratched.c: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include "pgmopts.h" 29 | #include "server.h" 30 | #include "openssl.h" 31 | #include "certforgery.h" 32 | #include "sighandler.h" 33 | #include "daemonize.h" 34 | #include "interceptdb.h" 35 | #include "hostname_ids.h" 36 | 37 | int main(int argc, char **argv) { 38 | if (!parse_options(argc, argv)) { 39 | show_syntax(argv[0]); 40 | exit(EXIT_FAILURE); 41 | } 42 | 43 | if (pgm_options->log.logfilename) { 44 | if (!open_logfile(pgm_options->log.logfilename)) { 45 | logmsg(LLVL_FATAL, "Could not open logfile for writing."); 46 | exit(EXIT_FAILURE); 47 | } 48 | } 49 | 50 | if (!init_signal_handlers()) { 51 | logmsg(LLVL_FATAL, "Could not install signal handlers."); 52 | exit(EXIT_FAILURE); 53 | } 54 | 55 | init_hostname_ids(); 56 | 57 | struct multithread_dumper_t mtdump; 58 | if (!open_pcap_write(&mtdump, pgm_options->pcapng.filename, pgm_options->pcapng.comment)) { 59 | logmsg(LLVL_FATAL, "Could not open dump file %s for writing: %s", pgm_options->pcapng.filename, strerror(errno)); 60 | exit(EXIT_FAILURE); 61 | } 62 | 63 | if (pgm_options->operation.daemonize && !daemonize()) { 64 | logmsg(LLVL_FATAL, "Requested daemonization failed."); 65 | exit(EXIT_FAILURE); 66 | } 67 | 68 | openssl_init(); 69 | if (certforgery_init()) { 70 | if (init_interceptdb()) { 71 | start_forwarding(&mtdump); 72 | deinit_interceptdb(); 73 | } else { 74 | logmsg(LLVL_FATAL, "Cannot continue without properly initialized interception database."); 75 | } 76 | certforgery_deinit(); 77 | } else { 78 | logmsg(LLVL_FATAL, "Cannot continue without proper certificates and keys."); 79 | } 80 | 81 | openssl_deinit(); 82 | close_pcap(&mtdump); 83 | deinit_hostname_ids(); 84 | free_pgm_options(); 85 | 86 | return 0; 87 | } 88 | -------------------------------------------------------------------------------- /server.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #ifndef __SERVER_H__ 25 | #define __SERVER_H__ 26 | 27 | #include 28 | #include "tcpip.h" 29 | 30 | /*************** AUTO GENERATED SECTION FOLLOWS ***************/ 31 | void stop_forwarding(bool force); 32 | bool start_forwarding(struct multithread_dumper_t *mtdump); 33 | /*************** AUTO GENERATED SECTION ENDS ***************/ 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /server/client_koo.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDCjCCAfKgAwIBAgIJAJxxD+i+dzxhMA0GCSqGSIb3DQEBCwUAMBoxGDAWBgNV 3 | BAMMD0NsaWVudCBjZXJ0IEtPTzAeFw0xNzExMjUwOTQwMzFaFw0yNzExMjMwOTQw 4 | MzFaMBoxGDAWBgNVBAMMD0NsaWVudCBjZXJ0IEtPTzCCASIwDQYJKoZIhvcNAQEB 5 | BQADggEPADCCAQoCggEBAM8hAHJsubRznWW34OgarcF3gAkKE6I3MYSU34Rrt4DB 6 | bF2vV/RAzJKZR2S3GKkrJCQMz/bFW1RUSgwq7ykhiw7n3OHSMW4hxFSPMnU64/Xe 7 | 7lOdCNUJKDZI3ko8pUQ/9e9pcC1JX2XJvJlqiNfCEJ01K6vG5mAibnjCSj/zfA3n 8 | 3NkCAKCtQ2OYIqkPYJieliMZ+pvGsZk21DyiZWfjX/UwkmbzmnuxWbbnl6cF8Iqj 9 | r1Xkms0JuuDISOGqOGRzfrbTwUG3q2XwiYqXSBC8We8nP1iN2e35t/U+EICDNB0Y 10 | 3MqL2TsVOS68RwEv/JnPzffFRfZiUs2uK83LNqmIix8CAwEAAaNTMFEwHQYDVR0O 11 | BBYEFNDNn2HraLTsK4K8FJgJKCxbTmmXMB8GA1UdIwQYMBaAFNDNn2HraLTsK4K8 12 | FJgJKCxbTmmXMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAK8r 13 | PCk/Jl2HzmGaffPJkOmaB7vE6bIhzD+NWXFT1gJ8in+5wRcVx9JUa5QKbltL79OJ 14 | GkZ3XKiyI1xeD/T17UiMUsCBI9JfMofg1nrt3yxGKodoKWmXRkudElDyGZ70RbEn 15 | 29kBoMYfnjJY1n4FSBdoDVAh4gAuotspSeUQ2fpZCGaoool7H2YPZV32ozmnDfdx 16 | /fdjAiZcy/HWcGOhJHuzj+3CZOqxX6qD1rWwgNZgfExD5qmdvWsX9tAgK9ga1mrt 17 | 6M4fjpQl1opKZ3oYgGqmxpGc5ern2lbWw9nOgqh+TXHnhUtgvKMJoogy5w/1F4BP 18 | N8/JTd+7XuoFdiVcHMI= 19 | -----END CERTIFICATE----- 20 | -------------------------------------------------------------------------------- /server/client_koo.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDPIQBybLm0c51l 3 | t+DoGq3Bd4AJChOiNzGElN+Ea7eAwWxdr1f0QMySmUdktxipKyQkDM/2xVtUVEoM 4 | Ku8pIYsO59zh0jFuIcRUjzJ1OuP13u5TnQjVCSg2SN5KPKVEP/XvaXAtSV9lybyZ 5 | aojXwhCdNSurxuZgIm54wko/83wN59zZAgCgrUNjmCKpD2CYnpYjGfqbxrGZNtQ8 6 | omVn41/1MJJm85p7sVm255enBfCKo69V5JrNCbrgyEjhqjhkc36208FBt6tl8ImK 7 | l0gQvFnvJz9Yjdnt+bf1PhCAgzQdGNzKi9k7FTkuvEcBL/yZz833xUX2YlLNrivN 8 | yzapiIsfAgMBAAECggEAJVgl5HuF3+sYbcaBXlexDDindPnEIHMjEmxlAFMLesNk 9 | 7l821Gr6d1P7c0UvxRBqK7XDqRJcLRAlaZw0Eo5hrAZR5MUo9FpSM4y95DUB9MqE 10 | 3b5qYT6NaXwp1+inQ27kwI2aFBAuiwOcZWy3z27F4BI+FXJ/BsYudMdS68TSkQ7x 11 | hZ4HqWzhRwn/NCL6uc1MfVlwjWD14kT5/dyKd3k/MCAPhxuZU8H22nPZ1zzRnXi1 12 | G9MZRnXy03EDPFSua1Yqe3Aul73R3HXwNsDhkuoghvmHAZE8wFMoccTZTZJKQkx6 13 | 7zPCZ1YnQ84S6lLCV8oxrB3Upwg7WZEYbxFNDXznAQKBgQD6lWbfLfXFM4ZWoRrx 14 | cXUXHU4zcRI1BCjYfRVi5LT95NObs502hZBmaUXLGJXpHq279fp1rrGnmEsLvEkO 15 | hxOE/Bzx1pn1JFSzLZUEXgwYTDuRVLCWZT3wzvh3Fif3fv/zHmwxy2+8qQa5fJO5 16 | zupBkrc1eKKEgqybiSFhW7LF0QKBgQDTmyT7gHv777H8mjF4D++kk57CVt61BBfx 17 | okpyODmBO4mD+lUq86GAHsafxZVy1UqmfmpLY7DKHDVWgkh97TitmvAi9l+KWxd9 18 | WKbqWo9ADXh2e/kIOS37Yv54QhE7Ia2C/A3wr2ru37jfqkWrxZlBCQfO3ogd+7NZ 19 | 10IYlIJN7wKBgGzjCuakFA3zC8cNDqYoBRdcNqUH1z+OZSldgTON6lABZSpdbE1K 20 | 0KqPyDIupsW7/QaWJpWIqc4H0WRyFtTnQUYiP3mfJRtvBBcwEXbqXxsX1TKbuHhB 21 | 2h6P8UveJtPXLeU5LQ6eNhmm4TMsvQyaqxR/ankjyIsINXUIq6agsBhhAoGAD9cr 22 | W5Bwt5ln74rzbRN0UxOh7NZn8ZEO4c3OWOKQm3YDg1e4DHEUg+zJ3agC2gfRgMkx 23 | 19bsoxSdgY5bMuIRPh29IEDlQgwzo/SA+kYxNxBLFkONjuoI4Sq19fasJ4sL3CRW 24 | PtBC5wLkagnrEULHiDDO3tOVyPjQokcU8ZYccw0CgYEA+jQXpE45zp1weVZdgnLL 25 | njcWbfPjJpGWqrW6tpzziPRBg4eOGN/JBkpgAhHqWt0SmJlYMtfFMNzvoKxOKqtN 26 | KzezuW/GHgotYTSD8KcIy+gqMlp/Tq9B58CBO5MpQa32r/ycy2EtXo/vnXiP0M7z 27 | kfaVZDUnnb2V8OfdPOTFwGM= 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /server/client_moo.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDCjCCAfKgAwIBAgIJAK7sPEwj69ZKMA0GCSqGSIb3DQEBCwUAMBoxGDAWBgNV 3 | BAMMD0NsaWVudCBjZXJ0IE1PTzAeFw0xNzExMjUwOTQwMTFaFw0yNzExMjMwOTQw 4 | MTFaMBoxGDAWBgNVBAMMD0NsaWVudCBjZXJ0IE1PTzCCASIwDQYJKoZIhvcNAQEB 5 | BQADggEPADCCAQoCggEBALdmHK6JpWzaKkx/pr1MOi4UP+sclw99O7KSyYveqRbR 6 | 3Q0XHujGfCdeox2x8BBhR3xqgODDMvABrVtxSkyLMEbJ1+2eJcmsdSNykNMsbC/7 7 | 0sf4zGrL8D3q1Gh6mG6n6xkhT9PWKIAoyuwXXEeKXT9ues3IMDXrX2yMMJUPcwL1 8 | UrvKkDsYGBQh9fBogT30s0EfnjzSRlbeVM0gSzNYQEbqa4pWqE3aFxUqu5EHRVDa 9 | 0/hSiAQ0U4ZIEZ0YNZKdpqlUq+Eoj9h1CIRP0DcUAFwkvTou54zX25OqLstVcQhU 10 | ikFErh8EFY4ncArXOSRs5euoHxdS+7bNYUEuVaL8sDkCAwEAAaNTMFEwHQYDVR0O 11 | BBYEFFeUWrG9tKzMZ/sk8hVlx/cR3x+tMB8GA1UdIwQYMBaAFFeUWrG9tKzMZ/sk 12 | 8hVlx/cR3x+tMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBACGB 13 | 8ewoBqPhfJvmqT70a6olYKoAroRPpvKkVVcPLM9KiuDpDO/B1fMaeOvHmF/VHnHM 14 | aFj0kdmAzF84oi7eyQOtnYvLOsOk45ESQQsF1MDoMZPoYVYyhNn5V/iqWCu1Sm9h 15 | H1fDKFYLvhMweB2TZaHU3jz6k4kkd31GGptl75ZKjIkVtvOv+n1kpcSRRHaMAt9Y 16 | jYwk0ziKC/EvF432XHIVdTrpEZC0HdjKHCOCzdKKafMwivkKmoQrVBvYNYsuGtE+ 17 | fLodFkK2YmrFYpCcFaGDOhpeAJMlBlzCq3OrkkpmHDdEXO7fnlit6BtH37ACYtyI 18 | HZWs8t7CpOSlpS5wtjg= 19 | -----END CERTIFICATE----- 20 | -------------------------------------------------------------------------------- /server/client_moo.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC3ZhyuiaVs2ipM 3 | f6a9TDouFD/rHJcPfTuyksmL3qkW0d0NFx7oxnwnXqMdsfAQYUd8aoDgwzLwAa1b 4 | cUpMizBGydftniXJrHUjcpDTLGwv+9LH+Mxqy/A96tRoephup+sZIU/T1iiAKMrs 5 | F1xHil0/bnrNyDA1619sjDCVD3MC9VK7ypA7GBgUIfXwaIE99LNBH5480kZW3lTN 6 | IEszWEBG6muKVqhN2hcVKruRB0VQ2tP4UogENFOGSBGdGDWSnaapVKvhKI/YdQiE 7 | T9A3FABcJL06LueM19uTqi7LVXEIVIpBRK4fBBWOJ3AK1zkkbOXrqB8XUvu2zWFB 8 | LlWi/LA5AgMBAAECggEBAKKuq4aPhvQ12guduDR2p600PTa7V6xftFLFLo8p5efe 9 | JS11cu+dEYiCxEKVEpQVFqpgdw3pWQfZFQPmTLf1R8+jQC0BeheZKRdWiu0nnJg7 10 | 00+bfQjG+saRxfUfupN91GeoSv1oHOkCRm6CklLLg8e+oqRjjZBmx3CsMnQnDihy 11 | IDO4zuyKNW6Fok59shSgDp0iJvZLXDdZhoIqmqgkNUr9ZmQcGi/vL9VXA5nJi5de 12 | h0VkRZJL0cIABAQ0GsMb/Z0grAeNO+E2uByZkgqkZu+1oli5Ja6RyYRuyBQSAsq/ 13 | P4QwxfNbgI13Gbl0kQOwpvAHj4mbSTdw3E9TyEHN8wECgYEA4pCFvcgfoYHpyvEd 14 | jjKLmZvYeiTW/QyTaCNQ3PwjWg6EnJeAg6Rm5YQ29t657QSR6CXL3HjfedcQY++9 15 | pMYGBfGXirJ9wLNT97alX4CCNnZ0WrEO4uUrYf1Wn1EAOiFdJeJySv4LNUb04T+3 16 | +yy/bVhZKqTOVgT1TY964kNeeNECgYEAzznpK80pForp2/Fi2YdRqJ35K4rqJSjn 17 | 03eYZjckJEDSuvDRRYECiE5vrFmJqNzR5bgkPrXxjGkYYuBWnaBA2w+N8/TFjOmi 18 | NYqXXGlavspyGZDr9PGxLXld7KDWdPam4ko6rpIuzZ7AdGwQcZ7ttU6gm9LiIeim 19 | siKyi5zjmukCgYAqSV8s9NUyh9TjE+24RKbZnMTix015HYfFwBGvrT/L5znJIF3U 20 | NDMgU3UOzrNVEa1J7wQFumm7i/B7NpvmzS8CnPzz3iyqcs4RRf3HvWyQTbuZ0cI9 21 | hxh5yZcJVUz9jIyeLY23gYMGBqBeCk6Eiu2PsxWxZ+E7HOHMACOnZ3uSgQKBgFw/ 22 | VVMQUzgbwpsMS4q2OF2tZRxDDJRaL0jttkPaTBZvXN+nECG2ml//OqsoeKVZF38B 23 | h/D6oXp11ks9vpEQo45g0DpHPiHKZ1EaTuLua1z/VeeXodI6PTsXCf6qYo1St1uI 24 | 27KWlIsoHlg1OuS5cOwDAnAbYlrh7ELkO0L3JkLxAoGALEDAbmqh9tSKezykKVrt 25 | 2vL2yGqTSwHQCHcrSu+/G8946u+M2x1cXO45tQQfXkwrLCH5joXFE/Xici7iOSYf 26 | cqLejgxVzcalNcU6YqXw45eRD4cNi+iEqyEhM8w8hoYMYSDkeTfp2Vp4HSUfc7rX 27 | N4TcvKm+S8Liw11gWTDELQo= 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /server/server_bar.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDEjCCAfqgAwIBAgIJAKqD5+zmjhuiMA0GCSqGSIb3DQEBCwUAMB4xHDAaBgNV 3 | BAMME09yaWdpbmFsIHNlcnZlciBCQVIwHhcNMTcxMTI1MDkzOTUwWhcNMjcxMTIz 4 | MDkzOTUwWjAeMRwwGgYDVQQDDBNPcmlnaW5hbCBzZXJ2ZXIgQkFSMIIBIjANBgkq 5 | hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5uaKD0vrffRDW988OrQaJJK1NtY92TIr 6 | mO8UC/wKK4eZ6txO8fYEPH6fatVQzSWd9+HtdedhZ8NYac8AyqeIeqZM+Lr1LZQh 7 | A4E54ekXQs6jqgb9jp1UfWnODdMq7RYCfKWytjSMb4BBQHqXApHSWIW2+efA9SIa 8 | 30lOoIY8HFxV1vw6+GKzKDG5SasOLwNXB3Mqn7NwXc+PoblZM0TDSLDrB3ZcFZWQ 9 | 9qlg5jfR8HzRz9r9z1gOgEn6a3iwaGeKJHYuIoNxCWEVu+vJlNN9iyWY9Mn1aBFD 10 | 41t/5WM9iLEmEB/iFOGmLeC8uONerOVFd/cwZx4IiCI5VOZQ4EoGkwIDAQABo1Mw 11 | UTAdBgNVHQ4EFgQUXlfYBDmLfwZgAxrhJHao6pva5t4wHwYDVR0jBBgwFoAUXlfY 12 | BDmLfwZgAxrhJHao6pva5t4wDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsF 13 | AAOCAQEAfWJn4bWsGnF6hLPCMue/bhorqhIqCLdUs1B0brRMvSLk2OmjR3/ZbTfP 14 | hizLX/UcfXwUT9vaB68DhvAicdwgBDbMN91iKW84NXSWhO9LXWXUFNj8vmRF9Lpy 15 | nniwCkqFRIWTj0dBEmd/LWq1cPxijjXgE7sEaTzuhvta7XJpnGUEjejrFSxQVtpc 16 | ZApdldCgJXCitEFTwapixw4KfbEZpCOdp29mC1zF22tz+LLmPMl71kXznMnGxpkN 17 | iReMyvJEAu6Z75dMDMebwFlFE3s165URzqExuXHk5RzH+ZGJZiHocWq5UsyWe/++ 18 | 1bBerxSq+lwxed10inmnoVGZ56YQFg== 19 | -----END CERTIFICATE----- 20 | -------------------------------------------------------------------------------- /server/server_bar.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDm5ooPS+t99ENb 3 | 3zw6tBokkrU21j3ZMiuY7xQL/Aorh5nq3E7x9gQ8fp9q1VDNJZ334e1152Fnw1hp 4 | zwDKp4h6pkz4uvUtlCEDgTnh6RdCzqOqBv2OnVR9ac4N0yrtFgJ8pbK2NIxvgEFA 5 | epcCkdJYhbb558D1IhrfSU6ghjwcXFXW/Dr4YrMoMblJqw4vA1cHcyqfs3Bdz4+h 6 | uVkzRMNIsOsHdlwVlZD2qWDmN9HwfNHP2v3PWA6ASfpreLBoZ4okdi4ig3EJYRW7 7 | 68mU032LJZj0yfVoEUPjW3/lYz2IsSYQH+IU4aYt4Ly4416s5UV39zBnHgiIIjlU 8 | 5lDgSgaTAgMBAAECggEBAJmMafcuJ5aFH14zH9xx9IipvzSOWGbdhDyZkJ0/qIu2 9 | C1cx1pX1Ym/QTLdA0BD8mQZFCiLEEfRs5ZjHfeFGc+4MNVebDHyY6zNndlSTK1LU 10 | E+Z365oxagRUniB3cy5i2piFoEimvVVQ1xPH8jBVRKp1kW6y/ZCGc5RVLaJ2YfcA 11 | 9P/AG/t7eaQa3g7BVLeT4Aak7WGmMzWcdh0QnvxlQkbDc5N5NNYEmXohtwB/oIsg 12 | icdagSv3EUUiahLBPlxQx+iXeh9wRuO7cmqyYlJv/JNRrSqAqN+9jKv7XkSdl3tT 13 | JmWQcdp5MIBVJNxqZ8HyyfosjcR/fxhqmaEc9ig/zzECgYEA81219PB3hECYBz5G 14 | In7zZbqvly4rPZi/H0VEuJ6IyXXkJFooPFt8rbMmNVuIbDEd5TBPU3AKymvFQWt0 15 | 7RWgY3zvRcI6ROe0AY19vTnpxPlGX+VmnxzGpQK6AhG2bz5X+Vh7SAg4FSayNuHu 16 | w3LvHCDQ7fcioZbz416TvqdOkA0CgYEA8uMqCHNSYe230/ySZm/bLEuMX0FwNDRC 17 | u8wyrILOMWopjz6feg/HShDfI2YuNe3K2/0d0aSaCBsHV1sWxsGgBGaohrW5+XZm 18 | hQgRa9l72RefAXG1M1pxohlikWMnXy869eWqpMUccbX1VqOP++X73xZtQLpQ1fL9 19 | 8hUoUWnmqR8CgYAFJKDYyVAtSlQsKwO+bOJl7vkQ/9fIGHdJiOQ35pnLcCNfJUye 20 | YeyTmyqejA2pA6y3EDtM7xw7ROXJSSUScZePIq/H0J/8nszuD3htzFCFaiMzmZx+ 21 | llQYXqNhsdAiL7YaPeV1Ez9kKwovIL00AjTNamAf904TDiafUnta1xxQ7QKBgAqU 22 | uNULaRBZEcQLYblSsCKa2++eYyvzBuE1gROg0yi17j+OQ9ZGb7EbUQ0yu1qgFFFH 23 | EpB6cjdeLhCxKCnab4Uhj7/mlMZ4UPkEo/Wl0M5hSA0BDhrBmuer4W5h+mocHZ5u 24 | teNdruKJQbnXgENB/pn2WSYTt8fKQSPVph791Q2TAoGAV25wRVRjK2DHyfqPugEW 25 | OUulCahb3Q8DB1JH3yrwICB1Rl3W/sOi57Qi8lontEJYBS9+rZgdy9Xi1PYgHM3S 26 | Vd1LIvKpaaD8omNcZan5AilisLgWa6lxoYrymvSqIkezDLSWSL2vbZRnee8AkK8Z 27 | 0ghPIzp2YpP93+veIih1nW0= 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /server/server_foo.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDEjCCAfqgAwIBAgIJANMPNbmCBXL1MA0GCSqGSIb3DQEBCwUAMB4xHDAaBgNV 3 | BAMME09yaWdpbmFsIHNlcnZlciBGT08wHhcNMTcxMTI1MDkzOTM5WhcNMjcxMTIz 4 | MDkzOTM5WjAeMRwwGgYDVQQDDBNPcmlnaW5hbCBzZXJ2ZXIgRk9PMIIBIjANBgkq 5 | hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApWEbWFS/s5n3GOQTSoEQE265YJMfEGRc 6 | eM27+53oQOq1+DmyQzpmgE04ZpPbHWIoCudrWFrJHL+FevVBNDIYa5nvCJi/49yi 7 | otfd4IizbDPVUDg2434Ytu1DadzrLWDRjWWl4DQYTt+ydFWQ3oYYz5Po1DDaBcGI 8 | 1AMjqPcJzOUdQIW9dv5WgeE1mTajbGBhQy3es7eNPAijlSP4SD0NwHrSerQPh/DE 9 | s21uSjw9lhfC3A+kKbSJakmIZIIQG0WnDMuJlkJBQNDqa2XpeqCgCYSDjGov/WtU 10 | Ji/MJPGvvM473JvFMkromVvSXeKkEzxI+L9s4F4kgCO/XRAkDp4hvQIDAQABo1Mw 11 | UTAdBgNVHQ4EFgQUBcTmL+fUHQySaPZG3IsPDotLuXgwHwYDVR0jBBgwFoAUBcTm 12 | L+fUHQySaPZG3IsPDotLuXgwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsF 13 | AAOCAQEAP8rR1+lMfcgKjwM9wzdl+/9SoJW+Qer/G+R26KpHp6acdFxyhmkuUJBk 14 | 3zxIEswZWS++peVJTUeSVT+GDbXq4/ubtmgT5uAzaQsr2bagG0i3qF7eKe2ah1GZ 15 | p0F2N2UE9lvl6EN34xnysSr+OdZKZDgiEDHTg2vXLScYExgYkuhUTTrLTy2QzR0c 16 | u+7cPAzdFLreUbisU+4feBz80VeAT/+RCf3Pb2hx0gTElR4BusDOu+tVwsjMkTd/ 17 | h/zjHNNWeiDjUWbAmaG7HT89bQ1HX67TeezhJs5RmF6/CABRE+EW7056uWqdKFfN 18 | g00YF+I4smk43xkVdSI2EVeTWmjWsA== 19 | -----END CERTIFICATE----- 20 | -------------------------------------------------------------------------------- /server/server_foo.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQClYRtYVL+zmfcY 3 | 5BNKgRATbrlgkx8QZFx4zbv7nehA6rX4ObJDOmaATThmk9sdYigK52tYWskcv4V6 4 | 9UE0Mhhrme8ImL/j3KKi193giLNsM9VQODbjfhi27UNp3OstYNGNZaXgNBhO37J0 5 | VZDehhjPk+jUMNoFwYjUAyOo9wnM5R1Ahb12/laB4TWZNqNsYGFDLd6zt408CKOV 6 | I/hIPQ3AetJ6tA+H8MSzbW5KPD2WF8LcD6QptIlqSYhkghAbRacMy4mWQkFA0Opr 7 | Zel6oKAJhIOMai/9a1QmL8wk8a+8zjvcm8UySuiZW9Jd4qQTPEj4v2zgXiSAI79d 8 | ECQOniG9AgMBAAECggEAdhHXGQAggRQqEq46i5WLKaSCWs2OfwB3+JNBY0mAWGB5 9 | nAdtGowmQ/Fdk/Z5mAfM+MPxonnmXUzq+jcA30fooWGcA3IyhXau8j3VnYlbN6Pl 10 | 5kjL/yy2blsEJx9fE92snht1CpWGyUDxwhaYwBXSvtglgOCDt1pN2reHDQmaCJpg 11 | bdkyGBWd8/hiYTCHhsbPqsU84pZHtubLVPev1fvVSSpH4jX/P2TKIPuzBApGShZi 12 | 6GhNAYzdZCHVWFpVXiEU4JbDbEmAG0pTk9Y6PISPurqPNyTlP3QO3QlDsnJKNzbQ 13 | lHwhaNQvOvS8xWn25JLJJXLpBaxoxmN63mq0guSUgQKBgQDW0vp6fr3+XIn0NL/v 14 | t/3jJG+xdQUm59YO1qXRLx76TXzwG6Wk+du6bW3PwhHnIlmDhn07hibKvHpySqs7 15 | eMWBEKKsuGNEDQT+p2/HFaeANpTJD4hR5tJoUbLneIj6ImXlpDrTIoQDMDfkf77T 16 | 2LxPh0j0ad9G8g8mPmGH+AtCYQKBgQDFE/aZanZbhLt7y9LoNjJXl82PA4i2MYoE 17 | ir0ttDBcHU6UzQ2s0naTTh/bSZUOFI85+TP8rbhfY7mvaGHqFeJFnIAIV4hrO5Xe 18 | uIhn1T8tq6DnGPgOqURIZ7X42Rabmxz7EMdLKcNAex0t0l9XGbCZmZQco52YfxfN 19 | jXUxi95U3QKBgQC8Hnj1t/NMwWCVF3RUybxsokWlEqJ2VWKgD9uY+TiZXC3iXXOK 20 | qrp94MHew0XGL9BPWwBjlbB2rOJVH4ofRD1ALn8l3TogJ36OObWqkw3hOurDvvRT 21 | NFxgudp+1JCu6lxs4ooYxgrwd9MaJ7vF6+/LfN6oGeZKTEJz7QCfftjtQQKBgHpx 22 | ss8StEKcLxf1RS59Lb36VP68BV6dXNEBmhQhVcKFeuM8m3h6sq1G5sgJ6Y/7+hjc 23 | 2g3tqRWrEh0HT35u5ky1tV55dAqb1LuyDx3kAgLQFYI/oy8Iv6H0vbzEtCUttE3Q 24 | 2OG8KtGPLEvh3tZw4aYtIza/+RRcMl/FucB01EgJAoGAFrlzgPQTEeOqXAdqhwDT 25 | KWM/CbMHTNGocIRRBEutfCYMC3gB5/VkZVQImm+qGZT5vxCv+cEJKnBMd8JHReT0 26 | dyFGUjfLKA6p5onOihSGyvBtlj0IZBB8c+HVbVzuiDv8z8cZ5ta7xhk1z0QZDI9E 27 | fAFgLyYrew0RlGMa/BLucPw= 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /server/start_server: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # 4 | 5 | if [ "$1" == "" ]; then 6 | ARGS="" 7 | elif [ "$1" == "www" ]; then 8 | ARGS="-www" 9 | else 10 | echo "Do not understand parameter: $1" 11 | exit 1 12 | fi 13 | 14 | openssl s_server -cert server_foo.crt -key server_foo.key -accept 9000 -msg -verify 2 ${ARGS} 15 | -------------------------------------------------------------------------------- /server/test_client: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # 4 | 5 | OPTS="" 6 | if [ "$1" != "" ]; then 7 | HOSTNAME="$1" 8 | OPTS="${OPTS} -servername ${HOSTNAME}" 9 | if [ -f "client_${HOSTNAME}.crt" ]; then 10 | # use client cert as well 11 | OPTS="${OPTS} -cert client_${HOSTNAME}.crt -key client_${HOSTNAME}.key" 12 | fi 13 | fi 14 | 15 | CMD="openssl s_client -connect 127.0.0.1:9999 $OPTS" 16 | echo "$CMD" 17 | $CMD 18 | -------------------------------------------------------------------------------- /sighandler.c: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include "sighandler.h" 29 | #include "logging.h" 30 | #include "server.h" 31 | 32 | static bool shutdown_requested; 33 | 34 | static void sigint_handler(int signal) { 35 | stop_forwarding(shutdown_requested); 36 | shutdown_requested = true; 37 | } 38 | 39 | bool init_signal_handlers(void) { 40 | { 41 | struct sigaction action = { 42 | .sa_handler = sigint_handler, 43 | .sa_flags = SA_RESTART, 44 | }; 45 | sigemptyset(&action.sa_mask); 46 | if (sigaction(SIGINT, &action, NULL) != 0) { 47 | logmsg(LLVL_ERROR, "sigaction failed to install SIGINT handler: %s", strerror(errno)); 48 | return false; 49 | } 50 | if (sigaction(SIGHUP, &action, NULL) != 0) { 51 | logmsg(LLVL_ERROR, "sigaction failed to install SIGHUP handler: %s", strerror(errno)); 52 | return false; 53 | } 54 | if (sigaction(SIGTERM, &action, NULL) != 0) { 55 | logmsg(LLVL_ERROR, "sigaction failed to install SIGTERM handler: %s", strerror(errno)); 56 | return false; 57 | } 58 | } 59 | 60 | { 61 | struct sigaction action = { 62 | .sa_handler = SIG_IGN, 63 | .sa_flags = SA_RESTART, 64 | }; 65 | if (sigaction(SIGPIPE, &action, NULL) != 0) { 66 | logmsg(LLVL_ERROR, "sigaction failed to install SIGPIPE handler: %s", strerror(errno)); 67 | return false; 68 | } 69 | } 70 | return true; 71 | } 72 | -------------------------------------------------------------------------------- /sighandler.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #ifndef __SIGHANDLER_H__ 25 | #define __SIGHANDLER_H__ 26 | 27 | #include 28 | 29 | /*************** AUTO GENERATED SECTION FOLLOWS ***************/ 30 | bool init_signal_handlers(void); 31 | /*************** AUTO GENERATED SECTION ENDS ***************/ 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /stringlist.c: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include "stringlist.h" 29 | 30 | bool parse_stringlist(struct stringlist_t *list, const char *string, const char *delim) { 31 | memset(list, 0, sizeof(struct stringlist_t)); 32 | list->dupstr = strdup(string); 33 | if (!list->dupstr) { 34 | return false; 35 | } 36 | 37 | char *strcopy = list->dupstr; 38 | char *saveptr = NULL; 39 | char *next; 40 | while ((next = strtok_r(strcopy, delim, &saveptr)) != NULL) { 41 | char **new_tokens = realloc(list->tokens, sizeof(char*) * (list->token_cnt + 1)); 42 | if (!new_tokens) { 43 | free(list->dupstr); 44 | free(list->tokens); 45 | return false; 46 | } 47 | list->tokens = new_tokens; 48 | list->tokens[list->token_cnt] = next; 49 | list->token_cnt++; 50 | strcopy = NULL; 51 | } 52 | 53 | return true; 54 | } 55 | 56 | void free_stringlist(struct stringlist_t *list) { 57 | free(list->dupstr); 58 | free(list->tokens); 59 | } 60 | 61 | void dump_stringlist(const struct stringlist_t *list) { 62 | fprintf(stderr, "%d strings in stringlist:\n", list->token_cnt); 63 | for (unsigned int i = 0; i < list->token_cnt; i++) { 64 | fprintf(stderr, " %3d: '%s'\n", i, list->tokens[i]); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /stringlist.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #ifndef __STRINGLIST_H__ 25 | #define __STRINGLIST_H__ 26 | 27 | #include 28 | 29 | struct stringlist_t { 30 | unsigned int token_cnt; 31 | char **tokens; 32 | char *dupstr; 33 | }; 34 | 35 | /*************** AUTO GENERATED SECTION FOLLOWS ***************/ 36 | bool parse_stringlist(struct stringlist_t *list, const char *string, const char *delim); 37 | void free_stringlist(struct stringlist_t *list); 38 | void dump_stringlist(const struct stringlist_t *list); 39 | /*************** AUTO GENERATED SECTION ENDS ***************/ 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /tcpip.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #ifndef __TCPIP_H__ 25 | #define __TCPIP_H__ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | struct multithread_dumper_t { 33 | pthread_mutex_t mutex; 34 | FILE *f; 35 | }; 36 | 37 | struct connection_t { 38 | bool ipv6_encapsulation; 39 | struct multithread_dumper_t *mtdump; 40 | struct { 41 | uint32_t ip_nbo; 42 | uint16_t port_nbo; 43 | uint32_t seqno; 44 | const char *hostname; 45 | uint16_t hostname_id; 46 | } connector; 47 | struct { 48 | uint32_t ip_nbo; 49 | uint16_t port_nbo; 50 | uint32_t seqno; 51 | const char *hostname; 52 | uint16_t hostname_id; 53 | } acceptor; 54 | }; 55 | 56 | /*************** AUTO GENERATED SECTION FOLLOWS ***************/ 57 | void create_tcp_ip_connection(struct multithread_dumper_t *mtdump, struct connection_t *conn, const char *comment, bool use_ipv6_encapsulation); 58 | void append_tcp_ip_data(struct connection_t *conn, bool direction, const uint8_t *payload, int payload_len); 59 | void append_tcp_ip_string(struct connection_t *conn, bool direction, const char *string); 60 | void teardown_tcp_ip_connection(struct connection_t *conn, bool direction); 61 | void flush_tcp_ip_connection(struct connection_t *conn); 62 | bool open_pcap_write(struct multithread_dumper_t *mtdump, const char *filename, const char *comment); 63 | bool close_pcap(struct multithread_dumper_t *mtdump); 64 | /*************** AUTO GENERATED SECTION ENDS ***************/ 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /tests/.gitignore: -------------------------------------------------------------------------------- 1 | tests.log 2 | 3 | test_filter 4 | test_hostname_ids 5 | test_keyvaluelist 6 | test_map 7 | test_ocsp 8 | test_openssl_certs 9 | test_openssl_clienthello 10 | test_openssl_tls 11 | test_parse 12 | test_pcapng 13 | test_stringlist 14 | test_tcpip 15 | test_tools 16 | 17 | mantest_openssl_sclient 18 | mantest_openssl_sserver 19 | 20 | tcpip.pcapng 21 | test.pcapng 22 | 23 | test_header_inclusion.c 24 | test_header_inclusion.o 25 | -------------------------------------------------------------------------------- /tests/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all test 2 | 3 | vpath %.c .. 4 | 5 | CFLAGS := -std=c11 -Wall -Werror -Wmissing-prototypes -Wstrict-prototypes -Werror=implicit-function-declaration -O3 -I.. -g3 -pthread 6 | CFLAGS += -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=500 7 | ifneq ($(USER),travis) 8 | # On Travis-CI, gcc does not support "undefined" and "leak" sanitizers. 9 | # Furthermore (and worse, actually), there seems to be a kernel < 4.12.8 10 | # installed which causes the address sanitizer to cause spurious fails ("Shadow 11 | # memory range interleaves with an existing memory mapping. ASan cannot proceed 12 | # correctly. ABORTING."), leading to a broken build. Therefore we do not run 13 | # sanitizers on Travis. 14 | CFLAGS += -pie -fPIE -fsanitize=address -fsanitize=undefined -fsanitize=leak -fno-omit-frame-pointer 15 | else 16 | # Ignore gcc bug #53119 for travis' old gcc version. 17 | CFLAGS += -Wno-missing-braces 18 | endif 19 | LDFLAGS := -lssl -lcrypto -L/usr/local/lib 20 | 21 | TEST_COMMON_OBJS := testbed.o 22 | TEST_OBJS := \ 23 | test_filter \ 24 | test_hostname_ids \ 25 | test_keyvaluelist \ 26 | test_map \ 27 | test_ocsp \ 28 | test_openssl_certs \ 29 | test_openssl_clienthello \ 30 | test_openssl_tls \ 31 | test_parse \ 32 | test_pcapng \ 33 | test_stringlist \ 34 | test_tcpip \ 35 | test_tools 36 | 37 | TEST_MANUAL_OBJS := \ 38 | mantest_openssl_sclient \ 39 | mantest_openssl_sserver 40 | 41 | all: $(TEST_COMMON_OBJS) $(TEST_OBJS) $(TEST_MANUAL_OBJS) 42 | 43 | test_filter: $(TEST_COMMON_OBJS) datafilter.o datafilter_hexdump.o datafilter_bytewise.o hexdump.o helper_logging.o 44 | test_hostname_ids: $(TEST_COMMON_OBJS) hostname_ids.o tools.o helper_logging.o map.o 45 | test_keyvaluelist: $(TEST_COMMON_OBJS) keyvaluelist.o stringlist.o parse.o helper_logging.o 46 | test_map: $(TEST_COMMON_OBJS) map.o helper_logging.o 47 | test_ocsp: $(TEST_COMMON_OBJS) helper_logging.o openssl.o ocsp_response.o openssl_certs.o tools.o errstack.o 48 | test_openssl_certs: $(TEST_COMMON_OBJS) openssl_certs.o openssl.o helper_logging.o errstack.o tools.o 49 | test_openssl_clienthello: $(TEST_COMMON_OBJS) openssl_clienthello.o openssl.o helper_logging.o errstack.o 50 | test_openssl_tls: $(TEST_COMMON_OBJS) openssl_tls.o ocsp_response.o errstack.o openssl_certs.o openssl.o helper_logging.o ipfwd.o atomic.o tools.o thread.o 51 | test_parse: $(TEST_COMMON_OBJS) helper_logging.o parse.o stringlist.o 52 | test_pcapng: $(TEST_COMMON_OBJS) pcapng.o helper_logging.o 53 | test_stringlist: $(TEST_COMMON_OBJS) stringlist.o 54 | test_tcpip: $(TEST_COMMON_OBJS) tcpip.o pcapng.o helper_logging.o tools.o 55 | test_tools: $(TEST_COMMON_OBJS) tools.o helper_logging.o 56 | 57 | mantest_openssl_sclient: $(TEST_COMMON_OBJS) openssl_tls.o ocsp_response.o errstack.o openssl.o helper_logging.o ipfwd.o 58 | mantest_openssl_sserver: $(TEST_COMMON_OBJS) openssl_tls.o ocsp_response.o errstack.o openssl.o helper_logging.o ipfwd.o openssl_certs.o tools.o 59 | 60 | test: all 61 | rm -f tests.log 62 | ./test_header_inclusion 63 | for testname in $(TEST_OBJS); do ./$$testname; done 64 | @./$(firstword $(TEST_OBJS)) --summary 65 | 66 | clean: 67 | rm -f $(TEST_COMMON_OBJS) $(TEST_OBJS) $(TEST_MANUAL_OBJS) ../*.o *.o 68 | rm -f tests.log 69 | rm -f test.pcapng tcpip.pcapng 70 | rm -f test_header_inclusion.c test_header_inclusion.o 71 | 72 | .c: 73 | $(CC) $(CFLAGS) -o $@ $+ $(LDFLAGS) 74 | 75 | .c.o: 76 | $(CC) $(CFLAGS) -include testbed.h -c -o $@ $< 77 | 78 | -------------------------------------------------------------------------------- /tests/helper_logging.c: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #include 25 | #include 26 | 27 | #include "logging.h" 28 | 29 | bool loglevel_at_least(enum loglvl_t lvl) { 30 | return true; 31 | } 32 | 33 | void logmsg_src(enum loglvl_t lvl, const char *src_file, unsigned int src_lineno, const char *msg, ...) { 34 | va_list ap; 35 | va_start(ap, msg); 36 | vfprintf(stderr, msg, ap); 37 | va_end(ap); 38 | fprintf(stderr, "\n"); 39 | } 40 | 41 | void logmsgext_src(enum loglvl_t lvl, const char *src_file, unsigned int src_lineno, unsigned int flags, const char *msg, ...) { 42 | va_list ap; 43 | va_start(ap, msg); 44 | vfprintf(stderr, msg, ap); 45 | va_end(ap); 46 | fprintf(stderr, "\n"); 47 | } 48 | 49 | void log_cert_src(enum loglvl_t lvl, const char *src_file, unsigned int src_lineno, X509 *crt, const char *msg) { 50 | } 51 | 52 | void log_ocsp_response_src(enum loglvl_t lvl, const char *src_file, unsigned int src_lineno, OCSP_RESPONSE *ocsp_response, const char *msg) { 53 | } 54 | 55 | void log_memory_src(enum loglvl_t lvl, const char *src_file, unsigned int src_lineno, const void *data, unsigned int length, const char *msg, ...) { 56 | } 57 | -------------------------------------------------------------------------------- /tests/local.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBkjCCATegAwIBAgIUBiWE9xQmbQTGjTJn97d4UI7u0AwwCgYIKoZIzj0EAwIw 3 | HjEcMBoGA1UEAwwTVGhpcyBpcyBhIHRlc3QgY2VydDAeFw0xNzExMjcyMjA0Mzda 4 | Fw0xNzEyMjcyMjA0MzdaMB4xHDAaBgNVBAMME1RoaXMgaXMgYSB0ZXN0IGNlcnQw 5 | WTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARfF5lkbdlGP8AYBtapKajyq2GmKoq+ 6 | +vR4EkeJFL7PvVU0UQqzGKf1KGvPa1UeB+Ag2AJw444VgCgG/lSpdydho1MwUTAd 7 | BgNVHQ4EFgQUL+/yuqgWTJZABQGbvQRM19d4hPIwHwYDVR0jBBgwFoAUL+/yuqgW 8 | TJZABQGbvQRM19d4hPIwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgNJADBG 9 | AiEAqVedQRPfI7ckxXnFqTy9kH1nM9kLZgMc+9VGxjn56kACIQCrrIHw3zp8HIKI 10 | 4SK5fzbCC/Al9aHKeEdJ364HAcXS1w== 11 | -----END CERTIFICATE----- 12 | -------------------------------------------------------------------------------- /tests/local.key: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PARAMETERS----- 2 | BggqhkjOPQMBBw== 3 | -----END EC PARAMETERS----- 4 | -----BEGIN EC PRIVATE KEY----- 5 | MHcCAQEEIBuvqSn5LMcP8NS5hDLkEOmojXcmt3Z3sgJp2e0+JvscoAoGCCqGSM49 6 | AwEHoUQDQgAEXxeZZG3ZRj/AGAbWqSmo8qthpiqKvvr0eBJHiRS+z71VNFEKsxin 7 | 9Shrz2tVHgfgINgCcOOOFYAoBv5UqXcnYQ== 8 | -----END EC PRIVATE KEY----- 9 | -------------------------------------------------------------------------------- /tests/mantest_openssl_sclient.c: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #include "testbed.h" 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | static void test_tcpip(void) { 32 | subtest_start(); 33 | openssl_init(); 34 | 35 | int sd = tcp_connect(htonl(0x7f000001), htons(9991)); 36 | struct tls_connection_request_t request = { 37 | .peer_fd = sd, 38 | .is_server = false, 39 | }; 40 | struct tls_connection_t connection = openssl_tls_connect(&request); 41 | if (connection.ssl) { 42 | SSL_write(connection.ssl, "foobar\n", 7); 43 | SSL_free(connection.ssl); 44 | } 45 | close(sd); 46 | openssl_deinit(); 47 | subtest_finished(); 48 | } 49 | 50 | int main(int argc, char **argv) { 51 | test_start(argc, argv); 52 | test_tcpip(); 53 | test_finished(); 54 | return 0; 55 | } 56 | 57 | -------------------------------------------------------------------------------- /tests/mantest_openssl_sserver.c: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #include "testbed.h" 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | static void test_sserver(void) { 32 | subtest_start(); 33 | openssl_init(); 34 | 35 | struct tls_endpoint_config_t config; 36 | struct tls_endpoint_cert_source_t certsrc = { 37 | .cert_filename = "local.crt", 38 | .key_filename = "local.key", 39 | }; 40 | test_assert(init_tls_endpoint_config(&config, "local config", &certsrc)); 41 | 42 | const int port = 7777; 43 | fprintf(stderr, "Listening on port %d...\n", port); 44 | int sd = tcp_accept(htons(port)); 45 | 46 | fprintf(stderr, "Someone connected, reading preliminary data...\n"); 47 | 48 | uint8_t client_data[1024]; 49 | ssize_t client_data_len = read(sd, client_data, sizeof(client_data)); 50 | fprintf(stderr, "Read %zd bytes of initial client data. Setting up TLS connection...\n", client_data_len); 51 | 52 | struct tls_connection_request_t request = { 53 | .peer_fd = sd, 54 | .is_server = true, 55 | .initial_peer_data = client_data, 56 | .initial_peer_data_length = client_data_len, 57 | .config = &config, 58 | }; 59 | struct tls_connection_t conn = openssl_tls_connect(&request); 60 | if (conn.ssl) { 61 | SSL_write(conn.ssl, "foobar\n", 7); 62 | SSL_free(conn.ssl); 63 | } 64 | close(sd); 65 | 66 | //EVP_PKEY_free(server_key); 67 | //X509_free(server_cert); 68 | 69 | openssl_deinit(); 70 | subtest_finished(); 71 | } 72 | 73 | int main(int argc, char **argv) { 74 | test_start(argc, argv); 75 | test_sserver(); 76 | test_finished(); 77 | return 0; 78 | } 79 | 80 | -------------------------------------------------------------------------------- /tests/test_filter.c: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #include 25 | #include "testbed.h" 26 | #include 27 | #include 28 | #include 29 | 30 | struct sink_callback_data_t { 31 | unsigned int length; 32 | uint8_t data[4096]; 33 | }; 34 | 35 | static void sink_callback(void *arg, const uint8_t *data, unsigned int length) { 36 | struct sink_callback_data_t *ctx = (struct sink_callback_data_t*)arg; 37 | if (length <= 4096) { 38 | memcpy(ctx->data, data, length); 39 | ctx->length = length; 40 | } 41 | } 42 | 43 | static void test_filter_sink(void) { 44 | subtest_start(); 45 | struct sink_callback_data_t cbdata = { 0 }; 46 | struct datafilter_t *sink = datafilter_new_sink(sink_callback, &cbdata); 47 | datafilter_put(sink, "foobar", 6); 48 | test_assert_int_eq(cbdata.length, 6); 49 | test_assert(!memcmp(cbdata.data, "foobar", cbdata.length)); 50 | datafilter_put(sink, "mookoo123", 9); 51 | test_assert_int_eq(cbdata.length, 9); 52 | test_assert(!memcmp(cbdata.data, "mookoo123", cbdata.length)); 53 | datafilter_free_chain(sink); 54 | subtest_finished(); 55 | } 56 | 57 | static void test_filter_hexdump(void) { 58 | subtest_start(); 59 | struct sink_callback_data_t cbdata = { 0 }; 60 | struct datafilter_t *filter = datafilter_new_sink(sink_callback, &cbdata); 61 | filter = datafilter_new(&filterclass_hexdump, NULL, filter); 62 | datafilter_put(filter, "mookoo123", 9); 63 | test_assert_int_eq(cbdata.length, 9); 64 | test_assert(!memcmp(cbdata.data, "mookoo123", cbdata.length)); 65 | datafilter_free_chain(filter); 66 | subtest_finished(); 67 | } 68 | 69 | static void test_filter_bytewise_hexdump(void) { 70 | subtest_start(); 71 | struct sink_callback_data_t cbdata = { 0 }; 72 | struct datafilter_t *filter = datafilter_new_sink(sink_callback, &cbdata); 73 | filter = datafilter_new(&filterclass_hexdump, NULL, filter); 74 | filter = datafilter_new(&filterclass_bytewise, NULL, filter); 75 | datafilter_put(filter, "mookoo123", 9); 76 | test_assert_int_eq(cbdata.length, 1); 77 | test_assert(!memcmp(cbdata.data, "3", cbdata.length)); 78 | datafilter_free_chain(filter); 79 | subtest_finished(); 80 | } 81 | 82 | int main(int argc, char **argv) { 83 | test_start(argc, argv); 84 | test_filter_sink(); 85 | test_filter_hexdump(); 86 | test_filter_bytewise_hexdump(); 87 | test_finished(); 88 | return 0; 89 | } 90 | -------------------------------------------------------------------------------- /tests/test_header_inclusion: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | # 3 | 4 | for HDRFILE in ../*.h; do 5 | echo "#include \"${HDRFILE}\"" >test_header_inclusion.c 6 | echo "Including $HDRFILE" 7 | gcc -Wall -O3 -c -o test_header_inclusion.o test_header_inclusion.c 8 | done 9 | -------------------------------------------------------------------------------- /tests/test_hostname_ids.c: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #include 25 | #include "testbed.h" 26 | #include 27 | 28 | static void test_hostname_ids(void) { 29 | subtest_start(); 30 | init_hostname_ids(); 31 | test_assert_int_eq(resolve_hostname_id(0x11223344, NULL), 0); 32 | test_assert_int_eq(resolve_hostname_id(0x22334455, NULL), 0); 33 | test_assert_int_eq(resolve_hostname_id(0x11223344, "foobar"), 1); 34 | test_assert_int_eq(resolve_hostname_id(0x11223344, "foobar"), 1); 35 | test_assert_int_eq(resolve_hostname_id(0x11223344, "barfoo"), 2); 36 | test_assert_int_eq(resolve_hostname_id(0x11223344, "foobar"), 1); 37 | test_assert_int_eq(resolve_hostname_id(0x22334455, "moo.com"), 1); 38 | test_assert_int_eq(resolve_hostname_id(0x22334455, "foo.bar"), 2); 39 | deinit_hostname_ids(); 40 | subtest_finished(); 41 | } 42 | 43 | int main(int argc, char **argv) { 44 | test_start(argc, argv); 45 | test_hostname_ids(); 46 | test_finished(); 47 | return 0; 48 | } 49 | 50 | -------------------------------------------------------------------------------- /tests/test_keyvaluelist.c: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #include 25 | #include 26 | #include "testbed.h" 27 | #include 28 | 29 | static void test_keyvalue(void) { 30 | subtest_start(); 31 | 32 | { 33 | long int longint = 0; 34 | char *foostring = NULL; 35 | struct keyvaluelist_def_t definition[] = { 36 | { .key = "longint", .parser = keyvalue_longint, .target = &longint }, 37 | { .key = "foostring", .parser = keyvalue_string, .target = &foostring }, 38 | { 0 }, 39 | }; 40 | test_assert_int_eq(parse_keyvalue_list("foo,longint=12345", 1, definition, NULL), 1); 41 | test_assert_int_eq(longint, 12345); 42 | test_assert_str_eq(foostring, NULL); 43 | 44 | test_assert_int_eq(parse_keyvalue_list("foo,longint=12345,longint=9", 1, definition, NULL), -1); 45 | test_assert_int_eq(parse_keyvalue_list("foo,longynt=12345", 1, definition, NULL), -1); 46 | 47 | longint = 0; 48 | foostring = NULL; 49 | test_assert_int_eq(parse_keyvalue_list("foo,foostring=bar,longint=98765", 1, definition, NULL), 2); 50 | test_assert_int_eq(longint, 98765); 51 | test_assert_str_eq(foostring, "bar"); 52 | free(foostring); 53 | 54 | longint = 0; 55 | foostring = NULL; 56 | test_assert_int_eq(parse_keyvalue_list("foo,foostring=bar,longint=28765", 0, definition, NULL), -1); 57 | test_assert_int_eq(longint, 0); 58 | test_assert_int_eq(parse_keyvalue_list("foo,foostring=bar,longint=28765", 2, definition, NULL), 1); 59 | test_assert_int_eq(longint, 28765); 60 | test_assert_int_eq(parse_keyvalue_list("", 0, definition, NULL), 0); 61 | 62 | test_assert_int_eq(parse_keyvalue_list("foo,foostring=mookoo", 2, definition, NULL), 0); 63 | test_assert_str_eq(foostring, NULL); 64 | test_assert_int_eq(parse_keyvalue_list("foo,foostring=mookoo", 1, definition, NULL), 1); 65 | test_assert_str_eq(foostring, "mookoo"); 66 | free(foostring); 67 | } 68 | 69 | subtest_finished(); 70 | } 71 | 72 | int main(int argc, char **argv) { 73 | test_start(argc, argv); 74 | test_keyvalue(); 75 | test_finished(); 76 | return 0; 77 | } 78 | 79 | -------------------------------------------------------------------------------- /tests/test_map.c: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #include 25 | #include "testbed.h" 26 | #include 27 | 28 | static void test_map_create_free(void) { 29 | subtest_start(); 30 | struct map_t *map = map_new(); 31 | map_free(map); 32 | subtest_finished(); 33 | } 34 | 35 | static void test_map_insert(void) { 36 | subtest_start(); 37 | struct map_t *map = map_new(); 38 | strmap_set_str(map, "foobar", "abc"); 39 | strmap_set_str(map, "barfoo", "abc"); 40 | strmap_set_str(map, "foomoo", "abc"); 41 | strmap_set_str(map, "X", "abc"); 42 | strmap_set_str(map, "Johannes", "0123"); 43 | strmap_set_str(map, "foobar", "123"); 44 | strmap_set_str(map, "foobar", "234"); 45 | strmap_set_str(map, "foobar", "345"); 46 | strmap_set_str(map, "foobar", "456"); 47 | map_free(map); 48 | subtest_finished(); 49 | } 50 | 51 | static void test_map_insert_retrieve(void) { 52 | subtest_start(); 53 | struct map_t *map = map_new(); 54 | test_assert_int_eq(map->element_count, 0); 55 | strmap_set_str(map, "key", "value"); 56 | test_assert_int_eq(map->element_count, 1); 57 | test_assert_str_eq(strmap_get_str(map, "key"), "value"); 58 | strmap_set_str(map, "key2", "new value"); 59 | test_assert_int_eq(map->element_count, 2); 60 | test_assert_str_eq(strmap_get_str(map, "key2"), "new value"); 61 | test_assert_str_eq(strmap_get_str(map, "key"), "value"); 62 | strmap_set_str(map, "key2", "other value"); 63 | test_assert_int_eq(map->element_count, 2); 64 | test_assert_str_eq(strmap_get_str(map, "key2"), "other value"); 65 | test_assert_str_eq(strmap_get_str(map, "key"), "value"); 66 | map_free(map); 67 | subtest_finished(); 68 | } 69 | 70 | static void test_map_raw(void) { 71 | subtest_start(); 72 | struct map_t *map = map_new(); 73 | strmap_set_ptr(map, "foobar", (void*)0x12345); 74 | strmap_set_ptr(map, "barfoo", (void*)0x23456); 75 | strmap_set_ptr(map, "foobar", (void*)0x34567); 76 | map_free(map); 77 | subtest_finished(); 78 | } 79 | 80 | static void test_map_int(void) { 81 | subtest_start(); 82 | struct map_t *map = map_new(); 83 | strmap_set_int(map, "foobar", 0x11111); 84 | test_assert_int_eq(strmap_get_int(map, "foobar"), 0x11111); 85 | test_assert_int_eq(strmap_get_int(map, "foobar2"), -1); 86 | test_assert_int_eq(strmap_get_int(map, "barfoo"), -1); 87 | strmap_set_int(map, "barfoo", 0x22222); 88 | test_assert_int_eq(strmap_get_int(map, "foobar"), 0x11111); 89 | test_assert_int_eq(strmap_get_int(map, "foobar2"), -1); 90 | test_assert_int_eq(strmap_get_int(map, "barfoo"), 0x22222); 91 | map_dump(map); 92 | map_free(map); 93 | subtest_finished(); 94 | } 95 | 96 | int main(int argc, char **argv) { 97 | test_start(argc, argv); 98 | test_map_create_free(); 99 | test_map_insert(); 100 | test_map_insert_retrieve(); 101 | test_map_raw(); 102 | test_map_int(); 103 | test_finished(); 104 | return 0; 105 | } 106 | -------------------------------------------------------------------------------- /tests/test_ocsp.c: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #include 25 | #include "testbed.h" 26 | #include 27 | #include 28 | #include 29 | 30 | static void test_ocsp(void) { 31 | subtest_start(); 32 | openssl_init(); 33 | 34 | X509 *cert = openssl_load_cert("local.crt", "root", false); 35 | EVP_PKEY *key = openssl_load_key("local.key", "root", false); 36 | test_assert(cert); 37 | test_assert(key); 38 | 39 | OCSP_RESPONSE *response = create_ocsp_response(cert, cert, key, 14); 40 | test_assert(response); 41 | 42 | if (response) { 43 | BIO *bio = BIO_new_fp(stderr, BIO_NOCLOSE); 44 | OCSP_RESPONSE_print(bio, response, 0); 45 | fprintf(stderr, "\n"); 46 | BIO_free(bio); 47 | } 48 | 49 | EVP_PKEY_free(key); 50 | X509_free(cert); 51 | 52 | OCSP_RESPONSE_free(response); 53 | openssl_deinit(); 54 | subtest_finished(); 55 | } 56 | 57 | int main(int argc, char **argv) { 58 | test_start(argc, argv); 59 | test_ocsp(); 60 | test_finished(); 61 | return 0; 62 | } 63 | 64 | -------------------------------------------------------------------------------- /tests/test_openssl_certs.c: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #include "testbed.h" 25 | #include 26 | #include 27 | 28 | static void test_cert_generation(void) { 29 | openssl_init(); 30 | 31 | struct keyspec_t keyspec = { 32 | .description = "test", 33 | .cryptosystem = CRYPTOSYSTEM_ECC_FP, 34 | .ecc_fp = { 35 | .curve_name = "secp256r1", 36 | }, 37 | }; 38 | 39 | EVP_PKEY *key = openssl_load_stored_key(&keyspec, "local.key"); 40 | test_assert(key); 41 | 42 | struct certificatespec_t certspec = { 43 | .description = "test", 44 | .subject_pubkey = key, 45 | .issuer_privkey = key, 46 | .common_name = "Pretty self-signed cert", 47 | .is_ca_certificate = true, 48 | .validity_seconds = 10, 49 | }; 50 | X509 *crt = openssl_load_stored_certificate(&certspec, "local.crt", true, true); 51 | test_assert(crt); 52 | 53 | X509_free(crt); 54 | EVP_PKEY_free(key); 55 | 56 | openssl_deinit(); 57 | } 58 | 59 | static void test_cert_forgery(void) { 60 | openssl_init(); 61 | X509 *crt = openssl_load_cert("local.crt", "local.crt", false); 62 | test_assert(crt); 63 | 64 | struct keyspec_t keyspec = { 65 | .description = "forged key", 66 | .cryptosystem = CRYPTOSYSTEM_ECC_FP, 67 | .ecc_fp = { 68 | .curve_name = "secp256r1", 69 | }, 70 | }; 71 | EVP_PKEY *key = openssl_create_key(&keyspec); 72 | test_assert(key); 73 | // X509_print_fp(stderr, crt); 74 | 75 | X509 *forgery = forge_client_certificate(crt, key, NULL, key, true, true); 76 | test_assert(forgery); 77 | // X509_print_fp(stderr, forgery); 78 | X509_free(forgery); 79 | 80 | X509_free(crt); 81 | EVP_PKEY_free(key); 82 | openssl_deinit(); 83 | } 84 | 85 | static void test_cert_id(void) { 86 | openssl_init(); 87 | X509 *cert = openssl_load_cert("local.crt", "local.crt", false); 88 | test_assert(cert); 89 | uint8_t hashval[32] = { 0 }; 90 | const uint8_t expected_hashval[32] = { 91 | 0x6e, 0x2a, 0xed, 0x85, 0x3c, 0xe5, 0x97, 0x54, 0x64, 0x61, 0xd0, 0x51, 0xa5, 0x9f, 0xb7, 0xbb, 92 | 0x49, 0xe6, 0xca, 0x46, 0x82, 0x6f, 0x8c, 0xa2, 0x8d, 0xdf, 0xf1, 0x0d, 0x50, 0xbd, 0x1e, 0xa4 93 | }; 94 | test_assert(get_certificate_hash(hashval, cert)); 95 | test_assert(memcmp(hashval, expected_hashval, 32) == 0); 96 | X509_free(cert); 97 | openssl_deinit(); 98 | } 99 | 100 | static void test_cert_pubkey_id(void) { 101 | openssl_init(); 102 | X509 *cert = openssl_load_cert("local.crt", "local.crt", false); 103 | test_assert(cert); 104 | uint8_t hashval[32] = { 0 }; 105 | const uint8_t expected_hashval[32] = { 106 | 0x80, 0x51, 0x45, 0x0f, 0xfc, 0xa2, 0x87, 0x1d, 0x51, 0x31, 0xc8, 0x08, 0xdb, 0xff, 0x33, 0x83, 107 | 0xeb, 0x54, 0x9a, 0x44, 0xa2, 0x06, 0x5c, 0xca, 0x8e, 0x40, 0x60, 0x49, 0x64, 0x3c, 0x98, 0x48 108 | }; 109 | test_assert(get_certificate_public_key_hash(hashval, cert)); 110 | test_assert(memcmp(hashval, expected_hashval, 32) == 0); 111 | X509_free(cert); 112 | openssl_deinit(); 113 | } 114 | 115 | static void test_key_pubkey_id(void) { 116 | openssl_init(); 117 | EVP_PKEY *key = openssl_load_key("local.key", "local.key", false); 118 | test_assert(key); 119 | uint8_t hashval[32] = { 0 }; 120 | const uint8_t expected_hashval[32] = { 121 | 0x80, 0x51, 0x45, 0x0f, 0xfc, 0xa2, 0x87, 0x1d, 0x51, 0x31, 0xc8, 0x08, 0xdb, 0xff, 0x33, 0x83, 122 | 0xeb, 0x54, 0x9a, 0x44, 0xa2, 0x06, 0x5c, 0xca, 0x8e, 0x40, 0x60, 0x49, 0x64, 0x3c, 0x98, 0x48 123 | }; 124 | test_assert(get_public_key_hash(hashval, key)); 125 | test_assert(memcmp(hashval, expected_hashval, 32) == 0); 126 | EVP_PKEY_free(key); 127 | openssl_deinit(); 128 | } 129 | 130 | int main(int argc, char **argv) { 131 | test_start(argc, argv); 132 | test_cert_generation(); 133 | test_cert_forgery(); 134 | test_cert_id(); 135 | test_cert_pubkey_id(); 136 | test_key_pubkey_id(); 137 | test_finished(); 138 | return 0; 139 | } 140 | 141 | -------------------------------------------------------------------------------- /tests/test_openssl_clienthello.c: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #include "testbed.h" 25 | #include 26 | #include 27 | 28 | static const uint8_t client_hello_example[] = { 29 | 0x16, 0x03, 0x01, 0x01, 0x04, 0x01, 0x00, 0x01, 0x00, 0x03, 0x03, 0x5a, 0x0d, 0x6e, 0x1e, 0x52, 30 | 0x94, 0x1c, 0x70, 0xf4, 0xe3, 0x8e, 0x3e, 0x9d, 0x93, 0x5a, 0x7c, 0x3c, 0x73, 0x33, 0xea, 0xb9, 31 | 0xf0, 0x7e, 0x7d, 0xaa, 0x20, 0x9f, 0x95, 0xa4, 0xc3, 0x63, 0x17, 0x00, 0x00, 0x6c, 0xc0, 0x2b, 32 | 0xc0, 0x2c, 0xc0, 0x86, 0xc0, 0x87, 0xc0, 0x09, 0xc0, 0x23, 0xc0, 0x0a, 0xc0, 0x24, 0xc0, 0x72, 33 | 0xc0, 0x73, 0xc0, 0xac, 0xc0, 0xad, 0xc0, 0x08, 0xc0, 0x2f, 0xc0, 0x30, 0xc0, 0x8a, 0xc0, 0x8b, 34 | 0xc0, 0x13, 0xc0, 0x27, 0xc0, 0x14, 0xc0, 0x28, 0xc0, 0x76, 0xc0, 0x77, 0xc0, 0x12, 0x00, 0x9c, 35 | 0x00, 0x9d, 0xc0, 0x7a, 0xc0, 0x7b, 0x00, 0x2f, 0x00, 0x3c, 0x00, 0x35, 0x00, 0x3d, 0x00, 0x41, 36 | 0x00, 0xba, 0x00, 0x84, 0x00, 0xc0, 0xc0, 0x9c, 0xc0, 0x9d, 0x00, 0x0a, 0x00, 0x9e, 0x00, 0x9f, 37 | 0xc0, 0x7c, 0xc0, 0x7d, 0x00, 0x33, 0x00, 0x67, 0x00, 0x39, 0x00, 0x6b, 0x00, 0x45, 0x00, 0xbe, 38 | 0x00, 0x88, 0x00, 0xc4, 0xc0, 0x9e, 0xc0, 0x9f, 0x00, 0x16, 0x01, 0x00, 0x00, 0x6b, 0x00, 0x17, 39 | 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 40 | 0x00, 0x00, 0x0e, 0x00, 0x0c, 0x00, 0x00, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 41 | 0x74, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x0c, 0x00, 0x0a, 42 | 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00, 0x15, 0x00, 0x13, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 43 | 0x00, 0x0d, 0x00, 0x16, 0x00, 0x14, 0x04, 0x01, 0x04, 0x03, 0x05, 0x01, 0x05, 0x03, 0x06, 0x01, 44 | 0x06, 0x03, 0x03, 0x01, 0x03, 0x03, 0x02, 0x01, 0x02, 0x03, 0x00, 0x10, 0x00, 0x0b, 0x00, 0x09, 45 | 0x08, 0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31 46 | }; 47 | 48 | static void test_clienthello_parse(void) { 49 | subtest_start(); 50 | openssl_init(); 51 | 52 | struct chello_t chello; 53 | test_assert(parse_client_hello(&chello, client_hello_example, sizeof(client_hello_example))); 54 | test_assert_str_eq(chello.server_name_indication, "localhost"); 55 | free_client_hello(&chello); 56 | openssl_deinit(); 57 | subtest_finished(); 58 | } 59 | 60 | int main(int argc, char **argv) { 61 | test_start(argc, argv); 62 | test_clienthello_parse(); 63 | test_finished(); 64 | return 0; 65 | } 66 | 67 | -------------------------------------------------------------------------------- /tests/test_openssl_tls.c: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #include "testbed.h" 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | struct test_ctx_t { 37 | int sds[2]; 38 | struct atomic_t client_state, server_state; 39 | struct tls_connection_t client_conn, server_conn; 40 | struct atomic_t teardown; 41 | const uint8_t *initial_data; 42 | int initial_data_length; 43 | }; 44 | 45 | static void tls_client_thread(void *arg) { 46 | struct test_ctx_t *ctx = (struct test_ctx_t*)arg; 47 | 48 | struct tls_connection_request_t request = { 49 | .peer_fd = ctx->sds[0], 50 | .is_server = false, 51 | }; 52 | ctx->client_conn = openssl_tls_connect(&request); 53 | atomic_inc(&ctx->client_state); 54 | 55 | atomic_wait_until_value(&ctx->teardown, 1); 56 | SSL_shutdown(ctx->server_conn.ssl); 57 | SSL_free(ctx->client_conn.ssl); 58 | close(ctx->sds[0]); 59 | atomic_inc(&ctx->teardown); 60 | } 61 | 62 | static void tls_server_thread(void *arg) { 63 | struct test_ctx_t *ctx = (struct test_ctx_t*)arg; 64 | 65 | struct tls_endpoint_config_t config = { 66 | .tls_versions = TLS_VERSION_TLS12, 67 | }; 68 | struct tls_endpoint_cert_source_t certsrc = { 69 | .cert_filename = "local.crt", 70 | .key_filename = "local.key", 71 | }; 72 | test_assert(init_tls_endpoint_config(&config, "local config", &certsrc)); 73 | 74 | struct tls_connection_request_t request = { 75 | .peer_fd = ctx->sds[1], 76 | .is_server = true, 77 | .initial_peer_data = ctx->initial_data, 78 | .initial_peer_data_length = ctx->initial_data_length, 79 | .config = &config, 80 | }; 81 | 82 | ctx->server_conn = openssl_tls_connect(&request); 83 | atomic_inc(&ctx->server_state); 84 | 85 | atomic_wait_until_value(&ctx->teardown, 2); 86 | SSL_shutdown(ctx->server_conn.ssl); 87 | SSL_free(ctx->server_conn.ssl); 88 | X509_free(config.cert); 89 | EVP_PKEY_free(config.key); 90 | close(ctx->sds[1]); 91 | atomic_inc(&ctx->teardown); 92 | } 93 | 94 | static void urandom(uint8_t *data, int length) { 95 | int fd = open("/dev/urandom", O_RDONLY); 96 | test_assert(fd != -1); 97 | test_assert_int_eq(read(fd, data, length), length); 98 | close(fd); 99 | } 100 | 101 | static void ssl_check_connection(SSL *ssl_write, SSL *ssl_read) { 102 | uint8_t data[32]; 103 | urandom(data, sizeof(data)); 104 | test_assert_int_eq(SSL_write(ssl_write, data, sizeof(data)), sizeof(data)); 105 | 106 | uint8_t read_data[sizeof(data)]; 107 | test_assert_int_eq(SSL_read(ssl_read, read_data, sizeof(read_data)), sizeof(read_data)); 108 | 109 | test_assert(memcmp(data, read_data, sizeof(data)) == 0); 110 | } 111 | 112 | static void check_communication(struct test_ctx_t *ctx) { 113 | atomic_wait_until_value(&ctx->server_state, 1); 114 | atomic_wait_until_value(&ctx->client_state, 1); 115 | 116 | ssl_check_connection(ctx->server_conn.ssl, ctx->client_conn.ssl); 117 | ssl_check_connection(ctx->client_conn.ssl, ctx->server_conn.ssl); 118 | ssl_check_connection(ctx->client_conn.ssl, ctx->server_conn.ssl); 119 | ssl_check_connection(ctx->server_conn.ssl, ctx->client_conn.ssl); 120 | ssl_check_connection(ctx->server_conn.ssl, ctx->client_conn.ssl); 121 | 122 | atomic_inc(&ctx->teardown); 123 | atomic_wait_until_value(&ctx->teardown, 3); 124 | } 125 | 126 | static void test_tls_direct(void) { 127 | subtest_start(); 128 | 129 | struct test_ctx_t test_ctx = { 0 }; 130 | atomic_init(&test_ctx.client_state); 131 | atomic_init(&test_ctx.server_state); 132 | atomic_init(&test_ctx.teardown); 133 | test_assert(socketpair(AF_LOCAL, SOCK_STREAM, 0, test_ctx.sds) == 0); 134 | 135 | /* Fire up client first */ 136 | start_detached_thread(tls_client_thread, &test_ctx); 137 | 138 | /* Then the server */ 139 | start_detached_thread(tls_server_thread, &test_ctx); 140 | 141 | check_communication(&test_ctx); 142 | subtest_finished(); 143 | } 144 | 145 | static void test_tls_initial_data(void) { 146 | subtest_start(); 147 | 148 | struct test_ctx_t test_ctx; 149 | atomic_init(&test_ctx.client_state); 150 | atomic_init(&test_ctx.server_state); 151 | atomic_init(&test_ctx.teardown); 152 | test_assert(socketpair(AF_LOCAL, SOCK_STREAM, 0, test_ctx.sds) == 0); 153 | 154 | /* Fire up client first */ 155 | start_detached_thread(tls_client_thread, &test_ctx); 156 | 157 | /* Read out data from client. */ 158 | uint8_t initial_data[1024]; 159 | ssize_t length_read = read(test_ctx.sds[1], initial_data, sizeof(initial_data)); 160 | test_assert(length_read > 0); 161 | 162 | test_ctx.initial_data = initial_data; 163 | test_ctx.initial_data_length = length_read; 164 | 165 | /* Then the server */ 166 | start_detached_thread(tls_server_thread, &test_ctx); 167 | 168 | check_communication(&test_ctx); 169 | subtest_finished(); 170 | } 171 | 172 | int main(int argc, char **argv) { 173 | test_start(argc, argv); 174 | test_tls_direct(); 175 | test_tls_initial_data(); 176 | test_finished(); 177 | return 0; 178 | } 179 | -------------------------------------------------------------------------------- /tests/test_parse.c: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #include "testbed.h" 25 | #include 26 | #include 27 | 28 | static void test_parse_ip(void) { 29 | subtest_start(); 30 | 31 | uint32_t result; 32 | test_assert(parse_ipv4("12.34.56.78", &result)); 33 | test_assert(ntohl(result) == 0x0c22384e); 34 | 35 | test_assert(parse_ipv4("170.187.204.221", &result)); 36 | test_assert(ntohl(result) == 0xaabbccdd); 37 | 38 | test_assert(parse_ipv4("0.0.0.0", &result)); 39 | test_assert(ntohl(result) == 0); 40 | 41 | test_assert(parse_ipv4("255.255.255.255", &result)); 42 | test_assert(ntohl(result) == 0xffffffff); 43 | 44 | test_fails(parse_ipv4("12.34.56.78:", &result)); 45 | test_fails(parse_ipv4("1.34.56.256", &result)); 46 | test_fails(parse_ipv4("1.34.56.", &result)); 47 | test_fails(parse_ipv4("...", &result)); 48 | test_fails(parse_ipv4("1.2.3.4:9999", &result)); 49 | subtest_finished(); 50 | } 51 | 52 | static void test_parse_ip_port(void) { 53 | subtest_start(); 54 | 55 | uint32_t result_ip; 56 | uint16_t result_port; 57 | test_assert(parse_ipv4_port("12.34.56.78:9948", &result_ip, &result_port)); 58 | subtest_finished(); 59 | } 60 | 61 | int main(int argc, char **argv) { 62 | test_start(argc, argv); 63 | test_parse_ip(); 64 | test_parse_ip_port(); 65 | test_finished(); 66 | return 0; 67 | } 68 | 69 | -------------------------------------------------------------------------------- /tests/test_pcapng.c: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #include "testbed.h" 25 | #include 26 | 27 | #define TEST_FILENAME "test.pcapng" 28 | 29 | static void test_pcapng_simple(void) { 30 | subtest_start(); 31 | FILE *f = fopen(TEST_FILENAME, "w"); 32 | test_assert(f); 33 | test_assert(pcapng_write_shb(f, NULL)); 34 | test_assert(pcapng_write_idb(f, LINKTYPE_RAW, 65535, "eth0", "My network interface")); 35 | uint32_t ip = 0x11223344; 36 | test_assert(pcapng_write_nrb(f, &ip, "www.foobar.com", true)); 37 | test_assert(pcapng_write_epb(f, (const uint8_t*)"foobar packet", 5, "my comment")); 38 | fclose(f); 39 | subtest_finished(); 40 | } 41 | 42 | int main(int argc, char **argv) { 43 | test_start(argc, argv); 44 | test_pcapng_simple(); 45 | test_finished(); 46 | return 0; 47 | } 48 | 49 | -------------------------------------------------------------------------------- /tests/test_stringlist.c: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #include "testbed.h" 25 | #include 26 | 27 | static void test_stringlist(void) { 28 | subtest_start(); 29 | 30 | struct stringlist_t list; 31 | parse_stringlist(&list, "foo:bar:koo", ":"); 32 | test_assert_int_eq(list.token_cnt, 3); 33 | test_assert_str_eq(list.tokens[0], "foo"); 34 | test_assert_str_eq(list.tokens[1], "bar"); 35 | test_assert_str_eq(list.tokens[2], "koo"); 36 | free_stringlist(&list); 37 | 38 | parse_stringlist(&list, "foo:bar:koo", ","); 39 | test_assert_int_eq(list.token_cnt, 1); 40 | test_assert_str_eq(list.tokens[0], "foo:bar:koo"); 41 | free_stringlist(&list); 42 | 43 | parse_stringlist(&list, "", ","); 44 | test_assert_int_eq(list.token_cnt, 0); 45 | free_stringlist(&list); 46 | 47 | subtest_finished(); 48 | } 49 | 50 | int main(int argc, char **argv) { 51 | test_start(argc, argv); 52 | test_stringlist(); 53 | test_finished(); 54 | return 0; 55 | } 56 | 57 | -------------------------------------------------------------------------------- /tests/test_tcpip.c: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #include "testbed.h" 25 | #include 26 | #include 27 | #include 28 | 29 | static void test_tcpip(void) { 30 | subtest_start(); 31 | struct multithread_dumper_t dumper; 32 | test_assert(open_pcap_write(&dumper, "tcpip.pcapng", NULL)); 33 | 34 | { 35 | struct connection_t conn = { 36 | .connector = { 37 | .ip_nbo = htonl(IPv4ADDR(1, 2, 3, 4)), 38 | .port_nbo = htons(2000), 39 | }, 40 | .acceptor = { 41 | .ip_nbo = htonl(IPv4ADDR(11, 22, 33, 44)), 42 | .port_nbo = htons(80), 43 | }, 44 | }; 45 | create_tcp_ip_connection(&dumper, &conn, "IPv4 without hostnames", false); 46 | append_tcp_ip_string(&conn, true, "foobar\n"); 47 | append_tcp_ip_string(&conn, false, "moep!!\n"); 48 | append_tcp_ip_string(&conn, true, "foobar?\n"); 49 | append_tcp_ip_string(&conn, false, "moep!! troet.\n"); 50 | teardown_tcp_ip_connection(&conn, true); 51 | } 52 | { 53 | struct connection_t conn = { 54 | .connector = { 55 | .ip_nbo = htonl(IPv4ADDR(1, 2, 3, 4)), 56 | .port_nbo = htons(2001), 57 | .hostname = "ipv4.smally", 58 | }, 59 | .acceptor = { 60 | .ip_nbo = htonl(IPv4ADDR(11, 22, 33, 44)), 61 | .port_nbo = htons(80), 62 | .hostname = "ipv4.large", 63 | }, 64 | }; 65 | create_tcp_ip_connection(&dumper, &conn, "IPv4 without hostnames", false); 66 | append_tcp_ip_string(&conn, true, "foobar\n"); 67 | append_tcp_ip_string(&conn, false, "moep!!\n"); 68 | append_tcp_ip_string(&conn, true, "foobar?\n"); 69 | append_tcp_ip_string(&conn, false, "moep!! troet.\n"); 70 | teardown_tcp_ip_connection(&conn, true); 71 | } 72 | { 73 | struct connection_t conn = { 74 | .connector = { 75 | .ip_nbo = htonl(IPv4ADDR(1, 2, 3, 4)), 76 | .port_nbo = htons(2002), 77 | .hostname = "kleine.zahlen", 78 | .hostname_id = 1234, 79 | }, 80 | .acceptor = { 81 | .ip_nbo = htonl(IPv4ADDR(11, 22, 33, 44)), 82 | .port_nbo = htons(80), 83 | .hostname = "grosse.zahlen", 84 | .hostname_id = 987, 85 | }, 86 | }; 87 | create_tcp_ip_connection(&dumper, &conn, "IPv6 with hostname records", true); 88 | append_tcp_ip_string(&conn, true, "foobar\n"); 89 | append_tcp_ip_string(&conn, false, "moep!!\n"); 90 | teardown_tcp_ip_connection(&conn, true); 91 | } 92 | { 93 | struct connection_t conn = { 94 | .connector = { 95 | .ip_nbo = htonl(IPv4ADDR(1, 2, 3, 4)), 96 | .port_nbo = htons(2003), 97 | .hostname = "neue.kleine.zahlen", 98 | .hostname_id = 1235, 99 | }, 100 | .acceptor = { 101 | .ip_nbo = htonl(IPv4ADDR(11, 22, 33, 44)), 102 | .port_nbo = htons(80), 103 | .hostname = "neue.grosse.zahlen", 104 | .hostname_id = 988, 105 | }, 106 | }; 107 | create_tcp_ip_connection(&dumper, &conn, "IPv6 with different hostname records", true); 108 | append_tcp_ip_string(&conn, true, "foobar\n"); 109 | append_tcp_ip_string(&conn, false, "moep!!\n"); 110 | teardown_tcp_ip_connection(&conn, true); 111 | } 112 | { 113 | struct connection_t conn = { 114 | .connector = { 115 | .ip_nbo = htonl(IPv4ADDR(1, 2, 3, 4)), 116 | .port_nbo = htons(2004), 117 | }, 118 | .acceptor = { 119 | .ip_nbo = htonl(IPv4ADDR(11, 22, 33, 44)), 120 | .port_nbo = htons(80), 121 | }, 122 | }; 123 | create_tcp_ip_connection(&dumper, &conn, "IPv6 without hostnames", true); 124 | append_tcp_ip_string(&conn, true, "foobar\n"); 125 | append_tcp_ip_string(&conn, false, "moep!!\n"); 126 | teardown_tcp_ip_connection(&conn, true); 127 | } 128 | close_pcap(&dumper); 129 | subtest_finished(); 130 | } 131 | 132 | int main(int argc, char **argv) { 133 | test_start(argc, argv); 134 | test_tcpip(); 135 | test_finished(); 136 | return 0; 137 | } 138 | 139 | -------------------------------------------------------------------------------- /tests/test_tools.c: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #include 25 | #include "testbed.h" 26 | #include 27 | 28 | static void test_strxcat(void) { 29 | subtest_start(); 30 | { 31 | char buf[3]; 32 | memset(buf, 0, sizeof(buf)); 33 | test_assert(strxcat(buf, sizeof(buf), "xy", NULL)); 34 | test_assert_str_eq(buf, "xy"); 35 | } 36 | { 37 | char buf[3]; 38 | memset(buf, 0, sizeof(buf)); 39 | test_fails(strxcat(buf, sizeof(buf), "xyz", NULL)); 40 | test_assert_str_eq(buf, "xy"); 41 | } 42 | { 43 | char buf[7]; 44 | memset(buf, 0, sizeof(buf)); 45 | test_assert(strxcat(buf, sizeof(buf), "x", "y", "z", "abc", NULL)); 46 | test_assert_str_eq(buf, "xyzabc"); 47 | } 48 | subtest_finished(); 49 | } 50 | 51 | static bool path_callback(const char *path, void *arg) { 52 | fprintf(stderr, "CALLBACK '%s'\n", path); 53 | return true; 54 | } 55 | 56 | static void test_pathtok(void) { 57 | subtest_start(); 58 | pathtok("/foo/bar/moo/koo", path_callback, NULL); 59 | pathtok("foo/bar/moo/koo", path_callback, NULL); 60 | pathtok("foo", path_callback, NULL); 61 | pathtok("foo/////bar", path_callback, NULL); 62 | subtest_finished(); 63 | } 64 | 65 | static void test_spnprintf(void) { 66 | subtest_start(); 67 | char foo[8]; 68 | char *buf = foo; 69 | int len = 8; 70 | buf = spnprintf(buf, &len, "foo"); 71 | test_assert_str_eq(foo, "foo"); 72 | buf = spnprintf(buf, &len, "b"); 73 | test_assert_str_eq(foo, "foob"); 74 | buf = spnprintf(buf, &len, "a"); 75 | test_assert_str_eq(foo, "fooba"); 76 | buf = spnprintf(buf, &len, "r"); 77 | test_assert_str_eq(foo, "foobar"); 78 | buf = spnprintf(buf, &len, "123456"); 79 | test_assert_str_eq(foo, "foobar1"); 80 | buf = spnprintf(buf, &len, "XXXXXXXX"); 81 | test_assert_str_eq(foo, "foobar1"); 82 | subtest_finished(); 83 | } 84 | 85 | int main(int argc, char **argv) { 86 | test_start(argc, argv); 87 | test_strxcat(); 88 | test_pathtok(); 89 | test_spnprintf(); 90 | test_finished(); 91 | return 0; 92 | } 93 | 94 | -------------------------------------------------------------------------------- /tests/testbed.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #ifndef __TESTBED_H__ 25 | #define __TESTBED_H__ 26 | 27 | #include 28 | #include 29 | 30 | typedef char* (*failfnc_t)(const void *lhs, const void *rhs); 31 | 32 | #define test_fail_if(cond) if (cond) test_fail(__FILE__, __LINE__, __FUNCTION__, #cond " was true") 33 | #define test_fail_unless(cond) if (!(cond)) test_fail(__FILE__, __LINE__, __FUNCTION__, #cond " was false") 34 | #define test_assert(cond) test_fail_unless(cond) 35 | #define test_fails(cond) test_assert(!(cond)) 36 | #define test_assert_str_eq(a, b) { const char *_a = (a); const char *_b = (b); if (((_a && _b) && strcmp(_a, _b)) || ((!_a || !_b) && (_a != _b))) test_fail_ext(__FILE__, __LINE__, __FUNCTION__, #a " != " #b, testbed_failfnc_str, _a, _b); } 37 | #define test_assert_int_eq(a, b) { int _a = (a); int _b = (b); if (_a != _b) test_fail_ext(__FILE__, __LINE__, __FUNCTION__, #a " != " #b, testbed_failfnc_int, &_a, &_b); } 38 | #define test_assert_int_almost_eq(a, b, m) { int _a = (a); int _b = (b); int _m = (m); if ((_a < _b - _m) || (_a > _b + _m)) test_fail_ext(__FILE__, __LINE__, __FUNCTION__, #a " !≈ " #b " with error margin " #m, testbed_failfnc_int, &_a, &_b); } 39 | 40 | #define subtest_start() subtest_start_specific(__FUNCTION__) 41 | #define subtest_finished() subtest_finish_specific(__FUNCTION__) 42 | 43 | /*************** AUTO GENERATED SECTION FOLLOWS ***************/ 44 | bool test_verbose(void); 45 | void debug(const char *msg, ...); 46 | void subtest_start_specific(const char *testname); 47 | void subtest_finish_specific(const char *testname); 48 | void test_start(int argc, char **argv); 49 | void test_success(void); 50 | void test_fail_ext(const char *file, int line, const char *fncname, const char *reason, failfnc_t failfnc, const void *lhs, const void *rhs); 51 | void test_finished(void); 52 | void test_fail(const char *file, int line, const char *fncname, const char *reason); 53 | char *testbed_failfnc_int(const void *vlhs, const void *vrhs); 54 | char *testbed_failfnc_str(const void *vlhs, const void *vrhs); 55 | /*************** AUTO GENERATED SECTION ENDS ***************/ 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /thread.c: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #include 25 | #include "thread.h" 26 | 27 | bool start_detached_thread(void (*thread_fnc)(void*), void *argument) { 28 | pthread_t thread; 29 | pthread_attr_t thread_attrs; 30 | pthread_attr_init(&thread_attrs); 31 | pthread_attr_setdetachstate(&thread_attrs, PTHREAD_CREATE_DETACHED); 32 | return pthread_create(&thread, &thread_attrs, (void* (*)(void*))thread_fnc, argument) == 0; 33 | } 34 | -------------------------------------------------------------------------------- /thread.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #ifndef __THREAD_H__ 25 | #define __THREAD_H__ 26 | 27 | #include 28 | 29 | /*************** AUTO GENERATED SECTION FOLLOWS ***************/ 30 | bool start_detached_thread(void (*thread_fnc)(void*), void *argument); 31 | /*************** AUTO GENERATED SECTION ENDS ***************/ 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /tools.c: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include "logging.h" 31 | #include "tools.h" 32 | 33 | bool select_read(int fd, double timeout_secs) { 34 | fd_set read_fds; 35 | FD_ZERO(&read_fds); 36 | FD_SET(fd, &read_fds); 37 | 38 | int usecs = (int)(timeout_secs * 1e6); 39 | struct timeval timeout = { 40 | .tv_sec = usecs / 1000000, 41 | .tv_usec = usecs % 1000000, 42 | }; 43 | int result = select(fd + 1, &read_fds, NULL, NULL, &timeout); 44 | if (result == -1) { 45 | logmsg(LLVL_ERROR, "select(2) of FD %d failed: %s", fd, strerror(errno)); 46 | } 47 | return result == 1; 48 | } 49 | 50 | bool pathtok(const char *path, bool (*callback)(const char *path, void *arg), void *arg) { 51 | char *strcopy = strdup(path); 52 | if (!strcopy) { 53 | logmsg(LLVL_ERROR, "Unable to strdup(3) path: %s", strerror(errno)); 54 | return false; 55 | } 56 | 57 | bool success = true; 58 | char *origstring = strcopy; 59 | char *string = strcopy; 60 | char *saveptr = NULL; 61 | char *next; 62 | while ((next = strtok_r(string, "/", &saveptr)) != NULL) { 63 | if (!string) { 64 | /* This is not the first run, restore last '/' */ 65 | next[-1] = '/'; 66 | } 67 | if (!callback(origstring, arg)) { 68 | success = false; 69 | break; 70 | } 71 | string = NULL; 72 | } 73 | 74 | free(origstring); 75 | return success; 76 | } 77 | 78 | static bool mkdir_callback(const char *path, void *arg) { 79 | if (mkdir(path, 0700) == -1) { 80 | /* Ignore error if already exists */ 81 | if (errno == EEXIST) { 82 | return true; 83 | } 84 | 85 | /* Otherwise, abort. */ 86 | logmsg(LLVL_ERROR, "mkdir(2) of %s failed: %s", path, strerror(errno)); 87 | return false; 88 | } 89 | return true; 90 | } 91 | 92 | bool makedirs(const char *path) { 93 | return pathtok(path, mkdir_callback, NULL); 94 | } 95 | 96 | bool strxcat(char *dest, int bufsize, ...) { 97 | if (bufsize < 1) { 98 | return false; 99 | } 100 | 101 | /* Reserve at least one byte for zero-termination */ 102 | bufsize--; 103 | 104 | bool success = true; 105 | va_list ap; 106 | va_start(ap, bufsize); 107 | const char *next_string; 108 | while ((next_string = va_arg(ap, const char*)) != NULL) { 109 | for (int i = 0; next_string[i]; i++) { 110 | if (bufsize == 0) { 111 | success = false; 112 | break; 113 | } 114 | *dest = next_string[i]; 115 | dest++; 116 | bufsize--; 117 | } 118 | } 119 | *dest = 0; 120 | va_end(ap); 121 | return success; 122 | } 123 | 124 | char *spnprintf(char *buf, int *size, const char *fmt, ...) { 125 | if (*size <= 0) { 126 | return buf; 127 | } 128 | 129 | va_list ap; 130 | va_start(ap, fmt); 131 | int chars = vsnprintf(buf, *size, fmt, ap); 132 | va_end(ap); 133 | 134 | if (chars > *size) { 135 | chars = *size; 136 | } 137 | *size -= chars; 138 | return buf + chars; 139 | } 140 | 141 | -------------------------------------------------------------------------------- /tools.h: -------------------------------------------------------------------------------- 1 | /** 2 | * ratched - TLS connection router that performs a man-in-the-middle attack 3 | * Copyright (C) 2017-2017 Johannes Bauer 4 | * 5 | * This file is part of ratched. 6 | * 7 | * ratched is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; this program is ONLY licensed under 10 | * version 3 of the License, later versions are explicitly excluded. 11 | * 12 | * ratched is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with ratched; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Johannes Bauer 22 | **/ 23 | 24 | #ifndef __TOOLS_H__ 25 | #define __TOOLS_H__ 26 | 27 | #include 28 | 29 | /*************** AUTO GENERATED SECTION FOLLOWS ***************/ 30 | bool select_read(int fd, double timeout_secs); 31 | bool pathtok(const char *path, bool (*callback)(const char *path, void *arg), void *arg); 32 | bool makedirs(const char *path); 33 | bool strxcat(char *dest, int bufsize, ...); 34 | char *spnprintf(char *buf, int *size, const char *fmt, ...); 35 | /*************** AUTO GENERATED SECTION ENDS ***************/ 36 | 37 | #endif 38 | --------------------------------------------------------------------------------