+Fri Nov 7 19:38:42 EET 2003 Pekka Riikonen <priikone@silcnet.org>
+
+ * Added some better comments to lib/silccrypt/silcpkcs.h,
+ optimized some routines in lib/silccrypt/silcpkcs.c.
+ Added test_silcpkcs into lib/silccrypt/tests/.
+
+ * Fixed silc_rng_global_init to actually init the global RNG
+ if RNG wasn't provided for it. Affected file is
+ lib/silccrypt/silrng.c.
+
Thu Nov 6 21:08:28 EET 2003 Pekka Riikonen <priikone@silcnet.org>
* Added silc_hash_table_find_by_context_ext. Affected files
bool silc_pkcs_generate_key(SilcPKCS pkcs, SilcUInt32 bits_key_len,
SilcRng rng)
{
- return pkcs->pkcs->init(pkcs->context, bits_key_len, rng);
+ bool ret = pkcs->pkcs->init(pkcs->context, bits_key_len, rng);
+ if (ret)
+ pkcs->key_len = bits_key_len;
+ return ret;
}
/* Returns the length of the key */
public_key = silc_calloc(1, sizeof(*public_key));
public_key->name = strdup(name);
public_key->pk_len = pk_len;
- public_key->pk = silc_calloc(pk_len, sizeof(*public_key->pk));
+ public_key->pk = silc_memdup(pk, pk_len);
public_key->pk_type = SILC_SKE_PK_TYPE_SILC;
- memcpy(public_key->pk, pk, pk_len);
if (!silc_utf8_valid(identifier, strlen(identifier))) {
int len = silc_utf8_encoded_len(identifier, strlen(identifier), 0);
private_key = silc_calloc(1, sizeof(*private_key));
private_key->name = strdup(name);
private_key->prv_len = prv_len;
- private_key->prv = silc_calloc(prv_len, sizeof(*private_key->prv));
- memcpy(private_key->prv, prv, prv_len);
+ private_key->prv = silc_memdup(prv, prv_len);
return private_key;
}
{
if (private_key) {
silc_free(private_key->name);
- silc_free(private_key->prv);
+ if (private_key->prv) {
+ memset(private_key->prv, 0, private_key->prv_len);
+ silc_free(private_key->prv);
+ }
silc_free(private_key);
}
}
unsigned char *
silc_pkcs_public_key_encode(SilcPublicKey public_key, SilcUInt32 *len)
{
- SilcBuffer buf;
- unsigned char *ret;
-
- buf = silc_buffer_alloc_size(public_key->len + 4);
- if (!buf)
- return NULL;
-
- silc_buffer_format(buf,
- SILC_STR_UI_INT(public_key->len),
- SILC_STR_UI_SHORT(strlen(public_key->name)),
- SILC_STR_UI32_STRING(public_key->name),
- SILC_STR_UI_SHORT(strlen(public_key->identifier)),
- SILC_STR_UI32_STRING(public_key->identifier),
- SILC_STR_UI_XNSTRING(public_key->pk,
- public_key->pk_len),
- SILC_STR_END);
-
- ret = silc_buffer_steal(buf, len);
- silc_buffer_free(buf);
- return ret;
+ return silc_pkcs_public_key_data_encode(public_key->pk,
+ public_key->pk_len,
+ public_key->name,
+ public_key->identifier, len);
}
/* Encodes SILC style public key. Returns the encoded data. */
unsigned char *
silc_pkcs_private_key_encode(SilcPrivateKey private_key, SilcUInt32 *len)
{
- SilcBuffer buf;
- unsigned char *ret;
- SilcUInt32 totlen;
-
- totlen = 2 + strlen(private_key->name) + private_key->prv_len;
- buf = silc_buffer_alloc_size(totlen);
- if (!buf)
- return NULL;
-
- silc_buffer_format(buf,
- SILC_STR_UI_SHORT(strlen(private_key->name)),
- SILC_STR_UI32_STRING(private_key->name),
- SILC_STR_UI_XNSTRING(private_key->prv,
- private_key->prv_len),
- SILC_STR_END);
-
- ret = silc_buffer_steal(buf, len);
- silc_buffer_free(buf);
- return ret;
+ return silc_pkcs_private_key_data_encode(private_key->prv,
+ private_key->prv_len,
+ private_key->name, len);
}
/* Encodes SILC private key. Returns the encoded data. */
/*
- silcpkcs.h
+ silcpkcs.h
Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1997 - 2002 Pekka Riikonen
+ Copyright (C) 1997 - 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
* DESCRIPTION
*
* Generate new key pair into the `pkcs' context. Returns FALSE on error.
+ * If the `rng' is NULL global SILC RNG will be used.
*
***/
bool silc_pkcs_generate_key(SilcPKCS pkcs, SilcUInt32 bits_key_len,
*
* DESCRIPTION
*
- * Returns the length of the key.
+ * Returns the length of the key in bits.
*
***/
SilcUInt32 silc_pkcs_get_key_len(SilcPKCS self);
*
* DESCRIPTION
*
- * Returns SILC style public key. The caller must free the returned
- * data.
+ * Returns SILC style public key for the PKCS. Note that this is not
+ * the SILC Public Key, but the raw public key data from the PKCS.
+ * The caller must free the returned data.
*
***/
unsigned char *silc_pkcs_get_public_key(SilcPKCS pkcs, SilcUInt32 *len);
*
* DESCRIPTION
*
- * Returns SILC style private key. The caller must free the returned
- * data and SHOULD zero the memory area before freeing.
+ * Returns SILC style private key. Note that this is not SilcPrivateKey
+ * but the raw private key bits from the PKCS. The caller must free the
+ * returned data and SHOULD zero the memory area before freeing.
*
***/
unsigned char *silc_pkcs_get_private_key(SilcPKCS pkcs, SilcUInt32 *len);
*
* DESCRIPTION
*
- * Sets public key from SilcPublicKey. Returns the length of the key.
+ * Sets public key from SilcPublicKey. Returns the length of the key in
+ * bits.
*
***/
SilcUInt32 silc_pkcs_public_key_set(SilcPKCS pkcs, SilcPublicKey public_key);
*
* DESCRIPTION
*
- * Sets private key from SilcPrivateKey. Returns the length of the key.
+ * Sets private key from SilcPrivateKey. Returns the length of the key
+ * in bits.
*
***/
-SilcUInt32 silc_pkcs_private_key_set(SilcPKCS pkcs, SilcPrivateKey private_key);
+SilcUInt32 silc_pkcs_private_key_set(SilcPKCS pkcs,
+ SilcPrivateKey private_key);
/****f* silccrypt/SilcPKCSAPI/silc_pkcs_private_key_data_set
*
*
* DESCRIPTION
*
- * Verifies signature. Returns FALSE on error.
+ * Verifies signature. Returns FALSE on error. The 'signature' is
+ * verified against the 'data'.
*
***/
bool silc_pkcs_verify(SilcPKCS pkcs, unsigned char *signature,
*
* DESCRIPTION
*
- * Allocates SILC style public key formed from sent arguments. All data
- * is duplicated.
+ * Allocates SILC style public key formed from sent arguments. The
+ * 'name' is the algorithm (PKCS) name, the 'identifier' is the public
+ * key identifier generated with silc_pkcs_encode_identifier, and the
+ * 'pk' and 'pk_len' are the raw public key data returned for example
+ * by silc_pkcs_get_public_key.
*
***/
SilcPublicKey silc_pkcs_public_key_alloc(const char *name,
*
* DESCRIPTION
*
- * Frees public key.
+ * Frees public key and all data in it.
*
***/
void silc_pkcs_public_key_free(SilcPublicKey public_key);
*
* DESCRIPTION
*
- * Allocates SILC private key formed from sent arguments. All data is
- * duplicated.
+ * Allocates SILC private key formed from sent arguments. The 'name'
+ * is the algorithm name, and the 'prv' and 'prv_len' are the raw
+ * private key bits returned by silc_pkcs_get_private_key.
*
***/
SilcPrivateKey silc_pkcs_private_key_alloc(const char *name,
*
* DESCRIPTION
*
- * Frees private key.
+ * Frees private key and all data in it. The private key is zeroed
+ * before it is freed.
*
***/
void silc_pkcs_private_key_free(SilcPrivateKey private_key);
/*
- silcrng.c
+ silcrng.c
Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1997 - 2002 Pekka Riikonen
+ Copyright (C) 1997 - 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
* Created: Sun Mar 9 00:09:18 1997
*
* The original RNG was based on Secure Shell's random number generator
- * by Tatu Ylönen and was used as reference when programming this RNG.
+ * by Tatu Ylönen and was used as reference when programming this RNG.
* This RNG has been rewritten twice since the creation.
*/
static void silc_rng_get_medium_noise(SilcRng rng);
static void silc_rng_get_soft_noise(SilcRng rng);
-/*
+/*
SILC SilcRng State context.
This object is used by the random number generator to provide
struct SilcRngStateContext *next;
} *SilcRngState;
-/*
- SILC Random Number Generator object.
+/*
+ SILC Random Number Generator object.
This object holds random pool which is used to generate the random
numbers used by various routines needing cryptographically strong
}
}
-/* Initializes random number generator by getting noise from environment.
+/* Initializes random number generator by getting noise from environment.
The environmental noise is our so called seed. One should not call
this function more than once. */
first = rng->state;
for (i = SILC_RNG_STATE_NUM - 1; i >= 1; i--) {
next = silc_calloc(1, sizeof(*rng->state));
- next->low =
+ next->low =
(i * (sizeof(rng->pool) / SILC_RNG_STATE_NUM));
next->pos =
(i * (sizeof(rng->pool) / SILC_RNG_STATE_NUM)) + 8;
struct tms ptime;
#endif
SilcUInt32 pos;
-
+
pos = silc_rng_get_position(rng);
silc_rng_xor(rng, clock(), 0);
#ifndef SILC_WIN32
unsigned char buf[32];
int fd, len, i;
-
+
/* Get noise from /dev/[u]random if available */
fd = open(rng->devrandom, O_RDONLY);
if (fd < 0)
FILE *fd;
int i;
int c;
-
+
/* Open process */
fd = popen(command, "r");
if (!fd)
return;
-
+
/* Get data as much as we can get into the buffer */
for (i = 0; i < sizeof(buf); i++) {
c = fgetc(fd);
if (c == EOF)
- break;
+ break;
buf[i] = c;
}
-
+
pclose(fd);
-
+
if (i != 0) {
/* Add the buffer into random pool */
silc_rng_add_noise(rng, buf, i);
#endif
}
-/* This function adds the contents of the buffer as noise into random
+/* This function adds the contents of the buffer as noise into random
pool. After adding the noise the pool is stirred. */
void silc_rng_add_noise(SilcRng rng, unsigned char *buffer, SilcUInt32 len)
SILC_PUT32_MSB(val, &rng->pool[pos]);
}
-/* This function stirs the random pool by encrypting buffer in CFB
+/* This function stirs the random pool by encrypting buffer in CFB
(cipher feedback) mode with SHA1 algorithm. */
static void silc_rng_stir_pool(SilcRng rng)
rng->state->pos = rng->state->low;
#ifdef SILC_RNG_DEBUG
- fprintf(stderr, "state: %p: low: %lu, pos: %lu\n",
+ fprintf(stderr, "state: %p: low: %lu, pos: %lu\n",
rng->state, rng->state->low, rng->state->pos);
#endif
bool silc_rng_global_init(SilcRng rng)
{
- if (rng)
+ if (rng) {
global_rng = rng;
- else
- global_rng = silc_rng_alloc();
+ return TRUE;
+ }
+
+ global_rng = silc_rng_alloc();
+ silc_rng_init(global_rng);
return TRUE;
}
Author: Giovanni Giacobbi <giovanni@giacobbi.net>
- Copyright (C) 1997 - 2002 Pekka Riikonen
+ Copyright (C) 1997 - 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
*/
#if defined(SILC_DEBUG)
#define SILC_LOG_HEXDUMP(fmt, data, len) silc_log_output_hexdump(__FILE__, \
- __FUNCTION__, \
- __LINE__, \
- (data), (len), \
+ __FUNCTION__, \
+ __LINE__, \
+ (void *)(data), (len), \
silc_format fmt)
#else
#define SILC_LOG_HEXDUMP(fmt, data, len)
*
* SYNOPSIS
*
- * bool silc_log_set_file(SilcLogType type, char *filename,
+ * bool silc_log_set_file(SilcLogType type, char *filename,
* SilcUInt32 maxsize,
* SilcSchedule scheduler);
*
* logging settings are not changed.
*
* You can disable logging for a channel by specifying NULL filename, the
- * maxsize in this case is not important. The `scheduler' parameter is
- * needed by the internal logging to allow buffered output and thus to
+ * maxsize in this case is not important. The `scheduler' parameter is
+ * needed by the internal logging to allow buffered output and thus to
* save HD activity.
*
***/
* handler.
*
* You can disable/remove a callback by setting it to NULL or calling the
- * function silc_log_reset_callbacks. If set, the callback function
+ * function silc_log_reset_callbacks. If set, the callback function
* must be in the form described by SilcLogCb.
*
* SEE ALSO