1 /* $KAME: isakmp_base.c,v 1.48 2001/12/12 15:29:13 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 /* Base Exchange (Base Mode) */
34 #include <sys/types.h>
35 #include <sys/param.h>
41 #if TIME_WITH_SYS_TIME
42 # include <sys/time.h>
46 # include <sys/time.h>
60 #include "localconf.h"
61 #include "remoteconf.h"
62 #include "isakmp_var.h"
66 #include "ipsec_doi.h"
67 #include "crypto_openssl.h"
69 #include "isakmp_base.h"
70 #include "isakmp_inf.h"
74 * begin Identity Protection Mode as initiator.
78 * psk: HDR, SA, Idii, Ni_b
79 * sig: HDR, SA, Idii, Ni_b
80 * rsa: HDR, SA, [HASH(1),] <IDii_b>Pubkey_r, <Ni_b>Pubkey_r
81 * rev: HDR, SA, [HASH(1),] <Ni_b>Pubkey_r, <IDii_b>Ke_i
84 base_i1send(iph1
, msg
)
85 struct ph1handle
*iph1
;
86 vchar_t
*msg
; /* must be null */
88 struct isakmp_gen
*gen
;
95 plog(LLV_ERROR
, LOCATION
, NULL
,
96 "msg has to be NULL in this function.\n");
99 if (iph1
->status
!= PHASE1ST_START
) {
100 plog(LLV_ERROR
, LOCATION
, NULL
,
101 "status mismatched %d.\n", iph1
->status
);
105 /* create isakmp index */
106 memset(&iph1
->index
, 0, sizeof(iph1
->index
));
107 isakmp_newcookie((caddr_t
)&iph1
->index
, iph1
->remote
, iph1
->local
);
109 /* make ID payload into isakmp status */
110 if (ipsecdoi_setid1(iph1
) < 0)
113 /* create SA payload for my proposal */
114 iph1
->sa
= ipsecdoi_setph1proposal(iph1
->rmconf
->proposal
);
115 if (iph1
->sa
== NULL
)
118 /* generate NONCE value */
119 iph1
->nonce
= eay_set_random(iph1
->rmconf
->nonce_size
);
120 if (iph1
->nonce
== NULL
)
123 /* create buffer to send isakmp payload */
124 tlen
= sizeof(struct isakmp
)
125 + sizeof(*gen
) + iph1
->sa
->l
126 + sizeof(*gen
) + iph1
->id
->l
127 + sizeof(*gen
) + iph1
->nonce
->l
;
129 iph1
->sendbuf
= vmalloc(tlen
);
130 if (iph1
->sendbuf
== NULL
) {
131 plog(LLV_ERROR
, LOCATION
, NULL
,
132 "failed to get buffer to send.\n");
136 /* set isakmp header */
137 p
= set_isakmp_header(iph1
->sendbuf
, iph1
, ISAKMP_NPTYPE_SA
);
141 /* set SA payload to propose */
142 p
= set_isakmp_payload(p
, iph1
->sa
, ISAKMP_NPTYPE_ID
);
144 /* create isakmp ID payload */
145 p
= set_isakmp_payload(p
, iph1
->id
, ISAKMP_NPTYPE_NONCE
);
147 /* create isakmp NONCE payload */
148 p
= set_isakmp_payload(p
, iph1
->nonce
, ISAKMP_NPTYPE_NONE
);
150 #ifdef HAVE_PRINT_ISAKMP_C
151 isakmp_printpacket(iph1
->sendbuf
, iph1
->local
, iph1
->remote
, 0);
154 /* send the packet, add to the schedule to resend */
155 iph1
->retry_counter
= iph1
->rmconf
->retry_counter
;
156 if (isakmp_ph1resend(iph1
) == -1)
159 iph1
->status
= PHASE1ST_MSG1SENT
;
169 * receive from responder
170 * psk: HDR, SA, Idir, Nr_b
171 * sig: HDR, SA, Idir, Nr_b, [ CR ]
172 * rsa: HDR, SA, <IDir_b>PubKey_i, <Nr_b>PubKey_i
173 * rev: HDR, SA, <Nr_b>PubKey_i, <IDir_b>Ke_r
176 base_i2recv(iph1
, msg
)
177 struct ph1handle
*iph1
;
180 vchar_t
*pbuf
= NULL
;
181 struct isakmp_parse_t
*pa
;
182 vchar_t
*satmp
= NULL
;
186 if (iph1
->status
!= PHASE1ST_MSG1SENT
) {
187 plog(LLV_ERROR
, LOCATION
, NULL
,
188 "status mismatched %d.\n", iph1
->status
);
192 /* validate the type of next payload */
193 pbuf
= isakmp_parse(msg
);
196 pa
= (struct isakmp_parse_t
*)pbuf
->v
;
198 /* SA payload is fixed postion */
199 if (pa
->type
!= ISAKMP_NPTYPE_SA
) {
200 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
201 "received invalid next payload type %d, "
203 pa
->type
, ISAKMP_NPTYPE_SA
);
206 if (isakmp_p2ph(&satmp
, pa
->ptr
) < 0)
211 pa
->type
!= ISAKMP_NPTYPE_NONE
;
215 case ISAKMP_NPTYPE_NONCE
:
216 if (isakmp_p2ph(&iph1
->nonce_p
, pa
->ptr
) < 0)
219 case ISAKMP_NPTYPE_ID
:
220 if (isakmp_p2ph(&iph1
->id_p
, pa
->ptr
) < 0)
223 case ISAKMP_NPTYPE_VID
:
224 (void)check_vendorid(pa
->ptr
);
227 /* don't send information, see ident_r1recv() */
228 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
229 "ignore the packet, "
230 "received unexpecting payload type %d.\n",
236 if (iph1
->nonce_p
== NULL
|| iph1
->id_p
== NULL
) {
237 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
238 "few isakmp message received.\n");
242 /* verify identifier */
243 if (ipsecdoi_checkid1(iph1
) != 0) {
244 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
245 "invalid ID payload.\n");
249 /* check SA payload and set approval SA for use */
250 if (ipsecdoi_checkph1proposal(satmp
, iph1
) < 0) {
251 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
252 "failed to get valid proposal.\n");
253 /* XXX send information */
261 iph1
->status
= PHASE1ST_MSG2RECEIVED
;
272 VPTRINIT(iph1
->nonce_p
);
273 VPTRINIT(iph1
->id_p
);
281 * psk: HDR, KE, HASH_I
282 * sig: HDR, KE, [ CR, ] [CERT,] SIG_I
283 * rsa: HDR, KE, HASH_I
284 * rev: HDR, <KE>Ke_i, HASH_I
287 base_i2send(iph1
, msg
)
288 struct ph1handle
*iph1
;
291 struct isakmp_gen
*gen
;
299 if (iph1
->status
!= PHASE1ST_MSG2RECEIVED
) {
300 plog(LLV_ERROR
, LOCATION
, NULL
,
301 "status mismatched %d.\n", iph1
->status
);
305 /* fix isakmp index */
306 memcpy(&iph1
->index
.r_ck
, &((struct isakmp
*)msg
->v
)->r_ck
,
309 /* generate DH public value */
310 if (oakley_dh_generate(iph1
->approval
->dhgrp
,
311 &iph1
->dhpub
, &iph1
->dhpriv
) < 0)
314 /* generate SKEYID to compute hash if not signature mode */
315 if (iph1
->approval
->authmethod
!= OAKLEY_ATTR_AUTH_METHOD_RSASIG
316 && iph1
->approval
->authmethod
!= OAKLEY_ATTR_AUTH_METHOD_DSSSIG
) {
317 if (oakley_skeyid(iph1
) < 0)
321 /* generate HASH to send */
322 plog(LLV_DEBUG
, LOCATION
, NULL
, "generate HASH_I\n");
323 iph1
->hash
= oakley_ph1hash_base_i(iph1
, GENERATE
);
324 if (iph1
->hash
== NULL
)
327 /* create buffer to send isakmp payload */
328 tlen
= sizeof(struct isakmp
);
330 switch (iph1
->approval
->authmethod
) {
331 case OAKLEY_ATTR_AUTH_METHOD_PSKEY
:
332 tlen
+= sizeof(*gen
) + iph1
->dhpub
->l
333 + sizeof(*gen
) + iph1
->hash
->l
;
334 if ((vid
= set_vendorid(iph1
->approval
->vendorid
)) != NULL
)
335 tlen
+= sizeof(*gen
) + vid
->l
;
337 iph1
->sendbuf
= vmalloc(tlen
);
338 if (iph1
->sendbuf
== NULL
) {
339 plog(LLV_ERROR
, LOCATION
, NULL
,
340 "failed to get buffer to send.\n");
344 /* set isakmp header */
345 p
= set_isakmp_header(iph1
->sendbuf
, iph1
, ISAKMP_NPTYPE_KE
);
349 /* create isakmp KE payload */
350 p
= set_isakmp_payload(p
, iph1
->dhpub
, ISAKMP_NPTYPE_HASH
);
352 /* create isakmp HASH payload */
353 p
= set_isakmp_payload(p
, iph1
->hash
,
354 vid
? ISAKMP_NPTYPE_VID
: ISAKMP_NPTYPE_NONE
);
356 /* append vendor id, if needed */
358 p
= set_isakmp_payload(p
, vid
, ISAKMP_NPTYPE_NONE
);
360 #ifdef HAVE_SIGNING_C
361 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG
:
362 case OAKLEY_ATTR_AUTH_METHOD_RSASIG
:
363 /* XXX if there is CR or not ? */
365 if (oakley_getmycert(iph1
) < 0)
368 if (oakley_getsign(iph1
) < 0)
371 if (iph1
->cert
&& iph1
->rmconf
->send_cert
)
374 tlen
+= sizeof(*gen
) + iph1
->dhpub
->l
375 + sizeof(*gen
) + iph1
->sig
->l
;
377 tlen
+= sizeof(*gen
) + iph1
->cert
->pl
->l
;
379 iph1
->sendbuf
= vmalloc(tlen
);
380 if (iph1
->sendbuf
== NULL
) {
381 plog(LLV_ERROR
, LOCATION
, NULL
,
382 "failed to get buffer to send.\n");
386 /* set isakmp header */
387 p
= set_isakmp_header(iph1
->sendbuf
, iph1
, ISAKMP_NPTYPE_KE
);
391 /* create isakmp KE payload */
392 p
= set_isakmp_payload(p
, iph1
->dhpub
, need_cert
394 : ISAKMP_NPTYPE_SIG
);
396 /* add CERT payload if there */
398 p
= set_isakmp_payload(p
, iph1
->cert
->pl
, ISAKMP_NPTYPE_SIG
);
399 /* add SIG payload */
400 p
= set_isakmp_payload(p
, iph1
->sig
, ISAKMP_NPTYPE_NONE
);
403 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB
:
406 case OAKLEY_ATTR_AUTH_METHOD_RSAENC
:
407 case OAKLEY_ATTR_AUTH_METHOD_RSAREV
:
408 tlen
+= sizeof(*gen
) + iph1
->hash
->l
;
412 #ifdef HAVE_PRINT_ISAKMP_C
413 isakmp_printpacket(iph1
->sendbuf
, iph1
->local
, iph1
->remote
, 0);
416 /* send the packet, add to the schedule to resend */
417 iph1
->retry_counter
= iph1
->rmconf
->retry_counter
;
418 if (isakmp_ph1resend(iph1
) == -1)
421 /* the sending message is added to the received-list. */
422 if (add_recvdpkt(iph1
->remote
, iph1
->local
, iph1
->sendbuf
, msg
) == -1) {
423 plog(LLV_ERROR
, LOCATION
, NULL
,
424 "failed to add a response packet to the tree.\n");
428 iph1
->status
= PHASE1ST_MSG2SENT
;
439 * receive from responder
440 * psk: HDR, KE, HASH_R
441 * sig: HDR, KE, [CERT,] SIG_R
442 * rsa: HDR, KE, HASH_R
443 * rev: HDR, <KE>_Ke_r, HASH_R
446 base_i3recv(iph1
, msg
)
447 struct ph1handle
*iph1
;
450 vchar_t
*pbuf
= NULL
;
451 struct isakmp_parse_t
*pa
;
455 if (iph1
->status
!= PHASE1ST_MSG2SENT
) {
456 plog(LLV_ERROR
, LOCATION
, NULL
,
457 "status mismatched %d.\n", iph1
->status
);
461 /* validate the type of next payload */
462 pbuf
= isakmp_parse(msg
);
466 for (pa
= (struct isakmp_parse_t
*)pbuf
->v
;
467 pa
->type
!= ISAKMP_NPTYPE_NONE
;
471 case ISAKMP_NPTYPE_KE
:
472 if (isakmp_p2ph(&iph1
->dhpub_p
, pa
->ptr
) < 0)
475 case ISAKMP_NPTYPE_HASH
:
476 iph1
->pl_hash
= (struct isakmp_pl_hash
*)pa
->ptr
;
478 #ifdef HAVE_SIGNING_C
479 case ISAKMP_NPTYPE_CERT
:
480 if (oakley_savecert(iph1
, pa
->ptr
) < 0)
483 case ISAKMP_NPTYPE_SIG
:
484 if (isakmp_p2ph(&iph1
->sig_p
, pa
->ptr
) < 0)
488 case ISAKMP_NPTYPE_VID
:
489 (void)check_vendorid(pa
->ptr
);
492 /* don't send information, see ident_r1recv() */
493 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
494 "ignore the packet, "
495 "received unexpecting payload type %d.\n",
501 /* payload existency check */
502 /* validate authentication value */
505 type
= oakley_validate_auth(iph1
);
508 /* message printed inner oakley_validate_auth() */
511 isakmp_info_send_n1(iph1
, type
, NULL
);
516 /* compute sharing secret of DH */
517 if (oakley_dh_compute(iph1
->approval
->dhgrp
, iph1
->dhpub
,
518 iph1
->dhpriv
, iph1
->dhpub_p
, &iph1
->dhgxy
) < 0)
521 /* generate SKEYID to compute hash if signature mode */
522 if (iph1
->approval
->authmethod
== OAKLEY_ATTR_AUTH_METHOD_RSASIG
523 || iph1
->approval
->authmethod
== OAKLEY_ATTR_AUTH_METHOD_DSSSIG
) {
524 if (oakley_skeyid(iph1
) < 0)
528 /* generate SKEYIDs & IV & final cipher key */
529 if (oakley_skeyid_dae(iph1
) < 0)
531 if (oakley_compute_enckey(iph1
) < 0)
533 if (oakley_newiv(iph1
) < 0)
536 /* see handler.h about IV synchronization. */
537 memcpy(iph1
->ivm
->iv
->v
, iph1
->ivm
->ive
->v
, iph1
->ivm
->iv
->l
);
539 /* set encryption flag */
540 iph1
->flags
|= ISAKMP_FLAG_E
;
542 iph1
->status
= PHASE1ST_MSG3RECEIVED
;
551 VPTRINIT(iph1
->dhpub_p
);
552 oakley_delcert(iph1
->cert_p
);
554 oakley_delcert(iph1
->crl_p
);
556 VPTRINIT(iph1
->sig_p
);
563 * status update and establish isakmp sa.
566 base_i3send(iph1
, msg
)
567 struct ph1handle
*iph1
;
573 if (iph1
->status
!= PHASE1ST_MSG3RECEIVED
) {
574 plog(LLV_ERROR
, LOCATION
, NULL
,
575 "status mismatched %d.\n", iph1
->status
);
579 iph1
->status
= PHASE1ST_ESTABLISHED
;
588 * receive from initiator
589 * psk: HDR, SA, Idii, Ni_b
590 * sig: HDR, SA, Idii, Ni_b
591 * rsa: HDR, SA, [HASH(1),] <IDii_b>Pubkey_r, <Ni_b>Pubkey_r
592 * rev: HDR, SA, [HASH(1),] <Ni_b>Pubkey_r, <IDii_b>Ke_i
595 base_r1recv(iph1
, msg
)
596 struct ph1handle
*iph1
;
599 vchar_t
*pbuf
= NULL
;
600 struct isakmp_parse_t
*pa
;
604 if (iph1
->status
!= PHASE1ST_START
) {
605 plog(LLV_ERROR
, LOCATION
, NULL
,
606 "status mismatched %d.\n", iph1
->status
);
610 /* validate the type of next payload */
612 * NOTE: XXX even if multiple VID, we'll silently ignore those.
614 pbuf
= isakmp_parse(msg
);
617 pa
= (struct isakmp_parse_t
*)pbuf
->v
;
619 /* check the position of SA payload */
620 if (pa
->type
!= ISAKMP_NPTYPE_SA
) {
621 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
622 "received invalid next payload type %d, "
624 pa
->type
, ISAKMP_NPTYPE_SA
);
627 if (isakmp_p2ph(&iph1
->sa
, pa
->ptr
) < 0)
632 pa
->type
!= ISAKMP_NPTYPE_NONE
;
636 case ISAKMP_NPTYPE_NONCE
:
637 if (isakmp_p2ph(&iph1
->nonce_p
, pa
->ptr
) < 0)
640 case ISAKMP_NPTYPE_ID
:
641 if (isakmp_p2ph(&iph1
->id_p
, pa
->ptr
) < 0)
644 case ISAKMP_NPTYPE_VID
:
645 (void)check_vendorid(pa
->ptr
);
648 /* don't send information, see ident_r1recv() */
649 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
650 "ignore the packet, "
651 "received unexpecting payload type %d.\n",
657 if (iph1
->nonce_p
== NULL
|| iph1
->id_p
== NULL
) {
658 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
659 "few isakmp message received.\n");
663 /* verify identifier */
664 if (ipsecdoi_checkid1(iph1
) != 0) {
665 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
666 "invalid ID payload.\n");
670 /* check SA payload and set approval SA for use */
671 if (ipsecdoi_checkph1proposal(iph1
->sa
, iph1
) < 0) {
672 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
673 "failed to get valid proposal.\n");
674 /* XXX send information */
678 iph1
->status
= PHASE1ST_MSG1RECEIVED
;
688 VPTRINIT(iph1
->nonce_p
);
689 VPTRINIT(iph1
->id_p
);
697 * psk: HDR, SA, Idir, Nr_b
698 * sig: HDR, SA, Idir, Nr_b, [ CR ]
699 * rsa: HDR, SA, <IDir_b>PubKey_i, <Nr_b>PubKey_i
700 * rev: HDR, SA, <Nr_b>PubKey_i, <IDir_b>Ke_r
703 base_r1send(iph1
, msg
)
704 struct ph1handle
*iph1
;
707 struct isakmp_gen
*gen
;
713 if (iph1
->status
!= PHASE1ST_MSG1RECEIVED
) {
714 plog(LLV_ERROR
, LOCATION
, NULL
,
715 "status mismatched %d.\n", iph1
->status
);
719 /* set responder's cookie */
720 isakmp_newcookie((caddr_t
)&iph1
->index
.r_ck
, iph1
->remote
, iph1
->local
);
722 /* make ID payload into isakmp status */
723 if (ipsecdoi_setid1(iph1
) < 0)
726 /* generate NONCE value */
727 iph1
->nonce
= eay_set_random(iph1
->rmconf
->nonce_size
);
728 if (iph1
->nonce
== NULL
)
731 /* create buffer to send isakmp payload */
732 tlen
= sizeof(struct isakmp
)
733 + sizeof(*gen
) + iph1
->sa_ret
->l
734 + sizeof(*gen
) + iph1
->id
->l
735 + sizeof(*gen
) + iph1
->nonce
->l
;
737 iph1
->sendbuf
= vmalloc(tlen
);
738 if (iph1
->sendbuf
== NULL
) {
739 plog(LLV_ERROR
, LOCATION
, NULL
,
740 "failed to get buffer to send.\n");
744 /* set isakmp header */
745 p
= set_isakmp_header(iph1
->sendbuf
, iph1
, ISAKMP_NPTYPE_SA
);
749 /* set SA payload to reply */
750 p
= set_isakmp_payload(p
, iph1
->sa_ret
, ISAKMP_NPTYPE_ID
);
752 /* create isakmp ID payload */
753 p
= set_isakmp_payload(p
, iph1
->id
, ISAKMP_NPTYPE_NONCE
);
755 /* create isakmp NONCE payload */
756 p
= set_isakmp_payload(p
, iph1
->nonce
, ISAKMP_NPTYPE_NONE
);
758 #ifdef HAVE_PRINT_ISAKMP_C
759 isakmp_printpacket(iph1
->sendbuf
, iph1
->local
, iph1
->remote
, 0);
762 /* send the packet, add to the schedule to resend */
763 iph1
->retry_counter
= iph1
->rmconf
->retry_counter
;
764 if (isakmp_ph1resend(iph1
) == -1)
767 /* the sending message is added to the received-list. */
768 if (add_recvdpkt(iph1
->remote
, iph1
->local
, iph1
->sendbuf
, msg
) == -1) {
769 plog(LLV_ERROR
, LOCATION
, NULL
,
770 "failed to add a response packet to the tree.\n");
774 iph1
->status
= PHASE1ST_MSG1SENT
;
788 * receive from initiator
789 * psk: HDR, KE, HASH_I
790 * sig: HDR, KE, [ CR, ] [CERT,] SIG_I
791 * rsa: HDR, KE, HASH_I
792 * rev: HDR, <KE>Ke_i, HASH_I
795 base_r2recv(iph1
, msg
)
796 struct ph1handle
*iph1
;
799 vchar_t
*pbuf
= NULL
;
800 struct isakmp_parse_t
*pa
;
804 if (iph1
->status
!= PHASE1ST_MSG1SENT
) {
805 plog(LLV_ERROR
, LOCATION
, NULL
,
806 "status mismatched %d.\n", iph1
->status
);
810 /* validate the type of next payload */
811 pbuf
= isakmp_parse(msg
);
815 iph1
->pl_hash
= NULL
;
817 for (pa
= (struct isakmp_parse_t
*)pbuf
->v
;
818 pa
->type
!= ISAKMP_NPTYPE_NONE
;
822 case ISAKMP_NPTYPE_KE
:
823 if (isakmp_p2ph(&iph1
->dhpub_p
, pa
->ptr
) < 0)
826 case ISAKMP_NPTYPE_HASH
:
827 iph1
->pl_hash
= (struct isakmp_pl_hash
*)pa
->ptr
;
829 #ifdef HAVE_SIGNING_C
830 case ISAKMP_NPTYPE_CERT
:
831 if (oakley_savecert(iph1
, pa
->ptr
) < 0)
834 case ISAKMP_NPTYPE_SIG
:
835 if (isakmp_p2ph(&iph1
->sig_p
, pa
->ptr
) < 0)
839 case ISAKMP_NPTYPE_VID
:
840 (void)check_vendorid(pa
->ptr
);
843 /* don't send information, see ident_r1recv() */
844 plog(LLV_ERROR
, LOCATION
, iph1
->remote
,
845 "ignore the packet, "
846 "received unexpecting payload type %d.\n",
852 /* generate DH public value */
853 if (oakley_dh_generate(iph1
->approval
->dhgrp
,
854 &iph1
->dhpub
, &iph1
->dhpriv
) < 0)
857 /* compute sharing secret of DH */
858 if (oakley_dh_compute(iph1
->approval
->dhgrp
, iph1
->dhpub
,
859 iph1
->dhpriv
, iph1
->dhpub_p
, &iph1
->dhgxy
) < 0)
862 /* generate SKEYID */
863 if (oakley_skeyid(iph1
) < 0)
866 /* payload existency check */
867 /* validate authentication value */
870 type
= oakley_validate_auth(iph1
);
873 /* message printed inner oakley_validate_auth() */
876 isakmp_info_send_n1(iph1
, type
, NULL
);
881 iph1
->status
= PHASE1ST_MSG2RECEIVED
;
890 VPTRINIT(iph1
->dhpub_p
);
891 oakley_delcert(iph1
->cert_p
);
893 oakley_delcert(iph1
->crl_p
);
895 VPTRINIT(iph1
->sig_p
);
903 * psk: HDR, KE, HASH_R
904 * sig: HDR, KE, [CERT,] SIG_R
905 * rsa: HDR, KE, HASH_R
906 * rev: HDR, <KE>_Ke_r, HASH_R
909 base_r2send(iph1
, msg
)
910 struct ph1handle
*iph1
;
913 struct isakmp_gen
*gen
;
921 if (iph1
->status
!= PHASE1ST_MSG2RECEIVED
) {
922 plog(LLV_ERROR
, LOCATION
, NULL
,
923 "status mismatched %d.\n", iph1
->status
);
927 /* generate HASH to send */
928 plog(LLV_DEBUG
, LOCATION
, NULL
, "generate HASH_I\n");
929 switch (iph1
->approval
->authmethod
) {
930 case OAKLEY_ATTR_AUTH_METHOD_PSKEY
:
931 case OAKLEY_ATTR_AUTH_METHOD_RSAENC
:
932 case OAKLEY_ATTR_AUTH_METHOD_RSAREV
:
933 iph1
->hash
= oakley_ph1hash_common(iph1
, GENERATE
);
935 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG
:
936 case OAKLEY_ATTR_AUTH_METHOD_RSASIG
:
937 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB
:
938 iph1
->hash
= oakley_ph1hash_base_r(iph1
, GENERATE
);
941 plog(LLV_ERROR
, LOCATION
, NULL
,
942 "invalid authentication method %d\n",
943 iph1
->approval
->authmethod
);
946 if (iph1
->hash
== NULL
)
949 /* create HDR;KE;NONCE payload */
950 tlen
= sizeof(struct isakmp
);
952 switch (iph1
->approval
->authmethod
) {
953 case OAKLEY_ATTR_AUTH_METHOD_PSKEY
:
954 tlen
+= sizeof(*gen
) + iph1
->dhpub
->l
955 + sizeof(*gen
) + iph1
->hash
->l
;
956 if ((vid
= set_vendorid(iph1
->approval
->vendorid
)) != NULL
)
957 tlen
+= sizeof(*gen
) + vid
->l
;
959 iph1
->sendbuf
= vmalloc(tlen
);
960 if (iph1
->sendbuf
== NULL
) {
961 plog(LLV_ERROR
, LOCATION
, NULL
,
962 "failed to get iph1->sendbuf to send.\n");
966 /* set isakmp header */
967 p
= set_isakmp_header(iph1
->sendbuf
, iph1
, ISAKMP_NPTYPE_KE
);
971 /* create isakmp KE payload */
972 p
= set_isakmp_payload(p
, iph1
->dhpub
, ISAKMP_NPTYPE_HASH
);
974 /* create isakmp HASH payload */
975 p
= set_isakmp_payload(p
, iph1
->hash
,
976 vid
? ISAKMP_NPTYPE_VID
: ISAKMP_NPTYPE_NONE
);
978 /* append vendor id, if needed */
980 p
= set_isakmp_payload(p
, vid
, ISAKMP_NPTYPE_NONE
);
982 #ifdef HAVE_SIGNING_C
983 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG
:
984 case OAKLEY_ATTR_AUTH_METHOD_RSASIG
:
985 /* XXX if there is CR or not ? */
987 if (oakley_getmycert(iph1
) < 0)
990 if (oakley_getsign(iph1
) < 0)
993 if (iph1
->cert
&& iph1
->rmconf
->send_cert
)
996 tlen
+= sizeof(*gen
) + iph1
->dhpub
->l
997 + sizeof(*gen
) + iph1
->sig
->l
;
999 tlen
+= sizeof(*gen
) + iph1
->cert
->pl
->l
;
1001 iph1
->sendbuf
= vmalloc(tlen
);
1002 if (iph1
->sendbuf
== NULL
) {
1003 plog(LLV_ERROR
, LOCATION
, NULL
,
1004 "failed to get buffer to send.\n");
1008 /* set isakmp header */
1009 p
= set_isakmp_header(iph1
->sendbuf
, iph1
, ISAKMP_NPTYPE_KE
);
1013 /* create isakmp KE payload */
1014 p
= set_isakmp_payload(p
, iph1
->dhpub
, need_cert
1015 ? ISAKMP_NPTYPE_CERT
1016 : ISAKMP_NPTYPE_SIG
);
1018 /* add CERT payload if there */
1020 p
= set_isakmp_payload(p
, iph1
->cert
->pl
, ISAKMP_NPTYPE_SIG
);
1021 /* add SIG payload */
1022 p
= set_isakmp_payload(p
, iph1
->sig
, ISAKMP_NPTYPE_NONE
);
1025 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB
:
1028 case OAKLEY_ATTR_AUTH_METHOD_RSAENC
:
1029 case OAKLEY_ATTR_AUTH_METHOD_RSAREV
:
1030 tlen
+= sizeof(*gen
) + iph1
->hash
->l
;
1034 #ifdef HAVE_PRINT_ISAKMP_C
1035 isakmp_printpacket(iph1
->sendbuf
, iph1
->local
, iph1
->remote
, 0);
1038 /* send HDR;KE;NONCE to responder */
1039 if (isakmp_send(iph1
, iph1
->sendbuf
) < 0)
1042 /* the sending message is added to the received-list. */
1043 if (add_recvdpkt(iph1
->remote
, iph1
->local
, iph1
->sendbuf
, msg
) == -1) {
1044 plog(LLV_ERROR
, LOCATION
, NULL
,
1045 "failed to add a response packet to the tree.\n");
1049 /* generate SKEYIDs & IV & final cipher key */
1050 if (oakley_skeyid_dae(iph1
) < 0)
1052 if (oakley_compute_enckey(iph1
) < 0)
1054 if (oakley_newiv(iph1
) < 0)
1057 /* set encryption flag */
1058 iph1
->flags
|= ISAKMP_FLAG_E
;
1060 iph1
->status
= PHASE1ST_ESTABLISHED
;