Use more generic routines to convert fingerprints to/from hexadecimal
This is a first step towards non-MD5 fingerprints; now we need Loudmouth
support...
--- 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;
}
--- 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);
--- 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;