silcske.c
- Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
+ Author: Pekka Riikonen <priikone@silcnet.org>
Copyright (C) 2000 - 2001 Pekka Riikonen
#include "silcske.h"
#include "groups_internal.h"
-/* Structure to hold all SKE callbacks-> */
+/* Structure to hold all SKE callbacks. */
struct SilcSKECallbacksStruct {
SilcSKESendPacketCb send_packet;
SilcSKECb payload_receive;
status = silc_ske_payload_start_decode(ske, start_payload, &payload);
if (status != SILC_SKE_STATUS_OK) {
ske->status = status;
+ silc_ske_payload_start_free(ske->start_payload);
return status;
}
if (ske->status == SILC_SKE_STATUS_FREED) {
silc_ske_free(ske);
return;
- } else {
- ske->users--;
}
- payload = ske->ke2_payload;
-
/* If the caller returns PENDING status SKE library will assume that
the caller will re-call this callback when it is not anymore in
PENDING status. */
if (status == SILC_SKE_STATUS_PENDING)
return;
+ ske->users--;
+ payload = ske->ke2_payload;
+
/* If the status is an error then the public key that was verified
by the caller is not authentic. */
if (status != SILC_SKE_STATUS_OK) {
}
/* Continue to final state */
+ ske->users++;
silc_ske_initiator_finish_final(ske, SILC_SKE_STATUS_OK, NULL);
return SILC_SKE_STATUS_OK;
if (ske->status == SILC_SKE_STATUS_FREED) {
silc_ske_free(ske);
return;
- } else {
- ske->users--;
}
- recv_payload = ske->ke1_payload;
-
/* If the caller returns PENDING status SKE library will assume that
the caller will re-call this callback when it is not anymore in
PENDING status. */
if (status == SILC_SKE_STATUS_PENDING)
return;
+ ske->users--;
+ recv_payload = ske->ke1_payload;
+
/* If the status is an error then the public key that was verified
by the caller is not authentic. */
if (status != SILC_SKE_STATUS_OK) {
}
/* Continue to final state */
+ ske->users++;
silc_ske_responder_phase2_final(ske, SILC_SKE_STATUS_OK, NULL);
return SILC_SKE_STATUS_OK;
SILC_STR_END);
memset(k2, 0, sizeof(k2));
silc_hash_make(hash, dist->data, dist->len, k2);
-
+
/* Take third round */
dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
silc_buffer_pull_tail(dist, hash_len);
dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
memcpy(dtmp, k1, hash_len);
memcpy(dtmp + hash_len, k2, hash_len);
- memcpy(dtmp + hash_len, k3, hash_len);
+ memcpy(dtmp + hash_len + hash_len, k3, hash_len);
key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
memcpy(key->send_enc_key, dtmp, enc_key_len);
dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
memcpy(dtmp, k1, hash_len);
memcpy(dtmp + hash_len, k2, hash_len);
- memcpy(dtmp + hash_len, k3, hash_len);
+ memcpy(dtmp + hash_len + hash_len, k3, hash_len);
key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
memcpy(key->receive_enc_key, dtmp, enc_key_len);
key->enc_key_len = req_enc_key_len;
}
- /* Take HMAC key */
+ /* Take HMAC keys */
memset(hashd, 0, sizeof(hashd));
buf->data[0] = 4;
silc_hash_make(hash, buf->data, buf->len, hashd);
- key->hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
- memcpy(key->hmac_key, hashd, req_hmac_key_len);
+ key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
+ memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
+ memset(hashd, 0, sizeof(hashd));
+ buf->data[0] = 5;
+ silc_hash_make(hash, buf->data, buf->len, hashd);
+ key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
+ memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
key->hmac_key_len = req_hmac_key_len;
+ memset(hashd, 0, sizeof(hashd));
silc_buffer_free(buf);
memset(key->receive_enc_key, 0, key->enc_key_len / 8);
silc_free(key->receive_enc_key);
}
- if (key->hmac_key) {
- memset(key->hmac_key, 0, key->hmac_key_len);
- silc_free(key->hmac_key);
+ if (key->send_hmac_key) {
+ memset(key->send_hmac_key, 0, key->hmac_key_len);
+ silc_free(key->send_hmac_key);
+ }
+ if (key->receive_hmac_key) {
+ memset(key->receive_hmac_key, 0, key->hmac_key_len);
+ silc_free(key->receive_hmac_key);
}
silc_free(key);
}
+
+const char *silc_ske_status_string[] =
+{
+ /* Official */
+ "Ok",
+ "Unkown error occurred",
+ "Bad payload in packet",
+ "Unsupported group",
+ "Unsupported cipher",
+ "Unsupported PKCS",
+ "Unsupported hash function",
+ "Unsupported HMAC",
+ "Unsupported public key (or certificate)",
+ "Incorrect signature",
+ "Bad or unsupported version",
+ "Invalid cookie",
+
+ /* Other errors */
+ "Pending",
+ "Remote did not provide public key",
+ "Key exchange protocol is not active",
+ "Bad reserved field in packet",
+ "Bad payload length in packet",
+ "Incorrect hash",
+
+ NULL
+};
+
+/* Maps status to readable string and returns the string. If string is not
+ found and empty character string ("") is returned. */
+
+const char *silc_ske_map_status(SilcSKEStatus status)
+{
+ int i;
+
+ for (i = 0; silc_ske_status_string[i]; i++)
+ if (status == i)
+ return silc_ske_status_string[i];
+
+ return "";
+}