From 35a4e0d015dd5e62bbe9e4d817b1e8ff850d3cf1 Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Tue, 15 Oct 2002 20:16:32 +0000 Subject: [PATCH] Added user public key, user signature and server signature verification in requested attributes receiving. --- CHANGES | 12 ++ .../irssi/src/fe-common/silc/module-formats.c | 21 +-- .../irssi/src/fe-common/silc/module-formats.h | 1 + apps/irssi/src/silc/core/client_ops.c | 3 +- apps/irssi/src/silc/core/silc-queries.c | 162 +++++++++++++++--- apps/irssi/src/silc/core/silc-queries.h | 3 +- 6 files changed, 169 insertions(+), 33 deletions(-) diff --git a/CHANGES b/CHANGES index e7f1157e..f540db95 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,15 @@ +Tue Oct 15 18:05:24 EEST 2002 Pekka Riikonen + + * 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 * Periodically remove the NOATTR status from client entry diff --git a/apps/irssi/src/fe-common/silc/module-formats.c b/apps/irssi/src/fe-common/silc/module-formats.c index 720bd66a..bdfcdcfc 100644 --- a/apps/irssi/src/fe-common/silc/module-formats.c +++ b/apps/irssi/src/fe-common/silc/module-formats.c @@ -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 } }; diff --git a/apps/irssi/src/fe-common/silc/module-formats.h b/apps/irssi/src/fe-common/silc/module-formats.h index 8fdbd386..c996e96e 100644 --- a/apps/irssi/src/fe-common/silc/module-formats.h +++ b/apps/irssi/src/fe-common/silc/module-formats.h @@ -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[]; diff --git a/apps/irssi/src/silc/core/client_ops.c b/apps/irssi/src/silc/core/client_ops.c index 732812b8..72014628 100644 --- a/apps/irssi/src/silc/core/client_ops.c +++ b/apps/irssi/src/silc/core/client_ops.c @@ -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; diff --git a/apps/irssi/src/silc/core/silc-queries.c b/apps/irssi/src/silc/core/silc-queries.c index a88a9f53..a269ebf1 100644 --- a/apps/irssi/src/silc/core/silc-queries.c +++ b/apps/irssi/src/silc/core/silc-queries.c @@ -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); } diff --git a/apps/irssi/src/silc/core/silc-queries.h b/apps/irssi/src/silc/core/silc-queries.h index e5ea6c29..76d31be1 100644 --- a/apps/irssi/src/silc/core/silc-queries.h +++ b/apps/irssi/src/silc/core/silc-queries.h @@ -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 */ -- 2.43.0