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