/*
- silcauth.c
+ silcauth.c
Author: Pekka Riikonen <priikone@silcnet.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
+ the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
return NULL;
}
- if (newp->len != buffer.len) {
+ if (newp->len != buffer.len ||
+ newp->random_len + newp->auth_len > buffer.len - 8) {
+ silc_auth_payload_free(newp);
+ return NULL;
+ }
+
+ /* Authentication data must be provided */
+ if (newp->auth_len < 1) {
silc_auth_payload_free(newp);
return NULL;
}
static unsigned char *
silc_auth_public_key_encode_data(SilcPublicKey public_key,
- const unsigned char *random,
+ const unsigned char *randomdata,
SilcUInt32 random_len, const void *id,
SilcIdType type, SilcUInt32 *ret_len)
{
return NULL;
}
silc_buffer_format(buf,
- SILC_STR_UI_XNSTRING(random, random_len),
+ SILC_STR_UI_XNSTRING(randomdata, random_len),
SILC_STR_UI_XNSTRING(id_data, id_len),
SILC_STR_UI_XNSTRING(pk, pk_len),
SILC_STR_END);
if (ret_len)
*ret_len = buf->len;
+ silc_buffer_clear(buf);
silc_buffer_free(buf);
silc_free(id_data);
silc_free(pk);
SilcRng rng, SilcHash hash,
const void *id, SilcIdType type)
{
- unsigned char *random;
- unsigned char auth_data[1024];
+ unsigned char *randomdata;
+ unsigned char auth_data[2048];
SilcUInt32 auth_len;
unsigned char *tmp;
SilcUInt32 tmp_len;
/* Get 256 bytes of random data */
if (rng)
- random = silc_rng_get_rn_data(rng, 256);
+ randomdata = silc_rng_get_rn_data(rng, 256);
else
- random = silc_rng_global_get_rn_data(256);
- if (!random)
+ randomdata = silc_rng_global_get_rn_data(256);
+ if (!randomdata)
return NULL;
/* Encode the auth data */
- tmp = silc_auth_public_key_encode_data(public_key, random, 256, id, type,
- &tmp_len);
+ tmp = silc_auth_public_key_encode_data(public_key, randomdata, 256, id,
+ type, &tmp_len);
if (!tmp)
return NULL;
/* Allocate PKCS object */
- if (!silc_pkcs_alloc(public_key->name, &pkcs)) {
+ if (!silc_pkcs_alloc(private_key->name, &pkcs)) {
memset(tmp, 0, tmp_len);
silc_free(tmp);
return NULL;
silc_pkcs_private_key_set(pkcs, private_key);
/* Compute the hash and the signature. */
- if (!silc_pkcs_sign_with_hash(pkcs, hash, tmp, tmp_len, auth_data,
+ 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(random, 0, 256);
+ memset(randomdata, 0, 256);
memset(tmp, 0, tmp_len);
silc_free(tmp);
- silc_free(random);
+ silc_free(randomdata);
silc_pkcs_free(pkcs);
return NULL;
}
/* Encode Authentication Payload */
- buf = silc_auth_payload_encode(SILC_AUTH_PUBLIC_KEY, random, 256,
+ buf = silc_auth_payload_encode(SILC_AUTH_PUBLIC_KEY, randomdata, 256,
auth_data, auth_len);
memset(tmp, 0, tmp_len);
memset(auth_data, 0, sizeof(auth_data));
- memset(random, 0, 256);
+ memset(randomdata, 0, 256);
silc_free(tmp);
- silc_free(random);
+ silc_free(randomdata);
silc_pkcs_free(pkcs);
return buf;
{
SILC_LOG_DEBUG(("Verifying authentication"));
- if (auth_method != payload->auth_method)
+ if (!payload || auth_method != payload->auth_method)
return FALSE;
switch (payload->auth_method) {
case SILC_AUTH_PASSWORD:
/* Passphrase based authentication. The `pkcs', `hash', `id' and `type'
arguments are not needed. */
- /* Carefully check that the auth_data field of the payload is not empty
- (len=0), which seems to be a legal packet but would crash the
- application. Maybe such packet should be dropped. -Johnny 2002/14/4 */
- if ((payload->auth_len == 0) || !auth_data)
- break;
- /* if lengths mismatch, avoid comparing unallocated memory locations */
- if (payload->auth_len != auth_data_len)
+ /* Sanity checks */
+ if ((payload->auth_len == 0) || !auth_data ||
+ payload->auth_len != auth_data_len)
break;
+
if (!memcmp(payload->auth_data, auth_data, auth_data_len)) {
SILC_LOG_DEBUG(("Passphrase Authentication successful"));
return TRUE;