about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/command/command.c10
-rw-r--r--src/command/commands.c43
-rw-r--r--src/config/tlscerts.c39
-rw-r--r--src/config/tlscerts.h2
-rw-r--r--src/ui/console.c12
-rw-r--r--src/ui/ui.h1
6 files changed, 89 insertions, 18 deletions
diff --git a/src/command/command.c b/src/command/command.c
index 972b849f..bc2ee121 100644
--- a/src/command/command.c
+++ b/src/command/command.c
@@ -206,7 +206,7 @@ static struct cmd_t command_defs[] =
             "/tls allow",
             "/tls always",
             "/tls deny",
-            "/tls cert",
+            "/tls cert [<fingerprint>]",
             "/tls trust",
             "/tls trusted",
             "/tls revoke <fingerprint>",
@@ -221,8 +221,9 @@ static struct cmd_t command_defs[] =
             { "always",               "Always allow connections with TLS certificate." },
             { "deny",                 "Abort connection." },
             { "cert",                 "Show the current TLS certificate." },
+            { "cert <fingerprint>",   "Show details of trusted certificate." },
             { "trust",                "Add the current TLS certificate to manually trusted certiciates." },
-            { "trusted",              "List manually trusted certificates (with '/tls always' or '/tls trust')." },
+            { "trusted",              "List summary of manually trusted certificates (with '/tls always' or '/tls trust')." },
             { "revoke <fingerprint>", "Remove a manually trusted certificate." },
             { "certpath",             "Show the trusted certificate path." },
             { "certpath set <path>",  "Specify filesystem path containing trusted certificates." },
@@ -3877,6 +3878,11 @@ _tls_autocomplete(ProfWin *window, const char *const input)
         return result;
     }
 
+    result = autocomplete_param_with_func(input, "/tls cert", tlscerts_complete);
+    if (result) {
+        return result;
+    }
+
     result = autocomplete_param_with_ac(input, "/tls certpath", tls_certpath_ac, TRUE);
     if (result) {
         return result;
diff --git a/src/command/commands.c b/src/command/commands.c
index 8d2306e8..c17dca43 100644
--- a/src/command/commands.c
+++ b/src/command/commands.c
@@ -236,7 +236,7 @@ cmd_tls(ProfWin *window, const char *const command, gchar **args)
         }
         while (curr) {
             TLSCertificate *cert = curr->data;
-            cons_show_tlscert(cert);
+            cons_show_tlscert_summary(cert);
             cons_show("");
             curr = g_list_next(curr);
         }
@@ -267,24 +267,35 @@ cmd_tls(ProfWin *window, const char *const command, gchar **args)
         return _cmd_set_boolean_preference(args[1], command, "TLS titlebar indicator", PREF_TLS_SHOW);
     } else if (g_strcmp0(args[0], "cert") == 0) {
 #ifdef HAVE_LIBMESODE
-        jabber_conn_status_t conn_status = jabber_get_connection_status();
-        if (conn_status != JABBER_CONNECTED) {
-            cons_show("You are not currently connected.");
-            return TRUE;
-        }
-        if (!jabber_conn_is_secured()) {
-            cons_show("No TLS connection established");
+        if (args[1]) {
+            TLSCertificate *cert = tlscerts_get_trusted(args[1]);
+            if (!cert) {
+                cons_show("No such certificate.");
+            } else {
+                cons_show_tlscert(cert);
+                tlscerts_free(cert);
+            }
             return TRUE;
-        }
-        TLSCertificate *cert = jabber_get_tls_peer_cert();
-        if (!cert) {
-            cons_show("Error getting TLS certificate.");
+        } else {
+            jabber_conn_status_t conn_status = jabber_get_connection_status();
+            if (conn_status != JABBER_CONNECTED) {
+                cons_show("You are not currently connected.");
+                return TRUE;
+            }
+            if (!jabber_conn_is_secured()) {
+                cons_show("No TLS connection established");
+                return TRUE;
+            }
+            TLSCertificate *cert = jabber_get_tls_peer_cert();
+            if (!cert) {
+                cons_show("Error getting TLS certificate.");
+                return TRUE;
+            }
+            cons_show_tlscert(cert);
+            cons_show("");
+            tlscerts_free(cert);
             return TRUE;
         }
-        cons_show_tlscert(cert);
-        cons_show("");
-        tlscerts_free(cert);
-        return TRUE;
 #else
         cons_show("Certificate fetching not supported.");
         return TRUE;
diff --git a/src/config/tlscerts.c b/src/config/tlscerts.c
index 321e04c7..447e57dc 100644
--- a/src/config/tlscerts.c
+++ b/src/config/tlscerts.c
@@ -131,6 +131,15 @@ tlscerts_list(void)
         TLSCertificate *cert = tlscerts_new(fingerprint, version, serialnumber, subjectname, issuername, notbefore,
             notafter, keyalg, signaturealg);
 
+        free(fingerprint);
+        free(serialnumber);
+        free(subjectname);
+        free(issuername);
+        free(notbefore);
+        free(notafter);
+        free(keyalg);
+        free(signaturealg);
+
         res = g_list_append(res, cert);
     }
 
@@ -328,6 +337,36 @@ tlscerts_revoke(const char *const fingerprint)
     return result;
 }
 
+TLSCertificate*
+tlscerts_get_trusted(const char * const fingerprint)
+{
+    if (!g_key_file_has_group(tlscerts, fingerprint)) {
+        return NULL;
+    }
+
+    int version = g_key_file_get_integer(tlscerts, fingerprint, "version", NULL);
+    char *serialnumber = g_key_file_get_string(tlscerts, fingerprint, "serialnumber", NULL);
+    char *subjectname = g_key_file_get_string(tlscerts, fingerprint, "subjectname", NULL);
+    char *issuername = g_key_file_get_string(tlscerts, fingerprint, "issuername", NULL);
+    char *notbefore = g_key_file_get_string(tlscerts, fingerprint, "start", NULL);
+    char *notafter = g_key_file_get_string(tlscerts, fingerprint, "end", NULL);
+    char *keyalg = g_key_file_get_string(tlscerts, fingerprint, "keyalg", NULL);
+    char *signaturealg = g_key_file_get_string(tlscerts, fingerprint, "signaturealg", NULL);
+
+    TLSCertificate *cert = tlscerts_new(fingerprint, version, serialnumber, subjectname, issuername, notbefore,
+        notafter, keyalg, signaturealg);
+
+    free(serialnumber);
+    free(subjectname);
+    free(issuername);
+    free(notbefore);
+    free(notafter);
+    free(keyalg);
+    free(signaturealg);
+
+    return cert;
+}
+
 char*
 tlscerts_complete(const char *const prefix)
 {
diff --git a/src/config/tlscerts.h b/src/config/tlscerts.h
index d0e59218..dd827dbc 100644
--- a/src/config/tlscerts.h
+++ b/src/config/tlscerts.h
@@ -81,6 +81,8 @@ void tlscerts_add(TLSCertificate *cert);
 
 gboolean tlscerts_revoke(const char *const fingerprint);
 
+TLSCertificate* tlscerts_get_trusted(const char *const fingerprint);
+
 void tlscerts_free(TLSCertificate *cert);
 
 GList* tlscerts_list(void);
diff --git a/src/ui/console.c b/src/ui/console.c
index 54cd8d53..6aa706c5 100644
--- a/src/ui/console.c
+++ b/src/ui/console.c
@@ -189,6 +189,18 @@ cons_show_error(const char *const msg, ...)
 }
 
 void
+cons_show_tlscert_summary(TLSCertificate *cert)
+{
+    if (!cert) {
+        return;
+    }
+
+    cons_show("Subject     : %s", cert->subject_commonname);
+    cons_show("Issuer      : %s", cert->issuer_commonname);
+    cons_show("Fingerprint : %s", cert->fingerprint);
+}
+
+void
 cons_show_tlscert(TLSCertificate *cert)
 {
     if (!cert) {
diff --git a/src/ui/ui.h b/src/ui/ui.h
index da4b54a8..032a1161 100644
--- a/src/ui/ui.h
+++ b/src/ui/ui.h
@@ -293,6 +293,7 @@ void cons_show_contact_online(PContact contact, Resource *resource, GDateTime *l
 void cons_show_contact_offline(PContact contact, char *resource, char *status);
 void cons_theme_colours(void);
 void cons_show_tlscert(TLSCertificate *cert);
+void cons_show_tlscert_summary(TLSCertificate *cert);
 
 // title bar
 void title_bar_set_presence(contact_presence_t presence);