added better error printing to SKE library.
Fixed the usage of silc_pkcs_get_key_len as it returns the length
in bits not in bytes.
silc_pkcs_private_key_set(pkcs, private_key);
/* Compute the hash and the signature. */
silc_pkcs_private_key_set(pkcs, private_key);
/* Compute the hash and the signature. */
- if (silc_pkcs_get_key_len(pkcs) > sizeof(auth_data) - 1 ||
+ if (silc_pkcs_get_key_len(pkcs) / 8 > sizeof(auth_data) - 1 ||
!silc_pkcs_sign_with_hash(pkcs, hash, tmp, tmp_len, auth_data,
&auth_len)) {
memset(randomdata, 0, 256);
!silc_pkcs_sign_with_hash(pkcs, hash, tmp, tmp_len, auth_data,
&auth_len)) {
memset(randomdata, 0, 256);
/* The main SILC PKCS structure. */
struct SilcPKCSStruct {
/* The main SILC PKCS structure. */
struct SilcPKCSStruct {
- void *context;
- SilcPKCSObject *pkcs;
- SilcUInt32 key_len;
+ void *context; /* Algorithm internal context */
+ SilcPKCSObject *pkcs; /* Algorithm implementation */
+ SilcUInt32 key_len; /* Key length in bits */
return SILC_SKE_STATUS_ERROR;
buf = silc_buffer_alloc(payload->len);
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_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));
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->cookie_len = SILC_SKE_COOKIE_LEN;
/* Parse start of the payload */
&payload->comp_alg_len),
SILC_STR_END);
if (ret == -1) {
&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"));
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) {
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;
}
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);
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_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));
SILC_LOG_HEXDUMP(("KE Payload"), buffer->data, buffer->len);
payload = silc_calloc(1, sizeof(*payload));
+ if (!payload)
+ return SILC_SKE_STATUS_OUT_OF_MEMORY;
SILC_STR_UI_SHORT(&payload->pk_type),
SILC_STR_END);
if (ret == -1) {
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)) {
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;
}
status = SILC_SKE_STATUS_BAD_PAYLOAD;
goto err;
}
&payload->sign_len),
SILC_STR_END);
if (ret == -1) {
&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;
tot_len += payload->sign_len + 2;
if (x_len < 3) {
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;
}
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)) {
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) {
"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;
}
status = SILC_SKE_STATUS_BAD_PAYLOAD_LENGTH;
goto err;
}
SILC_LOG_DEBUG(("Allocating new Key Exchange object"));
ske = silc_calloc(1, sizeof(*ske));
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;
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)
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;
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)) {
/* 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;
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));
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)
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));
/* 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,
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));
/* 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"));
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);
/* 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);
!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_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"));
payload->sign_len, hash, hash_len) == FALSE) {
SILC_LOG_DEBUG(("Signature don't match"));
status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
goto err;
}
status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
goto err;
}
/* Get the public key */
pk = silc_pkcs_public_key_encode(public_key, &pk_len);
if (!pk) {
/* 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;
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);
/* 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;
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));
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"));
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);
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;
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);
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)
/* 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);
/* 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 */
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) {
/* 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);
} 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 =
/* 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;
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_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 */
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_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 */
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_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);
/* 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),
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",
"Key exchange protocol is not active",
"Bad reserved field in packet",
"Bad payload length in packet",
+ "Error computing signature",
+ "System out of memory",
SILC_SKE_STATUS_KEY_EXCHANGE_NOT_ACTIVE, /* SKE is not started */
SILC_SKE_STATUS_BAD_RESERVED_FIELD, /* Reserved field was not 0 */
SILC_SKE_STATUS_BAD_PAYLOAD_LENGTH, /* Payload includes garbage */
SILC_SKE_STATUS_KEY_EXCHANGE_NOT_ACTIVE, /* SKE is not started */
SILC_SKE_STATUS_BAD_RESERVED_FIELD, /* Reserved field was not 0 */
SILC_SKE_STATUS_BAD_PAYLOAD_LENGTH, /* Payload includes garbage */
+ SILC_SKE_STATUS_SIGNATURE_ERROR, /* Error computing signature */
+ SILC_SKE_STATUS_OUT_OF_MEMORY, /* System out of memory */
/* Other internal status types */
SILC_SKE_STATUS_FREED, /* Internal library status */
/* Other internal status types */
SILC_SKE_STATUS_FREED, /* Internal library status */