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