summaryrefslogtreecommitdiff
path: root/src/libtls
diff options
context:
space:
mode:
authorRomain Francoise <rfrancoise@debian.org>2014-04-15 19:34:32 +0200
committerRomain Francoise <rfrancoise@debian.org>2014-04-15 19:34:32 +0200
commitc5ebfc7b9c16551fe825dc1d79c3f7e2f096f6c9 (patch)
treed4e2118cbd411caa1a0528eac831030109bc6e65 /src/libtls
parent15fb7904f4431a6e7c305fd08732458f7f885e7e (diff)
downloadvyos-strongswan-c5ebfc7b9c16551fe825dc1d79c3f7e2f096f6c9.tar.gz
vyos-strongswan-c5ebfc7b9c16551fe825dc1d79c3f7e2f096f6c9.zip
Import upstream version 5.1.3
Diffstat (limited to 'src/libtls')
-rw-r--r--src/libtls/Makefile.am5
-rw-r--r--src/libtls/Makefile.in201
-rw-r--r--src/libtls/tests/Makefile.am22
-rw-r--r--src/libtls/tests/Makefile.in872
-rw-r--r--src/libtls/tests/suites/test_socket.c524
-rw-r--r--src/libtls/tests/suites/test_suites.c247
-rw-r--r--src/libtls/tests/tls_tests.c57
-rw-r--r--src/libtls/tests/tls_tests.h17
-rw-r--r--src/libtls/tls.c17
-rw-r--r--src/libtls/tls.h2
-rw-r--r--src/libtls/tls_aead.c217
-rw-r--r--src/libtls/tls_aead.h156
-rw-r--r--src/libtls/tls_aead_expl.c222
-rw-r--r--src/libtls/tls_aead_impl.c214
-rw-r--r--src/libtls/tls_aead_null.c159
-rw-r--r--src/libtls/tls_crypto.c588
-rw-r--r--src/libtls/tls_crypto.h9
-rw-r--r--src/libtls/tls_peer.c8
-rw-r--r--src/libtls/tls_protection.c214
-rw-r--r--src/libtls/tls_protection.h10
-rw-r--r--src/libtls/tls_socket.c16
-rw-r--r--src/libtls/tls_socket.h5
22 files changed, 3288 insertions, 494 deletions
diff --git a/src/libtls/Makefile.am b/src/libtls/Makefile.am
index b83ea8eba..d565a1479 100644
--- a/src/libtls/Makefile.am
+++ b/src/libtls/Makefile.am
@@ -8,6 +8,7 @@ ipseclib_LTLIBRARIES = libtls.la
libtls_la_SOURCES = \
tls_protection.c tls_compression.c tls_fragmentation.c tls_alert.c \
tls_crypto.c tls_prf.c tls_socket.c tls_eap.c tls_cache.c tls_peer.c \
+ tls_aead_expl.c tls_aead_impl.c tls_aead_null.c tls_aead.c \
tls_server.c tls.c
libtls_la_LIBADD = \
@@ -18,5 +19,7 @@ tls_includedir = ${dev_headers}/tls
nobase_tls_include_HEADERS = \
tls_protection.h tls_compression.h tls_fragmentation.h tls_alert.h \
tls_crypto.h tls_prf.h tls_socket.h tls_eap.h tls_cache.h tls_peer.h \
- tls_server.h tls_handshake.h tls_application.h tls.h
+ tls_server.h tls_handshake.h tls_application.h tls_aead.h tls.h
endif
+
+SUBDIRS = . tests
diff --git a/src/libtls/Makefile.in b/src/libtls/Makefile.in
index 87ae2a63d..b6abd1eac 100644
--- a/src/libtls/Makefile.in
+++ b/src/libtls/Makefile.in
@@ -134,6 +134,7 @@ libtls_la_DEPENDENCIES = \
am_libtls_la_OBJECTS = tls_protection.lo tls_compression.lo \
tls_fragmentation.lo tls_alert.lo tls_crypto.lo tls_prf.lo \
tls_socket.lo tls_eap.lo tls_cache.lo tls_peer.lo \
+ tls_aead_expl.lo tls_aead_impl.lo tls_aead_null.lo tls_aead.lo \
tls_server.lo tls.lo
libtls_la_OBJECTS = $(am_libtls_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
@@ -176,6 +177,14 @@ am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(libtls_la_SOURCES)
DIST_SOURCES = $(libtls_la_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+ ctags-recursive dvi-recursive html-recursive info-recursive \
+ install-data-recursive install-dvi-recursive \
+ install-exec-recursive install-html-recursive \
+ install-info-recursive install-pdf-recursive \
+ install-ps-recursive install-recursive installcheck-recursive \
+ installdirs-recursive pdf-recursive ps-recursive \
+ tags-recursive uninstall-recursive
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
@@ -184,8 +193,17 @@ am__can_run_installinfo = \
am__nobase_tls_include_HEADERS_DIST = tls_protection.h \
tls_compression.h tls_fragmentation.h tls_alert.h tls_crypto.h \
tls_prf.h tls_socket.h tls_eap.h tls_cache.h tls_peer.h \
- tls_server.h tls_handshake.h tls_application.h tls.h
+ tls_server.h tls_handshake.h tls_application.h tls_aead.h \
+ tls.h
HEADERS = $(nobase_tls_include_HEADERS)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+ $(RECURSIVE_TARGETS) \
+ $(RECURSIVE_CLEAN_TARGETS) \
+ $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+ distdir
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
@@ -205,7 +223,33 @@ am__define_uniq_tagged_files = \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
ACLOCAL = @ACLOCAL@
ALLOCA = @ALLOCA@
AMTAR = @AMTAR@
@@ -375,7 +419,6 @@ nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
nm_plugins = @nm_plugins@
oldincludedir = @oldincludedir@
-openac_plugins = @openac_plugins@
pcsclite_CFLAGS = @pcsclite_CFLAGS@
pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
@@ -425,6 +468,7 @@ ipseclib_LTLIBRARIES = libtls.la
libtls_la_SOURCES = \
tls_protection.c tls_compression.c tls_fragmentation.c tls_alert.c \
tls_crypto.c tls_prf.c tls_socket.c tls_eap.c tls_cache.c tls_peer.c \
+ tls_aead_expl.c tls_aead_impl.c tls_aead_null.c tls_aead.c \
tls_server.c tls.c
libtls_la_LIBADD = \
@@ -434,9 +478,10 @@ libtls_la_LIBADD = \
@USE_DEV_HEADERS_TRUE@nobase_tls_include_HEADERS = \
@USE_DEV_HEADERS_TRUE@ tls_protection.h tls_compression.h tls_fragmentation.h tls_alert.h \
@USE_DEV_HEADERS_TRUE@ tls_crypto.h tls_prf.h tls_socket.h tls_eap.h tls_cache.h tls_peer.h \
-@USE_DEV_HEADERS_TRUE@ tls_server.h tls_handshake.h tls_application.h tls.h
+@USE_DEV_HEADERS_TRUE@ tls_server.h tls_handshake.h tls_application.h tls_aead.h tls.h
-all: all-am
+SUBDIRS = . tests
+all: all-recursive
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
@@ -516,6 +561,10 @@ distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_aead.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_aead_expl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_aead_impl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_aead_null.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_alert.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_cache.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_compression.Plo@am__quote@
@@ -582,14 +631,61 @@ uninstall-nobase_tls_includeHEADERS:
$(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \
dir='$(DESTDIR)$(tls_includedir)'; $(am__uninstall_files_from_dir)
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+# (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+ @fail=; \
+ if $(am__make_keepgoing); then \
+ failcom='fail=yes'; \
+ else \
+ failcom='exit 1'; \
+ fi; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
-tags: tags-am
+tags: tags-recursive
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
@@ -602,7 +698,7 @@ tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$$unique; \
fi; \
fi
-ctags: ctags-am
+ctags: ctags-recursive
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
@@ -615,7 +711,7 @@ GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
-cscopelist: cscopelist-am
+cscopelist: cscopelist-recursive
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
@@ -664,22 +760,48 @@ distdir: $(DISTFILES)
|| exit 1; \
fi; \
done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ $(am__make_dryrun) \
+ || test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
check-am: all-am
-check: check-am
+check: check-recursive
all-am: Makefile $(LTLIBRARIES) $(HEADERS)
-installdirs:
+installdirs: installdirs-recursive
+installdirs-am:
for dir in "$(DESTDIR)$(ipseclibdir)" "$(DESTDIR)$(tls_includedir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-installcheck: installcheck-am
+installcheck: installcheck-recursive
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
@@ -701,92 +823,93 @@ distclean-generic:
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
+clean: clean-recursive
clean-am: clean-generic clean-ipseclibLTLIBRARIES clean-libtool \
mostlyclean-am
-distclean: distclean-am
+distclean: distclean-recursive
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
-dvi: dvi-am
+dvi: dvi-recursive
dvi-am:
-html: html-am
+html: html-recursive
html-am:
-info: info-am
+info: info-recursive
info-am:
install-data-am: install-ipseclibLTLIBRARIES \
install-nobase_tls_includeHEADERS
-install-dvi: install-dvi-am
+install-dvi: install-dvi-recursive
install-dvi-am:
install-exec-am:
-install-html: install-html-am
+install-html: install-html-recursive
install-html-am:
-install-info: install-info-am
+install-info: install-info-recursive
install-info-am:
install-man:
-install-pdf: install-pdf-am
+install-pdf: install-pdf-recursive
install-pdf-am:
-install-ps: install-ps-am
+install-ps: install-ps-recursive
install-ps-am:
installcheck-am:
-maintainer-clean: maintainer-clean-am
+maintainer-clean: maintainer-clean-recursive
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
-mostlyclean: mostlyclean-am
+mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
-pdf: pdf-am
+pdf: pdf-recursive
pdf-am:
-ps: ps-am
+ps: ps-recursive
ps-am:
uninstall-am: uninstall-ipseclibLTLIBRARIES \
uninstall-nobase_tls_includeHEADERS
-.MAKE: install-am install-strip
-
-.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
- clean-ipseclibLTLIBRARIES clean-libtool cscopelist-am ctags \
- ctags-am distclean distclean-compile distclean-generic \
- distclean-libtool distclean-tags distdir dvi dvi-am html \
- html-am info info-am install install-am install-data \
- install-data-am install-dvi install-dvi-am install-exec \
- install-exec-am install-html install-html-am install-info \
- install-info-am install-ipseclibLTLIBRARIES install-man \
+.MAKE: $(am__recursive_targets) install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
+ check-am clean clean-generic clean-ipseclibLTLIBRARIES \
+ clean-libtool cscopelist-am ctags ctags-am distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am \
+ install-ipseclibLTLIBRARIES install-man \
install-nobase_tls_includeHEADERS install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
- installcheck-am installdirs maintainer-clean \
+ installcheck-am installdirs installdirs-am maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags tags-am uninstall uninstall-am \
diff --git a/src/libtls/tests/Makefile.am b/src/libtls/tests/Makefile.am
new file mode 100644
index 000000000..1c0e2f941
--- /dev/null
+++ b/src/libtls/tests/Makefile.am
@@ -0,0 +1,22 @@
+TESTS = tls_tests
+
+check_PROGRAMS = $(TESTS)
+
+tls_tests_SOURCES = \
+ suites/test_socket.c \
+ suites/test_suites.c \
+ tls_tests.h tls_tests.c
+
+tls_tests_CFLAGS = \
+ -I$(top_srcdir)/src/libtls \
+ -I$(top_srcdir)/src/libstrongswan \
+ -I$(top_srcdir)/src/libstrongswan/tests \
+ -DPLUGINDIR=\""$(top_builddir)/src/libstrongswan/plugins\"" \
+ -DPLUGINS=\""${s_plugins}\"" \
+ @COVERAGE_CFLAGS@
+
+tls_tests_LDFLAGS = @COVERAGE_LDFLAGS@
+tls_tests_LDADD = \
+ $(top_builddir)/src/libtls/libtls.la \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la \
+ $(top_builddir)/src/libstrongswan/tests/libtest.la
diff --git a/src/libtls/tests/Makefile.in b/src/libtls/tests/Makefile.in
new file mode 100644
index 000000000..0b8ba33c4
--- /dev/null
+++ b/src/libtls/tests/Makefile.in
@@ -0,0 +1,872 @@
+# Makefile.in generated by automake 1.13.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+TESTS = tls_tests$(EXEEXT)
+check_PROGRAMS = $(am__EXEEXT_1)
+subdir = src/libtls/tests
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/depcomp
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
+ $(top_srcdir)/m4/config/ltoptions.m4 \
+ $(top_srcdir)/m4/config/ltsugar.m4 \
+ $(top_srcdir)/m4/config/ltversion.m4 \
+ $(top_srcdir)/m4/config/lt~obsolete.m4 \
+ $(top_srcdir)/m4/macros/split-package-version.m4 \
+ $(top_srcdir)/m4/macros/with.m4 \
+ $(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__EXEEXT_1 = tls_tests$(EXEEXT)
+am__dirstamp = $(am__leading_dot)dirstamp
+am_tls_tests_OBJECTS = suites/tls_tests-test_socket.$(OBJEXT) \
+ suites/tls_tests-test_suites.$(OBJEXT) \
+ tls_tests-tls_tests.$(OBJEXT)
+tls_tests_OBJECTS = $(am_tls_tests_OBJECTS)
+tls_tests_DEPENDENCIES = $(top_builddir)/src/libtls/libtls.la \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la \
+ $(top_builddir)/src/libstrongswan/tests/libtest.la
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+tls_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(tls_tests_CFLAGS) \
+ $(CFLAGS) $(tls_tests_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(tls_tests_SOURCES)
+DIST_SOURCES = $(tls_tests_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BFDLIB = @BFDLIB@
+BTLIB = @BTLIB@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+COVERAGE_CFLAGS = @COVERAGE_CFLAGS@
+COVERAGE_LDFLAGS = @COVERAGE_LDFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GENHTML = @GENHTML@
+GPERF = @GPERF@
+GPRBUILD = @GPRBUILD@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LCOV = @LCOV@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MYSQLCFLAG = @MYSQLCFLAG@
+MYSQLCONFIG = @MYSQLCONFIG@
+MYSQLLIB = @MYSQLLIB@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PACKAGE_VERSION_BUILD = @PACKAGE_VERSION_BUILD@
+PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@
+PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@
+PACKAGE_VERSION_REVIEW = @PACKAGE_VERSION_REVIEW@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PTHREADLIB = @PTHREADLIB@
+PYTHON = @PYTHON@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+RANLIB = @RANLIB@
+RTLIB = @RTLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
+RUBYLIB = @RUBYLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKLIB = @SOCKLIB@
+STRIP = @STRIP@
+UNWINDLIB = @UNWINDLIB@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+c_plugins = @c_plugins@
+charon_natt_port = @charon_natt_port@
+charon_plugins = @charon_plugins@
+charon_udp_port = @charon_udp_port@
+clearsilver_LIBS = @clearsilver_LIBS@
+cmd_plugins = @cmd_plugins@
+datadir = @datadir@
+datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
+dev_headers = @dev_headers@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+fips_mode = @fips_mode@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+imcvdir = @imcvdir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsec_script = @ipsec_script@
+ipsec_script_upper = @ipsec_script_upper@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+linux_headers = @linux_headers@
+localedir = @localedir@
+localstatedir = @localstatedir@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
+mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
+mkdir_p = @mkdir_p@
+nm_CFLAGS = @nm_CFLAGS@
+nm_LIBS = @nm_LIBS@
+nm_ca_dir = @nm_ca_dir@
+nm_plugins = @nm_plugins@
+oldincludedir = @oldincludedir@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+pdfdir = @pdfdir@
+piddir = @piddir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+pki_plugins = @pki_plugins@
+plugindir = @plugindir@
+pool_plugins = @pool_plugins@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+random_device = @random_device@
+resolv_conf = @resolv_conf@
+routing_table = @routing_table@
+routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
+sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
+sharedstatedir = @sharedstatedir@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+starter_plugins = @starter_plugins@
+strongswan_conf = @strongswan_conf@
+strongswan_options = @strongswan_options@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+t_plugins = @t_plugins@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+urandom_device = @urandom_device@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+tls_tests_SOURCES = \
+ suites/test_socket.c \
+ suites/test_suites.c \
+ tls_tests.h tls_tests.c
+
+tls_tests_CFLAGS = \
+ -I$(top_srcdir)/src/libtls \
+ -I$(top_srcdir)/src/libstrongswan \
+ -I$(top_srcdir)/src/libstrongswan/tests \
+ -DPLUGINDIR=\""$(top_builddir)/src/libstrongswan/plugins\"" \
+ -DPLUGINS=\""${s_plugins}\"" \
+ @COVERAGE_CFLAGS@
+
+tls_tests_LDFLAGS = @COVERAGE_LDFLAGS@
+tls_tests_LDADD = \
+ $(top_builddir)/src/libtls/libtls.la \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la \
+ $(top_builddir)/src/libstrongswan/tests/libtest.la
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libtls/tests/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libtls/tests/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-checkPROGRAMS:
+ @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+suites/$(am__dirstamp):
+ @$(MKDIR_P) suites
+ @: > suites/$(am__dirstamp)
+suites/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) suites/$(DEPDIR)
+ @: > suites/$(DEPDIR)/$(am__dirstamp)
+suites/tls_tests-test_socket.$(OBJEXT): suites/$(am__dirstamp) \
+ suites/$(DEPDIR)/$(am__dirstamp)
+suites/tls_tests-test_suites.$(OBJEXT): suites/$(am__dirstamp) \
+ suites/$(DEPDIR)/$(am__dirstamp)
+
+tls_tests$(EXEEXT): $(tls_tests_OBJECTS) $(tls_tests_DEPENDENCIES) $(EXTRA_tls_tests_DEPENDENCIES)
+ @rm -f tls_tests$(EXEEXT)
+ $(AM_V_CCLD)$(tls_tests_LINK) $(tls_tests_OBJECTS) $(tls_tests_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+ -rm -f suites/*.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_tests-tls_tests.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tls_tests-test_socket.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tls_tests-test_suites.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+suites/tls_tests-test_socket.o: suites/test_socket.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_tests_CFLAGS) $(CFLAGS) -MT suites/tls_tests-test_socket.o -MD -MP -MF suites/$(DEPDIR)/tls_tests-test_socket.Tpo -c -o suites/tls_tests-test_socket.o `test -f 'suites/test_socket.c' || echo '$(srcdir)/'`suites/test_socket.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/tls_tests-test_socket.Tpo suites/$(DEPDIR)/tls_tests-test_socket.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_socket.c' object='suites/tls_tests-test_socket.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_tests_CFLAGS) $(CFLAGS) -c -o suites/tls_tests-test_socket.o `test -f 'suites/test_socket.c' || echo '$(srcdir)/'`suites/test_socket.c
+
+suites/tls_tests-test_socket.obj: suites/test_socket.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_tests_CFLAGS) $(CFLAGS) -MT suites/tls_tests-test_socket.obj -MD -MP -MF suites/$(DEPDIR)/tls_tests-test_socket.Tpo -c -o suites/tls_tests-test_socket.obj `if test -f 'suites/test_socket.c'; then $(CYGPATH_W) 'suites/test_socket.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_socket.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/tls_tests-test_socket.Tpo suites/$(DEPDIR)/tls_tests-test_socket.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_socket.c' object='suites/tls_tests-test_socket.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_tests_CFLAGS) $(CFLAGS) -c -o suites/tls_tests-test_socket.obj `if test -f 'suites/test_socket.c'; then $(CYGPATH_W) 'suites/test_socket.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_socket.c'; fi`
+
+suites/tls_tests-test_suites.o: suites/test_suites.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_tests_CFLAGS) $(CFLAGS) -MT suites/tls_tests-test_suites.o -MD -MP -MF suites/$(DEPDIR)/tls_tests-test_suites.Tpo -c -o suites/tls_tests-test_suites.o `test -f 'suites/test_suites.c' || echo '$(srcdir)/'`suites/test_suites.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/tls_tests-test_suites.Tpo suites/$(DEPDIR)/tls_tests-test_suites.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_suites.c' object='suites/tls_tests-test_suites.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_tests_CFLAGS) $(CFLAGS) -c -o suites/tls_tests-test_suites.o `test -f 'suites/test_suites.c' || echo '$(srcdir)/'`suites/test_suites.c
+
+suites/tls_tests-test_suites.obj: suites/test_suites.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_tests_CFLAGS) $(CFLAGS) -MT suites/tls_tests-test_suites.obj -MD -MP -MF suites/$(DEPDIR)/tls_tests-test_suites.Tpo -c -o suites/tls_tests-test_suites.obj `if test -f 'suites/test_suites.c'; then $(CYGPATH_W) 'suites/test_suites.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_suites.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/tls_tests-test_suites.Tpo suites/$(DEPDIR)/tls_tests-test_suites.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_suites.c' object='suites/tls_tests-test_suites.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_tests_CFLAGS) $(CFLAGS) -c -o suites/tls_tests-test_suites.obj `if test -f 'suites/test_suites.c'; then $(CYGPATH_W) 'suites/test_suites.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_suites.c'; fi`
+
+tls_tests-tls_tests.o: tls_tests.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_tests_CFLAGS) $(CFLAGS) -MT tls_tests-tls_tests.o -MD -MP -MF $(DEPDIR)/tls_tests-tls_tests.Tpo -c -o tls_tests-tls_tests.o `test -f 'tls_tests.c' || echo '$(srcdir)/'`tls_tests.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tls_tests-tls_tests.Tpo $(DEPDIR)/tls_tests-tls_tests.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls_tests.c' object='tls_tests-tls_tests.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_tests_CFLAGS) $(CFLAGS) -c -o tls_tests-tls_tests.o `test -f 'tls_tests.c' || echo '$(srcdir)/'`tls_tests.c
+
+tls_tests-tls_tests.obj: tls_tests.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_tests_CFLAGS) $(CFLAGS) -MT tls_tests-tls_tests.obj -MD -MP -MF $(DEPDIR)/tls_tests-tls_tests.Tpo -c -o tls_tests-tls_tests.obj `if test -f 'tls_tests.c'; then $(CYGPATH_W) 'tls_tests.c'; else $(CYGPATH_W) '$(srcdir)/tls_tests.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tls_tests-tls_tests.Tpo $(DEPDIR)/tls_tests-tls_tests.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls_tests.c' object='tls_tests-tls_tests.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tls_tests_CFLAGS) $(CFLAGS) -c -o tls_tests-tls_tests.obj `if test -f 'tls_tests.c'; then $(CYGPATH_W) 'tls_tests.c'; else $(CYGPATH_W) '$(srcdir)/tls_tests.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+check-TESTS: $(TESTS)
+ @failed=0; all=0; xfail=0; xpass=0; skip=0; \
+ srcdir=$(srcdir); export srcdir; \
+ list=' $(TESTS) '; \
+ $(am__tty_colors); \
+ if test -n "$$list"; then \
+ for tst in $$list; do \
+ if test -f ./$$tst; then dir=./; \
+ elif test -f $$tst; then dir=; \
+ else dir="$(srcdir)/"; fi; \
+ if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xpass=`expr $$xpass + 1`; \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=XPASS; \
+ ;; \
+ *) \
+ col=$$grn; res=PASS; \
+ ;; \
+ esac; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xfail=`expr $$xfail + 1`; \
+ col=$$lgn; res=XFAIL; \
+ ;; \
+ *) \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=FAIL; \
+ ;; \
+ esac; \
+ else \
+ skip=`expr $$skip + 1`; \
+ col=$$blu; res=SKIP; \
+ fi; \
+ echo "$${col}$$res$${std}: $$tst"; \
+ done; \
+ if test "$$all" -eq 1; then \
+ tests="test"; \
+ All=""; \
+ else \
+ tests="tests"; \
+ All="All "; \
+ fi; \
+ if test "$$failed" -eq 0; then \
+ if test "$$xfail" -eq 0; then \
+ banner="$$All$$all $$tests passed"; \
+ else \
+ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
+ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
+ fi; \
+ else \
+ if test "$$xpass" -eq 0; then \
+ banner="$$failed of $$all $$tests failed"; \
+ else \
+ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
+ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+ fi; \
+ fi; \
+ dashes="$$banner"; \
+ skipped=""; \
+ if test "$$skip" -ne 0; then \
+ if test "$$skip" -eq 1; then \
+ skipped="($$skip test was not run)"; \
+ else \
+ skipped="($$skip tests were not run)"; \
+ fi; \
+ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$skipped"; \
+ fi; \
+ report=""; \
+ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+ report="Please report to $(PACKAGE_BUGREPORT)"; \
+ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$report"; \
+ fi; \
+ dashes=`echo "$$dashes" | sed s/./=/g`; \
+ if test "$$failed" -eq 0; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ fi; \
+ echo "$${col}$$dashes$${std}"; \
+ echo "$${col}$$banner$${std}"; \
+ test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \
+ test -z "$$report" || echo "$${col}$$report$${std}"; \
+ echo "$${col}$$dashes$${std}"; \
+ test "$$failed" -eq 0; \
+ else :; fi
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+ -rm -f suites/$(DEPDIR)/$(am__dirstamp)
+ -rm -f suites/$(am__dirstamp)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR) suites/$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR) suites/$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
+ clean-checkPROGRAMS clean-generic clean-libtool cscopelist-am \
+ ctags ctags-am distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libtls/tests/suites/test_socket.c b/src/libtls/tests/suites/test_socket.c
new file mode 100644
index 000000000..42a4607b7
--- /dev/null
+++ b/src/libtls/tests/suites/test_socket.c
@@ -0,0 +1,524 @@
+/*
+ * Copyright (C) 2014 Martin Willi
+ * Copyright (C) 2014 revosec AG
+ *
+ * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program 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.
+ */
+
+#include <test_suite.h>
+
+#include <unistd.h>
+#include <errno.h>
+
+#include <processing/jobs/callback_job.h>
+#include <credentials/sets/mem_cred.h>
+
+#include "tls_socket.h"
+
+/**
+ * Credentials for authentication
+ */
+static mem_cred_t *creds;
+
+/**
+ * RSA private key, 2048 bit
+ */
+static char rsa[] = {
+ 0x30,0x82,0x04,0xa4,0x02,0x01,0x00,0x02,0x82,0x01,0x01,0x00,0xee,0xa3,0x28,0xcc,
+ 0x48,0xca,0x37,0xfc,0xb6,0xfa,0xfc,0x18,0x0d,0xa2,0x28,0x44,0xb4,0x16,0x56,0xf7,
+ 0x97,0x5f,0x38,0x83,0xfc,0xd4,0x30,0xea,0xf7,0x5e,0xaa,0xd4,0x21,0x0e,0x71,0x49,
+ 0x13,0x39,0xaf,0x89,0xa1,0x1d,0x1b,0x9a,0x08,0x44,0xff,0x0b,0xeb,0x4b,0xad,0x8e,
+ 0xc4,0x6d,0x1e,0x0c,0x02,0xbb,0x17,0x59,0xc7,0x66,0xc7,0xff,0x4c,0x3c,0x11,0x40,
+ 0x1a,0xe3,0xca,0x34,0xf8,0x41,0xe0,0x39,0x3e,0xce,0x72,0x9f,0x56,0x9e,0x69,0xad,
+ 0x98,0x43,0x5f,0x35,0xc2,0xd0,0xd9,0xbc,0x8b,0xed,0xc6,0xc7,0x74,0x73,0x74,0x30,
+ 0x92,0x86,0x39,0x26,0x3d,0xf1,0xd5,0x16,0x45,0x7d,0xcc,0x90,0x54,0xff,0x44,0x74,
+ 0xf3,0xba,0x41,0x5c,0x58,0xa4,0x66,0xe6,0x9d,0x58,0xbe,0x7e,0x89,0xe1,0x7c,0xf7,
+ 0x28,0xb0,0xde,0xe2,0x01,0x0a,0x89,0xc7,0x63,0x3f,0xef,0x2b,0xcb,0xef,0x65,0x89,
+ 0x82,0x23,0x32,0xa7,0xa3,0x1c,0x0d,0xc6,0x8f,0x76,0x59,0x8b,0x55,0x65,0x9c,0x91,
+ 0xd4,0x93,0x89,0xad,0x37,0x47,0x23,0x25,0xb3,0x53,0xea,0xef,0x73,0xeb,0x97,0xd3,
+ 0xd7,0x74,0x38,0x73,0x8d,0x16,0x0d,0x6f,0xae,0x59,0x33,0x4e,0x24,0xe9,0x52,0xf6,
+ 0x6f,0x8c,0x5c,0x13,0xcf,0x1d,0x0a,0xcc,0xb7,0x6a,0x88,0xce,0x91,0xe2,0xe0,0xcb,
+ 0xc6,0xd2,0xfb,0x81,0xf6,0xd2,0x9f,0x0a,0x82,0x70,0x80,0xbf,0x93,0x70,0xc0,0x57,
+ 0x23,0x6e,0x97,0x1c,0x9d,0x7d,0xf0,0xa3,0x54,0x86,0xec,0x40,0xae,0x09,0x20,0xed,
+ 0x02,0x43,0xa3,0xf8,0x7e,0x0e,0x5b,0xd0,0x22,0x7b,0x74,0x39,0x02,0x03,0x01,0x00,
+ 0x01,0x02,0x82,0x01,0x01,0x00,0xd9,0x5b,0x99,0x74,0x80,0xb4,0x57,0xcc,0x82,0x2a,
+ 0x17,0x66,0x1d,0x3c,0xde,0xea,0xbd,0x11,0x40,0x03,0x62,0x47,0xe3,0xe5,0x2c,0x6b,
+ 0x65,0x67,0x0f,0x0b,0x96,0x13,0x83,0x4c,0x71,0x58,0xfa,0xfe,0xe6,0xe9,0x37,0xeb,
+ 0x98,0x51,0x73,0x48,0xcc,0xf9,0xe1,0x46,0x5b,0xfe,0x16,0xe1,0xc0,0xa5,0x75,0xf3,
+ 0x4d,0x30,0x84,0x14,0x15,0x04,0x6f,0x3e,0xa3,0x03,0xbd,0xba,0x4f,0x5a,0x71,0xe9,
+ 0x26,0xbf,0x5d,0x7a,0x93,0x22,0x98,0xb5,0xcf,0x51,0xc3,0xc7,0x51,0xb8,0x59,0x0a,
+ 0xfb,0xd7,0xe5,0xa8,0x1d,0x0f,0x5c,0xfd,0x30,0x0e,0x71,0xd7,0x79,0xc4,0x60,0x55,
+ 0x9e,0x1e,0x1c,0x0b,0x9a,0x40,0xb8,0x7a,0x8d,0xb2,0xec,0xb0,0x70,0x8a,0x19,0x5f,
+ 0x1d,0x2e,0xde,0x90,0x8f,0x68,0x56,0x08,0xce,0x0c,0x08,0xde,0xc7,0xf8,0x13,0xef,
+ 0xd2,0xbc,0x92,0xb6,0xfb,0xec,0xb6,0x04,0xf6,0x8f,0x7d,0x95,0xe9,0xeb,0xc7,0xfb,
+ 0xcc,0x4f,0xad,0x41,0xf1,0x4c,0x79,0x07,0xdd,0x4b,0x40,0xb4,0x74,0x44,0x9a,0x06,
+ 0x0a,0x0f,0xb2,0xda,0x12,0x46,0xe5,0xee,0x01,0x64,0xe5,0xf0,0x82,0x69,0xf9,0xf1,
+ 0xe9,0x41,0x13,0x5a,0xee,0xc0,0x37,0x9a,0xbe,0x9a,0x9a,0x06,0x4b,0x52,0xd6,0xf3,
+ 0x1b,0x30,0x64,0x93,0x3a,0x97,0xe1,0xdc,0x50,0x1f,0x46,0xc4,0x81,0x6a,0x17,0x52,
+ 0x49,0x85,0xc6,0x85,0xb7,0x60,0xd4,0xf0,0xd1,0x6a,0xeb,0x50,0x8c,0xb7,0xeb,0x1f,
+ 0x17,0x0e,0xf0,0xfd,0x67,0x03,0x7c,0x74,0x1a,0xac,0x66,0x81,0x00,0x45,0x5e,0xf3,
+ 0xd9,0x9d,0x22,0x99,0xc4,0x11,0x02,0x81,0x81,0x00,0xfa,0x44,0x32,0x14,0xb2,0x82,
+ 0x28,0x02,0x46,0x05,0xdd,0x8d,0xb1,0x9f,0x9e,0x6f,0x61,0xf2,0x01,0xa0,0x2b,0x76,
+ 0xee,0x46,0xaa,0x2d,0x2d,0x5b,0xd2,0x67,0x90,0x36,0xbb,0xa0,0x07,0xdf,0x9b,0xad,
+ 0x18,0x1e,0xa7,0xe6,0x36,0xc6,0x49,0xda,0xc5,0x0d,0x52,0x29,0x5a,0x40,0xcf,0xdf,
+ 0x8d,0xd0,0xa3,0xc2,0x34,0x17,0x9f,0xb5,0xf1,0x67,0xac,0x29,0x10,0xc2,0x5c,0x62,
+ 0xe3,0xe2,0x5c,0x9f,0x93,0xcc,0xb5,0xeb,0x16,0x64,0x44,0x9f,0x6b,0x5a,0xac,0x19,
+ 0x09,0xff,0x4b,0x78,0x7f,0xec,0x5a,0xbd,0xe9,0xcb,0x74,0xbb,0x30,0x13,0xc5,0x25,
+ 0x8b,0xac,0x8d,0xf9,0xa9,0x99,0x25,0xf5,0xce,0x07,0xb6,0x2b,0x1b,0x42,0xed,0x3a,
+ 0x30,0x4a,0xfc,0x5f,0xf0,0xe2,0x26,0xa6,0x60,0x5d,0x02,0x81,0x81,0x00,0xf4,0x1a,
+ 0xc2,0x7e,0xa0,0xa0,0xad,0x20,0x65,0x04,0xe8,0xf7,0xb0,0xb1,0x76,0x79,0x08,0x18,
+ 0x58,0x93,0x21,0xf1,0x56,0x58,0x58,0x18,0x4a,0x5c,0x59,0x08,0x27,0x64,0x09,0xcb,
+ 0x0b,0x0b,0x4e,0x26,0xc8,0x0b,0x87,0x67,0x40,0xc1,0xab,0x31,0x60,0xa6,0x78,0xdd,
+ 0x78,0xc8,0x86,0x38,0xbd,0x19,0xde,0x0b,0x70,0x72,0xec,0x36,0x88,0x39,0x69,0x70,
+ 0xda,0xa6,0x2e,0xf9,0x5c,0xd8,0x17,0xc5,0xfa,0xf8,0xa5,0xc9,0x9b,0xf0,0xfe,0x03,
+ 0x71,0x57,0xfa,0x58,0x0f,0x33,0xc3,0xab,0xce,0xb0,0x5d,0xd0,0x40,0x07,0x9a,0x0b,
+ 0xff,0xb9,0xaa,0x9d,0xc5,0x33,0x7f,0x5f,0x48,0x7e,0x54,0x82,0xd1,0xdf,0x75,0x69,
+ 0xee,0xe5,0xf5,0x80,0x44,0xce,0x52,0x72,0x14,0x2c,0xe6,0xa7,0xd5,0x8d,0x02,0x81,
+ 0x81,0x00,0xb8,0xf7,0x70,0x20,0x35,0xf2,0xd6,0x89,0x1f,0xa1,0xb4,0x26,0xc6,0x51,
+ 0xd7,0xb2,0x30,0xac,0xc1,0xa0,0xd4,0x9e,0xf8,0xea,0x87,0x5a,0x0e,0x7d,0x1f,0xdb,
+ 0xe5,0x0d,0x5e,0xcc,0x9f,0x25,0x18,0x14,0xed,0x8f,0xb2,0xbe,0x06,0x5b,0xb5,0x38,
+ 0x18,0x8d,0x88,0xdd,0x01,0x54,0x87,0x8e,0x8d,0x6c,0xd7,0xab,0x6f,0xfe,0xc9,0xce,
+ 0x9a,0x15,0xea,0x7b,0x0b,0x64,0xeb,0x0d,0x37,0xaa,0x14,0x94,0xe8,0x92,0xd3,0x1d,
+ 0x66,0x16,0x43,0x55,0xa3,0xed,0x86,0xe6,0x96,0xa9,0xf5,0xe8,0xa0,0x7b,0x5a,0x71,
+ 0xa4,0x7a,0xf7,0xd2,0x65,0x6d,0x27,0x37,0x61,0xac,0xed,0xdd,0xc9,0x08,0x64,0xb2,
+ 0xf0,0x4c,0x68,0xca,0x21,0x42,0xec,0xbc,0x25,0xf7,0x35,0xe1,0xde,0xd1,0xf6,0x88,
+ 0xdf,0x0d,0x02,0x81,0x80,0x44,0xb0,0xcb,0x0e,0x6b,0x11,0x0b,0xe6,0xd3,0xc6,0x7f,
+ 0xf0,0x43,0x6e,0x8c,0xd2,0x1e,0x2f,0x0b,0xad,0xcb,0x9d,0x68,0x18,0xd0,0x21,0x75,
+ 0xbb,0x6a,0xea,0x5a,0x7b,0x52,0x2e,0x2a,0xdb,0x71,0x90,0x84,0x36,0x8a,0x51,0xc9,
+ 0xed,0x35,0xc9,0x5d,0x53,0x3b,0x2b,0xc7,0x73,0x56,0x21,0xdd,0x44,0xcc,0x31,0x17,
+ 0xe1,0x9f,0x0a,0xf1,0x66,0x86,0x7f,0x55,0x67,0xf2,0x4c,0x05,0x8e,0x61,0x92,0x3a,
+ 0xbf,0x81,0x97,0xac,0x24,0x32,0xb6,0xb1,0x4c,0x7a,0x8c,0x11,0x2b,0x15,0xe2,0xe0,
+ 0xf4,0xcc,0x51,0x6f,0xd3,0x33,0xcc,0x30,0x98,0x04,0xa5,0x04,0xfb,0x2a,0xda,0x9b,
+ 0x41,0xc1,0x72,0x56,0xb0,0xb5,0x0f,0xac,0x44,0x55,0xc3,0x54,0x99,0x62,0xa5,0xeb,
+ 0x7b,0x7f,0x24,0xb7,0x79,0x02,0x81,0x80,0x0a,0x3b,0x9b,0x91,0x1d,0x9b,0x04,0x4e,
+ 0xdf,0xd9,0xe6,0x47,0xf3,0x79,0xb7,0x17,0xcf,0x42,0xa5,0xde,0x94,0xf0,0xfe,0xed,
+ 0x46,0xf6,0xaf,0x3e,0x6c,0x91,0x01,0x89,0x79,0x81,0xea,0x2b,0x82,0x68,0x0e,0xd8,
+ 0x25,0xaf,0x79,0x8b,0x14,0xfd,0xf2,0x29,0x20,0x34,0x2d,0x0b,0x08,0x8c,0x3b,0x2b,
+ 0xfc,0x75,0xe9,0x4e,0x21,0xa6,0xb2,0x35,0x67,0x8d,0x4c,0x90,0x94,0x02,0xd5,0x32,
+ 0x23,0xc6,0xa0,0x92,0x2e,0xfa,0x97,0x48,0x5b,0x95,0xc3,0xf1,0xbc,0x6b,0xe8,0x4c,
+ 0x92,0x6f,0x5e,0x3d,0xf9,0xbd,0x2c,0xf0,0x83,0x1c,0xe6,0xb3,0x45,0x68,0x32,0x8d,
+ 0x85,0x20,0xcb,0x9d,0xd2,0x30,0x5a,0x57,0xa4,0x6e,0x27,0xb5,0x29,0x14,0xdb,0xf1,
+ 0x4b,0x9a,0xc3,0xc1,0xc5,0x37,0x6d,0x1b,
+};
+
+/**
+ * ECDSA private key
+ */
+static char ecdsa[] = {
+ 0x30,0x81,0xa4,0x02,0x01,0x01,0x04,0x30,0xc0,0x1f,0xfd,0x65,0xc6,0xc4,0x4c,0xb8,
+ 0xff,0x56,0x08,0xb5,0xbd,0xb8,0xf5,0x93,0xf7,0x51,0x0e,0x92,0x1f,0x06,0xbf,0xa6,
+ 0xd9,0x1d,0xae,0xa3,0x16,0x0d,0x0f,0xc9,0xd5,0x97,0x90,0x46,0xf1,0x98,0xa8,0x18,
+ 0x07,0xba,0xcf,0x91,0x8e,0x07,0xed,0x88,0xa0,0x07,0x06,0x05,0x2b,0x81,0x04,0x00,
+ 0x22,0xa1,0x64,0x03,0x62,0x00,0x04,0xd6,0xba,0xe1,0xf0,0x09,0x22,0x21,0x12,0x69,
+ 0xed,0x0e,0xd5,0x02,0x8c,0xb8,0x52,0xbb,0x57,0x68,0x0e,0xf3,0xdb,0xb9,0xb1,0xee,
+ 0x9c,0x67,0xa0,0xb8,0xdc,0x13,0x1e,0x5b,0x44,0x71,0x04,0xef,0x4e,0xe3,0xdd,0xf4,
+ 0xa6,0xc3,0xba,0x77,0x53,0xb8,0x28,0x5f,0xd2,0x97,0x05,0xa3,0x5b,0xe6,0xde,0x0a,
+ 0xce,0x11,0xa8,0xaf,0x02,0xbd,0xfa,0x17,0xf9,0xa7,0x38,0x3e,0x5b,0x57,0xb0,0x01,
+ 0xb3,0xc6,0x09,0x29,0x65,0xae,0xfb,0x87,0x92,0xa3,0xd7,0x3d,0x9a,0x1c,0x52,0x09,
+ 0xb1,0x47,0xc8,0xf6,0x18,0xbb,0x97,
+};
+
+/**
+ * TLS certificate for RSA key
+ */
+static char rsa_crt[] = {
+ 0x30,0x82,0x03,0x1f,0x30,0x82,0x02,0x07,0xa0,0x03,0x02,0x01,0x02,0x02,0x09,0x00,
+ 0xf0,0xbb,0xac,0xc3,0xa1,0x6b,0xf3,0x1c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,
+ 0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x30,0x34,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,
+ 0x04,0x06,0x13,0x02,0x43,0x48,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0a,0x13,
+ 0x0a,0x73,0x74,0x72,0x6f,0x6e,0x67,0x53,0x77,0x61,0x6e,0x31,0x10,0x30,0x0e,0x06,
+ 0x03,0x55,0x04,0x03,0x13,0x07,0x74,0x6c,0x73,0x2d,0x72,0x73,0x61,0x30,0x1e,0x17,
+ 0x0d,0x31,0x34,0x30,0x33,0x32,0x34,0x31,0x36,0x32,0x37,0x32,0x36,0x5a,0x17,0x0d,
+ 0x31,0x37,0x30,0x33,0x32,0x33,0x31,0x36,0x32,0x37,0x32,0x36,0x5a,0x30,0x34,0x31,
+ 0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x43,0x48,0x31,0x13,0x30,0x11,
+ 0x06,0x03,0x55,0x04,0x0a,0x13,0x0a,0x73,0x74,0x72,0x6f,0x6e,0x67,0x53,0x77,0x61,
+ 0x6e,0x31,0x10,0x30,0x0e,0x06,0x03,0x55,0x04,0x03,0x13,0x07,0x74,0x6c,0x73,0x2d,
+ 0x72,0x73,0x61,0x30,0x82,0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
+ 0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,0x02,
+ 0x82,0x01,0x01,0x00,0xee,0xa3,0x28,0xcc,0x48,0xca,0x37,0xfc,0xb6,0xfa,0xfc,0x18,
+ 0x0d,0xa2,0x28,0x44,0xb4,0x16,0x56,0xf7,0x97,0x5f,0x38,0x83,0xfc,0xd4,0x30,0xea,
+ 0xf7,0x5e,0xaa,0xd4,0x21,0x0e,0x71,0x49,0x13,0x39,0xaf,0x89,0xa1,0x1d,0x1b,0x9a,
+ 0x08,0x44,0xff,0x0b,0xeb,0x4b,0xad,0x8e,0xc4,0x6d,0x1e,0x0c,0x02,0xbb,0x17,0x59,
+ 0xc7,0x66,0xc7,0xff,0x4c,0x3c,0x11,0x40,0x1a,0xe3,0xca,0x34,0xf8,0x41,0xe0,0x39,
+ 0x3e,0xce,0x72,0x9f,0x56,0x9e,0x69,0xad,0x98,0x43,0x5f,0x35,0xc2,0xd0,0xd9,0xbc,
+ 0x8b,0xed,0xc6,0xc7,0x74,0x73,0x74,0x30,0x92,0x86,0x39,0x26,0x3d,0xf1,0xd5,0x16,
+ 0x45,0x7d,0xcc,0x90,0x54,0xff,0x44,0x74,0xf3,0xba,0x41,0x5c,0x58,0xa4,0x66,0xe6,
+ 0x9d,0x58,0xbe,0x7e,0x89,0xe1,0x7c,0xf7,0x28,0xb0,0xde,0xe2,0x01,0x0a,0x89,0xc7,
+ 0x63,0x3f,0xef,0x2b,0xcb,0xef,0x65,0x89,0x82,0x23,0x32,0xa7,0xa3,0x1c,0x0d,0xc6,
+ 0x8f,0x76,0x59,0x8b,0x55,0x65,0x9c,0x91,0xd4,0x93,0x89,0xad,0x37,0x47,0x23,0x25,
+ 0xb3,0x53,0xea,0xef,0x73,0xeb,0x97,0xd3,0xd7,0x74,0x38,0x73,0x8d,0x16,0x0d,0x6f,
+ 0xae,0x59,0x33,0x4e,0x24,0xe9,0x52,0xf6,0x6f,0x8c,0x5c,0x13,0xcf,0x1d,0x0a,0xcc,
+ 0xb7,0x6a,0x88,0xce,0x91,0xe2,0xe0,0xcb,0xc6,0xd2,0xfb,0x81,0xf6,0xd2,0x9f,0x0a,
+ 0x82,0x70,0x80,0xbf,0x93,0x70,0xc0,0x57,0x23,0x6e,0x97,0x1c,0x9d,0x7d,0xf0,0xa3,
+ 0x54,0x86,0xec,0x40,0xae,0x09,0x20,0xed,0x02,0x43,0xa3,0xf8,0x7e,0x0e,0x5b,0xd0,
+ 0x22,0x7b,0x74,0x39,0x02,0x03,0x01,0x00,0x01,0xa3,0x34,0x30,0x32,0x30,0x1f,0x06,
+ 0x03,0x55,0x1d,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x96,0x0e,0xc8,0xd3,0xb3,0x3f,
+ 0xd1,0x11,0xb6,0x36,0x70,0xdb,0x37,0x98,0x3c,0xab,0x69,0x03,0x69,0x56,0x30,0x0f,
+ 0x06,0x03,0x55,0x1d,0x11,0x04,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,0x01,0x30,
+ 0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x82,
+ 0x01,0x01,0x00,0x94,0x1d,0x08,0xda,0x7b,0xc4,0xa3,0xf4,0x40,0x54,0xae,0x45,0x6a,
+ 0xb3,0x62,0xb6,0x0b,0x35,0xc7,0x5f,0xed,0xb9,0x42,0x33,0xd5,0x32,0x80,0x23,0x76,
+ 0x87,0xae,0x59,0xbb,0x77,0x00,0xc4,0xbf,0x60,0x3b,0x9b,0x04,0x46,0x52,0xde,0x9f,
+ 0x16,0xc6,0x96,0x5e,0x7a,0xb5,0xbb,0x49,0x6a,0x89,0x4a,0x60,0x0b,0x85,0x15,0xec,
+ 0xbb,0x83,0x79,0x01,0xfa,0x3c,0xd5,0x1e,0x6a,0x75,0xe7,0x93,0xc9,0xc4,0xbb,0xea,
+ 0xad,0xa2,0x23,0x32,0xc5,0x57,0x4c,0x41,0xb2,0x41,0x91,0x53,0x5e,0xaf,0x98,0x83,
+ 0xcb,0x6b,0xa8,0x2f,0xc8,0x06,0x16,0x18,0x5a,0x75,0xe1,0xee,0xac,0xc0,0x28,0x08,
+ 0x0a,0x09,0xd1,0x03,0xba,0x65,0xf1,0x89,0xcc,0x63,0x6f,0xb2,0x70,0xdc,0x46,0x2b,
+ 0x62,0x5b,0x64,0xd4,0x7a,0xc4,0x12,0xe2,0x88,0x3a,0x54,0x0a,0xf5,0x1e,0x1c,0x9e,
+ 0x9a,0xb2,0x62,0xf9,0xd3,0x02,0xf0,0xc1,0xf0,0x7b,0x4d,0xf3,0x44,0xd8,0x3c,0x13,
+ 0x1d,0xfc,0x78,0xa3,0x54,0x68,0xce,0x43,0x31,0x78,0x58,0x2f,0x5d,0xb8,0xa7,0xff,
+ 0x54,0xae,0x6e,0x25,0xd7,0x40,0x6c,0x59,0x7b,0x5f,0x18,0x31,0xe9,0xfc,0x53,0x34,
+ 0xb2,0xb0,0x18,0xd4,0x2c,0x85,0x9d,0xad,0x2d,0xd2,0x05,0x5d,0x2e,0x47,0xee,0x09,
+ 0x3d,0x05,0x2e,0x46,0x66,0xea,0x09,0xb2,0x81,0xd3,0x9b,0x28,0xbf,0xf9,0x9c,0x54,
+ 0x98,0xb7,0x2d,0x38,0xd8,0xae,0x03,0x70,0xae,0x1e,0xd4,0xa9,0xb7,0x2e,0xdb,0x02,
+ 0x6a,0x84,0x0f,0x6c,0xe8,0xb8,0x25,0x73,0x84,0x13,0x9f,0x34,0x24,0xb8,0xfc,0x96,
+ 0x4c,0x91,0xfa,
+};
+
+/**
+ * TLS certificate for ECDSA key
+ */
+static char ecdsa_crt[] = {
+ 0x30,0x82,0x01,0xd3,0x30,0x82,0x01,0x59,0xa0,0x03,0x02,0x01,0x02,0x02,0x09,0x00,
+ 0xaa,0x92,0xf5,0x39,0x85,0xf5,0xd5,0xa3,0x30,0x09,0x06,0x07,0x2a,0x86,0x48,0xce,
+ 0x3d,0x04,0x01,0x30,0x36,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,
+ 0x43,0x48,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0a,0x13,0x0a,0x73,0x74,0x72,
+ 0x6f,0x6e,0x67,0x53,0x77,0x61,0x6e,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x03,
+ 0x13,0x09,0x74,0x6c,0x73,0x2d,0x65,0x63,0x64,0x73,0x61,0x30,0x1e,0x17,0x0d,0x31,
+ 0x34,0x30,0x33,0x32,0x34,0x31,0x36,0x32,0x39,0x33,0x34,0x5a,0x17,0x0d,0x31,0x37,
+ 0x30,0x33,0x32,0x33,0x31,0x36,0x32,0x39,0x33,0x34,0x5a,0x30,0x36,0x31,0x0b,0x30,
+ 0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x43,0x48,0x31,0x13,0x30,0x11,0x06,0x03,
+ 0x55,0x04,0x0a,0x13,0x0a,0x73,0x74,0x72,0x6f,0x6e,0x67,0x53,0x77,0x61,0x6e,0x31,
+ 0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x74,0x6c,0x73,0x2d,0x65,0x63,
+ 0x64,0x73,0x61,0x30,0x76,0x30,0x10,0x06,0x07,0x2a,0x86,0x48,0xce,0x3d,0x02,0x01,
+ 0x06,0x05,0x2b,0x81,0x04,0x00,0x22,0x03,0x62,0x00,0x04,0xd6,0xba,0xe1,0xf0,0x09,
+ 0x22,0x21,0x12,0x69,0xed,0x0e,0xd5,0x02,0x8c,0xb8,0x52,0xbb,0x57,0x68,0x0e,0xf3,
+ 0xdb,0xb9,0xb1,0xee,0x9c,0x67,0xa0,0xb8,0xdc,0x13,0x1e,0x5b,0x44,0x71,0x04,0xef,
+ 0x4e,0xe3,0xdd,0xf4,0xa6,0xc3,0xba,0x77,0x53,0xb8,0x28,0x5f,0xd2,0x97,0x05,0xa3,
+ 0x5b,0xe6,0xde,0x0a,0xce,0x11,0xa8,0xaf,0x02,0xbd,0xfa,0x17,0xf9,0xa7,0x38,0x3e,
+ 0x5b,0x57,0xb0,0x01,0xb3,0xc6,0x09,0x29,0x65,0xae,0xfb,0x87,0x92,0xa3,0xd7,0x3d,
+ 0x9a,0x1c,0x52,0x09,0xb1,0x47,0xc8,0xf6,0x18,0xbb,0x97,0xa3,0x34,0x30,0x32,0x30,
+ 0x1f,0x06,0x03,0x55,0x1d,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x4f,0x1e,0x5d,0x94,
+ 0x85,0xe2,0xbc,0x86,0x0e,0x80,0xce,0x17,0x92,0x42,0xb4,0xb8,0x19,0x67,0xb8,0xfe,
+ 0x30,0x0f,0x06,0x03,0x55,0x1d,0x11,0x04,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
+ 0x01,0x30,0x09,0x06,0x07,0x2a,0x86,0x48,0xce,0x3d,0x04,0x01,0x03,0x69,0x00,0x30,
+ 0x66,0x02,0x31,0x00,0xdc,0x6e,0x3b,0xe4,0x9f,0x36,0xa5,0xa8,0x88,0x8d,0xcf,0x2d,
+ 0xa1,0x6e,0x33,0x68,0x73,0xd6,0x6a,0xd6,0x1d,0x00,0xe5,0x5c,0x76,0x09,0x5e,0xe9,
+ 0x7a,0x3a,0x00,0x5e,0xbc,0xef,0x0d,0x8d,0x95,0x5c,0x2b,0xfc,0xa4,0xe3,0xe3,0xcf,
+ 0x74,0x95,0x00,0x21,0x02,0x31,0x00,0x8f,0x40,0x3e,0xfc,0xe9,0xae,0x17,0x9b,0x36,
+ 0x39,0xe2,0x79,0xa5,0x7b,0x5d,0xe3,0xe0,0x84,0x68,0x7e,0x00,0x57,0xbe,0x4d,0xe3,
+ 0x0e,0xff,0x20,0x9c,0xce,0xd1,0x43,0x76,0x00,0x6e,0x59,0x7b,0xac,0x94,0x05,0xef,
+ 0xed,0xca,0x8b,0xe5,0x7f,0xa5,0xd7,
+};
+
+START_SETUP(setup_creds)
+{
+ private_key_t *key;
+ certificate_t *cert;
+
+ creds = mem_cred_create();
+
+ key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
+ BUILD_BLOB, chunk_from_thing(rsa), BUILD_END);
+ if (key)
+ {
+ creds->add_key(creds, key);
+ }
+ key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA,
+ BUILD_BLOB, chunk_from_thing(ecdsa), BUILD_END);
+ if (key)
+ {
+ creds->add_key(creds, key);
+ }
+ cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
+ BUILD_BLOB, chunk_from_thing(rsa_crt), BUILD_END);
+ if (cert)
+ {
+ creds->add_cert(creds, TRUE, cert);
+ }
+ cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
+ BUILD_BLOB, chunk_from_thing(ecdsa_crt), BUILD_END);
+ if (cert)
+ {
+ creds->add_cert(creds, TRUE, cert);
+ }
+
+ lib->credmgr->add_set(lib->credmgr, &creds->set);
+}
+END_SETUP
+
+START_TEARDOWN(teardown_creds)
+{
+ lib->credmgr->remove_set(lib->credmgr, &creds->set);
+ creds->destroy(creds);
+}
+END_TEARDOWN
+
+/**
+ * Configuration for an echo server
+ */
+typedef struct {
+ tls_version_t version;
+ u_int16_t port;
+ char *addr;
+ chunk_t data;
+ int fd;
+ bool cauth;
+} echo_server_config_t;
+
+/**
+ * Run an echo server
+ */
+static job_requeue_t serve_echo(echo_server_config_t *config)
+{
+ tls_socket_t *tls;
+ int sfd, cfd;
+ identification_t *server, *client = NULL;
+ ssize_t len, total, done;
+ char buf[128];
+
+ server = identification_create_from_string(config->addr);
+ if (config->cauth)
+ {
+ client = server;
+ }
+ sfd = config->fd;
+ while (TRUE)
+ {
+ cfd = accept(sfd, NULL, NULL);
+ if (cfd < 0)
+ {
+ break;
+ }
+
+ tls = tls_socket_create(TRUE, server, client, cfd, NULL,
+ config->version, TRUE);
+ ck_assert(tls != NULL);
+
+ while (TRUE)
+ {
+ len = tls->read(tls, buf, sizeof(buf), TRUE);
+ if (len <= 0)
+ {
+ break;
+ }
+ total = 0;
+ while (total < len)
+ {
+ done = tls->write(tls, buf + total, len - total);
+ ck_assert_msg(done > 0, "%s", strerror(errno));
+ total += done;
+ }
+ }
+
+ tls->destroy(tls);
+ close(cfd);
+ }
+ server->destroy(server);
+
+ return JOB_REQUEUE_NONE;
+}
+
+/**
+ * Start a echo server using config
+ */
+static void start_echo_server(echo_server_config_t *config)
+{
+ host_t *host;
+ int on = 1;
+
+ host = host_create_from_string(config->addr, config->port);
+
+ config->fd = socket(AF_INET, SOCK_STREAM, 0);
+ ck_assert(config->fd != -1);
+ ck_assert(setsockopt(config->fd, SOL_SOCKET, SO_REUSEADDR,
+ (void*)&on, sizeof(on)) != -1);
+ ck_assert_msg(bind(config->fd, host->get_sockaddr(host),
+ *host->get_sockaddr_len(host)) != -1, "%s", strerror(errno));
+ host->destroy(host);
+ ck_assert(listen(config->fd, 1) != -1);
+
+ lib->processor->set_threads(lib->processor, 8);
+
+ lib->processor->queue_job(lib->processor, (job_t*)
+ callback_job_create((void*)serve_echo, config, NULL, NULL));
+}
+
+/**
+ * Run client to perform echo test
+ */
+static void run_echo_client(echo_server_config_t *config)
+{
+ tls_socket_t *tls;
+ ssize_t len, rd, wr;
+ int fd;
+ host_t *host;
+ identification_t *server, *client = NULL;
+ char buf[128];
+
+ host = host_create_from_string(config->addr, config->port);
+ server = identification_create_from_string(config->addr);
+ if (config->cauth)
+ {
+ client = server;
+ }
+
+ fd = socket(AF_INET, SOCK_STREAM, 0);
+ ck_assert(fd != -1);
+ ck_assert(connect(fd, host->get_sockaddr(host),
+ *host->get_sockaddr_len(host)) != -1);
+ tls = tls_socket_create(FALSE, server, client, fd, NULL,
+ config->version, TRUE);
+ ck_assert(tls != NULL);
+
+ wr = rd = 0;
+ while (rd < config->data.len)
+ {
+ len = tls->write(tls, config->data.ptr + wr, config->data.len - wr);
+ ck_assert(len >= 0);
+ wr += len;
+
+ len = tls->read(tls, buf, sizeof(buf), FALSE);
+ if (len == -1 && errno == EWOULDBLOCK)
+ {
+ continue;
+ }
+ if (len == 0)
+ {
+ ck_assert_int_eq(rd, config->data.len);
+ break;
+ }
+ ck_assert(len > 0);
+ ck_assert(rd + len <= config->data.len);
+ ck_assert(memeq(buf, config->data.ptr + rd, len));
+ rd += len;
+ }
+
+ tls->destroy(tls);
+ close(fd);
+ host->destroy(host);
+ server->destroy(server);
+}
+
+/**
+ * Common test wrapper function for different test variants
+ */
+static void test_tls(tls_version_t version, u_int16_t port, bool cauth, u_int i)
+{
+ echo_server_config_t *config;
+ tls_cipher_suite_t *suites;
+ char suite[128];
+ int count;
+
+ INIT(config,
+ .version = version,
+ .addr = "127.0.0.1",
+ .port = port,
+ .cauth = cauth,
+ .data = chunk_from_chars(0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08),
+ );
+
+ start_echo_server(config);
+
+ count = tls_crypto_get_supported_suites(TRUE, &suites);
+
+ ck_assert(i < count);
+ snprintf(suite, sizeof(suite), "%N", tls_cipher_suite_names, suites[i]);
+ lib->settings->set_str(lib->settings, "%s.tls.suites", suite, lib->ns);
+
+ run_echo_client(config);
+
+ free(suites);
+
+ shutdown(config->fd, SHUT_RDWR);
+ close(config->fd);
+
+ free(config);
+}
+
+START_TEST(test_tls12)
+{
+ test_tls(TLS_1_2, 5671, FALSE, _i);
+}
+END_TEST
+
+START_TEST(test_tls12_mutual)
+{
+ test_tls(TLS_1_2, 5672, TRUE, _i);
+}
+END_TEST
+
+START_TEST(test_tls11)
+{
+ test_tls(TLS_1_1, 5673, FALSE, _i);
+}
+END_TEST
+
+START_TEST(test_tls11_mutual)
+{
+ test_tls(TLS_1_1, 5674, TRUE, _i);
+}
+END_TEST
+
+START_TEST(test_tls10)
+{
+ test_tls(TLS_1_0, 5675, FALSE, _i);
+}
+END_TEST
+
+START_TEST(test_tls10_mutual)
+{
+ test_tls(TLS_1_0, 5676, TRUE, _i);
+}
+END_TEST
+
+Suite *socket_suite_create()
+{
+ Suite *s;
+ TCase *tc;
+ int count;
+
+ count = tls_crypto_get_supported_suites(TRUE, NULL);
+
+ s = suite_create("socket");
+
+ tc = tcase_create("TLS 1.2/anon");
+ tcase_add_checked_fixture(tc, setup_creds, teardown_creds);
+ tcase_add_loop_test(tc, test_tls12, 0, count);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("TLS 1.2/mutl");
+ tcase_add_checked_fixture(tc, setup_creds, teardown_creds);
+ tcase_add_loop_test(tc, test_tls12_mutual, 0, count);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("TLS 1.1/anon");
+ tcase_add_checked_fixture(tc, setup_creds, teardown_creds);
+ tcase_add_loop_test(tc, test_tls11, 0, count);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("TLS 1.1/mutl");
+ tcase_add_checked_fixture(tc, setup_creds, teardown_creds);
+ tcase_add_loop_test(tc, test_tls11_mutual, 0, count);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("TLS 1.0/anon");
+ tcase_add_checked_fixture(tc, setup_creds, teardown_creds);
+ tcase_add_loop_test(tc, test_tls10, 0, count);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("TLS 1.0/mutl");
+ tcase_add_checked_fixture(tc, setup_creds, teardown_creds);
+ tcase_add_loop_test(tc, test_tls10_mutual, 0, count);
+ suite_add_tcase(s, tc);
+
+ return s;
+}
diff --git a/src/libtls/tests/suites/test_suites.c b/src/libtls/tests/suites/test_suites.c
new file mode 100644
index 000000000..f8ae12eb3
--- /dev/null
+++ b/src/libtls/tests/suites/test_suites.c
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2014 Martin Willi
+ * Copyright (C) 2014 revosec AG
+ *
+ * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program 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.
+ */
+
+#include <test_suite.h>
+
+#include <unistd.h>
+
+#include "tls_crypto.h"
+
+START_TEST(test_cipher_names)
+{
+ char buf[128];
+
+#define CHECK_NAME(x) { \
+ snprintf(buf, sizeof(buf), "%N", tls_cipher_suite_names, x); \
+ ck_assert_str_eq(#x, buf); }
+
+ CHECK_NAME(TLS_NULL_WITH_NULL_NULL);
+ CHECK_NAME(TLS_RSA_WITH_NULL_MD5);
+ CHECK_NAME(TLS_RSA_WITH_NULL_SHA);
+ CHECK_NAME(TLS_RSA_EXPORT_WITH_RC4_40_MD5);
+ CHECK_NAME(TLS_RSA_WITH_RC4_128_MD5);
+ CHECK_NAME(TLS_RSA_WITH_RC4_128_SHA);
+ CHECK_NAME(TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5);
+ CHECK_NAME(TLS_RSA_WITH_IDEA_CBC_SHA);
+ CHECK_NAME(TLS_RSA_EXPORT_WITH_DES40_CBC_SHA);
+ CHECK_NAME(TLS_RSA_WITH_DES_CBC_SHA);
+ CHECK_NAME(TLS_RSA_WITH_3DES_EDE_CBC_SHA);
+ CHECK_NAME(TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA);
+ CHECK_NAME(TLS_DH_DSS_WITH_DES_CBC_SHA);
+ CHECK_NAME(TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA);
+ CHECK_NAME(TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA);
+ CHECK_NAME(TLS_DH_RSA_WITH_DES_CBC_SHA);
+ CHECK_NAME(TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA);
+ CHECK_NAME(TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA);
+ CHECK_NAME(TLS_DHE_DSS_WITH_DES_CBC_SHA);
+ CHECK_NAME(TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA);
+ CHECK_NAME(TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA);
+ CHECK_NAME(TLS_DHE_RSA_WITH_DES_CBC_SHA);
+ CHECK_NAME(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA);
+ CHECK_NAME(TLS_DH_anon_EXPORT_WITH_RC4_40_MD5);
+ CHECK_NAME(TLS_DH_anon_WITH_RC4_128_MD5);
+ CHECK_NAME(TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA);
+ CHECK_NAME(TLS_DH_anon_WITH_DES_CBC_SHA);
+ CHECK_NAME(TLS_DH_anon_WITH_3DES_EDE_CBC_SHA);
+ CHECK_NAME(TLS_KRB5_WITH_DES_CBC_SHA);
+ CHECK_NAME(TLS_KRB5_WITH_3DES_EDE_CBC_SHA);
+ CHECK_NAME(TLS_KRB5_WITH_RC4_128_SHA);
+ CHECK_NAME(TLS_KRB5_WITH_IDEA_CBC_SHA);
+ CHECK_NAME(TLS_KRB5_WITH_DES_CBC_MD5);
+ CHECK_NAME(TLS_KRB5_WITH_3DES_EDE_CBC_MD5);
+ CHECK_NAME(TLS_KRB5_WITH_RC4_128_MD5);
+ CHECK_NAME(TLS_KRB5_WITH_IDEA_CBC_MD5);
+ CHECK_NAME(TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA);
+ CHECK_NAME(TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA);
+ CHECK_NAME(TLS_KRB5_EXPORT_WITH_RC4_40_SHA);
+ CHECK_NAME(TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5);
+ CHECK_NAME(TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5);
+ CHECK_NAME(TLS_KRB5_EXPORT_WITH_RC4_40_MD5);
+ CHECK_NAME(TLS_PSK_WITH_NULL_SHA);
+ CHECK_NAME(TLS_DHE_PSK_WITH_NULL_SHA);
+ CHECK_NAME(TLS_RSA_PSK_WITH_NULL_SHA);
+ CHECK_NAME(TLS_RSA_WITH_AES_128_CBC_SHA);
+ CHECK_NAME(TLS_DH_DSS_WITH_AES_128_CBC_SHA);
+ CHECK_NAME(TLS_DH_RSA_WITH_AES_128_CBC_SHA);
+ CHECK_NAME(TLS_DHE_DSS_WITH_AES_128_CBC_SHA);
+ CHECK_NAME(TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
+ CHECK_NAME(TLS_DH_anon_WITH_AES_128_CBC_SHA);
+ CHECK_NAME(TLS_RSA_WITH_AES_256_CBC_SHA);
+ CHECK_NAME(TLS_DH_DSS_WITH_AES_256_CBC_SHA);
+ CHECK_NAME(TLS_DH_RSA_WITH_AES_256_CBC_SHA);
+ CHECK_NAME(TLS_DHE_DSS_WITH_AES_256_CBC_SHA);
+ CHECK_NAME(TLS_DHE_RSA_WITH_AES_256_CBC_SHA);
+ CHECK_NAME(TLS_DH_anon_WITH_AES_256_CBC_SHA);
+ CHECK_NAME(TLS_RSA_WITH_NULL_SHA256);
+ CHECK_NAME(TLS_RSA_WITH_AES_128_CBC_SHA256);
+ CHECK_NAME(TLS_RSA_WITH_AES_256_CBC_SHA256);
+ CHECK_NAME(TLS_DH_DSS_WITH_AES_128_CBC_SHA256);
+ CHECK_NAME(TLS_DH_RSA_WITH_AES_128_CBC_SHA256);
+ CHECK_NAME(TLS_DHE_DSS_WITH_AES_128_CBC_SHA256);
+ CHECK_NAME(TLS_RSA_WITH_CAMELLIA_128_CBC_SHA);
+ CHECK_NAME(TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA);
+ CHECK_NAME(TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA);
+ CHECK_NAME(TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA);
+ CHECK_NAME(TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA);
+ CHECK_NAME(TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA);
+ CHECK_NAME(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256);
+ CHECK_NAME(TLS_DH_DSS_WITH_AES_256_CBC_SHA256);
+ CHECK_NAME(TLS_DH_RSA_WITH_AES_256_CBC_SHA256);
+ CHECK_NAME(TLS_DHE_DSS_WITH_AES_256_CBC_SHA256);
+ CHECK_NAME(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256);
+ CHECK_NAME(TLS_DH_anon_WITH_AES_128_CBC_SHA256);
+ CHECK_NAME(TLS_DH_anon_WITH_AES_256_CBC_SHA256);
+ CHECK_NAME(TLS_RSA_WITH_CAMELLIA_256_CBC_SHA);
+ CHECK_NAME(TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA);
+ CHECK_NAME(TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA);
+ CHECK_NAME(TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA);
+ CHECK_NAME(TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA);
+ CHECK_NAME(TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA);
+ CHECK_NAME(TLS_PSK_WITH_RC4_128_SHA);
+ CHECK_NAME(TLS_PSK_WITH_3DES_EDE_CBC_SHA);
+ CHECK_NAME(TLS_PSK_WITH_AES_128_CBC_SHA);
+ CHECK_NAME(TLS_PSK_WITH_AES_256_CBC_SHA);
+ CHECK_NAME(TLS_DHE_PSK_WITH_RC4_128_SHA);
+ CHECK_NAME(TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA);
+ CHECK_NAME(TLS_DHE_PSK_WITH_AES_128_CBC_SHA);
+ CHECK_NAME(TLS_DHE_PSK_WITH_AES_256_CBC_SHA);
+ CHECK_NAME(TLS_RSA_PSK_WITH_RC4_128_SHA);
+ CHECK_NAME(TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA);
+ CHECK_NAME(TLS_RSA_PSK_WITH_AES_128_CBC_SHA);
+ CHECK_NAME(TLS_RSA_PSK_WITH_AES_256_CBC_SHA);
+ CHECK_NAME(TLS_RSA_WITH_SEED_CBC_SHA);
+ CHECK_NAME(TLS_DH_DSS_WITH_SEED_CBC_SHA);
+ CHECK_NAME(TLS_DH_RSA_WITH_SEED_CBC_SHA);
+ CHECK_NAME(TLS_DHE_DSS_WITH_SEED_CBC_SHA);
+ CHECK_NAME(TLS_DHE_RSA_WITH_SEED_CBC_SHA);
+ CHECK_NAME(TLS_DH_anon_WITH_SEED_CBC_SHA);
+ CHECK_NAME(TLS_RSA_WITH_AES_128_GCM_SHA256);
+ CHECK_NAME(TLS_RSA_WITH_AES_256_GCM_SHA384);
+ CHECK_NAME(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256);
+ CHECK_NAME(TLS_DHE_RSA_WITH_AES_256_GCM_SHA384);
+ CHECK_NAME(TLS_DH_RSA_WITH_AES_128_GCM_SHA256);
+ CHECK_NAME(TLS_DH_RSA_WITH_AES_256_GCM_SHA384);
+ CHECK_NAME(TLS_DHE_DSS_WITH_AES_128_GCM_SHA256);
+ CHECK_NAME(TLS_DHE_DSS_WITH_AES_256_GCM_SHA384);
+ CHECK_NAME(TLS_DH_DSS_WITH_AES_128_GCM_SHA256);
+ CHECK_NAME(TLS_DH_DSS_WITH_AES_256_GCM_SHA384);
+ CHECK_NAME(TLS_DH_anon_WITH_AES_128_GCM_SHA256);
+ CHECK_NAME(TLS_DH_anon_WITH_AES_256_GCM_SHA384);
+ CHECK_NAME(TLS_PSK_WITH_AES_128_GCM_SHA256);
+ CHECK_NAME(TLS_PSK_WITH_AES_256_GCM_SHA384);
+ CHECK_NAME(TLS_DHE_PSK_WITH_AES_128_GCM_SHA256);
+ CHECK_NAME(TLS_DHE_PSK_WITH_AES_256_GCM_SHA384);
+ CHECK_NAME(TLS_RSA_PSK_WITH_AES_128_GCM_SHA256);
+ CHECK_NAME(TLS_RSA_PSK_WITH_AES_256_GCM_SHA384);
+ CHECK_NAME(TLS_PSK_WITH_AES_128_CBC_SHA256);
+ CHECK_NAME(TLS_PSK_WITH_AES_256_CBC_SHA384);
+ CHECK_NAME(TLS_PSK_WITH_NULL_SHA256);
+ CHECK_NAME(TLS_PSK_WITH_NULL_SHA384);
+ CHECK_NAME(TLS_DHE_PSK_WITH_AES_128_CBC_SHA256);
+ CHECK_NAME(TLS_DHE_PSK_WITH_AES_256_CBC_SHA384);
+ CHECK_NAME(TLS_DHE_PSK_WITH_NULL_SHA256);
+ CHECK_NAME(TLS_DHE_PSK_WITH_NULL_SHA384);
+ CHECK_NAME(TLS_RSA_PSK_WITH_AES_128_CBC_SHA256);
+ CHECK_NAME(TLS_RSA_PSK_WITH_AES_256_CBC_SHA384);
+ CHECK_NAME(TLS_RSA_PSK_WITH_NULL_SHA256);
+ CHECK_NAME(TLS_RSA_PSK_WITH_NULL_SHA384);
+ CHECK_NAME(TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256);
+ CHECK_NAME(TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256);
+ CHECK_NAME(TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256);
+ CHECK_NAME(TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256);
+ CHECK_NAME(TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256);
+ CHECK_NAME(TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256);
+ CHECK_NAME(TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256);
+ CHECK_NAME(TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256);
+ CHECK_NAME(TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256);
+ CHECK_NAME(TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256);
+ CHECK_NAME(TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256);
+ CHECK_NAME(TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256);
+ CHECK_NAME(TLS_EMPTY_RENEGOTIATION_INFO_SCSV);
+ CHECK_NAME(TLS_ECDH_ECDSA_WITH_NULL_SHA);
+ CHECK_NAME(TLS_ECDH_ECDSA_WITH_RC4_128_SHA);
+ CHECK_NAME(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA);
+ CHECK_NAME(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA);
+ CHECK_NAME(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA);
+ CHECK_NAME(TLS_ECDHE_ECDSA_WITH_NULL_SHA);
+ CHECK_NAME(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA);
+ CHECK_NAME(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA);
+ CHECK_NAME(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA);
+ CHECK_NAME(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA);
+ CHECK_NAME(TLS_ECDH_RSA_WITH_NULL_SHA);
+ CHECK_NAME(TLS_ECDH_RSA_WITH_RC4_128_SHA);
+ CHECK_NAME(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA);
+ CHECK_NAME(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA);
+ CHECK_NAME(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA);
+ CHECK_NAME(TLS_ECDHE_RSA_WITH_NULL_SHA);
+ CHECK_NAME(TLS_ECDHE_RSA_WITH_RC4_128_SHA);
+ CHECK_NAME(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA);
+ CHECK_NAME(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA);
+ CHECK_NAME(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA);
+ CHECK_NAME(TLS_ECDH_anon_WITH_NULL_SHA);
+ CHECK_NAME(TLS_ECDH_anon_WITH_RC4_128_SHA);
+ CHECK_NAME(TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA);
+ CHECK_NAME(TLS_ECDH_anon_WITH_AES_128_CBC_SHA);
+ CHECK_NAME(TLS_ECDH_anon_WITH_AES_256_CBC_SHA);
+ CHECK_NAME(TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA);
+ CHECK_NAME(TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA);
+ CHECK_NAME(TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA);
+ CHECK_NAME(TLS_SRP_SHA_WITH_AES_128_CBC_SHA);
+ CHECK_NAME(TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA);
+ CHECK_NAME(TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA);
+ CHECK_NAME(TLS_SRP_SHA_WITH_AES_256_CBC_SHA);
+ CHECK_NAME(TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA);
+ CHECK_NAME(TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA);
+ CHECK_NAME(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256);
+ CHECK_NAME(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384);
+ CHECK_NAME(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256);
+ CHECK_NAME(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384);
+ CHECK_NAME(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256);
+ CHECK_NAME(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384);
+ CHECK_NAME(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256);
+ CHECK_NAME(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384);
+ CHECK_NAME(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256);
+ CHECK_NAME(TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384);
+ CHECK_NAME(TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256);
+ CHECK_NAME(TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384);
+ CHECK_NAME(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256);
+ CHECK_NAME(TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384);
+ CHECK_NAME(TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256);
+ CHECK_NAME(TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384);
+ CHECK_NAME(TLS_ECDHE_PSK_WITH_RC4_128_SHA);
+ CHECK_NAME(TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA);
+ CHECK_NAME(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA);
+ CHECK_NAME(TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA);
+ CHECK_NAME(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256);
+ CHECK_NAME(TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384);
+ CHECK_NAME(TLS_ECDHE_PSK_WITH_NULL_SHA);
+ CHECK_NAME(TLS_ECDHE_PSK_WITH_NULL_SHA256);
+ CHECK_NAME(TLS_ECDHE_PSK_WITH_NULL_SHA384);
+}
+END_TEST
+
+Suite *suites_suite_create()
+{
+ Suite *s;
+ TCase *tc;
+
+ s = suite_create("suites");
+
+ tc = tcase_create("cipher-names");
+ tcase_add_test(tc, test_cipher_names);
+ suite_add_tcase(s, tc);
+
+ return s;
+}
diff --git a/src/libtls/tests/tls_tests.c b/src/libtls/tests/tls_tests.c
new file mode 100644
index 000000000..2c2c5bacc
--- /dev/null
+++ b/src/libtls/tests/tls_tests.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2014 Martin Willi
+ * Copyright (C) 2014 revosec AG
+ *
+ * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program 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.
+ */
+
+#include <test_runner.h>
+
+/* declare test suite constructors */
+#define TEST_SUITE(x) test_suite_t* x();
+#define TEST_SUITE_DEPEND(x, ...) TEST_SUITE(x)
+#include "tls_tests.h"
+#undef TEST_SUITE
+#undef TEST_SUITE_DEPEND
+
+static test_configuration_t tests[] = {
+#define TEST_SUITE(x) \
+ { .suite = x, },
+#define TEST_SUITE_DEPEND(x, type, args) \
+ { .suite = x, .feature = PLUGIN_DEPENDS(type, args) },
+#include "tls_tests.h"
+ { .suite = NULL, }
+};
+
+static bool test_runner_init(bool init)
+{
+ if (init)
+ {
+ plugin_loader_add_plugindirs(PLUGINDIR, PLUGINS);
+ if (!lib->plugins->load(lib->plugins, PLUGINS))
+ {
+ return FALSE;
+ }
+ }
+ else
+ {
+ lib->credmgr->flush_cache(lib->credmgr, CERT_ANY);
+ lib->processor->set_threads(lib->processor, 0);
+ lib->processor->cancel(lib->processor);
+ lib->plugins->unload(lib->plugins);
+ }
+ return TRUE;
+}
+
+int main(int argc, char *argv[])
+{
+ return test_runner_run("libtls", tests, test_runner_init);
+}
diff --git a/src/libtls/tests/tls_tests.h b/src/libtls/tests/tls_tests.h
new file mode 100644
index 000000000..489b2ddb1
--- /dev/null
+++ b/src/libtls/tests/tls_tests.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2014 Martin Willi
+ * Copyright (C) 2014 revosec AG
+ *
+ * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program 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.
+ */
+
+TEST_SUITE(socket_suite_create)
+TEST_SUITE(suites_suite_create)
diff --git a/src/libtls/tls.c b/src/libtls/tls.c
index 6b51e7593..6e2955814 100644
--- a/src/libtls/tls.c
+++ b/src/libtls/tls.c
@@ -218,14 +218,7 @@ METHOD(tls_t, process, status_t,
{
if (this->input.len == 0)
{
- if (buflen < sizeof(tls_record_t))
- {
- DBG2(DBG_TLS, "received incomplete TLS record header");
- memcpy(&this->head, buf, buflen);
- this->headpos = buflen;
- break;
- }
- while (TRUE)
+ while (buflen >= sizeof(tls_record_t))
{
/* try to process records inline */
record = buf;
@@ -252,6 +245,13 @@ METHOD(tls_t, process, status_t,
return NEED_MORE;
}
}
+ if (buflen < sizeof(tls_record_t))
+ {
+ DBG2(DBG_TLS, "received incomplete TLS record header");
+ memcpy(&this->head, buf, buflen);
+ this->headpos = buflen;
+ break;
+ }
}
len = min(buflen, this->input.len - this->inpos);
memcpy(this->input.ptr + this->inpos, buf, len);
@@ -447,6 +447,7 @@ tls_t *tls_create(bool is_server, identification_t *server,
case TLS_PURPOSE_EAP_TTLS:
case TLS_PURPOSE_EAP_PEAP:
case TLS_PURPOSE_GENERIC:
+ case TLS_PURPOSE_GENERIC_NULLOK:
break;
default:
return NULL;
diff --git a/src/libtls/tls.h b/src/libtls/tls.h
index db332fbbf..fc1d9b9fd 100644
--- a/src/libtls/tls.h
+++ b/src/libtls/tls.h
@@ -107,6 +107,8 @@ enum tls_purpose_t {
TLS_PURPOSE_EAP_PEAP,
/** non-EAP TLS */
TLS_PURPOSE_GENERIC,
+ /** non-EAP TLS accepting NULL encryption */
+ TLS_PURPOSE_GENERIC_NULLOK,
/** EAP binding for TNC */
TLS_PURPOSE_EAP_TNC
};
diff --git a/src/libtls/tls_aead.c b/src/libtls/tls_aead.c
new file mode 100644
index 000000000..1d0779dc0
--- /dev/null
+++ b/src/libtls/tls_aead.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2014 Martin Willi
+ * Copyright (C) 2014 revosec AG
+ *
+ * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program 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.
+ */
+
+#include "tls_aead.h"
+
+#include <crypto/iv/iv_gen_rand.h>
+
+typedef struct private_tls_aead_t private_tls_aead_t;
+
+/**
+ * Private data of an tls_aead_t object.
+ */
+struct private_tls_aead_t {
+
+ /**
+ * Public tls_aead_t interface.
+ */
+ tls_aead_t public;
+
+ /**
+ * AEAD transform
+ */
+ aead_t *aead;
+
+ /**
+ * Size of salt, the implicit nonce
+ */
+ size_t salt;
+};
+
+/**
+ * Associated header data to create signature over
+ */
+typedef struct __attribute__((__packed__)) {
+ u_int64_t seq;
+ u_int8_t type;
+ u_int16_t version;
+ u_int16_t length;
+} sigheader_t;
+
+METHOD(tls_aead_t, encrypt, bool,
+ private_tls_aead_t *this, tls_version_t version, tls_content_type_t type,
+ u_int64_t seq, chunk_t *data)
+{
+ chunk_t assoc, encrypted, iv, plain;
+ u_int8_t icvlen;
+ sigheader_t hdr;
+ iv_gen_t *gen;
+
+ gen = this->aead->get_iv_gen(this->aead);
+ iv.len = this->aead->get_iv_size(this->aead);
+ icvlen = this->aead->get_icv_size(this->aead);
+
+ encrypted = chunk_alloc(iv.len + data->len + icvlen);
+ iv.ptr = encrypted.ptr;
+ if (!gen->get_iv(gen, seq, iv.len, iv.ptr))
+ {
+ chunk_free(&encrypted);
+ return FALSE;
+ }
+ memcpy(encrypted.ptr + iv.len, data->ptr, data->len);
+ plain = chunk_skip(encrypted, iv.len);
+ plain.len -= icvlen;
+
+ hdr.type = type;
+ htoun64(&hdr.seq, seq);
+ htoun16(&hdr.version, version);
+ htoun16(&hdr.length, plain.len);
+
+ assoc = chunk_from_thing(hdr);
+ if (!this->aead->encrypt(this->aead, plain, assoc, iv, NULL))
+ {
+ return FALSE;
+ }
+ chunk_free(data);
+ *data = encrypted;
+ return TRUE;
+}
+
+METHOD(tls_aead_t, decrypt, bool,
+ private_tls_aead_t *this, tls_version_t version, tls_content_type_t type,
+ u_int64_t seq, chunk_t *data)
+{
+ chunk_t assoc, iv;
+ u_int8_t icvlen;
+ sigheader_t hdr;
+
+ iv.len = this->aead->get_iv_size(this->aead);
+ if (data->len < iv.len)
+ {
+ return FALSE;
+ }
+ iv.ptr = data->ptr;
+ *data = chunk_skip(*data, iv.len);
+ icvlen = this->aead->get_icv_size(this->aead);
+ if (data->len < icvlen)
+ {
+ return FALSE;
+ }
+
+ hdr.type = type;
+ htoun64(&hdr.seq, seq);
+ htoun16(&hdr.version, version);
+ htoun16(&hdr.length, data->len - icvlen);
+
+ assoc = chunk_from_thing(hdr);
+ if (!this->aead->decrypt(this->aead, *data, assoc, iv, NULL))
+ {
+ return FALSE;
+ }
+ data->len -= icvlen;
+ return TRUE;
+}
+
+METHOD(tls_aead_t, get_mac_key_size, size_t,
+ private_tls_aead_t *this)
+{
+ return 0;
+}
+
+METHOD(tls_aead_t, get_encr_key_size, size_t,
+ private_tls_aead_t *this)
+{
+ return this->aead->get_key_size(this->aead) - this->salt;
+}
+
+METHOD(tls_aead_t, get_iv_size, size_t,
+ private_tls_aead_t *this)
+{
+ return this->salt;
+}
+
+METHOD(tls_aead_t, set_keys, bool,
+ private_tls_aead_t *this, chunk_t mac, chunk_t encr, chunk_t iv)
+{
+ chunk_t key;
+
+ if (mac.len)
+ {
+ return FALSE;
+ }
+ key = chunk_cata("cc", encr, iv);
+ return this->aead->set_key(this->aead, key);
+}
+
+METHOD(tls_aead_t, destroy, void,
+ private_tls_aead_t *this)
+{
+ this->aead->destroy(this->aead);
+ free(this);
+}
+
+/**
+ * See header
+ */
+tls_aead_t *tls_aead_create_aead(encryption_algorithm_t encr, size_t encr_size)
+{
+ private_tls_aead_t *this;
+ size_t salt;
+
+ switch (encr)
+ {
+ case ENCR_AES_GCM_ICV8:
+ case ENCR_AES_GCM_ICV12:
+ case ENCR_AES_GCM_ICV16:
+ case ENCR_AES_CCM_ICV8:
+ case ENCR_AES_CCM_ICV12:
+ case ENCR_AES_CCM_ICV16:
+ case ENCR_CAMELLIA_CCM_ICV8:
+ case ENCR_CAMELLIA_CCM_ICV12:
+ case ENCR_CAMELLIA_CCM_ICV16:
+ salt = 4;
+ break;
+ default:
+ return NULL;
+ }
+
+ INIT(this,
+ .public = {
+ .encrypt = _encrypt,
+ .decrypt = _decrypt,
+ .get_mac_key_size = _get_mac_key_size,
+ .get_encr_key_size = _get_encr_key_size,
+ .get_iv_size = _get_iv_size,
+ .set_keys = _set_keys,
+ .destroy = _destroy,
+ },
+ .aead = lib->crypto->create_aead(lib->crypto, encr, encr_size, salt),
+ .salt = salt,
+ );
+
+ if (!this->aead)
+ {
+ free(this);
+ return NULL;
+ }
+
+ if (this->aead->get_block_size(this->aead) != 1)
+ { /* TLS does not define any padding scheme for AEAD */
+ destroy(this);
+ return NULL;
+ }
+
+ return &this->public;
+}
diff --git a/src/libtls/tls_aead.h b/src/libtls/tls_aead.h
new file mode 100644
index 000000000..1d5ba92b5
--- /dev/null
+++ b/src/libtls/tls_aead.h
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2014 Martin Willi
+ * Copyright (C) 2014 revosec AG
+ *
+ * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program 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.
+ */
+
+/**
+ * @defgroup tls_aead tls_aead
+ * @{ @ingroup tls
+ */
+
+#ifndef TLS_AEAD_H_
+#define TLS_AEAD_H_
+
+typedef struct tls_aead_t tls_aead_t;
+
+#include "tls.h"
+
+/**
+ * TLS specific AEAD interface, includes padding.
+ *
+ * As TLS uses sign-then-encrypt instead of the more modern encrypt-then-sign,
+ * we can't directly abstract traditional transforms using our aead_t interface.
+ * With traditional transforms, the AEAD operation has to manage padding, as
+ * the MAC is calculated over unpadded data.
+ */
+struct tls_aead_t {
+
+ /**
+ * Encrypt and sign a TLS record.
+ *
+ * The plain data chunk gets freed on success, and the data chunk
+ * gets updated with a new allocation of the encrypted data.
+ * If next_iv is given, it must contain the IV for this operation. It
+ * gets updated to the IV for the next record.
+ *
+ * @param version TLS version
+ * @param type TLS content type
+ * @param seq record sequence number
+ * @param data data to encrypt, encryption result
+ * @return TRUE if successfully encrypted
+ */
+ bool (*encrypt)(tls_aead_t *this, tls_version_t version,
+ tls_content_type_t type, u_int64_t seq, chunk_t *data);
+
+ /**
+ * Decrypt and verify a TLS record.
+ *
+ * The passed encrypted data chunk gets updated to the decrypted record
+ * length, decryption is done inline.
+ *
+ * @param version TLS version
+ * @param type TLS content type
+ * @param seq record sequence number
+ * @param data data to decrypt, decrypted result
+ * @return TRUE if successfully decrypted
+ */
+ bool (*decrypt)(tls_aead_t *this, tls_version_t version,
+ tls_content_type_t type, u_int64_t seq, chunk_t *data);
+
+ /**
+ * Get the authentication key size.
+ *
+ * @return key size, in bytes, 0 if not used
+ */
+ size_t (*get_mac_key_size)(tls_aead_t *this);
+
+ /**
+ * Get the encrytion key size, if used.
+ *
+ * @return key size, in bytes, 0 if not used
+ */
+ size_t (*get_encr_key_size)(tls_aead_t *this);
+
+ /**
+ * Get the size of implicit IV (or AEAD salt), if used.
+ *
+ * @return IV/salt size, in bytes, 0 if not used
+ */
+ size_t (*get_iv_size)(tls_aead_t *this);
+
+ /**
+ * Set the keys used by an AEAD transform.
+ *
+ * @param mac authentication key, if used
+ * @param encr encryption key, if used
+ * @param iv initial implicit IV or AEAD salt, if any
+ * @return TRUE if key valid and set
+ */
+ bool (*set_keys)(tls_aead_t *this, chunk_t mac, chunk_t ecnr, chunk_t iv);
+
+ /**
+ * Destroy a tls_aead_t.
+ */
+ void (*destroy)(tls_aead_t *this);
+};
+
+/**
+ * Create a tls_aead instance using traditional transforms, explicit IV.
+ *
+ * An explicit IV means that the IV is prepended to each TLS record. This is
+ * the mechanism used in TLS 1.1 and newer.
+ *
+ * @param mac integrity protection algorithm
+ * @param encr encryption algorithm
+ * @param encr_size encryption key size, in bytes
+ * @return TLS AEAD transform
+ */
+tls_aead_t *tls_aead_create_explicit(integrity_algorithm_t mac,
+ encryption_algorithm_t encr, size_t encr_size);
+
+/**
+ * Create a tls_aead instance using traditional transforms, implicit IV.
+ *
+ * An implicit IV uses a first IV derived from the TLS keymat, which then
+ * gets replaced by the last encrypted records tail. This is the mechanism
+ * used for TLS 1.0 and older.
+ *
+ * @param mac integrity protection algorithm
+ * @param encr encryption algorithm
+ * @param encr_size encryption key size, in bytes
+ * @return TLS AEAD transform
+ */
+tls_aead_t *tls_aead_create_implicit(integrity_algorithm_t mac,
+ encryption_algorithm_t encr, size_t encr_size);
+
+/**
+ * Create a tls_aead instance using NULL encryption.
+ *
+ * As no IV is involved with null encryption, this AEAD works with any
+ * version of TLS.
+ *
+ * @param mac integrity protection algorithm
+ * @return TLS AEAD transform
+ */
+tls_aead_t *tls_aead_create_null(integrity_algorithm_t mac);
+
+/**
+ * Create a tls_aead instance using real a AEAD cipher.
+ *
+ * @param encr AEAD encryption algorithm
+ * @param encr_size encryption key size, in bytes
+ * @return TLS AEAD transform
+ */
+tls_aead_t *tls_aead_create_aead(encryption_algorithm_t encr, size_t encr_size);
+
+#endif /** TLS_AEAD_H_ @}*/
diff --git a/src/libtls/tls_aead_expl.c b/src/libtls/tls_aead_expl.c
new file mode 100644
index 000000000..5e4d33e14
--- /dev/null
+++ b/src/libtls/tls_aead_expl.c
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2014 Martin Willi
+ * Copyright (C) 2014 revosec AG
+ *
+ * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program 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.
+ */
+
+#include "tls_aead.h"
+
+#include <crypto/iv/iv_gen_rand.h>
+
+typedef struct private_tls_aead_t private_tls_aead_t;
+
+/**
+ * Private data of an tls_aead_t object.
+ */
+struct private_tls_aead_t {
+
+ /**
+ * Public tls_aead_t interface.
+ */
+ tls_aead_t public;
+
+ /**
+ * traditional crypter
+ */
+ crypter_t *crypter;
+
+ /**
+ * traditional signer
+ */
+ signer_t *signer;
+
+ /**
+ * IV generator
+ */
+ iv_gen_t *iv_gen;
+};
+
+/**
+ * Associated header data to create signature over
+ */
+typedef struct __attribute__((__packed__)) {
+ u_int64_t seq;
+ u_int8_t type;
+ u_int16_t version;
+ u_int16_t length;
+} sigheader_t;
+
+METHOD(tls_aead_t, encrypt, bool,
+ private_tls_aead_t *this, tls_version_t version, tls_content_type_t type,
+ u_int64_t seq, chunk_t *data)
+{
+ chunk_t assoc, mac, padding, iv;
+ u_int8_t bs, padlen;
+ sigheader_t hdr;
+
+ hdr.type = type;
+ htoun64(&hdr.seq, seq);
+ htoun16(&hdr.version, version);
+ htoun16(&hdr.length, data->len);
+
+ assoc = chunk_from_thing(hdr);
+ if (!this->signer->get_signature(this->signer, assoc, NULL) ||
+ !this->signer->allocate_signature(this->signer, *data, &mac))
+ {
+ return FALSE;
+ }
+ bs = this->crypter->get_block_size(this->crypter);
+ padlen = pad_len(data->len + mac.len + 1, bs);
+
+ padding = chunk_alloca(padlen);
+ memset(padding.ptr, padlen, padding.len);
+
+ /* TLSv1.1 uses random IVs, prepended to record */
+ iv.len = this->crypter->get_iv_size(this->crypter);
+ iv = chunk_alloca(iv.len);
+ if (!this->iv_gen->get_iv(this->iv_gen, seq, iv.len, iv.ptr))
+ {
+ return FALSE;
+ }
+ *data = chunk_cat("mmcc", *data, mac, padding, chunk_from_thing(padlen));
+ /* encrypt inline */
+ if (!this->crypter->encrypt(this->crypter, *data, iv, NULL))
+ {
+ free(data->ptr);
+ return FALSE;
+ }
+ /* prepend IV */
+ *data = chunk_cat("cm", iv, *data);
+ return TRUE;
+}
+
+METHOD(tls_aead_t, decrypt, bool,
+ private_tls_aead_t *this, tls_version_t version, tls_content_type_t type,
+ u_int64_t seq, chunk_t *data)
+{
+ chunk_t assoc, mac, iv;
+ u_int8_t bs, padlen;
+ sigheader_t hdr;
+
+ iv.len = this->crypter->get_iv_size(this->crypter);
+ if (data->len < iv.len)
+ {
+ return FALSE;
+ }
+ iv.ptr = data->ptr;
+ *data = chunk_skip(*data, iv.len);
+ bs = this->crypter->get_block_size(this->crypter);
+ if (data->len < bs || data->len % bs)
+ {
+ return FALSE;
+ }
+ if (!this->crypter->decrypt(this->crypter, *data, iv, NULL))
+ {
+ return FALSE;
+ }
+ padlen = data->ptr[data->len - 1];
+ if (padlen < data->len)
+ { /* If padding looks valid, remove it */
+ data->len -= padlen + 1;
+ }
+
+ bs = this->signer->get_block_size(this->signer);
+ if (data->len < bs)
+ {
+ return FALSE;
+ }
+ mac = chunk_skip(*data, data->len - bs);
+ data->len -= bs;
+
+ hdr.type = type;
+ htoun64(&hdr.seq, seq);
+ htoun16(&hdr.version, version);
+ htoun16(&hdr.length, data->len);
+
+ assoc = chunk_from_thing(hdr);
+ if (!this->signer->get_signature(this->signer, assoc, NULL) ||
+ !this->signer->verify_signature(this->signer, *data, mac))
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+METHOD(tls_aead_t, get_mac_key_size, size_t,
+ private_tls_aead_t *this)
+{
+ return this->signer->get_key_size(this->signer);
+}
+
+METHOD(tls_aead_t, get_encr_key_size, size_t,
+ private_tls_aead_t *this)
+{
+ return this->crypter->get_key_size(this->crypter);
+}
+
+METHOD(tls_aead_t, get_iv_size, size_t,
+ private_tls_aead_t *this)
+{
+ return 0;
+}
+
+METHOD(tls_aead_t, set_keys, bool,
+ private_tls_aead_t *this, chunk_t mac, chunk_t encr, chunk_t iv)
+{
+ if (iv.len)
+ {
+ return FALSE;
+ }
+ return this->signer->set_key(this->signer, mac) &&
+ this->crypter->set_key(this->crypter, encr);
+}
+
+METHOD(tls_aead_t, destroy, void,
+ private_tls_aead_t *this)
+{
+ this->iv_gen->destroy(this->iv_gen);
+ DESTROY_IF(this->crypter);
+ DESTROY_IF(this->signer);
+ free(this);
+}
+
+/**
+ * See header
+ */
+tls_aead_t *tls_aead_create_explicit(integrity_algorithm_t mac,
+ encryption_algorithm_t encr, size_t encr_size)
+{
+ private_tls_aead_t *this;
+
+ INIT(this,
+ .public = {
+ .encrypt = _encrypt,
+ .decrypt = _decrypt,
+ .get_mac_key_size = _get_mac_key_size,
+ .get_encr_key_size = _get_encr_key_size,
+ .get_iv_size = _get_iv_size,
+ .set_keys = _set_keys,
+ .destroy = _destroy,
+ },
+ .crypter = lib->crypto->create_crypter(lib->crypto, encr, encr_size),
+ .signer = lib->crypto->create_signer(lib->crypto, mac),
+ .iv_gen = iv_gen_rand_create(),
+ );
+
+ if (!this->crypter || !this->signer)
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ return &this->public;
+}
diff --git a/src/libtls/tls_aead_impl.c b/src/libtls/tls_aead_impl.c
new file mode 100644
index 000000000..fb14026e0
--- /dev/null
+++ b/src/libtls/tls_aead_impl.c
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2014 Martin Willi
+ * Copyright (C) 2014 revosec AG
+ *
+ * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program 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.
+ */
+
+#include "tls_aead.h"
+
+typedef struct private_tls_aead_t private_tls_aead_t;
+
+/**
+ * Private data of an tls_aead_t object.
+ */
+struct private_tls_aead_t {
+
+ /**
+ * Public tls_aead_t interface.
+ */
+ tls_aead_t public;
+
+ /**
+ * traditional crypter
+ */
+ crypter_t *crypter;
+
+ /**
+ * traditional signer
+ */
+ signer_t *signer;
+
+ /**
+ * Next implicit IV
+ */
+ chunk_t iv;
+};
+
+/**
+ * Associated header data to create signature over
+ */
+typedef struct __attribute__((__packed__)) {
+ u_int64_t seq;
+ u_int8_t type;
+ u_int16_t version;
+ u_int16_t length;
+} sigheader_t;
+
+METHOD(tls_aead_t, encrypt, bool,
+ private_tls_aead_t *this, tls_version_t version,
+ tls_content_type_t type, u_int64_t seq, chunk_t *data)
+{
+ chunk_t assoc, mac, padding;
+ u_int8_t bs, padlen;
+ sigheader_t hdr;
+
+ hdr.type = type;
+ htoun64(&hdr.seq, seq);
+ htoun16(&hdr.version, version);
+ htoun16(&hdr.length, data->len);
+
+ assoc = chunk_from_thing(hdr);
+ if (!this->signer->get_signature(this->signer, assoc, NULL) ||
+ !this->signer->allocate_signature(this->signer, *data, &mac))
+ {
+ return FALSE;
+ }
+ bs = this->crypter->get_block_size(this->crypter);
+ padlen = pad_len(data->len + mac.len + 1, bs);
+
+ padding = chunk_alloca(padlen);
+ memset(padding.ptr, padlen, padding.len);
+
+ *data = chunk_cat("mmcc", *data, mac, padding, chunk_from_thing(padlen));
+ /* encrypt inline */
+ if (!this->crypter->encrypt(this->crypter, *data, this->iv, NULL))
+ {
+ return FALSE;
+ }
+ if (data->len < this->iv.len)
+ {
+ return FALSE;
+ }
+ /* next record IV is last ciphertext block of this record */
+ memcpy(this->iv.ptr, data->ptr + data->len - this->iv.len, this->iv.len);
+ return TRUE;
+}
+
+METHOD(tls_aead_t, decrypt, bool,
+ private_tls_aead_t *this, tls_version_t version,
+ tls_content_type_t type, u_int64_t seq, chunk_t *data)
+{
+ chunk_t assoc, mac, iv;
+ u_int8_t bs, padlen;
+ sigheader_t hdr;
+
+ bs = this->crypter->get_block_size(this->crypter);
+ if (data->len < bs || data->len < this->iv.len || data->len % bs)
+ {
+ return FALSE;
+ }
+ iv = chunk_alloca(this->iv.len);
+ memcpy(iv.ptr, this->iv.ptr, this->iv.len);
+ memcpy(this->iv.ptr, data->ptr + data->len - this->iv.len, this->iv.len);
+ if (!this->crypter->decrypt(this->crypter, *data, iv, NULL))
+ {
+ return FALSE;
+ }
+ padlen = data->ptr[data->len - 1];
+ if (padlen < data->len)
+ { /* If padding looks valid, remove it */
+ data->len -= padlen + 1;
+ }
+
+ bs = this->signer->get_block_size(this->signer);
+ if (data->len < bs)
+ {
+ return FALSE;
+ }
+ mac = chunk_skip(*data, data->len - bs);
+ data->len -= bs;
+
+ hdr.type = type;
+ htoun64(&hdr.seq, seq);
+ htoun16(&hdr.version, version);
+ htoun16(&hdr.length, data->len);
+
+ assoc = chunk_from_thing(hdr);
+ if (!this->signer->get_signature(this->signer, assoc, NULL) ||
+ !this->signer->verify_signature(this->signer, *data, mac))
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+METHOD(tls_aead_t, get_mac_key_size, size_t,
+ private_tls_aead_t *this)
+{
+ return this->signer->get_key_size(this->signer);
+}
+
+METHOD(tls_aead_t, get_encr_key_size, size_t,
+ private_tls_aead_t *this)
+{
+ return this->crypter->get_key_size(this->crypter);
+}
+
+METHOD(tls_aead_t, get_iv_size, size_t,
+ private_tls_aead_t *this)
+{
+ return this->iv.len;
+}
+
+METHOD(tls_aead_t, set_keys, bool,
+ private_tls_aead_t *this, chunk_t mac, chunk_t encr, chunk_t iv)
+{
+ if (iv.len != this->iv.len)
+ {
+ return FALSE;
+ }
+ memcpy(this->iv.ptr, iv.ptr, this->iv.len);
+ return this->signer->set_key(this->signer, mac) &&
+ this->crypter->set_key(this->crypter, encr);
+}
+
+METHOD(tls_aead_t, destroy, void,
+ private_tls_aead_t *this)
+{
+ DESTROY_IF(this->crypter);
+ DESTROY_IF(this->signer);
+ chunk_free(&this->iv);
+ free(this);
+}
+
+/**
+ * See header
+ */
+tls_aead_t *tls_aead_create_implicit(integrity_algorithm_t mac,
+ encryption_algorithm_t encr, size_t encr_size)
+{
+ private_tls_aead_t *this;
+
+ INIT(this,
+ .public = {
+ .encrypt = _encrypt,
+ .decrypt = _decrypt,
+ .get_mac_key_size = _get_mac_key_size,
+ .get_encr_key_size = _get_encr_key_size,
+ .get_iv_size = _get_iv_size,
+ .set_keys = _set_keys,
+ .destroy = _destroy,
+ },
+ .crypter = lib->crypto->create_crypter(lib->crypto, encr, encr_size),
+ .signer = lib->crypto->create_signer(lib->crypto, mac),
+ );
+
+ if (!this->crypter || !this->signer)
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ this->iv = chunk_alloc(this->crypter->get_iv_size(this->crypter));
+
+ return &this->public;
+}
diff --git a/src/libtls/tls_aead_null.c b/src/libtls/tls_aead_null.c
new file mode 100644
index 000000000..595b64000
--- /dev/null
+++ b/src/libtls/tls_aead_null.c
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2014 Martin Willi
+ * Copyright (C) 2014 revosec AG
+ *
+ * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program 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.
+ */
+
+#include "tls_aead.h"
+
+typedef struct private_tls_aead_t private_tls_aead_t;
+
+/**
+ * Private data of an tls_aead_t object.
+ */
+struct private_tls_aead_t {
+
+ /**
+ * Public tls_aead_t interface.
+ */
+ tls_aead_t public;
+
+ /**
+ * traditional signer
+ */
+ signer_t *signer;
+};
+
+/**
+ * Associated header data to create signature over
+ */
+typedef struct __attribute__((__packed__)) {
+ u_int64_t seq;
+ u_int8_t type;
+ u_int16_t version;
+ u_int16_t length;
+} sigheader_t;
+
+METHOD(tls_aead_t, encrypt, bool,
+ private_tls_aead_t *this, tls_version_t version,
+ tls_content_type_t type, u_int64_t seq, chunk_t *data)
+{
+ chunk_t assoc, mac;
+ sigheader_t hdr;
+
+ hdr.type = type;
+ htoun64(&hdr.seq, seq);
+ htoun16(&hdr.version, version);
+ htoun16(&hdr.length, data->len);
+
+ assoc = chunk_from_thing(hdr);
+ if (!this->signer->get_signature(this->signer, assoc, NULL) ||
+ !this->signer->allocate_signature(this->signer, *data, &mac))
+ {
+ return FALSE;
+ }
+ *data = chunk_cat("mm", *data, mac);
+ return TRUE;
+}
+
+METHOD(tls_aead_t, decrypt, bool,
+ private_tls_aead_t *this, tls_version_t version,
+ tls_content_type_t type, u_int64_t seq, chunk_t *data)
+{
+ chunk_t assoc, mac;
+ sigheader_t hdr;
+
+ mac.len = this->signer->get_block_size(this->signer);
+ if (data->len < mac.len)
+ {
+ return FALSE;
+ }
+ mac = chunk_skip(*data, data->len - mac.len);
+ data->len -= mac.len;
+
+ hdr.type = type;
+ htoun64(&hdr.seq, seq);
+ htoun16(&hdr.version, version);
+ htoun16(&hdr.length, data->len);
+
+ assoc = chunk_from_thing(hdr);
+ if (!this->signer->get_signature(this->signer, assoc, NULL) ||
+ !this->signer->verify_signature(this->signer, *data, mac))
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+METHOD(tls_aead_t, get_mac_key_size, size_t,
+ private_tls_aead_t *this)
+{
+ return this->signer->get_key_size(this->signer);
+}
+
+METHOD(tls_aead_t, get_encr_key_size, size_t,
+ private_tls_aead_t *this)
+{
+ return 0;
+}
+
+METHOD(tls_aead_t, get_iv_size, size_t,
+ private_tls_aead_t *this)
+{
+ return 0;
+}
+
+METHOD(tls_aead_t, set_keys, bool,
+ private_tls_aead_t *this, chunk_t mac, chunk_t encr, chunk_t iv)
+{
+ if (iv.len || encr.len)
+ {
+ return FALSE;
+ }
+ return this->signer->set_key(this->signer, mac);
+}
+
+METHOD(tls_aead_t, destroy, void,
+ private_tls_aead_t *this)
+{
+ this->signer->destroy(this->signer);
+ free(this);
+}
+
+/**
+ * See header
+ */
+tls_aead_t *tls_aead_create_null(integrity_algorithm_t alg)
+{
+ private_tls_aead_t *this;
+
+ INIT(this,
+ .public = {
+ .encrypt = _encrypt,
+ .decrypt = _decrypt,
+ .get_mac_key_size = _get_mac_key_size,
+ .get_encr_key_size = _get_encr_key_size,
+ .get_iv_size = _get_iv_size,
+ .set_keys = _set_keys,
+ .destroy = _destroy,
+ },
+ .signer = lib->crypto->create_signer(lib->crypto, alg),
+ );
+
+ if (!this->signer)
+ {
+ free(this);
+ return NULL;
+ }
+
+ return &this->public;
+}
diff --git a/src/libtls/tls_crypto.c b/src/libtls/tls_crypto.c
index cc73ebaeb..4f67b20d6 100644
--- a/src/libtls/tls_crypto.c
+++ b/src/libtls/tls_crypto.c
@@ -1,6 +1,6 @@
/*
- * Copyright (C) 2010 Martin Willi
- * Copyright (C) 2010 revosec AG
+ * Copyright (C) 2010-2014 Martin Willi
+ * Copyright (C) 2010-2014 revosec AG
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -16,6 +16,7 @@
#include "tls_crypto.h"
#include <utils/debug.h>
+#include <plugins/plugin_feature.h>
ENUM_BEGIN(tls_cipher_suite_names, TLS_NULL_WITH_NULL_NULL,
TLS_DH_anon_WITH_3DES_EDE_CBC_SHA,
@@ -80,7 +81,7 @@ ENUM_NEXT(tls_cipher_suite_names, TLS_KRB5_WITH_DES_CBC_SHA,
"TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
"TLS_DH_anon_WITH_AES_256_CBC_SHA",
"TLS_RSA_WITH_NULL_SHA256",
- "TLS_RSA_WITH_AES_128_CBC_SHA256 ",
+ "TLS_RSA_WITH_AES_128_CBC_SHA256",
"TLS_RSA_WITH_AES_256_CBC_SHA256",
"TLS_DH_DSS_WITH_AES_128_CBC_SHA256",
"TLS_DH_RSA_WITH_AES_128_CBC_SHA256",
@@ -111,13 +112,13 @@ ENUM_NEXT(tls_cipher_suite_names, TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
"TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA",
"TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA",
"TLS_PSK_WITH_RC4_128_SHA",
- "TLS_PSK_WITH_3DES_EDE_CBC_SHA2",
+ "TLS_PSK_WITH_3DES_EDE_CBC_SHA",
"TLS_PSK_WITH_AES_128_CBC_SHA",
"TLS_PSK_WITH_AES_256_CBC_SHA",
"TLS_DHE_PSK_WITH_RC4_128_SHA",
"TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA",
"TLS_DHE_PSK_WITH_AES_128_CBC_SHA",
- "TLS_DHE_PSK_WITH_AES_256_CBC_SHA2",
+ "TLS_DHE_PSK_WITH_AES_256_CBC_SHA",
"TLS_RSA_PSK_WITH_RC4_128_SHA",
"TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA",
"TLS_RSA_PSK_WITH_AES_128_CBC_SHA",
@@ -385,34 +386,14 @@ struct private_tls_crypto_t {
tls_prf_t *prf;
/**
- * Signer instance for inbound traffic
+ * AEAD transform for inbound traffic
*/
- signer_t *signer_in;
+ tls_aead_t *aead_in;
/**
- * Signer instance for outbound traffic
+ * AEAD transform for outbound traffic
*/
- signer_t *signer_out;
-
- /**
- * Crypter instance for inbound traffic
- */
- crypter_t *crypter_in;
-
- /**
- * Crypter instance for outbound traffic
- */
- crypter_t *crypter_out;
-
- /**
- * IV for input decryption, if < TLSv1.2
- */
- chunk_t iv_in;
-
- /**
- * IV for output decryption, if < TLSv1.2
- */
- chunk_t iv_out;
+ tls_aead_t *aead_out;
/**
* EAP-[T]TLS MSK
@@ -460,6 +441,16 @@ static suite_algs_t suite_algs[] = {
HASH_SHA384, PRF_HMAC_SHA2_384,
AUTH_HMAC_SHA2_384_384, ENCR_AES_CBC, 32
},
+ { TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+ KEY_ECDSA, ECP_256_BIT,
+ HASH_SHA256, PRF_HMAC_SHA2_256,
+ AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 16
+ },
+ { TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+ KEY_ECDSA, ECP_384_BIT,
+ HASH_SHA384, PRF_HMAC_SHA2_384,
+ AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 32
+ },
{ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
KEY_RSA, ECP_256_BIT,
HASH_SHA256, PRF_HMAC_SHA2_256,
@@ -480,6 +471,16 @@ static suite_algs_t suite_algs[] = {
HASH_SHA384, PRF_HMAC_SHA2_384,
AUTH_HMAC_SHA2_384_384, ENCR_AES_CBC, 32
},
+ { TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ KEY_RSA, ECP_256_BIT,
+ HASH_SHA256, PRF_HMAC_SHA2_256,
+ AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 16
+ },
+ { TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+ KEY_RSA, ECP_384_BIT,
+ HASH_SHA384, PRF_HMAC_SHA2_384,
+ AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 32
+ },
{ TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
KEY_RSA, MODP_2048_BIT,
HASH_SHA256,PRF_HMAC_SHA2_256,
@@ -500,6 +501,16 @@ static suite_algs_t suite_algs[] = {
HASH_SHA256, PRF_HMAC_SHA2_256,
AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 32
},
+ { TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
+ KEY_RSA, MODP_3072_BIT,
+ HASH_SHA256, PRF_HMAC_SHA2_256,
+ AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 16
+ },
+ { TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
+ KEY_RSA, MODP_4096_BIT,
+ HASH_SHA384, PRF_HMAC_SHA2_384,
+ AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 32
+ },
{ TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
KEY_RSA, MODP_2048_BIT,
HASH_SHA256, PRF_HMAC_SHA2_256,
@@ -545,6 +556,16 @@ static suite_algs_t suite_algs[] = {
HASH_SHA256, PRF_HMAC_SHA2_256,
AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 32
},
+ { TLS_RSA_WITH_AES_128_GCM_SHA256,
+ KEY_RSA, MODP_NONE,
+ HASH_SHA256, PRF_HMAC_SHA2_256,
+ AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 16
+ },
+ { TLS_RSA_WITH_AES_256_GCM_SHA384,
+ KEY_RSA, MODP_NONE,
+ HASH_SHA384, PRF_HMAC_SHA2_384,
+ AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 32
+ },
{ TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
KEY_RSA, MODP_NONE,
HASH_SHA256, PRF_HMAC_SHA2_256,
@@ -627,8 +648,7 @@ static suite_algs_t *find_suite(tls_cipher_suite_t suite)
/**
* Filter a suite list using a transform enumerator
*/
-static void filter_suite(private_tls_crypto_t *this,
- suite_algs_t suites[], int *count, int offset,
+static void filter_suite(suite_algs_t suites[], int *count, int offset,
enumerator_t*(*create_enumerator)(crypto_factory_t*))
{
const char *plugin_name;
@@ -641,21 +661,56 @@ static void filter_suite(private_tls_crypto_t *this,
for (i = 0; i < *count; i++)
{
+ if (create_enumerator == lib->crypto->create_crypter_enumerator &&
+ encryption_algorithm_is_aead(suites[i].encr))
+ { /* filtering crypters, but current suite uses an AEAD, apply */
+ suites[remaining] = suites[i];
+ remaining++;
+ continue;
+ }
+ if (create_enumerator == lib->crypto->create_aead_enumerator &&
+ !encryption_algorithm_is_aead(suites[i].encr))
+ { /* filtering AEADs, but current suite doesn't use one, apply */
+ suites[remaining] = suites[i];
+ remaining++;
+ continue;
+ }
enumerator = create_enumerator(lib->crypto);
while (enumerator->enumerate(enumerator, current_alg, &plugin_name))
{
- if ((suites[i].encr == ENCR_NULL ||
- !current.encr || current.encr == suites[i].encr) &&
- (!current.mac || current.mac == suites[i].mac) &&
- (!current.prf || current.prf == suites[i].prf) &&
- (!current.hash || current.hash == suites[i].hash) &&
- (suites[i].dh == MODP_NONE ||
- !current.dh || current.dh == suites[i].dh))
+ if (current.encr && current.encr != suites[i].encr)
{
- suites[remaining] = suites[i];
- remaining++;
- break;
+ if (suites[i].encr != ENCR_NULL)
+ { /* skip, ENCR does not match nor is NULL */
+ continue;
+ }
}
+ if (current.mac && current.mac != suites[i].mac)
+ {
+ if (suites[i].mac != AUTH_UNDEFINED)
+ { /* skip, MAC does not match nor is it undefined */
+ continue;
+ }
+ }
+ if (current.prf && current.prf != suites[i].prf)
+ { /* skip, PRF does not match */
+ continue;
+ }
+ if (current.hash && current.hash != suites[i].hash)
+ { /* skip, hash does not match */
+ continue;
+ }
+ if (current.dh && current.dh != suites[i].dh)
+ {
+ if (suites[i].dh != MODP_NONE)
+ { /* skip DH group, does not match nor NONE */
+ continue;
+ }
+ }
+ /* suite supported, apply */
+ suites[remaining] = suites[i];
+ remaining++;
+ break;
}
enumerator->destroy(enumerator);
}
@@ -665,8 +720,7 @@ static void filter_suite(private_tls_crypto_t *this,
/**
* Purge NULL encryption cipher suites from list
*/
-static void filter_null_suites(private_tls_crypto_t *this,
- suite_algs_t suites[], int *count)
+static void filter_null_suites(suite_algs_t suites[], int *count)
{
int i, remaining = 0;
@@ -789,6 +843,20 @@ static void filter_cipher_config_suites(private_tls_crypto_t *this,
suites[remaining++] = suites[i];
break;
}
+ if (strcaseeq(token, "aes128gcm") &&
+ suites[i].encr == ENCR_AES_GCM_ICV16 &&
+ suites[i].encr_size == 16)
+ {
+ suites[remaining++] = suites[i];
+ break;
+ }
+ if (strcaseeq(token, "aes256gcm") &&
+ suites[i].encr == ENCR_AES_GCM_ICV16 &&
+ suites[i].encr_size == 32)
+ {
+ suites[remaining++] = suites[i];
+ break;
+ }
if (strcaseeq(token, "camellia128") &&
suites[i].encr == ENCR_CAMELLIA_CBC &&
suites[i].encr_size == 16)
@@ -905,6 +973,26 @@ static void filter_specific_config_suites(private_tls_crypto_t *this,
}
/**
+ * Filter out unsupported suites on given suite array
+ */
+static void filter_unsupported_suites(suite_algs_t suites[], int *count)
+{
+ /* filter suite list by each algorithm */
+ filter_suite(suites, count, offsetof(suite_algs_t, encr),
+ lib->crypto->create_crypter_enumerator);
+ filter_suite(suites, count, offsetof(suite_algs_t, encr),
+ lib->crypto->create_aead_enumerator);
+ filter_suite(suites, count, offsetof(suite_algs_t, mac),
+ lib->crypto->create_signer_enumerator);
+ filter_suite(suites, count, offsetof(suite_algs_t, prf),
+ lib->crypto->create_prf_enumerator);
+ filter_suite(suites, count, offsetof(suite_algs_t, hash),
+ lib->crypto->create_hasher_enumerator);
+ filter_suite(suites, count, offsetof(suite_algs_t, dh),
+ lib->crypto->create_dh_enumerator);
+}
+
+/**
* Initialize the cipher suite list
*/
static void build_cipher_suite_list(private_tls_crypto_t *this,
@@ -918,9 +1006,10 @@ static void build_cipher_suite_list(private_tls_crypto_t *this,
{
suites[i] = suite_algs[i];
}
+
if (require_encryption)
{
- filter_null_suites(this, suites, &count);
+ filter_null_suites(suites, &count);
}
if (!this->rsa)
{
@@ -931,17 +1020,7 @@ static void build_cipher_suite_list(private_tls_crypto_t *this,
filter_key_suites(this, suites, &count, KEY_ECDSA);
}
- /* filter suite list by each algorithm */
- filter_suite(this, suites, &count, offsetof(suite_algs_t, encr),
- lib->crypto->create_crypter_enumerator);
- filter_suite(this, suites, &count, offsetof(suite_algs_t, mac),
- lib->crypto->create_signer_enumerator);
- filter_suite(this, suites, &count, offsetof(suite_algs_t, prf),
- lib->crypto->create_prf_enumerator);
- filter_suite(this, suites, &count, offsetof(suite_algs_t, hash),
- lib->crypto->create_hasher_enumerator);
- filter_suite(this, suites, &count, offsetof(suite_algs_t, dh),
- lib->crypto->create_dh_enumerator);
+ filter_unsupported_suites(suites, &count);
/* filter suites with strongswan.conf options */
filter_key_exchange_config_suites(this, suites, &count);
@@ -969,10 +1048,82 @@ METHOD(tls_crypto_t, get_cipher_suites, int,
}
/**
+ * Create NULL encryption transforms
+ */
+static bool create_null(private_tls_crypto_t *this, suite_algs_t *algs)
+{
+ this->aead_in = tls_aead_create_null(algs->mac);
+ this->aead_out = tls_aead_create_null(algs->mac);
+ if (!this->aead_in || !this->aead_out)
+ {
+ DBG1(DBG_TLS, "selected TLS MAC %N not supported",
+ integrity_algorithm_names, algs->mac);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ * Create traditional transforms
+ */
+static bool create_traditional(private_tls_crypto_t *this, suite_algs_t *algs)
+{
+ if (this->tls->get_version(this->tls) < TLS_1_1)
+ {
+ this->aead_in = tls_aead_create_implicit(algs->mac,
+ algs->encr, algs->encr_size);
+ this->aead_out = tls_aead_create_implicit(algs->mac,
+ algs->encr, algs->encr_size);
+ }
+ else
+ {
+ this->aead_in = tls_aead_create_explicit(algs->mac,
+ algs->encr, algs->encr_size);
+ this->aead_out = tls_aead_create_explicit(algs->mac,
+ algs->encr, algs->encr_size);
+ }
+ if (!this->aead_in || !this->aead_out)
+ {
+ DBG1(DBG_TLS, "selected TLS transforms %N-%u-%N not supported",
+ encryption_algorithm_names, algs->encr, algs->encr_size * 8,
+ integrity_algorithm_names, algs->mac);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ * Create AEAD transforms
+ */
+static bool create_aead(private_tls_crypto_t *this, suite_algs_t *algs)
+{
+ this->aead_in = tls_aead_create_aead(algs->encr, algs->encr_size);
+ this->aead_out = tls_aead_create_aead(algs->encr, algs->encr_size);
+ if (!this->aead_in || !this->aead_out)
+ {
+ DBG1(DBG_TLS, "selected TLS transforms %N-%u not supported",
+ encryption_algorithm_names, algs->encr, algs->encr_size * 8);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ * Clean up and unset AEAD transforms
+ */
+static void destroy_aeads(private_tls_crypto_t *this)
+{
+ DESTROY_IF(this->aead_in);
+ DESTROY_IF(this->aead_out);
+ this->aead_in = this->aead_out = NULL;
+}
+
+/**
* Create crypto primitives
*/
static bool create_ciphers(private_tls_crypto_t *this, suite_algs_t *algs)
{
+ destroy_aeads(this);
DESTROY_IF(this->prf);
if (this->tls->get_version(this->tls) < TLS_1_2)
{
@@ -987,38 +1138,29 @@ static bool create_ciphers(private_tls_crypto_t *this, suite_algs_t *algs)
DBG1(DBG_TLS, "selected TLS PRF not supported");
return FALSE;
}
-
- DESTROY_IF(this->signer_in);
- DESTROY_IF(this->signer_out);
- this->signer_in = lib->crypto->create_signer(lib->crypto, algs->mac);
- this->signer_out = lib->crypto->create_signer(lib->crypto, algs->mac);
- if (!this->signer_in || !this->signer_out)
+ if (algs->encr == ENCR_NULL)
{
- DBG1(DBG_TLS, "selected TLS MAC %N not supported",
- integrity_algorithm_names, algs->mac);
- return FALSE;
+ if (create_null(this, algs))
+ {
+ return TRUE;
+ }
}
-
- DESTROY_IF(this->crypter_in);
- DESTROY_IF(this->crypter_out);
- if (algs->encr == ENCR_NULL)
+ else if (encryption_algorithm_is_aead(algs->encr))
{
- this->crypter_in = this->crypter_out = NULL;
+ if (create_aead(this, algs))
+ {
+ return TRUE;
+ }
}
else
{
- this->crypter_in = lib->crypto->create_crypter(lib->crypto,
- algs->encr, algs->encr_size);
- this->crypter_out = lib->crypto->create_crypter(lib->crypto,
- algs->encr, algs->encr_size);
- if (!this->crypter_in || !this->crypter_out)
+ if (create_traditional(this, algs))
{
- DBG1(DBG_TLS, "selected TLS crypter %N not supported",
- encryption_algorithm_names, algs->encr);
- return FALSE;
+ return TRUE;
}
}
- return TRUE;
+ destroy_aeads(this);
+ return FALSE;
}
METHOD(tls_crypto_t, select_cipher_suite, tls_cipher_suite_t,
@@ -1065,54 +1207,52 @@ METHOD(tls_crypto_t, get_dh_group, diffie_hellman_group_t,
return MODP_NONE;
}
+/**
+ * Map signature schemes to TLS key types and hashes, ordered by preference
+ */
+static struct {
+ tls_signature_algorithm_t sig;
+ tls_hash_algorithm_t hash;
+ signature_scheme_t scheme;
+} schemes[] = {
+ { TLS_SIG_ECDSA, TLS_HASH_SHA256, SIGN_ECDSA_WITH_SHA256_DER },
+ { TLS_SIG_ECDSA, TLS_HASH_SHA384, SIGN_ECDSA_WITH_SHA384_DER },
+ { TLS_SIG_ECDSA, TLS_HASH_SHA512, SIGN_ECDSA_WITH_SHA512_DER },
+ { TLS_SIG_ECDSA, TLS_HASH_SHA1, SIGN_ECDSA_WITH_SHA1_DER },
+ { TLS_SIG_RSA, TLS_HASH_SHA256, SIGN_RSA_EMSA_PKCS1_SHA256 },
+ { TLS_SIG_RSA, TLS_HASH_SHA384, SIGN_RSA_EMSA_PKCS1_SHA384 },
+ { TLS_SIG_RSA, TLS_HASH_SHA512, SIGN_RSA_EMSA_PKCS1_SHA512 },
+ { TLS_SIG_RSA, TLS_HASH_SHA224, SIGN_RSA_EMSA_PKCS1_SHA224 },
+ { TLS_SIG_RSA, TLS_HASH_SHA1, SIGN_RSA_EMSA_PKCS1_SHA1 },
+ { TLS_SIG_RSA, TLS_HASH_MD5, SIGN_RSA_EMSA_PKCS1_MD5 },
+};
+
METHOD(tls_crypto_t, get_signature_algorithms, void,
private_tls_crypto_t *this, bio_writer_t *writer)
{
bio_writer_t *supported;
- enumerator_t *enumerator;
- hash_algorithm_t alg;
- tls_hash_algorithm_t hash;
- const char *plugin_name;
+ int i;
supported = bio_writer_create(32);
- enumerator = lib->crypto->create_hasher_enumerator(lib->crypto);
- while (enumerator->enumerate(enumerator, &alg, &plugin_name))
+
+ for (i = 0; i < countof(schemes); i++)
{
- switch (alg)
+ if (schemes[i].sig == TLS_SIG_RSA && !this->rsa)
{
- case HASH_MD5:
- hash = TLS_HASH_MD5;
- break;
- case HASH_SHA1:
- hash = TLS_HASH_SHA1;
- break;
- case HASH_SHA224:
- hash = TLS_HASH_SHA224;
- break;
- case HASH_SHA256:
- hash = TLS_HASH_SHA256;
- break;
- case HASH_SHA384:
- hash = TLS_HASH_SHA384;
- break;
- case HASH_SHA512:
- hash = TLS_HASH_SHA512;
- break;
- default:
- continue;
+ continue;
}
- if (this->rsa)
+ if (schemes[i].sig == TLS_SIG_ECDSA && !this->ecdsa)
{
- supported->write_uint8(supported, hash);
- supported->write_uint8(supported, TLS_SIG_RSA);
+ continue;
}
- if (this->ecdsa && alg != HASH_MD5 && alg != HASH_SHA224)
- { /* currently we have no signature scheme for MD5/SHA224 */
- supported->write_uint8(supported, hash);
- supported->write_uint8(supported, TLS_SIG_ECDSA);
+ if (!lib->plugins->has_feature(lib->plugins,
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, schemes[i].scheme)))
+ {
+ continue;
}
+ supported->write_uint8(supported, schemes[i].hash);
+ supported->write_uint8(supported, schemes[i].sig);
}
- enumerator->destroy(enumerator);
supported->wrap16(supported);
writer->write_data16(writer, supported->get_buf(supported));
@@ -1120,6 +1260,29 @@ METHOD(tls_crypto_t, get_signature_algorithms, void,
}
/**
+ * Get the signature scheme from a TLS 1.2 hash/sig algorithm pair
+ */
+static signature_scheme_t hashsig_to_scheme(key_type_t type,
+ tls_hash_algorithm_t hash,
+ tls_signature_algorithm_t sig)
+{
+ int i;
+
+ if ((sig == TLS_SIG_RSA && type == KEY_RSA) ||
+ (sig == TLS_SIG_ECDSA && type == KEY_ECDSA))
+ {
+ for (i = 0; i < countof(schemes); i++)
+ {
+ if (schemes[i].sig == sig && schemes[i].hash == hash)
+ {
+ return schemes[i].scheme;
+ }
+ }
+ }
+ return SIGN_UNKNOWN;
+}
+
+/**
* Mapping groups to TLS named curves
*/
static struct {
@@ -1236,59 +1399,6 @@ static bool hash_data(private_tls_crypto_t *this, chunk_t data, chunk_t *hash)
return TRUE;
}
-/**
- * Get the signature scheme from a TLS 1.2 hash/sig algorithm pair
- */
-static signature_scheme_t hashsig_to_scheme(key_type_t type,
- tls_hash_algorithm_t hash, tls_signature_algorithm_t sig)
-{
- switch (sig)
- {
- case TLS_SIG_RSA:
- if (type != KEY_RSA)
- {
- return SIGN_UNKNOWN;
- }
- switch (hash)
- {
- case TLS_HASH_MD5:
- return SIGN_RSA_EMSA_PKCS1_MD5;
- case TLS_HASH_SHA1:
- return SIGN_RSA_EMSA_PKCS1_SHA1;
- case TLS_HASH_SHA224:
- return SIGN_RSA_EMSA_PKCS1_SHA224;
- case TLS_HASH_SHA256:
- return SIGN_RSA_EMSA_PKCS1_SHA256;
- case TLS_HASH_SHA384:
- return SIGN_RSA_EMSA_PKCS1_SHA384;
- case TLS_HASH_SHA512:
- return SIGN_RSA_EMSA_PKCS1_SHA512;
- default:
- return SIGN_UNKNOWN;
- }
- case TLS_SIG_ECDSA:
- if (type != KEY_ECDSA)
- {
- return SIGN_UNKNOWN;
- }
- switch (hash)
- {
- case TLS_HASH_SHA224:
- return SIGN_ECDSA_WITH_SHA1_DER;
- case TLS_HASH_SHA256:
- return SIGN_ECDSA_WITH_SHA256_DER;
- case TLS_HASH_SHA384:
- return SIGN_ECDSA_WITH_SHA384_DER;
- case TLS_HASH_SHA512:
- return SIGN_ECDSA_WITH_SHA512_DER;
- default:
- return SIGN_UNKNOWN;
- }
- default:
- return SIGN_UNKNOWN;
- }
-}
-
METHOD(tls_crypto_t, sign, bool,
private_tls_crypto_t *this, private_key_t *key, bio_writer_t *writer,
chunk_t data, chunk_t hashsig)
@@ -1512,93 +1622,63 @@ static bool derive_master(private_tls_crypto_t *this, chunk_t premaster,
static bool expand_keys(private_tls_crypto_t *this,
chunk_t client_random, chunk_t server_random)
{
- chunk_t seed, block, client_write, server_write;
- int mks, eks = 0, ivs = 0;
+ chunk_t seed, block;
+ chunk_t cw_mac, cw, cw_iv;
+ chunk_t sw_mac, sw, sw_iv;
+ int mklen, eklen, ivlen;
- /* derive key block for key expansion */
- mks = this->signer_out->get_key_size(this->signer_out);
- if (this->crypter_out)
+ if (!this->aead_in || !this->aead_out)
{
- eks = this->crypter_out->get_key_size(this->crypter_out);
- if (this->tls->get_version(this->tls) < TLS_1_1)
- {
- ivs = this->crypter_out->get_iv_size(this->crypter_out);
- }
+ return FALSE;
}
+
+ /* derive key block for key expansion */
+ mklen = this->aead_in->get_mac_key_size(this->aead_in);
+ eklen = this->aead_in->get_encr_key_size(this->aead_in);
+ ivlen = this->aead_in->get_iv_size(this->aead_in);
seed = chunk_cata("cc", server_random, client_random);
- block = chunk_alloca((mks + eks + ivs) * 2);
+ block = chunk_alloca((mklen + eklen + ivlen) * 2);
if (!this->prf->get_bytes(this->prf, "key expansion", seed,
block.len, block.ptr))
{
return FALSE;
}
- /* signer keys */
- client_write = chunk_create(block.ptr, mks);
- block = chunk_skip(block, mks);
- server_write = chunk_create(block.ptr, mks);
- block = chunk_skip(block, mks);
+ /* client/server write signer keys */
+ cw_mac = chunk_create(block.ptr, mklen);
+ block = chunk_skip(block, mklen);
+ sw_mac = chunk_create(block.ptr, mklen);
+ block = chunk_skip(block, mklen);
+
+ /* client/server write encryption keys */
+ cw = chunk_create(block.ptr, eklen);
+ block = chunk_skip(block, eklen);
+ sw = chunk_create(block.ptr, eklen);
+ block = chunk_skip(block, eklen);
+
+ /* client/server write IV; TLS 1.0 implicit IVs or AEAD salt, if any */
+ cw_iv = chunk_create(block.ptr, ivlen);
+ block = chunk_skip(block, ivlen);
+ sw_iv = chunk_create(block.ptr, ivlen);
+ block = chunk_skip(block, ivlen);
+
if (this->tls->is_server(this->tls))
{
- if (!this->signer_in->set_key(this->signer_in, client_write) ||
- !this->signer_out->set_key(this->signer_out, server_write))
+ if (!this->aead_in->set_keys(this->aead_in, cw_mac, cw, cw_iv) ||
+ !this->aead_out->set_keys(this->aead_out, sw_mac, sw, sw_iv))
{
return FALSE;
}
}
else
{
- if (!this->signer_out->set_key(this->signer_out, client_write) ||
- !this->signer_in->set_key(this->signer_in, server_write))
+ if (!this->aead_out->set_keys(this->aead_out, cw_mac, cw, cw_iv) ||
+ !this->aead_in->set_keys(this->aead_in, sw_mac, sw, sw_iv))
{
return FALSE;
}
}
- /* crypter keys, and IVs if < TLSv1.2 */
- if (this->crypter_out && this->crypter_in)
- {
- client_write = chunk_create(block.ptr, eks);
- block = chunk_skip(block, eks);
- server_write = chunk_create(block.ptr, eks);
- block = chunk_skip(block, eks);
-
- if (this->tls->is_server(this->tls))
- {
- if (!this->crypter_in->set_key(this->crypter_in, client_write) ||
- !this->crypter_out->set_key(this->crypter_out, server_write))
- {
- return FALSE;
- }
- }
- else
- {
- if (!this->crypter_out->set_key(this->crypter_out, client_write) ||
- !this->crypter_in->set_key(this->crypter_in, server_write))
- {
- return FALSE;
- }
- }
- if (ivs)
- {
- client_write = chunk_create(block.ptr, ivs);
- block = chunk_skip(block, ivs);
- server_write = chunk_create(block.ptr, ivs);
- block = chunk_skip(block, ivs);
-
- if (this->tls->is_server(this->tls))
- {
- this->iv_in = chunk_clone(client_write);
- this->iv_out = chunk_clone(server_write);
- }
- else
- {
- this->iv_out = chunk_clone(client_write);
- this->iv_in = chunk_clone(server_write);
- }
- }
- }
-
/* EAP-MSK */
if (this->msk_label)
{
@@ -1666,13 +1746,11 @@ METHOD(tls_crypto_t, change_cipher, void,
{
if (inbound)
{
- this->protection->set_cipher(this->protection, TRUE,
- this->signer_in, this->crypter_in, this->iv_in);
+ this->protection->set_cipher(this->protection, TRUE, this->aead_in);
}
else
{
- this->protection->set_cipher(this->protection, FALSE,
- this->signer_out, this->crypter_out, this->iv_out);
+ this->protection->set_cipher(this->protection, FALSE, this->aead_out);
}
}
}
@@ -1686,12 +1764,7 @@ METHOD(tls_crypto_t, get_eap_msk, chunk_t,
METHOD(tls_crypto_t, destroy, void,
private_tls_crypto_t *this)
{
- DESTROY_IF(this->signer_in);
- DESTROY_IF(this->signer_out);
- DESTROY_IF(this->crypter_in);
- DESTROY_IF(this->crypter_out);
- free(this->iv_in.ptr);
- free(this->iv_out.ptr);
+ destroy_aeads(this);
free(this->handshake.ptr);
free(this->msk.ptr);
DESTROY_IF(this->prf);
@@ -1773,8 +1846,43 @@ tls_crypto_t *tls_crypto_create(tls_t *tls, tls_cache_t *cache)
case TLS_PURPOSE_GENERIC:
build_cipher_suite_list(this, TRUE);
break;
+ case TLS_PURPOSE_GENERIC_NULLOK:
+ build_cipher_suite_list(this, FALSE);
+ break;
default:
break;
}
return &this->public;
}
+
+/**
+ * See header.
+ */
+int tls_crypto_get_supported_suites(bool null, tls_cipher_suite_t **out)
+{
+ suite_algs_t suites[countof(suite_algs)];
+ int count = countof(suite_algs), i;
+
+ /* initialize copy of suite list */
+ for (i = 0; i < count; i++)
+ {
+ suites[i] = suite_algs[i];
+ }
+
+ filter_unsupported_suites(suites, &count);
+
+ if (!null)
+ {
+ filter_null_suites(suites, &count);
+ }
+
+ if (out)
+ {
+ *out = calloc(count, sizeof(tls_cipher_suite_t));
+ for (i = 0; i < count; i++)
+ {
+ (*out)[i] = suites[i].suite;
+ }
+ }
+ return count;
+}
diff --git a/src/libtls/tls_crypto.h b/src/libtls/tls_crypto.h
index 5512b1f48..a42e07bb3 100644
--- a/src/libtls/tls_crypto.h
+++ b/src/libtls/tls_crypto.h
@@ -572,4 +572,13 @@ struct tls_crypto_t {
*/
tls_crypto_t *tls_crypto_create(tls_t *tls, tls_cache_t *cache);
+/**
+ * Get a list of all supported TLS cipher suites.
+ *
+ * @param null include supported NULL encryption suites
+ * @param suites pointer to allocated suites array, to free(), or NULL
+ * @return number of suites supported
+ */
+int tls_crypto_get_supported_suites(bool null, tls_cipher_suite_t **suites);
+
#endif /** TLS_CRYPTO_H_ @}*/
diff --git a/src/libtls/tls_peer.c b/src/libtls/tls_peer.c
index b429da300..a95b40f55 100644
--- a/src/libtls/tls_peer.c
+++ b/src/libtls/tls_peer.c
@@ -80,6 +80,11 @@ struct private_tls_peer_t {
peer_state_t state;
/**
+ * TLS version we offered in hello
+ */
+ tls_version_t hello_version;
+
+ /**
* Hello random data selected by client
*/
char client_random[32];
@@ -724,6 +729,7 @@ static status_t send_client_hello(private_tls_peer_t *this,
/* TLS version */
version = this->tls->get_version(this->tls);
+ this->hello_version = version;
writer->write_uint16(writer, version);
writer->write_data(writer, chunk_from_thing(this->client_random));
@@ -917,7 +923,7 @@ static status_t send_key_exchange_encrypt(private_tls_peer_t *this,
return NEED_MORE;
}
rng->destroy(rng);
- htoun16(premaster, TLS_1_2);
+ htoun16(premaster, this->hello_version);
if (!this->crypto->derive_secrets(this->crypto, chunk_from_thing(premaster),
this->session, this->server,
diff --git a/src/libtls/tls_protection.c b/src/libtls/tls_protection.c
index 0d5df18f7..b016db21f 100644
--- a/src/libtls/tls_protection.c
+++ b/src/libtls/tls_protection.c
@@ -45,74 +45,26 @@ struct private_tls_protection_t {
tls_alert_t *alert;
/**
- * RNG if we generate IVs ourself
- */
- rng_t *rng;
-
- /**
* Sequence number of incoming records
*/
- u_int32_t seq_in;
+ u_int64_t seq_in;
/**
* Sequence number for outgoing records
*/
- u_int32_t seq_out;
-
- /**
- * Signer instance for inbound traffic
- */
- signer_t *signer_in;
-
- /**
- * Signer instance for outbound traffic
- */
- signer_t *signer_out;
+ u_int64_t seq_out;
/**
- * Crypter instance for inbound traffic
+ * AEAD transform for inbound traffic
*/
- crypter_t *crypter_in;
+ tls_aead_t *aead_in;
/**
- * Crypter instance for outbound traffic
+ * AEAD transform for outbound traffic
*/
- crypter_t *crypter_out;
-
- /**
- * Current IV for input decryption
- */
- chunk_t iv_in;
-
- /**
- * Current IV for output decryption
- */
- chunk_t iv_out;
+ tls_aead_t *aead_out;
};
-/**
- * Create the header and feed it into a signer for MAC verification
- */
-static bool sigheader(signer_t *signer, u_int32_t seq, u_int8_t type,
- u_int16_t version, u_int16_t length)
-{
- /* we only support 32 bit sequence numbers, but TLS uses 64 bit */
- struct __attribute__((__packed__)) {
- u_int32_t seq_high;
- u_int32_t seq_low;
- u_int8_t type;
- u_int16_t version;
- u_int16_t length;
- } header = {
- .type = type,
- };
- htoun32(&header.seq_low, seq);
- htoun16(&header.version, version);
- htoun16(&header.length, length);
-
- return signer->get_signature(signer, chunk_from_thing(header), NULL);
-}
-
METHOD(tls_protection_t, process, status_t,
private_tls_protection_t *this, tls_content_type_t type, chunk_t data)
{
@@ -121,75 +73,12 @@ METHOD(tls_protection_t, process, status_t,
return NEED_MORE;
}
- if (this->crypter_in)
- {
- chunk_t iv, next_iv = chunk_empty;
- u_int8_t bs, padding_length;
-
- bs = this->crypter_in->get_block_size(this->crypter_in);
- if (this->iv_in.len)
- { /* < TLSv1.1 uses IV from key derivation/last block */
- if (data.len < bs || data.len % bs)
- {
- DBG1(DBG_TLS, "encrypted TLS record length invalid");
- this->alert->add(this->alert, TLS_FATAL, TLS_BAD_RECORD_MAC);
- return NEED_MORE;
- }
- iv = this->iv_in;
- next_iv = chunk_clone(chunk_create(data.ptr + data.len - bs, bs));
- }
- else
- { /* TLSv1.1 uses random IVs, prepended to record */
- iv.len = this->crypter_in->get_iv_size(this->crypter_in);
- iv = chunk_create(data.ptr, iv.len);
- data = chunk_skip(data, iv.len);
- if (data.len < bs || data.len % bs)
- {
- DBG1(DBG_TLS, "encrypted TLS record length invalid");
- this->alert->add(this->alert, TLS_FATAL, TLS_BAD_RECORD_MAC);
- return NEED_MORE;
- }
- }
- if (!this->crypter_in->decrypt(this->crypter_in, data, iv, NULL))
- {
- free(next_iv.ptr);
- this->alert->add(this->alert, TLS_FATAL, TLS_BAD_RECORD_MAC);
- return NEED_MORE;
- }
-
- if (next_iv.len)
- { /* next record IV is last ciphertext block of this record */
- memcpy(this->iv_in.ptr, next_iv.ptr, next_iv.len);
- free(next_iv.ptr);
- }
-
- padding_length = data.ptr[data.len - 1];
- if (padding_length < data.len)
- { /* remove padding if it looks valid. Continue with no padding, try
- * to prevent timing attacks. */
- data.len -= padding_length + 1;
- }
- }
- if (this->signer_in)
+ if (this->aead_in)
{
- chunk_t mac;
- u_int8_t bs;
-
- bs = this->signer_in->get_block_size(this->signer_in);
- if (data.len < bs)
+ if (!this->aead_in->decrypt(this->aead_in, this->version,
+ type, this->seq_in, &data))
{
- DBG1(DBG_TLS, "TLS record too short to verify MAC");
- this->alert->add(this->alert, TLS_FATAL, TLS_BAD_RECORD_MAC);
- return NEED_MORE;
- }
- mac = chunk_skip(data, data.len - bs);
- data.len -= bs;
-
- if (!sigheader(this->signer_in, this->seq_in, type,
- this->version, data.len) ||
- !this->signer_in->verify_signature(this->signer_in, data, mac))
- {
- DBG1(DBG_TLS, "TLS record MAC verification failed");
+ DBG1(DBG_TLS, "TLS record decryption failed");
this->alert->add(this->alert, TLS_FATAL, TLS_BAD_RECORD_MAC);
return NEED_MORE;
}
@@ -220,72 +109,15 @@ METHOD(tls_protection_t, build, status_t,
if (status == NEED_MORE)
{
- if (this->signer_out)
+ if (this->aead_out)
{
- chunk_t mac;
-
- if (!sigheader(this->signer_out, this->seq_out, *type,
- this->version, data->len) ||
- !this->signer_out->allocate_signature(this->signer_out,
- *data, &mac))
+ if (!this->aead_out->encrypt(this->aead_out, this->version,
+ *type, this->seq_out, data))
{
+ DBG1(DBG_TLS, "TLS record encryption failed");
+ chunk_free(data);
return FAILED;
}
- if (this->crypter_out)
- {
- chunk_t padding, iv;
- u_int8_t bs, padding_length;
-
- bs = this->crypter_out->get_block_size(this->crypter_out);
- padding_length = bs - ((data->len + mac.len + 1) % bs);
-
- padding = chunk_alloca(padding_length);
- memset(padding.ptr, padding_length, padding.len);
-
- if (this->iv_out.len)
- { /* < TLSv1.1 uses IV from key derivation/last block */
- iv = this->iv_out;
- }
- else
- { /* TLSv1.1 uses random IVs, prepended to record */
- iv.len = this->crypter_out->get_iv_size(this->crypter_out);
- if (!this->rng ||
- !this->rng->allocate_bytes(this->rng, iv.len, &iv))
- {
- DBG1(DBG_TLS, "failed to generate TLS IV");
- free(data->ptr);
- return FAILED;
- }
- }
-
- *data = chunk_cat("mmcc", *data, mac, padding,
- chunk_from_thing(padding_length));
- /* encrypt inline */
- if (!this->crypter_out->encrypt(this->crypter_out, *data,
- iv, NULL))
- {
- if (!this->iv_out.len)
- {
- free(iv.ptr);
- }
- free(data->ptr);
- return FAILED;
- }
-
- if (this->iv_out.len)
- { /* next record IV is last ciphertext block of this record */
- memcpy(this->iv_out.ptr, data->ptr + data->len -
- this->iv_out.len, this->iv_out.len);
- }
- else
- { /* prepend IV */
- *data = chunk_cat("mm", iv, *data);
- }
- }
- else
- { /* NULL encryption */
- *data = chunk_cat("mm", *data, mac);
- }
}
this->seq_out++;
}
@@ -293,24 +125,15 @@ METHOD(tls_protection_t, build, status_t,
}
METHOD(tls_protection_t, set_cipher, void,
- private_tls_protection_t *this, bool inbound, signer_t *signer,
- crypter_t *crypter, chunk_t iv)
+ private_tls_protection_t *this, bool inbound, tls_aead_t *aead)
{
if (inbound)
{
- this->signer_in = signer;
- this->crypter_in = crypter;
- this->iv_in = iv;
+ this->aead_in = aead;
}
else
{
- this->signer_out = signer;
- this->crypter_out = crypter;
- this->iv_out = iv;
- if (!iv.len)
- { /* generate IVs if none given */
- this->rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
- }
+ this->aead_out = aead;
}
}
@@ -323,7 +146,6 @@ METHOD(tls_protection_t, set_version, void,
METHOD(tls_protection_t, destroy, void,
private_tls_protection_t *this)
{
- DESTROY_IF(this->rng);
free(this);
}
diff --git a/src/libtls/tls_protection.h b/src/libtls/tls_protection.h
index 05cf3df45..3280fb5a9 100644
--- a/src/libtls/tls_protection.h
+++ b/src/libtls/tls_protection.h
@@ -26,6 +26,7 @@
typedef struct tls_protection_t tls_protection_t;
#include "tls.h"
+#include "tls_aead.h"
#include "tls_alert.h"
#include "tls_compression.h"
@@ -62,15 +63,12 @@ struct tls_protection_t {
tls_content_type_t *type, chunk_t *data);
/**
- * Set a new cipher, including encryption and integrity algorithms.
+ * Set a new transforms to use at protection layer
*
* @param inbound TRUE to use cipher for inbound data, FALSE for outbound
- * @param signer new signer to use, gets owned by protection layer
- * @param crypter new crypter to use, gets owned by protection layer
- * @param iv initial IV for crypter, gets owned by protection layer
+ * @param aead new AEAD transform
*/
- void (*set_cipher)(tls_protection_t *this, bool inbound, signer_t *signer,
- crypter_t *crypter, chunk_t iv);
+ void (*set_cipher)(tls_protection_t *this, bool inbound, tls_aead_t *aead);
/**
* Set the TLS version negotiated, used for MAC calculation.
diff --git a/src/libtls/tls_socket.c b/src/libtls/tls_socket.c
index 19232750b..648771e75 100644
--- a/src/libtls/tls_socket.c
+++ b/src/libtls/tls_socket.c
@@ -406,9 +406,11 @@ METHOD(tls_socket_t, destroy, void,
* See header
*/
tls_socket_t *tls_socket_create(bool is_server, identification_t *server,
- identification_t *peer, int fd, tls_cache_t *cache)
+ identification_t *peer, int fd, tls_cache_t *cache,
+ tls_version_t max_version, bool nullok)
{
private_tls_socket_t *this;
+ tls_purpose_t purpose;
INIT(this,
.public = {
@@ -430,13 +432,23 @@ tls_socket_t *tls_socket_create(bool is_server, identification_t *server,
.fd = fd,
);
- this->tls = tls_create(is_server, server, peer, TLS_PURPOSE_GENERIC,
+ if (nullok)
+ {
+ purpose = TLS_PURPOSE_GENERIC_NULLOK;
+ }
+ else
+ {
+ purpose = TLS_PURPOSE_GENERIC;
+ }
+
+ this->tls = tls_create(is_server, server, peer, purpose,
&this->app.application, cache);
if (!this->tls)
{
free(this);
return NULL;
}
+ this->tls->set_version(this->tls, max_version);
return &this->public;
}
diff --git a/src/libtls/tls_socket.h b/src/libtls/tls_socket.h
index 75130a4d3..0d4db3b41 100644
--- a/src/libtls/tls_socket.h
+++ b/src/libtls/tls_socket.h
@@ -104,9 +104,12 @@ struct tls_socket_t {
* @param peer client identity, NULL for no client authentication
* @param fd socket to read/write from
* @param cache session cache to use, or NULL
+ * @param max_version maximun TLS version to negotiate
+ * @param nullok accept NULL encryption ciphers
* @return TLS socket wrapper
*/
tls_socket_t *tls_socket_create(bool is_server, identification_t *server,
- identification_t *peer, int fd, tls_cache_t *cache);
+ identification_t *peer, int fd, tls_cache_t *cache,
+ tls_version_t max_version, bool nullok);
#endif /** TLS_SOCKET_H_ @}*/