xref: /netbsd-src/external/bsd/ntp/dist/sntp/crypto.c (revision b1c86f5f087524e68db12794ee9c3e3da1ab17a0)
1 /*	$NetBSD: crypto.c,v 1.1.1.1 2009/12/13 16:57:10 kardel Exp $	*/
2 
3 #include "crypto.h"
4 
5 struct key *key_ptr;
6 int 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  */
13 int
14 auth_md5(
15 	char *pkt_data,
16 	int mac_size,
17 	struct key *cmp_key
18 	)
19 {
20 	register int 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 < 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  */
54 int
55 auth_init(
56 	const char *keyfile,
57 	struct key **keys
58 	)
59 {
60 	FILE *keyf = fopen(keyfile, "r");
61 	struct key *prev = NULL;
62 	register int a, line_limit;
63 	int scan_cnt, line_cnt = 0;
64 	char kbuf[96];
65 
66 	if (keyf == NULL) {
67 		if (ENABLED_OPT(NORMALVERBOSE))
68 			printf("sntp auth_init: Couldn't open key file %s for reading!\n", keyfile);
69 
70 		return -1;
71 	}
72 
73 	line_cnt = 0;
74 
75 	if (feof(keyf)) {
76 		if (ENABLED_OPT(NORMALVERBOSE))
77 			printf("sntp auth_init: Key file %s is empty!\n", keyfile);
78 		fclose(keyf);
79 
80 		return -1;
81 	}
82 
83 	while (!feof(keyf)) {
84 		struct key *act = emalloc(sizeof(struct key));
85 		line_limit = 0;
86 
87 		fgets(kbuf, sizeof(kbuf), keyf);
88 
89 		for (a = 0; a < strlen(kbuf) && a < sizeof(kbuf); a++) {
90 			if (kbuf[a] == '#') {
91 				line_limit = a;
92 				break;
93 			}
94 		}
95 
96 		if (line_limit != 0)
97 			kbuf[line_limit] = '\0';
98 
99 #ifdef DEBUG
100 		printf("sntp auth_init: fgets: %s", kbuf);
101 #endif
102 
103 
104 		if ((scan_cnt = sscanf(kbuf, "%i %c %16s", &act->key_id, &act->type, act->key_seq)) == 3) {
105 			act->key_len = strlen(act->key_seq);
106 			act->next = NULL;
107 
108 			if (NULL == prev)
109 				*keys = act;
110 			else
111 				prev->next = act;
112 			prev = act;
113 
114 			key_cnt++;
115 
116 #ifdef DEBUG
117 			printf("sntp auth_init: key_id %i type %c with key %s\n", act->key_id, act->type, act->key_seq);
118 #endif
119 		} else {
120 #ifdef DEBUG
121 			printf("sntp auth_init: scanf read %i items, doesn't look good, skipping line %i.\n", scan_cnt, line_cnt);
122 #endif
123 
124 			free(act);
125 		}
126 
127 		line_cnt++;
128 	}
129 
130 	fclose(keyf);
131 
132 #ifdef DEBUG
133 	STDLINE
134 	printf("sntp auth_init: Read %i keys from file %s:\n", line_cnt, keyfile);
135 
136 	{
137 		struct key *kptr = *keys;
138 
139 		for (a = 0; a < key_cnt; a++) {
140 			printf("key_id %i type %c with key %s (key length: %i)\n",
141 			       kptr->key_id, kptr->type, kptr->key_seq, kptr->key_len);
142 			kptr = kptr->next;
143 		}
144 	}
145 	STDLINE
146 #endif
147 
148 	key_cnt = line_cnt;
149 	key_ptr = *keys;
150 
151 	return line_cnt;
152 }
153 
154 /* Looks for the key with keyid key_id and sets the d_key pointer to the
155  * address of the key. If no matching key is found the pointer is not touched.
156  */
157 void
158 get_key(
159 	int key_id,
160 	struct key **d_key
161 	)
162 {
163 	register int a;
164 	struct key *itr_key = key_ptr;
165 
166 	if (key_cnt == 0)
167 		return;
168 
169 	for (a = 0; a < key_cnt && itr_key != NULL; a++) {
170 		if (itr_key->key_id == key_id) {
171 			*d_key = itr_key;
172 			return;
173 		}
174 	}
175 
176 	return;
177 }
178