commit 6ce4075695e4708a67c3efee0aa95c553b4c7906
parent fba944f866cc5e8646c59cb14ca4515837b655b0
Author: Colin Leroy <colin@colino.net>
Date: Fri, 4 Jul 2008 17:11:13 +0000
2008-07-04 [colin] 3.5.0cvs6
* src/common/ssl.c
* src/common/ssl.h
* src/common/ssl_certificate.c
Workaround distro bugs and fix certificate checking
with OpenSSL
Diffstat:
6 files changed, 96 insertions(+), 31 deletions(-)
diff --git a/ChangeLog b/ChangeLog
@@ -1,3 +1,11 @@
+2008-07-04 [colin] 3.5.0cvs6
+
+ * src/common/ssl.c
+ * src/common/ssl.h
+ * src/common/ssl_certificate.c
+ Workaround distro bugs and fix certificate checking
+ with OpenSSL
+
2008-07-04 [colin] 3.5.0cvs5
* src/filtering.c
diff --git a/PATCHSETS b/PATCHSETS
@@ -3417,3 +3417,4 @@
( cvs diff -u -r 1.105.2.133 -r 1.105.2.134 src/prefs_account.c; ) > 3.5.0cvs3.patchset
( cvs diff -u -r 1.105.2.134 -r 1.105.2.135 src/prefs_account.c; ) > 3.5.0cvs4.patchset
( cvs diff -u -r 1.60.2.45 -r 1.60.2.46 src/filtering.c; cvs diff -u -r 1.4.2.28 -r 1.4.2.29 src/common/ssl_certificate.c; cvs diff -u -r 1.1.4.11 -r 1.1.4.12 src/common/ssl_certificate.h; cvs diff -u -r 1.1.4.102 -r 1.1.4.103 src/etpan/imap-thread.c; cvs diff -u -r 1.1.2.7 -r 1.1.2.8 src/etpan/nntp-thread.c; ) > 3.5.0cvs5.patchset
+( cvs diff -u -r 1.9.2.29 -r 1.9.2.30 src/common/ssl.c; cvs diff -u -r 1.2.2.8 -r 1.2.2.9 src/common/ssl.h; cvs diff -u -r 1.4.2.29 -r 1.4.2.30 src/common/ssl_certificate.c; ) > 3.5.0cvs6.patchset
diff --git a/configure.ac b/configure.ac
@@ -11,7 +11,7 @@ MINOR_VERSION=5
MICRO_VERSION=0
INTERFACE_AGE=0
BINARY_AGE=0
-EXTRA_VERSION=5
+EXTRA_VERSION=6
EXTRA_RELEASE=
EXTRA_GTK2_VERSION=
diff --git a/src/common/ssl.c b/src/common/ssl.c
@@ -135,6 +135,66 @@ static int gnutls_client_cert_cb(gnutls_session session,
return -1;
}
#endif
+
+#ifdef USE_OPENSSL
+SSL_CTX *ssl_get_ctx(void)
+{
+ return ssl_ctx;
+}
+#endif
+
+const gchar *claws_ssl_get_cert_file(void)
+{
+ const char *cert_files[]={
+ "/etc/pki/tls/certs/ca-bundle.crt",
+ "/etc/certs/ca-bundle.crt",
+ "/usr/share/ssl/certs/ca-bundle.crt",
+ "/etc/ssl/certs/ca-certificates.crt",
+ "/usr/local/ssl/certs/ca-bundle.crt",
+ "/etc/apache/ssl.crt/ca-bundle.crt",
+ "/usr/share/curl/curl-ca-bundle.crt",
+ NULL};
+ int i;
+
+ if (g_getenv("SSL_CERT_FILE"))
+ return g_getenv("SSL_CERT_FILE");
+#ifndef G_OS_WIN32
+ for (i = 0; cert_files[i]; i++) {
+ if (is_file_exist(cert_files[i]))
+ return cert_files[i];
+ }
+ return NULL;
+#else
+ return "put_what_s_needed_here";
+#endif
+}
+
+const gchar *claws_ssl_get_cert_dir(void)
+{
+ const char *cert_dirs[]={
+ "/etc/pki/tls/certs",
+ "/etc/certs",
+ "/usr/share/ssl/certs",
+ "/etc/ssl/certs",
+ "/usr/local/ssl/certs",
+ "/etc/apache/ssl.crt",
+ "/usr/share/curl",
+ NULL};
+ int i;
+
+ if (g_getenv("SSL_CERT_FILE"))
+ return g_getenv("SSL_CERT_FILE");
+#ifndef G_OS_WIN32
+ for (i = 0; cert_dirs[i]; i++) {
+ if (is_dir_exist(cert_dirs[i]))
+ return cert_dirs[i];
+ }
+ return NULL;
+#else
+ return "put_what_s_needed_here";
+#endif
+}
+
void ssl_init(void)
{
#ifdef USE_OPENSSL
@@ -159,8 +219,17 @@ void ssl_init(void)
SSL_CTX_set_client_cert_cb(ssl_ctx, openssl_client_cert_cb);
/* Set default certificate paths */
- SSL_CTX_set_default_verify_paths(ssl_ctx);
-
+ if (claws_ssl_get_cert_file() || claws_ssl_get_cert_dir()) {
+ int r = SSL_CTX_load_verify_locations(ssl_ctx, claws_ssl_get_cert_file(), claws_ssl_get_cert_dir());
+ if (r != 1) {
+ g_warning("can't set cert file %s dir %s: %s\n",
+ claws_ssl_get_cert_file(), claws_ssl_get_cert_dir(), ERR_error_string(ERR_get_error(), NULL));
+ SSL_CTX_set_default_verify_paths(ssl_ctx);
+ }
+ } else {
+ g_warning("cant");
+ SSL_CTX_set_default_verify_paths(ssl_ctx);
+ }
#if (OPENSSL_VERSION_NUMBER < 0x0090600fL)
SSL_CTX_set_verify_depth(ssl_ctx,1);
#endif
@@ -275,19 +344,6 @@ gboolean ssl_init_socket(SockInfo *sockinfo)
return ssl_init_socket_with_method(sockinfo, SSL_METHOD_SSLv23);
}
-#ifdef USE_GNUTLS
-static const gchar *ssl_get_cert_file(void)
-{
- if (g_getenv("SSL_CERT_FILE"))
- return g_getenv("SSL_CERT_FILE");
-#ifndef G_OS_WIN32
- return "/etc/ssl/certs/ca-certificates.crt";
-#else
- return "put_what_s_needed_here";
-#endif
-}
-#endif
-
gboolean ssl_init_socket_with_method(SockInfo *sockinfo, SSLMethod method)
{
#ifdef USE_OPENSSL
@@ -379,12 +435,15 @@ gboolean ssl_init_socket_with_method(SockInfo *sockinfo, SSLMethod method)
gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred);
- r = gnutls_certificate_set_x509_trust_file(xcred, ssl_get_cert_file(), GNUTLS_X509_FMT_PEM);
- if (r < 0)
- g_warning("Can't read SSL_CERT_FILE %s: %s\n",
- ssl_get_cert_file(),
- gnutls_strerror(r));
-
+ if (claws_ssl_get_cert_file()) {
+ r = gnutls_certificate_set_x509_trust_file(xcred, claws_ssl_get_cert_file(), GNUTLS_X509_FMT_PEM);
+ if (r < 0)
+ g_warning("Can't read SSL_CERT_FILE %s: %s\n",
+ claws_ssl_get_cert_file(),
+ gnutls_strerror(r));
+ } else {
+ debug_print("Can't find SSL ca-certificates file\n");
+ }
gnutls_certificate_set_verify_flags (xcred, GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
gnutls_transport_set_ptr(session, (gnutls_transport_ptr) sockinfo->sock);
diff --git a/src/common/ssl.h b/src/common/ssl.h
@@ -68,6 +68,10 @@ struct _SSLClientCertHookData
gboolean is_smtp;
};
+#ifdef USE_OPENSSL
+SSL_CTX *ssl_get_ctx(void);
+#endif
+
#endif /* USE_OPENSSL */
#endif /* __SSL_H__ */
diff --git a/src/common/ssl_certificate.c b/src/common/ssl_certificate.c
@@ -623,19 +623,14 @@ static gboolean ssl_certificate_compare (SSLCertificate *cert_a, SSLCertificate
char *ssl_certificate_check_signer (X509 *cert)
{
X509_STORE_CTX store_ctx;
- X509_STORE *store;
+ X509_STORE *store = SSL_CTX_get_cert_store(ssl_get_ctx());
char *err_msg = NULL;
- store = X509_STORE_new();
if (store == NULL) {
g_print("Can't create X509_STORE\n");
return NULL;
}
- if (!X509_STORE_set_default_paths(store)) {
- X509_STORE_free (store);
- return g_strdup(_("Couldn't load X509 default paths"));
- }
-
+
X509_STORE_CTX_init (&store_ctx, store, cert, NULL);
if(!X509_verify_cert (&store_ctx)) {
@@ -643,12 +638,10 @@ char *ssl_certificate_check_signer (X509 *cert)
X509_STORE_CTX_get_error(&store_ctx)));
debug_print("Can't check signer: %s\n", err_msg);
X509_STORE_CTX_cleanup (&store_ctx);
- X509_STORE_free (store);
return err_msg;
}
X509_STORE_CTX_cleanup (&store_ctx);
- X509_STORE_free (store);
return NULL;
}
#else