Added SILC Server library.
[silc.git] / lib / silccrypt / silcpkcs.c
index d74072c0123a0ffb0b181301301544b8f66fa2c7..240456ff481380d89647ee664654bb9700b4d430 100644 (file)
@@ -18,7 +18,7 @@
 */
 /* $Id$ */
 
-#include "silcincludes.h"
+#include "silc.h"
 
 #include "rsa.h"
 
@@ -40,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;
@@ -75,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;
@@ -105,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;
@@ -139,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;
@@ -151,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;
@@ -172,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;
 
@@ -182,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;
     }
   }
@@ -191,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;
       }
@@ -222,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;
@@ -289,10 +295,10 @@ 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)
 {
-  bool ret = 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;
@@ -368,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);
@@ -376,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);
@@ -384,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);
@@ -392,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)
 {
@@ -402,7 +408,7 @@ 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)
 {
@@ -424,7 +430,7 @@ 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,
@@ -743,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;
@@ -811,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);
@@ -870,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)
 {
@@ -912,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;
@@ -987,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;
@@ -1033,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;
@@ -1058,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)
@@ -1104,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,
@@ -1120,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,
@@ -1131,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,
@@ -1280,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,
@@ -1288,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,
@@ -1302,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;
@@ -1362,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,