]> git.saurik.com Git - apple/ipsec.git/blobdiff - ipsec-tools/racoon/isakmp_agg.c
ipsec-146.3.tar.gz
[apple/ipsec.git] / ipsec-tools / racoon / isakmp_agg.c
index 7dddea3de5e4d679781b032ef3c3c849fdbd65c4..2b29675dc7861777fda6f53a0bf1fb505ec8b9e6 100644 (file)
@@ -99,6 +99,9 @@
 #include "vpn_control_var.h"
 #include "ipsecSessionTracer.h"
 #include "ipsecMessageTracer.h"
 #include "vpn_control_var.h"
 #include "ipsecSessionTracer.h"
 #include "ipsecMessageTracer.h"
+#ifndef HAVE_OPENSSL
+#include <Security/SecDH.h>
+#endif
 
 /*
  * begin Aggressive Mode as initiator.
 
 /*
  * begin Aggressive Mode as initiator.
@@ -180,8 +183,13 @@ agg_i1send(iph1, msg)
        }
 
        /* generate DH public value */
        }
 
        /* generate DH public value */
+#ifdef HAVE_OPENSSL
+       if (oakley_dh_generate(iph1->rmconf->dhgrp,
+                                                  &iph1->dhpub, &iph1->dhpriv) < 0) {  
+#else
        if (oakley_dh_generate(iph1->rmconf->dhgrp,
        if (oakley_dh_generate(iph1->rmconf->dhgrp,
-                                                  &iph1->dhpub, &iph1->dhpriv) < 0) {
+                                                  &iph1->dhpub, &iph1->publicKeySize, &iph1->dhC) < 0) {
+#endif         
                plog(LLV_ERROR, LOCATION, NULL,
                         "failed to generate DH");
                goto end;
                plog(LLV_ERROR, LOCATION, NULL,
                         "failed to generate DH");
                goto end;
@@ -383,6 +391,7 @@ agg_i2recv(iph1, msg)
 #ifdef HAVE_GSSAPI
        vchar_t *gsstoken = NULL;
 #endif
 #ifdef HAVE_GSSAPI
        vchar_t *gsstoken = NULL;
 #endif
+       int received_cert = 0;
 
 #ifdef ENABLE_NATT
        int natd_seq = 0;
 
 #ifdef ENABLE_NATT
        int natd_seq = 0;
@@ -471,6 +480,7 @@ agg_i2recv(iph1, msg)
                                         "failed to process CERT payload");
                                goto end;
                        }
                                         "failed to process CERT payload");
                                goto end;
                        }
+                       received_cert = 1;
                        break;
                case ISAKMP_NPTYPE_SIG:
                        if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0) {
                        break;
                case ISAKMP_NPTYPE_SIG:
                        if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0) {
@@ -507,6 +517,14 @@ agg_i2recv(iph1, msg)
                                plog(LLV_DEBUG, LOCATION, NULL,
                                         "remote supports DPD\n");
                        }
                                plog(LLV_DEBUG, LOCATION, NULL,
                                         "remote supports DPD\n");
                        }
+#endif
+#ifdef ENABLE_FRAG
+                       if ((vid_numeric == VENDORID_FRAG) &&
+                               (vendorid_frag_cap(pa->ptr) & VENDORID_FRAG_AGG)) {
+                               plog(LLV_DEBUG, LOCATION, NULL,
+                                        "remote supports FRAGMENTATION\n");
+                               iph1->frag = 1;
+                       }
 #endif
                        break;
                case ISAKMP_NPTYPE_N:
 #endif
                        break;
                case ISAKMP_NPTYPE_N:
@@ -526,9 +544,7 @@ agg_i2recv(iph1, msg)
 #ifdef ENABLE_NATT
                case ISAKMP_NPTYPE_NATD_DRAFT:
                case ISAKMP_NPTYPE_NATD_RFC:
 #ifdef ENABLE_NATT
                case ISAKMP_NPTYPE_NATD_DRAFT:
                case ISAKMP_NPTYPE_NATD_RFC:
-#ifdef __APPLE__
                case ISAKMP_NPTYPE_NATD_BADDRAFT:
                case ISAKMP_NPTYPE_NATD_BADDRAFT:
-#endif
                        if (NATT_AVAILABLE(iph1) && iph1->natt_options != NULL &&
                            pa->type == iph1->natt_options->payload_nat_d) {
                                struct natd_payload *natd;
                        if (NATT_AVAILABLE(iph1) && iph1->natt_options != NULL &&
                            pa->type == iph1->natt_options->payload_nat_d) {
                                struct natd_payload *natd;
@@ -567,6 +583,10 @@ agg_i2recv(iph1, msg)
                }
        }
 
                }
        }
 
+       if (received_cert) {
+               oakley_verify_certid(iph1);
+       }
+
        /* payload existency check */
        if (iph1->dhpub_p == NULL || iph1->nonce_p == NULL) {
                plog(LLV_ERROR, LOCATION, iph1->remote,
        /* payload existency check */
        if (iph1->dhpub_p == NULL || iph1->nonce_p == NULL) {
                plog(LLV_ERROR, LOCATION, iph1->remote,
@@ -631,12 +651,17 @@ agg_i2recv(iph1, msg)
 
                if (iph1->natt_flags & NAT_DETECTED)
                        natt_float_ports (iph1);
 
                if (iph1->natt_flags & NAT_DETECTED)
                        natt_float_ports (iph1);
+               ike_session_update_natt_version(iph1);
        }
 #endif
 
        /* compute sharing secret of DH */
        }
 #endif
 
        /* compute sharing secret of DH */
+#ifdef HAVE_OPENSSL
        if (oakley_dh_compute(iph1->rmconf->dhgrp, iph1->dhpub,
                                                  iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0) {
        if (oakley_dh_compute(iph1->rmconf->dhgrp, iph1->dhpub,
                                                  iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0) {
+#else
+               if (oakley_dh_compute(iph1->rmconf->dhgrp, iph1->dhpub_p, iph1->publicKeySize, &iph1->dhgxy, iph1->dhC) < 0) {
+#endif
                plog(LLV_ERROR, LOCATION, NULL,
                         "failed to compute DH");
                goto end;
                plog(LLV_ERROR, LOCATION, NULL,
                         "failed to compute DH");
                goto end;
@@ -819,6 +844,7 @@ agg_i2send(iph1, msg)
                        need_cert = 1;
 
                /* add CERT payload if there */
                        need_cert = 1;
 
                /* add CERT payload if there */
+               // we don't support sending of certchains
                if (need_cert)
                        plist = isakmp_plist_append(plist, iph1->cert->pl, ISAKMP_NPTYPE_CERT);
 
                if (need_cert)
                        plist = isakmp_plist_append(plist, iph1->cert->pl, ISAKMP_NPTYPE_CERT);
 
@@ -864,14 +890,11 @@ agg_i2send(iph1, msg)
                                "NAT-D hashing failed for %s\n", saddr2str(iph1->local));
                        goto end;
                }
                                "NAT-D hashing failed for %s\n", saddr2str(iph1->local));
                        goto end;
                }
-
-#ifdef __APPLE__
                /* old Apple version sends natd payloads in the wrong order */
                if (iph1->natt_options->version == VENDORID_NATT_APPLE) {
                        plist = isakmp_plist_append(plist, natd[1], iph1->natt_options->payload_nat_d);
                        plist = isakmp_plist_append(plist, natd[0], iph1->natt_options->payload_nat_d);
                } else
                /* old Apple version sends natd payloads in the wrong order */
                if (iph1->natt_options->version == VENDORID_NATT_APPLE) {
                        plist = isakmp_plist_append(plist, natd[1], iph1->natt_options->payload_nat_d);
                        plist = isakmp_plist_append(plist, natd[0], iph1->natt_options->payload_nat_d);
                } else
-#endif
                {
                        plist = isakmp_plist_append(plist, natd[0], iph1->natt_options->payload_nat_d);
                        plist = isakmp_plist_append(plist, natd[1], iph1->natt_options->payload_nat_d);
                {
                        plist = isakmp_plist_append(plist, natd[0], iph1->natt_options->payload_nat_d);
                        plist = isakmp_plist_append(plist, natd[1], iph1->natt_options->payload_nat_d);
@@ -896,7 +919,7 @@ agg_i2send(iph1, msg)
 
        /* the sending message is added to the received-list. */
        if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg,
 
        /* the sending message is added to the received-list. */
        if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg,
-                     PH1_NON_ESP_EXTRA_LEN(iph1)) == -1) {
+                     PH1_NON_ESP_EXTRA_LEN(iph1), PH1_FRAG_FLAGS(iph1)) == -1) {
                plog(LLV_ERROR , LOCATION, NULL,
                        "failed to add a response packet to the tree.\n");
                goto end;
                plog(LLV_ERROR , LOCATION, NULL,
                        "failed to add a response packet to the tree.\n");
                goto end;
@@ -1058,8 +1081,11 @@ agg_r1recv(iph1, msg)
 #endif
 #ifdef ENABLE_FRAG
                        if ((vid_numeric == VENDORID_FRAG) &&
 #endif
 #ifdef ENABLE_FRAG
                        if ((vid_numeric == VENDORID_FRAG) &&
-                           (vendorid_frag_cap(pa->ptr) & VENDORID_FRAG_AGG))
+                               (vendorid_frag_cap(pa->ptr) & VENDORID_FRAG_AGG)) {
+                               plog(LLV_DEBUG, LOCATION, NULL,
+                                        "remote supports FRAGMENTATION\n");
                                iph1->frag = 1;
                                iph1->frag = 1;
+                       }
 #endif
                        break;
 
 #endif
                        break;
 
@@ -1106,10 +1132,12 @@ agg_r1recv(iph1, msg)
        }
 
 #ifdef ENABLE_NATT
        }
 
 #ifdef ENABLE_NATT
-       if (NATT_AVAILABLE(iph1))
+       if (NATT_AVAILABLE(iph1)) {
                plog(LLV_INFO, LOCATION, iph1->remote,
                     "Selected NAT-T version: %s\n",
                     vid_string_by_id(iph1->natt_options->version));
                plog(LLV_INFO, LOCATION, iph1->remote,
                     "Selected NAT-T version: %s\n",
                     vid_string_by_id(iph1->natt_options->version));
+               ike_session_update_natt_version(iph1);
+       }
 #endif
 
        /* check SA payload and set approval SA for use */
 #endif
 
        /* check SA payload and set approval SA for use */
@@ -1217,8 +1245,13 @@ agg_r1send(iph1, msg)
        }
 
        /* generate DH public value */
        }
 
        /* generate DH public value */
+#ifdef HAVE_OPENSSL
+       if (oakley_dh_generate(iph1->rmconf->dhgrp,
+                                                  &iph1->dhpub, &iph1->dhpriv) < 0) {  
+#else
        if (oakley_dh_generate(iph1->rmconf->dhgrp,
        if (oakley_dh_generate(iph1->rmconf->dhgrp,
-                                                  &iph1->dhpub, &iph1->dhpriv) < 0) {
+                                                  &iph1->dhpub, &iph1->publicKeySize, &iph1->dhC) < 0) {
+#endif
                plog(LLV_ERROR, LOCATION, NULL,
                         "failed to generate DH");
                goto end;
                plog(LLV_ERROR, LOCATION, NULL,
                         "failed to generate DH");
                goto end;
@@ -1233,8 +1266,12 @@ agg_r1send(iph1, msg)
        }
 
        /* compute sharing secret of DH */
        }
 
        /* compute sharing secret of DH */
-       if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub,
-                                                 iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0) {
+#ifdef HAVE_OPENSSL
+               if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub,
+                                                         iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0) {
+#else
+       if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub_p, iph1->publicKeySize, &iph1->dhgxy, iph1->dhC) < 0) {
+#endif
                plog(LLV_ERROR, LOCATION, NULL,
                         "failed to compute DH");
                goto end;
                plog(LLV_ERROR, LOCATION, NULL,
                         "failed to compute DH");
                goto end;
@@ -1499,13 +1536,11 @@ agg_r1send(iph1, msg)
                /* chosen VID */
                plist = isakmp_plist_append(plist, vid_natt, ISAKMP_NPTYPE_VID);
                /* NAT-D */
                /* chosen VID */
                plist = isakmp_plist_append(plist, vid_natt, ISAKMP_NPTYPE_VID);
                /* NAT-D */
-#ifdef __APPLE__
                /* old Apple version sends natd payloads in the wrong order */
                if (iph1->natt_options->version == VENDORID_NATT_APPLE) {
                        plist = isakmp_plist_append(plist, natd[1], iph1->natt_options->payload_nat_d);
                        plist = isakmp_plist_append(plist, natd[0], iph1->natt_options->payload_nat_d);
                } else
                /* old Apple version sends natd payloads in the wrong order */
                if (iph1->natt_options->version == VENDORID_NATT_APPLE) {
                        plist = isakmp_plist_append(plist, natd[1], iph1->natt_options->payload_nat_d);
                        plist = isakmp_plist_append(plist, natd[0], iph1->natt_options->payload_nat_d);
                } else
-#endif
                {
                        plist = isakmp_plist_append(plist, natd[0], iph1->natt_options->payload_nat_d);
                        plist = isakmp_plist_append(plist, natd[1], iph1->natt_options->payload_nat_d);
                {
                        plist = isakmp_plist_append(plist, natd[0], iph1->natt_options->payload_nat_d);
                        plist = isakmp_plist_append(plist, natd[1], iph1->natt_options->payload_nat_d);
@@ -1539,7 +1574,7 @@ agg_r1send(iph1, msg)
 
        /* the sending message is added to the received-list. */
        if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg,
 
        /* the sending message is added to the received-list. */
        if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg,
-                     PH1_NON_ESP_EXTRA_LEN(iph1)) == -1) {
+                     PH1_NON_ESP_EXTRA_LEN(iph1), PH1_FRAG_FLAGS(iph1)) == -1) {
                plog(LLV_ERROR , LOCATION, NULL,
                        "failed to add a response packet to the tree.\n");
                goto end;
                plog(LLV_ERROR , LOCATION, NULL,
                        "failed to add a response packet to the tree.\n");
                goto end;
@@ -1623,6 +1658,7 @@ agg_r2recv(iph1, msg0)
 #ifdef ENABLE_NATT
        int natd_seq = 0;
 #endif
 #ifdef ENABLE_NATT
        int natd_seq = 0;
 #endif
+       int received_cert = 0;
 
        /* validity check */
        if (iph1->status != PHASE1ST_MSG1SENT) {
 
        /* validity check */
        if (iph1->status != PHASE1ST_MSG1SENT) {
@@ -1671,6 +1707,7 @@ agg_r2recv(iph1, msg0)
                                         "failed to process CERT payload");
                                goto end;
                        }
                                         "failed to process CERT payload");
                                goto end;
                        }
+                       received_cert = 1;
                        break;
                case ISAKMP_NPTYPE_SIG:
                        if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0) {
                        break;
                case ISAKMP_NPTYPE_SIG:
                        if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0) {
@@ -1735,6 +1772,10 @@ agg_r2recv(iph1, msg0)
                      iph1->natt_flags & NAT_DETECTED_PEER ? "PEER" : "");
 #endif
 
                      iph1->natt_flags & NAT_DETECTED_PEER ? "PEER" : "");
 #endif
 
+       if (received_cert) {
+               oakley_verify_certid(iph1);
+       }
+       
        /* validate authentication value */
        ptype = oakley_validate_auth(iph1);
        if (ptype != 0) {
        /* validate authentication value */
        ptype = oakley_validate_auth(iph1);
        if (ptype != 0) {