1 /* $NetBSD: isakmp_agg.c,v 1.15 2009/03/12 10:57:26 tteras Exp $ */
3 /* Id: isakmp_agg.c,v 1.28 2006/04/06 16:46:08 manubsd Exp */
6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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.
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
34 /* Aggressive Exchange (Aggressive Mode) */
38 #include <sys/types.h>
39 #include <sys/param.h>
45 #if TIME_WITH_SYS_TIME
46 # include <sys/time.h>
50 # include <sys/time.h>
68 #include "localconf.h"
69 #include "remoteconf.h"
70 #include "isakmp_var.h"
75 #include "ipsec_doi.h"
76 #include "crypto_openssl.h"
78 #include "isakmp_agg.h"
79 #include "isakmp_inf.h"
81 #include "isakmp_xauth.h"
82 #include "isakmp_cfg.h"
85 #include "isakmp_frag.h"
91 #include "nattraversal.h"
99 * begin Aggressive Mode as initiator.
103 * psk: HDR, SA, KE, Ni, IDi1
104 * sig: HDR, SA, KE, Ni, IDi1 [, CR ]
105 * gssapi: HDR, SA, KE, Ni, IDi1, GSSi
106 * rsa: HDR, SA, [ HASH(1),] KE, <IDi1_b>Pubkey_r, <Ni_b>Pubkey_r
107 * rev: HDR, SA, [ HASH(1),] <Ni_b>Pubkey_r, <KE_b>Ke_i,
108 * <IDii_b>Ke_i [, <Cert-I_b>Ke_i ]
111 agg_i1send(iph1
, msg
)
112 struct ph1handle
*iph1
;
113 vchar_t
*msg
; /* must be null */
115 struct payload_list
*plist
= NULL
;
118 vchar_t
*vid_natt
[MAX_NATT_VID_COUNT
] = { NULL
};
122 vchar_t
*vid_xauth
= NULL
;
123 vchar_t
*vid_unity
= NULL
;
126 vchar_t
*vid_frag
= NULL
;
129 vchar_t
*gsstoken
= NULL
;
133 vchar_t
*vid_dpd
= NULL
;
138 plog(LLV_ERROR
, LOCATION
, NULL
,
139 "msg has to be NULL in this function.\n");
142 if (iph1
->status
!= PHASE1ST_START
) {
143 plog(LLV_ERROR
, LOCATION
, NULL
,
144 "status mismatched %d.\n", iph1
->status
);
148 /* create isakmp index */
149 memset(&iph1
->index
, 0, sizeof(iph1
->index
));
150 isakmp_newcookie((caddr_t
)&iph1
->index
, iph1
->remote
, iph1
->local
);
152 /* make ID payload into isakmp status */
153 if (ipsecdoi_setid1(iph1
) < 0)
156 /* create SA payload for my proposal */
157 iph1
->sa
= ipsecdoi_setph1proposal(iph1
->rmconf
, iph1
->rmconf
->proposal
);
158 if (iph1
->sa
== NULL
)
161 /* consistency check of proposals */
162 if (iph1
->rmconf
->dhgrp
== NULL
) {
163 plog(LLV_ERROR
, LOCATION
, NULL
,
164 "configuration failure about DH group.\n");
168 /* generate DH public value */
169 if (oakley_dh_generate(iph1
->rmconf
->dhgrp
,
170 &iph1
->dhpub
, &iph1
->dhpriv
) < 0)
173 /* generate NONCE value */
174 iph1
->nonce
= eay_set_random(iph1
->rmconf
->nonce_size
);
175 if (iph1
->nonce
== NULL
)
179 /* Do we need Xauth VID? */
180 switch (iph1
->rmconf
->proposal
->authmethod
) {
181 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I
:
182 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
183 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I
:
184 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I
:
185 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I
:
186 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I
:
187 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I
:
188 if ((vid_xauth
= set_vendorid(VENDORID_XAUTH
)) == NULL
)
189 plog(LLV_ERROR
, LOCATION
, NULL
,
190 "Xauth vendor ID generation failed\n");
191 if ((vid_unity
= set_vendorid(VENDORID_UNITY
)) == NULL
)
192 plog(LLV_ERROR
, LOCATION
, NULL
,
193 "Unity vendor ID generation failed\n");
201 if (iph1
->rmconf
->ike_frag
) {
202 vid_frag
= set_vendorid(VENDORID_FRAG
);
203 if (vid_frag
!= NULL
)
204 vid_frag
= isakmp_frag_addcap(vid_frag
,
206 if (vid_frag
== NULL
)
207 plog(LLV_ERROR
, LOCATION
, NULL
,
208 "Frag vendorID construction failed\n");
212 plog(LLV_DEBUG
, LOCATION
, NULL
, "authmethod is %s\n",
213 s_oakley_attr_method(iph1
->rmconf
->proposal
->authmethod
));
215 if (iph1
->rmconf
->proposal
->authmethod
== OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB
)
216 gssapi_get_itoken(iph1
, &len
);
219 /* set SA payload to propose */
220 plist
= isakmp_plist_append(plist
, iph1
->sa
, ISAKMP_NPTYPE_SA
);
222 /* create isakmp KE payload */
223 plist
= isakmp_plist_append(plist
, iph1
->dhpub
, ISAKMP_NPTYPE_KE
);
225 /* create isakmp NONCE payload */
226 plist
= isakmp_plist_append(plist
, iph1
->nonce
, ISAKMP_NPTYPE_NONCE
);
228 /* create isakmp ID payload */
229 plist
= isakmp_plist_append(plist
, iph1
->id
, ISAKMP_NPTYPE_ID
);
232 if (iph1
->rmconf
->proposal
->authmethod
== OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB
) {
233 if (gssapi_get_token_to_send(iph1
, &gsstoken
) < 0) {
234 plog(LLV_ERROR
, LOCATION
, NULL
,
235 "Failed to get gssapi token.\n");
238 plist
= isakmp_plist_append(plist
, gsstoken
, ISAKMP_NPTYPE_GSS
);
241 /* create isakmp CR payload */
242 if (oakley_needcr(iph1
->rmconf
->proposal
->authmethod
))
243 plist
= oakley_append_cr(plist
, iph1
);
247 plist
= isakmp_plist_append(plist
, vid_frag
, ISAKMP_NPTYPE_VID
);
251 * set VID payload for NAT-T if NAT-T
252 * support allowed in the config file
254 if (iph1
->rmconf
->nat_traversal
)
255 plist
= isakmp_plist_append_natt_vids(plist
, vid_natt
);
259 plist
= isakmp_plist_append(plist
,
260 vid_xauth
, ISAKMP_NPTYPE_VID
);
262 plist
= isakmp_plist_append(plist
,
263 vid_unity
, ISAKMP_NPTYPE_VID
);
266 if(iph1
->rmconf
->dpd
){
267 vid_dpd
= set_vendorid(VENDORID_DPD
);
269 plist
= isakmp_plist_append(plist
, vid_dpd
, ISAKMP_NPTYPE_VID
);
273 iph1
->sendbuf
= isakmp_plist_set_all (&plist
, iph1
);
275 #ifdef HAVE_PRINT_ISAKMP_C
276 isakmp_printpacket(iph1
->sendbuf
, iph1
->local
, iph1
->remote
, 0);
279 /* send the packet, add to the schedule to resend */
280 if (isakmp_ph1send(iph1
) == -1)
283 iph1
->status
= PHASE1ST_MSG1SENT
;
297 for (i
= 0; i
< MAX_NATT_VID_COUNT
&& vid_natt
[i
] != NULL
; i
++)
301 if (vid_xauth
!= NULL
)
303 if (vid_unity
!= NULL
)
315 * receive from responder
316 * psk: HDR, SA, KE, Nr, IDr1, HASH_R
317 * sig: HDR, SA, KE, Nr, IDr1, [ CR, ] [ CERT, ] SIG_R
318 * gssapi: HDR, SA, KE, Nr, IDr1, GSSr, HASH_R
319 * rsa: HDR, SA, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i, HASH_R
320 * rev: HDR, SA, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDir_b>Ke_r, HASH_R
323 agg_i2recv(iph1
, msg
)
324 struct ph1handle
*iph1
;
327 vchar_t
*pbuf
= NULL
;
328 struct isakmp_parse_t
*pa
;
329 vchar_t
*satmp
= NULL
;
337 vchar_t
*gsstoken
= NULL
;
342 struct natd_payload
{
345 TAILQ_ENTRY(natd_payload
) chain
;
347 TAILQ_HEAD(_natd_payload
, natd_payload
) natd_tree
;
348 TAILQ_INIT(&natd_tree
);
352 if (iph1
->status
!= PHASE1ST_MSG1SENT
) {
353 plog(LLV_ERROR
, LOCATION
, NULL
,
354 "status mismatched %d.\n", iph1
->status
);
358 /* validate the type of next payload */
359 pbuf
= isakmp_parse(msg
);
362 pa
= (struct isakmp_parse_t
*)pbuf
->v
;
364 iph1
->pl_hash
= NULL
;
366 /* SA payload is fixed postion */
367 if (pa
->type
!= ISAKMP_NPTYPE_SA
) {
368 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
369 "received invalid next payload type %d, "
371 pa
->type
, ISAKMP_NPTYPE_SA
);
375 if (isakmp_p2ph(&satmp
, pa
->ptr
) < 0)
380 pa
->type
!= ISAKMP_NPTYPE_NONE
;
384 case ISAKMP_NPTYPE_KE
:
385 if (isakmp_p2ph(&iph1
->dhpub_p
, pa
->ptr
) < 0)
388 case ISAKMP_NPTYPE_NONCE
:
389 if (isakmp_p2ph(&iph1
->nonce_p
, pa
->ptr
) < 0)
392 case ISAKMP_NPTYPE_ID
:
393 if (isakmp_p2ph(&iph1
->id_p
, pa
->ptr
) < 0)
396 case ISAKMP_NPTYPE_HASH
:
397 iph1
->pl_hash
= (struct isakmp_pl_hash
*)pa
->ptr
;
399 case ISAKMP_NPTYPE_CR
:
400 if (oakley_savecr(iph1
, pa
->ptr
) < 0)
403 case ISAKMP_NPTYPE_CERT
:
404 if (oakley_savecert(iph1
, pa
->ptr
) < 0)
407 case ISAKMP_NPTYPE_SIG
:
408 if (isakmp_p2ph(&iph1
->sig_p
, pa
->ptr
) < 0)
411 case ISAKMP_NPTYPE_VID
:
412 handle_vendorid(iph1
, pa
->ptr
);
414 case ISAKMP_NPTYPE_N
:
415 isakmp_log_notify(iph1
,
416 (struct isakmp_pl_n
*) pa
->ptr
,
417 "aggressive exchange");
420 case ISAKMP_NPTYPE_GSS
:
421 if (isakmp_p2ph(&gsstoken
, pa
->ptr
) < 0)
423 gssapi_save_received_token(iph1
, gsstoken
);
428 case ISAKMP_NPTYPE_NATD_DRAFT
:
429 case ISAKMP_NPTYPE_NATD_RFC
:
430 if (NATT_AVAILABLE(iph1
) && iph1
->natt_options
!= NULL
&&
431 pa
->type
== iph1
->natt_options
->payload_nat_d
) {
432 struct natd_payload
*natd
;
433 natd
= (struct natd_payload
*)racoon_malloc(sizeof(*natd
));
437 natd
->payload
= NULL
;
439 if (isakmp_p2ph (&natd
->payload
, pa
->ptr
) < 0)
442 natd
->seq
= natd_seq
++;
444 TAILQ_INSERT_TAIL(&natd_tree
, natd
, chain
);
447 /* passthrough to default... */
451 /* don't send information, see isakmp_ident_r1() */
452 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
453 "ignore the packet, "
454 "received unexpecting payload type %d.\n",
460 /* payload existency check */
461 if (iph1
->dhpub_p
== NULL
|| iph1
->nonce_p
== NULL
) {
462 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
463 "few isakmp message received.\n");
467 /* verify identifier */
468 if (ipsecdoi_checkid1(iph1
) != 0) {
469 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
470 "invalid ID payload.\n");
474 /* check SA payload and set approval SA for use */
475 if (ipsecdoi_checkph1proposal(satmp
, iph1
) < 0) {
476 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
477 "failed to get valid proposal.\n");
478 /* XXX send information */
481 VPTRINIT(iph1
->sa_ret
);
483 /* fix isakmp index */
484 memcpy(&iph1
->index
.r_ck
, &((struct isakmp
*)msg
->v
)->r_ck
,
488 if (NATT_AVAILABLE(iph1
)) {
489 struct natd_payload
*natd
= NULL
;
492 plog(LLV_INFO
, LOCATION
, iph1
->remote
,
493 "Selected NAT-T version: %s\n",
494 vid_string_by_id(iph1
->natt_options
->version
));
496 /* set both bits first so that we can clear them
497 upon verifying hashes */
498 iph1
->natt_flags
|= NAT_DETECTED
;
500 while ((natd
= TAILQ_FIRST(&natd_tree
)) != NULL
) {
501 /* this function will clear appropriate bits bits
502 from iph1->natt_flags */
503 natd_verified
= natt_compare_addr_hash (iph1
,
504 natd
->payload
, natd
->seq
);
506 plog (LLV_INFO
, LOCATION
, NULL
, "NAT-D payload #%d %s\n",
508 natd_verified
? "verified" : "doesn't match");
510 vfree (natd
->payload
);
512 TAILQ_REMOVE(&natd_tree
, natd
, chain
);
516 plog (LLV_INFO
, LOCATION
, NULL
, "NAT %s %s%s\n",
517 iph1
->natt_flags
& NAT_DETECTED
?
518 "detected:" : "not detected",
519 iph1
->natt_flags
& NAT_DETECTED_ME
? "ME " : "",
520 iph1
->natt_flags
& NAT_DETECTED_PEER
? "PEER" : "");
522 if (iph1
->natt_flags
& NAT_DETECTED
)
523 natt_float_ports (iph1
);
527 /* compute sharing secret of DH */
528 if (oakley_dh_compute(iph1
->rmconf
->dhgrp
, iph1
->dhpub
,
529 iph1
->dhpriv
, iph1
->dhpub_p
, &iph1
->dhgxy
) < 0)
532 /* generate SKEYIDs & IV & final cipher key */
533 if (oakley_skeyid(iph1
) < 0)
535 if (oakley_skeyid_dae(iph1
) < 0)
537 if (oakley_compute_enckey(iph1
) < 0)
539 if (oakley_newiv(iph1
) < 0)
542 /* validate authentication value */
543 ptype
= oakley_validate_auth(iph1
);
546 /* message printed inner oakley_validate_auth() */
549 evt_phase1(iph1
, EVT_PHASE1_AUTH_FAILED
, NULL
);
550 isakmp_info_send_n1(iph1
, ptype
, NULL
);
554 if (oakley_checkcr(iph1
) < 0) {
555 /* Ignore this error in order to be interoperability. */
559 /* change status of isakmp status entry */
560 iph1
->status
= PHASE1ST_MSG2RECEIVED
;
574 VPTRINIT(iph1
->dhpub_p
);
575 VPTRINIT(iph1
->nonce_p
);
576 VPTRINIT(iph1
->id_p
);
577 VPTRINIT(iph1
->cert_p
);
578 VPTRINIT(iph1
->crl_p
);
579 VPTRINIT(iph1
->sig_p
);
580 VPTRINIT(iph1
->cr_p
);
589 * gssapi: HDR, HASH_I
590 * sig: HDR, [ CERT, ] SIG_I
595 agg_i2send(iph1
, msg
)
596 struct ph1handle
*iph1
;
599 struct payload_list
*plist
= NULL
;
602 vchar_t
*gsshash
= NULL
;
605 if (iph1
->status
!= PHASE1ST_MSG2RECEIVED
) {
606 plog(LLV_ERROR
, LOCATION
, NULL
,
607 "status mismatched %d.\n", iph1
->status
);
611 /* generate HASH to send */
612 plog(LLV_DEBUG
, LOCATION
, NULL
, "generate HASH_I\n");
613 iph1
->hash
= oakley_ph1hash_common(iph1
, GENERATE
);
614 if (iph1
->hash
== NULL
) {
616 if (gssapi_more_tokens(iph1
) &&
618 !iph1
->rmconf
->xauth
&&
621 isakmp_info_send_n1(iph1
,
622 ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE
, NULL
);
627 switch (iph1
->approval
->authmethod
) {
628 case OAKLEY_ATTR_AUTH_METHOD_PSKEY
:
630 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I
:
631 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I
:
632 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I
:
634 /* set HASH payload */
635 plist
= isakmp_plist_append(plist
,
636 iph1
->hash
, ISAKMP_NPTYPE_HASH
);
639 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG
:
640 case OAKLEY_ATTR_AUTH_METHOD_RSASIG
:
642 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I
:
643 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I
:
645 /* XXX if there is CR or not ? */
647 if (oakley_getmycert(iph1
) < 0)
650 if (oakley_getsign(iph1
) < 0)
653 if (iph1
->cert
!= NULL
&& iph1
->rmconf
->send_cert
)
656 /* add CERT payload if there */
658 plist
= isakmp_plist_append(plist
, iph1
->cert
,
661 /* add SIG payload */
662 plist
= isakmp_plist_append(plist
,
663 iph1
->sig
, ISAKMP_NPTYPE_SIG
);
666 case OAKLEY_ATTR_AUTH_METHOD_RSAENC
:
667 case OAKLEY_ATTR_AUTH_METHOD_RSAREV
:
669 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I
:
670 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I
:
674 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB
:
675 gsshash
= gssapi_wraphash(iph1
);
676 if (gsshash
== NULL
) {
677 plog(LLV_ERROR
, LOCATION
, NULL
,
678 "failed to wrap hash\n");
679 isakmp_info_send_n1(iph1
,
680 ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE
, NULL
);
684 plist
= isakmp_plist_append(plist
,
685 gsshash
, ISAKMP_NPTYPE_HASH
);
691 /* generate NAT-D payloads */
692 if (NATT_AVAILABLE(iph1
)) {
693 vchar_t
*natd
[2] = { NULL
, NULL
};
695 plog(LLV_INFO
, LOCATION
,
696 NULL
, "Adding remote and local NAT-D payloads.\n");
698 if ((natd
[0] = natt_hash_addr (iph1
, iph1
->remote
)) == NULL
) {
699 plog(LLV_ERROR
, LOCATION
, NULL
,
700 "NAT-D hashing failed for %s\n",
701 saddr2str(iph1
->remote
));
705 if ((natd
[1] = natt_hash_addr (iph1
, iph1
->local
)) == NULL
) {
706 plog(LLV_ERROR
, LOCATION
, NULL
,
707 "NAT-D hashing failed for %s\n",
708 saddr2str(iph1
->local
));
712 plist
= isakmp_plist_append(plist
,
713 natd
[0], iph1
->natt_options
->payload_nat_d
);
714 plist
= isakmp_plist_append(plist
,
715 natd
[1], iph1
->natt_options
->payload_nat_d
);
719 iph1
->sendbuf
= isakmp_plist_set_all (&plist
, iph1
);
721 #ifdef HAVE_PRINT_ISAKMP_C
722 isakmp_printpacket(iph1
->sendbuf
, iph1
->local
, iph1
->remote
, 0);
725 /* send to responder */
726 if (isakmp_send(iph1
, iph1
->sendbuf
) < 0)
729 /* the sending message is added to the received-list. */
730 if (add_recvdpkt(iph1
->remote
, iph1
->local
, iph1
->sendbuf
, msg
) == -1) {
731 plog(LLV_ERROR
, LOCATION
, NULL
,
732 "failed to add a response packet to the tree.\n");
736 /* set encryption flag */
737 iph1
->flags
|= ISAKMP_FLAG_E
;
739 iph1
->status
= PHASE1ST_ESTABLISHED
;
750 * receive from initiator
751 * psk: HDR, SA, KE, Ni, IDi1
752 * sig: HDR, SA, KE, Ni, IDi1 [, CR ]
753 * gssapi: HDR, SA, KE, Ni, IDi1 , GSSi
754 * rsa: HDR, SA, [ HASH(1),] KE, <IDi1_b>Pubkey_r, <Ni_b>Pubkey_r
755 * rev: HDR, SA, [ HASH(1),] <Ni_b>Pubkey_r, <KE_b>Ke_i,
756 * <IDii_b>Ke_i [, <Cert-I_b>Ke_i ]
759 agg_r1recv(iph1
, msg
)
760 struct ph1handle
*iph1
;
764 vchar_t
*pbuf
= NULL
;
765 struct isakmp_parse_t
*pa
;
768 vchar_t
*gsstoken
= NULL
;
772 if (iph1
->status
!= PHASE1ST_START
) {
773 plog(LLV_ERROR
, LOCATION
, NULL
,
774 "status mismatched %d.\n", iph1
->status
);
778 /* validate the type of next payload */
779 pbuf
= isakmp_parse(msg
);
782 pa
= (struct isakmp_parse_t
*)pbuf
->v
;
784 /* SA payload is fixed postion */
785 if (pa
->type
!= ISAKMP_NPTYPE_SA
) {
786 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
787 "received invalid next payload type %d, "
789 pa
->type
, ISAKMP_NPTYPE_SA
);
792 if (isakmp_p2ph(&iph1
->sa
, pa
->ptr
) < 0)
797 pa
->type
!= ISAKMP_NPTYPE_NONE
;
800 plog(LLV_DEBUG
, LOCATION
, NULL
,
801 "received payload of type %s\n",
802 s_isakmp_nptype(pa
->type
));
805 case ISAKMP_NPTYPE_KE
:
806 if (isakmp_p2ph(&iph1
->dhpub_p
, pa
->ptr
) < 0)
809 case ISAKMP_NPTYPE_NONCE
:
810 if (isakmp_p2ph(&iph1
->nonce_p
, pa
->ptr
) < 0)
813 case ISAKMP_NPTYPE_ID
:
814 if (isakmp_p2ph(&iph1
->id_p
, pa
->ptr
) < 0)
817 case ISAKMP_NPTYPE_VID
:
818 vid_numeric
= handle_vendorid(iph1
, pa
->ptr
);
820 if ((vid_numeric
== VENDORID_FRAG
) &&
821 (vendorid_frag_cap(pa
->ptr
) & VENDORID_FRAG_AGG
))
826 case ISAKMP_NPTYPE_CR
:
827 if (oakley_savecr(iph1
, pa
->ptr
) < 0)
832 case ISAKMP_NPTYPE_GSS
:
833 if (isakmp_p2ph(&gsstoken
, pa
->ptr
) < 0)
835 gssapi_save_received_token(iph1
, gsstoken
);
839 /* don't send information, see isakmp_ident_r1() */
840 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
841 "ignore the packet, "
842 "received unexpecting payload type %d.\n",
848 /* payload existency check */
849 if (iph1
->dhpub_p
== NULL
|| iph1
->nonce_p
== NULL
) {
850 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
851 "few isakmp message received.\n");
855 /* verify identifier */
856 if (ipsecdoi_checkid1(iph1
) != 0) {
857 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
858 "invalid ID payload.\n");
863 if (NATT_AVAILABLE(iph1
))
864 plog(LLV_INFO
, LOCATION
, iph1
->remote
,
865 "Selected NAT-T version: %s\n",
866 vid_string_by_id(iph1
->natt_options
->version
));
869 /* check SA payload and set approval SA for use */
870 if (ipsecdoi_checkph1proposal(iph1
->sa
, iph1
) < 0) {
871 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
872 "failed to get valid proposal.\n");
873 /* XXX send information */
877 if (oakley_checkcr(iph1
) < 0) {
878 /* Ignore this error in order to be interoperability. */
882 iph1
->status
= PHASE1ST_MSG1RECEIVED
;
895 VPTRINIT(iph1
->dhpub_p
);
896 VPTRINIT(iph1
->nonce_p
);
897 VPTRINIT(iph1
->id_p
);
898 VPTRINIT(iph1
->cr_p
);
906 * psk: HDR, SA, KE, Nr, IDr1, HASH_R
907 * sig: HDR, SA, KE, Nr, IDr1, [ CR, ] [ CERT, ] SIG_R
908 * gssapi: HDR, SA, KE, Nr, IDr1, GSSr, HASH_R
909 * rsa: HDR, SA, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i, HASH_R
910 * rev: HDR, SA, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDir_b>Ke_r, HASH_R
913 agg_r1send(iph1
, msg
)
914 struct ph1handle
*iph1
;
917 struct payload_list
*plist
= NULL
;
921 vchar_t
*xauth_vid
= NULL
;
922 vchar_t
*unity_vid
= NULL
;
925 vchar_t
*vid_natt
= NULL
;
926 vchar_t
*natd
[2] = { NULL
, NULL
};
929 vchar_t
*vid_dpd
= NULL
;
932 vchar_t
*vid_frag
= NULL
;
937 vchar_t
*gsstoken
= NULL
, *gsshash
= NULL
;
938 vchar_t
*gss_sa
= NULL
;
943 if (iph1
->status
!= PHASE1ST_MSG1RECEIVED
) {
944 plog(LLV_ERROR
, LOCATION
, NULL
,
945 "status mismatched %d.\n", iph1
->status
);
949 /* set responder's cookie */
950 isakmp_newcookie((caddr_t
)&iph1
->index
.r_ck
, iph1
->remote
, iph1
->local
);
952 /* make ID payload into isakmp status */
953 if (ipsecdoi_setid1(iph1
) < 0)
956 /* generate DH public value */
957 if (oakley_dh_generate(iph1
->rmconf
->dhgrp
,
958 &iph1
->dhpub
, &iph1
->dhpriv
) < 0)
961 /* generate NONCE value */
962 iph1
->nonce
= eay_set_random(iph1
->rmconf
->nonce_size
);
963 if (iph1
->nonce
== NULL
)
966 /* compute sharing secret of DH */
967 if (oakley_dh_compute(iph1
->approval
->dhgrp
, iph1
->dhpub
,
968 iph1
->dhpriv
, iph1
->dhpub_p
, &iph1
->dhgxy
) < 0)
971 /* generate SKEYIDs & IV & final cipher key */
972 if (oakley_skeyid(iph1
) < 0)
974 if (oakley_skeyid_dae(iph1
) < 0)
976 if (oakley_compute_enckey(iph1
) < 0)
978 if (oakley_newiv(iph1
) < 0)
982 if (iph1
->rmconf
->proposal
->authmethod
== OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB
)
983 gssapi_get_rtoken(iph1
, &gsslen
);
986 /* generate HASH to send */
987 plog(LLV_DEBUG
, LOCATION
, NULL
, "generate HASH_R\n");
988 iph1
->hash
= oakley_ph1hash_common(iph1
, GENERATE
);
989 if (iph1
->hash
== NULL
) {
991 if (gssapi_more_tokens(iph1
))
992 isakmp_info_send_n1(iph1
,
993 ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE
, NULL
);
999 /* Has the peer announced NAT-T? */
1000 if (NATT_AVAILABLE(iph1
)) {
1001 /* set chosen VID */
1002 vid_natt
= set_vendorid(iph1
->natt_options
->version
);
1004 /* generate NAT-D payloads */
1005 plog (LLV_INFO
, LOCATION
, NULL
, "Adding remote and local NAT-D payloads.\n");
1006 if ((natd
[0] = natt_hash_addr (iph1
, iph1
->remote
)) == NULL
) {
1007 plog(LLV_ERROR
, LOCATION
, NULL
,
1008 "NAT-D hashing failed for %s\n", saddr2str(iph1
->remote
));
1012 if ((natd
[1] = natt_hash_addr (iph1
, iph1
->local
)) == NULL
) {
1013 plog(LLV_ERROR
, LOCATION
, NULL
,
1014 "NAT-D hashing failed for %s\n", saddr2str(iph1
->local
));
1020 /* Only send DPD support if remote announced DPD and if DPD support is active */
1021 if (iph1
->dpd_support
&& iph1
->rmconf
->dpd
)
1022 vid_dpd
= set_vendorid(VENDORID_DPD
);
1026 vid_frag
= set_vendorid(VENDORID_FRAG
);
1027 if (vid_frag
!= NULL
)
1028 vid_frag
= isakmp_frag_addcap(vid_frag
,
1030 if (vid_frag
== NULL
)
1031 plog(LLV_ERROR
, LOCATION
, NULL
,
1032 "Frag vendorID construction failed\n");
1036 switch (iph1
->approval
->authmethod
) {
1037 case OAKLEY_ATTR_AUTH_METHOD_PSKEY
:
1038 #ifdef ENABLE_HYBRID
1039 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R
:
1041 /* set SA payload to reply */
1042 plist
= isakmp_plist_append(plist
,
1043 iph1
->sa_ret
, ISAKMP_NPTYPE_SA
);
1045 /* create isakmp KE payload */
1046 plist
= isakmp_plist_append(plist
,
1047 iph1
->dhpub
, ISAKMP_NPTYPE_KE
);
1049 /* create isakmp NONCE payload */
1050 plist
= isakmp_plist_append(plist
,
1051 iph1
->nonce
, ISAKMP_NPTYPE_NONCE
);
1053 /* create isakmp ID payload */
1054 plist
= isakmp_plist_append(plist
,
1055 iph1
->id
, ISAKMP_NPTYPE_ID
);
1057 /* create isakmp HASH payload */
1058 plist
= isakmp_plist_append(plist
,
1059 iph1
->hash
, ISAKMP_NPTYPE_HASH
);
1061 /* create isakmp CR payload if needed */
1062 if (oakley_needcr(iph1
->approval
->authmethod
))
1063 plist
= oakley_append_cr(plist
, iph1
);
1065 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG
:
1066 case OAKLEY_ATTR_AUTH_METHOD_RSASIG
:
1067 #ifdef ENABLE_HYBRID
1068 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R
:
1069 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R
:
1070 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R
:
1071 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R
:
1073 /* XXX if there is CR or not ? */
1075 if (oakley_getmycert(iph1
) < 0)
1078 if (oakley_getsign(iph1
) < 0)
1081 if (iph1
->cert
!= NULL
&& iph1
->rmconf
->send_cert
)
1084 /* set SA payload to reply */
1085 plist
= isakmp_plist_append(plist
,
1086 iph1
->sa_ret
, ISAKMP_NPTYPE_SA
);
1088 /* create isakmp KE payload */
1089 plist
= isakmp_plist_append(plist
,
1090 iph1
->dhpub
, ISAKMP_NPTYPE_KE
);
1092 /* create isakmp NONCE payload */
1093 plist
= isakmp_plist_append(plist
,
1094 iph1
->nonce
, ISAKMP_NPTYPE_NONCE
);
1096 /* add ID payload */
1097 plist
= isakmp_plist_append(plist
,
1098 iph1
->id
, ISAKMP_NPTYPE_ID
);
1100 /* add CERT payload if there */
1102 plist
= isakmp_plist_append(plist
, iph1
->cert
,
1103 ISAKMP_NPTYPE_CERT
);
1105 /* add SIG payload */
1106 plist
= isakmp_plist_append(plist
,
1107 iph1
->sig
, ISAKMP_NPTYPE_SIG
);
1109 /* create isakmp CR payload if needed */
1110 if (oakley_needcr(iph1
->approval
->authmethod
))
1111 plist
= oakley_append_cr(plist
, iph1
);
1114 case OAKLEY_ATTR_AUTH_METHOD_RSAENC
:
1115 case OAKLEY_ATTR_AUTH_METHOD_RSAREV
:
1116 #ifdef ENABLE_HYBRID
1117 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R
:
1118 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R
:
1122 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB
:
1123 /* create buffer to send isakmp payload */
1124 gsshash
= gssapi_wraphash(iph1
);
1125 if (gsshash
== NULL
) {
1126 plog(LLV_ERROR
, LOCATION
, NULL
,
1127 "failed to wrap hash\n");
1129 * This is probably due to the GSS
1130 * roundtrips not being finished yet.
1131 * Return this error in the hope that
1132 * a fallback to main mode will be done.
1134 isakmp_info_send_n1(iph1
,
1135 ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE
, NULL
);
1138 if (iph1
->approval
->gssid
!= NULL
)
1139 gss_sa
= ipsecdoi_setph1proposal(iph1
->rmconf
,
1142 gss_sa
= iph1
->sa_ret
;
1144 if (gss_sa
!= iph1
->sa_ret
)
1147 /* set SA payload to reply */
1148 plist
= isakmp_plist_append(plist
,
1149 gss_sa
, ISAKMP_NPTYPE_SA
);
1151 /* create isakmp KE payload */
1152 plist
= isakmp_plist_append(plist
,
1153 iph1
->dhpub
, ISAKMP_NPTYPE_KE
);
1155 /* create isakmp NONCE payload */
1156 plist
= isakmp_plist_append(plist
,
1157 iph1
->nonce
, ISAKMP_NPTYPE_NONCE
);
1159 /* create isakmp ID payload */
1160 plist
= isakmp_plist_append(plist
,
1161 iph1
->id
, ISAKMP_NPTYPE_ID
);
1163 /* create GSS payload */
1164 if (gssapi_get_token_to_send(iph1
, &gsstoken
) < 0) {
1165 plog(LLV_ERROR
, LOCATION
, NULL
,
1166 "Failed to get gssapi token.\n");
1169 plist
= isakmp_plist_append(plist
,
1170 gsstoken
, ISAKMP_NPTYPE_GSS
);
1172 /* create isakmp HASH payload */
1173 plist
= isakmp_plist_append(plist
,
1174 gsshash
, ISAKMP_NPTYPE_HASH
);
1176 /* append vendor id, if needed */
1181 #ifdef ENABLE_HYBRID
1182 if (iph1
->mode_cfg
->flags
& ISAKMP_CFG_VENDORID_XAUTH
) {
1183 plog (LLV_INFO
, LOCATION
, NULL
, "Adding xauth VID payload.\n");
1184 if ((xauth_vid
= set_vendorid(VENDORID_XAUTH
)) == NULL
) {
1185 plog(LLV_ERROR
, LOCATION
, NULL
,
1186 "Cannot create Xauth vendor ID\n");
1189 plist
= isakmp_plist_append(plist
,
1190 xauth_vid
, ISAKMP_NPTYPE_VID
);
1193 if (iph1
->mode_cfg
->flags
& ISAKMP_CFG_VENDORID_UNITY
) {
1194 if ((unity_vid
= set_vendorid(VENDORID_UNITY
)) == NULL
) {
1195 plog(LLV_ERROR
, LOCATION
, NULL
,
1196 "Cannot create Unity vendor ID\n");
1199 plist
= isakmp_plist_append(plist
,
1200 unity_vid
, ISAKMP_NPTYPE_VID
);
1205 /* append NAT-T payloads */
1208 plist
= isakmp_plist_append(plist
, vid_natt
, ISAKMP_NPTYPE_VID
);
1210 plist
= isakmp_plist_append(plist
, natd
[0], iph1
->natt_options
->payload_nat_d
);
1211 plist
= isakmp_plist_append(plist
, natd
[1], iph1
->natt_options
->payload_nat_d
);
1217 plist
= isakmp_plist_append(plist
, vid_frag
, ISAKMP_NPTYPE_VID
);
1222 plist
= isakmp_plist_append(plist
, vid_dpd
, ISAKMP_NPTYPE_VID
);
1225 iph1
->sendbuf
= isakmp_plist_set_all (&plist
, iph1
);
1227 #ifdef HAVE_PRINT_ISAKMP_C
1228 isakmp_printpacket(iph1
->sendbuf
, iph1
->local
, iph1
->remote
, 1);
1231 /* send the packet, add to the schedule to resend */
1232 if (isakmp_ph1send(iph1
) == -1)
1235 /* the sending message is added to the received-list. */
1236 if (add_recvdpkt(iph1
->remote
, iph1
->local
, iph1
->sendbuf
, msg
) == -1) {
1237 plog(LLV_ERROR
, LOCATION
, NULL
,
1238 "failed to add a response packet to the tree.\n");
1242 iph1
->status
= PHASE1ST_MSG1SENT
;
1247 #ifdef ENABLE_HYBRID
1274 * receive from initiator
1276 * gssapi: HDR, HASH_I
1277 * sig: HDR, [ CERT, ] SIG_I
1282 agg_r2recv(iph1
, msg0
)
1283 struct ph1handle
*iph1
;
1286 vchar_t
*msg
= NULL
;
1287 vchar_t
*pbuf
= NULL
;
1288 struct isakmp_parse_t
*pa
;
1289 int error
= -1, ptype
;
1294 /* validity check */
1295 if (iph1
->status
!= PHASE1ST_MSG1SENT
) {
1296 plog(LLV_ERROR
, LOCATION
, NULL
,
1297 "status mismatched %d.\n", iph1
->status
);
1301 /* decrypting if need. */
1302 /* XXX configurable ? */
1303 if (ISSET(((struct isakmp
*)msg0
->v
)->flags
, ISAKMP_FLAG_E
)) {
1304 msg
= oakley_do_decrypt(iph1
, msg0
,
1305 iph1
->ivm
->iv
, iph1
->ivm
->ive
);
1311 /* validate the type of next payload */
1312 pbuf
= isakmp_parse(msg
);
1316 iph1
->pl_hash
= NULL
;
1318 for (pa
= (struct isakmp_parse_t
*)pbuf
->v
;
1319 pa
->type
!= ISAKMP_NPTYPE_NONE
;
1323 case ISAKMP_NPTYPE_HASH
:
1324 iph1
->pl_hash
= (struct isakmp_pl_hash
*)pa
->ptr
;
1326 case ISAKMP_NPTYPE_VID
:
1327 handle_vendorid(iph1
, pa
->ptr
);
1329 case ISAKMP_NPTYPE_CERT
:
1330 if (oakley_savecert(iph1
, pa
->ptr
) < 0)
1333 case ISAKMP_NPTYPE_SIG
:
1334 if (isakmp_p2ph(&iph1
->sig_p
, pa
->ptr
) < 0)
1337 case ISAKMP_NPTYPE_N
:
1338 isakmp_log_notify(iph1
,
1339 (struct isakmp_pl_n
*) pa
->ptr
,
1340 "aggressive exchange");
1344 case ISAKMP_NPTYPE_NATD_DRAFT
:
1345 case ISAKMP_NPTYPE_NATD_RFC
:
1346 if (NATT_AVAILABLE(iph1
) && iph1
->natt_options
!= NULL
&&
1347 pa
->type
== iph1
->natt_options
->payload_nat_d
)
1349 vchar_t
*natd_received
= NULL
;
1352 if (isakmp_p2ph (&natd_received
, pa
->ptr
) < 0)
1356 iph1
->natt_flags
|= NAT_DETECTED
;
1358 natd_verified
= natt_compare_addr_hash (iph1
,
1359 natd_received
, natd_seq
++);
1361 plog (LLV_INFO
, LOCATION
, NULL
, "NAT-D payload #%d %s\n",
1363 natd_verified
? "verified" : "doesn't match");
1365 vfree (natd_received
);
1368 /* passthrough to default... */
1372 /* don't send information, see isakmp_ident_r1() */
1373 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
1374 "ignore the packet, "
1375 "received unexpecting payload type %d.\n",
1382 if (NATT_AVAILABLE(iph1
))
1383 plog (LLV_INFO
, LOCATION
, NULL
, "NAT %s %s%s\n",
1384 iph1
->natt_flags
& NAT_DETECTED
?
1385 "detected:" : "not detected",
1386 iph1
->natt_flags
& NAT_DETECTED_ME
? "ME " : "",
1387 iph1
->natt_flags
& NAT_DETECTED_PEER
? "PEER" : "");
1390 /* validate authentication value */
1391 ptype
= oakley_validate_auth(iph1
);
1394 /* message printed inner oakley_validate_auth() */
1397 evt_phase1(iph1
, EVT_PHASE1_AUTH_FAILED
, NULL
);
1398 isakmp_info_send_n1(iph1
, ptype
, NULL
);
1402 iph1
->status
= PHASE1ST_MSG2RECEIVED
;
1412 VPTRINIT(iph1
->cert_p
);
1413 VPTRINIT(iph1
->crl_p
);
1414 VPTRINIT(iph1
->sig_p
);
1421 * status update and establish isakmp sa.
1424 agg_r2send(iph1
, msg
)
1425 struct ph1handle
*iph1
;
1430 /* validity check */
1431 if (iph1
->status
!= PHASE1ST_MSG2RECEIVED
) {
1432 plog(LLV_ERROR
, LOCATION
, NULL
,
1433 "status mismatched %d.\n", iph1
->status
);
1437 /* IV synchronized when packet encrypted. */
1438 /* see handler.h about IV synchronization. */
1439 if (ISSET(((struct isakmp
*)msg
->v
)->flags
, ISAKMP_FLAG_E
))
1440 memcpy(iph1
->ivm
->iv
->v
, iph1
->ivm
->ive
->v
, iph1
->ivm
->iv
->l
);
1442 /* set encryption flag */
1443 iph1
->flags
|= ISAKMP_FLAG_E
;
1445 iph1
->status
= PHASE1ST_ESTABLISHED
;