1 /* $KAME: isakmp_base.c,v 1.49 2003/11/13 02:30:20 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) */
36 #include <sys/types.h>
37 #include <sys/param.h>
43 #if TIME_WITH_SYS_TIME
44 # include <sys/time.h>
48 # include <sys/time.h>
62 #include "localconf.h"
63 #include "remoteconf.h"
64 #include "isakmp_var.h"
69 #include "ipsec_doi.h"
70 #include "crypto_openssl.h"
72 #include "isakmp_base.h"
73 #include "isakmp_inf.h"
76 #include "nattraversal.h"
79 #include "isakmp_frag.h"
83 * begin Identity Protection Mode as initiator.
87 * psk: HDR, SA, Idii, Ni_b
88 * sig: HDR, SA, Idii, Ni_b
89 * rsa: HDR, SA, [HASH(1),] <IDii_b>Pubkey_r, <Ni_b>Pubkey_r
90 * rev: HDR, SA, [HASH(1),] <Ni_b>Pubkey_r, <IDii_b>Ke_i
93 base_i1send(iph1, msg)
94 struct ph1handle *iph1;
95 vchar_t *msg; /* must be null */
97 struct payload_list *plist = NULL;
100 vchar_t *vid_natt[MAX_NATT_VID_COUNT];
101 int i, vid_natt_i = 0;
104 vchar_t *vid_frag = NULL;
109 plog(LLV_ERROR, LOCATION, NULL,
110 "msg has to be NULL in this function.\n");
113 if (iph1->status != PHASE1ST_START) {
114 plog(LLV_ERROR, LOCATION, NULL,
115 "status mismatched %d.\n", iph1->status);
119 /* create isakmp index */
120 memset(&iph1->index, 0, sizeof(iph1->index));
121 isakmp_newcookie((caddr_t)&iph1->index, iph1->remote, iph1->local);
123 /* make ID payload into isakmp status */
124 if (ipsecdoi_setid1(iph1) < 0)
127 /* create SA payload for my proposal */
128 iph1->sa = ipsecdoi_setph1proposal(iph1->rmconf->proposal);
129 if (iph1->sa == NULL)
132 /* generate NONCE value */
133 iph1->nonce = eay_set_random(iph1->rmconf->nonce_size);
134 if (iph1->nonce == NULL)
138 if (iph1->rmconf->ike_frag) {
139 vid_frag = set_vendorid(VENDORID_FRAG);
140 if (vid_frag != NULL)
141 vid_frag = isakmp_frag_addcap(vid_frag,
143 if (vid_frag == NULL)
144 plog(LLV_ERROR, LOCATION, NULL,
145 "Frag vendorID construction failed\n");
149 /* Is NAT-T support allowed in the config file? */
150 if (iph1->rmconf->nat_traversal) {
151 /* Advertise NAT-T capability */
152 memset (vid_natt, 0, sizeof (vid_natt));
153 #ifdef VENDORID_NATT_00
154 if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_00)) != NULL)
157 #ifdef VENDORID_NATT_02
158 if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_02)) != NULL)
161 #ifdef VENDORID_NATT_02_N
162 if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_02_N)) != NULL)
165 #ifdef VENDORID_NATT_RFC
166 if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_RFC)) != NULL)
172 /* set SA payload to propose */
173 plist = isakmp_plist_append(plist, iph1->sa, ISAKMP_NPTYPE_SA);
175 /* create isakmp ID payload */
176 plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID);
178 /* create isakmp NONCE payload */
179 plist = isakmp_plist_append(plist, iph1->nonce, ISAKMP_NPTYPE_NONCE);
183 plist = isakmp_plist_append(plist, vid_frag, ISAKMP_NPTYPE_VID);
186 /* set VID payload for NAT-T */
187 for (i = 0; i < vid_natt_i; i++)
188 plist = isakmp_plist_append(plist, vid_natt[i], ISAKMP_NPTYPE_VID);
190 iph1->sendbuf = isakmp_plist_set_all (&plist, iph1);
193 #ifdef HAVE_PRINT_ISAKMP_C
194 isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
197 /* send the packet, add to the schedule to resend */
198 iph1->retry_counter = iph1->rmconf->retry_counter;
199 if (isakmp_ph1resend(iph1) == -1)
202 iph1->status = PHASE1ST_MSG1SENT;
212 for (i = 0; i < vid_natt_i; i++)
220 * receive from responder
221 * psk: HDR, SA, Idir, Nr_b
222 * sig: HDR, SA, Idir, Nr_b, [ CR ]
223 * rsa: HDR, SA, <IDir_b>PubKey_i, <Nr_b>PubKey_i
224 * rev: HDR, SA, <Nr_b>PubKey_i, <IDir_b>Ke_r
227 base_i2recv(iph1, msg)
228 struct ph1handle *iph1;
231 vchar_t *pbuf = NULL;
232 struct isakmp_parse_t *pa;
233 vchar_t *satmp = NULL;
238 if (iph1->status != PHASE1ST_MSG1SENT) {
239 plog(LLV_ERROR, LOCATION, NULL,
240 "status mismatched %d.\n", iph1->status);
244 /* validate the type of next payload */
245 pbuf = isakmp_parse(msg);
248 pa = (struct isakmp_parse_t *)pbuf->v;
250 /* SA payload is fixed postion */
251 if (pa->type != ISAKMP_NPTYPE_SA) {
252 plog(LLV_ERROR, LOCATION, iph1->remote,
253 "received invalid next payload type %d, "
255 pa->type, ISAKMP_NPTYPE_SA);
258 if (isakmp_p2ph(&satmp, pa->ptr) < 0)
263 pa->type != ISAKMP_NPTYPE_NONE;
267 case ISAKMP_NPTYPE_NONCE:
268 if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0)
271 case ISAKMP_NPTYPE_ID:
272 if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0)
275 case ISAKMP_NPTYPE_VID:
276 vid_numeric = check_vendorid(pa->ptr);
278 if (iph1->rmconf->nat_traversal && natt_vendorid(vid_numeric))
279 natt_handle_vendorid(iph1, vid_numeric);
283 /* don't send information, see ident_r1recv() */
284 plog(LLV_ERROR, LOCATION, iph1->remote,
285 "ignore the packet, "
286 "received unexpecting payload type %d.\n",
292 if (iph1->nonce_p == NULL || iph1->id_p == NULL) {
293 plog(LLV_ERROR, LOCATION, iph1->remote,
294 "few isakmp message received.\n");
298 /* verify identifier */
299 if (ipsecdoi_checkid1(iph1) != 0) {
300 plog(LLV_ERROR, LOCATION, iph1->remote,
301 "invalid ID payload.\n");
306 if (NATT_AVAILABLE(iph1))
307 plog(LLV_INFO, LOCATION, iph1->remote,
308 "Selected NAT-T version: %s\n",
309 vid_string_by_id(iph1->natt_options->version));
312 /* check SA payload and set approval SA for use */
313 if (ipsecdoi_checkph1proposal(satmp, iph1) < 0) {
314 plog(LLV_ERROR, LOCATION, iph1->remote,
315 "failed to get valid proposal.\n");
316 /* XXX send information */
319 VPTRINIT(iph1->sa_ret);
321 iph1->status = PHASE1ST_MSG2RECEIVED;
332 VPTRINIT(iph1->nonce_p);
333 VPTRINIT(iph1->id_p);
341 * psk: HDR, KE, HASH_I
342 * sig: HDR, KE, [ CR, ] [CERT,] SIG_I
343 * rsa: HDR, KE, HASH_I
344 * rev: HDR, <KE>Ke_i, HASH_I
347 base_i2send(iph1, msg)
348 struct ph1handle *iph1;
351 struct payload_list *plist = NULL;
357 if (iph1->status != PHASE1ST_MSG2RECEIVED) {
358 plog(LLV_ERROR, LOCATION, NULL,
359 "status mismatched %d.\n", iph1->status);
363 /* fix isakmp index */
364 memcpy(&iph1->index.r_ck, &((struct isakmp *)msg->v)->r_ck,
367 /* generate DH public value */
368 if (oakley_dh_generate(iph1->approval->dhgrp,
369 &iph1->dhpub, &iph1->dhpriv) < 0)
372 /* generate SKEYID to compute hash if not signature mode */
373 if (iph1->approval->authmethod != OAKLEY_ATTR_AUTH_METHOD_RSASIG
374 && iph1->approval->authmethod != OAKLEY_ATTR_AUTH_METHOD_DSSSIG) {
375 if (oakley_skeyid(iph1) < 0)
379 /* generate HASH to send */
380 plog(LLV_DEBUG, LOCATION, NULL, "generate HASH_I\n");
381 iph1->hash = oakley_ph1hash_base_i(iph1, GENERATE);
382 if (iph1->hash == NULL)
385 switch (iph1->approval->authmethod) {
386 case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
387 vid = set_vendorid(iph1->approval->vendorid);
389 /* create isakmp KE payload */
390 plist = isakmp_plist_append(plist, iph1->dhpub, ISAKMP_NPTYPE_KE);
392 /* create isakmp HASH payload */
393 plist = isakmp_plist_append(plist, iph1->hash, ISAKMP_NPTYPE_HASH);
395 /* append vendor id, if needed */
397 plist = isakmp_plist_append(plist, vid, ISAKMP_NPTYPE_VID);
399 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
400 case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
401 /* XXX if there is CR or not ? */
403 if (oakley_getmycert(iph1) < 0)
406 if (oakley_getsign(iph1) < 0)
409 if (iph1->cert && iph1->rmconf->send_cert)
412 /* create isakmp KE payload */
413 plist = isakmp_plist_append(plist, iph1->dhpub, ISAKMP_NPTYPE_KE);
415 /* add CERT payload if there */
417 plist = isakmp_plist_append(plist, iph1->cert->pl, ISAKMP_NPTYPE_CERT);
419 /* add SIG payload */
420 plist = isakmp_plist_append(plist, iph1->sig, ISAKMP_NPTYPE_SIG);
422 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
425 case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
426 case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
431 /* generate NAT-D payloads */
432 if (NATT_AVAILABLE(iph1))
434 vchar_t *natd[2] = { NULL, NULL };
436 plog (LLV_INFO, LOCATION, NULL, "Adding remote and local NAT-D payloads.\n");
437 if ((natd[0] = natt_hash_addr (iph1, iph1->remote)) == NULL) {
438 plog(LLV_ERROR, LOCATION, NULL,
439 "NAT-D hashing failed for %s\n", saddr2str(iph1->remote));
443 if ((natd[1] = natt_hash_addr (iph1, iph1->local)) == NULL) {
444 plog(LLV_ERROR, LOCATION, NULL,
445 "NAT-D hashing failed for %s\n", saddr2str(iph1->local));
449 plist = isakmp_plist_append(plist, natd[0], iph1->natt_options->payload_nat_d);
450 plist = isakmp_plist_append(plist, natd[1], iph1->natt_options->payload_nat_d);
454 iph1->sendbuf = isakmp_plist_set_all (&plist, iph1);
456 #ifdef HAVE_PRINT_ISAKMP_C
457 isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
460 /* send the packet, add to the schedule to resend */
461 iph1->retry_counter = iph1->rmconf->retry_counter;
462 if (isakmp_ph1resend(iph1) == -1)
465 /* the sending message is added to the received-list. */
466 if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
467 plog(LLV_ERROR , LOCATION, NULL,
468 "failed to add a response packet to the tree.\n");
472 iph1->status = PHASE1ST_MSG2SENT;
483 * receive from responder
484 * psk: HDR, KE, HASH_R
485 * sig: HDR, KE, [CERT,] SIG_R
486 * rsa: HDR, KE, HASH_R
487 * rev: HDR, <KE>_Ke_r, HASH_R
490 base_i3recv(iph1, msg)
491 struct ph1handle *iph1;
494 vchar_t *pbuf = NULL;
495 struct isakmp_parse_t *pa;
499 vchar_t *natd_received;
500 int natd_seq = 0, natd_verified;
504 if (iph1->status != PHASE1ST_MSG2SENT) {
505 plog(LLV_ERROR, LOCATION, NULL,
506 "status mismatched %d.\n", iph1->status);
510 /* validate the type of next payload */
511 pbuf = isakmp_parse(msg);
515 for (pa = (struct isakmp_parse_t *)pbuf->v;
516 pa->type != ISAKMP_NPTYPE_NONE;
520 case ISAKMP_NPTYPE_KE:
521 if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0)
524 case ISAKMP_NPTYPE_HASH:
525 iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr;
527 case ISAKMP_NPTYPE_CERT:
528 if (oakley_savecert(iph1, pa->ptr) < 0)
531 case ISAKMP_NPTYPE_SIG:
532 if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0)
535 case ISAKMP_NPTYPE_VID:
536 (void)check_vendorid(pa->ptr);
540 case ISAKMP_NPTYPE_NATD_DRAFT:
541 case ISAKMP_NPTYPE_NATD_RFC:
542 if (NATT_AVAILABLE(iph1) && iph1->natt_options &&
543 pa->type == iph1->natt_options->payload_nat_d) {
544 natd_received = NULL;
545 if (isakmp_p2ph (&natd_received, pa->ptr) < 0)
548 /* set both bits first so that we can clear them
549 upon verifying hashes */
551 iph1->natt_flags |= NAT_DETECTED;
553 /* this function will clear appropriate bits bits
554 from iph1->natt_flags */
555 natd_verified = natt_compare_addr_hash (iph1,
556 natd_received, natd_seq++);
558 plog (LLV_INFO, LOCATION, NULL, "NAT-D payload #%d %s\n",
560 natd_verified ? "verified" : "doesn't match");
562 vfree (natd_received);
565 /* passthrough to default... */
569 /* don't send information, see ident_r1recv() */
570 plog(LLV_ERROR, LOCATION, iph1->remote,
571 "ignore the packet, "
572 "received unexpecting payload type %d.\n",
579 if (NATT_AVAILABLE(iph1)) {
580 plog (LLV_INFO, LOCATION, NULL, "NAT %s %s%s\n",
581 iph1->natt_flags & NAT_DETECTED ?
582 "detected:" : "not detected",
583 iph1->natt_flags & NAT_DETECTED_ME ? "ME " : "",
584 iph1->natt_flags & NAT_DETECTED_PEER ? "PEER" : "");
585 if (iph1->natt_flags & NAT_DETECTED)
586 natt_float_ports (iph1);
590 /* payload existency check */
591 /* validate authentication value */
592 ptype = oakley_validate_auth(iph1);
595 /* message printed inner oakley_validate_auth() */
598 EVT_PUSH(iph1->local, iph1->remote,
599 EVTT_PEERPH1AUTH_FAILED, NULL);
600 isakmp_info_send_n1(iph1, ptype, NULL);
604 /* compute sharing secret of DH */
605 if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub,
606 iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0)
609 /* generate SKEYID to compute hash if signature mode */
610 if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_RSASIG
611 || iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_DSSSIG) {
612 if (oakley_skeyid(iph1) < 0)
616 /* generate SKEYIDs & IV & final cipher key */
617 if (oakley_skeyid_dae(iph1) < 0)
619 if (oakley_compute_enckey(iph1) < 0)
621 if (oakley_newiv(iph1) < 0)
624 /* see handler.h about IV synchronization. */
625 memcpy(iph1->ivm->iv->v, iph1->ivm->ive->v, iph1->ivm->iv->l);
627 /* set encryption flag */
628 iph1->flags |= ISAKMP_FLAG_E;
630 iph1->status = PHASE1ST_MSG3RECEIVED;
639 VPTRINIT(iph1->dhpub_p);
640 oakley_delcert(iph1->cert_p);
642 oakley_delcert(iph1->crl_p);
644 VPTRINIT(iph1->sig_p);
651 * status update and establish isakmp sa.
654 base_i3send(iph1, msg)
655 struct ph1handle *iph1;
661 if (iph1->status != PHASE1ST_MSG3RECEIVED) {
662 plog(LLV_ERROR, LOCATION, NULL,
663 "status mismatched %d.\n", iph1->status);
667 iph1->status = PHASE1ST_ESTABLISHED;
676 * receive from initiator
677 * psk: HDR, SA, Idii, Ni_b
678 * sig: HDR, SA, Idii, Ni_b
679 * rsa: HDR, SA, [HASH(1),] <IDii_b>Pubkey_r, <Ni_b>Pubkey_r
680 * rev: HDR, SA, [HASH(1),] <Ni_b>Pubkey_r, <IDii_b>Ke_i
683 base_r1recv(iph1, msg)
684 struct ph1handle *iph1;
687 vchar_t *pbuf = NULL;
688 struct isakmp_parse_t *pa;
693 if (iph1->status != PHASE1ST_START) {
694 plog(LLV_ERROR, LOCATION, NULL,
695 "status mismatched %d.\n", iph1->status);
699 /* validate the type of next payload */
701 * NOTE: XXX even if multiple VID, we'll silently ignore those.
703 pbuf = isakmp_parse(msg);
706 pa = (struct isakmp_parse_t *)pbuf->v;
708 /* check the position of SA payload */
709 if (pa->type != ISAKMP_NPTYPE_SA) {
710 plog(LLV_ERROR, LOCATION, iph1->remote,
711 "received invalid next payload type %d, "
713 pa->type, ISAKMP_NPTYPE_SA);
716 if (isakmp_p2ph(&iph1->sa, pa->ptr) < 0)
721 pa->type != ISAKMP_NPTYPE_NONE;
725 case ISAKMP_NPTYPE_NONCE:
726 if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0)
729 case ISAKMP_NPTYPE_ID:
730 if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0)
733 case ISAKMP_NPTYPE_VID:
734 vid_numeric = check_vendorid(pa->ptr);
736 if (iph1->rmconf->nat_traversal && natt_vendorid(vid_numeric))
737 natt_handle_vendorid(iph1, vid_numeric);
740 if ((vid_numeric == VENDORID_FRAG) &&
741 (vendorid_frag_cap(pa->ptr) & VENDORID_FRAG_BASE))
746 /* don't send information, see ident_r1recv() */
747 plog(LLV_ERROR, LOCATION, iph1->remote,
748 "ignore the packet, "
749 "received unexpecting payload type %d.\n",
755 if (iph1->nonce_p == NULL || iph1->id_p == NULL) {
756 plog(LLV_ERROR, LOCATION, iph1->remote,
757 "few isakmp message received.\n");
761 /* verify identifier */
762 if (ipsecdoi_checkid1(iph1) != 0) {
763 plog(LLV_ERROR, LOCATION, iph1->remote,
764 "invalid ID payload.\n");
769 if (NATT_AVAILABLE(iph1))
770 plog(LLV_INFO, LOCATION, iph1->remote,
771 "Selected NAT-T version: %s\n",
772 vid_string_by_id(iph1->natt_options->version));
775 /* check SA payload and set approval SA for use */
776 if (ipsecdoi_checkph1proposal(iph1->sa, iph1) < 0) {
777 plog(LLV_ERROR, LOCATION, iph1->remote,
778 "failed to get valid proposal.\n");
779 /* XXX send information */
783 iph1->status = PHASE1ST_MSG1RECEIVED;
793 VPTRINIT(iph1->nonce_p);
794 VPTRINIT(iph1->id_p);
802 * psk: HDR, SA, Idir, Nr_b
803 * sig: HDR, SA, Idir, Nr_b, [ CR ]
804 * rsa: HDR, SA, <IDir_b>PubKey_i, <Nr_b>PubKey_i
805 * rev: HDR, SA, <Nr_b>PubKey_i, <IDir_b>Ke_r
808 base_r1send(iph1, msg)
809 struct ph1handle *iph1;
812 struct payload_list *plist = NULL;
815 vchar_t *vid_natt = NULL;
819 if (iph1->status != PHASE1ST_MSG1RECEIVED) {
820 plog(LLV_ERROR, LOCATION, NULL,
821 "status mismatched %d.\n", iph1->status);
825 /* set responder's cookie */
826 isakmp_newcookie((caddr_t)&iph1->index.r_ck, iph1->remote, iph1->local);
828 /* make ID payload into isakmp status */
829 if (ipsecdoi_setid1(iph1) < 0)
832 /* generate NONCE value */
833 iph1->nonce = eay_set_random(iph1->rmconf->nonce_size);
834 if (iph1->nonce == NULL)
837 /* set SA payload to reply */
838 plist = isakmp_plist_append(plist, iph1->sa_ret, ISAKMP_NPTYPE_SA);
840 /* create isakmp ID payload */
841 plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID);
843 /* create isakmp NONCE payload */
844 plist = isakmp_plist_append(plist, iph1->nonce, ISAKMP_NPTYPE_NONCE);
847 /* has the peer announced nat-t? */
848 if (NATT_AVAILABLE(iph1))
849 vid_natt = set_vendorid(iph1->natt_options->version);
851 plist = isakmp_plist_append(plist, vid_natt, ISAKMP_NPTYPE_VID);
854 iph1->sendbuf = isakmp_plist_set_all (&plist, iph1);
856 #ifdef HAVE_PRINT_ISAKMP_C
857 isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
860 /* send the packet, add to the schedule to resend */
861 iph1->retry_counter = iph1->rmconf->retry_counter;
862 if (isakmp_ph1resend(iph1) == -1)
865 /* the sending message is added to the received-list. */
866 if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
867 plog(LLV_ERROR , LOCATION, NULL,
868 "failed to add a response packet to the tree.\n");
872 iph1->status = PHASE1ST_MSG1SENT;
882 VPTRINIT(iph1->sa_ret);
888 * receive from initiator
889 * psk: HDR, KE, HASH_I
890 * sig: HDR, KE, [ CR, ] [CERT,] SIG_I
891 * rsa: HDR, KE, HASH_I
892 * rev: HDR, <KE>Ke_i, HASH_I
895 base_r2recv(iph1, msg)
896 struct ph1handle *iph1;
899 vchar_t *pbuf = NULL;
900 struct isakmp_parse_t *pa;
908 if (iph1->status != PHASE1ST_MSG1SENT) {
909 plog(LLV_ERROR, LOCATION, NULL,
910 "status mismatched %d.\n", iph1->status);
914 /* validate the type of next payload */
915 pbuf = isakmp_parse(msg);
919 iph1->pl_hash = NULL;
921 for (pa = (struct isakmp_parse_t *)pbuf->v;
922 pa->type != ISAKMP_NPTYPE_NONE;
926 case ISAKMP_NPTYPE_KE:
927 if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0)
930 case ISAKMP_NPTYPE_HASH:
931 iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr;
933 case ISAKMP_NPTYPE_CERT:
934 if (oakley_savecert(iph1, pa->ptr) < 0)
937 case ISAKMP_NPTYPE_SIG:
938 if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0)
941 case ISAKMP_NPTYPE_VID:
942 (void)check_vendorid(pa->ptr);
946 case ISAKMP_NPTYPE_NATD_DRAFT:
947 case ISAKMP_NPTYPE_NATD_RFC:
948 if (pa->type == iph1->natt_options->payload_nat_d)
950 vchar_t *natd_received = NULL;
953 if (isakmp_p2ph (&natd_received, pa->ptr) < 0)
957 iph1->natt_flags |= NAT_DETECTED;
959 natd_verified = natt_compare_addr_hash (iph1,
960 natd_received, natd_seq++);
962 plog (LLV_INFO, LOCATION, NULL, "NAT-D payload #%d %s\n",
964 natd_verified ? "verified" : "doesn't match");
966 vfree (natd_received);
969 /* passthrough to default... */
973 /* don't send information, see ident_r1recv() */
974 plog(LLV_ERROR, LOCATION, iph1->remote,
975 "ignore the packet, "
976 "received unexpecting payload type %d.\n",
982 /* generate DH public value */
983 if (oakley_dh_generate(iph1->approval->dhgrp,
984 &iph1->dhpub, &iph1->dhpriv) < 0)
987 /* compute sharing secret of DH */
988 if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub,
989 iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0)
992 /* generate SKEYID */
993 if (oakley_skeyid(iph1) < 0)
997 if (NATT_AVAILABLE(iph1))
998 plog (LLV_INFO, LOCATION, NULL, "NAT %s %s%s\n",
999 iph1->natt_flags & NAT_DETECTED ?
1000 "detected:" : "not detected",
1001 iph1->natt_flags & NAT_DETECTED_ME ? "ME " : "",
1002 iph1->natt_flags & NAT_DETECTED_PEER ? "PEER" : "");
1005 /* payload existency check */
1006 /* validate authentication value */
1007 ptype = oakley_validate_auth(iph1);
1010 /* message printed inner oakley_validate_auth() */
1013 EVT_PUSH(iph1->local, iph1->remote,
1014 EVTT_PEERPH1AUTH_FAILED, NULL);
1015 isakmp_info_send_n1(iph1, ptype, NULL);
1019 iph1->status = PHASE1ST_MSG2RECEIVED;
1028 VPTRINIT(iph1->dhpub_p);
1029 oakley_delcert(iph1->cert_p);
1030 iph1->cert_p = NULL;
1031 oakley_delcert(iph1->crl_p);
1033 VPTRINIT(iph1->sig_p);
1041 * psk: HDR, KE, HASH_R
1042 * sig: HDR, KE, [CERT,] SIG_R
1043 * rsa: HDR, KE, HASH_R
1044 * rev: HDR, <KE>_Ke_r, HASH_R
1047 base_r2send(iph1, msg)
1048 struct ph1handle *iph1;
1051 struct payload_list *plist = NULL;
1052 vchar_t *vid = NULL;
1056 /* validity check */
1057 if (iph1->status != PHASE1ST_MSG2RECEIVED) {
1058 plog(LLV_ERROR, LOCATION, NULL,
1059 "status mismatched %d.\n", iph1->status);
1063 /* generate HASH to send */
1064 plog(LLV_DEBUG, LOCATION, NULL, "generate HASH_I\n");
1065 switch (iph1->approval->authmethod) {
1066 case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
1067 case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
1068 case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
1069 iph1->hash = oakley_ph1hash_common(iph1, GENERATE);
1071 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
1072 case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
1073 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
1074 iph1->hash = oakley_ph1hash_base_r(iph1, GENERATE);
1077 plog(LLV_ERROR, LOCATION, NULL,
1078 "invalid authentication method %d\n",
1079 iph1->approval->authmethod);
1082 if (iph1->hash == NULL)
1085 switch (iph1->approval->authmethod) {
1086 case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
1087 vid = set_vendorid(iph1->approval->vendorid);
1089 /* create isakmp KE payload */
1090 plist = isakmp_plist_append(plist, iph1->dhpub, ISAKMP_NPTYPE_KE);
1092 /* create isakmp HASH payload */
1093 plist = isakmp_plist_append(plist, iph1->hash, ISAKMP_NPTYPE_HASH);
1095 /* append vendor id, if needed */
1097 plist = isakmp_plist_append(plist, vid, ISAKMP_NPTYPE_VID);
1099 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
1100 case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
1101 /* XXX if there is CR or not ? */
1103 if (oakley_getmycert(iph1) < 0)
1106 if (oakley_getsign(iph1) < 0)
1109 if (iph1->cert && iph1->rmconf->send_cert)
1112 /* create isakmp KE payload */
1113 plist = isakmp_plist_append(plist, iph1->dhpub, ISAKMP_NPTYPE_KE);
1115 /* add CERT payload if there */
1117 plist = isakmp_plist_append(plist, iph1->cert->pl, ISAKMP_NPTYPE_CERT);
1118 /* add SIG payload */
1119 plist = isakmp_plist_append(plist, iph1->sig, ISAKMP_NPTYPE_SIG);
1121 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
1124 case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
1125 case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
1130 /* generate NAT-D payloads */
1131 if (NATT_AVAILABLE(iph1))
1133 vchar_t *natd[2] = { NULL, NULL };
1135 plog (LLV_INFO, LOCATION, NULL, "Adding remote and local NAT-D payloads.\n");
1136 if ((natd[0] = natt_hash_addr (iph1, iph1->remote)) == NULL) {
1137 plog(LLV_ERROR, LOCATION, NULL,
1138 "NAT-D hashing failed for %s\n", saddr2str(iph1->remote));
1142 if ((natd[1] = natt_hash_addr (iph1, iph1->local)) == NULL) {
1143 plog(LLV_ERROR, LOCATION, NULL,
1144 "NAT-D hashing failed for %s\n", saddr2str(iph1->local));
1148 plist = isakmp_plist_append(plist, natd[0], iph1->natt_options->payload_nat_d);
1149 plist = isakmp_plist_append(plist, natd[1], iph1->natt_options->payload_nat_d);
1153 iph1->sendbuf = isakmp_plist_set_all (&plist, iph1);
1155 #ifdef HAVE_PRINT_ISAKMP_C
1156 isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
1159 /* send HDR;KE;NONCE to responder */
1160 if (isakmp_send(iph1, iph1->sendbuf) < 0)
1163 /* the sending message is added to the received-list. */
1164 if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
1165 plog(LLV_ERROR , LOCATION, NULL,
1166 "failed to add a response packet to the tree.\n");
1170 /* generate SKEYIDs & IV & final cipher key */
1171 if (oakley_skeyid_dae(iph1) < 0)
1173 if (oakley_compute_enckey(iph1) < 0)
1175 if (oakley_newiv(iph1) < 0)
1178 /* set encryption flag */
1179 iph1->flags |= ISAKMP_FLAG_E;
1181 iph1->status = PHASE1ST_ESTABLISHED;