# HG changeset patch # User Mikael Berthe # Date 1444663159 -7200 # Node ID 170597f5365bd5e62168b151511796f7a63df8b6 # Parent ff18feb75a6d7e0801cb8322fc150b38caee812c Use more generic routines to convert fingerprints to/from hexadecimal This is a first step towards non-MD5 fingerprints; now we need Loudmouth support... diff -r ff18feb75a6d -r 170597f5365b mcabber/mcabber/utils.c --- a/mcabber/mcabber/utils.c Mon Oct 12 11:41:34 2015 +0200 +++ b/mcabber/mcabber/utils.c Mon Oct 12 17:19:19 2015 +0200 @@ -155,36 +155,48 @@ return g_strdup(fname); } -void fingerprint_to_hex(const char *fprstr, char hex[48]) +// fingerprint_to_hex(fprstr, hex, fpr_len) +// Convert the binary fingerprint fprstr (which is fpr_len bytes long) +// to a NULL-terminated hexadecimal string hex. +// The destination array hex should have been preallocated by the caller, +// and should be big enough (i.e. >= 3*fpr_len bytes). +void fingerprint_to_hex(const char *fprstr, char *hex, size_t fpr_len) { - int i; + unsigned int i; const unsigned char *fpr = (const unsigned char *)fprstr; char *p; hex[0] = 0; - if (!fpr) return; + if (!fpr || fpr_len < 16) return; - for (p = hex, i = 0; i < 15; i++, p+=3) + for (p = hex, i = 0; i < fpr_len - 1; i++, p+=3) g_snprintf(p, 4, "%02X:", fpr[i]); g_snprintf(p, 3, "%02X", fpr[i]); } -gboolean hex_to_fingerprint(const char *hex, char fpr[17]) +// hex_to_fingerprint(hex, fpr, fpr_len) +// Convert the hexadecimal fingerprint hex to a byte array fpr[]. +// The fpr array should have been preallocated with a size >= fpr_len. +gboolean hex_to_fingerprint(const char *hex, char *fpr, size_t fpr_len) { - int i; + unsigned int i; const char *p; + if (fpr_len < 16) return FALSE; + fpr[0] = 0; - if (strlen(hex) != 47) + + if (strlen(hex) != fpr_len*3 - 1) return FALSE; - for (i = 0, p = hex; *p && *(p+1); i++, p += 3) { - if (*(p+2) && (*(p+2) != ':')) { - fpr[i] = 0; + + for (i = 0, p = hex; i < fpr_len && *p && *(p+1); i++, p += 3) { + // Check we have two hex digits followed by a colon (or end of string) + if (!isxdigit(*p) || !isxdigit(*(p+1))) return FALSE; - } + if (*(p+2) && (*(p+2) != ':')) + return FALSE; fpr[i] = (char)g_ascii_strtoull(p, NULL, 16); } - fpr[i] = 0; return TRUE; } diff -r ff18feb75a6d -r 170597f5365b mcabber/mcabber/utils.h --- a/mcabber/mcabber/utils.h Mon Oct 12 11:41:34 2015 +0200 +++ b/mcabber/mcabber/utils.h Mon Oct 12 17:19:19 2015 +0200 @@ -21,8 +21,8 @@ const char *resource); gboolean jid_equal(const char *jid1, const char *jid2); -void fingerprint_to_hex(const char *fpr, char hex[48]); -gboolean hex_to_fingerprint(const char *hex, char fpr[17]); +void fingerprint_to_hex(const char *fpr, char *hex, size_t fpr_len); +gboolean hex_to_fingerprint(const char *hex, char *fpr, size_t fpr_len); void ut_init_debug(void); void ut_write_log(unsigned int flag, const char *data); diff -r ff18feb75a6d -r 170597f5365b mcabber/mcabber/xmpp.c --- a/mcabber/mcabber/xmpp.c Mon Oct 12 11:41:34 2015 +0200 +++ b/mcabber/mcabber/xmpp.c Mon Oct 12 17:19:19 2015 +0200 @@ -44,6 +44,8 @@ #define RECONNECTION_TIMEOUT 60L +#define FINGERPRINT_LENGTH 16 // Currently Loudmouth only supports MD5 + LmConnection* lconnection = NULL; static guint AutoConnection; @@ -714,8 +716,8 @@ "Certificate hostname does not match expected hostname!"); break; case LM_SSL_STATUS_CERT_FINGERPRINT_MISMATCH: { - char fpr[49] = {0}; - fingerprint_to_hex(lm_ssl_get_fingerprint(ssl), fpr); + char fpr[3*FINGERPRINT_LENGTH] = {0}; + fingerprint_to_hex(lm_ssl_get_fingerprint(ssl), fpr, FINGERPRINT_LENGTH); scr_LogPrint(LPRINT_LOGNORM, "Certificate fingerprint does not match expected fingerprint!"); scr_LogPrint(LPRINT_LOGNORM, "Remote fingerprint: %s", fpr); @@ -743,8 +745,8 @@ { LmSSL *lssl; if ((lssl = lm_connection_get_ssl(connection)) != NULL) { - char fpr[49] = {0}; - fingerprint_to_hex(lm_ssl_get_fingerprint(lssl), fpr); + char fpr[3*FINGERPRINT_LENGTH] = {0}; + fingerprint_to_hex(lm_ssl_get_fingerprint(lssl), fpr, FINGERPRINT_LENGTH); scr_LogPrint(LPRINT_LOGNORM, "Connection established.\n" "Remote fingerprint: %s", fpr); } @@ -1738,7 +1740,7 @@ { const char *userjid, *password, *resource, *servername, *ssl_fpr; char *dynresource = NULL; - char fpr[17] = {0}; + char fpr[FINGERPRINT_LENGTH] = {0}; const char *proxy_host; const char *resource_prefix = PACKAGE_NAME; char *fjid; @@ -1883,7 +1885,7 @@ port = (ssl ? LM_CONNECTION_DEFAULT_PORT_SSL : LM_CONNECTION_DEFAULT_PORT); lm_connection_set_port(lconnection, port); - if (ssl_fpr && (!hex_to_fingerprint(ssl_fpr, fpr))) { + if (ssl_fpr && (!hex_to_fingerprint(ssl_fpr, fpr, FINGERPRINT_LENGTH))) { scr_LogPrint(LPRINT_LOGNORM, "** Please set the fingerprint in the format " "97:5C:00:3F:1D:77:45:25:E2:C5:70:EC:83:C8:87:EE"); return -1;