Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Weryfikacja certyfikatów SSL.

  • Loading branch information...
commit 04bde7415ff0d87267a2dfd78aa3ba8da6434389 1 parent 035e3cf
wojtekka authored
Showing with 78 additions and 0 deletions.
  1. +41 −0 configure.ac
  2. +37 −0 src/events.c
View
41 configure.ac
@@ -252,6 +252,47 @@ if test "x$with_gnutls" != "xno"; then
fi
dnl
+dnl Sprawdzamy czy mamy używać systemowych certyfikatów
+dnl
+
+AC_ARG_ENABLE(ssl-system-trust,
+ [ --disable-ssl-system-trust disable the use of system default trusted CAs])
+
+AC_ARG_WITH([gnutls-system-trust-store],
+ [ --with-gnutls-system-trust-store=FILE provide alternative path of system default trust store for GnuTLS versions <= 3.x])
+
+if test "x$enable_ssl_system_trust" != "xno"; then
+ AC_DEFINE([GG_CONFIG_SSL_SYSTEM_TRUST], [], [Defined if libgadu uses system defalt trusted CAs])
+
+ if test "x$have_gnutls" = "xyes"; then
+ AC_CHECK_FUNCS([gnutls_certificate_set_x509_system_trust], [have_gnutls_certificate_set_x509_system_trust=yes], [have_gnutls_certificate_set_x509_system_trust=no])
+
+ if test "x$with_gnutls_system_trust_store" = "x"; then
+ # Lista certyfikatów skopiowana z GnuTLS (https://gitorious.org/gnutls/gnutls/blobs/c59329a089a9ed108692066de95f533f482b5422/configure.ac)
+ for i in /etc/ssl/ca-bundle.pem \
+ /etc/ssl/certs/ca-certificates.crt \
+ /etc/pki/tls/cert.pem \
+ /usr/local/share/certs/ca-root-nss.crt \
+ /etc/ssl/cert.pem
+ do
+ if test -e $i; then
+ with_gnutls_system_trust_store="$i"
+ break
+ fi
+ done
+ fi
+
+ if test "x$with_gnutls_system_trust_store" = "xno";then
+ with_gnutls_system_trust_store=""
+ fi
+
+ if test "x$with_gnutls_system_trust_store" != "x"; then
+ AC_DEFINE_UNQUOTED([GG_CONFIG_GNUTLS_SYSTEM_TRUST_STORE], ["$with_gnutls_system_trust_store"], [use the given file as GnuTLS default trust store])
+ fi
+ fi
+fi
+
+dnl
dnl Sprawdzamy OpenSSL, jeśli nie ma GnuTLS
dnl
View
37 src/events.c
@@ -39,6 +39,7 @@
#include "debug.h"
#include "session.h"
#include "resolver.h"
+#include "config.h"
#include <errno.h>
#include <string.h>
@@ -254,6 +255,13 @@ static int gg_session_init_ssl(struct gg_session *gs)
gnutls_global_init();
gnutls_certificate_allocate_credentials(&tmp->xcred);
+#ifdef GG_CONFIG_SSL_SYSTEM_TRUST
+#ifdef HAVE_GNUTLS_CERTIFICATE_SET_X509_SYSTEM_TRUST
+ gnutls_certificate_set_x509_system_trust(tmp->xcred);
+#else
+ gnutls_certificate_set_x509_trust_file(tmp->xcred, GG_CONFIG_GNUTLS_SYSTEM_TRUST_STORE, GNUTLS_X509_FMT_PEM);
+#endif
+#endif
} else {
gnutls_deinit(tmp->session);
}
@@ -293,7 +301,9 @@ static int gg_session_init_ssl(struct gg_session *gs)
}
SSL_CTX_set_verify(gs->ssl_ctx, SSL_VERIFY_NONE, NULL);
+#ifdef GG_CONFIG_SSL_SYSTEM_TRUST
SSL_CTX_set_default_verify_paths(gs->ssl_ctx);
+#endif
}
if (gs->ssl != NULL)
@@ -1029,6 +1039,8 @@ static gg_action_t gg_handle_send_proxy_gg(struct gg_session *sess, struct gg_ev
static gg_action_t gg_handle_tls_negotiation(struct gg_session *sess, struct gg_event *e, enum gg_state_t next_state, enum gg_state_t alt_state, enum gg_state_t alt2_state)
{
#ifdef GG_CONFIG_HAVE_GNUTLS
+ unsigned int status;
+ int valid_hostname = 0;
int res;
gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() GG_STATE_TLS_NEGOTIATION\n");
@@ -1088,6 +1100,9 @@ static gg_action_t gg_handle_tls_negotiation(struct gg_session *sess, struct gg_
size = sizeof(buf);
gnutls_x509_crt_get_issuer_dn(cert, buf, &size);
gg_debug_session(sess, GG_DEBUG_MISC, "// cert issuer: %s\n", buf);
+
+ if (gnutls_x509_crt_check_hostname(cert, sess->connect_host) != 0)
+ valid_hostname = 1;
}
}
@@ -1095,6 +1110,28 @@ static gg_action_t gg_handle_tls_negotiation(struct gg_session *sess, struct gg_
}
}
+ if (!valid_hostname) {
+ gg_debug_session(sess, GG_DEBUG_MISC, "//   WARNING! unable to verify hostname\n");
+
+ if (sess->ssl_flag == GG_SSL_REQUIRED) {
+ e->event.failure = GG_FAILURE_TLS;
+ return GG_ACTION_FAIL;
+ }
+ }
+
+ res = gnutls_certificate_verify_peers2(GG_SESSION_GNUTLS(sess), &status);
+
+ if (res != 0) {
+ gg_debug_session(sess, GG_DEBUG_MISC, "//   WARNING! unable to verify peer certificate: %d, %s\n", res, gnutls_strerror(res));
+
+ if (sess->ssl_flag == GG_SSL_REQUIRED) {
+ e->event.failure = GG_FAILURE_TLS;
+ return GG_ACTION_FAIL;
+ }
+ } else {
+ gg_debug_session(sess, GG_DEBUG_MISC, "// verified peer certificate\n");
+ }
+
sess->state = next_state;
sess->check = GG_CHECK_READ;
sess->timeout = GG_DEFAULT_TIMEOUT;
Please sign in to comment.
Something went wrong with that request. Please try again.