crypto.c revision 1.2.6.1 1 1.2.6.1 yamt /* $NetBSD: crypto.c,v 1.2.6.1 2012/04/17 00:03:50 yamt Exp $ */
2 1.1 kardel
3 1.2.6.1 yamt #include <config.h>
4 1.1 kardel #include "crypto.h"
5 1.2.6.1 yamt #include <ctype.h>
6 1.1 kardel
7 1.1 kardel struct key *key_ptr;
8 1.2 christos size_t key_cnt = 0;
9 1.1 kardel
10 1.2.6.1 yamt int
11 1.2.6.1 yamt make_mac(
12 1.2.6.1 yamt char *pkt_data,
13 1.2.6.1 yamt int pkt_size,
14 1.2.6.1 yamt int mac_size,
15 1.2.6.1 yamt struct key *cmp_key,
16 1.2.6.1 yamt char * digest
17 1.2.6.1 yamt )
18 1.2.6.1 yamt {
19 1.2.6.1 yamt u_int len = mac_size;
20 1.2.6.1 yamt int key_type;
21 1.2.6.1 yamt EVP_MD_CTX ctx;
22 1.2.6.1 yamt
23 1.2.6.1 yamt if (cmp_key->key_len > 64)
24 1.2.6.1 yamt return 0;
25 1.2.6.1 yamt if (pkt_size % 4 != 0)
26 1.2.6.1 yamt return 0;
27 1.2.6.1 yamt
28 1.2.6.1 yamt INIT_SSL();
29 1.2.6.1 yamt key_type = keytype_from_text(cmp_key->type, NULL);
30 1.2.6.1 yamt EVP_DigestInit(&ctx, EVP_get_digestbynid(key_type));
31 1.2.6.1 yamt EVP_DigestUpdate(&ctx, (u_char *)cmp_key->key_seq, (u_int)cmp_key->key_len);
32 1.2.6.1 yamt EVP_DigestUpdate(&ctx, (u_char *)pkt_data, (u_int)pkt_size);
33 1.2.6.1 yamt EVP_DigestFinal(&ctx, (u_char *)digest, &len);
34 1.2.6.1 yamt
35 1.2.6.1 yamt return (int)len;
36 1.2.6.1 yamt }
37 1.2.6.1 yamt
38 1.2.6.1 yamt
39 1.2.6.1 yamt /* Generates a md5 digest of the key specified in keyid concatinated with the
40 1.2.6.1 yamt * ntp packet (exluding the MAC) and compares this digest to the digest in
41 1.1 kardel * the packet's MAC. If they're equal this function returns 1 (packet is
42 1.1 kardel * authentic) or else 0 (not authentic).
43 1.1 kardel */
44 1.1 kardel int
45 1.1 kardel auth_md5(
46 1.1 kardel char *pkt_data,
47 1.2.6.1 yamt int pkt_size,
48 1.1 kardel int mac_size,
49 1.1 kardel struct key *cmp_key
50 1.1 kardel )
51 1.1 kardel {
52 1.2.6.1 yamt int hash_len;
53 1.2.6.1 yamt int authentic;
54 1.2.6.1 yamt char digest[20];
55 1.2.6.1 yamt
56 1.2.6.1 yamt if (mac_size > (int)sizeof(digest))
57 1.2.6.1 yamt return 0;
58 1.2.6.1 yamt hash_len = make_mac(pkt_data, pkt_size, sizeof(digest), cmp_key,
59 1.2.6.1 yamt digest);
60 1.2.6.1 yamt if (!hash_len)
61 1.2.6.1 yamt authentic = FALSE;
62 1.2.6.1 yamt else
63 1.2.6.1 yamt authentic = !memcmp(digest, pkt_data + pkt_size + 4,
64 1.2.6.1 yamt hash_len);
65 1.2.6.1 yamt return authentic;
66 1.2.6.1 yamt }
67 1.1 kardel
68 1.2.6.1 yamt static int
69 1.2.6.1 yamt hex_val(
70 1.2.6.1 yamt unsigned char x
71 1.2.6.1 yamt )
72 1.2.6.1 yamt {
73 1.2.6.1 yamt int val;
74 1.1 kardel
75 1.2.6.1 yamt if ('0' <= x && x <= '9')
76 1.2.6.1 yamt val = x - '0';
77 1.2.6.1 yamt else if ('a' <= x && x <= 'f')
78 1.2.6.1 yamt val = x - 'a' + 0xa;
79 1.2.6.1 yamt else if ('A' <= x && x <= 'F')
80 1.2.6.1 yamt val = x - 'A' + 0xA;
81 1.2.6.1 yamt else
82 1.2.6.1 yamt val = -1;
83 1.1 kardel
84 1.2.6.1 yamt return val;
85 1.1 kardel }
86 1.1 kardel
87 1.1 kardel /* Load keys from the specified keyfile into the key structures.
88 1.1 kardel * Returns -1 if the reading failed, otherwise it returns the
89 1.1 kardel * number of keys it read
90 1.1 kardel */
91 1.1 kardel int
92 1.1 kardel auth_init(
93 1.1 kardel const char *keyfile,
94 1.1 kardel struct key **keys
95 1.1 kardel )
96 1.1 kardel {
97 1.1 kardel FILE *keyf = fopen(keyfile, "r");
98 1.1 kardel struct key *prev = NULL;
99 1.1 kardel int scan_cnt, line_cnt = 0;
100 1.2.6.1 yamt char kbuf[200];
101 1.2.6.1 yamt char keystring[129];
102 1.1 kardel
103 1.1 kardel if (keyf == NULL) {
104 1.1 kardel if (ENABLED_OPT(NORMALVERBOSE))
105 1.1 kardel printf("sntp auth_init: Couldn't open key file %s for reading!\n", keyfile);
106 1.1 kardel return -1;
107 1.1 kardel }
108 1.1 kardel if (feof(keyf)) {
109 1.1 kardel if (ENABLED_OPT(NORMALVERBOSE))
110 1.1 kardel printf("sntp auth_init: Key file %s is empty!\n", keyfile);
111 1.1 kardel fclose(keyf);
112 1.1 kardel return -1;
113 1.1 kardel }
114 1.2.6.1 yamt key_cnt = 0;
115 1.1 kardel while (!feof(keyf)) {
116 1.2.6.1 yamt char * octothorpe;
117 1.1 kardel struct key *act = emalloc(sizeof(struct key));
118 1.2.6.1 yamt int goodline = 0;
119 1.2.6.1 yamt
120 1.2.6.1 yamt if (NULL == fgets(kbuf, sizeof(kbuf), keyf))
121 1.2.6.1 yamt continue;
122 1.1 kardel
123 1.2.6.1 yamt kbuf[sizeof(kbuf) - 1] = '\0';
124 1.2.6.1 yamt octothorpe = strchr(kbuf, '#');
125 1.2.6.1 yamt if (octothorpe)
126 1.2.6.1 yamt *octothorpe = '\0';
127 1.2.6.1 yamt scan_cnt = sscanf(kbuf, "%d %9s %128s", &act->key_id, act->type, keystring);
128 1.2.6.1 yamt if (scan_cnt == 3) {
129 1.2.6.1 yamt int len = strlen(keystring);
130 1.2.6.1 yamt if (len <= 20) {
131 1.2.6.1 yamt act->key_len = len;
132 1.2.6.1 yamt memcpy(act->key_seq, keystring, len + 1);
133 1.2.6.1 yamt goodline = 1;
134 1.2.6.1 yamt } else if ((len & 1) != 0) {
135 1.2.6.1 yamt goodline = 0; /* it's bad */
136 1.2.6.1 yamt } else {
137 1.2.6.1 yamt int j;
138 1.2.6.1 yamt goodline = 1;
139 1.2.6.1 yamt act->key_len = len >> 1;
140 1.2.6.1 yamt for (j = 0; j < len; j+=2) {
141 1.2.6.1 yamt int val;
142 1.2.6.1 yamt val = (hex_val(keystring[j]) << 4) |
143 1.2.6.1 yamt hex_val(keystring[j+1]);
144 1.2.6.1 yamt if (val < 0) {
145 1.2.6.1 yamt goodline = 0; /* it's bad */
146 1.2.6.1 yamt break;
147 1.2.6.1 yamt }
148 1.2.6.1 yamt act->key_seq[j>>1] = (char)val;
149 1.2.6.1 yamt }
150 1.1 kardel }
151 1.1 kardel }
152 1.2.6.1 yamt if (goodline) {
153 1.1 kardel act->next = NULL;
154 1.1 kardel if (NULL == prev)
155 1.1 kardel *keys = act;
156 1.1 kardel else
157 1.1 kardel prev->next = act;
158 1.1 kardel prev = act;
159 1.1 kardel key_cnt++;
160 1.1 kardel } else {
161 1.2.6.1 yamt msyslog(LOG_DEBUG, "auth_init: scanf %d items, skipping line %d.",
162 1.2.6.1 yamt scan_cnt, line_cnt);
163 1.1 kardel free(act);
164 1.1 kardel }
165 1.1 kardel line_cnt++;
166 1.1 kardel }
167 1.1 kardel fclose(keyf);
168 1.1 kardel
169 1.1 kardel key_ptr = *keys;
170 1.2.6.1 yamt return key_cnt;
171 1.1 kardel }
172 1.1 kardel
173 1.1 kardel /* Looks for the key with keyid key_id and sets the d_key pointer to the
174 1.1 kardel * address of the key. If no matching key is found the pointer is not touched.
175 1.1 kardel */
176 1.1 kardel void
177 1.1 kardel get_key(
178 1.1 kardel int key_id,
179 1.1 kardel struct key **d_key
180 1.1 kardel )
181 1.1 kardel {
182 1.2.6.1 yamt struct key *itr_key;
183 1.1 kardel
184 1.1 kardel if (key_cnt == 0)
185 1.1 kardel return;
186 1.2.6.1 yamt for (itr_key = key_ptr; itr_key; itr_key = itr_key->next) {
187 1.1 kardel if (itr_key->key_id == key_id) {
188 1.1 kardel *d_key = itr_key;
189 1.2.6.1 yamt break;
190 1.1 kardel }
191 1.1 kardel }
192 1.1 kardel return;
193 1.1 kardel }
194