/src/ntp-dev/ntpd/ntp_crypto.c
Line | Count | Source |
1 | | /* |
2 | | * ntp_crypto.c - NTP version 4 public key routines |
3 | | */ |
4 | | #ifdef HAVE_CONFIG_H |
5 | | #include <config.h> |
6 | | #endif |
7 | | |
8 | | #ifdef AUTOKEY |
9 | | #include <stdio.h> |
10 | | #include <stdlib.h> /* strtoul */ |
11 | | #include <sys/types.h> |
12 | | #include <sys/param.h> |
13 | | #include <unistd.h> |
14 | | #include <fcntl.h> |
15 | | |
16 | | #include "ntpd.h" |
17 | | #include "ntp_stdlib.h" |
18 | | #include "ntp_unixtime.h" |
19 | | #include "ntp_string.h" |
20 | | #include "ntp_random.h" |
21 | | #include "ntp_assert.h" |
22 | | #include "ntp_calendar.h" |
23 | | #include "ntp_leapsec.h" |
24 | | |
25 | | #include "openssl/asn1.h" |
26 | | #include "openssl/bn.h" |
27 | | #include "openssl/crypto.h" |
28 | | #include "openssl/err.h" |
29 | | #include "openssl/evp.h" |
30 | | #include "openssl/opensslv.h" |
31 | | #include "openssl/pem.h" |
32 | | #include "openssl/rand.h" |
33 | | #include "openssl/x509.h" |
34 | | #include "openssl/x509v3.h" |
35 | | #include "libssl_compat.h" |
36 | | |
37 | | #ifdef KERNEL_PLL |
38 | | #include "ntp_syscall.h" |
39 | | #endif /* KERNEL_PLL */ |
40 | | |
41 | | /* |
42 | | * calcomp - compare two calendar structures, ignoring yearday and weekday; like strcmp |
43 | | * No, it's not a plotter. If you don't understand that, you're too young. |
44 | | */ |
45 | | static int calcomp(struct calendar *pjd1, struct calendar *pjd2) |
46 | 0 | { |
47 | 0 | int32_t diff; /* large enough to hold the signed difference between two uint16_t values */ |
48 | |
|
49 | 0 | diff = pjd1->year - pjd2->year; |
50 | 0 | if (diff < 0) return -1; else if (diff > 0) return 1; |
51 | | /* same year; compare months */ |
52 | 0 | diff = pjd1->month - pjd2->month; |
53 | 0 | if (diff < 0) return -1; else if (diff > 0) return 1; |
54 | | /* same year and month; compare monthday */ |
55 | 0 | diff = pjd1->monthday - pjd2->monthday; |
56 | 0 | if (diff < 0) return -1; else if (diff > 0) return 1; |
57 | | /* same year and month and monthday; compare time */ |
58 | 0 | diff = pjd1->hour - pjd2->hour; |
59 | 0 | if (diff < 0) return -1; else if (diff > 0) return 1; |
60 | 0 | diff = pjd1->minute - pjd2->minute; |
61 | 0 | if (diff < 0) return -1; else if (diff > 0) return 1; |
62 | 0 | diff = pjd1->second - pjd2->second; |
63 | 0 | if (diff < 0) return -1; else if (diff > 0) return 1; |
64 | | /* identical */ |
65 | 0 | return 0; |
66 | 0 | } |
67 | | |
68 | | /* |
69 | | * Extension field message format |
70 | | * |
71 | | * These are always signed and saved before sending in network byte |
72 | | * order. They must be converted to and from host byte order for |
73 | | * processing. |
74 | | * |
75 | | * +-------+-------+ |
76 | | * | op | len | <- extension pointer |
77 | | * +-------+-------+ |
78 | | * | associd | |
79 | | * +---------------+ |
80 | | * | timestamp | <- value pointer |
81 | | * +---------------+ |
82 | | * | filestamp | |
83 | | * +---------------+ |
84 | | * | value len | |
85 | | * +---------------+ |
86 | | * | | |
87 | | * = value = |
88 | | * | | |
89 | | * +---------------+ |
90 | | * | signature len | |
91 | | * +---------------+ |
92 | | * | | |
93 | | * = signature = |
94 | | * | | |
95 | | * +---------------+ |
96 | | * |
97 | | * The CRYPTO_RESP bit is set to 0 for requests, 1 for responses. |
98 | | * Requests carry the association ID of the receiver; responses carry |
99 | | * the association ID of the sender. Some messages include only the |
100 | | * operation/length and association ID words and so have length 8 |
101 | | * octets. Ohers include the value structure and associated value and |
102 | | * signature fields. These messages include the timestamp, filestamp, |
103 | | * value and signature words and so have length at least 24 octets. The |
104 | | * signature and/or value fields can be empty, in which case the |
105 | | * respective length words are zero. An empty value with nonempty |
106 | | * signature is syntactically valid, but semantically questionable. |
107 | | * |
108 | | * The filestamp represents the time when a cryptographic data file such |
109 | | * as a public/private key pair is created. It follows every reference |
110 | | * depending on that file and serves as a means to obsolete earlier data |
111 | | * of the same type. The timestamp represents the time when the |
112 | | * cryptographic data of the message were last signed. Creation of a |
113 | | * cryptographic data file or signing a message can occur only when the |
114 | | * creator or signor is synchronized to an authoritative source and |
115 | | * proventicated to a trusted authority. |
116 | | * |
117 | | * Note there are several conditions required for server trust. First, |
118 | | * the public key on the server certificate must be verified, which can |
119 | | * involve a hike along the certificate trail to a trusted host. Next, |
120 | | * the server trust must be confirmed by one of several identity |
121 | | * schemes. Valid cryptographic values are signed with attached |
122 | | * timestamp and filestamp. Individual packet trust is confirmed |
123 | | * relative to these values by a message digest with keys generated by a |
124 | | * reverse-order pseudorandom hash. |
125 | | * |
126 | | * State decomposition. These flags are lit in the order given. They are |
127 | | * dim only when the association is demobilized. |
128 | | * |
129 | | * CRYPTO_FLAG_ENAB Lit upon acceptance of a CRYPTO_ASSOC message |
130 | | * CRYPTO_FLAG_CERT Lit when a self-digned trusted certificate is |
131 | | * accepted. |
132 | | * CRYPTO_FLAG_VRFY Lit when identity is confirmed. |
133 | | * CRYPTO_FLAG_PROV Lit when the first signature is verified. |
134 | | * CRYPTO_FLAG_COOK Lit when a valid cookie is accepted. |
135 | | * CRYPTO_FLAG_AUTO Lit when valid autokey values are accepted. |
136 | | * CRYPTO_FLAG_SIGN Lit when the server signed certificate is |
137 | | * accepted. |
138 | | * CRYPTO_FLAG_LEAP Lit when the leapsecond values are accepted. |
139 | | */ |
140 | | /* |
141 | | * Cryptodefines |
142 | | */ |
143 | | #define TAI_1972 10 /* initial TAI offset (s) */ |
144 | | #define MAX_LEAP 100 /* max UTC leapseconds (s) */ |
145 | 0 | #define VALUE_LEN (6 * 4) /* min response field length */ |
146 | 0 | #define MAX_VALLEN (65535 - VALUE_LEN) |
147 | 0 | #define YEAR (60 * 60 * 24 * 365) /* seconds in year */ |
148 | | |
149 | | /* |
150 | | * Global cryptodata in host byte order |
151 | | */ |
152 | | u_int32 crypto_flags = 0x0; /* status word */ |
153 | | int crypto_nid = KEY_TYPE_MD5; /* digest nid */ |
154 | | char *sys_hostname = NULL; |
155 | | char *sys_groupname = NULL; |
156 | | static char *host_filename = NULL; /* host file name */ |
157 | | static char *ident_filename = NULL; /* group file name */ |
158 | | |
159 | | /* |
160 | | * Global cryptodata in network byte order |
161 | | */ |
162 | | struct cert_info *cinfo = NULL; /* certificate info/value cache */ |
163 | | struct cert_info *cert_host = NULL; /* host certificate */ |
164 | | struct pkey_info *pkinfo = NULL; /* key info/value cache */ |
165 | | struct value hostval; /* host value */ |
166 | | struct value pubkey; /* public key */ |
167 | | struct value tai_leap; /* leapseconds values */ |
168 | | struct pkey_info *iffkey_info = NULL; /* IFF keys */ |
169 | | struct pkey_info *gqkey_info = NULL; /* GQ keys */ |
170 | | struct pkey_info *mvkey_info = NULL; /* MV keys */ |
171 | | |
172 | | /* |
173 | | * Private cryptodata in host byte order |
174 | | */ |
175 | | static char *passwd = NULL; /* private key password */ |
176 | | static EVP_PKEY *host_pkey = NULL; /* host key */ |
177 | | static EVP_PKEY *sign_pkey = NULL; /* sign key */ |
178 | | static const EVP_MD *sign_digest = NULL; /* sign digest */ |
179 | | static u_int sign_siglen; /* sign key length */ |
180 | | static char *rand_file = NULL; /* random seed file */ |
181 | | |
182 | | /* |
183 | | * Cryptotypes |
184 | | */ |
185 | | static int crypto_verify (struct exten *, struct value *, |
186 | | struct peer *); |
187 | | static int crypto_encrypt (const u_char *, u_int, keyid_t *, |
188 | | struct value *); |
189 | | static int crypto_alice (struct peer *, struct value *); |
190 | | static int crypto_alice2 (struct peer *, struct value *); |
191 | | static int crypto_alice3 (struct peer *, struct value *); |
192 | | static int crypto_bob (struct exten *, struct value *); |
193 | | static int crypto_bob2 (struct exten *, struct value *); |
194 | | static int crypto_bob3 (struct exten *, struct value *); |
195 | | static int crypto_iff (struct exten *, struct peer *); |
196 | | static int crypto_gq (struct exten *, struct peer *); |
197 | | static int crypto_mv (struct exten *, struct peer *); |
198 | | static int crypto_send (struct exten *, struct value *, int); |
199 | | static tstamp_t crypto_time (void); |
200 | | static void asn_to_calendar (const ASN1_TIME *, struct calendar*); |
201 | | static struct cert_info *cert_parse (const u_char *, long, tstamp_t); |
202 | | static int cert_sign (struct exten *, struct value *); |
203 | | static struct cert_info *cert_install (struct exten *, struct peer *); |
204 | | static int cert_hike (struct peer *, struct cert_info *); |
205 | | static void cert_free (struct cert_info *); |
206 | | static struct pkey_info *crypto_key (char *, char *, sockaddr_u *); |
207 | | static void bighash (BIGNUM *, BIGNUM *); |
208 | | static struct cert_info *crypto_cert (char *); |
209 | | static u_int exten_payload_size(const struct exten *); |
210 | | |
211 | | #ifdef SYS_WINNT |
212 | | int |
213 | | readlink(char * link, char * file, int len) { |
214 | | return (-1); |
215 | | } |
216 | | #endif |
217 | | |
218 | | /* |
219 | | * session_key - generate session key |
220 | | * |
221 | | * This routine generates a session key from the source address, |
222 | | * destination address, key ID and private value. The value of the |
223 | | * session key is the MD5 hash of these values, while the next key ID is |
224 | | * the first four octets of the hash. |
225 | | * |
226 | | * Returns the next key ID or 0 if there is no destination address. |
227 | | */ |
228 | | keyid_t |
229 | | session_key( |
230 | | sockaddr_u *srcadr, /* source address */ |
231 | | sockaddr_u *dstadr, /* destination address */ |
232 | | keyid_t keyno, /* key ID */ |
233 | | keyid_t private, /* private value */ |
234 | | u_long lifetime /* key lifetime */ |
235 | | ) |
236 | 0 | { |
237 | 0 | EVP_MD_CTX *ctx; /* message digest context */ |
238 | 0 | u_char dgst[EVP_MAX_MD_SIZE]; /* message digest */ |
239 | 0 | keyid_t keyid; /* key identifer */ |
240 | 0 | u_int32 header[10]; /* data in network byte order */ |
241 | 0 | u_int hdlen, len; |
242 | |
|
243 | 0 | if (!dstadr) |
244 | 0 | return 0; |
245 | | |
246 | | /* |
247 | | * Generate the session key and key ID. If the lifetime is |
248 | | * greater than zero, install the key and call it trusted. |
249 | | */ |
250 | 0 | hdlen = 0; |
251 | 0 | switch(AF(srcadr)) { |
252 | 0 | case AF_INET: |
253 | 0 | header[0] = NSRCADR(srcadr); |
254 | 0 | header[1] = NSRCADR(dstadr); |
255 | 0 | header[2] = htonl(keyno); |
256 | 0 | header[3] = htonl(private); |
257 | 0 | hdlen = 4 * sizeof(u_int32); |
258 | 0 | break; |
259 | | |
260 | 0 | case AF_INET6: |
261 | 0 | memcpy(&header[0], PSOCK_ADDR6(srcadr), |
262 | 0 | sizeof(struct in6_addr)); |
263 | 0 | memcpy(&header[4], PSOCK_ADDR6(dstadr), |
264 | 0 | sizeof(struct in6_addr)); |
265 | 0 | header[8] = htonl(keyno); |
266 | 0 | header[9] = htonl(private); |
267 | 0 | hdlen = 10 * sizeof(u_int32); |
268 | 0 | break; |
269 | 0 | } |
270 | 0 | ctx = digest_ctx; |
271 | 0 | EVP_DigestInit(ctx, EVP_get_digestbynid(crypto_nid)); |
272 | 0 | EVP_DigestUpdate(ctx, (u_char *)header, hdlen); |
273 | 0 | EVP_DigestFinal(ctx, dgst, &len); |
274 | 0 | memcpy(&keyid, dgst, 4); |
275 | 0 | keyid = ntohl(keyid); |
276 | 0 | if (lifetime != 0) { |
277 | 0 | MD5auth_setkey(keyno, crypto_nid, dgst, len, NULL); |
278 | 0 | authtrust(keyno, lifetime); |
279 | 0 | } |
280 | 0 | DPRINTF(2, ("session_key: %s > %s %08x %08x hash %08x life %lu\n", |
281 | 0 | stoa(srcadr), stoa(dstadr), keyno, |
282 | 0 | private, keyid, lifetime)); |
283 | |
|
284 | 0 | return (keyid); |
285 | 0 | } |
286 | | |
287 | | |
288 | | /* |
289 | | * make_keylist - generate key list |
290 | | * |
291 | | * Returns |
292 | | * XEVNT_OK success |
293 | | * XEVNT_ERR protocol error |
294 | | * |
295 | | * This routine constructs a pseudo-random sequence by repeatedly |
296 | | * hashing the session key starting from a given source address, |
297 | | * destination address, private value and the next key ID of the |
298 | | * preceeding session key. The last entry on the list is saved along |
299 | | * with its sequence number and public signature. |
300 | | */ |
301 | | int |
302 | | make_keylist( |
303 | | struct peer *peer, /* peer structure pointer */ |
304 | | endpt *dstadr /* interface */ |
305 | | ) |
306 | 0 | { |
307 | 0 | EVP_MD_CTX *ctx; /* signature context */ |
308 | 0 | tstamp_t tstamp; /* NTP timestamp */ |
309 | 0 | struct autokey *ap; /* autokey pointer */ |
310 | 0 | struct value *vp; /* value pointer */ |
311 | 0 | keyid_t keyid = 0; /* next key ID */ |
312 | 0 | keyid_t cookie; /* private value */ |
313 | 0 | long lifetime; |
314 | 0 | u_int len, mpoll; |
315 | 0 | int i; |
316 | |
|
317 | 0 | if (!dstadr) |
318 | 0 | return XEVNT_ERR; |
319 | | |
320 | | /* |
321 | | * Allocate the key list if necessary. |
322 | | */ |
323 | 0 | tstamp = crypto_time(); |
324 | 0 | if (peer->keylist == NULL) |
325 | 0 | peer->keylist = eallocarray(NTP_MAXSESSION, |
326 | 0 | sizeof(keyid_t)); |
327 | | |
328 | | /* |
329 | | * Generate an initial key ID which is unique and greater than |
330 | | * NTP_MAXKEY. |
331 | | */ |
332 | 0 | while (1) { |
333 | 0 | keyid = ntp_random() & 0xffffffff; |
334 | 0 | if (keyid <= NTP_MAXKEY) |
335 | 0 | continue; |
336 | | |
337 | 0 | if (authhavekey(keyid)) |
338 | 0 | continue; |
339 | 0 | break; |
340 | 0 | } |
341 | | |
342 | | /* |
343 | | * Generate up to NTP_MAXSESSION session keys. Stop if the |
344 | | * next one would not be unique or not a session key ID or if |
345 | | * it would expire before the next poll. The private value |
346 | | * included in the hash is zero if broadcast mode, the peer |
347 | | * cookie if client mode or the host cookie if symmetric modes. |
348 | | */ |
349 | 0 | mpoll = 1U << min(peer->ppoll, peer->hpoll); |
350 | 0 | lifetime = min((1UL << sys_automax), NTP_MAXSESSION * mpoll); |
351 | 0 | if (peer->hmode == MODE_BROADCAST) |
352 | 0 | cookie = 0; |
353 | 0 | else |
354 | 0 | cookie = peer->pcookie; |
355 | 0 | for (i = 0; i < NTP_MAXSESSION; i++) { |
356 | 0 | peer->keylist[i] = keyid; |
357 | 0 | peer->keynumber = i; |
358 | 0 | keyid = session_key(&dstadr->sin, &peer->srcadr, keyid, |
359 | 0 | cookie, lifetime + mpoll); |
360 | 0 | lifetime -= mpoll; |
361 | 0 | if (auth_havekey(keyid) || keyid <= NTP_MAXKEY || |
362 | 0 | lifetime < 0 || tstamp == 0) |
363 | 0 | break; |
364 | 0 | } |
365 | | |
366 | | /* |
367 | | * Save the last session key ID, sequence number and timestamp, |
368 | | * then sign these values for later retrieval by the clients. Be |
369 | | * careful not to use invalid key media. Use the public values |
370 | | * timestamp as filestamp. |
371 | | */ |
372 | 0 | vp = &peer->sndval; |
373 | 0 | if (vp->ptr == NULL) |
374 | 0 | vp->ptr = emalloc(sizeof(struct autokey)); |
375 | 0 | ap = (struct autokey *)vp->ptr; |
376 | 0 | ap->seq = htonl(peer->keynumber); |
377 | 0 | ap->key = htonl(keyid); |
378 | 0 | vp->tstamp = htonl(tstamp); |
379 | 0 | vp->fstamp = hostval.tstamp; |
380 | 0 | vp->vallen = htonl(sizeof(struct autokey)); |
381 | 0 | vp->siglen = 0; |
382 | 0 | if (tstamp != 0) { |
383 | 0 | if (vp->sig == NULL) |
384 | 0 | vp->sig = emalloc(sign_siglen); |
385 | 0 | ctx = digest_ctx; |
386 | 0 | EVP_SignInit(ctx, sign_digest); |
387 | 0 | EVP_SignUpdate(ctx, (u_char *)vp, 12); |
388 | 0 | EVP_SignUpdate(ctx, vp->ptr, sizeof(struct autokey)); |
389 | 0 | if (EVP_SignFinal(ctx, vp->sig, &len, sign_pkey)) { |
390 | 0 | INSIST(len <= sign_siglen); |
391 | 0 | vp->siglen = htonl(len); |
392 | 0 | peer->flags |= FLAG_ASSOC; |
393 | 0 | } |
394 | 0 | } |
395 | 0 | DPRINTF(1, ("make_keys: %d %08x %08x ts %u fs %u poll %d\n", |
396 | 0 | peer->keynumber, keyid, cookie, ntohl(vp->tstamp), |
397 | 0 | ntohl(vp->fstamp), peer->hpoll)); |
398 | 0 | return (XEVNT_OK); |
399 | 0 | } |
400 | | |
401 | | |
402 | | /* |
403 | | * crypto_recv - parse extension fields |
404 | | * |
405 | | * This routine is called when the packet has been matched to an |
406 | | * association and passed sanity, format and MAC checks. We believe the |
407 | | * extension field values only if the field has proper format and |
408 | | * length, the timestamp and filestamp are valid and the signature has |
409 | | * valid length and is verified. There are a few cases where some values |
410 | | * are believed even if the signature fails, but only if the proventic |
411 | | * bit is not set. |
412 | | * |
413 | | * Returns |
414 | | * XEVNT_OK success |
415 | | * XEVNT_ERR protocol error |
416 | | * XEVNT_LEN bad field format or length |
417 | | */ |
418 | | int |
419 | | crypto_recv( |
420 | | struct peer *peer, /* peer structure pointer */ |
421 | | struct recvbuf *rbufp /* packet buffer pointer */ |
422 | | ) |
423 | 0 | { |
424 | 0 | const EVP_MD *dp; /* message digest algorithm */ |
425 | 0 | u_int32 *pkt; /* receive packet pointer */ |
426 | 0 | struct autokey *ap, *bp; /* autokey pointer */ |
427 | 0 | struct exten *ep, *fp; /* extension pointers */ |
428 | 0 | struct cert_info *xinfo; /* certificate info pointer */ |
429 | 0 | int macbytes; /* length of MAC field, signed by intention */ |
430 | 0 | int authlen; /* offset of MAC field */ |
431 | 0 | associd_t associd; /* association ID */ |
432 | 0 | tstamp_t fstamp = 0; /* filestamp */ |
433 | 0 | u_int len; /* extension field length */ |
434 | 0 | u_int code; /* extension field opcode */ |
435 | 0 | u_int vallen = 0; /* value length */ |
436 | 0 | X509 *cert; /* X509 certificate */ |
437 | 0 | char statstr[NTP_MAXSTRLEN]; /* statistics for filegen */ |
438 | 0 | keyid_t cookie; /* crumbles */ |
439 | 0 | int hismode; /* packet mode */ |
440 | 0 | int rval = XEVNT_OK; |
441 | 0 | const u_char *puch; |
442 | 0 | u_int32 temp32; |
443 | | |
444 | | /* |
445 | | * Initialize. Note that the packet has already been checked for |
446 | | * valid format and extension field lengths. First extract the |
447 | | * field length, command code and association ID in host byte |
448 | | * order. These are used with all commands and modes. Then check |
449 | | * the version number, which must be 2, and length, which must |
450 | | * be at least 8 for requests and VALUE_LEN (24) for responses. |
451 | | * Packets that fail either test sink without a trace. The |
452 | | * association ID is saved only if nonzero. |
453 | | */ |
454 | 0 | authlen = LEN_PKT_NOMAC; |
455 | 0 | hismode = (int)PKT_MODE((&rbufp->recv_pkt)->li_vn_mode); |
456 | 0 | while ((macbytes = rbufp->recv_length - authlen) > (int)MAX_MAC_LEN) { |
457 | | /* We can be reasonably sure that we can read at least |
458 | | * the opcode and the size field here. More stringent |
459 | | * checks follow up shortly. |
460 | | */ |
461 | 0 | pkt = (u_int32 *)&rbufp->recv_pkt + authlen / 4; |
462 | 0 | ep = (struct exten *)pkt; |
463 | 0 | code = ntohl(ep->opcode) & 0xffff0000; |
464 | 0 | len = ntohl(ep->opcode) & 0x0000ffff; |
465 | | // HMS: Why pkt[1] instead of ep->associd ? |
466 | 0 | associd = (associd_t)ntohl(pkt[1]); |
467 | 0 | rval = XEVNT_OK; |
468 | 0 | DPRINTF(1, ("crypto_recv: flags 0x%x ext offset %d len %u code 0x%x associd %d\n", |
469 | 0 | peer->crypto, authlen, len, code >> 16, |
470 | 0 | associd)); |
471 | | |
472 | | /* |
473 | | * Check version number and field length. If bad, |
474 | | * quietly ignore the packet. |
475 | | */ |
476 | 0 | if (((code >> 24) & 0x3f) != CRYPTO_VN || len < 8) { |
477 | 0 | sys_badlength++; |
478 | 0 | code |= CRYPTO_ERROR; |
479 | 0 | } |
480 | | |
481 | | /* Check if the declared size fits into the remaining |
482 | | * buffer. We *know* 'macbytes' > 0 here! |
483 | | */ |
484 | 0 | if (len > (u_int)macbytes) { |
485 | 0 | DPRINTF(1, ("crypto_recv: possible attack detected, associd %d\n", |
486 | 0 | associd)); |
487 | 0 | return XEVNT_LEN; |
488 | 0 | } |
489 | | |
490 | | /* Check if the paylod of the extension fits into the |
491 | | * declared frame. |
492 | | */ |
493 | 0 | if (len >= VALUE_LEN) { |
494 | 0 | fstamp = ntohl(ep->fstamp); |
495 | 0 | vallen = ntohl(ep->vallen); |
496 | | /* |
497 | | * Bug 2761: I hope this isn't too early... |
498 | | */ |
499 | 0 | if ( vallen == 0 |
500 | 0 | || len - VALUE_LEN < vallen) |
501 | 0 | return XEVNT_LEN; |
502 | 0 | } |
503 | 0 | switch (code) { |
504 | | |
505 | | /* |
506 | | * Install status word, host name, signature scheme and |
507 | | * association ID. In OpenSSL the signature algorithm is |
508 | | * bound to the digest algorithm, so the NID completely |
509 | | * defines the signature scheme. Note the request and |
510 | | * response are identical, but neither is validated by |
511 | | * signature. The request is processed here only in |
512 | | * symmetric modes. The server name field might be |
513 | | * useful to implement access controls in future. |
514 | | */ |
515 | 0 | case CRYPTO_ASSOC: |
516 | | |
517 | | /* |
518 | | * If our state machine is running when this |
519 | | * message arrives, the other fellow might have |
520 | | * restarted. However, this could be an |
521 | | * intruder, so just clamp the poll interval and |
522 | | * find out for ourselves. Otherwise, pass the |
523 | | * extension field to the transmit side. |
524 | | */ |
525 | 0 | if (peer->crypto & CRYPTO_FLAG_CERT) { |
526 | 0 | rval = XEVNT_ERR; |
527 | 0 | break; |
528 | 0 | } |
529 | 0 | if (peer->cmmd) { |
530 | 0 | if (peer->assoc != associd) { |
531 | 0 | rval = XEVNT_ERR; |
532 | 0 | break; |
533 | 0 | } |
534 | 0 | free(peer->cmmd); /* will be set again! */ |
535 | 0 | } |
536 | 0 | fp = emalloc(len); |
537 | 0 | memcpy(fp, ep, len); |
538 | 0 | fp->associd = htonl(peer->associd); |
539 | 0 | peer->cmmd = fp; |
540 | | /* fall through */ |
541 | |
|
542 | 0 | case CRYPTO_ASSOC | CRYPTO_RESP: |
543 | | |
544 | | /* |
545 | | * Discard the message if it has already been |
546 | | * stored or the message has been amputated. |
547 | | */ |
548 | 0 | if (peer->crypto) { |
549 | 0 | if (peer->assoc != associd) |
550 | 0 | rval = XEVNT_ERR; |
551 | 0 | break; |
552 | 0 | } |
553 | 0 | INSIST(len >= VALUE_LEN); |
554 | 0 | if (vallen == 0 || vallen > MAXHOSTNAME || |
555 | 0 | len - VALUE_LEN < vallen) { |
556 | 0 | rval = XEVNT_LEN; |
557 | 0 | break; |
558 | 0 | } |
559 | 0 | DPRINTF(1, ("crypto_recv: ident host 0x%x %d server 0x%x %d\n", |
560 | 0 | crypto_flags, peer->associd, fstamp, |
561 | 0 | peer->assoc)); |
562 | 0 | temp32 = crypto_flags & CRYPTO_FLAG_MASK; |
563 | | |
564 | | /* |
565 | | * If the client scheme is PC, the server scheme |
566 | | * must be PC. The public key and identity are |
567 | | * presumed valid, so we skip the certificate |
568 | | * and identity exchanges and move immediately |
569 | | * to the cookie exchange which confirms the |
570 | | * server signature. |
571 | | */ |
572 | 0 | if (crypto_flags & CRYPTO_FLAG_PRIV) { |
573 | 0 | if (!(fstamp & CRYPTO_FLAG_PRIV)) { |
574 | 0 | rval = XEVNT_KEY; |
575 | 0 | break; |
576 | 0 | } |
577 | 0 | fstamp |= CRYPTO_FLAG_CERT | |
578 | 0 | CRYPTO_FLAG_VRFY | CRYPTO_FLAG_SIGN; |
579 | | |
580 | | /* |
581 | | * It is an error if either peer supports |
582 | | * identity, but the other does not. |
583 | | */ |
584 | 0 | } else if (hismode == MODE_ACTIVE || hismode == |
585 | 0 | MODE_PASSIVE) { |
586 | 0 | if ((temp32 && !(fstamp & |
587 | 0 | CRYPTO_FLAG_MASK)) || |
588 | 0 | (!temp32 && (fstamp & |
589 | 0 | CRYPTO_FLAG_MASK))) { |
590 | 0 | rval = XEVNT_KEY; |
591 | 0 | break; |
592 | 0 | } |
593 | 0 | } |
594 | | |
595 | | /* |
596 | | * Discard the message if the signature digest |
597 | | * NID is not supported. |
598 | | */ |
599 | 0 | temp32 = (fstamp >> 16) & 0xffff; |
600 | 0 | dp = |
601 | 0 | (const EVP_MD *)EVP_get_digestbynid(temp32); |
602 | 0 | if (dp == NULL) { |
603 | 0 | rval = XEVNT_MD; |
604 | 0 | break; |
605 | 0 | } |
606 | | |
607 | | /* |
608 | | * Save status word, host name and message |
609 | | * digest/signature type. If this is from a |
610 | | * broadcast and the association ID has changed, |
611 | | * request the autokey values. |
612 | | */ |
613 | 0 | peer->assoc = associd; |
614 | 0 | if (hismode == MODE_SERVER) |
615 | 0 | fstamp |= CRYPTO_FLAG_AUTO; |
616 | 0 | if (!(fstamp & CRYPTO_FLAG_TAI)) |
617 | 0 | fstamp |= CRYPTO_FLAG_LEAP; |
618 | 0 | RAND_bytes((u_char *)&peer->hcookie, 4); |
619 | 0 | peer->crypto = fstamp; |
620 | 0 | peer->digest = dp; |
621 | 0 | if (peer->subject != NULL) |
622 | 0 | free(peer->subject); |
623 | 0 | peer->subject = emalloc(vallen + 1); |
624 | 0 | memcpy(peer->subject, ep->pkt, vallen); |
625 | 0 | peer->subject[vallen] = '\0'; |
626 | 0 | if (peer->issuer != NULL) |
627 | 0 | free(peer->issuer); |
628 | 0 | peer->issuer = estrdup(peer->subject); |
629 | 0 | snprintf(statstr, sizeof(statstr), |
630 | 0 | "assoc %d %d host %s %s", peer->associd, |
631 | 0 | peer->assoc, peer->subject, |
632 | 0 | OBJ_nid2ln(temp32)); |
633 | 0 | record_crypto_stats(&peer->srcadr, statstr); |
634 | 0 | DPRINTF(1, ("crypto_recv: %s\n", statstr)); |
635 | 0 | break; |
636 | | |
637 | | /* |
638 | | * Decode X509 certificate in ASN.1 format and extract |
639 | | * the data containing, among other things, subject |
640 | | * name and public key. In the default identification |
641 | | * scheme, the certificate trail is followed to a self |
642 | | * signed trusted certificate. |
643 | | */ |
644 | 0 | case CRYPTO_CERT | CRYPTO_RESP: |
645 | | |
646 | | /* |
647 | | * Discard the message if empty or invalid. |
648 | | */ |
649 | 0 | if (len < VALUE_LEN) |
650 | 0 | break; |
651 | | |
652 | 0 | if ((rval = crypto_verify(ep, NULL, peer)) != |
653 | 0 | XEVNT_OK) |
654 | 0 | break; |
655 | | |
656 | | /* |
657 | | * Scan the certificate list to delete old |
658 | | * versions and link the newest version first on |
659 | | * the list. Then, verify the signature. If the |
660 | | * certificate is bad or missing, just ignore |
661 | | * it. |
662 | | */ |
663 | 0 | if ((xinfo = cert_install(ep, peer)) == NULL) { |
664 | 0 | rval = XEVNT_CRT; |
665 | 0 | break; |
666 | 0 | } |
667 | 0 | if ((rval = cert_hike(peer, xinfo)) != XEVNT_OK) |
668 | 0 | break; |
669 | | |
670 | | /* |
671 | | * We plug in the public key and lifetime from |
672 | | * the first certificate received. However, note |
673 | | * that this certificate might not be signed by |
674 | | * the server, so we can't check the |
675 | | * signature/digest NID. |
676 | | */ |
677 | 0 | if (peer->pkey == NULL) { |
678 | 0 | puch = xinfo->cert.ptr; |
679 | 0 | cert = d2i_X509(NULL, &puch, |
680 | 0 | ntohl(xinfo->cert.vallen)); |
681 | 0 | peer->pkey = X509_get_pubkey(cert); |
682 | 0 | X509_free(cert); |
683 | 0 | } |
684 | 0 | peer->flash &= ~TEST8; |
685 | 0 | temp32 = xinfo->nid; |
686 | 0 | snprintf(statstr, sizeof(statstr), |
687 | 0 | "cert %s %s 0x%x %s (%u) fs %u", |
688 | 0 | xinfo->subject, xinfo->issuer, xinfo->flags, |
689 | 0 | OBJ_nid2ln(temp32), temp32, |
690 | 0 | ntohl(ep->fstamp)); |
691 | 0 | record_crypto_stats(&peer->srcadr, statstr); |
692 | 0 | DPRINTF(1, ("crypto_recv: %s\n", statstr)); |
693 | 0 | break; |
694 | | |
695 | | /* |
696 | | * Schnorr (IFF) identity scheme. This scheme is |
697 | | * designed for use with shared secret server group keys |
698 | | * and where the certificate may be generated by a third |
699 | | * party. The client sends a challenge to the server, |
700 | | * which performs a calculation and returns the result. |
701 | | * A positive result is possible only if both client and |
702 | | * server contain the same secret group key. |
703 | | */ |
704 | 0 | case CRYPTO_IFF | CRYPTO_RESP: |
705 | | |
706 | | /* |
707 | | * Discard the message if invalid. |
708 | | */ |
709 | 0 | if ((rval = crypto_verify(ep, NULL, peer)) != |
710 | 0 | XEVNT_OK) |
711 | 0 | break; |
712 | | |
713 | | /* |
714 | | * If the challenge matches the response, the |
715 | | * server public key, signature and identity are |
716 | | * all verified at the same time. The server is |
717 | | * declared trusted, so we skip further |
718 | | * certificate exchanges and move immediately to |
719 | | * the cookie exchange. |
720 | | */ |
721 | 0 | if ((rval = crypto_iff(ep, peer)) != XEVNT_OK) |
722 | 0 | break; |
723 | | |
724 | 0 | peer->crypto |= CRYPTO_FLAG_VRFY; |
725 | 0 | peer->flash &= ~TEST8; |
726 | 0 | snprintf(statstr, sizeof(statstr), "iff %s fs %u", |
727 | 0 | peer->issuer, ntohl(ep->fstamp)); |
728 | 0 | record_crypto_stats(&peer->srcadr, statstr); |
729 | 0 | DPRINTF(1, ("crypto_recv: %s\n", statstr)); |
730 | 0 | break; |
731 | | |
732 | | /* |
733 | | * Guillou-Quisquater (GQ) identity scheme. This scheme |
734 | | * is designed for use with public certificates carrying |
735 | | * the GQ public key in an extension field. The client |
736 | | * sends a challenge to the server, which performs a |
737 | | * calculation and returns the result. A positive result |
738 | | * is possible only if both client and server contain |
739 | | * the same group key and the server has the matching GQ |
740 | | * private key. |
741 | | */ |
742 | 0 | case CRYPTO_GQ | CRYPTO_RESP: |
743 | | |
744 | | /* |
745 | | * Discard the message if invalid |
746 | | */ |
747 | 0 | if ((rval = crypto_verify(ep, NULL, peer)) != |
748 | 0 | XEVNT_OK) |
749 | 0 | break; |
750 | | |
751 | | /* |
752 | | * If the challenge matches the response, the |
753 | | * server public key, signature and identity are |
754 | | * all verified at the same time. The server is |
755 | | * declared trusted, so we skip further |
756 | | * certificate exchanges and move immediately to |
757 | | * the cookie exchange. |
758 | | */ |
759 | 0 | if ((rval = crypto_gq(ep, peer)) != XEVNT_OK) |
760 | 0 | break; |
761 | | |
762 | 0 | peer->crypto |= CRYPTO_FLAG_VRFY; |
763 | 0 | peer->flash &= ~TEST8; |
764 | 0 | snprintf(statstr, sizeof(statstr), "gq %s fs %u", |
765 | 0 | peer->issuer, ntohl(ep->fstamp)); |
766 | 0 | record_crypto_stats(&peer->srcadr, statstr); |
767 | 0 | DPRINTF(1, ("crypto_recv: %s\n", statstr)); |
768 | 0 | break; |
769 | | |
770 | | /* |
771 | | * Mu-Varadharajan (MV) identity scheme. This scheme is |
772 | | * designed for use with three levels of trust, trusted |
773 | | * host, server and client. The trusted host key is |
774 | | * opaque to servers and clients; the server keys are |
775 | | * opaque to clients and each client key is different. |
776 | | * Client keys can be revoked without requiring new key |
777 | | * generations. |
778 | | */ |
779 | 0 | case CRYPTO_MV | CRYPTO_RESP: |
780 | | |
781 | | /* |
782 | | * Discard the message if invalid. |
783 | | */ |
784 | 0 | if ((rval = crypto_verify(ep, NULL, peer)) != |
785 | 0 | XEVNT_OK) |
786 | 0 | break; |
787 | | |
788 | | /* |
789 | | * If the challenge matches the response, the |
790 | | * server public key, signature and identity are |
791 | | * all verified at the same time. The server is |
792 | | * declared trusted, so we skip further |
793 | | * certificate exchanges and move immediately to |
794 | | * the cookie exchange. |
795 | | */ |
796 | 0 | if ((rval = crypto_mv(ep, peer)) != XEVNT_OK) |
797 | 0 | break; |
798 | | |
799 | 0 | peer->crypto |= CRYPTO_FLAG_VRFY; |
800 | 0 | peer->flash &= ~TEST8; |
801 | 0 | snprintf(statstr, sizeof(statstr), "mv %s fs %u", |
802 | 0 | peer->issuer, ntohl(ep->fstamp)); |
803 | 0 | record_crypto_stats(&peer->srcadr, statstr); |
804 | 0 | DPRINTF(1, ("crypto_recv: %s\n", statstr)); |
805 | 0 | break; |
806 | | |
807 | | |
808 | | /* |
809 | | * Cookie response in client and symmetric modes. If the |
810 | | * cookie bit is set, the working cookie is the EXOR of |
811 | | * the current and new values. |
812 | | */ |
813 | 0 | case CRYPTO_COOK | CRYPTO_RESP: |
814 | | |
815 | | /* |
816 | | * Discard the message if invalid or signature |
817 | | * not verified with respect to the cookie |
818 | | * values. |
819 | | */ |
820 | 0 | if ((rval = crypto_verify(ep, &peer->cookval, |
821 | 0 | peer)) != XEVNT_OK) |
822 | 0 | break; |
823 | | |
824 | | /* |
825 | | * Decrypt the cookie, hunting all the time for |
826 | | * errors. |
827 | | */ |
828 | 0 | if (vallen == (u_int)EVP_PKEY_size(host_pkey)) { |
829 | 0 | RSA *rsa = EVP_PKEY_get1_RSA(host_pkey); |
830 | 0 | u_int32 *cookiebuf = malloc(RSA_size(rsa)); |
831 | 0 | if (!cookiebuf) { |
832 | 0 | rval = XEVNT_CKY; |
833 | 0 | break; |
834 | 0 | } |
835 | | |
836 | 0 | if (RSA_private_decrypt(vallen, |
837 | 0 | (u_char *)ep->pkt, |
838 | 0 | (u_char *)cookiebuf, |
839 | 0 | rsa, |
840 | 0 | RSA_PKCS1_OAEP_PADDING) != 4) { |
841 | 0 | rval = XEVNT_CKY; |
842 | 0 | free(cookiebuf); |
843 | 0 | break; |
844 | 0 | } else { |
845 | 0 | cookie = ntohl(*cookiebuf); |
846 | 0 | free(cookiebuf); |
847 | 0 | } |
848 | 0 | RSA_free(rsa); |
849 | 0 | } else { |
850 | 0 | rval = XEVNT_CKY; |
851 | 0 | break; |
852 | 0 | } |
853 | | |
854 | | /* |
855 | | * Install cookie values and light the cookie |
856 | | * bit. If this is not broadcast client mode, we |
857 | | * are done here. |
858 | | */ |
859 | 0 | key_expire(peer); |
860 | 0 | if (hismode == MODE_ACTIVE || hismode == |
861 | 0 | MODE_PASSIVE) |
862 | 0 | peer->pcookie = peer->hcookie ^ cookie; |
863 | 0 | else |
864 | 0 | peer->pcookie = cookie; |
865 | 0 | peer->crypto |= CRYPTO_FLAG_COOK; |
866 | 0 | peer->flash &= ~TEST8; |
867 | 0 | snprintf(statstr, sizeof(statstr), |
868 | 0 | "cook %x ts %u fs %u", peer->pcookie, |
869 | 0 | ntohl(ep->tstamp), ntohl(ep->fstamp)); |
870 | 0 | record_crypto_stats(&peer->srcadr, statstr); |
871 | 0 | DPRINTF(1, ("crypto_recv: %s\n", statstr)); |
872 | 0 | break; |
873 | | |
874 | | /* |
875 | | * Install autokey values in broadcast client and |
876 | | * symmetric modes. We have to do this every time the |
877 | | * sever/peer cookie changes or a new keylist is |
878 | | * rolled. Ordinarily, this is automatic as this message |
879 | | * is piggybacked on the first NTP packet sent upon |
880 | | * either of these events. Note that a broadcast client |
881 | | * or symmetric peer can receive this response without a |
882 | | * matching request. |
883 | | */ |
884 | 0 | case CRYPTO_AUTO | CRYPTO_RESP: |
885 | | |
886 | | /* |
887 | | * Discard the message if invalid or signature |
888 | | * not verified with respect to the receive |
889 | | * autokey values. |
890 | | */ |
891 | 0 | if ((rval = crypto_verify(ep, &peer->recval, |
892 | 0 | peer)) != XEVNT_OK) |
893 | 0 | break; |
894 | | |
895 | | /* |
896 | | * Discard the message if a broadcast client and |
897 | | * the association ID does not match. This might |
898 | | * happen if a broacast server restarts the |
899 | | * protocol. A protocol restart will occur at |
900 | | * the next ASSOC message. |
901 | | */ |
902 | 0 | if ((peer->cast_flags & MDF_BCLNT) && |
903 | 0 | peer->assoc != associd) |
904 | 0 | break; |
905 | | |
906 | | /* |
907 | | * Install autokey values and light the |
908 | | * autokey bit. This is not hard. |
909 | | */ |
910 | 0 | if (ep->tstamp == 0) |
911 | 0 | break; |
912 | | |
913 | 0 | if (peer->recval.ptr == NULL) |
914 | 0 | peer->recval.ptr = |
915 | 0 | emalloc(sizeof(struct autokey)); |
916 | 0 | bp = (struct autokey *)peer->recval.ptr; |
917 | 0 | peer->recval.tstamp = ep->tstamp; |
918 | 0 | peer->recval.fstamp = ep->fstamp; |
919 | 0 | ap = (struct autokey *)ep->pkt; |
920 | 0 | bp->seq = ntohl(ap->seq); |
921 | 0 | bp->key = ntohl(ap->key); |
922 | 0 | peer->pkeyid = bp->key; |
923 | 0 | peer->crypto |= CRYPTO_FLAG_AUTO; |
924 | 0 | peer->flash &= ~TEST8; |
925 | 0 | snprintf(statstr, sizeof(statstr), |
926 | 0 | "auto seq %d key %x ts %u fs %u", bp->seq, |
927 | 0 | bp->key, ntohl(ep->tstamp), |
928 | 0 | ntohl(ep->fstamp)); |
929 | 0 | record_crypto_stats(&peer->srcadr, statstr); |
930 | 0 | DPRINTF(1, ("crypto_recv: %s\n", statstr)); |
931 | 0 | break; |
932 | | |
933 | | /* |
934 | | * X509 certificate sign response. Validate the |
935 | | * certificate signed by the server and install. Later |
936 | | * this can be provided to clients of this server in |
937 | | * lieu of the self signed certificate in order to |
938 | | * validate the public key. |
939 | | */ |
940 | 0 | case CRYPTO_SIGN | CRYPTO_RESP: |
941 | | |
942 | | /* |
943 | | * Discard the message if invalid. |
944 | | */ |
945 | 0 | if ((rval = crypto_verify(ep, NULL, peer)) != |
946 | 0 | XEVNT_OK) |
947 | 0 | break; |
948 | | |
949 | | /* |
950 | | * Scan the certificate list to delete old |
951 | | * versions and link the newest version first on |
952 | | * the list. |
953 | | */ |
954 | 0 | if ((xinfo = cert_install(ep, peer)) == NULL) { |
955 | 0 | rval = XEVNT_CRT; |
956 | 0 | break; |
957 | 0 | } |
958 | 0 | peer->crypto |= CRYPTO_FLAG_SIGN; |
959 | 0 | peer->flash &= ~TEST8; |
960 | 0 | temp32 = xinfo->nid; |
961 | 0 | snprintf(statstr, sizeof(statstr), |
962 | 0 | "sign %s %s 0x%x %s (%u) fs %u", |
963 | 0 | xinfo->subject, xinfo->issuer, xinfo->flags, |
964 | 0 | OBJ_nid2ln(temp32), temp32, |
965 | 0 | ntohl(ep->fstamp)); |
966 | 0 | record_crypto_stats(&peer->srcadr, statstr); |
967 | 0 | DPRINTF(1, ("crypto_recv: %s\n", statstr)); |
968 | 0 | break; |
969 | | |
970 | | /* |
971 | | * Install leapseconds values. While the leapsecond |
972 | | * values epoch, TAI offset and values expiration epoch |
973 | | * are retained, only the current TAI offset is provided |
974 | | * via the kernel to other applications. |
975 | | */ |
976 | 0 | case CRYPTO_LEAP | CRYPTO_RESP: |
977 | | /* |
978 | | * Discard the message if invalid. We can't |
979 | | * compare the value timestamps here, as they |
980 | | * can be updated by different servers. |
981 | | */ |
982 | 0 | rval = crypto_verify(ep, NULL, peer); |
983 | 0 | if ((rval != XEVNT_OK ) || |
984 | 0 | (vallen != 3*sizeof(uint32_t)) ) |
985 | 0 | break; |
986 | | |
987 | | /* Check if we can update the basic TAI offset |
988 | | * for our current leap frame. This is a hack |
989 | | * and ignores the time stamps in the autokey |
990 | | * message. |
991 | | */ |
992 | 0 | if (sys_leap != LEAP_NOTINSYNC) |
993 | 0 | leapsec_autokey_tai(ntohl(ep->pkt[0]), |
994 | 0 | rbufp->recv_time.l_ui, NULL); |
995 | 0 | tai_leap.tstamp = ep->tstamp; |
996 | 0 | tai_leap.fstamp = ep->fstamp; |
997 | 0 | crypto_update(); |
998 | 0 | mprintf_event(EVNT_TAI, peer, |
999 | 0 | "%d seconds", ntohl(ep->pkt[0])); |
1000 | 0 | peer->crypto |= CRYPTO_FLAG_LEAP; |
1001 | 0 | peer->flash &= ~TEST8; |
1002 | 0 | snprintf(statstr, sizeof(statstr), |
1003 | 0 | "leap TAI offset %d at %u expire %u fs %u", |
1004 | 0 | ntohl(ep->pkt[0]), ntohl(ep->pkt[1]), |
1005 | 0 | ntohl(ep->pkt[2]), ntohl(ep->fstamp)); |
1006 | 0 | record_crypto_stats(&peer->srcadr, statstr); |
1007 | 0 | DPRINTF(1, ("crypto_recv: %s\n", statstr)); |
1008 | 0 | break; |
1009 | | |
1010 | | /* |
1011 | | * We come here in symmetric modes for miscellaneous |
1012 | | * commands that have value fields but are processed on |
1013 | | * the transmit side. All we need do here is check for |
1014 | | * valid field length. Note that ASSOC is handled |
1015 | | * separately. |
1016 | | */ |
1017 | 0 | case CRYPTO_CERT: |
1018 | 0 | case CRYPTO_IFF: |
1019 | 0 | case CRYPTO_GQ: |
1020 | 0 | case CRYPTO_MV: |
1021 | 0 | case CRYPTO_COOK: |
1022 | 0 | case CRYPTO_SIGN: |
1023 | 0 | if (len < VALUE_LEN) { |
1024 | 0 | rval = XEVNT_LEN; |
1025 | 0 | break; |
1026 | 0 | } |
1027 | | /* fall through */ |
1028 | | |
1029 | | /* |
1030 | | * We come here in symmetric modes for requests |
1031 | | * requiring a response (above plus AUTO and LEAP) and |
1032 | | * for responses. If a request, save the extension field |
1033 | | * for later; invalid requests will be caught on the |
1034 | | * transmit side. If an error or invalid response, |
1035 | | * declare a protocol error. |
1036 | | */ |
1037 | 0 | default: |
1038 | 0 | if (code & (CRYPTO_RESP | CRYPTO_ERROR)) { |
1039 | 0 | rval = XEVNT_ERR; |
1040 | 0 | } else if (peer->cmmd == NULL) { |
1041 | 0 | fp = emalloc(len); |
1042 | 0 | memcpy(fp, ep, len); |
1043 | 0 | peer->cmmd = fp; |
1044 | 0 | } |
1045 | 0 | } |
1046 | | |
1047 | | /* |
1048 | | * The first error found terminates the extension field |
1049 | | * scan and we return the laundry to the caller. |
1050 | | */ |
1051 | 0 | if (rval != XEVNT_OK) { |
1052 | 0 | snprintf(statstr, sizeof(statstr), |
1053 | 0 | "%04x %d %02x %s", htonl(ep->opcode), |
1054 | 0 | associd, rval, eventstr(rval)); |
1055 | 0 | record_crypto_stats(&peer->srcadr, statstr); |
1056 | 0 | DPRINTF(1, ("crypto_recv: %s\n", statstr)); |
1057 | 0 | return (rval); |
1058 | 0 | } |
1059 | 0 | authlen += (len + 3) / 4 * 4; |
1060 | 0 | } |
1061 | 0 | return (rval); |
1062 | 0 | } |
1063 | | |
1064 | | |
1065 | | /* |
1066 | | * crypto_xmit - construct extension fields |
1067 | | * |
1068 | | * This routine is called both when an association is configured and |
1069 | | * when one is not. The only case where this matters is to retrieve the |
1070 | | * autokey information, in which case the caller has to provide the |
1071 | | * association ID to match the association. |
1072 | | * |
1073 | | * Side effect: update the packet offset. |
1074 | | * |
1075 | | * Errors |
1076 | | * XEVNT_OK success |
1077 | | * XEVNT_CRT bad or missing certificate |
1078 | | * XEVNT_ERR protocol error |
1079 | | * XEVNT_LEN bad field format or length |
1080 | | * XEVNT_PER host certificate expired |
1081 | | */ |
1082 | | int |
1083 | | crypto_xmit( |
1084 | | struct peer *peer, /* peer structure pointer */ |
1085 | | struct pkt *xpkt, /* transmit packet pointer */ |
1086 | | struct recvbuf *rbufp, /* receive buffer pointer */ |
1087 | | int start, /* offset to extension field */ |
1088 | | struct exten *ep, /* extension pointer */ |
1089 | | keyid_t cookie /* session cookie */ |
1090 | | ) |
1091 | 0 | { |
1092 | 0 | struct exten *fp; /* extension pointers */ |
1093 | 0 | struct cert_info *cp, *xp, *yp; /* cert info/value pointer */ |
1094 | 0 | sockaddr_u *srcadr_sin; /* source address */ |
1095 | 0 | u_int32 *pkt; /* packet pointer */ |
1096 | 0 | u_int opcode; /* extension field opcode */ |
1097 | 0 | char certname[MAXHOSTNAME + 1]; /* subject name buffer */ |
1098 | 0 | char statstr[NTP_MAXSTRLEN]; /* statistics for filegen */ |
1099 | 0 | tstamp_t tstamp; |
1100 | 0 | struct calendar tscal; |
1101 | 0 | u_int vallen; |
1102 | 0 | struct value vtemp; |
1103 | 0 | associd_t associd; |
1104 | 0 | int rval; |
1105 | 0 | int len; |
1106 | 0 | keyid_t tcookie; |
1107 | | |
1108 | | /* |
1109 | | * Generate the requested extension field request code, length |
1110 | | * and association ID. If this is a response and the host is not |
1111 | | * synchronized, light the error bit and go home. |
1112 | | */ |
1113 | 0 | pkt = (u_int32 *)xpkt + start / 4; |
1114 | 0 | fp = (struct exten *)pkt; |
1115 | 0 | opcode = ntohl(ep->opcode); |
1116 | 0 | if (peer != NULL) { |
1117 | 0 | srcadr_sin = &peer->srcadr; |
1118 | 0 | if (!(opcode & CRYPTO_RESP)) |
1119 | 0 | peer->opcode = ep->opcode; |
1120 | 0 | } else { |
1121 | 0 | srcadr_sin = &rbufp->recv_srcadr; |
1122 | 0 | } |
1123 | 0 | associd = (associd_t) ntohl(ep->associd); |
1124 | 0 | len = 8; |
1125 | 0 | fp->opcode = htonl((opcode & 0xffff0000) | len); |
1126 | 0 | fp->associd = ep->associd; |
1127 | 0 | rval = XEVNT_OK; |
1128 | 0 | tstamp = crypto_time(); |
1129 | 0 | switch (opcode & 0xffff0000) { |
1130 | | |
1131 | | /* |
1132 | | * Send association request and response with status word and |
1133 | | * host name. Note, this message is not signed and the filestamp |
1134 | | * contains only the status word. |
1135 | | */ |
1136 | 0 | case CRYPTO_ASSOC: |
1137 | 0 | case CRYPTO_ASSOC | CRYPTO_RESP: |
1138 | 0 | len = crypto_send(fp, &hostval, start); |
1139 | 0 | fp->fstamp = htonl(crypto_flags); |
1140 | 0 | break; |
1141 | | |
1142 | | /* |
1143 | | * Send certificate request. Use the values from the extension |
1144 | | * field. |
1145 | | */ |
1146 | 0 | case CRYPTO_CERT: |
1147 | 0 | memset(&vtemp, 0, sizeof(vtemp)); |
1148 | 0 | vtemp.tstamp = ep->tstamp; |
1149 | 0 | vtemp.fstamp = ep->fstamp; |
1150 | 0 | vtemp.vallen = ep->vallen; |
1151 | 0 | vtemp.ptr = (u_char *)ep->pkt; |
1152 | 0 | len = crypto_send(fp, &vtemp, start); |
1153 | 0 | break; |
1154 | | |
1155 | | /* |
1156 | | * Send sign request. Use the host certificate, which is self- |
1157 | | * signed and may or may not be trusted. |
1158 | | */ |
1159 | 0 | case CRYPTO_SIGN: |
1160 | 0 | (void)ntpcal_ntp_to_date(&tscal, tstamp, NULL); |
1161 | 0 | if ((calcomp(&tscal, &(cert_host->first)) < 0) |
1162 | 0 | || (calcomp(&tscal, &(cert_host->last)) > 0)) |
1163 | 0 | rval = XEVNT_PER; |
1164 | 0 | else |
1165 | 0 | len = crypto_send(fp, &cert_host->cert, start); |
1166 | 0 | break; |
1167 | | |
1168 | | /* |
1169 | | * Send certificate response. Use the name in the extension |
1170 | | * field to find the certificate in the cache. If the request |
1171 | | * contains no subject name, assume the name of this host. This |
1172 | | * is for backwards compatibility. Private certificates are |
1173 | | * never sent. |
1174 | | * |
1175 | | * There may be several certificates matching the request. First |
1176 | | * choice is a self-signed trusted certificate; second choice is |
1177 | | * any certificate signed by another host. There is no third |
1178 | | * choice. |
1179 | | */ |
1180 | 0 | case CRYPTO_CERT | CRYPTO_RESP: |
1181 | 0 | vallen = exten_payload_size(ep); /* Must be <64k */ |
1182 | 0 | if (vallen == 0 || vallen >= sizeof(certname) ) { |
1183 | 0 | rval = XEVNT_LEN; |
1184 | 0 | break; |
1185 | 0 | } |
1186 | | |
1187 | | /* |
1188 | | * Find all public valid certificates with matching |
1189 | | * subject. If a self-signed, trusted certificate is |
1190 | | * found, use that certificate. If not, use the last non |
1191 | | * self-signed certificate. |
1192 | | */ |
1193 | 0 | memcpy(certname, ep->pkt, vallen); |
1194 | 0 | certname[vallen] = '\0'; |
1195 | 0 | xp = yp = NULL; |
1196 | 0 | for (cp = cinfo; cp != NULL; cp = cp->link) { |
1197 | 0 | if (cp->flags & (CERT_PRIV | CERT_ERROR)) |
1198 | 0 | continue; |
1199 | | |
1200 | 0 | if (strcmp(certname, cp->subject) != 0) |
1201 | 0 | continue; |
1202 | | |
1203 | 0 | if (strcmp(certname, cp->issuer) != 0) |
1204 | 0 | yp = cp; |
1205 | 0 | else if (cp ->flags & CERT_TRUST) |
1206 | 0 | xp = cp; |
1207 | 0 | continue; |
1208 | 0 | } |
1209 | | |
1210 | | /* |
1211 | | * Be careful who you trust. If the certificate is not |
1212 | | * found, return an empty response. Note that we dont |
1213 | | * enforce lifetimes here. |
1214 | | * |
1215 | | * The timestamp and filestamp are taken from the |
1216 | | * certificate value structure. For all certificates the |
1217 | | * timestamp is the latest signature update time. For |
1218 | | * host and imported certificates the filestamp is the |
1219 | | * creation epoch. For signed certificates the filestamp |
1220 | | * is the creation epoch of the trusted certificate at |
1221 | | * the root of the certificate trail. In principle, this |
1222 | | * allows strong checking for signature masquerade. |
1223 | | */ |
1224 | 0 | if (xp == NULL) |
1225 | 0 | xp = yp; |
1226 | 0 | if (xp == NULL) |
1227 | 0 | break; |
1228 | | |
1229 | 0 | if (tstamp == 0) |
1230 | 0 | break; |
1231 | | |
1232 | 0 | len = crypto_send(fp, &xp->cert, start); |
1233 | 0 | break; |
1234 | | |
1235 | | /* |
1236 | | * Send challenge in Schnorr (IFF) identity scheme. |
1237 | | */ |
1238 | 0 | case CRYPTO_IFF: |
1239 | 0 | if (peer == NULL) |
1240 | 0 | break; /* hack attack */ |
1241 | | |
1242 | 0 | if ((rval = crypto_alice(peer, &vtemp)) == XEVNT_OK) { |
1243 | 0 | len = crypto_send(fp, &vtemp, start); |
1244 | 0 | value_free(&vtemp); |
1245 | 0 | } |
1246 | 0 | break; |
1247 | | |
1248 | | /* |
1249 | | * Send response in Schnorr (IFF) identity scheme. |
1250 | | */ |
1251 | 0 | case CRYPTO_IFF | CRYPTO_RESP: |
1252 | 0 | if ((rval = crypto_bob(ep, &vtemp)) == XEVNT_OK) { |
1253 | 0 | len = crypto_send(fp, &vtemp, start); |
1254 | 0 | value_free(&vtemp); |
1255 | 0 | } |
1256 | 0 | break; |
1257 | | |
1258 | | /* |
1259 | | * Send challenge in Guillou-Quisquater (GQ) identity scheme. |
1260 | | */ |
1261 | 0 | case CRYPTO_GQ: |
1262 | 0 | if (peer == NULL) |
1263 | 0 | break; /* hack attack */ |
1264 | | |
1265 | 0 | if ((rval = crypto_alice2(peer, &vtemp)) == XEVNT_OK) { |
1266 | 0 | len = crypto_send(fp, &vtemp, start); |
1267 | 0 | value_free(&vtemp); |
1268 | 0 | } |
1269 | 0 | break; |
1270 | | |
1271 | | /* |
1272 | | * Send response in Guillou-Quisquater (GQ) identity scheme. |
1273 | | */ |
1274 | 0 | case CRYPTO_GQ | CRYPTO_RESP: |
1275 | 0 | if ((rval = crypto_bob2(ep, &vtemp)) == XEVNT_OK) { |
1276 | 0 | len = crypto_send(fp, &vtemp, start); |
1277 | 0 | value_free(&vtemp); |
1278 | 0 | } |
1279 | 0 | break; |
1280 | | |
1281 | | /* |
1282 | | * Send challenge in MV identity scheme. |
1283 | | */ |
1284 | 0 | case CRYPTO_MV: |
1285 | 0 | if (peer == NULL) |
1286 | 0 | break; /* hack attack */ |
1287 | | |
1288 | 0 | if ((rval = crypto_alice3(peer, &vtemp)) == XEVNT_OK) { |
1289 | 0 | len = crypto_send(fp, &vtemp, start); |
1290 | 0 | value_free(&vtemp); |
1291 | 0 | } |
1292 | 0 | break; |
1293 | | |
1294 | | /* |
1295 | | * Send response in MV identity scheme. |
1296 | | */ |
1297 | 0 | case CRYPTO_MV | CRYPTO_RESP: |
1298 | 0 | if ((rval = crypto_bob3(ep, &vtemp)) == XEVNT_OK) { |
1299 | 0 | len = crypto_send(fp, &vtemp, start); |
1300 | 0 | value_free(&vtemp); |
1301 | 0 | } |
1302 | 0 | break; |
1303 | | |
1304 | | /* |
1305 | | * Send certificate sign response. The integrity of the request |
1306 | | * certificate has already been verified on the receive side. |
1307 | | * Sign the response using the local server key. Use the |
1308 | | * filestamp from the request and use the timestamp as the |
1309 | | * current time. Light the error bit if the certificate is |
1310 | | * invalid or contains an unverified signature. |
1311 | | */ |
1312 | 0 | case CRYPTO_SIGN | CRYPTO_RESP: |
1313 | 0 | if ((rval = cert_sign(ep, &vtemp)) == XEVNT_OK) { |
1314 | 0 | len = crypto_send(fp, &vtemp, start); |
1315 | 0 | value_free(&vtemp); |
1316 | 0 | } |
1317 | 0 | break; |
1318 | | |
1319 | | /* |
1320 | | * Send public key and signature. Use the values from the public |
1321 | | * key. |
1322 | | */ |
1323 | 0 | case CRYPTO_COOK: |
1324 | 0 | len = crypto_send(fp, &pubkey, start); |
1325 | 0 | break; |
1326 | | |
1327 | | /* |
1328 | | * Encrypt and send cookie and signature. Light the error bit if |
1329 | | * anything goes wrong. |
1330 | | */ |
1331 | 0 | case CRYPTO_COOK | CRYPTO_RESP: |
1332 | 0 | vallen = ntohl(ep->vallen); /* Must be <64k */ |
1333 | 0 | if ( vallen == 0 |
1334 | 0 | || (vallen >= MAX_VALLEN) |
1335 | 0 | || (opcode & 0x0000ffff) < VALUE_LEN + vallen) { |
1336 | 0 | rval = XEVNT_LEN; |
1337 | 0 | break; |
1338 | 0 | } |
1339 | 0 | if (peer == NULL) |
1340 | 0 | tcookie = cookie; |
1341 | 0 | else |
1342 | 0 | tcookie = peer->hcookie; |
1343 | 0 | if ((rval = crypto_encrypt((const u_char *)ep->pkt, vallen, &tcookie, &vtemp)) |
1344 | 0 | == XEVNT_OK) { |
1345 | 0 | len = crypto_send(fp, &vtemp, start); |
1346 | 0 | value_free(&vtemp); |
1347 | 0 | } |
1348 | 0 | break; |
1349 | | |
1350 | | /* |
1351 | | * Find peer and send autokey data and signature in broadcast |
1352 | | * server and symmetric modes. Use the values in the autokey |
1353 | | * structure. If no association is found, either the server has |
1354 | | * restarted with new associations or some perp has replayed an |
1355 | | * old message, in which case light the error bit. |
1356 | | */ |
1357 | 0 | case CRYPTO_AUTO | CRYPTO_RESP: |
1358 | 0 | if (peer == NULL) { |
1359 | 0 | if ((peer = findpeerbyassoc(associd)) == NULL) { |
1360 | 0 | rval = XEVNT_ERR; |
1361 | 0 | break; |
1362 | 0 | } |
1363 | 0 | } |
1364 | 0 | peer->flags &= ~FLAG_ASSOC; |
1365 | 0 | len = crypto_send(fp, &peer->sndval, start); |
1366 | 0 | break; |
1367 | | |
1368 | | /* |
1369 | | * Send leapseconds values and signature. Use the values from |
1370 | | * the tai structure. If no table has been loaded, just send an |
1371 | | * empty request. |
1372 | | */ |
1373 | 0 | case CRYPTO_LEAP | CRYPTO_RESP: |
1374 | 0 | len = crypto_send(fp, &tai_leap, start); |
1375 | 0 | break; |
1376 | | |
1377 | | /* |
1378 | | * Default - Send a valid command for unknown requests; send |
1379 | | * an error response for unknown resonses. |
1380 | | */ |
1381 | 0 | default: |
1382 | 0 | if (opcode & CRYPTO_RESP) |
1383 | 0 | rval = XEVNT_ERR; |
1384 | 0 | } |
1385 | | |
1386 | | /* |
1387 | | * In case of error, flame the log. If a request, toss the |
1388 | | * puppy; if a response, return so the sender can flame, too. |
1389 | | */ |
1390 | 0 | if (rval != XEVNT_OK) { |
1391 | 0 | u_int32 opcode_bits; |
1392 | |
|
1393 | 0 | opcode_bits = CRYPTO_ERROR; |
1394 | 0 | opcode |= opcode_bits; |
1395 | 0 | fp->opcode |= htonl(opcode_bits); |
1396 | 0 | snprintf(statstr, sizeof(statstr), |
1397 | 0 | "%04x %d %02x %s", opcode, associd, rval, |
1398 | 0 | eventstr(rval)); |
1399 | 0 | record_crypto_stats(srcadr_sin, statstr); |
1400 | 0 | DPRINTF(1, ("crypto_xmit: %s\n", statstr)); |
1401 | 0 | if (!(opcode & CRYPTO_RESP)) |
1402 | 0 | return (0); |
1403 | 0 | } |
1404 | 0 | DPRINTF(1, ("crypto_xmit: flags 0x%x offset %d len %d code 0x%x associd %d\n", |
1405 | 0 | crypto_flags, start, len, opcode >> 16, associd)); |
1406 | 0 | return (len); |
1407 | 0 | } |
1408 | | |
1409 | | |
1410 | | /* |
1411 | | * crypto_verify - verify the extension field value and signature |
1412 | | * |
1413 | | * Returns |
1414 | | * XEVNT_OK success |
1415 | | * XEVNT_ERR protocol error |
1416 | | * XEVNT_FSP bad filestamp |
1417 | | * XEVNT_LEN bad field format or length |
1418 | | * XEVNT_PUB bad or missing public key |
1419 | | * XEVNT_SGL bad signature length |
1420 | | * XEVNT_SIG signature not verified |
1421 | | * XEVNT_TSP bad timestamp |
1422 | | */ |
1423 | | static int |
1424 | | crypto_verify( |
1425 | | struct exten *ep, /* extension pointer */ |
1426 | | struct value *vp, /* value pointer */ |
1427 | | struct peer *peer /* peer structure pointer */ |
1428 | | ) |
1429 | 0 | { |
1430 | 0 | EVP_PKEY *pkey; /* server public key */ |
1431 | 0 | EVP_MD_CTX *ctx; /* signature context */ |
1432 | 0 | tstamp_t tstamp, tstamp1 = 0; /* timestamp */ |
1433 | 0 | tstamp_t fstamp, fstamp1 = 0; /* filestamp */ |
1434 | 0 | u_int vallen; /* value length */ |
1435 | 0 | u_int siglen; /* signature length */ |
1436 | 0 | u_int opcode, len; |
1437 | 0 | int i; |
1438 | | |
1439 | | /* |
1440 | | * We are extremely parannoyed. We require valid opcode, length, |
1441 | | * association ID, timestamp, filestamp, public key, digest, |
1442 | | * signature length and signature, where relevant. Note that |
1443 | | * preliminary length checks are done in the main loop. |
1444 | | */ |
1445 | 0 | len = ntohl(ep->opcode) & 0x0000ffff; |
1446 | 0 | opcode = ntohl(ep->opcode) & 0xffff0000; |
1447 | | |
1448 | | /* |
1449 | | * Check for valid value header, association ID and extension |
1450 | | * field length. Remember, it is not an error to receive an |
1451 | | * unsolicited response; however, the response ID must match |
1452 | | * the association ID. |
1453 | | */ |
1454 | 0 | if (opcode & CRYPTO_ERROR) |
1455 | 0 | return (XEVNT_ERR); |
1456 | | |
1457 | 0 | if (len < VALUE_LEN) |
1458 | 0 | return (XEVNT_LEN); |
1459 | | |
1460 | 0 | if (opcode == (CRYPTO_AUTO | CRYPTO_RESP) && (peer->pmode == |
1461 | 0 | MODE_BROADCAST || (peer->cast_flags & MDF_BCLNT))) { |
1462 | 0 | if (ntohl(ep->associd) != peer->assoc) |
1463 | 0 | return (XEVNT_ERR); |
1464 | 0 | } else { |
1465 | 0 | if (ntohl(ep->associd) != peer->associd) |
1466 | 0 | return (XEVNT_ERR); |
1467 | 0 | } |
1468 | | |
1469 | | /* |
1470 | | * We have a valid value header. Check for valid value and |
1471 | | * signature field lengths. The extension field length must be |
1472 | | * long enough to contain the value header, value and signature. |
1473 | | * Note both the value and signature field lengths are rounded |
1474 | | * up to the next word (4 octets). |
1475 | | */ |
1476 | 0 | vallen = ntohl(ep->vallen); |
1477 | 0 | if ( vallen == 0 |
1478 | 0 | || vallen > MAX_VALLEN) |
1479 | 0 | return (XEVNT_LEN); |
1480 | | |
1481 | 0 | i = (vallen + 3) / 4; |
1482 | 0 | siglen = ntohl(ep->pkt[i]); |
1483 | 0 | ++i; |
1484 | 0 | if ( siglen > MAX_VALLEN |
1485 | 0 | || len - VALUE_LEN < ((vallen + 3) / 4) * 4 |
1486 | 0 | || len - VALUE_LEN - ((vallen + 3) / 4) * 4 |
1487 | 0 | < ((siglen + 3) / 4) * 4) |
1488 | 0 | return (XEVNT_LEN); |
1489 | | |
1490 | | /* |
1491 | | * Check for valid timestamp and filestamp. If the timestamp is |
1492 | | * zero, the sender is not synchronized and signatures are |
1493 | | * not possible. If nonzero the timestamp must not precede the |
1494 | | * filestamp. The timestamp and filestamp must not precede the |
1495 | | * corresponding values in the value structure, if present. |
1496 | | */ |
1497 | 0 | tstamp = ntohl(ep->tstamp); |
1498 | 0 | fstamp = ntohl(ep->fstamp); |
1499 | 0 | if (tstamp == 0) |
1500 | 0 | return (XEVNT_TSP); |
1501 | | |
1502 | 0 | if (tstamp < fstamp) |
1503 | 0 | return (XEVNT_TSP); |
1504 | | |
1505 | 0 | if (vp != NULL) { |
1506 | 0 | tstamp1 = ntohl(vp->tstamp); |
1507 | 0 | fstamp1 = ntohl(vp->fstamp); |
1508 | 0 | if (tstamp1 != 0 && fstamp1 != 0) { |
1509 | 0 | if (tstamp < tstamp1) |
1510 | 0 | return (XEVNT_TSP); |
1511 | | |
1512 | 0 | if ((tstamp < fstamp1 || fstamp < fstamp1)) |
1513 | 0 | return (XEVNT_FSP); |
1514 | 0 | } |
1515 | 0 | } |
1516 | | |
1517 | | /* |
1518 | | * At the time the certificate message is validated, the public |
1519 | | * key in the message is not available. Thus, don't try to |
1520 | | * verify the signature. |
1521 | | */ |
1522 | 0 | if (opcode == (CRYPTO_CERT | CRYPTO_RESP)) |
1523 | 0 | return (XEVNT_OK); |
1524 | | |
1525 | | /* |
1526 | | * Check for valid signature length, public key and digest |
1527 | | * algorithm. |
1528 | | */ |
1529 | 0 | if (crypto_flags & peer->crypto & CRYPTO_FLAG_PRIV) |
1530 | 0 | pkey = sign_pkey; |
1531 | 0 | else |
1532 | 0 | pkey = peer->pkey; |
1533 | 0 | if (siglen == 0 || pkey == NULL || peer->digest == NULL) |
1534 | 0 | return (XEVNT_ERR); |
1535 | | |
1536 | 0 | if (siglen != (u_int)EVP_PKEY_size(pkey)) |
1537 | 0 | return (XEVNT_SGL); |
1538 | | |
1539 | | /* |
1540 | | * Darn, I thought we would never get here. Verify the |
1541 | | * signature. If the identity exchange is verified, light the |
1542 | | * proventic bit. What a relief. |
1543 | | */ |
1544 | 0 | ctx = digest_ctx; |
1545 | 0 | EVP_VerifyInit(ctx, peer->digest); |
1546 | 0 | EVP_VerifyUpdate(ctx, (u_char *)&ep->tstamp, vallen + |
1547 | 0 | sizeof(ep->tstamp) + sizeof(ep->fstamp) + |
1548 | 0 | sizeof(ep->vallen)); |
1549 | 0 | if (EVP_VerifyFinal(ctx, (u_char *)&ep->pkt[i], siglen, |
1550 | 0 | pkey) <= 0) { |
1551 | 0 | return (XEVNT_SIG); |
1552 | 0 | } |
1553 | | |
1554 | 0 | if (peer->crypto & CRYPTO_FLAG_VRFY) |
1555 | 0 | peer->crypto |= CRYPTO_FLAG_PROV; |
1556 | 0 | return (XEVNT_OK); |
1557 | 0 | } |
1558 | | |
1559 | | |
1560 | | /* |
1561 | | * crypto_encrypt - construct vp (encrypted cookie and signature) from |
1562 | | * the public key and cookie. |
1563 | | * |
1564 | | * Returns: |
1565 | | * XEVNT_OK success |
1566 | | * XEVNT_CKY bad or missing cookie |
1567 | | * XEVNT_PUB bad or missing public key |
1568 | | */ |
1569 | | static int |
1570 | | crypto_encrypt( |
1571 | | const u_char *ptr, /* Public Key */ |
1572 | | u_int vallen, /* Length of Public Key */ |
1573 | | keyid_t *cookie, /* server cookie */ |
1574 | | struct value *vp /* value pointer */ |
1575 | | ) |
1576 | 0 | { |
1577 | 0 | EVP_PKEY *pkey; /* public key */ |
1578 | 0 | RSA* rsa; /* public key */ |
1579 | 0 | EVP_MD_CTX *ctx; /* signature context */ |
1580 | 0 | tstamp_t tstamp; /* NTP timestamp */ |
1581 | 0 | u_int32 temp32; |
1582 | 0 | u_char *puch; |
1583 | | |
1584 | | /* |
1585 | | * Extract the public key from the request. |
1586 | | */ |
1587 | 0 | pkey = d2i_PublicKey(EVP_PKEY_RSA, NULL, &ptr, vallen); |
1588 | 0 | if (pkey == NULL) { |
1589 | 0 | msyslog(LOG_ERR, "crypto_encrypt: %s", |
1590 | 0 | ERR_error_string(ERR_get_error(), NULL)); |
1591 | 0 | return (XEVNT_PUB); |
1592 | 0 | } |
1593 | | |
1594 | | /* |
1595 | | * Encrypt the cookie, encode in ASN.1 and sign. |
1596 | | */ |
1597 | 0 | memset(vp, 0, sizeof(struct value)); |
1598 | 0 | tstamp = crypto_time(); |
1599 | 0 | vp->tstamp = htonl(tstamp); |
1600 | 0 | vp->fstamp = hostval.tstamp; |
1601 | 0 | vallen = EVP_PKEY_size(pkey); |
1602 | 0 | vp->vallen = htonl(vallen); |
1603 | 0 | vp->ptr = emalloc(vallen); |
1604 | 0 | puch = vp->ptr; |
1605 | 0 | temp32 = htonl(*cookie); |
1606 | 0 | rsa = EVP_PKEY_get1_RSA(pkey); |
1607 | 0 | if (RSA_public_encrypt(4, (u_char *)&temp32, puch, rsa, |
1608 | 0 | RSA_PKCS1_OAEP_PADDING) <= 0) { |
1609 | 0 | msyslog(LOG_ERR, "crypto_encrypt: %s", |
1610 | 0 | ERR_error_string(ERR_get_error(), NULL)); |
1611 | 0 | free(vp->ptr); |
1612 | 0 | EVP_PKEY_free(pkey); |
1613 | 0 | return (XEVNT_CKY); |
1614 | 0 | } |
1615 | 0 | EVP_PKEY_free(pkey); |
1616 | 0 | pkey = NULL; |
1617 | 0 | RSA_free(rsa); |
1618 | 0 | rsa = NULL; |
1619 | 0 | if (tstamp == 0) |
1620 | 0 | return (XEVNT_OK); |
1621 | | |
1622 | 0 | vp->sig = emalloc(sign_siglen); |
1623 | 0 | ctx = digest_ctx; |
1624 | 0 | EVP_SignInit(ctx, sign_digest); |
1625 | 0 | EVP_SignUpdate(ctx, (u_char *)&vp->tstamp, 12); |
1626 | 0 | EVP_SignUpdate(ctx, vp->ptr, vallen); |
1627 | 0 | if (EVP_SignFinal(ctx, vp->sig, &vallen, sign_pkey)) { |
1628 | 0 | INSIST(vallen <= sign_siglen); |
1629 | 0 | vp->siglen = htonl(vallen); |
1630 | 0 | } |
1631 | 0 | return (XEVNT_OK); |
1632 | 0 | } |
1633 | | |
1634 | | |
1635 | | /* |
1636 | | * crypto_ident - construct extension field for identity scheme |
1637 | | * |
1638 | | * This routine determines which identity scheme is in use and |
1639 | | * constructs an extension field for that scheme. |
1640 | | * |
1641 | | * Returns |
1642 | | * CRYTPO_IFF IFF scheme |
1643 | | * CRYPTO_GQ GQ scheme |
1644 | | * CRYPTO_MV MV scheme |
1645 | | * CRYPTO_NULL no available scheme |
1646 | | */ |
1647 | | u_int |
1648 | | crypto_ident( |
1649 | | struct peer *peer /* peer structure pointer */ |
1650 | | ) |
1651 | 0 | { |
1652 | 0 | char filename[MAXFILENAME]; |
1653 | 0 | const char * scheme_name; |
1654 | 0 | u_int scheme_id; |
1655 | | |
1656 | | /* |
1657 | | * We come here after the group trusted host has been found; its |
1658 | | * name defines the group name. Search the key cache for all |
1659 | | * keys matching the same group name in order IFF, GQ and MV. |
1660 | | * Use the first one available. |
1661 | | */ |
1662 | 0 | scheme_name = NULL; |
1663 | 0 | if (peer->crypto & CRYPTO_FLAG_IFF) { |
1664 | 0 | scheme_name = "iff"; |
1665 | 0 | scheme_id = CRYPTO_IFF; |
1666 | 0 | } else if (peer->crypto & CRYPTO_FLAG_GQ) { |
1667 | 0 | scheme_name = "gq"; |
1668 | 0 | scheme_id = CRYPTO_GQ; |
1669 | 0 | } else if (peer->crypto & CRYPTO_FLAG_MV) { |
1670 | 0 | scheme_name = "mv"; |
1671 | 0 | scheme_id = CRYPTO_MV; |
1672 | 0 | } |
1673 | |
|
1674 | 0 | if (scheme_name != NULL) { |
1675 | 0 | snprintf(filename, sizeof(filename), "ntpkey_%spar_%s", |
1676 | 0 | scheme_name, peer->ident); |
1677 | 0 | peer->ident_pkey = crypto_key(filename, NULL, |
1678 | 0 | &peer->srcadr); |
1679 | 0 | if (peer->ident_pkey != NULL) |
1680 | 0 | return scheme_id; |
1681 | 0 | } |
1682 | | |
1683 | 0 | msyslog(LOG_NOTICE, |
1684 | 0 | "crypto_ident: no identity parameters found for group %s", |
1685 | 0 | peer->ident); |
1686 | |
|
1687 | 0 | return CRYPTO_NULL; |
1688 | 0 | } |
1689 | | |
1690 | | |
1691 | | /* |
1692 | | * crypto_args - construct extension field from arguments |
1693 | | * |
1694 | | * This routine creates an extension field with current timestamps and |
1695 | | * specified opcode, association ID and optional string. Note that the |
1696 | | * extension field is created here, but freed after the crypto_xmit() |
1697 | | * call in the protocol module. |
1698 | | * |
1699 | | * Returns extension field pointer (no errors) |
1700 | | * |
1701 | | * XXX: opcode and len should really be 32-bit quantities and |
1702 | | * we should make sure that str is not too big. |
1703 | | */ |
1704 | | struct exten * |
1705 | | crypto_args( |
1706 | | struct peer *peer, /* peer structure pointer */ |
1707 | | u_int opcode, /* operation code */ |
1708 | | associd_t associd, /* association ID */ |
1709 | | char *str /* argument string */ |
1710 | | ) |
1711 | 0 | { |
1712 | 0 | tstamp_t tstamp; /* NTP timestamp */ |
1713 | 0 | struct exten *ep; /* extension field pointer */ |
1714 | 0 | u_int len; /* extension field length */ |
1715 | 0 | size_t slen = 0; |
1716 | |
|
1717 | 0 | tstamp = crypto_time(); |
1718 | 0 | len = sizeof(struct exten); |
1719 | 0 | if (str != NULL) { |
1720 | 0 | slen = strlen(str); |
1721 | 0 | INSIST(slen < MAX_VALLEN); |
1722 | 0 | len += slen; |
1723 | 0 | } |
1724 | 0 | ep = emalloc_zero(len); |
1725 | 0 | if (opcode == 0) |
1726 | 0 | return (ep); |
1727 | | |
1728 | 0 | REQUIRE(0 == (len & ~0x0000ffff)); |
1729 | 0 | REQUIRE(0 == (opcode & ~0xffff0000)); |
1730 | | |
1731 | 0 | ep->opcode = htonl(opcode + len); |
1732 | 0 | ep->associd = htonl(associd); |
1733 | 0 | ep->tstamp = htonl(tstamp); |
1734 | 0 | ep->fstamp = hostval.tstamp; |
1735 | 0 | ep->vallen = 0; |
1736 | 0 | if (str != NULL) { |
1737 | 0 | ep->vallen = htonl(slen); |
1738 | 0 | memcpy((char *)ep->pkt, str, slen); |
1739 | 0 | } |
1740 | 0 | return (ep); |
1741 | 0 | } |
1742 | | |
1743 | | |
1744 | | /* |
1745 | | * crypto_send - construct extension field from value components |
1746 | | * |
1747 | | * The value and signature fields are zero-padded to a word boundary. |
1748 | | * Note: it is not polite to send a nonempty signature with zero |
1749 | | * timestamp or a nonzero timestamp with an empty signature, but those |
1750 | | * rules are not enforced here. |
1751 | | * |
1752 | | * XXX This code won't work on a box with 16-bit ints. |
1753 | | */ |
1754 | | int |
1755 | | crypto_send( |
1756 | | struct exten *ep, /* extension field pointer */ |
1757 | | struct value *vp, /* value pointer */ |
1758 | | int start /* buffer offset */ |
1759 | | ) |
1760 | 0 | { |
1761 | 0 | u_int len, vallen, siglen, opcode; |
1762 | 0 | u_int i, j; |
1763 | | |
1764 | | /* |
1765 | | * Calculate extension field length and check for buffer |
1766 | | * overflow. Leave room for the MAC. |
1767 | | */ |
1768 | 0 | len = 16; /* XXX Document! */ |
1769 | 0 | vallen = ntohl(vp->vallen); |
1770 | 0 | INSIST(vallen <= MAX_VALLEN); |
1771 | 0 | len += ((vallen + 3) / 4 + 1) * 4; |
1772 | 0 | siglen = ntohl(vp->siglen); |
1773 | 0 | len += ((siglen + 3) / 4 + 1) * 4; |
1774 | 0 | if (start + len > sizeof(struct pkt) - MAX_MAC_LEN) |
1775 | 0 | return (0); |
1776 | | |
1777 | | /* |
1778 | | * Copy timestamps. |
1779 | | */ |
1780 | 0 | ep->tstamp = vp->tstamp; |
1781 | 0 | ep->fstamp = vp->fstamp; |
1782 | 0 | ep->vallen = vp->vallen; |
1783 | | |
1784 | | /* |
1785 | | * Copy value. If the data field is empty or zero length, |
1786 | | * encode an empty value with length zero. |
1787 | | */ |
1788 | 0 | i = 0; |
1789 | 0 | if (vallen > 0 && vp->ptr != NULL) { |
1790 | 0 | j = vallen / 4; |
1791 | 0 | if (j * 4 < vallen) |
1792 | 0 | ep->pkt[i + j++] = 0; |
1793 | 0 | memcpy(&ep->pkt[i], vp->ptr, vallen); |
1794 | 0 | i += j; |
1795 | 0 | } |
1796 | | |
1797 | | /* |
1798 | | * Copy signature. If the signature field is empty or zero |
1799 | | * length, encode an empty signature with length zero. |
1800 | | */ |
1801 | 0 | ep->pkt[i++] = vp->siglen; |
1802 | 0 | if (siglen > 0 && vp->sig != NULL) { |
1803 | 0 | j = siglen / 4; |
1804 | 0 | if (j * 4 < siglen) |
1805 | 0 | ep->pkt[i + j++] = 0; |
1806 | 0 | memcpy(&ep->pkt[i], vp->sig, siglen); |
1807 | | /* i += j; */ /* We don't use i after this */ |
1808 | 0 | } |
1809 | 0 | opcode = ntohl(ep->opcode); |
1810 | 0 | ep->opcode = htonl((opcode & 0xffff0000) | len); |
1811 | 0 | ENSURE(len <= MAX_VALLEN); |
1812 | 0 | return (len); |
1813 | 0 | } |
1814 | | |
1815 | | |
1816 | | /* |
1817 | | * crypto_update - compute new public value and sign extension fields |
1818 | | * |
1819 | | * This routine runs periodically, like once a day, and when something |
1820 | | * changes. It updates the timestamps on three value structures and one |
1821 | | * value structure list, then signs all the structures: |
1822 | | * |
1823 | | * hostval host name (not signed) |
1824 | | * pubkey public key |
1825 | | * cinfo certificate info/value list |
1826 | | * tai_leap leap values |
1827 | | * |
1828 | | * Filestamps are proventic data, so this routine runs only when the |
1829 | | * host is synchronized to a proventicated source. Thus, the timestamp |
1830 | | * is proventic and can be used to deflect clogging attacks. |
1831 | | * |
1832 | | * Returns void (no errors) |
1833 | | */ |
1834 | | void |
1835 | | crypto_update(void) |
1836 | 0 | { |
1837 | 0 | EVP_MD_CTX *ctx; /* message digest context */ |
1838 | 0 | struct cert_info *cp; /* certificate info/value */ |
1839 | 0 | char statstr[NTP_MAXSTRLEN]; /* statistics for filegen */ |
1840 | 0 | u_int32 *ptr; |
1841 | 0 | u_int len; |
1842 | 0 | leap_result_t leap_data; |
1843 | |
|
1844 | 0 | hostval.tstamp = htonl(crypto_time()); |
1845 | 0 | if (hostval.tstamp == 0) |
1846 | 0 | return; |
1847 | | |
1848 | 0 | ctx = digest_ctx; |
1849 | | |
1850 | | /* |
1851 | | * Sign public key and timestamps. The filestamp is derived from |
1852 | | * the host key file extension from wherever the file was |
1853 | | * generated. |
1854 | | */ |
1855 | 0 | if (pubkey.vallen != 0) { |
1856 | 0 | pubkey.tstamp = hostval.tstamp; |
1857 | 0 | pubkey.siglen = 0; |
1858 | 0 | if (pubkey.sig == NULL) |
1859 | 0 | pubkey.sig = emalloc(sign_siglen); |
1860 | 0 | EVP_SignInit(ctx, sign_digest); |
1861 | 0 | EVP_SignUpdate(ctx, (u_char *)&pubkey, 12); |
1862 | 0 | EVP_SignUpdate(ctx, pubkey.ptr, ntohl(pubkey.vallen)); |
1863 | 0 | if (EVP_SignFinal(ctx, pubkey.sig, &len, sign_pkey)) { |
1864 | 0 | INSIST(len <= sign_siglen); |
1865 | 0 | pubkey.siglen = htonl(len); |
1866 | 0 | } |
1867 | 0 | } |
1868 | | |
1869 | | /* |
1870 | | * Sign certificates and timestamps. The filestamp is derived |
1871 | | * from the certificate file extension from wherever the file |
1872 | | * was generated. Note we do not throw expired certificates |
1873 | | * away; they may have signed younger ones. |
1874 | | */ |
1875 | 0 | for (cp = cinfo; cp != NULL; cp = cp->link) { |
1876 | 0 | cp->cert.tstamp = hostval.tstamp; |
1877 | 0 | cp->cert.siglen = 0; |
1878 | 0 | if (cp->cert.sig == NULL) |
1879 | 0 | cp->cert.sig = emalloc(sign_siglen); |
1880 | 0 | EVP_SignInit(ctx, sign_digest); |
1881 | 0 | EVP_SignUpdate(ctx, (u_char *)&cp->cert, 12); |
1882 | 0 | EVP_SignUpdate(ctx, cp->cert.ptr, |
1883 | 0 | ntohl(cp->cert.vallen)); |
1884 | 0 | if (EVP_SignFinal(ctx, cp->cert.sig, &len, sign_pkey)) { |
1885 | 0 | INSIST(len <= sign_siglen); |
1886 | 0 | cp->cert.siglen = htonl(len); |
1887 | 0 | } |
1888 | 0 | } |
1889 | | |
1890 | | /* |
1891 | | * Sign leapseconds values and timestamps. Note it is not an |
1892 | | * error to return null values. |
1893 | | */ |
1894 | 0 | tai_leap.tstamp = hostval.tstamp; |
1895 | 0 | tai_leap.fstamp = hostval.fstamp; |
1896 | | |
1897 | | /* Get the leap second era. We might need a full lookup early |
1898 | | * after start, when the cache is not yet loaded. |
1899 | | */ |
1900 | 0 | leapsec_frame(&leap_data); |
1901 | 0 | if ( ! memcmp(&leap_data.ebase, &leap_data.ttime, sizeof(vint64))) { |
1902 | 0 | time_t now = time(NULL); |
1903 | 0 | uint32_t nowntp = (uint32_t)now + JAN_1970; |
1904 | 0 | leapsec_query(&leap_data, nowntp, &now); |
1905 | 0 | } |
1906 | | |
1907 | | /* Create the data block. The protocol does not work without. */ |
1908 | 0 | len = 3 * sizeof(u_int32); |
1909 | 0 | if (tai_leap.ptr == NULL || ntohl(tai_leap.vallen) != len) { |
1910 | 0 | free(tai_leap.ptr); |
1911 | 0 | tai_leap.ptr = emalloc(len); |
1912 | 0 | tai_leap.vallen = htonl(len); |
1913 | 0 | } |
1914 | 0 | ptr = (u_int32 *)tai_leap.ptr; |
1915 | 0 | if (leap_data.tai_offs > 10) { |
1916 | | /* create a TAI / leap era block. The end time is a |
1917 | | * fake -- maybe we can do better. |
1918 | | */ |
1919 | 0 | ptr[0] = htonl(leap_data.tai_offs); |
1920 | 0 | ptr[1] = htonl(leap_data.ebase.d_s.lo); |
1921 | 0 | if (leap_data.ttime.d_s.hi >= 0) |
1922 | 0 | ptr[2] = htonl(leap_data.ttime.D_s.lo + 7*86400); |
1923 | 0 | else |
1924 | 0 | ptr[2] = htonl(leap_data.ebase.D_s.lo + 25*86400); |
1925 | 0 | } else { |
1926 | | /* no leap era available */ |
1927 | 0 | memset(ptr, 0, len); |
1928 | 0 | } |
1929 | 0 | if (tai_leap.sig == NULL) |
1930 | 0 | tai_leap.sig = emalloc(sign_siglen); |
1931 | 0 | EVP_SignInit(ctx, sign_digest); |
1932 | 0 | EVP_SignUpdate(ctx, (u_char *)&tai_leap, 12); |
1933 | 0 | EVP_SignUpdate(ctx, tai_leap.ptr, len); |
1934 | 0 | if (EVP_SignFinal(ctx, tai_leap.sig, &len, sign_pkey)) { |
1935 | 0 | INSIST(len <= sign_siglen); |
1936 | 0 | tai_leap.siglen = htonl(len); |
1937 | 0 | } |
1938 | 0 | crypto_flags |= CRYPTO_FLAG_TAI; |
1939 | |
|
1940 | 0 | snprintf(statstr, sizeof(statstr), "signature update ts %u", |
1941 | 0 | ntohl(hostval.tstamp)); |
1942 | 0 | record_crypto_stats(NULL, statstr); |
1943 | 0 | DPRINTF(1, ("crypto_update: %s\n", statstr)); |
1944 | 0 | } |
1945 | | |
1946 | | /* |
1947 | | * crypto_update_taichange - eventually trigger crypto_update |
1948 | | * |
1949 | | * This is called when a change in 'sys_tai' is detected. This will |
1950 | | * happen shortly after a leap second is detected, but unhappily also |
1951 | | * early after system start; also, the crypto stuff might be unused and |
1952 | | * an unguarded call to crypto_update() causes a crash. |
1953 | | * |
1954 | | * This function makes sure that there already *is* a valid crypto block |
1955 | | * for the use with autokey, and only calls 'crypto_update()' if it can |
1956 | | * succeed. |
1957 | | * |
1958 | | * Returns void (no errors) |
1959 | | */ |
1960 | | void |
1961 | | crypto_update_taichange(void) |
1962 | 0 | { |
1963 | 0 | static const u_int len = 3 * sizeof(u_int32); |
1964 | | |
1965 | | /* check if the signing digest algo is available */ |
1966 | 0 | if (sign_digest == NULL || sign_pkey == NULL) |
1967 | 0 | return; |
1968 | | |
1969 | | /* check size of TAI extension block */ |
1970 | 0 | if (tai_leap.ptr == NULL || ntohl(tai_leap.vallen) != len) |
1971 | 0 | return; |
1972 | | |
1973 | | /* crypto_update should at least not crash here! */ |
1974 | 0 | crypto_update(); |
1975 | 0 | } |
1976 | | |
1977 | | /* |
1978 | | * value_free - free value structure components. |
1979 | | * |
1980 | | * Returns void (no errors) |
1981 | | */ |
1982 | | void |
1983 | | value_free( |
1984 | | struct value *vp /* value structure */ |
1985 | | ) |
1986 | 0 | { |
1987 | 0 | if (vp->ptr != NULL) |
1988 | 0 | free(vp->ptr); |
1989 | 0 | if (vp->sig != NULL) |
1990 | 0 | free(vp->sig); |
1991 | 0 | memset(vp, 0, sizeof(struct value)); |
1992 | 0 | } |
1993 | | |
1994 | | |
1995 | | /* |
1996 | | * crypto_time - returns current NTP time. |
1997 | | * |
1998 | | * Returns NTP seconds if in synch, 0 otherwise |
1999 | | */ |
2000 | | tstamp_t |
2001 | | crypto_time(void) |
2002 | 0 | { |
2003 | 0 | l_fp tstamp; /* NTP time */ |
2004 | |
|
2005 | 0 | L_CLR(&tstamp); |
2006 | 0 | if (sys_leap != LEAP_NOTINSYNC) |
2007 | 0 | get_systime(&tstamp); |
2008 | 0 | return (tstamp.l_ui); |
2009 | 0 | } |
2010 | | |
2011 | | |
2012 | | /* |
2013 | | * asn_to_calendar - convert ASN1_TIME time structure to struct calendar. |
2014 | | * |
2015 | | */ |
2016 | | static |
2017 | | void |
2018 | | asn_to_calendar ( |
2019 | | const ASN1_TIME *asn1time, /* pointer to ASN1_TIME structure */ |
2020 | | struct calendar *pjd /* pointer to result */ |
2021 | | ) |
2022 | 0 | { |
2023 | 0 | size_t len; /* length of ASN1_TIME string */ |
2024 | 0 | char v[24]; /* writable copy of ASN1_TIME string */ |
2025 | 0 | unsigned long temp; /* result from strtoul */ |
2026 | | |
2027 | | /* |
2028 | | * Extract time string YYMMDDHHMMSSZ from ASN1 time structure. |
2029 | | * Or YYYYMMDDHHMMSSZ. |
2030 | | * Note that the YY, MM, DD fields start with one, the HH, MM, |
2031 | | * SS fields start with zero and the Z character is ignored. |
2032 | | * Also note that two-digit years less than 50 map to years greater than |
2033 | | * 100. Dontcha love ASN.1? Better than MIL-188. |
2034 | | */ |
2035 | 0 | len = asn1time->length; |
2036 | 0 | REQUIRE(len < sizeof(v)); |
2037 | 0 | (void)strncpy(v, (char *)(asn1time->data), len); |
2038 | 0 | REQUIRE(len >= 13); |
2039 | 0 | temp = strtoul(v+len-3, NULL, 10); |
2040 | 0 | pjd->second = temp; |
2041 | 0 | v[len-3] = '\0'; |
2042 | |
|
2043 | 0 | temp = strtoul(v+len-5, NULL, 10); |
2044 | 0 | pjd->minute = temp; |
2045 | 0 | v[len-5] = '\0'; |
2046 | |
|
2047 | 0 | temp = strtoul(v+len-7, NULL, 10); |
2048 | 0 | pjd->hour = temp; |
2049 | 0 | v[len-7] = '\0'; |
2050 | |
|
2051 | 0 | temp = strtoul(v+len-9, NULL, 10); |
2052 | 0 | pjd->monthday = temp; |
2053 | 0 | v[len-9] = '\0'; |
2054 | |
|
2055 | 0 | temp = strtoul(v+len-11, NULL, 10); |
2056 | 0 | pjd->month = temp; |
2057 | 0 | v[len-11] = '\0'; |
2058 | |
|
2059 | 0 | temp = strtoul(v, NULL, 10); |
2060 | | /* handle two-digit years */ |
2061 | 0 | if (temp < 50UL) |
2062 | 0 | temp += 100UL; |
2063 | 0 | if (temp < 150UL) |
2064 | 0 | temp += 1900UL; |
2065 | 0 | pjd->year = temp; |
2066 | |
|
2067 | 0 | pjd->yearday = pjd->weekday = 0; |
2068 | 0 | return; |
2069 | 0 | } |
2070 | | |
2071 | | |
2072 | | /* |
2073 | | * bighash() - compute a BIGNUM MD5 hash of a BIGNUM number. |
2074 | | * |
2075 | | * Returns void (no errors) |
2076 | | */ |
2077 | | static void |
2078 | | bighash( |
2079 | | BIGNUM *bn, /* BIGNUM * from */ |
2080 | | BIGNUM *bk /* BIGNUM * to */ |
2081 | | ) |
2082 | 0 | { |
2083 | 0 | EVP_MD_CTX *ctx; /* message digest context */ |
2084 | 0 | u_char dgst[EVP_MAX_MD_SIZE]; /* message digest */ |
2085 | 0 | u_char *ptr; /* a BIGNUM as binary string */ |
2086 | 0 | u_int len; |
2087 | |
|
2088 | 0 | len = BN_num_bytes(bn); |
2089 | 0 | ptr = emalloc(len); |
2090 | 0 | BN_bn2bin(bn, ptr); |
2091 | 0 | ctx = digest_ctx; |
2092 | 0 | EVP_DigestInit(ctx, EVP_md5()); |
2093 | 0 | EVP_DigestUpdate(ctx, ptr, len); |
2094 | 0 | EVP_DigestFinal(ctx, dgst, &len); |
2095 | 0 | BN_bin2bn(dgst, len, bk); |
2096 | 0 | free(ptr); |
2097 | 0 | } |
2098 | | |
2099 | | |
2100 | | /* |
2101 | | *********************************************************************** |
2102 | | * * |
2103 | | * The following routines implement the Schnorr (IFF) identity scheme * |
2104 | | * * |
2105 | | *********************************************************************** |
2106 | | * |
2107 | | * The Schnorr (IFF) identity scheme is intended for use when |
2108 | | * certificates are generated by some other trusted certificate |
2109 | | * authority and the certificate cannot be used to convey public |
2110 | | * parameters. There are two kinds of files: encrypted server files that |
2111 | | * contain private and public values and nonencrypted client files that |
2112 | | * contain only public values. New generations of server files must be |
2113 | | * securely transmitted to all servers of the group; client files can be |
2114 | | * distributed by any means. The scheme is self contained and |
2115 | | * independent of new generations of host keys, sign keys and |
2116 | | * certificates. |
2117 | | * |
2118 | | * The IFF values hide in a DSA cuckoo structure which uses the same |
2119 | | * parameters. The values are used by an identity scheme based on DSA |
2120 | | * cryptography and described in Stimson p. 285. The p is a 512-bit |
2121 | | * prime, g a generator of Zp* and q a 160-bit prime that divides p - 1 |
2122 | | * and is a qth root of 1 mod p; that is, g^q = 1 mod p. The TA rolls a |
2123 | | * private random group key b (0 < b < q) and public key v = g^b, then |
2124 | | * sends (p, q, g, b) to the servers and (p, q, g, v) to the clients. |
2125 | | * Alice challenges Bob to confirm identity using the protocol described |
2126 | | * below. |
2127 | | * |
2128 | | * How it works |
2129 | | * |
2130 | | * The scheme goes like this. Both Alice and Bob have the public primes |
2131 | | * p, q and generator g. The TA gives private key b to Bob and public |
2132 | | * key v to Alice. |
2133 | | * |
2134 | | * Alice rolls new random challenge r (o < r < q) and sends to Bob in |
2135 | | * the IFF request message. Bob rolls new random k (0 < k < q), then |
2136 | | * computes y = k + b r mod q and x = g^k mod p and sends (y, hash(x)) |
2137 | | * to Alice in the response message. Besides making the response |
2138 | | * shorter, the hash makes it effectivey impossible for an intruder to |
2139 | | * solve for b by observing a number of these messages. |
2140 | | * |
2141 | | * Alice receives the response and computes g^y v^r mod p. After a bit |
2142 | | * of algebra, this simplifies to g^k. If the hash of this result |
2143 | | * matches hash(x), Alice knows that Bob has the group key b. The signed |
2144 | | * response binds this knowledge to Bob's private key and the public key |
2145 | | * previously received in his certificate. |
2146 | | * |
2147 | | * crypto_alice - construct Alice's challenge in IFF scheme |
2148 | | * |
2149 | | * Returns |
2150 | | * XEVNT_OK success |
2151 | | * XEVNT_ID bad or missing group key |
2152 | | * XEVNT_PUB bad or missing public key |
2153 | | */ |
2154 | | static int |
2155 | | crypto_alice( |
2156 | | struct peer *peer, /* peer pointer */ |
2157 | | struct value *vp /* value pointer */ |
2158 | | ) |
2159 | 0 | { |
2160 | 0 | const DSA *dsa; /* IFF parameters */ |
2161 | 0 | BN_CTX *bctx; /* BIGNUM context */ |
2162 | 0 | EVP_MD_CTX *ctx; /* signature context */ |
2163 | 0 | tstamp_t tstamp; |
2164 | 0 | u_int len; |
2165 | 0 | const BIGNUM *q; |
2166 | | |
2167 | | /* |
2168 | | * The identity parameters must have correct format and content. |
2169 | | */ |
2170 | 0 | if (peer->ident_pkey == NULL) { |
2171 | 0 | msyslog(LOG_NOTICE, "crypto_alice: scheme unavailable"); |
2172 | 0 | return (XEVNT_ID); |
2173 | 0 | } |
2174 | | |
2175 | 0 | if ((dsa = EVP_PKEY_get0_DSA(peer->ident_pkey->pkey)) == NULL) { |
2176 | 0 | msyslog(LOG_NOTICE, "crypto_alice: defective key"); |
2177 | 0 | return (XEVNT_PUB); |
2178 | 0 | } |
2179 | | |
2180 | | /* |
2181 | | * Roll new random r (0 < r < q). |
2182 | | */ |
2183 | 0 | if (peer->iffval != NULL) |
2184 | 0 | BN_free(peer->iffval); |
2185 | 0 | peer->iffval = BN_new(); |
2186 | 0 | DSA_get0_pqg(dsa, NULL, &q, NULL); |
2187 | 0 | len = BN_num_bytes(q); |
2188 | 0 | BN_rand(peer->iffval, len * 8, -1, 1); /* r mod q*/ |
2189 | 0 | bctx = BN_CTX_new(); |
2190 | 0 | BN_mod(peer->iffval, peer->iffval, q, bctx); |
2191 | 0 | BN_CTX_free(bctx); |
2192 | | |
2193 | | /* |
2194 | | * Sign and send to Bob. The filestamp is from the local file. |
2195 | | */ |
2196 | 0 | memset(vp, 0, sizeof(struct value)); |
2197 | 0 | tstamp = crypto_time(); |
2198 | 0 | vp->tstamp = htonl(tstamp); |
2199 | 0 | vp->fstamp = htonl(peer->ident_pkey->fstamp); |
2200 | 0 | vp->vallen = htonl(len); |
2201 | 0 | vp->ptr = emalloc(len); |
2202 | 0 | BN_bn2bin(peer->iffval, vp->ptr); |
2203 | 0 | if (tstamp == 0) |
2204 | 0 | return (XEVNT_OK); |
2205 | | |
2206 | 0 | vp->sig = emalloc(sign_siglen); |
2207 | 0 | ctx = digest_ctx; |
2208 | 0 | EVP_SignInit(ctx, sign_digest); |
2209 | 0 | EVP_SignUpdate(ctx, (u_char *)&vp->tstamp, 12); |
2210 | 0 | EVP_SignUpdate(ctx, vp->ptr, len); |
2211 | 0 | if (EVP_SignFinal(ctx, vp->sig, &len, sign_pkey)) { |
2212 | 0 | INSIST(len <= sign_siglen); |
2213 | 0 | vp->siglen = htonl(len); |
2214 | 0 | } |
2215 | 0 | return (XEVNT_OK); |
2216 | 0 | } |
2217 | | |
2218 | | |
2219 | | /* |
2220 | | * crypto_bob - construct Bob's response to Alice's challenge |
2221 | | * |
2222 | | * Returns |
2223 | | * XEVNT_OK success |
2224 | | * XEVNT_ERR protocol error |
2225 | | * XEVNT_ID bad or missing group key |
2226 | | */ |
2227 | | static int |
2228 | | crypto_bob( |
2229 | | struct exten *ep, /* extension pointer */ |
2230 | | struct value *vp /* value pointer */ |
2231 | | ) |
2232 | 0 | { |
2233 | 0 | int retv; /* return value */ |
2234 | 0 | const DSA *dsa; /* IFF parameters */ |
2235 | 0 | DSA_SIG *sdsa; /* DSA signature context fake */ |
2236 | 0 | BN_CTX *bctx; /* BIGNUM context */ |
2237 | 0 | EVP_MD_CTX *ctx; /* signature context */ |
2238 | 0 | tstamp_t tstamp; /* NTP timestamp */ |
2239 | 0 | BIGNUM *bn, *bk, *r; |
2240 | 0 | u_char *ptr; |
2241 | 0 | u_int len; /* extension field value length */ |
2242 | 0 | const BIGNUM *p, *q, *g; |
2243 | 0 | const BIGNUM *priv_key; |
2244 | | |
2245 | | /* |
2246 | | * If the IFF parameters are not valid, something awful |
2247 | | * happened or we are being tormented. |
2248 | | */ |
2249 | 0 | if (iffkey_info == NULL) { |
2250 | 0 | msyslog(LOG_NOTICE, "crypto_bob: scheme unavailable"); |
2251 | 0 | return (XEVNT_ID); |
2252 | 0 | } |
2253 | | |
2254 | | /* Initialize pointers that may need freeing in cleanup. */ |
2255 | 0 | sdsa = NULL; |
2256 | |
|
2257 | 0 | dsa = EVP_PKEY_get0_DSA(iffkey_info->pkey); |
2258 | 0 | DSA_get0_pqg(dsa, &p, &q, &g); |
2259 | 0 | DSA_get0_key(dsa, NULL, &priv_key); |
2260 | | |
2261 | | /* |
2262 | | * Extract r from the challenge. |
2263 | | */ |
2264 | 0 | len = exten_payload_size(ep); |
2265 | 0 | if (len == 0 || len > MAX_VALLEN) |
2266 | 0 | return (XEVNT_LEN); |
2267 | 0 | if ((r = BN_bin2bn((u_char *)ep->pkt, len, NULL)) == NULL) { |
2268 | 0 | msyslog(LOG_ERR, "crypto_bob: %s", |
2269 | 0 | ERR_error_string(ERR_get_error(), NULL)); |
2270 | 0 | return (XEVNT_ERR); |
2271 | 0 | } |
2272 | | |
2273 | | /* |
2274 | | * Bob rolls random k (0 < k < q), computes y = k + b r mod q |
2275 | | * and x = g^k mod p, then sends (y, hash(x)) to Alice. |
2276 | | */ |
2277 | 0 | bctx = BN_CTX_new(); bk = BN_new(); bn = BN_new(); |
2278 | 0 | sdsa = DSA_SIG_new(); |
2279 | 0 | BN_rand(bk, len * 8, -1, 1); /* k */ |
2280 | 0 | BN_mod_mul(bn, priv_key, r, q, bctx); /* b r mod q */ |
2281 | 0 | BN_add(bn, bn, bk); |
2282 | 0 | BN_mod(bn, bn, q, bctx); /* k + b r mod q */ |
2283 | 0 | BN_mod_exp(bk, g, bk, p, bctx); /* g^k mod p */ |
2284 | 0 | bighash(bk, bk); |
2285 | 0 | DSA_SIG_set0(sdsa, bn, bk); |
2286 | 0 | BN_CTX_free(bctx); |
2287 | 0 | BN_free(r); |
2288 | 0 | #ifdef DEBUG |
2289 | 0 | if (debug > 1) |
2290 | 0 | DSA_print_fp(stdout, dsa, 0); |
2291 | 0 | #endif |
2292 | | |
2293 | | /* |
2294 | | * Encode the values in ASN.1 and sign. The filestamp is from |
2295 | | * the local file. |
2296 | | */ |
2297 | 0 | len = i2d_DSA_SIG(sdsa, NULL); |
2298 | 0 | if (len == 0) { |
2299 | 0 | msyslog(LOG_ERR, "crypto_bob: %s", |
2300 | 0 | ERR_error_string(ERR_get_error(), NULL)); |
2301 | 0 | retv = XEVNT_ERR; |
2302 | 0 | goto cleanup; |
2303 | 0 | } |
2304 | 0 | if (len > MAX_VALLEN) { |
2305 | 0 | msyslog(LOG_ERR, "crypto_bob: signature is too big: %u", |
2306 | 0 | len); |
2307 | 0 | retv = XEVNT_ERR; |
2308 | 0 | goto cleanup; |
2309 | 0 | } |
2310 | 0 | ZERO(*vp); |
2311 | 0 | tstamp = crypto_time(); |
2312 | 0 | vp->tstamp = htonl(tstamp); |
2313 | 0 | vp->fstamp = htonl(iffkey_info->fstamp); |
2314 | 0 | vp->vallen = htonl(len); |
2315 | 0 | ptr = emalloc(len); |
2316 | 0 | vp->ptr = ptr; |
2317 | 0 | i2d_DSA_SIG(sdsa, &ptr); |
2318 | 0 | if (0 == tstamp) { |
2319 | 0 | retv = XEVNT_OK; |
2320 | 0 | goto cleanup; |
2321 | 0 | } |
2322 | | |
2323 | | /* XXX: more validation to make sure the sign fits... */ |
2324 | 0 | vp->sig = emalloc(sign_siglen); |
2325 | 0 | ctx = digest_ctx; |
2326 | 0 | EVP_SignInit(ctx, sign_digest); |
2327 | 0 | EVP_SignUpdate(ctx, (u_char *)&vp->tstamp, 12); |
2328 | 0 | EVP_SignUpdate(ctx, vp->ptr, len); |
2329 | 0 | if (EVP_SignFinal(ctx, vp->sig, &len, sign_pkey)) { |
2330 | 0 | INSIST(len <= sign_siglen); |
2331 | 0 | vp->siglen = htonl(len); |
2332 | 0 | } |
2333 | 0 | retv = XEVNT_OK; |
2334 | |
|
2335 | 0 | cleanup: |
2336 | 0 | DSA_SIG_free(sdsa); |
2337 | 0 | return retv; |
2338 | 0 | } |
2339 | | |
2340 | | |
2341 | | /* |
2342 | | * crypto_iff - verify Bob's response to Alice's challenge |
2343 | | * |
2344 | | * Returns |
2345 | | * XEVNT_OK success |
2346 | | * XEVNT_FSP bad filestamp |
2347 | | * XEVNT_ID bad or missing group key |
2348 | | * XEVNT_PUB bad or missing public key |
2349 | | */ |
2350 | | int |
2351 | | crypto_iff( |
2352 | | struct exten *ep, /* extension pointer */ |
2353 | | struct peer *peer /* peer structure pointer */ |
2354 | | ) |
2355 | 0 | { |
2356 | 0 | const DSA *dsa; /* IFF parameters */ |
2357 | 0 | BN_CTX *bctx; /* BIGNUM context */ |
2358 | 0 | DSA_SIG *sdsa; /* DSA parameters */ |
2359 | 0 | BIGNUM *bn, *bk; |
2360 | 0 | u_int len; |
2361 | 0 | const u_char *ptr; |
2362 | 0 | int temp; |
2363 | 0 | const BIGNUM *p, *g; |
2364 | 0 | const BIGNUM *r, *s; |
2365 | 0 | const BIGNUM *pub_key; |
2366 | | |
2367 | | /* |
2368 | | * If the IFF parameters are not valid or no challenge was sent, |
2369 | | * something awful happened or we are being tormented. |
2370 | | */ |
2371 | 0 | if (peer->ident_pkey == NULL) { |
2372 | 0 | msyslog(LOG_NOTICE, "crypto_iff: scheme unavailable"); |
2373 | 0 | return (XEVNT_ID); |
2374 | 0 | } |
2375 | 0 | if (ntohl(ep->fstamp) != peer->ident_pkey->fstamp) { |
2376 | 0 | msyslog(LOG_NOTICE, "crypto_iff: invalid filestamp %u", |
2377 | 0 | ntohl(ep->fstamp)); |
2378 | 0 | return (XEVNT_FSP); |
2379 | 0 | } |
2380 | 0 | if ((dsa = EVP_PKEY_get0_DSA(peer->ident_pkey->pkey)) == NULL) { |
2381 | 0 | msyslog(LOG_NOTICE, "crypto_iff: defective key"); |
2382 | 0 | return (XEVNT_PUB); |
2383 | 0 | } |
2384 | 0 | if (peer->iffval == NULL) { |
2385 | 0 | msyslog(LOG_NOTICE, "crypto_iff: missing challenge"); |
2386 | 0 | return (XEVNT_ID); |
2387 | 0 | } |
2388 | | |
2389 | | /* |
2390 | | * Extract the k + b r and g^k values from the response. |
2391 | | */ |
2392 | 0 | bctx = BN_CTX_new(); bk = BN_new(); bn = BN_new(); |
2393 | 0 | len = ntohl(ep->vallen); |
2394 | 0 | ptr = (u_char *)ep->pkt; |
2395 | 0 | if ((sdsa = d2i_DSA_SIG(NULL, &ptr, len)) == NULL) { |
2396 | 0 | BN_free(bn); BN_free(bk); BN_CTX_free(bctx); |
2397 | 0 | msyslog(LOG_ERR, "crypto_iff: %s", |
2398 | 0 | ERR_error_string(ERR_get_error(), NULL)); |
2399 | 0 | return (XEVNT_ERR); |
2400 | 0 | } |
2401 | | |
2402 | | /* |
2403 | | * Compute g^(k + b r) g^(q - b)r mod p. |
2404 | | */ |
2405 | 0 | DSA_get0_key(dsa, &pub_key, NULL); |
2406 | 0 | DSA_get0_pqg(dsa, &p, NULL, &g); |
2407 | 0 | DSA_SIG_get0(sdsa, &r, &s); |
2408 | 0 | BN_mod_exp(bn, pub_key, peer->iffval, p, bctx); |
2409 | 0 | BN_mod_exp(bk, g, r, p, bctx); |
2410 | 0 | BN_mod_mul(bn, bn, bk, p, bctx); |
2411 | | |
2412 | | /* |
2413 | | * Verify the hash of the result matches hash(x). |
2414 | | */ |
2415 | 0 | bighash(bn, bn); |
2416 | 0 | temp = BN_cmp(bn, s); |
2417 | 0 | BN_free(bn); BN_free(bk); BN_CTX_free(bctx); |
2418 | 0 | BN_free(peer->iffval); |
2419 | 0 | peer->iffval = NULL; |
2420 | 0 | DSA_SIG_free(sdsa); |
2421 | 0 | if (temp == 0) |
2422 | 0 | return (XEVNT_OK); |
2423 | | |
2424 | 0 | msyslog(LOG_NOTICE, "crypto_iff: identity not verified"); |
2425 | 0 | return (XEVNT_ID); |
2426 | 0 | } |
2427 | | |
2428 | | |
2429 | | /* |
2430 | | *********************************************************************** |
2431 | | * * |
2432 | | * The following routines implement the Guillou-Quisquater (GQ) * |
2433 | | * identity scheme * |
2434 | | * * |
2435 | | *********************************************************************** |
2436 | | * |
2437 | | * The Guillou-Quisquater (GQ) identity scheme is intended for use when |
2438 | | * the certificate can be used to convey public parameters. The scheme |
2439 | | * uses a X509v3 certificate extension field do convey the public key of |
2440 | | * a private key known only to servers. There are two kinds of files: |
2441 | | * encrypted server files that contain private and public values and |
2442 | | * nonencrypted client files that contain only public values. New |
2443 | | * generations of server files must be securely transmitted to all |
2444 | | * servers of the group; client files can be distributed by any means. |
2445 | | * The scheme is self contained and independent of new generations of |
2446 | | * host keys and sign keys. The scheme is self contained and independent |
2447 | | * of new generations of host keys and sign keys. |
2448 | | * |
2449 | | * The GQ parameters hide in a RSA cuckoo structure which uses the same |
2450 | | * parameters. The values are used by an identity scheme based on RSA |
2451 | | * cryptography and described in Stimson p. 300 (with errors). The 512- |
2452 | | * bit public modulus is n = p q, where p and q are secret large primes. |
2453 | | * The TA rolls private random group key b as RSA exponent. These values |
2454 | | * are known to all group members. |
2455 | | * |
2456 | | * When rolling new certificates, a server recomputes the private and |
2457 | | * public keys. The private key u is a random roll, while the public key |
2458 | | * is the inverse obscured by the group key v = (u^-1)^b. These values |
2459 | | * replace the private and public keys normally generated by the RSA |
2460 | | * scheme. Alice challenges Bob to confirm identity using the protocol |
2461 | | * described below. |
2462 | | * |
2463 | | * How it works |
2464 | | * |
2465 | | * The scheme goes like this. Both Alice and Bob have the same modulus n |
2466 | | * and some random b as the group key. These values are computed and |
2467 | | * distributed in advance via secret means, although only the group key |
2468 | | * b is truly secret. Each has a private random private key u and public |
2469 | | * key (u^-1)^b, although not necessarily the same ones. Bob and Alice |
2470 | | * can regenerate the key pair from time to time without affecting |
2471 | | * operations. The public key is conveyed on the certificate in an |
2472 | | * extension field; the private key is never revealed. |
2473 | | * |
2474 | | * Alice rolls new random challenge r and sends to Bob in the GQ |
2475 | | * request message. Bob rolls new random k, then computes y = k u^r mod |
2476 | | * n and x = k^b mod n and sends (y, hash(x)) to Alice in the response |
2477 | | * message. Besides making the response shorter, the hash makes it |
2478 | | * effectivey impossible for an intruder to solve for b by observing |
2479 | | * a number of these messages. |
2480 | | * |
2481 | | * Alice receives the response and computes y^b v^r mod n. After a bit |
2482 | | * of algebra, this simplifies to k^b. If the hash of this result |
2483 | | * matches hash(x), Alice knows that Bob has the group key b. The signed |
2484 | | * response binds this knowledge to Bob's private key and the public key |
2485 | | * previously received in his certificate. |
2486 | | * |
2487 | | * crypto_alice2 - construct Alice's challenge in GQ scheme |
2488 | | * |
2489 | | * Returns |
2490 | | * XEVNT_OK success |
2491 | | * XEVNT_ID bad or missing group key |
2492 | | * XEVNT_PUB bad or missing public key |
2493 | | */ |
2494 | | static int |
2495 | | crypto_alice2( |
2496 | | struct peer *peer, /* peer pointer */ |
2497 | | struct value *vp /* value pointer */ |
2498 | | ) |
2499 | 0 | { |
2500 | 0 | const RSA *rsa; /* GQ parameters */ |
2501 | 0 | BN_CTX *bctx; /* BIGNUM context */ |
2502 | 0 | EVP_MD_CTX *ctx; /* signature context */ |
2503 | 0 | tstamp_t tstamp; |
2504 | 0 | u_int len; |
2505 | 0 | const BIGNUM *n; |
2506 | | |
2507 | | /* |
2508 | | * The identity parameters must have correct format and content. |
2509 | | */ |
2510 | 0 | if (peer->ident_pkey == NULL) |
2511 | 0 | return (XEVNT_ID); |
2512 | | |
2513 | 0 | if ((rsa = EVP_PKEY_get0_RSA(peer->ident_pkey->pkey)) == NULL) { |
2514 | 0 | msyslog(LOG_NOTICE, "crypto_alice2: defective key"); |
2515 | 0 | return (XEVNT_PUB); |
2516 | 0 | } |
2517 | | |
2518 | | /* |
2519 | | * Roll new random r (0 < r < n). |
2520 | | */ |
2521 | 0 | if (peer->iffval != NULL) |
2522 | 0 | BN_free(peer->iffval); |
2523 | 0 | peer->iffval = BN_new(); |
2524 | 0 | RSA_get0_key(rsa, &n, NULL, NULL); |
2525 | 0 | len = BN_num_bytes(n); |
2526 | 0 | BN_rand(peer->iffval, len * 8, -1, 1); /* r mod n */ |
2527 | 0 | bctx = BN_CTX_new(); |
2528 | 0 | BN_mod(peer->iffval, peer->iffval, n, bctx); |
2529 | 0 | BN_CTX_free(bctx); |
2530 | | |
2531 | | /* |
2532 | | * Sign and send to Bob. The filestamp is from the local file. |
2533 | | */ |
2534 | 0 | memset(vp, 0, sizeof(struct value)); |
2535 | 0 | tstamp = crypto_time(); |
2536 | 0 | vp->tstamp = htonl(tstamp); |
2537 | 0 | vp->fstamp = htonl(peer->ident_pkey->fstamp); |
2538 | 0 | vp->vallen = htonl(len); |
2539 | 0 | vp->ptr = emalloc(len); |
2540 | 0 | BN_bn2bin(peer->iffval, vp->ptr); |
2541 | 0 | if (tstamp == 0) |
2542 | 0 | return (XEVNT_OK); |
2543 | | |
2544 | 0 | vp->sig = emalloc(sign_siglen); |
2545 | 0 | ctx = digest_ctx; |
2546 | 0 | EVP_SignInit(ctx, sign_digest); |
2547 | 0 | EVP_SignUpdate(ctx, (u_char *)&vp->tstamp, 12); |
2548 | 0 | EVP_SignUpdate(ctx, vp->ptr, len); |
2549 | 0 | if (EVP_SignFinal(ctx, vp->sig, &len, sign_pkey)) { |
2550 | 0 | INSIST(len <= sign_siglen); |
2551 | 0 | vp->siglen = htonl(len); |
2552 | 0 | } |
2553 | 0 | return (XEVNT_OK); |
2554 | 0 | } |
2555 | | |
2556 | | |
2557 | | /* |
2558 | | * crypto_bob2 - construct Bob's response to Alice's challenge |
2559 | | * |
2560 | | * Returns |
2561 | | * XEVNT_OK success |
2562 | | * XEVNT_ERR protocol error |
2563 | | * XEVNT_ID bad or missing group key |
2564 | | */ |
2565 | | static int |
2566 | | crypto_bob2( |
2567 | | struct exten *ep, /* extension pointer */ |
2568 | | struct value *vp /* value pointer */ |
2569 | | ) |
2570 | 0 | { |
2571 | 0 | const RSA *rsa; /* GQ parameters */ |
2572 | 0 | DSA_SIG *sdsa; /* DSA parameters */ |
2573 | 0 | BN_CTX *bctx; /* BIGNUM context */ |
2574 | 0 | EVP_MD_CTX *ctx; /* signature context */ |
2575 | 0 | tstamp_t tstamp; /* NTP timestamp */ |
2576 | 0 | BIGNUM *r, *k, *g, *y; |
2577 | 0 | u_char *ptr; |
2578 | 0 | u_int len; |
2579 | 0 | int s_len; |
2580 | 0 | const BIGNUM *n, *p, *e; |
2581 | | |
2582 | | /* |
2583 | | * If the GQ parameters are not valid, something awful |
2584 | | * happened or we are being tormented. |
2585 | | */ |
2586 | 0 | if (gqkey_info == NULL) { |
2587 | 0 | msyslog(LOG_NOTICE, "crypto_bob2: scheme unavailable"); |
2588 | 0 | return (XEVNT_ID); |
2589 | 0 | } |
2590 | 0 | rsa = EVP_PKEY_get0_RSA(gqkey_info->pkey); |
2591 | 0 | RSA_get0_key(rsa, &n, &p, &e); |
2592 | | |
2593 | | /* |
2594 | | * Extract r from the challenge. |
2595 | | */ |
2596 | 0 | len = exten_payload_size(ep); |
2597 | 0 | if (len == 0 || len > MAX_VALLEN) |
2598 | 0 | return (XEVNT_LEN); |
2599 | 0 | if ((r = BN_bin2bn((u_char *)ep->pkt, len, NULL)) == NULL) { |
2600 | 0 | msyslog(LOG_ERR, "crypto_bob2: %s", |
2601 | 0 | ERR_error_string(ERR_get_error(), NULL)); |
2602 | 0 | return (XEVNT_ERR); |
2603 | 0 | } |
2604 | | |
2605 | | /* |
2606 | | * Bob rolls random k (0 < k < n), computes y = k u^r mod n and |
2607 | | * x = k^b mod n, then sends (y, hash(x)) to Alice. |
2608 | | */ |
2609 | 0 | bctx = BN_CTX_new(); k = BN_new(); g = BN_new(); y = BN_new(); |
2610 | 0 | sdsa = DSA_SIG_new(); |
2611 | 0 | BN_rand(k, len * 8, -1, 1); /* k */ |
2612 | 0 | BN_mod(k, k, n, bctx); |
2613 | 0 | BN_mod_exp(y, p, r, n, bctx); /* u^r mod n */ |
2614 | 0 | BN_mod_mul(y, k, y, n, bctx); /* k u^r mod n */ |
2615 | 0 | BN_mod_exp(g, k, e, n, bctx); /* k^b mod n */ |
2616 | 0 | bighash(g, g); |
2617 | 0 | DSA_SIG_set0(sdsa, y, g); |
2618 | 0 | BN_CTX_free(bctx); |
2619 | 0 | BN_free(r); BN_free(k); |
2620 | 0 | #ifdef DEBUG |
2621 | 0 | if (debug > 1) |
2622 | 0 | RSA_print_fp(stdout, rsa, 0); |
2623 | 0 | #endif |
2624 | | |
2625 | | /* |
2626 | | * Encode the values in ASN.1 and sign. The filestamp is from |
2627 | | * the local file. |
2628 | | */ |
2629 | 0 | len = s_len = i2d_DSA_SIG(sdsa, NULL); |
2630 | 0 | if (s_len <= 0) { |
2631 | 0 | msyslog(LOG_ERR, "crypto_bob2: %s", |
2632 | 0 | ERR_error_string(ERR_get_error(), NULL)); |
2633 | 0 | DSA_SIG_free(sdsa); |
2634 | 0 | return (XEVNT_ERR); |
2635 | 0 | } |
2636 | 0 | memset(vp, 0, sizeof(struct value)); |
2637 | 0 | tstamp = crypto_time(); |
2638 | 0 | vp->tstamp = htonl(tstamp); |
2639 | 0 | vp->fstamp = htonl(gqkey_info->fstamp); |
2640 | 0 | vp->vallen = htonl(len); |
2641 | 0 | ptr = emalloc(len); |
2642 | 0 | vp->ptr = ptr; |
2643 | 0 | i2d_DSA_SIG(sdsa, &ptr); |
2644 | 0 | DSA_SIG_free(sdsa); |
2645 | 0 | if (tstamp == 0) |
2646 | 0 | return (XEVNT_OK); |
2647 | | |
2648 | 0 | vp->sig = emalloc(sign_siglen); |
2649 | 0 | ctx = digest_ctx; |
2650 | 0 | EVP_SignInit(ctx, sign_digest); |
2651 | 0 | EVP_SignUpdate(ctx, (u_char *)&vp->tstamp, 12); |
2652 | 0 | EVP_SignUpdate(ctx, vp->ptr, len); |
2653 | 0 | if (EVP_SignFinal(ctx, vp->sig, &len, sign_pkey)) { |
2654 | 0 | INSIST(len <= sign_siglen); |
2655 | 0 | vp->siglen = htonl(len); |
2656 | 0 | } |
2657 | 0 | return (XEVNT_OK); |
2658 | 0 | } |
2659 | | |
2660 | | |
2661 | | /* |
2662 | | * crypto_gq - verify Bob's response to Alice's challenge |
2663 | | * |
2664 | | * Returns |
2665 | | * XEVNT_OK success |
2666 | | * XEVNT_ERR protocol error |
2667 | | * XEVNT_FSP bad filestamp |
2668 | | * XEVNT_ID bad or missing group keys |
2669 | | * XEVNT_PUB bad or missing public key |
2670 | | */ |
2671 | | int |
2672 | | crypto_gq( |
2673 | | struct exten *ep, /* extension pointer */ |
2674 | | struct peer *peer /* peer structure pointer */ |
2675 | | ) |
2676 | 0 | { |
2677 | 0 | const RSA *rsa; /* GQ parameters */ |
2678 | 0 | BN_CTX *bctx; /* BIGNUM context */ |
2679 | 0 | DSA_SIG *sdsa; /* RSA signature context fake */ |
2680 | 0 | BIGNUM *y, *v; |
2681 | 0 | const u_char *ptr; |
2682 | 0 | long len; |
2683 | 0 | u_int temp; |
2684 | 0 | const BIGNUM *n, *e; |
2685 | 0 | const BIGNUM *r, *s; |
2686 | | |
2687 | | /* |
2688 | | * If the GQ parameters are not valid or no challenge was sent, |
2689 | | * something awful happened or we are being tormented. Note that |
2690 | | * the filestamp on the local key file can be greater than on |
2691 | | * the remote parameter file if the keys have been refreshed. |
2692 | | */ |
2693 | 0 | if (peer->ident_pkey == NULL) { |
2694 | 0 | msyslog(LOG_NOTICE, "crypto_gq: scheme unavailable"); |
2695 | 0 | return (XEVNT_ID); |
2696 | 0 | } |
2697 | 0 | if (ntohl(ep->fstamp) < peer->ident_pkey->fstamp) { |
2698 | 0 | msyslog(LOG_NOTICE, "crypto_gq: invalid filestamp %u", |
2699 | 0 | ntohl(ep->fstamp)); |
2700 | 0 | return (XEVNT_FSP); |
2701 | 0 | } |
2702 | 0 | if ((rsa = EVP_PKEY_get0_RSA(peer->ident_pkey->pkey)) == NULL) { |
2703 | 0 | msyslog(LOG_NOTICE, "crypto_gq: defective key"); |
2704 | 0 | return (XEVNT_PUB); |
2705 | 0 | } |
2706 | 0 | RSA_get0_key(rsa, &n, NULL, &e); |
2707 | 0 | if (peer->iffval == NULL) { |
2708 | 0 | msyslog(LOG_NOTICE, "crypto_gq: missing challenge"); |
2709 | 0 | return (XEVNT_ID); |
2710 | 0 | } |
2711 | | |
2712 | | /* |
2713 | | * Extract the y = k u^r and hash(x = k^b) values from the |
2714 | | * response. |
2715 | | */ |
2716 | 0 | bctx = BN_CTX_new(); y = BN_new(); v = BN_new(); |
2717 | 0 | len = ntohl(ep->vallen); |
2718 | 0 | ptr = (u_char *)ep->pkt; |
2719 | 0 | if ((sdsa = d2i_DSA_SIG(NULL, &ptr, len)) == NULL) { |
2720 | 0 | BN_CTX_free(bctx); BN_free(y); BN_free(v); |
2721 | 0 | msyslog(LOG_ERR, "crypto_gq: %s", |
2722 | 0 | ERR_error_string(ERR_get_error(), NULL)); |
2723 | 0 | return (XEVNT_ERR); |
2724 | 0 | } |
2725 | 0 | DSA_SIG_get0(sdsa, &r, &s); |
2726 | | |
2727 | | /* |
2728 | | * Compute v^r y^b mod n. |
2729 | | */ |
2730 | 0 | if (peer->grpkey == NULL) { |
2731 | 0 | msyslog(LOG_NOTICE, "crypto_gq: missing group key"); |
2732 | 0 | return (XEVNT_ID); |
2733 | 0 | } |
2734 | 0 | BN_mod_exp(v, peer->grpkey, peer->iffval, n, bctx); |
2735 | | /* v^r mod n */ |
2736 | 0 | BN_mod_exp(y, r, e, n, bctx); /* y^b mod n */ |
2737 | 0 | BN_mod_mul(y, v, y, n, bctx); /* v^r y^b mod n */ |
2738 | | |
2739 | | /* |
2740 | | * Verify the hash of the result matches hash(x). |
2741 | | */ |
2742 | 0 | bighash(y, y); |
2743 | 0 | temp = BN_cmp(y, s); |
2744 | 0 | BN_CTX_free(bctx); BN_free(y); BN_free(v); |
2745 | 0 | BN_free(peer->iffval); |
2746 | 0 | peer->iffval = NULL; |
2747 | 0 | DSA_SIG_free(sdsa); |
2748 | 0 | if (temp == 0) |
2749 | 0 | return (XEVNT_OK); |
2750 | | |
2751 | 0 | msyslog(LOG_NOTICE, "crypto_gq: identity not verified"); |
2752 | 0 | return (XEVNT_ID); |
2753 | 0 | } |
2754 | | |
2755 | | |
2756 | | /* |
2757 | | *********************************************************************** |
2758 | | * * |
2759 | | * The following routines implement the Mu-Varadharajan (MV) identity * |
2760 | | * scheme * |
2761 | | * * |
2762 | | *********************************************************************** |
2763 | | * |
2764 | | * The Mu-Varadharajan (MV) cryptosystem was originally intended when |
2765 | | * servers broadcast messages to clients, but clients never send |
2766 | | * messages to servers. There is one encryption key for the server and a |
2767 | | * separate decryption key for each client. It operated something like a |
2768 | | * pay-per-view satellite broadcasting system where the session key is |
2769 | | * encrypted by the broadcaster and the decryption keys are held in a |
2770 | | * tamperproof set-top box. |
2771 | | * |
2772 | | * The MV parameters and private encryption key hide in a DSA cuckoo |
2773 | | * structure which uses the same parameters, but generated in a |
2774 | | * different way. The values are used in an encryption scheme similar to |
2775 | | * El Gamal cryptography and a polynomial formed from the expansion of |
2776 | | * product terms (x - x[j]), as described in Mu, Y., and V. |
2777 | | * Varadharajan: Robust and Secure Broadcasting, Proc. Indocrypt 2001, |
2778 | | * 223-231. The paper has significant errors and serious omissions. |
2779 | | * |
2780 | | * Let q be the product of n distinct primes s1[j] (j = 1...n), where |
2781 | | * each s1[j] has m significant bits. Let p be a prime p = 2 * q + 1, so |
2782 | | * that q and each s1[j] divide p - 1 and p has M = n * m + 1 |
2783 | | * significant bits. Let g be a generator of Zp; that is, gcd(g, p - 1) |
2784 | | * = 1 and g^q = 1 mod p. We do modular arithmetic over Zq and then |
2785 | | * project into Zp* as exponents of g. Sometimes we have to compute an |
2786 | | * inverse b^-1 of random b in Zq, but for that purpose we require |
2787 | | * gcd(b, q) = 1. We expect M to be in the 500-bit range and n |
2788 | | * relatively small, like 30. These are the parameters of the scheme and |
2789 | | * they are expensive to compute. |
2790 | | * |
2791 | | * We set up an instance of the scheme as follows. A set of random |
2792 | | * values x[j] mod q (j = 1...n), are generated as the zeros of a |
2793 | | * polynomial of order n. The product terms (x - x[j]) are expanded to |
2794 | | * form coefficients a[i] mod q (i = 0...n) in powers of x. These are |
2795 | | * used as exponents of the generator g mod p to generate the private |
2796 | | * encryption key A. The pair (gbar, ghat) of public server keys and the |
2797 | | * pairs (xbar[j], xhat[j]) (j = 1...n) of private client keys are used |
2798 | | * to construct the decryption keys. The devil is in the details. |
2799 | | * |
2800 | | * This routine generates a private server encryption file including the |
2801 | | * private encryption key E and partial decryption keys gbar and ghat. |
2802 | | * It then generates public client decryption files including the public |
2803 | | * keys xbar[j] and xhat[j] for each client j. The partial decryption |
2804 | | * files are used to compute the inverse of E. These values are suitably |
2805 | | * blinded so secrets are not revealed. |
2806 | | * |
2807 | | * The distinguishing characteristic of this scheme is the capability to |
2808 | | * revoke keys. Included in the calculation of E, gbar and ghat is the |
2809 | | * product s = prod(s1[j]) (j = 1...n) above. If the factor s1[j] is |
2810 | | * subsequently removed from the product and E, gbar and ghat |
2811 | | * recomputed, the jth client will no longer be able to compute E^-1 and |
2812 | | * thus unable to decrypt the messageblock. |
2813 | | * |
2814 | | * How it works |
2815 | | * |
2816 | | * The scheme goes like this. Bob has the server values (p, E, q, gbar, |
2817 | | * ghat) and Alice has the client values (p, xbar, xhat). |
2818 | | * |
2819 | | * Alice rolls new random nonce r mod p and sends to Bob in the MV |
2820 | | * request message. Bob rolls random nonce k mod q, encrypts y = r E^k |
2821 | | * mod p and sends (y, gbar^k, ghat^k) to Alice. |
2822 | | * |
2823 | | * Alice receives the response and computes the inverse (E^k)^-1 from |
2824 | | * the partial decryption keys gbar^k, ghat^k, xbar and xhat. She then |
2825 | | * decrypts y and verifies it matches the original r. The signed |
2826 | | * response binds this knowledge to Bob's private key and the public key |
2827 | | * previously received in his certificate. |
2828 | | * |
2829 | | * crypto_alice3 - construct Alice's challenge in MV scheme |
2830 | | * |
2831 | | * Returns |
2832 | | * XEVNT_OK success |
2833 | | * XEVNT_ID bad or missing group key |
2834 | | * XEVNT_PUB bad or missing public key |
2835 | | */ |
2836 | | static int |
2837 | | crypto_alice3( |
2838 | | struct peer *peer, /* peer pointer */ |
2839 | | struct value *vp /* value pointer */ |
2840 | | ) |
2841 | 0 | { |
2842 | 0 | const DSA *dsa; /* MV parameters */ |
2843 | 0 | BN_CTX *bctx; /* BIGNUM context */ |
2844 | 0 | EVP_MD_CTX *ctx; /* signature context */ |
2845 | 0 | tstamp_t tstamp; |
2846 | 0 | u_int len; |
2847 | 0 | const BIGNUM *p; |
2848 | | |
2849 | | /* |
2850 | | * The identity parameters must have correct format and content. |
2851 | | */ |
2852 | 0 | if (peer->ident_pkey == NULL) |
2853 | 0 | return (XEVNT_ID); |
2854 | | |
2855 | 0 | if ((dsa = EVP_PKEY_get0_DSA(peer->ident_pkey->pkey)) == NULL) { |
2856 | 0 | msyslog(LOG_NOTICE, "crypto_alice3: defective key"); |
2857 | 0 | return (XEVNT_PUB); |
2858 | 0 | } |
2859 | 0 | DSA_get0_pqg(dsa, &p, NULL, NULL); |
2860 | | |
2861 | | /* |
2862 | | * Roll new random r (0 < r < q). |
2863 | | */ |
2864 | 0 | if (peer->iffval != NULL) |
2865 | 0 | BN_free(peer->iffval); |
2866 | 0 | peer->iffval = BN_new(); |
2867 | 0 | len = BN_num_bytes(p); |
2868 | 0 | BN_rand(peer->iffval, len * 8, -1, 1); /* r mod p */ |
2869 | 0 | bctx = BN_CTX_new(); |
2870 | 0 | BN_mod(peer->iffval, peer->iffval, p, bctx); |
2871 | 0 | BN_CTX_free(bctx); |
2872 | | |
2873 | | /* |
2874 | | * Sign and send to Bob. The filestamp is from the local file. |
2875 | | */ |
2876 | 0 | memset(vp, 0, sizeof(struct value)); |
2877 | 0 | tstamp = crypto_time(); |
2878 | 0 | vp->tstamp = htonl(tstamp); |
2879 | 0 | vp->fstamp = htonl(peer->ident_pkey->fstamp); |
2880 | 0 | vp->vallen = htonl(len); |
2881 | 0 | vp->ptr = emalloc(len); |
2882 | 0 | BN_bn2bin(peer->iffval, vp->ptr); |
2883 | 0 | if (tstamp == 0) |
2884 | 0 | return (XEVNT_OK); |
2885 | | |
2886 | 0 | vp->sig = emalloc(sign_siglen); |
2887 | 0 | ctx = digest_ctx; |
2888 | 0 | EVP_SignInit(ctx, sign_digest); |
2889 | 0 | EVP_SignUpdate(ctx, (u_char *)&vp->tstamp, 12); |
2890 | 0 | EVP_SignUpdate(ctx, vp->ptr, len); |
2891 | 0 | if (EVP_SignFinal(ctx, vp->sig, &len, sign_pkey)) { |
2892 | 0 | INSIST(len <= sign_siglen); |
2893 | 0 | vp->siglen = htonl(len); |
2894 | 0 | } |
2895 | 0 | return (XEVNT_OK); |
2896 | 0 | } |
2897 | | |
2898 | | |
2899 | | /* |
2900 | | * crypto_bob3 - construct Bob's response to Alice's challenge |
2901 | | * |
2902 | | * Returns |
2903 | | * XEVNT_OK success |
2904 | | * XEVNT_ERR protocol error |
2905 | | */ |
2906 | | static int |
2907 | | crypto_bob3( |
2908 | | struct exten *ep, /* extension pointer */ |
2909 | | struct value *vp /* value pointer */ |
2910 | | ) |
2911 | 0 | { |
2912 | 0 | const DSA *dsa; /* MV parameters */ |
2913 | 0 | DSA *sdsa; /* DSA signature context fake */ |
2914 | 0 | BN_CTX *bctx; /* BIGNUM context */ |
2915 | 0 | EVP_MD_CTX *ctx; /* signature context */ |
2916 | 0 | tstamp_t tstamp; /* NTP timestamp */ |
2917 | 0 | BIGNUM *r, *k, *u; |
2918 | 0 | u_char *ptr; |
2919 | 0 | u_int len; |
2920 | 0 | const BIGNUM *p, *q, *g; |
2921 | 0 | const BIGNUM *pub_key, *priv_key; |
2922 | 0 | BIGNUM *sp, *sq, *sg; |
2923 | | |
2924 | | /* |
2925 | | * If the MV parameters are not valid, something awful |
2926 | | * happened or we are being tormented. |
2927 | | */ |
2928 | 0 | if (mvkey_info == NULL) { |
2929 | 0 | msyslog(LOG_NOTICE, "crypto_bob3: scheme unavailable"); |
2930 | 0 | return (XEVNT_ID); |
2931 | 0 | } |
2932 | 0 | dsa = EVP_PKEY_get0_DSA(mvkey_info->pkey); |
2933 | 0 | DSA_get0_pqg(dsa, &p, &q, &g); |
2934 | 0 | DSA_get0_key(dsa, &pub_key, &priv_key); |
2935 | | |
2936 | | /* |
2937 | | * Extract r from the challenge. |
2938 | | */ |
2939 | 0 | len = exten_payload_size(ep); |
2940 | 0 | if (len == 0 || len > MAX_VALLEN) |
2941 | 0 | return (XEVNT_LEN); |
2942 | 0 | if ((r = BN_bin2bn((u_char *)ep->pkt, len, NULL)) == NULL) { |
2943 | 0 | msyslog(LOG_ERR, "crypto_bob3: %s", |
2944 | 0 | ERR_error_string(ERR_get_error(), NULL)); |
2945 | 0 | return (XEVNT_ERR); |
2946 | 0 | } |
2947 | | |
2948 | | /* |
2949 | | * Bob rolls random k (0 < k < q), making sure it is not a |
2950 | | * factor of q. He then computes y = r A^k and sends (y, gbar^k, |
2951 | | * and ghat^k) to Alice. |
2952 | | */ |
2953 | 0 | bctx = BN_CTX_new(); k = BN_new(); u = BN_new(); |
2954 | 0 | sdsa = DSA_new(); |
2955 | 0 | sp = BN_new(); sq = BN_new(); sg = BN_new(); |
2956 | 0 | while (1) { |
2957 | 0 | BN_rand(k, BN_num_bits(q), 0, 0); |
2958 | 0 | BN_mod(k, k, q, bctx); |
2959 | 0 | BN_gcd(u, k, q, bctx); |
2960 | 0 | if (BN_is_one(u)) |
2961 | 0 | break; |
2962 | 0 | } |
2963 | 0 | BN_mod_exp(u, g, k, p, bctx); /* A^k r */ |
2964 | 0 | BN_mod_mul(sp, u, r, p, bctx); |
2965 | 0 | BN_mod_exp(sq, priv_key, k, p, bctx); /* gbar */ |
2966 | 0 | BN_mod_exp(sg, pub_key, k, p, bctx); /* ghat */ |
2967 | 0 | DSA_set0_key(sdsa, BN_dup(pub_key), NULL); |
2968 | 0 | DSA_set0_pqg(sdsa, sp, sq, sg); |
2969 | 0 | BN_CTX_free(bctx); BN_free(k); BN_free(r); BN_free(u); |
2970 | 0 | #ifdef DEBUG |
2971 | 0 | if (debug > 1) |
2972 | 0 | DSA_print_fp(stdout, sdsa, 0); |
2973 | 0 | #endif |
2974 | | |
2975 | | /* |
2976 | | * Encode the values in ASN.1 and sign. The filestamp is from |
2977 | | * the local file. |
2978 | | */ |
2979 | 0 | memset(vp, 0, sizeof(struct value)); |
2980 | 0 | tstamp = crypto_time(); |
2981 | 0 | vp->tstamp = htonl(tstamp); |
2982 | 0 | vp->fstamp = htonl(mvkey_info->fstamp); |
2983 | 0 | len = i2d_DSAparams(sdsa, NULL); |
2984 | 0 | if (len == 0) { |
2985 | 0 | msyslog(LOG_ERR, "crypto_bob3: %s", |
2986 | 0 | ERR_error_string(ERR_get_error(), NULL)); |
2987 | 0 | DSA_free(sdsa); |
2988 | 0 | return (XEVNT_ERR); |
2989 | 0 | } |
2990 | 0 | vp->vallen = htonl(len); |
2991 | 0 | ptr = emalloc(len); |
2992 | 0 | vp->ptr = ptr; |
2993 | 0 | i2d_DSAparams(sdsa, &ptr); |
2994 | 0 | DSA_free(sdsa); |
2995 | 0 | if (tstamp == 0) |
2996 | 0 | return (XEVNT_OK); |
2997 | | |
2998 | 0 | vp->sig = emalloc(sign_siglen); |
2999 | 0 | ctx = digest_ctx; |
3000 | 0 | EVP_SignInit(ctx, sign_digest); |
3001 | 0 | EVP_SignUpdate(ctx, (u_char *)&vp->tstamp, 12); |
3002 | 0 | EVP_SignUpdate(ctx, vp->ptr, len); |
3003 | 0 | if (EVP_SignFinal(ctx, vp->sig, &len, sign_pkey)) { |
3004 | 0 | INSIST(len <= sign_siglen); |
3005 | 0 | vp->siglen = htonl(len); |
3006 | 0 | } |
3007 | 0 | return (XEVNT_OK); |
3008 | 0 | } |
3009 | | |
3010 | | |
3011 | | /* |
3012 | | * crypto_mv - verify Bob's response to Alice's challenge |
3013 | | * |
3014 | | * Returns |
3015 | | * XEVNT_OK success |
3016 | | * XEVNT_ERR protocol error |
3017 | | * XEVNT_FSP bad filestamp |
3018 | | * XEVNT_ID bad or missing group key |
3019 | | * XEVNT_PUB bad or missing public key |
3020 | | */ |
3021 | | int |
3022 | | crypto_mv( |
3023 | | struct exten *ep, /* extension pointer */ |
3024 | | struct peer *peer /* peer structure pointer */ |
3025 | | ) |
3026 | 0 | { |
3027 | 0 | const DSA *dsa; /* MV parameters */ |
3028 | 0 | DSA *sdsa; /* DSA parameters */ |
3029 | 0 | BN_CTX *bctx; /* BIGNUM context */ |
3030 | 0 | BIGNUM *k, *u, *v; |
3031 | 0 | u_int len; |
3032 | 0 | const u_char *ptr; |
3033 | 0 | int temp; |
3034 | 0 | const BIGNUM *p; |
3035 | 0 | const BIGNUM *pub_key, *priv_key; |
3036 | 0 | const BIGNUM *sp, *sq, *sg; |
3037 | | |
3038 | | /* |
3039 | | * If the MV parameters are not valid or no challenge was sent, |
3040 | | * something awful happened or we are being tormented. |
3041 | | */ |
3042 | 0 | if (peer->ident_pkey == NULL) { |
3043 | 0 | msyslog(LOG_NOTICE, "crypto_mv: scheme unavailable"); |
3044 | 0 | return (XEVNT_ID); |
3045 | 0 | } |
3046 | 0 | if (ntohl(ep->fstamp) != peer->ident_pkey->fstamp) { |
3047 | 0 | msyslog(LOG_NOTICE, "crypto_mv: invalid filestamp %u", |
3048 | 0 | ntohl(ep->fstamp)); |
3049 | 0 | return (XEVNT_FSP); |
3050 | 0 | } |
3051 | 0 | if ((dsa = EVP_PKEY_get0_DSA(peer->ident_pkey->pkey)) == NULL) { |
3052 | 0 | msyslog(LOG_NOTICE, "crypto_mv: defective key"); |
3053 | 0 | return (XEVNT_PUB); |
3054 | 0 | } |
3055 | 0 | DSA_get0_pqg(dsa, &p, NULL, NULL); |
3056 | 0 | DSA_get0_key(dsa, &pub_key, &priv_key); |
3057 | 0 | if (peer->iffval == NULL) { |
3058 | 0 | msyslog(LOG_NOTICE, "crypto_mv: missing challenge"); |
3059 | 0 | return (XEVNT_ID); |
3060 | 0 | } |
3061 | | |
3062 | | /* |
3063 | | * Extract the y, gbar and ghat values from the response. |
3064 | | */ |
3065 | 0 | bctx = BN_CTX_new(); k = BN_new(); u = BN_new(); v = BN_new(); |
3066 | 0 | len = ntohl(ep->vallen); |
3067 | 0 | ptr = (u_char *)ep->pkt; |
3068 | 0 | if ((sdsa = d2i_DSAparams(NULL, &ptr, len)) == NULL) { |
3069 | 0 | msyslog(LOG_ERR, "crypto_mv: %s", |
3070 | 0 | ERR_error_string(ERR_get_error(), NULL)); |
3071 | 0 | return (XEVNT_ERR); |
3072 | 0 | } |
3073 | 0 | DSA_get0_pqg(sdsa, &sp, &sq, &sg); |
3074 | | |
3075 | | /* |
3076 | | * Compute (gbar^xhat ghat^xbar) mod p. |
3077 | | */ |
3078 | 0 | BN_mod_exp(u, sq, pub_key, p, bctx); |
3079 | 0 | BN_mod_exp(v, sg, priv_key, p, bctx); |
3080 | 0 | BN_mod_mul(u, u, v, p, bctx); |
3081 | 0 | BN_mod_mul(u, u, sp, p, bctx); |
3082 | | |
3083 | | /* |
3084 | | * The result should match r. |
3085 | | */ |
3086 | 0 | temp = BN_cmp(u, peer->iffval); |
3087 | 0 | BN_CTX_free(bctx); BN_free(k); BN_free(u); BN_free(v); |
3088 | 0 | BN_free(peer->iffval); |
3089 | 0 | peer->iffval = NULL; |
3090 | 0 | DSA_free(sdsa); |
3091 | 0 | if (temp == 0) |
3092 | 0 | return (XEVNT_OK); |
3093 | | |
3094 | 0 | msyslog(LOG_NOTICE, "crypto_mv: identity not verified"); |
3095 | 0 | return (XEVNT_ID); |
3096 | 0 | } |
3097 | | |
3098 | | |
3099 | | /* |
3100 | | *********************************************************************** |
3101 | | * * |
3102 | | * The following routines are used to manipulate certificates * |
3103 | | * * |
3104 | | *********************************************************************** |
3105 | | */ |
3106 | | /* |
3107 | | * cert_sign - sign x509 certificate equest and update value structure. |
3108 | | * |
3109 | | * The certificate request includes a copy of the host certificate, |
3110 | | * which includes the version number, subject name and public key of the |
3111 | | * host. The resulting certificate includes these values plus the |
3112 | | * serial number, issuer name and valid interval of the server. The |
3113 | | * valid interval extends from the current time to the same time one |
3114 | | * year hence. This may extend the life of the signed certificate beyond |
3115 | | * that of the signer certificate. |
3116 | | * |
3117 | | * It is convenient to use the NTP seconds of the current time as the |
3118 | | * serial number. In the value structure the timestamp is the current |
3119 | | * time and the filestamp is taken from the extension field. Note this |
3120 | | * routine is called only when the client clock is synchronized to a |
3121 | | * proventic source, so timestamp comparisons are valid. |
3122 | | * |
3123 | | * The host certificate is valid from the time it was generated for a |
3124 | | * period of one year. A signed certificate is valid from the time of |
3125 | | * signature for a period of one year, but only the host certificate (or |
3126 | | * sign certificate if used) is actually used to encrypt and decrypt |
3127 | | * signatures. The signature trail is built from the client via the |
3128 | | * intermediate servers to the trusted server. Each signature on the |
3129 | | * trail must be valid at the time of signature, but it could happen |
3130 | | * that a signer certificate expire before the signed certificate, which |
3131 | | * remains valid until its expiration. |
3132 | | * |
3133 | | * Returns |
3134 | | * XEVNT_OK success |
3135 | | * XEVNT_CRT bad or missing certificate |
3136 | | * XEVNT_PER host certificate expired |
3137 | | * XEVNT_PUB bad or missing public key |
3138 | | * XEVNT_VFY certificate not verified |
3139 | | */ |
3140 | | static int |
3141 | | cert_sign( |
3142 | | struct exten *ep, /* extension field pointer */ |
3143 | | struct value *vp /* value pointer */ |
3144 | | ) |
3145 | 0 | { |
3146 | 0 | X509 *req; /* X509 certificate request */ |
3147 | 0 | X509 *cert; /* X509 certificate */ |
3148 | 0 | X509_EXTENSION *ext; /* certificate extension */ |
3149 | 0 | ASN1_INTEGER *serial; /* serial number */ |
3150 | 0 | X509_NAME *subj; /* distinguished (common) name */ |
3151 | 0 | EVP_PKEY *pkey; /* public key */ |
3152 | 0 | EVP_MD_CTX *ctx; /* message digest context */ |
3153 | 0 | tstamp_t tstamp; /* NTP timestamp */ |
3154 | 0 | struct calendar tscal; |
3155 | 0 | u_int len; |
3156 | 0 | const u_char *cptr; |
3157 | 0 | u_char *ptr; |
3158 | 0 | int i, temp; |
3159 | | |
3160 | | /* |
3161 | | * Decode ASN.1 objects and construct certificate structure. |
3162 | | * Make sure the system clock is synchronized to a proventic |
3163 | | * source. |
3164 | | */ |
3165 | 0 | tstamp = crypto_time(); |
3166 | 0 | if (tstamp == 0) |
3167 | 0 | return (XEVNT_TSP); |
3168 | | |
3169 | 0 | len = exten_payload_size(ep); |
3170 | 0 | if (len == 0 || len > MAX_VALLEN) |
3171 | 0 | return (XEVNT_LEN); |
3172 | 0 | cptr = (void *)ep->pkt; |
3173 | 0 | if ((req = d2i_X509(NULL, &cptr, len)) == NULL) { |
3174 | 0 | msyslog(LOG_ERR, "cert_sign: %s", |
3175 | 0 | ERR_error_string(ERR_get_error(), NULL)); |
3176 | 0 | return (XEVNT_CRT); |
3177 | 0 | } |
3178 | | /* |
3179 | | * Extract public key and check for errors. |
3180 | | */ |
3181 | 0 | if ((pkey = X509_get_pubkey(req)) == NULL) { |
3182 | 0 | msyslog(LOG_ERR, "cert_sign: %s", |
3183 | 0 | ERR_error_string(ERR_get_error(), NULL)); |
3184 | 0 | X509_free(req); |
3185 | 0 | return (XEVNT_PUB); |
3186 | 0 | } |
3187 | | |
3188 | | /* |
3189 | | * Generate X509 certificate signed by this server. If this is a |
3190 | | * trusted host, the issuer name is the group name; otherwise, |
3191 | | * it is the host name. Also copy any extensions that might be |
3192 | | * present. |
3193 | | */ |
3194 | 0 | cert = X509_new(); |
3195 | 0 | X509_set_version(cert, X509_get_version(req)); |
3196 | 0 | serial = ASN1_INTEGER_new(); |
3197 | 0 | ASN1_INTEGER_set(serial, tstamp); |
3198 | 0 | X509_set_serialNumber(cert, serial); |
3199 | 0 | X509_gmtime_adj(X509_getm_notBefore(cert), 0L); |
3200 | 0 | X509_gmtime_adj(X509_getm_notAfter(cert), YEAR); |
3201 | 0 | subj = X509_get_issuer_name(cert); |
3202 | 0 | X509_NAME_add_entry_by_txt(subj, "commonName", MBSTRING_ASC, |
3203 | 0 | hostval.ptr, strlen((const char *)hostval.ptr), -1, 0); |
3204 | 0 | subj = X509_get_subject_name(req); |
3205 | 0 | X509_set_subject_name(cert, subj); |
3206 | 0 | X509_set_pubkey(cert, pkey); |
3207 | 0 | temp = X509_get_ext_count(req); |
3208 | 0 | for (i = 0; i < temp; i++) { |
3209 | 0 | ext = X509_get_ext(req, i); |
3210 | 0 | INSIST(X509_add_ext(cert, ext, -1)); |
3211 | 0 | } |
3212 | 0 | X509_free(req); |
3213 | | |
3214 | | /* |
3215 | | * Sign and verify the client certificate, but only if the host |
3216 | | * certificate has not expired. |
3217 | | */ |
3218 | 0 | (void)ntpcal_ntp_to_date(&tscal, tstamp, NULL); |
3219 | 0 | if ((calcomp(&tscal, &(cert_host->first)) < 0) |
3220 | 0 | || (calcomp(&tscal, &(cert_host->last)) > 0)) { |
3221 | 0 | X509_free(cert); |
3222 | 0 | return (XEVNT_PER); |
3223 | 0 | } |
3224 | 0 | X509_sign(cert, sign_pkey, sign_digest); |
3225 | 0 | if (X509_verify(cert, sign_pkey) <= 0) { |
3226 | 0 | msyslog(LOG_ERR, "cert_sign: %s", |
3227 | 0 | ERR_error_string(ERR_get_error(), NULL)); |
3228 | 0 | X509_free(cert); |
3229 | 0 | return (XEVNT_VFY); |
3230 | 0 | } |
3231 | 0 | len = i2d_X509(cert, NULL); |
3232 | | |
3233 | | /* |
3234 | | * Build and sign the value structure. We have to sign it here, |
3235 | | * since the response has to be returned right away. This is a |
3236 | | * clogging hazard. |
3237 | | */ |
3238 | 0 | memset(vp, 0, sizeof(struct value)); |
3239 | 0 | vp->tstamp = htonl(tstamp); |
3240 | 0 | vp->fstamp = ep->fstamp; |
3241 | 0 | vp->vallen = htonl(len); |
3242 | 0 | vp->ptr = emalloc(len); |
3243 | 0 | ptr = vp->ptr; |
3244 | 0 | i2d_X509(cert, (unsigned char **)(intptr_t)&ptr); |
3245 | 0 | vp->siglen = 0; |
3246 | 0 | if (tstamp != 0) { |
3247 | 0 | vp->sig = emalloc(sign_siglen); |
3248 | 0 | ctx = digest_ctx; |
3249 | 0 | EVP_SignInit(ctx, sign_digest); |
3250 | 0 | EVP_SignUpdate(ctx, (u_char *)vp, 12); |
3251 | 0 | EVP_SignUpdate(ctx, vp->ptr, len); |
3252 | 0 | if (EVP_SignFinal(ctx, vp->sig, &len, sign_pkey)) { |
3253 | 0 | INSIST(len <= sign_siglen); |
3254 | 0 | vp->siglen = htonl(len); |
3255 | 0 | } |
3256 | 0 | } |
3257 | 0 | #ifdef DEBUG |
3258 | 0 | if (debug > 1) |
3259 | 0 | X509_print_fp(stdout, cert); |
3260 | 0 | #endif |
3261 | 0 | X509_free(cert); |
3262 | 0 | return (XEVNT_OK); |
3263 | 0 | } |
3264 | | |
3265 | | |
3266 | | /* |
3267 | | * cert_install - install certificate in certificate cache |
3268 | | * |
3269 | | * This routine encodes an extension field into a certificate info/value |
3270 | | * structure. It searches the certificate list for duplicates and |
3271 | | * expunges whichever is older. Finally, it inserts this certificate |
3272 | | * first on the list. |
3273 | | * |
3274 | | * Returns certificate info pointer if valid, NULL if not. |
3275 | | */ |
3276 | | struct cert_info * |
3277 | | cert_install( |
3278 | | struct exten *ep, /* cert info/value */ |
3279 | | struct peer *peer /* peer structure */ |
3280 | | ) |
3281 | 0 | { |
3282 | 0 | struct cert_info *cp, *xp, **zp; |
3283 | | |
3284 | | /* |
3285 | | * Parse and validate the signed certificate. If valid, |
3286 | | * construct the info/value structure; otherwise, scamper home |
3287 | | * empty handed. |
3288 | | */ |
3289 | 0 | if ((cp = cert_parse((u_char *)ep->pkt, (long)ntohl(ep->vallen), |
3290 | 0 | (tstamp_t)ntohl(ep->fstamp))) == NULL) |
3291 | 0 | return (NULL); |
3292 | | |
3293 | | /* |
3294 | | * Scan certificate list looking for another certificate with |
3295 | | * the same subject and issuer. If another is found with the |
3296 | | * same or older filestamp, unlink it and return the goodies to |
3297 | | * the heap. If another is found with a later filestamp, discard |
3298 | | * the new one and leave the building with the old one. |
3299 | | * |
3300 | | * Make a note to study this issue again. An earlier certificate |
3301 | | * with a long lifetime might be overtaken by a later |
3302 | | * certificate with a short lifetime, thus invalidating the |
3303 | | * earlier signature. However, we gotta find a way to leak old |
3304 | | * stuff from the cache, so we do it anyway. |
3305 | | */ |
3306 | 0 | zp = &cinfo; |
3307 | 0 | for (xp = cinfo; xp != NULL; xp = xp->link) { |
3308 | 0 | if (strcmp(cp->subject, xp->subject) == 0 && |
3309 | 0 | strcmp(cp->issuer, xp->issuer) == 0) { |
3310 | 0 | if (ntohl(cp->cert.fstamp) <= |
3311 | 0 | ntohl(xp->cert.fstamp)) { |
3312 | 0 | cert_free(cp); |
3313 | 0 | cp = xp; |
3314 | 0 | } else { |
3315 | 0 | *zp = xp->link; |
3316 | 0 | cert_free(xp); |
3317 | 0 | xp = NULL; |
3318 | 0 | } |
3319 | 0 | break; |
3320 | 0 | } |
3321 | 0 | zp = &xp->link; |
3322 | 0 | } |
3323 | 0 | if (xp == NULL) { |
3324 | 0 | cp->link = cinfo; |
3325 | 0 | cinfo = cp; |
3326 | 0 | } |
3327 | 0 | cp->flags |= CERT_VALID; |
3328 | 0 | crypto_update(); |
3329 | 0 | return (cp); |
3330 | 0 | } |
3331 | | |
3332 | | |
3333 | | /* |
3334 | | * cert_hike - verify the signature using the issuer public key |
3335 | | * |
3336 | | * Returns |
3337 | | * XEVNT_OK success |
3338 | | * XEVNT_CRT bad or missing certificate |
3339 | | * XEVNT_PER host certificate expired |
3340 | | * XEVNT_VFY certificate not verified |
3341 | | */ |
3342 | | int |
3343 | | cert_hike( |
3344 | | struct peer *peer, /* peer structure pointer */ |
3345 | | struct cert_info *yp /* issuer certificate */ |
3346 | | ) |
3347 | 0 | { |
3348 | 0 | struct cert_info *xp; /* subject certificate */ |
3349 | 0 | X509 *cert; /* X509 certificate */ |
3350 | 0 | const u_char *ptr; |
3351 | | |
3352 | | /* |
3353 | | * Save the issuer on the new certificate, but remember the old |
3354 | | * one. |
3355 | | */ |
3356 | 0 | if (peer->issuer != NULL) |
3357 | 0 | free(peer->issuer); |
3358 | 0 | peer->issuer = estrdup(yp->issuer); |
3359 | 0 | xp = peer->xinfo; |
3360 | 0 | peer->xinfo = yp; |
3361 | | |
3362 | | /* |
3363 | | * If subject Y matches issuer Y, then the certificate trail is |
3364 | | * complete. If Y is not trusted, the server certificate has yet |
3365 | | * been signed, so keep trying. Otherwise, save the group key |
3366 | | * and light the valid bit. If the host certificate is trusted, |
3367 | | * do not execute a sign exchange. If no identity scheme is in |
3368 | | * use, light the identity and proventic bits. |
3369 | | */ |
3370 | 0 | if (strcmp(yp->subject, yp->issuer) == 0) { |
3371 | 0 | if (!(yp->flags & CERT_TRUST)) |
3372 | 0 | return (XEVNT_OK); |
3373 | | |
3374 | | /* |
3375 | | * If the server has an an identity scheme, fetch the |
3376 | | * identity credentials. If not, the identity is |
3377 | | * verified only by the trusted certificate. The next |
3378 | | * signature will set the server proventic. |
3379 | | */ |
3380 | 0 | peer->crypto |= CRYPTO_FLAG_CERT; |
3381 | 0 | peer->grpkey = yp->grpkey; |
3382 | 0 | if (peer->ident == NULL || !(peer->crypto & |
3383 | 0 | CRYPTO_FLAG_MASK)) |
3384 | 0 | peer->crypto |= CRYPTO_FLAG_VRFY; |
3385 | 0 | } |
3386 | | |
3387 | | /* |
3388 | | * If X exists, verify signature X using public key Y. |
3389 | | */ |
3390 | 0 | if (xp == NULL) |
3391 | 0 | return (XEVNT_OK); |
3392 | | |
3393 | 0 | ptr = (u_char *)xp->cert.ptr; |
3394 | 0 | cert = d2i_X509(NULL, &ptr, ntohl(xp->cert.vallen)); |
3395 | 0 | if (cert == NULL) { |
3396 | 0 | xp->flags |= CERT_ERROR; |
3397 | 0 | return (XEVNT_CRT); |
3398 | 0 | } |
3399 | 0 | if (X509_verify(cert, yp->pkey) <= 0) { |
3400 | 0 | X509_free(cert); |
3401 | 0 | xp->flags |= CERT_ERROR; |
3402 | 0 | return (XEVNT_VFY); |
3403 | 0 | } |
3404 | 0 | X509_free(cert); |
3405 | | |
3406 | | /* |
3407 | | * Signature X is valid only if it begins during the |
3408 | | * lifetime of Y. |
3409 | | */ |
3410 | 0 | if ((calcomp(&(xp->first), &(yp->first)) < 0) |
3411 | 0 | || (calcomp(&(xp->first), &(yp->last)) > 0)) { |
3412 | 0 | xp->flags |= CERT_ERROR; |
3413 | 0 | return (XEVNT_PER); |
3414 | 0 | } |
3415 | 0 | xp->flags |= CERT_SIGN; |
3416 | 0 | return (XEVNT_OK); |
3417 | 0 | } |
3418 | | |
3419 | | |
3420 | | /* |
3421 | | * cert_parse - parse x509 certificate and create info/value structures. |
3422 | | * |
3423 | | * The server certificate includes the version number, issuer name, |
3424 | | * subject name, public key and valid date interval. If the issuer name |
3425 | | * is the same as the subject name, the certificate is self signed and |
3426 | | * valid only if the server is configured as trustable. If the names are |
3427 | | * different, another issuer has signed the server certificate and |
3428 | | * vouched for it. In this case the server certificate is valid if |
3429 | | * verified by the issuer public key. |
3430 | | * |
3431 | | * Returns certificate info/value pointer if valid, NULL if not. |
3432 | | */ |
3433 | | struct cert_info * /* certificate information structure */ |
3434 | | cert_parse( |
3435 | | const u_char *asn1cert, /* X509 certificate */ |
3436 | | long len, /* certificate length */ |
3437 | | tstamp_t fstamp /* filestamp */ |
3438 | | ) |
3439 | 0 | { |
3440 | 0 | X509 *cert; /* X509 certificate */ |
3441 | 0 | struct cert_info *ret; /* certificate info/value */ |
3442 | 0 | BIO *bp; |
3443 | 0 | char pathbuf[MAXFILENAME]; |
3444 | 0 | const u_char *ptr; |
3445 | 0 | char *pch; |
3446 | 0 | int cnt, i; |
3447 | 0 | struct calendar fscal; |
3448 | | |
3449 | | /* |
3450 | | * Decode ASN.1 objects and construct certificate structure. |
3451 | | */ |
3452 | 0 | ptr = asn1cert; |
3453 | 0 | if ((cert = d2i_X509(NULL, &ptr, len)) == NULL) { |
3454 | 0 | msyslog(LOG_ERR, "cert_parse: %s", |
3455 | 0 | ERR_error_string(ERR_get_error(), NULL)); |
3456 | 0 | return (NULL); |
3457 | 0 | } |
3458 | 0 | #ifdef DEBUG |
3459 | 0 | if (debug > 1) |
3460 | 0 | X509_print_fp(stdout, cert); |
3461 | 0 | #endif |
3462 | | |
3463 | | /* |
3464 | | * Extract version, subject name and public key. |
3465 | | */ |
3466 | 0 | ret = emalloc_zero(sizeof(*ret)); |
3467 | 0 | if ((ret->pkey = X509_get_pubkey(cert)) == NULL) { |
3468 | 0 | msyslog(LOG_ERR, "cert_parse: %s", |
3469 | 0 | ERR_error_string(ERR_get_error(), NULL)); |
3470 | 0 | cert_free(ret); |
3471 | 0 | X509_free(cert); |
3472 | 0 | return (NULL); |
3473 | 0 | } |
3474 | 0 | ret->version = X509_get_version(cert); |
3475 | 0 | X509_NAME_oneline(X509_get_subject_name(cert), pathbuf, |
3476 | 0 | sizeof(pathbuf)); |
3477 | 0 | pch = strstr(pathbuf, "CN="); |
3478 | 0 | if (NULL == pch) { |
3479 | 0 | msyslog(LOG_NOTICE, "cert_parse: invalid subject %s", |
3480 | 0 | pathbuf); |
3481 | 0 | cert_free(ret); |
3482 | 0 | X509_free(cert); |
3483 | 0 | return (NULL); |
3484 | 0 | } |
3485 | 0 | ret->subject = estrdup(pch + 3); |
3486 | | |
3487 | | /* |
3488 | | * Extract remaining objects. Note that the NTP serial number is |
3489 | | * the NTP seconds at the time of signing, but this might not be |
3490 | | * the case for other authority. We don't bother to check the |
3491 | | * objects at this time, since the real crunch can happen only |
3492 | | * when the time is valid but not yet certificated. |
3493 | | */ |
3494 | 0 | ret->nid = X509_get_signature_nid(cert); |
3495 | 0 | ret->digest = (const EVP_MD *)EVP_get_digestbynid(ret->nid); |
3496 | 0 | ret->serial = |
3497 | 0 | (u_long)ASN1_INTEGER_get(X509_get_serialNumber(cert)); |
3498 | 0 | X509_NAME_oneline(X509_get_issuer_name(cert), pathbuf, |
3499 | 0 | sizeof(pathbuf)); |
3500 | 0 | if ((pch = strstr(pathbuf, "CN=")) == NULL) { |
3501 | 0 | msyslog(LOG_NOTICE, "cert_parse: invalid issuer %s", |
3502 | 0 | pathbuf); |
3503 | 0 | cert_free(ret); |
3504 | 0 | X509_free(cert); |
3505 | 0 | return (NULL); |
3506 | 0 | } |
3507 | 0 | ret->issuer = estrdup(pch + 3); |
3508 | 0 | asn_to_calendar(X509_get0_notBefore(cert), &(ret->first)); |
3509 | 0 | asn_to_calendar(X509_get0_notAfter(cert), &(ret->last)); |
3510 | | |
3511 | | /* |
3512 | | * Extract extension fields. These are ad hoc ripoffs of |
3513 | | * currently assigned functions and will certainly be changed |
3514 | | * before prime time. |
3515 | | */ |
3516 | 0 | cnt = X509_get_ext_count(cert); |
3517 | 0 | for (i = 0; i < cnt; i++) { |
3518 | 0 | X509_EXTENSION *ext; |
3519 | 0 | ASN1_OBJECT *obj; |
3520 | 0 | int nid; |
3521 | 0 | ASN1_OCTET_STRING *data; |
3522 | |
|
3523 | 0 | ext = X509_get_ext(cert, i); |
3524 | 0 | obj = X509_EXTENSION_get_object(ext); |
3525 | 0 | nid = OBJ_obj2nid(obj); |
3526 | |
|
3527 | 0 | switch (nid) { |
3528 | | |
3529 | | /* |
3530 | | * If a key_usage field is present, we decode whether |
3531 | | * this is a trusted or private certificate. This is |
3532 | | * dorky; all we want is to compare NIDs, but OpenSSL |
3533 | | * insists on BIO text strings. |
3534 | | */ |
3535 | 0 | case NID_ext_key_usage: |
3536 | 0 | bp = BIO_new(BIO_s_mem()); |
3537 | 0 | X509V3_EXT_print(bp, ext, 0, 0); |
3538 | 0 | BIO_gets(bp, pathbuf, sizeof(pathbuf)); |
3539 | 0 | BIO_free(bp); |
3540 | 0 | if (strcmp(pathbuf, "Trust Root") == 0) |
3541 | 0 | ret->flags |= CERT_TRUST; |
3542 | 0 | else if (strcmp(pathbuf, "Private") == 0) |
3543 | 0 | ret->flags |= CERT_PRIV; |
3544 | 0 | DPRINTF(1, ("cert_parse: %s: %s\n", |
3545 | 0 | OBJ_nid2ln(nid), pathbuf)); |
3546 | 0 | break; |
3547 | | |
3548 | | /* |
3549 | | * If a NID_subject_key_identifier field is present, it |
3550 | | * contains the GQ public key. |
3551 | | */ |
3552 | 0 | case NID_subject_key_identifier: |
3553 | 0 | data = X509_EXTENSION_get_data(ext); |
3554 | 0 | ret->grpkey = BN_bin2bn(&data->data[2], |
3555 | 0 | data->length - 2, NULL); |
3556 | | /* fall through */ |
3557 | 0 | default: |
3558 | 0 | DPRINTF(1, ("cert_parse: %s\n", |
3559 | 0 | OBJ_nid2ln(nid))); |
3560 | 0 | break; |
3561 | 0 | } |
3562 | 0 | } |
3563 | 0 | if (strcmp(ret->subject, ret->issuer) == 0) { |
3564 | | |
3565 | | /* |
3566 | | * If certificate is self signed, verify signature. |
3567 | | */ |
3568 | 0 | if (X509_verify(cert, ret->pkey) <= 0) { |
3569 | 0 | msyslog(LOG_NOTICE, |
3570 | 0 | "cert_parse: signature not verified %s", |
3571 | 0 | ret->subject); |
3572 | 0 | cert_free(ret); |
3573 | 0 | X509_free(cert); |
3574 | 0 | return (NULL); |
3575 | 0 | } |
3576 | 0 | } else { |
3577 | | |
3578 | | /* |
3579 | | * Check for a certificate loop. |
3580 | | */ |
3581 | 0 | if (strcmp((const char *)hostval.ptr, ret->issuer) == 0) { |
3582 | 0 | msyslog(LOG_NOTICE, |
3583 | 0 | "cert_parse: certificate trail loop %s", |
3584 | 0 | ret->subject); |
3585 | 0 | cert_free(ret); |
3586 | 0 | X509_free(cert); |
3587 | 0 | return (NULL); |
3588 | 0 | } |
3589 | 0 | } |
3590 | | |
3591 | | /* |
3592 | | * Verify certificate valid times. Note that certificates cannot |
3593 | | * be retroactive. |
3594 | | */ |
3595 | 0 | (void)ntpcal_ntp_to_date(&fscal, fstamp, NULL); |
3596 | 0 | if ((calcomp(&(ret->first), &(ret->last)) > 0) |
3597 | 0 | || (calcomp(&(ret->first), &fscal) < 0)) { |
3598 | 0 | msyslog(LOG_NOTICE, |
3599 | 0 | "cert_parse: invalid times %s first %u-%02u-%02uT%02u:%02u:%02u last %u-%02u-%02uT%02u:%02u:%02u fstamp %u-%02u-%02uT%02u:%02u:%02u", |
3600 | 0 | ret->subject, |
3601 | 0 | ret->first.year, ret->first.month, ret->first.monthday, |
3602 | 0 | ret->first.hour, ret->first.minute, ret->first.second, |
3603 | 0 | ret->last.year, ret->last.month, ret->last.monthday, |
3604 | 0 | ret->last.hour, ret->last.minute, ret->last.second, |
3605 | 0 | fscal.year, fscal.month, fscal.monthday, |
3606 | 0 | fscal.hour, fscal.minute, fscal.second); |
3607 | 0 | cert_free(ret); |
3608 | 0 | X509_free(cert); |
3609 | 0 | return (NULL); |
3610 | 0 | } |
3611 | | |
3612 | | /* |
3613 | | * Build the value structure to sign and send later. |
3614 | | */ |
3615 | 0 | ret->cert.fstamp = htonl(fstamp); |
3616 | 0 | ret->cert.vallen = htonl(len); |
3617 | 0 | ret->cert.ptr = emalloc(len); |
3618 | 0 | memcpy(ret->cert.ptr, asn1cert, len); |
3619 | 0 | X509_free(cert); |
3620 | 0 | return (ret); |
3621 | 0 | } |
3622 | | |
3623 | | |
3624 | | /* |
3625 | | * cert_free - free certificate information structure |
3626 | | */ |
3627 | | void |
3628 | | cert_free( |
3629 | | struct cert_info *cinf /* certificate info/value structure */ |
3630 | | ) |
3631 | 0 | { |
3632 | 0 | if (cinf->pkey != NULL) |
3633 | 0 | EVP_PKEY_free(cinf->pkey); |
3634 | 0 | if (cinf->subject != NULL) |
3635 | 0 | free(cinf->subject); |
3636 | 0 | if (cinf->issuer != NULL) |
3637 | 0 | free(cinf->issuer); |
3638 | 0 | if (cinf->grpkey != NULL) |
3639 | 0 | BN_free(cinf->grpkey); |
3640 | 0 | value_free(&cinf->cert); |
3641 | 0 | free(cinf); |
3642 | 0 | } |
3643 | | |
3644 | | |
3645 | | /* |
3646 | | * crypto_key - load cryptographic parameters and keys |
3647 | | * |
3648 | | * This routine searches the key cache for matching name in the form |
3649 | | * ntpkey_<key>_<name>, where <key> is one of host, sign, iff, gq, mv, |
3650 | | * and <name> is the host/group name. If not found, it tries to load a |
3651 | | * PEM-encoded file of the same name and extracts the filestamp from |
3652 | | * the first line of the file name. It returns the key pointer if valid, |
3653 | | * NULL if not. |
3654 | | */ |
3655 | | static struct pkey_info * |
3656 | | crypto_key( |
3657 | | char *cp, /* file name */ |
3658 | | char *passwd1, /* password */ |
3659 | | sockaddr_u *addr /* IP address */ |
3660 | | ) |
3661 | 0 | { |
3662 | 0 | FILE *str; /* file handle */ |
3663 | 0 | struct pkey_info *pkp; /* generic key */ |
3664 | 0 | EVP_PKEY *pkey = NULL; /* public/private key */ |
3665 | 0 | tstamp_t fstamp; |
3666 | 0 | char filename[MAXFILENAME]; /* name of key file */ |
3667 | 0 | char linkname[MAXFILENAME]; /* filestamp buffer) */ |
3668 | 0 | char statstr[NTP_MAXSTRLEN]; /* statistics for filegen */ |
3669 | 0 | char *ptr; |
3670 | | |
3671 | | /* |
3672 | | * Search the key cache for matching key and name. |
3673 | | */ |
3674 | 0 | for (pkp = pkinfo; pkp != NULL; pkp = pkp->link) { |
3675 | 0 | if (strcmp(cp, pkp->name) == 0) |
3676 | 0 | return (pkp); |
3677 | 0 | } |
3678 | | |
3679 | | /* |
3680 | | * Open the key file. If the first character of the file name is |
3681 | | * not '/', prepend the keys directory string. If something goes |
3682 | | * wrong, abandon ship. |
3683 | | */ |
3684 | 0 | if (*cp == '/') |
3685 | 0 | strlcpy(filename, cp, sizeof(filename)); |
3686 | 0 | else |
3687 | 0 | snprintf(filename, sizeof(filename), "%s/%s", keysdir, |
3688 | 0 | cp); |
3689 | 0 | str = fopen(filename, "r"); |
3690 | 0 | if (str == NULL) |
3691 | 0 | return (NULL); |
3692 | | |
3693 | | /* |
3694 | | * Read the filestamp, which is contained in the first line. |
3695 | | */ |
3696 | 0 | if ((ptr = fgets(linkname, sizeof(linkname), str)) == NULL) { |
3697 | 0 | msyslog(LOG_ERR, "crypto_key: empty file %s", |
3698 | 0 | filename); |
3699 | 0 | fclose(str); |
3700 | 0 | return (NULL); |
3701 | 0 | } |
3702 | 0 | if ((ptr = strrchr(ptr, '.')) == NULL) { |
3703 | 0 | msyslog(LOG_ERR, "crypto_key: no filestamp %s", |
3704 | 0 | filename); |
3705 | 0 | fclose(str); |
3706 | 0 | return (NULL); |
3707 | 0 | } |
3708 | 0 | if (sscanf(++ptr, "%u", &fstamp) != 1) { |
3709 | 0 | msyslog(LOG_ERR, "crypto_key: invalid filestamp %s", |
3710 | 0 | filename); |
3711 | 0 | fclose(str); |
3712 | 0 | return (NULL); |
3713 | 0 | } |
3714 | | |
3715 | | /* |
3716 | | * Read and decrypt PEM-encoded private key. If it fails to |
3717 | | * decrypt, game over. |
3718 | | */ |
3719 | 0 | pkey = PEM_read_PrivateKey(str, NULL, NULL, passwd1); |
3720 | 0 | fclose(str); |
3721 | 0 | if (pkey == NULL) { |
3722 | 0 | msyslog(LOG_ERR, "crypto_key: %s", |
3723 | 0 | ERR_error_string(ERR_get_error(), NULL)); |
3724 | 0 | exit (-1); |
3725 | 0 | } |
3726 | | |
3727 | | /* |
3728 | | * Make a new entry in the key cache. |
3729 | | */ |
3730 | 0 | pkp = emalloc(sizeof(struct pkey_info)); |
3731 | 0 | pkp->link = pkinfo; |
3732 | 0 | pkinfo = pkp; |
3733 | 0 | pkp->pkey = pkey; |
3734 | 0 | pkp->name = estrdup(cp); |
3735 | 0 | pkp->fstamp = fstamp; |
3736 | | |
3737 | | /* |
3738 | | * Leave tracks in the cryptostats. |
3739 | | */ |
3740 | 0 | if ((ptr = strrchr(linkname, '\n')) != NULL) |
3741 | 0 | *ptr = '\0'; |
3742 | 0 | snprintf(statstr, sizeof(statstr), "%s mod %d", &linkname[2], |
3743 | 0 | EVP_PKEY_size(pkey) * 8); |
3744 | 0 | record_crypto_stats(addr, statstr); |
3745 | | |
3746 | 0 | DPRINTF(1, ("crypto_key: %s\n", statstr)); |
3747 | 0 | #ifdef DEBUG |
3748 | 0 | if (debug > 1) { |
3749 | 0 | if (EVP_PKEY_base_id(pkey) == EVP_PKEY_DSA) |
3750 | 0 | DSA_print_fp(stdout, EVP_PKEY_get0_DSA(pkey), 0); |
3751 | 0 | else if (EVP_PKEY_base_id(pkey) == EVP_PKEY_RSA) |
3752 | 0 | RSA_print_fp(stdout, EVP_PKEY_get0_RSA(pkey), 0); |
3753 | 0 | } |
3754 | 0 | #endif |
3755 | 0 | return (pkp); |
3756 | 0 | } |
3757 | | |
3758 | | |
3759 | | /* |
3760 | | *********************************************************************** |
3761 | | * * |
3762 | | * The following routines are used only at initialization time * |
3763 | | * * |
3764 | | *********************************************************************** |
3765 | | */ |
3766 | | /* |
3767 | | * crypto_cert - load certificate from file |
3768 | | * |
3769 | | * This routine loads an X.509 RSA or DSA certificate from a file and |
3770 | | * constructs a info/cert value structure for this machine. The |
3771 | | * structure includes a filestamp extracted from the file name. Later |
3772 | | * the certificate can be sent to another machine on request. |
3773 | | * |
3774 | | * Returns certificate info/value pointer if valid, NULL if not. |
3775 | | */ |
3776 | | static struct cert_info * /* certificate information */ |
3777 | | crypto_cert( |
3778 | | char *cp /* file name */ |
3779 | | ) |
3780 | 0 | { |
3781 | 0 | struct cert_info *ret; /* certificate information */ |
3782 | 0 | FILE *str; /* file handle */ |
3783 | 0 | char filename[MAXFILENAME]; /* name of certificate file */ |
3784 | 0 | char linkname[MAXFILENAME]; /* filestamp buffer */ |
3785 | 0 | char statstr[NTP_MAXSTRLEN]; /* statistics for filegen */ |
3786 | 0 | tstamp_t fstamp; /* filestamp */ |
3787 | 0 | long len; |
3788 | 0 | char *ptr; |
3789 | 0 | char *name, *header; |
3790 | 0 | u_char *data; |
3791 | | |
3792 | | /* |
3793 | | * Open the certificate file. If the first character of the file |
3794 | | * name is not '/', prepend the keys directory string. If |
3795 | | * something goes wrong, abandon ship. |
3796 | | */ |
3797 | 0 | if (*cp == '/') |
3798 | 0 | strlcpy(filename, cp, sizeof(filename)); |
3799 | 0 | else |
3800 | 0 | snprintf(filename, sizeof(filename), "%s/%s", keysdir, |
3801 | 0 | cp); |
3802 | 0 | str = fopen(filename, "r"); |
3803 | 0 | if (str == NULL) |
3804 | 0 | return (NULL); |
3805 | | |
3806 | | /* |
3807 | | * Read the filestamp, which is contained in the first line. |
3808 | | */ |
3809 | 0 | if ((ptr = fgets(linkname, sizeof(linkname), str)) == NULL) { |
3810 | 0 | msyslog(LOG_ERR, "crypto_cert: empty file %s", |
3811 | 0 | filename); |
3812 | 0 | fclose(str); |
3813 | 0 | return (NULL); |
3814 | 0 | } |
3815 | 0 | if ((ptr = strrchr(ptr, '.')) == NULL) { |
3816 | 0 | msyslog(LOG_ERR, "crypto_cert: no filestamp %s", |
3817 | 0 | filename); |
3818 | 0 | fclose(str); |
3819 | 0 | return (NULL); |
3820 | 0 | } |
3821 | 0 | if (sscanf(++ptr, "%u", &fstamp) != 1) { |
3822 | 0 | msyslog(LOG_ERR, "crypto_cert: invalid filestamp %s", |
3823 | 0 | filename); |
3824 | 0 | fclose(str); |
3825 | 0 | return (NULL); |
3826 | 0 | } |
3827 | | |
3828 | | /* |
3829 | | * Read PEM-encoded certificate and install. |
3830 | | */ |
3831 | 0 | if (!PEM_read(str, &name, &header, &data, &len)) { |
3832 | 0 | msyslog(LOG_ERR, "crypto_cert: %s", |
3833 | 0 | ERR_error_string(ERR_get_error(), NULL)); |
3834 | 0 | fclose(str); |
3835 | 0 | return (NULL); |
3836 | 0 | } |
3837 | 0 | fclose(str); |
3838 | 0 | free(header); |
3839 | 0 | if (strcmp(name, "CERTIFICATE") != 0) { |
3840 | 0 | msyslog(LOG_NOTICE, "crypto_cert: wrong PEM type %s", |
3841 | 0 | name); |
3842 | 0 | free(name); |
3843 | 0 | free(data); |
3844 | 0 | return (NULL); |
3845 | 0 | } |
3846 | 0 | free(name); |
3847 | | |
3848 | | /* |
3849 | | * Parse certificate and generate info/value structure. The |
3850 | | * pointer and copy nonsense is due something broken in Solaris. |
3851 | | */ |
3852 | 0 | ret = cert_parse(data, len, fstamp); |
3853 | 0 | free(data); |
3854 | 0 | if (ret == NULL) |
3855 | 0 | return (NULL); |
3856 | | |
3857 | 0 | if ((ptr = strrchr(linkname, '\n')) != NULL) |
3858 | 0 | *ptr = '\0'; |
3859 | 0 | snprintf(statstr, sizeof(statstr), "%s 0x%x len %lu", |
3860 | 0 | &linkname[2], ret->flags, len); |
3861 | 0 | record_crypto_stats(NULL, statstr); |
3862 | 0 | DPRINTF(1, ("crypto_cert: %s\n", statstr)); |
3863 | 0 | return (ret); |
3864 | 0 | } |
3865 | | |
3866 | | |
3867 | | /* |
3868 | | * crypto_setup - load keys, certificate and identity parameters |
3869 | | * |
3870 | | * This routine loads the public/private host key and certificate. If |
3871 | | * available, it loads the public/private sign key, which defaults to |
3872 | | * the host key. The host key must be RSA, but the sign key can be |
3873 | | * either RSA or DSA. If a trusted certificate, it loads the identity |
3874 | | * parameters. In either case, the public key on the certificate must |
3875 | | * agree with the sign key. |
3876 | | * |
3877 | | * Required but missing files and inconsistent data and errors are |
3878 | | * fatal. Allowing configuration to continue would be hazardous and |
3879 | | * require really messy error checks. |
3880 | | */ |
3881 | | void |
3882 | | crypto_setup(void) |
3883 | 0 | { |
3884 | 0 | struct pkey_info *pinfo; /* private/public key */ |
3885 | 0 | char filename[MAXFILENAME]; /* file name buffer */ |
3886 | 0 | char hostname[MAXFILENAME]; /* host name buffer */ |
3887 | 0 | char *randfile; |
3888 | 0 | char statstr[NTP_MAXSTRLEN]; /* statistics for filegen */ |
3889 | 0 | l_fp seed; /* crypto PRNG seed as NTP timestamp */ |
3890 | 0 | u_int len; |
3891 | 0 | int bytes; |
3892 | 0 | u_char *ptr; |
3893 | | |
3894 | | /* |
3895 | | * Check for correct OpenSSL version and avoid initialization in |
3896 | | * the case of multiple crypto commands. |
3897 | | */ |
3898 | 0 | if (crypto_flags & CRYPTO_FLAG_ENAB) { |
3899 | 0 | msyslog(LOG_NOTICE, |
3900 | 0 | "crypto_setup: spurious crypto command"); |
3901 | 0 | return; |
3902 | 0 | } |
3903 | | |
3904 | | /* |
3905 | | * Load required random seed file and seed the random number |
3906 | | * generator. Be default, it is found as .rnd in the user home |
3907 | | * directory. The root home directory may be / or /root, |
3908 | | * depending on the system. Wiggle the contents a bit and write |
3909 | | * it back so the sequence does not repeat when we next restart. |
3910 | | */ |
3911 | 0 | if (!RAND_status()) { |
3912 | 0 | if (rand_file == NULL) { |
3913 | 0 | RAND_file_name(filename, sizeof(filename)); |
3914 | 0 | randfile = filename; |
3915 | 0 | } else if (*rand_file != '/') { |
3916 | 0 | snprintf(filename, sizeof(filename), "%s/%s", |
3917 | 0 | keysdir, rand_file); |
3918 | 0 | randfile = filename; |
3919 | 0 | } else |
3920 | 0 | randfile = rand_file; |
3921 | |
|
3922 | 0 | if ((bytes = RAND_load_file(randfile, -1)) == 0) { |
3923 | 0 | msyslog(LOG_ERR, |
3924 | 0 | "crypto_setup: random seed file %s missing", |
3925 | 0 | randfile); |
3926 | 0 | exit (-1); |
3927 | 0 | } |
3928 | 0 | get_systime(&seed); |
3929 | 0 | RAND_seed(&seed, sizeof(l_fp)); |
3930 | 0 | RAND_write_file(randfile); |
3931 | 0 | DPRINTF(1, ("crypto_setup: OpenSSL version %lx random seed file %s bytes read %d\n", |
3932 | 0 | OpenSSL_version_num(), randfile, bytes)); |
3933 | |
|
3934 | 0 | } |
3935 | | |
3936 | | /* |
3937 | | * Initialize structures. |
3938 | | */ |
3939 | 0 | gethostname(hostname, sizeof(hostname)); |
3940 | 0 | if (host_filename != NULL) |
3941 | 0 | strlcpy(hostname, host_filename, sizeof(hostname)); |
3942 | 0 | if (passwd == NULL) |
3943 | 0 | passwd = estrdup(hostname); |
3944 | 0 | memset(&hostval, 0, sizeof(hostval)); |
3945 | 0 | memset(&pubkey, 0, sizeof(pubkey)); |
3946 | 0 | memset(&tai_leap, 0, sizeof(tai_leap)); |
3947 | | |
3948 | | /* |
3949 | | * Load required host key from file "ntpkey_host_<hostname>". If |
3950 | | * no host key file is not found or has invalid password, life |
3951 | | * as we know it ends. The host key also becomes the default |
3952 | | * sign key. |
3953 | | */ |
3954 | 0 | snprintf(filename, sizeof(filename), "ntpkey_host_%s", hostname); |
3955 | 0 | pinfo = crypto_key(filename, passwd, NULL); |
3956 | 0 | if (pinfo == NULL) { |
3957 | 0 | msyslog(LOG_ERR, |
3958 | 0 | "crypto_setup: host key file %s not found or corrupt", |
3959 | 0 | filename); |
3960 | 0 | exit (-1); |
3961 | 0 | } |
3962 | 0 | if (EVP_PKEY_base_id(pinfo->pkey) != EVP_PKEY_RSA) { |
3963 | 0 | msyslog(LOG_ERR, |
3964 | 0 | "crypto_setup: host key is not RSA key type"); |
3965 | 0 | exit (-1); |
3966 | 0 | } |
3967 | 0 | host_pkey = pinfo->pkey; |
3968 | 0 | sign_pkey = host_pkey; |
3969 | 0 | hostval.fstamp = htonl(pinfo->fstamp); |
3970 | | |
3971 | | /* |
3972 | | * Construct public key extension field for agreement scheme. |
3973 | | */ |
3974 | 0 | len = i2d_PublicKey(host_pkey, NULL); |
3975 | 0 | ptr = emalloc(len); |
3976 | 0 | pubkey.ptr = ptr; |
3977 | 0 | i2d_PublicKey(host_pkey, &ptr); |
3978 | 0 | pubkey.fstamp = hostval.fstamp; |
3979 | 0 | pubkey.vallen = htonl(len); |
3980 | | |
3981 | | /* |
3982 | | * Load optional sign key from file "ntpkey_sign_<hostname>". If |
3983 | | * available, it becomes the sign key. |
3984 | | */ |
3985 | 0 | snprintf(filename, sizeof(filename), "ntpkey_sign_%s", hostname); |
3986 | 0 | pinfo = crypto_key(filename, passwd, NULL); |
3987 | 0 | if (pinfo != NULL) |
3988 | 0 | sign_pkey = pinfo->pkey; |
3989 | | |
3990 | | /* |
3991 | | * Load required certificate from file "ntpkey_cert_<hostname>". |
3992 | | */ |
3993 | 0 | snprintf(filename, sizeof(filename), "ntpkey_cert_%s", hostname); |
3994 | 0 | cinfo = crypto_cert(filename); |
3995 | 0 | if (cinfo == NULL) { |
3996 | 0 | msyslog(LOG_ERR, |
3997 | 0 | "crypto_setup: certificate file %s not found or corrupt", |
3998 | 0 | filename); |
3999 | 0 | exit (-1); |
4000 | 0 | } |
4001 | 0 | cert_host = cinfo; |
4002 | 0 | sign_digest = cinfo->digest; |
4003 | 0 | sign_siglen = EVP_PKEY_size(sign_pkey); |
4004 | 0 | if (cinfo->flags & CERT_PRIV) |
4005 | 0 | crypto_flags |= CRYPTO_FLAG_PRIV; |
4006 | | |
4007 | | /* |
4008 | | * The certificate must be self-signed. |
4009 | | */ |
4010 | 0 | if (strcmp(cinfo->subject, cinfo->issuer) != 0) { |
4011 | 0 | msyslog(LOG_ERR, |
4012 | 0 | "crypto_setup: certificate %s is not self-signed", |
4013 | 0 | filename); |
4014 | 0 | exit (-1); |
4015 | 0 | } |
4016 | 0 | hostval.ptr = estrdup(cinfo->subject); |
4017 | 0 | hostval.vallen = htonl(strlen(cinfo->subject)); |
4018 | 0 | sys_hostname = hostval.ptr; |
4019 | 0 | ptr = (u_char *)strchr(sys_hostname, '@'); |
4020 | 0 | if (ptr != NULL) |
4021 | 0 | sys_groupname = estrdup((char *)++ptr); |
4022 | 0 | if (ident_filename != NULL) |
4023 | 0 | strlcpy(hostname, ident_filename, sizeof(hostname)); |
4024 | | |
4025 | | /* |
4026 | | * Load optional IFF parameters from file |
4027 | | * "ntpkey_iffkey_<hostname>". |
4028 | | */ |
4029 | 0 | snprintf(filename, sizeof(filename), "ntpkey_iffkey_%s", |
4030 | 0 | hostname); |
4031 | 0 | iffkey_info = crypto_key(filename, passwd, NULL); |
4032 | 0 | if (iffkey_info != NULL) |
4033 | 0 | crypto_flags |= CRYPTO_FLAG_IFF; |
4034 | | |
4035 | | /* |
4036 | | * Load optional GQ parameters from file |
4037 | | * "ntpkey_gqkey_<hostname>". |
4038 | | */ |
4039 | 0 | snprintf(filename, sizeof(filename), "ntpkey_gqkey_%s", |
4040 | 0 | hostname); |
4041 | 0 | gqkey_info = crypto_key(filename, passwd, NULL); |
4042 | 0 | if (gqkey_info != NULL) |
4043 | 0 | crypto_flags |= CRYPTO_FLAG_GQ; |
4044 | | |
4045 | | /* |
4046 | | * Load optional MV parameters from file |
4047 | | * "ntpkey_mvkey_<hostname>". |
4048 | | */ |
4049 | 0 | snprintf(filename, sizeof(filename), "ntpkey_mvkey_%s", |
4050 | 0 | hostname); |
4051 | 0 | mvkey_info = crypto_key(filename, passwd, NULL); |
4052 | 0 | if (mvkey_info != NULL) |
4053 | 0 | crypto_flags |= CRYPTO_FLAG_MV; |
4054 | | |
4055 | | /* |
4056 | | * We met the enemy and he is us. Now strike up the dance. |
4057 | | */ |
4058 | 0 | crypto_flags |= CRYPTO_FLAG_ENAB | (cinfo->nid << 16); |
4059 | 0 | snprintf(statstr, sizeof(statstr), "setup 0x%x host %s %s", |
4060 | 0 | crypto_flags, hostname, OBJ_nid2ln(cinfo->nid)); |
4061 | 0 | record_crypto_stats(NULL, statstr); |
4062 | 0 | DPRINTF(1, ("crypto_setup: %s\n", statstr)); |
4063 | 0 | } |
4064 | | |
4065 | | |
4066 | | /* |
4067 | | * crypto_config - configure data from the crypto command. |
4068 | | */ |
4069 | | void |
4070 | | crypto_config( |
4071 | | int item, /* configuration item */ |
4072 | | char *cp /* item name */ |
4073 | | ) |
4074 | 0 | { |
4075 | 0 | int nid; |
4076 | |
|
4077 | 0 | DPRINTF(1, ("crypto_config: item %d %s\n", item, cp)); |
4078 | |
|
4079 | 0 | switch (item) { |
4080 | | |
4081 | | /* |
4082 | | * Set host name (host). |
4083 | | */ |
4084 | 0 | case CRYPTO_CONF_PRIV: |
4085 | 0 | if (NULL != host_filename) |
4086 | 0 | free(host_filename); |
4087 | 0 | host_filename = estrdup(cp); |
4088 | 0 | break; |
4089 | | |
4090 | | /* |
4091 | | * Set group name (ident). |
4092 | | */ |
4093 | 0 | case CRYPTO_CONF_IDENT: |
4094 | 0 | if (NULL != ident_filename) |
4095 | 0 | free(ident_filename); |
4096 | 0 | ident_filename = estrdup(cp); |
4097 | 0 | break; |
4098 | | |
4099 | | /* |
4100 | | * Set private key password (pw). |
4101 | | */ |
4102 | 0 | case CRYPTO_CONF_PW: |
4103 | 0 | if (NULL != passwd) |
4104 | 0 | free(passwd); |
4105 | 0 | passwd = estrdup(cp); |
4106 | 0 | break; |
4107 | | |
4108 | | /* |
4109 | | * Set random seed file name (randfile). |
4110 | | */ |
4111 | 0 | case CRYPTO_CONF_RAND: |
4112 | 0 | if (NULL != rand_file) |
4113 | 0 | free(rand_file); |
4114 | 0 | rand_file = estrdup(cp); |
4115 | 0 | break; |
4116 | | |
4117 | | /* |
4118 | | * Set message digest NID. |
4119 | | */ |
4120 | 0 | case CRYPTO_CONF_NID: |
4121 | 0 | nid = OBJ_sn2nid(cp); |
4122 | 0 | if (nid == 0) |
4123 | 0 | msyslog(LOG_ERR, |
4124 | 0 | "crypto_config: invalid digest name %s", cp); |
4125 | 0 | else |
4126 | 0 | crypto_nid = nid; |
4127 | 0 | break; |
4128 | 0 | } |
4129 | 0 | } |
4130 | | |
4131 | | /* |
4132 | | * Get the payload size (internal value length) of an extension packet. |
4133 | | * If the inner value size does not match the outer packet size (that |
4134 | | * is, the value would end behind the frame given by the opcode/size |
4135 | | * field) the function will effectively return UINT_MAX. If the frame is |
4136 | | * too short to hold a variable-sized value, the return value is zero. |
4137 | | */ |
4138 | | static u_int |
4139 | | exten_payload_size( |
4140 | | const struct exten * ep) |
4141 | 0 | { |
4142 | 0 | typedef const u_char *BPTR; |
4143 | | |
4144 | 0 | size_t extn_size; |
4145 | 0 | size_t data_size; |
4146 | 0 | size_t head_size; |
4147 | |
|
4148 | 0 | data_size = 0; |
4149 | 0 | if (NULL != ep) { |
4150 | 0 | head_size = (BPTR)(&ep->vallen + 1) - (BPTR)ep; |
4151 | 0 | extn_size = (uint16_t)(ntohl(ep->opcode) & 0x0000ffff); |
4152 | 0 | if (extn_size >= head_size) { |
4153 | 0 | data_size = (uint32_t)ntohl(ep->vallen); |
4154 | 0 | if (data_size > extn_size - head_size) |
4155 | 0 | data_size = ~(size_t)0u; |
4156 | 0 | } |
4157 | 0 | } |
4158 | 0 | return (u_int)data_size; |
4159 | 0 | } |
4160 | | # else /* !AUTOKEY follows */ |
4161 | | NONEMPTY_TRANSLATION_UNIT |
4162 | | # endif /* !AUTOKEY */ |