1 #include <config.h> 2 #include "crypto.h" 3 #include <ctype.h> 4 5 struct key *key_ptr; 6 size_t key_cnt = 0; 7 8 int 9 make_mac( 10 char *pkt_data, 11 int pkt_size, 12 int mac_size, 13 struct key *cmp_key, 14 char * digest 15 ) 16 { 17 u_int len = mac_size; 18 int key_type; 19 EVP_MD_CTX ctx; 20 21 if (cmp_key->key_len > 64) 22 return 0; 23 if (pkt_size % 4 != 0) 24 return 0; 25 26 INIT_SSL(); 27 key_type = keytype_from_text(cmp_key->type, NULL); 28 EVP_DigestInit(&ctx, EVP_get_digestbynid(key_type)); 29 EVP_DigestUpdate(&ctx, (u_char *)cmp_key->key_seq, (u_int)cmp_key->key_len); 30 EVP_DigestUpdate(&ctx, (u_char *)pkt_data, (u_int)pkt_size); 31 EVP_DigestFinal(&ctx, (u_char *)digest, &len); 32 33 return (int)len; 34 } 35 36 37 /* Generates a md5 digest of the key specified in keyid concatinated with the 38 * ntp packet (exluding the MAC) and compares this digest to the digest in 39 * the packet's MAC. If they're equal this function returns 1 (packet is 40 * authentic) or else 0 (not authentic). 41 */ 42 int 43 auth_md5( 44 char *pkt_data, 45 int pkt_size, 46 int mac_size, 47 struct key *cmp_key 48 ) 49 { 50 int hash_len; 51 int authentic; 52 char digest[20]; 53 54 if (mac_size > (int)sizeof(digest)) 55 return 0; 56 hash_len = make_mac(pkt_data, pkt_size, sizeof(digest), cmp_key, 57 digest); 58 if (!hash_len) 59 authentic = FALSE; 60 else 61 authentic = !memcmp(digest, pkt_data + pkt_size + 4, 62 hash_len); 63 return authentic; 64 } 65 66 static int 67 hex_val( 68 unsigned char x 69 ) 70 { 71 int val; 72 73 if ('0' <= x && x <= '9') 74 val = x - '0'; 75 else if ('a' <= x && x <= 'f') 76 val = x - 'a' + 0xa; 77 else if ('A' <= x && x <= 'F') 78 val = x - 'A' + 0xA; 79 else 80 val = -1; 81 82 return val; 83 } 84 85 /* Load keys from the specified keyfile into the key structures. 86 * Returns -1 if the reading failed, otherwise it returns the 87 * number of keys it read 88 */ 89 int 90 auth_init( 91 const char *keyfile, 92 struct key **keys 93 ) 94 { 95 FILE *keyf = fopen(keyfile, "r"); 96 struct key *prev = NULL; 97 int scan_cnt, line_cnt = 0; 98 char kbuf[200]; 99 char keystring[129]; 100 101 if (keyf == NULL) { 102 if (debug) 103 printf("sntp auth_init: Couldn't open key file %s for reading!\n", keyfile); 104 return -1; 105 } 106 if (feof(keyf)) { 107 if (debug) 108 printf("sntp auth_init: Key file %s is empty!\n", keyfile); 109 fclose(keyf); 110 return -1; 111 } 112 key_cnt = 0; 113 while (!feof(keyf)) { 114 char * octothorpe; 115 struct key *act; 116 int goodline = 0; 117 118 if (NULL == fgets(kbuf, sizeof(kbuf), keyf)) 119 continue; 120 121 kbuf[sizeof(kbuf) - 1] = '\0'; 122 octothorpe = strchr(kbuf, '#'); 123 if (octothorpe) 124 *octothorpe = '\0'; 125 act = emalloc(sizeof(*act)); 126 scan_cnt = sscanf(kbuf, "%d %9s %128s", &act->key_id, act->type, keystring); 127 if (scan_cnt == 3) { 128 int len = strlen(keystring); 129 if (len <= 20) { 130 act->key_len = len; 131 memcpy(act->key_seq, keystring, len + 1); 132 goodline = 1; 133 } else if ((len & 1) != 0) { 134 goodline = 0; /* it's bad */ 135 } else { 136 int j; 137 goodline = 1; 138 act->key_len = len >> 1; 139 for (j = 0; j < len; j+=2) { 140 int val; 141 val = (hex_val(keystring[j]) << 4) | 142 hex_val(keystring[j+1]); 143 if (val < 0) { 144 goodline = 0; /* it's bad */ 145 break; 146 } 147 act->key_seq[j>>1] = (char)val; 148 } 149 } 150 } 151 if (goodline) { 152 act->next = NULL; 153 if (NULL == prev) 154 *keys = act; 155 else 156 prev->next = act; 157 prev = act; 158 key_cnt++; 159 } else { 160 msyslog(LOG_DEBUG, "auth_init: scanf %d items, skipping line %d.", 161 scan_cnt, line_cnt); 162 free(act); 163 } 164 line_cnt++; 165 } 166 fclose(keyf); 167 168 key_ptr = *keys; 169 return key_cnt; 170 } 171 172 /* Looks for the key with keyid key_id and sets the d_key pointer to the 173 * address of the key. If no matching key is found the pointer is not touched. 174 */ 175 void 176 get_key( 177 int key_id, 178 struct key **d_key 179 ) 180 { 181 struct key *itr_key; 182 183 if (key_cnt == 0) 184 return; 185 for (itr_key = key_ptr; itr_key; itr_key = itr_key->next) { 186 if (itr_key->key_id == key_id) { 187 *d_key = itr_key; 188 break; 189 } 190 } 191 return; 192 } 193