Fixed timeout double free. Makek sure prop->cipher and prop->hash
[silc.git] / lib / silcske / silcske.c
index acb3fd1132621478b12ab0bfdb6de2592b916dab..b5686595213f6494d278f45012d40a5e99aef2d3 100644 (file)
@@ -184,7 +184,6 @@ static SilcSKEStatus silc_ske_check_version(SilcSKE ske)
 {
   SilcUInt32 r_software_version = 0;
   char *r_software_string = NULL;
-  SilcBool src_set = FALSE;
 
   if (!ske->remote_version || !ske->version)
     return SILC_SKE_STATUS_BAD_VERSION;
@@ -194,30 +193,6 @@ static SilcSKEStatus silc_ske_check_version(SilcSKE ske)
                                 &r_software_string, NULL))
     return SILC_SKE_STATUS_BAD_VERSION;
 
-  /* Backwards compatibility checks */
-
-  /* Old server versions requires "valid" looking Source ID in the SILC
-     packets during initial key exchange.  All version before 1.1.0. */
-  silc_packet_get_ids(ske->stream, &src_set, NULL, NULL, NULL);
-  if (!src_set && !ske->responder && r_software_string &&
-      r_software_version < 110) {
-    SILC_LOG_DEBUG(("Remote is old version, add dummy Source ID to packets"));
-
-    if (strstr(r_software_string, "server")) {
-      SilcServerID sid;
-      memset(&sid, 0, sizeof(sid));
-      sid.ip.data_len = 4;
-      silc_packet_set_ids(ske->stream, SILC_ID_SERVER, &sid, 0, NULL);
-    }
-
-    if (strstr(r_software_string, "client")) {
-      SilcClientID cid;
-      memset(&cid, 0, sizeof(cid));
-      cid.ip.data_len = 4;
-      silc_packet_set_ids(ske->stream, SILC_ID_CLIENT, &cid, 0, NULL);
-    }
-  }
-
   return SILC_SKE_STATUS_OK;
 }
 
@@ -1807,9 +1782,6 @@ SILC_FSM_STATE(silc_ske_st_initiator_failure)
   SilcSKE ske = fsm_context;
   SilcUInt32 error = SILC_SKE_STATUS_ERROR;
 
-  SILC_LOG_DEBUG(("Error %s (%d) received during key exchange",
-                 silc_ske_map_status(ske->status), ske->status));
-
   if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
     SILC_GET32_MSB(error, ske->packet->buffer.data);
     ske->status = error;
@@ -1817,6 +1789,9 @@ SILC_FSM_STATE(silc_ske_st_initiator_failure)
     ske->packet = NULL;
   }
 
+  SILC_LOG_DEBUG(("Error %s (%d) received during key exchange",
+                 silc_ske_map_status(ske->status), ske->status));
+
   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
   silc_schedule_task_del_by_context(ske->schedule, ske);
 
@@ -2575,10 +2550,15 @@ SILC_FSM_STATE(silc_ske_st_rekey_initiator_done)
                         &hmac_send, NULL, NULL)) {
     /** Cannot get keys */
     ske->status = SILC_SKE_STATUS_ERROR;
+    ske->prop->cipher = NULL;
+    ske->prop->hmac = NULL;
     silc_fsm_next(fsm, silc_ske_st_initiator_error);
     return SILC_FSM_CONTINUE;
   }
 
+  ske->prop->cipher = NULL;
+  ske->prop->hmac = NULL;
+
   /* Set the new keys into use.  This will also send REKEY_DONE packet.  Any
      packet sent after this call will be protected with the new keys. */
   if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
@@ -2586,6 +2566,8 @@ SILC_FSM_STATE(silc_ske_st_rekey_initiator_done)
     /** Cannot set keys */
     SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
     ske->status = SILC_SKE_STATUS_ERROR;
+    silc_cipher_free(send_key);
+    silc_hmac_free(hmac_send);
     silc_fsm_next(fsm, silc_ske_st_initiator_error);
     return SILC_FSM_CONTINUE;
   }
@@ -2622,6 +2604,8 @@ SILC_FSM_STATE(silc_ske_st_rekey_initiator_end)
                         NULL, &hmac_receive, NULL)) {
     /** Cannot get keys */
     ske->status = SILC_SKE_STATUS_ERROR;
+    ske->prop->cipher = NULL;
+    ske->prop->hmac = NULL;
     silc_fsm_next(fsm, silc_ske_st_initiator_error);
     return SILC_FSM_CONTINUE;
   }
@@ -2633,6 +2617,8 @@ SILC_FSM_STATE(silc_ske_st_rekey_initiator_end)
     /** Cannot set keys */
     SILC_LOG_DEBUG(("Cannot set new keys"));
     ske->status = SILC_SKE_STATUS_ERROR;
+    silc_cipher_free(receive_key);
+    silc_hmac_free(hmac_receive);
     silc_fsm_next(fsm, silc_ske_st_initiator_error);
     return SILC_FSM_CONTINUE;
   }
@@ -2644,6 +2630,8 @@ SILC_FSM_STATE(silc_ske_st_rekey_initiator_end)
   if (!rekey) {
     /** No memory */
     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
+    ske->prop->cipher = NULL;
+    ske->prop->hmac = NULL;
     silc_fsm_next(fsm, silc_ske_st_initiator_error);
     return SILC_FSM_CONTINUE;
   }
@@ -2721,7 +2709,6 @@ SILC_FSM_STATE(silc_ske_st_rekey_responder_wait)
   silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
                                 ske, 30, 0);
 
-
   silc_fsm_next(fsm, silc_ske_st_rekey_responder_start);
 
   /* If REKEY packet already received process it directly */
@@ -2837,10 +2824,15 @@ SILC_FSM_STATE(silc_ske_st_rekey_responder_done)
                         &hmac_send, NULL, NULL)) {
     /** Cannot get keys */
     ske->status = SILC_SKE_STATUS_ERROR;
+    ske->prop->cipher = NULL;
+    ske->prop->hmac = NULL;
     silc_fsm_next(fsm, silc_ske_st_responder_error);
     return SILC_FSM_CONTINUE;
   }
 
+  ske->prop->cipher = NULL;
+  ske->prop->hmac = NULL;
+
   /* Set the new keys into use.  This will also send REKEY_DONE packet.  Any
      packet sent after this call will be protected with the new keys. */
   if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
@@ -2848,6 +2840,8 @@ SILC_FSM_STATE(silc_ske_st_rekey_responder_done)
     /** Cannot set keys */
     SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
     ske->status = SILC_SKE_STATUS_ERROR;
+    silc_cipher_free(send_key);
+    silc_hmac_free(hmac_send);
     silc_fsm_next(fsm, silc_ske_st_responder_error);
     return SILC_FSM_CONTINUE;
   }
@@ -2884,6 +2878,8 @@ SILC_FSM_STATE(silc_ske_st_rekey_responder_end)
                         NULL, &hmac_receive, NULL)) {
     /** Cannot get keys */
     ske->status = SILC_SKE_STATUS_ERROR;
+    ske->prop->cipher = NULL;
+    ske->prop->hmac = NULL;
     silc_fsm_next(fsm, silc_ske_st_responder_error);
     return SILC_FSM_CONTINUE;
   }
@@ -2895,6 +2891,10 @@ SILC_FSM_STATE(silc_ske_st_rekey_responder_end)
     /** Cannot set keys */
     SILC_LOG_DEBUG(("Cannot set new keys"));
     ske->status = SILC_SKE_STATUS_ERROR;
+    ske->prop->cipher = NULL;
+    ske->prop->hmac = NULL;
+    silc_cipher_free(receive_key);
+    silc_hmac_free(hmac_receive);
     silc_fsm_next(fsm, silc_ske_st_responder_error);
     return SILC_FSM_CONTINUE;
   }
@@ -2906,6 +2906,8 @@ SILC_FSM_STATE(silc_ske_st_rekey_responder_end)
   if (!rekey) {
     /** No memory */
     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
+    ske->prop->cipher = NULL;
+    ske->prop->hmac = NULL;
     silc_fsm_next(fsm, silc_ske_st_responder_error);
     return SILC_FSM_CONTINUE;
   }