1 /* $KAME: isakmp_agg.c,v 1.54 2001/12/11 20:33:41 sakane 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 /* Aggressive Exchange (Aggressive Mode) */
34 #include <sys/types.h>
35 #include <sys/param.h>
41 #if TIME_WITH_SYS_TIME
42 # include <sys/time.h>
46 # include <sys/time.h>
60 #include "localconf.h"
61 #include "remoteconf.h"
62 #include "isakmp_var.h"
66 #include "ipsec_doi.h"
67 #include "crypto_openssl.h"
69 #include "isakmp_agg.h"
70 #include "isakmp_inf.h"
79 * begin Aggressive Mode as initiator.
83 * psk: HDR, SA, KE, Ni, IDi1
84 * sig: HDR, SA, KE, Ni, IDi1 [, CR ]
85 * gssapi: HDR, SA, KE, Ni, IDi1, GSSi
86 * rsa: HDR, SA, [ HASH(1),] KE, <IDi1_b>Pubkey_r, <Ni_b>Pubkey_r
87 * rev: HDR, SA, [ HASH(1),] <Ni_b>Pubkey_r, <KE_b>Ke_i,
88 * <IDii_b>Ke_i [, <Cert-I_b>Ke_i ]
92 struct ph1handle
*iph1
;
93 vchar_t
*msg
; /* must be null */
95 struct isakmp_gen
*gen
;
99 vchar_t
*cr
= NULL
, *gsstoken
= NULL
;
108 plog(LLV_ERROR
, LOCATION
, NULL
,
109 "msg has to be NULL in this function.\n");
112 if (iph1
->status
!= PHASE1ST_START
) {
113 plog(LLV_ERROR
, LOCATION
, NULL
,
114 "status mismatched %d.\n", iph1
->status
);
118 /* create isakmp index */
119 memset(&iph1
->index
, 0, sizeof(iph1
->index
));
120 isakmp_newcookie((caddr_t
)&iph1
->index
, iph1
->remote
, iph1
->local
);
122 /* make ID payload into isakmp status */
123 if (ipsecdoi_setid1(iph1
) < 0)
126 /* create SA payload for my proposal */
127 iph1
->sa
= ipsecdoi_setph1proposal(iph1
->rmconf
->proposal
);
128 if (iph1
->sa
== NULL
)
131 /* consistency check of proposals */
132 if (iph1
->rmconf
->dhgrp
== NULL
) {
133 plog(LLV_ERROR
, LOCATION
, NULL
,
134 "configuration failure about DH group.\n");
138 /* generate DH public value */
139 if (oakley_dh_generate(iph1
->rmconf
->dhgrp
,
140 &iph1
->dhpub
, &iph1
->dhpriv
) < 0)
143 /* generate NONCE value */
144 iph1
->nonce
= eay_set_random(iph1
->rmconf
->nonce_size
);
145 if (iph1
->nonce
== NULL
)
148 #ifdef HAVE_SIGNING_C
149 /* create CR if need */
150 if (iph1
->rmconf
->send_cr
151 && oakley_needcr(iph1
->rmconf
->proposal
->authmethod
)
152 && iph1
->rmconf
->peerscertfile
== NULL
) {
154 cr
= oakley_getcr(iph1
);
156 plog(LLV_ERROR
, LOCATION
, NULL
,
157 "failed to get cr buffer.\n");
162 plog(LLV_DEBUG
, LOCATION
, NULL
, "authmethod is %s\n",
163 s_oakley_attr_method(iph1
->rmconf
->proposal
->authmethod
));
164 /* create buffer to send isakmp payload */
165 tlen
= sizeof(struct isakmp
)
166 + sizeof(*gen
) + iph1
->sa
->l
167 + sizeof(*gen
) + iph1
->dhpub
->l
168 + sizeof(*gen
) + iph1
->nonce
->l
169 + sizeof(*gen
) + iph1
->id
->l
;
171 tlen
+= sizeof(*gen
) + cr
->l
;
173 if (iph1
->rmconf
->proposal
->authmethod
==
174 OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB
) {
175 gssapi_get_itoken(iph1
, &len
);
176 tlen
+= sizeof (*gen
) + len
;
180 iph1
->sendbuf
= vmalloc(tlen
);
181 if (iph1
->sendbuf
== NULL
) {
182 plog(LLV_ERROR
, LOCATION
, NULL
,
183 "failed to get buffer to send.\n");
187 /* set isakmp header */
188 p
= set_isakmp_header(iph1
->sendbuf
, iph1
, ISAKMP_NPTYPE_SA
);
192 /* set SA payload to propose */
193 p
= set_isakmp_payload(p
, iph1
->sa
, ISAKMP_NPTYPE_KE
);
195 /* create isakmp KE payload */
196 p
= set_isakmp_payload(p
, iph1
->dhpub
, ISAKMP_NPTYPE_NONCE
);
198 /* create isakmp NONCE payload */
199 p
= set_isakmp_payload(p
, iph1
->nonce
, ISAKMP_NPTYPE_ID
);
201 /* create isakmp ID payload */
203 if (iph1
->rmconf
->proposal
->authmethod
==
204 OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB
)
205 nptype
= ISAKMP_NPTYPE_GSS
;
209 nptype
= ISAKMP_NPTYPE_CR
;
211 nptype
= ISAKMP_NPTYPE_NONE
;
213 p
= set_isakmp_payload(p
, iph1
->id
, nptype
);
216 if (iph1
->rmconf
->proposal
->authmethod
==
217 OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB
) {
218 gssapi_get_token_to_send(iph1
, &gsstoken
);
219 p
= set_isakmp_payload(p
, gsstoken
, ISAKMP_NPTYPE_NONE
);
223 /* create isakmp CR payload */
224 p
= set_isakmp_payload(p
, cr
, ISAKMP_NPTYPE_NONE
);
226 #ifdef HAVE_PRINT_ISAKMP_C
227 isakmp_printpacket(iph1
->sendbuf
, iph1
->local
, iph1
->remote
, 0);
230 /* send the packet, add to the schedule to resend */
231 iph1
->retry_counter
= iph1
->rmconf
->retry_counter
;
232 if (isakmp_ph1resend(iph1
) == -1)
235 iph1
->status
= PHASE1ST_MSG1SENT
;
249 * receive from responder
250 * psk: HDR, SA, KE, Nr, IDr1, HASH_R
251 * sig: HDR, SA, KE, Nr, IDr1, [ CR, ] [ CERT, ] SIG_R
252 * gssapi: HDR, SA, KE, Nr, IDr1, GSSr, HASH_R
253 * rsa: HDR, SA, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i, HASH_R
254 * rev: HDR, SA, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDir_b>Ke_r, HASH_R
257 agg_i2recv(iph1
, msg
)
258 struct ph1handle
*iph1
;
261 vchar_t
*pbuf
= NULL
;
262 struct isakmp_parse_t
*pa
;
263 vchar_t
*satmp
= NULL
;
266 vchar_t
*gsstoken
= NULL
;
270 if (iph1
->status
!= PHASE1ST_MSG1SENT
) {
271 plog(LLV_ERROR
, LOCATION
, NULL
,
272 "status mismatched %d.\n", iph1
->status
);
276 /* validate the type of next payload */
277 pbuf
= isakmp_parse(msg
);
280 pa
= (struct isakmp_parse_t
*)pbuf
->v
;
282 iph1
->pl_hash
= NULL
;
284 /* SA payload is fixed postion */
285 if (pa
->type
!= ISAKMP_NPTYPE_SA
) {
286 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
287 "received invalid next payload type %d, "
289 pa
->type
, ISAKMP_NPTYPE_SA
);
292 if (isakmp_p2ph(&satmp
, pa
->ptr
) < 0)
297 pa
->type
!= ISAKMP_NPTYPE_NONE
;
301 case ISAKMP_NPTYPE_KE
:
302 if (isakmp_p2ph(&iph1
->dhpub_p
, pa
->ptr
) < 0)
305 case ISAKMP_NPTYPE_NONCE
:
306 if (isakmp_p2ph(&iph1
->nonce_p
, pa
->ptr
) < 0)
309 case ISAKMP_NPTYPE_ID
:
310 if (isakmp_p2ph(&iph1
->id_p
, pa
->ptr
) < 0)
313 case ISAKMP_NPTYPE_HASH
:
314 iph1
->pl_hash
= (struct isakmp_pl_hash
*)pa
->ptr
;
316 #ifdef HAVE_SIGNING_C
317 case ISAKMP_NPTYPE_CR
:
318 if (oakley_savecr(iph1
, pa
->ptr
) < 0)
321 case ISAKMP_NPTYPE_CERT
:
322 if (oakley_savecert(iph1
, pa
->ptr
) < 0)
325 case ISAKMP_NPTYPE_SIG
:
326 if (isakmp_p2ph(&iph1
->sig_p
, pa
->ptr
) < 0)
330 case ISAKMP_NPTYPE_VID
:
331 (void)check_vendorid(pa
->ptr
);
333 case ISAKMP_NPTYPE_N
:
334 isakmp_check_notify(pa
->ptr
, iph1
);
337 case ISAKMP_NPTYPE_GSS
:
338 if (isakmp_p2ph(&gsstoken
, pa
->ptr
) < 0)
340 gssapi_save_received_token(iph1
, gsstoken
);
344 /* don't send information, see isakmp_ident_r1() */
345 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
346 "ignore the packet, "
347 "received unexpecting payload type %d.\n",
353 /* payload existency check */
354 /* XXX to be checked each authentication method. */
356 /* verify identifier */
357 if (ipsecdoi_checkid1(iph1
) != 0) {
358 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
359 "invalid ID payload.\n");
363 /* check SA payload and set approval SA for use */
364 if (ipsecdoi_checkph1proposal(satmp
, iph1
) < 0) {
365 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
366 "failed to get valid proposal.\n");
367 /* XXX send information */
375 /* fix isakmp index */
376 memcpy(&iph1
->index
.r_ck
, &((struct isakmp
*)msg
->v
)->r_ck
,
379 /* compute sharing secret of DH */
380 if (oakley_dh_compute(iph1
->rmconf
->dhgrp
, iph1
->dhpub
,
381 iph1
->dhpriv
, iph1
->dhpub_p
, &iph1
->dhgxy
) < 0)
384 /* generate SKEYIDs & IV & final cipher key */
385 if (oakley_skeyid(iph1
) < 0)
387 if (oakley_skeyid_dae(iph1
) < 0)
389 if (oakley_compute_enckey(iph1
) < 0)
391 if (oakley_newiv(iph1
) < 0)
394 /* validate authentication value */
397 type
= oakley_validate_auth(iph1
);
400 /* message printed inner oakley_validate_auth() */
403 isakmp_info_send_n1(iph1
, type
, NULL
);
408 #ifdef HAVE_SIGNING_C
409 if (oakley_checkcr(iph1
) < 0) {
410 /* Ignore this error in order to be interoperability. */
415 /* change status of isakmp status entry */
416 iph1
->status
= PHASE1ST_MSG2RECEIVED
;
426 VPTRINIT(iph1
->dhpub_p
);
427 VPTRINIT(iph1
->nonce_p
);
428 VPTRINIT(iph1
->id_p
);
429 oakley_delcert(iph1
->cert_p
);
431 oakley_delcert(iph1
->crl_p
);
433 VPTRINIT(iph1
->sig_p
);
434 oakley_delcert(iph1
->cr_p
);
444 * gssapi: HDR, HASH_I
445 * sig: HDR, [ CERT, ] SIG_I
450 agg_i2send(iph1
, msg
)
451 struct ph1handle
*iph1
;
454 struct isakmp_gen
*gen
;
459 vchar_t
*gsshash
= NULL
;
462 if (iph1
->status
!= PHASE1ST_MSG2RECEIVED
) {
463 plog(LLV_ERROR
, LOCATION
, NULL
,
464 "status mismatched %d.\n", iph1
->status
);
468 /* generate HASH to send */
469 plog(LLV_DEBUG
, LOCATION
, NULL
, "generate HASH_I\n");
470 iph1
->hash
= oakley_ph1hash_common(iph1
, GENERATE
);
471 if (iph1
->hash
== NULL
) {
473 if (gssapi_more_tokens(iph1
))
474 isakmp_info_send_n1(iph1
,
475 ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE
, NULL
);
480 tlen
= sizeof(struct isakmp
);
482 switch (iph1
->approval
->authmethod
) {
483 case OAKLEY_ATTR_AUTH_METHOD_PSKEY
:
484 tlen
+= sizeof(*gen
) + iph1
->hash
->l
;
486 iph1
->sendbuf
= vmalloc(tlen
);
487 if (iph1
->sendbuf
== NULL
) {
488 plog(LLV_ERROR
, LOCATION
, NULL
,
489 "failed to get buffer to send.\n");
493 /* set isakmp header */
494 p
= set_isakmp_header(iph1
->sendbuf
, iph1
, ISAKMP_NPTYPE_HASH
);
498 /* set HASH payload */
499 p
= set_isakmp_payload(p
, iph1
->hash
, ISAKMP_NPTYPE_NONE
);
501 #ifdef HAVE_SIGNING_C
502 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG
:
503 case OAKLEY_ATTR_AUTH_METHOD_RSASIG
:
504 /* XXX if there is CR or not ? */
506 if (oakley_getmycert(iph1
) < 0)
509 if (oakley_getsign(iph1
) < 0)
512 if (iph1
->cert
!= NULL
&& iph1
->rmconf
->send_cert
)
515 tlen
+= sizeof(*gen
) + iph1
->sig
->l
;
517 tlen
+= sizeof(*gen
) + iph1
->cert
->pl
->l
;
519 iph1
->sendbuf
= vmalloc(tlen
);
520 if (iph1
->sendbuf
== NULL
) {
521 plog(LLV_ERROR
, LOCATION
, NULL
,
522 "failed to get buffer to send.\n");
526 /* set isakmp header */
527 p
= set_isakmp_header(iph1
->sendbuf
, iph1
, need_cert
529 : ISAKMP_NPTYPE_SIG
);
533 /* add CERT payload if there */
535 p
= set_isakmp_payload(p
, iph1
->cert
->pl
, ISAKMP_NPTYPE_SIG
);
536 /* add SIG payload */
537 p
= set_isakmp_payload(p
, iph1
->sig
, ISAKMP_NPTYPE_NONE
);
540 case OAKLEY_ATTR_AUTH_METHOD_RSAENC
:
541 case OAKLEY_ATTR_AUTH_METHOD_RSAREV
:
542 tlen
+= sizeof(*gen
) + iph1
->hash
->l
;
545 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB
:
546 gsshash
= gssapi_wraphash(iph1
);
547 if (gsshash
== NULL
) {
548 plog(LLV_ERROR
, LOCATION
, NULL
,
549 "failed to wrap hash\n");
550 isakmp_info_send_n1(iph1
,
551 ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE
, NULL
);
554 tlen
+= sizeof(*gen
) + gsshash
->l
;
556 iph1
->sendbuf
= vmalloc(tlen
);
557 if (iph1
->sendbuf
== NULL
) {
558 plog(LLV_ERROR
, LOCATION
, NULL
,
559 "failed to get buffer to send.\n");
562 /* set isakmp header */
563 p
= set_isakmp_header(iph1
->sendbuf
, iph1
, ISAKMP_NPTYPE_HASH
);
566 p
= set_isakmp_payload(p
, gsshash
, ISAKMP_NPTYPE_NONE
);
571 #ifdef HAVE_PRINT_ISAKMP_C
572 isakmp_printpacket(iph1
->sendbuf
, iph1
->local
, iph1
->remote
, 0);
575 /* send to responder */
576 if (isakmp_send(iph1
, iph1
->sendbuf
) < 0)
579 /* the sending message is added to the received-list. */
580 if (add_recvdpkt(iph1
->remote
, iph1
->local
, iph1
->sendbuf
, msg
) == -1) {
581 plog(LLV_ERROR
, LOCATION
, NULL
,
582 "failed to add a response packet to the tree.\n");
586 /* set encryption flag */
587 iph1
->flags
|= ISAKMP_FLAG_E
;
589 iph1
->status
= PHASE1ST_ESTABLISHED
;
600 * receive from initiator
601 * psk: HDR, SA, KE, Ni, IDi1
602 * sig: HDR, SA, KE, Ni, IDi1 [, CR ]
603 * gssapi: HDR, SA, KE, Ni, IDi1 , GSSi
604 * rsa: HDR, SA, [ HASH(1),] KE, <IDi1_b>Pubkey_r, <Ni_b>Pubkey_r
605 * rev: HDR, SA, [ HASH(1),] <Ni_b>Pubkey_r, <KE_b>Ke_i,
606 * <IDii_b>Ke_i [, <Cert-I_b>Ke_i ]
609 agg_r1recv(iph1
, msg
)
610 struct ph1handle
*iph1
;
614 vchar_t
*pbuf
= NULL
;
615 struct isakmp_parse_t
*pa
;
617 vchar_t
*gsstoken
= NULL
;
621 if (iph1
->status
!= PHASE1ST_START
) {
622 plog(LLV_ERROR
, LOCATION
, NULL
,
623 "status mismatched %d.\n", iph1
->status
);
627 /* validate the type of next payload */
628 pbuf
= isakmp_parse(msg
);
631 pa
= (struct isakmp_parse_t
*)pbuf
->v
;
633 /* SA payload is fixed postion */
634 if (pa
->type
!= ISAKMP_NPTYPE_SA
) {
635 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
636 "received invalid next payload type %d, "
638 pa
->type
, ISAKMP_NPTYPE_SA
);
641 if (isakmp_p2ph(&iph1
->sa
, pa
->ptr
) < 0)
646 pa
->type
!= ISAKMP_NPTYPE_NONE
;
649 plog(LLV_DEBUG
, LOCATION
, NULL
,
650 "received payload of type %s\n",
651 s_isakmp_nptype(pa
->type
));
654 case ISAKMP_NPTYPE_KE
:
655 if (isakmp_p2ph(&iph1
->dhpub_p
, pa
->ptr
) < 0)
658 case ISAKMP_NPTYPE_NONCE
:
659 if (isakmp_p2ph(&iph1
->nonce_p
, pa
->ptr
) < 0)
662 case ISAKMP_NPTYPE_ID
:
663 if (isakmp_p2ph(&iph1
->id_p
, pa
->ptr
) < 0)
666 case ISAKMP_NPTYPE_VID
:
667 (void)check_vendorid(pa
->ptr
);
669 #ifdef HAVE_SIGNING_C
670 case ISAKMP_NPTYPE_CR
:
671 if (oakley_savecr(iph1
, pa
->ptr
) < 0)
676 case ISAKMP_NPTYPE_GSS
:
677 if (isakmp_p2ph(&gsstoken
, pa
->ptr
) < 0)
679 gssapi_save_received_token(iph1
, gsstoken
);
683 /* don't send information, see isakmp_ident_r1() */
684 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
685 "ignore the packet, "
686 "received unexpecting payload type %d.\n",
692 /* payload existency check */
693 /* XXX to be checked each authentication method. */
695 /* verify identifier */
696 if (ipsecdoi_checkid1(iph1
) != 0) {
697 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
698 "invalid ID payload.\n");
702 /* check SA payload and set approval SA for use */
703 if (ipsecdoi_checkph1proposal(iph1
->sa
, iph1
) < 0) {
704 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
705 "failed to get valid proposal.\n");
706 /* XXX send information */
710 #ifdef HAVE_SIGNING_C
711 if (oakley_checkcr(iph1
) < 0) {
712 /* Ignore this error in order to be interoperability. */
717 iph1
->status
= PHASE1ST_MSG1RECEIVED
;
726 VPTRINIT(iph1
->dhpub_p
);
727 VPTRINIT(iph1
->nonce_p
);
728 VPTRINIT(iph1
->id_p
);
729 oakley_delcert(iph1
->cr_p
);
738 * psk: HDR, SA, KE, Nr, IDr1, HASH_R
739 * sig: HDR, SA, KE, Nr, IDr1, [ CR, ] [ CERT, ] SIG_R
740 * gssapi: HDR, SA, KE, Nr, IDr1, GSSr, HASH_R
741 * rsa: HDR, SA, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i, HASH_R
742 * rev: HDR, SA, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDir_b>Ke_r, HASH_R
745 agg_r1send(iph1
, msg
)
746 struct ph1handle
*iph1
;
749 struct isakmp_gen
*gen
;
759 vchar_t
*gsstoken
= NULL
, *gsshash
= NULL
;
760 vchar_t
*gss_sa
= NULL
;
764 if (iph1
->status
!= PHASE1ST_MSG1RECEIVED
) {
765 plog(LLV_ERROR
, LOCATION
, NULL
,
766 "status mismatched %d.\n", iph1
->status
);
770 /* set responder's cookie */
771 isakmp_newcookie((caddr_t
)&iph1
->index
.r_ck
, iph1
->remote
, iph1
->local
);
773 /* make ID payload into isakmp status */
774 if (ipsecdoi_setid1(iph1
) < 0)
777 /* generate DH public value */
778 if (oakley_dh_generate(iph1
->rmconf
->dhgrp
,
779 &iph1
->dhpub
, &iph1
->dhpriv
) < 0)
782 /* generate NONCE value */
783 iph1
->nonce
= eay_set_random(iph1
->rmconf
->nonce_size
);
784 if (iph1
->nonce
== NULL
)
787 /* compute sharing secret of DH */
788 if (oakley_dh_compute(iph1
->approval
->dhgrp
, iph1
->dhpub
,
789 iph1
->dhpriv
, iph1
->dhpub_p
, &iph1
->dhgxy
) < 0)
792 /* generate SKEYIDs & IV & final cipher key */
793 if (oakley_skeyid(iph1
) < 0)
795 if (oakley_skeyid_dae(iph1
) < 0)
797 if (oakley_compute_enckey(iph1
) < 0)
799 if (oakley_newiv(iph1
) < 0)
803 if (iph1
->rmconf
->proposal
->authmethod
==
804 OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB
)
805 gssapi_get_rtoken(iph1
, &gsslen
);
808 /* generate HASH to send */
809 plog(LLV_DEBUG
, LOCATION
, NULL
, "generate HASH_R\n");
810 iph1
->hash
= oakley_ph1hash_common(iph1
, GENERATE
);
811 if (iph1
->hash
== NULL
) {
813 if (gssapi_more_tokens(iph1
))
814 isakmp_info_send_n1(iph1
,
815 ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE
, NULL
);
820 #ifdef HAVE_SIGNING_C
821 /* create CR if need */
822 if (iph1
->rmconf
->send_cr
823 && oakley_needcr(iph1
->approval
->authmethod
)
824 && iph1
->rmconf
->peerscertfile
== NULL
) {
826 cr
= oakley_getcr(iph1
);
828 plog(LLV_ERROR
, LOCATION
, NULL
,
829 "failed to get cr buffer.\n");
835 tlen
= sizeof(struct isakmp
);
837 switch (iph1
->approval
->authmethod
) {
838 case OAKLEY_ATTR_AUTH_METHOD_PSKEY
:
839 /* create buffer to send isakmp payload */
840 tlen
+= sizeof(*gen
) + iph1
->sa_ret
->l
841 + sizeof(*gen
) + iph1
->dhpub
->l
842 + sizeof(*gen
) + iph1
->nonce
->l
843 + sizeof(*gen
) + iph1
->id
->l
844 + sizeof(*gen
) + iph1
->hash
->l
;
845 if ((vid
= set_vendorid(iph1
->approval
->vendorid
)) != NULL
)
846 tlen
+= sizeof(*gen
) + vid
->l
;
848 tlen
+= sizeof(*gen
) + cr
->l
;
850 iph1
->sendbuf
= vmalloc(tlen
);
851 if (iph1
->sendbuf
== NULL
) {
852 plog(LLV_ERROR
, LOCATION
, NULL
,
853 "failed to get buffer to send\n");
857 /* set isakmp header */
858 p
= set_isakmp_header(iph1
->sendbuf
, iph1
, ISAKMP_NPTYPE_SA
);
862 /* set SA payload to reply */
863 p
= set_isakmp_payload(p
, iph1
->sa_ret
, ISAKMP_NPTYPE_KE
);
865 /* create isakmp KE payload */
866 p
= set_isakmp_payload(p
, iph1
->dhpub
, ISAKMP_NPTYPE_NONCE
);
868 /* create isakmp NONCE payload */
869 p
= set_isakmp_payload(p
, iph1
->nonce
, ISAKMP_NPTYPE_ID
);
871 /* create isakmp ID payload */
872 p
= set_isakmp_payload(p
, iph1
->id
, ISAKMP_NPTYPE_HASH
);
874 /* create isakmp HASH payload */
875 p
= set_isakmp_payload(p
, iph1
->hash
,
876 vid
? ISAKMP_NPTYPE_VID
877 : (need_cr
? ISAKMP_NPTYPE_CR
878 : ISAKMP_NPTYPE_NONE
));
880 /* append vendor id, if needed */
882 p
= set_isakmp_payload(p
, vid
,
883 need_cr
? ISAKMP_NPTYPE_CR
884 : ISAKMP_NPTYPE_NONE
);
886 /* create isakmp CR payload if needed */
888 p
= set_isakmp_payload(p
, cr
, ISAKMP_NPTYPE_NONE
);
890 #ifdef HAVE_SIGNING_C
891 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG
:
892 case OAKLEY_ATTR_AUTH_METHOD_RSASIG
:
893 /* XXX if there is CR or not ? */
895 if (oakley_getmycert(iph1
) < 0)
898 if (oakley_getsign(iph1
) < 0)
901 if (iph1
->cert
!= NULL
&& iph1
->rmconf
->send_cert
)
904 tlen
+= sizeof(*gen
) + iph1
->sa_ret
->l
905 + sizeof(*gen
) + iph1
->dhpub
->l
906 + sizeof(*gen
) + iph1
->nonce
->l
907 + sizeof(*gen
) + iph1
->id
->l
908 + sizeof(*gen
) + iph1
->sig
->l
;
910 tlen
+= sizeof(*gen
) + iph1
->cert
->pl
->l
;
911 if ((vid
= set_vendorid(iph1
->approval
->vendorid
)) != NULL
)
912 tlen
+= sizeof(*gen
) + vid
->l
;
914 tlen
+= sizeof(*gen
) + cr
->l
;
916 iph1
->sendbuf
= vmalloc(tlen
);
917 if (iph1
->sendbuf
== NULL
) {
918 plog(LLV_ERROR
, LOCATION
, NULL
,
919 "failed to get buffer to send.\n");
923 /* set isakmp header */
924 p
= set_isakmp_header(iph1
->sendbuf
, iph1
, ISAKMP_NPTYPE_SA
);
928 /* set SA payload to reply */
929 p
= set_isakmp_payload(p
, iph1
->sa_ret
, ISAKMP_NPTYPE_KE
);
931 /* create isakmp KE payload */
932 p
= set_isakmp_payload(p
, iph1
->dhpub
, ISAKMP_NPTYPE_NONCE
);
934 /* create isakmp NONCE payload */
935 p
= set_isakmp_payload(p
, iph1
->nonce
, ISAKMP_NPTYPE_ID
);
938 p
= set_isakmp_payload(p
, iph1
->id
, need_cert
940 : ISAKMP_NPTYPE_SIG
);
942 /* add CERT payload if there */
944 p
= set_isakmp_payload(p
, iph1
->cert
->pl
, ISAKMP_NPTYPE_SIG
);
945 /* add SIG payload */
946 p
= set_isakmp_payload(p
, iph1
->sig
,
947 vid
? ISAKMP_NPTYPE_VID
948 : (need_cr
? ISAKMP_NPTYPE_CR
949 : ISAKMP_NPTYPE_NONE
));
951 /* append vendor id, if needed */
953 p
= set_isakmp_payload(p
, vid
,
954 need_cr
? ISAKMP_NPTYPE_CR
955 : ISAKMP_NPTYPE_NONE
);
957 /* create isakmp CR payload if needed */
959 p
= set_isakmp_payload(p
, cr
, ISAKMP_NPTYPE_NONE
);
962 case OAKLEY_ATTR_AUTH_METHOD_RSAENC
:
963 case OAKLEY_ATTR_AUTH_METHOD_RSAREV
:
964 tlen
+= sizeof(*gen
) + iph1
->hash
->l
;
967 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB
:
968 /* create buffer to send isakmp payload */
969 gsshash
= gssapi_wraphash(iph1
);
970 if (gsshash
== NULL
) {
971 plog(LLV_ERROR
, LOCATION
, NULL
,
972 "failed to wrap hash\n");
974 * This is probably due to the GSS roundtrips not
975 * being finished yet. Return this error in
976 * the hope that a fallback to main mode will
979 isakmp_info_send_n1(iph1
,
980 ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE
, NULL
);
983 if (iph1
->approval
->gssid
!= NULL
)
984 gss_sa
= ipsecdoi_setph1proposal(iph1
->approval
);
986 gss_sa
= iph1
->sa_ret
;
988 tlen
+= sizeof(*gen
) + gss_sa
->l
989 + sizeof(*gen
) + iph1
->dhpub
->l
990 + sizeof(*gen
) + iph1
->nonce
->l
991 + sizeof(*gen
) + iph1
->id
->l
992 + sizeof(*gen
) + gsslen
993 + sizeof(*gen
) + gsshash
->l
;
994 if ((vid
= set_vendorid(iph1
->approval
->vendorid
)) != NULL
)
995 tlen
+= sizeof(*gen
) + vid
->l
;
996 iph1
->sendbuf
= vmalloc(tlen
);
997 if (iph1
->sendbuf
== NULL
) {
998 plog(LLV_ERROR
, LOCATION
, NULL
,
999 "failed to get buffer to send\n");
1003 /* set isakmp header */
1004 p
= set_isakmp_header(iph1
->sendbuf
, iph1
, ISAKMP_NPTYPE_SA
);
1008 /* set SA payload to reply */
1009 p
= set_isakmp_payload(p
, gss_sa
, ISAKMP_NPTYPE_KE
);
1011 /* create isakmp KE payload */
1012 p
= set_isakmp_payload(p
, iph1
->dhpub
, ISAKMP_NPTYPE_NONCE
);
1014 /* create isakmp NONCE payload */
1015 p
= set_isakmp_payload(p
, iph1
->nonce
, ISAKMP_NPTYPE_ID
);
1017 /* create isakmp ID payload */
1018 p
= set_isakmp_payload(p
, iph1
->id
, ISAKMP_NPTYPE_GSS
);
1020 /* create GSS payload */
1021 gssapi_get_token_to_send(iph1
, &gsstoken
);
1022 p
= set_isakmp_payload(p
, gsstoken
, ISAKMP_NPTYPE_HASH
);
1024 /* create isakmp HASH payload */
1025 p
= set_isakmp_payload(p
, gsshash
,
1026 vid
!= NULL
? ISAKMP_NPTYPE_VID
1027 : ISAKMP_NPTYPE_NONE
);
1029 /* append vendor id, if needed */
1031 p
= set_isakmp_payload(p
, vid
, ISAKMP_NPTYPE_NONE
);
1037 #ifdef HAVE_PRINT_ISAKMP_C
1038 isakmp_printpacket(iph1
->sendbuf
, iph1
->local
, iph1
->remote
, 1);
1041 /* send the packet, add to the schedule to resend */
1042 iph1
->retry_counter
= iph1
->rmconf
->retry_counter
;
1043 if (isakmp_ph1resend(iph1
) == -1)
1046 /* the sending message is added to the received-list. */
1047 if (add_recvdpkt(iph1
->remote
, iph1
->local
, iph1
->sendbuf
, msg
) == -1) {
1048 plog(LLV_ERROR
, LOCATION
, NULL
,
1049 "failed to add a response packet to the tree.\n");
1053 iph1
->status
= PHASE1ST_MSG1SENT
;
1067 if (gss_sa
!= iph1
->sa_ret
)
1075 * receive from initiator
1077 * gssapi: HDR, HASH_I
1078 * sig: HDR, [ CERT, ] SIG_I
1083 agg_r2recv(iph1
, msg0
)
1084 struct ph1handle
*iph1
;
1087 vchar_t
*msg
= NULL
;
1088 vchar_t
*pbuf
= NULL
;
1089 struct isakmp_parse_t
*pa
;
1092 /* validity check */
1093 if (iph1
->status
!= PHASE1ST_MSG1SENT
) {
1094 plog(LLV_ERROR
, LOCATION
, NULL
,
1095 "status mismatched %d.\n", iph1
->status
);
1099 /* decrypting if need. */
1100 /* XXX configurable ? */
1101 if (ISSET(((struct isakmp
*)msg0
->v
)->flags
, ISAKMP_FLAG_E
)) {
1102 msg
= oakley_do_decrypt(iph1
, msg0
,
1103 iph1
->ivm
->iv
, iph1
->ivm
->ive
);
1109 /* validate the type of next payload */
1110 pbuf
= isakmp_parse(msg
);
1114 iph1
->pl_hash
= NULL
;
1116 for (pa
= (struct isakmp_parse_t
*)pbuf
->v
;
1117 pa
->type
!= ISAKMP_NPTYPE_NONE
;
1121 case ISAKMP_NPTYPE_HASH
:
1122 iph1
->pl_hash
= (struct isakmp_pl_hash
*)pa
->ptr
;
1124 case ISAKMP_NPTYPE_VID
:
1125 (void)check_vendorid(pa
->ptr
);
1127 #ifdef HAVE_SIGNING_C
1128 case ISAKMP_NPTYPE_CERT
:
1129 if (oakley_savecert(iph1
, pa
->ptr
) < 0)
1132 case ISAKMP_NPTYPE_SIG
:
1133 if (isakmp_p2ph(&iph1
->sig_p
, pa
->ptr
) < 0)
1137 case ISAKMP_NPTYPE_N
:
1138 isakmp_check_notify(pa
->ptr
, iph1
);
1141 /* don't send information, see isakmp_ident_r1() */
1142 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
1143 "ignore the packet, "
1144 "received unexpecting payload type %d.\n",
1150 /* validate authentication value */
1153 type
= oakley_validate_auth(iph1
);
1156 /* message printed inner oakley_validate_auth() */
1159 isakmp_info_send_n1(iph1
, type
, NULL
);
1164 iph1
->status
= PHASE1ST_MSG2RECEIVED
;
1174 oakley_delcert(iph1
->cert_p
);
1175 iph1
->cert_p
= NULL
;
1176 oakley_delcert(iph1
->crl_p
);
1178 VPTRINIT(iph1
->sig_p
);
1185 * status update and establish isakmp sa.
1188 agg_r2send(iph1
, msg
)
1189 struct ph1handle
*iph1
;
1194 /* validity check */
1195 if (iph1
->status
!= PHASE1ST_MSG2RECEIVED
) {
1196 plog(LLV_ERROR
, LOCATION
, NULL
,
1197 "status mismatched %d.\n", iph1
->status
);
1201 /* IV synchronized when packet encrypted. */
1202 /* see handler.h about IV synchronization. */
1203 if (ISSET(((struct isakmp
*)msg
->v
)->flags
, ISAKMP_FLAG_E
))
1204 memcpy(iph1
->ivm
->iv
->v
, iph1
->ivm
->ive
->v
, iph1
->ivm
->iv
->l
);
1206 /* set encryption flag */
1207 iph1
->flags
|= ISAKMP_FLAG_E
;
1209 iph1
->status
= PHASE1ST_ESTABLISHED
;