updates.
authorPekka Riikonen <priikone@silcnet.org>
Sat, 16 Mar 2002 17:54:53 +0000 (17:54 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Sat, 16 Mar 2002 17:54:53 +0000 (17:54 +0000)
35 files changed:
CHANGES
TODO
TODO-1.0
apps/irssi/src/silc/core/clientutil.c
apps/irssi/src/silc/core/silc-core.c
apps/irssi/src/silc/core/silc-core.h
apps/silcd/packet_send.c
apps/silcd/server.c
apps/silcd/serverconfig.c
apps/silcd/silcd.c
lib/silcclient/client_channel.c
lib/silcclient/client_ftp.c
lib/silcclient/client_prvmsg.c
lib/silcclient/command.c
lib/silccore/silcauth.c
lib/silccore/silcauth.h
lib/silccore/silcchannel.c
lib/silccore/silcchannel.h
lib/silccore/silcprivate.c
lib/silccore/silcprivate.h
lib/silccrypt/rsa.c
lib/silccrypt/silccipher.c
lib/silccrypt/silchash.c
lib/silccrypt/silchmac.c
lib/silccrypt/silcpkcs.c
lib/silccrypt/silcpkcs.h
lib/silcmath/silcmath.h
lib/silcmath/silcprimegen.c
lib/silcsftp/sftp_client.c
lib/silcsftp/sftp_server.c
lib/silcsftp/silcsftp.h
lib/silcsim/silcsim.c
lib/silcsim/silcsim.h
lib/silcutil/silcnet.c
lib/silcutil/silcutil.c

diff --git a/CHANGES b/CHANGES
index d2b8fed1b9651128574d2b7fd055a59f52dee402..90cf547086a6fcf169b3ea17fe1017602ff4ca82 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,35 @@
+Sat Mar 16 18:04:30 EET 2002  Pekka Riikonen <priikone@silcnet.org>
+
+       * Changed all library interfaces that use Global RNG to also
+         accept SilcRng as argument.  Affected files are
+         lib/silcclient/command.c, lib/silccore/silcauth.[ch],
+         lib/silccore/silcchanel.[ch], lib/silcclient/client_channel.c,
+         silcd/packet_send.c, lib/silccore/silcprivate.[ch],
+         lib/silcmath/silcprimegen.c, lib/silcmath/silcmath.h, and
+         lib/silccrypt/rsa.c.
+
+       * Added function silc_pkcs_generate_key to the
+         lib/silccrypt/silcpkcs.[ch] for applications so that they
+         don't need to do pkcs->pkcs->init calls anymore.
+
+       * Remove SilcSocketConnection from the SFTP API since it really
+         wasn't needed there.  The application has the information
+         saved in its contexts anyway and the SFTP layer doesn't need
+         know about it.  Affected files lib/silcsft/silcsftp.h and
+         lib/silcsftp/sftp_[server/client].c.
+
+       * Rewrote the SILC SIM (modules) interface in lib/silcsim.[ch].
+         The SilcSimContext is not SilcSim.
+
+       * Fixed possible buffer overflows in silc_id_render in the
+         lib/silcutil/silcutil.c.
+
+       * On EPOC the global crypto module lists are not used at all
+         in the crypto library.  Added support for using the constant
+         algorithm list on EPOC.  Affected files are
+         lib/silccrypt/silccipher.c, silchash.c, silchmac.c and
+         silcpkcs.c.
+
 Sat Mar 16 09:07:27 EET 2002  Pekka Riikonen <priikone@silcnet.org>
 
        * Handled CHANNEL_CHANGE notify (ignore it) in Irssi SILC
diff --git a/TODO b/TODO
index 322e71f0792fc5dee65317a83331b397127010e0..e4ff0f1b20a06ae9722591c5337304cb743d8f4d 100644 (file)
--- a/TODO
+++ b/TODO
@@ -79,45 +79,14 @@ TODO/bugs In SILC Server
 TODO/bugs In SILC Libraries
 ===========================
 
- o Fix possible buffer overflows in silc_id_render function.
-
  o WIN32 silc_net_create_connection_async does not work the same way
    than on Unix.  Do it with threads on WIN32.  The function works but
    is not actually async currently.
 
- o Rewrite the lib/silcsim/silcsim.h.  The SilcSimContext should be
-   private and silc_sim_alloc should take necessary arguments.
-
- o SILC RNG does not implement random seed files, and they should be
-   implemented.
-
- o The SilcSocketConnection in the SFTP interface is actually redundant
-   and should perhaps be removed.  The application can save it in the
-   context it provides, which is delivered by SFTP libary to all 
-   callback functions.
-
  o EPOC specific additions/changes required:
 
        o lib/silcutil/epoc routines missing or not completed.
 
-       o Rewrite the lib/silcutil/silcprotocol.[ch] not to have 
-         [un]register functions, but to make it context based all the 
-         way.  The alloc should take as argument the protocol type and 
-         its callback (not only final callback).  It is not good that we 
-         have now global list of registered protocols.
-
-       o Global RNG should not be allowed on EPOC, since it won't
-         work.  Every function in library that calls the global RNG must
-         also take the RNG context as argument so that application can
-         provide it if it doesn't want to use global RNG.
-
-       o Think some solution to the global crypto lists in lib/silccrypt.
-         They won't work on EPOC.
-
-       o Something needs to be thought to the logging globals as well, 
-         like silc_debug etc.  They won't work on EPOC.  Perhaps logging
-         and debugging is to be disabled on EPOC.
-
 
 TODO in Toolkit Documentation
 =============================
@@ -220,3 +189,6 @@ describe new stuff to be added to protocol versions 1.x.
 
  12. The router to router connection diagram in spec-xx is showing the
      primary routers direction to wrong direction.  Swap it.
+
+ 13. Add the killer's client ID to the KILLED notify.  To be included in 
+     protocol version 1.1.
index cc751428bd4bef498f10224e0565141bece29183..814075631fe9c44b62620f0889d420fd9b26068a 100644 (file)
--- a/TODO-1.0
+++ b/TODO-1.0
@@ -132,12 +132,32 @@ least could be done.
          SERVER_SIGNOFF away entirely).
 
  o Add SilcAsyncOperation to utility library.  Any function that takes
-   callback as an argument must return SilcAsyncOperation.
+   callback as an argument must/should return SilcAsyncOperation (see 
+   ~/silcasync).
+
+ o Rewrite SilcProtocol to be SilcFSM (see ~/silcfsm).
+
+ o Change SILC_TASK_CALLBACK to non-static, and remove the macro
+   SILC_TASK_CALLBACK_GLOBAL.
 
  o Add DSS support.
 
+ o SILC RNG does not implement random seed files, and they should be
+   implemented.
+
  o Cipher optimizations (asm, that this) at least for i386 would be nice.
 
  o Add builtin SOCKS and HTTP Proxy support, well the SOCKS at least.
    SILC currently supports SOCKS4 and SOCKS5 but it needs to be compiled
    in separately.
+
+ o EPOC specific additions/changes required:
+
+       o In lib/silccore/silcpacket.c global RNG is used.  Change the
+         interface for that function.  The PKCS#1 also calls global RNG
+         (even though it is not used currently in SILC, the interface
+         allows its use).
+
+       o Something needs to be thought to the logging globals as well, 
+         like silc_debug etc.  They won't work on EPOC.  Perhaps logging
+         and debugging is to be disabled on EPOC.
index 93b575fe9a5fdc14a38da05166f101a169c7ce1d..3e3c13c7370c46619d7ed0191de03200493e02c5 100644 (file)
@@ -245,7 +245,7 @@ New pair of keys will be created.  Please, answer to following questions.\n\
 
   /* Generate keys */
   silc_pkcs_alloc(pkcs_name, &pkcs);
-  pkcs->pkcs->init(pkcs->context, bits, rng);
+  silc_pkcs_generate_key(pkcs, bits, rng);
 
   /* Save public key into file */
   key = silc_pkcs_get_public_key(pkcs, &key_len);
index 8ddbe364f85a2bc890293b1deb75dff5fa8e898e..a58a1ec3a2d9e92b8ec75899bcd7a7de2459887b 100644 (file)
@@ -50,11 +50,6 @@ SilcClient silc_client = NULL;
 extern SilcClientOperations ops;
 extern bool silc_debug;
 extern bool silc_debug_hexdump;
-#ifdef SILC_SIM
-/* SIM (SILC Module) table */
-SilcSimContext **sims = NULL;
-SilcUInt32 sims_count = 0;
-#endif
 
 void silc_expandos_init(void);
 void silc_expandos_deinit(void);
index 47467f2875ac50b7111819f58b5f6063cb290aec..bae19a0aef1e95df55ad7644a5eae2833254ee05 100644 (file)
 
 extern SilcClient silc_client;
 
-#ifdef SILC_SIM
-/* SIM (SILC Module) table */
-extern SilcSimContext **sims;
-extern SilcUInt32 sims_count;
-#endif
-
 #define IS_SILC_ITEM(rec) (IS_SILC_CHANNEL(rec) || IS_SILC_QUERY(rec))
 
 #endif
index 7ead93203810eb2a313b86b1e0df631b6e7735a2..4519cc75446464e5cbc489dc90a6924d511030a7 100644 (file)
@@ -710,7 +710,7 @@ silc_server_packet_relay_to_channel_encrypt(SilcServer server,
     chp = silc_channel_message_payload_encode(flags, dlen, data + 4,
                                              iv_len, channel->iv,
                                              channel->channel_key,
-                                             channel->hmac);
+                                             channel->hmac, NULL);
     memcpy(data, chp->data, chp->len);
     silc_buffer_free(chp);
   }
index 1f468f1dac29103a9450488c7af211a98e8f44c5..c00001d9db9be0968ac02a3c3aa562a1371fa459 100644 (file)
@@ -74,7 +74,7 @@ void silc_server_free(SilcServer server)
 {
   if (server) {
 #ifdef SILC_SIM
-    SilcSimContext *sim;
+    SilcSim sim;
 #endif
 
     silc_free(server->local_list);
index 0a0bfe55ee4762a35aefc556d1f6a281d52f0706..2e4773c77ffdb465725a5140570cfa873b5816f6 100644 (file)
@@ -1326,7 +1326,7 @@ bool silc_server_config_register_ciphers(SilcServer server)
       /* Load (try at least) the crypto SIM module */
       char buf[1023], *alg_name;
       SilcCipherObject cipher_obj;
-      SilcSimContext *sim;
+      SilcSim sim;
 
       memset(&cipher_obj, 0, sizeof(cipher_obj));
       cipher_obj.name = cipher->name;
@@ -1336,9 +1336,7 @@ bool silc_server_config_register_ciphers(SilcServer server)
       /* build the libname */
       snprintf(buf, sizeof(buf), "%s/%s", config->module_path,
                cipher->module);
-      sim = silc_sim_alloc();
-      sim->type = SILC_SIM_CIPHER;
-      sim->libname = buf;
+      sim = silc_sim_alloc(SILC_SIM_CIPHER, buf, 0);
 
       alg_name = strdup(cipher->name);
       if (strchr(alg_name, '-'))
@@ -1426,16 +1424,14 @@ bool silc_server_config_register_hashfuncs(SilcServer server)
 #ifdef SILC_SIM
       /* Load (try at least) the hash SIM module */
       SilcHashObject hash_obj;
-      SilcSimContext *sim;
+      SilcSim sim;
 
       memset(&hash_obj, 0, sizeof(hash_obj));
       hash_obj.name = hash->name;
       hash_obj.block_len = hash->block_length;
       hash_obj.hash_len = hash->digest_length;
 
-      sim = silc_sim_alloc();
-      sim->type = SILC_SIM_HASH;
-      sim->libname = hash->module;
+      sim = silc_sim_alloc(SILC_SIM_HASH, hash->module, 0);
 
       if ((silc_sim_load(sim))) {
        hash_obj.init =
index 84e35dc4aab629b45a250e625db6410b121e3b25..21af435ba25be1a0e11cbf9962a732c3234048de 100644 (file)
@@ -357,7 +357,7 @@ silc_server_create_key_pair(char *pkcs_name, int bits, char *path,
 
   /* Generate keys */
   silc_pkcs_alloc(pkcs_name, &pkcs);
-  pkcs->pkcs->init(pkcs->context, bits, rng);
+  silc_pkcs_generate_key(pkcs, bits, rng);
 
   /* Save public key into file */
   key = silc_pkcs_get_public_key(pkcs, &key_len);
index c98a8823909d602fe8b666995b99e7e0f5e4e5ed..ee2cc2b8eccd26e45cfb6ec1cda4e3182f4dcf65 100644 (file)
@@ -101,7 +101,8 @@ void silc_client_send_channel_message(SilcClient client,
 
   /* Encode the channel payload. This also encrypts the message payload. */
   payload = silc_channel_message_payload_encode(flags, data_len, data, iv_len, 
-                                               channel->iv, cipher, hmac);
+                                               channel->iv, cipher, hmac,
+                                               client->rng);
 
   /* Get data used in packet header encryption, keys and stuff. */
   cipher = conn->send_key;
index 73681d15d4165b8bfd2881276d9a0faf25df830e..494923b19a6077ed3e5a184316f3048ba5999921 100644 (file)
@@ -159,8 +159,7 @@ silc_client_connect_to_client(SilcClient client,
 /* SFTP packet send callback. This will use preallocated buffer to avoid
    reallocation of outgoing data buffer everytime. */
 
-static void silc_client_ftp_send_packet(SilcSocketConnection sock,
-                                       SilcBuffer packet, void *context)
+static void silc_client_ftp_send_packet(SilcBuffer packet, void *context)
 {
   SilcClientFtpSession session = (SilcClientFtpSession)context;
   SilcClient client = session->client;
@@ -183,8 +182,9 @@ static void silc_client_ftp_send_packet(SilcSocketConnection sock,
                     SILC_STR_END);
 
   /* Send the packet immediately */
-  silc_client_packet_send(client, sock, SILC_PACKET_FTP, NULL, 0, NULL, NULL,
-                         session->packet->data, session->packet->len, TRUE);
+  silc_client_packet_send(client, session->sock, SILC_PACKET_FTP, NULL, 
+                         0, NULL, NULL, session->packet->data, 
+                         session->packet->len, TRUE);
 
   /* Clear buffer */
   session->packet->data = session->packet->tail = session->packet->head;
@@ -490,14 +490,12 @@ SILC_TASK_CALLBACK(silc_client_ftp_key_agreement_final)
   if (!session->server) {
     /* If we are the SFTP client then start the SFTP session and retrieve
        the info about the file available for download. */
-    session->sftp = silc_sftp_client_start(conn->sock,
-                                          silc_client_ftp_send_packet,
-                                          session, 
-                                          silc_client_ftp_version, session);
+    session->sftp = silc_sftp_client_start(silc_client_ftp_send_packet,
+                                          session, silc_client_ftp_version, 
+                                          session);
   } else {
     /* Start SFTP server */
-    session->sftp = silc_sftp_server_start(conn->sock,
-                                          silc_client_ftp_send_packet,
+    session->sftp = silc_sftp_server_start(silc_client_ftp_send_packet,
                                           session, session->fs);
 
     /* Monitor transmission */
index e472853fecf10f8487623d4d9bfee40fe472caab..eb90186885a55de14ff53fdf507886f0a471d2bb 100644 (file)
@@ -53,7 +53,8 @@ void silc_client_send_private_message(SilcClient client,
   /* Encode private message payload */
   buffer = silc_private_message_payload_encode(flags,
                                               data_len, data,
-                                              client_entry->send_key);
+                                              client_entry->send_key,
+                                              client->rng);
 
   /* If we don't have private message specific key then private messages
      are just as any normal packet thus call normal packet sending.  If
index 2a388e96459215d6f69dc6448a17747e27ff65ca..48a0fa56231cd50841b5b8f375d6fd1d5731c718 100644 (file)
@@ -987,7 +987,7 @@ SILC_CLIENT_CMD_FUNC(join)
       if (!strcasecmp(cmd->argv[i + 1], "-pubkey")) {
        auth = silc_auth_public_key_auth_generate(cmd->client->public_key,
                                                  cmd->client->private_key,
-                                                 conn->hash,
+                                                 cmd->client->rng, conn->hash,
                                                  conn->local_id,
                                                  SILC_ID_CLIENT);
       } else {
@@ -1336,6 +1336,7 @@ SILC_CLIENT_CMD_FUNC(cmode)
        if (!strcasecmp(cmd->argv[3], "-pubkey")) {
          auth = silc_auth_public_key_auth_generate(cmd->client->public_key,
                                                    cmd->client->private_key,
+                                                   cmd->client->rng, 
                                                    conn->hash,
                                                    conn->local_id,
                                                    SILC_ID_CLIENT);
@@ -1494,6 +1495,7 @@ SILC_CLIENT_CMD_FUNC(cumode)
          if (!strcasecmp(cmd->argv[4], "-pubkey")) {
            auth = silc_auth_public_key_auth_generate(cmd->client->public_key,
                                                      cmd->client->private_key,
+                                                     cmd->client->rng,
                                                      conn->hash,
                                                      conn->local_id,
                                                      SILC_ID_CLIENT);
@@ -1660,7 +1662,7 @@ static void silc_client_command_oper_send(unsigned char *data,
     /* Encode the public key authentication payload */
     auth = silc_auth_public_key_auth_generate(cmd->client->public_key,
                                              cmd->client->private_key,
-                                             conn->hash,
+                                             cmd->client->rng, conn->hash,
                                              conn->local_id,
                                              SILC_ID_CLIENT);
   } else {
@@ -1728,7 +1730,7 @@ static void silc_client_command_silcoper_send(unsigned char *data,
     /* Encode the public key authentication payload */
     auth = silc_auth_public_key_auth_generate(cmd->client->public_key,
                                              cmd->client->private_key,
-                                             conn->hash,
+                                             cmd->client->rng, conn->hash,
                                              conn->local_id,
                                              SILC_ID_CLIENT);
   } else {
index b3fb455891707f1efc0f250078a14cf40a675616..6e73a9f468bff84c7d84f0ee993e1bc32c613d22 100644 (file)
@@ -208,7 +208,7 @@ silc_auth_public_key_encode_data(SilcPublicKey public_key,
 
 SilcBuffer silc_auth_public_key_auth_generate(SilcPublicKey public_key,
                                              SilcPrivateKey private_key,
-                                             SilcHash hash,
+                                             SilcRng rng, SilcHash hash,
                                              const void *id, SilcIdType type)
 {
   unsigned char *random;
@@ -222,7 +222,10 @@ SilcBuffer silc_auth_public_key_auth_generate(SilcPublicKey public_key,
   SILC_LOG_DEBUG(("Generating Authentication Payload with data"));
 
   /* Get 256 bytes of random data */
-  random = silc_rng_global_get_rn_data(256);
+  if (rng)
+    random = silc_rng_get_rn_data(rng, 256);
+  else
+    random = silc_rng_global_get_rn_data(256);
   if (!random)
     return NULL;
   
index 008a8ead0fe10f6dbe04bb598904c25f6b2a7eb9..38a0a418b3938aa1b00b8c244547c78dee667ad0 100644 (file)
@@ -185,6 +185,7 @@ unsigned char *silc_auth_get_data(SilcAuthPayload payload,
  *
  *    SilcBuffer silc_auth_public_key_auth_generate(SilcPublicKey public_key,
  *                                                  SilcPrivateKey private_key,
+ *                                                  SilcRng rng,
  *                                                  SilcHash hash,
  *                                                  const void *id, 
  *                                                  SilcIdType type);
@@ -196,10 +197,16 @@ unsigned char *silc_auth_get_data(SilcAuthPayload payload,
  *    and the actual authentication data. Returns NULL on error and the
  *    encoded Authentication Payload on success.
  *
+ *    The `private_key' is used to sign the payload.  The `public_key', the
+ *    and the `id' is encoded in the payload and signed.  If the `rng' is
+ *    NULL then global RNG is used, if non-NULL then `rng' is used as
+ *    random number generator.  Also random number is encoded in the
+ *    payload before signing it with `private_key'.
+ *
  ***/
 SilcBuffer silc_auth_public_key_auth_generate(SilcPublicKey public_key,
                                              SilcPrivateKey private_key,
-                                             SilcHash hash,
+                                             SilcRng rng, SilcHash hash,
                                              const void *id, SilcIdType type);
 
 /****f* silccore/SilcAuthAPI/silc_auth_public_key_auth_verify
index 8fcc4c539be5cfbbb652a702f3f8fae962a9ee3f..cb28fab434df0b27f4551938921bc6c133bb6b36 100644 (file)
@@ -370,7 +370,8 @@ SilcBuffer silc_channel_message_payload_encode(SilcUInt16 flags,
                                               SilcUInt16 iv_len,
                                               unsigned char *iv,
                                               SilcCipher cipher,
-                                              SilcHmac hmac)
+                                              SilcHmac hmac,
+                                              SilcRng rng)
 {
   int i;
   SilcBuffer buffer;
@@ -393,7 +394,11 @@ SilcBuffer silc_channel_message_payload_encode(SilcUInt16 flags,
     return NULL;
 
   /* Generate padding */
-  for (i = 0; i < pad_len; i++) pad[i] = silc_rng_global_get_byte();
+  if (rng) {
+    for (i = 0; i < pad_len; i++) pad[i] = silc_rng_get_byte(rng);
+  } else {
+    for (i = 0; i < pad_len; i++) pad[i] = silc_rng_global_get_byte();
+  }
 
   /* Encode the Channel Message Payload */
   silc_buffer_pull_tail(buffer, 6 + data_len + pad_len);
index fe4ce3a2aff2b59f86533d8399b985c26341e43a..3b734fba9d79b5500a6bc13aa3fbf34f0c366505 100644 (file)
@@ -326,7 +326,8 @@ silc_channel_message_payload_parse(unsigned char *payload,
  *                                                   SilcUInt16 iv_len,
  *                                                   unsigned char *iv,
  *                                                   SilcCipher cipher,
- *                                                   SilcHmac hmac);
+ *                                                   SilcHmac hmac.
+ *                                                   SilcRng rng);
  *
  * DESCRIPTION
  *
@@ -336,7 +337,8 @@ silc_channel_message_payload_parse(unsigned char *payload,
  *    must be applied to the payload. The function generates the padding
  *    automatically from random data.  The `cipher' is the cipher used
  *    encrypt the payload and `hmac' is used to compute the MAC for the
- *    payload.
+ *    payload.  If `rng' is NULL then global RNG is used, if non-NULL then
+ *    the `rng' is used.
  *
  ***/
 SilcBuffer silc_channel_message_payload_encode(SilcUInt16 flags,
@@ -345,7 +347,8 @@ SilcBuffer silc_channel_message_payload_encode(SilcUInt16 flags,
                                               SilcUInt16 iv_len,
                                               unsigned char *iv,
                                               SilcCipher cipher,
-                                              SilcHmac hmac);
+                                              SilcHmac hmac,
+                                              SilcRng rng);
 
 /****f* silccore/SilcChannelAPI/silc_channel_message_payload_free
  *
index fa9bfa9e926e9af2249344600b84efbdc507de4d..6136dc75349eb720bae50ac568731c558616adfc 100644 (file)
@@ -95,7 +95,8 @@ silc_private_message_payload_parse(unsigned char *payload,
 SilcBuffer silc_private_message_payload_encode(SilcUInt16 flags,
                                               SilcUInt16 data_len,
                                               const unsigned char *data,
-                                              SilcCipher cipher)
+                                              SilcCipher cipher,
+                                              SilcRng rng)
 {
   int i;
   SilcBuffer buffer;
index d4f6abff617330f5c93fd5183246a2c77dff919c..766485defbdbaff23f04bf648323387950661c1f 100644 (file)
@@ -77,19 +77,22 @@ silc_private_message_payload_parse(unsigned char *payload,
  *    SilcBuffer silc_private_message_payload_encode(SilcUInt16 flags,
  *                                                   SilcUInt16 data_len,
  *                                                   const unsigned char *data,
- *                                                   SilcCipher cipher);
+ *                                                   SilcCipher cipher,
+ *                                                   SilcRng rng);
  *
  * DESCRIPTION
  *
  *    Encodes private message payload into a buffer and returns it.  If
  *    the cipher is provided the packet is also encrypted here.  It is provided
- *    if the private message private keys are used.
+ *    if the private message private keys are used.  If the `rng' is NULL
+ *    then global RNG is used, if non-NULL then `rng' is used.
  *
  ***/
 SilcBuffer silc_private_message_payload_encode(SilcUInt16 flags,
                                               SilcUInt16 data_len,
                                               const unsigned char *data,
-                                              SilcCipher cipher);
+                                              SilcCipher cipher,
+                                              SilcRng rng);
 
 /****f* silccore/SilcPrivateAPI/silc_private_message_payload_free
  *
index b0b7bf50cde27c2fe68c108360dfa511df3e0503..47158aab0a4700fc79a31101a154bc5391229b2b 100644 (file)
      The `tmplen' in encrypt, decrypt, sign and verify PKCS API functions
      is now calculated by (key->bits + 7) / 8.  It is the length of one block.
 
+   o Sat Mar 16 18:27:19 EET 2002  Pekka
+
+     Use the SilcRng sent as argument to SILC_PKCS_API_INIT in prime 
+     generation.
+
 */
 
 #include "silcincludes.h"
@@ -87,10 +92,10 @@ SILC_PKCS_API_INIT(rsa)
   /* Find p and q */
   while (!found) {
     printf("Finding p: ");
-    silc_math_gen_prime(&p, prime_bits, TRUE);
+    silc_math_gen_prime(&p, prime_bits, TRUE, rng);
     
     printf("\nFinding q: ");
-    silc_math_gen_prime(&q, prime_bits, TRUE);
+    silc_math_gen_prime(&q, prime_bits, TRUE, rng);
 
     if ((silc_mp_cmp(&p, &q)) == 0)
       printf("\nFound equal primes, not good, retrying...\n");
index d07de22af88d5e9e43a63dd25d732006dcfc9877..27e63395a30f9e27efc0d410235e2984b89b73ff 100644 (file)
 /* $Id$ */
 
 #include "silcincludes.h"
-
 #include "ciphers.h"           /* Includes cipher definitions */
 
+#ifndef SILC_EPOC
 /* Dynamically registered list of ciphers. */
 SilcDList silc_cipher_list = NULL;
+#endif /* SILC_EPOC */
 
 /* Static list of ciphers for silc_cipher_register_default(). */
 const SilcCipherObject silc_default_ciphers[] =
@@ -91,6 +92,7 @@ const SilcCipherObject silc_default_ciphers[] =
 
 bool silc_cipher_register(SilcCipherObject *cipher)
 {
+#ifndef SILC_EPOC
   SilcCipherObject *new;
 
   SILC_LOG_DEBUG(("Registering new cipher `%s'", cipher->name));
@@ -120,6 +122,7 @@ bool silc_cipher_register(SilcCipherObject *cipher)
     silc_cipher_list = silc_dlist_init();
   silc_dlist_add(silc_cipher_list, new);
 
+#endif /* SILC_EPOC */
   return TRUE;
 }
 
@@ -127,6 +130,7 @@ bool silc_cipher_register(SilcCipherObject *cipher)
 
 bool silc_cipher_unregister(SilcCipherObject *cipher)
 {
+#ifndef SILC_EPOC
   SilcCipherObject *entry;
 
   SILC_LOG_DEBUG(("Unregistering cipher"));
@@ -150,6 +154,7 @@ bool silc_cipher_unregister(SilcCipherObject *cipher)
     }
   }
 
+#endif /* SILC_EPOC */
   return FALSE;
 }
 
@@ -159,11 +164,13 @@ bool silc_cipher_unregister(SilcCipherObject *cipher)
 
 bool silc_cipher_register_default(void)
 {
+#ifndef SILC_EPOC
   int i;
 
   for (i = 0; silc_default_ciphers[i].name; i++)
     silc_cipher_register((SilcCipherObject *)&(silc_default_ciphers[i]));
 
+#endif /* SILC_EPOC */
   return TRUE;
 }
 
@@ -174,25 +181,41 @@ bool silc_cipher_register_default(void)
 
 bool silc_cipher_alloc(const unsigned char *name, SilcCipher *new_cipher)
 {
-  SilcCipherObject *entry;
+  SilcCipherObject *entry = NULL;
 
   SILC_LOG_DEBUG(("Allocating new cipher object"));
   
+#ifndef SILC_EPOC
   if (silc_cipher_list) {
     silc_dlist_start(silc_cipher_list);
     while ((entry = silc_dlist_get(silc_cipher_list)) != SILC_LIST_END) {
-      if (!strcmp(entry->name, name)) {
-       *new_cipher = silc_calloc(1, sizeof(**new_cipher));
-       (*new_cipher)->cipher = entry; 
-       (*new_cipher)->context = silc_calloc(1, entry->context_len());
-       (*new_cipher)->set_iv = silc_cipher_set_iv;
-       (*new_cipher)->get_iv = silc_cipher_get_iv;
-       (*new_cipher)->get_key_len = silc_cipher_get_key_len;
-       (*new_cipher)->get_block_len = silc_cipher_get_block_len;
-       return TRUE;
+      if (!strcmp(entry->name, name))
+       break;
+    }
+  }
+#else
+  {
+    /* On EPOC which don't have globals we check our constant cipher list. */
+    int i;
+    for (i = 0; silc_default_ciphers[i].name; i++) {
+      if (!strcmp(silc_default_ciphers[i].name, name)) {
+       entry = (SilcCipherObject *)&(silc_default_ciphers[i]);
+       break;
       }
     }
   }
+#endif /* SILC_EPOC */
+
+  if (entry) {
+    *new_cipher = silc_calloc(1, sizeof(**new_cipher));
+    (*new_cipher)->cipher = entry; 
+    (*new_cipher)->context = silc_calloc(1, entry->context_len());
+    (*new_cipher)->set_iv = silc_cipher_set_iv;
+    (*new_cipher)->get_iv = silc_cipher_get_iv;
+    (*new_cipher)->get_key_len = silc_cipher_get_key_len;
+    (*new_cipher)->get_block_len = silc_cipher_get_block_len;
+    return TRUE;
+  }
 
   return FALSE;
 }
@@ -211,6 +234,7 @@ void silc_cipher_free(SilcCipher cipher)
 
 bool silc_cipher_is_supported(const unsigned char *name)
 {
+#ifndef SILC_EPOC
   SilcCipherObject *entry;
 
   if (silc_cipher_list) {
@@ -220,7 +244,14 @@ bool silc_cipher_is_supported(const unsigned char *name)
        return TRUE;
     }
   }
-
+#else
+  {
+    int i;
+    for (i = 0; silc_default_ciphers[i].name; i++)
+      if (!strcmp(silc_default_ciphers[i].name, name))
+       return TRUE;
+  }
+#endif /* SILC_EPOC */
   return FALSE;
 }
 
@@ -230,9 +261,9 @@ char *silc_cipher_get_supported(void)
 {
   SilcCipherObject *entry;
   char *list = NULL;
-  int len;
+  int len = 0;
 
-  len = 0;
+#ifndef SILC_EPOC
   if (silc_cipher_list) {
     silc_dlist_start(silc_cipher_list);
     while ((entry = silc_dlist_get(silc_cipher_list)) != SILC_LIST_END) {
@@ -244,8 +275,24 @@ char *silc_cipher_get_supported(void)
       memcpy(list + len, ",", 1);
       len++;
     }
-    list[len - 1] = 0;
   }
+#else
+  {
+    int i;
+    for (i = 0; silc_default_ciphers[i].name; i++) {
+      entry = (SilcCipherObject *)&(silc_default_ciphers[i]);
+      len += strlen(entry->name);
+      list = silc_realloc(list, len + 1);
+      
+      memcpy(list + (len - strlen(entry->name)), 
+            entry->name, strlen(entry->name));
+      memcpy(list + len, ",", 1);
+      len++;
+    }
+  }
+#endif /* SILC_EPOC */
+
+  list[len - 1] = 0;
 
   return list;
 }
index 66a6ab8ef5dcf8e0dbb06979c7686ddf666b9790..138ba09c8f14f2c0dc2e73717a63ce2bec7180c3 100644 (file)
 #include "md5.h"
 #include "sha1.h"
 
+#ifndef SILC_EPOC
 /* List of dynamically registered hash functions. */
 SilcDList silc_hash_list = NULL;
+#endif /* SILC_EPOC */
 
 /* Default hash functions for silc_hash_register_default(). */
 const SilcHashObject silc_default_hash[] = 
@@ -43,6 +45,7 @@ const SilcHashObject silc_default_hash[] =
 
 bool silc_hash_register(SilcHashObject *hash)
 {
+#ifndef SILC_EPOC
   SilcHashObject *new;
 
   SILC_LOG_DEBUG(("Registering new hash function `%s'", hash->name));
@@ -72,6 +75,7 @@ bool silc_hash_register(SilcHashObject *hash)
     silc_hash_list = silc_dlist_init();
   silc_dlist_add(silc_hash_list, new);
 
+#endif /* SILC_EPOC */
   return TRUE;
 }
 
@@ -79,6 +83,7 @@ bool silc_hash_register(SilcHashObject *hash)
 
 bool silc_hash_unregister(SilcHashObject *hash)
 {
+#ifndef SILC_EPOC
   SilcHashObject *entry;
 
   SILC_LOG_DEBUG(("Unregistering hash function"));
@@ -100,6 +105,7 @@ bool silc_hash_unregister(SilcHashObject *hash)
     }
   }
 
+#endif /* SILC_EPOC */
   return FALSE;
 }
 
@@ -109,11 +115,13 @@ bool silc_hash_unregister(SilcHashObject *hash)
 
 bool silc_hash_register_default(void)
 {
+#ifndef SILC_EPOC
   int i;
 
   for (i = 0; silc_default_hash[i].name; i++)
     silc_hash_register((SilcHashObject *)&(silc_default_hash[i]));
 
+#endif /* SILC_EPOC */
   return TRUE;
 }
 
@@ -122,22 +130,37 @@ bool silc_hash_register_default(void)
 
 bool silc_hash_alloc(const unsigned char *name, SilcHash *new_hash)
 {
-  SilcHashObject *entry;
+  SilcHashObject *entry = NULL;
   
   SILC_LOG_DEBUG(("Allocating new hash object"));
 
+#ifndef SILC_EPOC
   if (silc_hash_list) {
     silc_dlist_start(silc_hash_list);
     while ((entry = silc_dlist_get(silc_hash_list)) != SILC_LIST_END) {
-      if (!strcmp(entry->name, name)) {
-       *new_hash = silc_calloc(1, sizeof(**new_hash));
-       (*new_hash)->hash = entry;
-       (*new_hash)->context = silc_calloc(1, entry->context_len());
-       (*new_hash)->make_hash = silc_hash_make;
-       return TRUE;
+      if (!strcmp(entry->name, name))
+       break;
+    }
+  }
+#else
+  {
+    /* On EPOC which don't have globals we check our constant hash list. */
+    int i;
+    for (i = 0; silc_default_hash[i].name; i++) {
+      if (!strcmp(silc_default_hash[i].name, name)) {
+       entry = (SilcHashObject *)&(silc_default_hash[i]);
+       break;
       }
     }
   }
+#endif /* SILC_EPOC */
+
+  if (entry) {
+    *new_hash = silc_calloc(1, sizeof(**new_hash));
+    (*new_hash)->hash = entry;
+    (*new_hash)->context = silc_calloc(1, entry->context_len());
+    (*new_hash)->make_hash = silc_hash_make;
+  }
 
   return FALSE;
 }
@@ -163,6 +186,7 @@ SilcUInt32 silc_hash_len(SilcHash hash)
 
 bool silc_hash_is_supported(const unsigned char *name)
 {
+#ifndef SILC_EPOC
   SilcHashObject *entry;
 
   if (silc_hash_list) {
@@ -172,7 +196,14 @@ bool silc_hash_is_supported(const unsigned char *name)
        return TRUE;
     }
   }
-
+#else
+  {
+    int i;
+    for (i = 0; silc_default_hash[i].name; i++)
+      if (!strcmp(silc_default_hash[i].name, name))
+       return TRUE;
+  }
+#endif /* SILC_EPOC */
   return FALSE;
 }
 
@@ -182,9 +213,9 @@ char *silc_hash_get_supported(void)
 {
   SilcHashObject *entry;
   char *list = NULL;
-  int len;
+  int len = 0;
 
-  len = 0;
+#ifndef SILC_EPOC
   if (silc_hash_list) {
     silc_dlist_start(silc_hash_list);
     while ((entry = silc_dlist_get(silc_hash_list)) != SILC_LIST_END) {
@@ -196,8 +227,24 @@ char *silc_hash_get_supported(void)
       memcpy(list + len, ",", 1);
       len++;
     }
-    list[len - 1] = 0;
   }
+#else
+  {
+    int i;
+    for (i = 0; silc_default_hash[i].name; i++) {
+      entry = (SilcHashObject *)&(silc_default_hash[i]);
+      len += strlen(entry->name);
+      list = silc_realloc(list, len + 1);
+      
+      memcpy(list + (len - strlen(entry->name)), 
+            entry->name, strlen(entry->name));
+      memcpy(list + len, ",", 1);
+      len++;
+    }
+  }
+#endif /* SILC_EPOC */
+
+  list[len - 1] = 0;
 
   return list;
 }
index 4c7013059c6ea789eafe28af85f6f062ab9cb2c7..21bb1e5f94a73e29dfa252dfd3c93421f702a35d 100644 (file)
@@ -34,8 +34,10 @@ struct SilcHmacStruct {
   void *hash_context;
 };
 
+#ifndef SILC_EPOC
 /* List of dynamically registered HMACs. */
 SilcDList silc_hmac_list = NULL;
+#endif /* SILC_EPOC */
 
 /* Default hmacs for silc_hmac_register_default(). */
 const SilcHmacObject silc_default_hmacs[] =
@@ -82,6 +84,7 @@ static void silc_hmac_init_internal(SilcHmac hmac, unsigned char *key,
 
 bool silc_hmac_register(SilcHmacObject *hmac)
 {
+#ifndef SILC_EPOC
   SilcHmacObject *new;
 
   SILC_LOG_DEBUG(("Registering new HMAC `%s'", hmac->name));
@@ -105,6 +108,7 @@ bool silc_hmac_register(SilcHmacObject *hmac)
     silc_hmac_list = silc_dlist_init();
   silc_dlist_add(silc_hmac_list, new);
 
+#endif /* SILC_EPOC */
   return TRUE;
 }
 
@@ -112,6 +116,7 @@ bool silc_hmac_register(SilcHmacObject *hmac)
 
 bool silc_hmac_unregister(SilcHmacObject *hmac)
 {
+#ifndef SILC_EPOC
   SilcHmacObject *entry;
 
   SILC_LOG_DEBUG(("Unregistering HMAC"));
@@ -133,6 +138,7 @@ bool silc_hmac_unregister(SilcHmacObject *hmac)
     }
   }
 
+#endif /* SILC_EPOC */
   return FALSE;
 }
 
@@ -142,11 +148,13 @@ bool silc_hmac_unregister(SilcHmacObject *hmac)
 
 bool silc_hmac_register_default(void)
 {
+#ifndef SILC_EPOC
   int i;
 
   for (i = 0; silc_default_hmacs[i].name; i++)
     silc_hmac_register((SilcHmacObject *)&(silc_default_hmacs[i]));
 
+#endif /* SILC_EPOC */
   return TRUE;
 }
 
@@ -157,8 +165,6 @@ bool silc_hmac_register_default(void)
 
 bool silc_hmac_alloc(char *name, SilcHash hash, SilcHmac *new_hmac)
 {
-  SilcHmacObject *entry;
-
   SILC_LOG_DEBUG(("Allocating new HMAC"));
 
   /* Allocate the new object */
@@ -186,7 +192,9 @@ bool silc_hmac_alloc(char *name, SilcHash hash, SilcHmac *new_hmac)
 
   (*new_hmac)->hash = hash;
 
+#ifndef SILC_EPOC
   if (silc_hmac_list) {
+    SilcHmacObject *entry;
     silc_dlist_start(silc_hmac_list);
     while ((entry = silc_dlist_get(silc_hmac_list)) != SILC_LIST_END) {
       if (!strcmp(entry->name, name)) {
@@ -195,6 +203,18 @@ bool silc_hmac_alloc(char *name, SilcHash hash, SilcHmac *new_hmac)
       }
     }
   }
+#else
+  {
+    /* On EPOC which don't have globals we check our constant hash list. */
+    int i;
+    for (i = 0; silc_default_hmacs[i].name; i++) {
+      if (!strcmp(silc_default_hmacs[i].name, name)) {
+       (*new_hmac)->hmac = (SilcHmacObject *)&(silc_default_hmacs[i]);
+       return TRUE;
+      }
+    }
+  }
+#endif /* SILC_EPOC */
 
   silc_free(*new_hmac);
   *new_hmac = NULL;
@@ -244,6 +264,7 @@ const char *silc_hmac_get_name(SilcHmac hmac)
 
 bool silc_hmac_is_supported(const char *name)
 {
+#ifndef SILC_EPOC
   SilcHmacObject *entry;
 
   if (!name)
@@ -256,7 +277,14 @@ bool silc_hmac_is_supported(const char *name)
        return TRUE;
     }
   }
-
+#else
+  {
+    int i;
+    for (i = 0; silc_default_hmacs[i].name; i++)
+      if (!strcmp(silc_default_hmacs[i].name, name))
+       return TRUE;
+  }
+#endif /* SILC_EPOC */
   return FALSE;
 }
 
@@ -266,9 +294,9 @@ char *silc_hmac_get_supported()
 {
   SilcHmacObject *entry;
   char *list = NULL;
-  int len;
+  int len = 0;
 
-  len = 0;
+#ifndef SILC_EPOC
   if (silc_hmac_list) {
     silc_dlist_start(silc_hmac_list);
     while ((entry = silc_dlist_get(silc_hmac_list)) != SILC_LIST_END) {
@@ -280,8 +308,24 @@ char *silc_hmac_get_supported()
       memcpy(list + len, ",", 1);
       len++;
     }
-    list[len - 1] = 0;
   }
+#else
+  {
+    int i;
+    for (i = 0; silc_default_hmacs[i].name; i++) {
+      entry = (SilcHmacObject *)&(silc_default_hmacs[i]);
+      len += strlen(entry->name);
+      list = silc_realloc(list, len + 1);
+      
+      memcpy(list + (len - strlen(entry->name)), 
+            entry->name, strlen(entry->name));
+      memcpy(list + len, ",", 1);
+      len++;
+    }
+  }
+#endif /* SILC_EPOC */
+
+  list[len - 1] = 0;
 
   return list;
 }
index e1497387d67a087f762f40fde64a01255f433ff6..d61ed0c826db0ca0e7933954661cc7bd36acd35b 100644 (file)
 #include "rsa.h"
 #include "pkcs1.h"
 
+#ifndef SILC_EPOC
 /* Dynamically registered list of PKCS. */
 SilcDList silc_pkcs_list = NULL;
+#define SILC_PKCS_LIST silc_pkcs_list
+#else
+#define SILC_PKCS_LIST TRUE
+#endif /* SILC_EPOC */
 
 /* Static list of PKCS for silc_pkcs_register_default(). */
 const SilcPKCSObject silc_default_pkcs[] =
@@ -55,6 +60,7 @@ const SilcPKCSObject silc_default_pkcs[] =
 
 bool silc_pkcs_register(SilcPKCSObject *pkcs)
 {
+#ifndef SILC_EPOC
   SilcPKCSObject *new;
 
   SILC_LOG_DEBUG(("Registering new PKCS `%s'", pkcs->name));
@@ -78,6 +84,7 @@ bool silc_pkcs_register(SilcPKCSObject *pkcs)
     silc_pkcs_list = silc_dlist_init();
   silc_dlist_add(silc_pkcs_list, new);
 
+#endif /* SILC_EPOC */
   return TRUE;
 }
 
@@ -85,6 +92,7 @@ bool silc_pkcs_register(SilcPKCSObject *pkcs)
 
 bool silc_pkcs_unregister(SilcPKCSObject *pkcs)
 {
+#ifndef SILC_EPOC
   SilcPKCSObject *entry;
 
   SILC_LOG_DEBUG(("Unregistering PKCS"));
@@ -106,6 +114,7 @@ bool silc_pkcs_unregister(SilcPKCSObject *pkcs)
     }
   }
 
+#endif /* SILC_EPOC */
   return FALSE;
 }
 
@@ -115,11 +124,13 @@ bool silc_pkcs_unregister(SilcPKCSObject *pkcs)
 
 bool silc_pkcs_register_default(void)
 {
+#ifndef SILC_EPOC
   int i;
 
   for (i = 0; silc_default_pkcs[i].name; i++)
     silc_pkcs_register((SilcPKCSObject *)&(silc_default_pkcs[i]));
 
+#endif /* SILC_EPOC */
   return TRUE;
 }
 
@@ -128,22 +139,38 @@ bool silc_pkcs_register_default(void)
 
 bool silc_pkcs_alloc(const unsigned char *name, SilcPKCS *new_pkcs)
 {
-  SilcPKCSObject *entry;
+  SilcPKCSObject *entry = NULL;
 
   SILC_LOG_DEBUG(("Allocating new PKCS object"));
 
+#ifndef SILC_EPOC
   if (silc_pkcs_list) {
     silc_dlist_start(silc_pkcs_list);
     while ((entry = silc_dlist_get(silc_pkcs_list)) != SILC_LIST_END) {
-      if (!strcmp(entry->name, name)) {
-       *new_pkcs = silc_calloc(1, sizeof(**new_pkcs));
-       (*new_pkcs)->pkcs = entry;
-       (*new_pkcs)->context = silc_calloc(1, entry->context_len());
-       (*new_pkcs)->get_key_len = silc_pkcs_get_key_len;
-       return TRUE;
+      if (!strcmp(entry->name, name))
+       break;
+    }
+  }
+#else
+  {
+    /* On EPOC which don't have globals we check our constant hash list. */
+    int i;
+    for (i = 0; silc_default_pkcs[i].name; i++) {
+      if (!strcmp(silc_default_pkcs[i].name, name)) {
+       entry = (SilcPKCSObject *)&(silc_default_pkcs[i]);
+       break;
       }
     }
   }
+#endif /* SILC_EPOC */
+
+  if (entry) {
+    *new_pkcs = silc_calloc(1, sizeof(**new_pkcs));
+    (*new_pkcs)->pkcs = entry;
+    (*new_pkcs)->context = silc_calloc(1, entry->context_len());
+    (*new_pkcs)->get_key_len = silc_pkcs_get_key_len;
+    return TRUE;
+  }
 
   return FALSE;
 }
@@ -163,6 +190,7 @@ void silc_pkcs_free(SilcPKCS pkcs)
 
 int silc_pkcs_is_supported(const unsigned char *name)
 {
+#ifndef SILC_EPOC
   SilcPKCSObject *entry;
 
   if (silc_pkcs_list) {
@@ -172,7 +200,14 @@ int silc_pkcs_is_supported(const unsigned char *name)
        return TRUE;
     }
   }
-
+#else
+  {
+    int i;
+    for (i = 0; silc_default_pkcs[i].name; i++)
+      if (!strcmp(silc_default_pkcs[i].name, name))
+       return TRUE;
+  }
+#endif /* SILC_EPOC */
   return FALSE;
 }
 
@@ -182,9 +217,9 @@ char *silc_pkcs_get_supported(void)
 {
   SilcPKCSObject *entry;
   char *list = NULL;
-  int len;
+  int len = 0;
 
-  len = 0;
+#ifndef SILC_EPOC
   if (silc_pkcs_list) {
     silc_dlist_start(silc_pkcs_list);
     while ((entry = silc_dlist_get(silc_pkcs_list)) != SILC_LIST_END) {
@@ -196,12 +231,36 @@ char *silc_pkcs_get_supported(void)
       memcpy(list + len, ",", 1);
       len++;
     }
-    list[len - 1] = 0;
   }
+#else
+  {
+    int i;
+    for (i = 0; silc_default_pkcs[i].name; i++) {
+      entry = (SilcPKCSObject *)&(silc_default_pkcs[i]);
+      len += strlen(entry->name);
+      list = silc_realloc(list, len + 1);
+      
+      memcpy(list + (len - strlen(entry->name)), 
+            entry->name, strlen(entry->name));
+      memcpy(list + len, ",", 1);
+      len++;
+    }
+  }
+#endif /* SILC_EPOC */
+
+  list[len - 1] = 0;
 
   return list;
 }
 
+/* Generate new key pair into the `pkcs' context. */
+
+int silc_pkcs_generate_key(SilcPKCS pkcs, SilcUInt32 bits_key_len,
+                          SilcRng rng)
+{
+  return pkcs->pkcs->init(pkcs->context, bits_key_len, rng);
+}
+
 /* Returns the length of the key */
 
 SilcUInt32 silc_pkcs_get_key_len(SilcPKCS pkcs)
@@ -668,7 +727,7 @@ int silc_pkcs_public_key_decode(unsigned char *data, SilcUInt32 data_len,
     goto err;
 
   /* See if we support this algorithm (check only if PKCS are registered) */
-  if (silc_pkcs_list && !silc_pkcs_is_supported(pkcs_name)) {
+  if (SILC_PKCS_LIST && !silc_pkcs_is_supported(pkcs_name)) {
     SILC_LOG_DEBUG(("Unknown PKCS %s", pkcs_name));
     goto err;
   }
@@ -693,7 +752,7 @@ int silc_pkcs_public_key_decode(unsigned char *data, SilcUInt32 data_len,
   /* Try to set the key. If this fails the key must be malformed. This
      code assumes that the PKCS routine checks the format of the key. 
      (check only if PKCS are registered) */
-  if (silc_pkcs_list) {
+  if (SILC_PKCS_LIST) {
     silc_pkcs_alloc(pkcs_name, &alg);
     if (!alg->pkcs->set_public_key(alg->context, key_data, key_len))
       goto err;
@@ -829,7 +888,7 @@ int silc_pkcs_private_key_decode(unsigned char *data, SilcUInt32 data_len,
     goto err;
 
   /* See if we support this algorithm (check only if PKCS are registered). */
-  if (silc_pkcs_list && !silc_pkcs_is_supported(pkcs_name)) {
+  if (SILC_PKCS_LIST && !silc_pkcs_is_supported(pkcs_name)) {
     SILC_LOG_DEBUG(("Unknown PKCS `%s'", pkcs_name));
     goto err;
   }
@@ -846,7 +905,7 @@ int silc_pkcs_private_key_decode(unsigned char *data, SilcUInt32 data_len,
   /* Try to set the key. If this fails the key must be malformed. This
      code assumes that the PKCS routine checks the format of the key. 
      (check only if PKCS are registered) */
-  if (silc_pkcs_list) {
+  if (SILC_PKCS_LIST) {
     silc_pkcs_alloc(pkcs_name, &alg);
     if (!alg->pkcs->set_private_key(alg->context, key_data, key_len))
       goto err;
index 5c1542ce3c9afb393396bd5bffe187e42d24d3d2..15bb8b521d68d0e77bdc000ec1c3759df54b77ab 100644 (file)
@@ -179,6 +179,8 @@ bool silc_pkcs_alloc(const unsigned char *name, SilcPKCS *new_pkcs);
 void silc_pkcs_free(SilcPKCS pkcs);
 int silc_pkcs_is_supported(const unsigned char *name);
 char *silc_pkcs_get_supported(void);
+int silc_pkcs_generate_key(SilcPKCS pkcs, SilcUInt32 bits_key_len,
+                          SilcRng rng);
 SilcUInt32 silc_pkcs_get_key_len(SilcPKCS self);
 unsigned char *silc_pkcs_get_public_key(SilcPKCS pkcs, SilcUInt32 *len);
 unsigned char *silc_pkcs_get_private_key(SilcPKCS pkcs, SilcUInt32 *len);
index d9233d30690fd1deae81f2acd0ab4db2b438ae3e..f4b90fb243689df624f756211615e6510187bf7c 100644 (file)
@@ -31,6 +31,8 @@
 #ifndef SILCMATH_H
 #define SILCMATH_H
 
+#include "silcrng.h"
+
 /****f* silcmath/SilcMathAPI/silc_math_gen_prime
  *
  * SYNOPSIS
  *    (r.joosten@pijnenburg.nl) for such a good help with prime tests. 
  *
  *    If argument verbose is TRUE this will display some status information
- *    about the progress of generation.
+ *    about the progress of generation.  If the `rng' is NULL then global
+ *    RNG is used, if non-NULL then `rng' is used to generate the random
+ *    number number.
  *
  ***/
-bool silc_math_gen_prime(SilcMPInt *prime, SilcUInt32 bits, bool verbose);
+bool silc_math_gen_prime(SilcMPInt *prime, SilcUInt32 bits, bool verbose,
+                        SilcRng rng);
 
 /****f* silcmath/SilcMathAPI/silc_math_prime_test
  *
index 515f2b400fc8a0dc6d5c724f43e2fd9ddd260a25..7079f7d1885476cab8ce9ce99ef39e6e3666ce85 100644 (file)
@@ -195,7 +195,8 @@ static SilcUInt32 primetable[] =
    If argument verbose is TRUE this will display some status information
    about the progress of generation. */
 
-bool silc_math_gen_prime(SilcMPInt *prime, SilcUInt32 bits, bool verbose)
+bool silc_math_gen_prime(SilcMPInt *prime, SilcUInt32 bits, bool verbose,
+                        SilcRng rng)
 {
   unsigned char *numbuf = NULL;
   SilcUInt32 i, b, k;
@@ -219,7 +220,10 @@ bool silc_math_gen_prime(SilcMPInt *prime, SilcUInt32 bits, bool verbose)
       memset(numbuf, 0, (bits / 8));
       silc_free(numbuf);
     }
-    numbuf = silc_rng_global_get_rn_string((bits / 8));
+    if (rng)
+      numbuf = silc_rng_get_rn_string(rng, (bits / 8));
+    else
+      numbuf = silc_rng_global_get_rn_string((bits / 8));
     if (!numbuf)
       return FALSE;
   } while (numbuf[0] == '0');
index a4b671e46fa36b43b55fa782f9b21d2d06b979b1..0b4ee1647345499ecdd2f39a847b02f2f8d05fce 100644 (file)
@@ -39,7 +39,6 @@ typedef struct SilcSFTPRequestStruct {
 
 /* SFTP client context */
 typedef struct {
-  SilcSocketConnection sock;
   SilcSFTPSendPacketCallback send_packet;
   void *send_context;
   SilcSFTPVersionCallback version;
@@ -109,7 +108,7 @@ static void silc_sftp_send_packet(SilcSFTPClient sftp,
                   sftp->packet->len);
 
   /* Send the packet */
-  (*sftp->send_packet)(sftp->sock, sftp->packet, sftp->send_context);
+  (*sftp->send_packet)(sftp->packet, sftp->send_context);
 
   /* Clear packet */
   sftp->packet->data = sftp->packet->tail = sftp->packet->head;
@@ -291,15 +290,13 @@ static void silc_sftp_call_request(SilcSFTPClient sftp,
   va_end(vp);
 }
 
-/* Starts SFTP client by associating the socket connection `sock' to the
-   created SFTP client context.  The version callback indicated by the
-   `callback' will be called after the SFTP session has been started
-   and server has returned the version of the protocol.  The SFTP client
-   context is returned in the callback too.  This returns the allocated
-   SFTP client context or NULL on error. */
+/* Starts SFTP client and returns context for it.  The version callback
+   indicated by the `callback' will be called after the SFTP session has
+   been started and server has returned the version of the protocol.  The
+   SFTP client context is returned in the callback too.  This returns 
+   allocated SFTP client context or NULL on error. */
 
-SilcSFTP silc_sftp_client_start(SilcSocketConnection sock,
-                               SilcSFTPSendPacketCallback send_packet,
+SilcSFTP silc_sftp_client_start(SilcSFTPSendPacketCallback send_packet,
                                void *send_context,
                                SilcSFTPVersionCallback callback,
                                void *context)
@@ -310,7 +307,6 @@ SilcSFTP silc_sftp_client_start(SilcSocketConnection sock,
     return NULL;
 
   sftp = silc_calloc(1, sizeof(*sftp));
-  sftp->sock = sock;
   sftp->send_packet = send_packet;
   sftp->send_context = send_context;
   sftp->version = callback;
index f3bda1d64642d4dcdf1f100be04b07b6272efc4e..1f7d26eb6ca12550c6f2d826ed1dea1ba6126ca1 100644 (file)
@@ -25,7 +25,6 @@
 
 /* SFTP Server context */
 typedef struct {
-  SilcSocketConnection sock;
   SilcSFTPSendPacketCallback send_packet;
   void *send_context;
   SilcSFTPMonitors monitors;
@@ -55,7 +54,7 @@ static void silc_sftp_send_packet(SilcSFTPServer sftp,
                   sftp->packet->len);
 
   /* Send the packet */
-  (*sftp->send_packet)(sftp->sock, sftp->packet, sftp->send_context);
+  (*sftp->send_packet)(sftp->packet, sftp->send_context);
 
   /* Clear packet */
   sftp->packet->data = sftp->packet->tail = sftp->packet->head;
@@ -255,21 +254,18 @@ static void silc_sftp_server_extended(SilcSFTP sftp,
                        SILC_STR_END);
 }
 
-/* Starts SFTP server by associating the socket connection `sock' to the
-   created SFTP server context.  This function returns the allocated
-   SFTP client context or NULL on error. The `send_packet' is called
+/* Starts SFTP server and returns context to it.  This function returns the
+   allocated SFTP client context or NULL on error. The `send_packet' is called
    by the library when it needs to send a packet. The `fs' is the
    structure containing filesystem access callbacks. */
 
-SilcSFTP silc_sftp_server_start(SilcSocketConnection sock,
-                               SilcSFTPSendPacketCallback send_packet,
+SilcSFTP silc_sftp_server_start(SilcSFTPSendPacketCallback send_packet,
                                void *send_context,
                                SilcSFTPFilesystem fs)
 {
   SilcSFTPServer server;
 
   server = silc_calloc(1, sizeof(*server));
-  server->sock = sock;
   server->send_packet = send_packet;
   server->send_context = send_context;
   server->fs = fs;
index ef5735a8cc097ac37b5306a0a5e8a25e22555de6..45954677a9f5ba075f19ea556588a9393e4d8f82 100644 (file)
@@ -189,20 +189,17 @@ typedef struct SilcSFTPHandleStruct *SilcSFTPHandle;
  *
  * SYNOPSIS
  *
- *    typedef void (*SilcSFTPSendPacketCallback)(SilcSocketConnection sock,
- *                                               SilcBuffer packet, 
+ *    typedef void (*SilcSFTPSendPacketCallback)(SilcBuffer packet, 
  *                                               void *context);
  *
  * DESCRIPTION
  *
  *    Packet sending callback. The caller of this interface will provide this
  *    function for the library. The libary will call this function everytime
- *    it needs to send a packet to the socket connection indicated by the
- *    `sock'. 
+ *    it needs to send a packet to the remote host.
  *
  ***/
-typedef void (*SilcSFTPSendPacketCallback)(SilcSocketConnection sock,
-                                          SilcBuffer packet, void *context);
+typedef void (*SilcSFTPSendPacketCallback)(SilcBuffer packet, void *context);
 
 /****f* silcsftp/SilcSFTPAPI/SilcSFTPVersionCallback
  *
@@ -369,24 +366,22 @@ typedef void (*SilcSFTPExtendedCallback)(SilcSFTP sftp,
  *
  * SYNOPSIS
  *
- *    SilcSFTP silc_sftp_client_start(SilcSocketConnection sock,
- *                                    SilcSFTPSendPacketCallback send_packet,
+ *    SilcSFTP silc_sftp_client_start(SilcSFTPSendPacketCallback send_packet,
  *                                    void *send_context,
  *                                    SilcSFTPVersionCallback callback,
  *                                    void *context);
  *
  * DESCRIPTION
  *
- *    Starts SFTP client by associating the socket connection `sock' to the
- *    created SFTP client context.  The version callback indicated by the
- *    `callback' will be called after the SFTP session has been started
- *    and server has returned the version of the protocol.  The SFTP client
- *    context is returned in the callback too.  This returns the allocated
- *    SFTP client context or NULL on error.
+ *    Starts SFTP client and returns context to it.  The version callback
+ *    indicated by the `callback' will be called after the SFTP session has
+ *    been started and server has returned the version of the protocol.  The
+ *    SFTP client context is returned in the callback too.  This returns the
+ *    allocated SFTP client context or NULL on error.  Each socket connection
+ *    should allocate their own SFTP client by calling this function.
  *
  ***/
-SilcSFTP silc_sftp_client_start(SilcSocketConnection sock,
-                               SilcSFTPSendPacketCallback send_packet,
+SilcSFTP silc_sftp_client_start(SilcSFTPSendPacketCallback send_packet,
                                void *send_context,
                                SilcSFTPVersionCallback callback,
                                void *context);
@@ -840,22 +835,20 @@ void silc_sftp_extended(SilcSFTP sftp,
  *
  * SYNOPSIS
  *
- *    SilcSFTP silc_sftp_server_start(SilcSocketConnection sock,
- *                                    SilcSFTPSendPacketCallback send_packet,
+ *    SilcSFTP silc_sftp_server_start(SilcSFTPSendPacketCallback send_packet,
  *                                    void *send_context, 
  *                                    SilcSFTPFilesystem fs);
  *
  * DESCRIPTION
  *
- *    Starts SFTP server by associating the socket connection `sock' to the
- *    created SFTP server context.  This function returns the allocated
- *    SFTP client context or NULL on error. The `send_packet' is called
- *    by the library when it needs to send a packet. The `fs' is the
- *    filesystem context allocated by the application.
+ *    Starts SFTP server and returns a context to it.  This function returns
+ *    the allocated SFTP client context or NULL on error. The `send_packet'
+ *    is called by the library when it needs to send a packet. The `fs' is the
+ *    filesystem context allocated by the application.  Each socket connection
+ *    should start its own server by calling this function.
  *
  ***/
-SilcSFTP silc_sftp_server_start(SilcSocketConnection sock,
-                               SilcSFTPSendPacketCallback send_packet,
+SilcSFTP silc_sftp_server_start(SilcSFTPSendPacketCallback send_packet,
                                void *send_context, 
                                SilcSFTPFilesystem fs);
 
index ab9b3433615c6923d212c040773869922626aa46..43e6be79296599d9b5b6a1443b3d94dbf5af282e 100644 (file)
 
 #include "silcincludes.h"
 
+/* 
+   SILC Module (SIM) Context.
+
+   This context holds relevant information about the SIM loaded into
+   the system. Following short description of the fields.
+
+   void *handle
+
+       Pointer to the SIM. This is used to get the symbols out of
+       the SIM. This is initalized by system specific routine.
+
+   SilcSimType type
+
+       Type of the SIM.
+
+   char *libname;
+
+       Filename and path to the SIM library file.
+
+   int flags
+
+       Flags used with the SIM. These are system specific flags.
+       See below for more information.
+
+*/
+struct SilcSimStruct {
+  void *handle;
+  SilcSimType type;
+  char *libname;
+  int flags;
+};
+
 #ifdef SILC_SIM                        /* SIM upport enabled */
 
 /* Allocates new SIM context. This is later send to all SIM 
    routines. */
 
-SilcSimContext *silc_sim_alloc()
+SilcSim silc_sim_alloc(SilcSimType type, const char *libname, 
+                      SilcUInt32 flags)
 {
-  SilcSimContext *new;
+  SilcSim sim;
 
   SILC_LOG_DEBUG(("Initializing new SIM context"));
 
-  new = silc_calloc(1, sizeof(*new));
-  if (!new) {
+  sim = silc_calloc(1, sizeof(*sim));
+  if (!sim) {
     SILC_LOG_ERROR(("Could not allocate new SIM context"));
     return NULL;
   }
 
-  new->handle = NULL;
-  new->type = SILC_SIM_NONE;
-  new->libname = NULL;
-  new->flags = SILC_SIM_FLAGS;
+  sim->handle = NULL;
+  sim->type = type;
+  sim->libname = strdup(libname);
+  sim->flags = !flags ? SILC_SIM_FLAGS : flags;
 
-  return new;
+  return sim;
 }
 
 /* Free's SIM context. SIM must be closed with silc_sim_close before
    calling this. */
 
-void silc_sim_free(SilcSimContext *sim)
+void silc_sim_free(SilcSim sim)
 {
   assert(sim->handle == NULL);
-
-  if (sim)
-    silc_free(sim);
+  silc_free(sim->libname);
+  silc_free(sim);
 }
 
 /* Loads SIM into the SILC system. */
 
-int silc_sim_load(SilcSimContext *sim)
+int silc_sim_load(SilcSim sim)
 {
   assert(sim != NULL);
 
@@ -90,7 +122,7 @@ int silc_sim_load(SilcSimContext *sim)
   /* Load the library */
   sim->handle = dlopen(sim->libname, sim->flags);
   if (!sim->handle) {
-    SILC_LOG_ERROR(("Error loading SIM: %s", silc_sim_error()));
+    SILC_LOG_ERROR(("Error loading SIM: %s", silc_sim_error(sim)));
     return FALSE;
   }
 
@@ -100,7 +132,7 @@ int silc_sim_load(SilcSimContext *sim)
 /* Closes SIM. This is called when execution of program is ending or
    one explicitly wants to remove this SIM from SILC. */
 
-int silc_sim_close(SilcSimContext *sim)
+int silc_sim_close(SilcSim sim)
 {
   assert(sim != NULL);
 
@@ -115,7 +147,7 @@ int silc_sim_close(SilcSimContext *sim)
 
 /* Returns error string if error has occured while processing SIM's. */
 
-char *silc_sim_error()
+char *silc_sim_error(SilcSim sim)
 {
   return dlerror();
 }
@@ -124,7 +156,7 @@ char *silc_sim_error()
    symbols they want to get from SIM and use the returned pointer to
    what ever it is intended. */
 
-void *silc_sim_getsym(SilcSimContext *sim, const char *symbol)
+void *silc_sim_getsym(SilcSim sim, const char *symbol)
 {
   assert(sim != NULL);
 
index 99ba428252c125a249d7940ff782e90dc7cf3341..b541b0ec7f63985575b64028c5a73b7787820df5 100644 (file)
@@ -21,6 +21,8 @@
 #ifndef SILCSIM_H
 #define SILCSIM_H
 
+typedef struct SilcSimStruct *SilcSim;
+
 /* All SIM types. New types maybe freely added. */
 typedef enum {
   SILC_SIM_NONE = 0,
@@ -28,38 +30,6 @@ typedef enum {
   SILC_SIM_HASH,
 } SilcSimType;
 
-/* 
-   SILC Module (SIM) Context.
-
-   This context holds relevant information about the SIM loaded into
-   the system. Following short description of the fields.
-
-   void *handle
-
-       Pointer to the SIM. This is used to get the symbols out of
-       the SIM. This is initalized by system specific routine.
-
-   SilcSimType type
-
-       Type of the SIM.
-
-   char *libname;
-
-       Filename and path to the SIM library file.
-
-   int flags
-
-       Flags used with the SIM. These are system specific flags.
-       See below for more information.
-
-*/
-typedef struct {
-  void *handle;
-  SilcSimType type;
-  char *libname;
-  int flags;
-} SilcSimContext;
-
 /* Flags used to retrieve the symbols from the library file. Default
    is that the symbols are resolved as they are loaded. However, if
    system doesn't support this we have no other choice but to do it lazy
@@ -68,11 +38,12 @@ typedef struct {
 /*#define SILC_SIM_FLAGS RTLD_LAZY */
 
 /* Prototypes */
-SilcSimContext *silc_sim_alloc();
-void silc_sim_free(SilcSimContext *sim);
-int silc_sim_load(SilcSimContext *sim);
-int silc_sim_close(SilcSimContext *sim);
-char *silc_sim_error();
-void *silc_sim_getsym(SilcSimContext *sim, const char *symbol);
+SilcSim silc_sim_alloc(SilcSimType type, const char *libname, 
+                      SilcUInt32 flags);
+void silc_sim_free(SilcSim sim);
+int silc_sim_load(SilcSim sim);
+int silc_sim_close(SilcSim sim);
+char *silc_sim_error(SilcSim sim);
+void *silc_sim_getsym(SilcSim sim, const char *symbol);
 
 #endif
index 07207030c044be91c64b6a814bc604bc1b681080..b45a7acded381424bd447c31ab250627f82e9924 100644 (file)
@@ -309,6 +309,7 @@ bool silc_net_check_host_by_sock(int sock, char **hostname, char **ip)
     return FALSE;
 #else
   struct sockaddr_in remote;
+  char *host_ip;
 
   *hostname = NULL;
   *ip = NULL;
@@ -381,6 +382,7 @@ bool silc_net_check_local_by_sock(int sock, char **hostname, char **ip)
     return FALSE;
 #else
   struct sockaddr_in local;
+  char *host_ip;
 
   *hostname = NULL;
   *ip = NULL;
index ad6b45adac5540749f6eae31b30142efe478a4af..47427023d84128fe52e00c80af23880bda994313 100644 (file)
@@ -382,11 +382,22 @@ char *silc_format(char *fmt, ...)
 /* Renders ID to suitable to print for example to log file. */
 
 static char rid[256];
+#define _PUT_STRING(d, s)                              \
+do {                                                   \
+  int sp = (sizeof(d) - 1) - strlen(d);                        \
+  if (sp < strlen(s)) {                                        \
+    if (sp)                                            \
+      strncat(d, s, (sizeof(d) - 1) - strlen(d));      \
+  } else {                                             \
+    strncat(d, s, strlen(s));                          \
+  }                                                    \
+} while(0)
 
 char *silc_id_render(void *id, SilcUInt16 type)
 {
   char tmp[100];
   unsigned char tmps[2];
+  char *cp;
 
   memset(rid, 0, sizeof(rid));
   switch(type) {
@@ -400,22 +411,24 @@ char *silc_id_render(void *id, SilcUInt16 type)
        ipv6.sin6_family = AF_INET6;
        memmove(&ipv6.sin6_addr, server_id->ip.data, sizeof(ipv6.sin6_addr));
        if (!getnameinfo((struct sockaddr *)&ipv6, sizeof(ipv6),
-                        tmp, sizeof(tmp), NULL, 0, NI_NUMERICHOST))
-         strcat(rid, tmp);
+                        tmp, sizeof(tmp) - 1, NULL, 0, NI_NUMERICHOST))
+         _PUT_STRING(rid, tmp);
 #endif
       } else {
        struct in_addr ipv4;
        memmove(&ipv4.s_addr, server_id->ip.data, 4);
-       strcat(rid, inet_ntoa(ipv4));
+       cp = inet_ntoa(ipv4);
+       if (cp)
+         _PUT_STRING(rid, cp);
       }
 
       memset(tmp, 0, sizeof(tmp));
-      snprintf(tmp, sizeof(tmp), ",%d,", ntohs(server_id->port));
-      strcat(rid, tmp);
+      snprintf(tmp, sizeof(tmp) - 1, ",%d,", ntohs(server_id->port));
+      _PUT_STRING(rid, tmp);
       SILC_PUT16_MSB(server_id->rnd, tmps);
       memset(tmp, 0, sizeof(tmp));
-      snprintf(tmp, sizeof(tmp), "[%02x %02x]", tmps[0], tmps[1]);
-      strcat(rid, tmp);
+      snprintf(tmp, sizeof(tmp) - 1, "[%02x %02x]", tmps[0], tmps[1]);
+      _PUT_STRING(rid, tmp);
     }
     break;
   case SILC_ID_CLIENT:
@@ -428,23 +441,25 @@ char *silc_id_render(void *id, SilcUInt16 type)
        ipv6.sin6_family = AF_INET6;
        memmove(&ipv6.sin6_addr, client_id->ip.data, sizeof(ipv6.sin6_addr));
        if (!getnameinfo((struct sockaddr *)&ipv6, sizeof(ipv6),
-                        tmp, sizeof(tmp), NULL, 0, NI_NUMERICHOST))
-         strcat(rid, tmp);
+                        tmp, sizeof(tmp) - 1, NULL, 0, NI_NUMERICHOST))
+         _PUT_STRING(rid, tmp);
 #endif
       } else {
        struct in_addr ipv4;
        memmove(&ipv4.s_addr, client_id->ip.data, 4);
-       strcat(rid, inet_ntoa(ipv4));
+       cp = inet_ntoa(ipv4);
+       if (cp)
+         _PUT_STRING(rid, cp);
       }
 
       memset(tmp, 0, sizeof(tmp));
-      snprintf(tmp, sizeof(tmp), ",%02x,", client_id->rnd);
-      strcat(rid, tmp);
+      snprintf(tmp, sizeof(tmp) - 1, ",%02x,", client_id->rnd);
+      _PUT_STRING(rid, tmp);
       memset(tmp, 0, sizeof(tmp));
-      snprintf(tmp, sizeof(tmp), "[%02x %02x %02x %02x...]", 
+      snprintf(tmp, sizeof(tmp) - 1, "[%02x %02x %02x %02x...]", 
               client_id->hash[0], client_id->hash[1],
               client_id->hash[2], client_id->hash[3]);
-      strcat(rid, tmp);
+      _PUT_STRING(rid, tmp);
     }
     break;
   case SILC_ID_CHANNEL:
@@ -457,22 +472,24 @@ char *silc_id_render(void *id, SilcUInt16 type)
        ipv6.sin6_family = AF_INET6;
        memmove(&ipv6.sin6_addr, channel_id->ip.data, sizeof(ipv6.sin6_addr));
        if (!getnameinfo((struct sockaddr *)&ipv6, sizeof(ipv6),
-                        tmp, sizeof(tmp), NULL, 0, NI_NUMERICHOST))
-         strcat(rid, tmp);
+                        tmp, sizeof(tmp) - 1, NULL, 0, NI_NUMERICHOST))
+         _PUT_STRING(rid, tmp);
 #endif
       } else {
        struct in_addr ipv4;
        memmove(&ipv4.s_addr, channel_id->ip.data, 4);
-       strcat(rid, inet_ntoa(ipv4));
+       cp = inet_ntoa(ipv4);
+       if (cp)
+         _PUT_STRING(rid, cp);
       }
 
       memset(tmp, 0, sizeof(tmp));
-      snprintf(tmp, sizeof(tmp), ",%d,", ntohs(channel_id->port));
-      strcat(rid, tmp);
+      snprintf(tmp, sizeof(tmp) - 1, ",%d,", ntohs(channel_id->port));
+      _PUT_STRING(rid, tmp);
       SILC_PUT16_MSB(channel_id->rnd, tmps);
       memset(tmp, 0, sizeof(tmp));
-      snprintf(tmp, sizeof(tmp), "[%02x %02x]", tmps[0], tmps[1]);
-      strcat(rid, tmp);
+      snprintf(tmp, sizeof(tmp) - 1, "[%02x %02x]", tmps[0], tmps[1]);
+      _PUT_STRING(rid, tmp);
     }
     break;
   }