updates.
authorPekka Riikonen <priikone@silcnet.org>
Mon, 9 Apr 2001 10:48:00 +0000 (10:48 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Mon, 9 Apr 2001 10:48:00 +0000 (10:48 +0000)
apps/silc/clientutil.c
lib/silccrypt/silcpkcs.c

index 4070b419c138f58a50e94d11723b193469966821..e37eba5309834361db4322b2be924b9bb70b15f0 100644 (file)
@@ -711,3 +711,59 @@ int silc_client_load_keys(SilcClient client)
 
   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;
+  unsigned char *pk;
+  uint32 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)
+      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);
+
+  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); 
+
+  fflush(stdout);
+
+  silc_free(fingerprint);
+  silc_free(pk);
+  silc_pkcs_public_key_free(public_key);
+  silc_pkcs_free_identifier(ident);
+
+  return TRUE;
+}
index 33abe8cac276de8bf2ae975fe8fe7fa1a9554a05..1f9cb8afef1c16e735d545ef25f29a6eee0084dd 100644 (file)
@@ -153,18 +153,20 @@ unsigned char *silc_pkcs_get_private_key(SilcPKCS pkcs, uint32 *len)
 
 /* Sets public key from SilcPublicKey. */
 
-int silc_pkcs_public_key_set(SilcPKCS pkcs, SilcPublicKey public_key)
+uint32 silc_pkcs_public_key_set(SilcPKCS pkcs, SilcPublicKey public_key)
 {
-  return pkcs->pkcs->set_public_key(pkcs->context, public_key->pk, 
-                                   public_key->pk_len);
+  pkcs->key_len = pkcs->pkcs->set_public_key(pkcs->context, public_key->pk, 
+                                            public_key->pk_len);
+  return pkcs->key_len;
 }
 
 /* Sets public key from data. */
 
-int silc_pkcs_public_key_data_set(SilcPKCS pkcs, unsigned char *pk,
-                                 uint32 pk_len)
+uint32 silc_pkcs_public_key_data_set(SilcPKCS pkcs, unsigned char *pk,
+                                    uint32 pk_len)
 {
-  return pkcs->pkcs->set_public_key(pkcs->context, pk, pk_len);
+  pkcs->key_len = pkcs->pkcs->set_public_key(pkcs->context, pk, pk_len);
+  return pkcs->key_len;
 }
 
 /* Sets private key from SilcPrivateKey. */
@@ -358,6 +360,63 @@ char *silc_pkcs_encode_identifier(char *username, char *host, char *realname,
   return identifier;
 }
 
+/* Decodes the provided `identifier' and returns allocated context for
+   the identifier. */
+
+SilcPublicKeyIdentifier silc_pkcs_decode_identifier(char *identifier)
+{
+  SilcPublicKeyIdentifier ident;
+  char *cp, *item;
+  int len;
+
+  ident = silc_calloc(1, sizeof(*ident));
+
+  cp = identifier;
+  while (cp) {
+    len = strcspn(cp, ",");
+    item = silc_calloc(len + 1, sizeof(char));
+    memcpy(item, cp, len);
+
+    if (strstr(item, "UN="))
+      ident->username = strdup(item + 3);
+    else if (strstr(item, "HN="))
+      ident->host = strdup(item + 3);
+    else if (strstr(item, "RN="))
+      ident->realname = strdup(item + 3);
+    else if (strstr(item, "E="))
+      ident->email = strdup(item + 2);
+    else if (strstr(item, "O="))
+      ident->org = strdup(item + 2);
+    else if (strstr(item, "C="))
+      ident->country = strdup(item + 2);
+    
+    cp += len;
+    if (strlen(cp) == 0)
+      cp = NULL;
+    else
+      cp += 2;
+    
+    if (item)
+      silc_free(item);
+  }
+
+  return ident;
+}
+
+/* Free's decoded public key identifier context. Call this to free the
+   context returned by the silc_pkcs_decode_identifier. */
+
+void silc_pkcs_free_identifier(SilcPublicKeyIdentifier identifier)
+{
+  silc_free(identifier->username);
+  silc_free(identifier->host);
+  silc_free(identifier->realname);
+  silc_free(identifier->email);
+  silc_free(identifier->org);
+  silc_free(identifier->country);
+  silc_free(identifier);
+}
+
 /* Allocates SILC style public key formed from sent arguments. All data
    is duplicated. */
 
@@ -528,13 +587,18 @@ int silc_pkcs_public_key_decode(unsigned char *data, uint32 data_len,
     goto err;
 
   /* See if we support this algorithm */
-  if (!silc_pkcs_is_supported(pkcs_name))
+  if (!silc_pkcs_is_supported(pkcs_name)) {
+    SILC_LOG_DEBUG(("Unsupported PKCS %s", pkcs_name));
     goto err;
+  }
 
   /* Protocol says that at least UN and HN must be provided as identifier,
      check for these. */
-  if (!strstr(ident, "UN=") && !strstr(ident, "HN="))
+  if (!strstr(ident, "UN=") && !strstr(ident, "HN=")) {
+    SILC_LOG_DEBUG(("The public does not have the required UN= and HN= "
+                   "identifiers"));
     goto err;
+  }
 
   /* Get key data. We assume that rest of the buffer is key data. */
   silc_buffer_pull(buf, 2 + pkcs_len + 2 + identifier_len);