required CA is that.ca not this.ca
[strongswan.git] / src / pluto / ipsec_doi.c
index 216835d..1183f9c 100644 (file)
 #endif /* !VENDORID */
 
 /*
- * are we sending an XAUTH VID (Cisco Mode Config Interoperability)?
- */
-#ifdef XAUTH_VID
-#define SEND_XAUTH_VID 1
-#else /* !XAUTH_VID */
-#define SEND_XAUTH_VID 0
-#endif /* !XAUTH_VID */
-
-/*
  * are we sending a Cisco Unity VID?
  */
 #ifdef CISCO_QUIRKS
 #define SEND_CISCO_UNITY_VID   1
 #else /* !CISCO_QUIRKS */
-#define SEND_XAUTH_VID 0
+#define SEND_CISCO_UNITY_VID   0
 #endif /* !CISCO_QUIRKS */
 
 /* MAGIC: perform f, a function that returns notification_t
@@ -462,9 +453,11 @@ send_notification_from_state(struct state *st, enum state_kind state,
     if (state == STATE_UNDEFINED)
        state = st->st_state;
 
-    if (IS_QUICK(state)) {
+    if (IS_QUICK(state))
+    {
        p1st = find_phase1_state(st->st_connection, ISAKMP_SA_ESTABLISHED_STATES);
-       if ((p1st == NULL) || (!IS_ISAKMP_SA_ESTABLISHED(p1st->st_state))) {
+       if ((p1st == NULL) || (!IS_ISAKMP_SA_ESTABLISHED(p1st->st_state)))
+       {
            loglog(RC_LOG_SERIOUS,
                "no Phase1 state for Quick mode notification");
            return;
@@ -472,11 +465,13 @@ send_notification_from_state(struct state *st, enum state_kind state,
        send_notification(st, type, p1st, generate_msgid(p1st),
            st->st_icookie, st->st_rcookie, NULL, 0, PROTO_ISAKMP);
     }
-    else if (IS_ISAKMP_ENCRYPTED(state)) {
+    else if (IS_ISAKMP_ENCRYPTED(state) && st->st_enc_key.ptr != NULL)
+    {
        send_notification(st, type, st, generate_msgid(st),
            st->st_icookie, st->st_rcookie, NULL, 0, PROTO_ISAKMP);
     }
-    else {
+    else
+    {
        /* no ISAKMP SA established - don't encrypt notification */
        send_notification(st, type, NULL, 0,
            st->st_icookie, st->st_rcookie, NULL, 0, PROTO_ISAKMP);
@@ -900,12 +895,12 @@ main_outI1(int whack_sock, struct connection *c, struct state *predecessor
     /* determine how many Vendor ID payloads we will be sending */
     if (SEND_PLUTO_VID)
        vids_to_send++;
-    if (SEND_XAUTH_VID)
-       vids_to_send++;
     if (SEND_CISCO_UNITY_VID)
        vids_to_send++;
     if (c->spd.this.cert.type == CERT_PGP)
        vids_to_send++;
+    /* always send XAUTH Vendor ID */
+       vids_to_send++;
     /* always send DPD Vendor ID */
        vids_to_send++;
     if (nat_traversal_enabled)
@@ -950,8 +945,8 @@ main_outI1(int whack_sock, struct connection *c, struct state *predecessor
        u_char *sa_start = rbody.cur;
        lset_t auth_policy = policy & POLICY_ID_AUTH_MASK;
 
-       if (!out_sa(&rbody, &oakley_sadb[auth_policy >> POLICY_ISAKMP_SHIFT]
-       , st, TRUE, vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE))
+       if (!out_sa(&rbody, &oakley_sadb, st, TRUE
+       , vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE))
        {
            reset_cur_state();
            return STF_INTERNAL_ERROR;
@@ -974,17 +969,6 @@ main_outI1(int whack_sock, struct connection *c, struct state *predecessor
        }
     }
 
-    /* if enabled send XAUTH Vendor ID */
-    if (SEND_XAUTH_VID)
-    {
-       if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
-       , &rbody, VID_MISC_XAUTH))
-       {
-           reset_cur_state();
-           return STF_INTERNAL_ERROR;
-       }
-    }
-
     /* if enabled send Cisco Unity Vendor ID */
     if (SEND_CISCO_UNITY_VID)
     {
@@ -1008,6 +992,14 @@ main_outI1(int whack_sock, struct connection *c, struct state *predecessor
        }
     }
 
+    /* Announce our ability to do eXtended AUTHentication to the peer */
+    if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
+    , &rbody, VID_MISC_XAUTH))
+    {
+       reset_cur_state();
+       return STF_INTERNAL_ERROR;
+    }
+
     /* Announce our ability to do Dead Peer Detection to the peer */
     {
        if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
@@ -1211,11 +1203,15 @@ generate_skeyids_iv(struct state *st)
     switch (st->st_oakley.auth)
     {
        case OAKLEY_PRESHARED_KEY:
+       case XAUTHInitPreShared:
+       case XAUTHRespPreShared:
            if (!skeyid_preshared(st))
                return FALSE;
            break;
 
        case OAKLEY_RSA_SIG:
+       case XAUTHInitRSA:
+       case XAUTHRespRSA:
            if (!skeyid_digisig(st))
                return FALSE;
            break;
@@ -1780,7 +1776,7 @@ RSA_check_signature(const struct id* peer
     {
        char id_buf[BUF_LEN];   /* arbitrary limit on length of ID reported */
 
-       (void) idtoa(&st->st_connection->spd.that.id, id_buf, sizeof(id_buf));
+       (void) idtoa(peer, id_buf, sizeof(id_buf));
 
        if (s.best_ugh == NULL)
        {
@@ -2483,7 +2479,7 @@ switch_connection(struct msg_digest *md, struct id *peer, bool initiator)
        DBG(DBG_CONTROL,
            char buf[BUF_LEN];
 
-           dntoa_or_null(buf, BUF_LEN, c->spd.this.ca, "%none");
+           dntoa_or_null(buf, BUF_LEN, c->spd.that.ca, "%none");
            DBG_log("required CA:  '%s'", buf);
         )
 
@@ -3114,12 +3110,12 @@ main_inI1_outR1(struct msg_digest *md)
     /* determine how many Vendor ID payloads we will be sending */
     if (SEND_PLUTO_VID)
        vids_to_send++;
-    if (SEND_XAUTH_VID)
-       vids_to_send++;
     if (SEND_CISCO_UNITY_VID)
        vids_to_send++;
     if (md->openpgp)
        vids_to_send++;
+    /* always send XAUTH Vendor ID */
+       vids_to_send++;
     /* always send DPD Vendor ID */
        vids_to_send++;
     if (md->nat_traversal_vid && nat_traversal_enabled)
@@ -3151,7 +3147,7 @@ main_inI1_outR1(struct msg_digest *md)
 
     /* SA body in and out */
     RETURN_STF_FAILURE(parse_isakmp_sa_body(ipsecdoisit, &proposal_pbs
-       ,&proposal, &r_sa_pbs, st));
+       ,&proposal, &r_sa_pbs, st, FALSE));
 
     /* if enabled send Pluto Vendor ID */
     if (SEND_PLUTO_VID)
@@ -3163,16 +3159,6 @@ main_inI1_outR1(struct msg_digest *md)
        }
     }
 
-    /* if enabled send XAUTH Vendor ID */
-    if (SEND_XAUTH_VID)
-    {
-       if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
-       , &md->rbody, VID_MISC_XAUTH))
-       {
-           return STF_INTERNAL_ERROR;
-       }
-    }
-
     /* if enabled send Cisco Unity Vendor ID */
     if (SEND_CISCO_UNITY_VID)
     {
@@ -3195,13 +3181,18 @@ main_inI1_outR1(struct msg_digest *md)
        }
     }
 
+    /* Announce our ability to do eXtended AUTHentication to the peer */
+    if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
+    , &md->rbody, VID_MISC_XAUTH))
+    {
+       return STF_INTERNAL_ERROR;
+    }
+
     /* Announce our ability to do Dead Peer Detection to the peer */
+    if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
+    , &md->rbody, VID_MISC_DPD))
     {
-       if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
-       , &md->rbody, VID_MISC_DPD))
-       {
-           return STF_INTERNAL_ERROR;
-       }
+       return STF_INTERNAL_ERROR;
     }
 
     if (md->nat_traversal_vid && nat_traversal_enabled)
@@ -3258,7 +3249,7 @@ main_inR1_outI2(struct msg_digest *md)
            RETURN_STF_FAILURE(BAD_PROPOSAL_SYNTAX);
         }
        RETURN_STF_FAILURE(parse_isakmp_sa_body(ipsecdoisit
-           , &proposal_pbs, &proposal, NULL, st));
+           , &proposal_pbs, &proposal, NULL, st, TRUE));
     }
 
     if (nat_traversal_enabled && md->nat_traversal_vid)
@@ -3343,9 +3334,11 @@ main_inI2_outR2(struct msg_digest *md)
     pb_stream *keyex_pbs = &md->chain[ISAKMP_NEXT_KE]->pbs;
  
     /* send CR if auth is RSA and no preloaded RSA public key exists*/
-    bool send_cr = !no_cr_send && (st->st_oakley.auth == OAKLEY_RSA_SIG) &&
-                  !has_preloaded_public_key(st);
-   
+    bool RSA_auth = st->st_oakley.auth == OAKLEY_RSA_SIG
+                || st->st_oakley.auth == XAUTHInitRSA
+                || st->st_oakley.auth == XAUTHRespRSA;
+    bool send_cr = !no_cr_send && RSA_auth && !has_preloaded_public_key(st);
+
     u_int8_t np = ISAKMP_NEXT_NONE;
 
     /* KE in */
@@ -3480,14 +3473,18 @@ main_inR2_outI3(struct msg_digest *md)
 {
     struct state *const st = md->st;
     pb_stream *const keyex_pbs = &md->chain[ISAKMP_NEXT_KE]->pbs;
-    int auth_payload = st->st_oakley.auth == OAKLEY_PRESHARED_KEY
-       ? ISAKMP_NEXT_HASH : ISAKMP_NEXT_SIG;
     pb_stream id_pbs;  /* ID Payload; also used for hash calculation */
 
     certpolicy_t cert_policy = st->st_connection->spd.this.sendcert;
     cert_t mycert = st->st_connection->spd.this.cert;
     bool requested, send_cert, send_cr;
 
+    bool RSA_auth = st->st_oakley.auth == OAKLEY_RSA_SIG
+                || st->st_oakley.auth == XAUTHInitRSA
+                || st->st_oakley.auth == XAUTHRespRSA;
+
+    int auth_payload = RSA_auth ? ISAKMP_NEXT_SIG : ISAKMP_NEXT_HASH;
+
     /* KE in */
     RETURN_STF_FAILURE(accept_KE(&st->st_gr, "Gr", st->st_oakley.group, keyex_pbs));
 
@@ -3509,31 +3506,29 @@ main_inR2_outI3(struct msg_digest *md)
      */
     requested = cert_policy == CERT_SEND_IF_ASKED
                && st->st_connection->got_certrequest;
-    send_cert = st->st_oakley.auth == OAKLEY_RSA_SIG
-               && mycert.type != CERT_NONE
+    send_cert = RSA_auth && mycert.type != CERT_NONE
                && (cert_policy == CERT_ALWAYS_SEND || requested);
 
     /* send certificate request if we don't have a preloaded RSA public key */
     send_cr = !no_cr_send && send_cert && !has_preloaded_public_key(st);
 
     /* done parsing; initialize crypto  */
-
     compute_dh_shared(st, st->st_gr, st->st_oakley.group);
     if (!generate_skeyids_iv(st))
        return STF_FAIL + AUTHENTICATION_FAILED;
 
-       if (st->nat_traversal & NAT_T_WITH_NATD)
-       {
-           nat_traversal_natd_lookup(md);
-       }
-       if (st->nat_traversal)
-       {
-           nat_traversal_show_result(st->nat_traversal, md->sender_port);
-       }
-       if (st->nat_traversal & NAT_T_WITH_KA)
-       {
-           nat_traversal_new_ka_event();
-       }
+    if (st->nat_traversal & NAT_T_WITH_NATD)
+    {
+       nat_traversal_natd_lookup(md);
+    }
+    if (st->nat_traversal)
+    {
+       nat_traversal_show_result(st->nat_traversal, md->sender_port);
+    }
+    if (st->nat_traversal & NAT_T_WITH_KA)
+    {
+       nat_traversal_new_ka_event();
+    }
 
     /*************** build output packet HDR*;IDii;HASH/SIG_I ***************/
     /* ??? NOTE: this is almost the same as main_inI3_outR3's code */
@@ -3554,7 +3549,7 @@ main_inR2_outI3(struct msg_digest *md)
     }
 
     /* CERT out */
-    if ( st->st_oakley.auth == OAKLEY_RSA_SIG)
+    if (RSA_auth)
     {
        DBG(DBG_CONTROL,
            DBG_log("our certificate policy is %s"
@@ -3710,6 +3705,8 @@ main_id_and_auth(struct msg_digest *md
     switch (st->st_oakley.auth)
     {
     case OAKLEY_PRESHARED_KEY:
+    case XAUTHInitPreShared:
+    case XAUTHRespPreShared:
        {
            pb_stream *const hash_pbs = &md->chain[ISAKMP_NEXT_HASH]->pbs;
 
@@ -3726,6 +3723,8 @@ main_id_and_auth(struct msg_digest *md
        break;
 
     case OAKLEY_RSA_SIG:
+    case XAUTHInitRSA:
+    case XAUTHRespRSA:
        r = RSA_check_signature(&peer, st, hash_val, hash_len
            , &md->chain[ISAKMP_NEXT_SIG]->pbs
 #ifdef USE_KEYRR
@@ -3903,6 +3902,7 @@ main_inI3_outR3_tail(struct msg_digest *md
     pb_stream r_id_pbs;        /* ID Payload; also used for hash calculation */
     certpolicy_t cert_policy;
     cert_t mycert;
+    bool RSA_auth;
     bool send_cert;
     bool requested;
 
@@ -3925,7 +3925,10 @@ main_inI3_outR3_tail(struct msg_digest *md
     mycert = st->st_connection->spd.this.cert;
     requested = cert_policy == CERT_SEND_IF_ASKED
                && st->st_connection->got_certrequest;
-    send_cert = st->st_oakley.auth == OAKLEY_RSA_SIG
+    RSA_auth = st->st_oakley.auth == OAKLEY_RSA_SIG
+           || st->st_oakley.auth == XAUTHInitRSA
+            || st->st_oakley.auth == XAUTHRespRSA;
+    send_cert = RSA_auth
                && mycert.type != CERT_NONE
                && (cert_policy == CERT_ALWAYS_SEND || requested);
 
@@ -3943,8 +3946,7 @@ main_inI3_outR3_tail(struct msg_digest *md
      */
     echo_hdr(md, TRUE, ISAKMP_NEXT_ID);
 
-    auth_payload = st->st_oakley.auth == OAKLEY_PRESHARED_KEY
-       ? ISAKMP_NEXT_HASH : ISAKMP_NEXT_SIG;
+    auth_payload = RSA_auth ? ISAKMP_NEXT_SIG : ISAKMP_NEXT_HASH;
 
     /* IDir out */
     {
@@ -3963,7 +3965,7 @@ main_inI3_outR3_tail(struct msg_digest *md
     }
 
     /* CERT out */
-    if (st->st_oakley.auth == OAKLEY_RSA_SIG)
+    if (RSA_auth)
     {
        DBG(DBG_CONTROL,
            DBG_log("our certificate policy is %s"