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 #define KEY_TYPE_MD5 4 28 29 int 30 authusekey( 31 keyid_t keyno, 32 int keytype, 33 const u_char *str 34 ) 35 { 36 #ifdef DES 37 u_int32 key[2]; 38 u_char keybytes[8]; 39 char *xdigit; 40 int i; 41 static const char *hex = "0123456789abcdef"; 42 #endif 43 const u_char *cp; 44 int len; 45 46 cp = str; 47 len = strlen((const char *)cp); 48 if (len == 0) 49 return 0; 50 51 switch(keytype) { 52 #ifdef DES 53 case KEY_TYPE_STD: 54 case KEY_TYPE_NTP: 55 if (len != 16) /* Lazy. Should define constant */ 56 return 0; 57 /* 58 * Decode hex key. 59 */ 60 key[0] = 0; 61 key[1] = 0; 62 for (i = 0; i < 16; i++) { 63 if (!isascii(*cp)) 64 return 0; 65 xdigit = strchr(hex, isupper(*cp) ? tolower(*cp) : *cp); 66 cp++; 67 if (xdigit == 0) 68 return 0; 69 key[i>>3] <<= 4; 70 key[i>>3] |= (u_int32)(xdigit - hex) & 0xf; 71 } 72 73 /* 74 * If this is an NTP format key, put it into NBS format 75 */ 76 if (keytype == KEY_TYPE_NTP) { 77 for (i = 0; i < 2; i++) 78 key[i] = ((key[i] << 1) & ~STD_PARITY_BITS) 79 | ((key[i] >> 7) & STD_PARITY_BITS); 80 } 81 82 /* 83 * Check the parity, reject the key if the check fails 84 */ 85 if (!DESauth_parity(key)) { 86 return 0; 87 } 88 89 /* 90 * We can't find a good reason not to use this key. 91 * So use it. 92 */ 93 DESauth_setkey(keyno, key); 94 break; 95 96 case KEY_TYPE_ASCII: 97 /* 98 * Make up key from ascii representation 99 */ 100 memset((char *) keybytes, 0, sizeof(keybytes)); 101 for (i = 0; i < 8 && i < len; i++) 102 keybytes[i] = *cp++ << 1; 103 key[0] = (u_int32)keybytes[0] << 24 | (u_int32)keybytes[1] << 16 104 | (u_int32)keybytes[2] << 8 | (u_int32)keybytes[3]; 105 key[1] = (u_int32)keybytes[4] << 24 | (u_int32)keybytes[5] << 16 106 | (u_int32)keybytes[6] << 8 | (u_int32)keybytes[7]; 107 108 /* 109 * Set parity on key 110 */ 111 (void)DESauth_parity(key); 112 113 /* 114 * Now set key in. 115 */ 116 DESauth_setkey(keyno, key); 117 break; 118 #endif 119 120 case KEY_TYPE_MD5: 121 MD5auth_setkey(keyno, str, (int)strlen((const char *)str)); 122 break; 123 124 default: 125 /* Oh, well */ 126 return 0; 127 } 128 129 return 1; 130 } 131