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