/* $NetBSD: authusekey.c,v 1.1.1.2 2000/04/22 14:52:56 simonb Exp $ */ /* * authusekey - decode a key from ascii and use it */ #include #include #include "ntp_types.h" #include "ntp_string.h" #include "ntp_stdlib.h" /* * Types of ascii representations for keys. "Standard" means a 64 bit * hex number in NBS format, i.e. with the low order bit of each byte * a parity bit. "NTP" means a 64 bit key in NTP format, with the * high order bit of each byte a parity bit. "Ascii" means a 1-to-8 * character string whose ascii representation is used as the key. */ #ifdef DES #define KEY_TYPE_STD 1 #define KEY_TYPE_NTP 2 #define KEY_TYPE_ASCII 3 #define STD_PARITY_BITS ((unsigned)0x01010101) #endif #ifdef MD5 #define KEY_TYPE_MD5 4 #endif int authusekey( keyid_t keyno, int keytype, const u_char *str ) { #ifdef DES u_int32 key[2]; u_char keybytes[8]; char *xdigit; int i; static const char *hex = "0123456789abcdef"; #endif const u_char *cp; int len; cp = str; len = strlen((const char *)cp); if (len == 0) return 0; switch(keytype) { #ifdef DES case KEY_TYPE_STD: case KEY_TYPE_NTP: if (len != 16) /* Lazy. Should define constant */ return 0; /* * Decode hex key. */ key[0] = 0; key[1] = 0; for (i = 0; i < 16; i++) { if (!isascii(*cp)) return 0; xdigit = strchr(hex, isupper(*cp) ? tolower(*cp) : *cp); cp++; if (xdigit == 0) return 0; key[i>>3] <<= 4; key[i>>3] |= (u_int32)(xdigit - hex) & 0xf; } /* * If this is an NTP format key, put it into NBS format */ if (keytype == KEY_TYPE_NTP) { for (i = 0; i < 2; i++) key[i] = ((key[i] << 1) & ~STD_PARITY_BITS) | ((key[i] >> 7) & STD_PARITY_BITS); } /* * Check the parity, reject the key if the check fails */ if (!DESauth_parity(key)) { return 0; } /* * We can't find a good reason not to use this key. * So use it. */ DESauth_setkey(keyno, key); break; case KEY_TYPE_ASCII: /* * Make up key from ascii representation */ memset((char *) keybytes, 0, sizeof(keybytes)); for (i = 0; i < 8 && i < len; i++) keybytes[i] = *cp++ << 1; key[0] = (u_int32)keybytes[0] << 24 | (u_int32)keybytes[1] << 16 | (u_int32)keybytes[2] << 8 | (u_int32)keybytes[3]; key[1] = (u_int32)keybytes[4] << 24 | (u_int32)keybytes[5] << 16 | (u_int32)keybytes[6] << 8 | (u_int32)keybytes[7]; /* * Set parity on key */ (void)DESauth_parity(key); /* * Now set key in. */ DESauth_setkey(keyno, key); break; #endif #ifdef MD5 case KEY_TYPE_MD5: MD5auth_setkey(keyno, str, (int)strlen((const char *)str)); break; #endif default: /* Oh, well */ return 0; } return 1; }