Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 2001 - 2002 Pekka Riikonen
+ Copyright (C) 2001 - 2003 Pekka Riikonen
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;
return payload->auth_method;
}
+/* Get the public data from the auth payload. */
+
+unsigned char *silc_auth_get_public_data(SilcAuthPayload payload,
+ SilcUInt32 *pubdata_len)
+{
+ if (pubdata_len)
+ *pubdata_len = (SilcUInt32)payload->random_len;
+
+ return payload->random_data;
+}
+
/* Get the authentication data. If this is passphrase it is UTF-8 encoded. */
unsigned char *silc_auth_get_data(SilcAuthPayload payload,
SilcUInt32 *auth_len)
{
if (auth_len)
- *auth_len = payload->auth_len;
+ *auth_len = (SilcUInt32)payload->auth_len;
return payload->auth_data;
}
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);
- ret = silc_memdup(buf->data, buf->len);
- if (!ret)
- return NULL;
-
- if (ret_len)
- *ret_len = buf->len;
+ ret = silc_buffer_steal(buf, ret_len);
silc_buffer_free(buf);
silc_free(id_data);
SilcRng rng, SilcHash hash,
const void *id, SilcIdType type)
{
- unsigned char *random;
- unsigned char auth_data[1024];
+ unsigned char *randomdata;
+ SilcBuffer buf;
+
+ /* Get 256 bytes of random data */
+ if (rng)
+ randomdata = silc_rng_get_rn_data(rng, 256);
+ else
+ randomdata = silc_rng_global_get_rn_data(256);
+ if (!randomdata)
+ return NULL;
+
+ buf = silc_auth_public_key_auth_generate_wpub(public_key, private_key,
+ randomdata, 256, hash,
+ id, type);
+
+ memset(randomdata, 0, 256);
+ silc_free(randomdata);
+
+ return buf;
+}
+
+/* Generates Authentication Payload with authentication data. This is used
+ to do public key based authentication. This generates the random data
+ and the actual authentication data. Returns NULL on error. */
+
+SilcBuffer
+silc_auth_public_key_auth_generate_wpub(SilcPublicKey public_key,
+ SilcPrivateKey private_key,
+ const unsigned char *pubdata,
+ SilcUInt32 pubdata_len,
+ SilcHash hash,
+ const void *id, SilcIdType type)
+{
+ unsigned char auth_data[2048 + 1];
SilcUInt32 auth_len;
unsigned char *tmp;
SilcUInt32 tmp_len;
SILC_LOG_DEBUG(("Generating Authentication Payload with data"));
- /* Get 256 bytes of random data */
- if (rng)
- random = silc_rng_get_rn_data(rng, 256);
- else
- random = silc_rng_global_get_rn_data(256);
- if (!random)
- 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, pubdata, pubdata_len, 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(tmp, 0, tmp_len);
silc_free(tmp);
- silc_free(random);
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, pubdata, pubdata_len,
auth_data, auth_len);
memset(tmp, 0, tmp_len);
memset(auth_data, 0, sizeof(auth_data));
- memset(random, 0, 256);
silc_free(tmp);
- silc_free(random);
silc_pkcs_free(pkcs);
return buf;
&newp->hostname_len),
SILC_STR_UI_INT(&newp->port),
SILC_STR_END);
- if (ret == -1) {
+ if (ret == -1 || newp->hostname_len > buffer.len - 6) {
silc_free(newp);
return NULL;
}