Added silcapputil.[ch] for application utility functions for
authorPekka Riikonen <priikone@silcnet.org>
Tue, 29 Oct 2002 20:18:04 +0000 (20:18 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Tue, 29 Oct 2002 20:18:04 +0000 (20:18 +0000)
convenience.  Moved code around from irssi and server to this
new file.

CHANGES
apps/irssi/src/silc/core/clientutil.c
apps/irssi/src/silc/core/clientutil.h
apps/irssi/src/silc/core/silc-core.c
apps/silcd/silcd.c
includes/silcincludes.h
lib/silccrypt/silcpkcs.h
lib/silcutil/DIRECTORY
lib/silcutil/Makefile.am
lib/silcutil/silcapputil.c [new file with mode: 0644]
lib/silcutil/silcapputil.h [new file with mode: 0644]

diff --git a/CHANGES b/CHANGES
index 6eb656d8ec851f636523f2cf47568d8a7efeaf70..795059947b07f184ae0ee94c970683738aa6fe2b 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,10 @@
+Tue Oct 29 21:48:55 EET 2002  Pekka Riikonen <priikone@silcnet.org>
+
+       * Added lib/silcutil/silcapputil.[ch] for application
+         utility functions.  It includes routines for applications'
+         convenience.  Added silc_create_key_pair, silc_show_public_key
+         and silc_load_key_pair functions.
+
 Tue Oct 29 17:36:44 EET 2002  Pekka Riikonen <priikone@silcnet.org>
 
        * Send RESUME_CLIENT packet from router to backup routers
index 5a0f3438375f7a564751e12359a440e38f5c47a9..cdc0fc9ee3bb9fdd9bbccc4e33dcf3ae9991210a 100644 (file)
@@ -80,174 +80,6 @@ void silc_client_list_pkcs()
   silc_free(pkcs);
 }
 
-/* Returns identifier string for public key generation. */
-
-char *silc_client_create_identifier()
-{
-  char *username = NULL, *realname = NULL;
-  char *hostname, email[256];
-  char *ident;
-  
-  /* Get realname */
-  realname = silc_get_real_name();
-
-  /* Get hostname */
-  hostname = silc_net_localhost();
-  if (!hostname)
-    return NULL;
-
-  /* Get username (mandatory) */
-  username = silc_get_username();
-  if (!username)
-    return NULL;
-
-  /* Create default email address, whether it is right or not */
-  snprintf(email, sizeof(email), "%s@%s", username, hostname);
-
-  ident = silc_pkcs_encode_identifier(username, hostname, realname, email,
-                                     NULL, NULL);
-  if (realname)
-    silc_free(realname);
-  silc_free(hostname);
-  silc_free(username);
-
-  return ident;
-}
-
-/* Creates new public key and private key pair. This is used only
-   when user wants to create new key pair from command line. */
-
-int silc_client_create_key_pair(char *pkcs_name, int bits,
-                               char *public_key, char *private_key,
-                               char *identifier, 
-                               SilcPublicKey *ret_pub_key,
-                               SilcPrivateKey *ret_prv_key)
-{
-  SilcPKCS pkcs;
-  SilcPublicKey pub_key;
-  SilcPrivateKey prv_key;
-  SilcRng rng;
-  unsigned char *key;
-  SilcUInt32 key_len;
-  char line[256];
-  char *pkfile = NULL, *prvfile = NULL;
-
-  if (!pkcs_name || !public_key || !private_key)
-    printf("\
-New pair of keys will be created.  Please, answer to following questions.\n\
-");
-
-  if (!pkcs_name) {
-  again_name:
-    pkcs_name = silc_get_input("PKCS name (l to list names) [rsa]: ", FALSE);
-    if (!pkcs_name)
-      pkcs_name = strdup("rsa");
-
-    if (*pkcs_name == 'l' || *pkcs_name == 'L') {
-      silc_client_list_pkcs();
-      silc_free(pkcs_name);
-      goto again_name;
-    }
-  }
-
-  if (!silc_pkcs_is_supported(pkcs_name)) {
-    fprintf(stderr, "Unknown PKCS `%s'", pkcs_name);
-    return FALSE;
-  }
-
-  if (!bits) {
-    char *length = NULL;
-    length = silc_get_input("Key length in bits [2048]: ", FALSE);
-    if (!length)
-      bits = 2048;
-    else
-      bits = atoi(length);
-  }
-
-  if (!identifier) {
-    char *def = silc_client_create_identifier();
-
-    memset(line, 0, sizeof(line));
-    if (def)
-      snprintf(line, sizeof(line), "Identifier [%s]: ", def);
-    else
-      snprintf(line, sizeof(line),
-              "Identifier (eg. UN=jon, HN=jon.dummy.com, "
-              "RN=Jon Johnson, E=jon@dummy.com): ");
-
-    while (!identifier) {
-      identifier = silc_get_input(line, FALSE);
-      if (!identifier && def)
-       identifier = strdup(def);
-    }
-
-    if (def)
-      silc_free(def);
-  }
-
-  rng = silc_rng_alloc();
-  silc_rng_init(rng);
-  silc_rng_global_init(rng);
-
-  if (!public_key) {
-    memset(line, 0, sizeof(line));
-    snprintf(line, sizeof(line), "Public key filename [%s] ", 
-            SILC_CLIENT_PUBLIC_KEY_NAME);
-    pkfile = silc_get_input(line, FALSE);
-    if (!pkfile)
-      pkfile = SILC_CLIENT_PUBLIC_KEY_NAME;
-  } else {
-    pkfile = public_key;
-  }
-
-  if (!private_key) {
-    memset(line, 0, sizeof(line));
-    snprintf(line, sizeof(line), "Public key filename [%s] ", 
-            SILC_CLIENT_PRIVATE_KEY_NAME);
-    prvfile = silc_get_input(line, FALSE);
-    if (!prvfile)
-      prvfile = SILC_CLIENT_PRIVATE_KEY_NAME;
-  } else {
-    prvfile = private_key;
-  }
-
-  /* Generate keys */
-  silc_pkcs_alloc(pkcs_name, &pkcs);
-  silc_pkcs_generate_key(pkcs, bits, rng);
-
-  /* Save public key into file */
-  key = silc_pkcs_get_public_key(pkcs, &key_len);
-  pub_key = silc_pkcs_public_key_alloc(silc_pkcs_get_name(pkcs), identifier,
-                                      key, key_len);
-  silc_pkcs_save_public_key(pkfile, pub_key, SILC_PKCS_FILE_PEM);
-  if (ret_pub_key)
-    *ret_pub_key = pub_key;
-
-  memset(key, 0, key_len);
-  silc_free(key);
-
-  /* Save private key into file */
-  key = silc_pkcs_get_private_key(pkcs, &key_len);
-  prv_key = silc_pkcs_private_key_alloc(silc_pkcs_get_name(pkcs),
-                                       key, key_len);
-  silc_pkcs_save_private_key(prvfile, prv_key, NULL, SILC_PKCS_FILE_BIN);
-  if (ret_prv_key)
-    *ret_prv_key = prv_key;
-
-  printf("Public key has been saved into `%s'.\n", pkfile);
-  printf("Private key has been saved into `%s'.\n", prvfile);
-  printf("Press <Enter> to continue...\n");
-  getchar();
-
-  memset(key, 0, key_len);
-  silc_free(key);
-
-  silc_rng_free(rng);
-  silc_pkcs_free(pkcs);
-
-  return TRUE;
-}
-
 /* This checks stats for various SILC files and directories. First it 
    checks if ~/.silc directory exist and is owned by the correct user. If 
    it doesn't exist, it will create the directory. After that it checks if
@@ -259,10 +91,8 @@ int silc_client_check_silc_dir()
 {
   char filename[256], file_public_key[256], file_private_key[256];
   char servfilename[256], clientfilename[256], friendsfilename[256];
-  char *identifier;
   struct stat st;
   struct passwd *pw;
-  int firstime = FALSE;
   time_t curtime, modtime;
 
   SILC_LOG_DEBUG(("Checking ~./silc directory"));
@@ -271,13 +101,9 @@ int silc_client_check_silc_dir()
   memset(file_public_key, 0, sizeof(file_public_key));
   memset(file_private_key, 0, sizeof(file_private_key));
 
-  identifier = silc_client_create_identifier();
-
   pw = getpwuid(getuid());
   if (!pw) {
     fprintf(stderr, "silc: %s\n", strerror(errno));
-    if (identifier)
-      silc_free(identifier);
     return FALSE;
   }
 
@@ -301,9 +127,6 @@ int silc_client_check_silc_dir()
          fprintf(stderr, "Couldn't create `%s' directory\n", filename);
          return FALSE;
        }
-
-       /* Directory was created. First time running SILC */
-       firstime = TRUE;
       } else {
        fprintf(stderr, "Couldn't create `%s' directory due to a wrong uid!\n",
                filename);
@@ -408,30 +231,22 @@ int silc_client_check_silc_dir()
   snprintf(file_private_key, sizeof(file_private_key) - 1, "%s%s", 
           filename, SILC_CLIENT_PRIVATE_KEY_NAME);
   
-  /* If running SILC first time */
-  if (firstime) {
-    fprintf(stdout, "Running SILC for the first time\n");
-    silc_client_create_key_pair(SILC_CLIENT_DEF_PKCS, 
-                               SILC_CLIENT_DEF_PKCS_LEN,
-                               file_public_key, file_private_key, 
-                               identifier, NULL, NULL);
-    return TRUE;
-  }
-  
   if ((stat(file_public_key, &st)) == -1) {
     /* If file doesn't exist */
     if (errno == ENOENT) {
-      fprintf(stdout, "Your public key doesn't exist\n");
-      silc_client_create_key_pair(SILC_CLIENT_DEF_PKCS, 
-                                 SILC_CLIENT_DEF_PKCS_LEN,
-                                 file_public_key, 
-                                 file_private_key, identifier, NULL, NULL);
+      fprintf(stdout, "Running SILC for the first time\n");
+      silc_create_key_pair(SILC_CLIENT_DEF_PKCS,
+                          SILC_CLIENT_DEF_PKCS_LEN,
+                          file_public_key, file_private_key, NULL,
+                          NULL, NULL, NULL, FALSE);
+      printf("Press <Enter> to continue...\n");
+      getchar();
     } else {
       fprintf(stderr, "%s\n", strerror(errno));
       return FALSE;
     }
   }
-
+  
   /* Check the owner of the public key */
   if (st.st_uid != 0 && st.st_uid != pw->pw_uid) { 
     fprintf(stderr, "You don't seem to own your public key!?\n");
@@ -442,10 +257,12 @@ int silc_client_check_silc_dir()
     /* If file doesn't exist */
     if (errno == ENOENT) {
       fprintf(stdout, "Your private key doesn't exist\n");
-      silc_client_create_key_pair(SILC_CLIENT_DEF_PKCS, 
-                                 SILC_CLIENT_DEF_PKCS_LEN,
-                                 file_public_key, 
-                                 file_private_key, identifier, NULL, NULL);
+      silc_create_key_pair(SILC_CLIENT_DEF_PKCS,
+                          SILC_CLIENT_DEF_PKCS_LEN,
+                          file_public_key, file_private_key, NULL,
+                          NULL, NULL, NULL, FALSE);
+      printf("Press <Enter> to continue...\n");
+      getchar();
     } else {
       fprintf(stderr, "%s\n", strerror(errno));
       return FALSE;
@@ -492,10 +309,12 @@ int silc_client_check_silc_dir()
     answer = silc_get_input("Would you like to create a new key pair "
                            "([y]/n)?: ", FALSE);
     if (!answer || answer[0] == 'Y' || answer[0] == 'y') {
-      silc_client_create_key_pair(SILC_CLIENT_DEF_PKCS, 
-                                 SILC_CLIENT_DEF_PKCS_LEN,
-                                 file_public_key, 
-                                 file_private_key, identifier, NULL, NULL);
+      silc_create_key_pair(SILC_CLIENT_DEF_PKCS,
+                          SILC_CLIENT_DEF_PKCS_LEN,
+                          file_public_key, file_private_key, NULL,
+                          NULL, NULL, NULL, FALSE);
+      printf("Press <Enter> to continue...\n");
+      getchar();
     } else {
 #ifdef HAVE_UTIME
       struct utimbuf utim;
@@ -507,9 +326,6 @@ int silc_client_check_silc_dir()
     silc_free(answer);
   }
   
-  if (identifier)
-    silc_free(identifier);
-
   return TRUE;
 }
 
@@ -517,7 +333,7 @@ int silc_client_check_silc_dir()
 
 int silc_client_load_keys(SilcClient client)
 {
-  char filename[256];
+  char pub[256], prv[256];
   struct passwd *pw;
 
   SILC_LOG_DEBUG(("Loading public and private keys"));
@@ -526,90 +342,14 @@ int silc_client_load_keys(SilcClient client)
   if (!pw)
     return FALSE;
 
-  memset(filename, 0, sizeof(filename));
-  snprintf(filename, sizeof(filename) - 1, "%s/%s", 
+  memset(prv, 0, sizeof(prv));
+  snprintf(prv, sizeof(prv) - 1, "%s/%s",
           get_irssi_dir(), SILC_CLIENT_PRIVATE_KEY_NAME);
 
-  if (silc_pkcs_load_private_key(filename, &client->private_key,
-                                SILC_PKCS_FILE_BIN) == FALSE)
-    if (silc_pkcs_load_private_key(filename, &client->private_key,
-                                  SILC_PKCS_FILE_PEM) == FALSE)
-      return FALSE;
-
-  memset(filename, 0, sizeof(filename));
-  snprintf(filename, sizeof(filename) - 1, "%s/%s", 
+  memset(pub, 0, sizeof(pub));
+  snprintf(pub, sizeof(pub) - 1, "%s/%s",
           get_irssi_dir(), SILC_CLIENT_PUBLIC_KEY_NAME);
-
-  if (silc_pkcs_load_public_key(filename, &client->public_key,
-                               SILC_PKCS_FILE_PEM) == FALSE)
-    if (silc_pkcs_load_public_key(filename, &client->public_key,
-                                 SILC_PKCS_FILE_BIN) == FALSE)
-      return FALSE;
-
-  silc_pkcs_alloc(client->public_key->name, &client->pkcs);
-  silc_pkcs_public_key_set(client->pkcs, client->public_key);
-  silc_pkcs_private_key_set(client->pkcs, client->private_key);
-
-  return TRUE;
-}
-
-/* Dumps the public key on screen. Used from the command line option. */
-
-int silc_client_show_key(char *keyfile)
-{
-  SilcPublicKey public_key;
-  SilcPublicKeyIdentifier ident;
-  char *fingerprint, *babbleprint;
-  unsigned char *pk;
-  SilcUInt32 pk_len;
-  SilcPKCS pkcs;
-  int key_len = 0;
-
-  if (silc_pkcs_load_public_key(keyfile, &public_key,
-                               SILC_PKCS_FILE_PEM) == FALSE)
-    if (silc_pkcs_load_public_key(keyfile, &public_key,
-                                 SILC_PKCS_FILE_BIN) == FALSE) {
-      fprintf(stderr, "Could not load public key file `%s'\n", keyfile);
-      return FALSE;
-    }
-
-  ident = silc_pkcs_decode_identifier(public_key->identifier);
-
-  pk = silc_pkcs_public_key_encode(public_key, &pk_len);
-  fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
-  babbleprint = silc_hash_babbleprint(NULL, pk, pk_len);
-
-  if (silc_pkcs_alloc(public_key->name, &pkcs)) {
-    key_len = silc_pkcs_public_key_set(pkcs, public_key);
-    silc_pkcs_free(pkcs);
-  }
-
-  printf("Public key file    : %s\n", keyfile);
-  printf("Algorithm          : %s\n", public_key->name);
-  if (key_len)
-    printf("Key length (bits)  : %d\n", key_len);
-  if (ident->realname)
-    printf("Real name          : %s\n", ident->realname);
-  if (ident->username)
-    printf("Username           : %s\n", ident->username);
-  if (ident->host)
-    printf("Hostname           : %s\n", ident->host);
-  if (ident->email)
-    printf("Email              : %s\n", ident->email);
-  if (ident->org)
-    printf("Organization       : %s\n", ident->org);
-  if (ident->country)
-    printf("Country            : %s\n", ident->country);
-  printf("Fingerprint (SHA1) : %s\n", fingerprint); 
-  printf("Babbleprint (SHA1) : %s\n", babbleprint); 
-
-  fflush(stdout);
-
-  silc_free(fingerprint);
-  silc_free(babbleprint);
-  silc_free(pk);
-  silc_pkcs_public_key_free(public_key);
-  silc_pkcs_free_identifier(ident);
-
-  return TRUE;
+  
+  return silc_load_key_pair(pub, prv, &client->pkcs, &client->public_key,
+                           &client->private_key);
 }
index 3f4a604633f1a655026f2fe8a3b80a186088ae67..6b703f5d8645b7427c17b26a0c83849a7c7cf4d6 100644 (file)
@@ -28,14 +28,7 @@ void silc_client_list_ciphers();
 void silc_client_list_hash_funcs();
 void silc_client_list_hmacs();
 void silc_client_list_pkcs();
-char *silc_client_create_identifier();
-int silc_client_create_key_pair(char *pkcs_name, int bits,
-                               char *public_key, char *private_key,
-                               char *identifier, 
-                               SilcPublicKey *ret_pub_key,
-                               SilcPrivateKey *ret_prv_key);
 int silc_client_check_silc_dir();
 int silc_client_load_keys(SilcClient client);
-int silc_client_show_key(char *keyfile);
 
 #endif
index 2253c9ec9f72542ea68095e19b500c0113437f9e..f1410e7f3e9cdd1f0a03a45f8b32578de71fd703 100644 (file)
@@ -264,7 +264,7 @@ void silc_opt_callback(poptContext con,
     silc_pkcs_register_default();
     silc_hash_register_default();
     silc_hmac_register_default();
-    silc_client_show_key((char *)arg);
+    silc_show_public_key((char *)arg);
     exit(0);
   }
 
@@ -310,8 +310,8 @@ void silc_opt_callback(poptContext con,
     silc_pkcs_register_default();
     silc_hash_register_default();
     silc_hmac_register_default();
-    silc_client_create_key_pair(opt_pkcs, opt_bits, 
-                               NULL, NULL, NULL, NULL, NULL);
+    silc_create_key_pair(opt_pkcs, opt_bits, NULL, NULL, NULL,
+                        NULL, NULL, NULL, TRUE);
     exit(0);
   }
 }
index 306f771a5e2332d82f00b5f2934254a604623cc5..c110a649b3be9aa0b5737eacee7a7c9d71f21b0d 100644 (file)
 static SilcServer silcd;
 
 static void silc_usage(void);
-static char *silc_server_create_identifier(void);
-static int silc_server_create_key_pair(char *pkcs_name, int bits, char *path,
-                                      char *identifier,
-                                      SilcPublicKey *ret_pub_key,
-                                      SilcPrivateKey *ret_prv_key);
 
 /* Long command line options */
 static struct option long_opts[] =
@@ -519,12 +514,19 @@ int main(int argc, char **argv)
 
   if (opt_create_keypair == TRUE) {
     /* Create new key pair and exit */
+    char pubfile[256], prvfile[256];
+
+    memset(pubfile, 0, sizeof(pubfile));
+    memset(prvfile, 0, sizeof(prvfile));
+    snprintf(pubfile, sizeof(pubfile) - 1, "%s/silcd.pub", opt_keypath);
+    snprintf(prvfile, sizeof(prvfile) - 1, "%s/silcd.prv", opt_keypath);
+
     silc_cipher_register_default();
     silc_pkcs_register_default();
     silc_hash_register_default();
     silc_hmac_register_default();
-    silc_server_create_key_pair(opt_pkcs, opt_bits, opt_keypath,
-                               opt_identifier, NULL, NULL);
+    silc_create_key_pair(opt_pkcs, opt_bits, pubfile, prvfile,
+                        opt_identifier, NULL, NULL, NULL, FALSE);
     exit(0);
   }
 
@@ -606,108 +608,3 @@ int main(int argc, char **argv)
   silc_free(opt_keypath);
   exit(1);
 }
-
-/* Returns identifier string for public key generation. */
-
-static char *silc_server_create_identifier(void)
-{
-  char *username = NULL, *realname = NULL;
-  char hostname[256], email[256];
-
-  /* Get realname */
-  realname = silc_get_real_name();
-
-  /* Get hostname */
-  memset(hostname, 0, sizeof(hostname));
-  gethostname(hostname, sizeof(hostname));
-
-  /* Get username (mandatory) */
-  username = silc_get_username();
-  if (!username)
-    return NULL;
-
-  /* Create default email address, whether it is right or not */
-  snprintf(email, sizeof(email), "%s@%s", username, hostname);
-
-  return silc_pkcs_encode_identifier(username, hostname, realname, email,
-                                    NULL, NULL);
-}
-
-/* Creates new public key and private key pair. This is used only
-   when user wants to create new key pair from command line. */
-
-static int
-silc_server_create_key_pair(char *pkcs_name, int bits, char *path,
-                           char *identifier,
-                           SilcPublicKey *ret_pub_key,
-                           SilcPrivateKey *ret_prv_key)
-{
-  SilcPKCS pkcs;
-  SilcPublicKey pub_key;
-  SilcPrivateKey prv_key;
-  SilcRng rng;
-  unsigned char *key;
-  SilcUInt32 key_len;
-  char pkfile[256], prvfile[256];
-
-  if (!pkcs_name || !path)
-    return FALSE;
-
-  if (!silc_pkcs_is_supported(pkcs_name)) {
-    fprintf(stderr, "Unsupported PKCS `%s'", pkcs_name);
-    return FALSE;
-  }
-
-  if (!bits)
-    bits = 2048;
-
-  if (!identifier)
-    identifier = silc_server_create_identifier();
-
-  rng = silc_rng_alloc();
-  silc_rng_init(rng);
-  silc_rng_global_init(rng);
-
-  snprintf(pkfile, sizeof(pkfile) - 1, "%s%s", path,
-          SILC_SERVER_PUBLIC_KEY_NAME);
-  snprintf(prvfile, sizeof(prvfile) - 1, "%s%s", path,
-          SILC_SERVER_PRIVATE_KEY_NAME);
-
-  /* Generate keys */
-  silc_pkcs_alloc(pkcs_name, &pkcs);
-  silc_pkcs_generate_key(pkcs, bits, rng);
-
-  /* Save public key into file */
-  key = silc_pkcs_get_public_key(pkcs, &key_len);
-  pub_key = silc_pkcs_public_key_alloc(silc_pkcs_get_name(pkcs), identifier,
-                                      key, key_len);
-  silc_pkcs_save_public_key(pkfile, pub_key, SILC_PKCS_FILE_PEM);
-  if (ret_pub_key)
-    *ret_pub_key = pub_key;
-  else
-    silc_pkcs_public_key_free(pub_key);
-
-  memset(key, 0, sizeof(key_len));
-  silc_free(key);
-
-  /* Save private key into file */
-  key = silc_pkcs_get_private_key(pkcs, &key_len);
-  prv_key = silc_pkcs_private_key_alloc(silc_pkcs_get_name(pkcs),
-                                       key, key_len);
-  silc_pkcs_save_private_key(prvfile, prv_key, NULL, SILC_PKCS_FILE_BIN);
-  if (ret_prv_key)
-    *ret_prv_key = prv_key;
-  else
-    silc_pkcs_private_key_free(prv_key);
-
-  printf("Public key has been saved into `%s'\n", pkfile);
-  printf("Private key has been saved into `%s'\n", prvfile);
-
-  memset(key, 0, sizeof(key_len));
-  silc_free(key);
-
-  silc_rng_free(rng);
-  silc_pkcs_free(pkcs);
-
-  return TRUE;
-}
index 9933b084e09130f0360ab8f8569fd77193452b60..1e5a8ad06eff2c0210e9d122d7b3e712d37bb580 100644 (file)
@@ -266,6 +266,8 @@ extern "C" {
 #include "silcauth.h"
 #include "silcprivate.h"
 #include "silcattrs.h"
+#include "silcvcard.h"
+#include "silcapputil.h"
 
 #ifdef SILC_SIM
 /* SILC Module library includes */
index 43d602aafc6ec8b6913728106ba9d60df90dfe26..7b704b44608341b20a170e2aa0c00b22aebfeea8 100644 (file)
@@ -399,7 +399,8 @@ const char *silc_pkcs_get_name(SilcPKCS pkcs);
  *
  * DESCRIPTION
  *
- *    Returns SILC style public key.
+ *    Returns SILC style public key.  The caller must free the returned
+ *    data.
  *
  ***/
 unsigned char *silc_pkcs_get_public_key(SilcPKCS pkcs, SilcUInt32 *len);
@@ -413,7 +414,8 @@ unsigned char *silc_pkcs_get_public_key(SilcPKCS pkcs, SilcUInt32 *len);
  *
  * DESCRIPTION
  *
- *    Returns SILC style private key.
+ *    Returns SILC style private key.  The caller must free the returned
+ *    data and SHOULD zero the memory area before freeing.
  *
  ***/
 unsigned char *silc_pkcs_get_private_key(SilcPKCS pkcs, SilcUInt32 *len);
index 7341eafb2aaa6da930c4878f4521984f5c2889ed..6e178a56b54c65c55484e2f75b6aef68a9bfbf96 100644 (file)
@@ -20,6 +20,7 @@
 @LINK=silclist.html:SILC List Interface
 @LINK=silcdlist.html:SILC Dynamic List Interface
 @LINK=silcvcard.html:SILC VCard Interface
+@LINK=silcapputil.html:SILC Application Utilities
 -->
 
 <big><b>SILC Utility Library</b></big>
index c9c6d702c4d88419ab8938bec90f4a3e5163cbc1..96ae75c088f9635fc16f52690c35ca1f1272e88c 100644 (file)
@@ -59,7 +59,8 @@ libsilcutil_a_SOURCES = \
        silchashtable.c \
        silcsockconn.c  \
        silcprotocol.c  \
-       silcvcard.c
+       silcvcard.c     \
+       silcapputil.c
 
 if SILC_DIST_TOOLKIT
 include_HEADERS =      \
@@ -82,6 +83,7 @@ include_HEADERS =     \
        silcutil.h      \
        silcstrutil.h   \
        silcvcard.h     \
+       silcapputil.h   \
        silctypes.h
 endif
 
diff --git a/lib/silcutil/silcapputil.c b/lib/silcutil/silcapputil.c
new file mode 100644 (file)
index 0000000..6c0ecca
--- /dev/null
@@ -0,0 +1,314 @@
+/*
+
+  silcapputil.c 
+
+  Author: Pekka Riikonen <priikone@silcnet.org>
+
+  Copyright (C) 2002 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
+  the Free Software Foundation; version 2 of the License.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+*/
+/* $Id$ */
+
+#include "silcincludes.h"
+
+static char *silc_create_pk_identifier(void)
+{
+  char *username = NULL, *realname = NULL;
+  char *hostname, email[256];
+  char *ident;
+  
+  /* Get realname */
+  realname = silc_get_real_name();
+
+  /* Get hostname */
+  hostname = silc_net_localhost();
+  if (!hostname)
+    return NULL;
+
+  /* Get username (mandatory) */
+  username = silc_get_username();
+  if (!username)
+    return NULL;
+
+  /* Create default email address, whether it is right or not */
+  snprintf(email, sizeof(email), "%s@%s", username, hostname);
+
+  ident = silc_pkcs_encode_identifier(username, hostname, realname, email,
+                                     NULL, NULL);
+  if (realname)
+    silc_free(realname);
+  silc_free(hostname);
+  silc_free(username);
+
+  return ident;
+}
+
+/* Generate key pair */
+
+bool silc_create_key_pair(const char *pkcs_name,
+                         SilcUInt32 key_len_bits,
+                         const char *pub_filename,
+                         const char *prv_filename,
+                         const char *pub_identifier,
+                         SilcPKCS *return_pkcs,
+                         SilcPublicKey *return_public_key,
+                         SilcPrivateKey *return_private_key,
+                         bool interactive)
+{
+  SilcPKCS pkcs;
+  SilcPublicKey pub_key;
+  SilcPrivateKey prv_key;
+  SilcRng rng;
+  unsigned char *key;
+  SilcUInt32 key_len;
+  char line[256];
+  char *pkfile = pub_filename ? strdup(pub_filename) : NULL;
+  char *prvfile = prv_filename ? strdup(prv_filename) : NULL;
+  char *alg = pkcs_name ? strdup(pkcs_name) : NULL;
+  char *identifier = pub_identifier ? strdup(pub_identifier) : NULL;
+
+  if (interactive && (!alg || !pub_filename || !prv_filename))
+    printf("\
+New pair of keys will be created.  Please, answer to following questions.\n\
+");
+
+  if (!alg) {
+    if (interactive) {
+      while (!alg) {
+       alg = silc_get_input("PKCS name (l to list names) [rsa]: ", FALSE);
+       if (!alg)
+         alg = strdup("rsa");
+    
+       if (*alg == 'l' || *alg == 'L') {
+         char *list = silc_pkcs_get_supported();
+         printf("%s\n", list);
+         silc_free(list);
+         silc_free(alg);
+         alg = NULL;
+       }
+      }
+    } else {
+      alg = strdup("rsa");
+    }
+  }
+
+  if (!silc_pkcs_is_supported(alg)) {
+    fprintf(stderr, "Unknown PKCS algorithm `%s' or crypto library"
+           "is not initialized", alg);
+    return FALSE;
+  }
+
+  if (!key_len_bits) {
+    if (interactive) {
+      char *length = NULL;
+      length = silc_get_input("Key length in key_len_bits [2048]: ", FALSE);
+      if (length)
+       key_len_bits = atoi(length);
+      silc_free(length);
+    }
+    if (!key_len_bits)
+      key_len_bits = 2048;
+  }
+
+  if (!identifier) {
+    char *def = silc_create_pk_identifier();
+
+    if (interactive) {
+      memset(line, 0, sizeof(line));
+      if (def)
+       snprintf(line, sizeof(line), "Identifier [%s]: ", def);
+      else
+       snprintf(line, sizeof(line),
+              "Identifier (eg. UN=jon, HN=jon.dummy.com, "
+              "RN=Jon Johnson, E=jon@dummy.com): ");
+
+      while (!identifier) {
+       identifier = silc_get_input(line, FALSE);
+       if (!identifier && def)
+         identifier = strdup(def);
+      }
+    } else {
+      if (!def) {
+       fprintf(stderr, "Could not create public key identifier: %s\n",
+               strerror(errno));
+       return FALSE;
+      }
+      identifier = strdup(def);
+    }
+
+    silc_free(def);
+  }
+
+  rng = silc_rng_alloc();
+  silc_rng_init(rng);
+  silc_rng_global_init(rng);
+
+  if (!pkfile) {
+    if (interactive) {
+      memset(line, 0, sizeof(line));
+      snprintf(line, sizeof(line), "Public key filename [public_key.pub] ");
+      pkfile = silc_get_input(line, FALSE);
+    }
+    if (!pkfile)
+      pkfile = strdup("public_key.pub");
+  }
+
+  if (!prvfile) {
+    if (interactive) {
+      memset(line, 0, sizeof(line));
+      snprintf(line, sizeof(line), "Public key filename [private_key.prv] ");
+      prvfile = silc_get_input(line, FALSE);
+    }
+    if (!prvfile)
+      prvfile = strdup("private_key.prv");
+  }
+
+  /* Generate keys */
+  silc_pkcs_alloc(alg, &pkcs);
+  silc_pkcs_generate_key(pkcs, key_len_bits, rng);
+
+  /* Save public key into file */
+  key = silc_pkcs_get_public_key(pkcs, &key_len);
+  pub_key = silc_pkcs_public_key_alloc(silc_pkcs_get_name(pkcs),
+                                      identifier, key, key_len);
+  silc_pkcs_save_public_key(pkfile, pub_key, SILC_PKCS_FILE_PEM);
+  if (return_public_key)
+    *return_public_key = pub_key;
+  else
+    silc_pkcs_public_key_free(pub_key);
+  memset(key, 0, key_len);
+  silc_free(key);
+
+  /* Save private key into file */
+  key = silc_pkcs_get_private_key(pkcs, &key_len);
+  prv_key = silc_pkcs_private_key_alloc(silc_pkcs_get_name(pkcs),
+                                       key, key_len);
+  silc_pkcs_save_private_key(prvfile, prv_key, NULL, SILC_PKCS_FILE_BIN);
+  if (return_private_key)
+    *return_private_key = prv_key;
+  else
+    silc_pkcs_private_key_free(prv_key);
+  memset(key, 0, key_len);
+  silc_free(key);
+
+  printf("Public key has been saved into `%s'.\n", pkfile);
+  printf("Private key has been saved into `%s'.\n", prvfile);
+  if (interactive) {
+    printf("Press <Enter> to continue...\n");
+    getchar();
+  }
+
+  if (return_pkcs)
+    *return_pkcs = pkcs;
+  else
+    silc_pkcs_free(pkcs);
+
+  silc_rng_free(rng);
+  silc_free(alg);
+  silc_free(pkfile);
+  silc_free(prvfile);
+  silc_free(identifier);
+
+  return TRUE;
+}
+
+/* Load key pair */
+
+bool silc_load_key_pair(const char *pub_filename,
+                       const char *prv_filename,
+                       SilcPKCS *return_pkcs,
+                       SilcPublicKey *return_public_key,
+                       SilcPrivateKey *return_private_key)
+{
+  SILC_LOG_DEBUG(("Loading public and private keys"));
+
+  if (silc_pkcs_load_public_key((char *)pub_filename, return_public_key,
+                               SILC_PKCS_FILE_PEM) == FALSE)
+    if (silc_pkcs_load_public_key((char *)pub_filename, return_public_key,
+                                 SILC_PKCS_FILE_BIN) == FALSE)
+      return FALSE;
+
+  if (silc_pkcs_load_private_key((char *)prv_filename, return_private_key,
+                                SILC_PKCS_FILE_BIN) == FALSE)
+    if (silc_pkcs_load_private_key((char *)prv_filename, return_private_key,
+                                  SILC_PKCS_FILE_PEM) == FALSE)
+      return FALSE;
+
+  if (return_pkcs) {
+    silc_pkcs_alloc((*return_public_key)->name, return_pkcs);
+    silc_pkcs_public_key_set(*return_pkcs, *return_public_key);
+    silc_pkcs_private_key_set(*return_pkcs, *return_private_key);
+  }
+
+  return TRUE;
+}
+
+/* Dump public key into stdout */
+
+bool silc_show_public_key(const char *pub_filename)
+{
+  SilcPublicKey public_key;
+  SilcPublicKeyIdentifier ident;
+  char *fingerprint, *babbleprint;
+  unsigned char *pk;
+  SilcUInt32 pk_len;
+  SilcPKCS pkcs;
+  SilcUInt32 key_len = 0;
+
+  if (silc_pkcs_load_public_key((char *)pub_filename, &public_key,
+                               SILC_PKCS_FILE_PEM) == FALSE)
+    if (silc_pkcs_load_public_key((char *)pub_filename, &public_key,
+                                 SILC_PKCS_FILE_BIN) == FALSE) {
+      fprintf(stderr, "Could not load public key file `%s'\n", pub_filename);
+      return FALSE;
+    }
+
+  ident = silc_pkcs_decode_identifier(public_key->identifier);
+
+  pk = silc_pkcs_public_key_encode(public_key, &pk_len);
+  fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
+  babbleprint = silc_hash_babbleprint(NULL, pk, pk_len);
+
+  if (silc_pkcs_alloc(public_key->name, &pkcs)) {
+    key_len = silc_pkcs_public_key_set(pkcs, public_key);
+    silc_pkcs_free(pkcs);
+  }
+
+  printf("Public key file    : %s\n", pub_filename);
+  printf("Algorithm          : %s\n", public_key->name);
+  if (key_len)
+    printf("Key length (bits)  : %d\n", (unsigned int)key_len);
+  if (ident->realname)
+    printf("Real name          : %s\n", ident->realname);
+  if (ident->username)
+    printf("Username           : %s\n", ident->username);
+  if (ident->host)
+    printf("Hostname           : %s\n", ident->host);
+  if (ident->email)
+    printf("Email              : %s\n", ident->email);
+  if (ident->org)
+    printf("Organization       : %s\n", ident->org);
+  if (ident->country)
+    printf("Country            : %s\n", ident->country);
+  printf("Fingerprint (SHA1) : %s\n", fingerprint); 
+  printf("Babbleprint (SHA1) : %s\n", babbleprint); 
+
+  fflush(stdout);
+
+  silc_free(fingerprint);
+  silc_free(babbleprint);
+  silc_free(pk);
+  silc_pkcs_public_key_free(public_key);
+  silc_pkcs_free_identifier(ident);
+
+  return TRUE;
+}
diff --git a/lib/silcutil/silcapputil.h b/lib/silcutil/silcapputil.h
new file mode 100644 (file)
index 0000000..f054fa4
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+
+  silcapputil.h 
+
+  Author: Pekka Riikonen <priikone@silcnet.org>
+
+  Copyright (C) 2002 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
+  the Free Software Foundation; version 2 of the License.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+*/
+
+/****h* silcutil/SILC Application Utilities
+ *
+ * DESCRIPTION
+ *
+ * This interface provides utility functions for applications'
+ * convenience.  It provides functions that may be used for example by
+ * command line applications but also other applications may find some
+ * routines helpful.  None of these routines are mandatory in any other
+ * SILC routines or libraries, and are purely provided for convenience.
+ * These routines for example provide simple public key and private key
+ * pair generation, public key and private key file saving and loading
+ * for application, and other similar routines.
+ *
+ ***/
+
+#ifndef SILCAPPUTIL_H
+#define SILCAPPUTIL_H
+
+/****f* silcutil/SilcAppUtil/silc_create_key_pair
+ *
+ * SYNOPSIS
+ *
+ *    bool silc_create_key_pair(const char *pkcs_name,
+ *                              SilcUInt32 key_len_bits,
+ *                              const char *pub_filename,
+ *                              const char *prv_filename,
+ *                              const char *pub_identifier,
+ *                              SilcPKCS *return_pkcs,
+ *                              SilcPublicKey *return_public_key,
+ *                              SilcPrivateKey *return_private_key,
+ *                              bool interactive);
+ *
+ * DESCRIPTION
+ *
+ *    This routine can be used to generate new public key and private key
+ *    pair.  The `pkcs_name' is the name of public key algorithm, or if
+ *    NULL it defaults to "rsa".  The `key_len_bits' is the key length
+ *    in bits and if zero (0) it defaults to 2048 bits.  The `pub_filename'
+ *    and `prv_filename' is the public key and private key filenames.
+ *    The `pub_identifier' is the public key identifier (for example:
+ *    "UN=foobar, HN=hostname"), or if NULL the routine generates it
+ *    automatically.
+ *
+ *    The routine returns FALSE if error occurs during key generation.
+ *    Function returns TRUE when success and returns the created SilcPKCS
+ *    object, which can be used to perform public key cryptography into
+ *    `return_pkcs' pointer, created public key into `return_public_key',
+ *    and created private key into `return_private_key' pointer.
+ *
+ *    If the `interactive' is TRUE then this asks the user (by blocking
+ *    the process for input) some questions about key generation (like
+ *    public key algorithm, key length, filenames, etc).  If all
+ *    arguments are provided to this function already then `interactive'
+ *    has no effect.
+ *
+ * NOTES
+ *
+ *    Before calling this function the application must have initialized
+ *    the crypto library by registering the public key algorithms with
+ *    silc_pkcs_register_default function.
+ *
+ ***/
+bool silc_create_key_pair(const char *pkcs_name,
+                         SilcUInt32 key_len_bits,
+                         const char *pub_filename,
+                         const char *prv_filename,
+                         const char *pub_identifier,
+                         SilcPKCS *return_pkcs,
+                         SilcPublicKey *return_public_key,
+                         SilcPrivateKey *return_private_key,
+                         bool interactive);
+
+/****f* silcutil/SilcAppUtil/silc_load_key_pair
+ *
+ * SYNOPSIS
+ *
+ *    bool silc_load_key_pair(const char *pub_filename,
+ *                            const char *prv_filename,
+ *                            SilcPKCS *return_pkcs,
+ *                            SilcPublicKey *return_public_key,
+ *                            SilcPrivateKey *return_private_key);
+ *
+ * DESCRIPTION
+ *
+ *    This routine can be used to load the public key and private key
+ *    from files.  This retuns FALSE it either of the key could not be
+ *    loaded.  This function returns TRUE on success and returns the
+ *    public key into `return_public_key' pointer, private key into
+ *    `return_private_key' pointer and the SilcPKCS object to the
+ *    `return_pkcs'.  The SilcPKCS can be used to perform public key
+ *    cryptographic operations.
+ *
+ ***/
+bool silc_load_key_pair(const char *pub_filename,
+                       const char *prv_filename,
+                       SilcPKCS *return_pkcs,
+                       SilcPublicKey *return_public_key,
+                       SilcPrivateKey *return_private_key);
+
+/****f* silcutil/SilcAppUtil/silc_show_public_key
+ *
+ * SYNOPSIS
+ *
+ *    bool silc_show_public_key(const char *pub_filename);
+ *
+ * DESCRIPTION
+ *
+ *    This routine can be used to dump the contents of the public key
+ *    in the public key file `pub_filename'.  This dumps the public key
+ *    into human readable form into stdout.  Returns FALSE on error.
+ *
+ ***/
+bool silc_show_public_key(const char *pub_filename);
+
+#endif /* SILCAPPUTIL_H */