crypto.c revision 258945
1258945Sroberto#include <config.h> 2258945Sroberto#include "crypto.h" 3258945Sroberto#include <ctype.h> 4258945Sroberto 5258945Srobertostruct key *key_ptr; 6258945Srobertoint key_cnt = 0; 7258945Sroberto 8258945Srobertoint 9258945Srobertomake_mac( 10258945Sroberto char *pkt_data, 11258945Sroberto int pkt_size, 12258945Sroberto int mac_size, 13258945Sroberto struct key *cmp_key, 14258945Sroberto char * digest 15258945Sroberto ) 16258945Sroberto{ 17258945Sroberto u_int len = mac_size; 18258945Sroberto int key_type; 19258945Sroberto EVP_MD_CTX ctx; 20258945Sroberto 21258945Sroberto if (cmp_key->key_len > 64) 22258945Sroberto return 0; 23258945Sroberto if (pkt_size % 4 != 0) 24258945Sroberto return 0; 25258945Sroberto 26258945Sroberto INIT_SSL(); 27258945Sroberto key_type = keytype_from_text(cmp_key->type, NULL); 28258945Sroberto EVP_DigestInit(&ctx, EVP_get_digestbynid(key_type)); 29258945Sroberto EVP_DigestUpdate(&ctx, (u_char *)cmp_key->key_seq, (u_int)cmp_key->key_len); 30258945Sroberto EVP_DigestUpdate(&ctx, (u_char *)pkt_data, (u_int)pkt_size); 31258945Sroberto EVP_DigestFinal(&ctx, (u_char *)digest, &len); 32258945Sroberto 33258945Sroberto return (int)len; 34258945Sroberto} 35258945Sroberto 36258945Sroberto 37258945Sroberto/* Generates a md5 digest of the key specified in keyid concatinated with the 38258945Sroberto * ntp packet (exluding the MAC) and compares this digest to the digest in 39258945Sroberto * the packet's MAC. If they're equal this function returns 1 (packet is 40258945Sroberto * authentic) or else 0 (not authentic). 41258945Sroberto */ 42258945Srobertoint 43258945Srobertoauth_md5( 44258945Sroberto char *pkt_data, 45258945Sroberto int pkt_size, 46258945Sroberto int mac_size, 47258945Sroberto struct key *cmp_key 48258945Sroberto ) 49258945Sroberto{ 50258945Sroberto int hash_len; 51258945Sroberto int authentic; 52258945Sroberto char digest[20]; 53258945Sroberto 54258945Sroberto if (mac_size > sizeof(digest)) 55258945Sroberto return 0; 56258945Sroberto hash_len = make_mac(pkt_data, pkt_size, sizeof(digest), cmp_key, 57258945Sroberto digest); 58258945Sroberto if (!hash_len) 59258945Sroberto authentic = FALSE; 60258945Sroberto else 61258945Sroberto authentic = !memcmp(digest, pkt_data + pkt_size + 4, 62258945Sroberto hash_len); 63258945Sroberto return authentic; 64258945Sroberto} 65258945Sroberto 66258945Srobertostatic int 67258945Srobertohex_val( 68258945Sroberto unsigned char x 69258945Sroberto ) 70258945Sroberto{ 71258945Sroberto int val; 72258945Sroberto 73258945Sroberto if ('0' <= x && x <= '9') 74258945Sroberto val = x - '0'; 75258945Sroberto else if ('a' <= x && x <= 'f') 76258945Sroberto val = x - 'a' + 0xa; 77258945Sroberto else if ('A' <= x && x <= 'F') 78258945Sroberto val = x - 'A' + 0xA; 79258945Sroberto else 80258945Sroberto val = -1; 81258945Sroberto 82258945Sroberto return val; 83258945Sroberto} 84258945Sroberto 85258945Sroberto/* Load keys from the specified keyfile into the key structures. 86258945Sroberto * Returns -1 if the reading failed, otherwise it returns the 87258945Sroberto * number of keys it read 88258945Sroberto */ 89258945Srobertoint 90258945Srobertoauth_init( 91258945Sroberto const char *keyfile, 92258945Sroberto struct key **keys 93258945Sroberto ) 94258945Sroberto{ 95258945Sroberto FILE *keyf = fopen(keyfile, "r"); 96258945Sroberto struct key *prev = NULL; 97258945Sroberto int scan_cnt, line_cnt = 0; 98258945Sroberto char kbuf[200]; 99258945Sroberto char keystring[129]; 100258945Sroberto 101258945Sroberto if (keyf == NULL) { 102258945Sroberto if (ENABLED_OPT(NORMALVERBOSE)) 103258945Sroberto printf("sntp auth_init: Couldn't open key file %s for reading!\n", keyfile); 104258945Sroberto return -1; 105258945Sroberto } 106258945Sroberto if (feof(keyf)) { 107258945Sroberto if (ENABLED_OPT(NORMALVERBOSE)) 108258945Sroberto printf("sntp auth_init: Key file %s is empty!\n", keyfile); 109258945Sroberto fclose(keyf); 110258945Sroberto return -1; 111258945Sroberto } 112258945Sroberto key_cnt = 0; 113258945Sroberto while (!feof(keyf)) { 114258945Sroberto char * octothorpe; 115258945Sroberto struct key *act = emalloc(sizeof(struct key)); 116258945Sroberto int goodline = 0; 117258945Sroberto 118258945Sroberto if (NULL == fgets(kbuf, sizeof(kbuf), keyf)) 119258945Sroberto continue; 120258945Sroberto 121258945Sroberto kbuf[sizeof(kbuf) - 1] = '\0'; 122258945Sroberto octothorpe = strchr(kbuf, '#'); 123258945Sroberto if (octothorpe) 124258945Sroberto *octothorpe = '\0'; 125258945Sroberto scan_cnt = sscanf(kbuf, "%d %9s %128s", &act->key_id, act->type, keystring); 126258945Sroberto if (scan_cnt == 3) { 127258945Sroberto int len = strlen(keystring); 128258945Sroberto if (len <= 20) { 129258945Sroberto act->key_len = len; 130258945Sroberto memcpy(act->key_seq, keystring, len + 1); 131258945Sroberto goodline = 1; 132258945Sroberto } else if ((len & 1) != 0) { 133258945Sroberto goodline = 0; /* it's bad */ 134258945Sroberto } else { 135258945Sroberto int j; 136258945Sroberto goodline = 1; 137258945Sroberto act->key_len = len >> 1; 138258945Sroberto for (j = 0; j < len; j+=2) { 139258945Sroberto int val; 140258945Sroberto val = (hex_val(keystring[j]) << 4) | 141258945Sroberto hex_val(keystring[j+1]); 142258945Sroberto if (val < 0) { 143258945Sroberto goodline = 0; /* it's bad */ 144258945Sroberto break; 145258945Sroberto } 146258945Sroberto act->key_seq[j>>1] = (char)val; 147258945Sroberto } 148258945Sroberto } 149258945Sroberto } 150258945Sroberto if (goodline) { 151258945Sroberto act->next = NULL; 152258945Sroberto if (NULL == prev) 153258945Sroberto *keys = act; 154258945Sroberto else 155258945Sroberto prev->next = act; 156258945Sroberto prev = act; 157258945Sroberto key_cnt++; 158258945Sroberto } else { 159258945Sroberto msyslog(LOG_DEBUG, "auth_init: scanf %d items, skipping line %d.", 160258945Sroberto scan_cnt, line_cnt); 161258945Sroberto free(act); 162258945Sroberto } 163258945Sroberto line_cnt++; 164258945Sroberto } 165258945Sroberto fclose(keyf); 166258945Sroberto 167258945Sroberto key_ptr = *keys; 168258945Sroberto return key_cnt; 169258945Sroberto} 170258945Sroberto 171258945Sroberto/* Looks for the key with keyid key_id and sets the d_key pointer to the 172258945Sroberto * address of the key. If no matching key is found the pointer is not touched. 173258945Sroberto */ 174258945Srobertovoid 175258945Srobertoget_key( 176258945Sroberto int key_id, 177258945Sroberto struct key **d_key 178258945Sroberto ) 179258945Sroberto{ 180258945Sroberto struct key *itr_key; 181258945Sroberto 182258945Sroberto if (key_cnt == 0) 183258945Sroberto return; 184258945Sroberto for (itr_key = key_ptr; itr_key; itr_key = itr_key->next) { 185258945Sroberto if (itr_key->key_id == key_id) { 186258945Sroberto *d_key = itr_key; 187258945Sroberto break; 188258945Sroberto } 189258945Sroberto } 190258945Sroberto return; 191258945Sroberto} 192