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