File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / ipsec-tools / src / racoon / oakley.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 16:37:11 2014 UTC (10 years, 1 month ago) by misho
Branches: ipsec-tools, MAIN
CVS tags: v0_8_2p2, v0_8_1p0, v0_8_1, HEAD
ipsec-tools 0.8.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>