]> git.saurik.com Git - apple/network_cmds.git/blame - racoon.tproj/isakmp_agg.c
network_cmds-176.tar.gz
[apple/network_cmds.git] / racoon.tproj / isakmp_agg.c
CommitLineData
ac2f15b3 1/* $KAME: isakmp_agg.c,v 1.55 2001/12/12 15:29:13 sakane Exp $ */
7ba0088d
A
2
3/*
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
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.
18 *
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
29 * SUCH DAMAGE.
30 */
31
32/* Aggressive Exchange (Aggressive Mode) */
33
34#include <sys/types.h>
35#include <sys/param.h>
36
37#include <stdlib.h>
38#include <stdio.h>
39#include <string.h>
40#include <errno.h>
41#if TIME_WITH_SYS_TIME
42# include <sys/time.h>
43# include <time.h>
44#else
45# if HAVE_SYS_TIME_H
46# include <sys/time.h>
47# else
48# include <time.h>
49# endif
50#endif
ac2f15b3 51#include <netinet/in.h>
7ba0088d
A
52
53#include "var.h"
54#include "misc.h"
55#include "vmbuf.h"
56#include "plog.h"
57#include "sockmisc.h"
58#include "schedule.h"
59#include "debug.h"
60
61#include "localconf.h"
62#include "remoteconf.h"
63#include "isakmp_var.h"
64#include "isakmp.h"
65#include "oakley.h"
66#include "handler.h"
67#include "ipsec_doi.h"
68#include "crypto_openssl.h"
69#include "pfkey.h"
70#include "isakmp_agg.h"
71#include "isakmp_inf.h"
ac2f15b3 72#include "isakmp_natd.h"
7ba0088d
A
73#include "vendorid.h"
74#include "strnames.h"
75
76#ifdef HAVE_GSSAPI
77#include "gssapi.h"
78#endif
79
80/*
81 * begin Aggressive Mode as initiator.
82 */
83/*
84 * send to responder
85 * psk: HDR, SA, KE, Ni, IDi1
86 * sig: HDR, SA, KE, Ni, IDi1 [, CR ]
87 * gssapi: HDR, SA, KE, Ni, IDi1, GSSi
88 * rsa: HDR, SA, [ HASH(1),] KE, <IDi1_b>Pubkey_r, <Ni_b>Pubkey_r
89 * rev: HDR, SA, [ HASH(1),] <Ni_b>Pubkey_r, <KE_b>Ke_i,
90 * <IDii_b>Ke_i [, <Cert-I_b>Ke_i ]
91 */
92int
93agg_i1send(iph1, msg)
94 struct ph1handle *iph1;
95 vchar_t *msg; /* must be null */
96{
97 struct isakmp_gen *gen;
98 caddr_t p;
99 int tlen;
100 int need_cr = 0;
101 vchar_t *cr = NULL, *gsstoken = NULL;
ac2f15b3 102 vchar_t *vid = NULL;
7ba0088d
A
103 int error = -1;
104 int nptype;
105#ifdef HAVE_GSSAPI
106 int len;
107#endif
108
109 /* validity check */
110 if (msg != NULL) {
111 plog(LLV_ERROR, LOCATION, NULL,
112 "msg has to be NULL in this function.\n");
113 goto end;
114 }
115 if (iph1->status != PHASE1ST_START) {
116 plog(LLV_ERROR, LOCATION, NULL,
117 "status mismatched %d.\n", iph1->status);
118 goto end;
119 }
120
121 /* create isakmp index */
122 memset(&iph1->index, 0, sizeof(iph1->index));
123 isakmp_newcookie((caddr_t)&iph1->index, iph1->remote, iph1->local);
124
125 /* make ID payload into isakmp status */
126 if (ipsecdoi_setid1(iph1) < 0)
127 goto end;
128
129 /* create SA payload for my proposal */
130 iph1->sa = ipsecdoi_setph1proposal(iph1->rmconf->proposal);
131 if (iph1->sa == NULL)
132 goto end;
133
134 /* consistency check of proposals */
135 if (iph1->rmconf->dhgrp == NULL) {
136 plog(LLV_ERROR, LOCATION, NULL,
137 "configuration failure about DH group.\n");
138 goto end;
139 }
140
141 /* generate DH public value */
142 if (oakley_dh_generate(iph1->rmconf->dhgrp,
143 &iph1->dhpub, &iph1->dhpriv) < 0)
144 goto end;
145
146 /* generate NONCE value */
147 iph1->nonce = eay_set_random(iph1->rmconf->nonce_size);
148 if (iph1->nonce == NULL)
149 goto end;
ac2f15b3
A
150
151#ifdef IKE_NAT_T
152 vid = set_vendorid(VENDORID_NATT);
153#endif
7ba0088d
A
154
155#ifdef HAVE_SIGNING_C
156 /* create CR if need */
157 if (iph1->rmconf->send_cr
158 && oakley_needcr(iph1->rmconf->proposal->authmethod)
159 && iph1->rmconf->peerscertfile == NULL) {
160 need_cr = 1;
161 cr = oakley_getcr(iph1);
162 if (cr == NULL) {
163 plog(LLV_ERROR, LOCATION, NULL,
164 "failed to get cr buffer.\n");
165 goto end;
166 }
167 }
168#endif
169 plog(LLV_DEBUG, LOCATION, NULL, "authmethod is %s\n",
170 s_oakley_attr_method(iph1->rmconf->proposal->authmethod));
171 /* create buffer to send isakmp payload */
172 tlen = sizeof(struct isakmp)
173 + sizeof(*gen) + iph1->sa->l
174 + sizeof(*gen) + iph1->dhpub->l
175 + sizeof(*gen) + iph1->nonce->l
176 + sizeof(*gen) + iph1->id->l;
177 if (need_cr)
178 tlen += sizeof(*gen) + cr->l;
179#ifdef HAVE_GSSAPI
180 if (iph1->rmconf->proposal->authmethod ==
181 OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) {
182 gssapi_get_itoken(iph1, &len);
183 tlen += sizeof (*gen) + len;
184 }
185#endif
ac2f15b3
A
186 if (vid)
187 tlen += sizeof(*gen) + vid->l;
7ba0088d
A
188
189 iph1->sendbuf = vmalloc(tlen);
190 if (iph1->sendbuf == NULL) {
191 plog(LLV_ERROR, LOCATION, NULL,
192 "failed to get buffer to send.\n");
193 goto end;
194 }
195
196 /* set isakmp header */
197 p = set_isakmp_header(iph1->sendbuf, iph1, ISAKMP_NPTYPE_SA);
198 if (p == NULL)
199 goto end;
200
201 /* set SA payload to propose */
202 p = set_isakmp_payload(p, iph1->sa, ISAKMP_NPTYPE_KE);
203
204 /* create isakmp KE payload */
205 p = set_isakmp_payload(p, iph1->dhpub, ISAKMP_NPTYPE_NONCE);
206
207 /* create isakmp NONCE payload */
208 p = set_isakmp_payload(p, iph1->nonce, ISAKMP_NPTYPE_ID);
209
210 /* create isakmp ID payload */
211#ifdef HAVE_GSSAPI
212 if (iph1->rmconf->proposal->authmethod ==
213 OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB)
214 nptype = ISAKMP_NPTYPE_GSS;
215 else
216#endif
217 if (need_cr)
218 nptype = ISAKMP_NPTYPE_CR;
219 else
ac2f15b3 220 nptype = vid ? ISAKMP_NPTYPE_VID : ISAKMP_NPTYPE_NONE;
7ba0088d
A
221
222 p = set_isakmp_payload(p, iph1->id, nptype);
223
224#ifdef HAVE_GSSAPI
225 if (iph1->rmconf->proposal->authmethod ==
226 OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) {
227 gssapi_get_token_to_send(iph1, &gsstoken);
ac2f15b3 228 p = set_isakmp_payload(p, gsstoken, vid ? ISAKMP_NPTYPE_VID : ISAKMP_NPTYPE_NONE);
7ba0088d
A
229 } else
230#endif
231 if (need_cr)
232 /* create isakmp CR payload */
ac2f15b3
A
233 p = set_isakmp_payload(p, cr, vid ? ISAKMP_NPTYPE_VID : ISAKMP_NPTYPE_NONE);
234
235 if (vid)
236 p = set_isakmp_payload(p, vid, ISAKMP_NPTYPE_NONE);
7ba0088d
A
237
238#ifdef HAVE_PRINT_ISAKMP_C
239 isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
240#endif
241
242 /* send the packet, add to the schedule to resend */
243 iph1->retry_counter = iph1->rmconf->retry_counter;
244 if (isakmp_ph1resend(iph1) == -1)
245 goto end;
246
247 iph1->status = PHASE1ST_MSG1SENT;
248
249 error = 0;
250
251end:
252 if (cr)
253 vfree(cr);
254 if (gsstoken)
255 vfree(gsstoken);
ac2f15b3
A
256 if (vid)
257 vfree(vid);
7ba0088d
A
258
259 return error;
260}
261
262/*
263 * receive from responder
264 * psk: HDR, SA, KE, Nr, IDr1, HASH_R
265 * sig: HDR, SA, KE, Nr, IDr1, [ CR, ] [ CERT, ] SIG_R
266 * gssapi: HDR, SA, KE, Nr, IDr1, GSSr, HASH_R
267 * rsa: HDR, SA, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i, HASH_R
268 * rev: HDR, SA, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDir_b>Ke_r, HASH_R
269 */
270int
271agg_i2recv(iph1, msg)
272 struct ph1handle *iph1;
273 vchar_t *msg;
274{
275 vchar_t *pbuf = NULL;
276 struct isakmp_parse_t *pa;
277 vchar_t *satmp = NULL;
278 int error = -1;
279#ifdef HAVE_GSSAPI
280 vchar_t *gsstoken = NULL;
281#endif
282
283 /* validity check */
284 if (iph1->status != PHASE1ST_MSG1SENT) {
285 plog(LLV_ERROR, LOCATION, NULL,
286 "status mismatched %d.\n", iph1->status);
287 goto end;
288 }
289
290 /* validate the type of next payload */
291 pbuf = isakmp_parse(msg);
292 if (pbuf == NULL)
293 goto end;
294 pa = (struct isakmp_parse_t *)pbuf->v;
295
296 iph1->pl_hash = NULL;
297
298 /* SA payload is fixed postion */
299 if (pa->type != ISAKMP_NPTYPE_SA) {
300 plog(LLV_ERROR, LOCATION, iph1->remote,
301 "received invalid next payload type %d, "
302 "expecting %d.\n",
303 pa->type, ISAKMP_NPTYPE_SA);
304 goto end;
305 }
306 if (isakmp_p2ph(&satmp, pa->ptr) < 0)
307 goto end;
308 pa++;
309
310 for (/*nothing*/;
311 pa->type != ISAKMP_NPTYPE_NONE;
312 pa++) {
313
314 switch (pa->type) {
315 case ISAKMP_NPTYPE_KE:
316 if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0)
317 goto end;
318 break;
319 case ISAKMP_NPTYPE_NONCE:
320 if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0)
321 goto end;
322 break;
323 case ISAKMP_NPTYPE_ID:
324 if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0)
325 goto end;
326 break;
327 case ISAKMP_NPTYPE_HASH:
328 iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr;
329 break;
330#ifdef HAVE_SIGNING_C
331 case ISAKMP_NPTYPE_CR:
332 if (oakley_savecr(iph1, pa->ptr) < 0)
333 goto end;
334 break;
335 case ISAKMP_NPTYPE_CERT:
336 if (oakley_savecert(iph1, pa->ptr) < 0)
337 goto end;
338 break;
339 case ISAKMP_NPTYPE_SIG:
340 if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0)
341 goto end;
342 break;
343#endif
344 case ISAKMP_NPTYPE_VID:
ac2f15b3
A
345 if (check_vendorid(pa->ptr) == VENDORID_NATT)
346 {
347#ifdef IKE_NAT_T
348 iph1->natt_flags |= natt_remote_support;
349#endif
350 }
7ba0088d
A
351 break;
352 case ISAKMP_NPTYPE_N:
353 isakmp_check_notify(pa->ptr, iph1);
354 break;
355#ifdef HAVE_GSSAPI
356 case ISAKMP_NPTYPE_GSS:
357 if (isakmp_p2ph(&gsstoken, pa->ptr) < 0)
358 goto end;
359 gssapi_save_received_token(iph1, gsstoken);
360 break;
361#endif
ac2f15b3
A
362 case ISAKMP_NPTYPE_NATD:
363 /*
364 * ignored for now, we need to know the hash
365 * algorithm before we can evaluate the natd
366 * payload.
367 */
368 break;
7ba0088d
A
369 default:
370 /* don't send information, see isakmp_ident_r1() */
371 plog(LLV_ERROR, LOCATION, iph1->remote,
372 "ignore the packet, "
373 "received unexpecting payload type %d.\n",
374 pa->type);
375 goto end;
376 }
377 }
378
379 /* payload existency check */
380 /* XXX to be checked each authentication method. */
381
382 /* verify identifier */
383 if (ipsecdoi_checkid1(iph1) != 0) {
384 plog(LLV_ERROR, LOCATION, iph1->remote,
385 "invalid ID payload.\n");
386 goto end;
387 }
388
389 /* check SA payload and set approval SA for use */
390 if (ipsecdoi_checkph1proposal(satmp, iph1) < 0) {
391 plog(LLV_ERROR, LOCATION, iph1->remote,
392 "failed to get valid proposal.\n");
393 /* XXX send information */
394 goto end;
395 }
396 if (iph1->sa_ret) {
397 vfree(iph1->sa_ret);
398 iph1->sa_ret = NULL;
399 }
400
401 /* fix isakmp index */
402 memcpy(&iph1->index.r_ck, &((struct isakmp *)msg->v)->r_ck,
403 sizeof(cookie_t));
ac2f15b3
A
404
405 /* check natd payloads */
406#ifdef IKE_NAT_T
407 for (pa = (struct isakmp_parse_t *)pbuf->v;
408 pa->type != ISAKMP_NPTYPE_NONE;
409 pa++)
410 {
411 if (pa->type == ISAKMP_NPTYPE_NATD)
412 {
413 natd_match_t match = natd_matches(iph1, pa->ptr);
414 iph1->natt_flags |= natt_natd_received;
415 if ((match & natd_match_local) != 0)
416 iph1->natt_flags |= natt_no_local_nat;
417 if ((match & natd_match_remote) != 0)
418 iph1->natt_flags |= natt_no_remote_nat;
419 }
420 }
421#endif
7ba0088d
A
422
423 /* compute sharing secret of DH */
424 if (oakley_dh_compute(iph1->rmconf->dhgrp, iph1->dhpub,
425 iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0)
426 goto end;
427
428 /* generate SKEYIDs & IV & final cipher key */
429 if (oakley_skeyid(iph1) < 0)
430 goto end;
431 if (oakley_skeyid_dae(iph1) < 0)
432 goto end;
433 if (oakley_compute_enckey(iph1) < 0)
434 goto end;
435 if (oakley_newiv(iph1) < 0)
436 goto end;
ac2f15b3
A
437
438#ifdef IKE_NAT_T
439 /* Determine if we need to switch to port 4500 */
440 if (natd_hasnat(iph1))
441 {
442 /* There is a NAT between us! Switch to port 4500. */
443 if (iph1->remote->sa_family == AF_INET)
444 {
445 struct sockaddr_in *sin = (struct sockaddr_in*)iph1->remote;
446 plog(LLV_INFO, LOCATION, NULL,
447 "detected NAT, switching to port %d for %s",
448 PORT_ISAKMP_NATT, saddr2str(iph1->remote));
449 sin->sin_port = htons(PORT_ISAKMP_NATT);
450 sin = (struct sockaddr_in*)iph1->local;
451 sin->sin_port = htons(PORT_ISAKMP_NATT);
452 }
453 }
454#endif
7ba0088d
A
455
456 /* validate authentication value */
457 {
458 int type;
459 type = oakley_validate_auth(iph1);
460 if (type != 0) {
461 if (type == -1) {
462 /* message printed inner oakley_validate_auth() */
463 goto end;
464 }
465 isakmp_info_send_n1(iph1, type, NULL);
466 goto end;
467 }
468 }
469
470#ifdef HAVE_SIGNING_C
471 if (oakley_checkcr(iph1) < 0) {
472 /* Ignore this error in order to be interoperability. */
473 ;
474 }
475#endif
476
477 /* change status of isakmp status entry */
478 iph1->status = PHASE1ST_MSG2RECEIVED;
479
480 error = 0;
481
482end:
483 if (pbuf)
484 vfree(pbuf);
485 if (satmp)
486 vfree(satmp);
487 if (error) {
488 VPTRINIT(iph1->dhpub_p);
489 VPTRINIT(iph1->nonce_p);
490 VPTRINIT(iph1->id_p);
491 oakley_delcert(iph1->cert_p);
492 iph1->cert_p = NULL;
493 oakley_delcert(iph1->crl_p);
494 iph1->crl_p = NULL;
495 VPTRINIT(iph1->sig_p);
496 oakley_delcert(iph1->cr_p);
497 iph1->cr_p = NULL;
498 }
499
500 return error;
501}
502
503/*
504 * send to responder
505 * psk: HDR, HASH_I
506 * gssapi: HDR, HASH_I
507 * sig: HDR, [ CERT, ] SIG_I
508 * rsa: HDR, HASH_I
509 * rev: HDR, HASH_I
510 */
511int
512agg_i2send(iph1, msg)
513 struct ph1handle *iph1;
514 vchar_t *msg;
515{
516 struct isakmp_gen *gen;
ac2f15b3 517 char *p = NULL;
7ba0088d
A
518 int tlen;
519 int need_cert = 0;
520 int error = -1;
521 vchar_t *gsshash = NULL;
ac2f15b3 522 int need_natd = 0;
7ba0088d
A
523
524 /* validity check */
525 if (iph1->status != PHASE1ST_MSG2RECEIVED) {
526 plog(LLV_ERROR, LOCATION, NULL,
527 "status mismatched %d.\n", iph1->status);
528 goto end;
529 }
530
531 /* generate HASH to send */
532 plog(LLV_DEBUG, LOCATION, NULL, "generate HASH_I\n");
533 iph1->hash = oakley_ph1hash_common(iph1, GENERATE);
534 if (iph1->hash == NULL) {
535#ifdef HAVE_GSSAPI
536 if (gssapi_more_tokens(iph1))
537 isakmp_info_send_n1(iph1,
538 ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL);
539#endif
540 goto end;
541 }
542
543 tlen = sizeof(struct isakmp);
544
ac2f15b3
A
545#ifdef IKE_NAT_T
546 if ((iph1->natt_flags & natt_remote_support) != 0) {
547 need_natd = 1;
548 natd_create(iph1);
549 if (iph1->local_natd)
550 tlen += sizeof(*gen) + iph1->local_natd->l;
551 if (iph1->remote_natd)
552 tlen += sizeof(*gen) + iph1->remote_natd->l;
553 }
554#endif
555
7ba0088d
A
556 switch (iph1->approval->authmethod) {
557 case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
558 tlen += sizeof(*gen) + iph1->hash->l;
559
560 iph1->sendbuf = vmalloc(tlen);
561 if (iph1->sendbuf == NULL) {
562 plog(LLV_ERROR, LOCATION, NULL,
563 "failed to get buffer to send.\n");
564 goto end;
565 }
566
567 /* set isakmp header */
568 p = set_isakmp_header(iph1->sendbuf, iph1, ISAKMP_NPTYPE_HASH);
569 if (p == NULL)
570 goto end;
571
572 /* set HASH payload */
ac2f15b3
A
573 p = set_isakmp_payload(p, iph1->hash,
574 need_natd ? ISAKMP_NPTYPE_NATD
575 : ISAKMP_NPTYPE_NONE);
7ba0088d
A
576 break;
577#ifdef HAVE_SIGNING_C
578 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
579 case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
580 /* XXX if there is CR or not ? */
581
582 if (oakley_getmycert(iph1) < 0)
583 goto end;
584
585 if (oakley_getsign(iph1) < 0)
586 goto end;
587
588 if (iph1->cert != NULL && iph1->rmconf->send_cert)
589 need_cert = 1;
590
591 tlen += sizeof(*gen) + iph1->sig->l;
592 if (need_cert)
593 tlen += sizeof(*gen) + iph1->cert->pl->l;
594
595 iph1->sendbuf = vmalloc(tlen);
596 if (iph1->sendbuf == NULL) {
597 plog(LLV_ERROR, LOCATION, NULL,
598 "failed to get buffer to send.\n");
599 goto end;
600 }
601
602 /* set isakmp header */
603 p = set_isakmp_header(iph1->sendbuf, iph1, need_cert
604 ? ISAKMP_NPTYPE_CERT
605 : ISAKMP_NPTYPE_SIG);
606 if (p == NULL)
607 goto end;
608
609 /* add CERT payload if there */
610 if (need_cert)
611 p = set_isakmp_payload(p, iph1->cert->pl, ISAKMP_NPTYPE_SIG);
612 /* add SIG payload */
ac2f15b3
A
613 p = set_isakmp_payload(p, iph1->sig,
614 need_natd ? ISAKMP_NPTYPE_NATD
615 : ISAKMP_NPTYPE_NONE);
7ba0088d
A
616 break;
617#endif
618 case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
619 case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
620 tlen += sizeof(*gen) + iph1->hash->l;
621 break;
622#ifdef HAVE_GSSAPI
623 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
624 gsshash = gssapi_wraphash(iph1);
625 if (gsshash == NULL) {
626 plog(LLV_ERROR, LOCATION, NULL,
627 "failed to wrap hash\n");
628 isakmp_info_send_n1(iph1,
629 ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL);
630 goto end;
631 }
632 tlen += sizeof(*gen) + gsshash->l;
633
634 iph1->sendbuf = vmalloc(tlen);
635 if (iph1->sendbuf == NULL) {
636 plog(LLV_ERROR, LOCATION, NULL,
637 "failed to get buffer to send.\n");
638 goto end;
639 }
640 /* set isakmp header */
641 p = set_isakmp_header(iph1->sendbuf, iph1, ISAKMP_NPTYPE_HASH);
642 if (p == NULL)
643 goto end;
ac2f15b3
A
644 p = set_isakmp_payload(p, gsshash,
645 need_natd ? ISAKMP_NPTYPE_NATD
646 : ISAKMP_NPTYPE_NONE);
7ba0088d
A
647 break;
648#endif
649 }
650
ac2f15b3
A
651#ifdef IKE_NAT_T
652 if (need_natd) {
653 if (iph1->local_natd)
654 p = set_isakmp_payload(p, iph1->local_natd, ISAKMP_NPTYPE_NATD);
655 if (iph1->remote_natd)
656 p = set_isakmp_payload(p, iph1->remote_natd, ISAKMP_NPTYPE_NONE);
657 }
658#endif
659
7ba0088d
A
660#ifdef HAVE_PRINT_ISAKMP_C
661 isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
662#endif
663
664 /* send to responder */
665 if (isakmp_send(iph1, iph1->sendbuf) < 0)
666 goto end;
667
668 /* the sending message is added to the received-list. */
669 if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
670 plog(LLV_ERROR , LOCATION, NULL,
671 "failed to add a response packet to the tree.\n");
672 goto end;
673 }
674
675 /* set encryption flag */
676 iph1->flags |= ISAKMP_FLAG_E;
677
678 iph1->status = PHASE1ST_ESTABLISHED;
679
680 error = 0;
681
682end:
683 if (gsshash)
684 vfree(gsshash);
685 return error;
686}
687
688/*
689 * receive from initiator
690 * psk: HDR, SA, KE, Ni, IDi1
691 * sig: HDR, SA, KE, Ni, IDi1 [, CR ]
692 * gssapi: HDR, SA, KE, Ni, IDi1 , GSSi
693 * rsa: HDR, SA, [ HASH(1),] KE, <IDi1_b>Pubkey_r, <Ni_b>Pubkey_r
694 * rev: HDR, SA, [ HASH(1),] <Ni_b>Pubkey_r, <KE_b>Ke_i,
695 * <IDii_b>Ke_i [, <Cert-I_b>Ke_i ]
696 */
697int
698agg_r1recv(iph1, msg)
699 struct ph1handle *iph1;
700 vchar_t *msg;
701{
702 int error = -1;
703 vchar_t *pbuf = NULL;
704 struct isakmp_parse_t *pa;
705#ifdef HAVE_GSSAPI
706 vchar_t *gsstoken = NULL;
707#endif
708
709 /* validity check */
710 if (iph1->status != PHASE1ST_START) {
711 plog(LLV_ERROR, LOCATION, NULL,
712 "status mismatched %d.\n", iph1->status);
713 goto end;
714 }
715
716 /* validate the type of next payload */
717 pbuf = isakmp_parse(msg);
718 if (pbuf == NULL)
719 goto end;
720 pa = (struct isakmp_parse_t *)pbuf->v;
721
722 /* SA payload is fixed postion */
723 if (pa->type != ISAKMP_NPTYPE_SA) {
724 plog(LLV_ERROR, LOCATION, iph1->remote,
725 "received invalid next payload type %d, "
726 "expecting %d.\n",
727 pa->type, ISAKMP_NPTYPE_SA);
728 goto end;
729 }
730 if (isakmp_p2ph(&iph1->sa, pa->ptr) < 0)
731 goto end;
732 pa++;
733
734 for (/*nothing*/;
735 pa->type != ISAKMP_NPTYPE_NONE;
736 pa++) {
737
738 plog(LLV_DEBUG, LOCATION, NULL,
739 "received payload of type %s\n",
740 s_isakmp_nptype(pa->type));
741
742 switch (pa->type) {
743 case ISAKMP_NPTYPE_KE:
744 if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0)
745 goto end;
746 break;
747 case ISAKMP_NPTYPE_NONCE:
748 if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0)
749 goto end;
750 break;
751 case ISAKMP_NPTYPE_ID:
752 if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0)
753 goto end;
754 break;
755 case ISAKMP_NPTYPE_VID:
ac2f15b3
A
756 if (check_vendorid(pa->ptr) == VENDORID_NATT)
757 {
758#ifdef IKE_NAT_T
759 iph1->natt_flags |= natt_remote_support;
760#endif
761 }
7ba0088d
A
762 break;
763#ifdef HAVE_SIGNING_C
764 case ISAKMP_NPTYPE_CR:
765 if (oakley_savecr(iph1, pa->ptr) < 0)
766 goto end;
767 break;
768#endif
769#ifdef HAVE_GSSAPI
770 case ISAKMP_NPTYPE_GSS:
771 if (isakmp_p2ph(&gsstoken, pa->ptr) < 0)
772 goto end;
773 gssapi_save_received_token(iph1, gsstoken);
774 break;
775#endif
776 default:
777 /* don't send information, see isakmp_ident_r1() */
778 plog(LLV_ERROR, LOCATION, iph1->remote,
779 "ignore the packet, "
780 "received unexpecting payload type %d.\n",
781 pa->type);
782 goto end;
783 }
784 }
785
786 /* payload existency check */
787 /* XXX to be checked each authentication method. */
788
789 /* verify identifier */
790 if (ipsecdoi_checkid1(iph1) != 0) {
791 plog(LLV_ERROR, LOCATION, iph1->remote,
792 "invalid ID payload.\n");
793 goto end;
794 }
795
796 /* check SA payload and set approval SA for use */
797 if (ipsecdoi_checkph1proposal(iph1->sa, iph1) < 0) {
798 plog(LLV_ERROR, LOCATION, iph1->remote,
799 "failed to get valid proposal.\n");
800 /* XXX send information */
801 goto end;
802 }
803
804#ifdef HAVE_SIGNING_C
805 if (oakley_checkcr(iph1) < 0) {
806 /* Ignore this error in order to be interoperability. */
807 ;
808 }
809#endif
810
811 iph1->status = PHASE1ST_MSG1RECEIVED;
812
813 error = 0;
814
815end:
816 if (pbuf)
817 vfree(pbuf);
818 if (error) {
819 VPTRINIT(iph1->sa);
820 VPTRINIT(iph1->dhpub_p);
821 VPTRINIT(iph1->nonce_p);
822 VPTRINIT(iph1->id_p);
823 oakley_delcert(iph1->cr_p);
824 iph1->cr_p = NULL;
825 }
826
827 return error;
828}
829
830/*
831 * send to initiator
832 * psk: HDR, SA, KE, Nr, IDr1, HASH_R
833 * sig: HDR, SA, KE, Nr, IDr1, [ CR, ] [ CERT, ] SIG_R
834 * gssapi: HDR, SA, KE, Nr, IDr1, GSSr, HASH_R
835 * rsa: HDR, SA, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i, HASH_R
836 * rev: HDR, SA, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDir_b>Ke_r, HASH_R
837 */
838int
839agg_r1send(iph1, msg)
840 struct ph1handle *iph1;
841 vchar_t *msg;
842{
843 struct isakmp_gen *gen;
ac2f15b3 844 char *p = NULL;
7ba0088d
A
845 int tlen;
846 int need_cr = 0;
847 int need_cert = 0;
848 vchar_t *cr = NULL;
849 vchar_t *vid = NULL;
850 int error = -1;
851#ifdef HAVE_GSSAPI
852 int gsslen;
853 vchar_t *gsstoken = NULL, *gsshash = NULL;
854 vchar_t *gss_sa = NULL;
855#endif
ac2f15b3 856 vchar_t *nattvid = NULL;
7ba0088d
A
857
858 /* validity check */
859 if (iph1->status != PHASE1ST_MSG1RECEIVED) {
860 plog(LLV_ERROR, LOCATION, NULL,
861 "status mismatched %d.\n", iph1->status);
862 goto end;
863 }
864
865 /* set responder's cookie */
866 isakmp_newcookie((caddr_t)&iph1->index.r_ck, iph1->remote, iph1->local);
867
868 /* make ID payload into isakmp status */
869 if (ipsecdoi_setid1(iph1) < 0)
870 goto end;
871
872 /* generate DH public value */
873 if (oakley_dh_generate(iph1->rmconf->dhgrp,
874 &iph1->dhpub, &iph1->dhpriv) < 0)
875 goto end;
876
877 /* generate NONCE value */
878 iph1->nonce = eay_set_random(iph1->rmconf->nonce_size);
879 if (iph1->nonce == NULL)
880 goto end;
881
882 /* compute sharing secret of DH */
883 if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub,
884 iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0)
885 goto end;
886
887 /* generate SKEYIDs & IV & final cipher key */
888 if (oakley_skeyid(iph1) < 0)
889 goto end;
890 if (oakley_skeyid_dae(iph1) < 0)
891 goto end;
892 if (oakley_compute_enckey(iph1) < 0)
893 goto end;
894 if (oakley_newiv(iph1) < 0)
895 goto end;
896
897#ifdef HAVE_GSSAPI
898 if (iph1->rmconf->proposal->authmethod ==
899 OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB)
900 gssapi_get_rtoken(iph1, &gsslen);
901#endif
902
903 /* generate HASH to send */
904 plog(LLV_DEBUG, LOCATION, NULL, "generate HASH_R\n");
905 iph1->hash = oakley_ph1hash_common(iph1, GENERATE);
906 if (iph1->hash == NULL) {
907#ifdef HAVE_GSSAPI
908 if (gssapi_more_tokens(iph1))
909 isakmp_info_send_n1(iph1,
910 ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL);
911#endif
912 goto end;
913 }
914
915#ifdef HAVE_SIGNING_C
916 /* create CR if need */
917 if (iph1->rmconf->send_cr
918 && oakley_needcr(iph1->approval->authmethod)
919 && iph1->rmconf->peerscertfile == NULL) {
920 need_cr = 1;
921 cr = oakley_getcr(iph1);
922 if (cr == NULL) {
923 plog(LLV_ERROR, LOCATION, NULL,
924 "failed to get cr buffer.\n");
925 goto end;
926 }
927 }
928#endif
929
930 tlen = sizeof(struct isakmp);
931
ac2f15b3
A
932#ifdef IKE_NAT_T
933 if ((iph1->natt_flags & natt_remote_support) != 0) {
934 nattvid = set_vendorid(VENDORID_NATT);
935 natd_create(iph1);
936 if (nattvid) {
937 tlen += sizeof(*gen) + nattvid->l;
938 if (iph1->local_natd)
939 tlen += sizeof(*gen) + iph1->local_natd->l;
940 if (iph1->remote_natd)
941 tlen += sizeof(*gen) + iph1->remote_natd->l;
942 }
943 }
944#endif
945
7ba0088d
A
946 switch (iph1->approval->authmethod) {
947 case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
948 /* create buffer to send isakmp payload */
949 tlen += sizeof(*gen) + iph1->sa_ret->l
950 + sizeof(*gen) + iph1->dhpub->l
951 + sizeof(*gen) + iph1->nonce->l
952 + sizeof(*gen) + iph1->id->l
953 + sizeof(*gen) + iph1->hash->l;
954 if ((vid = set_vendorid(iph1->approval->vendorid)) != NULL)
955 tlen += sizeof(*gen) + vid->l;
956 if (need_cr)
957 tlen += sizeof(*gen) + cr->l;
958
959 iph1->sendbuf = vmalloc(tlen);
960 if (iph1->sendbuf == NULL) {
961 plog(LLV_ERROR, LOCATION, NULL,
962 "failed to get buffer to send\n");
963 goto end;
964 }
965
966 /* set isakmp header */
967 p = set_isakmp_header(iph1->sendbuf, iph1, ISAKMP_NPTYPE_SA);
968 if (p == NULL)
969 goto end;
970
971 /* set SA payload to reply */
972 p = set_isakmp_payload(p, iph1->sa_ret, ISAKMP_NPTYPE_KE);
973
974 /* create isakmp KE payload */
975 p = set_isakmp_payload(p, iph1->dhpub, ISAKMP_NPTYPE_NONCE);
976
977 /* create isakmp NONCE payload */
978 p = set_isakmp_payload(p, iph1->nonce, ISAKMP_NPTYPE_ID);
979
980 /* create isakmp ID payload */
981 p = set_isakmp_payload(p, iph1->id, ISAKMP_NPTYPE_HASH);
982
983 /* create isakmp HASH payload */
984 p = set_isakmp_payload(p, iph1->hash,
985 vid ? ISAKMP_NPTYPE_VID
986 : (need_cr ? ISAKMP_NPTYPE_CR
ac2f15b3
A
987 : (nattvid ? ISAKMP_NPTYPE_VID
988 : ISAKMP_NPTYPE_NONE)));
7ba0088d
A
989
990 /* append vendor id, if needed */
991 if (vid)
992 p = set_isakmp_payload(p, vid,
993 need_cr ? ISAKMP_NPTYPE_CR
ac2f15b3
A
994 : (nattvid ? ISAKMP_NPTYPE_VID
995 : ISAKMP_NPTYPE_NONE));
7ba0088d
A
996
997 /* create isakmp CR payload if needed */
998 if (need_cr)
ac2f15b3
A
999 p = set_isakmp_payload(p, cr,
1000 nattvid ? ISAKMP_NPTYPE_VID
1001 : ISAKMP_NPTYPE_NONE);
7ba0088d
A
1002 break;
1003#ifdef HAVE_SIGNING_C
1004 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
1005 case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
1006 /* XXX if there is CR or not ? */
1007
1008 if (oakley_getmycert(iph1) < 0)
1009 goto end;
1010
1011 if (oakley_getsign(iph1) < 0)
1012 goto end;
1013
1014 if (iph1->cert != NULL && iph1->rmconf->send_cert)
1015 need_cert = 1;
1016
1017 tlen += sizeof(*gen) + iph1->sa_ret->l
1018 + sizeof(*gen) + iph1->dhpub->l
1019 + sizeof(*gen) + iph1->nonce->l
1020 + sizeof(*gen) + iph1->id->l
1021 + sizeof(*gen) + iph1->sig->l;
1022 if (need_cert)
1023 tlen += sizeof(*gen) + iph1->cert->pl->l;
1024 if ((vid = set_vendorid(iph1->approval->vendorid)) != NULL)
1025 tlen += sizeof(*gen) + vid->l;
1026 if (need_cr)
1027 tlen += sizeof(*gen) + cr->l;
1028
1029 iph1->sendbuf = vmalloc(tlen);
1030 if (iph1->sendbuf == NULL) {
1031 plog(LLV_ERROR, LOCATION, NULL,
1032 "failed to get buffer to send.\n");
1033 goto end;
1034 }
1035
1036 /* set isakmp header */
1037 p = set_isakmp_header(iph1->sendbuf, iph1, ISAKMP_NPTYPE_SA);
1038 if (p == NULL)
1039 goto end;
1040
1041 /* set SA payload to reply */
1042 p = set_isakmp_payload(p, iph1->sa_ret, ISAKMP_NPTYPE_KE);
1043
1044 /* create isakmp KE payload */
1045 p = set_isakmp_payload(p, iph1->dhpub, ISAKMP_NPTYPE_NONCE);
1046
1047 /* create isakmp NONCE payload */
1048 p = set_isakmp_payload(p, iph1->nonce, ISAKMP_NPTYPE_ID);
1049
1050 /* add ID payload */
1051 p = set_isakmp_payload(p, iph1->id, need_cert
1052 ? ISAKMP_NPTYPE_CERT
1053 : ISAKMP_NPTYPE_SIG);
1054
1055 /* add CERT payload if there */
1056 if (need_cert)
1057 p = set_isakmp_payload(p, iph1->cert->pl, ISAKMP_NPTYPE_SIG);
1058 /* add SIG payload */
1059 p = set_isakmp_payload(p, iph1->sig,
1060 vid ? ISAKMP_NPTYPE_VID
1061 : (need_cr ? ISAKMP_NPTYPE_CR
1062 : ISAKMP_NPTYPE_NONE));
1063
1064 /* append vendor id, if needed */
1065 if (vid)
1066 p = set_isakmp_payload(p, vid,
1067 need_cr ? ISAKMP_NPTYPE_CR
ac2f15b3
A
1068 : (nattvid ? ISAKMP_NPTYPE_VID
1069 : ISAKMP_NPTYPE_NONE));
7ba0088d
A
1070
1071 /* create isakmp CR payload if needed */
1072 if (need_cr)
ac2f15b3
A
1073 p = set_isakmp_payload(p, cr,
1074 nattvid ? ISAKMP_NPTYPE_VID
1075 : ISAKMP_NPTYPE_NONE);
1076
1077#ifdef IKE_NAT_T
1078 if (nattvid) {
1079 p = set_isakmp_payload(p, nattvid, ISAKMP_NPTYPE_NATD);
1080 if (iph1->local_natd)
1081 p = set_isakmp_payload(p, iph1->local_natd, ISAKMP_NPTYPE_NATD);
1082 if (iph1->remote_natd)
1083 p = set_isakmp_payload(p, iph1->remote_natd, ISAKMP_NPTYPE_NONE);
1084 }
1085#endif
7ba0088d
A
1086 break;
1087#endif
1088 case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
1089 case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
1090 tlen += sizeof(*gen) + iph1->hash->l;
1091 break;
1092#ifdef HAVE_GSSAPI
1093 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
1094 /* create buffer to send isakmp payload */
1095 gsshash = gssapi_wraphash(iph1);
1096 if (gsshash == NULL) {
1097 plog(LLV_ERROR, LOCATION, NULL,
1098 "failed to wrap hash\n");
1099 /*
1100 * This is probably due to the GSS roundtrips not
1101 * being finished yet. Return this error in
1102 * the hope that a fallback to main mode will
1103 * be done.
1104 */
1105 isakmp_info_send_n1(iph1,
1106 ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL);
1107 goto end;
1108 }
1109 if (iph1->approval->gssid != NULL)
1110 gss_sa = ipsecdoi_setph1proposal(iph1->approval);
1111 else
1112 gss_sa = iph1->sa_ret;
1113
1114 tlen += sizeof(*gen) + gss_sa->l
1115 + sizeof(*gen) + iph1->dhpub->l
1116 + sizeof(*gen) + iph1->nonce->l
1117 + sizeof(*gen) + iph1->id->l
1118 + sizeof(*gen) + gsslen
1119 + sizeof(*gen) + gsshash->l;
1120 if ((vid = set_vendorid(iph1->approval->vendorid)) != NULL)
1121 tlen += sizeof(*gen) + vid->l;
1122 iph1->sendbuf = vmalloc(tlen);
1123 if (iph1->sendbuf == NULL) {
1124 plog(LLV_ERROR, LOCATION, NULL,
1125 "failed to get buffer to send\n");
1126 goto end;
1127 }
1128
1129 /* set isakmp header */
1130 p = set_isakmp_header(iph1->sendbuf, iph1, ISAKMP_NPTYPE_SA);
1131 if (p == NULL)
1132 goto end;
1133
1134 /* set SA payload to reply */
1135 p = set_isakmp_payload(p, gss_sa, ISAKMP_NPTYPE_KE);
1136
1137 /* create isakmp KE payload */
1138 p = set_isakmp_payload(p, iph1->dhpub, ISAKMP_NPTYPE_NONCE);
1139
1140 /* create isakmp NONCE payload */
1141 p = set_isakmp_payload(p, iph1->nonce, ISAKMP_NPTYPE_ID);
1142
1143 /* create isakmp ID payload */
1144 p = set_isakmp_payload(p, iph1->id, ISAKMP_NPTYPE_GSS);
1145
1146 /* create GSS payload */
1147 gssapi_get_token_to_send(iph1, &gsstoken);
1148 p = set_isakmp_payload(p, gsstoken, ISAKMP_NPTYPE_HASH);
1149
1150 /* create isakmp HASH payload */
1151 p = set_isakmp_payload(p, gsshash,
ac2f15b3 1152 vid != NULL || nattvid != NULL ? ISAKMP_NPTYPE_VID
7ba0088d
A
1153 : ISAKMP_NPTYPE_NONE);
1154
1155 /* append vendor id, if needed */
1156 if (vid)
ac2f15b3
A
1157 p = set_isakmp_payload(p, vid,
1158 nattvid != NULL ? ISAKMP_NPTYPE_VID
1159 : ISAKMP_NPTYPE_NONE);
7ba0088d
A
1160 break;
1161#endif
1162 }
ac2f15b3
A
1163
1164#ifdef IKE_NAT_T
1165 if (nattvid) {
1166 p = set_isakmp_payload(p, nattvid, ISAKMP_NPTYPE_NATD);
1167 if (iph1->local_natd)
1168 p = set_isakmp_payload(p, iph1->local_natd, ISAKMP_NPTYPE_NATD);
1169 if (iph1->remote_natd)
1170 p = set_isakmp_payload(p, iph1->remote_natd, ISAKMP_NPTYPE_NONE);
1171 }
1172#endif
7ba0088d
A
1173
1174
1175#ifdef HAVE_PRINT_ISAKMP_C
1176 isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 1);
1177#endif
1178
1179 /* send the packet, add to the schedule to resend */
1180 iph1->retry_counter = iph1->rmconf->retry_counter;
1181 if (isakmp_ph1resend(iph1) == -1)
1182 goto end;
1183
1184 /* the sending message is added to the received-list. */
1185 if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
1186 plog(LLV_ERROR , LOCATION, NULL,
1187 "failed to add a response packet to the tree.\n");
1188 goto end;
1189 }
1190
1191 iph1->status = PHASE1ST_MSG1SENT;
1192
1193 error = 0;
1194
1195end:
1196 if (cr)
1197 vfree(cr);
1198 if (vid)
1199 vfree(vid);
ac2f15b3
A
1200 if (nattvid)
1201 vfree(nattvid);
7ba0088d
A
1202#ifdef HAVE_GSSAPI
1203 if (gsstoken)
1204 vfree(gsstoken);
1205 if (gsshash)
1206 vfree(gsshash);
1207 if (gss_sa != iph1->sa_ret)
1208 vfree(gss_sa);
1209#endif
1210
1211 return error;
1212}
1213
1214/*
1215 * receive from initiator
1216 * psk: HDR, HASH_I
1217 * gssapi: HDR, HASH_I
1218 * sig: HDR, [ CERT, ] SIG_I
1219 * rsa: HDR, HASH_I
1220 * rev: HDR, HASH_I
1221 */
1222int
1223agg_r2recv(iph1, msg0)
1224 struct ph1handle *iph1;
1225 vchar_t *msg0;
1226{
1227 vchar_t *msg = NULL;
1228 vchar_t *pbuf = NULL;
1229 struct isakmp_parse_t *pa;
1230 int error = -1;
1231
1232 /* validity check */
1233 if (iph1->status != PHASE1ST_MSG1SENT) {
1234 plog(LLV_ERROR, LOCATION, NULL,
1235 "status mismatched %d.\n", iph1->status);
1236 goto end;
1237 }
1238
1239 /* decrypting if need. */
1240 /* XXX configurable ? */
1241 if (ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) {
1242 msg = oakley_do_decrypt(iph1, msg0,
1243 iph1->ivm->iv, iph1->ivm->ive);
1244 if (msg == NULL)
1245 goto end;
1246 } else
1247 msg = vdup(msg0);
1248
1249 /* validate the type of next payload */
1250 pbuf = isakmp_parse(msg);
1251 if (pbuf == NULL)
1252 goto end;
1253
1254 iph1->pl_hash = NULL;
1255
1256 for (pa = (struct isakmp_parse_t *)pbuf->v;
1257 pa->type != ISAKMP_NPTYPE_NONE;
1258 pa++) {
1259
1260 switch (pa->type) {
1261 case ISAKMP_NPTYPE_HASH:
1262 iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr;
1263 break;
1264 case ISAKMP_NPTYPE_VID:
1265 (void)check_vendorid(pa->ptr);
1266 break;
1267#ifdef HAVE_SIGNING_C
1268 case ISAKMP_NPTYPE_CERT:
1269 if (oakley_savecert(iph1, pa->ptr) < 0)
1270 goto end;
1271 break;
1272 case ISAKMP_NPTYPE_SIG:
1273 if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0)
1274 goto end;
1275 break;
1276#endif
1277 case ISAKMP_NPTYPE_N:
1278 isakmp_check_notify(pa->ptr, iph1);
1279 break;
ac2f15b3
A
1280 case ISAKMP_NPTYPE_NATD:
1281#ifdef IKE_NAT_T
1282 {
1283 natd_match_t match = natd_matches(iph1, pa->ptr);
1284 iph1->natt_flags |= natt_natd_received;
1285 if ((match & natd_match_local) != 0)
1286 iph1->natt_flags |= natt_no_local_nat;
1287 if ((match & natd_match_remote) != 0)
1288 iph1->natt_flags |= natt_no_remote_nat;
1289 }
1290#endif
1291 break;
7ba0088d
A
1292 default:
1293 /* don't send information, see isakmp_ident_r1() */
1294 plog(LLV_ERROR, LOCATION, iph1->remote,
1295 "ignore the packet, "
1296 "received unexpecting payload type %d.\n",
1297 pa->type);
1298 goto end;
1299 }
1300 }
1301
1302 /* validate authentication value */
1303 {
1304 int type;
1305 type = oakley_validate_auth(iph1);
1306 if (type != 0) {
1307 if (type == -1) {
1308 /* message printed inner oakley_validate_auth() */
1309 goto end;
1310 }
1311 isakmp_info_send_n1(iph1, type, NULL);
1312 goto end;
1313 }
1314 }
1315
1316 iph1->status = PHASE1ST_MSG2RECEIVED;
1317
1318 error = 0;
1319
1320end:
1321 if (pbuf)
1322 vfree(pbuf);
1323 if (msg)
1324 vfree(msg);
1325 if (error) {
1326 oakley_delcert(iph1->cert_p);
1327 iph1->cert_p = NULL;
1328 oakley_delcert(iph1->crl_p);
1329 iph1->crl_p = NULL;
1330 VPTRINIT(iph1->sig_p);
1331 }
1332
1333 return error;
1334}
1335
1336/*
1337 * status update and establish isakmp sa.
1338 */
1339int
1340agg_r2send(iph1, msg)
1341 struct ph1handle *iph1;
1342 vchar_t *msg;
1343{
1344 int error = -1;
1345
1346 /* validity check */
1347 if (iph1->status != PHASE1ST_MSG2RECEIVED) {
1348 plog(LLV_ERROR, LOCATION, NULL,
1349 "status mismatched %d.\n", iph1->status);
1350 goto end;
1351 }
1352
1353 /* IV synchronized when packet encrypted. */
1354 /* see handler.h about IV synchronization. */
1355 if (ISSET(((struct isakmp *)msg->v)->flags, ISAKMP_FLAG_E))
1356 memcpy(iph1->ivm->iv->v, iph1->ivm->ive->v, iph1->ivm->iv->l);
1357
1358 /* set encryption flag */
1359 iph1->flags |= ISAKMP_FLAG_E;
1360
1361 iph1->status = PHASE1ST_ESTABLISHED;
1362
1363 error = 0;
1364
1365end:
1366 return error;
1367}