/*	$NetBSD: isakmp_newg.c,v 1.4 2006/09/09 16:22:09 manu Exp $	*/

/*	$KAME: isakmp_newg.c,v 1.10 2002/09/27 05:55:52 itojun Exp $	*/

/*
 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the project nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include "config.h"

#include <sys/types.h>
#include <sys/param.h>

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

#include "var.h"
#include "misc.h"
#include "vmbuf.h"
#include "plog.h"
#include "sockmisc.h"
#include "debug.h"

#include "schedule.h"
#include "cfparse_proto.h"
#include "isakmp_var.h"
#include "isakmp.h"
#include "isakmp_newg.h"
#include "oakley.h"
#include "ipsec_doi.h"
#include "crypto_openssl.h"
#include "handler.h"
#include "pfkey.h"
#include "admin.h"
#include "str2val.h"
#include "vendorid.h"

/*
 * New group mode as responder
 */
int
isakmp_newgroup_r(iph1, msg)
	struct ph1handle *iph1;
	vchar_t *msg;
{
#if 0
	struct isakmp *isakmp = (struct isakmp *)msg->v;
	struct isakmp_pl_hash *hash = NULL;
	struct isakmp_pl_sa *sa = NULL;
	int error = -1;
	vchar_t *buf;
	struct oakley_sa *osa;
	int len;

	/* validate the type of next payload */
	/*
	 * ISAKMP_ETYPE_NEWGRP,
	 * ISAKMP_NPTYPE_HASH, (ISAKMP_NPTYPE_VID), ISAKMP_NPTYPE_SA,
	 * ISAKMP_NPTYPE_NONE
	 */
    {
	vchar_t *pbuf = NULL;
	struct isakmp_parse_t *pa;

	if ((pbuf = isakmp_parse(msg)) == NULL)
		goto end;

	for (pa = (struct isakmp_parse_t *)pbuf->v;
	     pa->type != ISAKMP_NPTYPE_NONE;
	     pa++) {

		switch (pa->type) {
		case ISAKMP_NPTYPE_HASH:
			if (hash) {
				isakmp_info_send_n1(iph1, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE, NULL);
				plog(LLV_ERROR, LOCATION, iph1->remote,
					"received multiple payload type %d.\n",
					pa->type);
				vfree(pbuf);
				goto end;
			}
			hash = (struct isakmp_pl_hash *)pa->ptr;
			break;
		case ISAKMP_NPTYPE_SA:
			if (sa) {
				isakmp_info_send_n1(iph1, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE, NULL);
				plog(LLV_ERROR, LOCATION, iph1->remote,
					"received multiple payload type %d.\n",
					pa->type);
				vfree(pbuf);
				goto end;
			}
			sa = (struct isakmp_pl_sa *)pa->ptr;
			break;
		case ISAKMP_NPTYPE_VID:
			(void)check_vendorid(pa->ptr);
			break;
		default:
			isakmp_info_send_n1(iph1, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE, NULL);
			plog(LLV_ERROR, LOCATION, iph1->remote,
				"ignore the packet, "
				"received unexpecting payload type %d.\n",
				pa->type);
			vfree(pbuf);
			goto end;
		}
	}
	vfree(pbuf);

	if (!hash || !sa) {
		isakmp_info_send_n1(iph1, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE, NULL);
		plog(LLV_ERROR, LOCATION, iph1->remote,
			"no HASH, or no SA payload.\n");
		goto end;
	}
    }

	/* validate HASH */
    {
	char *r_hash;
	vchar_t *my_hash = NULL;
	int result;

	plog(LLV_DEBUG, LOCATION, NULL, "validate HASH\n");

	len = sizeof(isakmp->msgid) + ntohs(sa->h.len);
	buf = vmalloc(len);
	if (buf == NULL) {
		plog(LLV_ERROR, LOCATION, NULL,
			"failed to get buffer to send.\n");
		goto end;
	}
	memcpy(buf->v, &isakmp->msgid, sizeof(isakmp->msgid));
	memcpy(buf->v + sizeof(isakmp->msgid), sa, ntohs(sa->h.len));

	plog(LLV_DEBUG, LOCATION, NULL, "hash source\n");
	plogdump(LLV_DEBUG, buf->v, buf->l);

	my_hash = isakmp_prf(iph1->skeyid_a, buf, iph1);
	vfree(buf);
	if (my_hash == NULL)
		goto end;

	plog(LLV_DEBUG, LOCATION, NULL, "hash result\n");
	plogdump(LLV_DEBUG, my_hash->v, my_hash->l);

	r_hash = (char *)hash + sizeof(*hash);

	plog(LLV_DEBUG, LOCATION, NULL, "original hash\n"));
	plogdump(LLV_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash)));

	result = memcmp(my_hash->v, r_hash, my_hash->l);
	vfree(my_hash);

	if (result) {
		plog(LLV_ERROR, LOCATION, iph1->remote,
			"HASH mismatch.\n");
		isakmp_info_send_n1(iph1, ISAKMP_NTYPE_INVALID_HASH_INFORMATION, NULL);
		goto end;
	}
    }

	/* check SA payload and get new one for use */
	buf = ipsecdoi_get_proposal((struct ipsecdoi_sa *)sa,
					OAKLEY_NEWGROUP_MODE);
	if (buf == NULL) {
		isakmp_info_send_n1(iph1, ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED, NULL);
		goto end;
	}

	/* save sa parameters */
	osa = ipsecdoi_get_oakley(buf);
	if (osa == NULL) {
		isakmp_info_send_n1(iph1, ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED, NULL);
		goto end;
	}
	vfree(buf);

	switch (osa->dhgrp) {
	case OAKLEY_ATTR_GRP_DESC_MODP768:
	case OAKLEY_ATTR_GRP_DESC_MODP1024:
	case OAKLEY_ATTR_GRP_DESC_MODP1536:
		/*XXX*/
	default:
		isakmp_info_send_n1(iph1, ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED, NULL);
		plog(LLV_ERROR, LOCATION, NULL,
			"dh group %d isn't supported.\n", osa->dhgrp);
		goto end;
	}

	plog(LLV_INFO, LOCATION, iph1->remote,
		"got new dh group %s.\n", isakmp_pindex(&iph1->index, 0));

	error = 0;

end:
	if (error) {
		if (iph1 != NULL)
			(void)isakmp_free_ph1(iph1);
	}
	return error;
#endif
	return 0;
}

