1 /* $KAME: isakmp_quick.c,v 1.93 2002/05/07 17:47:55 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 #include <sys/types.h>
33 #include <sys/param.h>
34 #include <sys/socket.h>
36 #include <netkey/key_var.h>
37 #include <netinet/in.h>
43 #if TIME_WITH_SYS_TIME
44 # include <sys/time.h>
48 # include <sys/time.h>
54 #ifdef IPV6_INRIA_VERSION
55 #include <netinet/ipsec.h>
57 #include <netinet6/ipsec.h>
67 #include "localconf.h"
68 #include "remoteconf.h"
69 #include "isakmp_var.h"
71 #include "isakmp_inf.h"
72 #include "isakmp_quick.h"
73 #include "isakmp_natd.h"
76 #include "ipsec_doi.h"
77 #include "crypto_openssl.h"
80 #include "algorithm.h"
89 static vchar_t
*quick_ir1mx
__P((struct ph2handle
*, vchar_t
*, vchar_t
*));
90 static int get_sainfo_r
__P((struct ph2handle
*));
91 static int get_proposal_r
__P((struct ph2handle
*));
92 static u_int32_t setscopeid
__P((struct sockaddr
*, struct sockaddr
*));
93 static int create_natoa_payloads(struct ph2handle
*iph2
, vchar_t
**, vchar_t
**);
99 * begin Quick Mode as initiator. send pfkey getspi message to kernel.
102 quick_i1prep(iph2
, msg
)
103 struct ph2handle
*iph2
;
104 vchar_t
*msg
; /* must be null pointer */
106 int error
= ISAKMP_INTERNAL_ERROR
;
109 if (iph2
->status
!= PHASE2ST_STATUS2
) {
110 plog(LLV_ERROR
, LOCATION
, NULL
,
111 "status mismatched %d.\n", iph2
->status
);
115 iph2
->msgid
= isakmp_newmsgid2(iph2
->ph1
);
116 iph2
->ivm
= oakley_newiv2(iph2
->ph1
, iph2
->msgid
);
117 if (iph2
->ivm
== NULL
)
120 iph2
->status
= PHASE2ST_GETSPISENT
;
122 /* don't anything if local test mode. */
128 /* send getspi message */
129 if (pk_sendgetspi(iph2
) < 0)
132 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey getspi sent.\n");
134 iph2
->sce
= sched_new(lcconf
->wait_ph2complete
,
135 pfkey_timeover_stub
, iph2
);
145 * HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ]
148 quick_i1send(iph2
, msg
)
149 struct ph2handle
*iph2
;
150 vchar_t
*msg
; /* must be null pointer */
152 vchar_t
*body
= NULL
;
153 vchar_t
*hash
= NULL
;
154 vchar_t
*natoa_i
= NULL
;
155 vchar_t
*natoa_r
= NULL
;
157 struct isakmp_gen
*gen
;
160 int error
= ISAKMP_INTERNAL_ERROR
;
161 int pfsgroup
, idci
, idcr
;
163 struct ipsecdoi_id_b
*id
, *id_p
;
167 plog(LLV_ERROR
, LOCATION
, NULL
,
168 "msg has to be NULL in this function.\n");
171 if (iph2
->status
!= PHASE2ST_GETSPIDONE
) {
172 plog(LLV_ERROR
, LOCATION
, NULL
,
173 "status mismatched %d.\n", iph2
->status
);
177 /* create SA payload for my proposal */
178 if (ipsecdoi_setph2proposal(iph2
) < 0)
181 /* generate NONCE value */
182 iph2
->nonce
= eay_set_random(iph2
->ph1
->rmconf
->nonce_size
);
183 if (iph2
->nonce
== NULL
)
187 * DH value calculation is kicked out into cfparse.y.
188 * because pfs group can not be negotiated, it's only to be checked
191 /* generate KE value if need */
192 pfsgroup
= iph2
->proposal
->pfs_group
;
194 /* DH group settting if PFS is required. */
195 if (oakley_setdhgroup(pfsgroup
, &iph2
->pfsgrp
) < 0) {
196 plog(LLV_ERROR
, LOCATION
, NULL
,
197 "failed to set DH value.\n");
200 if (oakley_dh_generate(iph2
->pfsgrp
,
201 &iph2
->dhpub
, &iph2
->dhpriv
) < 0) {
206 /* generate ID value */
207 if (ipsecdoi_setid2(iph2
) < 0) {
208 plog(LLV_ERROR
, LOCATION
, NULL
,
209 "failed to get ID.\n");
212 plog(LLV_DEBUG
, LOCATION
, NULL
, "IDci:");
213 plogdump(LLV_DEBUG
, iph2
->id
->v
, iph2
->id
->l
);
214 plog(LLV_DEBUG
, LOCATION
, NULL
, "IDcr:");
215 plogdump(LLV_DEBUG
, iph2
->id_p
->v
, iph2
->id_p
->l
);
218 * we do not attach IDci nor IDcr, under the following condition:
219 * - all proposals are transport mode
221 * - id payload suggests to encrypt all the traffic (no specific
224 id
= (struct ipsecdoi_id_b
*)iph2
->id
->v
;
225 id_p
= (struct ipsecdoi_id_b
*)iph2
->id_p
->v
;
226 if (id
->proto_id
== 0
227 && id_p
->proto_id
== 0
228 && iph2
->ph1
->rmconf
->support_mip6
== 0
229 && ipsecdoi_transportmode(iph2
)) {
234 /* create SA;NONCE payload, and KE if need, and IDii, IDir. */
235 tlen
= + sizeof(*gen
) + iph2
->sa
->l
236 + sizeof(*gen
) + iph2
->nonce
->l
;
238 tlen
+= (sizeof(*gen
) + iph2
->dhpub
->l
);
240 tlen
+= sizeof(*gen
) + iph2
->id
->l
;
242 tlen
+= sizeof(*gen
) + iph2
->id_p
->l
;
245 * create natoa payloads if needed but only
246 * if transport mode proposals are present
248 if (ipsecdoi_tunnelmode(iph2
) != 1) {
249 natoa_type
= create_natoa_payloads(iph2
, &natoa_i
, &natoa_r
);
250 if (natoa_type
== -1)
252 else if (natoa_type
!= 0) {
253 tlen
+= sizeof(*gen
) + natoa_i
->l
;
254 tlen
+= sizeof(*gen
) + natoa_r
->l
;
258 body
= vmalloc(tlen
);
260 plog(LLV_ERROR
, LOCATION
, NULL
,
261 "failed to get buffer to send.\n");
268 p
= set_isakmp_payload(p
, iph2
->sa
, ISAKMP_NPTYPE_NONCE
);
270 /* add NONCE payload */
272 np
= ISAKMP_NPTYPE_KE
;
273 else if (idci
|| idcr
)
274 np
= ISAKMP_NPTYPE_ID
;
276 np
= (natoa_type
? natoa_type
: ISAKMP_NPTYPE_NONE
);
277 p
= set_isakmp_payload(p
, iph2
->nonce
, np
);
279 /* add KE payload if need. */
280 np
= (idci
|| idcr
) ? ISAKMP_NPTYPE_ID
: (natoa_type
? natoa_type
: ISAKMP_NPTYPE_NONE
);
282 p
= set_isakmp_payload(p
, iph2
->dhpub
, np
);
285 np
= (idcr
) ? ISAKMP_NPTYPE_ID
: (natoa_type
? natoa_type
: ISAKMP_NPTYPE_NONE
);
287 p
= set_isakmp_payload(p
, iph2
->id
, np
);
291 p
= set_isakmp_payload(p
, iph2
->id_p
, natoa_type
? natoa_type
: ISAKMP_NPTYPE_NONE
);
295 p
= set_isakmp_payload(p
, natoa_i
, natoa_type
);
296 p
= set_isakmp_payload(p
, natoa_r
, ISAKMP_NPTYPE_NONE
);
299 /* generate HASH(1) */
300 hash
= oakley_compute_hash1(iph2
->ph1
, iph2
->msgid
, body
);
304 /* send isakmp payload */
305 iph2
->sendbuf
= quick_ir1mx(iph2
, body
, hash
);
306 if (iph2
->sendbuf
== NULL
)
309 /* send the packet, add to the schedule to resend */
310 iph2
->retry_counter
= iph2
->ph1
->rmconf
->retry_counter
;
311 if (isakmp_ph2resend(iph2
) == -1)
314 /* change status of isakmp status entry */
315 iph2
->status
= PHASE2ST_MSG1SENT
;
333 * receive from responder
334 * HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ]
337 quick_i2recv(iph2
, msg0
)
338 struct ph2handle
*iph2
;
342 vchar_t
*hbuf
= NULL
; /* for hash computing. */
343 vchar_t
*pbuf
= NULL
; /* for payload parsing */
344 struct isakmp_parse_t
*pa
;
345 struct isakmp
*isakmp
= (struct isakmp
*)msg0
->v
;
346 struct isakmp_pl_hash
*hash
= NULL
;
350 int error
= ISAKMP_INTERNAL_ERROR
;
353 if (iph2
->status
!= PHASE2ST_MSG1SENT
) {
354 plog(LLV_ERROR
, LOCATION
, NULL
,
355 "status mismatched %d.\n", iph2
->status
);
360 if (!ISSET(((struct isakmp
*)msg0
->v
)->flags
, ISAKMP_FLAG_E
)) {
361 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
362 "Packet wasn't encrypted.\n");
365 msg
= oakley_do_decrypt(iph2
->ph1
, msg0
, iph2
->ivm
->iv
, iph2
->ivm
->ive
);
369 /* create buffer for validating HASH(2) */
372 * 1. the first one must be HASH
373 * 2. the second one must be SA (added in isakmp-oakley-05!)
374 * 3. two IDs must be considered as IDci, then IDcr
376 pbuf
= isakmp_parse(msg
);
379 pa
= (struct isakmp_parse_t
*)pbuf
->v
;
381 /* HASH payload is fixed postion */
382 if (pa
->type
!= ISAKMP_NPTYPE_HASH
) {
383 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
384 "received invalid next payload type %d, "
386 pa
->type
, ISAKMP_NPTYPE_HASH
);
389 hash
= (struct isakmp_pl_hash
*)pa
->ptr
;
393 * this restriction was introduced in isakmp-oakley-05.
394 * we do not check this for backward compatibility.
395 * TODO: command line/config file option to enable/disable this code
397 /* HASH payload is fixed postion */
398 if (pa
->type
!= ISAKMP_NPTYPE_SA
) {
399 plog(LLV_WARNING
, LOCATION
, iph2
->ph1
->remote
,
400 "received invalid next payload type %d, "
402 pa
->type
, ISAKMP_NPTYPE_HASH
);
405 /* allocate buffer for computing HASH(2) */
406 tlen
= iph2
->nonce
->l
407 + ntohl(isakmp
->len
) - sizeof(*isakmp
);
408 hbuf
= vmalloc(tlen
);
410 plog(LLV_ERROR
, LOCATION
, NULL
,
411 "failed to get hash buffer.\n");
414 p
= hbuf
->v
+ iph2
->nonce
->l
; /* retain the space for Ni_b */
417 * parse the payloads.
418 * copy non-HASH payloads into hbuf, so that we can validate HASH.
421 f_id
= 0; /* flag to use checking ID */
422 tlen
= 0; /* count payload length except of HASH payload. */
423 for (; pa
->type
; pa
++) {
425 /* copy to buffer for HASH */
426 /* Don't modify the payload */
427 memcpy(p
, pa
->ptr
, pa
->len
);
430 case ISAKMP_NPTYPE_SA
:
431 if (iph2
->sa_ret
!= NULL
) {
432 plog(LLV_ERROR
, LOCATION
, NULL
,
433 "Ignored, multiple SA "
434 "isn't supported.\n");
437 if (isakmp_p2ph(&iph2
->sa_ret
, pa
->ptr
) < 0)
441 case ISAKMP_NPTYPE_NONCE
:
442 if (isakmp_p2ph(&iph2
->nonce_p
, pa
->ptr
) < 0)
446 case ISAKMP_NPTYPE_KE
:
447 if (isakmp_p2ph(&iph2
->dhpub_p
, pa
->ptr
) < 0)
451 case ISAKMP_NPTYPE_ID
:
464 if (!natd_hasnat(iph2
->ph1
)) {
465 /* RFC 2407 says that the protocol and port fields should be ignored
466 * if they are zero, therefore they need to be checked individually.
468 struct ipsecdoi_id_b
*id_ptr
= (struct ipsecdoi_id_b
*)vp
->v
;
469 struct ipsecdoi_pl_id
*idp_ptr
= (struct ipsecdoi_pl_id
*)pa
->ptr
;
471 if (id_ptr
->type
!= idp_ptr
->b
.type
472 || (idp_ptr
->b
.proto_id
!= 0 && idp_ptr
->b
.proto_id
!= id_ptr
->proto_id
)
473 || (idp_ptr
->b
.port
!= 0 && idp_ptr
->b
.port
!= id_ptr
->port
)
474 || memcmp(vp
->v
+ sizeof(struct ipsecdoi_id_b
), (caddr_t
)pa
->ptr
+ sizeof(struct ipsecdoi_pl_id
),
475 vp
->l
- sizeof(struct ipsecdoi_id_b
))) {
476 plog(LLV_ERROR
, LOCATION
, NULL
,
477 "mismatched ID was returned.\n");
478 error
= ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED
;
486 case ISAKMP_NPTYPE_NATOA_RFC
:
487 case ISAKMP_NPTYPE_NATOA_DRAFT
:
488 case ISAKMP_NPTYPE_NATOA_BADDRAFT
:
489 /* Ignore original source/destination messages */
493 case ISAKMP_NPTYPE_N
:
494 isakmp_check_notify(pa
->ptr
, iph2
->ph1
);
498 /* don't send information, see ident_r1recv() */
499 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
500 "ignore the packet, "
501 "received unexpecting payload type %d.\n",
508 /* compute true length of payload. */
512 /* payload existency check */
513 if (hash
== NULL
|| iph2
->sa_ret
== NULL
|| iph2
->nonce_p
== NULL
) {
514 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
515 "few isakmp message received.\n");
519 /* Fixed buffer for calculating HASH */
520 memcpy(hbuf
->v
, iph2
->nonce
->v
, iph2
->nonce
->l
);
521 plog(LLV_DEBUG
, LOCATION
, NULL
,
522 "HASH allocated:hbuf->l=%d actual:tlen=%d\n",
523 hbuf
->l
, tlen
+ iph2
->nonce
->l
);
524 /* adjust buffer length for HASH */
525 hbuf
->l
= iph2
->nonce
->l
+ tlen
;
527 /* validate HASH(2) */
530 vchar_t
*my_hash
= NULL
;
533 r_hash
= (char *)hash
+ sizeof(*hash
);
535 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH(2) received:");
536 plogdump(LLV_DEBUG
, r_hash
, ntohs(hash
->h
.len
) - sizeof(*hash
));
538 my_hash
= oakley_compute_hash1(iph2
->ph1
, iph2
->msgid
, hbuf
);
542 result
= memcmp(my_hash
->v
, r_hash
, my_hash
->l
);
546 plog(LLV_DEBUG
, LOCATION
, iph2
->ph1
->remote
,
547 "HASH(2) mismatch.\n");
548 error
= ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
553 /* validity check SA payload sent from responder */
554 if (ipsecdoi_checkph2proposal(iph2
) < 0) {
555 error
= ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN
;
559 /* change status of isakmp status entry */
560 iph2
->status
= PHASE2ST_STATUS6
;
573 VPTRINIT(iph2
->sa_ret
);
574 VPTRINIT(iph2
->nonce_p
);
575 VPTRINIT(iph2
->dhpub_p
);
577 VPTRINIT(iph2
->id_p
);
588 quick_i2send(iph2
, msg0
)
589 struct ph2handle
*iph2
;
594 vchar_t
*hash
= NULL
;
597 int error
= ISAKMP_INTERNAL_ERROR
;
600 if (iph2
->status
!= PHASE2ST_STATUS6
) {
601 plog(LLV_ERROR
, LOCATION
, NULL
,
602 "status mismatched %d.\n", iph2
->status
);
606 /* generate HASH(3) */
610 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH(3) generate\n");
612 tmp
= vmalloc(iph2
->nonce
->l
+ iph2
->nonce_p
->l
);
614 plog(LLV_ERROR
, LOCATION
, NULL
,
615 "failed to get hash buffer.\n");
618 memcpy(tmp
->v
, iph2
->nonce
->v
, iph2
->nonce
->l
);
619 memcpy(tmp
->v
+ iph2
->nonce
->l
, iph2
->nonce_p
->v
, iph2
->nonce_p
->l
);
621 hash
= oakley_compute_hash3(iph2
->ph1
, iph2
->msgid
, tmp
);
628 /* create buffer for isakmp payload */
629 tlen
= sizeof(struct isakmp
)
630 + sizeof(struct isakmp_gen
) + hash
->l
;
633 plog(LLV_ERROR
, LOCATION
, NULL
,
634 "failed to get buffer to send.\n");
638 /* create isakmp header */
639 p
= set_isakmp_header2(buf
, iph2
, ISAKMP_NPTYPE_HASH
);
643 /* add HASH(3) payload */
644 p
= set_isakmp_payload(p
, hash
, ISAKMP_NPTYPE_NONE
);
646 #ifdef HAVE_PRINT_ISAKMP_C
647 isakmp_printpacket(buf
, iph2
->ph1
->local
, iph2
->ph1
->remote
, 1);
651 iph2
->sendbuf
= oakley_do_encrypt(iph2
->ph1
, buf
, iph2
->ivm
->ive
, iph2
->ivm
->iv
);
652 if (iph2
->sendbuf
== NULL
)
655 /* if there is commit bit, need resending */
656 if (ISSET(iph2
->flags
, ISAKMP_FLAG_C
)) {
657 /* send the packet, add to the schedule to resend */
658 iph2
->retry_counter
= iph2
->ph1
->rmconf
->retry_counter
;
659 if (isakmp_ph2resend(iph2
) == -1)
662 /* send the packet */
663 if (isakmp_send(iph2
->ph1
, iph2
->sendbuf
) < 0)
667 /* the sending message is added to the received-list. */
668 if (add_recvdpkt(iph2
->ph1
->remote
, iph2
->ph1
->local
,
669 iph2
->sendbuf
, msg0
) == -1) {
670 plog(LLV_ERROR
, LOCATION
, NULL
,
671 "failed to add a response packet to the tree.\n");
675 /* compute both of KEYMATs */
676 if (oakley_compute_keymat(iph2
, INITIATOR
) < 0)
679 iph2
->status
= PHASE2ST_ADDSA
;
681 /* don't anything if local test mode. */
687 /* if there is commit bit don't set up SA now. */
688 if (ISSET(iph2
->flags
, ISAKMP_FLAG_C
)) {
689 iph2
->status
= PHASE2ST_COMMIT
;
694 /* Do UPDATE for initiator */
695 plog(LLV_DEBUG
, LOCATION
, NULL
, "call pk_sendupdate\n");
696 if (pk_sendupdate(iph2
) < 0) {
697 plog(LLV_ERROR
, LOCATION
, NULL
, "pfkey update failed.\n");
700 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey update sent.\n");
702 /* Do ADD for responder */
703 if (pk_sendadd(iph2
) < 0) {
704 plog(LLV_ERROR
, LOCATION
, NULL
, "pfkey add failed.\n");
707 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey add sent.\n");
723 * receive from responder
724 * HDR#*, HASH(4), notify
727 quick_i3recv(iph2
, msg0
)
728 struct ph2handle
*iph2
;
732 vchar_t
*pbuf
= NULL
; /* for payload parsing */
733 struct isakmp_parse_t
*pa
;
734 struct isakmp_pl_hash
*hash
= NULL
;
735 vchar_t
*notify
= NULL
;
736 int error
= ISAKMP_INTERNAL_ERROR
;
739 if (iph2
->status
!= PHASE2ST_COMMIT
) {
740 plog(LLV_ERROR
, LOCATION
, NULL
,
741 "status mismatched %d.\n", iph2
->status
);
746 if (!ISSET(((struct isakmp
*)msg0
->v
)->flags
, ISAKMP_FLAG_E
)) {
747 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
748 "Packet wasn't encrypted.\n");
751 msg
= oakley_do_decrypt(iph2
->ph1
, msg0
, iph2
->ivm
->iv
, iph2
->ivm
->ive
);
755 /* validate the type of next payload */
756 pbuf
= isakmp_parse(msg
);
760 for (pa
= (struct isakmp_parse_t
*)pbuf
->v
;
761 pa
->type
!= ISAKMP_NPTYPE_NONE
;
765 case ISAKMP_NPTYPE_HASH
:
766 hash
= (struct isakmp_pl_hash
*)pa
->ptr
;
768 case ISAKMP_NPTYPE_N
:
769 isakmp_check_notify(pa
->ptr
, iph2
->ph1
);
770 notify
= vmalloc(pa
->len
);
771 if (notify
== NULL
) {
772 plog(LLV_ERROR
, LOCATION
, NULL
,
773 "failed to get notify buffer.\n");
776 memcpy(notify
->v
, pa
->ptr
, notify
->l
);
779 /* don't send information, see ident_r1recv() */
780 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
781 "ignore the packet, "
782 "received unexpecting payload type %d.\n",
788 /* payload existency check */
790 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
791 "few isakmp message received.\n");
795 /* validate HASH(4) */
798 vchar_t
*my_hash
= NULL
;
802 r_hash
= (char *)hash
+ sizeof(*hash
);
804 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH(4) validate:");
805 plogdump(LLV_DEBUG
, r_hash
, ntohs(hash
->h
.len
) - sizeof(*hash
));
807 my_hash
= oakley_compute_hash1(iph2
->ph1
, iph2
->msgid
, notify
);
812 result
= memcmp(my_hash
->v
, r_hash
, my_hash
->l
);
816 plog(LLV_DEBUG
, LOCATION
, iph2
->ph1
->remote
,
817 "HASH(4) mismatch.\n");
818 error
= ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
823 iph2
->status
= PHASE2ST_ADDSA
;
824 iph2
->flags
^= ISAKMP_FLAG_C
; /* reset bit */
826 /* don't anything if local test mode. */
832 /* Do UPDATE for initiator */
833 plog(LLV_DEBUG
, LOCATION
, NULL
, "call pk_sendupdate\n");
834 if (pk_sendupdate(iph2
) < 0) {
835 plog(LLV_ERROR
, LOCATION
, NULL
, "pfkey update failed.\n");
838 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey update sent.\n");
840 /* Do ADD for responder */
841 if (pk_sendadd(iph2
) < 0) {
842 plog(LLV_ERROR
, LOCATION
, NULL
, "pfkey add failed.\n");
845 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey add sent.\n");
861 * receive from initiator
862 * HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ]
865 quick_r1recv(iph2
, msg0
)
866 struct ph2handle
*iph2
;
870 vchar_t
*hbuf
= NULL
; /* for hash computing. */
871 vchar_t
*pbuf
= NULL
; /* for payload parsing */
872 struct isakmp_parse_t
*pa
;
873 struct isakmp
*isakmp
= (struct isakmp
*)msg0
->v
;
874 struct isakmp_pl_hash
*hash
= NULL
;
877 int f_id_order
; /* for ID payload detection */
878 int error
= ISAKMP_INTERNAL_ERROR
;
881 if (iph2
->status
!= PHASE2ST_START
) {
882 plog(LLV_ERROR
, LOCATION
, NULL
,
883 "status mismatched %d.\n", iph2
->status
);
888 if (!ISSET(((struct isakmp
*)msg0
->v
)->flags
, ISAKMP_FLAG_E
)) {
889 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
890 "Packet wasn't encrypted.\n");
891 error
= ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
895 msg
= oakley_do_decrypt(iph2
->ph1
, msg0
, iph2
->ivm
->iv
, iph2
->ivm
->ive
);
899 /* create buffer for using to validate HASH(1) */
902 * 1. the first one must be HASH
903 * 2. the second one must be SA (added in isakmp-oakley-05!)
904 * 3. two IDs must be considered as IDci, then IDcr
906 pbuf
= isakmp_parse(msg
);
909 pa
= (struct isakmp_parse_t
*)pbuf
->v
;
911 /* HASH payload is fixed postion */
912 if (pa
->type
!= ISAKMP_NPTYPE_HASH
) {
913 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
914 "received invalid next payload type %d, "
916 pa
->type
, ISAKMP_NPTYPE_HASH
);
917 error
= ISAKMP_NTYPE_BAD_PROPOSAL_SYNTAX
;
920 hash
= (struct isakmp_pl_hash
*)pa
->ptr
;
924 * this restriction was introduced in isakmp-oakley-05.
925 * we do not check this for backward compatibility.
926 * TODO: command line/config file option to enable/disable this code
928 /* HASH payload is fixed postion */
929 if (pa
->type
!= ISAKMP_NPTYPE_SA
) {
930 plog(LLV_WARNING
, LOCATION
, iph2
->ph1
->remote
,
931 "received invalid next payload type %d, "
933 pa
->type
, ISAKMP_NPTYPE_HASH
);
934 error
= ISAKMP_NTYPE_BAD_PROPOSAL_SYNTAX
;
937 /* allocate buffer for computing HASH(1) */
938 tlen
= ntohl(isakmp
->len
) - sizeof(*isakmp
);
939 hbuf
= vmalloc(tlen
);
941 plog(LLV_ERROR
, LOCATION
, NULL
,
942 "failed to get hash buffer.\n");
948 * parse the payloads.
949 * copy non-HASH payloads into hbuf, so that we can validate HASH.
951 iph2
->sa
= NULL
; /* we don't support multi SAs. */
952 iph2
->nonce_p
= NULL
;
953 iph2
->dhpub_p
= NULL
;
956 tlen
= 0; /* count payload length except of HASH payload. */
959 * IDi2 MUST be immediatelly followed by IDr2. We allowed the
960 * illegal case, but logged. First ID payload is to be IDi2.
961 * And next ID payload is to be IDr2.
965 for (; pa
->type
; pa
++) {
967 /* copy to buffer for HASH */
968 /* Don't modify the payload */
969 memcpy(p
, pa
->ptr
, pa
->len
);
971 if (pa
->type
!= ISAKMP_NPTYPE_ID
)
975 case ISAKMP_NPTYPE_SA
:
976 if (iph2
->sa
!= NULL
) {
977 plog(LLV_ERROR
, LOCATION
, NULL
,
978 "Multi SAs isn't supported.\n");
981 if (isakmp_p2ph(&iph2
->sa
, pa
->ptr
) < 0)
985 case ISAKMP_NPTYPE_NONCE
:
986 if (isakmp_p2ph(&iph2
->nonce_p
, pa
->ptr
) < 0)
990 case ISAKMP_NPTYPE_KE
:
991 if (isakmp_p2ph(&iph2
->dhpub_p
, pa
->ptr
) < 0)
995 case ISAKMP_NPTYPE_ID
:
996 if (iph2
->id_p
== NULL
) {
1000 if (isakmp_p2ph(&iph2
->id_p
, pa
->ptr
) < 0)
1003 } else if (iph2
->id
== NULL
) {
1005 if (f_id_order
== 0) {
1006 plog(LLV_ERROR
, LOCATION
, NULL
,
1007 "IDr2 payload is not "
1008 "immediatelly followed "
1009 "by IDi2. We allowed.\n");
1010 /* XXX we allowed in this case. */
1013 if (isakmp_p2ph(&iph2
->id
, pa
->ptr
) < 0)
1016 plog(LLV_ERROR
, LOCATION
, NULL
,
1017 "received too many ID payloads.\n");
1018 plogdump(LLV_ERROR
, iph2
->id
->v
, iph2
->id
->l
);
1019 error
= ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
1024 case ISAKMP_NPTYPE_N
:
1025 isakmp_check_notify(pa
->ptr
, iph2
->ph1
);
1029 case ISAKMP_NPTYPE_NATOA_RFC
:
1030 case ISAKMP_NPTYPE_NATOA_DRAFT
:
1031 case ISAKMP_NPTYPE_NATOA_BADDRAFT
:
1032 /* Ignore original source/destination messages */
1037 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1038 "ignore the packet, "
1039 "received unexpecting payload type %d.\n",
1041 error
= ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
1047 /* compute true length of payload. */
1051 /* payload existency check */
1052 if (hash
== NULL
|| iph2
->sa
== NULL
|| iph2
->nonce_p
== NULL
) {
1053 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1054 "few isakmp message received.\n");
1055 error
= ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
1060 plog(LLV_DEBUG
, LOCATION
, NULL
, "received IDci2:");
1061 plogdump(LLV_DEBUG
, iph2
->id_p
->v
, iph2
->id_p
->l
);
1064 plog(LLV_DEBUG
, LOCATION
, NULL
, "received IDcr2:");
1065 plogdump(LLV_DEBUG
, iph2
->id
->v
, iph2
->id
->l
);
1068 /* adjust buffer length for HASH */
1071 /* validate HASH(1) */
1074 vchar_t
*my_hash
= NULL
;
1077 r_hash
= (caddr_t
)hash
+ sizeof(*hash
);
1079 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH(1) validate:");
1080 plogdump(LLV_DEBUG
, r_hash
, ntohs(hash
->h
.len
) - sizeof(*hash
));
1082 my_hash
= oakley_compute_hash1(iph2
->ph1
, iph2
->msgid
, hbuf
);
1083 if (my_hash
== NULL
)
1086 result
= memcmp(my_hash
->v
, r_hash
, my_hash
->l
);
1090 plog(LLV_DEBUG
, LOCATION
, iph2
->ph1
->remote
,
1091 "HASH(1) mismatch.\n");
1092 error
= ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
1098 error
= get_sainfo_r(iph2
);
1100 plog(LLV_ERROR
, LOCATION
, NULL
,
1101 "failed to get sainfo.\n");
1105 /* check the existence of ID payload and create responder's proposal */
1106 error
= get_proposal_r(iph2
);
1109 /* generate a policy template from peer's proposal */
1110 if (set_proposal_from_proposal(iph2
)) {
1111 plog(LLV_ERROR
, LOCATION
, NULL
,
1112 "failed to generate a proposal template "
1113 "from client's proposal.\n");
1114 return ISAKMP_INTERNAL_ERROR
;
1118 /* select single proposal or reject it. */
1119 if (ipsecdoi_selectph2proposal(iph2
) < 0) {
1120 error
= ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN
;
1125 plog(LLV_ERROR
, LOCATION
, NULL
,
1126 "failed to get proposal for responder.\n");
1130 /* check KE and attribute of PFS */
1131 if (iph2
->dhpub_p
!= NULL
&& iph2
->approval
->pfs_group
== 0) {
1132 plog(LLV_ERROR
, LOCATION
, NULL
,
1133 "no PFS is specified, but peer sends KE.\n");
1134 error
= ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN
;
1137 if (iph2
->dhpub_p
== NULL
&& iph2
->approval
->pfs_group
!= 0) {
1138 plog(LLV_ERROR
, LOCATION
, NULL
,
1139 "PFS is specified, but peer doesn't sends KE.\n");
1140 error
= ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN
;
1145 * save the packet from the initiator in order to resend the
1146 * responder's first packet against this packet.
1148 iph2
->msg1
= vdup(msg0
);
1150 /* change status of isakmp status entry */
1151 iph2
->status
= PHASE2ST_STATUS2
;
1165 VPTRINIT(iph2
->nonce_p
);
1166 VPTRINIT(iph2
->dhpub_p
);
1168 VPTRINIT(iph2
->id_p
);
1175 * call pfkey_getspi.
1178 quick_r1prep(iph2
, msg
)
1179 struct ph2handle
*iph2
;
1182 int error
= ISAKMP_INTERNAL_ERROR
;
1184 /* validity check */
1185 if (iph2
->status
!= PHASE2ST_STATUS2
) {
1186 plog(LLV_ERROR
, LOCATION
, NULL
,
1187 "status mismatched %d.\n", iph2
->status
);
1191 iph2
->status
= PHASE2ST_GETSPISENT
;
1193 /* send getspi message */
1194 if (pk_sendgetspi(iph2
) < 0)
1197 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey getspi sent.\n");
1199 iph2
->sce
= sched_new(lcconf
->wait_ph2complete
,
1200 pfkey_timeover_stub
, iph2
);
1210 * HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ]
1213 quick_r2send(iph2
, msg
)
1214 struct ph2handle
*iph2
;
1217 vchar_t
*body
= NULL
;
1218 vchar_t
*hash
= NULL
;
1219 vchar_t
*natoa_i
= NULL
;
1220 vchar_t
*natoa_r
= NULL
;
1223 struct isakmp_gen
*gen
;
1226 int error
= ISAKMP_INTERNAL_ERROR
;
1228 u_int8_t
*np_p
= NULL
;
1230 /* validity check */
1232 plog(LLV_ERROR
, LOCATION
, NULL
,
1233 "msg has to be NULL in this function.\n");
1236 if (iph2
->status
!= PHASE2ST_GETSPIDONE
) {
1237 plog(LLV_ERROR
, LOCATION
, NULL
,
1238 "status mismatched %d.\n", iph2
->status
);
1242 /* update responders SPI */
1243 if (ipsecdoi_updatespi(iph2
) < 0) {
1244 plog(LLV_ERROR
, LOCATION
, NULL
, "failed to update spi.\n");
1248 /* generate NONCE value */
1249 iph2
->nonce
= eay_set_random(iph2
->ph1
->rmconf
->nonce_size
);
1250 if (iph2
->nonce
== NULL
)
1253 /* generate KE value if need */
1254 pfsgroup
= iph2
->approval
->pfs_group
;
1255 if (iph2
->dhpub_p
!= NULL
&& pfsgroup
!= 0) {
1256 /* DH group settting if PFS is required. */
1257 if (oakley_setdhgroup(pfsgroup
, &iph2
->pfsgrp
) < 0) {
1258 plog(LLV_ERROR
, LOCATION
, NULL
,
1259 "failed to set DH value.\n");
1262 /* generate DH public value */
1263 if (oakley_dh_generate(iph2
->pfsgrp
,
1264 &iph2
->dhpub
, &iph2
->dhpriv
) < 0) {
1269 /* create SA;NONCE payload, and KE and ID if need */
1270 tlen
= sizeof(*gen
) + iph2
->sa_ret
->l
1271 + sizeof(*gen
) + iph2
->nonce
->l
;
1272 if (iph2
->dhpub_p
!= NULL
&& pfsgroup
!= 0)
1273 tlen
+= (sizeof(*gen
) + iph2
->dhpub
->l
);
1274 if (iph2
->id_p
!= NULL
)
1275 tlen
+= (sizeof(*gen
) + iph2
->id_p
->l
1276 + sizeof(*gen
) + iph2
->id
->l
);
1278 /* create natoa payloads if needed */
1279 encmode
= iph2
->approval
->head
->encmode
;
1280 if (encmode
== IPSECDOI_ATTR_ENC_MODE_TRNS
||
1281 encmode
== IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC
||
1282 encmode
== IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT
) {
1284 natoa_type
= create_natoa_payloads(iph2
, &natoa_i
, &natoa_r
);
1285 if (natoa_type
== -1)
1287 else if (natoa_type
!= 0) {
1288 tlen
+= sizeof(*gen
) + natoa_i
->l
;
1289 tlen
+= sizeof(*gen
) + natoa_r
->l
;
1293 body
= vmalloc(tlen
);
1295 plog(LLV_ERROR
, LOCATION
, NULL
,
1296 "failed to get buffer to send.\n");
1301 /* make SA payload */
1302 p
= set_isakmp_payload(body
->v
, iph2
->sa_ret
, ISAKMP_NPTYPE_NONCE
);
1304 /* add NONCE payload */
1305 np_p
= &((struct isakmp_gen
*)p
)->np
; /* XXX */
1306 p
= set_isakmp_payload(p
, iph2
->nonce
,
1307 (iph2
->dhpub_p
!= NULL
&& pfsgroup
!= 0)
1309 : (iph2
->id_p
!= NULL
1311 : (natoa_type
? natoa_type
: ISAKMP_NPTYPE_NONE
)));
1313 /* add KE payload if need. */
1314 if (iph2
->dhpub_p
!= NULL
&& pfsgroup
!= 0) {
1315 np_p
= &((struct isakmp_gen
*)p
)->np
; /* XXX */
1316 p
= set_isakmp_payload(p
, iph2
->dhpub
,
1317 (iph2
->id_p
== NULL
)
1318 ? (natoa_type
? natoa_type
: ISAKMP_NPTYPE_NONE
)
1319 : ISAKMP_NPTYPE_ID
);
1322 /* add ID payloads received. */
1323 if (iph2
->id_p
!= NULL
) {
1325 p
= set_isakmp_payload(p
, iph2
->id_p
, ISAKMP_NPTYPE_ID
);
1327 np_p
= &((struct isakmp_gen
*)p
)->np
; /* XXX */
1328 p
= set_isakmp_payload(p
, iph2
->id
, (natoa_type
? natoa_type
: ISAKMP_NPTYPE_NONE
));
1331 /* add a RESPONDER-LIFETIME notify payload if needed */
1333 vchar_t
*data
= NULL
;
1334 struct saprop
*pp
= iph2
->approval
;
1337 if (pp
->claim
& IPSECDOI_ATTR_SA_LD_TYPE_SEC
) {
1338 u_int32_t v
= htonl((u_int32_t
)pp
->lifetime
);
1339 data
= isakmp_add_attr_l(data
, IPSECDOI_ATTR_SA_LD_TYPE
,
1340 IPSECDOI_ATTR_SA_LD_TYPE_SEC
);
1343 data
= isakmp_add_attr_v(data
, IPSECDOI_ATTR_SA_LD
,
1344 (caddr_t
)&v
, sizeof(v
));
1348 if (pp
->claim
& IPSECDOI_ATTR_SA_LD_TYPE_KB
) {
1349 u_int32_t v
= htonl((u_int32_t
)pp
->lifebyte
);
1350 data
= isakmp_add_attr_l(data
, IPSECDOI_ATTR_SA_LD_TYPE
,
1351 IPSECDOI_ATTR_SA_LD_TYPE_KB
);
1354 data
= isakmp_add_attr_v(data
, IPSECDOI_ATTR_SA_LD
,
1355 (caddr_t
)&v
, sizeof(v
));
1361 * XXX Is there only single RESPONDER-LIFETIME payload in a IKE message
1362 * in the case of SA bundle ?
1365 for (pr
= pp
->head
; pr
; pr
= pr
->next
) {
1366 body
= isakmp_add_pl_n(body
, &np_p
,
1367 ISAKMP_NTYPE_RESPONDER_LIFETIME
, pr
, data
);
1370 return error
; /* XXX */
1379 p
= set_isakmp_payload(p
, natoa_i
, natoa_type
);
1380 p
= set_isakmp_payload(p
, natoa_r
, ISAKMP_NPTYPE_NONE
);
1383 /* generate HASH(2) */
1387 tmp
= vmalloc(iph2
->nonce_p
->l
+ body
->l
);
1389 plog(LLV_ERROR
, LOCATION
, NULL
,
1390 "failed to get hash buffer.\n");
1393 memcpy(tmp
->v
, iph2
->nonce_p
->v
, iph2
->nonce_p
->l
);
1394 memcpy(tmp
->v
+ iph2
->nonce_p
->l
, body
->v
, body
->l
);
1396 hash
= oakley_compute_hash1(iph2
->ph1
, iph2
->msgid
, tmp
);
1403 /* send isakmp payload */
1404 iph2
->sendbuf
= quick_ir1mx(iph2
, body
, hash
);
1405 if (iph2
->sendbuf
== NULL
)
1408 /* send the packet, add to the schedule to resend */
1409 iph2
->retry_counter
= iph2
->ph1
->rmconf
->retry_counter
;
1410 if (isakmp_ph2resend(iph2
) == -1)
1413 /* the sending message is added to the received-list. */
1414 if (add_recvdpkt(iph2
->ph1
->remote
, iph2
->ph1
->local
, iph2
->sendbuf
, iph2
->msg1
) == -1) {
1415 plog(LLV_ERROR
, LOCATION
, NULL
,
1416 "failed to add a response packet to the tree.\n");
1420 /* change status of isakmp status entry */
1421 iph2
->status
= PHASE2ST_MSG1SENT
;
1440 * receive from initiator
1444 quick_r3recv(iph2
, msg0
)
1445 struct ph2handle
*iph2
;
1448 vchar_t
*msg
= NULL
;
1449 vchar_t
*pbuf
= NULL
; /* for payload parsing */
1450 struct isakmp_parse_t
*pa
;
1451 struct isakmp_pl_hash
*hash
= NULL
;
1452 int error
= ISAKMP_INTERNAL_ERROR
;
1454 /* validity check */
1455 if (iph2
->status
!= PHASE2ST_MSG1SENT
) {
1456 plog(LLV_ERROR
, LOCATION
, NULL
,
1457 "status mismatched %d.\n", iph2
->status
);
1461 /* decrypt packet */
1462 if (!ISSET(((struct isakmp
*)msg0
->v
)->flags
, ISAKMP_FLAG_E
)) {
1463 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1464 "Packet wasn't encrypted.\n");
1467 msg
= oakley_do_decrypt(iph2
->ph1
, msg0
, iph2
->ivm
->iv
, iph2
->ivm
->ive
);
1471 /* validate the type of next payload */
1472 pbuf
= isakmp_parse(msg
);
1476 for (pa
= (struct isakmp_parse_t
*)pbuf
->v
;
1477 pa
->type
!= ISAKMP_NPTYPE_NONE
;
1481 case ISAKMP_NPTYPE_HASH
:
1482 hash
= (struct isakmp_pl_hash
*)pa
->ptr
;
1484 case ISAKMP_NPTYPE_N
:
1485 isakmp_check_notify(pa
->ptr
, iph2
->ph1
);
1488 /* don't send information, see ident_r1recv() */
1489 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1490 "ignore the packet, "
1491 "received unexpecting payload type %d.\n",
1497 /* payload existency check */
1499 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1500 "few isakmp message received.\n");
1504 /* validate HASH(3) */
1505 /* HASH(3) = prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b) */
1508 vchar_t
*my_hash
= NULL
;
1509 vchar_t
*tmp
= NULL
;
1512 r_hash
= (char *)hash
+ sizeof(*hash
);
1514 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH(3) validate:");
1515 plogdump(LLV_DEBUG
, r_hash
, ntohs(hash
->h
.len
) - sizeof(*hash
));
1517 tmp
= vmalloc(iph2
->nonce_p
->l
+ iph2
->nonce
->l
);
1519 plog(LLV_ERROR
, LOCATION
, NULL
,
1520 "failed to get hash buffer.\n");
1523 memcpy(tmp
->v
, iph2
->nonce_p
->v
, iph2
->nonce_p
->l
);
1524 memcpy(tmp
->v
+ iph2
->nonce_p
->l
, iph2
->nonce
->v
, iph2
->nonce
->l
);
1526 my_hash
= oakley_compute_hash3(iph2
->ph1
, iph2
->msgid
, tmp
);
1528 if (my_hash
== NULL
)
1531 result
= memcmp(my_hash
->v
, r_hash
, my_hash
->l
);
1535 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1536 "HASH(3) mismatch.\n");
1537 error
= ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
1542 /* if there is commit bit, don't set up SA now. */
1543 if (ISSET(iph2
->flags
, ISAKMP_FLAG_C
)) {
1544 iph2
->status
= PHASE2ST_COMMIT
;
1546 iph2
->status
= PHASE2ST_STATUS6
;
1561 * HDR#*, HASH(4), notify
1564 quick_r3send(iph2
, msg0
)
1565 struct ph2handle
*iph2
;
1568 vchar_t
*buf
= NULL
;
1569 vchar_t
*myhash
= NULL
;
1570 struct isakmp_pl_n
*n
;
1571 vchar_t
*notify
= NULL
;
1574 int error
= ISAKMP_INTERNAL_ERROR
;
1576 /* validity check */
1577 if (iph2
->status
!= PHASE2ST_COMMIT
) {
1578 plog(LLV_ERROR
, LOCATION
, NULL
,
1579 "status mismatched %d.\n", iph2
->status
);
1583 /* generate HASH(4) */
1584 /* XXX What can I do in the case of multiple different SA */
1585 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH(4) generate\n");
1587 /* XXX What should I do if there are multiple SAs ? */
1588 tlen
= sizeof(struct isakmp_pl_n
) + iph2
->approval
->head
->spisize
;
1589 notify
= vmalloc(tlen
);
1590 if (notify
== NULL
) {
1591 plog(LLV_ERROR
, LOCATION
, NULL
,
1592 "failed to get notify buffer.\n");
1595 n
= (struct isakmp_pl_n
*)notify
->v
;
1596 n
->h
.np
= ISAKMP_NPTYPE_NONE
;
1597 n
->h
.len
= htons(tlen
);
1599 n
->proto_id
= iph2
->approval
->head
->proto_id
;
1600 n
->spi_size
= sizeof(iph2
->approval
->head
->spisize
);
1601 n
->type
= htons(ISAKMP_NTYPE_CONNECTED
);
1602 memcpy(n
+ 1, &iph2
->approval
->head
->spi
, iph2
->approval
->head
->spisize
);
1604 myhash
= oakley_compute_hash1(iph2
->ph1
, iph2
->msgid
, notify
);
1608 /* create buffer for isakmp payload */
1609 tlen
= sizeof(struct isakmp
)
1610 + sizeof(struct isakmp_gen
) + myhash
->l
1612 buf
= vmalloc(tlen
);
1614 plog(LLV_ERROR
, LOCATION
, NULL
,
1615 "failed to get buffer to send.\n");
1619 /* create isakmp header */
1620 p
= set_isakmp_header2(buf
, iph2
, ISAKMP_NPTYPE_HASH
);
1624 /* add HASH(4) payload */
1625 p
= set_isakmp_payload(p
, myhash
, ISAKMP_NPTYPE_N
);
1627 /* add notify payload */
1628 memcpy(p
, notify
->v
, notify
->l
);
1630 #ifdef HAVE_PRINT_ISAKMP_C
1631 isakmp_printpacket(buf
, iph2
->ph1
->local
, iph2
->ph1
->remote
, 1);
1635 iph2
->sendbuf
= oakley_do_encrypt(iph2
->ph1
, buf
, iph2
->ivm
->ive
, iph2
->ivm
->iv
);
1636 if (iph2
->sendbuf
== NULL
)
1639 /* send the packet */
1640 if (isakmp_send(iph2
->ph1
, iph2
->sendbuf
) < 0)
1643 /* the sending message is added to the received-list. */
1644 if (add_recvdpkt(iph2
->ph1
->remote
, iph2
->ph1
->local
, iph2
->sendbuf
, msg0
) == -1) {
1645 plog(LLV_ERROR
, LOCATION
, NULL
,
1646 "failed to add a response packet to the tree.\n");
1650 iph2
->status
= PHASE2ST_COMMIT
;
1669 quick_r3prep(iph2
, msg0
)
1670 struct ph2handle
*iph2
;
1673 vchar_t
*msg
= NULL
;
1674 int error
= ISAKMP_INTERNAL_ERROR
;
1676 /* validity check */
1677 if (iph2
->status
!= PHASE2ST_STATUS6
) {
1678 plog(LLV_ERROR
, LOCATION
, NULL
,
1679 "status mismatched %d.\n", iph2
->status
);
1683 /* compute both of KEYMATs */
1684 if (oakley_compute_keymat(iph2
, RESPONDER
) < 0)
1687 iph2
->status
= PHASE2ST_ADDSA
;
1688 iph2
->flags
^= ISAKMP_FLAG_C
; /* reset bit */
1690 /* don't anything if local test mode. */
1696 /* Do UPDATE as responder */
1697 plog(LLV_DEBUG
, LOCATION
, NULL
, "call pk_sendupdate\n");
1698 if (pk_sendupdate(iph2
) < 0) {
1699 plog(LLV_ERROR
, LOCATION
, NULL
, "pfkey update failed.\n");
1702 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey update sent.\n");
1704 /* Do ADD for responder */
1705 if (pk_sendadd(iph2
) < 0) {
1706 plog(LLV_ERROR
, LOCATION
, NULL
, "pfkey add failed.\n");
1709 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey add sent.\n");
1712 * set policies into SPD if the policy is generated
1713 * from peer's policy.
1715 if (iph2
->spidx_gen
) {
1717 struct policyindex
*spidx
;
1718 struct sockaddr_storage addr
;
1720 struct sockaddr
*src
= iph2
->src
;
1721 struct sockaddr
*dst
= iph2
->dst
;
1723 /* make inbound policy */
1726 if (pk_sendspdupdate2(iph2
) < 0) {
1727 plog(LLV_ERROR
, LOCATION
, NULL
,
1728 "pfkey spdupdate2(inbound) failed.\n");
1731 plog(LLV_DEBUG
, LOCATION
, NULL
,
1732 "pfkey spdupdate2(inbound) sent.\n");
1734 /* make outbound policy */
1737 spidx
= (struct policyindex
*)iph2
->spidx_gen
;
1738 spidx
->dir
= IPSEC_DIR_OUTBOUND
;
1740 spidx
->src
= spidx
->dst
;
1742 pref
= spidx
->prefs
;
1743 spidx
->prefs
= spidx
->prefd
;
1744 spidx
->prefd
= pref
;
1746 if (pk_sendspdupdate2(iph2
) < 0) {
1747 plog(LLV_ERROR
, LOCATION
, NULL
,
1748 "pfkey spdupdate2(outbound) failed.\n");
1751 plog(LLV_DEBUG
, LOCATION
, NULL
,
1752 "pfkey spdupdate2(outbound) sent.\n");
1754 /* spidx_gen is unnecessary any more */
1755 delsp_bothdir((struct policyindex
*)iph2
->spidx_gen
);
1756 racoon_free(iph2
->spidx_gen
);
1757 iph2
->spidx_gen
= NULL
;
1770 * create HASH, body (SA, NONCE) payload with isakmp header.
1773 quick_ir1mx(iph2
, body
, hash
)
1774 struct ph2handle
*iph2
;
1775 vchar_t
*body
, *hash
;
1777 struct isakmp
*isakmp
;
1778 vchar_t
*buf
= NULL
, *new = NULL
;
1781 struct isakmp_gen
*gen
;
1782 int error
= ISAKMP_INTERNAL_ERROR
;
1784 /* create buffer for isakmp payload */
1785 tlen
= sizeof(*isakmp
)
1786 + sizeof(*gen
) + hash
->l
1788 buf
= vmalloc(tlen
);
1790 plog(LLV_ERROR
, LOCATION
, NULL
,
1791 "failed to get buffer to send.\n");
1795 /* re-set encryption flag, for serurity. */
1796 iph2
->flags
|= ISAKMP_FLAG_E
;
1798 /* set isakmp header */
1799 p
= set_isakmp_header2(buf
, iph2
, ISAKMP_NPTYPE_HASH
);
1803 /* add HASH payload */
1804 /* XXX is next type always SA ? */
1805 p
= set_isakmp_payload(p
, hash
, ISAKMP_NPTYPE_SA
);
1807 /* add body payload */
1808 memcpy(p
, body
->v
, body
->l
);
1810 #ifdef HAVE_PRINT_ISAKMP_C
1811 isakmp_printpacket(buf
, iph2
->ph1
->local
, iph2
->ph1
->remote
, 1);
1815 new = oakley_do_encrypt(iph2
->ph1
, buf
, iph2
->ivm
->ive
, iph2
->ivm
->iv
);
1826 if (error
&& buf
!= NULL
) {
1835 * get remote's sainfo.
1836 * NOTE: this function is for responder.
1840 struct ph2handle
*iph2
;
1842 vchar_t
*idsrc
= NULL
, *iddst
= NULL
;
1844 int error
= ISAKMP_INTERNAL_ERROR
;
1846 if (iph2
->id_p
== NULL
) {
1847 switch (iph2
->src
->sa_family
) {
1849 prefixlen
= sizeof(struct in_addr
) << 3;
1852 prefixlen
= sizeof(struct in6_addr
) << 3;
1855 plog(LLV_ERROR
, LOCATION
, NULL
,
1856 "invalid family: %d\n", iph2
->src
->sa_family
);
1859 idsrc
= ipsecdoi_sockaddr2id(iph2
->src
, prefixlen
,
1862 idsrc
= vdup(iph2
->id
);
1864 if (idsrc
== NULL
) {
1865 plog(LLV_ERROR
, LOCATION
, NULL
,
1866 "failed to set ID for source.\n");
1870 if (iph2
->id
== NULL
) {
1871 switch (iph2
->dst
->sa_family
) {
1873 prefixlen
= sizeof(struct in_addr
) << 3;
1876 prefixlen
= sizeof(struct in6_addr
) << 3;
1879 plog(LLV_ERROR
, LOCATION
, NULL
,
1880 "invalid family: %d\n", iph2
->dst
->sa_family
);
1883 iddst
= ipsecdoi_sockaddr2id(iph2
->dst
, prefixlen
,
1886 iddst
= vdup(iph2
->id_p
);
1888 if (iddst
== NULL
) {
1889 plog(LLV_ERROR
, LOCATION
, NULL
,
1890 "failed to set ID for destination.\n");
1894 iph2
->sainfo
= getsainfo(idsrc
, iddst
);
1895 if (iph2
->sainfo
== NULL
) {
1896 plog(LLV_ERROR
, LOCATION
, NULL
,
1897 "failed to get sainfo.\n");
1901 plog(LLV_DEBUG
, LOCATION
, NULL
,
1902 "get sa info: %s\n", sainfo2str(iph2
->sainfo
));
1915 * Copy both IP addresses in ID payloads into [src,dst]_id if both ID types
1916 * are IP address and same address family.
1917 * Then get remote's policy from SPD copied from kernel.
1918 * If the type of ID payload is address or subnet type, then the index is
1919 * made from the payload. If there is no ID payload, or the type of ID
1920 * payload is NOT address type, then the index is made from the address
1922 * NOTE: This function is only for responder.
1925 get_proposal_r(iph2
)
1926 struct ph2handle
*iph2
;
1928 struct policyindex spidx
;
1929 struct secpolicy
*sp_in
, *sp_out
;
1930 int idi2type
= 0; /* switch whether copy IDs into id[src,dst]. */
1931 int error
= ISAKMP_INTERNAL_ERROR
;
1933 /* check the existence of ID payload */
1934 if ((iph2
->id_p
!= NULL
&& iph2
->id
== NULL
)
1935 || (iph2
->id_p
== NULL
&& iph2
->id
!= NULL
)) {
1936 plog(LLV_ERROR
, LOCATION
, NULL
,
1937 "Both IDs wasn't found in payload.\n");
1938 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
1941 /* make sure if id[src,dst] is null. */
1942 if (iph2
->src_id
|| iph2
->dst_id
) {
1943 plog(LLV_ERROR
, LOCATION
, NULL
,
1944 "Why do ID[src,dst] exist already.\n");
1945 return ISAKMP_INTERNAL_ERROR
;
1948 memset(&spidx
, 0, sizeof(spidx
));
1950 #define _XIDT(d) ((struct ipsecdoi_id_b *)(d)->v)->type
1952 /* make a spidx; a key to search SPD */
1953 spidx
.dir
= IPSEC_DIR_INBOUND
;
1957 * make destination address in spidx from either ID payload
1958 * or phase 1 address into a address in spidx.
1960 if (iph2
->id
!= NULL
1961 && (_XIDT(iph2
->id
) == IPSECDOI_ID_IPV4_ADDR
1962 || _XIDT(iph2
->id
) == IPSECDOI_ID_IPV6_ADDR
1963 || _XIDT(iph2
->id
) == IPSECDOI_ID_IPV4_ADDR_SUBNET
1964 || _XIDT(iph2
->id
) == IPSECDOI_ID_IPV6_ADDR_SUBNET
)) {
1965 /* get a destination address of a policy */
1966 error
= ipsecdoi_id2sockaddr(iph2
->id
,
1967 (struct sockaddr
*)&spidx
.dst
,
1968 &spidx
.prefd
, &spidx
.ul_proto
);
1974 * get scopeid from the SA address.
1975 * note that the phase 1 source address is used as
1976 * a destination address to search for a inbound policy entry
1977 * because rcoon is responder.
1979 if (_XIDT(iph2
->id
) == IPSECDOI_ID_IPV6_ADDR
) {
1980 error
= setscopeid((struct sockaddr
*)&spidx
.dst
,
1987 if (_XIDT(iph2
->id
) == IPSECDOI_ID_IPV4_ADDR
1988 || _XIDT(iph2
->id
) == IPSECDOI_ID_IPV6_ADDR
)
1989 idi2type
= _XIDT(iph2
->id
);
1993 plog(LLV_DEBUG
, LOCATION
, NULL
,
1994 "get a destination address of SP index "
1995 "from phase1 address "
1996 "due to no ID payloads found "
1997 "OR because ID type is not address.\n");
2000 * copy the SOURCE address of IKE into the DESTINATION address
2001 * of the key to search the SPD because the direction of policy
2004 memcpy(&spidx
.dst
, iph2
->src
, iph2
->src
->sa_len
);
2005 switch (spidx
.dst
.ss_family
) {
2007 spidx
.prefd
= sizeof(struct in_addr
) << 3;
2011 spidx
.prefd
= sizeof(struct in6_addr
) << 3;
2020 /* make source address in spidx */
2021 if (iph2
->id_p
!= NULL
2022 && (_XIDT(iph2
->id_p
) == IPSECDOI_ID_IPV4_ADDR
2023 || _XIDT(iph2
->id_p
) == IPSECDOI_ID_IPV6_ADDR
2024 || _XIDT(iph2
->id_p
) == IPSECDOI_ID_IPV4_ADDR_SUBNET
2025 || _XIDT(iph2
->id_p
) == IPSECDOI_ID_IPV6_ADDR_SUBNET
)) {
2026 /* get a source address of inbound SA */
2027 error
= ipsecdoi_id2sockaddr(iph2
->id_p
,
2028 (struct sockaddr
*)&spidx
.src
,
2029 &spidx
.prefs
, &spidx
.ul_proto
);
2035 * get scopeid from the SA address.
2036 * for more detail, see above of this function.
2038 if (_XIDT(iph2
->id_p
) == IPSECDOI_ID_IPV6_ADDR
) {
2039 error
= setscopeid((struct sockaddr
*)&spidx
.src
,
2046 /* make id[src,dst] if both ID types are IP address and same */
2047 if (_XIDT(iph2
->id_p
) == idi2type
2048 && spidx
.dst
.ss_family
== spidx
.src
.ss_family
) {
2049 iph2
->src_id
= dupsaddr((struct sockaddr
*)&spidx
.dst
);
2050 iph2
->dst_id
= dupsaddr((struct sockaddr
*)&spidx
.src
);
2054 plog(LLV_DEBUG
, LOCATION
, NULL
,
2055 "get a source address of SP index "
2056 "from phase1 address "
2057 "due to no ID payloads found "
2058 "OR because ID type is not address.\n");
2060 /* see above comment. */
2061 memcpy(&spidx
.src
, iph2
->dst
, iph2
->dst
->sa_len
);
2062 switch (spidx
.src
.ss_family
) {
2064 spidx
.prefs
= sizeof(struct in_addr
) << 3;
2068 spidx
.prefs
= sizeof(struct in6_addr
) << 3;
2079 plog(LLV_DEBUG
, LOCATION
, NULL
,
2080 "get a src address from ID payload "
2081 "%s prefixlen=%u ul_proto=%u\n",
2082 saddr2str((struct sockaddr
*)&spidx
.src
),
2083 spidx
.prefs
, spidx
.ul_proto
);
2084 plog(LLV_DEBUG
, LOCATION
, NULL
,
2085 "get dst address from ID payload "
2086 "%s prefixlen=%u ul_proto=%u\n",
2087 saddr2str((struct sockaddr
*)&spidx
.dst
),
2088 spidx
.prefd
, spidx
.ul_proto
);
2091 * convert the ul_proto if it is 0
2092 * because 0 in ID payload means a wild card.
2094 if (spidx
.ul_proto
== 0)
2095 spidx
.ul_proto
= IPSEC_ULPROTO_ANY
;
2097 /* get inbound policy */
2098 sp_in
= getsp_r(&spidx
);
2099 if (sp_in
== NULL
) {
2100 if (iph2
->ph1
->rmconf
->gen_policy
) {
2101 plog(LLV_INFO
, LOCATION
, NULL
,
2103 "try to generate the policy : %s\n",
2105 iph2
->spidx_gen
= racoon_malloc(sizeof(spidx
));
2106 if (!iph2
->spidx_gen
) {
2107 plog(LLV_ERROR
, LOCATION
, NULL
,
2108 "buffer allocation failed.\n");
2109 return ISAKMP_INTERNAL_ERROR
;
2111 memcpy(iph2
->spidx_gen
, &spidx
, sizeof(spidx
));
2112 return -2; /* special value */
2114 plog(LLV_ERROR
, LOCATION
, NULL
,
2115 "no policy found: %s\n", spidx2str(&spidx
));
2116 return ISAKMP_INTERNAL_ERROR
;
2119 /* get outbound policy */
2121 struct sockaddr_storage addr
;
2124 spidx
.dir
= IPSEC_DIR_OUTBOUND
;
2126 spidx
.src
= spidx
.dst
;
2129 spidx
.prefs
= spidx
.prefd
;
2132 sp_out
= getsp_r(&spidx
);
2134 plog(LLV_WARNING
, LOCATION
, NULL
,
2135 "no outbound policy found: %s\n",
2140 plog(LLV_DEBUG
, LOCATION
, NULL
,
2141 "suitable SP found:%s\n", spidx2str(&spidx
));
2144 * In the responder side, the inbound policy should be using IPsec.
2145 * outbound policy is not checked currently.
2147 if (sp_in
->policy
!= IPSEC_POLICY_IPSEC
) {
2148 plog(LLV_ERROR
, LOCATION
, NULL
,
2149 "policy found, but no IPsec required: %s\n",
2151 return ISAKMP_INTERNAL_ERROR
;
2154 /* set new proposal derived from a policy into the iph2->proposal. */
2155 if (set_proposal_from_policy(iph2
, sp_in
, sp_out
) < 0) {
2156 plog(LLV_ERROR
, LOCATION
, NULL
,
2157 "failed to create saprop.\n");
2158 return ISAKMP_INTERNAL_ERROR
;
2165 create_natoa_payloads(struct ph2handle
*iph2
, vchar_t
**natoa_i
, vchar_t
**natoa_r
)
2175 *natoa_i
= *natoa_r
= NULL
;
2178 /* create natoa payloads if natt being used */
2179 /* don't send if type == apple */
2180 if ((natt_type
= natd_hasnat(iph2
->ph1
)) != 0)
2181 if (natt_type
== natt_type_rfc
)
2182 natoa_type
= ISAKMP_NPTYPE_NATOA_RFC
;
2183 else if (natt_type
== natt_type_02
|| natt_type
== natt_type_02N
)
2184 natoa_type
= ISAKMP_NPTYPE_NATOA_DRAFT
;
2186 if (natoa_type
== 0)
2189 switch (iph2
->src
->sa_family
) {
2191 src_size
= sizeof(in_addr_t
);
2195 src_size
= sizeof(struct in6_addr
);
2199 plog(LLV_ERROR
, LOCATION
, NULL
,
2200 "invalid address family: %d\n", iph2
->src
->sa_family
);
2204 switch (iph2
->dst
->sa_family
) {
2206 dst_size
= sizeof(in_addr_t
);
2210 dst_size
= sizeof(struct in6_addr
);
2214 plog(LLV_ERROR
, LOCATION
, NULL
,
2215 "invalid address family: %d\n", iph2
->dst
->sa_family
);
2219 i
= vmalloc(sizeof(struct isakmp_pl_natoa
) + src_size
- sizeof(struct isakmp_gen
));
2220 r
= vmalloc(sizeof(struct isakmp_pl_natoa
) + dst_size
- sizeof(struct isakmp_gen
));
2221 if (i
== NULL
|| r
== NULL
) {
2222 plog(LLV_ERROR
, LOCATION
, NULL
,
2223 "failed to get buffer for natoa payload.\n");
2227 /* copy src address */
2230 switch (iph2
->src
->sa_family
) {
2232 *p
= IPSECDOI_ID_IPV4_ADDR
;
2233 bcopy(&(((struct sockaddr_in
*)iph2
->src
)->sin_addr
.s_addr
), p
+ sizeof(u_int32_t
), src_size
);
2237 *p
= IPSECDOI_ID_IPV6_ADDR
;
2238 bcopy(&(((struct sockaddr_in6
*)iph2
->src
)->sin6_addr
), p
+ sizeof(u_int32_t
), src_size
);
2243 /* copy dst address */
2246 switch (iph2
->dst
->sa_family
) {
2248 *p
= IPSECDOI_ID_IPV4_ADDR
;
2249 bcopy(&(((struct sockaddr_in
*)iph2
->dst
)->sin_addr
.s_addr
), p
+ sizeof(u_int32_t
), dst_size
);
2253 *p
= IPSECDOI_ID_IPV6_ADDR
;
2254 bcopy(&(((struct sockaddr_in6
*)iph2
->dst
)->sin6_addr
), p
+ sizeof(u_int32_t
), dst_size
);
2268 setscopeid(sp_addr0
, sa_addr0
)
2269 struct sockaddr
*sp_addr0
, *sa_addr0
;
2271 struct sockaddr_in6
*sp_addr
, *sa_addr
;
2273 sp_addr
= (struct sockaddr_in6
*)sp_addr0
;
2274 sa_addr
= (struct sockaddr_in6
*)sa_addr0
;
2276 if (!IN6_IS_ADDR_LINKLOCAL(&sp_addr
->sin6_addr
)
2277 && !IN6_IS_ADDR_SITELOCAL(&sp_addr
->sin6_addr
)
2278 && !IN6_IS_ADDR_MULTICAST(&sp_addr
->sin6_addr
))
2281 /* this check should not be here ? */
2282 if (sa_addr
->sin6_family
!= AF_INET6
) {
2283 plog(LLV_ERROR
, LOCATION
, NULL
,
2284 "can't get scope ID: family mismatch\n");
2288 if (!IN6_IS_ADDR_LINKLOCAL(&sa_addr
->sin6_addr
)) {
2289 plog(LLV_ERROR
, LOCATION
, NULL
,
2290 "scope ID is not supported except of lladdr.\n");
2294 sp_addr
->sin6_scope_id
= sa_addr
->sin6_scope_id
;