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