1 /* $NetBSD: isakmp_newg.c,v 1.4 2006/09/09 16:22:09 manu Exp $ */ 2 3 /* $KAME: isakmp_newg.c,v 1.10 2002/09/27 05:55:52 itojun 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 39 #include <stdlib.h> 40 #include <stdio.h> 41 #include <string.h> 42 #include <errno.h> 43 44 #include "var.h" 45 #include "misc.h" 46 #include "vmbuf.h" 47 #include "plog.h" 48 #include "sockmisc.h" 49 #include "debug.h" 50 51 #include "schedule.h" 52 #include "cfparse_proto.h" 53 #include "isakmp_var.h" 54 #include "isakmp.h" 55 #include "isakmp_newg.h" 56 #include "oakley.h" 57 #include "ipsec_doi.h" 58 #include "crypto_openssl.h" 59 #include "handler.h" 60 #include "pfkey.h" 61 #include "admin.h" 62 #include "str2val.h" 63 #include "vendorid.h" 64 65 /* 66 * New group mode as responder 67 */ 68 int 69 isakmp_newgroup_r(iph1, msg) 70 struct ph1handle *iph1; 71 vchar_t *msg; 72 { 73 #if 0 74 struct isakmp *isakmp = (struct isakmp *)msg->v; 75 struct isakmp_pl_hash *hash = NULL; 76 struct isakmp_pl_sa *sa = NULL; 77 int error = -1; 78 vchar_t *buf; 79 struct oakley_sa *osa; 80 int len; 81 82 /* validate the type of next payload */ 83 /* 84 * ISAKMP_ETYPE_NEWGRP, 85 * ISAKMP_NPTYPE_HASH, (ISAKMP_NPTYPE_VID), ISAKMP_NPTYPE_SA, 86 * ISAKMP_NPTYPE_NONE 87 */ 88 { 89 vchar_t *pbuf = NULL; 90 struct isakmp_parse_t *pa; 91 92 if ((pbuf = isakmp_parse(msg)) == NULL) 93 goto end; 94 95 for (pa = (struct isakmp_parse_t *)pbuf->v; 96 pa->type != ISAKMP_NPTYPE_NONE; 97 pa++) { 98 99 switch (pa->type) { 100 case ISAKMP_NPTYPE_HASH: 101 if (hash) { 102 isakmp_info_send_n1(iph1, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE, NULL); 103 plog(LLV_ERROR, LOCATION, iph1->remote, 104 "received multiple payload type %d.\n", 105 pa->type); 106 vfree(pbuf); 107 goto end; 108 } 109 hash = (struct isakmp_pl_hash *)pa->ptr; 110 break; 111 case ISAKMP_NPTYPE_SA: 112 if (sa) { 113 isakmp_info_send_n1(iph1, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE, NULL); 114 plog(LLV_ERROR, LOCATION, iph1->remote, 115 "received multiple payload type %d.\n", 116 pa->type); 117 vfree(pbuf); 118 goto end; 119 } 120 sa = (struct isakmp_pl_sa *)pa->ptr; 121 break; 122 case ISAKMP_NPTYPE_VID: 123 handle_vendorid(iph1, pa->ptr); 124 break; 125 default: 126 isakmp_info_send_n1(iph1, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE, NULL); 127 plog(LLV_ERROR, LOCATION, iph1->remote, 128 "ignore the packet, " 129 "received unexpecting payload type %d.\n", 130 pa->type); 131 vfree(pbuf); 132 goto end; 133 } 134 } 135 vfree(pbuf); 136 137 if (!hash || !sa) { 138 isakmp_info_send_n1(iph1, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE, NULL); 139 plog(LLV_ERROR, LOCATION, iph1->remote, 140 "no HASH, or no SA payload.\n"); 141 goto end; 142 } 143 } 144 145 /* validate HASH */ 146 { 147 char *r_hash; 148 vchar_t *my_hash = NULL; 149 int result; 150 151 plog(LLV_DEBUG, LOCATION, NULL, "validate HASH\n"); 152 153 len = sizeof(isakmp->msgid) + ntohs(sa->h.len); 154 buf = vmalloc(len); 155 if (buf == NULL) { 156 plog(LLV_ERROR, LOCATION, NULL, 157 "failed to get buffer to send.\n"); 158 goto end; 159 } 160 memcpy(buf->v, &isakmp->msgid, sizeof(isakmp->msgid)); 161 memcpy(buf->v + sizeof(isakmp->msgid), sa, ntohs(sa->h.len)); 162 163 plog(LLV_DEBUG, LOCATION, NULL, "hash source\n"); 164 plogdump(LLV_DEBUG, buf->v, buf->l); 165 166 my_hash = isakmp_prf(iph1->skeyid_a, buf, iph1); 167 vfree(buf); 168 if (my_hash == NULL) 169 goto end; 170 171 plog(LLV_DEBUG, LOCATION, NULL, "hash result\n"); 172 plogdump(LLV_DEBUG, my_hash->v, my_hash->l); 173 174 r_hash = (char *)hash + sizeof(*hash); 175 176 plog(LLV_DEBUG, LOCATION, NULL, "original hash\n")); 177 plogdump(LLV_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash))); 178 179 result = memcmp(my_hash->v, r_hash, my_hash->l); 180 vfree(my_hash); 181 182 if (result) { 183 plog(LLV_ERROR, LOCATION, iph1->remote, 184 "HASH mismatch.\n"); 185 isakmp_info_send_n1(iph1, ISAKMP_NTYPE_INVALID_HASH_INFORMATION, NULL); 186 goto end; 187 } 188 } 189 190 /* check SA payload and get new one for use */ 191 buf = ipsecdoi_get_proposal((struct ipsecdoi_sa *)sa, 192 OAKLEY_NEWGROUP_MODE); 193 if (buf == NULL) { 194 isakmp_info_send_n1(iph1, ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED, NULL); 195 goto end; 196 } 197 198 /* save sa parameters */ 199 osa = ipsecdoi_get_oakley(buf); 200 if (osa == NULL) { 201 isakmp_info_send_n1(iph1, ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED, NULL); 202 goto end; 203 } 204 vfree(buf); 205 206 switch (osa->dhgrp) { 207 case OAKLEY_ATTR_GRP_DESC_MODP768: 208 case OAKLEY_ATTR_GRP_DESC_MODP1024: 209 case OAKLEY_ATTR_GRP_DESC_MODP1536: 210 /*XXX*/ 211 default: 212 isakmp_info_send_n1(iph1, ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED, NULL); 213 plog(LLV_ERROR, LOCATION, NULL, 214 "dh group %d isn't supported.\n", osa->dhgrp); 215 goto end; 216 } 217 218 plog(LLV_INFO, LOCATION, iph1->remote, 219 "got new dh group %s.\n", isakmp_pindex(&iph1->index, 0)); 220 221 error = 0; 222 223 end: 224 if (error) { 225 if (iph1 != NULL) 226 (void)isakmp_free_ph1(iph1); 227 } 228 return error; 229 #endif 230 return 0; 231 } 232 233