static SSLCertificate *ssl_certificate_new_lookup(X509 *x509_cert, gchar *host, gushort port, gboolean lookup)
{
SSLCertificate *cert = g_new0(SSLCertificate, 1);
+ unsigned int n;
+ unsigned char md[EVP_MAX_MD_SIZE];
if (host == NULL || x509_cert == NULL) {
ssl_certificate_destroy(cert);
else
cert->host = g_strdup(host);
cert->port = port;
+
+ /* fingerprint */
+ X509_digest(cert->x509_cert, EVP_md5(), md, &n);
+ cert->fingerprint = readable_fingerprint(md, (int)n);
+
return cert;
}
port = g_strdup_printf("%d", cert->port);
file = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
"certs", G_DIR_SEPARATOR_S,
- cert->host, ".", port, ".cert", NULL);
+ cert->host, ".", port, ".", cert->fingerprint, ".cert", NULL);
g_free(port);
fp = g_fopen(file, "wb");
if (cert->x509_cert)
X509_free(cert->x509_cert);
g_free(cert->host);
+ g_free(cert->fingerprint);
g_free(cert);
cert = NULL;
}
buf = g_strdup_printf("%d", cert->port);
file = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
"certs", G_DIR_SEPARATOR_S,
- cert->host, ".", buf, ".cert", NULL);
+ cert->host, ".", buf, ".", cert->fingerprint, ".cert", NULL);
g_unlink (file);
- g_free(buf);
g_free(file);
+ g_free(buf);
}
-SSLCertificate *ssl_certificate_find (gchar *host, gushort port)
+SSLCertificate *ssl_certificate_find (gchar *host, gushort port, const gchar *fingerprint)
{
- return ssl_certificate_find_lookup (host, port, TRUE);
+ return ssl_certificate_find_lookup (host, port, fingerprint, TRUE);
}
-SSLCertificate *ssl_certificate_find_lookup (gchar *host, gushort port, gboolean lookup)
+SSLCertificate *ssl_certificate_find_lookup (gchar *host, gushort port, const gchar *fingerprint, gboolean lookup)
{
- gchar *file;
+ gchar *file = NULL;
gchar *buf;
gchar *fqdn_host;
SSLCertificate *cert = NULL;
X509 *tmp_x509;
- FILE *fp;
+ FILE *fp = NULL;
+ gboolean must_rename = FALSE;
if (lookup)
fqdn_host = get_fqdn(host);
fqdn_host = g_strdup(host);
buf = g_strdup_printf("%d", port);
- file = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
+
+ if (fingerprint != NULL) {
+ file = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
+ "certs", G_DIR_SEPARATOR_S,
+ fqdn_host, ".", buf, ".", fingerprint, ".cert", NULL);
+ fp = g_fopen(file, "rb");
+ }
+ if (fp == NULL) {
+ /* see if we have the old one */
+ g_free(file);
+ file = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
"certs", G_DIR_SEPARATOR_S,
fqdn_host, ".", buf, ".cert", NULL);
+ fp = g_fopen(file, "rb");
- g_free(buf);
- fp = g_fopen(file, "rb");
+ if (fp)
+ must_rename = (fingerprint != NULL);
+ }
if (fp == NULL) {
g_free(file);
g_free(fqdn_host);
+ g_free(buf);
return NULL;
}
-
if ((tmp_x509 = d2i_X509_fp(fp, 0)) != NULL) {
cert = ssl_certificate_new_lookup(tmp_x509, fqdn_host, port, lookup);
X509_free(tmp_x509);
}
fclose(fp);
g_free(file);
- g_free(fqdn_host);
+ if (must_rename) {
+ gchar *old = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
+ "certs", G_DIR_SEPARATOR_S,
+ fqdn_host, ".", buf, ".cert", NULL);
+ gchar *new = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
+ "certs", G_DIR_SEPARATOR_S,
+ fqdn_host, ".", buf, ".", fingerprint, ".cert", NULL);
+ move_file(old, new, TRUE);
+ g_free(old);
+ g_free(new);
+ }
+ g_free(buf);
+ g_free(fqdn_host);
+
return cert;
}
SSLCertificate *known_cert;
SSLCertHookData cert_hook_data;
gchar *fqdn_host = NULL;
-
+ gchar *fingerprint;
+ unsigned int n;
+ unsigned char md[EVP_MAX_MD_SIZE];
+
if (fqdn)
fqdn_host = g_strdup(fqdn);
else if (host)
return FALSE;
}
- known_cert = ssl_certificate_find_lookup (fqdn_host, port, FALSE);
+ /* fingerprint */
+ X509_digest(x509_cert, EVP_md5(), md, &n);
+ fingerprint = readable_fingerprint(md, (int)n);
+ known_cert = ssl_certificate_find_lookup (fqdn_host, port, fingerprint, FALSE);
+
+ g_free(fingerprint);
g_free(fqdn_host);
if (known_cert == NULL) {
static char *get_server(char *str)
{
char *ret = NULL, *tmp = g_strdup(str);
- char *first_pos = NULL, *last_pos = NULL, *previous_pos = NULL;
+ char *first_pos = NULL, *last_pos = NULL;
+ char *previous_pos = NULL, *pre_previous_pos = NULL;
int previous_dot_pos;
+ if (!strchr(tmp, ':')) {
+ /* no fingerprint */
+ if (strstr(tmp, ".cert"))
+ *(strstr(tmp, ".cert")+1) = '.';
+ }
+
first_pos = tmp;
while (tmp && (tmp = strstr(tmp,".")) != NULL) {
tmp++;
+ pre_previous_pos = previous_pos;
previous_pos = last_pos;
last_pos = tmp;
}
- previous_dot_pos = (previous_pos - first_pos);
+ previous_dot_pos = (pre_previous_pos - first_pos);
if (previous_dot_pos - 1 > 0)
ret = g_strndup(first_pos, previous_dot_pos - 1);
else
}
static char *get_port(char *str)
+{
+ char *ret = NULL, *tmp = g_strdup(str);
+ char *last_pos = NULL;
+ char *previous_pos = NULL, *pre_previous_pos = NULL;
+
+ if (!strchr(tmp, ':')) {
+ /* no fingerprint */
+ if (strstr(tmp, ".cert"))
+ *(strstr(tmp, ".cert")+1) = '.';
+ }
+
+ while (tmp && (tmp = strstr(tmp,".")) != NULL) {
+ tmp++;
+ pre_previous_pos = previous_pos;
+ previous_pos = last_pos;
+ last_pos = tmp;
+ }
+ if (previous_pos && pre_previous_pos && (int)(previous_pos - pre_previous_pos - 1) > 0)
+ ret = g_strndup(pre_previous_pos, (int)(previous_pos - pre_previous_pos - 1));
+ else
+ ret = g_strdup("0");
+ g_free(tmp);
+ return ret;
+
+}
+
+static char *get_fingerprint(char *str)
{
char *ret = NULL, *tmp = g_strdup(str);
char *previous_pos = NULL, *last_pos = NULL;
+ if (!strchr(tmp, ':')) {
+ /* no fingerprint */
+ if (strstr(tmp, ".cert"))
+ *(strstr(tmp, ".cert")+1) = '.';
+ }
+
while (tmp && (tmp = strstr(tmp,".")) != NULL) {
tmp++;
previous_pos = last_pos;
if (last_pos && previous_pos && (int)(last_pos - previous_pos - 1) > 0)
ret = g_strndup(previous_pos, (int)(last_pos - previous_pos - 1));
else
- ret = g_strdup("0");
+ ret = NULL;
g_free(tmp);
return ret;
}
while ((d = readdir(dir)) != NULL) {
- gchar *server, *port;
+ gchar *server, *port, *fp;
SSLCertificate *cert;
if(!strstr(d->d_name, ".cert"))
server = get_server(d->d_name);
port = get_port(d->d_name);
+ fp = get_fingerprint(d->d_name);
-
- cert = ssl_certificate_find_lookup(server, atoi(port), FALSE);
-
+ cert = ssl_certificate_find_lookup(server, atoi(port), fp, FALSE);
+
ssl_manager_list_view_insert_cert(manager.certlist, NULL,
server, port, cert);
g_free(server);
g_free(port);
+ g_free(fp);
row++;
}
closedir(dir);