Annotation of embedaddon/ntp/sntp/crypto.c, revision 1.1.1.1
1.1 misho 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>