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