From bcbe9eb58e3f3b2e22c2bbd527978ca52a6ffea9 Mon Sep 17 00:00:00 2001 From: Michael Ortmann <41313082+michaelortmann@users.noreply.github.com> Date: Sat, 8 Mar 2025 03:29:56 +0100 Subject: [PATCH 1/4] WIP --- eggdrop.conf | 2 ++ src/eggdrop.h | 3 +++ src/mod/server.mod/server.c | 6 ++++++ src/mod/server.mod/server.h | 2 +- src/mod/server.mod/servmsg.c | 13 +++++++++---- src/tls.c | 34 ++++++++++++++++++++++++++++++---- 6 files changed, 51 insertions(+), 9 deletions(-) diff --git a/eggdrop.conf b/eggdrop.conf index 93ea11253..0f3f2cd47 100755 --- a/eggdrop.conf +++ b/eggdrop.conf @@ -1081,6 +1081,8 @@ server add you.need.to.change.this 6667 server add another.example.com 6669 password server add 2001:db8:618:5c0:263:: 6669 password server add ssl.example.net +7000 +# For tls ports the servers public key sha256 fingerprint can be pinned: +server add example.org +6697,55:88:55:88:55:88:55:88:55:88:55:88:55:88:55:88:55:88:55:88:55:88:55:88:55:88:55:88:55:88:55:88 #### CAP Features #### # This section controls IRCv3 capabilities supported natively by Eggdrop. You diff --git a/src/eggdrop.h b/src/eggdrop.h index 393de019d..1f16a70c9 100644 --- a/src/eggdrop.h +++ b/src/eggdrop.h @@ -352,6 +352,9 @@ struct dcc_t { struct dupwait_info *dupwait; int ident_sock; void *other; +#ifdef TLS + char *fingerprint; +#endif } u; /* Special use depending on type */ }; diff --git a/src/mod/server.mod/server.c b/src/mod/server.mod/server.c index bef2628a1..bf32c84b2 100644 --- a/src/mod/server.mod/server.c +++ b/src/mod/server.mod/server.c @@ -1040,6 +1040,12 @@ static int add_server(const char *name, const char *port, const char *pass) x->port = atoi(port); #ifdef TLS x->ssl = (port[0] == '+') ? 1 : 0; + char *fingerprint; + if (x->ssl && (fingerprint = strchr(port + 1, ',')) && fingerprint[1]) { + x->fingerprint = nmalloc(strlen(fingerprint) + 1); + strcpy(x->fingerprint, fingerprint + 1); + } else + x->fingerprint = NULL; #endif return 0; } diff --git a/src/mod/server.mod/server.h b/src/mod/server.mod/server.h index 19837ccc2..7c1789ddd 100644 --- a/src/mod/server.mod/server.h +++ b/src/mod/server.mod/server.h @@ -109,11 +109,11 @@ struct server_list { struct server_list *next; - char *name; int port; #ifdef TLS int ssl; + char *fingerprint; #endif char *pass; char *realname; diff --git a/src/mod/server.mod/servmsg.c b/src/mod/server.mod/servmsg.c index 63efe8fe9..f0237a953 100644 --- a/src/mod/server.mod/servmsg.c +++ b/src/mod/server.mod/servmsg.c @@ -1966,20 +1966,20 @@ static void connect_server(void) #ifdef IPV6 if (inet_pton(AF_INET6, botserver, buf)) { - len += egg_snprintf(s, sizeof s, "%s [%s]", IRC_SERVERTRY, botserver); + len += snprintf(s, sizeof s, "%s [%s]", IRC_SERVERTRY, botserver); } else { #endif - len += egg_snprintf(s, sizeof s, "%s %s", IRC_SERVERTRY, botserver); + len += snprintf(s, sizeof s, "%s %s", IRC_SERVERTRY, botserver); #ifdef IPV6 } #endif #ifdef TLS - len += egg_snprintf(s + len, sizeof s - len, ":%s%d", + len += snprintf(s + len, sizeof s - len, ":%s%d", use_ssl ? "+" : "", botserverport); dcc[servidx].ssl = use_ssl; #else - len += egg_snprintf(s + len, sizeof s - len, ":%d", botserverport); + len += snprintf(s + len, sizeof s - len, ":%d", botserverport); #endif putlog(LOG_SERV, "*", "%s", s); dcc[servidx].port = botserverport; @@ -2003,6 +2003,11 @@ static void connect_server(void) dcc[servidx].u.dns->dns_type = RES_IPBYHOST; dcc[servidx].u.dns->type = &SERVER_SOCKET; dcc[servidx].status |= STAT_SERV; +#ifdef TLS + printf("DEBUG: here fingerprint needs to be set to dcc_t entry, so, that tls.c:ssl_info()->sock->dcc->fingerprint can be used, not implemented yet\n"); + // if (fingerprint) + // dcc[servidx].u.fingerprint = fingerprint; +#endif if (server_cycle_wait) /* Back to 1st server & set wait time. diff --git a/src/tls.c b/src/tls.c index d3af0c6ea..4f52f1841 100644 --- a/src/tls.c +++ b/src/tls.c @@ -648,7 +648,7 @@ static void ssl_showcert(X509 *cert, const int loglev) } else putlog(loglev, "*", "TLS: cannot get issuer name from certificate!"); - /* Fingerprints */ + /* Certificate fingerprints */ if (X509_digest(cert, EVP_sha1(), md, &len)) { buf = OPENSSL_buf2hexstr(md, len); putlog(loglev, "*", "TLS: certificate SHA1 Fingerprint: %s", buf); @@ -656,17 +656,23 @@ static void ssl_showcert(X509 *cert, const int loglev) } if (X509_digest(cert, EVP_sha256(), md, &len)) { buf = OPENSSL_buf2hexstr(md, len); - putlog(loglev, "*", "TLS: certificate SHA-256 Fingerprint: %s", buf); + putlog(loglev, "*", "TLS: certificate SHA256 Fingerprint: %s", buf); OPENSSL_free(buf); } - /* Validity time */ from = ssl_printtime(X509_get_notBefore(cert)); to = ssl_printtime(X509_get_notAfter(cert)); putlog(loglev, "*", "TLS: certificate valid from %s to %s", from, to); nfree(from); nfree(to); + + /* Public key fingerprint */ + if (X509_pubkey_digest(cert, EVP_sha256(), md, &len)) { + buf = OPENSSL_buf2hexstr(md, len); + putlog(loglev, "*", "TLS: public key SHA256 Fingerprint: %s", buf); + OPENSSL_free(buf); + } } /* Certificate validation callback @@ -768,6 +774,24 @@ static void ssl_info(const SSL *ssl, int where, int ret) /* Callback for completed handshake. Cheaper and more convenient than using H_tls */ sock = SSL_get_fd(ssl); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + cert = SSL_get0_peer_certificate(ssl); +#else + cert = SSL_get_peer_certificate(ssl); +#endif + + /* Verify public key fingerprint */ + int idx = findanyidx(sock); + if (dcc[idx].u.fingerprint) { + unsigned char md[EVP_MAX_MD_SIZE]; + unsigned int len; + if (X509_pubkey_digest(cert, EVP_sha256(), md, &len)) { + char *fingerprint2 = OPENSSL_buf2hexstr(md, len); + OPENSSL_free(fingerprint2); + } + printf("DEBUG: Verifying public key fingerprint not implemented yet: %s\n", dcc[idx].u.fingerprint); + } + if (data->cb) data->cb(sock); /* Call TLS binds. We allow scripts to take over or disable displaying of @@ -778,9 +802,11 @@ static void ssl_info(const SSL *ssl, int where, int ret) putlog(data->loglevel, "*", "TLS: handshake successful. Secure connection " "established."); - if ((cert = SSL_get_peer_certificate(ssl))) { + if (cert) { ssl_showcert(cert, LOG_DEBUG); +#if OPENSSL_VERSION_NUMBER < 0x30000000L X509_free(cert); +#endif } else putlog(data->loglevel, "*", "TLS: peer did not present a certificate"); From 8c90473e4411307efc478c5c33a303594cbfc880 Mon Sep 17 00:00:00 2001 From: Michael Ortmann <41313082+michaelortmann@users.noreply.github.com> Date: Sat, 8 Mar 2025 03:47:22 +0100 Subject: [PATCH 2/4] Fix format specifier --- src/mod/server.mod/servmsg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/server.mod/servmsg.c b/src/mod/server.mod/servmsg.c index f0237a953..2f23ea4b1 100644 --- a/src/mod/server.mod/servmsg.c +++ b/src/mod/server.mod/servmsg.c @@ -1975,11 +1975,11 @@ static void connect_server(void) #endif #ifdef TLS - len += snprintf(s + len, sizeof s - len, ":%s%d", + len += snprintf(s + len, sizeof s - len, ":%s%u", use_ssl ? "+" : "", botserverport); dcc[servidx].ssl = use_ssl; #else - len += snprintf(s + len, sizeof s - len, ":%d", botserverport); + len += snprintf(s + len, sizeof s - len, ":%u", botserverport); #endif putlog(LOG_SERV, "*", "%s", s); dcc[servidx].port = botserverport; From 9ce75873dfb643a48785d0b6f2095e1b3be957dd Mon Sep 17 00:00:00 2001 From: Michael Ortmann <41313082+michaelortmann@users.noreply.github.com> Date: Sat, 8 Mar 2025 22:02:15 +0100 Subject: [PATCH 3/4] compare fingerprints. is this the right place to shutdown the conection? --- src/tls.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/tls.c b/src/tls.c index 469b23264..be5d7bb70 100644 --- a/src/tls.c +++ b/src/tls.c @@ -790,6 +790,11 @@ static void ssl_info(const SSL *ssl, int where, int ret) OPENSSL_free(fingerprint2); } printf("DEBUG: Verifying public key fingerprint not implemented yet: %s\n", dcc[idx].u.fingerprint); + // if (crypto_verify(fingerprint, fingerprint2)); /* verify not successful */ + // MAYBE THIS IS NOT THE RIGHT PLACE AT ALL TO VERIFY AND/OR SHUTDOWN THEN connection + // MAYBE WE NEED TO DO IT AT A LATER POINT? BUT WE WANT MOST LOGIC / PROCEEDIGN TO STOP HERE ALREADY + // SSL_shutdown(ssl); + // close(sock); } if (data->cb) From 01f00c016ef65977905b738e3dcf50bfc705849f Mon Sep 17 00:00:00 2001 From: Michael Ortmann <41313082+michaelortmann@users.noreply.github.com> Date: Sat, 8 Mar 2025 22:03:51 +0100 Subject: [PATCH 4/4] indent --- src/mod/server.mod/servmsg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/server.mod/servmsg.c b/src/mod/server.mod/servmsg.c index 2f23ea4b1..aabe63529 100644 --- a/src/mod/server.mod/servmsg.c +++ b/src/mod/server.mod/servmsg.c @@ -1975,8 +1975,8 @@ static void connect_server(void) #endif #ifdef TLS - len += snprintf(s + len, sizeof s - len, ":%s%u", - use_ssl ? "+" : "", botserverport); + len += snprintf(s + len, sizeof s - len, ":%s%u", use_ssl ? "+" : "", + botserverport); dcc[servidx].ssl = use_ssl; #else len += snprintf(s + len, sizeof s - len, ":%u", botserverport);