From 99d017720dd162122754bfbedc96744f4af8ce6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20F=C3=A6r=C3=B8y?= Date: Sun, 16 Oct 2016 14:07:22 +0200 Subject: [PATCH] Add TLS_REC. This patch adds the TLS_REC structure. This structure is used to emit information about the TLS handshake from the core of irssi to the front-end layers such that we can display connection information to the user. --- docs/signals.txt | 1 + src/core/Makefile.am | 2 + src/core/tls.c | 219 ++++++++++++++++++++++++++++++++++++++++ src/core/tls.h | 95 +++++++++++++++++ src/perl/get-signals.pl | 1 + 5 files changed, 318 insertions(+) create mode 100644 src/core/tls.c create mode 100644 src/core/tls.h diff --git a/docs/signals.txt b/docs/signals.txt index 5e03d901..47db3575 100644 --- a/docs/signals.txt +++ b/docs/signals.txt @@ -59,6 +59,7 @@ network-openssl.c: "tlsa available", SERVER_REC "tlsa verification success", SERVER_REC "tlsa verification failed", SERVER_REC + "tls handshake finished", SERVER_REC, TLS_REC nicklist.c: "nicklist new", CHANNEL_REC, NICK_REC diff --git a/src/core/Makefile.am b/src/core/Makefile.am index af323234..10bd035a 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -46,6 +46,7 @@ libcore_a_SOURCES = \ special-vars.c \ utf8.c \ wcwidth.c \ + tls.c \ write-buffer.c structure_headers = \ @@ -97,5 +98,6 @@ pkginc_core_HEADERS = \ special-vars.h \ utf8.h \ window-item-def.h \ + tls.h \ write-buffer.h \ $(structure_headers) diff --git a/src/core/tls.c b/src/core/tls.c new file mode 100644 index 00000000..8aad0c89 --- /dev/null +++ b/src/core/tls.c @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2015 Alexander Færøy + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301,USA + */ + +#include "module.h" + +#include "tls.h" + +TLS_REC *tls_create_rec() +{ + TLS_REC *rec = g_new0(TLS_REC, 1); + g_return_val_if_fail(rec != NULL, NULL); + + return rec; +} + +void tls_rec_free(TLS_REC *tls_rec) +{ + if (tls_rec == NULL) + return; + + g_free_and_null(tls_rec->protocol_version); + g_free_and_null(tls_rec->cipher); + g_free_and_null(tls_rec->public_key_algorithm); + g_free_and_null(tls_rec->public_key_fingerprint); + g_free_and_null(tls_rec->public_key_fingerprint_algorithm); + g_free_and_null(tls_rec->certificate_fingerprint); + g_free_and_null(tls_rec->certificate_fingerprint_algorithm); + g_free_and_null(tls_rec->not_after); + g_free_and_null(tls_rec->not_before); + +#ifdef SSL_get_server_tmp_key + g_free_and_null(tls_rec->ephemeral_key_algorithm); +#endif + + if (tls_rec->certs != NULL) { + g_slist_foreach(tls_rec->certs, (GFunc)tls_cert_rec_free, NULL); + g_slist_free(tls_rec->certs); + tls_rec->certs = NULL; + } + + g_free(tls_rec); +} + +void tls_rec_set_protocol_version(TLS_REC *tls_rec, const char *protocol_version) +{ + g_return_if_fail(tls_rec != NULL); + + tls_rec->protocol_version = g_strdup(protocol_version); +} + +void tls_rec_set_cipher(TLS_REC *tls_rec, const char *cipher) +{ + g_return_if_fail(tls_rec != NULL); + + tls_rec->cipher = g_strdup(cipher); +} + +void tls_rec_set_cipher_size(TLS_REC *tls_rec, size_t size) +{ + g_return_if_fail(tls_rec != NULL); + + tls_rec->cipher_size = size; +} + +void tls_rec_set_public_key_algorithm(TLS_REC *tls_rec, const char *algorithm) +{ + g_return_if_fail(tls_rec != NULL); + + tls_rec->public_key_algorithm = g_strdup(algorithm); +} + +void tls_rec_set_public_key_fingerprint(TLS_REC *tls_rec, const char *fingerprint) +{ + g_return_if_fail(tls_rec != NULL); + + tls_rec->public_key_fingerprint = g_strdup(fingerprint); +} + +void tls_rec_set_public_key_fingerprint_algorithm(TLS_REC *tls_rec, const char *algorithm) +{ + g_return_if_fail(tls_rec != NULL); + + tls_rec->public_key_fingerprint_algorithm = g_strdup(algorithm); +} + +void tls_rec_set_public_key_size(TLS_REC *tls_rec, size_t size) +{ + g_return_if_fail(tls_rec != NULL); + tls_rec->public_key_size = size; +} + +void tls_rec_set_certificate_fingerprint(TLS_REC *tls_rec, const char *fingerprint) +{ + g_return_if_fail(tls_rec != NULL); + + tls_rec->certificate_fingerprint = g_strdup(fingerprint); +} + +void tls_rec_set_certificate_fingerprint_algorithm(TLS_REC *tls_rec, const char *algorithm) +{ + g_return_if_fail(tls_rec != NULL); + + tls_rec->certificate_fingerprint_algorithm = g_strdup(algorithm); +} + +void tls_rec_set_not_after(TLS_REC *tls_rec, const char *not_after) +{ + g_return_if_fail(tls_rec != NULL); + tls_rec->not_after = g_strdup(not_after); +} + +void tls_rec_set_not_before(TLS_REC *tls_rec, const char *not_before) +{ + g_return_if_fail(tls_rec != NULL); + tls_rec->not_before = g_strdup(not_before); +} + +#ifdef SSL_get_server_tmp_key +void tls_rec_set_ephemeral_key_algorithm(TLS_REC *tls_rec, const char *algorithm) +{ + g_return_if_fail(tls_rec != NULL); + tls_rec->ephemeral_key_algorithm = g_strdup(algorithm); +} + +void tls_rec_set_ephemeral_key_size(TLS_REC *tls_rec, size_t size) +{ + g_return_if_fail(tls_rec != NULL); + tls_rec->ephemeral_key_size = size; +} +#endif + +void tls_rec_append_cert(TLS_REC *tls_rec, TLS_CERT_REC *tls_cert_rec) +{ + g_return_if_fail(tls_rec != NULL); + g_return_if_fail(tls_cert_rec != NULL); + + tls_rec->certs = g_slist_append(tls_rec->certs, tls_cert_rec); +} + +TLS_CERT_REC *tls_cert_create_rec() +{ + TLS_CERT_REC *rec = g_new0(TLS_CERT_REC, 1); + g_return_val_if_fail(rec != NULL, NULL); + + return rec; +} + +void tls_cert_rec_append_subject_entry(TLS_CERT_REC *tls_cert_rec, TLS_CERT_ENTRY_REC *tls_cert_entry_rec) +{ + g_return_if_fail(tls_cert_rec != NULL); + g_return_if_fail(tls_cert_entry_rec != NULL); + + tls_cert_rec->subject = g_slist_append(tls_cert_rec->subject, tls_cert_entry_rec); +} + +void tls_cert_rec_append_issuer_entry(TLS_CERT_REC *tls_cert_rec, TLS_CERT_ENTRY_REC *tls_cert_entry_rec) +{ + g_return_if_fail(tls_cert_rec != NULL); + g_return_if_fail(tls_cert_entry_rec != NULL); + + tls_cert_rec->issuer = g_slist_append(tls_cert_rec->issuer, tls_cert_entry_rec); +} + +void tls_cert_rec_free(TLS_CERT_REC *tls_cert_rec) +{ + if (tls_cert_rec == NULL) + return; + + if (tls_cert_rec->subject != NULL) { + g_slist_foreach(tls_cert_rec->subject, (GFunc)tls_cert_entry_rec_free, NULL); + g_slist_free(tls_cert_rec->subject); + tls_cert_rec->subject = NULL; + } + + if (tls_cert_rec->issuer != NULL) { + g_slist_foreach(tls_cert_rec->issuer, (GFunc)tls_cert_entry_rec_free, NULL); + g_slist_free(tls_cert_rec->issuer); + tls_cert_rec->issuer = NULL; + } + + g_free(tls_cert_rec); +} + +TLS_CERT_ENTRY_REC *tls_cert_entry_create_rec(const char *name, const char *value) +{ + TLS_CERT_ENTRY_REC *rec = g_new0(TLS_CERT_ENTRY_REC, 1); + g_return_val_if_fail(rec != NULL, NULL); + + rec->name = g_strdup(name); + rec->value = g_strdup(value); + + return rec; +} + +void tls_cert_entry_rec_free(TLS_CERT_ENTRY_REC *tls_cert_entry) +{ + if (tls_cert_entry == NULL) + return; + + g_free_and_null(tls_cert_entry->name); + g_free_and_null(tls_cert_entry->value); + + g_free(tls_cert_entry); +} diff --git a/src/core/tls.h b/src/core/tls.h new file mode 100644 index 00000000..4991f7ed --- /dev/null +++ b/src/core/tls.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2015 Alexander Færøy + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301,USA + */ + +#ifndef __TLS_H +#define __TLS_H + +#include + +#include + +typedef struct _TLS_REC TLS_REC; +typedef struct _TLS_CERT_REC TLS_CERT_REC; +typedef struct _TLS_CERT_ENTRY_REC TLS_CERT_ENTRY_REC; + +struct _TLS_REC { + char *protocol_version; + char *cipher; + size_t cipher_size; + + char *public_key_algorithm; + char *public_key_fingerprint; + char *public_key_fingerprint_algorithm; + size_t public_key_size; + + char *certificate_fingerprint; + char *certificate_fingerprint_algorithm; + + char *not_after; + char *not_before; + +#ifdef SSL_get_server_tmp_key + char *ephemeral_key_algorithm; + size_t ephemeral_key_size; +#endif + + GSList *certs; +}; + +struct _TLS_CERT_REC { + GSList *subject; + GSList *issuer; +}; + +struct _TLS_CERT_ENTRY_REC { + char *name; + char *value; +}; + +TLS_REC *tls_create_rec(); +void tls_rec_free(TLS_REC *tls_rec); + +void tls_rec_set_protocol_version(TLS_REC *tls_rec, const char *protocol_version); +void tls_rec_set_cipher(TLS_REC *tls_rec, const char *cipher); +void tls_rec_set_cipher_size(TLS_REC *tls_rec, size_t size); +void tls_rec_set_public_key_algorithm(TLS_REC *tls_rec, const char *algorithm); +void tls_rec_set_public_key_fingerprint(TLS_REC *tls_rec, const char *fingerprint); +void tls_rec_set_public_key_fingerprint_algorithm(TLS_REC *tls_rec, const char *algorithm); +void tls_rec_set_public_key_size(TLS_REC *tls_rec, size_t size); +void tls_rec_set_certificate_fingerprint(TLS_REC *tls_rec, const char *fingerprint); +void tls_rec_set_certificate_fingerprint_algorithm(TLS_REC *tls_rec, const char *algorithm); +void tls_rec_set_not_after(TLS_REC *tls_rec, const char *not_after); +void tls_rec_set_not_before(TLS_REC *tls_rec, const char *not_before); + +#ifdef SSL_get_server_tmp_key +void tls_rec_set_ephemeral_key_algorithm(TLS_REC *tls_rec, const char *algorithm); +void tls_rec_set_ephemeral_key_size(TLS_REC *tls_rec, size_t size); +#endif + +void tls_rec_append_cert(TLS_REC *tls_rec, TLS_CERT_REC *tls_cert_rec); + +TLS_CERT_REC *tls_cert_create_rec(); +void tls_cert_rec_free(TLS_CERT_REC *tls_cert_rec); + +void tls_cert_rec_append_subject_entry(TLS_CERT_REC *tls_cert_rec, TLS_CERT_ENTRY_REC *tls_cert_entry_rec); +void tls_cert_rec_append_issuer_entry(TLS_CERT_REC *tls_cert_rec, TLS_CERT_ENTRY_REC *tls_cert_entry_rec); + +TLS_CERT_ENTRY_REC *tls_cert_entry_create_rec(const char *name, const char *value); +void tls_cert_entry_rec_free(TLS_CERT_ENTRY_REC *tls_cert_entry); + +#endif diff --git a/src/perl/get-signals.pl b/src/perl/get-signals.pl index 529d35b1..806bcafa 100755 --- a/src/perl/get-signals.pl +++ b/src/perl/get-signals.pl @@ -37,6 +37,7 @@ while () { RAWLOG_REC => 'Irssi::Rawlog', IGNORE_REC => 'Irssi::Ignore', MODULE_REC => 'Irssi::Module', + TLS_REC => 'iobject', # irc BAN_REC => 'Irssi::Irc::Ban',