return SILC_SKE_STATUS_ERROR;
buf = silc_buffer_alloc(payload->len);
+ if (!buf)
+ return SILC_SKE_STATUS_OUT_OF_MEMORY;
silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf));
/* Encode the payload */
SILC_LOG_HEXDUMP(("KE Start Payload"), buffer->data, buffer->len);
payload = silc_calloc(1, sizeof(*payload));
+ if (!payload)
+ return SILC_SKE_STATUS_OUT_OF_MEMORY;
payload->cookie_len = SILC_SKE_COOKIE_LEN;
/* Parse start of the payload */
&payload->comp_alg_len),
SILC_STR_END);
if (ret == -1) {
- status = SILC_SKE_STATUS_ERROR;
+ SILC_LOG_ERROR(("Malformed KE Start Payload"));
+ status = SILC_SKE_STATUS_BAD_PAYLOAD;
goto err;
}
if (tmp != 0) {
SILC_LOG_DEBUG(("Bad reserved field"));
+ SILC_LOG_ERROR(("Bad RESERVED field in KE Start Payload"));
status = SILC_SKE_STATUS_BAD_RESERVED_FIELD;
goto err;
}
if (payload->len != buffer->len) {
- SILC_LOG_DEBUG(("Bad payload length"));
+ SILC_LOG_ERROR(("Garbage after KE Start Payload"));
status = SILC_SKE_STATUS_BAD_PAYLOAD_LENGTH;
goto err;
}
is 4 + public key + 2 + x + 2 + signature. */
buf = silc_buffer_alloc(4 + payload->pk_len + 2 + x_len +
2 + payload->sign_len);
+ if (!buf)
+ return SILC_SKE_STATUS_OUT_OF_MEMORY;
silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf));
/* Encode the payload */
SILC_LOG_HEXDUMP(("KE Payload"), buffer->data, buffer->len);
payload = silc_calloc(1, sizeof(*payload));
+ if (!payload)
+ return SILC_SKE_STATUS_OUT_OF_MEMORY;
len2 = buffer->len;
SILC_STR_UI_SHORT(&payload->pk_type),
SILC_STR_END);
if (ret == -1) {
- status = SILC_SKE_STATUS_ERROR;
+ SILC_LOG_ERROR(("Cannot decode public key from KE payload"));
+ status = SILC_SKE_STATUS_BAD_PAYLOAD;
goto err;
}
if (ske->start_payload &&
(payload->pk_type < SILC_SKE_PK_TYPE_SILC ||
payload->pk_type > SILC_SKE_PK_TYPE_SPKI)) {
+ SILC_LOG_ERROR(("Malformed public key in KE payload"));
status = SILC_SKE_STATUS_BAD_PAYLOAD;
goto err;
}
&payload->sign_len),
SILC_STR_END);
if (ret == -1) {
- status = SILC_SKE_STATUS_ERROR;
+ SILC_LOG_ERROR(("Malformed KE Payload"));
+ status = SILC_SKE_STATUS_BAD_PAYLOAD;
goto err;
}
tot_len += payload->sign_len + 2;
if (x_len < 3) {
+ SILC_LOG_ERROR(("Too short signature in KE Payload"));
status = SILC_SKE_STATUS_BAD_PAYLOAD;
goto err;
}
if (ske->start_payload &&
(ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) &&
(payload->sign_len < 3 || !payload->sign_data)) {
- SILC_LOG_DEBUG(("The signature data is missing - both parties are "
+ SILC_LOG_ERROR(("The signature data is missing - both parties are "
"required to do authentication"));
status = SILC_SKE_STATUS_BAD_PAYLOAD;
goto err;
}
if (tot_len != len2) {
+ SILC_LOG_ERROR(("Garbage after KE payload"));
status = SILC_SKE_STATUS_BAD_PAYLOAD_LENGTH;
goto err;
}
SILC_LOG_DEBUG(("Allocating new Key Exchange object"));
ske = silc_calloc(1, sizeof(*ske));
+ if (!ske)
+ return NULL;
ske->status = SILC_SKE_STATUS_OK;
ske->rng = rng;
ske->user_data = context;
if (ske->callbacks)
silc_free(ske->callbacks);
ske->callbacks = silc_calloc(1, sizeof(*ske->callbacks));
+ if (!ske->callbacks)
+ return;
ske->callbacks->send_packet = send_packet;
ske->callbacks->payload_receive = payload_receive;
ske->callbacks->verify_key = verify_key;
/* Check that the cookie is returned unmodified */
if (memcmp(ske->start_payload->cookie, payload->cookie,
ske->start_payload->cookie_len)) {
- SILC_LOG_DEBUG(("Responder modified our cookie and it must not do it"));
+ SILC_LOG_ERROR(("Responder modified our cookie and it must not do it"));
ske->status = SILC_SKE_STATUS_INVALID_COOKIE;
silc_ske_payload_start_free(ske->start_payload);
return status;
exchange. The same data is returned to upper levels by calling
the callback function. */
ske->prop = prop = silc_calloc(1, sizeof(*prop));
+ if (!ske->prop)
+ goto err;
prop->flags = payload->flags;
status = silc_ske_group_get_by_name(payload->ke_grp_list, &group);
if (status != SILC_SKE_STATUS_OK)
/* Create the random number x, 1 < x < q. */
x = silc_calloc(1, sizeof(*x));
+ if (!x){
+ ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
+ return ske->status;
+ }
silc_mp_init(x);
status =
silc_ske_create_rnd(ske, &ske->prop->group->group_order,
/* Encode the result to Key Exchange Payload. */
payload = silc_calloc(1, sizeof(*payload));
+ if (!payload) {
+ silc_mp_uninit(x);
+ silc_free(x);
+ ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
+ return ske->status;
+ }
ske->ke1_payload = payload;
SILC_LOG_DEBUG(("Computing e = g ^ x mod p"));
/* Sign the hash value */
silc_pkcs_private_key_data_set(ske->prop->pkcs, private_key->prv,
private_key->prv_len);
- if (silc_pkcs_get_key_len(ske->prop->pkcs) > sizeof(sign) - 1 ||
+ if (silc_pkcs_get_key_len(ske->prop->pkcs) / 8 > sizeof(sign) - 1 ||
!silc_pkcs_sign(ske->prop->pkcs, hash, hash_len, sign, &sign_len)) {
silc_mp_uninit(x);
silc_free(x);
silc_mp_uninit(&payload->x);
silc_free(payload->pk_data);
silc_free(payload);
- ske->status = status;
- return status;
+ ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
+ return ske->status;
}
payload->sign_data = silc_calloc(sign_len, sizeof(unsigned char));
memcpy(payload->sign_data, sign, sign_len);
payload->sign_len, hash, hash_len) == FALSE) {
SILC_LOG_DEBUG(("Signature don't match"));
-
status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
goto err;
}
/* Get the public key */
pk = silc_pkcs_public_key_encode(public_key, &pk_len);
if (!pk) {
- status = SILC_SKE_STATUS_ERROR;
+ status = SILC_SKE_STATUS_OUT_OF_MEMORY;
goto err;
}
ske->ke2_payload->pk_data = pk;
/* Sign the hash value */
silc_pkcs_private_key_data_set(ske->prop->pkcs, private_key->prv,
private_key->prv_len);
- if (silc_pkcs_get_key_len(ske->prop->pkcs) > sizeof(sign) - 1 ||
- !silc_pkcs_sign(ske->prop->pkcs, hash, hash_len, sign, &sign_len))
+ if (silc_pkcs_get_key_len(ske->prop->pkcs) / 8 > sizeof(sign) - 1 ||
+ !silc_pkcs_sign(ske->prop->pkcs, hash, hash_len, sign, &sign_len)) {
+ status = SILC_SKE_STATUS_SIGNATURE_ERROR;
goto err;
+ }
ske->ke2_payload->sign_data = silc_calloc(sign_len, sizeof(unsigned char));
memcpy(ske->ke2_payload->sign_data, sign, sign_len);
memset(sign, 0, sizeof(sign));
SILC_LOG_DEBUG(("Start"));
- packet = silc_buffer_alloc(4);
- silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
+ packet = silc_buffer_alloc_size(4);
+ if (!packet)
+ return SILC_SKE_STATUS_OUT_OF_MEMORY;
silc_buffer_format(packet,
SILC_STR_UI_INT((SilcUInt32)SILC_SKE_STATUS_OK),
SILC_STR_END);
if (status > SILC_SKE_STATUS_INVALID_COOKIE)
status = SILC_SKE_STATUS_BAD_PAYLOAD;
- packet = silc_buffer_alloc(4);
- silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
+ packet = silc_buffer_alloc_size(4);
+ if (!packet)
+ return SILC_SKE_STATUS_OUT_OF_MEMORY;
silc_buffer_format(packet,
SILC_STR_UI_INT((SilcUInt32)status),
SILC_STR_END);
/* Get the random number as string */
string = silc_rng_get_rn_data(ske->rng, (len / 8));
if (!string)
- return SILC_SKE_STATUS_ERROR;
+ return SILC_SKE_STATUS_OUT_OF_MEMORY;
/* Decode the string into a MP integer */
silc_mp_bin2mp(string, (len / 8), rnd);
KEY = silc_mp_mp2bin(ske->KEY, 0, &KEY_len);
/* Format the buffer used to compute the hash value */
- buf = silc_buffer_alloc(ske->start_payload_copy->len +
- ske->ke2_payload->pk_len +
- ske->ke1_payload->pk_len +
- e_len + f_len + KEY_len);
- silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf));
+ buf = silc_buffer_alloc_size(ske->start_payload_copy->len +
+ ske->ke2_payload->pk_len +
+ ske->ke1_payload->pk_len +
+ e_len + f_len + KEY_len);
+ if (!buf)
+ return SILC_SKE_STATUS_OUT_OF_MEMORY;
/* Initiator is not required to send its public key */
if (!ske->ke1_payload->pk_data) {
} else {
e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
- buf = silc_buffer_alloc(ske->start_payload_copy->len +
- ske->ke1_payload->pk_len + e_len);
- silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf));
+ buf = silc_buffer_alloc_size(ske->start_payload_copy->len +
+ ske->ke1_payload->pk_len + e_len);
+ if (!buf)
+ return SILC_SKE_STATUS_OUT_OF_MEMORY;
/* Format the buffer used to compute the hash value */
ret =
if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
return SILC_SKE_STATUS_ERROR;
- buf = silc_buffer_alloc(1 + data_len);
- silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf));
+ buf = silc_buffer_alloc_size(1 + data_len);
+ if (!buf)
+ return SILC_SKE_STATUS_OUT_OF_MEMORY;
silc_buffer_format(buf,
SILC_STR_UI_CHAR(0),
SILC_STR_UI_XNSTRING(data, data_len),
silc_hash_make(hash, buf->data, buf->len, k1);
/* Take second round */
- dist = silc_buffer_alloc(data_len + hash_len);
- silc_buffer_pull_tail(dist, SILC_BUFFER_END(dist));
+ dist = silc_buffer_alloc_size(data_len + hash_len);
+ if (!dist)
+ return SILC_SKE_STATUS_OUT_OF_MEMORY;
silc_buffer_format(dist,
SILC_STR_UI_XNSTRING(data, data_len),
SILC_STR_UI_XNSTRING(k1, hash_len),
silc_hash_make(hash, buf->data, buf->len, k1);
/* Take second round */
- dist = silc_buffer_alloc(data_len + hash_len);
- silc_buffer_pull_tail(dist, SILC_BUFFER_END(dist));
+ dist = silc_buffer_alloc_size(data_len + hash_len);
+ if (!dist)
+ return SILC_SKE_STATUS_OUT_OF_MEMORY;
silc_buffer_format(dist,
SILC_STR_UI_XNSTRING(data, data_len),
SILC_STR_UI_XNSTRING(k1, hash_len),
/* Encode KEY to binary data */
tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
- buf = silc_buffer_alloc(klen + ske->hash_len);
- silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf));
+ buf = silc_buffer_alloc_size(klen + ske->hash_len);
+ if (!buf)
+ return SILC_SKE_STATUS_OUT_OF_MEMORY;
silc_buffer_format(buf,
SILC_STR_UI_XNSTRING(tmpbuf, klen),
SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
"Key exchange protocol is not active",
"Bad reserved field in packet",
"Bad payload length in packet",
- "Incorrect hash",
+ "Error computing signature",
+ "System out of memory",
NULL
};