1 /* 2 * authusekey - decode a key from ascii and use it 3 */ 4 #include <stdio.h> 5 #include <ctype.h> 6 7 #include "ntp_types.h" 8 #include "ntp_string.h" 9 #include "ntp_stdlib.h" 10 11 /* 12 * Types of ascii representations for keys. "Standard" means a 64 bit 13 * hex number in NBS format, i.e. with the low order bit of each byte 14 * a parity bit. "NTP" means a 64 bit key in NTP format, with the 15 * high order bit of each byte a parity bit. "Ascii" means a 1-to-8 16 * character string whose ascii representation is used as the key. 17 */ 18 #ifdef DES 19 #define KEY_TYPE_STD 1 20 #define KEY_TYPE_NTP 2 21 #define KEY_TYPE_ASCII 3 22 23 #define STD_PARITY_BITS ((unsigned)0x01010101) 24 25 #endif 26 27 #ifdef MD5 28 #define KEY_TYPE_MD5 4 29 #endif 30 31 int 32 authusekey( 33 u_long keyno, 34 int keytype, 35 const u_char *str 36 ) 37 { 38 #ifdef DES 39 u_int32 key[2]; 40 u_char keybytes[8]; 41 char *xdigit; 42 int i; 43 static const char *hex = "0123456789abcdef"; 44 #endif 45 const u_char *cp; 46 int len; 47 48 cp = str; 49 len = strlen((const char *)cp); 50 if (len == 0) 51 return 0; 52 53 switch(keytype) { 54 #ifdef DES 55 case KEY_TYPE_STD: 56 case KEY_TYPE_NTP: 57 if (len != 16) /* Lazy. Should define constant */ 58 return 0; 59 /* 60 * Decode hex key. 61 */ 62 key[0] = 0; 63 key[1] = 0; 64 for (i = 0; i < 16; i++) { 65 if (!isascii(*cp)) 66 return 0; 67 xdigit = strchr(hex, isupper(*cp) ? tolower(*cp) : *cp); 68 cp++; 69 if (xdigit == 0) 70 return 0; 71 key[i>>3] <<= 4; 72 key[i>>3] |= (u_int32)(xdigit - hex) & 0xf; 73 } 74 75 /* 76 * If this is an NTP format key, put it into NBS format 77 */ 78 if (keytype == KEY_TYPE_NTP) { 79 for (i = 0; i < 2; i++) 80 key[i] = ((key[i] << 1) & ~STD_PARITY_BITS) 81 | ((key[i] >> 7) & STD_PARITY_BITS); 82 } 83 84 /* 85 * Check the parity, reject the key if the check fails 86 */ 87 if (!DESauth_parity(key)) { 88 return 0; 89 } 90 91 /* 92 * We can't find a good reason not to use this key. 93 * So use it. 94 */ 95 DESauth_setkey(keyno, key); 96 break; 97 98 case KEY_TYPE_ASCII: 99 /* 100 * Make up key from ascii representation 101 */ 102 memset((char *) keybytes, 0, sizeof(keybytes)); 103 for (i = 0; i < 8 && i < len; i++) 104 keybytes[i] = *cp++ << 1; 105 key[0] = (u_int32)keybytes[0] << 24 | (u_int32)keybytes[1] << 16 106 | (u_int32)keybytes[2] << 8 | (u_int32)keybytes[3]; 107 key[1] = (u_int32)keybytes[4] << 24 | (u_int32)keybytes[5] << 16 108 | (u_int32)keybytes[6] << 8 | (u_int32)keybytes[7]; 109 110 /* 111 * Set parity on key 112 */ 113 (void)DESauth_parity(key); 114 115 /* 116 * Now set key in. 117 */ 118 DESauth_setkey(keyno, key); 119 break; 120 #endif 121 122 #ifdef MD5 123 case KEY_TYPE_MD5: 124 MD5auth_setkey(keyno, str, (int)strlen((const char *)str)); 125 break; 126 #endif 127 128 default: 129 /* Oh, well */ 130 return 0; 131 } 132 133 return 1; 134 } 135