updates.
[silc.git] / lib / silccrypt / silcpkcs.c
index 2f9699bb064bdeb51674a554f13b12f9c839d129..4e7cdcfe6e76a55c5b997415dc8d4a2361e93c97 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(). */
-SilcPKCSObject silc_default_pkcs[] =
+const SilcPKCSObject silc_default_pkcs[] =
 {
   /* RSA with PKCS #1 (Uses directly routines from Raw RSA operations) */
   { "rsa", 
@@ -53,8 +58,9 @@ SilcPKCSObject silc_default_pkcs[] =
 /* Register a new PKCS into SILC. This is used at the initialization of
    the SILC. */
 
-bool silc_pkcs_register(SilcPKCSObject *pkcs)
+bool silc_pkcs_register(const 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(&(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,36 +231,60 @@ 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 */
 
-uint32 silc_pkcs_get_key_len(SilcPKCS pkcs)
+SilcUInt32 silc_pkcs_get_key_len(SilcPKCS pkcs)
 {
   return pkcs->key_len;
 }
 
 /* Returns SILC style public key */
 
-unsigned char *silc_pkcs_get_public_key(SilcPKCS pkcs, uint32 *len)
+unsigned char *silc_pkcs_get_public_key(SilcPKCS pkcs, SilcUInt32 *len)
 {
   return pkcs->pkcs->get_public_key(pkcs->context, len);
 }
 
 /* Returns SILC style private key */
 
-unsigned char *silc_pkcs_get_private_key(SilcPKCS pkcs, uint32 *len)
+unsigned char *silc_pkcs_get_private_key(SilcPKCS pkcs, SilcUInt32 *len)
 {
   return pkcs->pkcs->get_private_key(pkcs->context, len);
 }
 
 /* Sets public key from SilcPublicKey. */
 
-uint32 silc_pkcs_public_key_set(SilcPKCS pkcs, SilcPublicKey public_key)
+SilcUInt32 silc_pkcs_public_key_set(SilcPKCS pkcs, SilcPublicKey public_key)
 {
   pkcs->key_len = pkcs->pkcs->set_public_key(pkcs->context, public_key->pk, 
                                             public_key->pk_len);
@@ -234,8 +293,8 @@ uint32 silc_pkcs_public_key_set(SilcPKCS pkcs, SilcPublicKey public_key)
 
 /* Sets public key from data. */
 
-uint32 silc_pkcs_public_key_data_set(SilcPKCS pkcs, unsigned char *pk,
-                                    uint32 pk_len)
+SilcUInt32 silc_pkcs_public_key_data_set(SilcPKCS pkcs, unsigned char *pk,
+                                    SilcUInt32 pk_len)
 {
   pkcs->key_len = pkcs->pkcs->set_public_key(pkcs->context, pk, pk_len);
   return pkcs->key_len;
@@ -252,31 +311,31 @@ int silc_pkcs_private_key_set(SilcPKCS pkcs, SilcPrivateKey private_key)
 /* Sets private key from data. */
 
 int silc_pkcs_private_key_data_set(SilcPKCS pkcs, unsigned char *prv,
-                                  uint32 prv_len)
+                                  SilcUInt32 prv_len)
 {
   return pkcs->pkcs->set_private_key(pkcs->context, prv, prv_len);
 }
 
 /* Encrypts */
 
-int silc_pkcs_encrypt(SilcPKCS pkcs, unsigned char *src, uint32 src_len,
-                     unsigned char *dst, uint32 *dst_len)
+int 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);
 }
 
 /* Decrypts */
 
-int silc_pkcs_decrypt(SilcPKCS pkcs, unsigned char *src, uint32 src_len,
-                     unsigned char *dst, uint32 *dst_len)
+int 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);
 }
 
 /* Generates signature */
 
-int silc_pkcs_sign(SilcPKCS pkcs, unsigned char *src, uint32 src_len,
-                  unsigned char *dst, uint32 *dst_len)
+int 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);
 }
@@ -284,8 +343,8 @@ int silc_pkcs_sign(SilcPKCS pkcs, unsigned char *src, uint32 src_len,
 /* Verifies signature */
 
 int silc_pkcs_verify(SilcPKCS pkcs, unsigned char *signature, 
-                    uint32 signature_len, unsigned char *data, 
-                    uint32 data_len)
+                    SilcUInt32 signature_len, unsigned char *data, 
+                    SilcUInt32 data_len)
 {
   return pkcs->pkcs->verify(pkcs->context, signature, signature_len, 
                            data, data_len);
@@ -294,11 +353,11 @@ int silc_pkcs_verify(SilcPKCS pkcs, unsigned char *signature,
 /* Generates signature with hash. The hash is signed. */
 
 int silc_pkcs_sign_with_hash(SilcPKCS pkcs, SilcHash hash,
-                            unsigned char *src, uint32 src_len,
-                            unsigned char *dst, uint32 *dst_len)
+                            unsigned char *src, SilcUInt32 src_len,
+                            unsigned char *dst, SilcUInt32 *dst_len)
 {
   unsigned char hashr[32];
-  uint32 hash_len;
+  SilcUInt32 hash_len;
   int ret;
 
   silc_hash_make(hash, src, src_len, hashr);
@@ -317,12 +376,12 @@ int silc_pkcs_sign_with_hash(SilcPKCS pkcs, SilcHash hash,
 
 int silc_pkcs_verify_with_hash(SilcPKCS pkcs, SilcHash hash, 
                               unsigned char *signature, 
-                              uint32 signature_len, 
+                              SilcUInt32 signature_len, 
                               unsigned char *data, 
-                              uint32 data_len)
+                              SilcUInt32 data_len)
 {
   unsigned char hashr[32];
-  uint32 hash_len;
+  SilcUInt32 hash_len;
   int ret;
 
   silc_hash_make(hash, data, data_len, hashr);
@@ -346,7 +405,7 @@ char *silc_pkcs_encode_identifier(char *username, char *host, char *realname,
 {
   SilcBuffer buf;
   char *identifier;
-  uint32 len, tlen = 0;
+  SilcUInt32 len, tlen = 0;
 
   if (!username || !host)
     return NULL;
@@ -503,7 +562,7 @@ void silc_pkcs_free_identifier(SilcPublicKeyIdentifier identifier)
 
 SilcPublicKey silc_pkcs_public_key_alloc(char *name, char *identifier,
                                         unsigned char *pk, 
-                                        uint32 pk_len)
+                                        SilcUInt32 pk_len)
 {
   SilcPublicKey public_key;
 
@@ -534,7 +593,7 @@ void silc_pkcs_public_key_free(SilcPublicKey public_key)
    duplicated. */
 
 SilcPrivateKey silc_pkcs_private_key_alloc(char *name, unsigned char *prv,
-                                          uint32 prv_len)
+                                          SilcUInt32 prv_len)
 {
   SilcPrivateKey private_key;
 
@@ -562,7 +621,7 @@ void silc_pkcs_private_key_free(SilcPrivateKey private_key)
    data. */
 
 unsigned char *
-silc_pkcs_public_key_encode(SilcPublicKey public_key, uint32 *len)
+silc_pkcs_public_key_encode(SilcPublicKey public_key, SilcUInt32 *len)
 {
   SilcBuffer buf;
   unsigned char *ret;
@@ -592,13 +651,13 @@ silc_pkcs_public_key_encode(SilcPublicKey public_key, uint32 *len)
 /* Encodes SILC style public key. Returns the encoded data. */
 
 unsigned char *
-silc_pkcs_public_key_data_encode(unsigned char *pk, uint32 pk_len,
+silc_pkcs_public_key_data_encode(unsigned char *pk, SilcUInt32 pk_len,
                                 char *pkcs, char *identifier, 
-                                uint32 *len)
+                                SilcUInt32 *len)
 {
   SilcBuffer buf;
   unsigned char *ret;
-  uint32 totlen;
+  SilcUInt32 totlen;
 
   totlen = 4 + 2 + strlen(pkcs) + 2 + strlen(identifier) + pk_len;
   buf = silc_buffer_alloc(totlen);
@@ -625,13 +684,13 @@ silc_pkcs_public_key_data_encode(unsigned char *pk, uint32 pk_len,
 /* Decodes SILC style public key. Returns TRUE if the decoding was
    successful. Allocates new public key as well. */
 
-int silc_pkcs_public_key_decode(unsigned char *data, uint32 data_len,
+int silc_pkcs_public_key_decode(unsigned char *data, SilcUInt32 data_len,
                                SilcPublicKey *public_key)
 {
   SilcBuffer buf;
   SilcPKCS alg;
-  uint16 pkcs_len, identifier_len;
-  uint32 totlen, key_len;
+  SilcUInt16 pkcs_len, identifier_len;
+  SilcUInt32 totlen, key_len;
   unsigned char *pkcs_name = NULL, *ident = NULL, *key_data = NULL;
   int ret;
 
@@ -668,7 +727,7 @@ int silc_pkcs_public_key_decode(unsigned char *data, uint32 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, uint32 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;
@@ -745,11 +804,11 @@ bool silc_pkcs_public_key_compare(SilcPublicKey key1, SilcPublicKey key2)
 /* Encodes SILC private key from SilcPrivateKey. Returns the encoded data. */
 
 unsigned char *
-silc_pkcs_private_key_encode(SilcPrivateKey private_key, uint32 *len)
+silc_pkcs_private_key_encode(SilcPrivateKey private_key, SilcUInt32 *len)
 {
   SilcBuffer buf;
   unsigned char *ret;
-  uint32 totlen;
+  SilcUInt32 totlen;
 
   totlen = 2 + strlen(private_key->name) + private_key->prv_len;
   buf = silc_buffer_alloc(totlen);
@@ -774,12 +833,12 @@ silc_pkcs_private_key_encode(SilcPrivateKey private_key, uint32 *len)
 /* Encodes SILC private key. Returns the encoded data. */
 
 unsigned char *
-silc_pkcs_private_key_data_encode(unsigned char *prv, uint32 prv_len,
-                                 char *pkcs, uint32 *len)
+silc_pkcs_private_key_data_encode(unsigned char *prv, SilcUInt32 prv_len,
+                                 char *pkcs, SilcUInt32 *len)
 {
   SilcBuffer buf;
   unsigned char *ret;
-  uint32 totlen;
+  SilcUInt32 totlen;
 
   totlen = 2 + strlen(pkcs) + prv_len;
   buf = silc_buffer_alloc(totlen);
@@ -803,13 +862,13 @@ silc_pkcs_private_key_data_encode(unsigned char *prv, uint32 prv_len,
 /* Decodes SILC style public key. Returns TRUE if the decoding was
    successful. Allocates new private key as well. */
 
-int silc_pkcs_private_key_decode(unsigned char *data, uint32 data_len,
+int silc_pkcs_private_key_decode(unsigned char *data, SilcUInt32 data_len,
                                 SilcPrivateKey *private_key)
 {
   SilcBuffer buf;
   SilcPKCS alg;
-  uint16 pkcs_len;
-  uint32 key_len;
+  SilcUInt16 pkcs_len;
+  SilcUInt32 key_len;
   unsigned char *pkcs_name = NULL, *key_data = NULL;
   int ret;
 
@@ -829,7 +888,7 @@ int silc_pkcs_private_key_decode(unsigned char *data, uint32 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, uint32 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;
@@ -876,11 +935,11 @@ int silc_pkcs_private_key_decode(unsigned char *data, uint32 data_len,
 
 static int silc_pkcs_save_public_key_internal(char *filename,
                                              unsigned char *data,
-                                             uint32 data_len,
-                                             uint32 encoding)
+                                             SilcUInt32 data_len,
+                                             SilcUInt32 encoding)
 {
   SilcBuffer buf;
-  uint32 len;
+  SilcUInt32 len;
 
   switch(encoding) {
   case SILC_PKCS_FILE_BIN:
@@ -915,10 +974,10 @@ static int silc_pkcs_save_public_key_internal(char *filename,
 /* Saves public key into file */
 
 int silc_pkcs_save_public_key(char *filename, SilcPublicKey public_key,
-                             uint32 encoding)
+                             SilcUInt32 encoding)
 {
   unsigned char *data;
-  uint32 data_len;
+  SilcUInt32 data_len;
 
   data = silc_pkcs_public_key_encode(public_key, &data_len);
   return silc_pkcs_save_public_key_internal(filename, data, data_len,
@@ -928,8 +987,8 @@ int silc_pkcs_save_public_key(char *filename, SilcPublicKey public_key,
 /* Saves public key into file */
 
 int silc_pkcs_save_public_key_data(char *filename, unsigned char *data,
-                                  uint32 data_len,
-                                  uint32 encoding)
+                                  SilcUInt32 data_len,
+                                  SilcUInt32 encoding)
 {
   return silc_pkcs_save_public_key_internal(filename, data, data_len,
                                            encoding);
@@ -939,11 +998,11 @@ int silc_pkcs_save_public_key_data(char *filename, unsigned char *data,
 
 static int silc_pkcs_save_private_key_internal(char *filename,
                                               unsigned char *data,
-                                              uint32 data_len,
-                                              uint32 encoding)
+                                              SilcUInt32 data_len,
+                                              SilcUInt32 encoding)
 {
   SilcBuffer buf;
-  uint32 len;
+  SilcUInt32 len;
 
   switch(encoding) {
   case SILC_PKCS_FILE_BIN:
@@ -980,10 +1039,10 @@ static int silc_pkcs_save_private_key_internal(char *filename,
 
 int silc_pkcs_save_private_key(char *filename, SilcPrivateKey private_key, 
                               unsigned char *passphrase,
-                              uint32 encoding)
+                              SilcUInt32 encoding)
 {
   unsigned char *data;
-  uint32 data_len;
+  SilcUInt32 data_len;
 
   data = silc_pkcs_private_key_encode(private_key, &data_len);
   return silc_pkcs_save_private_key_internal(filename, data, data_len,
@@ -994,9 +1053,9 @@ int silc_pkcs_save_private_key(char *filename, SilcPrivateKey private_key,
 /* XXX The buffer should be encrypted if passphrase is provided. */
 
 int silc_pkcs_save_private_key_data(char *filename, unsigned char *data, 
-                                   uint32 data_len,
+                                   SilcUInt32 data_len,
                                    unsigned char *passphrase,
-                                   uint32 encoding)
+                                   SilcUInt32 encoding)
 {
   return silc_pkcs_save_private_key_internal(filename, data, data_len,
                                             encoding);
@@ -1006,10 +1065,10 @@ int silc_pkcs_save_private_key_data(char *filename, unsigned char *data,
    is loading was successful. */
 
 int silc_pkcs_load_public_key(char *filename, SilcPublicKey *public_key,
-                             uint32 encoding)
+                             SilcUInt32 encoding)
 {
   unsigned char *cp, *old, *data, byte;
-  uint32 i, data_len, len;
+  SilcUInt32 i, data_len, len;
 
   old = data = silc_file_readfile(filename, &data_len);
   if (!data)
@@ -1063,10 +1122,10 @@ int silc_pkcs_load_public_key(char *filename, SilcPublicKey *public_key,
 /* XXX Should support encrypted private key files */
 
 int silc_pkcs_load_private_key(char *filename, SilcPrivateKey *private_key,
-                              uint32 encoding)
+                              SilcUInt32 encoding)
 {
   unsigned char *cp, *old, *data, byte;
-  uint32 i, data_len, len;
+  SilcUInt32 i, data_len, len;
 
   old = data = silc_file_readfile(filename, &data_len);
   if (!data)