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