Retrieve and save new fingerprints from libstrophe.

This also reads the certificate SHA256 and pubkey fingerprint from
libstrophe, but doesn't store it persistently yet.

Related-to: https://github.com/profanity-im/profanity/issues/2068
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
This commit is contained in:
Steffen Jaeckel
2025-11-04 17:41:05 +01:00
parent 4dcaa839fa
commit 0acea8d0d2
5 changed files with 47 additions and 8 deletions

View File

@@ -173,6 +173,19 @@ AC_LINK_IFELSE([AC_LANG_SOURCE([[
[AC_MSG_RESULT([yes])], [AC_MSG_RESULT([yes])],
[AC_MSG_ERROR([libstrophe is broken, check config.log for details])]) [AC_MSG_ERROR([libstrophe is broken, check config.log for details])])
AC_MSG_CHECKING([whether libstrophe has XMPP_CERT_PUBKEY_FINGERPRINT_SHA256 support])
AC_LINK_IFELSE([AC_LANG_SOURCE([[
#include <strophe.h>
int main() {
xmpp_tlscert_get_string(NULL, XMPP_CERT_PUBKEY_FINGERPRINT_SHA256);
return 1;
}
]])],
[AC_MSG_RESULT([yes])
AC_DEFINE([HAVE_XMPP_CERT_PUBKEY_FINGERPRINT_SHA256], [1], [Have XMPP_CERT_PUBKEY_FINGERPRINT_SHA256])],
[AC_MSG_RESULT(no)])
## Check for curses library ## Check for curses library
PKG_CHECK_MODULES([ncursesw], [ncursesw], PKG_CHECK_MODULES([ncursesw], [ncursesw],
[NCURSES_CFLAGS="$ncursesw_CFLAGS"; NCURSES_LIBS="$ncursesw_LIBS"; CURSES="ncursesw"], [NCURSES_CFLAGS="$ncursesw_CFLAGS"; NCURSES_LIBS="$ncursesw_LIBS"; CURSES="ncursesw"],

View File

@@ -138,7 +138,7 @@ tlscerts_list(void)
auto_gchar gchar* signaturealg = g_key_file_get_string(tlscerts, fingerprint, "signaturealg", NULL); auto_gchar gchar* signaturealg = g_key_file_get_string(tlscerts, fingerprint, "signaturealg", NULL);
TLSCertificate* cert = tlscerts_new(fingerprint, version, serialnumber, subjectname, issuername, notbefore, TLSCertificate* cert = tlscerts_new(fingerprint, version, serialnumber, subjectname, issuername, notbefore,
notafter, keyalg, signaturealg, NULL); notafter, keyalg, signaturealg, NULL, NULL, NULL);
res = g_list_append(res, cert); res = g_list_append(res, cert);
} }
@@ -149,13 +149,17 @@ tlscerts_list(void)
TLSCertificate* TLSCertificate*
tlscerts_new(const char* fingerprint_sha1, int version, const char* serialnumber, const char* subjectname, tlscerts_new(const char* fingerprint_sha1, int version, const char* serialnumber, const char* subjectname,
const char* issuername, const char* notbefore, const char* notafter, const char* issuername, const char* notbefore, const char* notafter,
const char* key_alg, const char* signature_alg, const char* pem) const char* key_alg, const char* signature_alg, const char* pem,
const char* fingerprint_sha256, const char* pubkey_fingerprint)
{ {
TLSCertificate* cert = calloc(1, sizeof(TLSCertificate)); TLSCertificate* cert = calloc(1, sizeof(TLSCertificate));
if (fingerprint_sha1) { if (fingerprint_sha1) {
cert->fingerprint_sha1 = strdup(fingerprint_sha1); cert->fingerprint_sha1 = strdup(fingerprint_sha1);
} }
if (fingerprint_sha256) {
cert->fingerprint_sha256 = strdup(fingerprint_sha256);
}
cert->version = version; cert->version = version;
if (serialnumber) { if (serialnumber) {
cert->serialnumber = strdup(serialnumber); cert->serialnumber = strdup(serialnumber);
@@ -181,6 +185,9 @@ tlscerts_new(const char* fingerprint_sha1, int version, const char* serialnumber
if (pem) { if (pem) {
cert->pem = strdup(pem); cert->pem = strdup(pem);
} }
if (pubkey_fingerprint) {
cert->pubkey_fingerprint = strdup(pubkey_fingerprint);
}
auto_gcharv gchar** fields = g_strsplit(subjectname, "/", 0); auto_gcharv gchar** fields = g_strsplit(subjectname, "/", 0);
for (int i = 0; i < g_strv_length(fields); i++) { for (int i = 0; i < g_strv_length(fields); i++) {
@@ -315,9 +322,8 @@ tlscerts_get_trusted(const char* fingerprint)
auto_gchar gchar* keyalg = g_key_file_get_string(tlscerts, fingerprint, "keyalg", NULL); auto_gchar gchar* keyalg = g_key_file_get_string(tlscerts, fingerprint, "keyalg", NULL);
auto_gchar gchar* signaturealg = g_key_file_get_string(tlscerts, fingerprint, "signaturealg", NULL); auto_gchar gchar* signaturealg = g_key_file_get_string(tlscerts, fingerprint, "signaturealg", NULL);
TLSCertificate* cert = tlscerts_new(fingerprint, version, serialnumber, subjectname, issuername, notbefore, return tlscerts_new(fingerprint, version, serialnumber, subjectname, issuername, notbefore,
notafter, keyalg, signaturealg, NULL); notafter, keyalg, signaturealg, NULL, NULL, NULL);
return cert;
} }
char* char*
@@ -361,6 +367,8 @@ tlscerts_free(TLSCertificate* cert)
free(cert->notbefore); free(cert->notbefore);
free(cert->notafter); free(cert->notafter);
free(cert->fingerprint_sha1); free(cert->fingerprint_sha1);
free(cert->fingerprint_sha256);
free(cert->pubkey_fingerprint);
free(cert->key_alg); free(cert->key_alg);
free(cert->signature_alg); free(cert->signature_alg);

View File

@@ -63,16 +63,19 @@ typedef struct tls_cert_t
char* notbefore; char* notbefore;
char* notafter; char* notafter;
char* fingerprint_sha1; char* fingerprint_sha1;
char* fingerprint_sha256;
char* key_alg; char* key_alg;
char* signature_alg; char* signature_alg;
char* pem; char* pem;
char* pubkey_fingerprint;
} TLSCertificate; } TLSCertificate;
void tlscerts_init(void); void tlscerts_init(void);
TLSCertificate* tlscerts_new(const char* fingerprint_sha1, int version, const char* serialnumber, const char* subjectname, TLSCertificate* tlscerts_new(const char* fingerprint_sha1, int version, const char* serialnumber, const char* subjectname,
const char* issuername, const char* notbefore, const char* notafter, const char* issuername, const char* notbefore, const char* notafter,
const char* key_alg, const char* signature_alg, const char* pem); const char* key_alg, const char* signature_alg, const char* pem,
const char* fingerprint_sha256, const char* pubkey_fingerprint);
void tlscerts_set_current(const TLSCertificate* cert); void tlscerts_set_current(const TLSCertificate* cert);

View File

@@ -90,6 +90,13 @@ cons_show(const char* const msg, ...)
va_end(arg); va_end(arg);
} }
#define cons_show_if_set(fmt, elmnt) \
do { \
if (elmnt) { \
cons_show(fmt, elmnt); \
} \
} while (0)
void void
cons_show_padded(int pad, const char* const msg, ...) cons_show_padded(int pad, const char* const msg, ...)
{ {
@@ -260,7 +267,9 @@ cons_show_tlscert(const TLSCertificate* cert)
cons_show(" Start : %s", cert->notbefore); cons_show(" Start : %s", cert->notbefore);
cons_show(" End : %s", cert->notafter); cons_show(" End : %s", cert->notafter);
cons_show(" Fingerprint : %s", cert->fingerprint_sha1); cons_show_if_set(" Fingerprint SHA1 : %s", cert->fingerprint_sha1);
cons_show_if_set(" Fingerprint SHA256 : %s", cert->fingerprint_sha256);
cons_show_if_set(" Pubkey Fingerprint : %s", cert->pubkey_fingerprint);
} }
void void

View File

@@ -1082,6 +1082,10 @@ _connection_certfail_cb(const xmpp_tlscert_t* xmpptlscert, const char* errormsg)
TLSCertificate* TLSCertificate*
_xmppcert_to_profcert(const xmpp_tlscert_t* xmpptlscert) _xmppcert_to_profcert(const xmpp_tlscert_t* xmpptlscert)
{ {
const char* pubkey_fp = NULL;
#ifdef HAVE_XMPP_CERT_PUBKEY_FINGERPRINT_SHA256
pubkey_fp = xmpp_tlscert_get_string(xmpptlscert, XMPP_CERT_PUBKEY_FINGERPRINT_SHA256);
#endif
int version = (int)strtol( int version = (int)strtol(
xmpp_tlscert_get_string(xmpptlscert, XMPP_CERT_VERSION), NULL, 10); xmpp_tlscert_get_string(xmpptlscert, XMPP_CERT_VERSION), NULL, 10);
return tlscerts_new( return tlscerts_new(
@@ -1094,7 +1098,9 @@ _xmppcert_to_profcert(const xmpp_tlscert_t* xmpptlscert)
xmpp_tlscert_get_string(xmpptlscert, XMPP_CERT_NOTAFTER), xmpp_tlscert_get_string(xmpptlscert, XMPP_CERT_NOTAFTER),
xmpp_tlscert_get_string(xmpptlscert, XMPP_CERT_KEYALG), xmpp_tlscert_get_string(xmpptlscert, XMPP_CERT_KEYALG),
xmpp_tlscert_get_string(xmpptlscert, XMPP_CERT_SIGALG), xmpp_tlscert_get_string(xmpptlscert, XMPP_CERT_SIGALG),
xmpp_tlscert_get_pem(xmpptlscert)); xmpp_tlscert_get_pem(xmpptlscert),
xmpp_tlscert_get_string(xmpptlscert, XMPP_CERT_FINGERPRINT_SHA256),
pubkey_fp);
} }
static void static void