5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 1997 - 2000 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
23 * Revision 1.3 2000/07/10 05:35:43 priikone
24 * Added fingerprint functions.
26 * Revision 1.2 2000/07/05 06:08:43 priikone
27 * Global cosmetic change.
29 * Revision 1.1.1.1 2000/06/27 11:36:55 priikone
30 * Imported from internal CVS/Added Log headers.
35 #include "silcincludes.h"
40 /* List of all hash functions in SILC. You can dynamically add new hash
41 functions into the list. At the initialization of SILC this list is
42 filled with the configured hash functions. */
43 struct SilcHashListStruct {
45 struct SilcHashListStruct *next;
48 /* List of dynamically registered hash functions. */
49 struct SilcHashListStruct *silc_hash_list = NULL;
51 /* Statically declared list of hash functions. */
52 SilcHashObject silc_hash_builtin_list[] =
54 { "md5", 16, 64, silc_md5_init, silc_md5_update, silc_md5_final,
55 silc_md5_transform, silc_md5_context_len },
56 { "sha1", 20, 64, silc_sha1_init, silc_sha1_update, silc_sha1_final,
57 silc_sha1_transform, silc_sha1_context_len },
59 { NULL, 0, 0, NULL, NULL, NULL, NULL, NULL }
62 /* Registers a ned hash function into the SILC. This function is used at
63 the initialization of the SILC. */
65 int silc_hash_register(SilcHashObject *hash)
67 struct SilcHashListStruct *new, *h;
69 SILC_LOG_DEBUG(("Registering new hash function"));
71 new = silc_calloc(1, sizeof(*new));
72 new->hash = silc_calloc(1, sizeof(*new->hash));
74 /* Set the pointers */
75 new->hash->name = silc_calloc(1, strlen(hash->name));
76 memcpy(new->hash->name, hash->name, strlen(hash->name));
77 new->hash->hash_len = hash->hash_len;
78 new->hash->block_len = hash->block_len;
79 new->hash->init = hash->init;
80 new->hash->update = hash->update;
81 new->hash->final = hash->final;
82 new->hash->context_len = hash->context_len;
85 /* Add the new hash function to the list */
86 if (!silc_hash_list) {
103 /* Unregister a hash function from the SILC. */
105 int silc_hash_unregister(SilcHashObject *hash)
107 struct SilcHashListStruct *h, *tmp;
109 SILC_LOG_DEBUG(("Unregistering hash function"));
113 /* Unregister all hash functions */
114 if (hash == SILC_ALL_HASH_FUNCTIONS) {
115 /* Unregister all ciphers */
118 silc_free(h->hash->name);
126 /* Unregister the hash function */
127 if (h->hash == hash) {
129 silc_free(h->hash->name);
131 silc_hash_list = tmp;
137 if (h->next->hash == hash) {
139 silc_free(h->hash->name);
151 /* Allocates a new SilcHash object. New object is returned into new_hash
154 int silc_hash_alloc(const unsigned char *name, SilcHash *new_hash)
156 struct SilcHashListStruct *h;
159 SILC_LOG_DEBUG(("Allocating new hash object"));
161 /* Allocate the new object */
162 *new_hash = silc_calloc(1, sizeof(**new_hash));
164 if (silc_hash_list) {
167 if (!strcmp(h->hash->name, name))
175 /* Set the pointers */
176 (*new_hash)->hash = h->hash;
177 (*new_hash)->context = silc_calloc(1, h->hash->context_len());
178 (*new_hash)->make_hash = silc_hash_make;
184 for (i = 0; silc_hash_builtin_list[i].name; i++)
185 if (!strcmp(silc_hash_builtin_list[i].name, name))
188 if (silc_hash_builtin_list[i].name == NULL) {
189 silc_free(*new_hash);
193 /* Set the pointers */
194 (*new_hash)->hash = &silc_hash_builtin_list[i];
195 (*new_hash)->context = silc_calloc(1, (*new_hash)->hash->context_len());
196 (*new_hash)->make_hash = silc_hash_make;
201 /* Free's the SilcHash object */
203 void silc_hash_free(SilcHash hash)
206 silc_free(hash->context);
211 /* Returns TRUE if hash algorithm `name' is supported. */
213 int silc_hash_is_supported(const unsigned char *name)
215 struct SilcHashListStruct *h;
218 if (silc_hash_list) {
222 if (!strcmp(h->hash->name, name))
228 for (i = 0; silc_hash_builtin_list[i].name; i++)
229 if (!strcmp(silc_hash_builtin_list[i].name, name))
235 /* Returns comma separated list of supported hash functions. */
237 char *silc_hash_get_supported()
241 struct SilcHashListStruct *h;
244 if (silc_hash_list) {
248 len += strlen(h->hash->name);
249 list = silc_realloc(list, len + 1);
251 memcpy(list + (len - strlen(h->hash->name)),
252 h->hash->name, strlen(h->hash->name));
253 memcpy(list + len, ",", 1);
260 for (i = 0; silc_hash_builtin_list[i].name; i++) {
261 len += strlen(silc_hash_builtin_list[i].name);
262 list = silc_realloc(list, len + 1);
264 memcpy(list + (len - strlen(silc_hash_builtin_list[i].name)),
265 silc_hash_builtin_list[i].name,
266 strlen(silc_hash_builtin_list[i].name));
267 memcpy(list + len, ",", 1);
276 /* Creates the hash value and returns it to the return_hash argument. */
278 void silc_hash_make(SilcHash hash, const unsigned char *data,
279 unsigned int len, unsigned char *return_hash)
281 hash->hash->init(hash->context);
282 hash->hash->update(hash->context, (unsigned char *)data, len);
283 hash->hash->final(hash->context, return_hash);
286 /* Creates fingerprint of the data. If `hash' is NULL SHA1 is used as
287 default hash function. The returned fingerprint must be free's by the
290 char *silc_hash_fingerprint(SilcHash hash, const unsigned char *data,
291 unsigned int data_len)
293 char fingerprint[64], *cp;
298 silc_hash_alloc("sha1", &hash);
300 silc_hash_make(hash, data, data_len, h);
302 memset(fingerprint, 0, sizeof(fingerprint));
304 for (i = 0; i < hash->hash->hash_len; i++) {
305 snprintf(cp, sizeof(fingerprint), "%02X", h[i]);
308 if ((i + 1) % 2 == 0)
309 snprintf(cp++, sizeof(fingerprint), " ");
311 if ((i + 1) % 10 == 0)
312 snprintf(cp++, sizeof(fingerprint), " ");
315 return strdup(fingerprint);