}
/* Save selected cipher to security properties */
- if (silc_cipher_alloc(payload->enc_alg_list,
- &(*prop)->cipher) == FALSE) {
+ if (silc_cipher_alloc(payload->enc_alg_list, &(*prop)->cipher) == FALSE) {
silc_free(payload->ke_grp_list);
silc_free(payload->pkcs_alg_list);
silc_free(payload);
}
/* Save selected hash algorithm to security properties */
- if (silc_hash_alloc(ske->start_payload->hash_alg_list,
- &(*prop)->hash) == FALSE) {
+ if (silc_hash_alloc(payload->hash_alg_list, &(*prop)->hash) == FALSE) {
silc_free(payload->ke_grp_list);
silc_free(payload->pkcs_alg_list);
silc_free(payload->enc_alg_list);
}
/* Save selected HMACc to security properties */
- if (silc_hmac_alloc(ske->start_payload->hmac_alg_list, NULL,
- &(*prop)->hmac) == FALSE) {
+ if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &(*prop)->hmac) == FALSE) {
silc_free(payload->ke_grp_list);
silc_free(payload->pkcs_alg_list);
silc_free(payload->enc_alg_list);
SILC_LOG_DEBUG(("Allocating new Key Exchange object"));
- if (!rng || !schedule || !public_key)
+ if (!rng || !schedule)
return NULL;
+ if (!public_key) {
+ SILC_LOG_ERROR(("Public key must be given to silc_ske_alloc"));
+ return NULL;
+ }
+
ske = silc_calloc(1, sizeof(*ske));
if (!ske)
return NULL;
{
SILC_LOG_DEBUG(("Freeing Key Exchange object"));
- if (ske) {
- /* Free start payload */
- if (ske->start_payload)
- silc_ske_payload_start_free(ske->start_payload);
-
- /* Free KE payload */
- if (ske->ke1_payload)
- silc_ske_payload_ke_free(ske->ke1_payload);
- if (ske->ke2_payload)
- silc_ske_payload_ke_free(ske->ke2_payload);
- silc_free(ske->remote_version);
-
- /* Free rest */
- if (ske->prop) {
- if (ske->prop->group)
- silc_ske_group_free(ske->prop->group);
- if (ske->prop->cipher)
- silc_cipher_free(ske->prop->cipher);
- if (ske->prop->hash)
- silc_hash_free(ske->prop->hash);
- if (ske->prop->hmac)
- silc_hmac_free(ske->prop->hmac);
- silc_free(ske->prop);
- }
- if (ske->start_payload_copy)
- silc_buffer_free(ske->start_payload_copy);
- if (ske->x) {
- silc_mp_uninit(ske->x);
- silc_free(ske->x);
- }
- if (ske->KEY) {
- silc_mp_uninit(ske->KEY);
- silc_free(ske->KEY);
- }
- silc_free(ske->hash);
- silc_free(ske->callbacks);
+ if (!ske)
+ return;
+
+ if (ske->running) {
+ ske->freed = TRUE;
+ return;
+ }
- memset(ske, 'F', sizeof(*ske));
- silc_free(ske);
+ /* Free start payload */
+ if (ske->start_payload)
+ silc_ske_payload_start_free(ske->start_payload);
+
+ /* Free KE payload */
+ if (ske->ke1_payload)
+ silc_ske_payload_ke_free(ske->ke1_payload);
+ if (ske->ke2_payload)
+ silc_ske_payload_ke_free(ske->ke2_payload);
+ silc_free(ske->remote_version);
+
+ /* Free rest */
+ if (ske->prop) {
+ if (ske->prop->group)
+ silc_ske_group_free(ske->prop->group);
+ if (ske->prop->cipher)
+ silc_cipher_free(ske->prop->cipher);
+ if (ske->prop->hash)
+ silc_hash_free(ske->prop->hash);
+ if (ske->prop->hmac)
+ silc_hmac_free(ske->prop->hmac);
+ silc_free(ske->prop);
+ }
+ if (ske->start_payload_copy)
+ silc_buffer_free(ske->start_payload_copy);
+ if (ske->x) {
+ silc_mp_uninit(ske->x);
+ silc_free(ske->x);
+ }
+ if (ske->KEY) {
+ silc_mp_uninit(ske->KEY);
+ silc_free(ske->KEY);
}
+ silc_free(ske->hash);
+ silc_free(ske->callbacks);
+
+ memset(ske, 'F', sizeof(*ske));
+ silc_free(ske);
}
/* Return user context */
SilcSKEStatus status;
SilcSKEStartPayload payload;
SilcSKESecurityProperties prop;
- SilcSKEDiffieHellmanGroup group;
+ SilcSKEDiffieHellmanGroup group = NULL;
SilcBuffer packet_buf = &ske->packet->buffer;
SilcUInt16 remote_port = 0;
SilcID id;
err:
if (payload)
silc_ske_payload_start_free(payload);
-
- silc_ske_group_free(group);
-
+ if (group)
+ silc_ske_group_free(group);
if (prop->cipher)
silc_cipher_free(prop->cipher);
if (prop->hash)
ske->rekey, ske->callbacks->context);
silc_packet_free(ske->packet);
+ silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
return SILC_FSM_FINISH;
}
/* Send FAILURE packet */
SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, data);
silc_packet_send(ske->stream, SILC_PACKET_FAILURE, 0, data, 4);
+ silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
return SILC_FSM_FINISH;
}
ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
ske->callbacks->context);
+ silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
+
return SILC_FSM_FINISH;
}
ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
ske->callbacks->context);
+ silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
+
return SILC_FSM_FINISH;
}
void *destructor_context)
{
SilcSKE ske = fsm_context;
- silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
+
+ ske->running = FALSE;
+ if (ske->freed)
+ silc_ske_free(ske);
}
/* Starts the protocol as initiator */
ske->start_payload = start_payload;
ske->version = params->version;
+ ske->running = TRUE;
/* Link to packet stream to get key exchange packets */
ske->stream = stream;
ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
SILC_PUT32_MSB(ske->status, tmp);
silc_packet_send(ske->stream, SILC_PACKET_FAILURE, 0, tmp, 4);
-
silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
return SILC_FSM_FINISH;
static void silc_ske_responder_finished(SilcFSM fsm, void *fsm_context,
void *destructor_context)
{
+ SilcSKE ske = fsm_context;
+ ske->running = FALSE;
+ if (ske->freed)
+ silc_ske_free(ske);
}
/* Starts the protocol as responder. */
ske->version = strdup(params->version);
if (!ske->version)
return NULL;
+ ske->running = TRUE;
/* Link to packet stream to get key exchange packets */
ske->stream = stream;
{
return ske->prop;
}
+
+/* Get key material */
+
+SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)
+{
+ return ske->keymat;
+}