xref: /netbsd-src/crypto/dist/ipsec-tools/src/racoon/oakley.c (revision d909946ca08dceb44d7d0f22ec9488679695d976)
1 /*	$NetBSD: oakley.c,v 1.24 2012/08/29 11:34:37 tteras 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 	int no_verify_needed = -1;
1292 #ifdef HAVE_GSSAPI
1293 	vchar_t *gsshash = NULL;
1294 #endif
1295 #ifdef ENABLE_STATS
1296 	struct timeval start, end;
1297 #endif
1298 
1299 #ifdef ENABLE_STATS
1300 	gettimeofday(&start, NULL);
1301 #endif
1302 
1303 	switch (iph1->approval->authmethod) {
1304 	case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
1305 #ifdef ENABLE_HYBRID
1306 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
1307 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
1308 #endif
1309 		/* validate HASH */
1310 	    {
1311 		char *r_hash;
1312 
1313 		if (iph1->id_p == NULL || iph1->pl_hash == NULL) {
1314 			plog(LLV_ERROR, LOCATION, iph1->remote,
1315 				"few isakmp message received.\n");
1316 			return ISAKMP_NTYPE_PAYLOAD_MALFORMED;
1317 		}
1318 #ifdef ENABLE_HYBRID
1319 		if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I &&
1320 		    ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0))
1321 		{
1322 			plog(LLV_ERROR, LOCATION, NULL, "No SIG was passed, "
1323 			    "hybrid auth is enabled, "
1324 			    "but peer is no Xauth compliant\n");
1325 			return ISAKMP_NTYPE_SITUATION_NOT_SUPPORTED;
1326 			break;
1327 		}
1328 #endif
1329 		r_hash = (caddr_t)(iph1->pl_hash + 1);
1330 
1331 		plog(LLV_DEBUG, LOCATION, NULL, "HASH received:\n");
1332 		plogdump(LLV_DEBUG, r_hash,
1333 			ntohs(iph1->pl_hash->h.len) - sizeof(*iph1->pl_hash));
1334 
1335 		switch (iph1->etype) {
1336 		case ISAKMP_ETYPE_IDENT:
1337 		case ISAKMP_ETYPE_AGG:
1338 			my_hash = oakley_ph1hash_common(iph1, VALIDATE);
1339 			break;
1340 		case ISAKMP_ETYPE_BASE:
1341 			if (iph1->side == INITIATOR)
1342 				my_hash = oakley_ph1hash_common(iph1, VALIDATE);
1343 			else
1344 				my_hash = oakley_ph1hash_base_i(iph1, VALIDATE);
1345 			break;
1346 		default:
1347 			plog(LLV_ERROR, LOCATION, NULL,
1348 				"invalid etype %d\n", iph1->etype);
1349 			return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE;
1350 		}
1351 		if (my_hash == NULL)
1352 			return ISAKMP_INTERNAL_ERROR;
1353 
1354 		result = memcmp(my_hash->v, r_hash, my_hash->l);
1355 		vfree(my_hash);
1356 
1357 		if (result) {
1358 			plog(LLV_ERROR, LOCATION, NULL, "HASH mismatched\n");
1359 			return ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
1360 		}
1361 
1362 		plog(LLV_DEBUG, LOCATION, NULL, "HASH for PSK validated.\n");
1363 	    }
1364 		break;
1365 #ifdef ENABLE_HYBRID
1366 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
1367 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
1368 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
1369 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
1370 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
1371 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
1372 		no_verify_needed = 0;
1373 #endif
1374 	case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
1375 	case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
1376 	    {
1377 		int error = 0;
1378 		int certtype;
1379 
1380 		/* validation */
1381 		if (iph1->id_p == NULL) {
1382 			plog(LLV_ERROR, LOCATION, iph1->remote,
1383 				"no ID payload was passed.\n");
1384 			return ISAKMP_NTYPE_PAYLOAD_MALFORMED;
1385 		}
1386 		if (iph1->sig_p == NULL) {
1387 			plog(LLV_ERROR, LOCATION, iph1->remote,
1388 				"no SIG payload was passed.\n");
1389 			return ISAKMP_NTYPE_PAYLOAD_MALFORMED;
1390 		}
1391 
1392 		plog(LLV_DEBUG, LOCATION, NULL, "SIGN passed:\n");
1393 		plogdump(LLV_DEBUG, iph1->sig_p->v, iph1->sig_p->l);
1394 
1395 		/* get peer's cert */
1396 		certtype = oakley_get_certtype(iph1->rmconf->peerscert);
1397 		switch (certtype) {
1398 		case ISAKMP_CERT_NONE:
1399 			/* expect to receive one from peer */
1400 			if (iph1->cert_p == NULL) {
1401 				plog(LLV_ERROR, LOCATION, NULL,
1402 				     "no peer's CERT payload found.\n");
1403 				return ISAKMP_INTERNAL_ERROR;
1404 			}
1405 			/* verify the cert if needed */
1406 			if (!iph1->rmconf->verify_cert)
1407 				break;
1408 
1409 			switch (oakley_get_certtype(iph1->cert_p)) {
1410 			case ISAKMP_CERT_X509SIGN: {
1411 				char path[MAXPATHLEN];
1412 				char *ca;
1413 
1414 				if (iph1->rmconf->cacertfile != NULL) {
1415 					getpathname(path, sizeof(path),
1416 						    LC_PATHTYPE_CERT,
1417 						    iph1->rmconf->cacertfile);
1418 					ca = path;
1419 				} else {
1420 					ca = NULL;
1421 				}
1422 
1423 				error = eay_check_x509cert(
1424 					iph1->cert_p,
1425 					lcconf->pathinfo[LC_PATHTYPE_CERT],
1426 					ca, 0);
1427 				break;
1428 				}
1429 			default:
1430 				plog(LLV_ERROR, LOCATION, NULL,
1431 					"peers_cert certtype %d was not expected\n",
1432 					certtype);
1433 				return ISAKMP_INTERNAL_ERROR;
1434 			}
1435 
1436 			if (error != 0) {
1437 				plog(LLV_ERROR, LOCATION, iph1->remote,
1438 				     "the peer's certificate is not verified.\n");
1439 				return ISAKMP_NTYPE_INVALID_CERT_AUTHORITY;
1440 			}
1441 			break;
1442 		case ISAKMP_CERT_X509SIGN:
1443 			if (iph1->rmconf->peerscert == NULL) {
1444 				plog(LLV_ERROR, LOCATION, NULL,
1445 				     "no peer's CERT file found.\n");
1446 				return ISAKMP_INTERNAL_ERROR;
1447 			}
1448 			/* don't use received cert */
1449 			if (iph1->cert_p != NULL) {
1450 				vfree(iph1->cert_p);
1451 				iph1->cert_p = NULL;
1452 			}
1453 			/* copy from remoteconf instead */
1454 			iph1->cert_p = vdup(iph1->rmconf->peerscert);
1455 			break;
1456 		case ISAKMP_CERT_PLAINRSA:
1457 			if (get_plainrsa_fromlocal(iph1, 0))
1458 				return ISAKMP_INTERNAL_ERROR;
1459 			/* suppress CERT validation warning, unless hybrid mode in use */
1460 			if (no_verify_needed == -1)
1461 				no_verify_needed = 1;
1462 			break;
1463 		case ISAKMP_CERT_DNS:
1464 			/* don't use received cert */
1465 			if (iph1->cert_p != NULL) {
1466 				vfree(iph1->cert_p);
1467 				iph1->cert_p = NULL;
1468 			}
1469 
1470 			iph1->cert_p = dnssec_getcert(iph1->id_p);
1471 			if (iph1->cert_p == NULL) {
1472 				plog(LLV_ERROR, LOCATION, NULL,
1473 				     "no CERT RR found.\n");
1474 				return ISAKMP_INTERNAL_ERROR;
1475 			}
1476 			break;
1477 		default:
1478 			plog(LLV_ERROR, LOCATION, NULL,
1479 			     "invalid certificate type: %d\n",
1480 			     oakley_get_certtype(iph1->rmconf->peerscert));
1481 			return ISAKMP_INTERNAL_ERROR;
1482 		}
1483 
1484 		/* compare ID payload and certificate name */
1485 		if ((error = oakley_check_certid(iph1)) != 0)
1486 			return error;
1487 
1488 		/* Generate a warning unless verify_cert */
1489 		if (iph1->rmconf->verify_cert) {
1490 			plog(LLV_DEBUG, LOCATION, iph1->remote,
1491 			     "CERT validated\n");
1492 		} else if (no_verify_needed != 1) {
1493 			plog(LLV_WARNING, LOCATION, iph1->remote,
1494 			     "CERT validation disabled by configuration\n");
1495 		}
1496 
1497 		/* compute hash */
1498 		switch (iph1->etype) {
1499 		case ISAKMP_ETYPE_IDENT:
1500 		case ISAKMP_ETYPE_AGG:
1501 			my_hash = oakley_ph1hash_common(iph1, VALIDATE);
1502 			break;
1503 		case ISAKMP_ETYPE_BASE:
1504 			if (iph1->side == INITIATOR)
1505 				my_hash = oakley_ph1hash_base_r(iph1, VALIDATE);
1506 			else
1507 				my_hash = oakley_ph1hash_base_i(iph1, VALIDATE);
1508 			break;
1509 		default:
1510 			plog(LLV_ERROR, LOCATION, NULL,
1511 				"invalid etype %d\n", iph1->etype);
1512 			return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE;
1513 		}
1514 		if (my_hash == NULL)
1515 			return ISAKMP_INTERNAL_ERROR;
1516 
1517 		/* check signature */
1518 		certtype = oakley_get_certtype(iph1->cert_p);
1519 		if (certtype == ISAKMP_CERT_NONE)
1520 			certtype = oakley_get_certtype(iph1->rmconf->peerscert);
1521 		switch (certtype) {
1522 		case ISAKMP_CERT_X509SIGN:
1523 		case ISAKMP_CERT_DNS:
1524 			error = eay_check_x509sign(my_hash,
1525 						   iph1->sig_p,
1526 						   iph1->cert_p);
1527 			break;
1528 		case ISAKMP_CERT_PLAINRSA:
1529 			iph1->rsa_p = rsa_try_check_rsasign(my_hash,
1530 					iph1->sig_p, iph1->rsa_candidates);
1531 			error = iph1->rsa_p ? 0 : -1;
1532 			genlist_free(iph1->rsa_candidates, NULL);
1533 			iph1->rsa_candidates = NULL;
1534 			break;
1535 		default:
1536 			plog(LLV_ERROR, LOCATION, NULL,
1537 			     "cannot check signature for certtype %d\n",
1538 			     certtype);
1539 			vfree(my_hash);
1540 			return ISAKMP_INTERNAL_ERROR;
1541 		}
1542 
1543 		vfree(my_hash);
1544 		if (error != 0) {
1545 			plog(LLV_ERROR, LOCATION, NULL,
1546 				"Invalid SIG.\n");
1547 			return ISAKMP_NTYPE_INVALID_SIGNATURE;
1548 		}
1549 		plog(LLV_DEBUG, LOCATION, NULL, "SIG authenticated\n");
1550 	    }
1551 		break;
1552 #ifdef ENABLE_HYBRID
1553 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
1554 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
1555 	    {
1556 		if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
1557 			plog(LLV_ERROR, LOCATION, NULL, "No SIG was passed, "
1558 			    "hybrid auth is enabled, "
1559 			    "but peer is no Xauth compliant\n");
1560 			return ISAKMP_NTYPE_SITUATION_NOT_SUPPORTED;
1561 			break;
1562 		}
1563 		plog(LLV_INFO, LOCATION, NULL, "No SIG was passed, "
1564 		    "but hybrid auth is enabled\n");
1565 
1566 		return 0;
1567 		break;
1568 	    }
1569 #endif
1570 #ifdef HAVE_GSSAPI
1571 	case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
1572 		/* check if we're not into XAUTH_PSKEY_I instead */
1573 #ifdef ENABLE_HYBRID
1574 		if (iph1->rmconf->xauth)
1575 			break;
1576 #endif
1577 		switch (iph1->etype) {
1578 		case ISAKMP_ETYPE_IDENT:
1579 		case ISAKMP_ETYPE_AGG:
1580 			my_hash = oakley_ph1hash_common(iph1, VALIDATE);
1581 			break;
1582 		default:
1583 			plog(LLV_ERROR, LOCATION, NULL,
1584 				"invalid etype %d\n", iph1->etype);
1585 			return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE;
1586 		}
1587 
1588 		if (my_hash == NULL) {
1589 			if (gssapi_more_tokens(iph1))
1590 				return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE;
1591 			else
1592 				return ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
1593 		}
1594 
1595 		gsshash = gssapi_unwraphash(iph1);
1596 		if (gsshash == NULL) {
1597 			vfree(my_hash);
1598 			return ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
1599 		}
1600 
1601 		result = memcmp(my_hash->v, gsshash->v, my_hash->l);
1602 		vfree(my_hash);
1603 		vfree(gsshash);
1604 
1605 		if (result) {
1606 			plog(LLV_ERROR, LOCATION, NULL, "HASH mismatched\n");
1607 			return ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
1608 		}
1609 		plog(LLV_DEBUG, LOCATION, NULL, "hash compared OK\n");
1610 		break;
1611 #endif
1612 	case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
1613 	case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
1614 #ifdef ENABLE_HYBRID
1615 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
1616 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
1617 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
1618 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
1619 #endif
1620 		if (iph1->id_p == NULL || iph1->pl_hash == NULL) {
1621 			plog(LLV_ERROR, LOCATION, iph1->remote,
1622 				"few isakmp message received.\n");
1623 			return ISAKMP_NTYPE_PAYLOAD_MALFORMED;
1624 		}
1625 		plog(LLV_ERROR, LOCATION, iph1->remote,
1626 			"not supported authmethod type %s\n",
1627 			s_oakley_attr_method(iph1->approval->authmethod));
1628 		return ISAKMP_INTERNAL_ERROR;
1629 	default:
1630 		plog(LLV_ERROR, LOCATION, iph1->remote,
1631 			"invalid authmethod %d why ?\n",
1632 			iph1->approval->authmethod);
1633 		return ISAKMP_INTERNAL_ERROR;
1634 	}
1635 #ifdef ENABLE_STATS
1636 	gettimeofday(&end, NULL);
1637 	syslog(LOG_NOTICE, "%s(%s): %8.6f", __func__,
1638 		s_oakley_attr_method(iph1->approval->authmethod),
1639 		timedelta(&start, &end));
1640 #endif
1641 
1642 	return 0;
1643 }
1644 
1645 /* get my certificate
1646  * NOTE: include certificate type.
1647  */
1648 int
1649 oakley_getmycert(iph1)
1650 	struct ph1handle *iph1;
1651 {
1652 	switch (oakley_get_certtype(iph1->rmconf->mycert)) {
1653 	case ISAKMP_CERT_X509SIGN:
1654 		if (iph1->cert)
1655 			return 0;
1656 		iph1->cert = vdup(iph1->rmconf->mycert);
1657 		break;
1658 	case ISAKMP_CERT_PLAINRSA:
1659 		if (iph1->rsa)
1660 			return 0;
1661 		return get_plainrsa_fromlocal(iph1, 1);
1662 	default:
1663 		plog(LLV_ERROR, LOCATION, NULL,
1664 		     "Unknown certtype #%d\n",
1665 		     oakley_get_certtype(iph1->rmconf->mycert));
1666 		return -1;
1667 	}
1668 
1669 	return 0;
1670 }
1671 
1672 static int
1673 get_plainrsa_fromlocal(iph1, my)
1674 	struct ph1handle *iph1;
1675 	int my;
1676 {
1677 	char path[MAXPATHLEN];
1678 	vchar_t *cert = NULL;
1679 	char *certfile;
1680 	int error = -1;
1681 
1682 	iph1->rsa_candidates = rsa_lookup_keys(iph1, my);
1683 	if (!iph1->rsa_candidates ||
1684 	    rsa_list_count(iph1->rsa_candidates) == 0) {
1685 		plog(LLV_ERROR, LOCATION, NULL,
1686 			"%s RSA key not found for %s\n",
1687 			my ? "Private" : "Public",
1688 			saddr2str_fromto("%s <-> %s",
1689 			iph1->local, iph1->remote));
1690 		goto end;
1691 	}
1692 
1693 	if (my && rsa_list_count(iph1->rsa_candidates) > 1) {
1694 		plog(LLV_WARNING, LOCATION, NULL,
1695 			"More than one (=%lu) private "
1696 			"PlainRSA key found for %s\n",
1697 			rsa_list_count(iph1->rsa_candidates),
1698 			saddr2str_fromto("%s <-> %s",
1699 			iph1->local, iph1->remote));
1700 		plog(LLV_WARNING, LOCATION, NULL,
1701 			"This may have unpredictable results, "
1702 			"i.e. wrong key could be used!\n");
1703 		plog(LLV_WARNING, LOCATION, NULL,
1704 			"Consider using only one single private "
1705 			"key for all peers...\n");
1706 	}
1707 	if (my) {
1708 		iph1->rsa = ((struct rsa_key *)
1709 		    genlist_next(iph1->rsa_candidates, NULL))->rsa;
1710 
1711 		genlist_free(iph1->rsa_candidates, NULL);
1712 		iph1->rsa_candidates = NULL;
1713 
1714 		if (iph1->rsa == NULL)
1715 			goto end;
1716 	}
1717 
1718 	error = 0;
1719 
1720 end:
1721 	return error;
1722 }
1723 
1724 /* get signature */
1725 int
1726 oakley_getsign(iph1)
1727 	struct ph1handle *iph1;
1728 {
1729 	char path[MAXPATHLEN];
1730 	vchar_t *privkey = NULL;
1731 	int error = -1;
1732 
1733 	switch (oakley_get_certtype(iph1->rmconf->mycert)) {
1734 	case ISAKMP_CERT_X509SIGN:
1735 	case ISAKMP_CERT_DNS:
1736 		if (iph1->rmconf->myprivfile == NULL) {
1737 			plog(LLV_ERROR, LOCATION, NULL, "no cert defined.\n");
1738 			goto end;
1739 		}
1740 
1741 		/* make private file name */
1742 		getpathname(path, sizeof(path),
1743 			LC_PATHTYPE_CERT,
1744 			iph1->rmconf->myprivfile);
1745 		privkey = privsep_eay_get_pkcs1privkey(path);
1746 		if (privkey == NULL) {
1747 			plog(LLV_ERROR, LOCATION, NULL,
1748 				"failed to get private key.\n");
1749 			goto end;
1750 		}
1751 		plog(LLV_DEBUG2, LOCATION, NULL, "private key:\n");
1752 		plogdump(LLV_DEBUG2, privkey->v, privkey->l);
1753 		iph1->sig = eay_get_x509sign(iph1->hash, privkey);
1754 		break;
1755 	case ISAKMP_CERT_PLAINRSA:
1756 		iph1->sig = eay_get_rsasign(iph1->hash, iph1->rsa);
1757 		break;
1758 	default:
1759 		plog(LLV_ERROR, LOCATION, NULL,
1760 		     "Unknown certtype #%d\n",
1761 		     oakley_get_certtype(iph1->rmconf->mycert));
1762 		goto end;
1763 	}
1764 
1765 	if (iph1->sig == NULL) {
1766 		plog(LLV_ERROR, LOCATION, NULL, "failed to sign.\n");
1767 		goto end;
1768 	}
1769 
1770 	plog(LLV_DEBUG, LOCATION, NULL, "SIGN computed:\n");
1771 	plogdump(LLV_DEBUG, iph1->sig->v, iph1->sig->l);
1772 
1773 	error = 0;
1774 
1775 end:
1776 	if (privkey != NULL)
1777 		vfree(privkey);
1778 
1779 	return error;
1780 }
1781 
1782 /*
1783  * compare certificate name and ID value.
1784  */
1785 static int
1786 oakley_check_certid(iph1)
1787 	struct ph1handle *iph1;
1788 {
1789 	struct ipsecdoi_id_b *id_b;
1790 	vchar_t *name = NULL;
1791 	char *altname = NULL;
1792 	int idlen, type;
1793 	int error;
1794 
1795 	if (iph1->rmconf == NULL || iph1->rmconf->verify_cert == FALSE)
1796 		return 0;
1797 
1798 	if (iph1->id_p == NULL || iph1->cert_p == NULL) {
1799 		plog(LLV_ERROR, LOCATION, iph1->remote, "no ID nor CERT found.\n");
1800 		return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
1801 	}
1802 
1803 	id_b = (struct ipsecdoi_id_b *)iph1->id_p->v;
1804 	idlen = iph1->id_p->l - sizeof(*id_b);
1805 
1806 	switch (id_b->type) {
1807 	case IPSECDOI_ID_DER_ASN1_DN:
1808 		name = eay_get_x509asn1subjectname(iph1->cert_p);
1809 		if (!name) {
1810 			plog(LLV_ERROR, LOCATION, iph1->remote,
1811 				"failed to get subjectName\n");
1812 			return ISAKMP_NTYPE_INVALID_CERTIFICATE;
1813 		}
1814 		if (idlen != name->l) {
1815 			plog(LLV_ERROR, LOCATION, iph1->remote,
1816 				"Invalid ID length in phase 1.\n");
1817 			vfree(name);
1818 			return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
1819 		}
1820 		error = memcmp(id_b + 1, name->v, idlen);
1821 		if (error != 0) {
1822 			plog(LLV_ERROR, LOCATION, iph1->remote,
1823 				"ID mismatched with ASN1 SubjectName.\n");
1824 			plogdump(LLV_DEBUG, id_b + 1, idlen);
1825 			plogdump(LLV_DEBUG, name->v, idlen);
1826 			if (iph1->rmconf->verify_identifier) {
1827 				vfree(name);
1828 				return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
1829 			}
1830 		}
1831 		vfree(name);
1832 		return 0;
1833 	case IPSECDOI_ID_IPV4_ADDR:
1834 	case IPSECDOI_ID_IPV6_ADDR:
1835 	{
1836 		/*
1837 		 * converting to binary from string because openssl return
1838 		 * a string even if object is a binary.
1839 		 * XXX fix it !  access by ASN.1 directly without.
1840 		 */
1841 		struct addrinfo hints, *res;
1842 		caddr_t a = NULL;
1843 		int pos;
1844 
1845 		for (pos = 1; ; pos++) {
1846 			if (eay_get_x509subjectaltname(iph1->cert_p,
1847 					&altname, &type, pos) !=0) {
1848 				plog(LLV_ERROR, LOCATION, NULL,
1849 					"failed to get subjectAltName\n");
1850 				return ISAKMP_NTYPE_INVALID_CERTIFICATE;
1851 			}
1852 
1853 			/* it's the end condition of the loop. */
1854 			if (!altname) {
1855 				plog(LLV_ERROR, LOCATION, NULL,
1856 					"no proper subjectAltName.\n");
1857 				return ISAKMP_NTYPE_INVALID_CERTIFICATE;
1858 			}
1859 
1860 			if (check_typeofcertname(id_b->type, type) == 0)
1861 				break;
1862 
1863 			/* next name */
1864 			racoon_free(altname);
1865 			altname = NULL;
1866 		}
1867 		memset(&hints, 0, sizeof(hints));
1868 		hints.ai_family = PF_UNSPEC;
1869 		hints.ai_socktype = SOCK_RAW;
1870 		hints.ai_flags = AI_NUMERICHOST;
1871 		error = getaddrinfo(altname, NULL, &hints, &res);
1872 		racoon_free(altname);
1873 		altname = NULL;
1874 		if (error != 0) {
1875 			plog(LLV_ERROR, LOCATION, NULL,
1876 				"no proper subjectAltName.\n");
1877 			return ISAKMP_NTYPE_INVALID_CERTIFICATE;
1878 		}
1879 		switch (res->ai_family) {
1880 		case AF_INET:
1881 			a = (caddr_t)&((struct sockaddr_in *)res->ai_addr)->sin_addr.s_addr;
1882 			break;
1883 #ifdef INET6
1884 		case AF_INET6:
1885 			a = (caddr_t)&((struct sockaddr_in6 *)res->ai_addr)->sin6_addr.s6_addr;
1886 			break;
1887 #endif
1888 		default:
1889 			plog(LLV_ERROR, LOCATION, NULL,
1890 				"family not supported: %d.\n", res->ai_family);
1891 			freeaddrinfo(res);
1892 			return ISAKMP_NTYPE_INVALID_CERTIFICATE;
1893 		}
1894 		error = memcmp(id_b + 1, a, idlen);
1895 		freeaddrinfo(res);
1896 		vfree(name);
1897 		if (error != 0) {
1898 			plog(LLV_ERROR, LOCATION, NULL,
1899 				"ID mismatched with subjectAltName.\n");
1900 			plogdump(LLV_DEBUG, id_b + 1, idlen);
1901 			plogdump(LLV_DEBUG, a, idlen);
1902 			if (iph1->rmconf->verify_identifier)
1903 				return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
1904 		}
1905 		return 0;
1906 	}
1907 	case IPSECDOI_ID_FQDN:
1908 	case IPSECDOI_ID_USER_FQDN:
1909 	{
1910 		int pos;
1911 
1912 		for (pos = 1; ; pos++) {
1913 			if (eay_get_x509subjectaltname(iph1->cert_p,
1914 					&altname, &type, pos) != 0){
1915 				plog(LLV_ERROR, LOCATION, NULL,
1916 					"failed to get subjectAltName\n");
1917 				return ISAKMP_NTYPE_INVALID_CERTIFICATE;
1918 			}
1919 
1920 			/* it's the end condition of the loop. */
1921 			if (!altname) {
1922 				plog(LLV_ERROR, LOCATION, NULL,
1923 					"no proper subjectAltName.\n");
1924 				return ISAKMP_NTYPE_INVALID_CERTIFICATE;
1925 			}
1926 
1927 			if (check_typeofcertname(id_b->type, type) == 0)
1928 				break;
1929 
1930 			/* next name */
1931 			racoon_free(altname);
1932 			altname = NULL;
1933 		}
1934 		if (idlen != strlen(altname)) {
1935 			plog(LLV_ERROR, LOCATION, NULL,
1936 				"Invalid ID length in phase 1.\n");
1937 			racoon_free(altname);
1938 			return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
1939 		}
1940 		if (check_typeofcertname(id_b->type, type) != 0) {
1941 			plog(LLV_ERROR, LOCATION, NULL,
1942 				"ID type mismatched. ID: %s CERT: %s.\n",
1943 				s_ipsecdoi_ident(id_b->type),
1944 				s_ipsecdoi_ident(type));
1945 			racoon_free(altname);
1946 			return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
1947 		}
1948 		error = memcmp(id_b + 1, altname, idlen);
1949 		if (error) {
1950 			plog(LLV_ERROR, LOCATION, NULL, "ID mismatched.\n");
1951 			plogdump(LLV_DEBUG, id_b + 1, idlen);
1952 			plogdump(LLV_DEBUG, altname, idlen);
1953 			racoon_free(altname);
1954 			return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
1955 		}
1956 		racoon_free(altname);
1957 		return 0;
1958 	}
1959 	default:
1960 		plog(LLV_ERROR, LOCATION, NULL,
1961 			"Inpropper ID type passed: %s.\n",
1962 			s_ipsecdoi_ident(id_b->type));
1963 		return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
1964 	}
1965 	/*NOTREACHED*/
1966 }
1967 
1968 static int
1969 check_typeofcertname(doi, genid)
1970 	int doi, genid;
1971 {
1972 	switch (doi) {
1973 	case IPSECDOI_ID_IPV4_ADDR:
1974 	case IPSECDOI_ID_IPV4_ADDR_SUBNET:
1975 	case IPSECDOI_ID_IPV6_ADDR:
1976 	case IPSECDOI_ID_IPV6_ADDR_SUBNET:
1977 	case IPSECDOI_ID_IPV4_ADDR_RANGE:
1978 	case IPSECDOI_ID_IPV6_ADDR_RANGE:
1979 		if (genid != GENT_IPADD)
1980 			return -1;
1981 		return 0;
1982 	case IPSECDOI_ID_FQDN:
1983 		if (genid != GENT_DNS)
1984 			return -1;
1985 		return 0;
1986 	case IPSECDOI_ID_USER_FQDN:
1987 		if (genid != GENT_EMAIL)
1988 			return -1;
1989 		return 0;
1990 	case IPSECDOI_ID_DER_ASN1_DN: /* should not be passed to this function*/
1991 	case IPSECDOI_ID_DER_ASN1_GN:
1992 	case IPSECDOI_ID_KEY_ID:
1993 	default:
1994 		return -1;
1995 	}
1996 	/*NOTREACHED*/
1997 }
1998 
1999 /*
2000  * save certificate including certificate type.
2001  */
2002 int
2003 oakley_savecert(iph1, gen)
2004 	struct ph1handle *iph1;
2005 	struct isakmp_gen *gen;
2006 {
2007 	vchar_t **c;
2008 	u_int8_t type;
2009 	STACK_OF(X509) *certs=NULL;
2010 	PKCS7 *p7;
2011 
2012 	type = *(u_int8_t *)(gen + 1) & 0xff;
2013 
2014 	switch (type) {
2015 	case ISAKMP_CERT_DNS:
2016 		plog(LLV_WARNING, LOCATION, NULL,
2017 			"CERT payload is unnecessary in DNSSEC. "
2018 			"ignore this CERT payload.\n");
2019 		return 0;
2020 	case ISAKMP_CERT_PKCS7:
2021 	case ISAKMP_CERT_PGP:
2022 	case ISAKMP_CERT_X509SIGN:
2023 	case ISAKMP_CERT_KERBEROS:
2024 	case ISAKMP_CERT_SPKI:
2025 		c = &iph1->cert_p;
2026 		break;
2027 	case ISAKMP_CERT_CRL:
2028 		c = &iph1->crl_p;
2029 		break;
2030 	case ISAKMP_CERT_X509KE:
2031 	case ISAKMP_CERT_X509ATTR:
2032 	case ISAKMP_CERT_ARL:
2033 		plog(LLV_ERROR, LOCATION, NULL,
2034 			"No supported such CERT type %d\n", type);
2035 		return -1;
2036 	default:
2037 		plog(LLV_ERROR, LOCATION, NULL,
2038 			"Invalid CERT type %d\n", type);
2039 		return -1;
2040 	}
2041 
2042 	/* XXX choice the 1th cert, ignore after the cert. */
2043 	/* XXX should be processed. */
2044 	if (*c) {
2045 		plog(LLV_WARNING, LOCATION, NULL,
2046 			"ignore 2nd CERT payload.\n");
2047 		return 0;
2048 	}
2049 
2050 	if (type == ISAKMP_CERT_PKCS7) {
2051 		u_char *bp;
2052 		int i;
2053 
2054 		/* Skip the header */
2055 		bp = (u_char *)(gen + 1);
2056 		/* And the first byte is the certificate type,
2057 		 * we know that already
2058 		 */
2059 		bp++;
2060 		p7 = d2i_PKCS7(NULL, (void *)&bp,
2061 		    ntohs(gen->len) - sizeof(*gen) - 1);
2062 
2063 		if (!p7) {
2064 			plog(LLV_ERROR, LOCATION, NULL,
2065 			     "Failed to parse PKCS#7 CERT.\n");
2066 			return -1;
2067 		}
2068 
2069 		/* Copied this from the openssl pkcs7 application;
2070 		 * there"s little by way of documentation for any of
2071 		 * it. I can only presume it"s correct.
2072 		 */
2073 
2074 		i = OBJ_obj2nid(p7->type);
2075 		switch (i) {
2076 		case NID_pkcs7_signed:
2077 			certs=p7->d.sign->cert;
2078 			break;
2079 		case NID_pkcs7_signedAndEnveloped:
2080 			certs=p7->d.signed_and_enveloped->cert;
2081 			break;
2082 		default:
2083 			 break;
2084 		}
2085 
2086 		if (!certs) {
2087 			plog(LLV_ERROR, LOCATION, NULL,
2088 			     "CERT PKCS#7 bundle contains no certs.\n");
2089 			PKCS7_free(p7);
2090 			return -1;
2091 		}
2092 
2093 		for (i = 0; i < sk_X509_num(certs); i++) {
2094 			int len;
2095 			u_char *bp;
2096 			X509 *cert = sk_X509_value(certs,i);
2097 
2098 			plog(LLV_DEBUG, LOCATION, NULL,
2099 			     "Trying PKCS#7 cert %d.\n", i);
2100 
2101 			/* We'll just try each cert in turn */
2102 			*c = dump_x509(cert);
2103 
2104 			if (!*c) {
2105 				plog(LLV_ERROR, LOCATION, NULL,
2106 				     "Failed to get CERT buffer.\n");
2107 				continue;
2108 			}
2109 
2110 			/* Ignore cert if it doesn't match identity
2111 			 * XXX If verify cert is disabled, we still just take
2112 			 * the first certificate....
2113 			 */
2114 			if (oakley_check_certid(iph1)) {
2115 				plog(LLV_DEBUG, LOCATION, NULL,
2116 				     "Discarding CERT: does not match ID.\n");
2117 				vfree((*c));
2118 				*c = NULL;
2119 				continue;
2120 			}
2121 
2122 			{
2123 				char *p = eay_get_x509text(*c);
2124 				plog(LLV_DEBUG, LOCATION, NULL, "CERT saved:\n");
2125 				plogdump(LLV_DEBUG, (*c)->v, (*c)->l);
2126 				plog(LLV_DEBUG, LOCATION, NULL, "%s",
2127 				     p ? p : "\n");
2128 				racoon_free(p);
2129 			}
2130 			break;
2131 		}
2132 		PKCS7_free(p7);
2133 	} else {
2134 		*c = dump_isakmp_payload(gen);
2135 		if (!*c) {
2136 			plog(LLV_ERROR, LOCATION, NULL,
2137 			     "Failed to get CERT buffer.\n");
2138 			return -1;
2139 		}
2140 
2141 		switch (type) {
2142 		case ISAKMP_CERT_PGP:
2143 		case ISAKMP_CERT_X509SIGN:
2144 		case ISAKMP_CERT_KERBEROS:
2145 		case ISAKMP_CERT_SPKI:
2146 			/* Ignore cert if it doesn't match identity
2147 			 * XXX If verify cert is disabled, we still just take
2148 			 * the first certificate....
2149 			 */
2150 			if (oakley_check_certid(iph1)){
2151 				plog(LLV_DEBUG, LOCATION, NULL,
2152 				     "Discarding CERT: does not match ID.\n");
2153 				vfree((*c));
2154 				*c = NULL;
2155 				return 0;
2156 			}
2157 
2158 			{
2159 				char *p = eay_get_x509text(*c);
2160 				plog(LLV_DEBUG, LOCATION, NULL, "CERT saved:\n");
2161 				plogdump(LLV_DEBUG, (*c)->v, (*c)->l);
2162 				plog(LLV_DEBUG, LOCATION, NULL, "%s", p ? p : "\n");
2163 				racoon_free(p);
2164 			}
2165 			break;
2166 		case ISAKMP_CERT_CRL:
2167 			plog(LLV_DEBUG, LOCATION, NULL, "CRL saved:\n");
2168 			plogdump(LLV_DEBUG, (*c)->v, (*c)->l);
2169 			break;
2170 		case ISAKMP_CERT_X509KE:
2171 		case ISAKMP_CERT_X509ATTR:
2172 		case ISAKMP_CERT_ARL:
2173 		default:
2174 			/* XXX */
2175 			vfree(*c);
2176 			*c = NULL;
2177 			return 0;
2178 		}
2179 	}
2180 
2181 	return 0;
2182 }
2183 
2184 /*
2185  * save certificate including certificate type.
2186  */
2187 int
2188 oakley_savecr(iph1, gen)
2189 	struct ph1handle *iph1;
2190 	struct isakmp_gen *gen;
2191 {
2192 	vchar_t *cert;
2193 	vchar_t **c;
2194 	u_int8_t type;
2195 
2196 	type = *(u_int8_t *)(gen + 1) & 0xff;
2197 	switch (type) {
2198 	case ISAKMP_CERT_DNS:
2199 		plog(LLV_WARNING, LOCATION, NULL,
2200 			"CERT payload is unnecessary in DNSSEC\n");
2201 		/*FALLTHRU*/
2202 	case ISAKMP_CERT_PKCS7:
2203 	case ISAKMP_CERT_PGP:
2204 	case ISAKMP_CERT_X509SIGN:
2205 	case ISAKMP_CERT_KERBEROS:
2206 	case ISAKMP_CERT_SPKI:
2207 		c = &iph1->cr_p;
2208 		break;
2209 	case ISAKMP_CERT_X509KE:
2210 	case ISAKMP_CERT_X509ATTR:
2211 	case ISAKMP_CERT_ARL:
2212 		plog(LLV_ERROR, LOCATION, NULL,
2213 			"No supported such CR type %d\n", type);
2214 		return -1;
2215 	case ISAKMP_CERT_CRL:
2216 	default:
2217 		plog(LLV_ERROR, LOCATION, NULL,
2218 			"Invalid CR type %d\n", type);
2219 		return -1;
2220 	}
2221 
2222 	/* Already found an acceptable CR? */
2223 	if (*c != NULL)
2224 		return 0;
2225 
2226 	cert = dump_isakmp_payload(gen);
2227 	if (cert == NULL) {
2228 		plog(LLV_ERROR, LOCATION, NULL,
2229 			"Failed to get CR buffer.\n");
2230 		return -1;
2231 	}
2232 
2233 	plog(LLV_DEBUG, LOCATION, NULL, "CR received:\n");
2234 	plogdump(LLV_DEBUG, cert->v, cert->l);
2235 
2236 	*c = cert;
2237 	if (resolveph1rmconf(iph1) == 0) {
2238 		/* Found unique match */
2239 		plog(LLV_DEBUG, LOCATION, NULL, "CR saved.\n");
2240 	} else {
2241 		/* Still ambiguous or matches nothing, ignore this CR */
2242 		*c = NULL;
2243 		vfree(cert);
2244 	}
2245 	return 0;
2246 }
2247 
2248 /*
2249  * Add a single CR.
2250  */
2251 struct append_cr_ctx {
2252 	struct ph1handle *iph1;
2253 	struct payload_list *plist;
2254 };
2255 
2256 static int
2257 oakley_append_rmconf_cr(rmconf, ctx)
2258 	struct remoteconf *rmconf;
2259 	void *ctx;
2260 {
2261 	struct append_cr_ctx *actx = (struct append_cr_ctx *) ctx;
2262 	vchar_t *buf, *asn1dn = NULL;
2263 	int type;
2264 
2265 	/* Do we want to send CR about this? */
2266 	if (rmconf->send_cr == FALSE)
2267 		return 0;
2268 
2269 	if (rmconf->peerscert != NULL) {
2270 		type = oakley_get_certtype(rmconf->peerscert);
2271 		asn1dn = eay_get_x509asn1issuername(rmconf->peerscert);
2272 	} else if (rmconf->cacert != NULL) {
2273 		type = oakley_get_certtype(rmconf->cacert);
2274 		asn1dn = eay_get_x509asn1subjectname(rmconf->cacert);
2275 	} else
2276 		return 0;
2277 
2278 	if (asn1dn == NULL) {
2279 		plog(LLV_ERROR, LOCATION, actx->iph1->remote,
2280 		     "Failed to get CR ASN1 DN from certificate\n");
2281 		return 0;
2282 	}
2283 
2284 	buf = vmalloc(1 + asn1dn->l);
2285 	if (buf == NULL)
2286 		goto err;
2287 
2288 	buf->v[0] = type;
2289 	memcpy(&buf->v[1], asn1dn->v, asn1dn->l);
2290 
2291 	plog(LLV_DEBUG, LOCATION, actx->iph1->remote,
2292 	     "appending CR: %s\n",
2293 	     s_isakmp_certtype(buf->v[0]));
2294 	plogdump(LLV_DEBUG, buf->v, buf->l);
2295 
2296 	actx->plist = isakmp_plist_append_full(actx->plist, buf, ISAKMP_NPTYPE_CR, 1);
2297 
2298 err:
2299 	vfree(asn1dn);
2300 	return 0;
2301 }
2302 
2303 /*
2304  * Append list of acceptable CRs.
2305  * RFC2048 3.10
2306  */
2307 struct payload_list *
2308 oakley_append_cr(plist, iph1)
2309 	struct payload_list *plist;
2310 	struct ph1handle *iph1;
2311 {
2312 	struct append_cr_ctx ctx;
2313 	struct rmconfselector sel;
2314 
2315 	ctx.iph1 = iph1;
2316 	ctx.plist = plist;
2317 	if (iph1->rmconf == NULL) {
2318 		rmconf_selector_from_ph1(&sel, iph1);
2319 		enumrmconf(&sel, oakley_append_rmconf_cr, &ctx);
2320 	} else {
2321 		oakley_append_rmconf_cr(iph1->rmconf, &ctx);
2322 	}
2323 
2324 	return ctx.plist;
2325 }
2326 
2327 /*
2328  * check peer's CR.
2329  */
2330 int
2331 oakley_checkcr(iph1)
2332 	struct ph1handle *iph1;
2333 {
2334 	int type;
2335 
2336 	if (iph1->cr_p == NULL)
2337 		return 0;
2338 
2339 	plog(LLV_DEBUG, LOCATION, iph1->remote,
2340 		"peer transmitted CR: %s\n",
2341 		s_isakmp_certtype(oakley_get_certtype(iph1->cr_p)));
2342 
2343 	type = oakley_get_certtype(iph1->cr_p);
2344 	if (type != oakley_get_certtype(iph1->rmconf->mycert)) {
2345 		plog(LLV_ERROR, LOCATION, iph1->remote,
2346 		     "such a cert type isn't supported: %d\n",
2347 		     type);
2348 		return -1;
2349 	}
2350 
2351 	return 0;
2352 }
2353 
2354 /*
2355  * check to need CR payload.
2356  */
2357 int
2358 oakley_needcr(type)
2359 	int type;
2360 {
2361 	switch (type) {
2362 	case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
2363 	case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
2364 #ifdef ENABLE_HYBRID
2365 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
2366 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
2367 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
2368 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
2369 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
2370 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
2371 #endif
2372 		return 1;
2373 	default:
2374 		return 0;
2375 	}
2376 	/*NOTREACHED*/
2377 }
2378 
2379 /*
2380  * compute SKEYID
2381  * see seciton 5. Exchanges in RFC 2409
2382  * psk: SKEYID = prf(pre-shared-key, Ni_b | Nr_b)
2383  * sig: SKEYID = prf(Ni_b | Nr_b, g^ir)
2384  * enc: SKEYID = prf(H(Ni_b | Nr_b), CKY-I | CKY-R)
2385  */
2386 int
2387 oakley_skeyid(iph1)
2388 	struct ph1handle *iph1;
2389 {
2390 	vchar_t *buf = NULL, *bp;
2391 	char *p;
2392 	int len;
2393 	int error = -1;
2394 
2395 	/* SKEYID */
2396 	switch (iph1->approval->authmethod) {
2397 	case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
2398 #ifdef ENABLE_HYBRID
2399 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
2400 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
2401 #endif
2402 		if (iph1->etype != ISAKMP_ETYPE_IDENT) {
2403 			iph1->authstr = getpskbyname(iph1->id_p);
2404 			if (iph1->authstr == NULL) {
2405 				if (iph1->rmconf->verify_identifier) {
2406 					plog(LLV_ERROR, LOCATION, iph1->remote,
2407 						"couldn't find the pskey.\n");
2408 					goto end;
2409 				}
2410 				plog(LLV_NOTIFY, LOCATION, iph1->remote,
2411 					"couldn't find the proper pskey, "
2412 					"try to get one by the peer's address.\n");
2413 			}
2414 		}
2415 		if (iph1->authstr == NULL) {
2416 			/*
2417 			 * If the exchange type is the main mode or if it's
2418 			 * failed to get the psk by ID, racoon try to get
2419 			 * the psk by remote IP address.
2420 			 * It may be nonsense.
2421 			 */
2422 			iph1->authstr = getpskbyaddr(iph1->remote);
2423 			if (iph1->authstr == NULL) {
2424 				plog(LLV_ERROR, LOCATION, iph1->remote,
2425 					"couldn't find the pskey for %s.\n",
2426 					saddrwop2str(iph1->remote));
2427 				goto end;
2428 			}
2429 		}
2430 		plog(LLV_DEBUG, LOCATION, NULL, "the psk found.\n");
2431 		/* should be secret PSK */
2432 		plog(LLV_DEBUG2, LOCATION, NULL, "psk: ");
2433 		plogdump(LLV_DEBUG2, iph1->authstr->v, iph1->authstr->l);
2434 
2435 		len = iph1->nonce->l + iph1->nonce_p->l;
2436 		buf = vmalloc(len);
2437 		if (buf == NULL) {
2438 			plog(LLV_ERROR, LOCATION, NULL,
2439 				"failed to get skeyid buffer\n");
2440 			goto end;
2441 		}
2442 		p = buf->v;
2443 
2444 		bp = (iph1->side == INITIATOR ? iph1->nonce : iph1->nonce_p);
2445 		plog(LLV_DEBUG, LOCATION, NULL, "nonce 1: ");
2446 		plogdump(LLV_DEBUG, bp->v, bp->l);
2447 		memcpy(p, bp->v, bp->l);
2448 		p += bp->l;
2449 
2450 		bp = (iph1->side == INITIATOR ? iph1->nonce_p : iph1->nonce);
2451 		plog(LLV_DEBUG, LOCATION, NULL, "nonce 2: ");
2452 		plogdump(LLV_DEBUG, bp->v, bp->l);
2453 		memcpy(p, bp->v, bp->l);
2454 		p += bp->l;
2455 
2456 		iph1->skeyid = oakley_prf(iph1->authstr, buf, iph1);
2457 		if (iph1->skeyid == NULL)
2458 			goto end;
2459 		break;
2460 
2461 	case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
2462 	case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
2463 #ifdef ENABLE_HYBRID
2464 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
2465 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
2466 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
2467 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
2468 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
2469 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
2470 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
2471 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
2472 #endif
2473 #ifdef HAVE_GSSAPI
2474 	case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
2475 #endif
2476 		len = iph1->nonce->l + iph1->nonce_p->l;
2477 		buf = vmalloc(len);
2478 		if (buf == NULL) {
2479 			plog(LLV_ERROR, LOCATION, NULL,
2480 				"failed to get nonce buffer\n");
2481 			goto end;
2482 		}
2483 		p = buf->v;
2484 
2485 		bp = (iph1->side == INITIATOR ? iph1->nonce : iph1->nonce_p);
2486 		plog(LLV_DEBUG, LOCATION, NULL, "nonce1: ");
2487 		plogdump(LLV_DEBUG, bp->v, bp->l);
2488 		memcpy(p, bp->v, bp->l);
2489 		p += bp->l;
2490 
2491 		bp = (iph1->side == INITIATOR ? iph1->nonce_p : iph1->nonce);
2492 		plog(LLV_DEBUG, LOCATION, NULL, "nonce2: ");
2493 		plogdump(LLV_DEBUG, bp->v, bp->l);
2494 		memcpy(p, bp->v, bp->l);
2495 		p += bp->l;
2496 
2497 		iph1->skeyid = oakley_prf(buf, iph1->dhgxy, iph1);
2498 		if (iph1->skeyid == NULL)
2499 			goto end;
2500 		break;
2501 	case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
2502 	case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
2503 #ifdef ENABLE_HYBRID
2504 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
2505 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
2506 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
2507 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
2508 #endif
2509 		plog(LLV_WARNING, LOCATION, NULL,
2510 			"not supported authentication method %s\n",
2511 			s_oakley_attr_method(iph1->approval->authmethod));
2512 		goto end;
2513 	default:
2514 		plog(LLV_ERROR, LOCATION, NULL,
2515 			"invalid authentication method %d\n",
2516 			iph1->approval->authmethod);
2517 		goto end;
2518 	}
2519 
2520 	plog(LLV_DEBUG, LOCATION, NULL, "SKEYID computed:\n");
2521 	plogdump(LLV_DEBUG, iph1->skeyid->v, iph1->skeyid->l);
2522 
2523 	error = 0;
2524 
2525 end:
2526 	if (buf != NULL)
2527 		vfree(buf);
2528 	return error;
2529 }
2530 
2531 /*
2532  * compute SKEYID_[dae]
2533  * see seciton 5. Exchanges in RFC 2409
2534  * SKEYID_d = prf(SKEYID, g^ir | CKY-I | CKY-R | 0)
2535  * SKEYID_a = prf(SKEYID, SKEYID_d | g^ir | CKY-I | CKY-R | 1)
2536  * SKEYID_e = prf(SKEYID, SKEYID_a | g^ir | CKY-I | CKY-R | 2)
2537  */
2538 int
2539 oakley_skeyid_dae(iph1)
2540 	struct ph1handle *iph1;
2541 {
2542 	vchar_t *buf = NULL;
2543 	char *p;
2544 	int len;
2545 	int error = -1;
2546 
2547 	if (iph1->skeyid == NULL) {
2548 		plog(LLV_ERROR, LOCATION, NULL, "no SKEYID found.\n");
2549 		goto end;
2550 	}
2551 
2552 	/* SKEYID D */
2553 	/* SKEYID_d = prf(SKEYID, g^xy | CKY-I | CKY-R | 0) */
2554 	len = iph1->dhgxy->l + sizeof(cookie_t) * 2 + 1;
2555 	buf = vmalloc(len);
2556 	if (buf == NULL) {
2557 		plog(LLV_ERROR, LOCATION, NULL,
2558 			"failed to get skeyid buffer\n");
2559 		goto end;
2560 	}
2561 	p = buf->v;
2562 
2563 	memcpy(p, iph1->dhgxy->v, iph1->dhgxy->l);
2564 	p += iph1->dhgxy->l;
2565 	memcpy(p, (caddr_t)&iph1->index.i_ck, sizeof(cookie_t));
2566 	p += sizeof(cookie_t);
2567 	memcpy(p, (caddr_t)&iph1->index.r_ck, sizeof(cookie_t));
2568 	p += sizeof(cookie_t);
2569 	*p = 0;
2570 	iph1->skeyid_d = oakley_prf(iph1->skeyid, buf, iph1);
2571 	if (iph1->skeyid_d == NULL)
2572 		goto end;
2573 
2574 	vfree(buf);
2575 	buf = NULL;
2576 
2577 	plog(LLV_DEBUG, LOCATION, NULL, "SKEYID_d computed:\n");
2578 	plogdump(LLV_DEBUG, iph1->skeyid_d->v, iph1->skeyid_d->l);
2579 
2580 	/* SKEYID A */
2581 	/* SKEYID_a = prf(SKEYID, SKEYID_d | g^xy | CKY-I | CKY-R | 1) */
2582 	len = iph1->skeyid_d->l + iph1->dhgxy->l + sizeof(cookie_t) * 2 + 1;
2583 	buf = vmalloc(len);
2584 	if (buf == NULL) {
2585 		plog(LLV_ERROR, LOCATION, NULL,
2586 			"failed to get skeyid buffer\n");
2587 		goto end;
2588 	}
2589 	p = buf->v;
2590 	memcpy(p, iph1->skeyid_d->v, iph1->skeyid_d->l);
2591 	p += iph1->skeyid_d->l;
2592 	memcpy(p, iph1->dhgxy->v, iph1->dhgxy->l);
2593 	p += iph1->dhgxy->l;
2594 	memcpy(p, (caddr_t)&iph1->index.i_ck, sizeof(cookie_t));
2595 	p += sizeof(cookie_t);
2596 	memcpy(p, (caddr_t)&iph1->index.r_ck, sizeof(cookie_t));
2597 	p += sizeof(cookie_t);
2598 	*p = 1;
2599 	iph1->skeyid_a = oakley_prf(iph1->skeyid, buf, iph1);
2600 	if (iph1->skeyid_a == NULL)
2601 		goto end;
2602 
2603 	vfree(buf);
2604 	buf = NULL;
2605 
2606 	plog(LLV_DEBUG, LOCATION, NULL, "SKEYID_a computed:\n");
2607 	plogdump(LLV_DEBUG, iph1->skeyid_a->v, iph1->skeyid_a->l);
2608 
2609 	/* SKEYID E */
2610 	/* SKEYID_e = prf(SKEYID, SKEYID_a | g^xy | CKY-I | CKY-R | 2) */
2611 	len = iph1->skeyid_a->l + iph1->dhgxy->l + sizeof(cookie_t) * 2 + 1;
2612 	buf = vmalloc(len);
2613 	if (buf == NULL) {
2614 		plog(LLV_ERROR, LOCATION, NULL,
2615 			"failed to get skeyid buffer\n");
2616 		goto end;
2617 	}
2618 	p = buf->v;
2619 	memcpy(p, iph1->skeyid_a->v, iph1->skeyid_a->l);
2620 	p += iph1->skeyid_a->l;
2621 	memcpy(p, iph1->dhgxy->v, iph1->dhgxy->l);
2622 	p += iph1->dhgxy->l;
2623 	memcpy(p, (caddr_t)&iph1->index.i_ck, sizeof(cookie_t));
2624 	p += sizeof(cookie_t);
2625 	memcpy(p, (caddr_t)&iph1->index.r_ck, sizeof(cookie_t));
2626 	p += sizeof(cookie_t);
2627 	*p = 2;
2628 	iph1->skeyid_e = oakley_prf(iph1->skeyid, buf, iph1);
2629 	if (iph1->skeyid_e == NULL)
2630 		goto end;
2631 
2632 	vfree(buf);
2633 	buf = NULL;
2634 
2635 	plog(LLV_DEBUG, LOCATION, NULL, "SKEYID_e computed:\n");
2636 	plogdump(LLV_DEBUG, iph1->skeyid_e->v, iph1->skeyid_e->l);
2637 
2638 	error = 0;
2639 
2640 end:
2641 	if (buf != NULL)
2642 		vfree(buf);
2643 	return error;
2644 }
2645 
2646 /*
2647  * compute final encryption key.
2648  * see Appendix B.
2649  */
2650 int
2651 oakley_compute_enckey(iph1)
2652 	struct ph1handle *iph1;
2653 {
2654 	u_int keylen, prflen;
2655 	int error = -1;
2656 
2657 	/* RFC2409 p39 */
2658 	keylen = alg_oakley_encdef_keylen(iph1->approval->enctype,
2659 					iph1->approval->encklen);
2660 	if (keylen == -1) {
2661 		plog(LLV_ERROR, LOCATION, NULL,
2662 			"invalid encryption algorithm %d, "
2663 			"or invalid key length %d.\n",
2664 			iph1->approval->enctype,
2665 			iph1->approval->encklen);
2666 		goto end;
2667 	}
2668 	iph1->key = vmalloc(keylen >> 3);
2669 	if (iph1->key == NULL) {
2670 		plog(LLV_ERROR, LOCATION, NULL,
2671 			"failed to get key buffer\n");
2672 		goto end;
2673 	}
2674 
2675 	/* set prf length */
2676 	prflen = alg_oakley_hashdef_hashlen(iph1->approval->hashtype);
2677 	if (prflen == -1) {
2678 		plog(LLV_ERROR, LOCATION, NULL,
2679 			"invalid hash type %d.\n", iph1->approval->hashtype);
2680 		goto end;
2681 	}
2682 
2683 	/* see isakmp-oakley-08 5.3. */
2684 	if (iph1->key->l <= iph1->skeyid_e->l) {
2685 		/*
2686 		 * if length(Ka) <= length(SKEYID_e)
2687 		 *	Ka = first length(K) bit of SKEYID_e
2688 		 */
2689 		memcpy(iph1->key->v, iph1->skeyid_e->v, iph1->key->l);
2690 	} else {
2691 		vchar_t *buf = NULL, *res = NULL;
2692 		u_char *p, *ep;
2693 		int cplen;
2694 		int subkey;
2695 
2696 		/*
2697 		 * otherwise,
2698 		 *	Ka = K1 | K2 | K3
2699 		 * where
2700 		 *	K1 = prf(SKEYID_e, 0)
2701 		 *	K2 = prf(SKEYID_e, K1)
2702 		 *	K3 = prf(SKEYID_e, K2)
2703 		 */
2704 		plog(LLV_DEBUG, LOCATION, NULL,
2705 			"len(SKEYID_e) < len(Ka) (%zu < %zu), "
2706 			"generating long key (Ka = K1 | K2 | ...)\n",
2707 			iph1->skeyid_e->l, iph1->key->l);
2708 
2709 		if ((buf = vmalloc(prflen >> 3)) == 0) {
2710 			plog(LLV_ERROR, LOCATION, NULL,
2711 				"failed to get key buffer\n");
2712 			goto end;
2713 		}
2714 		p = (u_char *)iph1->key->v;
2715 		ep = p + iph1->key->l;
2716 
2717 		subkey = 1;
2718 		while (p < ep) {
2719 			if (p == (u_char *)iph1->key->v) {
2720 				/* just for computing K1 */
2721 				buf->v[0] = 0;
2722 				buf->l = 1;
2723 			}
2724 			res = oakley_prf(iph1->skeyid_e, buf, iph1);
2725 			if (res == NULL) {
2726 				vfree(buf);
2727 				goto end;
2728 			}
2729 			plog(LLV_DEBUG, LOCATION, NULL,
2730 				"compute intermediate encryption key K%d\n",
2731 				subkey);
2732 			plogdump(LLV_DEBUG, buf->v, buf->l);
2733 			plogdump(LLV_DEBUG, res->v, res->l);
2734 
2735 			cplen = (res->l < ep - p) ? res->l : ep - p;
2736 			memcpy(p, res->v, cplen);
2737 			p += cplen;
2738 
2739 			buf->l = prflen >> 3;	/* to cancel K1 speciality */
2740 			if (res->l != buf->l) {
2741 				plog(LLV_ERROR, LOCATION, NULL,
2742 					"internal error: res->l=%zu buf->l=%zu\n",
2743 					res->l, buf->l);
2744 				vfree(res);
2745 				vfree(buf);
2746 				goto end;
2747 			}
2748 			memcpy(buf->v, res->v, res->l);
2749 			vfree(res);
2750 			subkey++;
2751 		}
2752 
2753 		vfree(buf);
2754 	}
2755 
2756 	/*
2757 	 * don't check any weak key or not.
2758 	 * draft-ietf-ipsec-ike-01.txt Appendix B.
2759 	 * draft-ietf-ipsec-ciph-aes-cbc-00.txt Section 2.3.
2760 	 */
2761 #if 0
2762 	/* weakkey check */
2763 	if (iph1->approval->enctype > ARRAYLEN(oakley_encdef)
2764 	 || oakley_encdef[iph1->approval->enctype].weakkey == NULL) {
2765 		plog(LLV_ERROR, LOCATION, NULL,
2766 			"encryption algorithm %d isn't supported.\n",
2767 			iph1->approval->enctype);
2768 		goto end;
2769 	}
2770 	if ((oakley_encdef[iph1->approval->enctype].weakkey)(iph1->key)) {
2771 		plog(LLV_ERROR, LOCATION, NULL,
2772 			"weakkey was generated.\n");
2773 		goto end;
2774 	}
2775 #endif
2776 
2777 	plog(LLV_DEBUG, LOCATION, NULL, "final encryption key computed:\n");
2778 	plogdump(LLV_DEBUG, iph1->key->v, iph1->key->l);
2779 
2780 	error = 0;
2781 
2782 end:
2783 	return error;
2784 }
2785 
2786 /*
2787  * compute IV and set to ph1handle
2788  *	IV = hash(g^xi | g^xr)
2789  * see 4.1 Phase 1 state in draft-ietf-ipsec-ike.
2790  */
2791 int
2792 oakley_newiv(iph1)
2793 	struct ph1handle *iph1;
2794 {
2795 	struct isakmp_ivm *newivm = NULL;
2796 	vchar_t *buf = NULL, *bp;
2797 	char *p;
2798 	int len;
2799 
2800 	/* create buffer */
2801 	len = iph1->dhpub->l + iph1->dhpub_p->l;
2802 	buf = vmalloc(len);
2803 	if (buf == NULL) {
2804 		plog(LLV_ERROR, LOCATION, NULL,
2805 			"failed to get iv buffer\n");
2806 		return -1;
2807 	}
2808 
2809 	p = buf->v;
2810 
2811 	bp = (iph1->side == INITIATOR ? iph1->dhpub : iph1->dhpub_p);
2812 	memcpy(p, bp->v, bp->l);
2813 	p += bp->l;
2814 
2815 	bp = (iph1->side == INITIATOR ? iph1->dhpub_p : iph1->dhpub);
2816 	memcpy(p, bp->v, bp->l);
2817 	p += bp->l;
2818 
2819 	/* allocate IVm */
2820 	newivm = racoon_calloc(1, sizeof(struct isakmp_ivm));
2821 	if (newivm == NULL) {
2822 		plog(LLV_ERROR, LOCATION, NULL,
2823 			"failed to get iv buffer\n");
2824 		vfree(buf);
2825 		return -1;
2826 	}
2827 
2828 	/* compute IV */
2829 	newivm->iv = oakley_hash(buf, iph1);
2830 	if (newivm->iv == NULL) {
2831 		vfree(buf);
2832 		oakley_delivm(newivm);
2833 		return -1;
2834 	}
2835 
2836 	/* adjust length of iv */
2837 	newivm->iv->l = alg_oakley_encdef_blocklen(iph1->approval->enctype);
2838 	if (newivm->iv->l == -1) {
2839 		plog(LLV_ERROR, LOCATION, NULL,
2840 			"invalid encryption algorithm %d.\n",
2841 			iph1->approval->enctype);
2842 		vfree(buf);
2843 		oakley_delivm(newivm);
2844 		return -1;
2845 	}
2846 
2847 	/* create buffer to save iv */
2848 	if ((newivm->ive = vdup(newivm->iv)) == NULL) {
2849 		plog(LLV_ERROR, LOCATION, NULL,
2850 			"vdup (%s)\n", strerror(errno));
2851 		vfree(buf);
2852 		oakley_delivm(newivm);
2853 		return -1;
2854 	}
2855 
2856 	vfree(buf);
2857 
2858 	plog(LLV_DEBUG, LOCATION, NULL, "IV computed:\n");
2859 	plogdump(LLV_DEBUG, newivm->iv->v, newivm->iv->l);
2860 
2861 	iph1->ivm = newivm;
2862 
2863 	return 0;
2864 }
2865 
2866 /*
2867  * compute IV for the payload after phase 1.
2868  * It's not limited for phase 2.
2869  * if pahse 1 was encrypted.
2870  *	IV = hash(last CBC block of Phase 1 | M-ID)
2871  * if phase 1 was not encrypted.
2872  *	IV = hash(phase 1 IV | M-ID)
2873  * see 4.2 Phase 2 state in draft-ietf-ipsec-ike.
2874  */
2875 struct isakmp_ivm *
2876 oakley_newiv2(iph1, msgid)
2877 	struct ph1handle *iph1;
2878 	u_int32_t msgid;
2879 {
2880 	struct isakmp_ivm *newivm = NULL;
2881 	vchar_t *buf = NULL;
2882 	char *p;
2883 	int len;
2884 	int error = -1;
2885 
2886 	/* create buffer */
2887 	len = iph1->ivm->iv->l + sizeof(msgid_t);
2888 	buf = vmalloc(len);
2889 	if (buf == NULL) {
2890 		plog(LLV_ERROR, LOCATION, NULL,
2891 			"failed to get iv buffer\n");
2892 		goto end;
2893 	}
2894 
2895 	p = buf->v;
2896 
2897 	memcpy(p, iph1->ivm->iv->v, iph1->ivm->iv->l);
2898 	p += iph1->ivm->iv->l;
2899 
2900 	memcpy(p, &msgid, sizeof(msgid));
2901 
2902 	plog(LLV_DEBUG, LOCATION, NULL, "compute IV for phase2\n");
2903 	plog(LLV_DEBUG, LOCATION, NULL, "phase1 last IV:\n");
2904 	plogdump(LLV_DEBUG, buf->v, buf->l);
2905 
2906 	/* allocate IVm */
2907 	newivm = racoon_calloc(1, sizeof(struct isakmp_ivm));
2908 	if (newivm == NULL) {
2909 		plog(LLV_ERROR, LOCATION, NULL,
2910 			"failed to get iv buffer\n");
2911 		goto end;
2912 	}
2913 
2914 	/* compute IV */
2915 	if ((newivm->iv = oakley_hash(buf, iph1)) == NULL)
2916 		goto end;
2917 
2918 	/* adjust length of iv */
2919 	newivm->iv->l = alg_oakley_encdef_blocklen(iph1->approval->enctype);
2920 	if (newivm->iv->l == -1) {
2921 		plog(LLV_ERROR, LOCATION, NULL,
2922 			"invalid encryption algorithm %d.\n",
2923 			iph1->approval->enctype);
2924 		goto end;
2925 	}
2926 
2927 	/* create buffer to save new iv */
2928 	if ((newivm->ive = vdup(newivm->iv)) == NULL) {
2929 		plog(LLV_ERROR, LOCATION, NULL, "vdup (%s)\n", strerror(errno));
2930 		goto end;
2931 	}
2932 
2933 	error = 0;
2934 
2935 	plog(LLV_DEBUG, LOCATION, NULL, "phase2 IV computed:\n");
2936 	plogdump(LLV_DEBUG, newivm->iv->v, newivm->iv->l);
2937 
2938 end:
2939 	if (error && newivm != NULL){
2940 		oakley_delivm(newivm);
2941 		newivm=NULL;
2942 	}
2943 	if (buf != NULL)
2944 		vfree(buf);
2945 	return newivm;
2946 }
2947 
2948 void
2949 oakley_delivm(ivm)
2950 	struct isakmp_ivm *ivm;
2951 {
2952 	if (ivm == NULL)
2953 		return;
2954 
2955 	if (ivm->iv != NULL)
2956 		vfree(ivm->iv);
2957 	if (ivm->ive != NULL)
2958 		vfree(ivm->ive);
2959 	racoon_free(ivm);
2960 	plog(LLV_DEBUG, LOCATION, NULL, "IV freed\n");
2961 
2962 	return;
2963 }
2964 
2965 /*
2966  * decrypt packet.
2967  *   save new iv and old iv.
2968  */
2969 vchar_t *
2970 oakley_do_decrypt(iph1, msg, ivdp, ivep)
2971 	struct ph1handle *iph1;
2972 	vchar_t *msg, *ivdp, *ivep;
2973 {
2974 	vchar_t *buf = NULL, *new = NULL;
2975 	char *pl;
2976 	int len;
2977 	u_int8_t padlen;
2978 	int blen;
2979 	int error = -1;
2980 
2981 	plog(LLV_DEBUG, LOCATION, NULL, "begin decryption.\n");
2982 
2983 	blen = alg_oakley_encdef_blocklen(iph1->approval->enctype);
2984 	if (blen == -1) {
2985 		plog(LLV_ERROR, LOCATION, NULL,
2986 			"invalid encryption algorithm %d.\n",
2987 			iph1->approval->enctype);
2988 		goto end;
2989 	}
2990 
2991 	/* save IV for next, but not sync. */
2992 	memset(ivep->v, 0, ivep->l);
2993 	memcpy(ivep->v, (caddr_t)&msg->v[msg->l - blen], blen);
2994 
2995 	plog(LLV_DEBUG, LOCATION, NULL,
2996 		"IV was saved for next processing:\n");
2997 	plogdump(LLV_DEBUG, ivep->v, ivep->l);
2998 
2999 	pl = msg->v + sizeof(struct isakmp);
3000 
3001 	len = msg->l - sizeof(struct isakmp);
3002 
3003 	/* create buffer */
3004 	buf = vmalloc(len);
3005 	if (buf == NULL) {
3006 		plog(LLV_ERROR, LOCATION, NULL,
3007 			"failed to get buffer to decrypt.\n");
3008 		goto end;
3009 	}
3010 	memcpy(buf->v, pl, len);
3011 
3012 	/* do decrypt */
3013 	new = alg_oakley_encdef_decrypt(iph1->approval->enctype,
3014 					buf, iph1->key, ivdp);
3015 	if (new == NULL || new->v == NULL || new->l == 0) {
3016 		plog(LLV_ERROR, LOCATION, NULL,
3017 			"decryption %d failed.\n", iph1->approval->enctype);
3018 		goto end;
3019 	}
3020 	plog(LLV_DEBUG, LOCATION, NULL, "with key:\n");
3021 	plogdump(LLV_DEBUG, iph1->key->v, iph1->key->l);
3022 
3023 	vfree(buf);
3024 	buf = NULL;
3025 
3026 	plog(LLV_DEBUG, LOCATION, NULL, "decrypted payload by IV:\n");
3027 	plogdump(LLV_DEBUG, ivdp->v, ivdp->l);
3028 
3029 	plog(LLV_DEBUG, LOCATION, NULL,
3030 		"decrypted payload, but not trimed.\n");
3031 	plogdump(LLV_DEBUG, new->v, new->l);
3032 
3033 	/* get padding length */
3034 	if (lcconf->pad_excltail)
3035 		padlen = new->v[new->l - 1] + 1;
3036 	else
3037 		padlen = new->v[new->l - 1];
3038 	plog(LLV_DEBUG, LOCATION, NULL, "padding len=%u\n", padlen);
3039 
3040 	/* trim padding */
3041 	if (lcconf->pad_strict) {
3042 		if (padlen > new->l) {
3043 			plog(LLV_ERROR, LOCATION, NULL,
3044 				"invalied padding len=%u, buflen=%zu.\n",
3045 				padlen, new->l);
3046 			plogdump(LLV_ERROR, new->v, new->l);
3047 			goto end;
3048 		}
3049 		new->l -= padlen;
3050 		plog(LLV_DEBUG, LOCATION, NULL, "trimmed padding\n");
3051 	} else {
3052 		plog(LLV_DEBUG, LOCATION, NULL, "skip to trim padding.\n");
3053 	}
3054 
3055 	/* create new buffer */
3056 	len = sizeof(struct isakmp) + new->l;
3057 	buf = vmalloc(len);
3058 	if (buf == NULL) {
3059 		plog(LLV_ERROR, LOCATION, NULL,
3060 			"failed to get buffer to decrypt.\n");
3061 		goto end;
3062 	}
3063 	memcpy(buf->v, msg->v, sizeof(struct isakmp));
3064 	memcpy(buf->v + sizeof(struct isakmp), new->v, new->l);
3065 	((struct isakmp *)buf->v)->len = htonl(buf->l);
3066 
3067 	plog(LLV_DEBUG, LOCATION, NULL, "decrypted.\n");
3068 	plogdump(LLV_DEBUG, buf->v, buf->l);
3069 
3070 #ifdef HAVE_PRINT_ISAKMP_C
3071 	isakmp_printpacket(buf, iph1->remote, iph1->local, 1);
3072 #endif
3073 
3074 	error = 0;
3075 
3076 end:
3077 	if (error && buf != NULL) {
3078 		vfree(buf);
3079 		buf = NULL;
3080 	}
3081 	if (new != NULL)
3082 		vfree(new);
3083 
3084 	return buf;
3085 }
3086 
3087 /*
3088  * encrypt packet.
3089  */
3090 vchar_t *
3091 oakley_do_encrypt(iph1, msg, ivep, ivp)
3092 	struct ph1handle *iph1;
3093 	vchar_t *msg, *ivep, *ivp;
3094 {
3095 	vchar_t *buf = 0, *new = 0;
3096 	char *pl;
3097 	int len;
3098 	u_int padlen;
3099 	int blen;
3100 	int error = -1;
3101 
3102 	plog(LLV_DEBUG, LOCATION, NULL, "begin encryption.\n");
3103 
3104 	/* set cbc block length */
3105 	blen = alg_oakley_encdef_blocklen(iph1->approval->enctype);
3106 	if (blen == -1) {
3107 		plog(LLV_ERROR, LOCATION, NULL,
3108 			"invalid encryption algorithm %d.\n",
3109 			iph1->approval->enctype);
3110 		goto end;
3111 	}
3112 
3113 	pl = msg->v + sizeof(struct isakmp);
3114 	len = msg->l - sizeof(struct isakmp);
3115 
3116 	/* add padding */
3117 	padlen = oakley_padlen(len, blen);
3118 	plog(LLV_DEBUG, LOCATION, NULL, "pad length = %u\n", padlen);
3119 
3120 	/* create buffer */
3121 	buf = vmalloc(len + padlen);
3122 	if (buf == NULL) {
3123 		plog(LLV_ERROR, LOCATION, NULL,
3124 			"failed to get buffer to encrypt.\n");
3125 		goto end;
3126 	}
3127         if (padlen) {
3128                 int i;
3129 		char *p = &buf->v[len];
3130 		if (lcconf->pad_random) {
3131 			for (i = 0; i < padlen; i++)
3132 				*p++ = eay_random() & 0xff;
3133 		}
3134         }
3135         memcpy(buf->v, pl, len);
3136 
3137 	/* make pad into tail */
3138 	if (lcconf->pad_excltail)
3139 		buf->v[len + padlen - 1] = padlen - 1;
3140 	else
3141 		buf->v[len + padlen - 1] = padlen;
3142 
3143 	plogdump(LLV_DEBUG, buf->v, buf->l);
3144 
3145 	/* do encrypt */
3146 	new = alg_oakley_encdef_encrypt(iph1->approval->enctype,
3147 					buf, iph1->key, ivep);
3148 	if (new == NULL) {
3149 		plog(LLV_ERROR, LOCATION, NULL,
3150 			"encryption %d failed.\n", iph1->approval->enctype);
3151 		goto end;
3152 	}
3153 	plog(LLV_DEBUG, LOCATION, NULL, "with key:\n");
3154 	plogdump(LLV_DEBUG, iph1->key->v, iph1->key->l);
3155 
3156 	vfree(buf);
3157 	buf = NULL;
3158 
3159 	plog(LLV_DEBUG, LOCATION, NULL, "encrypted payload by IV:\n");
3160 	plogdump(LLV_DEBUG, ivep->v, ivep->l);
3161 
3162 	/* save IV for next */
3163 	memset(ivp->v, 0, ivp->l);
3164 	memcpy(ivp->v, (caddr_t)&new->v[new->l - blen], blen);
3165 
3166 	plog(LLV_DEBUG, LOCATION, NULL, "save IV for next:\n");
3167 	plogdump(LLV_DEBUG, ivp->v, ivp->l);
3168 
3169 	/* create new buffer */
3170 	len = sizeof(struct isakmp) + new->l;
3171 	buf = vmalloc(len);
3172 	if (buf == NULL) {
3173 		plog(LLV_ERROR, LOCATION, NULL,
3174 			"failed to get buffer to encrypt.\n");
3175 		goto end;
3176 	}
3177 	memcpy(buf->v, msg->v, sizeof(struct isakmp));
3178 	memcpy(buf->v + sizeof(struct isakmp), new->v, new->l);
3179 	((struct isakmp *)buf->v)->len = htonl(buf->l);
3180 
3181 	error = 0;
3182 
3183 	plog(LLV_DEBUG, LOCATION, NULL, "encrypted.\n");
3184 
3185 end:
3186 	if (error && buf != NULL) {
3187 		vfree(buf);
3188 		buf = NULL;
3189 	}
3190 	if (new != NULL)
3191 		vfree(new);
3192 
3193 	return buf;
3194 }
3195 
3196 /* culculate padding length */
3197 static int
3198 oakley_padlen(len, base)
3199 	int len, base;
3200 {
3201 	int padlen;
3202 
3203 	padlen = base - len % base;
3204 
3205 	if (lcconf->pad_randomlen)
3206 		padlen += ((eay_random() % (lcconf->pad_maxsize + 1) + 1) *
3207 		    base);
3208 
3209 	return padlen;
3210 }
3211 
3212