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