]> ruderich.org/simon Gitweb - tlsproxy/tlsproxy.git/blobdiff - src/tlsproxy.c
Intercept TLS connections between client and server.
[tlsproxy/tlsproxy.git] / src / tlsproxy.c
index 2a35eaefc6b45e3d4e6b35a62c32d5a8407a8aac..0e095689374b7cae7e4ce51546491d1e9ade25d4 100644 (file)
 /* pthread_*() */
 #include <pthread.h>
 
+/* For GnuTLS. */
+#include <gcrypt.h>
+
+GCRY_THREAD_OPTION_PTHREAD_IMPL;
+
+
 /* Size of ringbuffer. */
 #define RINGBUFFER_SIZE 10
 
+/* Bit size of Diffie-Hellman key exchange parameters. */
+#define DH_SIZE 1024
+
 
 /* Server should shut down. Set by SIGINT handler. */
 static volatile int done;
 
 /* Number of threads. */
 static size_t thread_count;
+
 /* Synchronized ring buffer storing accept()ed client sockets. */
 static int ringbuffer[RINGBUFFER_SIZE];
 static int ringbuffer_read;
@@ -58,6 +68,9 @@ static void sigint_handler(int signal);
 static void parse_arguments(int argc, char **argv);
 static void print_usage(const char *argv);
 
+static void initialize_gnutls(void);
+static void deinitialize_gnutls(void);
+
 static void worker_thread(void);
 
 
@@ -103,6 +116,8 @@ int main(int argc, char **argv) {
         return EXIT_FAILURE;
     }
 
+    initialize_gnutls();
+
     /* Spawn worker threads to handle requests. */
     threads = (pthread_t *)malloc(thread_count * sizeof(pthread_t));
     if (NULL == threads) {
@@ -202,6 +217,8 @@ int main(int argc, char **argv) {
 
     free(threads);
 
+    deinitialize_gnutls();
+
     free(global_proxy_host);
     free(global_proxy_port);
 
@@ -298,6 +315,46 @@ static void print_usage(const char *argv) {
     fprintf(stderr, "-t number of threads [default: 10]\n");
 }
 
+static void initialize_gnutls(void) {
+    int result;
+    gcry_error_t error = 0;
+
+    /* Thread safe setup. Must be called before gnutls_global_init(). */
+    error = gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
+    if (error) {
+        fprintf(stderr, "gcry_control(): %s/%s\n", gcry_strsource(error),
+                                                   gcry_strerror(error));
+        exit(EXIT_FAILURE);
+    }
+    /* Prevent usage of blocking /dev/random. */
+    error = gcry_control(GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+    if (error) {
+        fprintf(stderr, "gcry_control(): %s/%s\n", gcry_strsource(error),
+                                                   gcry_strerror(error));
+        exit(EXIT_FAILURE);
+    }
+
+    /* Initialize GnuTLS. */
+    result = gnutls_global_init();
+    GNUTLS_ERROR_EXIT(result, "gnutls_global_init()");
+
+    /* Setup GnuTLS cipher suites. */
+    result = gnutls_priority_init(&tls_priority_cache, "NORMAL", NULL);
+    GNUTLS_ERROR_EXIT(result, "gnutls_priority_init()");
+
+    /* Generate Diffie-Hellman parameters. */
+    result = gnutls_dh_params_init(&tls_dh_params);
+    GNUTLS_ERROR_EXIT(result, "gnutls_dh_params_init()");
+    result = gnutls_dh_params_generate2(tls_dh_params, DH_SIZE);
+    GNUTLS_ERROR_EXIT(result, "gnutls_dh_params_generate2()");
+}
+static void deinitialize_gnutls(void) {
+    gnutls_dh_params_deinit(tls_dh_params);
+    gnutls_priority_deinit(tls_priority_cache);
+
+    gnutls_global_deinit();
+}
+
 static void worker_thread(void) {
     int client_socket;