1 /* $Id: isakmp_quick.c,v 1.13.2.7 2005/07/20 08:02:05 vanhu 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
34 #include <sys/types.h>
35 #include <sys/param.h>
36 #include <sys/socket.h>
38 #include <netinet/in.h>
44 #if TIME_WITH_SYS_TIME
45 # include <sys/time.h>
49 # include <sys/time.h>
55 #ifndef HAVE_NETINET6_IPSEC
56 #include <netinet/ipsec.h>
58 #include <netinet6/ipsec.h>
68 #include "localconf.h"
69 #include "remoteconf.h"
70 #include "isakmp_var.h"
72 #include "isakmp_inf.h"
73 #include "isakmp_quick.h"
76 #include "ipsec_doi.h"
77 #include "crypto_openssl.h"
80 #include "algorithm.h"
86 #include "nattraversal.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
*, int));
97 * begin Quick Mode as initiator. send pfkey getspi message to kernel.
100 quick_i1prep(iph2
, msg
)
101 struct ph2handle
*iph2
;
102 vchar_t
*msg
; /* must be null pointer */
104 int error
= ISAKMP_INTERNAL_ERROR
;
107 if (iph2
->status
!= PHASE2ST_STATUS2
) {
108 plog(LLV_ERROR
, LOCATION
, NULL
,
109 "status mismatched %d.\n", iph2
->status
);
113 iph2
->msgid
= isakmp_newmsgid2(iph2
->ph1
);
114 iph2
->ivm
= oakley_newiv2(iph2
->ph1
, iph2
->msgid
);
115 if (iph2
->ivm
== NULL
)
118 iph2
->status
= PHASE2ST_GETSPISENT
;
120 /* don't anything if local test mode. */
126 /* send getspi message */
127 if (pk_sendgetspi(iph2
) < 0)
130 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey getspi sent.\n");
132 iph2
->sce
= sched_new(lcconf
->wait_ph2complete
,
133 pfkey_timeover_stub
, iph2
);
143 * HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ]
146 quick_i1send(iph2
, msg
)
147 struct ph2handle
*iph2
;
148 vchar_t
*msg
; /* must be null pointer */
150 vchar_t
*body
= NULL
;
151 vchar_t
*hash
= NULL
;
152 vchar_t
*natoa_i
= NULL
;
153 vchar_t
*natoa_r
= NULL
;
155 struct isakmp_gen
*gen
;
158 int error
= ISAKMP_INTERNAL_ERROR
;
159 int pfsgroup
, idci
, idcr
;
161 struct ipsecdoi_id_b
*id
, *id_p
;
165 plog(LLV_ERROR
, LOCATION
, NULL
,
166 "msg has to be NULL in this function.\n");
169 if (iph2
->status
!= PHASE2ST_GETSPIDONE
) {
170 plog(LLV_ERROR
, LOCATION
, NULL
,
171 "status mismatched %d.\n", iph2
->status
);
175 /* create SA payload for my proposal */
176 if (ipsecdoi_setph2proposal(iph2
) < 0)
179 /* generate NONCE value */
180 iph2
->nonce
= eay_set_random(iph2
->ph1
->rmconf
->nonce_size
);
181 if (iph2
->nonce
== NULL
)
185 * DH value calculation is kicked out into cfparse.y.
186 * because pfs group can not be negotiated, it's only to be checked
189 /* generate KE value if need */
190 pfsgroup
= iph2
->proposal
->pfs_group
;
192 /* DH group settting if PFS is required. */
193 if (oakley_setdhgroup(pfsgroup
, &iph2
->pfsgrp
) < 0) {
194 plog(LLV_ERROR
, LOCATION
, NULL
,
195 "failed to set DH value.\n");
198 if (oakley_dh_generate(iph2
->pfsgrp
,
199 &iph2
->dhpub
, &iph2
->dhpriv
) < 0) {
204 /* generate ID value */
205 if (ipsecdoi_setid2(iph2
) < 0) {
206 plog(LLV_ERROR
, LOCATION
, NULL
,
207 "failed to get ID.\n");
210 plog(LLV_DEBUG
, LOCATION
, NULL
, "IDci:");
211 plogdump(LLV_DEBUG
, iph2
->id
->v
, iph2
->id
->l
);
212 plog(LLV_DEBUG
, LOCATION
, NULL
, "IDcr:");
213 plogdump(LLV_DEBUG
, iph2
->id_p
->v
, iph2
->id_p
->l
);
216 * we do not attach IDci nor IDcr, under the following condition:
217 * - all proposals are transport mode
219 * - id payload suggests to encrypt all the traffic (no specific
222 id
= (struct ipsecdoi_id_b
*)iph2
->id
->v
;
223 id_p
= (struct ipsecdoi_id_b
*)iph2
->id_p
->v
;
224 if (id
->proto_id
== 0
225 && id_p
->proto_id
== 0
226 && iph2
->ph1
->rmconf
->support_proxy
== 0
227 && ipsecdoi_transportmode(iph2
->proposal
)) {
232 /* create SA;NONCE payload, and KE if need, and IDii, IDir. */
233 tlen
= + sizeof(*gen
) + iph2
->sa
->l
234 + sizeof(*gen
) + iph2
->nonce
->l
;
236 tlen
+= (sizeof(*gen
) + iph2
->dhpub
->l
);
238 tlen
+= sizeof(*gen
) + iph2
->id
->l
;
240 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
;
260 body
= vmalloc(tlen
);
262 plog(LLV_ERROR
, LOCATION
, NULL
,
263 "failed to get buffer to send.\n");
270 p
= set_isakmp_payload(p
, iph2
->sa
, ISAKMP_NPTYPE_NONCE
);
272 /* add NONCE payload */
274 np
= ISAKMP_NPTYPE_KE
;
275 else if (idci
|| idcr
)
276 np
= ISAKMP_NPTYPE_ID
;
279 np
= (natoa_type
? natoa_type
: ISAKMP_NPTYPE_NONE
);
281 np
= ISAKMP_NPTYPE_NONE
;
283 p
= set_isakmp_payload(p
, iph2
->nonce
, np
);
285 /* add KE payload if need. */
287 np
= (idci
|| idcr
) ? ISAKMP_NPTYPE_ID
: (natoa_type
? natoa_type
: ISAKMP_NPTYPE_NONE
);
289 np
= (idci
|| idcr
) ? ISAKMP_NPTYPE_ID
: ISAKMP_NPTYPE_NONE
;
292 p
= set_isakmp_payload(p
, iph2
->dhpub
, np
);
296 np
= (idcr
) ? ISAKMP_NPTYPE_ID
: (natoa_type
? natoa_type
: ISAKMP_NPTYPE_NONE
);
298 np
= (idcr
) ? ISAKMP_NPTYPE_ID
: ISAKMP_NPTYPE_NONE
;
301 p
= set_isakmp_payload(p
, iph2
->id
, np
);
306 p
= set_isakmp_payload(p
, iph2
->id_p
, natoa_type
? natoa_type
: ISAKMP_NPTYPE_NONE
);
310 p
= set_isakmp_payload(p
, natoa_i
, natoa_type
);
311 p
= set_isakmp_payload(p
, natoa_r
, ISAKMP_NPTYPE_NONE
);
314 p
= set_isakmp_payload(p
, iph2
->id_p
, ISAKMP_NPTYPE_NONE
);
317 /* generate HASH(1) */
318 hash
= oakley_compute_hash1(iph2
->ph1
, iph2
->msgid
, body
);
322 /* send isakmp payload */
323 iph2
->sendbuf
= quick_ir1mx(iph2
, body
, hash
);
324 if (iph2
->sendbuf
== NULL
)
327 /* send the packet, add to the schedule to resend */
328 iph2
->retry_counter
= iph2
->ph1
->rmconf
->retry_counter
;
329 if (isakmp_ph2resend(iph2
) == -1)
332 /* change status of isakmp status entry */
333 iph2
->status
= PHASE2ST_MSG1SENT
;
353 * receive from responder
354 * HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ]
357 quick_i2recv(iph2
, msg0
)
358 struct ph2handle
*iph2
;
362 vchar_t
*hbuf
= NULL
; /* for hash computing. */
363 vchar_t
*pbuf
= NULL
; /* for payload parsing */
364 struct isakmp_parse_t
*pa
;
365 struct isakmp
*isakmp
= (struct isakmp
*)msg0
->v
;
366 struct isakmp_pl_hash
*hash
= NULL
;
370 int error
= ISAKMP_INTERNAL_ERROR
;
373 if (iph2
->status
!= PHASE2ST_MSG1SENT
) {
374 plog(LLV_ERROR
, LOCATION
, NULL
,
375 "status mismatched %d.\n", iph2
->status
);
380 if (!ISSET(((struct isakmp
*)msg0
->v
)->flags
, ISAKMP_FLAG_E
)) {
381 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
382 "Packet wasn't encrypted.\n");
385 msg
= oakley_do_decrypt(iph2
->ph1
, msg0
, iph2
->ivm
->iv
, iph2
->ivm
->ive
);
389 /* create buffer for validating HASH(2) */
392 * 1. the first one must be HASH
393 * 2. the second one must be SA (added in isakmp-oakley-05!)
394 * 3. two IDs must be considered as IDci, then IDcr
396 pbuf
= isakmp_parse(msg
);
399 pa
= (struct isakmp_parse_t
*)pbuf
->v
;
401 /* HASH payload is fixed postion */
402 if (pa
->type
!= ISAKMP_NPTYPE_HASH
) {
403 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
404 "received invalid next payload type %d, "
406 pa
->type
, ISAKMP_NPTYPE_HASH
);
409 hash
= (struct isakmp_pl_hash
*)pa
->ptr
;
413 * this restriction was introduced in isakmp-oakley-05.
414 * we do not check this for backward compatibility.
415 * TODO: command line/config file option to enable/disable this code
417 /* HASH payload is fixed postion */
418 if (pa
->type
!= ISAKMP_NPTYPE_SA
) {
419 plog(LLV_WARNING
, LOCATION
, iph2
->ph1
->remote
,
420 "received invalid next payload type %d, "
422 pa
->type
, ISAKMP_NPTYPE_HASH
);
425 /* allocate buffer for computing HASH(2) */
426 tlen
= iph2
->nonce
->l
427 + ntohl(isakmp
->len
) - sizeof(*isakmp
);
428 hbuf
= vmalloc(tlen
);
430 plog(LLV_ERROR
, LOCATION
, NULL
,
431 "failed to get hash buffer.\n");
434 p
= hbuf
->v
+ iph2
->nonce
->l
; /* retain the space for Ni_b */
437 * parse the payloads.
438 * copy non-HASH payloads into hbuf, so that we can validate HASH.
441 f_id
= 0; /* flag to use checking ID */
442 tlen
= 0; /* count payload length except of HASH payload. */
443 for (; pa
->type
; pa
++) {
445 /* copy to buffer for HASH */
446 /* Don't modify the payload */
447 memcpy(p
, pa
->ptr
, pa
->len
);
450 case ISAKMP_NPTYPE_SA
:
451 if (iph2
->sa_ret
!= NULL
) {
452 plog(LLV_ERROR
, LOCATION
, NULL
,
453 "Ignored, multiple SA "
454 "isn't supported.\n");
457 if (isakmp_p2ph(&iph2
->sa_ret
, pa
->ptr
) < 0)
461 case ISAKMP_NPTYPE_NONCE
:
462 if (isakmp_p2ph(&iph2
->nonce_p
, pa
->ptr
) < 0)
466 case ISAKMP_NPTYPE_KE
:
467 if (isakmp_p2ph(&iph2
->dhpub_p
, pa
->ptr
) < 0)
471 case ISAKMP_NPTYPE_ID
:
484 /* These ids may not match when natt is used with some devices.
485 * RFC 2407 says that the protocol and port fields should be ignored
486 * if they are zero, therefore they need to be checked individually.
488 struct ipsecdoi_id_b
*id_ptr
= (struct ipsecdoi_id_b
*)vp
->v
;
489 struct ipsecdoi_pl_id
*idp_ptr
= (struct ipsecdoi_pl_id
*)pa
->ptr
;
491 if (id_ptr
->type
!= idp_ptr
->b
.type
492 || (idp_ptr
->b
.proto_id
!= 0 && idp_ptr
->b
.proto_id
!= id_ptr
->proto_id
)
493 || (idp_ptr
->b
.port
!= 0 && idp_ptr
->b
.port
!= id_ptr
->port
)
494 || memcmp(vp
->v
+ sizeof(struct ipsecdoi_id_b
), (caddr_t
)pa
->ptr
+ sizeof(struct ipsecdoi_pl_id
),
495 vp
->l
- sizeof(struct ipsecdoi_id_b
))) {
496 // to support servers that use our external nat address as our ID
497 if (iph2
->ph1
->natt_flags
& NAT_DETECTED
) {
498 plog(LLV_WARNING
, LOCATION
, NULL
,
499 "mismatched ID was returned - ignored because nat traversal is being used.\n");
500 /* If I'm behind a nat and the ID is type address - save the address
501 * and port for when the peer rekeys.
503 if (f_id
== 0 && (iph2
->ph1
->natt_flags
& NAT_DETECTED_ME
)) {
504 if (lcconf
->ext_nat_id
)
505 vfree(lcconf
->ext_nat_id
);
506 lcconf
->ext_nat_id
= vmalloc(idp_ptr
->h
.len
- sizeof(struct isakmp_gen
));
507 if (lcconf
->ext_nat_id
== NULL
) {
508 plog(LLV_ERROR
, LOCATION
, NULL
, "memory error while allocating external nat id.\n");
511 memcpy(lcconf
->ext_nat_id
->v
, &(idp_ptr
->b
), lcconf
->ext_nat_id
->l
);
512 plog(LLV_DEBUG
, LOCATION
, NULL
, "external nat address saved.\n");
515 plog(LLV_ERROR
, LOCATION
, NULL
, "mismatched ID was returned.\n");
516 error
= ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED
;
525 case ISAKMP_NPTYPE_N
:
526 isakmp_check_notify(pa
->ptr
, iph2
->ph1
);
530 case ISAKMP_NPTYPE_NATOA_DRAFT
:
531 case ISAKMP_NPTYPE_NATOA_BADDRAFT
:
532 case ISAKMP_NPTYPE_NATOA_RFC
:
533 /* Ignore original source/destination messages */
538 /* don't send information, see ident_r1recv() */
539 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
540 "ignore the packet, "
541 "received unexpecting payload type %d.\n",
548 /* compute true length of payload. */
552 /* payload existency check */
553 if (hash
== NULL
|| iph2
->sa_ret
== NULL
|| iph2
->nonce_p
== NULL
) {
554 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
555 "few isakmp message received.\n");
559 /* Fixed buffer for calculating HASH */
560 memcpy(hbuf
->v
, iph2
->nonce
->v
, iph2
->nonce
->l
);
561 plog(LLV_DEBUG
, LOCATION
, NULL
,
562 "HASH allocated:hbuf->l=%zu actual:tlen=%zu\n",
563 hbuf
->l
, tlen
+ iph2
->nonce
->l
);
564 /* adjust buffer length for HASH */
565 hbuf
->l
= iph2
->nonce
->l
+ tlen
;
567 /* validate HASH(2) */
570 vchar_t
*my_hash
= NULL
;
573 r_hash
= (char *)hash
+ sizeof(*hash
);
575 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH(2) received:");
576 plogdump(LLV_DEBUG
, r_hash
, ntohs(hash
->h
.len
) - sizeof(*hash
));
578 my_hash
= oakley_compute_hash1(iph2
->ph1
, iph2
->msgid
, hbuf
);
582 result
= memcmp(my_hash
->v
, r_hash
, my_hash
->l
);
586 plog(LLV_DEBUG
, LOCATION
, iph2
->ph1
->remote
,
587 "HASH(2) mismatch.\n");
588 error
= ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
593 /* validity check SA payload sent from responder */
594 if (ipsecdoi_checkph2proposal(iph2
) < 0) {
595 error
= ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN
;
599 /* change status of isakmp status entry */
600 iph2
->status
= PHASE2ST_STATUS6
;
613 VPTRINIT(iph2
->sa_ret
);
614 VPTRINIT(iph2
->nonce_p
);
615 VPTRINIT(iph2
->dhpub_p
);
617 VPTRINIT(iph2
->id_p
);
628 quick_i2send(iph2
, msg0
)
629 struct ph2handle
*iph2
;
634 vchar_t
*hash
= NULL
;
637 int error
= ISAKMP_INTERNAL_ERROR
;
640 if (iph2
->status
!= PHASE2ST_STATUS6
) {
641 plog(LLV_ERROR
, LOCATION
, NULL
,
642 "status mismatched %d.\n", iph2
->status
);
646 /* generate HASH(3) */
650 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH(3) generate\n");
652 tmp
= vmalloc(iph2
->nonce
->l
+ iph2
->nonce_p
->l
);
654 plog(LLV_ERROR
, LOCATION
, NULL
,
655 "failed to get hash buffer.\n");
658 memcpy(tmp
->v
, iph2
->nonce
->v
, iph2
->nonce
->l
);
659 memcpy(tmp
->v
+ iph2
->nonce
->l
, iph2
->nonce_p
->v
, iph2
->nonce_p
->l
);
661 hash
= oakley_compute_hash3(iph2
->ph1
, iph2
->msgid
, tmp
);
668 /* create buffer for isakmp payload */
669 tlen
= sizeof(struct isakmp
)
670 + sizeof(struct isakmp_gen
) + hash
->l
;
673 plog(LLV_ERROR
, LOCATION
, NULL
,
674 "failed to get buffer to send.\n");
678 /* create isakmp header */
679 p
= set_isakmp_header2(buf
, iph2
, ISAKMP_NPTYPE_HASH
);
683 /* add HASH(3) payload */
684 p
= set_isakmp_payload(p
, hash
, ISAKMP_NPTYPE_NONE
);
686 #ifdef HAVE_PRINT_ISAKMP_C
687 isakmp_printpacket(buf
, iph2
->ph1
->local
, iph2
->ph1
->remote
, 1);
691 iph2
->sendbuf
= oakley_do_encrypt(iph2
->ph1
, buf
, iph2
->ivm
->ive
, iph2
->ivm
->iv
);
692 if (iph2
->sendbuf
== NULL
)
695 /* if there is commit bit, need resending */
696 if (ISSET(iph2
->flags
, ISAKMP_FLAG_C
)) {
697 /* send the packet, add to the schedule to resend */
698 iph2
->retry_counter
= iph2
->ph1
->rmconf
->retry_counter
;
699 if (isakmp_ph2resend(iph2
) == -1)
702 /* send the packet */
703 if (isakmp_send(iph2
->ph1
, iph2
->sendbuf
) < 0)
707 /* the sending message is added to the received-list. */
708 if (add_recvdpkt(iph2
->ph1
->remote
, iph2
->ph1
->local
,
709 iph2
->sendbuf
, msg0
) == -1) {
710 plog(LLV_ERROR
, LOCATION
, NULL
,
711 "failed to add a response packet to the tree.\n");
715 /* compute both of KEYMATs */
716 if (oakley_compute_keymat(iph2
, INITIATOR
) < 0)
719 iph2
->status
= PHASE2ST_ADDSA
;
721 /* don't anything if local test mode. */
727 /* if there is commit bit don't set up SA now. */
728 if (ISSET(iph2
->flags
, ISAKMP_FLAG_C
)) {
729 iph2
->status
= PHASE2ST_COMMIT
;
734 /* Do UPDATE for initiator */
735 plog(LLV_DEBUG
, LOCATION
, NULL
, "call pk_sendupdate\n");
736 if (pk_sendupdate(iph2
) < 0) {
737 plog(LLV_ERROR
, LOCATION
, NULL
, "pfkey update failed.\n");
740 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey update sent.\n");
742 /* Do ADD for responder */
743 if (pk_sendadd(iph2
) < 0) {
744 plog(LLV_ERROR
, LOCATION
, NULL
, "pfkey add failed.\n");
747 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey add sent.\n");
763 * receive from responder
764 * HDR#*, HASH(4), notify
767 quick_i3recv(iph2
, msg0
)
768 struct ph2handle
*iph2
;
772 vchar_t
*pbuf
= NULL
; /* for payload parsing */
773 struct isakmp_parse_t
*pa
;
774 struct isakmp_pl_hash
*hash
= NULL
;
775 vchar_t
*notify
= NULL
;
776 int error
= ISAKMP_INTERNAL_ERROR
;
779 if (iph2
->status
!= PHASE2ST_COMMIT
) {
780 plog(LLV_ERROR
, LOCATION
, NULL
,
781 "status mismatched %d.\n", iph2
->status
);
786 if (!ISSET(((struct isakmp
*)msg0
->v
)->flags
, ISAKMP_FLAG_E
)) {
787 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
788 "Packet wasn't encrypted.\n");
791 msg
= oakley_do_decrypt(iph2
->ph1
, msg0
, iph2
->ivm
->iv
, iph2
->ivm
->ive
);
795 /* validate the type of next payload */
796 pbuf
= isakmp_parse(msg
);
800 for (pa
= (struct isakmp_parse_t
*)pbuf
->v
;
801 pa
->type
!= ISAKMP_NPTYPE_NONE
;
805 case ISAKMP_NPTYPE_HASH
:
806 hash
= (struct isakmp_pl_hash
*)pa
->ptr
;
808 case ISAKMP_NPTYPE_N
:
809 isakmp_check_notify(pa
->ptr
, iph2
->ph1
);
810 notify
= vmalloc(pa
->len
);
811 if (notify
== NULL
) {
812 plog(LLV_ERROR
, LOCATION
, NULL
,
813 "failed to get notify buffer.\n");
816 memcpy(notify
->v
, pa
->ptr
, notify
->l
);
819 /* don't send information, see ident_r1recv() */
820 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
821 "ignore the packet, "
822 "received unexpecting payload type %d.\n",
828 /* payload existency check */
830 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
831 "few isakmp message received.\n");
835 /* validate HASH(4) */
838 vchar_t
*my_hash
= NULL
;
842 r_hash
= (char *)hash
+ sizeof(*hash
);
844 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH(4) validate:");
845 plogdump(LLV_DEBUG
, r_hash
, ntohs(hash
->h
.len
) - sizeof(*hash
));
847 my_hash
= oakley_compute_hash1(iph2
->ph1
, iph2
->msgid
, notify
);
852 result
= memcmp(my_hash
->v
, r_hash
, my_hash
->l
);
856 plog(LLV_DEBUG
, LOCATION
, iph2
->ph1
->remote
,
857 "HASH(4) mismatch.\n");
858 error
= ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
863 iph2
->status
= PHASE2ST_ADDSA
;
864 iph2
->flags
^= ISAKMP_FLAG_C
; /* reset bit */
866 /* don't anything if local test mode. */
872 /* Do UPDATE for initiator */
873 plog(LLV_DEBUG
, LOCATION
, NULL
, "call pk_sendupdate\n");
874 if (pk_sendupdate(iph2
) < 0) {
875 plog(LLV_ERROR
, LOCATION
, NULL
, "pfkey update failed.\n");
878 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey update sent.\n");
880 /* Do ADD for responder */
881 if (pk_sendadd(iph2
) < 0) {
882 plog(LLV_ERROR
, LOCATION
, NULL
, "pfkey add failed.\n");
885 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey add sent.\n");
901 * receive from initiator
902 * HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ]
905 quick_r1recv(iph2
, msg0
)
906 struct ph2handle
*iph2
;
910 vchar_t
*hbuf
= NULL
; /* for hash computing. */
911 vchar_t
*pbuf
= NULL
; /* for payload parsing */
912 struct isakmp_parse_t
*pa
;
913 struct isakmp
*isakmp
= (struct isakmp
*)msg0
->v
;
914 struct isakmp_pl_hash
*hash
= NULL
;
917 int f_id_order
; /* for ID payload detection */
918 int error
= ISAKMP_INTERNAL_ERROR
;
921 if (iph2
->status
!= PHASE2ST_START
) {
922 plog(LLV_ERROR
, LOCATION
, NULL
,
923 "status mismatched %d.\n", iph2
->status
);
928 if (!ISSET(((struct isakmp
*)msg0
->v
)->flags
, ISAKMP_FLAG_E
)) {
929 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
930 "Packet wasn't encrypted.\n");
931 error
= ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
935 msg
= oakley_do_decrypt(iph2
->ph1
, msg0
, iph2
->ivm
->iv
, iph2
->ivm
->ive
);
939 /* create buffer for using to validate HASH(1) */
942 * 1. the first one must be HASH
943 * 2. the second one must be SA (added in isakmp-oakley-05!)
944 * 3. two IDs must be considered as IDci, then IDcr
946 pbuf
= isakmp_parse(msg
);
949 pa
= (struct isakmp_parse_t
*)pbuf
->v
;
951 /* HASH payload is fixed postion */
952 if (pa
->type
!= ISAKMP_NPTYPE_HASH
) {
953 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
954 "received invalid next payload type %d, "
956 pa
->type
, ISAKMP_NPTYPE_HASH
);
957 error
= ISAKMP_NTYPE_BAD_PROPOSAL_SYNTAX
;
960 hash
= (struct isakmp_pl_hash
*)pa
->ptr
;
964 * this restriction was introduced in isakmp-oakley-05.
965 * we do not check this for backward compatibility.
966 * TODO: command line/config file option to enable/disable this code
968 /* HASH payload is fixed postion */
969 if (pa
->type
!= ISAKMP_NPTYPE_SA
) {
970 plog(LLV_WARNING
, LOCATION
, iph2
->ph1
->remote
,
971 "received invalid next payload type %d, "
973 pa
->type
, ISAKMP_NPTYPE_SA
);
974 error
= ISAKMP_NTYPE_BAD_PROPOSAL_SYNTAX
;
977 /* allocate buffer for computing HASH(1) */
978 tlen
= ntohl(isakmp
->len
) - sizeof(*isakmp
);
979 hbuf
= vmalloc(tlen
);
981 plog(LLV_ERROR
, LOCATION
, NULL
,
982 "failed to get hash buffer.\n");
988 * parse the payloads.
989 * copy non-HASH payloads into hbuf, so that we can validate HASH.
991 iph2
->sa
= NULL
; /* we don't support multi SAs. */
992 iph2
->nonce_p
= NULL
;
993 iph2
->dhpub_p
= NULL
;
996 tlen
= 0; /* count payload length except of HASH payload. */
999 * IDi2 MUST be immediatelly followed by IDr2. We allowed the
1000 * illegal case, but logged. First ID payload is to be IDi2.
1001 * And next ID payload is to be IDr2.
1005 for (; pa
->type
; pa
++) {
1007 /* copy to buffer for HASH */
1008 /* Don't modify the payload */
1009 memcpy(p
, pa
->ptr
, pa
->len
);
1011 if (pa
->type
!= ISAKMP_NPTYPE_ID
)
1015 case ISAKMP_NPTYPE_SA
:
1016 if (iph2
->sa
!= NULL
) {
1017 plog(LLV_ERROR
, LOCATION
, NULL
,
1018 "Multi SAs isn't supported.\n");
1021 if (isakmp_p2ph(&iph2
->sa
, pa
->ptr
) < 0)
1025 case ISAKMP_NPTYPE_NONCE
:
1026 if (isakmp_p2ph(&iph2
->nonce_p
, pa
->ptr
) < 0)
1030 case ISAKMP_NPTYPE_KE
:
1031 if (isakmp_p2ph(&iph2
->dhpub_p
, pa
->ptr
) < 0)
1035 case ISAKMP_NPTYPE_ID
:
1036 if (iph2
->id_p
== NULL
) {
1040 if (isakmp_p2ph(&iph2
->id_p
, pa
->ptr
) < 0)
1043 } else if (iph2
->id
== NULL
) {
1045 if (f_id_order
== 0) {
1046 plog(LLV_ERROR
, LOCATION
, NULL
,
1047 "IDr2 payload is not "
1048 "immediatelly followed "
1049 "by IDi2. We allowed.\n");
1050 /* XXX we allowed in this case. */
1053 if (isakmp_p2ph(&iph2
->id
, pa
->ptr
) < 0)
1056 plog(LLV_ERROR
, LOCATION
, NULL
,
1057 "received too many ID payloads.\n");
1058 plogdump(LLV_ERROR
, iph2
->id
->v
, iph2
->id
->l
);
1059 error
= ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
1064 case ISAKMP_NPTYPE_N
:
1065 isakmp_check_notify(pa
->ptr
, iph2
->ph1
);
1069 case ISAKMP_NPTYPE_NATOA_DRAFT
:
1070 case ISAKMP_NPTYPE_NATOA_BADDRAFT
:
1071 case ISAKMP_NPTYPE_NATOA_RFC
:
1072 /* Ignore original source/destination messages */
1077 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1078 "ignore the packet, "
1079 "received unexpected payload type %d.\n",
1081 error
= ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
1087 /* compute true length of payload. */
1091 /* payload existency check */
1092 if (hash
== NULL
|| iph2
->sa
== NULL
|| iph2
->nonce_p
== NULL
) {
1093 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1094 "expected isakmp payloads missing.\n");
1095 error
= ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
1100 plog(LLV_DEBUG
, LOCATION
, NULL
, "received IDci2:");
1101 plogdump(LLV_DEBUG
, iph2
->id_p
->v
, iph2
->id_p
->l
);
1104 plog(LLV_DEBUG
, LOCATION
, NULL
, "received IDcr2:");
1105 plogdump(LLV_DEBUG
, iph2
->id
->v
, iph2
->id
->l
);
1108 /* adjust buffer length for HASH */
1111 /* validate HASH(1) */
1114 vchar_t
*my_hash
= NULL
;
1117 r_hash
= (caddr_t
)hash
+ sizeof(*hash
);
1119 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH(1) validate:");
1120 plogdump(LLV_DEBUG
, r_hash
, ntohs(hash
->h
.len
) - sizeof(*hash
));
1122 my_hash
= oakley_compute_hash1(iph2
->ph1
, iph2
->msgid
, hbuf
);
1123 if (my_hash
== NULL
)
1126 result
= memcmp(my_hash
->v
, r_hash
, my_hash
->l
);
1130 plog(LLV_DEBUG
, LOCATION
, iph2
->ph1
->remote
,
1131 "HASH(1) mismatch.\n");
1132 error
= ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
1138 error
= get_sainfo_r(iph2
);
1140 plog(LLV_ERROR
, LOCATION
, NULL
,
1141 "failed to get sainfo.\n");
1145 /* check the existence of ID payload and create responder's proposal */
1146 error
= get_proposal_r(iph2
, 0);
1147 if (error
!= -2 && error
!= 0 && (iph2
->ph1
->natt_flags
& NAT_DETECTED_ME
) && lcconf
->ext_nat_id
!= NULL
)
1148 error
= get_proposal_r(iph2
, 1);
1152 /* generate a policy template from peer's proposal */
1153 if (set_proposal_from_proposal(iph2
)) {
1154 plog(LLV_ERROR
, LOCATION
, NULL
,
1155 "failed to generate a proposal template "
1156 "from client's proposal.\n");
1157 return ISAKMP_INTERNAL_ERROR
;
1161 /* select single proposal or reject it. */
1162 if (ipsecdoi_selectph2proposal(iph2
) < 0) {
1163 error
= ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN
;
1168 plog(LLV_ERROR
, LOCATION
, NULL
,
1169 "failed to get proposal for responder.\n");
1173 /* check KE and attribute of PFS */
1174 if (iph2
->dhpub_p
!= NULL
&& iph2
->approval
->pfs_group
== 0) {
1175 plog(LLV_ERROR
, LOCATION
, NULL
,
1176 "no PFS is specified, but peer sends KE.\n");
1177 error
= ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN
;
1180 if (iph2
->dhpub_p
== NULL
&& iph2
->approval
->pfs_group
!= 0) {
1181 plog(LLV_ERROR
, LOCATION
, NULL
,
1182 "PFS is specified, but peer doesn't sends KE.\n");
1183 error
= ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN
;
1188 * save the packet from the initiator in order to resend the
1189 * responder's first packet against this packet.
1191 iph2
->msg1
= vdup(msg0
);
1193 /* change status of isakmp status entry */
1194 iph2
->status
= PHASE2ST_STATUS2
;
1208 VPTRINIT(iph2
->nonce_p
);
1209 VPTRINIT(iph2
->dhpub_p
);
1211 VPTRINIT(iph2
->id_p
);
1218 * call pfkey_getspi.
1221 quick_r1prep(iph2
, msg
)
1222 struct ph2handle
*iph2
;
1225 int error
= ISAKMP_INTERNAL_ERROR
;
1227 /* validity check */
1228 if (iph2
->status
!= PHASE2ST_STATUS2
) {
1229 plog(LLV_ERROR
, LOCATION
, NULL
,
1230 "status mismatched %d.\n", iph2
->status
);
1234 iph2
->status
= PHASE2ST_GETSPISENT
;
1236 /* send getspi message */
1237 if (pk_sendgetspi(iph2
) < 0)
1240 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey getspi sent.\n");
1242 iph2
->sce
= sched_new(lcconf
->wait_ph2complete
,
1243 pfkey_timeover_stub
, iph2
);
1253 * HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ]
1256 quick_r2send(iph2
, msg
)
1257 struct ph2handle
*iph2
;
1260 vchar_t
*body
= NULL
;
1261 vchar_t
*hash
= NULL
;
1262 vchar_t
*natoa_i
= NULL
;
1263 vchar_t
*natoa_r
= NULL
;
1266 struct isakmp_gen
*gen
;
1269 int error
= ISAKMP_INTERNAL_ERROR
;
1271 u_int8_t
*np_p
= NULL
;
1273 /* validity check */
1275 plog(LLV_ERROR
, LOCATION
, NULL
,
1276 "msg has to be NULL in this function.\n");
1279 if (iph2
->status
!= PHASE2ST_GETSPIDONE
) {
1280 plog(LLV_ERROR
, LOCATION
, NULL
,
1281 "status mismatched %d.\n", iph2
->status
);
1285 /* update responders SPI */
1286 if (ipsecdoi_updatespi(iph2
) < 0) {
1287 plog(LLV_ERROR
, LOCATION
, NULL
, "failed to update spi.\n");
1291 /* generate NONCE value */
1292 iph2
->nonce
= eay_set_random(iph2
->ph1
->rmconf
->nonce_size
);
1293 if (iph2
->nonce
== NULL
)
1296 /* generate KE value if need */
1297 pfsgroup
= iph2
->approval
->pfs_group
;
1298 if (iph2
->dhpub_p
!= NULL
&& pfsgroup
!= 0) {
1299 /* DH group settting if PFS is required. */
1300 if (oakley_setdhgroup(pfsgroup
, &iph2
->pfsgrp
) < 0) {
1301 plog(LLV_ERROR
, LOCATION
, NULL
,
1302 "failed to set DH value.\n");
1305 /* generate DH public value */
1306 if (oakley_dh_generate(iph2
->pfsgrp
,
1307 &iph2
->dhpub
, &iph2
->dhpriv
) < 0) {
1312 /* create SA;NONCE payload, and KE and ID if need */
1313 tlen
= sizeof(*gen
) + iph2
->sa_ret
->l
1314 + sizeof(*gen
) + iph2
->nonce
->l
;
1315 if (iph2
->dhpub_p
!= NULL
&& pfsgroup
!= 0)
1316 tlen
+= (sizeof(*gen
) + iph2
->dhpub
->l
);
1317 if (iph2
->id_p
!= NULL
)
1318 tlen
+= (sizeof(*gen
) + iph2
->id_p
->l
1319 + sizeof(*gen
) + iph2
->id
->l
);
1323 /* create natoa payloads if needed */
1324 encmode
= iph2
->approval
->head
->encmode
;
1325 if (encmode
== IPSECDOI_ATTR_ENC_MODE_TRNS
||
1326 encmode
== IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC
||
1327 encmode
== IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT
) {
1329 natoa_type
= create_natoa_payloads(iph2
, &natoa_i
, &natoa_r
);
1330 if (natoa_type
== -1)
1332 else if (natoa_type
!= 0) {
1333 tlen
+= sizeof(*gen
) + natoa_i
->l
;
1334 tlen
+= sizeof(*gen
) + natoa_r
->l
;
1341 body
= vmalloc(tlen
);
1343 plog(LLV_ERROR
, LOCATION
, NULL
,
1344 "failed to get buffer to send.\n");
1349 /* make SA payload */
1350 p
= set_isakmp_payload(body
->v
, iph2
->sa_ret
, ISAKMP_NPTYPE_NONCE
);
1352 /* add NONCE payload */
1353 np_p
= &((struct isakmp_gen
*)p
)->np
; /* XXX */
1354 p
= set_isakmp_payload(p
, iph2
->nonce
,
1355 (iph2
->dhpub_p
!= NULL
&& pfsgroup
!= 0)
1357 : (iph2
->id_p
!= NULL
1360 : (natoa_type
? natoa_type
: ISAKMP_NPTYPE_NONE
)));
1362 : ISAKMP_NPTYPE_ID
));
1365 /* add KE payload if need. */
1366 if (iph2
->dhpub_p
!= NULL
&& pfsgroup
!= 0) {
1367 np_p
= &((struct isakmp_gen
*)p
)->np
; /* XXX */
1368 p
= set_isakmp_payload(p
, iph2
->dhpub
,
1369 (iph2
->id_p
== NULL
)
1371 ? (natoa_type
? natoa_type
: ISAKMP_NPTYPE_NONE
)
1373 ? ISAKMP_NPTYPE_NONE
1375 : ISAKMP_NPTYPE_ID
);
1378 /* add ID payloads received. */
1379 if (iph2
->id_p
!= NULL
) {
1381 p
= set_isakmp_payload(p
, iph2
->id_p
, ISAKMP_NPTYPE_ID
);
1383 np_p
= &((struct isakmp_gen
*)p
)->np
; /* XXX */
1385 p
= set_isakmp_payload(p
, iph2
->id
, (natoa_type
? natoa_type
: ISAKMP_NPTYPE_NONE
));
1387 p
= set_isakmp_payload(p
, iph2
->id
, ISAKMP_NPTYPE_NONE
);
1391 /* add a RESPONDER-LIFETIME notify payload if needed */
1393 vchar_t
*data
= NULL
;
1394 struct saprop
*pp
= iph2
->approval
;
1397 if (pp
->claim
& IPSECDOI_ATTR_SA_LD_TYPE_SEC
) {
1398 u_int32_t v
= htonl((u_int32_t
)pp
->lifetime
);
1399 data
= isakmp_add_attr_l(data
, IPSECDOI_ATTR_SA_LD_TYPE
,
1400 IPSECDOI_ATTR_SA_LD_TYPE_SEC
);
1403 data
= isakmp_add_attr_v(data
, IPSECDOI_ATTR_SA_LD
,
1404 (caddr_t
)&v
, sizeof(v
));
1408 if (pp
->claim
& IPSECDOI_ATTR_SA_LD_TYPE_KB
) {
1409 u_int32_t v
= htonl((u_int32_t
)pp
->lifebyte
);
1410 data
= isakmp_add_attr_l(data
, IPSECDOI_ATTR_SA_LD_TYPE
,
1411 IPSECDOI_ATTR_SA_LD_TYPE_KB
);
1414 data
= isakmp_add_attr_v(data
, IPSECDOI_ATTR_SA_LD
,
1415 (caddr_t
)&v
, sizeof(v
));
1421 * XXX Is there only single RESPONDER-LIFETIME payload in a IKE message
1422 * in the case of SA bundle ?
1425 for (pr
= pp
->head
; pr
; pr
= pr
->next
) {
1426 body
= isakmp_add_pl_n(body
, &np_p
,
1427 ISAKMP_NTYPE_RESPONDER_LIFETIME
, pr
, data
);
1430 return error
; /* XXX */
1440 p
= set_isakmp_payload(p
, natoa_i
, natoa_type
);
1441 p
= set_isakmp_payload(p
, natoa_r
, ISAKMP_NPTYPE_NONE
);
1445 /* generate HASH(2) */
1449 tmp
= vmalloc(iph2
->nonce_p
->l
+ body
->l
);
1451 plog(LLV_ERROR
, LOCATION
, NULL
,
1452 "failed to get hash buffer.\n");
1455 memcpy(tmp
->v
, iph2
->nonce_p
->v
, iph2
->nonce_p
->l
);
1456 memcpy(tmp
->v
+ iph2
->nonce_p
->l
, body
->v
, body
->l
);
1458 hash
= oakley_compute_hash1(iph2
->ph1
, iph2
->msgid
, tmp
);
1465 /* send isakmp payload */
1466 iph2
->sendbuf
= quick_ir1mx(iph2
, body
, hash
);
1467 if (iph2
->sendbuf
== NULL
)
1470 /* send the packet, add to the schedule to resend */
1471 iph2
->retry_counter
= iph2
->ph1
->rmconf
->retry_counter
;
1472 if (isakmp_ph2resend(iph2
) == -1)
1475 /* the sending message is added to the received-list. */
1476 if (add_recvdpkt(iph2
->ph1
->remote
, iph2
->ph1
->local
, iph2
->sendbuf
, iph2
->msg1
) == -1) {
1477 plog(LLV_ERROR
, LOCATION
, NULL
,
1478 "failed to add a response packet to the tree.\n");
1482 /* change status of isakmp status entry */
1483 iph2
->status
= PHASE2ST_MSG1SENT
;
1503 * receive from initiator
1507 quick_r3recv(iph2
, msg0
)
1508 struct ph2handle
*iph2
;
1511 vchar_t
*msg
= NULL
;
1512 vchar_t
*pbuf
= NULL
; /* for payload parsing */
1513 struct isakmp_parse_t
*pa
;
1514 struct isakmp_pl_hash
*hash
= NULL
;
1515 int error
= ISAKMP_INTERNAL_ERROR
;
1517 /* validity check */
1518 if (iph2
->status
!= PHASE2ST_MSG1SENT
) {
1519 plog(LLV_ERROR
, LOCATION
, NULL
,
1520 "status mismatched %d.\n", iph2
->status
);
1524 /* decrypt packet */
1525 if (!ISSET(((struct isakmp
*)msg0
->v
)->flags
, ISAKMP_FLAG_E
)) {
1526 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1527 "Packet wasn't encrypted.\n");
1530 msg
= oakley_do_decrypt(iph2
->ph1
, msg0
, iph2
->ivm
->iv
, iph2
->ivm
->ive
);
1534 /* validate the type of next payload */
1535 pbuf
= isakmp_parse(msg
);
1539 for (pa
= (struct isakmp_parse_t
*)pbuf
->v
;
1540 pa
->type
!= ISAKMP_NPTYPE_NONE
;
1544 case ISAKMP_NPTYPE_HASH
:
1545 hash
= (struct isakmp_pl_hash
*)pa
->ptr
;
1547 case ISAKMP_NPTYPE_N
:
1548 isakmp_check_notify(pa
->ptr
, iph2
->ph1
);
1551 /* don't send information, see ident_r1recv() */
1552 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1553 "ignore the packet, "
1554 "received unexpecting payload type %d.\n",
1560 /* payload existency check */
1562 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1563 "few isakmp message received.\n");
1567 /* validate HASH(3) */
1568 /* HASH(3) = prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b) */
1571 vchar_t
*my_hash
= NULL
;
1572 vchar_t
*tmp
= NULL
;
1575 r_hash
= (char *)hash
+ sizeof(*hash
);
1577 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH(3) validate:");
1578 plogdump(LLV_DEBUG
, r_hash
, ntohs(hash
->h
.len
) - sizeof(*hash
));
1580 tmp
= vmalloc(iph2
->nonce_p
->l
+ iph2
->nonce
->l
);
1582 plog(LLV_ERROR
, LOCATION
, NULL
,
1583 "failed to get hash buffer.\n");
1586 memcpy(tmp
->v
, iph2
->nonce_p
->v
, iph2
->nonce_p
->l
);
1587 memcpy(tmp
->v
+ iph2
->nonce_p
->l
, iph2
->nonce
->v
, iph2
->nonce
->l
);
1589 my_hash
= oakley_compute_hash3(iph2
->ph1
, iph2
->msgid
, tmp
);
1591 if (my_hash
== NULL
)
1594 result
= memcmp(my_hash
->v
, r_hash
, my_hash
->l
);
1598 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1599 "HASH(3) mismatch.\n");
1600 error
= ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
1605 /* if there is commit bit, don't set up SA now. */
1606 if (ISSET(iph2
->flags
, ISAKMP_FLAG_C
)) {
1607 iph2
->status
= PHASE2ST_COMMIT
;
1609 iph2
->status
= PHASE2ST_STATUS6
;
1624 * HDR#*, HASH(4), notify
1627 quick_r3send(iph2
, msg0
)
1628 struct ph2handle
*iph2
;
1631 vchar_t
*buf
= NULL
;
1632 vchar_t
*myhash
= NULL
;
1633 struct isakmp_pl_n
*n
;
1634 vchar_t
*notify
= NULL
;
1637 int error
= ISAKMP_INTERNAL_ERROR
;
1639 /* validity check */
1640 if (iph2
->status
!= PHASE2ST_COMMIT
) {
1641 plog(LLV_ERROR
, LOCATION
, NULL
,
1642 "status mismatched %d.\n", iph2
->status
);
1646 /* generate HASH(4) */
1647 /* XXX What can I do in the case of multiple different SA */
1648 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH(4) generate\n");
1650 /* XXX What should I do if there are multiple SAs ? */
1651 tlen
= sizeof(struct isakmp_pl_n
) + iph2
->approval
->head
->spisize
;
1652 notify
= vmalloc(tlen
);
1653 if (notify
== NULL
) {
1654 plog(LLV_ERROR
, LOCATION
, NULL
,
1655 "failed to get notify buffer.\n");
1658 n
= (struct isakmp_pl_n
*)notify
->v
;
1659 n
->h
.np
= ISAKMP_NPTYPE_NONE
;
1660 n
->h
.len
= htons(tlen
);
1661 n
->doi
= htonl(IPSEC_DOI
);
1662 n
->proto_id
= iph2
->approval
->head
->proto_id
;
1663 n
->spi_size
= sizeof(iph2
->approval
->head
->spisize
);
1664 n
->type
= htons(ISAKMP_NTYPE_CONNECTED
);
1665 memcpy(n
+ 1, &iph2
->approval
->head
->spi
, iph2
->approval
->head
->spisize
);
1667 myhash
= oakley_compute_hash1(iph2
->ph1
, iph2
->msgid
, notify
);
1671 /* create buffer for isakmp payload */
1672 tlen
= sizeof(struct isakmp
)
1673 + sizeof(struct isakmp_gen
) + myhash
->l
1675 buf
= vmalloc(tlen
);
1677 plog(LLV_ERROR
, LOCATION
, NULL
,
1678 "failed to get buffer to send.\n");
1682 /* create isakmp header */
1683 p
= set_isakmp_header2(buf
, iph2
, ISAKMP_NPTYPE_HASH
);
1687 /* add HASH(4) payload */
1688 p
= set_isakmp_payload(p
, myhash
, ISAKMP_NPTYPE_N
);
1690 /* add notify payload */
1691 memcpy(p
, notify
->v
, notify
->l
);
1693 #ifdef HAVE_PRINT_ISAKMP_C
1694 isakmp_printpacket(buf
, iph2
->ph1
->local
, iph2
->ph1
->remote
, 1);
1698 iph2
->sendbuf
= oakley_do_encrypt(iph2
->ph1
, buf
, iph2
->ivm
->ive
, iph2
->ivm
->iv
);
1699 if (iph2
->sendbuf
== NULL
)
1702 /* send the packet */
1703 if (isakmp_send(iph2
->ph1
, iph2
->sendbuf
) < 0)
1706 /* the sending message is added to the received-list. */
1707 if (add_recvdpkt(iph2
->ph1
->remote
, iph2
->ph1
->local
, iph2
->sendbuf
, msg0
) == -1) {
1708 plog(LLV_ERROR
, LOCATION
, NULL
,
1709 "failed to add a response packet to the tree.\n");
1713 iph2
->status
= PHASE2ST_COMMIT
;
1732 quick_r3prep(iph2
, msg0
)
1733 struct ph2handle
*iph2
;
1736 vchar_t
*msg
= NULL
;
1737 int error
= ISAKMP_INTERNAL_ERROR
;
1739 /* validity check */
1740 if (iph2
->status
!= PHASE2ST_STATUS6
) {
1741 plog(LLV_ERROR
, LOCATION
, NULL
,
1742 "status mismatched %d.\n", iph2
->status
);
1746 /* compute both of KEYMATs */
1747 if (oakley_compute_keymat(iph2
, RESPONDER
) < 0)
1750 iph2
->status
= PHASE2ST_ADDSA
;
1751 iph2
->flags
^= ISAKMP_FLAG_C
; /* reset bit */
1753 /* don't anything if local test mode. */
1759 /* Do UPDATE as responder */
1760 plog(LLV_DEBUG
, LOCATION
, NULL
, "call pk_sendupdate\n");
1761 if (pk_sendupdate(iph2
) < 0) {
1762 plog(LLV_ERROR
, LOCATION
, NULL
, "pfkey update failed.\n");
1765 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey update sent.\n");
1767 /* Do ADD for responder */
1768 if (pk_sendadd(iph2
) < 0) {
1769 plog(LLV_ERROR
, LOCATION
, NULL
, "pfkey add failed.\n");
1772 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey add sent.\n");
1775 * set policies into SPD if the policy is generated
1776 * from peer's policy.
1778 if (iph2
->spidx_gen
) {
1780 struct policyindex
*spidx
;
1781 struct sockaddr_storage addr
;
1783 struct sockaddr
*src
= iph2
->src
;
1784 struct sockaddr
*dst
= iph2
->dst
;
1786 /* make inbound policy */
1789 if (pk_sendspdupdate2(iph2
) < 0) {
1790 plog(LLV_ERROR
, LOCATION
, NULL
,
1791 "pfkey spdupdate2(inbound) failed.\n");
1794 plog(LLV_DEBUG
, LOCATION
, NULL
,
1795 "pfkey spdupdate2(inbound) sent.\n");
1797 spidx
= (struct policyindex
*)iph2
->spidx_gen
;
1798 #ifdef HAVE_POLICY_FWD
1799 /* make forward policy if required */
1800 if (tunnel_mode_prop(iph2
->approval
)) {
1801 spidx
->dir
= IPSEC_DIR_FWD
;
1802 if (pk_sendspdupdate2(iph2
) < 0) {
1803 plog(LLV_ERROR
, LOCATION
, NULL
,
1804 "pfkey spdupdate2(forward) failed.\n");
1807 plog(LLV_DEBUG
, LOCATION
, NULL
,
1808 "pfkey spdupdate2(forward) sent.\n");
1812 /* make outbound policy */
1815 spidx
->dir
= IPSEC_DIR_OUTBOUND
;
1817 spidx
->src
= spidx
->dst
;
1819 pref
= spidx
->prefs
;
1820 spidx
->prefs
= spidx
->prefd
;
1821 spidx
->prefd
= pref
;
1823 if (pk_sendspdupdate2(iph2
) < 0) {
1824 plog(LLV_ERROR
, LOCATION
, NULL
,
1825 "pfkey spdupdate2(outbound) failed.\n");
1828 plog(LLV_DEBUG
, LOCATION
, NULL
,
1829 "pfkey spdupdate2(outbound) sent.\n");
1831 /* spidx_gen is unnecessary any more */
1832 delsp_bothdir((struct policyindex
*)iph2
->spidx_gen
);
1833 racoon_free(iph2
->spidx_gen
);
1834 iph2
->spidx_gen
= NULL
;
1835 iph2
->generated_spidx
=1;
1848 * create HASH, body (SA, NONCE) payload with isakmp header.
1851 quick_ir1mx(iph2
, body
, hash
)
1852 struct ph2handle
*iph2
;
1853 vchar_t
*body
, *hash
;
1855 struct isakmp
*isakmp
;
1856 vchar_t
*buf
= NULL
, *new = NULL
;
1859 struct isakmp_gen
*gen
;
1860 int error
= ISAKMP_INTERNAL_ERROR
;
1862 /* create buffer for isakmp payload */
1863 tlen
= sizeof(*isakmp
)
1864 + sizeof(*gen
) + hash
->l
1866 buf
= vmalloc(tlen
);
1868 plog(LLV_ERROR
, LOCATION
, NULL
,
1869 "failed to get buffer to send.\n");
1873 /* re-set encryption flag, for serurity. */
1874 iph2
->flags
|= ISAKMP_FLAG_E
;
1876 /* set isakmp header */
1877 p
= set_isakmp_header2(buf
, iph2
, ISAKMP_NPTYPE_HASH
);
1881 /* add HASH payload */
1882 /* XXX is next type always SA ? */
1883 p
= set_isakmp_payload(p
, hash
, ISAKMP_NPTYPE_SA
);
1885 /* add body payload */
1886 memcpy(p
, body
->v
, body
->l
);
1888 #ifdef HAVE_PRINT_ISAKMP_C
1889 isakmp_printpacket(buf
, iph2
->ph1
->local
, iph2
->ph1
->remote
, 1);
1893 new = oakley_do_encrypt(iph2
->ph1
, buf
, iph2
->ivm
->ive
, iph2
->ivm
->iv
);
1904 if (error
&& buf
!= NULL
) {
1913 * get remote's sainfo.
1914 * NOTE: this function is for responder.
1918 struct ph2handle
*iph2
;
1920 vchar_t
*idsrc
= NULL
, *iddst
= NULL
;
1922 int error
= ISAKMP_INTERNAL_ERROR
;
1924 if (iph2
->id_p
== NULL
) {
1925 switch (iph2
->src
->sa_family
) {
1927 prefixlen
= sizeof(struct in_addr
) << 3;
1930 prefixlen
= sizeof(struct in6_addr
) << 3;
1933 plog(LLV_ERROR
, LOCATION
, NULL
,
1934 "invalid family: %d\n", iph2
->src
->sa_family
);
1937 idsrc
= ipsecdoi_sockaddr2id(iph2
->src
, prefixlen
,
1940 idsrc
= vdup(iph2
->id
);
1942 if (idsrc
== NULL
) {
1943 plog(LLV_ERROR
, LOCATION
, NULL
,
1944 "failed to set ID for source.\n");
1948 if (iph2
->id
== NULL
) {
1949 switch (iph2
->dst
->sa_family
) {
1951 prefixlen
= sizeof(struct in_addr
) << 3;
1954 prefixlen
= sizeof(struct in6_addr
) << 3;
1957 plog(LLV_ERROR
, LOCATION
, NULL
,
1958 "invalid family: %d\n", iph2
->dst
->sa_family
);
1961 iddst
= ipsecdoi_sockaddr2id(iph2
->dst
, prefixlen
,
1964 iddst
= vdup(iph2
->id_p
);
1966 if (iddst
== NULL
) {
1967 plog(LLV_ERROR
, LOCATION
, NULL
,
1968 "failed to set ID for destination.\n");
1972 iph2
->sainfo
= getsainfo(idsrc
, iddst
, iph2
->ph1
->id_p
, 0);
1973 if (iph2
->sainfo
== NULL
)
1974 if ((iph2
->ph1
->natt_flags
& NAT_DETECTED_ME
) && lcconf
->ext_nat_id
!= NULL
)
1975 iph2
->sainfo
= getsainfo(idsrc
, iddst
, iph2
->ph1
->id_p
, 1);
1976 if (iph2
->sainfo
== NULL
) {
1977 plog(LLV_ERROR
, LOCATION
, NULL
,
1978 "failed to get sainfo.\n");
1982 plog(LLV_DEBUG
, LOCATION
, NULL
,
1983 "get sa info: %s\n", sainfo2str(iph2
->sainfo
));
1996 * Copy both IP addresses in ID payloads into [src,dst]_id if both ID types
1997 * are IP address and same address family.
1998 * Then get remote's policy from SPD copied from kernel.
1999 * If the type of ID payload is address or subnet type, then the index is
2000 * made from the payload. If there is no ID payload, or the type of ID
2001 * payload is NOT address type, then the index is made from the address
2003 * NOTE: This function is only for responder.
2006 get_proposal_r(iph2
, use_remote_addr
)
2007 struct ph2handle
*iph2
;
2008 int use_remote_addr
;
2010 struct policyindex spidx
;
2011 struct secpolicy
*sp_in
, *sp_out
;
2012 int idi2type
= 0; /* switch whether copy IDs into id[src,dst]. */
2013 int error
= ISAKMP_INTERNAL_ERROR
;
2015 /* check the existence of ID payload */
2016 if ((iph2
->id_p
!= NULL
&& iph2
->id
== NULL
)
2017 || (iph2
->id_p
== NULL
&& iph2
->id
!= NULL
)) {
2018 plog(LLV_ERROR
, LOCATION
, NULL
,
2019 "Both IDs wasn't found in payload.\n");
2020 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2023 /* make sure if id[src,dst] is null. */
2024 if (iph2
->src_id
|| iph2
->dst_id
) {
2025 plog(LLV_ERROR
, LOCATION
, NULL
,
2026 "Why do ID[src,dst] exist already.\n");
2027 return ISAKMP_INTERNAL_ERROR
;
2030 memset(&spidx
, 0, sizeof(spidx
));
2032 #define _XIDT(d) ((struct ipsecdoi_id_b *)(d)->v)->type
2034 /* make a spidx; a key to search SPD */
2035 spidx
.dir
= IPSEC_DIR_INBOUND
;
2039 * make destination address in spidx from either ID payload
2040 * or phase 1 address into a address in spidx.
2041 * If behind a nat - use phase1 address because server's
2042 * use the nat's address in the ID payload.
2044 if (iph2
->id
!= NULL
2045 && use_remote_addr
== 0
2046 && (_XIDT(iph2
->id
) == IPSECDOI_ID_IPV4_ADDR
2047 || _XIDT(iph2
->id
) == IPSECDOI_ID_IPV6_ADDR
2048 || _XIDT(iph2
->id
) == IPSECDOI_ID_IPV4_ADDR_SUBNET
2049 || _XIDT(iph2
->id
) == IPSECDOI_ID_IPV6_ADDR_SUBNET
)) {
2050 /* get a destination address of a policy */
2051 error
= ipsecdoi_id2sockaddr(iph2
->id
,
2052 (struct sockaddr
*)&spidx
.dst
,
2053 &spidx
.prefd
, &spidx
.ul_proto
);
2059 * get scopeid from the SA address.
2060 * note that the phase 1 source address is used as
2061 * a destination address to search for a inbound policy entry
2062 * because rcoon is responder.
2064 if (_XIDT(iph2
->id
) == IPSECDOI_ID_IPV6_ADDR
) {
2065 error
= setscopeid((struct sockaddr
*)&spidx
.dst
,
2072 if (_XIDT(iph2
->id
) == IPSECDOI_ID_IPV4_ADDR
2073 || _XIDT(iph2
->id
) == IPSECDOI_ID_IPV6_ADDR
)
2074 idi2type
= _XIDT(iph2
->id
);
2078 plog(LLV_DEBUG
, LOCATION
, NULL
,
2079 "get a destination address of SP index "
2080 "from phase1 address "
2081 "due to no ID payloads found "
2082 "OR because ID type is not address.\n");
2085 * copy the SOURCE address of IKE into the DESTINATION address
2086 * of the key to search the SPD because the direction of policy
2089 memcpy(&spidx
.dst
, iph2
->src
, sysdep_sa_len(iph2
->src
));
2090 switch (spidx
.dst
.ss_family
) {
2093 struct sockaddr_in
*s
= (struct sockaddr_in
*)&spidx
.dst
;
2094 spidx
.prefd
= sizeof(struct in_addr
) << 3;
2095 s
->sin_port
= htons(0);
2100 spidx
.prefd
= sizeof(struct in6_addr
) << 3;
2109 /* make source address in spidx */
2110 if (iph2
->id_p
!= NULL
2111 && use_remote_addr
== 0
2112 && (_XIDT(iph2
->id_p
) == IPSECDOI_ID_IPV4_ADDR
2113 || _XIDT(iph2
->id_p
) == IPSECDOI_ID_IPV6_ADDR
2114 || _XIDT(iph2
->id_p
) == IPSECDOI_ID_IPV4_ADDR_SUBNET
2115 || _XIDT(iph2
->id_p
) == IPSECDOI_ID_IPV6_ADDR_SUBNET
)) {
2116 /* get a source address of inbound SA */
2117 error
= ipsecdoi_id2sockaddr(iph2
->id_p
,
2118 (struct sockaddr
*)&spidx
.src
,
2119 &spidx
.prefs
, &spidx
.ul_proto
);
2125 * get scopeid from the SA address.
2126 * for more detail, see above of this function.
2128 if (_XIDT(iph2
->id_p
) == IPSECDOI_ID_IPV6_ADDR
) {
2129 error
= setscopeid((struct sockaddr
*)&spidx
.src
,
2136 /* make id[src,dst] if both ID types are IP address and same */
2137 if (_XIDT(iph2
->id_p
) == idi2type
2138 && spidx
.dst
.ss_family
== spidx
.src
.ss_family
) {
2139 iph2
->src_id
= dupsaddr((struct sockaddr
*)&spidx
.dst
);
2140 iph2
->dst_id
= dupsaddr((struct sockaddr
*)&spidx
.src
);
2144 plog(LLV_DEBUG
, LOCATION
, NULL
,
2145 "get a source address of SP index "
2146 "from phase1 address "
2147 "due to no ID payloads found "
2148 "OR because ID type is not address.\n");
2150 /* see above comment. */
2151 memcpy(&spidx
.src
, iph2
->dst
, sysdep_sa_len(iph2
->dst
));
2152 switch (spidx
.src
.ss_family
) {
2155 struct sockaddr_in
*s
= (struct sockaddr_in
*)&spidx
.src
;
2156 spidx
.prefs
= sizeof(struct in_addr
) << 3;
2157 s
->sin_port
= htons(0);
2162 spidx
.prefs
= sizeof(struct in6_addr
) << 3;
2173 plog(LLV_DEBUG
, LOCATION
, NULL
,
2174 "get a src address from ID payload "
2175 "%s prefixlen=%u ul_proto=%u\n",
2176 saddr2str((struct sockaddr
*)&spidx
.src
),
2177 spidx
.prefs
, spidx
.ul_proto
);
2178 plog(LLV_DEBUG
, LOCATION
, NULL
,
2179 "get dst address from ID payload "
2180 "%s prefixlen=%u ul_proto=%u\n",
2181 saddr2str((struct sockaddr
*)&spidx
.dst
),
2182 spidx
.prefd
, spidx
.ul_proto
);
2185 * convert the ul_proto if it is 0
2186 * because 0 in ID payload means a wild card.
2188 if (spidx
.ul_proto
== 0)
2189 spidx
.ul_proto
= IPSEC_ULPROTO_ANY
;
2191 /* get inbound policy */
2192 sp_in
= getsp_r(&spidx
);
2193 if (sp_in
== NULL
|| sp_in
->policy
== IPSEC_POLICY_GENERATE
) {
2194 if (iph2
->ph1
->rmconf
->gen_policy
) {
2195 plog(LLV_INFO
, LOCATION
, NULL
,
2197 "try to generate the policy : %s\n",
2199 iph2
->spidx_gen
= racoon_malloc(sizeof(spidx
));
2200 if (!iph2
->spidx_gen
) {
2201 plog(LLV_ERROR
, LOCATION
, NULL
,
2202 "buffer allocation failed.\n");
2203 return ISAKMP_INTERNAL_ERROR
;
2205 memcpy(iph2
->spidx_gen
, &spidx
, sizeof(spidx
));
2206 return -2; /* special value */
2208 plog(LLV_ERROR
, LOCATION
, NULL
,
2209 "no policy found: %s\n", spidx2str(&spidx
));
2210 return ISAKMP_INTERNAL_ERROR
;
2212 /* Refresh existing generated policies
2214 if (iph2
->ph1
->rmconf
->gen_policy
) {
2215 plog(LLV_INFO
, LOCATION
, NULL
,
2216 "Update the generated policy : %s\n",
2218 iph2
->spidx_gen
= racoon_malloc(sizeof(spidx
));
2219 if (!iph2
->spidx_gen
) {
2220 plog(LLV_ERROR
, LOCATION
, NULL
,
2221 "buffer allocation failed.\n");
2222 return ISAKMP_INTERNAL_ERROR
;
2224 memcpy(iph2
->spidx_gen
, &spidx
, sizeof(spidx
));
2227 /* get outbound policy */
2229 struct sockaddr_storage addr
;
2232 spidx
.dir
= IPSEC_DIR_OUTBOUND
;
2234 spidx
.src
= spidx
.dst
;
2237 spidx
.prefs
= spidx
.prefd
;
2240 sp_out
= getsp_r(&spidx
);
2242 plog(LLV_WARNING
, LOCATION
, NULL
,
2243 "no outbound policy found: %s\n",
2248 plog(LLV_DEBUG
, LOCATION
, NULL
,
2249 "suitable SP found:%s\n", spidx2str(&spidx
));
2252 * In the responder side, the inbound policy should be using IPsec.
2253 * outbound policy is not checked currently.
2255 if (sp_in
->policy
!= IPSEC_POLICY_IPSEC
) {
2256 plog(LLV_ERROR
, LOCATION
, NULL
,
2257 "policy found, but no IPsec required: %s\n",
2259 return ISAKMP_INTERNAL_ERROR
;
2262 /* set new proposal derived from a policy into the iph2->proposal. */
2263 if (set_proposal_from_policy(iph2
, sp_in
, sp_out
) < 0) {
2264 plog(LLV_ERROR
, LOCATION
, NULL
,
2265 "failed to create saprop.\n");
2266 return ISAKMP_INTERNAL_ERROR
;