From bb9ee0bcdd99d1c4c105b4f7c7680a8035934681 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Sun, 29 Sep 1996 21:27:03 +0000 Subject: Towards RFC 1938 compliance. Also, now supports SHA (secure hash algorithm). --- lib/libskey/shlib_version | 2 +- lib/libskey/skey.h | 6 +- lib/libskey/skeylogin.c | 22 ++++--- lib/libskey/skeysubr.c | 154 +++++++++++++++++++++++++++++++--------------- 4 files changed, 121 insertions(+), 63 deletions(-) (limited to 'lib') diff --git a/lib/libskey/shlib_version b/lib/libskey/shlib_version index 3d7c908e43d..dea2b62cafc 100644 --- a/lib/libskey/shlib_version +++ b/lib/libskey/shlib_version @@ -1,2 +1,2 @@ major=0 -minor=1 +minor=2 diff --git a/lib/libskey/skey.h b/lib/libskey/skey.h index e9de0d4c84d..a7955d30e85 100644 --- a/lib/libskey/skey.h +++ b/lib/libskey/skey.h @@ -11,7 +11,7 @@ * * Main client header * - * $Id: skey.h,v 1.3 1996/09/27 15:38:59 millert Exp $ + * $Id: skey.h,v 1.4 1996/09/29 21:27:01 millert Exp $ */ #if defined(__TURBOC__) || defined(__STDC__) || defined(LATTICE) @@ -73,5 +73,5 @@ int getskeyprompt __ARGS ((struct skey *, char *, char *)); int atob8 __ARGS((char *, char *)); int btoa8 __ARGS((char *, char *)); int htoi __ARGS((char)); -int skey_get_MDX __ARGS(()); -int skey_set_MDX __ARGS((int)); +const char * skey_get_algorithm __ARGS((void)); +char * skey_set_algorithm __ARGS((char *)); diff --git a/lib/libskey/skeylogin.c b/lib/libskey/skeylogin.c index 760faa6ab09..d315bafc5e1 100644 --- a/lib/libskey/skeylogin.c +++ b/lib/libskey/skeylogin.c @@ -8,7 +8,7 @@ * * S/KEY verification check, lookups, and authentication. * - * $Id: skeylogin.c,v 1.4 1996/09/29 04:30:39 millert Exp $ + * $Id: skeylogin.c,v 1.5 1996/09/29 21:27:01 millert Exp $ */ #include @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -52,12 +53,12 @@ getskeyprompt(mp, name, prompt) sevenbit(name); rval = skeylookup(mp, name); - (void)strcpy(prompt, "skey MD0 55 latour1\n"); + (void)strcpy(prompt, "otp-md0 55 latour1\n"); switch (rval) { case -1: /* File error */ return -1; case 0: /* Lookup succeeded, return challenge */ - (void)sprintf(prompt, "skey MD%d %d %s\n", skey_get_MDX(), + (void)sprintf(prompt, "otp-%s %d %s\n", skey_get_algorithm(), mp->n - 1, mp->seed); return 0; case 1: /* User not found */ @@ -87,7 +88,7 @@ skeychallenge(mp,name, ss) case -1: /* File error */ return -1; case 0: /* Lookup succeeded, issue challenge */ - (void)sprintf(ss, "skey MD%d %d %s", skey_get_MDX(), + (void)sprintf(ss, "otp-%s %d %s", skey_get_algorithm(), mp->n - 1, mp->seed); return 0; case 1: /* User not found */ @@ -139,13 +140,14 @@ skeylookup(mp,name) continue; if ((cp = strtok(NULL, " \t")) == NULL) continue; - /* Set MDX if specified, else use MD4 */ - if (cp[0] == 'M' && cp[1] == 'D') { - skey_set_MDX(atoi(&cp[2])); + /* Set hash type if specified, else use md4 */ + if (isalpha(*cp)) { + /* XXX - return val */ + skey_set_algorithm(cp); if ((cp = strtok(NULL, " \t")) == NULL) continue; } else { - skey_set_MDX(4); + skey_set_algorithm("md4"); } mp->n = atoi(cp); if ((mp->seed = strtok(NULL, " \t")) == NULL) @@ -248,8 +250,8 @@ skeyverify(mp,response) btoa8(mp->val,key); mp->n--; (void)fseek(mp->keyfile, mp->recstart, SEEK_SET); - (void)fprintf(mp->keyfile, "%s MD%d %04d %-16s %s %-21s\n", - mp->logname, skey_get_MDX(), mp->n, mp->seed, mp->val, tbuf); + (void)fprintf(mp->keyfile, "%s %s %04d %-16s %s %-21s\n", + mp->logname, skey_get_algorithm(), mp->n, mp->seed, mp->val, tbuf); (void)fclose(mp->keyfile); diff --git a/lib/libskey/skeysubr.c b/lib/libskey/skeysubr.c index 6c3f9ea985a..8907592c62f 100644 --- a/lib/libskey/skeysubr.c +++ b/lib/libskey/skeysubr.c @@ -10,7 +10,7 @@ * * S/KEY misc routines. * - * $Id: skeysubr.c,v 1.3 1996/09/27 20:40:17 millert Exp $ + * $Id: skeysubr.c,v 1.4 1996/09/29 21:27:02 millert Exp $ */ #include @@ -20,22 +20,43 @@ #include #include #include +#include #include "skey.h" -/* Default MDX function to use (currently 4 or 5) */ -#ifndef SKEY_MDX_DEFAULT -#define SKEY_MDX_DEFAULT 5 +/* Default hash function to use (index into skey_hash_types array) */ +#ifndef SKEY_HASH_DEFAULT +#define SKEY_HASH_DEFAULT 1 #endif static void trapped __ARGS((int sig)); -static void f_MD4 __ARGS ((char *x)); -static void f_MD5 __ARGS ((char *x)); -static void skey_echo __ARGS ((int)); -static int keycrunch_MD4 __ARGS ((char *result, char *seed, char *passwd)); -static int keycrunch_MD5 __ARGS ((char *result, char *seed, char *passwd)); +static void f_md4 __ARGS ((char *x)); +static void f_md5 __ARGS ((char *x)); +static void f_sha1 __ARGS ((char *x)); +static void skey_echo __ARGS ((int action)); +static int keycrunch_md4 __ARGS ((char *result, char *seed, char *passwd)); +static int keycrunch_md5 __ARGS ((char *result, char *seed, char *passwd)); +static int keycrunch_sha1 __ARGS ((char *result, char *seed, char *passwd)); + +/* Current hash type (index into skey_hash_types array) */ +static int skey_hash_type = SKEY_HASH_DEFAULT; + +/* + * Hash types we support. + * Each has an associated keycrunch() and f() function. + */ +#define SKEY_ALGORITH_MAX 3 +struct skey_algorithm_table { + const char *name; + int (*keycrunch) __ARGS((char *, char *, char *)); + void (*f) __ARGS((char *)); +}; +static struct skey_algorithm_table skey_algorithm_table[] = { + { "md4", keycrunch_md4, f_md4 }, + { "md5", keycrunch_md5, f_md5 }, + { "sha1", keycrunch_sha1, f_sha1 } +}; -static int skey_MDX = 0; /* * Crunch a key: @@ -48,19 +69,11 @@ keycrunch(result, seed, passwd) char *seed; /* Seed, any length */ char *passwd; /* Password, any length */ { - switch (skey_get_MDX()) { - /* - * Need a default case to appease gc even though - * skey_set_MDX() guantaees we get back 4 or 5 - */ - case 4 : return(keycrunch_MD4(result, seed, passwd)); - default : return(keycrunch_MD5(result, seed, passwd)); - } - /* NOTREACHED */ + return(skey_algorithm_table[skey_hash_type].keycrunch(result, seed, passwd)); } static int -keycrunch_MD4(result, seed, passwd) +keycrunch_md4(result, seed, passwd) char *result; /* 8-byte result */ char *seed; /* Seed, any length */ char *passwd; /* Password, any length */ @@ -93,7 +106,7 @@ keycrunch_MD4(result, seed, passwd) } static int -keycrunch_MD5(result, seed, passwd) +keycrunch_md5(result, seed, passwd) char *result; /* 8-byte result */ char *seed; /* Seed, any length */ char *passwd; /* Password, any length */ @@ -125,24 +138,49 @@ keycrunch_MD5(result, seed, passwd) return 0; } +static int +keycrunch_sha1(result, seed, passwd) + char *result; /* 8-byte result */ + char *seed; /* Seed, any length */ + char *passwd; /* Password, any length */ +{ + char *buf; + SHA1_INFO sha; + unsigned int buflen; + + buflen = strlen(seed) + strlen(passwd); + if ((buf = (char *)malloc(buflen+1)) == NULL) + return -1; + (void)strcpy(buf, seed); + (void)strcat(buf, passwd); + + /* Crunch the key through SHA1 */ + sevenbit(buf); + sha1Init(&sha); + sha1Update(&sha, (unsigned char *)buf, buflen); + sha1Final(&sha); + (void)free(buf); + + /* Fold 160 to 64 bits */ + sha.digest[0] ^= sha.digest[2]; + sha.digest[1] ^= sha.digest[3]; + sha.digest[0] ^= sha.digest[4]; + + (void)memcpy((void *)result, (void *)sha.digest, 8); + + return 0; +} + /* The one-way function f(). Takes 8 bytes and returns 8 bytes in place */ void f(x) char *x; { - switch (skey_get_MDX()) { - /* - * Need a default case to appease gc even though - * skey_set_MDX() guantaees we get back 4 or 5 - */ - case 4 : return(f_MD4(x)); - default : return(f_MD5(x)); - } - /* NOTREACHED */ + skey_algorithm_table[skey_hash_type].f(x); } void -f_MD4(x) +f_md4(x) char *x; { MD4_CTX md; @@ -160,7 +198,7 @@ f_MD4(x) } void -f_MD5(x) +f_md5(x) char *x; { MD5_CTX md; @@ -177,6 +215,24 @@ f_MD5(x) (void)memcpy((void *)x, (void *)results, 8); } +void +f_sha1(x) + char *x; +{ + SHA1_INFO sha; + + sha1Init(&sha); + sha1Update(&sha, (unsigned char *)x, 8); + sha1Final(&sha); + + /* Fold 160 to 64 bits */ + sha.digest[0] ^= sha.digest[2]; + sha.digest[1] ^= sha.digest[3]; + sha.digest[0] ^= sha.digest[4]; + + (void)memcpy((void *)x, (void *)sha.digest, 8); +} + /* Strip trailing cr/lf from a line of text */ void rip(buf) @@ -359,29 +415,29 @@ sevenbit(s) *s++ &= 0x7f; } -/* Set MDX type (returns previous) */ -int -skey_set_MDX(new) - int new; +/* Set hash type type */ +char * +skey_set_algorithm(new) + char *new; { - int old; + int i; - if (new != 4 && new != 5) - return -1; + for (i = 0; i < SKEY_ALGORITH_MAX; i++) { + /* XXX - should be case *sensitive* */ + if (strcasecmp(new, skey_algorithm_table[i].name) == 0) { + skey_hash_type = i; + return(new); + } + } - old = skey_get_MDX(); - skey_MDX = new; - return old; + return(NULL); } -/* Get current MDX type */ -int -skey_get_MDX() +/* Get current hash type */ +const char * +skey_get_algorithm() { - if (skey_MDX == 0) - skey_MDX = SKEY_MDX_DEFAULT; - - return skey_MDX; + return(skey_algorithm_table[skey_hash_type].name); } /* Turn echo on/off */ -- cgit v1.2.3