summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuslan N. Marchenko <me@ruff.mobi>2020-04-23 23:33:55 +0200
committerRuslan N. Marchenko <me@ruff.mobi>2020-05-17 22:39:30 +0200
commit71d67e44ce3072ebeae477f1b493bbb80f6f7958 (patch)
treecaf29b1acfbd794d21e5f4808711a64bd5e3a40c
parentaa31ef0b5192bf674044eec9678c08250405453f (diff)
Remove direct openssl backend, available via env GIO_USE_TLS
-rw-r--r--configure.ac78
-rw-r--r--examples/Makefile.am4
-rw-r--r--wocky/Makefile.am21
-rw-r--r--wocky/wocky-openssl-dh1024.c45
-rw-r--r--wocky/wocky-openssl-dh2048.c56
-rw-r--r--wocky/wocky-openssl-dh4096.c77
-rw-r--r--wocky/wocky-openssl-dh512.c40
-rw-r--r--wocky/wocky-openssl.c2127
8 files changed, 6 insertions, 2442 deletions
diff --git a/configure.ac b/configure.ac
index f1d339a..6a99912 100644
--- a/configure.ac
+++ b/configure.ac
@@ -128,81 +128,10 @@ AC_DEFINE([GLIB_VERSION_MAX_ALLOWED], [GLIB_VERSION_2_44], [Prevent post 2.44 AP
AC_SUBST(GLIB_CFLAGS)
AC_SUBST(GLIB_LIBS)
-dnl Choose an SSL/TLS backend (default gnutls)
-AC_ARG_WITH([tls],
- AC_HELP_STRING([--with-tls=BACKEND],
- [which TLS backend to use (gnutls, openssl, or auto) @<:@default=auto@:>@]),
- [],
- [with_tls=auto])
-
-
-AS_CASE([$with_tls],
- [gnutls], [PKG_CHECK_MODULES(TLS, [gnutls >= 2.8.2 ])],
- [openssl], [USING_OPENSSL=yes
- AC_DEFINE(USING_OPENSSL, 1, [Define if using openssl])
- PKG_CHECK_MODULES(TLS, [openssl >= 0.9.8g])],
- [auto], [PKG_CHECK_MODULES(TLS, [gnutls >= 2.8.2 ],
- [with_tls=gnutls],
- [USING_OPENSSL=yes
- AC_DEFINE(USING_OPENSSL, 1, [Define if using openssl])
- PKG_CHECK_MODULES(TLS, [openssl >= 0.9.8g],[with_tls=openssl],
- AC_MSG_ERROR([Neither gnutls nor openssl found]))])],
- [*], AC_MSG_ERROR([Must have a TLS backend (gnutls or openssl)]))
-
+PKG_CHECK_MODULES(TLS, [gnutls >= 3.0], [ HAVE_TLS=yes ], [ HAVE_TLS=no ])
AC_SUBST(TLS_CFLAGS)
AC_SUBST(TLS_LIBS)
-AM_CONDITIONAL(USING_OPENSSL, test x$USING_OPENSSL = xyes)
-
-AC_ARG_ENABLE([prefer-stream-ciphers],
- AC_HELP_STRING([--enable-prefer-stream-ciphers],
- [prefer stream ciphers over block ciphers to save bandwidth (at the possible expense of security)]),
- [prefer_stream_ciphers=$enableval], [prefer_stream_ciphers=no])
-
-if test x$prefer_stream_ciphers = xyes; then
- AC_DEFINE(ENABLE_PREFER_STREAM_CIPHERS, [],
- [Prefer stream ciphers over block ones to save bandwidth])
- if test $with_tls = gnutls; then
- # The *-ALL priority strings require gnutls 2.12.0.
- # We do this check here and not earlier to avoid accidentally falling
- # back to openssl because of the use of --enable-prefer-stream-ciphers.
- PKG_CHECK_MODULES(GNUTLS_FOR_STREAM_CIPHERS, [gnutls >= 2.12.0],[],
- AC_MSG_ERROR([gnutls 2.12.0 is needed to use --enable-prefer-stream-ciphers]))
- fi
-fi
-
-
-# -----------------------------------------------------------
-# Make CA certificates path configurable
-# Stolen from GIO's TLS
-# -----------------------------------------------------------
-AC_MSG_CHECKING([location of system Certificate Authority list])
-AC_ARG_WITH(ca-certificates,
- [AC_HELP_STRING([--with-ca-certificates=@<:@path@:>@],
- [path to system Certificate Authority list])])
-if test "$with_ca_certificates" = "no"; then
- AC_MSG_RESULT([disabled])
-else
- if test -z "$with_ca_certificates"; then
- for f in /etc/pki/tls/certs/ca-bundle.crt \
- /etc/ssl/certs/ca-certificates.crt; do
- if test -f "$f"; then
- with_ca_certificates="$f"
- fi
- done
- if test -z "$with_ca_certificates"; then
- AC_MSG_ERROR([could not find. Use --with-ca-certificates=path to set, or --without-ca-certificates to disable])
- fi
- fi
-
- AC_MSG_RESULT($with_ca_certificates)
- AC_DEFINE_UNQUOTED([GTLS_SYSTEM_CA_CERTIFICATES], ["$with_ca_certificates"], [path to system Certificate Authority list])
-fi
-
-if test -n "$with_ca_certificates"; then
- if ! test -f "$with_ca_certificates"; then
- AC_MSG_WARN([Specified certificate authority file '$with_ca_certificates' does not exist])
- fi
-fi
+AM_CONDITIONAL(HAVE_TLS, test x$HAVE_TLS = xyes)
GLIB_GENMARSHAL=`$PKG_CONFIG --variable=glib_genmarshal glib-2.0`
@@ -309,9 +238,6 @@ Configure summary:
Debug................: ${enable_debug}
Features:
- TLS Backend..........: ${with_tls}
- Prefer stream ciphers: ${prefer_stream_ciphers}
- System CA certs......: ${with_ca_certificates}
SASL2 Tests..........: ${HAVE_LIBSASL2}
gtk-doc documentation: ${enable_gtk_doc}
libiphb integration..: ${have_iphb}
diff --git a/examples/Makefile.am b/examples/Makefile.am
index cddb8a0..b5b0367 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -1,9 +1,8 @@
EXAMPLES =
-if ! USING_OPENSSL
+if HAVE_TLS
EXAMPLES += wocky-dump-certificates
endif
-
EXAMPLES += wocky-send-message
EXAMPLES += wocky-receive-messages
EXAMPLES += wocky-register
@@ -13,6 +12,7 @@ INCLUDES := -I$(top_builddir)/wocky
wocky_dump_certificates_SOURCES = dump-certificates.c
wocky_dump_certificates_CFLAGS = $(TLS_CFLAGS) $(AM_CFLAGS)
+
wocky_dump_certificates_LDADD = $(TLS_LIBS) $(LDADD)
wocky_send_message_SOURCES = send-message.c
diff --git a/wocky/Makefile.am b/wocky/Makefile.am
index 9871311..7dcca6b 100644
--- a/wocky/Makefile.am
+++ b/wocky/Makefile.am
@@ -37,15 +37,6 @@ built_sources = \
BUILT_SOURCES = $(built_headers) $(built_sources)
-OPENSSL_SRC = \
- wocky-openssl.c \
- wocky-openssl-dh512.c \
- wocky-openssl-dh1024.c \
- wocky-openssl-dh2048.c \
- wocky-openssl-dh4096.c
-
-GNUTLS_SRC = wocky-tls.c
-
handwritten_headers = \
wocky.h \
wocky-auth-handler.h \
@@ -168,6 +159,7 @@ handwritten_sources = \
wocky-session.c \
wocky-stanza.c \
wocky-utils.c \
+ wocky-tls.c \
wocky-tls-common.c \
wocky-tls-handler.c \
wocky-tls-connector.c \
@@ -177,14 +169,6 @@ handwritten_sources = \
wocky-xmpp-reader.c \
wocky-xmpp-writer.c
-if USING_OPENSSL
- handwritten_sources += $(OPENSSL_SRC)
- EXTRA_DIST += $(GNUTLS_SRC)
-else
- handwritten_sources += $(GNUTLS_SRC)
- EXTRA_DIST += $(OPENSSL_SRC)
-endif
-
libwocky_la_SOURCES = $(handwritten_sources) $(built_sources) \
$(handwritten_headers) $(built_headers)
@@ -234,7 +218,7 @@ wocky-signals-marshal.list: $(handwritten_sources) Makefile.am
AM_CFLAGS = $(ERROR_CFLAGS) $(GCOV_CFLAGS) \
- @GLIB_CFLAGS@ @LIBXML2_CFLAGS@ @SQLITE_CFLAGS@ @TLS_CFLAGS@ \
+ @GLIB_CFLAGS@ @LIBXML2_CFLAGS@ @SQLITE_CFLAGS@ \
@LIBIPHB_CFLAGS@ \
@SOUP_CFLAGS@ \
-DG_LOG_DOMAIN=\"wocky\" \
@@ -246,7 +230,6 @@ libwocky_la_LIBADD = \
@GLIB_LIBS@ \
@LIBXML2_LIBS@ \
@SQLITE_LIBS@ \
- @TLS_LIBS@ \
@LIBIPHB_LIBS@ \
@SOUP_LIBS@ \
$(NULL)
diff --git a/wocky/wocky-openssl-dh1024.c b/wocky/wocky-openssl-dh1024.c
deleted file mode 100644
index 15b2793..0000000
--- a/wocky/wocky-openssl-dh1024.c
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#ifndef HEADER_DH_H
-#include <openssl/dh.h>
-#endif
-DH *get_dh1024(void);
-DH *get_dh1024(void)
- {
- static unsigned char dh1024_p[]={
- 0xF4,0x88,0xFD,0x58,0x4E,0x49,0xDB,0xCD,0x20,0xB4,0x9D,0xE4,
- 0x91,0x07,0x36,0x6B,0x33,0x6C,0x38,0x0D,0x45,0x1D,0x0F,0x7C,
- 0x88,0xB3,0x1C,0x7C,0x5B,0x2D,0x8E,0xF6,0xF3,0xC9,0x23,0xC0,
- 0x43,0xF0,0xA5,0x5B,0x18,0x8D,0x8E,0xBB,0x55,0x8C,0xB8,0x5D,
- 0x38,0xD3,0x34,0xFD,0x7C,0x17,0x57,0x43,0xA3,0x1D,0x18,0x6C,
- 0xDE,0x33,0x21,0x2C,0xB5,0x2A,0xFF,0x3C,0xE1,0xB1,0x29,0x40,
- 0x18,0x11,0x8D,0x7C,0x84,0xA7,0x0A,0x72,0xD6,0x86,0xC4,0x03,
- 0x19,0xC8,0x07,0x29,0x7A,0xCA,0x95,0x0C,0xD9,0x96,0x9F,0xAB,
- 0xD0,0x0A,0x50,0x9B,0x02,0x46,0xD3,0x08,0x3D,0x66,0xA4,0x5D,
- 0x41,0x9F,0x9C,0x7C,0xBD,0x89,0x4B,0x22,0x19,0x26,0xBA,0xAB,
- 0xA2,0x5E,0xC3,0x55,0xE9,0x2F,0x78,0xC7,
- };
- static unsigned char dh1024_g[]={
- 0x02,
- };
- DH *dh;
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
- int r = 0;
-#endif
-
- if ((dh=DH_new()) == NULL) return(NULL);
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
- r = DH_set0_pqg(dh, BN_bin2bn(dh1024_p,sizeof(dh1024_p),NULL),
- NULL, BN_bin2bn(dh1024_g,sizeof(dh1024_g),NULL));
- if (!r)
- { DH_free(dh); return(NULL); }
-#else
- dh->p=BN_bin2bn(dh1024_p,sizeof(dh1024_p),NULL);
- dh->g=BN_bin2bn(dh1024_g,sizeof(dh1024_g),NULL);
- if ((dh->p == NULL) || (dh->g == NULL))
- { DH_free(dh); return(NULL); }
-#endif
- return(dh);
- }
diff --git a/wocky/wocky-openssl-dh2048.c b/wocky/wocky-openssl-dh2048.c
deleted file mode 100644
index f51f5b8..0000000
--- a/wocky/wocky-openssl-dh2048.c
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#ifndef HEADER_DH_H
-#include <openssl/dh.h>
-#endif
-DH *get_dh2048(void);
-DH *get_dh2048(void)
- {
- static unsigned char dh2048_p[]={
- 0xF6,0x42,0x57,0xB7,0x08,0x7F,0x08,0x17,0x72,0xA2,0xBA,0xD6,
- 0xA9,0x42,0xF3,0x05,0xE8,0xF9,0x53,0x11,0x39,0x4F,0xB6,0xF1,
- 0x6E,0xB9,0x4B,0x38,0x20,0xDA,0x01,0xA7,0x56,0xA3,0x14,0xE9,
- 0x8F,0x40,0x55,0xF3,0xD0,0x07,0xC6,0xCB,0x43,0xA9,0x94,0xAD,
- 0xF7,0x4C,0x64,0x86,0x49,0xF8,0x0C,0x83,0xBD,0x65,0xE9,0x17,
- 0xD4,0xA1,0xD3,0x50,0xF8,0xF5,0x59,0x5F,0xDC,0x76,0x52,0x4F,
- 0x3D,0x3D,0x8D,0xDB,0xCE,0x99,0xE1,0x57,0x92,0x59,0xCD,0xFD,
- 0xB8,0xAE,0x74,0x4F,0xC5,0xFC,0x76,0xBC,0x83,0xC5,0x47,0x30,
- 0x61,0xCE,0x7C,0xC9,0x66,0xFF,0x15,0xF9,0xBB,0xFD,0x91,0x5E,
- 0xC7,0x01,0xAA,0xD3,0x5B,0x9E,0x8D,0xA0,0xA5,0x72,0x3A,0xD4,
- 0x1A,0xF0,0xBF,0x46,0x00,0x58,0x2B,0xE5,0xF4,0x88,0xFD,0x58,
- 0x4E,0x49,0xDB,0xCD,0x20,0xB4,0x9D,0xE4,0x91,0x07,0x36,0x6B,
- 0x33,0x6C,0x38,0x0D,0x45,0x1D,0x0F,0x7C,0x88,0xB3,0x1C,0x7C,
- 0x5B,0x2D,0x8E,0xF6,0xF3,0xC9,0x23,0xC0,0x43,0xF0,0xA5,0x5B,
- 0x18,0x8D,0x8E,0xBB,0x55,0x8C,0xB8,0x5D,0x38,0xD3,0x34,0xFD,
- 0x7C,0x17,0x57,0x43,0xA3,0x1D,0x18,0x6C,0xDE,0x33,0x21,0x2C,
- 0xB5,0x2A,0xFF,0x3C,0xE1,0xB1,0x29,0x40,0x18,0x11,0x8D,0x7C,
- 0x84,0xA7,0x0A,0x72,0xD6,0x86,0xC4,0x03,0x19,0xC8,0x07,0x29,
- 0x7A,0xCA,0x95,0x0C,0xD9,0x96,0x9F,0xAB,0xD0,0x0A,0x50,0x9B,
- 0x02,0x46,0xD3,0x08,0x3D,0x66,0xA4,0x5D,0x41,0x9F,0x9C,0x7C,
- 0xBD,0x89,0x4B,0x22,0x19,0x26,0xBA,0xAB,0xA2,0x5E,0xC3,0x55,
- 0xE9,0x32,0x0B,0x3B,
- };
- static unsigned char dh2048_g[]={
- 0x02,
- };
- DH *dh;
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
- int r = 0;
-#endif
-
- if ((dh=DH_new()) == NULL) return(NULL);
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
- r = DH_set0_pqg(dh, BN_bin2bn(dh2048_p,sizeof(dh2048_p),NULL),
- NULL, BN_bin2bn(dh2048_g,sizeof(dh2048_g),NULL));
- if (!r)
- { DH_free(dh); return(NULL); }
-#else
- dh->p=BN_bin2bn(dh2048_p,sizeof(dh2048_p),NULL);
- dh->g=BN_bin2bn(dh2048_g,sizeof(dh2048_g),NULL);
- if ((dh->p == NULL) || (dh->g == NULL))
- { DH_free(dh); return(NULL); }
-#endif
- return(dh);
- }
diff --git a/wocky/wocky-openssl-dh4096.c b/wocky/wocky-openssl-dh4096.c
deleted file mode 100644
index c72f903..0000000
--- a/wocky/wocky-openssl-dh4096.c
+++ /dev/null
@@ -1,77 +0,0 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#ifndef HEADER_DH_H
-#include <openssl/dh.h>
-#endif
-DH *get_dh4096(void);
-DH *get_dh4096(void)
- {
- static unsigned char dh4096_p[]={
- 0xFA,0x14,0x72,0x52,0xC1,0x4D,0xE1,0x5A,0x49,0xD4,0xEF,0x09,
- 0x2D,0xC0,0xA8,0xFD,0x55,0xAB,0xD7,0xD9,0x37,0x04,0x28,0x09,
- 0xE2,0xE9,0x3E,0x77,0xE2,0xA1,0x7A,0x18,0xDD,0x46,0xA3,0x43,
- 0x37,0x23,0x90,0x97,0xF3,0x0E,0xC9,0x03,0x50,0x7D,0x65,0xCF,
- 0x78,0x62,0xA6,0x3A,0x62,0x22,0x83,0xA1,0x2F,0xFE,0x79,0xBA,
- 0x35,0xFF,0x59,0xD8,0x1D,0x61,0xDD,0x1E,0x21,0x13,0x17,0xFE,
- 0xCD,0x38,0x87,0x9E,0xF5,0x4F,0x79,0x10,0x61,0x8D,0xD4,0x22,
- 0xF3,0x5A,0xED,0x5D,0xEA,0x21,0xE9,0x33,0x6B,0x48,0x12,0x0A,
- 0x20,0x77,0xD4,0x25,0x60,0x61,0xDE,0xF6,0xB4,0x4F,0x1C,0x63,
- 0x40,0x8B,0x3A,0x21,0x93,0x8B,0x79,0x53,0x51,0x2C,0xCA,0xB3,
- 0x7B,0x29,0x56,0xA8,0xC7,0xF8,0xF4,0x7B,0x08,0x5E,0xA6,0xDC,
- 0xA2,0x45,0x12,0x56,0xDD,0x41,0x92,0xF2,0xDD,0x5B,0x8F,0x23,
- 0xF0,0xF3,0xEF,0xE4,0x3B,0x0A,0x44,0xDD,0xED,0x96,0x84,0xF1,
- 0xA8,0x32,0x46,0xA3,0xDB,0x4A,0xBE,0x3D,0x45,0xBA,0x4E,0xF8,
- 0x03,0xE5,0xDD,0x6B,0x59,0x0D,0x84,0x1E,0xCA,0x16,0x5A,0x8C,
- 0xC8,0xDF,0x7C,0x54,0x44,0xC4,0x27,0xA7,0x3B,0x2A,0x97,0xCE,
- 0xA3,0x7D,0x26,0x9C,0xAD,0xF4,0xC2,0xAC,0x37,0x4B,0xC3,0xAD,
- 0x68,0x84,0x7F,0x99,0xA6,0x17,0xEF,0x6B,0x46,0x3A,0x7A,0x36,
- 0x7A,0x11,0x43,0x92,0xAD,0xE9,0x9C,0xFB,0x44,0x6C,0x3D,0x82,
- 0x49,0xCC,0x5C,0x6A,0x52,0x42,0xF8,0x42,0xFB,0x44,0xF9,0x39,
- 0x73,0xFB,0x60,0x79,0x3B,0xC2,0x9E,0x0B,0xDC,0xD4,0xA6,0x67,
- 0xF7,0x66,0x3F,0xFC,0x42,0x3B,0x1B,0xDB,0x4F,0x66,0xDC,0xA5,
- 0x8F,0x66,0xF9,0xEA,0xC1,0xED,0x31,0xFB,0x48,0xA1,0x82,0x7D,
- 0xF8,0xE0,0xCC,0xB1,0xC7,0x03,0xE4,0xF8,0xB3,0xFE,0xB7,0xA3,
- 0x13,0x73,0xA6,0x7B,0xC1,0x0E,0x39,0xC7,0x94,0x48,0x26,0x00,
- 0x85,0x79,0xFC,0x6F,0x7A,0xAF,0xC5,0x52,0x35,0x75,0xD7,0x75,
- 0xA4,0x40,0xFA,0x14,0x74,0x61,0x16,0xF2,0xEB,0x67,0x11,0x6F,
- 0x04,0x43,0x3D,0x11,0x14,0x4C,0xA7,0x94,0x2A,0x39,0xA1,0xC9,
- 0x90,0xCF,0x83,0xC6,0xFF,0x02,0x8F,0xA3,0x2A,0xAC,0x26,0xDF,
- 0x0B,0x8B,0xBE,0x64,0x4A,0xF1,0xA1,0xDC,0xEE,0xBA,0xC8,0x03,
- 0x82,0xF6,0x62,0x2C,0x5D,0xB6,0xBB,0x13,0x19,0x6E,0x86,0xC5,
- 0x5B,0x2B,0x5E,0x3A,0xF3,0xB3,0x28,0x6B,0x70,0x71,0x3A,0x8E,
- 0xFF,0x5C,0x15,0xE6,0x02,0xA4,0xCE,0xED,0x59,0x56,0xCC,0x15,
- 0x51,0x07,0x79,0x1A,0x0F,0x25,0x26,0x27,0x30,0xA9,0x15,0xB2,
- 0xC8,0xD4,0x5C,0xCC,0x30,0xE8,0x1B,0xD8,0xD5,0x0F,0x19,0xA8,
- 0x80,0xA4,0xC7,0x01,0xAA,0x8B,0xBA,0x53,0xBB,0x47,0xC2,0x1F,
- 0x6B,0x54,0xB0,0x17,0x60,0xED,0x79,0x21,0x95,0xB6,0x05,0x84,
- 0x37,0xC8,0x03,0xA4,0xDD,0xD1,0x06,0x69,0x8F,0x4C,0x39,0xE0,
- 0xC8,0x5D,0x83,0x1D,0xBE,0x6A,0x9A,0x99,0xF3,0x9F,0x0B,0x45,
- 0x29,0xD4,0xCB,0x29,0x66,0xEE,0x1E,0x7E,0x3D,0xD7,0x13,0x4E,
- 0xDB,0x90,0x90,0x58,0xCB,0x5E,0x9B,0xCD,0x2E,0x2B,0x0F,0xA9,
- 0x4E,0x78,0xAC,0x05,0x11,0x7F,0xE3,0x9E,0x27,0xD4,0x99,0xE1,
- 0xB9,0xBD,0x78,0xE1,0x84,0x41,0xA0,0xDF,
- };
- static unsigned char dh4096_g[]={
- 0x02,
- };
- DH *dh;
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
- int r = 0;
-#endif
-
- if ((dh=DH_new()) == NULL) return(NULL);
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
- r = DH_set0_pqg(dh, BN_bin2bn(dh4096_p,sizeof(dh4096_p),NULL),
- NULL, BN_bin2bn(dh4096_g,sizeof(dh4096_g),NULL));
- if (!r)
- { DH_free(dh); return(NULL); }
-#else
- dh->p=BN_bin2bn(dh4096_p,sizeof(dh4096_p),NULL);
- dh->g=BN_bin2bn(dh4096_g,sizeof(dh4096_g),NULL);
- if ((dh->p == NULL) || (dh->g == NULL))
- { DH_free(dh); return(NULL); }
-#endif
- return(dh);
- }
diff --git a/wocky/wocky-openssl-dh512.c b/wocky/wocky-openssl-dh512.c
deleted file mode 100644
index 885fdc4..0000000
--- a/wocky/wocky-openssl-dh512.c
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#ifndef HEADER_DH_H
-#include <openssl/dh.h>
-#endif
-DH *get_dh512(void);
-DH *get_dh512(void)
- {
- static unsigned char dh512_p[]={
- 0xF5,0x2A,0xFF,0x3C,0xE1,0xB1,0x29,0x40,0x18,0x11,0x8D,0x7C,
- 0x84,0xA7,0x0A,0x72,0xD6,0x86,0xC4,0x03,0x19,0xC8,0x07,0x29,
- 0x7A,0xCA,0x95,0x0C,0xD9,0x96,0x9F,0xAB,0xD0,0x0A,0x50,0x9B,
- 0x02,0x46,0xD3,0x08,0x3D,0x66,0xA4,0x5D,0x41,0x9F,0x9C,0x7C,
- 0xBD,0x89,0x4B,0x22,0x19,0x26,0xBA,0xAB,0xA2,0x5E,0xC3,0x55,
- 0xE9,0x2A,0x05,0x5F,
- };
- static unsigned char dh512_g[]={
- 0x02,
- };
- DH *dh;
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
- int r = 0;
-#endif
-
- if ((dh=DH_new()) == NULL) return(NULL);
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
- r = DH_set0_pqg(dh, BN_bin2bn(dh512_p,sizeof(dh512_p),NULL),
- NULL, BN_bin2bn(dh512_g,sizeof(dh512_g),NULL));
- if (!r)
- { DH_free(dh); return(NULL); }
-#else
- dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL);
- dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL);
- if ((dh->p == NULL) || (dh->g == NULL))
- { DH_free(dh); return(NULL); }
-#endif
- return(dh);
- }
diff --git a/wocky/wocky-openssl.c b/wocky/wocky-openssl.c
deleted file mode 100644
index 18f9981..0000000
--- a/wocky/wocky-openssl.c
+++ /dev/null
@@ -1,2127 +0,0 @@
-/*
- * Copyright © 2008 Christian Kellner, Samuel Cormier-Iijima
- * Copyright © 2008-2009 Codethink Limited
- * Copyright © 2009-2010 Collabora Limited
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2 of the licence or (at
- * your option) any later version.
- *
- * Authors: Vivek Dasmohapatra <vivek@collabora.co.uk>
- * Ryan Lortie <desrt@desrt.ca>
- * Christian Kellner <gicmo@gnome.org>
- * Samuel Cormier-Iijima <sciyoshi@gmail.com>
- *
- * Based on wocky-tls.c, which was in turn based on an unmerged gnio feature.
- * See wocky-tls.c for details.
- *
- * This file follows the original coding style from upstream, not collabora
- * house style. See wocky-tls.c for details.
- */
-
-/**
- * SECTION: wocky-tls
- * @title: Wocky OpenSSL TLS
- * @short_description: Establish TLS sessions
- *
- * The WOCKY_TLS_DEBUG_LEVEL environment variable can be used to print debug
- * output from OpenSSL. To enable it, set it to a value from 1 to 9.
- * Higher values will print more information.
- *
- * Increasing the value past certain thresholds will also trigger increased
- * debugging output from within wocky-openssl.c as well.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "wocky-tls.h"
-
-/* Apparently an implicit requirement of OpenSSL's headers... */
-#ifdef G_OS_WIN32
-#include <windows.h>
-#endif
-
-#include <openssl/ssl.h>
-
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
-#include <openssl/err.h>
-#include <openssl/engine.h>
-#include <openssl/x509v3.h>
-
-#define WOCKY_DEBUG_FLAG WOCKY_DEBUG_TLS
-#define DEBUG_HANDSHAKE_LEVEL 5
-#define DEBUG_ASYNC_DETAIL_LEVEL 6
-
-#include "wocky-debug-internal.h"
-#include "wocky-utils.h"
-
-#include <openssl/ssl.h>
-#include <openssl/x509_vfy.h>
-
-#include <ctype.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/types.h>
-
-/* SSL_CTX_set_cipher_list() allows to restrict/alter the list of supported
- * ciphers; see ciphers(1) for documentation on the format.
- * Usually the normal ciphers are ok, but on mobile phones we prefer RC4 as
- * it decreases the size of packets. The bandwidth difference is tiny, but
- * the difference in power consumption between small and very small packets
- * can be significant on 3G. */
-#ifdef ENABLE_PREFER_STREAM_CIPHERS
-
-#define CIPHER_LIST \
- "RC4-SHA:" \
- "RC4-MD5:" \
- "ECDHE-RSA-RC4-SHA:" \
- "ECDHE-ECDSA-RC4-SHA:" \
- "ECDH-RSA-RC4-SHA:" \
- "ECDH-ECDSA-RC4-SHA:" \
- "PSK-RC4-SHA:" \
- "ALL" /* fall-back to all the other algorithms */
-
-#endif
-
-enum
-{
- PROP_S_NONE,
- PROP_S_STREAM,
- PROP_S_SERVER,
- PROP_S_DHBITS,
- PROP_S_KEYFILE,
- PROP_S_CERTFILE,
-};
-
-enum
-{
- PROP_C_NONE,
- PROP_C_SESSION,
-};
-
-enum
-{
- PROP_O_NONE,
- PROP_O_SESSION
-};
-
-enum
-{
- PROP_I_NONE,
- PROP_I_SESSION
-};
-
-typedef enum
-{
- WOCKY_TLS_OP_HANDSHAKE,
- WOCKY_TLS_OP_READ,
- WOCKY_TLS_OP_WRITE
-} WockyTLSOperation;
-
-/* from openssl docs: not clear if this is exported as a constant by openssl */
-#define MAX_SSLV3_BLOCK_SIZE 0x4000
-
-typedef struct
-{
- gboolean active;
-
- gint io_priority;
- GCancellable *cancellable;
- GObject *source_object;
- GAsyncReadyCallback callback;
- gpointer user_data;
- gpointer source_tag;
- GError *error;
- gboolean sync_complete;
- gchar *buffer;
- gsize count;
- gchar rbuf[MAX_SSLV3_BLOCK_SIZE];
-} WockyTLSJob;
-
-typedef struct
-{
- WockyTLSJob job;
- gulong state;
- gboolean done;
-} WockyTLSHandshake;
-
-typedef GIOStreamClass WockyTLSConnectionClass;
-typedef GObjectClass WockyTLSSessionClass;
-typedef GInputStreamClass WockyTLSInputStreamClass;
-typedef GOutputStreamClass WockyTLSOutputStreamClass;
-
-struct _WockyTLSSession
-{
- GObject parent;
-
- GIOStream *stream;
- GCancellable *cancellable;
- GError *error;
- gboolean async;
-
- /* tls server support */
- gboolean server;
- guint dh_bits;
- gchar *key_file;
- gchar *cert_file;
-
- /* frontend jobs */
- struct
- {
- WockyTLSHandshake handshake;
- WockyTLSJob read;
- WockyTLSJob write;
- } job;
-
- /* openssl structures */
- BIO *rbio;
- BIO *wbio;
- SSL_METHOD *method;
- SSL_CTX *ctx;
- SSL *ssl;
-};
-
-typedef struct
-{
- GInputStream parent;
- WockyTLSSession *session;
-} WockyTLSInputStream;
-
-typedef struct
-{
- GOutputStream parent;
- WockyTLSSession *session;
-} WockyTLSOutputStream;
-
-struct _WockyTLSConnection
-{
- GIOStream parent;
-
- WockyTLSSession *session;
- WockyTLSInputStream *input;
- WockyTLSOutputStream *output;
-};
-
-DH * get_dh4096 (void);
-DH * get_dh2048 (void);
-DH * get_dh1024 (void);
-DH * get_dh512 (void);
-
-static guint tls_debug_level = 0;
-
-static GType wocky_tls_input_stream_get_type (void);
-static GType wocky_tls_output_stream_get_type (void);
-G_DEFINE_TYPE (WockyTLSConnection, wocky_tls_connection, G_TYPE_IO_STREAM);
-G_DEFINE_TYPE (WockyTLSSession, wocky_tls_session, G_TYPE_OBJECT);
-G_DEFINE_TYPE (WockyTLSInputStream, wocky_tls_input_stream, G_TYPE_INPUT_STREAM);
-G_DEFINE_TYPE (WockyTLSOutputStream, wocky_tls_output_stream, G_TYPE_OUTPUT_STREAM);
-#define WOCKY_TYPE_TLS_INPUT_STREAM (wocky_tls_input_stream_get_type ())
-#define WOCKY_TYPE_TLS_OUTPUT_STREAM (wocky_tls_output_stream_get_type ())
-#define WOCKY_TLS_INPUT_STREAM(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
- WOCKY_TYPE_TLS_INPUT_STREAM, \
- WockyTLSInputStream))
-#define WOCKY_TLS_OUTPUT_STREAM(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
- WOCKY_TYPE_TLS_OUTPUT_STREAM, \
- WockyTLSOutputStream))
-
-/* Ok: This function tries to retrieve the error that caused a problem from *
- * bottom of the openssl error stack: The errnum argument is the error code *
- * returned by the last openssl operation which MAY NOT have come from the *
- * openssl error stack (cf SSL_get_error) and which MAY be SSL_ERROR_NONE: *
- * it's not supposed to be SSL_ERROR_NONE if a problem occurred, but this is *
- * not actually guaranteed anywhere so we have to check for it here: */
-static const gchar *error_to_string (long error)
-{
- static gchar ssl_error[256];
- int e;
- int x;
- /* SSL_ERROR_NONE from ERR_get_error means we have emptied the stack, *
- * in which case we should back up and use the last error we saw: */
- for (e = x = error; x != SSL_ERROR_NONE; x = ERR_get_error ())
- e = x;
-
- /* we found an error in the stack, or were passed one in errnum: */
- if (e != SSL_ERROR_NONE)
- {
- ERR_error_string_n ((gulong) e, ssl_error, sizeof (ssl_error));
- return ssl_error;
- }
-
- /* No useful/informative/relevant error found */
- return NULL;
-}
-
-static GSimpleAsyncResult *
-wocky_tls_job_make_result (WockyTLSJob *job,
- gssize result)
-{
- GSimpleAsyncResult *simple;
-
- simple = g_simple_async_result_new (job->source_object,
- job->callback,
- job->user_data,
- job->source_tag);
- if (job->error != NULL)
- {
- DEBUG ("setting error from job '%s'", job->error->message);
- g_simple_async_result_set_from_error (simple, job->error);
- g_error_free (job->error);
- job->error = NULL;
- }
-
- if (job->source_object != NULL)
- g_object_unref (job->source_object);
-
- job->source_object = NULL;
-
- if (job->cancellable != NULL)
- g_object_unref (job->cancellable);
-
- job->cancellable = NULL;
-
- job->active = FALSE;
-
- return simple;
-}
-
-static void
-wocky_tls_job_result_gssize (WockyTLSJob *job,
- gssize result)
-{
- GSimpleAsyncResult *simple;
-
- if ((simple = wocky_tls_job_make_result (job, result)))
- {
- if (result >= 0)
- g_simple_async_result_set_op_res_gssize (simple, result);
-
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
- }
-}
-
-/* only used for handshake results: read + write use result_gssize */
-static void
-wocky_tls_job_result_boolean (WockyTLSJob *job,
- gint result)
-{
- GSimpleAsyncResult *simple;
-
- if ((simple = wocky_tls_job_make_result (job, result)))
- {
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
- }
-}
-
-/* ************************************************************************* */
-static void
-wocky_tls_session_try_operation (WockyTLSSession *session,
- WockyTLSOperation operation);
-
-static void
-wocky_tls_session_write_ready (GObject *object,
- GAsyncResult *result,
- gpointer user_data);
-static void
-wocky_tls_session_read_ready (GObject *object,
- GAsyncResult *result,
- gpointer user_data);
-
-/* writes to the internal BIO should always succeed, so we should never
- * receive SSL_ERROR_WANT_WRITE: reads, on the other hand, obviously
- * depend on how much data we have buffered, so SSL_ERROR_WANT_READ can
- * clearly happen */
-static void
-handshake_write (WockyTLSSession *session)
-{
- gchar *wbuf;
- WockyTLSJob *handshake = &(session->job.handshake.job);
- GCancellable *cancel = handshake->cancellable;
- gint prio = handshake->io_priority;
- GOutputStream *output = g_io_stream_get_output_stream (session->stream);
- long wsize = BIO_get_mem_data (session->wbio, &wbuf);
-
- if (tls_debug_level >= DEBUG_ASYNC_DETAIL_LEVEL)
- DEBUG ("");
-
- g_output_stream_write_async (output, wbuf, wsize, prio, cancel,
- wocky_tls_session_write_ready, session);
-}
-
-static void
-handshake_read (WockyTLSSession *session)
-{
- GInputStream *input = g_io_stream_get_input_stream (session->stream);
- WockyTLSJob *handshake = (WockyTLSJob *) &session->job.handshake.job;
-
- if (tls_debug_level >= DEBUG_ASYNC_DETAIL_LEVEL)
- DEBUG ("");
-
- g_input_stream_read_async (input,
- &(handshake->rbuf),
- MAX_SSLV3_BLOCK_SIZE,
- handshake->io_priority,
- handshake->cancellable,
- wocky_tls_session_read_ready,
- session);
-}
-
-static int
-ssl_handshake (WockyTLSSession *session)
-{
- gint result = 1;
- gulong errnum = SSL_ERROR_NONE;
- gboolean want_read = FALSE;
- gboolean want_write = FALSE;
- const gchar *errstr = NULL;
- gboolean done = session->job.handshake.done;
- gboolean fatal = FALSE;
-
- if (tls_debug_level >= DEBUG_ASYNC_DETAIL_LEVEL)
- DEBUG ("");
-
- if (!done)
- {
- const gchar *method;
-
- if (session->server)
- {
- method = "SSL_accept";
- result = SSL_accept (session->ssl);
- }
- else
- {
- method = "SSL_connect";
- result = SSL_connect (session->ssl);
- }
- errnum = SSL_get_error (session->ssl, result);
- done = (result == 1);
- errstr = error_to_string (errnum);
- fatal = (errnum != SSL_ERROR_WANT_READ &&
- errnum != SSL_ERROR_WANT_WRITE &&
- errnum != SSL_ERROR_NONE);
- DEBUG ("%s - result: %d; error: %ld", method, result, errnum);
- DEBUG ("%s : %s", method, errstr);
- }
-
- /* buffered write data means we need to write */
- want_write = BIO_pending (session->wbio) > 0;
-
- /* check to see if there's data waiting to go out: *
- * since writes to a BIO should always succeed, it is possible to *
- * have buffered write data after a successful return, but not *
- * possible to be waiting on a read, since SSL_connect should not *
- * return success if waiting for data to come in */
- if (done)
- {
- session->job.handshake.done = TRUE;
-
- if (!want_write)
- {
- DEBUG ("Handshake completed");
- errnum = session->job.handshake.state = SSL_ERROR_NONE;
- }
- else
- {
- DEBUG ("Handshake completed (IO incomplete)");
- g_assert (errnum != SSL_ERROR_WANT_READ);
- errnum = SSL_ERROR_WANT_WRITE;
- }
- }
- else
- {
- DEBUG ("Handshake state: %ld", errnum);
- session->job.handshake.state = errnum;
- want_read = (errnum == SSL_ERROR_WANT_READ);
- }
- /* sif we want both a write (buffered data in the BIO) AND a read *
- * (SSL_ERROR_WANT_READ) then this will happen when the handshake_write *
- * invokes wocky_tls_session_write_ready which will in turn call *
- * wocky_tls_session_try_operation which will re-enter handshake *
- * and then proceed to fall back through to this block of code */
-
- if (!fatal)
- {
- DEBUG ("want write: %d; want read: %d;", want_write, want_read);
- if (want_write)
- handshake_write (session);
- else if (want_read)
- handshake_read (session);
- else
- wocky_tls_session_try_operation (session, WOCKY_TLS_OP_HANDSHAKE);
- }
- else
- {
- DEBUG ("Handshake failed: [%d:%ld] %s", result, errnum, errstr);
- if (session->job.handshake.job.error != NULL)
- {
- g_error_free (session->job.handshake.job.error);
- session->job.handshake.job.error = NULL;
- }
- g_set_error (&(session->job.handshake.job.error), WOCKY_TLS_ERROR, result,
- "Handshake failed: %s", errstr);
- wocky_tls_session_try_operation (session, WOCKY_TLS_OP_HANDSHAKE);
- }
-
- return errnum;
-}
-
-static void
-ssl_fill (WockyTLSSession *session)
-{
- GInputStream *input = g_io_stream_get_input_stream (session->stream);
- gchar *rbuf = session->job.read.rbuf;
- gint prio = session->job.read.io_priority;
- GCancellable *cancel = session->job.read.cancellable;
-
- if (tls_debug_level >= DEBUG_ASYNC_DETAIL_LEVEL)
- DEBUG ("");
-
- g_input_stream_read_async (input, rbuf, MAX_SSLV3_BLOCK_SIZE, prio, cancel,
- wocky_tls_session_read_ready, session);
-}
-
-static void
-ssl_flush (WockyTLSSession *session)
-{
- long wsize;
- gchar *wbuf;
- gint prio = session->job.read.io_priority;
- GOutputStream *output = g_io_stream_get_output_stream (session->stream);
- GCancellable *cancel = session->job.read.cancellable;
-
- if (tls_debug_level >= DEBUG_ASYNC_DETAIL_LEVEL)
- DEBUG ("");
-
- wsize = BIO_get_mem_data (session->wbio, &wbuf);
-
- if (wsize > 0)
- g_output_stream_write_async (output, wbuf, wsize, prio, cancel,
- wocky_tls_session_write_ready, session);
-}
-
-/* FALSE indicates we should go round again and try to get more data */
-static gboolean
-ssl_read_is_complete (WockyTLSSession *session, gint result)
-{
- /* if the job error is set, we should bail out now, we have failed *
- * otherwise: *
- * a -ve return with an SSL error of WANT_READ implies an incomplete *
- * crypto record: we need to go round again and get more data *
- * or: *
- * a 0 return means the SSL connection was shut down cleanly */
- if ((session->job.read.error == NULL) && (result <= 0))
- {
- int err = SSL_get_error (session->ssl, result);
-
- switch (err)
- {
- case SSL_ERROR_WANT_READ:
- DEBUG ("Incomplete SSL record, read again");
- return FALSE;
- case SSL_ERROR_WANT_WRITE:
- g_warning ("read caused write: unsupported TLS re-negotiation?");
- /* deliberately falling through to the default case, having logged a
- * more specific warning.
- */
- default:
- g_set_error (&session->job.read.error, WOCKY_TLS_ERROR, err,
- "OpenSSL read: protocol error %d", err);
- }
- }
-
- return TRUE;
-}
-
-static void
-wocky_tls_session_try_operation (WockyTLSSession *session,
- WockyTLSOperation operation)
-{
- WockyTLSJob *handshake = &(session->job.handshake.job);
-
- if (handshake->active || operation == WOCKY_TLS_OP_HANDSHAKE)
- {
- gint result = session->job.handshake.state;
- DEBUG ("async job handshake");
-
- if (tls_debug_level >= DEBUG_HANDSHAKE_LEVEL)
- DEBUG ("async job handshake: %d", result);
-
- switch (result)
- {
- case SSL_ERROR_WANT_READ:
- case SSL_ERROR_WANT_WRITE:
- DEBUG ("Handshake incomplete...");
- ssl_handshake (session);
- break;
- case SSL_ERROR_NONE:
- DEBUG ("Handshake complete (success): %d", result);
- wocky_tls_job_result_boolean (handshake, result);
- break;
- default:
- DEBUG ("Handshake complete (failure): %d", result);
- if (handshake->error == NULL)
- handshake->error =
- g_error_new (WOCKY_TLS_ERROR, result, "Handshake Error");
- wocky_tls_job_result_boolean (handshake, result);
- }
- }
- else if (operation == WOCKY_TLS_OP_READ)
- {
- gssize result = 0;
- gulong pending = 0;
- gsize wanted = 0;
-
- if (tls_debug_level >= DEBUG_ASYNC_DETAIL_LEVEL)
- DEBUG ("async job OP_READ");
-
- /* cipherbytes in the BIO != clearbytes after SSL_read */
- wanted = session->job.read.count;
- pending = (gulong)BIO_pending (session->rbio);
- result = SSL_read (session->ssl, session->job.read.buffer, wanted);
- DEBUG ("read %" G_GSSIZE_FORMAT " clearbytes (from %ld cipherbytes)",
- result, pending);
-
- if (ssl_read_is_complete (session, result))
- wocky_tls_job_result_gssize (&session->job.read, result);
- else
- ssl_fill (session);
- }
-
- else
- { /* we have no useful way of mapping SSL cipherbytes to raw *
- * clearbytes: it should always be a complete write unless *
- * there's been a network error, in which case the utility *
- * of a byte count is debatable anyway */
- gssize result = session->job.write.count;
-
- if (tls_debug_level >= DEBUG_ASYNC_DETAIL_LEVEL)
- DEBUG ("async job OP_WRITE");
-
- g_assert (operation == WOCKY_TLS_OP_WRITE);
- DEBUG ("wrote %" G_GSSIZE_FORMAT " clearbytes", result);
- wocky_tls_job_result_gssize (&session->job.write, result);
- }
-}
-
-static void
-wocky_tls_job_start (WockyTLSJob *job,
- gpointer source_object,
- gint io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data,
- gpointer source_tag)
-{
- g_assert (job->active == FALSE);
- g_assert (job->cancellable == NULL);
-
- /* this is always a circular reference, so it will keep the
- * session alive for as long as the job is running.
- */
- job->source_object = g_object_ref (source_object);
-
- job->io_priority = io_priority;
- if (cancellable != NULL)
- job->cancellable = g_object_ref (cancellable);
- job->callback = callback;
- job->user_data = user_data;
- job->source_tag = source_tag;
- job->error = NULL;
- job->active = TRUE;
-}
-
-typedef gint (*ssl_handler) (SSL *ssl);
-
-WockyTLSConnection *
-wocky_tls_session_handshake (WockyTLSSession *session,
- GCancellable *cancellable,
- GError **error)
-{
- gint result = -1;
- gboolean go = TRUE;
- gboolean done = FALSE;
- ssl_handler handler = session->server ? SSL_accept : SSL_connect;
- gboolean want_write = FALSE;
- gboolean want_read = FALSE;
- gint errnum = SSL_ERROR_NONE;
- const gchar *errstr = NULL;
-
- while (go)
- {
- DEBUG ("sync SSL handshake loop");
-
- if (!done)
- {
- result = handler (session->ssl);
- errnum = SSL_get_error (session->ssl, result);
- done = (result == 1);
- DEBUG ("SSL_%s: %d:%d",
- (handler == SSL_accept) ? "accept" : "connect",
- result, errnum);
- if (errnum != SSL_ERROR_NONE &&
- errnum != SSL_ERROR_WANT_READ &&
- errnum != SSL_ERROR_WANT_WRITE)
- {
- errstr = error_to_string (errnum);
- DEBUG ("SSL handshake error: [%d:%d] %s", result, errnum, errstr);
- }
- }
-
- want_write = BIO_pending (session->wbio) > 0;
- want_read = (errnum == SSL_ERROR_WANT_READ);
-
- if (want_write)
- {
- gchar *wbuf;
- GOutputStream *out = g_io_stream_get_output_stream (session->stream);
- long wsize = BIO_get_mem_data (session->wbio, &wbuf);
- gssize sent = 0;
- DEBUG ("sending %ld cipherbytes", wsize);
- if (wsize > 0)
- sent = g_output_stream_write (out, wbuf, wsize, NULL, error);
- DEBUG ("sent %" G_GSSIZE_FORMAT " cipherbytes", sent);
- (void) BIO_reset (session->wbio);
- }
-
- if (want_read)
- {
- char rbuf[MAX_SSLV3_BLOCK_SIZE];
- GInputStream *in = g_io_stream_get_input_stream (session->stream);
- gssize bytes =
- g_input_stream_read (in, &rbuf, sizeof(rbuf), NULL, error);
- DEBUG ("read %" G_GSSIZE_FORMAT " cipherbytes", bytes);
- BIO_write (session->rbio, &rbuf, bytes);
- }
-
- switch (errnum)
- {
- case SSL_ERROR_WANT_WRITE:
- /* WANT_WRITE is theoretically impossible, but what the hell */
- case SSL_ERROR_WANT_READ:
- break;
- case SSL_ERROR_NONE:
- DEBUG ("handshake complete, all IO done");
- go = FALSE;
- break;
- default:
- DEBUG ("SSL handshake error: [%d:%d] %s", result, errnum, errstr);
- *error =
- g_error_new (WOCKY_TLS_ERROR, errnum, "Handshake: %s", errstr);
- go = FALSE;
- }
- }
-
- if (done)
- return g_object_new (WOCKY_TYPE_TLS_CONNECTION, "session", session, NULL);
-
- return NULL;
-}
-
-/* ************************************************************************* */
-/* adding CA certificates & CRL lists for peer certificate verification */
-
-void
-wocky_tls_session_add_ca (WockyTLSSession *session,
- const gchar *path)
-{
- gboolean ok = FALSE;
-
- if (!g_file_test (path, G_FILE_TEST_EXISTS))
- {
- DEBUG ("CA file or path '%s' not accessible", path);
- return;
- }
-
- if (g_file_test (path, G_FILE_TEST_IS_DIR))
- {
- DEBUG ("Loading CA directory");
- ok = SSL_CTX_load_verify_locations (session->ctx, NULL, path);
- }
-
- if (g_file_test (path, G_FILE_TEST_IS_REGULAR))
- {
- DEBUG ("Loading CA file");
- ok = SSL_CTX_load_verify_locations (session->ctx, path, NULL);
- }
-
- if (!ok)
- {
- gulong e, f;
- for (f = e = ERR_get_error (); e != 0; e = ERR_get_error ())
- f = e;
- DEBUG ("CA '%s' failed: %s", path, ERR_error_string (f, NULL));
- }
- else
- DEBUG ("CA '%s' loaded", path);
-}
-
-void
-wocky_tls_session_add_crl (WockyTLSSession *session,
- const gchar *path)
-{
- gboolean ok = FALSE;
-
- if (!g_file_test (path, G_FILE_TEST_EXISTS))
- {
- DEBUG ("CRL file or path '%s' not accessible", path);
- return;
- }
-
- if (g_file_test (path, G_FILE_TEST_IS_DIR))
- {
- X509_STORE *store = SSL_CTX_get_cert_store (session->ctx);
- X509_LOOKUP_METHOD *method = X509_LOOKUP_hash_dir ();
- X509_LOOKUP *lookup = X509_STORE_add_lookup (store, method);
- DEBUG ("Loading CRL directory");
- ok = X509_LOOKUP_add_dir (lookup, path, X509_FILETYPE_PEM) == 1;
- }
-
- if (g_file_test (path, G_FILE_TEST_IS_REGULAR))
- {
- X509_STORE *store = SSL_CTX_get_cert_store (session->ctx);
- X509_LOOKUP_METHOD *method = X509_LOOKUP_file ();
- X509_LOOKUP *lookup = X509_STORE_add_lookup (store, method);
- DEBUG ("Loading CRL file");
- ok = X509_LOOKUP_load_file (lookup, path, X509_FILETYPE_PEM) == 1;
- }
-
- if (!ok)
- {
- gulong e, f;
- for (f = e = ERR_get_error (); e != 0; e = ERR_get_error ())
- f = e;
- DEBUG ("'%s' failed: %s\n", path, ERR_error_string (f, NULL));
- }
- else
- DEBUG ("'%s' loaded\n", path);
-}
-
-/* ************************************************************************* */
-
-void
-wocky_tls_session_handshake_async (WockyTLSSession *session,
- gint io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- DEBUG ("");
- wocky_tls_job_start (&session->job.handshake.job, session,
- io_priority, cancellable, callback, user_data,
- wocky_tls_session_handshake_async);
- ssl_handshake (session);
-}
-
-WockyTLSConnection *
-wocky_tls_session_handshake_finish (WockyTLSSession *session,
- GAsyncResult *result,
- GError **error)
-{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
- DEBUG ("");
- {
- GObject *source_object;
-
- source_object = g_async_result_get_source_object (result);
- g_object_unref (source_object);
- g_return_val_if_fail (G_OBJECT (session) == source_object, NULL);
- }
-
- g_return_val_if_fail (wocky_tls_session_handshake_async ==
- g_simple_async_result_get_source_tag (simple), NULL);
-
- if (g_simple_async_result_propagate_error (simple, error))
- return NULL;
-
- DEBUG ("connection OK");
- return g_object_new (WOCKY_TYPE_TLS_CONNECTION, "session", session, NULL);
-}
-
-static gboolean
-compare_wildcarded_hostname (const char *hostname, const char *certname)
-{
- DEBUG ("%s ~ %s", hostname, certname);
-
- if (g_ascii_strcasecmp (hostname, certname) == 0)
- return TRUE;
-
- /* We only allow leading '*.' wildcards. See the final bullet point of XMPP
- * Core §13.7.1.2.1
- * <http://xmpp.org/rfcs/rfc6120.html#security-certificates-generation-server>:
- *
- * DNS domain names in server certificates MAY contain the wildcard
- * character '*' as the complete left-most label within the identifier.
- */
- if (g_str_has_prefix (certname, "*."))
- {
- const gchar *certname_tail = certname + 2;
- const gchar *hostname_tail = index (hostname, '.');
-
- if (hostname_tail == NULL)
- return FALSE;
-
- hostname_tail++;
- DEBUG ("%s ~ %s", hostname_tail, certname_tail);
- return g_ascii_strcasecmp (hostname_tail, certname_tail) == 0;
- }
-
- return FALSE;
-}
-
-static gboolean
-check_peer_name (const char *target, X509 *cert)
-{
- int i;
- gboolean rval = FALSE;
- X509_NAME *subject = X509_get_subject_name (cert);
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
- const STACK_OF(X509_EXTENSION)* extensions = X509_get0_extensions(cert);
-#else
- const STACK_OF(X509_EXTENSION)* extensions = cert->cert_info->extensions;
-#endif
- static const long nid[] = { NID_commonName, NID_subject_alt_name, NID_undef };
-
- /* first, see if the x509 name contains the info we want: */
- for (i = 0; nid[i] != NID_undef; i++)
- {
- gssize len = X509_NAME_get_text_by_NID (subject, nid[i], NULL, -1);
- if (len > 0)
- {
- char *cname = g_new0 (gchar, len + 1);
- X509_NAME_get_text_by_NID (subject, nid[i], cname, len + 1);
- DEBUG ("got cname '%s' from x509 name, nid #%u", cname, i);
- rval = compare_wildcarded_hostname (target, cname);
- g_free (cname);
- }
- }
-
- /* ok, if that failed, we need to dive into the guts of the x509 structure *
- * and extract the subject_alt_name from the x509 v3 extensions: if that *
- * extension is present, and a string, use that. If it is present, and *
- * a multi-value stack, trawl it for the "DNS" entry and use that */
- if (!rval && (extensions != NULL))
- for (i = 0; i < sk_X509_EXTENSION_num(extensions) && !rval; i++)
- {
- X509_EXTENSION *ext = sk_X509_EXTENSION_value (extensions, i);
- ASN1_OBJECT *obj = X509_EXTENSION_get_object (ext);
- X509V3_EXT_METHOD *convert = NULL;
- long ni = OBJ_obj2nid (obj);
- const guchar *p;
- char *value = NULL;
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
- const ASN1_OCTET_STRING* ext_value = X509_EXTENSION_get_data(ext);
- int len = ASN1_STRING_length(ext_value);
-#else
- int len = ext->value->length;
-#endif
- void *ext_str = NULL;
-
- if (ni != NID_subject_alt_name)
- continue;
-
- /* OpenSSL >= 1.0 returns a const here, but we need to be also *
- * compatible with older versions that return a non-const value, *
- * hence the cast */
- if ((convert = (X509V3_EXT_METHOD *) X509V3_EXT_get (ext)) == NULL)
- continue;
-
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
- p = ASN1_STRING_get0_data(ext_value);
-#else
- p = ext->value->data;
-#endif
- ext_str = ((convert->it != NULL) ?
- ASN1_item_d2i (NULL, &p, len, ASN1_ITEM_ptr(convert->it)) :
- convert->d2i (NULL, &p, len) );
-
- if (ext_str == NULL)
- continue;
-
- if (convert->i2s != NULL)
- {
- value = convert->i2s (convert, ext_str);
- DEBUG ("got cname '%s' from subject_alt_name, which is a string",
- value);
- rval = compare_wildcarded_hostname (target, value);
- OPENSSL_free (value);
- }
- else if (convert->i2v != NULL)
- {
- int j;
- STACK_OF(CONF_VALUE) *nval = convert->i2v(convert, ext_str, NULL);
- for (j = 0; j < sk_CONF_VALUE_num (nval); j++)
- {
- CONF_VALUE *v = sk_CONF_VALUE_value(nval, j);
- if (!wocky_strdiff (v->name, "DNS"))
- {
- DEBUG ("Got cname '%s' from subject_alt_name, which is a "
- "multi-value stack with a 'DNS' entry", v->value);
- rval = compare_wildcarded_hostname (target, v->value);
- }
- }
- sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
- }
-
- if (convert->it)
- ASN1_item_free (ext_str, ASN1_ITEM_ptr (convert->it));
- else
- convert->ext_free (ext_str);
- }
-
- return rval;
-}
-
-static gboolean
-check_peer_names (const char *peer_name,
- GStrv extra_identities,
- X509 *cert)
-{
- gboolean tried = FALSE;
-
- if (peer_name != NULL)
- {
- if (check_peer_name (peer_name, cert))
- return TRUE;
-
- tried = TRUE;
- }
-
- if (extra_identities != NULL)
- {
- gint i;
-
- for (i = 0; extra_identities[i] != NULL; i++)
- {
- if (wocky_strdiff (extra_identities[i], peer_name))
- {
- if (check_peer_name (extra_identities[i], cert))
- return TRUE;
-
- tried = TRUE;
- }
- }
- }
-
- /* If no peer names were passed it means we didn't want to check the
- * certificate against anything.
- * If some attempts were made then it means the check failed. */
- return !tried;
-}
-
-GPtrArray *
-wocky_tls_session_get_peers_certificate (WockyTLSSession *session,
- WockyTLSCertType *type)
-{
- STACK_OF(X509) *cert_chain = NULL;
- guint cls = 0;
- GPtrArray *certificates;
- guint i;
-
- certificates =
- g_ptr_array_new_with_free_func ((GDestroyNotify) g_array_unref);
-
- cert_chain = SSL_get_peer_cert_chain (session->ssl);
-
- if (cert_chain == NULL)
- return NULL;
-
- if (type != NULL)
- *type = WOCKY_TLS_CERT_TYPE_X509;
-
- cls = sk_X509_num (cert_chain);
-
- for (i = 0; i < cls; i++)
- {
- GArray *certificate;
- X509 *peer;
- gint peer_len;
- guchar *peer_buffer;
-
- peer = sk_X509_value (cert_chain, i);
- peer_len = i2d_X509 (peer, NULL);
-
- certificate = g_array_sized_new (TRUE, TRUE, sizeof (guchar), peer_len);
-
- peer_buffer = g_malloc (peer_len);
- i2d_X509 (peer, &peer_buffer);
- peer_buffer -= peer_len;
-
- g_array_append_vals (certificate, peer_buffer, peer_len);
- g_ptr_array_add (certificates, certificate);
-
- g_free (peer_buffer);
- }
-
- return certificates;
-}
-
-static WockyTLSCertStatus
-_cert_status (WockyTLSSession *session,
- int ssl_code,
- WockyTLSVerificationLevel level,
- int old_code)
-{
- switch (ssl_code)
- {
- case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
- case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
- case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
- case X509_V_ERR_SUBJECT_ISSUER_MISMATCH:
- return WOCKY_TLS_CERT_SIGNER_UNKNOWN;
- break;
- case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
- case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
- case X509_V_ERR_CERT_SIGNATURE_FAILURE:
- case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
- case X509_V_ERR_INVALID_PURPOSE:
- case X509_V_ERR_CERT_REJECTED:
- case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
- return WOCKY_TLS_CERT_INVALID;
- break;
- case X509_V_ERR_CERT_REVOKED:
- return WOCKY_TLS_CERT_REVOKED;
- break;
- case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
- case X509_V_ERR_CERT_NOT_YET_VALID:
- return WOCKY_TLS_CERT_NOT_ACTIVE;
- break;
- case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
- case X509_V_ERR_CERT_HAS_EXPIRED:
- return WOCKY_TLS_CERT_EXPIRED;
- break;
- case X509_V_ERR_OUT_OF_MEM:
- return WOCKY_TLS_CERT_INTERNAL_ERROR;
- break;
- case X509_V_ERR_INVALID_CA:
- case X509_V_ERR_CERT_UNTRUSTED:
- case X509_V_ERR_AKID_SKID_MISMATCH:
- case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH:
- case X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
- return WOCKY_TLS_CERT_SIGNER_UNAUTHORISED;
- break;
- case X509_V_ERR_PATH_LENGTH_EXCEEDED:
- return WOCKY_TLS_CERT_MAYBE_DOS;
- break;
- case X509_V_ERR_UNABLE_TO_GET_CRL:
- /* if we are in STRICT mode, being unable to see the CRL is a
- * terminal condition: in NORMAL or LENIENT we can live with it.
- * Also, if we re-tried and got the same error, we're just going
- * to loop indefinitely, so bail out with the original error.
- * NOTE: 'unable to fetch' a CRL is not the same as CRL invalidated
- * the certificate, or we'd just turn the CRL checks off when in
- * NORMAL or LENIENT mode */
- if (level == WOCKY_TLS_VERIFY_STRICT ||
- old_code == X509_V_ERR_UNABLE_TO_GET_CRL)
- {
- return WOCKY_TLS_CERT_INSECURE;
- }
- else
- {
- WockyTLSCertStatus status = WOCKY_TLS_CERT_OK;
- X509_STORE_CTX *xctx = X509_STORE_CTX_new();
- X509_STORE *store = SSL_CTX_get_cert_store(session->ctx);
- X509 *cert = SSL_get_peer_certificate (session->ssl);
- STACK_OF(X509) *chain = SSL_get_peer_cert_chain (session->ssl);
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
- X509_VERIFY_PARAM* param = X509_STORE_get0_param(store);
- long old_flags = X509_VERIFY_PARAM_get_flags(param);
-#else
- long old_flags = store->param->flags;
-#endif
- long new_flags = old_flags;
- DEBUG("No CRL available, but not in strict mode - re-verifying");
-
- new_flags &= ~(X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
-
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
- X509_VERIFY_PARAM_set_flags(param, new_flags);
-#else
- store->param->flags = new_flags;
-#endif
- X509_STORE_CTX_init (xctx, store, cert, chain);
- X509_STORE_CTX_set_flags (xctx, new_flags);
-
- if( X509_verify_cert (xctx) < 1 )
- {
- int new_code = X509_STORE_CTX_get_error (xctx);
- status = _cert_status (session, new_code, level, ssl_code);
- }
-
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
- X509_VERIFY_PARAM_set_flags(param, old_flags);
-#else
- store->param->flags = old_flags;
-#endif
- X509_STORE_CTX_free (xctx);
- X509_free (cert);
-
- return status;
- }
- break;
- default:
- return WOCKY_TLS_CERT_UNKNOWN_ERROR;
- }
-}
-
-int
-wocky_tls_session_verify_peer (WockyTLSSession *session,
- const gchar *peername,
- GStrv extra_identities,
- WockyTLSVerificationLevel level,
- WockyTLSCertStatus *status)
-{
- int rval = -1;
- X509 *cert;
- gboolean lenient = (level == WOCKY_TLS_VERIFY_LENIENT);
-
- DEBUG ("");
- g_assert (status != NULL);
- *status = WOCKY_TLS_CERT_OK;
-
- switch (level)
- {
- case WOCKY_TLS_VERIFY_STRICT:
- case WOCKY_TLS_VERIFY_NORMAL:
- case WOCKY_TLS_VERIFY_LENIENT:
- break;
- default:
- g_warn_if_reached ();
- level = WOCKY_TLS_VERIFY_STRICT;
- }
-
- DEBUG ("setting ssl verify flags level to: %s",
- wocky_enum_to_nick (WOCKY_TYPE_TLS_VERIFICATION_LEVEL, level));
- cert = SSL_get_peer_certificate (session->ssl);
- rval = SSL_get_verify_result (session->ssl);
- DEBUG ("X509 cert: %p; verified: %d", cert, rval);
-
- /* If no certificate is presented, SSL_get_verify_result() always returns
- * X509_V_OK. This is listed as a bug in `man 3 SSL_get_verify_result`. To
- * future-proof against that bug being fixed, we don't assume that behaviour.
- */
- if (cert == NULL)
- {
- if (lenient)
- {
- *status = WOCKY_TLS_CERT_OK;
- return X509_V_OK;
- }
- else if (rval == X509_V_OK)
- {
- DEBUG ("Anonymous SSL handshake");
- rval = X509_V_ERR_CERT_UNTRUSTED;
- }
- }
- else if (!check_peer_names (peername, extra_identities, cert))
- {
- /* Irrespective of whether the certificate is valid, if it's for the
- * wrong host that's arguably a more useful error condition to report.
- */
- *status = WOCKY_TLS_CERT_NAME_MISMATCH;
- return X509_V_ERR_APPLICATION_VERIFICATION;
- }
-
- if (rval != X509_V_OK)
- {
- DEBUG ("cert verification error: %d", rval);
- *status = _cert_status (session, rval, level, X509_V_OK);
-
- /* some conditions are to be ignored when lenient, others still matter */
- if (lenient)
- switch (*status)
- {
- case WOCKY_TLS_CERT_INTERNAL_ERROR:
- case WOCKY_TLS_CERT_REVOKED:
- case WOCKY_TLS_CERT_MAYBE_DOS:
- DEBUG ("this error matters, even though we're in lenient mode");
- break;
- default:
- DEBUG ("ignoring errors: we're in lenient mode");
- rval = X509_V_OK;
- *status = WOCKY_TLS_CERT_OK;
- }
- }
-
- return rval;
-}
-
-static gssize
-wocky_tls_input_stream_read (GInputStream *stream,
- void *buffer,
- gsize count,
- GCancellable *cancellable,
- GError **error)
-{
- /* WockyTLSSession *session = WOCKY_TLS_INPUT_STREAM (stream)->session; */
-
- DEBUG ("sync read - not implmented");
- g_assert_not_reached ();
-
- return 0;
-}
-
-static void
-wocky_tls_input_stream_read_async (GInputStream *stream,
- void *buffer,
- gsize count,
- gint io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- WockyTLSSession *session = WOCKY_TLS_INPUT_STREAM (stream)->session;
- int ret;
-
- if (tls_debug_level >= DEBUG_ASYNC_DETAIL_LEVEL)
- DEBUG ("");
-
- g_assert (session->job.read.active == FALSE);
-
- /* It is possible for a complete SSL record to be present in the read BIO *
- * already as a result of a previous read, since SSL_read may extract *
- * just the first complete record, or some or all of them: *
- * as a result, we may not want to issue an actual read request as the *
- * data we are expecting may already have been read, causing us to wait *
- * until the next block of data arrives over the network (which may not *
- * ever happen): short-circuit the actual read if this is the case: */
- ret = SSL_read (session->ssl, buffer, count);
-
- if (ssl_read_is_complete (session, ret))
- {
- GSimpleAsyncResult *r;
-
- if (tls_debug_level >= DEBUG_ASYNC_DETAIL_LEVEL)
- DEBUG ("already have %d clearbytes buffered", ret);
-
- r = g_simple_async_result_new (G_OBJECT (stream),
- callback,
- user_data,
- wocky_tls_input_stream_read_async);
-
- if (session->job.read.error == NULL)
- g_simple_async_result_set_op_res_gssize (r, ret);
- else
- g_simple_async_result_set_from_error (r, session->job.read.error);
-
- g_simple_async_result_complete_in_idle (r);
- g_object_unref (r);
- return;
- }
-
- wocky_tls_job_start (&session->job.read, stream,
- io_priority, cancellable, callback, user_data,
- wocky_tls_input_stream_read_async);
-
- session->job.read.buffer = buffer;
- session->job.read.count = count;
- ssl_fill (session);
-}
-
-static gssize
-wocky_tls_input_stream_read_finish (GInputStream *stream,
- GAsyncResult *result,
- GError **error)
-{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
-
- if (tls_debug_level >= DEBUG_ASYNC_DETAIL_LEVEL)
- DEBUG ("");
-
- g_return_val_if_fail (g_simple_async_result_is_valid (result,
- G_OBJECT (stream), wocky_tls_input_stream_read_async), -1);
-
- if (g_simple_async_result_propagate_error (simple, error))
- return -1;
-
- return g_simple_async_result_get_op_res_gssize (simple);
-}
-
-static gssize
-wocky_tls_output_stream_write (GOutputStream *stream,
- const void *buffer,
- gsize count,
- GCancellable *cancellable,
- GError **error)
-{
- /* WockyTLSSession *session = WOCKY_TLS_OUTPUT_STREAM (stream)->session; */
-
- DEBUG ("sync write - not implemented");
-
- g_assert_not_reached ();
-
- return 0;
-}
-
-static void
-wocky_tls_output_stream_write_async (GOutputStream *stream,
- const void *buffer,
- gsize count,
- gint io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- int code;
- WockyTLSSession *session = WOCKY_TLS_OUTPUT_STREAM (stream)->session;
-
- DEBUG ("%" G_GSIZE_FORMAT " clearbytes to send", count);
- wocky_tls_job_start (&session->job.write, stream,
- io_priority, cancellable, callback, user_data,
- wocky_tls_output_stream_write_async);
-
- session->job.write.count = count;
-
- code = SSL_write (session->ssl, buffer, count);
- if (code < 0)
- {
- int error = SSL_get_error (session->ssl, code);
- switch (error)
- {
- case SSL_ERROR_WANT_WRITE:
- DEBUG ("Incomplete SSL write to BIO (theoretically impossible)");
- ssl_flush (session);
- return;
- case SSL_ERROR_WANT_READ:
- g_warning ("write caused read: unsupported TLS re-negotiation?");
- /* deliberately falling through to the default case, having logged a
- * more specific warning.
- */
- default:
- DEBUG ("SSL write failed, setting error %d", error);
- /* if we haven't already generated an error, set one here: */
- if(session->job.write.error == NULL)
- session->job.write.error =
- g_error_new (WOCKY_TLS_ERROR, error,
- "OpenSSL write: protocol error %d", error);
- wocky_tls_session_try_operation (session, WOCKY_TLS_OP_WRITE);
- return;
- }
- }
- ssl_flush (session);
-}
-
-static gssize
-wocky_tls_output_stream_write_finish (GOutputStream *stream,
- GAsyncResult *result,
- GError **error)
-{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
-
- if (tls_debug_level >= DEBUG_ASYNC_DETAIL_LEVEL)
- DEBUG ("");
- {
- GObject *source_object;
-
- source_object = g_async_result_get_source_object (result);
- g_object_unref (source_object);
- g_return_val_if_fail (G_OBJECT (stream) == source_object, -1);
- }
-
- g_return_val_if_fail (wocky_tls_output_stream_write_async ==
- g_simple_async_result_get_source_tag (simple), -1);
-
- if (g_simple_async_result_propagate_error (simple, error))
- return -1;
-
- return g_simple_async_result_get_op_res_gssize (simple);
-}
-
-static void
-wocky_tls_output_stream_init (WockyTLSOutputStream *stream)
-{
-}
-
-static void
-wocky_tls_input_stream_init (WockyTLSInputStream *stream)
-{
-}
-
-static void
-wocky_tls_output_stream_set_property (GObject *object, guint prop_id,
- const GValue *value, GParamSpec *pspec)
-{
- WockyTLSOutputStream *stream = WOCKY_TLS_OUTPUT_STREAM (object);
-
- switch (prop_id)
- {
- case PROP_C_SESSION:
- stream->session = g_value_dup_object (value);
- break;
-
- default:
- g_assert_not_reached ();
- }
-}
-
-static void
-wocky_tls_output_stream_constructed (GObject *object)
-{
- WockyTLSOutputStream *stream = WOCKY_TLS_OUTPUT_STREAM (object);
-
- g_assert (stream->session);
-}
-
-static void
-wocky_tls_output_stream_finalize (GObject *object)
-{
- WockyTLSOutputStream *stream = WOCKY_TLS_OUTPUT_STREAM (object);
-
- g_object_unref (stream->session);
-
- G_OBJECT_CLASS (wocky_tls_output_stream_parent_class)
- ->finalize (object);
-}
-
-static void
-wocky_tls_output_stream_class_init (GOutputStreamClass *class)
-{
- GObjectClass *obj_class = G_OBJECT_CLASS (class);
-
- class->write_fn = wocky_tls_output_stream_write;
- class->write_async = wocky_tls_output_stream_write_async;
- class->write_finish = wocky_tls_output_stream_write_finish;
- obj_class->set_property = wocky_tls_output_stream_set_property;
- obj_class->constructed = wocky_tls_output_stream_constructed;
- obj_class->finalize = wocky_tls_output_stream_finalize;
-
- g_object_class_install_property (obj_class, PROP_O_SESSION,
- g_param_spec_object ("session", "TLS session",
- "the TLS session object for this stream",
- WOCKY_TYPE_TLS_SESSION, G_PARAM_WRITABLE |
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
-}
-
-static void
-wocky_tls_input_stream_set_property (GObject *object, guint prop_id,
- const GValue *value, GParamSpec *pspec)
-{
- WockyTLSInputStream *stream = WOCKY_TLS_INPUT_STREAM (object);
-
- switch (prop_id)
- {
- case PROP_C_SESSION:
- stream->session = g_value_dup_object (value);
- break;
-
- default:
- g_assert_not_reached ();
- }
-}
-
-static void
-wocky_tls_input_stream_constructed (GObject *object)
-{
- WockyTLSInputStream *stream = WOCKY_TLS_INPUT_STREAM (object);
-
- g_assert (stream->session);
-}
-
-static void
-wocky_tls_input_stream_finalize (GObject *object)
-{
- WockyTLSInputStream *stream = WOCKY_TLS_INPUT_STREAM (object);
-
- g_object_unref (stream->session);
-
- G_OBJECT_CLASS (wocky_tls_input_stream_parent_class)
- ->finalize (object);
-}
-
-static void
-wocky_tls_input_stream_class_init (GInputStreamClass *class)
-{
- GObjectClass *obj_class = G_OBJECT_CLASS (class);
-
- class->read_fn = wocky_tls_input_stream_read;
- class->read_async = wocky_tls_input_stream_read_async;
- class->read_finish = wocky_tls_input_stream_read_finish;
- obj_class->set_property = wocky_tls_input_stream_set_property;
- obj_class->constructed = wocky_tls_input_stream_constructed;
- obj_class->finalize = wocky_tls_input_stream_finalize;
-
- g_object_class_install_property (obj_class, PROP_I_SESSION,
- g_param_spec_object ("session", "TLS session",
- "the TLS session object for this stream",
- WOCKY_TYPE_TLS_SESSION, G_PARAM_WRITABLE |
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
-}
-
-static void
-wocky_tls_connection_init (WockyTLSConnection *connection)
-{
-}
-
-static void
-wocky_tls_session_read_ready (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
-{
- WockyTLSSession *session = WOCKY_TLS_SESSION (user_data);
- GInputStream *input = G_INPUT_STREAM (object);
- GError **error = &(session->job.read.error);
- gssize rsize = 0;
- gchar *buf = session->job.handshake.job.active ?
- session->job.handshake.job.rbuf : session->job.read.rbuf;
-
- if (tls_debug_level >= DEBUG_ASYNC_DETAIL_LEVEL)
- DEBUG ("");
-
- rsize = g_input_stream_read_finish (input, result, error);
-
- if (rsize > 0)
- {
- int x;
- int y;
- DEBUG ("received %" G_GSSIZE_FORMAT " cipherbytes, filling SSL BIO",
- rsize);
- BIO_write (session->rbio, buf, rsize);
- if (tls_debug_level > DEBUG_ASYNC_DETAIL_LEVEL + 1)
- for (x = 0; x < rsize; x += 16)
- {
- for (y = 0; y < 16 && x + y < rsize; y++)
- {
- char c = *(buf + x + y);
- char d = (g_ascii_isprint (c) && g_ascii_isgraph (c)) ? c : '.';
- fprintf (stderr, "%02x %c ", c & 0xff, d);
- }
- fprintf (stderr, "\n");
- }
- }
- /* note that we never issue a read of 0, so this _must_ be EOF (0) *
- * or a fatal error (-ve rval) */
- else if (session->job.handshake.job.active)
- {
- if (tls_debug_level >= DEBUG_ASYNC_DETAIL_LEVEL)
- DEBUG("read SSL cipherbytes (handshake) failed: %" G_GSSIZE_FORMAT,
- rsize);
- session->job.handshake.state = SSL_ERROR_SSL;
- }
- else
- {
- DEBUG ("read of SSL cipherbytes failed: %" G_GSSIZE_FORMAT, rsize);
-
- if ((*error != NULL) && ((*error)->domain == g_io_error_quark ()))
- {
- /* if there were any errors we could ignore, we'd do it like this: *
- * g_error_free (*error); *error = NULL; */
- DEBUG ("failed op: [%d] %s", (*error)->code, (*error)->message);
- }
- /* in order for non-handshake reads to return an error properly *
- * we need to make sure the error in the job is set */
- else if (*error == NULL)
- {
- *error =
- g_error_new (WOCKY_TLS_ERROR, SSL_ERROR_SSL, "unknown error");
- }
- }
-
- wocky_tls_session_try_operation (session, WOCKY_TLS_OP_READ);
-}
-
-static void
-wocky_tls_session_write_ready (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
-{
- WockyTLSSession *session = WOCKY_TLS_SESSION (user_data);
- gint buffered = BIO_pending (session->wbio);
- gssize written;
-
- if (tls_debug_level >= DEBUG_ASYNC_DETAIL_LEVEL)
- DEBUG ("");
-
- written = g_output_stream_write_finish (G_OUTPUT_STREAM (object), result,
- &(session->job.write.error));
-
- if (written == buffered)
- {
- DEBUG ("%d bytes written, clearing write BIO", buffered);
- (void) BIO_reset (session->wbio);
- wocky_tls_session_try_operation (session, WOCKY_TLS_OP_WRITE);
- }
- else
- {
- gchar *buffer;
- long bsize = BIO_get_mem_data (session->wbio, &buffer);
- long psize = bsize - written;
-
- /* scrub the data we did manage to write from our buffer */
- if (written > 0)
- {
- gchar *pending = g_memdup (buffer + written, psize);
-
- (void) BIO_reset (session->wbio);
- (void) BIO_write (session->wbio, pending, psize);
- g_free (pending);
- }
-
- if (session->job.write.error != NULL)
- {
- if (tls_debug_level >= DEBUG_ASYNC_DETAIL_LEVEL)
- DEBUG ("Incomplete async write [%" G_GSSIZE_FORMAT "/%d bytes]: "
- "%s:%u %s",
- written, buffered,
- g_quark_to_string (session->job.write.error->domain),
- session->job.write.error->code,
- session->job.write.error->message);
-
- /* if we have a non-fatal error, erase it try again */
- if (g_error_matches (session->job.write.error,
- G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
- g_clear_error (&(session->job.write.error));
- }
-
- /* no error here means retry the operation; otherwise bail out */
- if (session->job.write.error == NULL)
- ssl_flush (session);
- else
- wocky_tls_session_try_operation (session, WOCKY_TLS_OP_WRITE);
- }
-}
-
-static void
-wocky_tls_session_init (WockyTLSSession *session)
-{
- const char *level;
- guint lvl = 0;
- static gsize initialised;
-
- if G_UNLIKELY (g_once_init_enter (&initialised))
- {
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
- DEBUG ("initialising SSL library and error strings");
-#else
- gint malloc_init_succeeded;
-
- DEBUG ("initialising SSL library and error strings");
-
- malloc_init_succeeded = CRYPTO_malloc_init ();
- g_warn_if_fail (malloc_init_succeeded);
-#endif
-
- SSL_library_init ();
- SSL_load_error_strings ();
- OpenSSL_add_all_algorithms();
- ENGINE_load_builtin_engines ();
- g_once_init_leave (&initialised, 1);
- }
-
- if ((level = getenv ("WOCKY_TLS_DEBUG_LEVEL")) != NULL)
- lvl = atoi (level);
-
- tls_debug_level = lvl;
-}
-
-static void
-wocky_tls_session_set_property (GObject *object, guint prop_id,
- const GValue *value, GParamSpec *pspec)
-{
- WockyTLSSession *session = WOCKY_TLS_SESSION (object);
-
- switch (prop_id)
- {
- case PROP_S_STREAM:
- session->stream = g_value_dup_object (value);
- break;
- case PROP_S_SERVER:
- session->server = g_value_get_boolean (value);
- break;
- case PROP_S_DHBITS:
- session->dh_bits = g_value_get_uint (value);
- break;
- case PROP_S_KEYFILE:
- session->key_file = g_value_dup_string (value);
- break;
- case PROP_S_CERTFILE:
- session->cert_file = g_value_dup_string (value);
- break;
- default:
- g_assert_not_reached ();
- }
-}
-
-static void
-set_dh_parameters (WockyTLSSession *session)
-{
- DH *dh;
-
- switch (session->dh_bits)
- {
- case 4096:
- DEBUG ("get_dh4096");
- dh = get_dh4096 ();
- break;
- case 2048:
- DEBUG ("get_dh2048");
- dh = get_dh2048 ();
- break;
- case 1024:
- DEBUG ("get_dh1024");
- dh = get_dh1024 ();
- break;
- case 512:
- DEBUG ("get_dh512");
- dh = get_dh512 ();
- break;
- default:
- DEBUG ("Bad dh-bits setting: %d, reset to 1024", session->dh_bits);
- dh = get_dh1024 ();
- }
-
- SSL_CTX_set_tmp_dh (session->ctx, dh);
- DH_free (dh);
-}
-
-static void
-set_ecdh_key (WockyTLSSession *session)
-{
- EC_KEY *ecdh = EC_KEY_new_by_curve_name (NID_sect163r2);
- if (ecdh == NULL)
- {
- DEBUG ("unable to create elliptical crypto key for sect163r2 curve");
- return;
- }
- SSL_CTX_set_tmp_ecdh (session->ctx,ecdh);
- EC_KEY_free (ecdh);
-}
-
-static void
-wocky_tls_session_constructed (GObject *object)
-{
- WockyTLSSession *session = WOCKY_TLS_SESSION (object);
-
- if (session->server)
- {
- DEBUG ("I'm a server; using TLSv1_server_method");
- /* OpenSSL >= 1.0 returns a const here, but we need to be also *
- * compatible with older versions that return a non-const value, *
- * hence the cast */
- session->method = (SSL_METHOD *) TLSv1_server_method ();
- }
- else
- {
- DEBUG ("I'm a client; using TLSv1_client_method");
- session->method = (SSL_METHOD *) TLSv1_client_method ();
- }
-
- session->ctx = SSL_CTX_new (session->method);
-
- if (!SSL_CTX_set_default_verify_paths (session->ctx))
- g_warning ("SSL_CTX_set_default_verify_paths() failed");
-
- /* verification will be done manually after the handshake: */
- SSL_CTX_set_verify (session->ctx, SSL_VERIFY_NONE, NULL);
- SSL_CTX_set_options (session->ctx,
- SSL_OP_CIPHER_SERVER_PREFERENCE |
- /* It is usually safe to use SSL_OP_ALL to enable the bug workaround
- * options if compatibility with somewhat broken implementations is
- * desired.
- */
- SSL_OP_ALL |
- /* Set the NO_TICKET option on the context to be kind to the Google Talk
- * server, which seems unwilling to handle empty session tickets due to a
- * bug in Java.
- *
- * See http://twistedmatrix.com/trac/ticket/3463 and
- * http://loudmouth.lighthouseapp.com/projects/17276/tickets/28.
- */
- SSL_OP_NO_TICKET |
- /* SSLv2 is excessively quaint. We shouldn't be using it anyway, since
- * we're using TLSv1 methods, but...
- */
- SSL_OP_NO_SSLv2);
- X509_STORE_set_flags (SSL_CTX_get_cert_store (session->ctx),
- X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
-
-#ifdef CIPHER_LIST
- SSL_CTX_set_cipher_list (session->ctx, CIPHER_LIST);
-#endif
-
- if (session->server)
- {
- set_dh_parameters (session);
- set_ecdh_key (session);
- }
-
- if ((session->key_file != NULL) && (session->cert_file != NULL))
- {
- long errnum;
- DEBUG ("cert: %s", session->cert_file);
- DEBUG ("key : %s", session->key_file);
- SSL_CTX_use_certificate_file (session->ctx,
- session->cert_file,
- SSL_FILETYPE_PEM);
- SSL_CTX_use_PrivateKey_file (session->ctx,
- session->key_file,
- SSL_FILETYPE_PEM);
- if (!SSL_CTX_check_private_key (session->ctx))
- {
- errnum = ERR_get_error ();
- DEBUG ("cert/key check: %ld %s", errnum, error_to_string (errnum));
- }
- else
- DEBUG ("certificate loaded");
- }
-
- session->ssl = SSL_new (session->ctx);
- session->rbio = BIO_new (BIO_s_mem ());
- session->wbio = BIO_new (BIO_s_mem ());
-
- if (session->rbio == NULL)
- g_error ("Could not allocate memory BIO for SSL reads");
-
- if (session->wbio == NULL)
- g_error ("Could not allocate memory BIO for SSL writes");
-
- if (tls_debug_level >= DEBUG_ASYNC_DETAIL_LEVEL)
- {
- int x = 0;
- const char *c = SSL_get_cipher_list (session->ssl, x);
- for (; c != NULL; c = SSL_get_cipher_list (session->ssl, ++x))
- DEBUG ("%03d: %s", x, c);
- }
-
- if (tls_debug_level >= DEBUG_ASYNC_DETAIL_LEVEL)
- {
- BIO_set_callback (session->rbio, BIO_debug_callback);
- BIO_set_callback (session->wbio, BIO_debug_callback);
- }
-
- BIO_set_mem_eof_return (session->rbio, -1);
- SSL_set_bio (session->ssl, session->rbio, session->wbio);
-
- DEBUG ("done");
-}
-
-static void
-wocky_tls_session_finalize (GObject *object)
-{
- WockyTLSSession *session = WOCKY_TLS_SESSION (object);
-
- /* the BIOs are freed by this call */
- SSL_free (session->ssl);
- /* free (session->method); handled by SSL_CTX_free */
- session->method = NULL;
- SSL_CTX_free (session->ctx);
- session->ctx = NULL;
-
- g_object_unref (session->stream);
-
- G_OBJECT_CLASS (wocky_tls_session_parent_class)->finalize (object);
-}
-
-static void
-wocky_tls_session_dispose (GObject *object)
-{
- WockyTLSSession *session = WOCKY_TLS_SESSION (object);
-
- g_free (session->key_file);
- session->key_file = NULL;
-
- g_free (session->cert_file);
- session->cert_file = NULL;
-
- G_OBJECT_CLASS (wocky_tls_session_parent_class)->dispose (object);
-}
-
-static void
-wocky_tls_session_class_init (GObjectClass *class)
-{
- class->set_property = wocky_tls_session_set_property;
- class->constructed = wocky_tls_session_constructed;
- class->finalize = wocky_tls_session_finalize;
- class->dispose = wocky_tls_session_dispose;
-
- g_object_class_install_property (class, PROP_S_STREAM,
- g_param_spec_object ("base-stream", "base stream",
- "the stream that TLS communicates over",
- G_TYPE_IO_STREAM, G_PARAM_WRITABLE |
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
-
- g_object_class_install_property (class, PROP_S_SERVER,
- g_param_spec_boolean ("server", "server",
- "whether this is a server",
- FALSE, G_PARAM_WRITABLE |
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
-
- g_object_class_install_property (class, PROP_S_DHBITS,
- g_param_spec_uint ("dh-bits", "Diffie-Hellman bits",
- "Diffie-Hellmann bits: 512, 1024, 2048, or 4096",
- 512, 4096, 1024, G_PARAM_WRITABLE |
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
-
- g_object_class_install_property (class, PROP_S_KEYFILE,
- g_param_spec_string ("x509-key", "x509 key",
- "x509 PEM key file",
- NULL, G_PARAM_WRITABLE |
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
-
- g_object_class_install_property (class, PROP_S_CERTFILE,
- g_param_spec_string ("x509-cert", "x509 certificate",
- "x509 PEM certificate file",
- NULL, G_PARAM_WRITABLE |
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
-}
-
-static void
-wocky_tls_connection_set_property (GObject *object, guint prop_id,
- const GValue *value, GParamSpec *pspec)
-{
- WockyTLSConnection *connection = WOCKY_TLS_CONNECTION (object);
-
- switch (prop_id)
- {
- case PROP_C_SESSION:
- connection->session = g_value_dup_object (value);
- break;
-
- default:
- g_assert_not_reached ();
- }
-}
-
-static gboolean
-wocky_tls_connection_close (GIOStream *stream, GCancellable *cancellable,
- GError **error)
-{
- WockyTLSConnection *connection = WOCKY_TLS_CONNECTION (stream);
-
- return g_io_stream_close (connection->session->stream, cancellable, error);
-}
-
-static GInputStream *
-wocky_tls_connection_get_input_stream (GIOStream *io_stream)
-{
- WockyTLSConnection *connection = WOCKY_TLS_CONNECTION (io_stream);
-
- if (connection->input == NULL)
- connection->input = g_object_new (WOCKY_TYPE_TLS_INPUT_STREAM,
- "session", connection->session,
- NULL);
-
- return (GInputStream *)connection->input;
-}
-
-static GOutputStream *
-wocky_tls_connection_get_output_stream (GIOStream *io_stream)
-{
- WockyTLSConnection *connection = WOCKY_TLS_CONNECTION (io_stream);
-
- if (connection->output == NULL)
- connection->output = g_object_new (WOCKY_TYPE_TLS_OUTPUT_STREAM,
- "session", connection->session,
- NULL);
-
- return (GOutputStream *)connection->output;
-}
-
-static void
-wocky_tls_connection_get_property (GObject *object, guint prop_id,
- GValue *value, GParamSpec *pspec)
-{
- switch (prop_id)
- {
- default:
- g_assert_not_reached ();
- }
-}
-
-static void
-wocky_tls_connection_constructed (GObject *object)
-{
- WockyTLSConnection *connection = WOCKY_TLS_CONNECTION (object);
-
- g_assert (connection->session);
-}
-
-static void
-wocky_tls_connection_finalize (GObject *object)
-{
- WockyTLSConnection *connection = WOCKY_TLS_CONNECTION (object);
-
- g_object_unref (connection->session);
-
- if (connection->input != NULL)
- g_object_unref (connection->input);
-
- if (connection->output != NULL)
- g_object_unref (connection->output);
-
- G_OBJECT_CLASS (wocky_tls_connection_parent_class)
- ->finalize (object);
-}
-
-static void
-wocky_tls_connection_class_init (WockyTLSConnectionClass *class)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (class);
- GIOStreamClass *stream_class = G_IO_STREAM_CLASS (class);
-
- gobject_class->get_property = wocky_tls_connection_get_property;
- gobject_class->set_property = wocky_tls_connection_set_property;
- gobject_class->constructed = wocky_tls_connection_constructed;
- gobject_class->finalize = wocky_tls_connection_finalize;
-
- g_object_class_install_property (gobject_class, PROP_C_SESSION,
- g_param_spec_object ("session", "TLS session",
- "the TLS session object for this connection",
- WOCKY_TYPE_TLS_SESSION, G_PARAM_WRITABLE |
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
- stream_class->get_input_stream = wocky_tls_connection_get_input_stream;
- stream_class->get_output_stream = wocky_tls_connection_get_output_stream;
- stream_class->close_fn = wocky_tls_connection_close;
-}
-
-WockyTLSSession *
-wocky_tls_session_new (GIOStream *stream)
-{
- return g_object_new (WOCKY_TYPE_TLS_SESSION,
- "base-stream", stream,
- "server", FALSE, NULL);
-}
-
-/**
- * wocky_tls_session_server_new:
- * @stream: a GIOStream on which we expect to receive the client TLS handshake
- * @dhbits: size of the DH parameters
- * @key: the path to the X509 PEM key file
- * @cert: the path to the X509 PEM certificate
- *
- * Create a new TLS server session
- *
- * Returns: a #WockyTLSSession object
- */
-WockyTLSSession *
-wocky_tls_session_server_new (GIOStream *stream, guint dhbits,
- const gchar* key, const gchar* cert)
-{
- if (dhbits == 0)
- dhbits = 1024;
- return g_object_new (WOCKY_TYPE_TLS_SESSION, "base-stream", stream,
- "dh-bits", dhbits, "x509-key", key, "x509-cert", cert,
- "server", TRUE,
- NULL);
-}
-
-/* this file is "borrowed" from an unmerged gnio feature: */
-/* Local Variables: */
-/* c-file-style: "gnu" */
-/* End: */