1 /* $KAME: isakmp_newg.c,v 1.10 2002/09/27 05:55:52 itojun Exp $ */
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/types.h>
33 #include <sys/param.h>
49 #include "isakmp_var.h"
51 #include "isakmp_newg.h"
53 #include "ipsec_doi.h"
54 #include "crypto_openssl.h"
62 * New group mode as responder
65 isakmp_newgroup_r(iph1
, msg
)
66 struct ph1handle
*iph1
;
70 struct isakmp
*isakmp
= (struct isakmp
*)msg
->v
;
71 struct isakmp_pl_hash
*hash
= NULL
;
72 struct isakmp_pl_sa
*sa
= NULL
;
75 struct oakley_sa
*osa
;
78 /* validate the type of next payload */
80 * ISAKMP_ETYPE_NEWGRP,
81 * ISAKMP_NPTYPE_HASH, (ISAKMP_NPTYPE_VID), ISAKMP_NPTYPE_SA,
86 struct isakmp_parse_t
*pa
;
88 if ((pbuf
= isakmp_parse(msg
)) == NULL
)
91 for (pa
= (struct isakmp_parse_t
*)pbuf
->v
;
92 pa
->type
!= ISAKMP_NPTYPE_NONE
;
96 case ISAKMP_NPTYPE_HASH
:
98 isakmp_info_send_n1(iph1
, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE
, NULL
);
99 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
100 "received multiple payload type %d.\n",
105 hash
= (struct isakmp_pl_hash
*)pa
->ptr
;
107 case ISAKMP_NPTYPE_SA
:
109 isakmp_info_send_n1(iph1
, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE
, NULL
);
110 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
111 "received multiple payload type %d.\n",
116 sa
= (struct isakmp_pl_sa
*)pa
->ptr
;
118 case ISAKMP_NPTYPE_VID
:
119 (void)check_vendorid(pa
->ptr
);
122 isakmp_info_send_n1(iph1
, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE
, NULL
);
123 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
124 "ignore the packet, "
125 "received unexpecting payload type %d.\n",
134 isakmp_info_send_n1(iph1
, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE
, NULL
);
135 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
136 "no HASH, or no SA payload.\n");
144 vchar_t
*my_hash
= NULL
;
147 plog(LLV_DEBUG
, LOCATION
, NULL
, "validate HASH\n");
149 len
= sizeof(isakmp
->msgid
) + ntohs(sa
->h
.len
);
152 plog(LLV_ERROR
, LOCATION
, NULL
,
153 "failed to get buffer to send.\n");
156 memcpy(buf
->v
, &isakmp
->msgid
, sizeof(isakmp
->msgid
));
157 memcpy(buf
->v
+ sizeof(isakmp
->msgid
), sa
, ntohs(sa
->h
.len
));
159 plog(LLV_DEBUG
, LOCATION
, NULL
, "hash source\n");
160 plogdump(LLV_DEBUG
, buf
->v
, buf
->l
);
162 my_hash
= isakmp_prf(iph1
->skeyid_a
, buf
, iph1
);
167 plog(LLV_DEBUG
, LOCATION
, NULL
, "hash result\n");
168 plogdump(LLV_DEBUG
, my_hash
->v
, my_hash
->l
);
170 r_hash
= (char *)hash
+ sizeof(*hash
);
172 plog(LLV_DEBUG
, LOCATION
, NULL
, "original hash\n"));
173 plogdump(LLV_DEBUG
, r_hash
, ntohs(hash
->h
.len
) - sizeof(*hash
)));
175 result
= memcmp(my_hash
->v
, r_hash
, my_hash
->l
);
179 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
181 isakmp_info_send_n1(iph1
, ISAKMP_NTYPE_INVALID_HASH_INFORMATION
, NULL
);
186 /* check SA payload and get new one for use */
187 buf
= ipsecdoi_get_proposal((struct ipsecdoi_sa
*)sa
,
188 OAKLEY_NEWGROUP_MODE
);
190 isakmp_info_send_n1(iph1
, ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED
, NULL
);
194 /* save sa parameters */
195 osa
= ipsecdoi_get_oakley(buf
);
197 isakmp_info_send_n1(iph1
, ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED
, NULL
);
202 switch (osa
->dhgrp
) {
203 case OAKLEY_ATTR_GRP_DESC_MODP768
:
204 case OAKLEY_ATTR_GRP_DESC_MODP1024
:
205 case OAKLEY_ATTR_GRP_DESC_MODP1536
:
208 isakmp_info_send_n1(iph1
, ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED
, NULL
);
209 plog(LLV_ERROR
, LOCATION
, NULL
,
210 "dh group %d isn't supported.\n", osa
->dhgrp
);
214 plog(LLV_INFO
, LOCATION
, iph1
->remote
,
215 "got new dh group %s.\n", isakmp_pindex(&iph1
->index
, 0));
222 (void)isakmp_free_ph1(iph1
);