Added SILC Thread Queue API
[crypto.git] / apps / silc / clientconfig.c
index 1e85aa4f2150e490f7a8604d1a331f86ca7307c5..2fc31faf06b09d4f5833e2537f3af38a5ca3e766 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
 
-  Copyright (C) 1997 - 2000 Pekka Riikonen
+  Copyright (C) 1997 - 2001 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
@@ -29,9 +29,11 @@ SilcClientConfigSection silc_client_config_sections[] = {
   { "[cipher]", 
     SILC_CLIENT_CONFIG_SECTION_TYPE_CIPHER, 4 },
   { "[pkcs]", 
-    SILC_CLIENT_CONFIG_SECTION_TYPE_PKCS, 2 },
+    SILC_CLIENT_CONFIG_SECTION_TYPE_PKCS, 1 },
   { "[hash]", 
     SILC_CLIENT_CONFIG_SECTION_TYPE_HASH_FUNCTION, 4 },
+  { "[hmac]", 
+    SILC_CLIENT_CONFIG_SECTION_TYPE_HMAC, 3 },
   { "[connection]", 
     SILC_CLIENT_CONFIG_SECTION_TYPE_CONNECTION, 4 },
   { "[commands]", 
@@ -95,7 +97,7 @@ int silc_client_config_parse(SilcClientConfig config, SilcBuffer buffer,
                             SilcClientConfigParse *return_config)
 {
   int i, begin;
-  unsigned int linenum;
+  int linenum;
   char line[1024], *cp;
   SilcClientConfigSection *cptr = NULL;
   SilcClientConfigParse parse = *return_config, first = NULL;
@@ -325,18 +327,6 @@ int silc_client_config_parse_lines(SilcClientConfig config,
        break;
       }
 
-      /* Get key length */
-      ret = silc_config_get_token(line, &tmp);
-      if (ret < 0)
-       break;
-      if (ret == 0) {
-       fprintf(stderr, "%s:%d: PKCS key length not defined\n",
-               config->filename, pc->linenum);
-       break;
-      }
-      config->pkcs->key_len = atoi(tmp);
-      silc_free(tmp);
-
       check = TRUE;
       break;
 
@@ -399,6 +389,57 @@ int silc_client_config_parse_lines(SilcClientConfig config,
       check = TRUE;
       break;
 
+    case SILC_CLIENT_CONFIG_SECTION_TYPE_HMAC:
+
+      if (!config->hmac) {
+       config->hmac = silc_calloc(1, sizeof(*config->hmac));
+       config->hmac->next = NULL;
+       config->hmac->prev = NULL;
+      } else {
+       if (!config->hmac->next) {
+         config->hmac->next = 
+           silc_calloc(1, sizeof(*config->hmac->next));
+         config->hmac->next->next = NULL;
+         config->hmac->next->prev = config->hmac;
+         config->hmac = config->hmac->next;
+       }
+      }
+
+      /* Get HMAC name */
+      ret = silc_config_get_token(line, &config->hmac->alg_name);
+      if (ret < 0)
+       break;
+      if (ret == 0) {
+       fprintf(stderr, "%s:%d: HMAC name not defined\n",
+               config->filename, pc->linenum);
+       break;
+      }
+      
+      /* Get Hash function name */
+      ret = silc_config_get_token(line, &config->hmac->sim_name);
+      if (ret < 0)
+       break;
+      if (ret == 0) {
+       fprintf(stderr, "%s:%d: Hash function name not defined\n",
+               config->filename, pc->linenum);
+       break;
+      }
+
+      /* Get MAC length */
+      ret = silc_config_get_token(line, &tmp);
+      if (ret < 0)
+       break;
+      if (ret == 0) {
+       fprintf(stderr, "%s:%d: HMAC's MAC length not defined\n",
+               config->filename, pc->linenum);
+       break;
+      }
+      config->hmac->key_len = atoi(tmp);
+      silc_free(tmp);
+
+      check = TRUE;
+      break;
+
     case SILC_CLIENT_CONFIG_SECTION_TYPE_CONNECTION:
 
       if (!config->conns) {
@@ -513,6 +554,8 @@ int silc_client_config_parse_lines(SilcClientConfig config,
     config->pkcs = config->pkcs->prev;
   while (config->hash_func && config->hash_func->prev)
     config->hash_func = config->hash_func->prev;
+  while (config->hmac && config->hmac->prev)
+    config->hmac = config->hmac->prev;
   while (config->conns && config->conns->prev)
     config->conns = config->conns->prev;
   while (config->commands && config->commands->prev)
@@ -526,7 +569,7 @@ int silc_client_config_parse_lines(SilcClientConfig config,
 /* Registers configured ciphers. These can then be allocated by the
    client when needed. */
 
-void silc_client_config_register_ciphers(SilcClientConfig config)
+bool silc_client_config_register_ciphers(SilcClientConfig config)
 {
   SilcClientConfigSectionAlg *alg;
   SilcClientInternal app = (SilcClientInternal)config->client;
@@ -534,20 +577,28 @@ void silc_client_config_register_ciphers(SilcClientConfig config)
 
   SILC_LOG_DEBUG(("Registering configured ciphers"));
 
+  if (!config->cipher)
+    return FALSE;
+
   alg = config->cipher;
   while(alg) {
 
     if (!alg->sim_name) {
-      /* Crypto module is supposed to be built in. Nothing to be done
-        here except to test that the cipher really is built in. */
-      SilcCipher tmp = NULL;
+      /* Crypto module is supposed to be built in. Get the pointer to the
+        built in cipher and register it. */
+      int i;
 
-      if (silc_cipher_alloc(alg->alg_name, &tmp) == FALSE) {
-       SILC_LOG_ERROR(("Unsupported cipher `%s'", alg->alg_name));
+      for (i = 0; silc_default_ciphers[i].name; i++)
+       if (!strcmp(silc_default_ciphers[i].name, alg->alg_name)) {
+         silc_cipher_register(&silc_default_ciphers[i]);
+         break;
+       }
+
+      if (!silc_cipher_is_supported(alg->alg_name)) {
+       SILC_LOG_ERROR(("Unknown cipher `%s'", alg->alg_name));
        silc_client_stop(client);
        exit(1);
       }
-      silc_cipher_free(tmp);
 
 #ifdef SILC_SIM
     } else {
@@ -576,7 +627,7 @@ void silc_client_config_register_ciphers(SilcClientConfig config)
        SILC_LOG_DEBUG(("set_key=%p", cipher.set_key));
        cipher.set_key_with_string = 
          silc_sim_getsym(sim, silc_sim_symname(alg_name, 
-                                               SILC_CIPHER_SIM_SET_KEY_WITH_STRING));
+                                        SILC_CIPHER_SIM_SET_KEY_WITH_STRING));
        SILC_LOG_DEBUG(("set_key_with_string=%p", cipher.set_key_with_string));
        cipher.encrypt = 
          silc_sim_getsym(sim, silc_sim_symname(alg_name,
@@ -612,40 +663,48 @@ void silc_client_config_register_ciphers(SilcClientConfig config)
 
     alg = alg->next;
   }
+
+  return TRUE;
 }
 
 /* Registers configured PKCS's. */
-/* XXX: This really doesn't do anything now since we have statically
-   registered our PKCS's. This should be implemented when PKCS works
-   as SIM's. This checks now only that the PKCS user requested is 
-   really out there. */
 
-void silc_client_config_register_pkcs(SilcClientConfig config)
+bool silc_client_config_register_pkcs(SilcClientConfig config)
 {
   SilcClientConfigSectionAlg *alg = config->pkcs;
   SilcClientInternal app = (SilcClientInternal)config->client;
   SilcClient client = app->client;
-  SilcPKCS tmp = NULL;
 
   SILC_LOG_DEBUG(("Registering configured PKCS"));
 
-  while(alg) {
+  if (!alg)
+    return FALSE;
 
-    if (silc_pkcs_alloc(alg->alg_name, &tmp) == FALSE) {
-      SILC_LOG_ERROR(("Unsupported PKCS `%s'", alg->alg_name));
+  while(alg) {
+    int i;
+    
+    for (i = 0; silc_default_pkcs[i].name; i++)
+      if (!strcmp(silc_default_pkcs[i].name, alg->alg_name)) {
+       silc_pkcs_register(&silc_default_pkcs[i]);
+       break;
+      }
+    
+    if (!silc_pkcs_is_supported(alg->alg_name)) {
+      SILC_LOG_ERROR(("Unknown PKCS `%s'", alg->alg_name));
       silc_client_stop(client);
       exit(1);
     }
-    silc_free(tmp);
 
     alg = alg->next;
   }
+
+  return TRUE;
 }
 
-/* Registers configured hash functions. These can then be allocated by the
+/* Registers configured hash funtions. These can then be allocated by the
    client when needed. */
 
-void silc_client_config_register_hashfuncs(SilcClientConfig config)
+bool silc_client_config_register_hashfuncs(SilcClientConfig config)
 {
   SilcClientConfigSectionAlg *alg;
   SilcClientInternal app = (SilcClientInternal)config->client;
@@ -653,21 +712,25 @@ void silc_client_config_register_hashfuncs(SilcClientConfig config)
 
   SILC_LOG_DEBUG(("Registering configured hash functions"));
 
+  if (!config->hash_func)
+    return FALSE;
+
   alg = config->hash_func;
   while(alg) {
-
     if (!alg->sim_name) {
-      /* Hash module is supposed to be built in. Nothing to be done
-        here except to test that the hash function really is built in. */
-      SilcHash tmp = NULL;
-
-      if (silc_hash_alloc(alg->alg_name, &tmp) == FALSE) {
-       SILC_LOG_ERROR(("Unsupported hash function `%s'", alg->alg_name));
+      int i;
+      
+      for (i = 0; silc_default_hash[i].name; i++)
+       if (!strcmp(silc_default_hash[i].name, alg->alg_name)) {
+         silc_hash_register(&silc_default_hash[i]);
+         break;
+       }
+      
+      if (!silc_hash_is_supported(alg->alg_name)) {
+       SILC_LOG_ERROR(("Unknown hash function `%s'", alg->alg_name));
        silc_client_stop(client);
        exit(1);
       }
-      silc_free(tmp);
-
 #ifdef SILC_SIM
     } else {
       /* Load (try at least) the hash SIM module */
@@ -713,15 +776,52 @@ void silc_client_config_register_hashfuncs(SilcClientConfig config)
        exit(1);
       }
 
-      /* Register the cipher */
+      /* Register the hash function */
       silc_hash_register(&hash);
 #endif
     }
-
     alg = alg->next;
   }
+
+  return TRUE;
 }
 
+/* Registers configured HMACs. These can then be allocated by the
+   client when needed. */
+
+bool silc_client_config_register_hmacs(SilcClientConfig config)
+{
+  SilcClientConfigSectionAlg *alg;
+  SilcClientInternal app = (SilcClientInternal)config->client;
+  SilcClient client = app->client;
+
+  SILC_LOG_DEBUG(("Registering configured HMACs"));
+
+  if (!config->hmac)
+    return FALSE;
+
+  alg = config->hmac;
+  while(alg) {
+    SilcHmacObject hmac;
+    
+    if (!silc_hash_is_supported(alg->sim_name)) {
+      SILC_LOG_ERROR(("Unknown hash function `%s' for HMAC `%s'", 
+                     alg->sim_name, alg->alg_name));
+      silc_client_stop(client);
+      exit(1);
+    }
+    
+    /* Register the HMAC */
+    memset(&hmac, 0, sizeof(hmac));
+    hmac.name = alg->alg_name;
+    hmac.len = alg->key_len;
+    silc_hmac_register(&hmac);
+
+    alg = alg->next;
+  }
+
+  return TRUE;
+}
 
 SilcClientConfigSectionConnection *
 silc_client_config_find_connection(SilcClientConfig config,