Added user public key, user signature and server signature
authorPekka Riikonen <priikone@silcnet.org>
Tue, 15 Oct 2002 20:16:32 +0000 (20:16 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Tue, 15 Oct 2002 20:16:32 +0000 (20:16 +0000)
verification in requested attributes receiving.

CHANGES
apps/irssi/src/fe-common/silc/module-formats.c
apps/irssi/src/fe-common/silc/module-formats.h
apps/irssi/src/silc/core/client_ops.c
apps/irssi/src/silc/core/silc-queries.c
apps/irssi/src/silc/core/silc-queries.h

diff --git a/CHANGES b/CHANGES
index e7f1157e20fa4e87949fe38713b1ae697cc506e8..f540db9571cb1f9812471d9bc96a0c455a9b0923 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,15 @@
+Tue Oct 15 18:05:24 EEST 2002  Pekka Riikonen <priikone@silcnet.org>
+
+       * Added silc_attribute_get_verify_data to return the signature
+         verification data for either user digital signature or
+         server digital signature in Requested Attributes.  Affected
+         files are lib/silccore/silcattrs.[ch].
+
+       * Added silc_vcard_alloc which is used to allocated dynamic
+         SilcVCard context.  The silc_vcard_free now checks whether
+         the context is dynamically allocated or not.  Affected files
+         are lib/silcutil/silcvcard.[ch].
+
 Mon Oct 14 17:55:44 EEST 2002  Pekka Riikonen <priikone@silcnet.org>
 
        * Periodically remove the NOATTR status from client entry
index 720bd66a8900a444c2adcbeeced96829a8d1188c..bdfcdcfc63cf0e935a92f5beb1d2a5b9caad085b 100644 (file)
@@ -96,9 +96,9 @@ FORMAT_REC fecommon_silc_formats[] = {
        { "pubkey_no_match", "{hilight $0} key does not match with your local copy", 1, { 0 } },
        { "pubkey_maybe_expired", "It is possible that the key has expired or changed", 0 },
        { "pubkey_mitm_attack", "It is also possible that someone is performing a man-in-the-middle attack", 0 },
-       { "getkey_notkey", "Server did not return any public key", 0 },
-       { "getkey_verified", "Verified successfully $0 {hilight $1}'s cached public key", 2, { 0, 0 } },
-       { "getkey_discard", "Could not verify $0 {hilight $1}'s public key", 2, { 0, 0 } },
+       { "pubkey_notkey", "Server did not return any public key", 0 },
+       { "pubkey_verified", "Verified successfully $0 {hilight $1}'s cached public key", 2, { 0, 0 } },
+       { "pubkey_notverified", "Could not verify $0 {hilight $1}'s public key", 2, { 0, 0 } },
 
        /* Misc messages */
        { NULL, "Misc", 0 },
@@ -157,13 +157,13 @@ FORMAT_REC fecommon_silc_formats[] = {
        { "attr_header",      "Requested Attributes", 0 },
        { "attr_footer",      "End of Requested Attributes", 0 },
        { "attr_allow",       " Sending allowed    : $0", 1, { 0 } },
-       { "attr_vcard_file",  " Business card file : $0", 1, { 0 } },
+       { "attr_vcard_file",  " Business card      : $0", 1, { 0 } },
        { "attr_services",    " Services used      : $0", 1, { 0 } },
        { "attr_service",     " Service            : port [$0] address [$1] logged in [$2]", 3, { 0, 0, 0 } },
        { "attr_status_mood", " User's mood        : $0", 1, { 0 } },
        { "attr_status_text", " User's message     : $0", 1, { 0 } },
        { "attr_status_message",      " User's message     : $0", 1, { 0 } },
-       { "attr_status_message_file", " Mmessage file      : $0", 1, { 0 } },
+       { "attr_status_message_file", " Message file       : $0", 1, { 0 } },
        { "attr_preferred_language",  " Preferred langauge : $0", 1, { 0 } },
        { "attr_preferred_contact",   " Preferred contact  : $0", 1, { 0 } },
        { "attr_geolocation",    " Geolocation        : $0", 1, { 0 } },
@@ -171,11 +171,12 @@ FORMAT_REC fecommon_silc_formats[] = {
        { "attr_public_keys",    " Public keys        : $0", 1, { 0 } },
        { "attr_timezone",       " Timezone           : $0", 1, { 0 } },
        { "attr_timezone_allow", " Sending timezone   : $0", 1, { 0 } },
-       { "attr_user_sign_verified",  " User's signature verified successfully", 0 },
-       { "attr_user_sign_failed",    " {hilight User's signature failed}", 0 },
-       { "attr_user_sign_not_present",  " User did not provide digital signature", 0 },
-       { "attr_server_sign_verified",  " Server's signature verified successfully", 0 },
-       { "attr_server_sign_failed",    " {hilight Server's signature failed}", 0 },
+       { "attr_user_sign_verified",  " User's signature   : verified successfully", 0 },
+       { "attr_user_sign_failed",    " User's signature   : {hilight signature failed}", 0 },
+       { "attr_user_sign_not_present",  " User's signature   : not available", 0 },
+       { "attr_server_sign_verified", " Server's signature : verified successfully", 0 },
+       { "attr_server_sign_failed",   " Server's signature : {hilight signature failed}", 0 },
+       { "attr_extension",            " Extension          : $0", 1, { 0 } },
 
        { NULL, NULL, 0 }
 };
index 8fdbd386150c2628fe4eb91b6256dcbc01fa9769..c996e96e68999ab1d57aeb2b8bdb560964fce9d3 100644 (file)
@@ -168,6 +168,7 @@ enum {
   SILCTXT_ATTR_USER_SIGN_NOT_PRESENT,
   SILCTXT_ATTR_SERVER_SIGN_VERIFIED,
   SILCTXT_ATTR_SERVER_SIGN_FAILED,
+  SILCTXT_ATTR_EXTENSION,
 };
 
 extern FORMAT_REC fecommon_silc_formats[];
index 732812b889a79648df2bdce38efc324e1e718bf0..72014628313f596f96a0b2c262d3f384979c0036 100644 (file)
@@ -1203,7 +1203,8 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
       }
 
       if (attrs)
-       silc_query_attributes_print(server, silc_client, conn, attrs);
+       silc_query_attributes_print(server, silc_client, conn, attrs,
+                                   client_entry);
     }
     break;
     
index a88a9f536d3473af4c11bb82dfed860dc0d4e963..a269ebf1f4a3b5e1a8d86fb1e1673188c4cd3b7b 100644 (file)
@@ -32,6 +32,8 @@
 #include "fe-common/core/keyboard.h"
 #include "fe-common/silc/module-formats.h"
 
+static void silc_query_attributes_print_final(bool success, void *context);
+
 QUERY_REC *silc_query_create(const char *server_tag,
                             const char *nick, int automatic)
 {
@@ -248,6 +250,7 @@ void silc_query_attributes_default(SilcClient client,
   SilcAttributeObjGeo geo;
   SilcAttributeObjDevice dev;
   SilcAttributeObjPk pk;
+  SilcVCardStruct vcard;
   bool allowed;
 
   memset(&service, 0, sizeof(service));
@@ -255,6 +258,7 @@ void silc_query_attributes_default(SilcClient client,
   memset(&geo, 0, sizeof(geo));
   memset(&dev, 0, sizeof(dev));
   memset(&pk, 0, sizeof(pk));
+  memset(&vcard, 0, sizeof(vcard));
 
   sv = settings_get_str("attr_vcard");
   if (sv && *sv) {
@@ -262,9 +266,11 @@ void silc_query_attributes_default(SilcClient client,
     silc_client_attribute_del(silc_client, conn,
                              SILC_ATTRIBUTE_USER_INFO, NULL);
     tmp = silc_file_readfile(sv, &tmp_len);
-    if (tmp)
+    if (tmp && silc_vcard_decode(tmp, tmp_len, &vcard))
       silc_client_attribute_add(silc_client, conn,
-                               SILC_ATTRIBUTE_USER_INFO, tmp, tmp_len);
+                               SILC_ATTRIBUTE_USER_INFO, (void *)&vcard,
+                               sizeof(vcard));
+    silc_vcard_free(&vcard);
     silc_free(tmp);
   }
 
@@ -488,7 +494,6 @@ void silc_query_attributes_default(SilcClient client,
                              SILC_ATTRIBUTE_USER_PUBLIC_KEY, NULL);
     list = g_strsplit(sv, " ", -1);
     for (entry = list; *entry != NULL; entry++) {
-      /* XXX we support only SILC keys currently */
       if (!strncasecmp(*entry, "silc-rsa:", 8)) {
        tmp = silc_file_readfile((*entry) + 8, &tmp_len);
        if (tmp) {
@@ -500,30 +505,48 @@ void silc_query_attributes_default(SilcClient client,
                                    sizeof(pk));
        }
        silc_free(tmp);
+      } else {
+       silc_say_error("Unsupported public key type '%s'", *entry);
       }
     }
     g_strfreev(list);
   }
 }
 
+typedef struct {
+  SILC_SERVER_REC *server;
+  char *name;
+  SilcAttributeObjPk userpk;
+  SilcVCardStruct vcard;
+  SilcAttributeObjMime message;
+  SilcAttributeObjMime extension;
+} *AttrVerify;
+
 void silc_query_attributes_print(SILC_SERVER_REC *server,
                                 SilcClient client,
                                 SilcClientConnection conn,
-                                SilcDList attrs)
+                                SilcDList attrs,
+                                SilcClientEntry client_entry)
 {
   SilcAttributePayload attr;
   SilcAttribute attribute;
   char tmp[512];
-  SilcAttributeObjPk userpk, serverpk, usersign, serversign;
+  SilcAttributeObjPk serverpk, usersign, serversign;
+  AttrVerify verify;
 
   printformat_module("fe-common/silc", server, NULL,
                     MSGLEVEL_CRAP, SILCTXT_ATTR_HEADER);
 
-  memset(&userpk, 0, sizeof(userpk));
   memset(&serverpk, 0, sizeof(serverpk));
   memset(&usersign, 0, sizeof(usersign));
   memset(&serversign, 0, sizeof(serversign));
 
+  verify = silc_calloc(1, sizeof(*verify));
+  if (!verify)
+    return;
+  verify->server = server;
+  verify->name = strdup(client_entry->nickname);
+
   silc_dlist_start(attrs);
   while ((attr = silc_dlist_get(attrs)) != SILC_LIST_END) {
     attribute = silc_attribute_get_attribute(attr);
@@ -533,11 +556,12 @@ void silc_query_attributes_print(SILC_SERVER_REC *server,
 
     case SILC_ATTRIBUTE_USER_INFO:
       {
-       SilcVCardStruct vcard;
-       memset(&vcard, 0, sizeof(vcard));
-       if (!silc_attribute_get_object(attr, (void *)&vcard, sizeof(vcard)))
+       if (!silc_attribute_get_object(attr, (void *)&verify->vcard,
+                                      sizeof(verify->vcard)))
          continue;
-       /* XXX */
+       printformat_module("fe-common/silc", server, NULL,
+                          MSGLEVEL_CRAP, SILCTXT_ATTR_VCARD_FILE,
+                          "present");
       }
       break;
 
@@ -600,11 +624,12 @@ void silc_query_attributes_print(SILC_SERVER_REC *server,
 
     case SILC_ATTRIBUTE_STATUS_MESSAGE:
       {
-       SilcAttributeObjMime mime;
-       memset(&mime, 0, sizeof(mime));
-       if (!silc_attribute_get_object(attr, (void *)&mime, sizeof(mime)))
+       if (!silc_attribute_get_object(attr, (void *)&verify->message,
+                                      sizeof(verify->message)))
          continue;
-       /* XXX */
+       printformat_module("fe-common/silc", server, NULL,
+                          MSGLEVEL_CRAP, SILCTXT_ATTR_STATUS_MESSAGE,
+                          "present");
       }
       break;
 
@@ -652,6 +677,14 @@ void silc_query_attributes_print(SILC_SERVER_REC *server,
       break;
 
     case SILC_ATTRIBUTE_EXTENSION:
+      {
+       if (!silc_attribute_get_object(attr, (void *)&verify->extension,
+                                      sizeof(verify->extension)))
+         continue;
+       printformat_module("fe-common/silc", server, NULL,
+                          MSGLEVEL_CRAP, SILCTXT_ATTR_EXTENSION,
+                          "present");
+      }
       break;
 
     case SILC_ATTRIBUTE_GEOLOCATION:
@@ -694,11 +727,14 @@ void silc_query_attributes_print(SILC_SERVER_REC *server,
 
     case SILC_ATTRIBUTE_USER_PUBLIC_KEY:
       {
-       if (userpk.type)
+       if (verify->userpk.type)
          continue;
-       if (!silc_attribute_get_object(attr, (void *)&userpk, sizeof(userpk)))
+       if (!silc_attribute_get_object(attr, (void *)&verify->userpk,
+                                      sizeof(verify->userpk)))
          continue;
       }
+      break;
+
     case SILC_ATTRIBUTE_SERVER_PUBLIC_KEY:
       {
        if (serverpk.type)
@@ -734,15 +770,99 @@ void silc_query_attributes_print(SILC_SERVER_REC *server,
     }
   }
 
-  if (!userpk.type)
+  /* Handle the signature verifications and public key verifying here */
+
+  if (usersign.data && !strcmp(verify->userpk.type, "silc-rsa")) {
+    /* Verify the signature now */
+    SilcPublicKey public_key;
+    SilcPKCS pkcs;
+    unsigned char *verifyd;
+    SilcUInt32 verify_len;
+
+    if (silc_pkcs_public_key_decode(verify->userpk.data,
+                                   verify->userpk.data_len,
+                                   &public_key)) {
+      silc_pkcs_alloc("rsa", &pkcs);
+      verifyd = silc_attribute_get_verify_data(attrs, FALSE, &verify_len);
+      if (verifyd && silc_pkcs_public_key_set(pkcs, public_key)){
+       if (silc_pkcs_verify_with_hash(pkcs, client->sha1hash,
+                                      usersign.data,
+                                      usersign.data_len,
+                                      verifyd, verify_len)) {
+         printformat_module("fe-common/silc", server, NULL,
+                            MSGLEVEL_CRAP, SILCTXT_ATTR_USER_SIGN_VERIFIED);
+       } else {
+         printformat_module("fe-common/silc", server, NULL,
+                            MSGLEVEL_CRAP, SILCTXT_ATTR_USER_SIGN_FAILED);
+       }
+      }
+
+      silc_pkcs_public_key_free(public_key);
+      silc_free(verifyd);
+    }
+  } else {
+    printformat_module("fe-common/silc", server, NULL,
+                      MSGLEVEL_CRAP, SILCTXT_ATTR_USER_SIGN_NOT_PRESENT);
+  }
+
+  if (serversign.data && !strcmp(serverpk.type, "silc-rsa")) {
+    /* Verify the signature now */
+    SilcPublicKey public_key;
+    SilcPKCS pkcs;
+    unsigned char *verifyd;
+    SilcUInt32 verify_len;
+
+    if (silc_pkcs_public_key_decode(serverpk.data, serverpk.data_len,
+                                   &public_key)) {
+      silc_pkcs_alloc("rsa", &pkcs);
+      verifyd = silc_attribute_get_verify_data(attrs, TRUE, &verify_len);
+      if (verifyd && silc_pkcs_public_key_set(pkcs, public_key)) {
+       if (silc_pkcs_verify_with_hash(pkcs, client->sha1hash,
+                                      serversign.data,
+                                      serversign.data_len,
+                                      verifyd, verify_len)) {
+         printformat_module("fe-common/silc", server, NULL,
+                            MSGLEVEL_CRAP, SILCTXT_ATTR_SERVER_SIGN_VERIFIED);
+       } else {
+         printformat_module("fe-common/silc", server, NULL,
+                            MSGLEVEL_CRAP, SILCTXT_ATTR_SERVER_SIGN_FAILED);
+       }
+      }
+
+      silc_pkcs_public_key_free(public_key);
+      silc_free(verifyd);
+    }
+  }
+
+  if (!verify->userpk.type || !usersign.data)
     printformat_module("fe-common/silc", server, NULL,
                       MSGLEVEL_CRAP, SILCTXT_ATTR_FOOTER);
 
-  /* Handle the signature verifications and public key verifying here */
+  silc_verify_public_key(client, conn, SILC_SOCKET_TYPE_CLIENT,
+                        verify->userpk.data, verify->userpk.data_len, 
+                        SILC_SKE_PK_TYPE_SILC,
+                        silc_query_attributes_print_final, verify);
+}
 
-  if (usersign.data && !strcmp(userpk.type, "silc-rsa")) {
-    /* Verify the signature now */
-    /* XXX */
+static void silc_query_attributes_print_final(bool success, void *context)
+{
+  AttrVerify verify = context;
+  SILC_SERVER_REC *server = verify->server;
+
+  if (success) {
+    printformat_module("fe-common/silc", NULL, NULL,
+                      MSGLEVEL_CRAP, SILCTXT_GETKEY_VERIFIED, "user",
+                      verify->name);
+  } else {
+    printformat_module("fe-common/silc", NULL, NULL,
+                      MSGLEVEL_CRAP, SILCTXT_GETKEY_DISCARD, "user",
+                      verify->name);
   }
 
+  printformat_module("fe-common/silc", server, NULL,
+                    MSGLEVEL_CRAP, SILCTXT_ATTR_FOOTER);
+
+  silc_free(verify->name);
+  silc_vcard_free(&verify->vcard);
+  silc_free(verify);
 }
index e5ea6c29deba0b91eed9196ca48c95d7c71aacda..76d31be14895a5b7b22c8c00af9d4c69ae56c2da 100644 (file)
@@ -43,6 +43,7 @@ void silc_query_attributes_default(SilcClient client,
 void silc_query_attributes_print(SILC_SERVER_REC *server,
                                 SilcClient client,
                                 SilcClientConnection conn,
-                                SilcDList attrs);
+                                SilcDList attrs,
+                                SilcClientEntry client_entry);
 
 #endif /* SILC_QUERIES_H */