From cbbe71752d7f9c6204ab0f16600fe7f10490f203 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Sat, 24 Apr 2004 22:38:50 +0000 Subject: Completed implementation of ldap/ntlm/simple handlers --- common/buffer.c | 216 +++++++++++++++++++++++++++++++++++++++++++++----------- common/hash.c | 130 ++++++++++++++++++++++++++-------- common/hash.h | 52 +++++++++++--- common/md5.c | 36 +++++++--- common/md5.h | 26 +++---- common/sha1.c | 164 ++++++++++++++++++++++++++++++++++++++++++ common/sha1.h | 30 ++++++++ 7 files changed, 555 insertions(+), 99 deletions(-) create mode 100644 common/sha1.c create mode 100644 common/sha1.h (limited to 'common') diff --git a/common/buffer.c b/common/buffer.c index 28cab24..a5b18a7 100644 --- a/common/buffer.c +++ b/common/buffer.c @@ -47,6 +47,12 @@ void buffer_bump(ha_buffer_t* buf, int count) } } +void ha_bufinit(ha_buffer_t* buf) +{ + memset(buf, 0, sizeof(*buf)); + ha_bufreset(buf); +} + void ha_bufreset(ha_buffer_t* buf) { if(!buf->_dt || buf->_al == 0) @@ -67,12 +73,6 @@ void ha_bufreset(ha_buffer_t* buf) buf->_pp = buf->_dt; } -void ha_bufinit(ha_buffer_t* buf) -{ - memset(buf, 0, sizeof(*buf)); - ha_bufreset(buf); -} - void ha_buffree(ha_buffer_t* buf) { if(buf->_dt) @@ -82,7 +82,8 @@ void ha_buffree(ha_buffer_t* buf) buf->_rp = buf->_pp = NULL; } -int ha_readline(int fd, ha_buffer_t* buf) + +int ha_bufreadline(int fd, ha_buffer_t* buf) { int l; @@ -137,7 +138,7 @@ int ha_readline(int fd, ha_buffer_t* buf) return 1; } -char* ha_parseword(ha_buffer_t* buf, const char* delims) +char* ha_bufparseword(ha_buffer_t* buf, const char* delims) { char* word = NULL; @@ -185,7 +186,7 @@ char* ha_parseword(ha_buffer_t* buf, const char* delims) return word; } -char* ha_parseline(ha_buffer_t* buf, int trim) +char* ha_bufparseline(ha_buffer_t* buf, int trim) { char* t; char* line = NULL; @@ -231,55 +232,93 @@ char* ha_parseline(ha_buffer_t* buf, int trim) return line; } -void ha_bufnext(ha_buffer_t* buf) -{ - buffer_bump(buf, 1); - - if(!ha_buferr(buf)) - { - buf->_rp++; - buf->_pp = buf->_rp; - *(buf->_rp) = 0; - } -} - -void ha_bufcat(ha_buffer_t* buf, ...) +char* ha_bufmcat(ha_buffer_t* buf, ...) { const char* str; va_list ap; va_start(ap, buf); + if(ha_buferr(buf)) + return NULL; + + /* Move up the block pointer if we're not joining strings */ + if(ha_buflen(buf) > 0 && *(buf->_rp - 1) != 0) + buf->_pp = buf->_rp; + while((str = va_arg(ap, char*)) != NULL) { int len = strlen(str); - buffer_bump(buf, len); + /* Always add one for the terminating char */ + buffer_bump(buf, len + 1); if(ha_buferr(buf)) - return; + return NULL; - /* _rpoint points to teh null */ + /* _rp always points to the next write point */ strcpy(buf->_rp, str); buf->_rp += len; } + + buf->_rp++; + return buf->_pp; +} + +char* ha_bufcpy(ha_buffer_t* buf, const char* src) +{ + size_t len = strlen(src); + return ha_bufncpy(buf, src, len); +} + +char* ha_bufncpy(ha_buffer_t* buf, const char* src, size_t len) +{ + if(ha_buferr(buf)) + return NULL; + + /* Move up the block pointer if we're not joining strings */ + if(ha_buflen(buf) > 0 && *(buf->_rp - 1) != 0) + buf->_pp = buf->_rp; + + /* Always add one for the terminating char */ + buffer_bump(buf, len + 1); + + if(ha_buferr(buf)) + return NULL; + + memcpy(buf->_rp, src, len * sizeof(char)); + buf->_rp += (len + 1); + *(buf->_rp - 1) = 0; + return buf->_pp; } void* ha_bufmalloc(ha_buffer_t* buf, size_t sz) { void* ret; - ha_bufnext(buf); + if(ha_buferr(buf)) + return NULL; + + /* TODO: Align memory on an appropriate boundary here */ + + /* We're not working with strings so always bump the pointer up */ + buf->_pp = buf->_rp; + buffer_bump(buf, sz); - buf->_rp += sz; if(ha_buferr(buf)) return NULL; - ret = (void*)ha_bufdata(buf); - ha_bufnext(buf); + buf->_rp += sz; + return (void*)buf->_pp; +} - return ret; +void* ha_bufmemdup(ha_buffer_t* buf, const void* src, size_t bytes) +{ + void* mem = ha_bufmalloc(buf, bytes); + if(mem) + memcpy(mem, src, bytes); + return mem; } /* @@ -311,14 +350,15 @@ static const char BASE64C[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; static const char PAD64C = '='; -void ha_bufenc64(ha_buffer_t* buf, const char* src, int len) +char* ha_bufenc64(ha_buffer_t* buf, const void* source, size_t len) { unsigned char input[3]; unsigned char output[4]; + unsigned char* src = (unsigned char*)source; size_t i; - if(len == -1) - len = strlen(src); + if(ha_buferr(buf)) + return NULL; while(2 < len) { @@ -332,10 +372,11 @@ void ha_bufenc64(ha_buffer_t* buf, const char* src, int len) output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); output[3] = input[2] & 0x3f; + /* This also accounts for the null terminator */ buffer_bump(buf, 5); if(ha_buferr(buf)) - return; + return NULL; *(buf->_rp++) = BASE64C[output[0]]; *(buf->_rp++) = BASE64C[output[1]]; @@ -355,10 +396,11 @@ void ha_bufenc64(ha_buffer_t* buf, const char* src, int len) output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + /* This also accounts for the null terminator */ buffer_bump(buf, 5); if(ha_buferr(buf)) - return; + return NULL; *(buf->_rp++) = BASE64C[output[0]]; *(buf->_rp++) = BASE64C[output[1]]; @@ -370,17 +412,23 @@ void ha_bufenc64(ha_buffer_t* buf, const char* src, int len) } *(buf->_rp++) = '\0'; + return buf->_pp; } -void ha_bufdec64(ha_buffer_t* buf, const char* src) +void* ha_bufdec64(ha_buffer_t* buf, const char* src, size_t bytes) { - int state; + int state = 0; int ch; char* pos; + size_t done = 0; - state = 0; + if(ha_buferr(buf)) + return NULL; - while((ch = *src++) != '\0') + if(bytes == 0) + bytes = ~0; + + while((ch = *src++) != '\0' && done < bytes) { if(isspace(ch)) /* Skip whitespace anywhere. */ continue; @@ -401,23 +449,27 @@ void ha_bufdec64(ha_buffer_t* buf, const char* src) { case 0: *(buf->_rp++) = (pos - BASE64C) << 2; + done++; state = 1; break; case 1: *(buf->_rp++) |= (pos - BASE64C) >> 4; + done++; *(buf->_rp) = ((pos - BASE64C) & 0x0f) << 4; state = 2; break; case 2: *(buf->_rp++) |= (pos - BASE64C) >> 2; + done++; *(buf->_rp) = ((pos - BASE64C) & 0x03) << 6; state = 3; break; case 3: *(buf->_rp++) |= (pos - BASE64C); + done++; state = 0; break; }; @@ -425,5 +477,89 @@ void ha_bufdec64(ha_buffer_t* buf, const char* src) /* TODO: Validate ending and return error if invalid somehow */ } - *(buf->_rp++) = '\0'; + /* If we were asked for a specific amount of bytes, then return null */ + if(bytes != ~0 && bytes != done) + return NULL; + + return buf->_pp; +} + +static const char HEXC[] = "0123456789ABCDEF"; + +char* ha_bufenchex(ha_buffer_t* buf, const void* source, size_t len) +{ + unsigned char* src = (unsigned char*)source; + unsigned char j; + + buffer_bump(buf, (len * 2) + 1); + + if(ha_buferr(buf)) + return NULL; + + while(len > 0) + { + j = *(src) >> 4 & 0xf; + if(j <= 9) + *(buf->_rp++) = (j + '0'); + else + *(buf->_rp++) = (j + 'a' - 10); + + j = *(src++) & 0xf; + len--; + + if(j <= 9) + *(buf->_rp++) = (j + '0'); + else + *(buf->_rp++) = (j + 'a' - 10); + } + + *(buf->_rp++) = 0; + return buf->_pp; +} + +void* ha_bufdechex(ha_buffer_t* buf, const char* src, size_t bytes) +{ + unsigned short a; + unsigned short b; + size_t done = 0; + char* pos; + + if(bytes != 0) + { + buffer_bump(buf, bytes + 1); + } + else + { + bytes = ~0; + buffer_bump(buf, (strlen(src) / 2) + 1); + } + + if(ha_buferr(buf)) + return NULL; + + while(src[0] && src[1] && done < bytes) + { + /* Find the position */ + pos = strchr(HEXC, src[0]); + if(pos == 0) + break; + + a = HEXC - pos; + + pos = strchr(HEXC, src[1]); + if(pos == 0); + break; + + b = HEXC - pos; + + *(buf->_rp++) = ((a & 0xf) << 4) | (b & 0xf); + src += 2; + done++; + } + + /* If we were asked for a specific amount of bytes, then return null */ + if(bytes != ~0 && bytes != done) + return NULL; + + return buf->_pp; } diff --git a/common/hash.c b/common/hash.c index 7d67e53..6471803 100644 --- a/common/hash.c +++ b/common/hash.c @@ -88,10 +88,14 @@ struct hash_t #ifdef HASH_COPYKEYS unsigned int klen; #endif +#ifdef HASH_CALLBACKS + hash_free_val_t f_free; + void* arg; +#endif }; -#define INITIAL_MAX 15 /* tunable == 2^n - 1 */ +#define INITIAL_MAX 15 /* tunable == 2^n - 1 */ /* * Hash creation functions. @@ -102,10 +106,18 @@ static hash_entry_t** alloc_array(hash_t* ht, unsigned int max) return malloc(sizeof(*(ht->array)) * (max + 1)); } -#ifdef HASH_COPYKEYS -hash_t* hash_create(size_t klen) +#ifdef HASH_CALLBACKS + #ifdef HASH_COPYKEYS +hash_t* hash_create(size_t klen, hash_free_val_t f_free, void* arg) + #else +hash_t* hash_create(hash_free_val_t f_free, void* arg) + #endif #else + #ifdef HASH_COPYKEYS +hash_t* hash_create(size_t klen) + #else hash_t* hash_create() + #endif #endif { hash_t* ht = malloc(sizeof(hash_t)); @@ -117,7 +129,10 @@ hash_t* hash_create() #ifdef HASH_COPYKEYS ht->klen = klen; #endif - +#ifdef HASH_CALLBACKS + ht->f_free = f_free; + ht->arg = arg; +#endif if(!ht->array) { free(ht); @@ -132,7 +147,13 @@ void hash_free(hash_t* ht) hash_index_t* hi; for(hi = hash_first(ht); hi; hi = hash_next(hi)) + { +#ifdef HASH_CALLBACKS + if(hi->ths->val && ht->f_free) + ht->f_free(ht->arg, (void*)hi->ths->val); +#endif free(hi->ths); + } if(ht->array) free(ht->array); @@ -362,58 +383,64 @@ void* hash_get(hash_t* ht, const void *key, size_t klen) } #ifdef HASH_COPYKEYS -int hash_set(hash_t* ht, const void* key, const void* val) +int hash_set(hash_t* ht, const void* key, void* val) { hash_entry_t** hep = find_entry(ht, key, val); #else -int hash_set(hash_t* ht, const void* key, size_t klen, const void* val) +int hash_set(hash_t* ht, const void* key, size_t klen, void* val) { hash_entry_t** hep = find_entry(ht, key, klen, val); #endif if(hep && *hep) { - if(val) - { - /* replace entry */ - (*hep)->val = val; +#ifdef HASH_CALLBACKS + if((*hep)->val && (*hep)->val != val && ht->f_free) + ht->f_free(ht->arg, (void*)((*hep)->val)); +#endif + + /* replace entry */ + (*hep)->val = val; #ifdef HASH_TIMESTAMP - /* Update or set the timestamp */ - (*hep)->stamp = time(NULL); + /* Update or set the timestamp */ + (*hep)->stamp = time(NULL); #endif - /* check that the collision rate isn't too high */ - if(ht->count > ht->max) - { - if(!expand_array(ht)) - return 0; - } - - return 1; + /* check that the collision rate isn't too high */ + if(ht->count > ht->max) + { + if(!expand_array(ht)) + return 0; } + + return 1; } return 0; } #ifdef HASH_COPYKEYS -void hash_rem(hash_t* ht, const void* key) +void* hash_rem(hash_t* ht, const void* key) { hash_entry_t** hep = find_entry(ht, key, NULL); #else -void hash_rem(hash_t* ht, const void* key, size_t klen) +void* hash_rem(hash_t* ht, const void* key, size_t klen) { hash_entry_t** hep = find_entry(ht, key, klen, NULL); #endif + void* val = NULL; if(hep && *hep) { hash_entry_t* old = *hep; *hep = (*hep)->next; --ht->count; + val = (void*)old->val; free(old); } + + return val; } unsigned int hash_count(hash_t* ht) @@ -426,6 +453,7 @@ int hash_purge(hash_t* ht, time_t stamp) { hash_index_t* hi; int r = 0; + void* val; for(hi = hash_first(ht); hi; hi = hash_next(hi)) { @@ -433,9 +461,14 @@ int hash_purge(hash_t* ht, time_t stamp) { /* No need to check for errors as we're deleting */ #ifdef HASH_COPYKEYS - hash_rem(ht, KEY_DATA(hi->ths)); + val = hash_rem(ht, KEY_DATA(hi->ths)); #else - hash_rem(ht, hi->ths->key, hi->ths->klen); + val = hash_rem(ht, hi->ths->key, hi->ths->klen); +#endif + +#ifdef HASH_CALLBACKS + if(val && ht->f_free) + (ht->f_free)(ht->arg, val); #endif r++; @@ -446,17 +479,58 @@ int hash_purge(hash_t* ht, time_t stamp) } #ifdef HASH_COPYKEYS -void* hash_touch(hash_index_t* hi, const void** key); +void hash_touch(hash_t* ht, const void* key) { hash_entry_t** hep = find_entry(ht, key, NULL); #else -void* hash_touch(hash_index_t* hi, const void** key, size_t* klen); +void hash_touch(hash_t* ht, const void* key, size_t* klen) { hash_entry_t** hep = find_entry(ht, key, klen, NULL); #endif - if(he && *he) - ((*he)->stamp) = time(NULL); + if(hep && *hep) + ((*hep)->stamp) = time(NULL); +} + +int hash_bump(hash_t* ht) +{ + hash_index_t* hi; + void* key = NULL; + void* val = NULL; + time_t least = 0; +#ifndef HASH_COPYKEYS + size_t klen = 0; +#endif + + for(hi = hash_first(ht); hi; hi = hash_next(hi)) + { + if(least == 0 || hi->ths->stamp < least) + { + least = hi->ths->stamp; + key = KEY_DATA(hi->ths); +#ifndef HASH_COPYKEYS + klen = hi->this->klen; +#endif + } + } + + if(key) + { +#ifdef HASH_COPYKEYS + val = hash_rem(ht, key); +#else + val = hash_rem(ht, key, klen); +#endif + +#ifdef HASH_CALLBACKS + if(val && ht->f_free) + (ht->f_free)(ht->arg, (void*)val); +#endif + + return 1; + } + + return 0; } #endif /* HASH_TIMESTAMP */ diff --git a/common/hash.h b/common/hash.h index 9e8174c..2b22b64 100644 --- a/common/hash.h +++ b/common/hash.h @@ -22,7 +22,7 @@ #define __HASH_H__ /* - * Options to define. You need to build both this file and + * Features to define. You need to build both this file and * the corresponding hash.c file with whatever options you set here */ @@ -32,6 +32,9 @@ /* Keep key values internally */ #define HASH_COPYKEYS 1 +/* Hash callback functionality */ +#define HASH_CALLBACKS 1 + #ifdef __cplusplus extern "C" { @@ -49,16 +52,31 @@ typedef struct hash_t hash_t; /* Abstract type for scanning hash tables. */ typedef struct hash_index_t hash_index_t; +/* A callback during remove operations */ +#ifdef HASH_CALLBACKS + typedef void (*hash_free_val_t)(void* arg, void* val); +#endif + /* Create a hash table */ -#ifdef HASH_COPYKEYS - hash_t* hash_create(size_t klen); +#ifdef HASH_CALLBACKS + #ifdef HASH_COPYKEYS + hash_t* hash_create(size_t klen, hash_free_val_t f_free, void* arg); + #else + hash_t* hash_create(hash_free_val_t f_free, void* arg); + #endif #else - hash_t* hash_create(); -#endif + #ifdef HASH_COPYKEYS + hash_t* hash_create(size_t klen); + #else + hash_t* hash_create(); + #endif +#endif /* HASH_CALLBACKS */ + /* To release all resources for a hash table */ void hash_free(hash_t* ht); + /** * Associate a value with a key in a hash table. * @@ -70,11 +88,12 @@ void hash_free(hash_t* ht); * val must not be null */ #ifdef HASH_COPYKEYS - int hash_set(hash_t* ht, const void* key, const void* val); + int hash_set(hash_t* ht, const void* key, void* val); #else - int hash_set(hash_t* ht, const void* key, size_t klen, const void* val); + int hash_set(hash_t* ht, const void* key, size_t klen, void* val); #endif + /** * Remove a value and key form the hash table * @@ -83,11 +102,12 @@ void hash_free(hash_t* ht); * klen Length of the key. Can be HASH_KEY_STRING to use the string length */ #ifdef HASH_COPYKEYS - void hash_rem(hash_t* ht, const void* key); + void* hash_rem(hash_t* ht, const void* key); #else - void hash_rem(hash_t* ht, const void* key, size_t klen); + void* hash_rem(hash_t* ht, const void* key, size_t klen); #endif + /** * Look up the value associated with a key in a hash table. * @@ -103,6 +123,7 @@ void hash_free(hash_t* ht); void* hash_get(hash_t* ht, const void* key, size_t klen); #endif + /** * Start iterating over the entries in a hash table. * @@ -114,6 +135,7 @@ void hash_free(hash_t* ht); */ hash_index_t* hash_first(hash_t* ht); + /** * Continue iterating over the entries in a hash table. * @@ -124,6 +146,7 @@ hash_index_t* hash_first(hash_t* ht); */ hash_index_t* hash_next(hash_index_t* hi); + /** * Get the current entry's details from the iteration state. * @@ -141,19 +164,26 @@ hash_index_t* hash_next(hash_index_t* hi); void* hash_this(hash_index_t* hi, const void** key, size_t* klen); #endif + /** * Purge entries before a certain timestamp */ #ifdef HASH_TIMESTAMP + int hash_purge(hash_t* ht, time_t stamp); #ifdef HASH_COPYKEYS - void hash_touch(hash_index_t* hi, const void** key); + void hash_touch(hash_t* ht, const void* key); #else - void hash_touch(hash_index_t* hi, const void** key, size_t* klen); + void hash_touch(hash_t* ht, const void* key, size_t* klen); #endif + +/* Bumps the oldest out */ +int hash_bump(hash_t* ht); + #endif + /** * Get the number of key/value pairs in the hash table. * diff --git a/common/md5.c b/common/md5.c index c909bb3..2f92bec 100644 --- a/common/md5.c +++ b/common/md5.c @@ -18,6 +18,8 @@ #include #include "md5.h" +void md5_transform(unsigned int buf[4], unsigned int const in[16]); + #ifdef BIG_ENDIAN void byteSwap(unsigned int *buf, unsigned words) @@ -39,7 +41,7 @@ byteSwap(unsigned int *buf, unsigned words) * initialization constants. */ void -MD5Init(struct MD5Context *ctx) +md5_init(md5_ctx_t* ctx) { ctx->buf[0] = 0x67452301; ctx->buf[1] = 0xefcdab89; @@ -55,9 +57,10 @@ MD5Init(struct MD5Context *ctx) * of bytes. */ void -MD5Update(struct MD5Context *ctx, const unsigned char* buf, unsigned len) +md5_update(md5_ctx_t* ctx, const void* b, unsigned len) { unsigned int t; + const unsigned char* buf = (const unsigned char*)b; /* Update byte count */ @@ -73,7 +76,7 @@ MD5Update(struct MD5Context *ctx, const unsigned char* buf, unsigned len) /* First chunk is an odd size */ memcpy((unsigned char *)ctx->in + 64 - t, buf, t); byteSwap(ctx->in, 16); - MD5Transform(ctx->buf, ctx->in); + md5_transform(ctx->buf, ctx->in); buf += t; len -= t; @@ -81,7 +84,7 @@ MD5Update(struct MD5Context *ctx, const unsigned char* buf, unsigned len) while (len >= 64) { memcpy(ctx->in, buf, 64); byteSwap(ctx->in, 16); - MD5Transform(ctx->buf, ctx->in); + md5_transform(ctx->buf, ctx->in); buf += 64; len -= 64; } @@ -95,7 +98,7 @@ MD5Update(struct MD5Context *ctx, const unsigned char* buf, unsigned len) * 1 0* (64-bit count of bits processed, MSB-first) */ void -MD5Final(unsigned char digest[16], struct MD5Context *ctx) +md5_final(unsigned char digest[16], md5_ctx_t* ctx) { int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */ unsigned char *p = (unsigned char *)ctx->in + count; @@ -109,7 +112,7 @@ MD5Final(unsigned char digest[16], struct MD5Context *ctx) if (count < 0) { /* Padding forces an extra block */ memset(p, 0, (unsigned int)count + 8); byteSwap(ctx->in, 16); - MD5Transform(ctx->buf, ctx->in); + md5_transform(ctx->buf, ctx->in); p = (unsigned char *)ctx->in; count = 56; } @@ -119,13 +122,30 @@ MD5Final(unsigned char digest[16], struct MD5Context *ctx) /* Append length in bits and transform */ ctx->in[14] = ctx->bytes[0] << 3; ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29; - MD5Transform(ctx->buf, ctx->in); + md5_transform(ctx->buf, ctx->in); byteSwap(ctx->buf, 4); memcpy(digest, ctx->buf, 16); memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ } +void +md5_string(unsigned char digest[MD5_LEN], const char* str) +{ + md5_ctx_t md5; + md5_init(&md5); + md5_update(&md5, str, strlen(str)); + md5_final(digest, &md5); +} + +int +md5_strcmp(unsigned char digest[MD5_LEN], const char* str) +{ + unsigned char other[MD5_LEN]; + md5_string(other, str); + return memcmp(digest, other, MD5_LEN); +} + /* The four core functions - F1 is optimized somewhat */ /* #define F1(x, y, z) (x & y | ~x & z) */ @@ -144,7 +164,7 @@ MD5Final(unsigned char digest[16], struct MD5Context *ctx) * the data and converts bytes into longwords for this routine. */ void -MD5Transform(unsigned int buf[4], unsigned int const in[16]) +md5_transform(unsigned int buf[4], unsigned int const in[16]) { register unsigned int a, b, c, d; diff --git a/common/md5.h b/common/md5.h index 62cbf2b..de431da 100644 --- a/common/md5.h +++ b/common/md5.h @@ -15,7 +15,7 @@ * will fill a supplied 16-byte array with the digest. * * Changed so as no longer to depend on Colin Plumb's `usual.h' - * header definitions; now uses stuff from dpkg's config.h + * header definitions * - Ian Jackson . * Still in the public domain. */ @@ -27,20 +27,22 @@ extern "C" { #ifndef MD5_H #define MD5_H +#define MD5_LEN 16 #define md5byte unsigned char -struct MD5Context { - unsigned int buf[4]; - unsigned int bytes[2]; - unsigned int in[16]; -}; - -typedef struct MD5Context MD5_CTX; +typedef struct md5_ctx +{ + unsigned int buf[4]; + unsigned int bytes[2]; + unsigned int in[16]; +} +md5_ctx_t; -void MD5Init(struct MD5Context *context); -void MD5Update(struct MD5Context *context, const md5byte* buf, unsigned len); -void MD5Final(unsigned char digest[16], struct MD5Context *context); -void MD5Transform(unsigned int buf[4], unsigned int const in[16]); +void md5_init(md5_ctx_t* context); +void md5_update(md5_ctx_t* context, const void* buf, unsigned len); +void md5_final(unsigned char digest[MD5_LEN], md5_ctx_t* context); +void md5_string(unsigned char digest[MD5_LEN], const char* str); +int md5_strcmp(unsigned char digest[MD5_LEN], const char* str); #ifdef __cplusplus } diff --git a/common/sha1.c b/common/sha1.c new file mode 100644 index 0000000..a40732e --- /dev/null +++ b/common/sha1.c @@ -0,0 +1,164 @@ +/* + * Fetched from ftp://ftp.funet.fi/pub/crypt/hash/sha/sha1.c on May 4, 1999 + * Modified by EPG May 6, 1999 + */ + +/* +SHA-1 in C +By Steve Reid +100% Public Domain +*/ + +#include +#include "sha1.h" + +typedef unsigned long ulong; +typedef unsigned char uchar; + +void SHA1Transform(ulong state[5], const uchar buffer[64]); + +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) + +/* blk0() and blk() perform the initial expand. */ +/* I got the idea of expanding during the round function from SSLeay */ +#ifdef LITTLE_ENDIAN +#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ + |(rol(block->l[i],8)&0x00FF00FF)) +#else +#define blk0(i) block->l[i] +#endif +#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ + ^block->l[(i+2)&15]^block->l[i&15],1)) + +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ +#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); +#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); +#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); + + +/* Hash a single 512-bit block. This is the core of the algorithm. */ + +void SHA1Transform(ulong state[5], const uchar buffer[64]) +{ + ulong a, b, c, d, e; + typedef union { + uchar c[64]; + ulong l[16]; + } CHAR64LONG16; + CHAR64LONG16* block; +#ifdef SHA1HANDSOFF + static uchar workspace[64]; + block = (CHAR64LONG16*)workspace; + memcpy(block, buffer, 64); +#else + block = (CHAR64LONG16*)buffer; +#endif + /* Copy context->state[] to working vars */ + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + /* 4 rounds of 20 operations each. Loop unrolled. */ + R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); + R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); + R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); + R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); + R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); + R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); + R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); + R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); + R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); + R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); + R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); + R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); + R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); + R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); + R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); + R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); + R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); + R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); + R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); + R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); + /* Add the working vars back into context.state[] */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + /* Wipe variables */ + a = b = c = d = e = 0; +} + + +/* SHA1Init - Initialize new context */ + +void sha1_init(sha1_ctx_t* context) +{ + /* SHA1 initialization constants */ + context->state[0] = 0x67452301; + context->state[1] = 0xEFCDAB89; + context->state[2] = 0x98BADCFE; + context->state[3] = 0x10325476; + context->state[4] = 0xC3D2E1F0; + context->count[0] = context->count[1] = 0; +} + + +/* Run your data through this. */ + +void sha1_update(sha1_ctx_t* context, const void* d, unsigned int len) +{ + unsigned int i, j; + const uchar* data = (uchar*)d; + + j = (context->count[0] >> 3) & 63; + if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++; + context->count[1] += (len >> 29); + if ((j + len) > 63) { + memcpy(&context->buffer[j], data, (i = 64-j)); + SHA1Transform(context->state, context->buffer); + for ( ; i + 63 < len; i += 64) { + SHA1Transform(context->state, &data[i]); + } + j = 0; + } + else i = 0; + memcpy(&context->buffer[j], &data[i], len - i); +} + + +/* Add padding and return the message digest. */ + +void sha1_final(uchar digest[20], sha1_ctx_t* context) +{ + ulong i; + uchar finalcount[8]; + + for (i = 0; i < 8; i++) { + finalcount[i] = (uchar)((context->count[(i >= 4 ? 0 : 1)] + >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ + } + sha1_update(context, (uchar *)"\200", 1); + while ((context->count[0] & 504) != 448) { + sha1_update(context, (uchar *)"\0", 1); + } + sha1_update(context, finalcount, 8); /* Should cause a SHA1Transform() */ + for (i = 0; i < 20; i++) { + digest[i] = (uchar) + ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); + } + /* Wipe variables */ + i = 0; + memset(context->buffer, 0, 64); + memset(context->state, 0, 20); + memset(context->count, 0, 8); + memset(&finalcount, 0, 8); +#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */ + SHA1Transform(context->state, context->buffer); +#endif +} + + diff --git a/common/sha1.h b/common/sha1.h new file mode 100644 index 0000000..37f734f --- /dev/null +++ b/common/sha1.h @@ -0,0 +1,30 @@ +#ifndef __SHA1_H__ +#define __SHA1_H__ + +#ifndef LITTLE_ENDIAN +#define LITTLE_ENDIAN +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define SHA1_LEN 20 + +typedef struct sha1_ctx +{ + unsigned long state[5]; + unsigned long count[2]; + unsigned char buffer[64]; +} +sha1_ctx_t; + +void sha1_init(sha1_ctx_t* context); +void sha1_update(sha1_ctx_t* context, const void* data, unsigned int len); +void sha1_final(unsigned char digest[SHA1_LEN], sha1_ctx_t* context); + +#ifdef __cplusplus +} +#endif + +#endif // __SHA1_H__ -- cgit v1.2.3