/*
* $Id$
* $Log$
+ * Revision 1.5 2000/07/19 07:04:37 priikone
+ * Added version detection support to SKE. Minor bugfixes.
+ *
* Revision 1.4 2000/07/10 05:34:22 priikone
* Added mp binary encoding as protocols defines.
*
SILC_STR_UI_SHORT(payload->len),
SILC_STR_UI_XNSTRING(payload->cookie,
payload->cookie_len),
+ SILC_STR_UI_SHORT(payload->version_len),
+ SILC_STR_UI_XNSTRING(payload->version,
+ payload->version_len),
SILC_STR_UI_SHORT(payload->ke_grp_len),
SILC_STR_UI_XNSTRING(payload->ke_grp_list,
payload->ke_grp_len),
SILC_STR_UI_CHAR(&payload->flags),
SILC_STR_UI_SHORT(&payload->len),
SILC_STR_UI_XNSTRING(&buf, SILC_SKE_COOKIE_LEN),
+ SILC_STR_UI16_NSTRING_ALLOC(&payload->version,
+ &payload->version_len),
SILC_STR_UI_SHORT(&payload->ke_grp_len),
SILC_STR_END);
goto err;
}
- len2 = len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN + 2;
+ len2 = len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN + 2 + payload->version_len + 2;
silc_buffer_pull(buffer, len);
/* Copy cookie from payload */
if (payload) {
if (payload->cookie)
silc_free(payload->cookie);
+ if (payload->version)
+ silc_free(payload->version);
if (payload->ke_grp_list)
silc_free(payload->ke_grp_list);
if (payload->pkcs_alg_list)
/* Encode the integer into binary data */
e_str = silc_mp_mp2bin(&payload->e, &e_len);
+ if (!e_str)
+ return SILC_SKE_STATUS_ERROR;
/* Allocate channel payload buffer. The length of the buffer
is 2 + e. */
- buf = silc_buffer_alloc(e_len + 2);
- silc_buffer_pull_tail(buf, e_len + 2);
+ buf = silc_buffer_alloc(e_len + 2 + payload->pk_len + 2 + 2);
+ silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf));
/* Encode the payload */
silc_buffer_format(buf,
- SILC_STR_UI_SHORT(e_len + 2),
+ SILC_STR_UI_SHORT(payload->pk_len),
+ SILC_STR_UI_SHORT(payload->pk_type),
+ SILC_STR_UI_XNSTRING(payload->pk_data,
+ payload->pk_len),
+ SILC_STR_UI_SHORT(e_len),
SILC_STR_UI_XNSTRING(e_str, e_len),
SILC_STR_END);
{
SilcSKEOnePayload *payload;
SilcSKEStatus status = SILC_SKE_STATUS_ERROR;
+ unsigned char *e;
unsigned short e_len;
SILC_LOG_DEBUG(("Decoding Key Exchange 1 Payload"));
payload = silc_calloc(1, sizeof(*payload));
- memset(buf, 0, sizeof(buf));
-
- /* Parse the payload */
silc_buffer_unformat(buffer,
- SILC_STR_UI_SHORT(&e_len),
+ SILC_STR_UI_SHORT(&payload->pk_len),
+ SILC_STR_UI_SHORT(&payload->pk_type),
SILC_STR_END);
- if (e_len < 1) {
- status = SILC_SKE_STATUS_BAD_PAYLOAD_LENGTH;
+ if (payload->pk_len < 5) {
+ status = SILC_SKE_STATUS_BAD_PAYLOAD;
goto err;
}
- if (e_len != buffer->len) {
- status = SILC_SKE_STATUS_BAD_PAYLOAD_LENGTH;
+ silc_buffer_pull(buffer, 2 + 2);
+ silc_buffer_unformat(buffer,
+ SILC_STR_UI_XNSTRING_ALLOC(&payload->pk_data,
+ payload->pk_len),
+ SILC_STR_UI16_NSTRING_ALLOC(&e, &e_len),
+ SILC_STR_END);
+
+ if (e_len < 3) {
+ status = SILC_SKE_STATUS_BAD_PAYLOAD;
goto err;
}
- /* Length includes the length field length as well. Remove it. */
- e_len -= 2;
+ silc_buffer_push(buffer, 2 + 2);
- silc_buffer_unformat(buffer,
- SILC_STR_UI_SHORT(NULL),
- SILC_STR_UI_XNSTRING(&buf, e_len),
- SILC_STR_END);
+ if (payload->pk_len + 2 + 2 + 2 + e_len != buffer->len) {
+ status = SILC_SKE_STATUS_BAD_PAYLOAD;
+ goto err;
+ }
/* Decode the HEX string to integer */
silc_mp_init(&payload->e);
- silc_mp_bin2mp(buf, e_len, &payload->e);
- memset(buf, 0, sizeof(buf));
+ silc_mp_bin2mp(e, e_len, &payload->e);
+ memset(e, 0, sizeof(e_len));
+ silc_free(e);
/* Return the payload */
*return_payload = payload;
err:
silc_free(payload);
-
return status;
}
void silc_ske_payload_one_free(SilcSKEOnePayload *payload)
{
if (payload) {
+ if (payload->pk_data)
+ silc_free(payload->pk_data);
silc_free(payload);
}
}
/* Encode the payload */
silc_buffer_format(buf,
- SILC_STR_UI_SHORT(payload->pk_len + 4),
+ SILC_STR_UI_SHORT(payload->pk_len),
SILC_STR_UI_SHORT(payload->pk_type),
SILC_STR_UI_XNSTRING(payload->pk_data,
payload->pk_len),
- SILC_STR_UI_SHORT(f_len + 2),
+ SILC_STR_UI_SHORT(f_len),
SILC_STR_UI_XNSTRING(f_str, f_len),
- SILC_STR_UI_SHORT(payload->sign_len + 2),
+ SILC_STR_UI_SHORT(payload->sign_len),
SILC_STR_UI_XNSTRING(payload->sign_data,
payload->sign_len),
SILC_STR_END);
{
SilcSKEStatus status = SILC_SKE_STATUS_ERROR;
SilcSKETwoPayload *payload;
+ unsigned char *f;
unsigned short f_len;
unsigned int tot_len = 0, len2;
SILC_STR_END);
if (payload->pk_len < 5) {
- status = SILC_SKE_STATUS_BAD_PAYLOAD_LENGTH;
+ status = SILC_SKE_STATUS_BAD_PAYLOAD;
goto err;
}
- tot_len += payload->pk_len;
+ tot_len += payload->pk_len + 4;
- payload->pk_len -= 4;
silc_buffer_pull(buffer, 4);
silc_buffer_unformat(buffer,
- SILC_STR_UI_XNSTRING(&buf, payload->pk_len),
- SILC_STR_UI_SHORT(&f_len),
+ SILC_STR_UI_XNSTRING_ALLOC(&payload->pk_data,
+ payload->pk_len),
+ SILC_STR_UI16_NSTRING_ALLOC(&f, &f_len),
+ SILC_STR_UI16_NSTRING_ALLOC(&payload->sign_data,
+ &payload->sign_len),
SILC_STR_END);
+ tot_len += f_len + 2;
+ tot_len += payload->sign_len + 2;
+
if (f_len < 3) {
- status = SILC_SKE_STATUS_BAD_PAYLOAD_LENGTH;
+ status = SILC_SKE_STATUS_BAD_PAYLOAD;
goto err;
}
- tot_len += f_len;
-
- payload->pk_data = silc_calloc(payload->pk_len + 1,
- sizeof(unsigned char));
- memcpy(payload->pk_data, buf, payload->pk_len);
- memset(buf, 0, sizeof(buf));
-
- f_len -= 2;
- silc_buffer_pull(buffer, payload->pk_len + 2);
- silc_buffer_unformat(buffer,
- SILC_STR_UI_XNSTRING(&buf, f_len),
- SILC_STR_UI_SHORT(&payload->sign_len),
- SILC_STR_END);
-
if (payload->sign_len < 3) {
- status = SILC_SKE_STATUS_BAD_PAYLOAD_LENGTH;
+ status = SILC_SKE_STATUS_BAD_PAYLOAD;
goto err;
}
- tot_len += payload->sign_len;
-
if (tot_len != len2) {
- status = SILC_SKE_STATUS_BAD_PAYLOAD_LENGTH;
+ status = SILC_SKE_STATUS_BAD_PAYLOAD;
goto err;
}
/* Decode the HEX string to integer */
silc_mp_init(&payload->f);
- silc_mp_bin2mp(buf, f_len, &payload->f);
- memset(buf, 0, sizeof(buf));
-
- payload->sign_len -= 2;
- silc_buffer_pull(buffer, f_len + 2);
- silc_buffer_unformat(buffer,
- SILC_STR_UI_XNSTRING(&buf, payload->sign_len),
- SILC_STR_END);
-
- payload->sign_data = silc_calloc(payload->sign_len + 1,
- sizeof(unsigned char));
- memcpy(payload->sign_data, buf, payload->sign_len);
- memset(buf, 0, sizeof(buf));
+ silc_mp_bin2mp(f, f_len, &payload->f);
+ memset(f, 0, sizeof(f_len));
+ silc_free(f);
/* Return the payload */
*return_payload = payload;
if (payload->sign_data)
silc_free(payload->sign_data);
silc_free(payload);
-
return status;
}
/*
* $Id$
* $Log$
+ * Revision 1.6 2000/07/19 07:04:37 priikone
+ * Added version detection support to SKE. Minor bugfixes.
+ *
* Revision 1.5 2000/07/10 05:34:22 priikone
* Added mp binary encoding as protocols defines.
*
Key Exchange 1 Payload. */
SilcSKEStatus silc_ske_initiator_phase_2(SilcSKE ske,
+ SilcPublicKey public_key,
SilcSKESendPacketCb send_packet,
void *context)
{
SilcBuffer payload_buf;
SilcInt x, e;
SilcSKEOnePayload *payload;
+ unsigned int pk_len;
SILC_LOG_DEBUG(("Start"));
/* Encode the result to Key Exchange 1 Payload. */
payload = silc_calloc(1, sizeof(*payload));
payload->e = e;
+ payload->pk_data = silc_pkcs_public_key_encode(public_key, &pk_len);
+ payload->pk_len = pk_len;
+ payload->pk_type = SILC_SKE_PK_TYPE_SILC;
status = silc_ske_payload_one_encode(ske, payload, &payload_buf);
if (status != SILC_SKE_STATUS_OK) {
silc_mp_clear(&x);
SilcSKEStatus silc_ske_responder_start(SilcSKE ske, SilcRng rng,
SilcSocketConnection sock,
+ char *version,
SilcBuffer start_payload,
SilcSKECb callback,
void *context)
/* Parse and select the security properties from the payload */
payload = silc_calloc(1, sizeof(*payload));
- status = silc_ske_select_security_properties(ske, payload, remote_payload);
+ status = silc_ske_select_security_properties(ske, version,
+ payload, remote_payload);
if (status != SILC_SKE_STATUS_OK)
goto err;
SilcSKEStatus
silc_ske_assemble_security_properties(SilcSKE ske,
+ char *version,
SilcSKEStartPayload **return_payload)
{
SilcSKEStartPayload *rp;
rp->cookie_len = SILC_SKE_COOKIE_LEN;
memcpy(rp->cookie, "1234567890123456", SILC_SKE_COOKIE_LEN);
+ /* Put version */
+ rp->version = strdup(version);
+ rp->version_len = strlen(version);
+
/* Get supported Key Exhange groups */
rp->ke_grp_list = silc_ske_get_supported_groups();
rp->ke_grp_len = strlen(rp->ke_grp_list);
rp->comp_alg_len = 0;
rp->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
+ 2 + rp->version_len +
2 + rp->ke_grp_len + 2 + rp->pkcs_alg_len +
2 + rp->enc_alg_len + 2 + rp->hash_alg_len +
2 + rp->comp_alg_len;
SilcSKEStatus
silc_ske_select_security_properties(SilcSKE ske,
+ char *version,
SilcSKEStartPayload *payload,
SilcSKEStartPayload *remote_payload)
{
/* Flags are returned unchanged. */
payload->flags = rp->flags;
- /* XXX Cookie check?? */
+ /* Take cookie */
payload->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(unsigned char));
payload->cookie_len = SILC_SKE_COOKIE_LEN;
memcpy(payload->cookie, rp->cookie, SILC_SKE_COOKIE_LEN);
+ /* XXX Do version check */
+
+ /* Put our version to our reply */
+ payload->version = strdup(version);
+ payload->version_len = strlen(version);
+
/* Get supported Key Exchange groups */
cp = rp->ke_grp_list;
if (cp && strchr(cp, ',')) {
#endif
payload->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
+ 2 + payload->version_len +
2 + payload->ke_grp_len + 2 + payload->pkcs_alg_len +
2 + payload->enc_alg_len + 2 + payload->hash_alg_len +
2 + payload->comp_alg_len;