Patrick Welche <prlw1@cam.ac.uk>
[netbsd-mini2440.git] / external / bsd / ntp / dist / sntp / crypto.c
blob265d49b942d4b31be2b58e9511da4b1351883ecf
1 /* $NetBSD$ */
3 #include "crypto.h"
5 struct key *key_ptr;
6 int key_cnt = 0;
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).
13 int
14 auth_md5(
15 char *pkt_data,
16 int mac_size,
17 struct key *cmp_key
20 register int a;
21 char digest[16];
22 MD5_CTX ctx;
23 char *digest_data;
25 if (cmp_key->type != 'M')
26 return -1;
28 MD5Init(&ctx);
30 digest_data = emalloc(sizeof(char) * (LEN_PKT_NOMAC + cmp_key->key_len));
32 for (a = 0; a < LEN_PKT_NOMAC; a++)
33 digest_data[a] = pkt_data[a];
35 for (a = 0; a < cmp_key->key_len; a++)
36 digest_data[LEN_PKT_NOMAC + a] = cmp_key->key_seq[a];
38 MD5Update(&ctx, (u_char *)digest_data, LEN_PKT_NOMAC + cmp_key->key_len);
39 MD5Final((u_char *)digest, &ctx);
41 free(digest_data);
43 for (a = 0; a < 16; a++)
44 if (digest[a] != pkt_data[LEN_PKT_MAC + a])
45 return 0;
47 return 1;
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
54 int
55 auth_init(
56 const char *keyfile,
57 struct key **keys
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];
66 if (keyf == NULL) {
67 if (ENABLED_OPT(NORMALVERBOSE))
68 printf("sntp auth_init: Couldn't open key file %s for reading!\n", keyfile);
70 return -1;
73 line_cnt = 0;
75 if (feof(keyf)) {
76 if (ENABLED_OPT(NORMALVERBOSE))
77 printf("sntp auth_init: Key file %s is empty!\n", keyfile);
78 fclose(keyf);
80 return -1;
83 while (!feof(keyf)) {
84 struct key *act = emalloc(sizeof(struct key));
85 line_limit = 0;
87 fgets(kbuf, sizeof(kbuf), keyf);
89 for (a = 0; a < strlen(kbuf) && a < sizeof(kbuf); a++) {
90 if (kbuf[a] == '#') {
91 line_limit = a;
92 break;
96 if (line_limit != 0)
97 kbuf[line_limit] = '\0';
99 #ifdef DEBUG
100 printf("sntp auth_init: fgets: %s", kbuf);
101 #endif
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;
108 if (NULL == prev)
109 *keys = act;
110 else
111 prev->next = act;
112 prev = act;
114 key_cnt++;
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
124 free(act);
127 line_cnt++;
130 fclose(keyf);
132 #ifdef DEBUG
133 STDLINE
134 printf("sntp auth_init: Read %i keys from file %s:\n", line_cnt, keyfile);
137 struct key *kptr = *keys;
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;
145 STDLINE
146 #endif
148 key_cnt = line_cnt;
149 key_ptr = *keys;
151 return line_cnt;
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.
157 void
158 get_key(
159 int key_id,
160 struct key **d_key
163 register int a;
164 struct key *itr_key = key_ptr;
166 if (key_cnt == 0)
167 return;
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;
176 return;