]> git.saurik.com Git - apple/network_cmds.git/blob - racoon.tproj/oakley.c
network_cmds-176.tar.gz
[apple/network_cmds.git] / racoon.tproj / oakley.c
1 /* $KAME: oakley.c,v 1.115 2003/01/10 08:38:23 sakane Exp $ */
2
3 /*
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32 #include <sys/types.h>
33 #include <sys/param.h>
34 #include <sys/socket.h> /* XXX for subjectaltname */
35 #include <netinet/in.h> /* XXX for subjectaltname */
36
37 #include <stdlib.h>
38 #include <stdio.h>
39 #include <string.h>
40 #include <errno.h>
41
42 #if TIME_WITH_SYS_TIME
43 # include <sys/time.h>
44 # include <time.h>
45 #else
46 # if HAVE_SYS_TIME_H
47 # include <sys/time.h>
48 # else
49 # include <time.h>
50 # endif
51 #endif
52
53 #include "var.h"
54 #include "misc.h"
55 #include "vmbuf.h"
56 #include "str2val.h"
57 #include "plog.h"
58 #include "debug.h"
59
60 #include "isakmp_var.h"
61 #include "isakmp.h"
62 #include "oakley.h"
63 #include "localconf.h"
64 #include "remoteconf.h"
65 #include "policy.h"
66 #include "handler.h"
67 #include "ipsec_doi.h"
68 #include "algorithm.h"
69 #include "dhgroup.h"
70 #include "sainfo.h"
71 #include "proposal.h"
72 #include "crypto_openssl.h"
73 #include "dnssec.h"
74 #include "sockmisc.h"
75 #include "strnames.h"
76 #include "gcmalloc.h"
77 #ifndef HAVE_ARC4RANDOM
78 #include "arc4random.h"
79 #endif
80
81 #ifdef HAVE_GSSAPI
82 #include "gssapi.h"
83 #endif
84
85 #define OUTBOUND_SA 0
86 #define INBOUND_SA 1
87
88 #define INITDHVAL(a, s, d, t) \
89 do { \
90 vchar_t buf; \
91 buf.v = str2val((s), 16, &buf.l); \
92 memset(&a, 0, sizeof(struct dhgroup)); \
93 a.type = (t); \
94 a.prime = vdup(&buf); \
95 racoon_free(buf.v); \
96 a.gen1 = 2; \
97 a.gen2 = 0; \
98 } while(0);
99
100 struct dhgroup dh_modp768;
101 struct dhgroup dh_modp1024;
102 struct dhgroup dh_modp1536;
103 struct dhgroup dh_modp2048;
104 struct dhgroup dh_modp3072;
105 struct dhgroup dh_modp4096;
106 struct dhgroup dh_modp6144;
107 struct dhgroup dh_modp8192;
108
109 static int oakley_compute_keymat_x __P((struct ph2handle *, int, int));
110 #ifdef HAVE_SIGNING_C
111 static int get_cert_fromlocal __P((struct ph1handle *, int));
112 static int oakley_check_certid __P((struct ph1handle *iph1));
113 static int check_typeofcertname __P((int, int));
114 static cert_t *save_certbuf __P((struct isakmp_gen *));
115 #endif
116 static int oakley_padlen __P((int, int));
117
118 int
119 oakley_get_defaultlifetime()
120 {
121 return OAKLEY_ATTR_SA_LD_SEC_DEFAULT;
122 }
123
124 int
125 oakley_dhinit()
126 {
127 /* set DH MODP */
128 INITDHVAL(dh_modp768, OAKLEY_PRIME_MODP768,
129 OAKLEY_ATTR_GRP_DESC_MODP768, OAKLEY_ATTR_GRP_TYPE_MODP);
130 INITDHVAL(dh_modp1024, OAKLEY_PRIME_MODP1024,
131 OAKLEY_ATTR_GRP_DESC_MODP1024, OAKLEY_ATTR_GRP_TYPE_MODP);
132 INITDHVAL(dh_modp1536, OAKLEY_PRIME_MODP1536,
133 OAKLEY_ATTR_GRP_DESC_MODP1536, OAKLEY_ATTR_GRP_TYPE_MODP);
134 INITDHVAL(dh_modp2048, OAKLEY_PRIME_MODP2048,
135 OAKLEY_ATTR_GRP_DESC_MODP2048, OAKLEY_ATTR_GRP_TYPE_MODP);
136 INITDHVAL(dh_modp3072, OAKLEY_PRIME_MODP3072,
137 OAKLEY_ATTR_GRP_DESC_MODP3072, OAKLEY_ATTR_GRP_TYPE_MODP);
138 INITDHVAL(dh_modp4096, OAKLEY_PRIME_MODP4096,
139 OAKLEY_ATTR_GRP_DESC_MODP4096, OAKLEY_ATTR_GRP_TYPE_MODP);
140 INITDHVAL(dh_modp6144, OAKLEY_PRIME_MODP6144,
141 OAKLEY_ATTR_GRP_DESC_MODP6144, OAKLEY_ATTR_GRP_TYPE_MODP);
142 INITDHVAL(dh_modp8192, OAKLEY_PRIME_MODP8192,
143 OAKLEY_ATTR_GRP_DESC_MODP8192, OAKLEY_ATTR_GRP_TYPE_MODP);
144
145 return 0;
146 }
147
148 void
149 oakley_dhgrp_free(dhgrp)
150 struct dhgroup *dhgrp;
151 {
152 if (dhgrp->prime)
153 vfree(dhgrp->prime);
154 if (dhgrp->curve_a)
155 vfree(dhgrp->curve_a);
156 if (dhgrp->curve_b)
157 vfree(dhgrp->curve_b);
158 if (dhgrp->order)
159 vfree(dhgrp->order);
160 racoon_free(dhgrp);
161 }
162
163 /*
164 * compute sharing secret of DH
165 * IN: *dh, *pub, *priv, *pub_p
166 * OUT: **gxy
167 */
168 int
169 oakley_dh_compute(dh, pub, priv, pub_p, gxy)
170 const struct dhgroup *dh;
171 vchar_t *pub, *priv, *pub_p, **gxy;
172 {
173 #ifdef ENABLE_STATS
174 struct timeval start, end;
175 #endif
176 if ((*gxy = vmalloc(dh->prime->l)) == NULL) {
177 plog(LLV_ERROR, LOCATION, NULL,
178 "failed to get DH buffer.\n");
179 return -1;
180 }
181
182 #ifdef ENABLE_STATS
183 gettimeofday(&start, NULL);
184 #endif
185 switch (dh->type) {
186 case OAKLEY_ATTR_GRP_TYPE_MODP:
187 if (eay_dh_compute(dh->prime, dh->gen1, pub, priv, pub_p, gxy) < 0) {
188 plog(LLV_ERROR, LOCATION, NULL,
189 "failed to compute dh value.\n");
190 return -1;
191 }
192 break;
193 case OAKLEY_ATTR_GRP_TYPE_ECP:
194 case OAKLEY_ATTR_GRP_TYPE_EC2N:
195 plog(LLV_ERROR, LOCATION, NULL,
196 "dh type %d isn't supported.\n", dh->type);
197 return -1;
198 default:
199 plog(LLV_ERROR, LOCATION, NULL,
200 "invalid dh type %d.\n", dh->type);
201 return -1;
202 }
203
204 #ifdef ENABLE_STATS
205 gettimeofday(&end, NULL);
206 syslog(LOG_NOTICE, "%s(%s%d): %8.6f", __func__,
207 s_attr_isakmp_group(dh->type), dh->prime->l << 3,
208 timedelta(&start, &end));
209 #endif
210
211 plog(LLV_DEBUG, LOCATION, NULL, "compute DH's shared.\n");
212 plogdump(LLV_DEBUG, (*gxy)->v, (*gxy)->l);
213
214 return 0;
215 }
216
217 /*
218 * generate values of DH
219 * IN: *dh
220 * OUT: **pub, **priv
221 */
222 int
223 oakley_dh_generate(dh, pub, priv)
224 const struct dhgroup *dh;
225 vchar_t **pub, **priv;
226 {
227 #ifdef ENABLE_STATS
228 struct timeval start, end;
229 gettimeofday(&start, NULL);
230 #endif
231 switch (dh->type) {
232 case OAKLEY_ATTR_GRP_TYPE_MODP:
233 if (eay_dh_generate(dh->prime, dh->gen1, dh->gen2, pub, priv) < 0) {
234 plog(LLV_ERROR, LOCATION, NULL,
235 "failed to compute dh value.\n");
236 return -1;
237 }
238 break;
239
240 case OAKLEY_ATTR_GRP_TYPE_ECP:
241 case OAKLEY_ATTR_GRP_TYPE_EC2N:
242 plog(LLV_ERROR, LOCATION, NULL,
243 "dh type %d isn't supported.\n", dh->type);
244 return -1;
245 default:
246 plog(LLV_ERROR, LOCATION, NULL,
247 "invalid dh type %d.\n", dh->type);
248 return -1;
249 }
250
251 #ifdef ENABLE_STATS
252 gettimeofday(&end, NULL);
253 syslog(LOG_NOTICE, "%s(%s%d): %8.6f", __func__,
254 s_attr_isakmp_group(dh->type), dh->prime->l << 3,
255 timedelta(&start, &end));
256 #endif
257 plog(LLV_DEBUG, LOCATION, NULL, "compute DH's private.\n");
258 plogdump(LLV_DEBUG, (*priv)->v, (*priv)->l);
259 plog(LLV_DEBUG, LOCATION, NULL, "compute DH's public.\n");
260 plogdump(LLV_DEBUG, (*pub)->v, (*pub)->l);
261
262 return 0;
263 }
264
265 /*
266 * copy pre-defined dhgroup values.
267 */
268 int
269 oakley_setdhgroup(group, dhgrp)
270 int group;
271 struct dhgroup **dhgrp;
272 {
273 struct dhgroup *g;
274
275 *dhgrp = NULL; /* just make sure, initialize */
276
277 g = alg_oakley_dhdef_group(group);
278 if (g == NULL) {
279 plog(LLV_ERROR, LOCATION, NULL,
280 "invalid DH parameter grp=%d.\n", group);
281 return -1;
282 }
283
284 if (!g->type || !g->prime || !g->gen1) {
285 /* unsuported */
286 plog(LLV_ERROR, LOCATION, NULL,
287 "unsupported DH parameters grp=%d.\n", group);
288 return -1;
289 }
290
291 *dhgrp = racoon_calloc(1, sizeof(struct dhgroup));
292 if (*dhgrp == NULL) {
293 plog(LLV_ERROR, LOCATION, NULL,
294 "failed to get DH buffer.\n");
295 return 0;
296 }
297
298 /* set defined dh vlaues */
299 memcpy(*dhgrp, g, sizeof(*g));
300 (*dhgrp)->prime = vdup(g->prime);
301
302 return 0;
303 }
304
305 /*
306 * PRF
307 *
308 * NOTE: we do not support prf with different input/output bitwidth,
309 * so we do not implement RFC2409 Appendix B (DOORAK-MAC example) in
310 * oakley_compute_keymat(). If you add support for such prf function,
311 * modify oakley_compute_keymat() accordingly.
312 */
313 vchar_t *
314 oakley_prf(key, buf, iph1)
315 vchar_t *key, *buf;
316 struct ph1handle *iph1;
317 {
318 vchar_t *res = NULL;
319 int type;
320
321 if (iph1->approval == NULL) {
322 /*
323 * it's before negotiating hash algorithm.
324 * We use md5 as default.
325 */
326 type = OAKLEY_ATTR_HASH_ALG_MD5;
327 } else
328 type = iph1->approval->hashtype;
329
330 res = alg_oakley_hmacdef_one(type, key, buf);
331 if (res == NULL) {
332 plog(LLV_ERROR, LOCATION, NULL,
333 "invalid hmac algorithm %d.\n", type);
334 return NULL;
335 }
336
337 return res;
338 }
339
340 /*
341 * hash
342 */
343 vchar_t *
344 oakley_hash(buf, iph1)
345 vchar_t *buf;
346 struct ph1handle *iph1;
347 {
348 vchar_t *res = NULL;
349 int type;
350
351 if (iph1->approval == NULL) {
352 /*
353 * it's before negotiating hash algorithm.
354 * We use md5 as default.
355 */
356 type = OAKLEY_ATTR_HASH_ALG_MD5;
357 } else
358 type = iph1->approval->hashtype;
359
360 res = alg_oakley_hashdef_one(type, buf);
361 if (res == NULL) {
362 plog(LLV_ERROR, LOCATION, NULL,
363 "invalid hash algorithm %d.\n", type);
364 return NULL;
365 }
366
367 return res;
368 }
369
370 /*
371 * compute KEYMAT
372 * see seciton 5.5 Phase 2 - Quick Mode in isakmp-oakley-05.
373 */
374 int
375 oakley_compute_keymat(iph2, side)
376 struct ph2handle *iph2;
377 int side;
378 {
379 int error = -1;
380
381 /* compute sharing secret of DH when PFS */
382 if (iph2->approval->pfs_group && iph2->dhpub_p) {
383 if (oakley_dh_compute(iph2->pfsgrp, iph2->dhpub,
384 iph2->dhpriv, iph2->dhpub_p, &iph2->dhgxy) < 0)
385 goto end;
386 }
387
388 /* compute keymat */
389 if (oakley_compute_keymat_x(iph2, side, INBOUND_SA) < 0
390 || oakley_compute_keymat_x(iph2, side, OUTBOUND_SA) < 0)
391 goto end;
392
393 plog(LLV_DEBUG, LOCATION, NULL, "KEYMAT computed.\n");
394
395 error = 0;
396
397 end:
398 return error;
399 }
400
401 /*
402 * compute KEYMAT.
403 * KEYMAT = prf(SKEYID_d, protocol | SPI | Ni_b | Nr_b).
404 * If PFS is desired and KE payloads were exchanged,
405 * KEYMAT = prf(SKEYID_d, g(qm)^xy | protocol | SPI | Ni_b | Nr_b)
406 *
407 * NOTE: we do not support prf with different input/output bitwidth,
408 * so we do not implement RFC2409 Appendix B (DOORAK-MAC example).
409 */
410 static int
411 oakley_compute_keymat_x(iph2, side, sa_dir)
412 struct ph2handle *iph2;
413 int side;
414 int sa_dir;
415 {
416 vchar_t *buf = NULL, *res = NULL, *bp;
417 char *p;
418 int len;
419 int error = -1;
420 int pfs = 0;
421 int dupkeymat; /* generate K[1-dupkeymat] */
422 struct saproto *pr;
423 struct satrns *tr;
424 int encklen, authklen, l;
425
426 pfs = ((iph2->approval->pfs_group && iph2->dhgxy) ? 1 : 0);
427
428 len = pfs ? iph2->dhgxy->l : 0;
429 len += (1
430 + sizeof(u_int32_t) /* XXX SPI size */
431 + iph2->nonce->l
432 + iph2->nonce_p->l);
433 buf = vmalloc(len);
434 if (buf == NULL) {
435 plog(LLV_ERROR, LOCATION, NULL,
436 "failed to get keymat buffer.\n");
437 goto end;
438 }
439
440 for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
441 p = buf->v;
442
443 /* if PFS */
444 if (pfs) {
445 memcpy(p, iph2->dhgxy->v, iph2->dhgxy->l);
446 p += iph2->dhgxy->l;
447 }
448
449 p[0] = pr->proto_id;
450 p += 1;
451
452 memcpy(p, (sa_dir == INBOUND_SA ? &pr->spi : &pr->spi_p),
453 sizeof(pr->spi));
454 p += sizeof(pr->spi);
455
456 bp = (side == INITIATOR ? iph2->nonce : iph2->nonce_p);
457 memcpy(p, bp->v, bp->l);
458 p += bp->l;
459
460 bp = (side == INITIATOR ? iph2->nonce_p : iph2->nonce);
461 memcpy(p, bp->v, bp->l);
462 p += bp->l;
463
464 /* compute IV */
465 plog(LLV_DEBUG, LOCATION, NULL, "KEYMAT compute with\n");
466 plogdump(LLV_DEBUG, buf->v, buf->l);
467
468 /* res = K1 */
469 res = oakley_prf(iph2->ph1->skeyid_d, buf, iph2->ph1);
470 if (res == NULL)
471 goto end;
472
473 /* compute key length needed */
474 encklen = authklen = 0;
475 switch (pr->proto_id) {
476 case IPSECDOI_PROTO_IPSEC_ESP:
477 for (tr = pr->head; tr; tr = tr->next) {
478 l = alg_ipsec_encdef_keylen(tr->trns_id,
479 tr->encklen);
480 if (l > encklen)
481 encklen = l;
482
483 l = alg_ipsec_hmacdef_hashlen(tr->authtype);
484 if (l > authklen)
485 authklen = l;
486 }
487 break;
488 case IPSECDOI_PROTO_IPSEC_AH:
489 for (tr = pr->head; tr; tr = tr->next) {
490 l = alg_ipsec_hmacdef_hashlen(tr->trns_id);
491 if (l > authklen)
492 authklen = l;
493 }
494 break;
495 default:
496 break;
497 }
498 plog(LLV_DEBUG, LOCATION, NULL, "encklen=%d authklen=%d\n",
499 encklen, authklen);
500
501 dupkeymat = (encklen + authklen) / 8 / res->l;
502 dupkeymat += 2; /* safety mergin */
503 if (dupkeymat < 3)
504 dupkeymat = 3;
505 plog(LLV_DEBUG, LOCATION, NULL,
506 "generating %d bits of key (dupkeymat=%d)\n",
507 dupkeymat * 8 * res->l, dupkeymat);
508 if (0 < --dupkeymat) {
509 vchar_t *prev = res; /* K(n-1) */
510 vchar_t *seed = NULL; /* seed for Kn */
511 size_t l;
512
513 /*
514 * generating long key (isakmp-oakley-08 5.5)
515 * KEYMAT = K1 | K2 | K3 | ...
516 * where
517 * src = [ g(qm)^xy | ] protocol | SPI | Ni_b | Nr_b
518 * K1 = prf(SKEYID_d, src)
519 * K2 = prf(SKEYID_d, K1 | src)
520 * K3 = prf(SKEYID_d, K2 | src)
521 * Kn = prf(SKEYID_d, K(n-1) | src)
522 */
523 plog(LLV_DEBUG, LOCATION, NULL,
524 "generating K1...K%d for KEYMAT.\n",
525 dupkeymat + 1);
526
527 seed = vmalloc(prev->l + buf->l);
528 if (seed == NULL) {
529 plog(LLV_ERROR, LOCATION, NULL,
530 "failed to get keymat buffer.\n");
531 if (prev && prev != res)
532 vfree(prev);
533 goto end;
534 }
535
536 while (dupkeymat--) {
537 vchar_t *this = NULL; /* Kn */
538
539 memcpy(seed->v, prev->v, prev->l);
540 memcpy(seed->v + prev->l, buf->v, buf->l);
541 this = oakley_prf(iph2->ph1->skeyid_d, seed,
542 iph2->ph1);
543 if (!this) {
544 plog(LLV_ERROR, LOCATION, NULL,
545 "oakley_prf memory overflow\n");
546 if (prev && prev != res)
547 vfree(prev);
548 vfree(this);
549 vfree(seed);
550 goto end;
551 }
552
553 l = res->l;
554 res = vrealloc(res, l + this->l);
555 if (res == NULL) {
556 plog(LLV_ERROR, LOCATION, NULL,
557 "failed to get keymat buffer.\n");
558 if (prev && prev != res)
559 vfree(prev);
560 vfree(this);
561 vfree(seed);
562 goto end;
563 }
564 memcpy(res->v + l, this->v, this->l);
565
566 if (prev && prev != res)
567 vfree(prev);
568 prev = this;
569 this = NULL;
570 }
571
572 if (prev && prev != res)
573 vfree(prev);
574 vfree(seed);
575 }
576
577 plogdump(LLV_DEBUG, res->v, res->l);
578
579 if (sa_dir == INBOUND_SA)
580 pr->keymat = res;
581 else
582 pr->keymat_p = res;
583 res = NULL;
584 }
585
586 error = 0;
587
588 end:
589 if (error) {
590 for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
591 if (pr->keymat) {
592 vfree(pr->keymat);
593 pr->keymat = NULL;
594 }
595 if (pr->keymat_p) {
596 vfree(pr->keymat_p);
597 pr->keymat_p = NULL;
598 }
599 }
600 }
601
602 if (buf != NULL)
603 vfree(buf);
604 if (res)
605 vfree(res);
606
607 return error;
608 }
609
610 #if notyet
611 /*
612 * NOTE: Must terminate by NULL.
613 */
614 vchar_t *
615 oakley_compute_hashx(struct ph1handle *iph1, ...)
616 {
617 vchar_t *buf, *res;
618 vchar_t *s;
619 caddr_t p;
620 int len;
621
622 va_list ap;
623
624 /* get buffer length */
625 va_start(ap, iph1);
626 len = 0;
627 while ((s = va_arg(ap, vchar_t *)) != NULL) {
628 len += s->l
629 }
630 va_end(ap);
631
632 buf = vmalloc(len);
633 if (buf == NULL) {
634 plog(LLV_ERROR, LOCATION, NULL,
635 "failed to get hash buffer\n");
636 return NULL;
637 }
638
639 /* set buffer */
640 va_start(ap, iph1);
641 p = buf->v;
642 while ((s = va_arg(ap, char *)) != NULL) {
643 memcpy(p, s->v, s->l);
644 p += s->l;
645 }
646 va_end(ap);
647
648 plog(LLV_DEBUG, LOCATION, NULL, "HASH with: \n");
649 plogdump(LLV_DEBUG, buf->v, buf->l);
650
651 /* compute HASH */
652 res = oakley_prf(iph1->skeyid_a, buf, iph1);
653 vfree(buf);
654 if (res == NULL)
655 return NULL;
656
657 plog(LLV_DEBUG, LOCATION, NULL, "HASH computed:\n");
658 plogdump(LLV_DEBUG, res->v, res->l);
659
660 return res;
661 }
662 #endif
663
664 /*
665 * compute HASH(3) prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b)
666 * see seciton 5.5 Phase 2 - Quick Mode in isakmp-oakley-05.
667 */
668 vchar_t *
669 oakley_compute_hash3(iph1, msgid, body)
670 struct ph1handle *iph1;
671 u_int32_t msgid;
672 vchar_t *body;
673 {
674 vchar_t *buf = 0, *res = 0;
675 int len;
676 int error = -1;
677
678 /* create buffer */
679 len = 1 + sizeof(u_int32_t) + body->l;
680 buf = vmalloc(len);
681 if (buf == NULL) {
682 plog(LLV_DEBUG, LOCATION, NULL,
683 "failed to get hash buffer\n");
684 goto end;
685 }
686
687 buf->v[0] = 0;
688
689 memcpy(buf->v + 1, (char *)&msgid, sizeof(msgid));
690
691 memcpy(buf->v + 1 + sizeof(u_int32_t), body->v, body->l);
692
693 plog(LLV_DEBUG, LOCATION, NULL, "HASH with: \n");
694 plogdump(LLV_DEBUG, buf->v, buf->l);
695
696 /* compute HASH */
697 res = oakley_prf(iph1->skeyid_a, buf, iph1);
698 if (res == NULL)
699 goto end;
700
701 error = 0;
702
703 plog(LLV_DEBUG, LOCATION, NULL, "HASH computed:\n");
704 plogdump(LLV_DEBUG, res->v, res->l);
705
706 end:
707 if (buf != NULL)
708 vfree(buf);
709 return res;
710 }
711
712 /*
713 * compute HASH type of prf(SKEYID_a, M-ID | buffer)
714 * e.g.
715 * for quick mode HASH(1):
716 * prf(SKEYID_a, M-ID | SA | Ni [ | KE ] [ | IDci | IDcr ])
717 * for quick mode HASH(2):
718 * prf(SKEYID_a, M-ID | Ni_b | SA | Nr [ | KE ] [ | IDci | IDcr ])
719 * for Informational exchange:
720 * prf(SKEYID_a, M-ID | N/D)
721 */
722 vchar_t *
723 oakley_compute_hash1(iph1, msgid, body)
724 struct ph1handle *iph1;
725 u_int32_t msgid;
726 vchar_t *body;
727 {
728 vchar_t *buf = NULL, *res = NULL;
729 char *p;
730 int len;
731 int error = -1;
732
733 /* create buffer */
734 len = sizeof(u_int32_t) + body->l;
735 buf = vmalloc(len);
736 if (buf == NULL) {
737 plog(LLV_DEBUG, LOCATION, NULL,
738 "failed to get hash buffer\n");
739 goto end;
740 }
741
742 p = buf->v;
743
744 memcpy(buf->v, (char *)&msgid, sizeof(msgid));
745 p += sizeof(u_int32_t);
746
747 memcpy(p, body->v, body->l);
748
749 plog(LLV_DEBUG, LOCATION, NULL, "HASH with:\n");
750 plogdump(LLV_DEBUG, buf->v, buf->l);
751
752 /* compute HASH */
753 res = oakley_prf(iph1->skeyid_a, buf, iph1);
754 if (res == NULL)
755 goto end;
756
757 error = 0;
758
759 plog(LLV_DEBUG, LOCATION, NULL, "HASH computed:\n");
760 plogdump(LLV_DEBUG, res->v, res->l);
761
762 end:
763 if (buf != NULL)
764 vfree(buf);
765 return res;
766 }
767
768 /*
769 * compute phase1 HASH
770 * main/aggressive
771 * I-digest = prf(SKEYID, g^i | g^r | CKY-I | CKY-R | SAi_b | ID_i1_b)
772 * R-digest = prf(SKEYID, g^r | g^i | CKY-R | CKY-I | SAi_b | ID_r1_b)
773 * for gssapi, also include all GSS tokens, and call gss_wrap on the result
774 */
775 vchar_t *
776 oakley_ph1hash_common(iph1, sw)
777 struct ph1handle *iph1;
778 int sw;
779 {
780 vchar_t *buf = NULL, *res = NULL, *bp;
781 char *p, *bp2;
782 int len, bl;
783 int error = -1;
784 #ifdef HAVE_GSSAPI
785 vchar_t *gsstokens = NULL;
786 #endif
787
788 /* create buffer */
789 len = iph1->dhpub->l
790 + iph1->dhpub_p->l
791 + sizeof(cookie_t) * 2
792 + iph1->sa->l
793 + (sw == GENERATE ? iph1->id->l : iph1->id_p->l);
794
795 #ifdef HAVE_GSSAPI
796 if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) {
797 if (iph1->gi_i != NULL && iph1->gi_r != NULL) {
798 bp = (sw == GENERATE ? iph1->gi_i : iph1->gi_r);
799 len += bp->l;
800 }
801 if (sw == GENERATE)
802 gssapi_get_itokens(iph1, &gsstokens);
803 else
804 gssapi_get_rtokens(iph1, &gsstokens);
805 if (gsstokens == NULL)
806 return NULL;
807 len += gsstokens->l;
808 }
809 #endif
810
811 buf = vmalloc(len);
812 if (buf == NULL) {
813 plog(LLV_ERROR, LOCATION, NULL,
814 "failed to get hash buffer\n");
815 goto end;
816 }
817
818 p = buf->v;
819
820 bp = (sw == GENERATE ? iph1->dhpub : iph1->dhpub_p);
821 memcpy(p, bp->v, bp->l);
822 p += bp->l;
823
824 bp = (sw == GENERATE ? iph1->dhpub_p : iph1->dhpub);
825 memcpy(p, bp->v, bp->l);
826 p += bp->l;
827
828 if (iph1->side == INITIATOR)
829 bp2 = (sw == GENERATE ?
830 (char *)&iph1->index.i_ck : (char *)&iph1->index.r_ck);
831 else
832 bp2 = (sw == GENERATE ?
833 (char *)&iph1->index.r_ck : (char *)&iph1->index.i_ck);
834 bl = sizeof(cookie_t);
835 memcpy(p, bp2, bl);
836 p += bl;
837
838 if (iph1->side == INITIATOR)
839 bp2 = (sw == GENERATE ?
840 (char *)&iph1->index.r_ck : (char *)&iph1->index.i_ck);
841 else
842 bp2 = (sw == GENERATE ?
843 (char *)&iph1->index.i_ck : (char *)&iph1->index.r_ck);
844 bl = sizeof(cookie_t);
845 memcpy(p, bp2, bl);
846 p += bl;
847
848 bp = iph1->sa;
849 memcpy(p, bp->v, bp->l);
850 p += bp->l;
851
852 bp = (sw == GENERATE ? iph1->id : iph1->id_p);
853 memcpy(p, bp->v, bp->l);
854 p += bp->l;
855
856 #ifdef HAVE_GSSAPI
857 if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) {
858 if (iph1->gi_i != NULL && iph1->gi_r != NULL) {
859 bp = (sw == GENERATE ? iph1->gi_i : iph1->gi_r);
860 memcpy(p, bp->v, bp->l);
861 p += bp->l;
862 }
863 memcpy(p, gsstokens->v, gsstokens->l);
864 p += gsstokens->l;
865 }
866 #endif
867
868 plog(LLV_DEBUG, LOCATION, NULL, "HASH with:\n");
869 plogdump(LLV_DEBUG, buf->v, buf->l);
870
871 /* compute HASH */
872 res = oakley_prf(iph1->skeyid, buf, iph1);
873 if (res == NULL)
874 goto end;
875
876 error = 0;
877
878 plog(LLV_DEBUG, LOCATION, NULL, "HASH computed:\n");
879 plogdump(LLV_DEBUG, res->v, res->l);
880
881 end:
882 if (buf != NULL)
883 vfree(buf);
884 #ifdef HAVE_GSSAPI
885 if (gsstokens != NULL)
886 vfree(gsstokens);
887 #endif
888 return res;
889 }
890
891 /*
892 * compute HASH_I on base mode.
893 * base:psk,rsa
894 * HASH_I = prf(SKEYID, g^xi | CKY-I | CKY-R | SAi_b | IDii_b)
895 * base:sig
896 * HASH_I = prf(hash(Ni_b | Nr_b), g^xi | CKY-I | CKY-R | SAi_b | IDii_b)
897 */
898 vchar_t *
899 oakley_ph1hash_base_i(iph1, sw)
900 struct ph1handle *iph1;
901 int sw;
902 {
903 vchar_t *buf = NULL, *res = NULL, *bp;
904 vchar_t *hashkey = NULL;
905 vchar_t *hash = NULL; /* for signature mode */
906 char *p;
907 int len;
908 int error = -1;
909
910 /* sanity check */
911 if (iph1->etype != ISAKMP_ETYPE_BASE) {
912 plog(LLV_ERROR, LOCATION, NULL,
913 "invalid etype for this hash function\n");
914 return NULL;
915 }
916
917 switch (iph1->approval->authmethod) {
918 case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
919 case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
920 case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
921 if (iph1->skeyid == NULL) {
922 plog(LLV_ERROR, LOCATION, NULL, "no SKEYID found.\n");
923 return NULL;
924 }
925 hashkey = iph1->skeyid;
926 break;
927
928 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
929 case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
930 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
931 /* make hash for seed */
932 len = iph1->nonce->l + iph1->nonce_p->l;
933 buf = vmalloc(len);
934 if (buf == NULL) {
935 plog(LLV_ERROR, LOCATION, NULL,
936 "failed to get hash buffer\n");
937 goto end;
938 }
939 p = buf->v;
940
941 bp = (sw == GENERATE ? iph1->nonce_p : iph1->nonce);
942 memcpy(p, bp->v, bp->l);
943 p += bp->l;
944
945 bp = (sw == GENERATE ? iph1->nonce : iph1->nonce_p);
946 memcpy(p, bp->v, bp->l);
947 p += bp->l;
948
949 hash = oakley_hash(buf, iph1);
950 if (hash == NULL)
951 goto end;
952 vfree(buf);
953 buf = NULL;
954
955 hashkey = hash;
956 break;
957
958 default:
959 plog(LLV_ERROR, LOCATION, NULL,
960 "not supported authentication method %d\n",
961 iph1->approval->authmethod);
962 return NULL;
963
964 }
965
966 len = (sw == GENERATE ? iph1->dhpub->l : iph1->dhpub_p->l)
967 + sizeof(cookie_t) * 2
968 + iph1->sa->l
969 + (sw == GENERATE ? iph1->id->l : iph1->id_p->l);
970 buf = vmalloc(len);
971 if (buf == NULL) {
972 plog(LLV_ERROR, LOCATION, NULL,
973 "failed to get hash buffer\n");
974 goto end;
975 }
976 p = buf->v;
977
978 bp = (sw == GENERATE ? iph1->dhpub : iph1->dhpub_p);
979 memcpy(p, bp->v, bp->l);
980 p += bp->l;
981
982 memcpy(p, &iph1->index.i_ck, sizeof(cookie_t));
983 p += sizeof(cookie_t);
984 memcpy(p, &iph1->index.r_ck, sizeof(cookie_t));
985 p += sizeof(cookie_t);
986
987 memcpy(p, iph1->sa->v, iph1->sa->l);
988 p += iph1->sa->l;
989
990 bp = (sw == GENERATE ? iph1->id : iph1->id_p);
991 memcpy(p, bp->v, bp->l);
992 p += bp->l;
993
994 plog(LLV_DEBUG, LOCATION, NULL, "HASH_I with:\n");
995 plogdump(LLV_DEBUG, buf->v, buf->l);
996
997 /* compute HASH */
998 res = oakley_prf(hashkey, buf, iph1);
999 if (res == NULL)
1000 goto end;
1001
1002 error = 0;
1003
1004 plog(LLV_DEBUG, LOCATION, NULL, "HASH_I computed:\n");
1005 plogdump(LLV_DEBUG, res->v, res->l);
1006
1007 end:
1008 if (hash != NULL)
1009 vfree(hash);
1010 if (buf != NULL)
1011 vfree(buf);
1012 return res;
1013 }
1014
1015 /*
1016 * compute HASH_R on base mode for signature method.
1017 * base:
1018 * HASH_R = prf(hash(Ni_b | Nr_b), g^xi | g^xr | CKY-I | CKY-R | SAi_b | IDii_b)
1019 */
1020 vchar_t *
1021 oakley_ph1hash_base_r(iph1, sw)
1022 struct ph1handle *iph1;
1023 int sw;
1024 {
1025 vchar_t *buf = NULL, *res = NULL, *bp;
1026 vchar_t *hash = NULL;
1027 char *p;
1028 int len;
1029 int error = -1;
1030
1031 /* sanity check */
1032 if (iph1->etype != ISAKMP_ETYPE_BASE) {
1033 plog(LLV_ERROR, LOCATION, NULL,
1034 "invalid etype for this hash function\n");
1035 return NULL;
1036 }
1037 if (iph1->approval->authmethod != OAKLEY_ATTR_AUTH_METHOD_DSSSIG
1038 && iph1->approval->authmethod != OAKLEY_ATTR_AUTH_METHOD_RSASIG) {
1039 plog(LLV_ERROR, LOCATION, NULL,
1040 "not supported authentication method %d\n",
1041 iph1->approval->authmethod);
1042 return NULL;
1043 }
1044
1045 /* make hash for seed */
1046 len = iph1->nonce->l + iph1->nonce_p->l;
1047 buf = vmalloc(len);
1048 if (buf == NULL) {
1049 plog(LLV_ERROR, LOCATION, NULL,
1050 "failed to get hash buffer\n");
1051 goto end;
1052 }
1053 p = buf->v;
1054
1055 bp = (sw == GENERATE ? iph1->nonce_p : iph1->nonce);
1056 memcpy(p, bp->v, bp->l);
1057 p += bp->l;
1058
1059 bp = (sw == GENERATE ? iph1->nonce : iph1->nonce_p);
1060 memcpy(p, bp->v, bp->l);
1061 p += bp->l;
1062
1063 hash = oakley_hash(buf, iph1);
1064 if (hash == NULL)
1065 goto end;
1066 vfree(buf);
1067 buf = NULL;
1068
1069 /* make really hash */
1070 len = (sw == GENERATE ? iph1->dhpub_p->l : iph1->dhpub->l)
1071 + (sw == GENERATE ? iph1->dhpub->l : iph1->dhpub_p->l)
1072 + sizeof(cookie_t) * 2
1073 + iph1->sa->l
1074 + (sw == GENERATE ? iph1->id_p->l : iph1->id->l);
1075 buf = vmalloc(len);
1076 if (buf == NULL) {
1077 plog(LLV_ERROR, LOCATION, NULL,
1078 "failed to get hash buffer\n");
1079 goto end;
1080 }
1081 p = buf->v;
1082
1083
1084 bp = (sw == GENERATE ? iph1->dhpub_p : iph1->dhpub);
1085 memcpy(p, bp->v, bp->l);
1086 p += bp->l;
1087
1088 bp = (sw == GENERATE ? iph1->dhpub : iph1->dhpub_p);
1089 memcpy(p, bp->v, bp->l);
1090 p += bp->l;
1091
1092 memcpy(p, &iph1->index.i_ck, sizeof(cookie_t));
1093 p += sizeof(cookie_t);
1094 memcpy(p, &iph1->index.r_ck, sizeof(cookie_t));
1095 p += sizeof(cookie_t);
1096
1097 memcpy(p, iph1->sa->v, iph1->sa->l);
1098 p += iph1->sa->l;
1099
1100 bp = (sw == GENERATE ? iph1->id_p : iph1->id);
1101 memcpy(p, bp->v, bp->l);
1102 p += bp->l;
1103
1104 plog(LLV_DEBUG, LOCATION, NULL, "HASH with:\n");
1105 plogdump(LLV_DEBUG, buf->v, buf->l);
1106
1107 /* compute HASH */
1108 res = oakley_prf(hash, buf, iph1);
1109 if (res == NULL)
1110 goto end;
1111
1112 error = 0;
1113
1114 plog(LLV_DEBUG, LOCATION, NULL, "HASH computed:\n");
1115 plogdump(LLV_DEBUG, res->v, res->l);
1116
1117 end:
1118 if (buf != NULL)
1119 vfree(buf);
1120 if (hash)
1121 vfree(hash);
1122 return res;
1123 }
1124
1125 /*
1126 * compute each authentication method in phase 1.
1127 * OUT:
1128 * 0: OK
1129 * -1: error
1130 * other: error to be reply with notification.
1131 * the value is notification type.
1132 */
1133 int
1134 oakley_validate_auth(iph1)
1135 struct ph1handle *iph1;
1136 {
1137 vchar_t *my_hash = NULL;
1138 int result;
1139 #ifdef HAVE_GSSAPI
1140 vchar_t *gsshash = NULL;
1141 #endif
1142 #ifdef ENABLE_STATS
1143 struct timeval start, end;
1144 #endif
1145
1146 #ifdef ENABLE_STATS
1147 gettimeofday(&start, NULL);
1148 #endif
1149 switch (iph1->approval->authmethod) {
1150 case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
1151 /* validate HASH */
1152 {
1153 char *r_hash;
1154
1155 if (iph1->id_p == NULL || iph1->pl_hash == NULL) {
1156 plog(LLV_ERROR, LOCATION, iph1->remote,
1157 "few isakmp message received.\n");
1158 return ISAKMP_NTYPE_PAYLOAD_MALFORMED;
1159 }
1160
1161 r_hash = (caddr_t)(iph1->pl_hash + 1);
1162
1163 plog(LLV_DEBUG, LOCATION, NULL, "HASH received:");
1164 plogdump(LLV_DEBUG, r_hash,
1165 ntohs(iph1->pl_hash->h.len) - sizeof(*iph1->pl_hash));
1166
1167 switch (iph1->etype) {
1168 case ISAKMP_ETYPE_IDENT:
1169 case ISAKMP_ETYPE_AGG:
1170 my_hash = oakley_ph1hash_common(iph1, VALIDATE);
1171 break;
1172 case ISAKMP_ETYPE_BASE:
1173 if (iph1->side == INITIATOR)
1174 my_hash = oakley_ph1hash_common(iph1, VALIDATE);
1175 else
1176 my_hash = oakley_ph1hash_base_i(iph1, VALIDATE);
1177 break;
1178 default:
1179 plog(LLV_ERROR, LOCATION, NULL,
1180 "invalid etype %d\n", iph1->etype);
1181 return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE;
1182 }
1183 if (my_hash == NULL)
1184 return ISAKMP_INTERNAL_ERROR;
1185
1186 result = memcmp(my_hash->v, r_hash, my_hash->l);
1187 vfree(my_hash);
1188
1189 if (result) {
1190 plog(LLV_ERROR, LOCATION, NULL, "HASH mismatched\n");
1191 return ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
1192 }
1193
1194 plog(LLV_DEBUG, LOCATION, NULL, "HASH for PSK validated.\n");
1195 }
1196 break;
1197 #ifdef HAVE_SIGNING_C
1198 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
1199 case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
1200 {
1201 int error = 0;
1202
1203 /* validation */
1204 if (iph1->id_p == NULL) {
1205 plog(LLV_ERROR, LOCATION, iph1->remote,
1206 "no ID payload was passed.\n");
1207 return ISAKMP_NTYPE_PAYLOAD_MALFORMED;
1208 }
1209 if (iph1->sig_p == NULL) {
1210 plog(LLV_ERROR, LOCATION, iph1->remote,
1211 "no SIG payload was passed.\n");
1212 return ISAKMP_NTYPE_PAYLOAD_MALFORMED;
1213 }
1214
1215 plog(LLV_DEBUG, LOCATION, NULL, "SIGN passed:\n");
1216 plogdump(LLV_DEBUG, iph1->sig_p->v, iph1->sig_p->l);
1217
1218 /* get peer's cert */
1219 switch (iph1->rmconf->getcert_method) {
1220 case ISAKMP_GETCERT_PAYLOAD:
1221 if (iph1->cert_p == NULL) {
1222 plog(LLV_ERROR, LOCATION, NULL,
1223 "no peer's CERT payload found.\n");
1224 return ISAKMP_INTERNAL_ERROR;
1225 }
1226 break;
1227 case ISAKMP_GETCERT_LOCALFILE:
1228 if (iph1->rmconf->peerscertfile == NULL) {
1229 plog(LLV_ERROR, LOCATION, NULL,
1230 "no peer's CERT file found.\n");
1231 return ISAKMP_INTERNAL_ERROR;
1232 }
1233
1234 /* don't use cached cert */
1235 if (iph1->cert_p != NULL) {
1236 oakley_delcert(iph1->cert_p);
1237 iph1->cert_p = NULL;
1238 }
1239
1240 error = get_cert_fromlocal(iph1, 0);
1241 if (error)
1242 return ISAKMP_INTERNAL_ERROR;
1243 break;
1244 case ISAKMP_GETCERT_DNS:
1245 if (iph1->rmconf->peerscertfile != NULL) {
1246 plog(LLV_ERROR, LOCATION, NULL,
1247 "why peer's CERT file is defined "
1248 "though getcert method is dns ?\n");
1249 return ISAKMP_INTERNAL_ERROR;
1250 }
1251
1252 /* don't use cached cert */
1253 if (iph1->cert_p != NULL) {
1254 oakley_delcert(iph1->cert_p);
1255 iph1->cert_p = NULL;
1256 }
1257
1258 iph1->cert_p = dnssec_getcert(iph1->id_p);
1259 if (iph1->cert_p == NULL) {
1260 plog(LLV_ERROR, LOCATION, NULL,
1261 "no CERT RR found.\n");
1262 return ISAKMP_INTERNAL_ERROR;
1263 }
1264 break;
1265 default:
1266 plog(LLV_ERROR, LOCATION, NULL,
1267 "invalid getcert_mothod: %d\n",
1268 iph1->rmconf->getcert_method);
1269 return ISAKMP_INTERNAL_ERROR;
1270 }
1271
1272 /* compare ID payload and certificate name */
1273 if (iph1->rmconf->verify_cert &&
1274 (error = oakley_check_certid(iph1)) != 0)
1275 return error;
1276
1277 /* verify certificate */
1278 if (iph1->rmconf->verify_cert
1279 && iph1->rmconf->getcert_method == ISAKMP_GETCERT_PAYLOAD) {
1280 switch (iph1->rmconf->certtype) {
1281 case ISAKMP_CERT_X509SIGN:
1282 error = eay_check_x509cert(&iph1->cert_p->cert,
1283 lcconf->pathinfo[LC_PATHTYPE_CERT]);
1284 break;
1285 default:
1286 plog(LLV_ERROR, LOCATION, NULL,
1287 "no supported certtype %d\n",
1288 iph1->rmconf->certtype);
1289 return ISAKMP_INTERNAL_ERROR;
1290 }
1291 if (error != 0) {
1292 plog(LLV_ERROR, LOCATION, NULL,
1293 "the peer's certificate is not verified.\n");
1294 return ISAKMP_NTYPE_INVALID_CERT_AUTHORITY;
1295 }
1296 }
1297
1298 plog(LLV_DEBUG, LOCATION, NULL, "CERT validated\n");
1299
1300 /* compute hash */
1301 switch (iph1->etype) {
1302 case ISAKMP_ETYPE_IDENT:
1303 case ISAKMP_ETYPE_AGG:
1304 my_hash = oakley_ph1hash_common(iph1, VALIDATE);
1305 break;
1306 case ISAKMP_ETYPE_BASE:
1307 if (iph1->side == INITIATOR)
1308 my_hash = oakley_ph1hash_base_r(iph1, VALIDATE);
1309 else
1310 my_hash = oakley_ph1hash_base_i(iph1, VALIDATE);
1311 break;
1312 default:
1313 plog(LLV_ERROR, LOCATION, NULL,
1314 "invalid etype %d\n", iph1->etype);
1315 return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE;
1316 }
1317 if (my_hash == NULL)
1318 return ISAKMP_INTERNAL_ERROR;
1319
1320 /* check signature */
1321 switch (iph1->rmconf->certtype) {
1322 case ISAKMP_CERT_X509SIGN:
1323 case ISAKMP_CERT_DNS:
1324 error = eay_check_x509sign(my_hash,
1325 iph1->sig_p,
1326 &iph1->cert_p->cert);
1327 break;
1328 default:
1329 plog(LLV_ERROR, LOCATION, NULL,
1330 "no supported certtype %d\n",
1331 iph1->rmconf->certtype);
1332 vfree(my_hash);
1333 return ISAKMP_INTERNAL_ERROR;
1334 }
1335
1336 vfree(my_hash);
1337 if (error != 0) {
1338 plog(LLV_ERROR, LOCATION, NULL,
1339 "Invalid SIG.\n");
1340 return ISAKMP_NTYPE_INVALID_SIGNATURE;
1341 }
1342 plog(LLV_DEBUG, LOCATION, NULL, "SIG authenticated\n");
1343 }
1344 break;
1345 #endif
1346 #ifdef HAVE_GSSAPI
1347 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
1348 switch (iph1->etype) {
1349 case ISAKMP_ETYPE_IDENT:
1350 case ISAKMP_ETYPE_AGG:
1351 my_hash = oakley_ph1hash_common(iph1, VALIDATE);
1352 break;
1353 default:
1354 plog(LLV_ERROR, LOCATION, NULL,
1355 "invalid etype %d\n", iph1->etype);
1356 return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE;
1357 }
1358
1359 if (my_hash == NULL) {
1360 if (gssapi_more_tokens(iph1))
1361 return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE;
1362 else
1363 return ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
1364 }
1365
1366 gsshash = gssapi_unwraphash(iph1);
1367 if (gsshash == NULL) {
1368 vfree(my_hash);
1369 return ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
1370 }
1371
1372 result = memcmp(my_hash->v, gsshash->v, my_hash->l);
1373 vfree(my_hash);
1374 vfree(gsshash);
1375
1376 if (result) {
1377 plog(LLV_ERROR, LOCATION, NULL, "HASH mismatched\n");
1378 return ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
1379 }
1380 plog(LLV_DEBUG, LOCATION, NULL, "hash compared OK\n");
1381 break;
1382 #endif
1383 case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
1384 case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
1385 if (iph1->id_p == NULL || iph1->pl_hash == NULL) {
1386 plog(LLV_ERROR, LOCATION, iph1->remote,
1387 "few isakmp message received.\n");
1388 return ISAKMP_NTYPE_PAYLOAD_MALFORMED;
1389 }
1390 plog(LLV_ERROR, LOCATION, iph1->remote,
1391 "not supported authmethod type %s\n",
1392 s_oakley_attr_method(iph1->approval->authmethod));
1393 return ISAKMP_INTERNAL_ERROR;
1394 default:
1395 plog(LLV_ERROR, LOCATION, iph1->remote,
1396 "invalid authmethod %d why ?\n",
1397 iph1->approval->authmethod);
1398 return ISAKMP_INTERNAL_ERROR;
1399 }
1400 #ifdef ENABLE_STATS
1401 gettimeofday(&end, NULL);
1402 syslog(LOG_NOTICE, "%s(%s): %8.6f", __func__,
1403 s_oakley_attr_method(iph1->approval->authmethod),
1404 timedelta(&start, &end));
1405 #endif
1406
1407 return 0;
1408 }
1409
1410 #ifdef HAVE_SIGNING_C
1411 /* get my certificate
1412 * NOTE: include certificate type.
1413 */
1414 int
1415 oakley_getmycert(iph1)
1416 struct ph1handle *iph1;
1417 {
1418 if (iph1->cert)
1419 return 0; /* There is CERT. */
1420
1421 return get_cert_fromlocal(iph1, 1);
1422 }
1423
1424 /*
1425 * get a CERT from local file.
1426 * IN:
1427 * my != 0 my cert.
1428 * my == 0 peer's cert.
1429 */
1430 static int
1431 get_cert_fromlocal(iph1, my)
1432 struct ph1handle *iph1;
1433 int my;
1434 {
1435 char path[MAXPATHLEN];
1436 vchar_t *cert = NULL;
1437 cert_t **certpl;
1438 char *certfile;
1439 int error = -1;
1440
1441 if (my) {
1442 certfile = iph1->rmconf->mycertfile;
1443 certpl = &iph1->cert;
1444 } else {
1445 certfile = iph1->rmconf->peerscertfile;
1446 certpl = &iph1->cert_p;
1447 }
1448 if (!certfile) {
1449 plog(LLV_ERROR, LOCATION, NULL, "no CERT defined.\n");
1450 return 0;
1451 }
1452
1453 switch (iph1->rmconf->certtype) {
1454 case ISAKMP_CERT_X509SIGN:
1455 case ISAKMP_CERT_DNS:
1456 /* make public file name */
1457 getpathname(path, sizeof(path), LC_PATHTYPE_CERT, certfile);
1458 cert = eay_get_x509cert(path);
1459 if (cert) {
1460 char *p = NULL;
1461 p = eay_get_x509text(cert);
1462 plog(LLV_DEBUG, LOCATION, NULL, "%s", p ? p : "\n");
1463 racoon_free(p);
1464 };
1465 break;
1466
1467 default:
1468 plog(LLV_ERROR, LOCATION, NULL,
1469 "not supported certtype %d\n",
1470 iph1->rmconf->certtype);
1471 goto end;
1472 }
1473
1474 if (!cert) {
1475 plog(LLV_ERROR, LOCATION, NULL,
1476 "failed to get %s CERT.\n",
1477 my ? "my" : "peers");
1478 goto end;
1479 }
1480
1481 *certpl = oakley_newcert();
1482 if (!*certpl) {
1483 plog(LLV_ERROR, LOCATION, NULL,
1484 "failed to get cert buffer.\n");
1485 goto end;
1486 }
1487 (*certpl)->pl = vmalloc(cert->l + 1);
1488 if ((*certpl)->pl == NULL) {
1489 plog(LLV_ERROR, LOCATION, NULL,
1490 "failed to get cert buffer\n");
1491 oakley_delcert(*certpl);
1492 *certpl = NULL;
1493 goto end;
1494 }
1495 memcpy((*certpl)->pl->v + 1, cert->v, cert->l);
1496 (*certpl)->pl->v[0] = iph1->rmconf->certtype;
1497 (*certpl)->type = iph1->rmconf->certtype;
1498 (*certpl)->cert.v = (*certpl)->pl->v + 1;
1499 (*certpl)->cert.l = (*certpl)->pl->l - 1;
1500
1501 plog(LLV_DEBUG, LOCATION, NULL, "created CERT payload:\n");
1502 plogdump(LLV_DEBUG, (*certpl)->pl->v, (*certpl)->pl->l);
1503
1504 error = 0;
1505
1506 end:
1507 if (cert != NULL)
1508 vfree(cert);
1509
1510 return error;
1511 }
1512
1513 /* get signature */
1514 int
1515 oakley_getsign(iph1)
1516 struct ph1handle *iph1;
1517 {
1518 char path[MAXPATHLEN];
1519 vchar_t *privkey = NULL;
1520 int error = -1;
1521
1522 switch (iph1->rmconf->certtype) {
1523 case ISAKMP_CERT_X509SIGN:
1524 case ISAKMP_CERT_DNS:
1525 if (iph1->rmconf->myprivfile == NULL) {
1526 plog(LLV_ERROR, LOCATION, NULL, "no cert defined.\n");
1527 goto end;
1528 }
1529
1530 /* make private file name */
1531 getpathname(path, sizeof(path),
1532 LC_PATHTYPE_CERT,
1533 iph1->rmconf->myprivfile);
1534 privkey = eay_get_pkcs1privkey(path);
1535 if (privkey == NULL) {
1536 plog(LLV_ERROR, LOCATION, NULL,
1537 "failed to get private key.\n");
1538 goto end;
1539 }
1540 plog(LLV_DEBUG2, LOCATION, NULL, "private key:\n");
1541 plogdump(LLV_DEBUG2, privkey->v, privkey->l);
1542
1543 iph1->sig = eay_get_x509sign(iph1->hash,
1544 privkey, &iph1->cert->cert);
1545 break;
1546 default:
1547 goto end;
1548 }
1549
1550 if (iph1->sig == NULL) {
1551 plog(LLV_ERROR, LOCATION, NULL, "failed to sign.\n");
1552 goto end;
1553 }
1554
1555 plog(LLV_DEBUG, LOCATION, NULL, "SIGN computed:\n");
1556 plogdump(LLV_DEBUG, iph1->sig->v, iph1->sig->l);
1557
1558 error = 0;
1559
1560 end:
1561 if (privkey != NULL)
1562 vfree(privkey);
1563
1564 return error;
1565 }
1566
1567 /*
1568 * compare certificate name and ID value.
1569 */
1570 static int
1571 oakley_check_certid(iph1)
1572 struct ph1handle *iph1;
1573 {
1574 struct ipsecdoi_id_b *id_b;
1575 vchar_t *name = NULL;
1576 char *altname = NULL;
1577 int idlen, type;
1578 int error;
1579
1580 if (iph1->id_p == NULL || iph1->cert_p == NULL) {
1581 plog(LLV_ERROR, LOCATION, NULL, "no ID nor CERT found.\n");
1582 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
1583 }
1584
1585 id_b = (struct ipsecdoi_id_b *)iph1->id_p->v;
1586 idlen = iph1->id_p->l - sizeof(*id_b);
1587
1588 switch (id_b->type) {
1589 case IPSECDOI_ID_DER_ASN1_DN:
1590 name = eay_get_x509asn1subjectname(&iph1->cert_p->cert);
1591 if (!name) {
1592 plog(LLV_ERROR, LOCATION, NULL,
1593 "failed to get subjectName\n");
1594 return ISAKMP_NTYPE_INVALID_CERTIFICATE;
1595 }
1596 if (idlen != name->l) {
1597 plog(LLV_ERROR, LOCATION, NULL,
1598 "Invalid ID length in phase 1.\n");
1599 vfree(name);
1600 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
1601 }
1602 error = memcmp(id_b + 1, name->v, idlen);
1603 vfree(name);
1604 if (error != 0) {
1605 plog(LLV_ERROR, LOCATION, NULL,
1606 "ID mismatched with subjectAltName.\n");
1607 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
1608 }
1609 return 0;
1610 case IPSECDOI_ID_IPV4_ADDR:
1611 case IPSECDOI_ID_IPV6_ADDR:
1612 {
1613 /*
1614 * converting to binary from string because openssl return
1615 * a string even if object is a binary.
1616 * XXX fix it ! access by ASN.1 directly without.
1617 */
1618 struct addrinfo hints, *res;
1619 caddr_t a = NULL;
1620 int pos;
1621
1622 for (pos = 1; ; pos++) {
1623 if (eay_get_x509subjectaltname(&iph1->cert_p->cert,
1624 &altname, &type, pos) !=0) {
1625 plog(LLV_ERROR, LOCATION, NULL,
1626 "failed to get subjectAltName\n");
1627 return ISAKMP_NTYPE_INVALID_CERTIFICATE;
1628 }
1629
1630 /* it's the end condition of the loop. */
1631 if (!altname) {
1632 plog(LLV_ERROR, LOCATION, NULL,
1633 "no proper subjectAltName.\n");
1634 return ISAKMP_NTYPE_INVALID_CERTIFICATE;
1635 }
1636
1637 if (check_typeofcertname(id_b->type, type) == 0)
1638 break;
1639
1640 /* next name */
1641 racoon_free(altname);
1642 altname = NULL;
1643 }
1644 memset(&hints, 0, sizeof(hints));
1645 hints.ai_family = PF_UNSPEC;
1646 hints.ai_socktype = SOCK_RAW;
1647 hints.ai_flags = AI_NUMERICHOST;
1648 error = getaddrinfo(altname, NULL, &hints, &res);
1649 if (error != 0) {
1650 plog(LLV_ERROR, LOCATION, NULL,
1651 "no proper subjectAltName.\n");
1652 racoon_free(altname);
1653 return ISAKMP_NTYPE_INVALID_CERTIFICATE;
1654 }
1655 switch (res->ai_family) {
1656 case AF_INET:
1657 a = (caddr_t)&((struct sockaddr_in *)res->ai_addr)->sin_addr.s_addr;
1658 break;
1659 #ifdef INET6
1660 case AF_INET6:
1661 a = (caddr_t)&((struct sockaddr_in6 *)res->ai_addr)->sin6_addr.s6_addr;
1662 break;
1663 #endif
1664 default:
1665 plog(LLV_ERROR, LOCATION, NULL,
1666 "family not supported: %d.\n", res->ai_family);
1667 racoon_free(altname);
1668 freeaddrinfo(res);
1669 return ISAKMP_NTYPE_INVALID_CERTIFICATE;
1670 }
1671 error = memcmp(id_b + 1, a, idlen);
1672 freeaddrinfo(res);
1673 vfree(name);
1674 if (error != 0) {
1675 plog(LLV_ERROR, LOCATION, NULL,
1676 "ID mismatched with subjectAltName.\n");
1677 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
1678 }
1679 return 0;
1680 }
1681 case IPSECDOI_ID_FQDN:
1682 case IPSECDOI_ID_USER_FQDN:
1683 {
1684 int pos;
1685
1686 for (pos = 1; ; pos++) {
1687 if (eay_get_x509subjectaltname(&iph1->cert_p->cert,
1688 &altname, &type, pos) != 0){
1689 plog(LLV_ERROR, LOCATION, NULL,
1690 "failed to get subjectAltName\n");
1691 return ISAKMP_NTYPE_INVALID_CERTIFICATE;
1692 }
1693
1694 /* it's the end condition of the loop. */
1695 if (!altname) {
1696 plog(LLV_ERROR, LOCATION, NULL,
1697 "no proper subjectAltName.\n");
1698 return ISAKMP_NTYPE_INVALID_CERTIFICATE;
1699 }
1700
1701 if (check_typeofcertname(id_b->type, type) == 0)
1702 break;
1703
1704 /* next name */
1705 racoon_free(altname);
1706 altname = NULL;
1707 }
1708 if (idlen != strlen(altname)) {
1709 plog(LLV_ERROR, LOCATION, NULL,
1710 "Invalid ID length in phase 1.\n");
1711 racoon_free(altname);
1712 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
1713 }
1714 if (check_typeofcertname(id_b->type, type) != 0) {
1715 plog(LLV_ERROR, LOCATION, NULL,
1716 "ID type mismatched. ID: %s CERT: %s.\n",
1717 s_ipsecdoi_ident(id_b->type),
1718 s_ipsecdoi_ident(type));
1719 racoon_free(altname);
1720 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
1721 }
1722 error = memcmp(id_b + 1, altname, idlen);
1723 if (error) {
1724 plog(LLV_ERROR, LOCATION, NULL, "ID mismatched.\n");
1725 racoon_free(altname);
1726 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
1727 }
1728 racoon_free(altname);
1729 return 0;
1730 }
1731 default:
1732 plog(LLV_ERROR, LOCATION, NULL,
1733 "Inpropper ID type passed: %s.\n",
1734 s_ipsecdoi_ident(id_b->type));
1735 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
1736 }
1737 /*NOTREACHED*/
1738 }
1739
1740 static int
1741 check_typeofcertname(doi, genid)
1742 int doi, genid;
1743 {
1744 switch (doi) {
1745 case IPSECDOI_ID_IPV4_ADDR:
1746 case IPSECDOI_ID_IPV4_ADDR_SUBNET:
1747 case IPSECDOI_ID_IPV6_ADDR:
1748 case IPSECDOI_ID_IPV6_ADDR_SUBNET:
1749 case IPSECDOI_ID_IPV4_ADDR_RANGE:
1750 case IPSECDOI_ID_IPV6_ADDR_RANGE:
1751 if (genid != GENT_IPADD)
1752 return -1;
1753 return 0;
1754 case IPSECDOI_ID_FQDN:
1755 if (genid != GENT_DNS)
1756 return -1;
1757 return 0;
1758 case IPSECDOI_ID_USER_FQDN:
1759 if (genid != GENT_EMAIL)
1760 return -1;
1761 return 0;
1762 case IPSECDOI_ID_DER_ASN1_DN: /* should not be passed to this function*/
1763 case IPSECDOI_ID_DER_ASN1_GN:
1764 case IPSECDOI_ID_KEY_ID:
1765 default:
1766 return -1;
1767 }
1768 /*NOTREACHED*/
1769 }
1770
1771 /*
1772 * save certificate including certificate type.
1773 */
1774 int
1775 oakley_savecert(iph1, gen)
1776 struct ph1handle *iph1;
1777 struct isakmp_gen *gen;
1778 {
1779 cert_t **c;
1780 u_int8_t type;
1781
1782 type = *(u_int8_t *)(gen + 1) & 0xff;
1783
1784 switch (type) {
1785 case ISAKMP_CERT_DNS:
1786 plog(LLV_WARNING, LOCATION, NULL,
1787 "CERT payload is unnecessary in DNSSEC. "
1788 "ignore this CERT payload.\n");
1789 return 0;
1790 case ISAKMP_CERT_PKCS7:
1791 case ISAKMP_CERT_PGP:
1792 case ISAKMP_CERT_X509SIGN:
1793 case ISAKMP_CERT_KERBEROS:
1794 case ISAKMP_CERT_SPKI:
1795 c = &iph1->cert_p;
1796 break;
1797 case ISAKMP_CERT_CRL:
1798 c = &iph1->crl_p;
1799 break;
1800 case ISAKMP_CERT_X509KE:
1801 case ISAKMP_CERT_X509ATTR:
1802 case ISAKMP_CERT_ARL:
1803 plog(LLV_ERROR, LOCATION, NULL,
1804 "No supported such CERT type %d\n", type);
1805 return -1;
1806 default:
1807 plog(LLV_ERROR, LOCATION, NULL,
1808 "Invalid CERT type %d\n", type);
1809 return -1;
1810 }
1811
1812 /* XXX choice the 1th cert, ignore after the cert. */
1813 /* XXX should be processed. */
1814 if (*c) {
1815 plog(LLV_WARNING, LOCATION, NULL,
1816 "ignore 2nd CERT payload.\n");
1817 return 0;
1818 }
1819
1820 *c = save_certbuf(gen);
1821 if (!*c) {
1822 plog(LLV_ERROR, LOCATION, NULL,
1823 "Failed to get CERT buffer.\n");
1824 return -1;
1825 }
1826
1827 switch ((*c)->type) {
1828 case ISAKMP_CERT_DNS:
1829 plog(LLV_WARNING, LOCATION, NULL,
1830 "CERT payload is unnecessary in DNSSEC. "
1831 "ignore it.\n");
1832 return 0;
1833 case ISAKMP_CERT_PKCS7:
1834 case ISAKMP_CERT_PGP:
1835 case ISAKMP_CERT_X509SIGN:
1836 case ISAKMP_CERT_KERBEROS:
1837 case ISAKMP_CERT_SPKI:
1838 plog(LLV_DEBUG, LOCATION, NULL, "CERT saved:\n");
1839 plogdump(LLV_DEBUG, (*c)->cert.v, (*c)->cert.l);
1840 {
1841 char *p = eay_get_x509text(&(*c)->cert);
1842 plog(LLV_DEBUG, LOCATION, NULL, "%s", p ? p : "\n");
1843 racoon_free(p);
1844 }
1845 break;
1846 case ISAKMP_CERT_CRL:
1847 plog(LLV_DEBUG, LOCATION, NULL, "CRL saved:\n");
1848 plogdump(LLV_DEBUG, (*c)->cert.v, (*c)->cert.l);
1849 break;
1850 case ISAKMP_CERT_X509KE:
1851 case ISAKMP_CERT_X509ATTR:
1852 case ISAKMP_CERT_ARL:
1853 default:
1854 /* XXX */
1855 oakley_delcert((*c));
1856 *c = NULL;
1857 return 0;
1858 }
1859
1860 return 0;
1861 }
1862
1863 /*
1864 * save certificate including certificate type.
1865 */
1866 int
1867 oakley_savecr(iph1, gen)
1868 struct ph1handle *iph1;
1869 struct isakmp_gen *gen;
1870 {
1871 cert_t **c;
1872 u_int8_t type;
1873
1874 type = *(u_int8_t *)(gen + 1) & 0xff;
1875
1876 switch (type) {
1877 case ISAKMP_CERT_DNS:
1878 plog(LLV_WARNING, LOCATION, NULL,
1879 "CERT payload is unnecessary in DNSSEC\n");
1880 /*FALLTHRU*/
1881 case ISAKMP_CERT_PKCS7:
1882 case ISAKMP_CERT_PGP:
1883 case ISAKMP_CERT_X509SIGN:
1884 case ISAKMP_CERT_KERBEROS:
1885 case ISAKMP_CERT_SPKI:
1886 c = &iph1->cr_p;
1887 break;
1888 case ISAKMP_CERT_X509KE:
1889 case ISAKMP_CERT_X509ATTR:
1890 case ISAKMP_CERT_ARL:
1891 plog(LLV_ERROR, LOCATION, NULL,
1892 "No supported such CR type %d\n", type);
1893 return -1;
1894 case ISAKMP_CERT_CRL:
1895 default:
1896 plog(LLV_ERROR, LOCATION, NULL,
1897 "Invalid CR type %d\n", type);
1898 return -1;
1899 }
1900
1901 *c = save_certbuf(gen);
1902 if (!*c) {
1903 plog(LLV_ERROR, LOCATION, NULL,
1904 "Failed to get CR buffer.\n");
1905 return -1;
1906 }
1907
1908 plog(LLV_DEBUG, LOCATION, NULL, "CR saved:\n");
1909 plogdump(LLV_DEBUG, (*c)->cert.v, (*c)->cert.l);
1910
1911 return 0;
1912 }
1913
1914 static cert_t *
1915 save_certbuf(gen)
1916 struct isakmp_gen *gen;
1917 {
1918 cert_t *new;
1919
1920 new = oakley_newcert();
1921 if (!new) {
1922 plog(LLV_ERROR, LOCATION, NULL,
1923 "Failed to get CERT buffer.\n");
1924 return NULL;
1925 }
1926
1927 new->pl = vmalloc(ntohs(gen->len) - sizeof(*gen));
1928 if (new->pl == NULL) {
1929 plog(LLV_ERROR, LOCATION, NULL,
1930 "Failed to copy CERT from packet.\n");
1931 oakley_delcert(new);
1932 new = NULL;
1933 return NULL;
1934 }
1935 memcpy(new->pl->v, gen + 1, new->pl->l);
1936 new->type = new->pl->v[0] & 0xff;
1937 new->cert.v = new->pl->v + 1;
1938 new->cert.l = new->pl->l - 1;
1939
1940 return new;
1941 }
1942
1943 /*
1944 * get my CR.
1945 * NOTE: No Certificate Authority field is included to CR payload at the
1946 * moment. Becuase any certificate authority are accepted without any check.
1947 * The section 3.10 in RFC2408 says that this field SHOULD not be included,
1948 * if there is no specific certificate authority requested.
1949 */
1950 vchar_t *
1951 oakley_getcr(iph1)
1952 struct ph1handle *iph1;
1953 {
1954 vchar_t *buf;
1955
1956 buf = vmalloc(1);
1957 if (buf == NULL) {
1958 plog(LLV_ERROR, LOCATION, NULL,
1959 "failed to get cr buffer\n");
1960 return NULL;
1961 }
1962 buf->v[0] = iph1->rmconf->certtype;
1963
1964 plog(LLV_DEBUG, LOCATION, NULL, "create my CR: %s\n",
1965 s_isakmp_certtype(iph1->rmconf->certtype));
1966 if (buf->l > 1)
1967 plogdump(LLV_DEBUG, buf->v, buf->l);
1968
1969 return buf;
1970 }
1971
1972 /*
1973 * check peer's CR.
1974 */
1975 int
1976 oakley_checkcr(iph1)
1977 struct ph1handle *iph1;
1978 {
1979 if (iph1->cr_p == NULL)
1980 return 0;
1981
1982 plog(LLV_DEBUG, LOCATION, iph1->remote,
1983 "peer transmitted CR: %s\n",
1984 s_isakmp_certtype(iph1->cr_p->type));
1985
1986 if (iph1->cr_p->type != iph1->rmconf->certtype) {
1987 plog(LLV_ERROR, LOCATION, iph1->remote,
1988 "such a cert type isn't supported: %d\n",
1989 (char)iph1->cr_p->type);
1990 return -1;
1991 }
1992
1993 return 0;
1994 }
1995
1996 /*
1997 * check to need CR payload.
1998 */
1999 int
2000 oakley_needcr(type)
2001 int type;
2002 {
2003 switch (type) {
2004 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
2005 case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
2006 return 1;
2007 default:
2008 return 0;
2009 }
2010 /*NOTREACHED*/
2011 }
2012 #endif /*HAVE_SIGNING_C*/
2013
2014 /*
2015 * compute SKEYID
2016 * see seciton 5. Exchanges in RFC 2409
2017 * psk: SKEYID = prf(pre-shared-key, Ni_b | Nr_b)
2018 * sig: SKEYID = prf(Ni_b | Nr_b, g^ir)
2019 * enc: SKEYID = prf(H(Ni_b | Nr_b), CKY-I | CKY-R)
2020 */
2021 int
2022 oakley_skeyid(iph1)
2023 struct ph1handle *iph1;
2024 {
2025 vchar_t *buf = NULL, *bp;
2026 char *p;
2027 int len;
2028 int error = -1;
2029
2030 /* SKEYID */
2031 switch(iph1->approval->authmethod) {
2032 case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
2033 /* if we have a preshared key defined, just use it */
2034 if (iph1->rmconf->shared_secret) {
2035
2036 switch (iph1->rmconf->secrettype) {
2037 case SECRETTYPE_KEY:
2038 iph1->authstr = getpsk(iph1->rmconf->shared_secret->v, iph1->rmconf->shared_secret->l-1);
2039 break;
2040 case SECRETTYPE_KEYCHAIN:
2041 iph1->authstr = getpskfromkeychain(iph1->rmconf->shared_secret->v);
2042 break;
2043 case SECRETTYPE_USE:
2044 default:
2045 iph1->authstr = vdup(iph1->rmconf->shared_secret);
2046 }
2047
2048 }
2049 else if (iph1->etype != ISAKMP_ETYPE_IDENT) {
2050 iph1->authstr = getpskbyname(iph1->id_p);
2051 if (iph1->authstr == NULL) {
2052 if (iph1->rmconf->verify_identifier) {
2053 plog(LLV_ERROR, LOCATION, iph1->remote,
2054 "couldn't find the pskey.\n");
2055 goto end;
2056 }
2057 plog(LLV_NOTIFY, LOCATION, iph1->remote,
2058 "couldn't find the proper pskey, "
2059 "try to get one by the peer's address.\n");
2060 }
2061 }
2062 if (iph1->authstr == NULL) {
2063 /*
2064 * If the exchange type is the main mode or if it's
2065 * failed to get the psk by ID, racoon try to get
2066 * the psk by remote IP address.
2067 * It may be nonsense.
2068 */
2069 iph1->authstr = getpskbyaddr(iph1->remote);
2070 if (iph1->authstr == NULL) {
2071 plog(LLV_ERROR, LOCATION, iph1->remote,
2072 "couldn't find the pskey for %s.\n",
2073 saddrwop2str(iph1->remote));
2074 goto end;
2075 }
2076 }
2077 plog(LLV_DEBUG, LOCATION, NULL, "the psk found.\n");
2078 /* should be secret PSK */
2079 plog(LLV_DEBUG2, LOCATION, NULL, "psk: ");
2080 plogdump(LLV_DEBUG2, iph1->authstr->v, iph1->authstr->l);
2081
2082 len = iph1->nonce->l + iph1->nonce_p->l;
2083 buf = vmalloc(len);
2084 if (buf == NULL) {
2085 plog(LLV_ERROR, LOCATION, NULL,
2086 "failed to get skeyid buffer\n");
2087 goto end;
2088 }
2089 p = buf->v;
2090
2091 bp = (iph1->side == INITIATOR ? iph1->nonce : iph1->nonce_p);
2092 plog(LLV_DEBUG, LOCATION, NULL, "nonce 1: ");
2093 plogdump(LLV_DEBUG, bp->v, bp->l);
2094 memcpy(p, bp->v, bp->l);
2095 p += bp->l;
2096
2097 bp = (iph1->side == INITIATOR ? iph1->nonce_p : iph1->nonce);
2098 plog(LLV_DEBUG, LOCATION, NULL, "nonce 2: ");
2099 plogdump(LLV_DEBUG, bp->v, bp->l);
2100 memcpy(p, bp->v, bp->l);
2101 p += bp->l;
2102
2103 iph1->skeyid = oakley_prf(iph1->authstr, buf, iph1);
2104 if (iph1->skeyid == NULL)
2105 goto end;
2106 break;
2107
2108 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
2109 case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
2110 #ifdef HAVE_GSSAPI
2111 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
2112 #endif
2113 len = iph1->nonce->l + iph1->nonce_p->l;
2114 buf = vmalloc(len);
2115 if (buf == NULL) {
2116 plog(LLV_ERROR, LOCATION, NULL,
2117 "failed to get nonce buffer\n");
2118 goto end;
2119 }
2120 p = buf->v;
2121
2122 bp = (iph1->side == INITIATOR ? iph1->nonce : iph1->nonce_p);
2123 plog(LLV_DEBUG, LOCATION, NULL, "nonce1: ");
2124 plogdump(LLV_DEBUG, bp->v, bp->l);
2125 memcpy(p, bp->v, bp->l);
2126 p += bp->l;
2127
2128 bp = (iph1->side == INITIATOR ? iph1->nonce_p : iph1->nonce);
2129 plog(LLV_DEBUG, LOCATION, NULL, "nonce2: ");
2130 plogdump(LLV_DEBUG, bp->v, bp->l);
2131 memcpy(p, bp->v, bp->l);
2132 p += bp->l;
2133
2134 iph1->skeyid = oakley_prf(buf, iph1->dhgxy, iph1);
2135 if (iph1->skeyid == NULL)
2136 goto end;
2137 break;
2138 case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
2139 case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
2140 plog(LLV_WARNING, LOCATION, NULL,
2141 "not supported authentication method %s\n",
2142 s_oakley_attr_method(iph1->approval->authmethod));
2143 goto end;
2144 default:
2145 plog(LLV_ERROR, LOCATION, NULL,
2146 "invalid authentication method %d\n",
2147 iph1->approval->authmethod);
2148 goto end;
2149 }
2150
2151 plog(LLV_DEBUG, LOCATION, NULL, "SKEYID computed:\n");
2152 plogdump(LLV_DEBUG, iph1->skeyid->v, iph1->skeyid->l);
2153
2154 error = 0;
2155
2156 end:
2157 if (buf != NULL)
2158 vfree(buf);
2159 return error;
2160 }
2161
2162 /*
2163 * compute SKEYID_[dae]
2164 * see seciton 5. Exchanges in RFC 2409
2165 * SKEYID_d = prf(SKEYID, g^ir | CKY-I | CKY-R | 0)
2166 * SKEYID_a = prf(SKEYID, SKEYID_d | g^ir | CKY-I | CKY-R | 1)
2167 * SKEYID_e = prf(SKEYID, SKEYID_a | g^ir | CKY-I | CKY-R | 2)
2168 */
2169 int
2170 oakley_skeyid_dae(iph1)
2171 struct ph1handle *iph1;
2172 {
2173 vchar_t *buf = NULL;
2174 char *p;
2175 int len;
2176 int error = -1;
2177
2178 if (iph1->skeyid == NULL) {
2179 plog(LLV_ERROR, LOCATION, NULL, "no SKEYID found.\n");
2180 goto end;
2181 }
2182
2183 /* SKEYID D */
2184 /* SKEYID_d = prf(SKEYID, g^xy | CKY-I | CKY-R | 0) */
2185 len = iph1->dhgxy->l + sizeof(cookie_t) * 2 + 1;
2186 buf = vmalloc(len);
2187 if (buf == NULL) {
2188 plog(LLV_ERROR, LOCATION, NULL,
2189 "failed to get skeyid buffer\n");
2190 goto end;
2191 }
2192 p = buf->v;
2193
2194 memcpy(p, iph1->dhgxy->v, iph1->dhgxy->l);
2195 p += iph1->dhgxy->l;
2196 memcpy(p, (caddr_t)&iph1->index.i_ck, sizeof(cookie_t));
2197 p += sizeof(cookie_t);
2198 memcpy(p, (caddr_t)&iph1->index.r_ck, sizeof(cookie_t));
2199 p += sizeof(cookie_t);
2200 *p = 0;
2201 iph1->skeyid_d = oakley_prf(iph1->skeyid, buf, iph1);
2202 if (iph1->skeyid_d == NULL)
2203 goto end;
2204
2205 vfree(buf);
2206 buf = NULL;
2207
2208 plog(LLV_DEBUG, LOCATION, NULL, "SKEYID_d computed:\n");
2209 plogdump(LLV_DEBUG, iph1->skeyid_d->v, iph1->skeyid->l);
2210
2211 /* SKEYID A */
2212 /* SKEYID_a = prf(SKEYID, SKEYID_d | g^xy | CKY-I | CKY-R | 1) */
2213 len = iph1->skeyid_d->l + iph1->dhgxy->l + sizeof(cookie_t) * 2 + 1;
2214 buf = vmalloc(len);
2215 if (buf == NULL) {
2216 plog(LLV_ERROR, LOCATION, NULL,
2217 "failed to get skeyid buffer\n");
2218 goto end;
2219 }
2220 p = buf->v;
2221 memcpy(p, iph1->skeyid_d->v, iph1->skeyid_d->l);
2222 p += iph1->skeyid_d->l;
2223 memcpy(p, iph1->dhgxy->v, iph1->dhgxy->l);
2224 p += iph1->dhgxy->l;
2225 memcpy(p, (caddr_t)&iph1->index.i_ck, sizeof(cookie_t));
2226 p += sizeof(cookie_t);
2227 memcpy(p, (caddr_t)&iph1->index.r_ck, sizeof(cookie_t));
2228 p += sizeof(cookie_t);
2229 *p = 1;
2230 iph1->skeyid_a = oakley_prf(iph1->skeyid, buf, iph1);
2231 if (iph1->skeyid_a == NULL)
2232 goto end;
2233
2234 vfree(buf);
2235 buf = NULL;
2236
2237 plog(LLV_DEBUG, LOCATION, NULL, "SKEYID_a computed:\n");
2238 plogdump(LLV_DEBUG, iph1->skeyid_a->v, iph1->skeyid_a->l);
2239
2240 /* SKEYID E */
2241 /* SKEYID_e = prf(SKEYID, SKEYID_a | g^xy | CKY-I | CKY-R | 2) */
2242 len = iph1->skeyid_a->l + iph1->dhgxy->l + sizeof(cookie_t) * 2 + 1;
2243 buf = vmalloc(len);
2244 if (buf == NULL) {
2245 plog(LLV_ERROR, LOCATION, NULL,
2246 "failed to get skeyid buffer\n");
2247 goto end;
2248 }
2249 p = buf->v;
2250 memcpy(p, iph1->skeyid_a->v, iph1->skeyid_a->l);
2251 p += iph1->skeyid_a->l;
2252 memcpy(p, iph1->dhgxy->v, iph1->dhgxy->l);
2253 p += iph1->dhgxy->l;
2254 memcpy(p, (caddr_t)&iph1->index.i_ck, sizeof(cookie_t));
2255 p += sizeof(cookie_t);
2256 memcpy(p, (caddr_t)&iph1->index.r_ck, sizeof(cookie_t));
2257 p += sizeof(cookie_t);
2258 *p = 2;
2259 iph1->skeyid_e = oakley_prf(iph1->skeyid, buf, iph1);
2260 if (iph1->skeyid_e == NULL)
2261 goto end;
2262
2263 vfree(buf);
2264 buf = NULL;
2265
2266 plog(LLV_DEBUG, LOCATION, NULL, "SKEYID_e computed:\n");
2267 plogdump(LLV_DEBUG, iph1->skeyid_e->v, iph1->skeyid_e->l);
2268
2269 error = 0;
2270
2271 end:
2272 if (buf != NULL)
2273 vfree(buf);
2274 return error;
2275 }
2276
2277 /*
2278 * compute final encryption key.
2279 * see Appendix B.
2280 */
2281 int
2282 oakley_compute_enckey(iph1)
2283 struct ph1handle *iph1;
2284 {
2285 u_int keylen, prflen;
2286 int error = -1;
2287
2288 /* RFC2409 p39 */
2289 keylen = alg_oakley_encdef_keylen(iph1->approval->enctype,
2290 iph1->approval->encklen);
2291 if (keylen == -1) {
2292 plog(LLV_ERROR, LOCATION, NULL,
2293 "invalid encryption algoritym %d, "
2294 "or invalid key length %d.\n",
2295 iph1->approval->enctype,
2296 iph1->approval->encklen);
2297 goto end;
2298 }
2299 iph1->key = vmalloc(keylen >> 3);
2300 if (iph1->key == NULL) {
2301 plog(LLV_ERROR, LOCATION, NULL,
2302 "failed to get key buffer\n");
2303 goto end;
2304 }
2305
2306 /* set prf length */
2307 prflen = alg_oakley_hashdef_hashlen(iph1->approval->hashtype);
2308 if (prflen == -1) {
2309 plog(LLV_ERROR, LOCATION, NULL,
2310 "invalid hash type %d.\n", iph1->approval->hashtype);
2311 goto end;
2312 }
2313
2314 /* see isakmp-oakley-08 5.3. */
2315 if (iph1->key->l <= iph1->skeyid_e->l) {
2316 /*
2317 * if length(Ka) <= length(SKEYID_e)
2318 * Ka = first length(K) bit of SKEYID_e
2319 */
2320 memcpy(iph1->key->v, iph1->skeyid_e->v, iph1->key->l);
2321 } else {
2322 vchar_t *buf = NULL, *res = NULL;
2323 u_char *p, *ep;
2324 int cplen;
2325 int subkey;
2326
2327 /*
2328 * otherwise,
2329 * Ka = K1 | K2 | K3
2330 * where
2331 * K1 = prf(SKEYID_e, 0)
2332 * K2 = prf(SKEYID_e, K1)
2333 * K3 = prf(SKEYID_e, K2)
2334 */
2335 plog(LLV_DEBUG, LOCATION, NULL,
2336 "len(SKEYID_e) < len(Ka) (%d < %d), "
2337 "generating long key (Ka = K1 | K2 | ...)\n",
2338 iph1->skeyid_e->l, iph1->key->l);
2339
2340 if ((buf = vmalloc(prflen >> 3)) == 0) {
2341 plog(LLV_ERROR, LOCATION, NULL,
2342 "failed to get key buffer\n");
2343 goto end;
2344 }
2345 p = (u_char *)iph1->key->v;
2346 ep = p + iph1->key->l;
2347
2348 subkey = 1;
2349 while (p < ep) {
2350 if (p == (u_char *)iph1->key->v) {
2351 /* just for computing K1 */
2352 buf->v[0] = 0;
2353 buf->l = 1;
2354 }
2355 res = oakley_prf(iph1->skeyid_e, buf, iph1);
2356 if (res == NULL) {
2357 vfree(buf);
2358 goto end;
2359 }
2360 plog(LLV_DEBUG, LOCATION, NULL,
2361 "compute intermediate encryption key K%d\n",
2362 subkey);
2363 plogdump(LLV_DEBUG, buf->v, buf->l);
2364 plogdump(LLV_DEBUG, res->v, res->l);
2365
2366 cplen = (res->l < ep - p) ? res->l : ep - p;
2367 memcpy(p, res->v, cplen);
2368 p += cplen;
2369
2370 buf->l = prflen >> 3; /* to cancel K1 speciality */
2371 if (res->l != buf->l) {
2372 plog(LLV_ERROR, LOCATION, NULL,
2373 "internal error: res->l=%d buf->l=%d\n",
2374 res->l, buf->l);
2375 vfree(res);
2376 vfree(buf);
2377 goto end;
2378 }
2379 memcpy(buf->v, res->v, res->l);
2380 vfree(res);
2381 subkey++;
2382 }
2383
2384 vfree(buf);
2385 }
2386
2387 /*
2388 * don't check any weak key or not.
2389 * draft-ietf-ipsec-ike-01.txt Appendix B.
2390 * draft-ietf-ipsec-ciph-aes-cbc-00.txt Section 2.3.
2391 */
2392 #if 0
2393 /* weakkey check */
2394 if (iph1->approval->enctype > ARRAYLEN(oakley_encdef)
2395 || oakley_encdef[iph1->approval->enctype].weakkey == NULL) {
2396 plog(LLV_ERROR, LOCATION, NULL,
2397 "encryption algoritym %d isn't supported.\n",
2398 iph1->approval->enctype);
2399 goto end;
2400 }
2401 if ((oakley_encdef[iph1->approval->enctype].weakkey)(iph1->key)) {
2402 plog(LLV_ERROR, LOCATION, NULL,
2403 "weakkey was generated.\n");
2404 goto end;
2405 }
2406 #endif
2407
2408 plog(LLV_DEBUG, LOCATION, NULL, "final encryption key computed:\n");
2409 plogdump(LLV_DEBUG, iph1->key->v, iph1->key->l);
2410
2411 error = 0;
2412
2413 end:
2414 return error;
2415 }
2416
2417 /* allocated new buffer for CERT */
2418 cert_t *
2419 oakley_newcert()
2420 {
2421 cert_t *new;
2422
2423 new = racoon_calloc(1, sizeof(*new));
2424 if (new == NULL) {
2425 plog(LLV_ERROR, LOCATION, NULL,
2426 "failed to get cert's buffer\n");
2427 return NULL;
2428 }
2429
2430 new->pl = NULL;
2431
2432 return new;
2433 }
2434
2435 /* delete buffer for CERT */
2436 void
2437 oakley_delcert(cert)
2438 cert_t *cert;
2439 {
2440 if (!cert)
2441 return;
2442 if (cert->pl)
2443 VPTRINIT(cert->pl);
2444 racoon_free(cert);
2445 }
2446
2447 /*
2448 * compute IV and set to ph1handle
2449 * IV = hash(g^xi | g^xr)
2450 * see 4.1 Phase 1 state in draft-ietf-ipsec-ike.
2451 */
2452 int
2453 oakley_newiv(iph1)
2454 struct ph1handle *iph1;
2455 {
2456 struct isakmp_ivm *newivm = NULL;
2457 vchar_t *buf = NULL, *bp;
2458 char *p;
2459 int len;
2460
2461 /* create buffer */
2462 len = iph1->dhpub->l + iph1->dhpub_p->l;
2463 buf = vmalloc(len);
2464 if (buf == NULL) {
2465 plog(LLV_ERROR, LOCATION, NULL,
2466 "failed to get iv buffer\n");
2467 return -1;
2468 }
2469
2470 p = buf->v;
2471
2472 bp = (iph1->side == INITIATOR ? iph1->dhpub : iph1->dhpub_p);
2473 memcpy(p, bp->v, bp->l);
2474 p += bp->l;
2475
2476 bp = (iph1->side == INITIATOR ? iph1->dhpub_p : iph1->dhpub);
2477 memcpy(p, bp->v, bp->l);
2478 p += bp->l;
2479
2480 /* allocate IVm */
2481 newivm = racoon_calloc(1, sizeof(struct isakmp_ivm));
2482 if (newivm == NULL) {
2483 plog(LLV_ERROR, LOCATION, NULL,
2484 "failed to get iv buffer\n");
2485 vfree(buf);
2486 return -1;
2487 }
2488
2489 /* compute IV */
2490 newivm->iv = oakley_hash(buf, iph1);
2491 if (newivm->iv == NULL) {
2492 vfree(buf);
2493 oakley_delivm(newivm);
2494 return -1;
2495 }
2496
2497 /* adjust length of iv */
2498 newivm->iv->l = alg_oakley_encdef_blocklen(iph1->approval->enctype);
2499 if (newivm->iv->l == -1) {
2500 plog(LLV_ERROR, LOCATION, NULL,
2501 "invalid encryption algoriym %d.\n",
2502 iph1->approval->enctype);
2503 vfree(buf);
2504 oakley_delivm(newivm);
2505 return -1;
2506 }
2507
2508 /* create buffer to save iv */
2509 if ((newivm->ive = vdup(newivm->iv)) == NULL) {
2510 plog(LLV_ERROR, LOCATION, NULL,
2511 "vdup (%s)\n", strerror(errno));
2512 vfree(buf);
2513 oakley_delivm(newivm);
2514 return -1;
2515 }
2516
2517 vfree(buf);
2518
2519 plog(LLV_DEBUG, LOCATION, NULL, "IV computed:\n");
2520 plogdump(LLV_DEBUG, newivm->iv->v, newivm->iv->l);
2521
2522 iph1->ivm = newivm;
2523
2524 return 0;
2525 }
2526
2527 /*
2528 * compute IV for the payload after phase 1.
2529 * It's not limited for phase 2.
2530 * if pahse 1 was encrypted.
2531 * IV = hash(last CBC block of Phase 1 | M-ID)
2532 * if phase 1 was not encrypted.
2533 * IV = hash(phase 1 IV | M-ID)
2534 * see 4.2 Phase 2 state in draft-ietf-ipsec-ike.
2535 */
2536 struct isakmp_ivm *
2537 oakley_newiv2(iph1, msgid)
2538 struct ph1handle *iph1;
2539 u_int32_t msgid;
2540 {
2541 struct isakmp_ivm *newivm = NULL;
2542 vchar_t *buf = NULL;
2543 char *p;
2544 int len;
2545 int error = -1;
2546
2547 /* create buffer */
2548 len = iph1->ivm->iv->l + sizeof(msgid_t);
2549 buf = vmalloc(len);
2550 if (buf == NULL) {
2551 plog(LLV_ERROR, LOCATION, NULL,
2552 "failed to get iv buffer\n");
2553 goto end;
2554 }
2555
2556 p = buf->v;
2557
2558 memcpy(p, iph1->ivm->iv->v, iph1->ivm->iv->l);
2559 p += iph1->ivm->iv->l;
2560
2561 memcpy(p, &msgid, sizeof(msgid));
2562
2563 plog(LLV_DEBUG, LOCATION, NULL, "compute IV for phase2\n");
2564 plog(LLV_DEBUG, LOCATION, NULL, "phase1 last IV:\n");
2565 plogdump(LLV_DEBUG, buf->v, buf->l);
2566
2567 /* allocate IVm */
2568 newivm = racoon_calloc(1, sizeof(struct isakmp_ivm));
2569 if (newivm == NULL) {
2570 plog(LLV_ERROR, LOCATION, NULL,
2571 "failed to get iv buffer\n");
2572 goto end;
2573 }
2574
2575 /* compute IV */
2576 if ((newivm->iv = oakley_hash(buf, iph1)) == NULL)
2577 goto end;
2578
2579 /* adjust length of iv */
2580 newivm->iv->l = alg_oakley_encdef_blocklen(iph1->approval->enctype);
2581 if (newivm->iv->l == -1) {
2582 plog(LLV_ERROR, LOCATION, NULL,
2583 "invalid encryption algoriym %d.\n",
2584 iph1->approval->enctype);
2585 goto end;
2586 }
2587
2588 /* create buffer to save new iv */
2589 if ((newivm->ive = vdup(newivm->iv)) == NULL) {
2590 plog(LLV_ERROR, LOCATION, NULL, "vdup (%s)\n", strerror(errno));
2591 goto end;
2592 }
2593
2594 error = 0;
2595
2596 plog(LLV_DEBUG, LOCATION, NULL, "phase2 IV computed:\n");
2597 plogdump(LLV_DEBUG, newivm->iv->v, newivm->iv->l);
2598
2599 end:
2600 if (error && newivm != NULL)
2601 oakley_delivm(newivm);
2602 if (buf != NULL)
2603 vfree(buf);
2604 return newivm;
2605 }
2606
2607 void
2608 oakley_delivm(ivm)
2609 struct isakmp_ivm *ivm;
2610 {
2611 if (ivm == NULL)
2612 return;
2613
2614 if (ivm->iv != NULL)
2615 vfree(ivm->iv);
2616 if (ivm->ive != NULL)
2617 vfree(ivm->ive);
2618 racoon_free(ivm);
2619
2620 return;
2621 }
2622
2623 /*
2624 * decrypt packet.
2625 * save new iv and old iv.
2626 */
2627 vchar_t *
2628 oakley_do_decrypt(iph1, msg, ivdp, ivep)
2629 struct ph1handle *iph1;
2630 vchar_t *msg, *ivdp, *ivep;
2631 {
2632 vchar_t *buf = NULL, *new = NULL;
2633 char *pl;
2634 int len;
2635 u_int8_t padlen;
2636 int blen;
2637 int error = -1;
2638
2639 plog(LLV_DEBUG, LOCATION, NULL, "begin decryption.\n");
2640
2641 blen = alg_oakley_encdef_blocklen(iph1->approval->enctype);
2642 if (blen == -1) {
2643 plog(LLV_ERROR, LOCATION, NULL,
2644 "invalid encryption algoriym %d.\n",
2645 iph1->approval->enctype);
2646 goto end;
2647 }
2648
2649 /* save IV for next, but not sync. */
2650 memset(ivep->v, 0, ivep->l);
2651 memcpy(ivep->v, (caddr_t)&msg->v[msg->l - blen], blen);
2652
2653 plog(LLV_DEBUG, LOCATION, NULL,
2654 "IV was saved for next processing:\n");
2655 plogdump(LLV_DEBUG, ivep->v, ivep->l);
2656
2657 pl = msg->v + sizeof(struct isakmp);
2658
2659 len = msg->l - sizeof(struct isakmp);
2660
2661 /* create buffer */
2662 buf = vmalloc(len);
2663 if (buf == NULL) {
2664 plog(LLV_ERROR, LOCATION, NULL,
2665 "failed to get buffer to decrypt.\n");
2666 goto end;
2667 }
2668 memcpy(buf->v, pl, len);
2669
2670 /* do decrypt */
2671 new = alg_oakley_encdef_decrypt(iph1->approval->enctype,
2672 buf, iph1->key, ivdp);
2673 if (new == NULL) {
2674 plog(LLV_ERROR, LOCATION, NULL,
2675 "decryption %d failed.\n", iph1->approval->enctype);
2676 goto end;
2677 }
2678 plog(LLV_DEBUG, LOCATION, NULL, "with key:\n");
2679 plogdump(LLV_DEBUG, iph1->key->v, iph1->key->l);
2680
2681 vfree(buf);
2682 buf = NULL;
2683 if (new == NULL)
2684 goto end;
2685
2686 plog(LLV_DEBUG, LOCATION, NULL, "decrypted payload by IV:\n");
2687 plogdump(LLV_DEBUG, ivdp->v, ivdp->l);
2688
2689 plog(LLV_DEBUG, LOCATION, NULL,
2690 "decrypted payload, but not trimed.\n");
2691 plogdump(LLV_DEBUG, new->v, new->l);
2692
2693 /* get padding length */
2694 if (lcconf->pad_excltail)
2695 padlen = new->v[new->l - 1] + 1;
2696 else
2697 padlen = new->v[new->l - 1];
2698 plog(LLV_DEBUG, LOCATION, NULL, "padding len=%u\n", padlen);
2699
2700 /* trim padding */
2701 if (lcconf->pad_strict) {
2702 if (padlen > new->l) {
2703 plog(LLV_ERROR, LOCATION, NULL,
2704 "invalied padding len=%u, buflen=%u.\n",
2705 padlen, new->l);
2706 plogdump(LLV_ERROR, new->v, new->l);
2707 goto end;
2708 }
2709 new->l -= padlen;
2710 plog(LLV_DEBUG, LOCATION, NULL, "trimmed padding\n");
2711 } else {
2712 plog(LLV_DEBUG, LOCATION, NULL, "skip to trim padding.\n");
2713 }
2714
2715 /* create new buffer */
2716 len = sizeof(struct isakmp) + new->l;
2717 buf = vmalloc(len);
2718 if (buf == NULL) {
2719 plog(LLV_ERROR, LOCATION, NULL,
2720 "failed to get buffer to decrypt.\n");
2721 goto end;
2722 }
2723 memcpy(buf->v, msg->v, sizeof(struct isakmp));
2724 memcpy(buf->v + sizeof(struct isakmp), new->v, new->l);
2725 ((struct isakmp *)buf->v)->len = htonl(buf->l);
2726
2727 plog(LLV_DEBUG, LOCATION, NULL, "decrypted.\n");
2728 plogdump(LLV_DEBUG, buf->v, buf->l);
2729
2730 #ifdef HAVE_PRINT_ISAKMP_C
2731 isakmp_printpacket(buf, iph1->remote, iph1->local, 1);
2732 #endif
2733
2734 error = 0;
2735
2736 end:
2737 if (error && buf != NULL) {
2738 vfree(buf);
2739 buf = NULL;
2740 }
2741 if (new != NULL)
2742 vfree(new);
2743
2744 return buf;
2745 }
2746
2747 /*
2748 * encrypt packet.
2749 */
2750 vchar_t *
2751 oakley_do_encrypt(iph1, msg, ivep, ivp)
2752 struct ph1handle *iph1;
2753 vchar_t *msg, *ivep, *ivp;
2754 {
2755 vchar_t *buf = 0, *new = 0;
2756 char *pl;
2757 int len;
2758 u_int padlen;
2759 int blen;
2760 int error = -1;
2761
2762 plog(LLV_DEBUG, LOCATION, NULL, "begin encryption.\n");
2763
2764 /* set cbc block length */
2765 blen = alg_oakley_encdef_blocklen(iph1->approval->enctype);
2766 if (blen == -1) {
2767 plog(LLV_ERROR, LOCATION, NULL,
2768 "invalid encryption algoriym %d.\n",
2769 iph1->approval->enctype);
2770 goto end;
2771 }
2772
2773 pl = msg->v + sizeof(struct isakmp);
2774 len = msg->l - sizeof(struct isakmp);
2775
2776 /* add padding */
2777 padlen = oakley_padlen(len, blen);
2778 plog(LLV_DEBUG, LOCATION, NULL, "pad length = %u\n", padlen);
2779
2780 /* create buffer */
2781 buf = vmalloc(len + padlen);
2782 if (buf == NULL) {
2783 plog(LLV_ERROR, LOCATION, NULL,
2784 "failed to get buffer to encrypt.\n");
2785 goto end;
2786 }
2787 if (padlen) {
2788 int i;
2789 char *p = &buf->v[len];
2790 if (lcconf->pad_random) {
2791 for (i = 0; i < padlen; i++)
2792 *p++ = arc4random() & 0xff;
2793 }
2794 }
2795 memcpy(buf->v, pl, len);
2796
2797 /* make pad into tail */
2798 if (lcconf->pad_excltail)
2799 buf->v[len + padlen - 1] = padlen - 1;
2800 else
2801 buf->v[len + padlen - 1] = padlen;
2802
2803 plogdump(LLV_DEBUG, buf->v, buf->l);
2804
2805 /* do encrypt */
2806 new = alg_oakley_encdef_encrypt(iph1->approval->enctype,
2807 buf, iph1->key, ivep);
2808 if (new == NULL) {
2809 plog(LLV_ERROR, LOCATION, NULL,
2810 "encryption %d failed.\n", iph1->approval->enctype);
2811 goto end;
2812 }
2813 plog(LLV_DEBUG, LOCATION, NULL, "with key:\n");
2814 plogdump(LLV_DEBUG, iph1->key->v, iph1->key->l);
2815
2816 vfree(buf);
2817 buf = NULL;
2818 if (new == NULL)
2819 goto end;
2820
2821 plog(LLV_DEBUG, LOCATION, NULL, "encrypted payload by IV:\n");
2822 plogdump(LLV_DEBUG, ivep->v, ivep->l);
2823
2824 /* save IV for next */
2825 memset(ivp->v, 0, ivp->l);
2826 memcpy(ivp->v, (caddr_t)&new->v[new->l - blen], blen);
2827
2828 plog(LLV_DEBUG, LOCATION, NULL, "save IV for next:\n");
2829 plogdump(LLV_DEBUG, ivp->v, ivp->l);
2830
2831 /* create new buffer */
2832 len = sizeof(struct isakmp) + new->l;
2833 buf = vmalloc(len);
2834 if (buf == NULL) {
2835 plog(LLV_ERROR, LOCATION, NULL,
2836 "failed to get buffer to encrypt.\n");
2837 goto end;
2838 }
2839 memcpy(buf->v, msg->v, sizeof(struct isakmp));
2840 memcpy(buf->v + sizeof(struct isakmp), new->v, new->l);
2841 ((struct isakmp *)buf->v)->len = htonl(buf->l);
2842
2843 error = 0;
2844
2845 plog(LLV_DEBUG, LOCATION, NULL, "encrypted.\n");
2846
2847 end:
2848 if (error && buf != NULL) {
2849 vfree(buf);
2850 buf = NULL;
2851 }
2852 if (new != NULL)
2853 vfree(new);
2854
2855 return buf;
2856 }
2857
2858 /* culculate padding length */
2859 static int
2860 oakley_padlen(len, base)
2861 int len, base;
2862 {
2863 int padlen;
2864
2865 padlen = base - len % base;
2866
2867 if (lcconf->pad_randomlen)
2868 padlen += ((arc4random() % (lcconf->pad_maxsize + 1) + 1) *
2869 base);
2870
2871 return padlen;
2872 }
2873