Revision: 4277
http://tigervnc.svn.sourceforge.net/tigervnc/?rev=4277&view=rev
Author: atkac
Date: 2011-02-09 14:15:09 +0000 (Wed, 09 Feb 2011)
Log Message:
-----------
[Development] os: add gnutls_x509_crt_print() implementation, older systems
don't have it and improve backward compatibility of TLS code.
Modified Paths:
--------------
trunk/common/os/CMakeLists.txt
trunk/common/os/Makefile.am
trunk/common/rfb/CSecurityTLS.cxx
trunk/configure.ac
Added Paths:
-----------
trunk/common/os/tls.cxx
trunk/common/os/tls.h
Modified: trunk/common/os/CMakeLists.txt
===================================================================
--- trunk/common/os/CMakeLists.txt 2011-02-09 14:13:41 UTC (rev 4276)
+++ trunk/common/os/CMakeLists.txt 2011-02-09 14:15:09 UTC (rev 4277)
@@ -3,4 +3,5 @@
add_library(os STATIC
print.c
net.c
- os.cxx)
+ os.cxx
+ tls.cxx)
Modified: trunk/common/os/Makefile.am
===================================================================
--- trunk/common/os/Makefile.am 2011-02-09 14:13:41 UTC (rev 4276)
+++ trunk/common/os/Makefile.am 2011-02-09 14:15:09 UTC (rev 4277)
@@ -1,8 +1,8 @@
noinst_LTLIBRARIES = libos.la
-HDRS = net.h print.h os.h
+HDRS = net.h print.h os.h tls.h
-libos_la_SOURCES = $(HDRS) print.c net.c os.cxx
+libos_la_SOURCES = $(HDRS) print.c net.c os.cxx tls.cxx
libos_la_CPPFLAGS = -I$(top_srcdir)/common
Added: trunk/common/os/tls.cxx
===================================================================
--- trunk/common/os/tls.cxx (rev 0)
+++ trunk/common/os/tls.cxx 2011-02-09 14:15:09 UTC (rev 4277)
@@ -0,0 +1,193 @@
+/* Copyright (C) 2011 TightVNC Team. All Rights Reserved.
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this software; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ * USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <os/tls.h>
+
+#include <iomanip>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sstream>
+#include <sys/types.h>
+#include <time.h>
+
+using namespace std;
+
+#ifdef HAVE_GNUTLS
+#include <gnutls/gnutls.h>
+#include <gnutls/x509.h>
+
+#ifndef HAVE_GNUTLS_X509_CRT_PRINT
+
+#define UNKNOWN_SUBJECT(err) \
+ do { \
+ ss << "unknown subject (" << gnutls_strerror(err) << "), "; \
+ } while (0)
+
+#define UNKNOWN_ISSUER(err) \
+ do { \
+ ss << "unknown issuer (" << gnutls_strerror(err) << "), "; \
+ } while (0)
+
+
+static void
+hexprint(ostringstream &ss, const char *data, size_t len)
+{
+ size_t j;
+ char tmp[3];
+
+ if (len == 0)
+ ss << "00";
+ else {
+ for (j = 0; j < len; j++) {
+ snprintf(tmp, sizeof(tmp), "%.2x", (unsigned char)
data[j]);
+ ss << tmp;
+ }
+ }
+}
+
+/* Implementation based on gnutls_x509_crt_print from GNUTLS */
+int
+gnutls_x509_crt_print(gnutls_x509_crt_t cert,
+ gnutls_certificate_print_formats_t format,
+ gnutls_datum_t * out)
+{
+ ostringstream ss;
+
+ int err;
+
+ char *dn;
+ size_t dn_size = 0;
+
+ /* Subject */
+ err = gnutls_x509_crt_get_dn(cert, NULL, &dn_size);
+ if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
+ UNKNOWN_SUBJECT(err);
+ else {
+ dn = (char *)malloc(dn_size);
+ if (dn == NULL) {
+ UNKNOWN_SUBJECT(GNUTLS_E_MEMORY_ERROR);
+ } else {
+ err = gnutls_x509_crt_get_dn(cert, dn, &dn_size);
+ if (err < 0) {
+ UNKNOWN_SUBJECT(err);
+ } else
+ ss << "subject `" << dn << "', ";
+ free(dn);
+ }
+ }
+
+ /* Issuer */
+ dn = NULL;
+ dn_size = 0;
+ err = gnutls_x509_crt_get_issuer_dn(cert, NULL, &dn_size);
+ if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
+ UNKNOWN_ISSUER(err);
+ else {
+ dn = (char *)malloc(dn_size);
+ if (dn == NULL) {
+ UNKNOWN_ISSUER(GNUTLS_E_MEMORY_ERROR);
+ } else {
+ err = gnutls_x509_crt_get_issuer_dn(cert, dn, &dn_size);
+ if (err < 0)
+ UNKNOWN_ISSUER(err);
+ else
+ ss << "issuer `" << dn << "', ";
+ free(dn);
+ }
+ }
+
+ /* Key algorithm and size */
+ unsigned int bits;
+ const char *name;
+ name = gnutls_pk_algorithm_get_name( (gnutls_pk_algorithm_t)
+ gnutls_x509_crt_get_pk_algorithm(cert, &bits));
+ if (name == NULL)
+ name = "Unknown";
+ ss << name << " key " << bits << " bits, ";
+
+ /* Signature algorithm */
+ err = gnutls_x509_crt_get_signature_algorithm(cert);
+ if (err < 0) {
+ ss << "unknown signature algorithm (" << gnutls_strerror(err)
+ << "), ";
+ } else {
+ const char *name;
+ name =
gnutls_sign_algorithm_get_name((gnutls_sign_algorithm_t)err);
+ if (name == NULL)
+ name = "Unknown";
+
+ ss << "signed using " << name;
+ if (err == GNUTLS_SIGN_RSA_MD5 || err == GNUTLS_SIGN_RSA_MD2)
+ ss << " (broken!)";
+ ss << ", ";
+ }
+
+ /* Validity */
+ time_t tim;
+ char s[42];
+ size_t max = sizeof(s);
+ struct tm t;
+
+ tim = gnutls_x509_crt_get_activation_time(cert);
+ if (gmtime_r(&tim, &t) == NULL)
+ ss << "unknown activation (" << (unsigned long) tim << ")";
+ else if (strftime(s, max, "%Y-%m-%d %H:%M:%S UTC", &t) == 0)
+ ss << "failed activation (" << (unsigned long) tim << ")";
+ else
+ ss << "activated `" << s << "'";
+ ss << ", ";
+
+ tim = gnutls_x509_crt_get_expiration_time(cert);
+ if (gmtime_r(&tim, &t) == NULL)
+ ss << "unknown expiry (" << (unsigned long) tim << ")";
+ else if (strftime(s, max, "%Y-%m-%d %H:%M:%S UTC", &t) == 0)
+ ss << "failed expiry (" << (unsigned long) tim << ")";
+ else
+ ss << "expires `" << s << "'";
+ ss << ", ";
+
+ /* Fingerprint */
+ char buffer[20];
+ size_t size = sizeof(buffer);
+
+ err = gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_SHA1, buffer,
&size);
+ if (err < 0)
+ ss << "unknown fingerprint (" << gnutls_strerror(err) << ")";
+ else {
+ ss << "SHA-1 fingerprint `";
+ hexprint(ss, buffer, size);
+ ss << "'";
+ }
+
+ out->data = (unsigned char *) strdup(ss.str().c_str());
+ if (out->data == NULL)
+ return GNUTLS_E_MEMORY_ERROR;
+ out->size = strlen((char *)out->data);
+
+ return 0;
+}
+
+#endif /* HAVE_GNUTLS_X509_CRT_PRINT */
+
+#endif /* HAVE_GNUTLS */
+
Added: trunk/common/os/tls.h
===================================================================
--- trunk/common/os/tls.h (rev 0)
+++ trunk/common/os/tls.h 2011-02-09 14:15:09 UTC (rev 4277)
@@ -0,0 +1,49 @@
+/* Copyright (C) 2011 TightVNC Team. All Rights Reserved.
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this software; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ * USA.
+ */
+
+#ifndef OS_TLS_H
+#define OS_TLS_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_GNUTLS
+#include <gnutls/gnutls.h>
+
+#ifndef HAVE_GNUTLS_X509_CRT_PRINT
+#ifdef WIN32
+#error "Please install more recent GNUTLS with gnutls_x509_crt_print()
function"
+#endif
+
+typedef enum {
+ GNUTLS_CRT_PRINT_ONELINE = 1
+} gnutls_certificate_print_formats_t;
+
+/*
+ * Prints certificate in human-readable form.
+ */
+int
+gnutls_x509_crt_print(gnutls_x509_crt_t cert,
+ gnutls_certificate_print_formats_t format,
+ gnutls_datum_t * out);
+#endif /* HAVE_GNUTLS_X509_CRT_PRINT */
+#endif /* HAVE_GNUTLS */
+
+#endif /* OS_TLS_H */
+
Modified: trunk/common/rfb/CSecurityTLS.cxx
===================================================================
--- trunk/common/rfb/CSecurityTLS.cxx 2011-02-09 14:13:41 UTC (rev 4276)
+++ trunk/common/rfb/CSecurityTLS.cxx 2011-02-09 14:15:09 UTC (rev 4277)
@@ -43,18 +43,20 @@
#include <rdr/TLSOutStream.h>
#include <os/os.h>
#include <os/print.h>
+#include <os/tls.h>
#include <gnutls/x509.h>
-#if !defined(GNUTLS_VERSION_NUMBER) || (GNUTLS_VERSION_NUMBER < 0x020708)
-#define GNUTLS_CERT_NOT_ACTIVATED 512
-#define GNUTLS_CERT_EXPIRED 1024
+/*
+ * GNUTLS 2.6.5 and older didn't have some variables defined so don't use them.
+ * GNUTLS 1.X.X defined LIBGNUTLS_VERSION_NUMBER so treat it as "old" gnutls as
+ * well
+ */
+#if (defined(GNUTLS_VERSION_NUMBER) && GNUTLS_VERSION_NUMBER < 0x020606) || \
+ defined(LIBGNUTLS_VERSION_NUMBER)
+#define WITHOUT_X509_TIMES
#endif
-#if !defined(GNUTLS_VERSION_NUMBER) || (GNUTLS_VERSION_NUMBER < 0x020301)
-#define GNUTLS_CRT_PRINT_ONELINE 1
-#endif
-
#define TLS_DEBUG
using namespace rfb;
@@ -284,6 +286,7 @@
if (status & GNUTLS_CERT_REVOKED)
throw AuthFailureException("server certificate has been revoked");
+#ifndef WITHOUT_X509_TIMES
if (status & GNUTLS_CERT_NOT_ACTIVATED)
throw AuthFailureException("server certificate has not been activated");
@@ -294,6 +297,7 @@
"do you want to continue?"))
throw AuthFailureException("server certificate has expired");
}
+#endif
/* Process other errors later */
cert_list = gnutls_certificate_get_peers(session, &cert_list_size);
@@ -338,7 +342,6 @@
vlog.debug("Saved server certificates don't match");
- #if defined(GNUTLS_VERSION_NUMBER) && (GNUTLS_VERSION_NUMBER >= 0x010706)
if (gnutls_x509_crt_print(crt, GNUTLS_CRT_PRINT_ONELINE, &info)) {
/*
* GNUTLS doesn't correctly export gnutls_free symbol which is
@@ -352,9 +355,8 @@
#endif
throw AuthFailureException("Could not find certificate to display");
}
- #endif
- size_t out_size;
+ size_t out_size = 0;
char *out_buf = NULL;
char *certinfo = NULL;
int len = 0;
Modified: trunk/configure.ac
===================================================================
--- trunk/configure.ac 2011-02-09 14:13:41 UTC (rev 4276)
+++ trunk/configure.ac 2011-02-09 14:15:09 UTC (rev 4277)
@@ -107,6 +107,12 @@
AC_MSG_RESULT(yes),
[AC_DEFINE(HAVE_OLD_GNUTLS, 1, [Does gnutls lack the
gnutls_transport_set_global_errno() function? ])
AC_MSG_RESULT(no)])
+ AC_MSG_CHECKING([for gnutls_x509_crt_print() function])
+ AC_LINK_IFELSE(AC_LANG_CALL([], gnutls_x509_crt_print),
+ [AC_DEFINE(HAVE_GNUTLS_X509_CRT_PRINT, 1, [Is the
gnutls_x509_crt_print() function present? ])
+ AC_MSG_RESULT(yes)],
+ AC_MSG_RESULT(no))
+
LIBS=${SAVE_LIBS}
fi
AC_SUBST([GNUTLS_LIBS])
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
The ultimate all-in-one performance toolkit: Intel(R) Parallel Studio XE:
Pinpoint memory and threading errors before they happen.
Find and fix more than 250 security defects in the development cycle.
Locate bottlenecks in serial and parallel code that limit performance.
http://p.sf.net/sfu/intel-dev2devfeb
_______________________________________________
Tigervnc-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tigervnc-commits