X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilcutil%2Fsilcutil.c;h=75e85f933fbecc049e1251b132f6b338714590d2;hb=e7b6c157b80152bf9fb9266e6bdd93f9fb0db776;hp=eb0d989e835791fd78d5e2514e1a2709cd8a3c47;hpb=96d69ecd5b1e5090db05efee7c992e2b2b1e3062;p=silc.git diff --git a/lib/silcutil/silcutil.c b/lib/silcutil/silcutil.c index eb0d989e..75e85f93 100644 --- a/lib/silcutil/silcutil.c +++ b/lib/silcutil/silcutil.c @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 1997 - 2007 Pekka Riikonen + Copyright (C) 1997 - 2008 Pekka Riikonen 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 @@ -224,136 +224,54 @@ char *silc_format(char *fmt, ...) va_list args; char buf[8192]; - memset(buf, 0, sizeof(buf)); va_start(args, fmt); - silc_vsnprintf(buf, sizeof(buf) - 1, fmt, args); + silc_vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); return silc_strdup(buf); } -/* Hash a ID. The `user_context' is the ID type. */ +/* Creates fingerprint from data, usually used with SHA1 digests */ -SilcUInt32 silc_hash_id(void *key, void *user_context) +char *silc_fingerprint(const unsigned char *data, SilcUInt32 data_len) { - SilcIdType id_type = (SilcIdType)SILC_PTR_TO_32(user_context); - SilcUInt32 h = 0; - int i; - - switch (id_type) { - case SILC_ID_CLIENT: - { - SilcClientID *id = (SilcClientID *)key; - - /* The client ID is hashed by hashing the hash of the ID - (which is a truncated MD5 hash of the nickname) so that we - can access the entry from the cache with both Client ID but - with just a hash from the ID as well. */ - return silc_hash_client_id_hash(id->hash, NULL); - } - break; - case SILC_ID_SERVER: - { - SilcServerID *id = (SilcServerID *)key; + unsigned char *fingerprint, *cp; + unsigned int len, blocks, i; - h = id->port * id->rnd; - for (i = 0; i < id->ip.data_len; i++) - h ^= id->ip.data[i]; - - return h; - } - break; - case SILC_ID_CHANNEL: - { - SilcChannelID *id = (SilcChannelID *)key; - - h = id->port * id->rnd; - for (i = 0; i < id->ip.data_len; i++) - h ^= id->ip.data[i]; - - return h; - } - break; - default: - break; - } - - return h; -} - -/* Hash Client ID's hash. */ - -SilcUInt32 silc_hash_client_id_hash(void *key, void *user_context) -{ - int i; - unsigned char *hash = key; - SilcUInt32 h = 0, g; - - for (i = 0; i < CLIENTID_HASH_LEN; i++) { - h = (h << 4) + hash[i]; - if ((g = h & 0xf0000000)) { - h = h ^ (g >> 24); - h = h ^ g; - } + if (!data || !data_len) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); + return NULL; } - return h; -} - -/* Compares two ID's. May be used as SilcHashTable comparison function. - The Client ID's compares only the hash of the Client ID not any other - part of the Client ID. Other ID's are fully compared. */ - -SilcBool silc_hash_id_compare(void *key1, void *key2, void *user_context) -{ - SilcIdType id_type = (SilcIdType)SILC_PTR_TO_32(user_context); - return (id_type == SILC_ID_CLIENT ? - SILC_ID_COMPARE_HASH((SilcClientID *)key1, (SilcClientID *)key2) : - SILC_ID_COMPARE_TYPE(key1, key2, id_type)); -} + if (data_len >= 256) + data_len = 255; -/* Compares two ID's. Compares full IDs. */ + /* Align and calculate total length */ + len = ((data_len + 19) / 20) * 20; + blocks = (len / 10); + len = (len * 2) + ((blocks - 1) * 2) + (4 * blocks) + 2 + 1; -SilcBool silc_hash_id_compare_full(void *key1, void *key2, void *user_context) -{ - SilcIdType id_type = (SilcIdType)SILC_PTR_TO_32(user_context); - return SILC_ID_COMPARE_TYPE(key1, key2, id_type); -} + cp = fingerprint = silc_calloc(len, sizeof(*fingerprint)); + if (!cp) + return NULL; -/* Compare two Client ID's entirely and not just the hash from the ID. */ - -SilcBool silc_hash_client_id_compare(void *key1, void *key2, - void *user_context) -{ - return SILC_ID_COMPARE_TYPE(key1, key2, SILC_ID_CLIENT); -} - -/* Creates fingerprint from data, usually used with SHA1 digests */ - -char *silc_fingerprint(const unsigned char *data, SilcUInt32 data_len) -{ - char fingerprint[64], *cp; - int i; - - memset(fingerprint, 0, sizeof(fingerprint)); - cp = fingerprint; for (i = 0; i < data_len; i++) { - silc_snprintf(cp, sizeof(fingerprint), "%02X", data[i]); + silc_snprintf(cp, len, "%02X", data[i]); cp += 2; + len -= 2; if ((i + 1) % 2 == 0) - silc_snprintf(cp++, sizeof(fingerprint), " "); - + silc_snprintf(cp++, len--, " "); if ((i + 1) % 10 == 0) - silc_snprintf(cp++, sizeof(fingerprint), " "); + silc_snprintf(cp++, len--, " "); } i--; - if ((i + 1) % 2 == 0) - cp[-2] = 0; if ((i + 1) % 10 == 0) - cp[-1] = 0; + *(--cp) = '\0'; + if ((i + 1) % 2 == 0) + *(--cp) = '\0'; - return silc_strdup(fingerprint); + return fingerprint; } /* Return TRUE if the `data' is ASCII string. */ @@ -554,8 +472,6 @@ SilcBool silc_hex2data(const char *hex, unsigned char *data, if (ret_data_len) *ret_data_len = i; - SILC_LOG_HEXDUMP(("len %d", i), data, i); - return TRUE; } @@ -584,7 +500,5 @@ SilcBool silc_data2hex(const unsigned char *data, SilcUInt32 data_len, *cp++ = l + (l > 9 ? 'A' - 10 : '0'); } - SILC_LOG_DEBUG(("HEX string: '%s'", hex)); - return TRUE; }