File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / ntp / sntp / crypto.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue May 29 12:08:38 2012 UTC (12 years, 2 months ago) by misho
Branches: ntp, MAIN
CVS tags: v4_2_6p5p0, v4_2_6p5, HEAD
ntp 4.2.6p5

    1: #include <config.h>
    2: #include "crypto.h"
    3: #include <ctype.h>
    4: 
    5: struct key *key_ptr;
    6: int 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 > 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 (ENABLED_OPT(NORMALVERBOSE))
  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 (ENABLED_OPT(NORMALVERBOSE))
  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 = emalloc(sizeof(struct key));
  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: 		scan_cnt = sscanf(kbuf, "%d %9s %128s", &act->key_id, act->type, keystring);
  126: 		if (scan_cnt == 3) {
  127: 			int len = strlen(keystring);
  128: 			if (len <= 20) {
  129: 				act->key_len = len;
  130: 				memcpy(act->key_seq, keystring, len + 1);
  131: 				goodline = 1;
  132: 			} else if ((len & 1) != 0) {
  133: 				goodline = 0; /* it's bad */
  134: 			} else {
  135: 				int j;
  136: 				goodline = 1;
  137: 				act->key_len = len >> 1;
  138: 				for (j = 0; j < len; j+=2) {
  139: 					int val;
  140: 					val = (hex_val(keystring[j]) << 4) |
  141: 					       hex_val(keystring[j+1]);
  142: 					if (val < 0) {
  143: 						goodline = 0; /* it's bad */
  144: 						break;
  145: 					}
  146: 					act->key_seq[j>>1] = (char)val;
  147: 				}
  148: 			}
  149: 		}
  150: 		if (goodline) {
  151: 			act->next = NULL;
  152: 			if (NULL == prev)
  153: 				*keys = act;
  154: 			else
  155: 				prev->next = act;
  156: 			prev = act;
  157: 			key_cnt++;
  158: 		} else {
  159: 			msyslog(LOG_DEBUG, "auth_init: scanf %d items, skipping line %d.",
  160: 				scan_cnt, line_cnt);
  161: 			free(act);
  162: 		}
  163: 		line_cnt++;
  164: 	}
  165: 	fclose(keyf);
  166: 	
  167: 	key_ptr = *keys;
  168: 	return key_cnt;
  169: }
  170: 
  171: /* Looks for the key with keyid key_id and sets the d_key pointer to the 
  172:  * address of the key. If no matching key is found the pointer is not touched.
  173:  */
  174: void
  175: get_key(
  176: 	int key_id,
  177: 	struct key **d_key
  178: 	)
  179: {
  180: 	struct key *itr_key;
  181: 
  182: 	if (key_cnt == 0)
  183: 		return;
  184: 	for (itr_key = key_ptr; itr_key; itr_key = itr_key->next) {
  185: 		if (itr_key->key_id == key_id) {
  186: 			*d_key = itr_key;
  187: 			break;
  188: 		}
  189: 	}
  190: 	return;
  191: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>