| /* $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: |
| handle_vendorid(iph1, 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; |
| } |
| |