1#include "crypto.h" 2 3struct key *key_ptr; 4int key_cnt = 0; 5 6/* Generates a md5 digest of the ntp packet (exluding the MAC) concatinated 7 * with the key specified in keyid and compares this digest to the digest in 8 * the packet's MAC. If they're equal this function returns 1 (packet is 9 * authentic) or else 0 (not authentic). 10 */ 11int 12auth_md5( 13 char *pkt_data, 14 int mac_size, 15 struct key *cmp_key 16 ) 17{ 18 register int a; 19 char digest[16]; 20 MD5_CTX ctx; 21 char *digest_data; 22 23 if (cmp_key->type != 'M') 24 return -1; 25 26 MD5Init(&ctx); 27 28 digest_data = emalloc(sizeof(char) * (LEN_PKT_NOMAC + cmp_key->key_len)); 29 30 for (a = 0; a < LEN_PKT_NOMAC; a++) 31 digest_data[a] = pkt_data[a]; 32 33 for (a = 0; a < cmp_key->key_len; a++) 34 digest_data[LEN_PKT_NOMAC + a] = cmp_key->key_seq[a]; 35 36 MD5Update(&ctx, (u_char *)digest_data, LEN_PKT_NOMAC + cmp_key->key_len); 37 MD5Final((u_char *)digest, &ctx); 38 39 free(digest_data); 40 41 for (a = 0; a < 16; a++) 42 if (digest[a] != pkt_data[LEN_PKT_MAC + a]) 43 return 0; 44 45 return 1; 46} 47 48/* Load keys from the specified keyfile into the key structures. 49 * Returns -1 if the reading failed, otherwise it returns the 50 * number of keys it read 51 */ 52int 53auth_init( 54 const char *keyfile, 55 struct key **keys 56 ) 57{ 58 FILE *keyf = fopen(keyfile, "r"); 59 struct key *prev = NULL; 60 register int a, line_limit; 61 int scan_cnt, line_cnt = 0; 62 char kbuf[96]; 63 64 if (keyf == NULL) { 65 if (ENABLED_OPT(NORMALVERBOSE)) 66 printf("sntp auth_init: Couldn't open key file %s for reading!\n", keyfile); 67 68 return -1; 69 } 70 71 line_cnt = 0; 72 73 if (feof(keyf)) { 74 if (ENABLED_OPT(NORMALVERBOSE)) 75 printf("sntp auth_init: Key file %s is empty!\n", keyfile); 76 fclose(keyf); 77 78 return -1; 79 } 80 81 while (!feof(keyf)) { 82 struct key *act = emalloc(sizeof(struct key)); 83 line_limit = 0; 84 85 fgets(kbuf, sizeof(kbuf), keyf); 86 87 for (a = 0; a < strlen(kbuf) && a < sizeof(kbuf); a++) { 88 if (kbuf[a] == '#') { 89 line_limit = a; 90 break; 91 } 92 } 93 94 if (line_limit != 0) 95 kbuf[line_limit] = '\0'; 96 97#ifdef DEBUG 98 printf("sntp auth_init: fgets: %s", kbuf); 99#endif 100 101 102 if ((scan_cnt = sscanf(kbuf, "%i %c %16s", &act->key_id, &act->type, act->key_seq)) == 3) { 103 act->key_len = strlen(act->key_seq); 104 act->next = NULL; 105 106 if (NULL == prev) 107 *keys = act; 108 else 109 prev->next = act; 110 prev = act; 111 112 key_cnt++; 113 114#ifdef DEBUG 115 printf("sntp auth_init: key_id %i type %c with key %s\n", act->key_id, act->type, act->key_seq); 116#endif 117 } else { 118#ifdef DEBUG 119 printf("sntp auth_init: scanf read %i items, doesn't look good, skipping line %i.\n", scan_cnt, line_cnt); 120#endif 121 122 free(act); 123 } 124 125 line_cnt++; 126 } 127 128 fclose(keyf); 129 130#ifdef DEBUG 131 STDLINE 132 printf("sntp auth_init: Read %i keys from file %s:\n", line_cnt, keyfile); 133 134 { 135 struct key *kptr = *keys; 136 137 for (a = 0; a < key_cnt; a++) { 138 printf("key_id %i type %c with key %s (key length: %i)\n", 139 kptr->key_id, kptr->type, kptr->key_seq, kptr->key_len); 140 kptr = kptr->next; 141 } 142 } 143 STDLINE 144#endif 145 146 key_cnt = line_cnt; 147 key_ptr = *keys; 148 149 return line_cnt; 150} 151 152/* Looks for the key with keyid key_id and sets the d_key pointer to the 153 * address of the key. If no matching key is found the pointer is not touched. 154 */ 155void 156get_key( 157 int key_id, 158 struct key **d_key 159 ) 160{ 161 register int a; 162 struct key *itr_key = key_ptr; 163 164 if (key_cnt == 0) 165 return; 166 167 for (a = 0; a < key_cnt && itr_key != NULL; a++) { 168 if (itr_key->key_id == key_id) { 169 *d_key = itr_key; 170 return; 171 } 172 } 173 174 return; 175} 176