summaryrefslogtreecommitdiff
path: root/extra/claws-mail/claws-ssl-2.patch
blob: 77186d20befefa3ebf3c9babae34a45ecdf87359 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
From fe50206b4385404c38ad0421bdfb707bb6994d80 Mon Sep 17 00:00:00 2001
From: Nepu User <nepu@localhost.localdomain>
Date: Sun, 27 Apr 2014 14:55:18 +0200
Subject: [PATCH 2/3] upstream commit dda3675203030f329d527c697e14342c9c13a75c

---
 src/common/ssl_certificate.c | 17 ++++++++++++++
 src/common/ssl_certificate.h |  1 +
 src/etpan/etpan-ssl.c        | 53 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 71 insertions(+)

diff --git a/src/common/ssl_certificate.c b/src/common/ssl_certificate.c
index 84e017e..72f73ac 100644
--- a/src/common/ssl_certificate.c
+++ b/src/common/ssl_certificate.c
@@ -647,6 +647,23 @@ gboolean ssl_certificate_check (gnutls_x509_crt_t x509_cert, guint status, const
 	return TRUE;
 }
 
+gboolean ssl_certificate_check_chain(gnutls_x509_crt_t *certs, gint chain_len, const gchar *host, gushort port)
+{
+	gboolean result = FALSE;
+	gint status;
+
+	gnutls_x509_crt_list_verify (certs,
+                             chain_len,
+                             NULL, 0,
+                             NULL, 0,
+                             GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT,
+                             &status);
+
+	result = ssl_certificate_check(certs[0], status, host, port);
+
+	return result;
+}
+
 gnutls_x509_crt_t ssl_certificate_get_x509_from_pem_file(const gchar *file)
 {
 	gnutls_x509_crt_t x509 = NULL;
diff --git a/src/common/ssl_certificate.h b/src/common/ssl_certificate.h
index 8bbe2ac..fd8822a 100644
--- a/src/common/ssl_certificate.h
+++ b/src/common/ssl_certificate.h
@@ -58,6 +58,7 @@ struct _SSLCertHookData
 
 SSLCertificate *ssl_certificate_find (const gchar *host, gushort port, const gchar *fingerprint);
 gboolean ssl_certificate_check (gnutls_x509_crt_t x509_cert, guint status, const gchar *host, gushort port);
+gboolean ssl_certificate_check_chain(gnutls_x509_crt_t *certs, gint chain_len, const gchar *host, gushort port);
 void ssl_certificate_destroy(SSLCertificate *cert);
 void ssl_certificate_delete_from_disk(SSLCertificate *cert);
 char * readable_fingerprint(unsigned char *src, int len);
diff --git a/src/etpan/etpan-ssl.c b/src/etpan/etpan-ssl.c
index 6642e40..c9dc9d8 100644
--- a/src/etpan/etpan-ssl.c
+++ b/src/etpan/etpan-ssl.c
@@ -26,6 +26,7 @@
 #ifdef USE_GNUTLS
 #ifdef HAVE_LIBETPAN
 #include <libetpan/libetpan.h>
+#include <libetpan/libetpan_version.h>
 #include <gnutls/gnutls.h>
 #include <gnutls/x509.h>
 #include <stdlib.h>
@@ -33,6 +34,7 @@
 #include <glib/gi18n.h>
 #include <errno.h>
 
+#include "etpan-ssl.h"
 #include "ssl_certificate.h"
 #include "utils.h"
 #include "log.h"
@@ -40,6 +42,7 @@
 
 gboolean etpan_certificate_check(mailstream *stream, const char *host, gint port)
 {
+#if (!defined LIBETPAN_API_CURRENT || LIBETPAN_API_CURRENT < 18)
 	unsigned char *cert_der = NULL;
 	int len;
 	gnutls_x509_crt_t cert = NULL;
@@ -75,6 +78,56 @@ gboolean etpan_certificate_check(mailstream *stream, const char *host, gint port
 		gnutls_x509_crt_deinit(cert);
 		return FALSE;
 	}
+#else
+	carray *certs_der = NULL;
+	gint chain_len = 0, i;
+	gnutls_x509_crt_t *certs = NULL;
+	gboolean result;
+
+	if (stream == NULL)
+		return FALSE;
+
+	certs_der = mailstream_get_certificate_chain(stream);
+	if (!certs_der) {
+		g_warning("could not get certs");
+		return FALSE;
+	}
+	chain_len = carray_count(certs_der);
+
+	certs = malloc(sizeof(gnutls_x509_crt_t) * chain_len);
+	if  (certs == NULL) {
+		g_warning("could not allocate certs");
+		return FALSE;
+	}
+
+	result = TRUE;
+	for (i = 0; i < chain_len; i++) {
+		MMAPString *cert_str = carray_get(certs_der, i);
+		gnutls_datum_t tmp;
+
+		tmp.data = malloc(cert_str->len);
+		memcpy(tmp.data, cert_str->str, cert_str->len);
+		tmp.size = cert_str->len;
+
+		mmap_string_free(cert_str);
+
+		gnutls_x509_crt_init(&certs[i]);
+		if (gnutls_x509_crt_import(certs[i], &tmp, GNUTLS_X509_FMT_DER) < 0)
+			result = FALSE;
+
+		free(tmp.data);
+	}
+
+	carray_free(certs_der);
+
+	if (result == TRUE)
+		result = ssl_certificate_check_chain(certs, chain_len, host, port);
+
+	for (i = 0; i < chain_len; i++)
+		gnutls_x509_crt_deinit(certs[i]);
+
+	return result;
+#endif
 }
 
 void etpan_connect_ssl_context_cb(struct mailstream_ssl_context * ssl_context, void * data)
-- 
1.9.2