1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
| static stf_status main_inI3_outR3_tail(struct msg_digest *md , struct key_continuation *kc) { struct state *const st = md->st; u_int8_t auth_payload; pb_stream r_id_pbs; cert_t mycert; bool send_cert; unsigned int np;
{ stf_status r = main_id_and_auth(md, FALSE , main_inI3_outR3_continue , kc);
if (r != STF_OK) return r; }
mycert = st->st_connection->spd.this.cert;
send_cert = st->st_oakley.auth == OAKLEY_RSA_SIG && mycert.type != CERT_NONE && ((st->st_connection->spd.this.sendcert == cert_sendifasked && st->hidden_variables.st_got_certrequest) || st->st_connection->spd.this.sendcert==cert_alwayssend);
doi_log_cert_thinking(md , st->st_oakley.auth , mycert.type , st->st_connection->spd.this.sendcert , st->hidden_variables.st_got_certrequest , send_cert);
echo_hdr(md, TRUE, ISAKMP_NEXT_ID);
auth_payload = st->st_oakley.auth == OAKLEY_PRESHARED_KEY ? ISAKMP_NEXT_HASH : ISAKMP_NEXT_SIG;
{
struct isakmp_ipsec_id id_hd; chunk_t id_b;
build_id_payload(&id_hd, &id_b, &st->st_connection->spd.this); id_hd.isaiid_np = (send_cert)? ISAKMP_NEXT_CERT : auth_payload; if (!out_struct(&id_hd, &isakmp_ipsec_identification_desc, &md->rbody, &r_id_pbs) || !out_chunk(id_b, &r_id_pbs, "my identity")) return STF_INTERNAL_ERROR; close_output_pbs(&r_id_pbs); }
if (send_cert) { pb_stream cert_pbs;
struct isakmp_cert cert_hd; cert_hd.isacert_np = ISAKMP_NEXT_SIG; cert_hd.isacert_type = mycert.type;
openswan_log("I am sending my cert"); if (!out_struct(&cert_hd, &isakmp_ipsec_certificate_desc, &md->rbody, &cert_pbs)) return STF_INTERNAL_ERROR; if (!out_chunk(get_mycert(mycert), &cert_pbs, "CERT")) return STF_INTERNAL_ERROR; close_output_pbs(&cert_pbs); }
#ifdef TPM { pb_stream *pbs = &md->rbody; size_t enc_len = pbs_offset(pbs) - sizeof(struct isakmp_hdr);
TCLCALLOUT_crypt("preHash", st,pbs,sizeof(struct isakmp_hdr),enc_len);
tpm_findID(pbs, &r_id_pbs); } #endif
np = ISAKMP_NEXT_NONE; if(st->st_connection->policy & POLICY_IKEV2_ALLOW) { np = ISAKMP_NEXT_VID; }
{ u_char hash_val[MAX_DIGEST_LEN]; size_t hash_len = main_mode_hash(st, hash_val, FALSE, &r_id_pbs);
if (auth_payload == ISAKMP_NEXT_HASH) { if (!out_generic_raw(np, &isakmp_hash_desc, &md->rbody , hash_val, hash_len, "HASH_R")) return STF_INTERNAL_ERROR; } else { u_char sig_val[RSA_MAX_OCTETS]; size_t sig_len = RSA_sign_hash(st->st_connection , sig_val, hash_val, hash_len);
if (sig_len == 0) { loglog(RC_LOG_SERIOUS, "unable to locate my private key for RSA Signature"); return STF_FAIL + AUTHENTICATION_FAILED; }
if (!out_generic_raw(np, &isakmp_signature_desc , &md->rbody, sig_val, sig_len, "SIG_R")) return STF_INTERNAL_ERROR; } }
if(st->st_connection->policy & POLICY_IKEV2_ALLOW) { if(!out_vid(ISAKMP_NEXT_NONE, &md->rbody, VID_MISC_IKEv2)) return STF_INTERNAL_ERROR; }
if (!encrypt_message(&md->rbody, st)) return STF_INTERNAL_ERROR;
DBG_cond_dump(DBG_CRYPT, "last encrypted block of Phase 1:" , st->st_new_iv, st->st_new_iv_len);
st->st_ph1_iv_len = st->st_new_iv_len; set_ph1_iv(st, st->st_new_iv);
if( st->st_connection->remotepeertype == CISCO && st->st_connection->newest_isakmp_sa != SOS_NOBODY && st->st_connection->spd.this.xauth_client) { DBG(DBG_CONTROL, DBG_log("Skipping XAUTH for rekey for Cisco Peer compatibility.")); st->hidden_variables.st_xauth_client_done = TRUE; st->st_oakley.xauth = 0;
if(st->st_connection->spd.this.modecfg_client) { DBG(DBG_CONTROL, DBG_log("Skipping ModeCFG for rekey for Cisco Peer compatibility.")); st->hidden_variables.st_modecfg_vars_set = TRUE; st->hidden_variables.st_modecfg_started = TRUE; } }
ISAKMP_SA_established(st->st_connection, st->st_serialno);
return STF_OK; }
|