Added SILC Server library.
[silc.git] / lib / silccrypt / silcpkcs.c
index 11dda7c95ad2e1d8c3f22d0101613f72b967dae4..240456ff481380d89647ee664654bb9700b4d430 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 1997 - 2003 Pekka Riikonen
+  Copyright (C) 1997 - 2005 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
 */
 /* $Id$ */
 
-#include "silcincludes.h"
+#include "silc.h"
 
 #include "rsa.h"
-#include "pkcs1.h"
 
 /* The main SILC PKCS structure. */
 struct SilcPKCSStruct {
@@ -41,30 +40,32 @@ SilcDList silc_pkcs_list = NULL;
 /* Static list of PKCS for silc_pkcs_register_default(). */
 const SilcPKCSObject silc_default_pkcs[] =
 {
-  /* RSA with PKCS #1 (Uses directly routines from Raw RSA operations) */
-  { "rsa",
+  /* RSA with PKCS #1 for SILC PKCS */
+  { "rsa", SILC_PKCS_SILC,
     silc_rsa_init, silc_rsa_clear_keys, silc_rsa_get_public_key,
     silc_rsa_get_private_key, silc_rsa_set_public_key,
     silc_rsa_set_private_key, silc_rsa_context_len,
     silc_pkcs1_encrypt, silc_pkcs1_decrypt,
     silc_pkcs1_sign, silc_pkcs1_verify },
 
-  /* Raw RSA operations */
-  { "rsa-raw",
+  /* RSASSA-PKCS1-V1_5 for SSH2 PKCS */
+/*
+  { "rsa", SILC_PKCS_SSH2,
     silc_rsa_init, silc_rsa_clear_keys, silc_rsa_get_public_key,
     silc_rsa_get_private_key, silc_rsa_set_public_key,
     silc_rsa_set_private_key, silc_rsa_context_len,
-    silc_rsa_encrypt, silc_rsa_decrypt,
-    silc_rsa_sign, silc_rsa_verify },
+    silc_pkcs1_encrypt, silc_pkcs1_decrypt,
+    silc_pkcs1_sign, silc_pkcs1_verify },
+*/
 
-  { NULL, NULL, NULL, NULL, NULL,
+  { NULL, 0, NULL, NULL, NULL, NULL,
     NULL, NULL, NULL, NULL, NULL, NULL }
 };
 
 /* Register a new PKCS into SILC. This is used at the initialization of
    the SILC. */
 
-bool silc_pkcs_register(const SilcPKCSObject *pkcs)
+SilcBool silc_pkcs_register(const SilcPKCSObject *pkcs)
 {
 #ifndef SILC_EPOC
   SilcPKCSObject *new;
@@ -76,13 +77,15 @@ bool silc_pkcs_register(const SilcPKCSObject *pkcs)
     SilcPKCSObject *entry;
     silc_dlist_start(silc_pkcs_list);
     while ((entry = silc_dlist_get(silc_pkcs_list)) != SILC_LIST_END) {
-      if (!strcmp(entry->name, pkcs->name))
+      if (!strcmp(entry->name, pkcs->name) &&
+         entry->type == pkcs->type)
         return FALSE;
     }
   }
 
   new = silc_calloc(1, sizeof(*new));
   new->name = strdup(pkcs->name);
+  new->type = pkcs->type;
   new->init = pkcs->init;
   new->clear_keys = pkcs->clear_keys;
   new->get_public_key = pkcs->get_public_key;
@@ -106,7 +109,7 @@ bool silc_pkcs_register(const SilcPKCSObject *pkcs)
 
 /* Unregister a PKCS from the SILC. */
 
-bool silc_pkcs_unregister(SilcPKCSObject *pkcs)
+SilcBool silc_pkcs_unregister(SilcPKCSObject *pkcs)
 {
 #ifndef SILC_EPOC
   SilcPKCSObject *entry;
@@ -140,7 +143,7 @@ bool silc_pkcs_unregister(SilcPKCSObject *pkcs)
    The application may use this to register the default PKCS if specific
    PKCS in any specific order is not wanted. */
 
-bool silc_pkcs_register_default(void)
+SilcBool silc_pkcs_register_default(void)
 {
 #ifndef SILC_EPOC
   int i;
@@ -152,7 +155,7 @@ bool silc_pkcs_register_default(void)
   return TRUE;
 }
 
-bool silc_pkcs_unregister_all(void)
+SilcBool silc_pkcs_unregister_all(void)
 {
 #ifndef SILC_EPOC
   SilcPKCSObject *entry;
@@ -173,7 +176,8 @@ bool silc_pkcs_unregister_all(void)
 /* Allocates a new SilcPKCS object. The new allocated object is returned
    to the 'new_pkcs' argument. */
 
-bool silc_pkcs_alloc(const unsigned char *name, SilcPKCS *new_pkcs)
+SilcBool silc_pkcs_alloc(const unsigned char *name, SilcPKCSType type,
+                        SilcPKCS *new_pkcs)
 {
   SilcPKCSObject *entry = NULL;
 
@@ -183,7 +187,7 @@ bool silc_pkcs_alloc(const unsigned char *name, SilcPKCS *new_pkcs)
   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))
+      if (!strcmp(entry->name, name) && entry->type == type)
        break;
     }
   }
@@ -192,7 +196,8 @@ bool silc_pkcs_alloc(const unsigned char *name, SilcPKCS *new_pkcs)
     /* 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)) {
+      if (!strcmp(silc_default_pkcs[i].name, name) &&
+         silc_default_pkcs[i].type == type) {
        entry = (SilcPKCSObject *)&(silc_default_pkcs[i]);
        break;
       }
@@ -223,7 +228,7 @@ void silc_pkcs_free(SilcPKCS pkcs)
 
 /* Return TRUE if PKCS algorithm `name' is supported. */
 
-bool silc_pkcs_is_supported(const unsigned char *name)
+SilcBool silc_pkcs_is_supported(const unsigned char *name)
 {
 #ifndef SILC_EPOC
   SilcPKCSObject *entry;
@@ -290,10 +295,13 @@ char *silc_pkcs_get_supported(void)
 
 /* Generate new key pair into the `pkcs' context. */
 
-bool silc_pkcs_generate_key(SilcPKCS pkcs, SilcUInt32 bits_key_len,
-                           SilcRng rng)
+SilcBool silc_pkcs_generate_key(SilcPKCS pkcs, SilcUInt32 bits_key_len,
+                               SilcRng rng)
 {
-  return pkcs->pkcs->init(pkcs->context, bits_key_len, rng);
+  SilcBool 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 */
@@ -366,7 +374,7 @@ SilcUInt32 silc_pkcs_private_key_data_set(SilcPKCS pkcs, unsigned char *prv,
 
 /* Encrypts */
 
-bool silc_pkcs_encrypt(SilcPKCS pkcs, unsigned char *src, SilcUInt32 src_len,
+SilcBool silc_pkcs_encrypt(SilcPKCS pkcs, unsigned char *src, SilcUInt32 src_len,
                       unsigned char *dst, SilcUInt32 *dst_len)
 {
   return pkcs->pkcs->encrypt(pkcs->context, src, src_len, dst, dst_len);
@@ -374,7 +382,7 @@ bool silc_pkcs_encrypt(SilcPKCS pkcs, unsigned char *src, SilcUInt32 src_len,
 
 /* Decrypts */
 
-bool silc_pkcs_decrypt(SilcPKCS pkcs, unsigned char *src, SilcUInt32 src_len,
+SilcBool silc_pkcs_decrypt(SilcPKCS pkcs, unsigned char *src, SilcUInt32 src_len,
                       unsigned char *dst, SilcUInt32 *dst_len)
 {
   return pkcs->pkcs->decrypt(pkcs->context, src, src_len, dst, dst_len);
@@ -382,7 +390,7 @@ bool silc_pkcs_decrypt(SilcPKCS pkcs, unsigned char *src, SilcUInt32 src_len,
 
 /* Generates signature */
 
-bool silc_pkcs_sign(SilcPKCS pkcs, unsigned char *src, SilcUInt32 src_len,
+SilcBool silc_pkcs_sign(SilcPKCS pkcs, unsigned char *src, SilcUInt32 src_len,
                    unsigned char *dst, SilcUInt32 *dst_len)
 {
   return pkcs->pkcs->sign(pkcs->context, src, src_len, dst, dst_len);
@@ -390,7 +398,7 @@ bool silc_pkcs_sign(SilcPKCS pkcs, unsigned char *src, SilcUInt32 src_len,
 
 /* Verifies signature */
 
-bool silc_pkcs_verify(SilcPKCS pkcs, unsigned char *signature,
+SilcBool silc_pkcs_verify(SilcPKCS pkcs, unsigned char *signature,
                      SilcUInt32 signature_len, unsigned char *data,
                      SilcUInt32 data_len)
 {
@@ -400,11 +408,11 @@ bool silc_pkcs_verify(SilcPKCS pkcs, unsigned char *signature,
 
 /* Generates signature with hash. The hash is signed. */
 
-bool silc_pkcs_sign_with_hash(SilcPKCS pkcs, SilcHash hash,
+SilcBool silc_pkcs_sign_with_hash(SilcPKCS pkcs, SilcHash hash,
                              unsigned char *src, SilcUInt32 src_len,
                              unsigned char *dst, SilcUInt32 *dst_len)
 {
-  unsigned char hashr[32];
+  unsigned char hashr[SILC_HASH_MAXLEN];
   SilcUInt32 hash_len;
   int ret;
 
@@ -422,13 +430,13 @@ bool silc_pkcs_sign_with_hash(SilcPKCS pkcs, SilcHash hash,
 /* Verifies signature with hash. The `data' is hashed and verified against
    the `signature'. */
 
-bool silc_pkcs_verify_with_hash(SilcPKCS pkcs, SilcHash hash,
+SilcBool silc_pkcs_verify_with_hash(SilcPKCS pkcs, SilcHash hash,
                                unsigned char *signature,
                                SilcUInt32 signature_len,
                                unsigned char *data,
                                SilcUInt32 data_len)
 {
-  unsigned char hashr[32];
+  unsigned char hashr[SILC_HASH_MAXLEN];
   SilcUInt32 hash_len;
   int ret;
 
@@ -636,9 +644,8 @@ SilcPublicKey silc_pkcs_public_key_alloc(const char *name,
   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);
@@ -678,8 +685,7 @@ SilcPrivateKey silc_pkcs_private_key_alloc(const char *name,
   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;
 }
@@ -690,7 +696,10 @@ void silc_pkcs_private_key_free(SilcPrivateKey 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);
   }
 }
@@ -701,26 +710,10 @@ void silc_pkcs_private_key_free(SilcPrivateKey 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. */
@@ -756,7 +749,7 @@ silc_pkcs_public_key_data_encode(unsigned char *pk, SilcUInt32 pk_len,
 /* Decodes SILC style public key. Returns TRUE if the decoding was
    successful. Allocates new public key as well. */
 
-bool silc_pkcs_public_key_decode(unsigned char *data, SilcUInt32 data_len,
+SilcBool silc_pkcs_public_key_decode(unsigned char *data, SilcUInt32 data_len,
                                 SilcPublicKey *public_key)
 {
   SilcBufferStruct buf;
@@ -813,7 +806,7 @@ bool silc_pkcs_public_key_decode(unsigned char *data, SilcUInt32 data_len,
 
   /* Get key data. We assume that rest of the buffer is key data. */
   silc_buffer_pull(&buf, 2 + pkcs_len + 2 + identifier_len);
-  key_len = buf.len;
+  key_len = silc_buffer_len(&buf);
   ret = silc_buffer_unformat(&buf,
                             SILC_STR_UI_XNSTRING_ALLOC(&key_data, key_len),
                             SILC_STR_END);
@@ -824,7 +817,7 @@ bool silc_pkcs_public_key_decode(unsigned char *data, SilcUInt32 data_len,
      code assumes that the PKCS routine checks the format of the key.
      (check only if PKCS are registered) */
   if (SILC_PKCS_LIST) {
-    silc_pkcs_alloc(pkcs_name, &alg);
+    silc_pkcs_alloc(pkcs_name, SILC_PKCS_SILC, &alg);
     if (!alg->pkcs->set_public_key(alg->context, key_data, key_len))
       goto err;
     silc_pkcs_free(alg);
@@ -883,7 +876,7 @@ SilcBuffer silc_pkcs_public_key_payload_encode(SilcPublicKey public_key)
 /* Decode Public Key Payload and decodes the public key inside it to
    to `payload'. */
 
-bool silc_pkcs_public_key_payload_decode(unsigned char *data,
+SilcBool silc_pkcs_public_key_payload_decode(unsigned char *data,
                                         SilcUInt32 data_len,
                                         SilcPublicKey *public_key)
 {
@@ -925,7 +918,7 @@ bool silc_pkcs_public_key_payload_decode(unsigned char *data,
 /* Compares two public keys and returns TRUE if they are same key, and
    FALSE if they are not same. */
 
-bool silc_pkcs_public_key_compare(SilcPublicKey key1, SilcPublicKey key2)
+SilcBool silc_pkcs_public_key_compare(SilcPublicKey key1, SilcPublicKey key2)
 {
   if (key1 == key2)
     return TRUE;
@@ -966,25 +959,9 @@ SilcPublicKey silc_pkcs_public_key_copy(SilcPublicKey public_key)
 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. */
@@ -1016,7 +993,7 @@ silc_pkcs_private_key_data_encode(unsigned char *prv, SilcUInt32 prv_len,
 /* Decodes SILC style private key. Returns TRUE if the decoding was
    successful. Allocates new private key as well. */
 
-bool silc_pkcs_private_key_decode(unsigned char *data, SilcUInt32 data_len,
+SilcBool silc_pkcs_private_key_decode(unsigned char *data, SilcUInt32 data_len,
                                  SilcPrivateKey *private_key)
 {
   SilcBufferStruct buf;
@@ -1038,7 +1015,7 @@ bool silc_pkcs_private_key_decode(unsigned char *data, SilcUInt32 data_len,
     goto err;
   }
 
-  if (pkcs_len < 1 || pkcs_len > buf.truelen) {
+  if (pkcs_len < 1 || pkcs_len > silc_buffer_truelen(&buf)) {
     SILC_LOG_DEBUG(("Malformed private key buffer"));
     goto err;
   }
@@ -1051,7 +1028,7 @@ bool silc_pkcs_private_key_decode(unsigned char *data, SilcUInt32 data_len,
 
   /* Get key data. We assume that rest of the buffer is key data. */
   silc_buffer_pull(&buf, 2 + pkcs_len);
-  key_len = buf.len;
+  key_len = silc_buffer_len(&buf);
   ret = silc_buffer_unformat(&buf,
                             SILC_STR_UI_XNSTRING_ALLOC(&key_data, key_len),
                             SILC_STR_END);
@@ -1062,7 +1039,7 @@ bool silc_pkcs_private_key_decode(unsigned char *data, SilcUInt32 data_len,
      code assumes that the PKCS routine checks the format of the key.
      (check only if PKCS are registered) */
   if (SILC_PKCS_LIST) {
-    silc_pkcs_alloc(pkcs_name, &alg);
+    silc_pkcs_alloc(pkcs_name, SILC_PKCS_SILC, &alg);
     if (!alg->pkcs->set_private_key(alg->context, key_data, key_len)) {
       SILC_LOG_DEBUG(("Could not set private key data"));
       goto err;
@@ -1087,7 +1064,7 @@ bool silc_pkcs_private_key_decode(unsigned char *data, SilcUInt32 data_len,
 
 /* Internal routine to save public key */
 
-static bool silc_pkcs_save_public_key_internal(const char *filename,
+static SilcBool silc_pkcs_save_public_key_internal(const char *filename,
                                               unsigned char *data,
                                               SilcUInt32 data_len,
                                               SilcUInt32 encoding)
@@ -1120,7 +1097,7 @@ static bool silc_pkcs_save_public_key_internal(const char *filename,
                     SILC_STR_END);
 
   /* Save into file */
-  if (silc_file_writefile(filename, buf->data, buf->len)) {
+  if (silc_file_writefile(filename, buf->data, silc_buffer_len(buf))) {
     silc_free(tmp);
     silc_buffer_free(buf);
     return FALSE;
@@ -1133,12 +1110,12 @@ static bool silc_pkcs_save_public_key_internal(const char *filename,
 
 /* Saves public key into file */
 
-bool silc_pkcs_save_public_key(const char *filename, SilcPublicKey public_key,
+SilcBool silc_pkcs_save_public_key(const char *filename, SilcPublicKey public_key,
                               SilcUInt32 encoding)
 {
   unsigned char *data;
   SilcUInt32 data_len;
-  bool ret;
+  SilcBool ret;
 
   data = silc_pkcs_public_key_encode(public_key, &data_len);
   ret = silc_pkcs_save_public_key_internal(filename, data, data_len,
@@ -1149,7 +1126,7 @@ bool silc_pkcs_save_public_key(const char *filename, SilcPublicKey public_key,
 
 /* Saves public key into file */
 
-bool silc_pkcs_save_public_key_data(const char *filename, unsigned char *data,
+SilcBool silc_pkcs_save_public_key_data(const char *filename, unsigned char *data,
                                    SilcUInt32 data_len, SilcUInt32 encoding)
 {
   return silc_pkcs_save_public_key_internal(filename, data, data_len,
@@ -1160,7 +1137,7 @@ bool silc_pkcs_save_public_key_data(const char *filename, unsigned char *data,
 
 /* Internal routine to save private key. */
 
-static bool silc_pkcs_save_private_key_internal(const char *filename,
+static SilcBool silc_pkcs_save_private_key_internal(const char *filename,
                                                unsigned char *data,
                                                SilcUInt32 data_len,
                                                unsigned char *key,
@@ -1247,14 +1224,14 @@ static bool silc_pkcs_save_private_key_internal(const char *filename,
                     SILC_STR_END);
 
   /* Encrypt. */
-  silc_cipher_encrypt(aes, enc->data, enc->data, enc->len - len,
+  silc_cipher_encrypt(aes, enc->data, enc->data, silc_buffer_len(enc) - len,
                      silc_cipher_get_iv(aes));
 
   silc_buffer_push(enc, 4);
 
   /* Compute HMAC over the encrypted data and append the MAC to data.
      The key is the first digest of the original key material. */
-  data_len = enc->len - len;
+  data_len = silc_buffer_len(enc) - len;
   silc_hmac_init_with_key(sha1hmac, keymat, 16);
   silc_hmac_update(sha1hmac, enc->data, data_len);
   silc_buffer_pull(enc, data_len);
@@ -1269,7 +1246,7 @@ static bool silc_pkcs_save_private_key_internal(const char *filename,
   silc_cipher_free(aes);
 
   data = enc->data;
-  data_len = enc->len;
+  data_len = silc_buffer_len(enc);
 
   switch (encoding) {
   case SILC_PKCS_FILE_BIN:
@@ -1291,7 +1268,8 @@ static bool silc_pkcs_save_private_key_internal(const char *filename,
                     SILC_STR_END);
 
   /* Save into a file */
-  if (silc_file_writefile_mode(filename, buf->data, buf->len, 0600)) {
+  if (silc_file_writefile_mode(filename, buf->data,
+                              silc_buffer_len(buf), 0600)) {
     silc_buffer_clear(buf);
     silc_buffer_free(buf);
     silc_buffer_clear(enc);
@@ -1308,7 +1286,7 @@ static bool silc_pkcs_save_private_key_internal(const char *filename,
 
 /* Saves private key into file. */
 
-bool silc_pkcs_save_private_key(const char *filename,
+SilcBool silc_pkcs_save_private_key(const char *filename,
                                SilcPrivateKey private_key,
                                unsigned char *passphrase,
                                SilcUInt32 passphrase_len,
@@ -1316,7 +1294,7 @@ bool silc_pkcs_save_private_key(const char *filename,
 {
   unsigned char *data;
   SilcUInt32 data_len;
-  bool ret;
+  SilcBool ret;
 
   data = silc_pkcs_private_key_encode(private_key, &data_len);
   ret = silc_pkcs_save_private_key_internal(filename, data, data_len,
@@ -1330,7 +1308,7 @@ bool silc_pkcs_save_private_key(const char *filename,
 /* Loads public key from file and allocates new public key. Returns TRUE
    if loading was successful. */
 
-bool silc_pkcs_load_public_key(const char *filename, SilcPublicKey *public_key,
+SilcBool silc_pkcs_load_public_key(const char *filename, SilcPublicKey *public_key,
                               SilcUInt32 encoding)
 {
   unsigned char *cp, *old, *data, byte;
@@ -1390,7 +1368,7 @@ bool silc_pkcs_load_public_key(const char *filename, SilcPublicKey *public_key,
 /* Load private key from file and allocates new private key. Returns TRUE
    if loading was successful. */
 
-bool silc_pkcs_load_private_key(const char *filename,
+SilcBool silc_pkcs_load_private_key(const char *filename,
                                SilcPrivateKey *private_key,
                                unsigned char *passphrase,
                                SilcUInt32 passphrase_len,