{
SilcSKE ske = context;
- if (ske->retry_count++ >= SILC_SKE_RETRY_COUNT) {
+ if (ske->retry_count++ >= SILC_SKE_RETRY_COUNT ||
+ ske->aborted) {
SILC_LOG_DEBUG(("Retry limit reached, packet was lost"));
ske->retry_count = 0;
ske->retry_timer = SILC_SKE_RETRY_MIN;
if (ske->aborted) {
/** Aborted */
silc_packet_free(ske->packet);
+ ske->packet = NULL;
silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
return SILC_FSM_CONTINUE;
}
/* See if received failure from remote */
if (ske->packet->type == SILC_PACKET_FAILURE) {
- silc_packet_free(ske->packet);
silc_fsm_next(fsm, silc_ske_st_initiator_failure);
return SILC_FSM_CONTINUE;
}
if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE) {
SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
silc_packet_free(ske->packet);
+ ske->packet = NULL;
return SILC_FSM_WAIT;
}
if (status != SILC_SKE_STATUS_OK) {
/** Error decoding Start Payload */
silc_packet_free(ske->packet);
+ ske->packet = NULL;
ske->status = status;
silc_fsm_next(fsm, silc_ske_st_initiator_error);
return SILC_FSM_CONTINUE;
}
silc_packet_free(ske->packet);
+ ske->packet = NULL;
/* Check that the cookie is returned unmodified. In case IV included
flag and session port has been set, the first two bytes of cookie
if (ske->aborted) {
/** Aborted */
silc_packet_free(ske->packet);
+ ske->packet = NULL;
silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
return SILC_FSM_CONTINUE;
}
/* See if received failure from remote */
if (ske->packet->type == SILC_PACKET_FAILURE) {
- silc_packet_free(ske->packet);
silc_fsm_next(fsm, silc_ske_st_initiator_failure);
return SILC_FSM_CONTINUE;
}
if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
silc_packet_free(ske->packet);
+ ske->packet = NULL;
return SILC_FSM_WAIT;
}
if (status != SILC_SKE_STATUS_OK) {
/** Error decoding KE payload */
silc_packet_free(ske->packet);
+ ske->packet = NULL;
ske->status = status;
silc_fsm_next(fsm, silc_ske_st_initiator_error);
return SILC_FSM_CONTINUE;
}
silc_packet_free(ske->packet);
+ ske->packet = NULL;
ske->ke2_payload = payload;
if (!payload->pk_data && (ske->callbacks->verify_key || ske->repository)) {
/* See if received failure from remote */
if (ske->packet->type == SILC_PACKET_FAILURE) {
- silc_packet_free(ske->packet);
silc_fsm_next(fsm, silc_ske_st_initiator_failure);
return SILC_FSM_CONTINUE;
}
if (ske->packet->type != SILC_PACKET_SUCCESS) {
SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
silc_packet_free(ske->packet);
+ ske->packet = NULL;
return SILC_FSM_WAIT;
}
ske->rekey, ske->callbacks->context);
silc_packet_free(ske->packet);
+ ske->packet = NULL;
silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
silc_schedule_task_del_by_context(ske->schedule, ske);
silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
/* Call the completion callback */
- if (ske->callbacks->completed)
+ if (!ske->aborted && ske->callbacks->completed)
ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
ske->callbacks->context);
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;
+ silc_packet_free(ske->packet);
+ ske->packet = NULL;
+ }
+
/* Call the completion callback */
- if (ske->callbacks->completed)
+ if (!ske->aborted && ske->callbacks->completed)
ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
ske->callbacks->context);
if (ske->aborted) {
/** Aborted */
silc_packet_free(ske->packet);
+ ske->packet = NULL;
silc_fsm_next(fsm, silc_ske_st_responder_aborted);
return SILC_FSM_CONTINUE;
}
/* See if received failure from remote */
if (ske->packet->type == SILC_PACKET_FAILURE) {
- silc_packet_free(ske->packet);
silc_fsm_next(fsm, silc_ske_st_responder_failure);
return SILC_FSM_CONTINUE;
}
if (status != SILC_SKE_STATUS_OK) {
/** Error decoding Start Payload */
silc_packet_free(ske->packet);
+ ske->packet = NULL;
ske->status = status;
silc_fsm_next(fsm, silc_ske_st_responder_error);
return SILC_FSM_CONTINUE;
ske->start_payload_copy = silc_buffer_copy(packet_buf);
silc_packet_free(ske->packet);
+ ske->packet = NULL;
/* Force the mutual authentication flag if we want to do it. */
if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
silc_packet_free(ske->packet);
+ ske->packet = NULL;
return SILC_FSM_WAIT;
}
if (status != SILC_SKE_STATUS_OK) {
/** Error decoding KE payload */
silc_packet_free(ske->packet);
+ ske->packet = NULL;
ske->status = status;
silc_fsm_next(fsm, silc_ske_st_responder_error);
return SILC_FSM_CONTINUE;
ske->ke1_payload = recv_payload;
silc_packet_free(ske->packet);
+ ske->packet = NULL;
/* Verify the received public key and verify the signature if we are
doing mutual authentication. */
if (ske->packet->type != SILC_PACKET_SUCCESS) {
SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
silc_packet_free(ske->packet);
+ ske->packet = NULL;
return SILC_FSM_WAIT;
}
silc_packet_free(ske->packet);
+ ske->packet = NULL;
/* Process key material */
key_len = silc_cipher_get_key_len(ske->prop->cipher);
SILC_LOG_DEBUG(("Key exchange protocol failed"));
- if (silc_buffer_len(&ske->packet->buffer) == 4)
+ if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
SILC_GET32_MSB(error, ske->packet->buffer.data);
- ske->status = error;
+ ske->status = error;
+ silc_packet_free(ske->packet);
+ ske->packet = NULL;
+ }
/* Call the completion callback */
- if (ske->callbacks->completed)
+ if (!ske->aborted && ske->callbacks->completed)
ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
ske->callbacks->context);
- silc_packet_free(ske->packet);
silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
silc_schedule_task_del_by_context(ske->schedule, ske);