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