summaryrefslogtreecommitdiff
path: root/src/gnutls
diff options
context:
space:
mode:
Diffstat (limited to 'src/gnutls')
-rw-r--r--src/gnutls/Makefile.am58
-rw-r--r--src/gnutls/Makefile.in786
-rw-r--r--src/gnutls/README6
-rw-r--r--src/gnutls/app.c998
-rw-r--r--src/gnutls/asymkeys.c455
-rw-r--r--src/gnutls/ciphers.c82
-rw-r--r--src/gnutls/crypto.c351
-rw-r--r--src/gnutls/digests.c112
-rw-r--r--src/gnutls/globals.h31
-rw-r--r--src/gnutls/hmac.c141
-rw-r--r--src/gnutls/kw_aes.c72
-rw-r--r--src/gnutls/kw_des.c51
-rw-r--r--src/gnutls/signatures.c148
-rw-r--r--src/gnutls/symkeys.c125
-rw-r--r--src/gnutls/x509.c1960
-rw-r--r--src/gnutls/x509utils.c1687
-rw-r--r--src/gnutls/x509utils.h143
-rw-r--r--src/gnutls/x509vfy.c802
18 files changed, 8008 insertions, 0 deletions
diff --git a/src/gnutls/Makefile.am b/src/gnutls/Makefile.am
new file mode 100644
index 00000000..84ce637a
--- /dev/null
+++ b/src/gnutls/Makefile.am
@@ -0,0 +1,58 @@
+NULL =
+
+EXTRA_DIST = \
+ README \
+ $(NULL)
+
+lib_LTLIBRARIES = \
+ libxmlsec1-gnutls.la \
+ $(NULL)
+
+libxmlsec1_gnutls_la_CPPFLAGS = \
+ -DPACKAGE=\"@PACKAGE@\" \
+ -I../../include \
+ -I$(top_srcdir)/include \
+ $(XMLSEC_DEFINES) \
+ $(GNUTLS_CFLAGS) \
+ $(LIBXSLT_CFLAGS) \
+ $(LIBXML_CFLAGS) \
+ $(NULL)
+
+libxmlsec1_gnutls_la_SOURCES =\
+ app.c \
+ ciphers.c \
+ crypto.c \
+ digests.c \
+ hmac.c \
+ kw_aes.c \
+ kw_des.c \
+ symkeys.c \
+ asymkeys.c \
+ signatures.c \
+ x509utils.h \
+ x509utils.c \
+ x509.c \
+ x509vfy.c \
+ globals.h \
+ $(NULL)
+
+if SHAREDLIB_HACK
+libxmlsec1_gnutls_la_SOURCES += ../strings.c
+endif
+
+# xmlsec-gnutls library requires xmlsec-gcrypt
+libxmlsec1_gnutls_la_LIBADD = \
+ $(GNUTLS_LIBS) \
+ $(LIBXSLT_LIBS) \
+ $(LIBXML_LIBS) \
+ ../libxmlsec1.la \
+ ../gcrypt/libxmlsec1-gcrypt.la \
+ $(NULL)
+
+libxmlsec1_gnutls_la_DEPENDENCIES = \
+ $(NULL)
+
+libxmlsec1_gnutls_la_LDFLAGS = \
+ @XMLSEC_CRYPTO_EXTRA_LDFLAGS@ \
+ -version-info @XMLSEC_VERSION_INFO@ \
+ $(NULL)
diff --git a/src/gnutls/Makefile.in b/src/gnutls/Makefile.in
new file mode 100644
index 00000000..93a57352
--- /dev/null
+++ b/src/gnutls/Makefile.in
@@ -0,0 +1,786 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 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@
+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@
+@SHAREDLIB_HACK_TRUE@am__append_1 = ../strings.c
+subdir = src/gnutls
+DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/configure.in
+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__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(libdir)"
+LTLIBRARIES = $(lib_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+am__libxmlsec1_gnutls_la_SOURCES_DIST = app.c ciphers.c crypto.c \
+ digests.c hmac.c kw_aes.c kw_des.c symkeys.c asymkeys.c \
+ signatures.c x509utils.h x509utils.c x509.c x509vfy.c \
+ globals.h ../strings.c
+am__objects_1 =
+@SHAREDLIB_HACK_TRUE@am__objects_2 = libxmlsec1_gnutls_la-strings.lo
+am_libxmlsec1_gnutls_la_OBJECTS = libxmlsec1_gnutls_la-app.lo \
+ libxmlsec1_gnutls_la-ciphers.lo libxmlsec1_gnutls_la-crypto.lo \
+ libxmlsec1_gnutls_la-digests.lo libxmlsec1_gnutls_la-hmac.lo \
+ libxmlsec1_gnutls_la-kw_aes.lo libxmlsec1_gnutls_la-kw_des.lo \
+ libxmlsec1_gnutls_la-symkeys.lo \
+ libxmlsec1_gnutls_la-asymkeys.lo \
+ libxmlsec1_gnutls_la-signatures.lo \
+ libxmlsec1_gnutls_la-x509utils.lo libxmlsec1_gnutls_la-x509.lo \
+ libxmlsec1_gnutls_la-x509vfy.lo $(am__objects_1) \
+ $(am__objects_2)
+libxmlsec1_gnutls_la_OBJECTS = $(am_libxmlsec1_gnutls_la_OBJECTS)
+libxmlsec1_gnutls_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libxmlsec1_gnutls_la_LDFLAGS) $(LDFLAGS) -o $@
+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) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libxmlsec1_gnutls_la_SOURCES)
+DIST_SOURCES = $(am__libxmlsec1_gnutls_la_SOURCES_DIST)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CP = @CP@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GCRYPT_CFLAGS = @GCRYPT_CFLAGS@
+GCRYPT_CRYPTO_LIB = @GCRYPT_CRYPTO_LIB@
+GCRYPT_LIBS = @GCRYPT_LIBS@
+GCRYPT_MIN_VERSION = @GCRYPT_MIN_VERSION@
+GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
+GNUTLS_CRYPTO_LIB = @GNUTLS_CRYPTO_LIB@
+GNUTLS_LIBS = @GNUTLS_LIBS@
+GNUTLS_MIN_VERSION = @GNUTLS_MIN_VERSION@
+GREP = @GREP@
+HELP2MAN = @HELP2MAN@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBXML_CFLAGS = @LIBXML_CFLAGS@
+LIBXML_CONFIG = @LIBXML_CONFIG@
+LIBXML_LIBS = @LIBXML_LIBS@
+LIBXML_MIN_VERSION = @LIBXML_MIN_VERSION@
+LIBXSLT_CFLAGS = @LIBXSLT_CFLAGS@
+LIBXSLT_CONFIG = @LIBXSLT_CONFIG@
+LIBXSLT_LIBS = @LIBXSLT_LIBS@
+LIBXSLT_MIN_VERSION = @LIBXSLT_MIN_VERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MAN2HTML = @MAN2HTML@
+MKDIR_P = @MKDIR_P@
+MOZILLA_MIN_VERSION = @MOZILLA_MIN_VERSION@
+MSCRYPTO_CFLAGS = @MSCRYPTO_CFLAGS@
+MSCRYPTO_CRYPTO_LIB = @MSCRYPTO_CRYPTO_LIB@
+MSCRYPTO_LIBS = @MSCRYPTO_LIBS@
+MV = @MV@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSPR_MIN_VERSION = @NSPR_MIN_VERSION@
+NSPR_PACKAGE = @NSPR_PACKAGE@
+NSS_CFLAGS = @NSS_CFLAGS@
+NSS_CRYPTO_LIB = @NSS_CRYPTO_LIB@
+NSS_LIBS = @NSS_LIBS@
+NSS_MIN_VERSION = @NSS_MIN_VERSION@
+NSS_PACKAGE = @NSS_PACKAGE@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
+OPENSSL_CRYPTO_LIB = @OPENSSL_CRYPTO_LIB@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+OPENSSL_MIN_VERSION = @OPENSSL_MIN_VERSION@
+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@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKGCONFIG_PRESENT = @PKGCONFIG_PRESENT@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+RANLIB = @RANLIB@
+RM = @RM@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+TAR = @TAR@
+U = @U@
+VERSION = @VERSION@
+XMLSEC_APP_DEFINES = @XMLSEC_APP_DEFINES@
+XMLSEC_CFLAGS = @XMLSEC_CFLAGS@
+XMLSEC_CORE_CFLAGS = @XMLSEC_CORE_CFLAGS@
+XMLSEC_CORE_LIBS = @XMLSEC_CORE_LIBS@
+XMLSEC_CRYPTO = @XMLSEC_CRYPTO@
+XMLSEC_CRYPTO_CFLAGS = @XMLSEC_CRYPTO_CFLAGS@
+XMLSEC_CRYPTO_DISABLED_LIST = @XMLSEC_CRYPTO_DISABLED_LIST@
+XMLSEC_CRYPTO_EXTRA_LDFLAGS = @XMLSEC_CRYPTO_EXTRA_LDFLAGS@
+XMLSEC_CRYPTO_LIB = @XMLSEC_CRYPTO_LIB@
+XMLSEC_CRYPTO_LIBS = @XMLSEC_CRYPTO_LIBS@
+XMLSEC_CRYPTO_LIST = @XMLSEC_CRYPTO_LIST@
+XMLSEC_CRYPTO_PC_FILES_LIST = @XMLSEC_CRYPTO_PC_FILES_LIST@
+XMLSEC_DEFINES = @XMLSEC_DEFINES@
+XMLSEC_DL_INCLUDES = @XMLSEC_DL_INCLUDES@
+XMLSEC_DL_LIBS = @XMLSEC_DL_LIBS@
+XMLSEC_DOCDIR = @XMLSEC_DOCDIR@
+XMLSEC_EXTRA_LDFLAGS = @XMLSEC_EXTRA_LDFLAGS@
+XMLSEC_GCRYPT_CFLAGS = @XMLSEC_GCRYPT_CFLAGS@
+XMLSEC_GCRYPT_LIBS = @XMLSEC_GCRYPT_LIBS@
+XMLSEC_GNUTLS_CFLAGS = @XMLSEC_GNUTLS_CFLAGS@
+XMLSEC_GNUTLS_LIBS = @XMLSEC_GNUTLS_LIBS@
+XMLSEC_LIBDIR = @XMLSEC_LIBDIR@
+XMLSEC_LIBS = @XMLSEC_LIBS@
+XMLSEC_NO_AES = @XMLSEC_NO_AES@
+XMLSEC_NO_APPS_CRYPTO_DYNAMIC_LOADING = @XMLSEC_NO_APPS_CRYPTO_DYNAMIC_LOADING@
+XMLSEC_NO_CRYPTO_DYNAMIC_LOADING = @XMLSEC_NO_CRYPTO_DYNAMIC_LOADING@
+XMLSEC_NO_DES = @XMLSEC_NO_DES@
+XMLSEC_NO_DSA = @XMLSEC_NO_DSA@
+XMLSEC_NO_GCRYPT = @XMLSEC_NO_GCRYPT@
+XMLSEC_NO_GNUTLS = @XMLSEC_NO_GNUTLS@
+XMLSEC_NO_GOST = @XMLSEC_NO_GOST@
+XMLSEC_NO_HMAC = @XMLSEC_NO_HMAC@
+XMLSEC_NO_LIBXSLT = @XMLSEC_NO_LIBXSLT@
+XMLSEC_NO_MD5 = @XMLSEC_NO_MD5@
+XMLSEC_NO_MSCRYPTO = @XMLSEC_NO_MSCRYPTO@
+XMLSEC_NO_NSS = @XMLSEC_NO_NSS@
+XMLSEC_NO_OPENSSL = @XMLSEC_NO_OPENSSL@
+XMLSEC_NO_RIPEMD160 = @XMLSEC_NO_RIPEMD160@
+XMLSEC_NO_RSA = @XMLSEC_NO_RSA@
+XMLSEC_NO_SHA1 = @XMLSEC_NO_SHA1@
+XMLSEC_NO_SHA224 = @XMLSEC_NO_SHA224@
+XMLSEC_NO_SHA256 = @XMLSEC_NO_SHA256@
+XMLSEC_NO_SHA384 = @XMLSEC_NO_SHA384@
+XMLSEC_NO_SHA512 = @XMLSEC_NO_SHA512@
+XMLSEC_NO_X509 = @XMLSEC_NO_X509@
+XMLSEC_NO_XKMS = @XMLSEC_NO_XKMS@
+XMLSEC_NO_XMLDSIG = @XMLSEC_NO_XMLDSIG@
+XMLSEC_NO_XMLENC = @XMLSEC_NO_XMLENC@
+XMLSEC_NSS_CFLAGS = @XMLSEC_NSS_CFLAGS@
+XMLSEC_NSS_LIBS = @XMLSEC_NSS_LIBS@
+XMLSEC_OPENSSL_CFLAGS = @XMLSEC_OPENSSL_CFLAGS@
+XMLSEC_OPENSSL_LIBS = @XMLSEC_OPENSSL_LIBS@
+XMLSEC_PACKAGE = @XMLSEC_PACKAGE@
+XMLSEC_STATIC_BINARIES = @XMLSEC_STATIC_BINARIES@
+XMLSEC_VERSION = @XMLSEC_VERSION@
+XMLSEC_VERSION_INFO = @XMLSEC_VERSION_INFO@
+XMLSEC_VERSION_MAJOR = @XMLSEC_VERSION_MAJOR@
+XMLSEC_VERSION_MINOR = @XMLSEC_VERSION_MINOR@
+XMLSEC_VERSION_SAFE = @XMLSEC_VERSION_SAFE@
+XMLSEC_VERSION_SUBMINOR = @XMLSEC_VERSION_SUBMINOR@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+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@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+NULL =
+EXTRA_DIST = \
+ README \
+ $(NULL)
+
+lib_LTLIBRARIES = \
+ libxmlsec1-gnutls.la \
+ $(NULL)
+
+libxmlsec1_gnutls_la_CPPFLAGS = \
+ -DPACKAGE=\"@PACKAGE@\" \
+ -I../../include \
+ -I$(top_srcdir)/include \
+ $(XMLSEC_DEFINES) \
+ $(GNUTLS_CFLAGS) \
+ $(LIBXSLT_CFLAGS) \
+ $(LIBXML_CFLAGS) \
+ $(NULL)
+
+libxmlsec1_gnutls_la_SOURCES = app.c ciphers.c crypto.c digests.c \
+ hmac.c kw_aes.c kw_des.c symkeys.c asymkeys.c signatures.c \
+ x509utils.h x509utils.c x509.c x509vfy.c globals.h $(NULL) \
+ $(am__append_1)
+
+# xmlsec-gnutls library requires xmlsec-gcrypt
+libxmlsec1_gnutls_la_LIBADD = \
+ $(GNUTLS_LIBS) \
+ $(LIBXSLT_LIBS) \
+ $(LIBXML_LIBS) \
+ ../libxmlsec1.la \
+ ../gcrypt/libxmlsec1-gcrypt.la \
+ $(NULL)
+
+libxmlsec1_gnutls_la_DEPENDENCIES = \
+ $(NULL)
+
+libxmlsec1_gnutls_la_LDFLAGS = \
+ @XMLSEC_CRYPTO_EXTRA_LDFLAGS@ \
+ -version-info @XMLSEC_VERSION_INFO@ \
+ $(NULL)
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(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/gnutls/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/gnutls/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: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+ }
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libxmlsec1-gnutls.la: $(libxmlsec1_gnutls_la_OBJECTS) $(libxmlsec1_gnutls_la_DEPENDENCIES)
+ $(libxmlsec1_gnutls_la_LINK) -rpath $(libdir) $(libxmlsec1_gnutls_la_OBJECTS) $(libxmlsec1_gnutls_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxmlsec1_gnutls_la-app.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxmlsec1_gnutls_la-asymkeys.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxmlsec1_gnutls_la-ciphers.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxmlsec1_gnutls_la-crypto.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxmlsec1_gnutls_la-digests.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxmlsec1_gnutls_la-hmac.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxmlsec1_gnutls_la-kw_aes.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxmlsec1_gnutls_la-kw_des.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxmlsec1_gnutls_la-signatures.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxmlsec1_gnutls_la-strings.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxmlsec1_gnutls_la-symkeys.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxmlsec1_gnutls_la-x509.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxmlsec1_gnutls_la-x509utils.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxmlsec1_gnutls_la-x509vfy.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+libxmlsec1_gnutls_la-app.lo: app.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxmlsec1_gnutls_la-app.lo -MD -MP -MF $(DEPDIR)/libxmlsec1_gnutls_la-app.Tpo -c -o libxmlsec1_gnutls_la-app.lo `test -f 'app.c' || echo '$(srcdir)/'`app.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libxmlsec1_gnutls_la-app.Tpo $(DEPDIR)/libxmlsec1_gnutls_la-app.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='app.c' object='libxmlsec1_gnutls_la-app.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxmlsec1_gnutls_la-app.lo `test -f 'app.c' || echo '$(srcdir)/'`app.c
+
+libxmlsec1_gnutls_la-ciphers.lo: ciphers.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxmlsec1_gnutls_la-ciphers.lo -MD -MP -MF $(DEPDIR)/libxmlsec1_gnutls_la-ciphers.Tpo -c -o libxmlsec1_gnutls_la-ciphers.lo `test -f 'ciphers.c' || echo '$(srcdir)/'`ciphers.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libxmlsec1_gnutls_la-ciphers.Tpo $(DEPDIR)/libxmlsec1_gnutls_la-ciphers.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ciphers.c' object='libxmlsec1_gnutls_la-ciphers.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxmlsec1_gnutls_la-ciphers.lo `test -f 'ciphers.c' || echo '$(srcdir)/'`ciphers.c
+
+libxmlsec1_gnutls_la-crypto.lo: crypto.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxmlsec1_gnutls_la-crypto.lo -MD -MP -MF $(DEPDIR)/libxmlsec1_gnutls_la-crypto.Tpo -c -o libxmlsec1_gnutls_la-crypto.lo `test -f 'crypto.c' || echo '$(srcdir)/'`crypto.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libxmlsec1_gnutls_la-crypto.Tpo $(DEPDIR)/libxmlsec1_gnutls_la-crypto.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto.c' object='libxmlsec1_gnutls_la-crypto.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxmlsec1_gnutls_la-crypto.lo `test -f 'crypto.c' || echo '$(srcdir)/'`crypto.c
+
+libxmlsec1_gnutls_la-digests.lo: digests.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxmlsec1_gnutls_la-digests.lo -MD -MP -MF $(DEPDIR)/libxmlsec1_gnutls_la-digests.Tpo -c -o libxmlsec1_gnutls_la-digests.lo `test -f 'digests.c' || echo '$(srcdir)/'`digests.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libxmlsec1_gnutls_la-digests.Tpo $(DEPDIR)/libxmlsec1_gnutls_la-digests.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='digests.c' object='libxmlsec1_gnutls_la-digests.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxmlsec1_gnutls_la-digests.lo `test -f 'digests.c' || echo '$(srcdir)/'`digests.c
+
+libxmlsec1_gnutls_la-hmac.lo: hmac.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxmlsec1_gnutls_la-hmac.lo -MD -MP -MF $(DEPDIR)/libxmlsec1_gnutls_la-hmac.Tpo -c -o libxmlsec1_gnutls_la-hmac.lo `test -f 'hmac.c' || echo '$(srcdir)/'`hmac.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libxmlsec1_gnutls_la-hmac.Tpo $(DEPDIR)/libxmlsec1_gnutls_la-hmac.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='hmac.c' object='libxmlsec1_gnutls_la-hmac.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxmlsec1_gnutls_la-hmac.lo `test -f 'hmac.c' || echo '$(srcdir)/'`hmac.c
+
+libxmlsec1_gnutls_la-kw_aes.lo: kw_aes.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxmlsec1_gnutls_la-kw_aes.lo -MD -MP -MF $(DEPDIR)/libxmlsec1_gnutls_la-kw_aes.Tpo -c -o libxmlsec1_gnutls_la-kw_aes.lo `test -f 'kw_aes.c' || echo '$(srcdir)/'`kw_aes.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libxmlsec1_gnutls_la-kw_aes.Tpo $(DEPDIR)/libxmlsec1_gnutls_la-kw_aes.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='kw_aes.c' object='libxmlsec1_gnutls_la-kw_aes.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxmlsec1_gnutls_la-kw_aes.lo `test -f 'kw_aes.c' || echo '$(srcdir)/'`kw_aes.c
+
+libxmlsec1_gnutls_la-kw_des.lo: kw_des.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxmlsec1_gnutls_la-kw_des.lo -MD -MP -MF $(DEPDIR)/libxmlsec1_gnutls_la-kw_des.Tpo -c -o libxmlsec1_gnutls_la-kw_des.lo `test -f 'kw_des.c' || echo '$(srcdir)/'`kw_des.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libxmlsec1_gnutls_la-kw_des.Tpo $(DEPDIR)/libxmlsec1_gnutls_la-kw_des.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='kw_des.c' object='libxmlsec1_gnutls_la-kw_des.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxmlsec1_gnutls_la-kw_des.lo `test -f 'kw_des.c' || echo '$(srcdir)/'`kw_des.c
+
+libxmlsec1_gnutls_la-symkeys.lo: symkeys.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxmlsec1_gnutls_la-symkeys.lo -MD -MP -MF $(DEPDIR)/libxmlsec1_gnutls_la-symkeys.Tpo -c -o libxmlsec1_gnutls_la-symkeys.lo `test -f 'symkeys.c' || echo '$(srcdir)/'`symkeys.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libxmlsec1_gnutls_la-symkeys.Tpo $(DEPDIR)/libxmlsec1_gnutls_la-symkeys.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='symkeys.c' object='libxmlsec1_gnutls_la-symkeys.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxmlsec1_gnutls_la-symkeys.lo `test -f 'symkeys.c' || echo '$(srcdir)/'`symkeys.c
+
+libxmlsec1_gnutls_la-asymkeys.lo: asymkeys.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxmlsec1_gnutls_la-asymkeys.lo -MD -MP -MF $(DEPDIR)/libxmlsec1_gnutls_la-asymkeys.Tpo -c -o libxmlsec1_gnutls_la-asymkeys.lo `test -f 'asymkeys.c' || echo '$(srcdir)/'`asymkeys.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libxmlsec1_gnutls_la-asymkeys.Tpo $(DEPDIR)/libxmlsec1_gnutls_la-asymkeys.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='asymkeys.c' object='libxmlsec1_gnutls_la-asymkeys.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxmlsec1_gnutls_la-asymkeys.lo `test -f 'asymkeys.c' || echo '$(srcdir)/'`asymkeys.c
+
+libxmlsec1_gnutls_la-signatures.lo: signatures.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxmlsec1_gnutls_la-signatures.lo -MD -MP -MF $(DEPDIR)/libxmlsec1_gnutls_la-signatures.Tpo -c -o libxmlsec1_gnutls_la-signatures.lo `test -f 'signatures.c' || echo '$(srcdir)/'`signatures.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libxmlsec1_gnutls_la-signatures.Tpo $(DEPDIR)/libxmlsec1_gnutls_la-signatures.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='signatures.c' object='libxmlsec1_gnutls_la-signatures.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxmlsec1_gnutls_la-signatures.lo `test -f 'signatures.c' || echo '$(srcdir)/'`signatures.c
+
+libxmlsec1_gnutls_la-x509utils.lo: x509utils.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxmlsec1_gnutls_la-x509utils.lo -MD -MP -MF $(DEPDIR)/libxmlsec1_gnutls_la-x509utils.Tpo -c -o libxmlsec1_gnutls_la-x509utils.lo `test -f 'x509utils.c' || echo '$(srcdir)/'`x509utils.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libxmlsec1_gnutls_la-x509utils.Tpo $(DEPDIR)/libxmlsec1_gnutls_la-x509utils.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='x509utils.c' object='libxmlsec1_gnutls_la-x509utils.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxmlsec1_gnutls_la-x509utils.lo `test -f 'x509utils.c' || echo '$(srcdir)/'`x509utils.c
+
+libxmlsec1_gnutls_la-x509.lo: x509.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxmlsec1_gnutls_la-x509.lo -MD -MP -MF $(DEPDIR)/libxmlsec1_gnutls_la-x509.Tpo -c -o libxmlsec1_gnutls_la-x509.lo `test -f 'x509.c' || echo '$(srcdir)/'`x509.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libxmlsec1_gnutls_la-x509.Tpo $(DEPDIR)/libxmlsec1_gnutls_la-x509.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='x509.c' object='libxmlsec1_gnutls_la-x509.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxmlsec1_gnutls_la-x509.lo `test -f 'x509.c' || echo '$(srcdir)/'`x509.c
+
+libxmlsec1_gnutls_la-x509vfy.lo: x509vfy.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxmlsec1_gnutls_la-x509vfy.lo -MD -MP -MF $(DEPDIR)/libxmlsec1_gnutls_la-x509vfy.Tpo -c -o libxmlsec1_gnutls_la-x509vfy.lo `test -f 'x509vfy.c' || echo '$(srcdir)/'`x509vfy.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libxmlsec1_gnutls_la-x509vfy.Tpo $(DEPDIR)/libxmlsec1_gnutls_la-x509vfy.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='x509vfy.c' object='libxmlsec1_gnutls_la-x509vfy.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxmlsec1_gnutls_la-x509vfy.lo `test -f 'x509vfy.c' || echo '$(srcdir)/'`x509vfy.c
+
+libxmlsec1_gnutls_la-strings.lo: ../strings.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxmlsec1_gnutls_la-strings.lo -MD -MP -MF $(DEPDIR)/libxmlsec1_gnutls_la-strings.Tpo -c -o libxmlsec1_gnutls_la-strings.lo `test -f '../strings.c' || echo '$(srcdir)/'`../strings.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libxmlsec1_gnutls_la-strings.Tpo $(DEPDIR)/libxmlsec1_gnutls_la-strings.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='../strings.c' object='libxmlsec1_gnutls_la-strings.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxmlsec1_gnutls_la-strings.lo `test -f '../strings.c' || echo '$(srcdir)/'`../strings.c
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+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
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(libdir)"; 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-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+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)
+
+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-generic clean-libLTLIBRARIES clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(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-libLTLIBRARIES
+
+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)
+ -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: uninstall-libLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libLTLIBRARIES clean-libtool ctags 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-libLTLIBRARIES 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 uninstall uninstall-am uninstall-libLTLIBRARIES
+
+
+# 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/gnutls/README b/src/gnutls/README
new file mode 100644
index 00000000..404aa878
--- /dev/null
+++ b/src/gnutls/README
@@ -0,0 +1,6 @@
+The xmlsec-gnutls uses both libgcrypt and libgnutls because GnuTLS
+does not provide direct access to low-level crypto operations (digests,
+hmac, aes, des, etc.).
+
+
+
diff --git a/src/gnutls/app.c b/src/gnutls/app.c
new file mode 100644
index 00000000..856257f3
--- /dev/null
+++ b/src/gnutls/app.c
@@ -0,0 +1,998 @@
+/**
+ * XMLSec library
+ *
+ * This is free software; see Copyright file in the source
+ * distribution for preciese wording.
+ *
+ * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
+ */
+#include "globals.h"
+
+#include <string.h>
+
+#include <xmlsec/xmlsec.h>
+#include <xmlsec/keys.h>
+#include <xmlsec/transforms.h>
+#include <xmlsec/errors.h>
+
+#include <xmlsec/gnutls/app.h>
+#include <xmlsec/gnutls/crypto.h>
+#include <xmlsec/gnutls/x509.h>
+
+#include "x509utils.h"
+
+/**************************************************************************
+ *
+ * We use xmlsec-gcrypt for all the basic crypto ops
+ *
+ *****************************************************************************/
+#include <xmlsec/gcrypt/crypto.h>
+#include <xmlsec/gcrypt/app.h>
+
+static xmlSecKeyPtr xmlSecGnuTLSAppKeyFromCertLoad (const char *filename,
+ xmlSecKeyDataFormat format);
+static xmlSecKeyPtr xmlSecGnuTLSAppKeyFromCertLoadMemory (const xmlSecByte* data,
+ xmlSecSize dataSize,
+ xmlSecKeyDataFormat format);
+
+/**
+ * xmlSecGnuTLSAppInit:
+ * @config: the path to GnuTLS configuration (unused).
+ *
+ * General crypto engine initialization. This function is used
+ * by XMLSec command line utility and called before
+ * @xmlSecInit function.
+ *
+ * Returns: 0 on success or a negative value otherwise.
+ */
+int
+xmlSecGnuTLSAppInit(const char* config) {
+ int err;
+
+ err = gnutls_global_init();
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_global_init",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ return(-1);
+ }
+
+ return(xmlSecGCryptAppInit(config));
+}
+
+/**
+ * xmlSecGnuTLSAppShutdown:
+ *
+ * General crypto engine shutdown. This function is used
+ * by XMLSec command line utility and called after
+ * @xmlSecShutdown function.
+ *
+ * Returns: 0 on success or a negative value otherwise.
+ */
+int
+xmlSecGnuTLSAppShutdown(void) {
+ gnutls_global_deinit();
+
+ return(xmlSecGCryptAppShutdown());
+}
+
+/**
+ * xmlSecGnuTLSAppKeyLoad:
+ * @filename: the key filename.
+ * @format: the key file format.
+ * @pwd: the key file password.
+ * @pwdCallback: the key password callback.
+ * @pwdCallbackCtx: the user context for password callback.
+ *
+ * Reads key from the a file.
+ *
+ * Returns: pointer to the key or NULL if an error occurs.
+ */
+xmlSecKeyPtr
+xmlSecGnuTLSAppKeyLoad(const char *filename, xmlSecKeyDataFormat format,
+ const char *pwd,
+ void* pwdCallback,
+ void* pwdCallbackCtx) {
+ xmlSecKeyPtr key;
+
+ xmlSecAssert2(filename != NULL, NULL);
+ xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, NULL);
+
+ switch(format) {
+#ifndef XMLSEC_NO_X509
+ case xmlSecKeyDataFormatPkcs12:
+ key = xmlSecGnuTLSAppPkcs12Load(filename, pwd, pwdCallback, pwdCallbackCtx);
+ break;
+ case xmlSecKeyDataFormatCertPem:
+ case xmlSecKeyDataFormatCertDer:
+ key = xmlSecGnuTLSAppKeyFromCertLoad(filename, format);
+ break;
+#endif /* XMLSEC_NO_X509 */
+ default:
+ key = xmlSecGCryptAppKeyLoad(filename, format, pwd, pwdCallback, pwdCallbackCtx);
+ break;
+ }
+
+ return(key);
+}
+
+/**
+ * xmlSecGnuTLSAppKeyLoadMemory:
+ * @data: the binary key data.
+ * @dataSize: the size of binary key.
+ * @format: the key file format.
+ * @pwd: the key file password.
+ * @pwdCallback: the key password callback.
+ * @pwdCallbackCtx: the user context for password callback.
+ *
+ * Reads key from the memory buffer.
+ *
+ * Returns: pointer to the key or NULL if an error occurs.
+ */
+xmlSecKeyPtr
+xmlSecGnuTLSAppKeyLoadMemory(const xmlSecByte* data, xmlSecSize dataSize,
+ xmlSecKeyDataFormat format, const char *pwd,
+ void* pwdCallback, void* pwdCallbackCtx) {
+ xmlSecKeyPtr key;
+
+ xmlSecAssert2(data != NULL, NULL);
+ xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, NULL);
+
+ switch(format) {
+#ifndef XMLSEC_NO_X509
+ case xmlSecKeyDataFormatPkcs12:
+ key = xmlSecGnuTLSAppPkcs12LoadMemory(data, dataSize, pwd, pwdCallback, pwdCallbackCtx);
+ break;
+ case xmlSecKeyDataFormatCertPem:
+ case xmlSecKeyDataFormatCertDer:
+ key = xmlSecGnuTLSAppKeyFromCertLoadMemory(data, dataSize, format);
+ break;
+#endif /* XMLSEC_NO_X509 */
+ default:
+ key = xmlSecGCryptAppKeyLoadMemory(data, dataSize, format, pwd, pwdCallback, pwdCallbackCtx);
+ break;
+ }
+ return(key);
+}
+
+#ifndef XMLSEC_NO_X509
+/**
+ * xmlSecGnuTLSAppKeyCertLoad:
+ * @key: the pointer to key.
+ * @filename: the certificate filename.
+ * @format: the certificate file format.
+ *
+ * Reads the certificate from $@filename and adds it to key.
+ *
+ * Returns: 0 on success or a negative value otherwise.
+ */
+int
+xmlSecGnuTLSAppKeyCertLoad(xmlSecKeyPtr key, const char* filename,
+ xmlSecKeyDataFormat format) {
+ xmlSecBuffer buffer;
+ int ret;
+
+ xmlSecAssert2(key != NULL, -1);
+ xmlSecAssert2(filename != NULL, -1);
+ xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, -1);
+
+ ret = xmlSecBufferInitialize(&buffer, 4*1024);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecBufferInitialize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ ret = xmlSecBufferReadFile(&buffer, filename);
+ if((ret < 0) || (xmlSecBufferGetData(&buffer) == NULL) || (xmlSecBufferGetSize(&buffer) <= 0)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecBufferReadFile",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "filename=%s",
+ xmlSecErrorsSafeString(filename));
+ xmlSecBufferFinalize(&buffer);
+ return(-1);
+ }
+
+ ret = xmlSecGnuTLSAppKeyCertLoadMemory(key,
+ xmlSecBufferGetData(&buffer),
+ xmlSecBufferGetSize(&buffer),
+ format);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSAppKeyCertLoadMemory",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "filename=%s",
+ xmlSecErrorsSafeString(filename));
+ xmlSecBufferFinalize(&buffer);
+ return(-1);
+ }
+
+ /* cleanup */
+ xmlSecBufferFinalize(&buffer);
+ return(0);
+}
+
+/**
+ * xmlSecGnuTLSAppKeyCertLoadMemory:
+ * @key: the pointer to key.
+ * @data: the certificate binary data.
+ * @dataSize: the certificate binary data size.
+ * @format: the certificate file format.
+ *
+ * Reads the certificate from memory buffer and adds it to key.
+ *
+ * Returns: 0 on success or a negative value otherwise.
+ */
+int
+xmlSecGnuTLSAppKeyCertLoadMemory(xmlSecKeyPtr key,
+ const xmlSecByte* data,
+ xmlSecSize dataSize,
+ xmlSecKeyDataFormat format) {
+ gnutls_x509_crt_t cert;
+ xmlSecKeyDataPtr keyData;
+ int ret;
+
+ xmlSecAssert2(key != NULL, -1);
+ xmlSecAssert2(data != NULL, -1);
+ xmlSecAssert2(dataSize > 0, -1);
+ xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, -1);
+
+ keyData = xmlSecKeyEnsureData(key, xmlSecGnuTLSKeyDataX509Id);
+ if(keyData == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyEnsureData",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ cert = xmlSecGnuTLSX509CertRead(data, dataSize, format);
+ if(cert == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSX509CertRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ ret = xmlSecGnuTLSKeyDataX509AdoptCert(keyData, cert);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSKeyDataX509AdoptCert",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ gnutls_x509_crt_deinit(cert);
+ return(-1);
+ }
+
+ return(0);
+}
+
+/**
+ * xmlSecGnuTLSAppPkcs12Load:
+ * @filename: the PKCS12 key filename.
+ * @pwd: the PKCS12 file password.
+ * @pwdCallback: the password callback.
+ * @pwdCallbackCtx: the user context for password callback.
+ *
+ * Reads key and all associated certificates from the PKCS12 file.
+ * For uniformity, call xmlSecGnuTLSAppKeyLoad instead of this function. Pass
+ * in format=xmlSecKeyDataFormatPkcs12.
+ *
+ * Returns: pointer to the key or NULL if an error occurs.
+ */
+xmlSecKeyPtr
+xmlSecGnuTLSAppPkcs12Load(const char *filename,
+ const char *pwd,
+ void* pwdCallback,
+ void* pwdCallbackCtx) {
+ xmlSecKeyPtr key;
+ xmlSecBuffer buffer;
+ int ret;
+
+ xmlSecAssert2(filename != NULL, NULL);
+
+ ret = xmlSecBufferInitialize(&buffer, 4*1024);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecBufferInitialize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+
+ ret = xmlSecBufferReadFile(&buffer, filename);
+ if((ret < 0) || (xmlSecBufferGetData(&buffer) == NULL) || (xmlSecBufferGetSize(&buffer) <= 0)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecBufferReadFile",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "filename=%s",
+ xmlSecErrorsSafeString(filename));
+ xmlSecBufferFinalize(&buffer);
+ return(NULL);
+ }
+
+ key = xmlSecGnuTLSAppPkcs12LoadMemory(xmlSecBufferGetData(&buffer),
+ xmlSecBufferGetSize(&buffer),
+ pwd, pwdCallback, pwdCallbackCtx);
+ if(key == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSAppPkcs12LoadMemory",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "filename=%s",
+ xmlSecErrorsSafeString(filename));
+ xmlSecBufferFinalize(&buffer);
+ return(NULL);
+ }
+
+ /* cleanup */
+ xmlSecBufferFinalize(&buffer);
+ return(key);
+}
+
+/**
+ * xmlSecGnuTLSAppPkcs12LoadMemory:
+ * @data: the PKCS12 binary data.
+ * @dataSize: the PKCS12 binary data size.
+ * @pwd: the PKCS12 file password.
+ * @pwdCallback: the password callback.
+ * @pwdCallbackCtx: the user context for password callback.
+ *
+ * Reads key and all associated certificates from the PKCS12 data in memory buffer.
+ * For uniformity, call xmlSecGnuTLSAppKeyLoadMemory instead of this function. Pass
+ * in format=xmlSecKeyDataFormatPkcs12.
+ *
+ * Returns: pointer to the key or NULL if an error occurs.
+ */
+xmlSecKeyPtr
+xmlSecGnuTLSAppPkcs12LoadMemory(const xmlSecByte* data, xmlSecSize dataSize,
+ const char *pwd,
+ void* pwdCallback ATTRIBUTE_UNUSED,
+ void* pwdCallbackCtx ATTRIBUTE_UNUSED)
+{
+ xmlSecKeyPtr key = NULL;
+ xmlSecKeyPtr res = NULL;
+ xmlSecPtrList certsList;
+ xmlSecKeyDataPtr keyData = NULL;
+ xmlSecKeyDataPtr x509Data = NULL;
+ gnutls_x509_privkey_t priv_key = NULL;
+ gnutls_x509_crt_t key_cert = NULL;
+ xmlSecSize certsSize;
+ int ret;
+
+ xmlSecAssert2(data != NULL, NULL);
+ xmlSecAssert2(dataSize > 0, NULL);
+
+ /* prepare */
+ ret = xmlSecPtrListInitialize(&(certsList), xmlSecGnuTLSX509CrtListId);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecPtrListInitialize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "certsList");
+ return(NULL);
+ }
+
+ /* load pkcs12 */
+ ret = xmlSecGnuTLSPkcs12LoadMemory(data, dataSize, pwd, &priv_key, &key_cert, &certsList);
+ if((ret < 0) || (priv_key == NULL)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSPkcs12LoadMemory",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+
+ /* create key */
+ key = xmlSecKeyCreate();
+ if(key == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyCreate",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+
+ /* create key value data */
+ keyData = xmlSecGnuTLSCreateKeyDataAndAdoptPrivKey(priv_key);
+ if(keyData == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSCreateKeyDataAndAdoptPrivKey",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+ priv_key = NULL; /* owned by keyData now */
+
+ ret = xmlSecKeySetValue(key, keyData);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeySetValue",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "data=%s",
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
+ goto done;
+ }
+ keyData = NULL; /* owned by key now */
+
+
+ /* create x509 certs data */
+ certsSize = xmlSecPtrListGetSize(&certsList);
+ if((certsSize > 0) || (key_cert != NULL)) {
+ xmlSecSize ii;
+
+ x509Data = xmlSecKeyDataCreate(xmlSecGnuTLSKeyDataX509Id);
+ if(x509Data == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyDataCreate(xmlSecGnuTLSKeyDataX509Id)",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+
+ /* set key's cert */
+ if(key_cert != NULL) {
+ ret = xmlSecGnuTLSKeyDataX509AdoptKeyCert(x509Data, key_cert);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSKeyDataX509AdoptKeyCert",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+ key_cert = NULL; /* owned by x509Data now */
+ }
+
+ /* copy all other certs */
+ for(ii = 0; ii < certsSize; ++ii) {
+ gnutls_x509_crt_t cert = xmlSecPtrListRemoveAndReturn(&certsList, ii);
+ if(cert == NULL) {
+ continue;
+ }
+
+ ret = xmlSecGnuTLSKeyDataX509AdoptCert(x509Data, cert);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSKeyDataX509AdoptCert",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ gnutls_x509_crt_deinit(cert);
+ goto done;
+ }
+ }
+
+ /* set in the key */
+ ret = xmlSecKeyAdoptData(key, x509Data);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyAdoptData",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "data=%s",
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
+ goto done;
+ }
+ x509Data = NULL; /* owned by key now */
+ }
+
+ /* success!!! */
+ res = key;
+ key = NULL;
+
+done:
+ if(key_cert != NULL) {
+ gnutls_x509_crt_deinit(key_cert);
+ }
+ if(priv_key != NULL) {
+ gnutls_x509_privkey_deinit(priv_key);
+ }
+ if(keyData != NULL) {
+ xmlSecKeyDataDestroy(keyData);
+ }
+ if(x509Data != NULL) {
+ xmlSecKeyDataDestroy(x509Data);
+ }
+ if(key != NULL) {
+ xmlSecKeyDestroy(key);
+ }
+ xmlSecPtrListFinalize(&certsList);
+ return(res);
+}
+
+static xmlSecKeyPtr
+xmlSecGnuTLSAppKeyFromCertLoad(const char *filename,
+ xmlSecKeyDataFormat format)
+{
+ xmlSecKeyPtr key;
+ xmlSecBuffer buffer;
+ int ret;
+
+ xmlSecAssert2(filename != NULL, NULL);
+
+ ret = xmlSecBufferInitialize(&buffer, 4*1024);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecBufferInitialize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+
+ ret = xmlSecBufferReadFile(&buffer, filename);
+ if((ret < 0) || (xmlSecBufferGetData(&buffer) == NULL) || (xmlSecBufferGetSize(&buffer) <= 0)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecBufferReadFile",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "filename=%s",
+ xmlSecErrorsSafeString(filename));
+ xmlSecBufferFinalize(&buffer);
+ return(NULL);
+ }
+
+ key = xmlSecGnuTLSAppKeyFromCertLoadMemory(
+ xmlSecBufferGetData(&buffer),
+ xmlSecBufferGetSize(&buffer),
+ format);
+ if(key == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSAppKeyFromCertLoadMemory",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "filename=%s",
+ xmlSecErrorsSafeString(filename));
+ xmlSecBufferFinalize(&buffer);
+ return(NULL);
+ }
+
+ /* cleanup */
+ xmlSecBufferFinalize(&buffer);
+ return(key);
+}
+
+static xmlSecKeyPtr
+xmlSecGnuTLSAppKeyFromCertLoadMemory(const xmlSecByte* data,
+ xmlSecSize dataSize,
+ xmlSecKeyDataFormat format)
+{
+ xmlSecKeyPtr key = NULL;
+ xmlSecKeyDataPtr keyData = NULL;
+ xmlSecKeyDataPtr x509Data = NULL;
+ gnutls_x509_crt_t cert = NULL;
+ xmlSecKeyPtr res = NULL;
+ int ret;
+
+ xmlSecAssert2(data != NULL, NULL);
+ xmlSecAssert2(dataSize > 0, NULL);
+ xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, NULL);
+
+ /* read cert */
+ cert = xmlSecGnuTLSX509CertRead(data, dataSize, format);
+ if(cert == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSX509CertRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+
+ /* create key */
+ key = xmlSecKeyCreate();
+ if(key == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyCreate",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+
+ /* create key value data */
+ keyData = xmlSecGnuTLSX509CertGetKey(cert);
+ if(keyData == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSX509CertGetKey",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+
+ ret = xmlSecKeySetValue(key, keyData);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeySetValue",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "data=%s",
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
+ goto done;
+ }
+ keyData = NULL; /* owned by key now */
+
+ /* create x509 data */
+ x509Data = xmlSecKeyEnsureData(key, xmlSecGnuTLSKeyDataX509Id);
+ if(x509Data == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyEnsureData",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+ ret = xmlSecGnuTLSKeyDataX509AdoptKeyCert(x509Data, cert);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSKeyDataX509AdoptKeyCert",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+ cert = NULL; /* owned by x509Data now */
+
+ /* success */
+ res = key;
+ key = NULL;
+
+done:
+ if(cert != NULL) {
+ gnutls_x509_crt_deinit(cert);
+ }
+ if(keyData != NULL) {
+ xmlSecKeyDataDestroy(keyData);
+ }
+ if(key != NULL) {
+ xmlSecKeyDestroy(key);
+ }
+ return(res);
+}
+
+/**
+ * xmlSecGnuTLSAppKeysMngrCertLoad:
+ * @mngr: the keys manager.
+ * @filename: the certificate file.
+ * @format: the certificate file format.
+ * @type: the flag that indicates is the certificate in @filename
+ * trusted or not.
+ *
+ * Reads cert from @filename and adds to the list of trusted or known
+ * untrusted certs in @store.
+ *
+ * Returns: 0 on success or a negative value otherwise.
+ */
+int
+xmlSecGnuTLSAppKeysMngrCertLoad(xmlSecKeysMngrPtr mngr,
+ const char *filename,
+ xmlSecKeyDataFormat format,
+ xmlSecKeyDataType type) {
+ xmlSecBuffer buffer;
+ int ret;
+
+ xmlSecAssert2(mngr != NULL, -1);
+ xmlSecAssert2(filename != NULL, -1);
+ xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, -1);
+
+ ret = xmlSecBufferInitialize(&buffer, 4*1024);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecBufferInitialize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ ret = xmlSecBufferReadFile(&buffer, filename);
+ if((ret < 0) || (xmlSecBufferGetData(&buffer) == NULL) || (xmlSecBufferGetSize(&buffer) <= 0)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecBufferReadFile",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "filename=%s",
+ xmlSecErrorsSafeString(filename));
+ xmlSecBufferFinalize(&buffer);
+ return(-1);
+ }
+
+ ret = xmlSecGnuTLSAppKeysMngrCertLoadMemory(mngr,
+ xmlSecBufferGetData(&buffer),
+ xmlSecBufferGetSize(&buffer),
+ format,
+ type);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSAppKeysMngrCertLoadMemory",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "filename=%s",
+ xmlSecErrorsSafeString(filename));
+ xmlSecBufferFinalize(&buffer);
+ return(-1);
+ }
+
+ /* cleanup */
+ xmlSecBufferFinalize(&buffer);
+ return(0);
+}
+
+/**
+ * xmlSecGnuTLSAppKeysMngrCertLoadMemory:
+ * @mngr: the keys manager.
+ * @data: the certificate binary data.
+ * @dataSize: the certificate binary data size.
+ * @format: the certificate file format.
+ * @type: the flag that indicates is the certificate trusted or not.
+ *
+ * Reads cert from binary buffer @data and adds to the list of trusted or known
+ * untrusted certs in @store.
+ *
+ * Returns: 0 on success or a negative value otherwise.
+ */
+int
+xmlSecGnuTLSAppKeysMngrCertLoadMemory(xmlSecKeysMngrPtr mngr,
+ const xmlSecByte* data,
+ xmlSecSize dataSize,
+ xmlSecKeyDataFormat format,
+ xmlSecKeyDataType type) {
+ xmlSecKeyDataStorePtr x509Store;
+ gnutls_x509_crt_t cert;
+ int ret;
+
+ xmlSecAssert2(mngr != NULL, -1);
+ xmlSecAssert2(data != NULL, -1);
+ xmlSecAssert2(dataSize > 0, -1);
+ xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, -1);
+
+ x509Store = xmlSecKeysMngrGetDataStore(mngr, xmlSecGnuTLSX509StoreId);
+ if(x509Store == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeysMngrGetDataStore",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "xmlSecGnuTLSX509StoreId");
+ return(-1);
+ }
+
+ cert = xmlSecGnuTLSX509CertRead(data, dataSize, format);
+ if(cert == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSX509CertRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ ret = xmlSecGnuTLSX509StoreAdoptCert(x509Store, cert, type);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSX509StoreAdoptCert",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ gnutls_x509_crt_deinit(cert);
+ return(-1);
+ }
+
+ return(0);
+}
+
+#endif /* XMLSEC_NO_X509 */
+
+/**
+ * xmlSecGnuTLSAppDefaultKeysMngrInit:
+ * @mngr: the pointer to keys manager.
+ *
+ * Initializes @mngr with simple keys store #xmlSecSimpleKeysStoreId
+ * and a default GnuTLS crypto key data stores.
+ *
+ * Returns: 0 on success or a negative value otherwise.
+ */
+int
+xmlSecGnuTLSAppDefaultKeysMngrInit(xmlSecKeysMngrPtr mngr) {
+ int ret;
+
+ xmlSecAssert2(mngr != NULL, -1);
+
+ /* create simple keys store if needed */
+ if(xmlSecKeysMngrGetKeysStore(mngr) == NULL) {
+ xmlSecKeyStorePtr keysStore;
+
+ keysStore = xmlSecKeyStoreCreate(xmlSecSimpleKeysStoreId);
+ if(keysStore == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyStoreCreate",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "xmlSecSimpleKeysStoreId");
+ return(-1);
+ }
+
+ ret = xmlSecKeysMngrAdoptKeysStore(mngr, keysStore);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeysMngrAdoptKeysStore",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecKeyStoreDestroy(keysStore);
+ return(-1);
+ }
+ }
+
+ ret = xmlSecGnuTLSKeysMngrInit(mngr);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSKeysMngrInit",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* TODO */
+ mngr->getKey = xmlSecKeysMngrGetKey;
+ return(0);
+}
+
+/**
+ * xmlSecGnuTLSAppDefaultKeysMngrAdoptKey:
+ * @mngr: the pointer to keys manager.
+ * @key: the pointer to key.
+ *
+ * Adds @key to the keys manager @mngr created with #xmlSecGnuTLSAppDefaultKeysMngrInit
+ * function.
+ *
+ * Returns: 0 on success or a negative value otherwise.
+ */
+int
+xmlSecGnuTLSAppDefaultKeysMngrAdoptKey(xmlSecKeysMngrPtr mngr, xmlSecKeyPtr key) {
+ xmlSecKeyStorePtr store;
+ int ret;
+
+ xmlSecAssert2(mngr != NULL, -1);
+ xmlSecAssert2(key != NULL, -1);
+
+ store = xmlSecKeysMngrGetKeysStore(mngr);
+ if(store == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeysMngrGetKeysStore",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ ret = xmlSecSimpleKeysStoreAdoptKey(store, key);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecSimpleKeysStoreAdoptKey",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ return(0);
+}
+
+/**
+ * xmlSecGnuTLSAppDefaultKeysMngrLoad:
+ * @mngr: the pointer to keys manager.
+ * @uri: the uri.
+ *
+ * Loads XML keys file from @uri to the keys manager @mngr created
+ * with #xmlSecGnuTLSAppDefaultKeysMngrInit function.
+ *
+ * Returns: 0 on success or a negative value otherwise.
+ */
+int
+xmlSecGnuTLSAppDefaultKeysMngrLoad(xmlSecKeysMngrPtr mngr, const char* uri) {
+ xmlSecKeyStorePtr store;
+ int ret;
+
+ xmlSecAssert2(mngr != NULL, -1);
+ xmlSecAssert2(uri != NULL, -1);
+
+ store = xmlSecKeysMngrGetKeysStore(mngr);
+ if(store == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeysMngrGetKeysStore",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ ret = xmlSecSimpleKeysStoreLoad(store, uri, mngr);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecSimpleKeysStoreLoad",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "uri=%s", xmlSecErrorsSafeString(uri));
+ return(-1);
+ }
+
+ return(0);
+}
+
+/**
+ * xmlSecGnuTLSAppDefaultKeysMngrSave:
+ * @mngr: the pointer to keys manager.
+ * @filename: the destination filename.
+ * @type: the type of keys to save (public/private/symmetric).
+ *
+ * Saves keys from @mngr to XML keys file.
+ *
+ * Returns: 0 on success or a negative value otherwise.
+ */
+int
+xmlSecGnuTLSAppDefaultKeysMngrSave(xmlSecKeysMngrPtr mngr, const char* filename, xmlSecKeyDataType type) {
+ xmlSecKeyStorePtr store;
+ int ret;
+
+ xmlSecAssert2(mngr != NULL, -1);
+ xmlSecAssert2(filename != NULL, -1);
+
+ store = xmlSecKeysMngrGetKeysStore(mngr);
+ if(store == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeysMngrGetKeysStore",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ ret = xmlSecSimpleKeysStoreSave(store, filename, type);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecSimpleKeysStoreSave",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "filename=%s",
+ xmlSecErrorsSafeString(filename));
+ return(-1);
+ }
+
+ return(0);
+}
+
+/**
+ * xmlSecGnuTLSAppGetDefaultPwdCallback:
+ *
+ * Gets default password callback.
+ *
+ * Returns: default password callback.
+ */
+void*
+xmlSecGnuTLSAppGetDefaultPwdCallback(void) {
+ return(NULL);
+}
+
diff --git a/src/gnutls/asymkeys.c b/src/gnutls/asymkeys.c
new file mode 100644
index 00000000..6ac68a78
--- /dev/null
+++ b/src/gnutls/asymkeys.c
@@ -0,0 +1,455 @@
+/**
+ * XMLSec library
+ *
+ * This is free software; see Copyright file in the source
+ * distribution for preciese wording.
+ *
+ * Copyright (C) 2010 Aleksey Sanin <aleksey@aleksey.com>
+ */
+#include "globals.h"
+
+#include <string.h>
+
+#include <gnutls/gnutls.h>
+#include <gnutls/x509.h>
+
+#include <xmlsec/xmlsec.h>
+#include <xmlsec/xmltree.h>
+#include <xmlsec/keys.h>
+#include <xmlsec/base64.h>
+#include <xmlsec/keyinfo.h>
+#include <xmlsec/transforms.h>
+#include <xmlsec/errors.h>
+
+#include <xmlsec/gnutls/crypto.h>
+
+/**************************************************************************
+ *
+ * We use xmlsec-gcrypt for all the basic crypto ops
+ *
+ *****************************************************************************/
+#include <xmlsec/gcrypt/crypto.h>
+#include <gcrypt.h>
+
+static void xmlSecGnuTLSDestroyParams(gnutls_datum_t * params, xmlSecSize num) {
+ xmlSecSize ii;
+
+ xmlSecAssert(params != NULL);
+ for(ii = 0; ii < num; ++ii) {
+ gnutls_free(params[ii].data);
+ }
+}
+
+static void xmlSecGnuTLSDestroyMpis(gcry_mpi_t * mpis, xmlSecSize num) {
+ xmlSecSize ii;
+
+ xmlSecAssert(mpis != NULL);
+ for(ii = 0; ii < num; ++ii) {
+ gcry_mpi_release(mpis[ii]);
+ }
+}
+
+static int xmlSecGnuTLSConvertParamsToMpis(gnutls_datum_t * params, xmlSecSize paramsNum,
+ gcry_mpi_t * mpis, xmlSecSize mpisNum) {
+
+ xmlSecSize ii;
+ int rc;
+
+ xmlSecAssert2(params != NULL, -1);
+ xmlSecAssert2(mpis != NULL, -1);
+ xmlSecAssert2(paramsNum == mpisNum, -1);
+
+ for(ii = 0; ii < paramsNum; ++ii) {
+ rc = gcry_mpi_scan(&(mpis[ii]), GCRYMPI_FMT_USG, params[ii].data, params[ii].size, NULL);
+ if((rc != GPG_ERR_NO_ERROR) || (mpis[ii] == NULL)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gcry_mpi_scan",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_GCRYPT_REPORT_ERROR(rc));
+ xmlSecGnuTLSDestroyMpis(mpis, ii); /* destroy up to now */
+ return(-1);
+ }
+ }
+
+ /* done */
+ return(0);
+}
+
+#ifndef XMLSEC_NO_DSA
+
+/**
+ * xmlSecGnuTLSKeyDataDsaGetKlass:
+ *
+ * The DSA key data klass.
+ *
+ * Returns: pointer to DSA key data klass.
+ */
+xmlSecKeyDataId
+xmlSecGnuTLSKeyDataDsaGetKlass(void) {
+ return (xmlSecGCryptKeyDataDsaGetKlass());
+}
+
+/**
+ * xmlSecGnuTLSKeyDataDsaAdoptPrivateKey:
+ * @data: the pointer to DSA key data.
+ * @dsa_key: the pointer to GnuTLS DSA private key.
+ *
+ * Sets the value of DSA key data.
+ *
+ * Returns: 0 on success or a negative value otherwise.
+ */
+int
+xmlSecGnuTLSKeyDataDsaAdoptPrivateKey(xmlSecKeyDataPtr data, gnutls_x509_privkey_t dsa_key) {
+ gnutls_datum_t params[5];
+ gcry_mpi_t mpis[5];
+ gcry_sexp_t priv_key = NULL;
+ gcry_sexp_t pub_key = NULL;
+ int rc;
+ int err;
+ int ret;
+
+ xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataDsaId), -1);
+ xmlSecAssert2(dsa_key != NULL, -1);
+ xmlSecAssert2(gnutls_x509_privkey_get_pk_algorithm(dsa_key) == GNUTLS_PK_DSA, -1);
+
+ /* get raw values */
+ err = gnutls_x509_privkey_export_dsa_raw(dsa_key,
+ &(params[0]), &(params[1]), &(params[2]),
+ &(params[3]), &(params[4]));
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_privkey_export_dsa_raw",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ return(-1);
+ }
+
+ /* convert to mpis */
+ ret = xmlSecGnuTLSConvertParamsToMpis(
+ params, sizeof(params)/sizeof(params[0]),
+ mpis, sizeof(mpis)/sizeof(mpis[0]));
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSConvertParamsToMpis",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecGnuTLSDestroyParams(params, sizeof(params)/sizeof(params[0]));
+ return(-1);
+ }
+ xmlSecGnuTLSDestroyParams(params, sizeof(params)/sizeof(params[0]));
+
+ /* build expressions */
+ rc = gcry_sexp_build(&(priv_key), NULL, "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))",
+ mpis[0], mpis[1], mpis[2], mpis[3], mpis[4]);
+ if((rc != GPG_ERR_NO_ERROR) || (priv_key == NULL)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gcry_sexp_build(private/dsa)",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_GNUTLS_GCRYPT_REPORT_ERROR(rc));
+ xmlSecGnuTLSDestroyMpis(mpis, sizeof(mpis)/sizeof(mpis[0]));
+ return(-1);
+ }
+ rc = gcry_sexp_build(&(pub_key), NULL, "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
+ mpis[0], mpis[1], mpis[2], mpis[3]);
+ if((rc != GPG_ERR_NO_ERROR) || (pub_key == NULL)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gcry_sexp_build(private/rsa)",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_GNUTLS_GCRYPT_REPORT_ERROR(rc));
+ gcry_sexp_release(priv_key);
+ xmlSecGnuTLSDestroyMpis(mpis, sizeof(mpis)/sizeof(mpis[0]));
+ return(-1);
+ }
+ xmlSecGnuTLSDestroyMpis(mpis, sizeof(mpis)/sizeof(mpis[0]));
+
+ ret = xmlSecGCryptKeyDataDsaAdoptKeyPair(data, pub_key, priv_key);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGCryptKeyDataDsaAdoptKeyPair",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ gcry_sexp_release(pub_key);
+ gcry_sexp_release(priv_key);
+ return(-1);
+ }
+
+ /* done, we "adopted" the key - destroy it! */
+ gnutls_x509_privkey_deinit(dsa_key);
+ return(0);
+}
+
+
+/**
+ * xmlSecGnuTLSKeyDataDsaAdoptPublicKey:
+ * @data: the pointer to DSA key data.
+ * @p: the pointer to p component of the DSA public key
+ * @q: the pointer to q component of the DSA public key
+ * @g: the pointer to g component of the DSA public key
+ * @y: the pointer to y component of the DSA public key
+ *
+ * Sets the value of DSA key data.
+ *
+ * Returns: 0 on success or a negative value otherwise.
+ */
+int
+xmlSecGnuTLSKeyDataDsaAdoptPublicKey(xmlSecKeyDataPtr data,
+ gnutls_datum_t * p, gnutls_datum_t * q,
+ gnutls_datum_t * g, gnutls_datum_t * y) {
+ gnutls_datum_t params[4];
+ gcry_mpi_t mpis[4];
+ gcry_sexp_t pub_key = NULL;
+ int rc;
+ int ret;
+
+ xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataDsaId), -1);
+ xmlSecAssert2(p != NULL, -1);
+ xmlSecAssert2(q != NULL, -1);
+ xmlSecAssert2(g != NULL, -1);
+ xmlSecAssert2(y != NULL, -1);
+
+ /* copy */
+ memcpy(&(params[0]), p, sizeof(*p));
+ memcpy(&(params[1]), q, sizeof(*q));
+ memcpy(&(params[2]), g, sizeof(*g));
+ memcpy(&(params[3]), y, sizeof(*y));
+
+ /* convert to mpis */
+ ret = xmlSecGnuTLSConvertParamsToMpis(
+ params, sizeof(params)/sizeof(params[0]),
+ mpis, sizeof(mpis)/sizeof(mpis[0]));
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSConvertParamsToMpis",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ /* don't destroy params - we got them from outside !!! */
+ return(-1);
+ }
+ /* don't destroy params - we got them from outside !!! */
+
+ /* build expressions */
+ rc = gcry_sexp_build(&(pub_key), NULL, "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
+ mpis[0], mpis[1], mpis[2], mpis[3]);
+ if((rc != GPG_ERR_NO_ERROR) || (pub_key == NULL)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gcry_sexp_build(private/rsa)",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_GNUTLS_GCRYPT_REPORT_ERROR(rc));
+ xmlSecGnuTLSDestroyMpis(mpis, sizeof(mpis)/sizeof(mpis[0]));
+ return(-1);
+ }
+ xmlSecGnuTLSDestroyMpis(mpis, sizeof(mpis)/sizeof(mpis[0]));
+
+ ret = xmlSecGCryptKeyDataDsaAdoptKeyPair(data, pub_key, NULL);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGCryptKeyDataDsaAdoptKeyPair",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ gcry_sexp_release(pub_key);
+ return(-1);
+ }
+
+ /* done, we "adopted" the key - destroy it! */
+ gnutls_free(p->data);
+ gnutls_free(q->data);
+ gnutls_free(g->data);
+ gnutls_free(y->data);
+ return(0);
+}
+
+#endif /* XMLSEC_NO_DSA */
+
+
+#ifndef XMLSEC_NO_RSA
+
+/**
+ * xmlSecGnuTLSKeyDataRsaGetKlass:
+ *
+ * The GnuTLS RSA key data klass.
+ *
+ * Returns: pointer to GnuTLS RSA key data klass.
+ */
+xmlSecKeyDataId
+xmlSecGnuTLSKeyDataRsaGetKlass(void) {
+ return (xmlSecGCryptKeyDataRsaGetKlass());
+}
+
+/**
+ * xmlSecGnuTLSKeyDataRsaAdoptPrivateKey:
+ * @data: the pointer to RSA key data.
+ * @rsa_key: the pointer to GnuTLS RSA private key.
+ *
+ * Sets the value of RSA key data.
+ *
+ * Returns: 0 on success or a negative value otherwise.
+ */
+int
+xmlSecGnuTLSKeyDataRsaAdoptPrivateKey(xmlSecKeyDataPtr data, gnutls_x509_privkey_t rsa_key) {
+ gnutls_datum_t params[6];
+ gcry_mpi_t mpis[6];
+ gcry_sexp_t priv_key = NULL;
+ gcry_sexp_t pub_key = NULL;
+ int rc;
+ int err;
+ int ret;
+
+ xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataRsaId), -1);
+ xmlSecAssert2(rsa_key != NULL, -1);
+ xmlSecAssert2(gnutls_x509_privkey_get_pk_algorithm(rsa_key) == GNUTLS_PK_RSA, -1);
+
+ /* get raw values */
+ err = gnutls_x509_privkey_export_rsa_raw(rsa_key,
+ &(params[0]), &(params[1]), &(params[2]),
+ &(params[3]), &(params[4]), &(params[5]));
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_privkey_export_rsa_raw",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ return(-1);
+ }
+
+ /* convert to mpis */
+ ret = xmlSecGnuTLSConvertParamsToMpis(
+ params, sizeof(params)/sizeof(params[0]),
+ mpis, sizeof(mpis)/sizeof(mpis[0]));
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSConvertParamsToMpis",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecGnuTLSDestroyParams(params, sizeof(params)/sizeof(params[0]));
+ return(-1);
+ }
+ xmlSecGnuTLSDestroyParams(params, sizeof(params)/sizeof(params[0]));
+
+ /* build expressions */
+ rc = gcry_sexp_build(&(priv_key), NULL, "(private-key(rsa((n%m)(e%m)(d%m)(p%m)(q%m)(u%m))))",
+ mpis[0], mpis[1], mpis[2],
+ mpis[3], mpis[4], mpis[5]);
+ if((rc != GPG_ERR_NO_ERROR) || (priv_key == NULL)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gcry_sexp_build(private/rsa)",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_GNUTLS_GCRYPT_REPORT_ERROR(rc));
+ xmlSecGnuTLSDestroyMpis(mpis, sizeof(mpis)/sizeof(mpis[0]));
+ return(-1);
+ }
+ rc = gcry_sexp_build(&(pub_key), NULL, "(public-key(rsa((n%m)(e%m))))",
+ mpis[0], mpis[1]);
+ if((rc != GPG_ERR_NO_ERROR) || (pub_key == NULL)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gcry_sexp_build(private/rsa)",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_GNUTLS_GCRYPT_REPORT_ERROR(rc));
+ gcry_sexp_release(priv_key);
+ xmlSecGnuTLSDestroyMpis(mpis, sizeof(mpis)/sizeof(mpis[0]));
+ return(-1);
+ }
+ xmlSecGnuTLSDestroyMpis(mpis, sizeof(mpis)/sizeof(mpis[0]));
+
+ ret = xmlSecGCryptKeyDataRsaAdoptKeyPair(data, pub_key, priv_key);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGCryptKeyDataRsaAdoptKeyPair",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ gcry_sexp_release(pub_key);
+ gcry_sexp_release(priv_key);
+ return(-1);
+ }
+
+ /* done, we "adopted" the key - destroy it! */
+ gnutls_x509_privkey_deinit(rsa_key);
+ return(0);
+}
+
+
+/**
+ * xmlSecGnuTLSKeyDataRsaAdoptPublicKey:
+ * @data: the pointer to RSA key data.
+ * @m: the pointer to m component of the RSA public key
+ * @e: the pointer to e component of the RSA public key
+ *
+ * Sets the value of RSA key data.
+ *
+ * Returns: 0 on success or a negative value otherwise.
+ */
+int
+xmlSecGnuTLSKeyDataRsaAdoptPublicKey(xmlSecKeyDataPtr data,
+ gnutls_datum_t * m, gnutls_datum_t * e) {
+ gnutls_datum_t params[2];
+ gcry_mpi_t mpis[2];
+ gcry_sexp_t pub_key = NULL;
+ int rc;
+ int ret;
+
+ xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataRsaId), -1);
+ xmlSecAssert2(m != NULL, -1);
+ xmlSecAssert2(e != NULL, -1);
+
+ /* copy */
+ memcpy(&(params[0]), m, sizeof(*m));
+ memcpy(&(params[1]), e, sizeof(*e));
+
+ /* convert to mpis */
+ ret = xmlSecGnuTLSConvertParamsToMpis(
+ params, sizeof(params)/sizeof(params[0]),
+ mpis, sizeof(mpis)/sizeof(mpis[0]));
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSConvertParamsToMpis",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ /* don't destroy params - we got them from outside !!! */
+ return(-1);
+ }
+ /* don't destroy params - we got them from outside !!! */
+
+ /* build expressions */
+ rc = gcry_sexp_build(&(pub_key), NULL, "(public-key(rsa((n%m)(e%m))))",
+ mpis[0], mpis[1]);
+ if((rc != GPG_ERR_NO_ERROR) || (pub_key == NULL)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gcry_sexp_build(private/rsa)",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_GNUTLS_GCRYPT_REPORT_ERROR(rc));
+ xmlSecGnuTLSDestroyMpis(mpis, sizeof(mpis)/sizeof(mpis[0]));
+ return(-1);
+ }
+ xmlSecGnuTLSDestroyMpis(mpis, sizeof(mpis)/sizeof(mpis[0]));
+
+ ret = xmlSecGCryptKeyDataRsaAdoptKeyPair(data, pub_key, NULL);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGCryptKeyDataRsaAdoptKeyPair",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ gcry_sexp_release(pub_key);
+ return(-1);
+ }
+
+ /* done, we "adopted" the key - destroy it! */
+ gnutls_free(m->data);
+ gnutls_free(e->data);
+ return(0);
+}
+#endif /* XMLSEC_NO_RSA */
diff --git a/src/gnutls/ciphers.c b/src/gnutls/ciphers.c
new file mode 100644
index 00000000..eacfede6
--- /dev/null
+++ b/src/gnutls/ciphers.c
@@ -0,0 +1,82 @@
+/**
+ * XMLSec library
+ *
+ * This is free software; see Copyright file in the source
+ * distribution for preciese wording.
+ *
+ * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
+ */
+#include "globals.h"
+
+#include <string.h>
+
+#include <xmlsec/xmlsec.h>
+#include <xmlsec/keys.h>
+#include <xmlsec/transforms.h>
+#include <xmlsec/errors.h>
+
+#include <xmlsec/gnutls/crypto.h>
+
+/**************************************************************************
+ *
+ * We use xmlsec-gcrypt for all the basic crypto ops
+ *
+ *****************************************************************************/
+#include <xmlsec/gcrypt/crypto.h>
+
+
+
+
+#ifndef XMLSEC_NO_AES
+
+/**
+ * xmlSecGnuTLSTransformAes128CbcGetKlass:
+ *
+ * AES 128 CBC encryption transform klass.
+ *
+ * Returns: pointer to AES 128 CBC encryption transform.
+ */
+xmlSecTransformId
+xmlSecGnuTLSTransformAes128CbcGetKlass(void) {
+ return (xmlSecGCryptTransformAes128CbcGetKlass());
+}
+
+/**
+ * xmlSecGnuTLSTransformAes192CbcGetKlass:
+ *
+ * AES 192 CBC encryption transform klass.
+ *
+ * Returns: pointer to AES 192 CBC encryption transform.
+ */
+xmlSecTransformId
+xmlSecGnuTLSTransformAes192CbcGetKlass(void) {
+ return (xmlSecGCryptTransformAes192CbcGetKlass());
+}
+
+/**
+ * xmlSecGnuTLSTransformAes256CbcGetKlass:
+ *
+ * AES 256 CBC encryption transform klass.
+ *
+ * Returns: pointer to AES 256 CBC encryption transform.
+ */
+xmlSecTransformId
+xmlSecGnuTLSTransformAes256CbcGetKlass(void) {
+ return (xmlSecGCryptTransformAes256CbcGetKlass());
+}
+#endif /* XMLSEC_NO_AES */
+
+#ifndef XMLSEC_NO_DES
+/**
+ * xmlSecGnuTLSTransformDes3CbcGetKlass:
+ *
+ * Triple DES CBC encryption transform klass.
+ *
+ * Returns: pointer to Triple DES encryption transform.
+ */
+xmlSecTransformId
+xmlSecGnuTLSTransformDes3CbcGetKlass(void) {
+ return (xmlSecGCryptTransformDes3CbcGetKlass());
+}
+#endif /* XMLSEC_NO_DES */
+
diff --git a/src/gnutls/crypto.c b/src/gnutls/crypto.c
new file mode 100644
index 00000000..83175e69
--- /dev/null
+++ b/src/gnutls/crypto.c
@@ -0,0 +1,351 @@
+/**
+ * XMLSec library
+ *
+ * This is free software; see Copyright file in the source
+ * distribution for preciese wording.
+ *
+ * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
+ */
+#include "globals.h"
+
+#include <string.h>
+
+#include <gcrypt.h>
+
+#include <xmlsec/xmlsec.h>
+#include <xmlsec/keys.h>
+#include <xmlsec/transforms.h>
+#include <xmlsec/errors.h>
+#include <xmlsec/dl.h>
+#include <xmlsec/private.h>
+
+#include <xmlsec/gnutls/app.h>
+#include <xmlsec/gnutls/crypto.h>
+#include <xmlsec/gnutls/x509.h>
+
+static xmlSecCryptoDLFunctionsPtr gXmlSecGnuTLSFunctions = NULL;
+
+/**
+ * xmlSecCryptoGetFunctions_gnutls:
+ *
+ * Gets the pointer to xmlsec-gnutls functions table.
+ *
+ * Returns: the xmlsec-gnutls functions table or NULL if an error occurs.
+ */
+xmlSecCryptoDLFunctionsPtr
+xmlSecCryptoGetFunctions_gnutls(void) {
+ static xmlSecCryptoDLFunctions functions;
+
+ if(gXmlSecGnuTLSFunctions != NULL) {
+ return(gXmlSecGnuTLSFunctions);
+ }
+
+ memset(&functions, 0, sizeof(functions));
+ gXmlSecGnuTLSFunctions = &functions;
+
+ /********************************************************************
+ *
+ * Crypto Init/shutdown
+ *
+ ********************************************************************/
+ gXmlSecGnuTLSFunctions->cryptoInit = xmlSecGnuTLSInit;
+ gXmlSecGnuTLSFunctions->cryptoShutdown = xmlSecGnuTLSShutdown;
+ gXmlSecGnuTLSFunctions->cryptoKeysMngrInit = xmlSecGnuTLSKeysMngrInit;
+
+ /********************************************************************
+ *
+ * Key data ids
+ *
+ ********************************************************************/
+#ifndef XMLSEC_NO_AES
+ gXmlSecGnuTLSFunctions->keyDataAesGetKlass = xmlSecGnuTLSKeyDataAesGetKlass;
+#endif /* XMLSEC_NO_AES */
+
+#ifndef XMLSEC_NO_DES
+ gXmlSecGnuTLSFunctions->keyDataDesGetKlass = xmlSecGnuTLSKeyDataDesGetKlass;
+#endif /* XMLSEC_NO_DES */
+
+#ifndef XMLSEC_NO_DSA
+ gXmlSecGnuTLSFunctions->keyDataDsaGetKlass = xmlSecGnuTLSKeyDataDsaGetKlass;
+#endif /* XMLSEC_NO_DSA */
+
+#ifndef XMLSEC_NO_HMAC
+ gXmlSecGnuTLSFunctions->keyDataHmacGetKlass = xmlSecGnuTLSKeyDataHmacGetKlass;
+#endif /* XMLSEC_NO_HMAC */
+
+#ifndef XMLSEC_NO_RSA
+ gXmlSecGnuTLSFunctions->keyDataRsaGetKlass = xmlSecGnuTLSKeyDataRsaGetKlass;
+#endif /* XMLSEC_NO_RSA */
+
+#ifndef XMLSEC_NO_X509
+ gXmlSecGnuTLSFunctions->keyDataX509GetKlass = xmlSecGnuTLSKeyDataX509GetKlass;
+ gXmlSecGnuTLSFunctions->keyDataRawX509CertGetKlass = xmlSecGnuTLSKeyDataRawX509CertGetKlass;
+#endif /* XMLSEC_NO_X509 */
+
+ /********************************************************************
+ *
+ * Key data store ids
+ *
+ ********************************************************************/
+#ifndef XMLSEC_NO_X509
+ gXmlSecGnuTLSFunctions->x509StoreGetKlass = xmlSecGnuTLSX509StoreGetKlass;
+#endif /* XMLSEC_NO_X509 */
+
+ /********************************************************************
+ *
+ * Crypto transforms ids
+ *
+ ********************************************************************/
+
+ /******************************* AES ********************************/
+#ifndef XMLSEC_NO_AES
+ gXmlSecGnuTLSFunctions->transformAes128CbcGetKlass = xmlSecGnuTLSTransformAes128CbcGetKlass;
+ gXmlSecGnuTLSFunctions->transformAes192CbcGetKlass = xmlSecGnuTLSTransformAes192CbcGetKlass;
+ gXmlSecGnuTLSFunctions->transformAes256CbcGetKlass = xmlSecGnuTLSTransformAes256CbcGetKlass;
+ gXmlSecGnuTLSFunctions->transformKWAes128GetKlass = xmlSecGnuTLSTransformKWAes128GetKlass;
+ gXmlSecGnuTLSFunctions->transformKWAes192GetKlass = xmlSecGnuTLSTransformKWAes192GetKlass;
+ gXmlSecGnuTLSFunctions->transformKWAes256GetKlass = xmlSecGnuTLSTransformKWAes256GetKlass;
+#endif /* XMLSEC_NO_AES */
+
+ /******************************* DES ********************************/
+#ifndef XMLSEC_NO_DES
+ gXmlSecGnuTLSFunctions->transformDes3CbcGetKlass = xmlSecGnuTLSTransformDes3CbcGetKlass;
+ gXmlSecGnuTLSFunctions->transformKWDes3GetKlass = xmlSecGnuTLSTransformKWDes3GetKlass;
+#endif /* XMLSEC_NO_DES */
+
+ /******************************* DSA ********************************/
+#ifndef XMLSEC_NO_DSA
+
+#ifndef XMLSEC_NO_SHA1
+ gXmlSecGnuTLSFunctions->transformDsaSha1GetKlass = xmlSecGnuTLSTransformDsaSha1GetKlass;
+#endif /* XMLSEC_NO_SHA1 */
+
+#endif /* XMLSEC_NO_DSA */
+
+ /******************************* HMAC ********************************/
+#ifndef XMLSEC_NO_HMAC
+
+#ifndef XMLSEC_NO_MD5
+ gXmlSecGnuTLSFunctions->transformHmacMd5GetKlass = xmlSecGnuTLSTransformHmacMd5GetKlass;
+#endif /* XMLSEC_NO_MD5 */
+
+#ifndef XMLSEC_NO_RIPEMD160
+ gXmlSecGnuTLSFunctions->transformHmacRipemd160GetKlass = xmlSecGnuTLSTransformHmacRipemd160GetKlass;
+#endif /* XMLSEC_NO_RIPEMD160 */
+
+#ifndef XMLSEC_NO_SHA1
+ gXmlSecGnuTLSFunctions->transformHmacSha1GetKlass = xmlSecGnuTLSTransformHmacSha1GetKlass;
+#endif /* XMLSEC_NO_SHA1 */
+
+#ifndef XMLSEC_NO_SHA256
+ gXmlSecGnuTLSFunctions->transformHmacSha256GetKlass = xmlSecGnuTLSTransformHmacSha256GetKlass;
+#endif /* XMLSEC_NO_SHA256 */
+
+#ifndef XMLSEC_NO_SHA384
+ gXmlSecGnuTLSFunctions->transformHmacSha384GetKlass = xmlSecGnuTLSTransformHmacSha384GetKlass;
+#endif /* XMLSEC_NO_SHA384 */
+
+#ifndef XMLSEC_NO_SHA512
+ gXmlSecGnuTLSFunctions->transformHmacSha512GetKlass = xmlSecGnuTLSTransformHmacSha512GetKlass;
+#endif /* XMLSEC_NO_SHA512 */
+
+#endif /* XMLSEC_NO_HMAC */
+
+ /******************************* MD5 ********************************/
+#ifndef XMLSEC_NO_MD5
+ gXmlSecGnuTLSFunctions->transformMd5GetKlass = xmlSecGnuTLSTransformMd5GetKlass;
+#endif /* XMLSEC_NO_MD5 */
+
+ /******************************* RIPEMD160 ********************************/
+#ifndef XMLSEC_NO_RIPEMD160
+ gXmlSecGnuTLSFunctions->transformRipemd160GetKlass = xmlSecGnuTLSTransformRipemd160GetKlass;
+#endif /* XMLSEC_NO_RIPEMD160 */
+
+ /******************************* RSA ********************************/
+#ifndef XMLSEC_NO_RSA
+
+#ifndef XMLSEC_NO_MD5
+ gXmlSecGnuTLSFunctions->transformRsaMd5GetKlass = xmlSecGnuTLSTransformRsaMd5GetKlass;
+#endif /* XMLSEC_NO_MD5 */
+
+#ifndef XMLSEC_NO_RIPEMD160
+ gXmlSecGnuTLSFunctions->transformRsaRipemd160GetKlass = xmlSecGnuTLSTransformRsaRipemd160GetKlass;
+#endif /* XMLSEC_NO_RIPEMD160 */
+
+#ifndef XMLSEC_NO_SHA1
+ gXmlSecGnuTLSFunctions->transformRsaSha1GetKlass = xmlSecGnuTLSTransformRsaSha1GetKlass;
+#endif /* XMLSEC_NO_SHA1 */
+
+#ifndef XMLSEC_NO_SHA256
+ gXmlSecGnuTLSFunctions->transformRsaSha256GetKlass = xmlSecGnuTLSTransformRsaSha256GetKlass;
+#endif /* XMLSEC_NO_SHA256 */
+
+#ifndef XMLSEC_NO_SHA384
+ gXmlSecGnuTLSFunctions->transformRsaSha384GetKlass = xmlSecGnuTLSTransformRsaSha384GetKlass;
+#endif /* XMLSEC_NO_SHA384 */
+
+#ifndef XMLSEC_NO_SHA512
+ gXmlSecGnuTLSFunctions->transformRsaSha512GetKlass = xmlSecGnuTLSTransformRsaSha512GetKlass;
+#endif /* XMLSEC_NO_SHA512 */
+
+#endif /* XMLSEC_NO_RSA */
+
+ /******************************* SHA ********************************/
+#ifndef XMLSEC_NO_SHA1
+ gXmlSecGnuTLSFunctions->transformSha1GetKlass = xmlSecGnuTLSTransformSha1GetKlass;
+#endif /* XMLSEC_NO_SHA1 */
+
+#ifndef XMLSEC_NO_SHA256
+ gXmlSecGnuTLSFunctions->transformSha256GetKlass = xmlSecGnuTLSTransformSha256GetKlass;
+#endif /* XMLSEC_NO_SHA256 */
+
+#ifndef XMLSEC_NO_SHA384
+ gXmlSecGnuTLSFunctions->transformSha384GetKlass = xmlSecGnuTLSTransformSha384GetKlass;
+#endif /* XMLSEC_NO_SHA384 */
+
+#ifndef XMLSEC_NO_SHA512
+ gXmlSecGnuTLSFunctions->transformSha512GetKlass = xmlSecGnuTLSTransformSha512GetKlass;
+#endif /* XMLSEC_NO_SHA512 */
+
+
+ /********************************************************************
+ *
+ * High level routines form xmlsec command line utility
+ *
+ ********************************************************************/
+ gXmlSecGnuTLSFunctions->cryptoAppInit = xmlSecGnuTLSAppInit;
+ gXmlSecGnuTLSFunctions->cryptoAppShutdown = xmlSecGnuTLSAppShutdown;
+ gXmlSecGnuTLSFunctions->cryptoAppDefaultKeysMngrInit = xmlSecGnuTLSAppDefaultKeysMngrInit;
+ gXmlSecGnuTLSFunctions->cryptoAppDefaultKeysMngrAdoptKey = xmlSecGnuTLSAppDefaultKeysMngrAdoptKey;
+ gXmlSecGnuTLSFunctions->cryptoAppDefaultKeysMngrLoad = xmlSecGnuTLSAppDefaultKeysMngrLoad;
+ gXmlSecGnuTLSFunctions->cryptoAppDefaultKeysMngrSave = xmlSecGnuTLSAppDefaultKeysMngrSave;
+#ifndef XMLSEC_NO_X509
+ gXmlSecGnuTLSFunctions->cryptoAppKeysMngrCertLoad = xmlSecGnuTLSAppKeysMngrCertLoad;
+ gXmlSecGnuTLSFunctions->cryptoAppPkcs12Load = xmlSecGnuTLSAppPkcs12Load;
+ gXmlSecGnuTLSFunctions->cryptoAppKeyCertLoad = xmlSecGnuTLSAppKeyCertLoad;
+#endif /* XMLSEC_NO_X509 */
+ gXmlSecGnuTLSFunctions->cryptoAppKeyLoad = xmlSecGnuTLSAppKeyLoad;
+ gXmlSecGnuTLSFunctions->cryptoAppDefaultPwdCallback = (void*)xmlSecGnuTLSAppGetDefaultPwdCallback();
+
+ return(gXmlSecGnuTLSFunctions);
+}
+
+
+/**
+ * xmlSecGnuTLSInit:
+ *
+ * XMLSec library specific crypto engine initialization.
+ *
+ * Returns: 0 on success or a negative value otherwise.
+ */
+int
+xmlSecGnuTLSInit (void) {
+ /* Check loaded xmlsec library version */
+ if(xmlSecCheckVersionExact() != 1) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecCheckVersionExact",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* register our klasses */
+ if(xmlSecCryptoDLFunctionsRegisterKeyDataAndTransforms(xmlSecCryptoGetFunctions_gnutls()) < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecCryptoDLFunctionsRegisterKeyDataAndTransforms",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ return(0);
+}
+
+/**
+ * xmlSecGnuTLSShutdown:
+ *
+ * XMLSec library specific crypto engine shutdown.
+ *
+ * Returns: 0 on success or a negative value otherwise.
+ */
+int
+xmlSecGnuTLSShutdown(void) {
+ return(0);
+}
+
+/**
+ * xmlSecGnuTLSKeysMngrInit:
+ * @mngr: the pointer to keys manager.
+ *
+ * Adds GnuTLS specific key data stores in keys manager.
+ *
+ * Returns: 0 on success or a negative value otherwise.
+ */
+int
+xmlSecGnuTLSKeysMngrInit(xmlSecKeysMngrPtr mngr) {
+ int ret;
+
+ xmlSecAssert2(mngr != NULL, -1);
+
+#ifndef XMLSEC_NO_X509
+ /* create x509 store if needed */
+ if(xmlSecKeysMngrGetDataStore(mngr, xmlSecGnuTLSX509StoreId) == NULL) {
+ xmlSecKeyDataStorePtr x509Store;
+
+ x509Store = xmlSecKeyDataStoreCreate(xmlSecGnuTLSX509StoreId);
+ if(x509Store == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyDataStoreCreate",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "xmlSecGnuTLSX509StoreId");
+ return(-1);
+ }
+
+ ret = xmlSecKeysMngrAdoptDataStore(mngr, x509Store);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeysMngrAdoptDataStore",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecKeyDataStoreDestroy(x509Store);
+ return(-1);
+ }
+ }
+#endif /* XMLSEC_NO_X509 */
+ return(0);
+}
+
+/**
+ * xmlSecGnuTLSGenerateRandom:
+ * @buffer: the destination buffer.
+ * @size: the numer of bytes to generate.
+ *
+ * Generates @size random bytes and puts result in @buffer.
+ *
+ * Returns: 0 on success or a negative value otherwise.
+ */
+int
+xmlSecGnuTLSGenerateRandom(xmlSecBufferPtr buffer, xmlSecSize size) {
+ int ret;
+
+ xmlSecAssert2(buffer != NULL, -1);
+ xmlSecAssert2(size > 0, -1);
+
+ ret = xmlSecBufferSetSize(buffer, size);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecBufferSetSize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "size=%d", size);
+ return(-1);
+ }
+
+ /* get random data */
+ gcry_randomize(xmlSecBufferGetData(buffer), size, GCRY_STRONG_RANDOM);
+ return(0);
+}
diff --git a/src/gnutls/digests.c b/src/gnutls/digests.c
new file mode 100644
index 00000000..2df20706
--- /dev/null
+++ b/src/gnutls/digests.c
@@ -0,0 +1,112 @@
+/**
+ * XMLSec library
+ *
+ * This is free software; see Copyright file in the source
+ * distribution for preciese wording.
+ *
+ * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
+ */
+#include "globals.h"
+
+#include <string.h>
+
+#include <xmlsec/xmlsec.h>
+#include <xmlsec/keys.h>
+#include <xmlsec/transforms.h>
+#include <xmlsec/errors.h>
+
+#include <xmlsec/gnutls/app.h>
+#include <xmlsec/gnutls/crypto.h>
+
+/**************************************************************************
+ *
+ * We use xmlsec-gcrypt for all the basic crypto ops
+ *
+ *****************************************************************************/
+#include <xmlsec/gcrypt/crypto.h>
+
+#ifndef XMLSEC_NO_SHA1
+/**
+ * xmlSecGnuTLSTransformSha1GetKlass:
+ *
+ * SHA-1 digest transform klass.
+ *
+ * Returns: pointer to SHA-1 digest transform klass.
+ */
+xmlSecTransformId
+xmlSecGnuTLSTransformSha1GetKlass(void) {
+ return (xmlSecGCryptTransformSha1GetKlass());
+}
+#endif /* XMLSEC_NO_SHA1 */
+
+
+#ifndef XMLSEC_NO_SHA256
+/**
+ * xmlSecGnuTLSTransformSha256GetKlass:
+ *
+ * SHA256 digest transform klass.
+ *
+ * Returns: pointer to SHA256 digest transform klass.
+ */
+xmlSecTransformId
+xmlSecGnuTLSTransformSha256GetKlass(void) {
+ return (xmlSecGCryptTransformSha256GetKlass());
+}
+#endif /* XMLSEC_NO_SHA256 */
+
+#ifndef XMLSEC_NO_SHA384
+/**
+ * xmlSecGnuTLSTransformSha384GetKlass:
+ *
+ * SHA384 digest transform klass.
+ *
+ * Returns: pointer to SHA384 digest transform klass.
+ */
+xmlSecTransformId
+xmlSecGnuTLSTransformSha384GetKlass(void) {
+ return (xmlSecGCryptTransformSha384GetKlass());
+}
+#endif /* XMLSEC_NO_SHA384 */
+
+#ifndef XMLSEC_NO_SHA512
+/**
+ * xmlSecGnuTLSTransformSha512GetKlass:
+ *
+ * SHA512 digest transform klass.
+ *
+ * Returns: pointer to SHA512 digest transform klass.
+ */
+xmlSecTransformId
+xmlSecGnuTLSTransformSha512GetKlass(void) {
+ return (xmlSecGCryptTransformSha512GetKlass());
+}
+#endif /* XMLSEC_NO_SHA512 */
+
+#ifndef XMLSEC_NO_MD5
+
+/**
+ * xmlSecGnuTLSTransformMd5GetKlass:
+ *
+ * MD5 digest transform klass.
+ *
+ * Returns: pointer to MD5 digest transform klass.
+ */
+xmlSecTransformId
+xmlSecGnuTLSTransformMd5GetKlass(void) {
+ return (xmlSecGCryptTransformMd5GetKlass());
+}
+#endif /* XMLSEC_NO_MD5 */
+
+#ifndef XMLSEC_NO_RIPEMD160
+/**
+ * xmlSecGnuTLSTransformRipemd160GetKlass:
+ *
+ * RIPEMD160 digest transform klass.
+ *
+ * Returns: pointer to RIPEMD160 digest transform klass.
+ */
+xmlSecTransformId
+xmlSecGnuTLSTransformRipemd160GetKlass(void) {
+ return (xmlSecGCryptTransformRipemd160GetKlass());
+}
+#endif /* XMLSEC_NO_RIPEMD160 */
diff --git a/src/gnutls/globals.h b/src/gnutls/globals.h
new file mode 100644
index 00000000..b49e2404
--- /dev/null
+++ b/src/gnutls/globals.h
@@ -0,0 +1,31 @@
+/*
+ * XML Security Library
+ *
+ * globals.h: internal header only used during the compilation
+ *
+ * This is free software; see Copyright file in the source
+ * distribution for preciese wording.
+ *
+ * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
+ */
+#ifndef __XMLSEC_GLOBALS_H__
+#define __XMLSEC_GLOBALS_H__
+
+/**
+ * Use autoconf defines if present.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#define IN_XMLSEC_CRYPTO
+#define XMLSEC_PRIVATE
+
+#define XMLSEC_GNUTLS_GCRYPT_REPORT_ERROR(err) \
+ "error code=%d; error message='%s'", \
+ (int)err, xmlSecErrorsSafeString(gcry_strerror((err)))
+#define XMLSEC_GNUTLS_REPORT_ERROR(err) \
+ "error code=%d; error message='%s'", \
+ (int)err, xmlSecErrorsSafeString(gnutls_strerror((err)))
+
+#endif /* ! __XMLSEC_GLOBALS_H__ */
diff --git a/src/gnutls/hmac.c b/src/gnutls/hmac.c
new file mode 100644
index 00000000..5d1acfc2
--- /dev/null
+++ b/src/gnutls/hmac.c
@@ -0,0 +1,141 @@
+/**
+ * XMLSec library
+ *
+ * This is free software; see Copyright file in the source
+ * distribution for preciese wording.
+ *
+ * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
+ */
+#ifndef XMLSEC_NO_HMAC
+#include "globals.h"
+
+#include <string.h>
+
+#include <xmlsec/xmlsec.h>
+#include <xmlsec/xmltree.h>
+#include <xmlsec/keys.h>
+#include <xmlsec/transforms.h>
+#include <xmlsec/errors.h>
+
+#include <xmlsec/gnutls/app.h>
+#include <xmlsec/gnutls/crypto.h>
+
+/**************************************************************************
+ *
+ * We use xmlsec-gcrypt for all the basic crypto ops
+ *
+ *****************************************************************************/
+#include <xmlsec/gcrypt/crypto.h>
+
+/**
+ * xmlSecGnuTLSHmacGetMinOutputLength:
+ *
+ * Gets the value of min HMAC length.
+ *
+ * Returns: the min HMAC output length
+ */
+int xmlSecGnuTLSHmacGetMinOutputLength(void)
+{
+ return xmlSecGCryptHmacGetMinOutputLength();
+}
+
+/**
+ * xmlSecGnuTLSHmacSetMinOutputLength:
+ * @min_length: the new min length
+ *
+ * Sets the min HMAC output length
+ */
+void xmlSecGnuTLSHmacSetMinOutputLength(int min_length)
+{
+ xmlSecGCryptHmacSetMinOutputLength(min_length);
+}
+
+
+
+#ifndef XMLSEC_NO_SHA1
+/**
+ * xmlSecGnuTLSTransformHmacSha1GetKlass:
+ *
+ * The HMAC-SHA1 transform klass.
+ *
+ * Returns: the HMAC-SHA1 transform klass.
+ */
+xmlSecTransformId
+xmlSecGnuTLSTransformHmacSha1GetKlass(void) {
+ return (xmlSecGCryptTransformHmacSha1GetKlass());
+}
+#endif /* XMLSEC_NO_SHA1 */
+
+#ifndef XMLSEC_NO_SHA256
+/**
+ * xmlSecGnuTLSTransformHmacSha256GetKlass:
+ *
+ * The HMAC-SHA256 transform klass.
+ *
+ * Returns: the HMAC-SHA256 transform klass.
+ */
+xmlSecTransformId
+xmlSecGnuTLSTransformHmacSha256GetKlass(void) {
+ return (xmlSecGCryptTransformHmacSha256GetKlass());
+}
+#endif /* XMLSEC_NO_SHA256 */
+
+#ifndef XMLSEC_NO_SHA384
+/**
+ * xmlSecGnuTLSTransformHmacSha384GetKlass:
+ *
+ * The HMAC-SHA384 transform klass.
+ *
+ * Returns: the HMAC-SHA384 transform klass.
+ */
+xmlSecTransformId
+xmlSecGnuTLSTransformHmacSha384GetKlass(void) {
+ return (xmlSecGCryptTransformHmacSha384GetKlass());
+}
+#endif /* XMLSEC_NO_SHA384 */
+
+#ifndef XMLSEC_NO_SHA512
+/**
+ * xmlSecGnuTLSTransformHmacSha512GetKlass:
+ *
+ * The HMAC-SHA512 transform klass.
+ *
+ * Returns: the HMAC-SHA512 transform klass.
+ */
+xmlSecTransformId
+xmlSecGnuTLSTransformHmacSha512GetKlass(void) {
+ return (xmlSecGCryptTransformHmacSha512GetKlass());
+}
+#endif /* XMLSEC_NO_SHA512 */
+
+
+#ifndef XMLSEC_NO_RIPEMD160
+/**
+ * xmlSecGnuTLSTransformHmacRipemd160GetKlass:
+ *
+ * The HMAC-RIPEMD160 transform klass.
+ *
+ * Returns: the HMAC-RIPEMD160 transform klass.
+ */
+xmlSecTransformId
+xmlSecGnuTLSTransformHmacRipemd160GetKlass(void) {
+ return (xmlSecGCryptTransformHmacRipemd160GetKlass());
+}
+#endif /* XMLSEC_NO_RIPEMD160 */
+
+#ifndef XMLSEC_NO_MD5
+/**
+ * xmlSecGnuTLSTransformHmacMd5GetKlass:
+ *
+ * The HMAC-MD5 transform klass.
+ *
+ * Returns: the HMAC-MD5 transform klass.
+ */
+xmlSecTransformId
+xmlSecGnuTLSTransformHmacMd5GetKlass(void) {
+ return (xmlSecGCryptTransformHmacMd5GetKlass());
+}
+#endif /* XMLSEC_NO_MD5 */
+
+
+#endif /* XMLSEC_NO_HMAC */
diff --git a/src/gnutls/kw_aes.c b/src/gnutls/kw_aes.c
new file mode 100644
index 00000000..63f8a6be
--- /dev/null
+++ b/src/gnutls/kw_aes.c
@@ -0,0 +1,72 @@
+/**
+ *
+ * XMLSec library
+ *
+ * AES Algorithm support
+ *
+ * This is free software; see Copyright file in the source
+ * distribution for preciese wording.
+ *
+ * Copyright (C) 2010 Aleksey Sanin <aleksey@aleksey.com>
+ */
+#ifndef XMLSEC_NO_AES
+#include "globals.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <xmlsec/xmlsec.h>
+#include <xmlsec/xmltree.h>
+#include <xmlsec/keys.h>
+#include <xmlsec/transforms.h>
+#include <xmlsec/errors.h>
+
+#include <xmlsec/gnutls/crypto.h>
+
+/**************************************************************************
+ *
+ * We use xmlsec-gcrypt for all the basic crypto ops
+ *
+ *****************************************************************************/
+#include <xmlsec/gcrypt/crypto.h>
+
+
+
+/**
+ * xmlSecGnuTLSTransformKWAes128GetKlass:
+ *
+ * The AES-128 kew wrapper transform klass.
+ *
+ * Returns: AES-128 kew wrapper transform klass.
+ */
+xmlSecTransformId
+xmlSecGnuTLSTransformKWAes128GetKlass(void) {
+ return(xmlSecGCryptTransformKWAes128GetKlass());
+}
+
+/**
+ * xmlSecGnuTLSTransformKWAes192GetKlass:
+ *
+ * The AES-192 kew wrapper transform klass.
+ *
+ * Returns: AES-192 kew wrapper transform klass.
+ */
+xmlSecTransformId
+xmlSecGnuTLSTransformKWAes192GetKlass(void) {
+ return(xmlSecGCryptTransformKWAes192GetKlass());
+}
+
+/**
+ * xmlSecGnuTLSTransformKWAes256GetKlass:
+ *
+ * The AES-256 kew wrapper transform klass.
+ *
+ * Returns: AES-256 kew wrapper transform klass.
+ */
+xmlSecTransformId
+xmlSecGnuTLSTransformKWAes256GetKlass(void) {
+ return(xmlSecGCryptTransformKWAes256GetKlass());
+}
+
+#endif /* XMLSEC_NO_AES */
diff --git a/src/gnutls/kw_des.c b/src/gnutls/kw_des.c
new file mode 100644
index 00000000..5d2a2e55
--- /dev/null
+++ b/src/gnutls/kw_des.c
@@ -0,0 +1,51 @@
+/**
+ *
+ * XMLSec library
+ *
+ * DES Algorithm support
+ *
+ * This is free software; see Copyright file in the source
+ * distribution for preciese wording.
+ *
+ * Copyright (C) 2010 Aleksey Sanin <aleksey@aleksey.com>
+ */
+#ifndef XMLSEC_NO_DES
+#include "globals.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <gcrypt.h>
+
+
+#include <xmlsec/xmlsec.h>
+#include <xmlsec/xmltree.h>
+#include <xmlsec/keys.h>
+#include <xmlsec/transforms.h>
+#include <xmlsec/errors.h>
+
+#include <xmlsec/gnutls/crypto.h>
+
+/**************************************************************************
+ *
+ * We use xmlsec-gcrypt for all the basic crypto ops
+ *
+ *****************************************************************************/
+#include <xmlsec/gcrypt/crypto.h>
+
+
+/**
+ * xmlSecGnuTLSTransformKWDes3GetKlass:
+ *
+ * The Triple DES key wrapper transform klass.
+ *
+ * Returns: Triple DES key wrapper transform klass.
+ */
+xmlSecTransformId
+xmlSecGnuTLSTransformKWDes3GetKlass(void) {
+ return(xmlSecGCryptTransformKWDes3GetKlass());
+}
+
+#endif /* XMLSEC_NO_DES */
+
diff --git a/src/gnutls/signatures.c b/src/gnutls/signatures.c
new file mode 100644
index 00000000..98d1f832
--- /dev/null
+++ b/src/gnutls/signatures.c
@@ -0,0 +1,148 @@
+/**
+ * XMLSec library
+ *
+ * This is free software; see Copyright file in the source
+ * distribution for preciese wording.
+ *
+ * Copyright (C) 2010 Aleksey Sanin <aleksey@aleksey.com>
+ */
+#include "globals.h"
+
+#include <string.h>
+
+#include <xmlsec/xmlsec.h>
+#include <xmlsec/keys.h>
+#include <xmlsec/transforms.h>
+#include <xmlsec/errors.h>
+
+#include <xmlsec/gnutls/crypto.h>
+
+/**************************************************************************
+ *
+ * We use xmlsec-gcrypt for all the basic crypto ops
+ *
+ *****************************************************************************/
+#include <xmlsec/gcrypt/crypto.h>
+#include <gcrypt.h>
+
+
+#ifndef XMLSEC_NO_DSA
+
+#ifndef XMLSEC_NO_SHA1
+
+/**
+ * xmlSecGnuTLSTransformDsaSha1GetKlass:
+ *
+ * The DSA-SHA1 signature transform klass.
+ *
+ * Returns: DSA-SHA1 signature transform klass.
+ */
+xmlSecTransformId
+xmlSecGnuTLSTransformDsaSha1GetKlass(void) {
+ return (xmlSecGCryptTransformDsaSha1GetKlass());
+}
+
+#endif /* XMLSEC_NO_SHA1 */
+
+#endif /* XMLSEC_NO_DSA */
+
+#ifndef XMLSEC_NO_RSA
+
+#ifndef XMLSEC_NO_MD5
+
+/**
+ * xmlSecGnuTLSTransformRsaMd5GetKlass:
+ *
+ * The RSA-MD5 signature transform klass.
+ *
+ * Returns: RSA-MD5 signature transform klass.
+ */
+xmlSecTransformId
+xmlSecGnuTLSTransformRsaMd5GetKlass(void) {
+ return (xmlSecGCryptTransformRsaMd5GetKlass());
+}
+
+#endif /* XMLSEC_NO_MD5 */
+
+#ifndef XMLSEC_NO_RIPEMD160
+
+/**
+ * xmlSecGnuTLSTransformRsaRipemd160GetKlass:
+ *
+ * The RSA-RIPEMD160 signature transform klass.
+ *
+ * Returns: RSA-RIPEMD160 signature transform klass.
+ */
+xmlSecTransformId
+xmlSecGnuTLSTransformRsaRipemd160GetKlass(void) {
+ return (xmlSecGCryptTransformRsaRipemd160GetKlass());
+}
+
+#endif /* XMLSEC_NO_RIPEMD160 */
+
+#ifndef XMLSEC_NO_SHA1
+/**
+ * xmlSecGnuTLSTransformRsaSha1GetKlass:
+ *
+ * The RSA-SHA1 signature transform klass.
+ *
+ * Returns: RSA-SHA1 signature transform klass.
+ */
+xmlSecTransformId
+xmlSecGnuTLSTransformRsaSha1GetKlass(void) {
+ return (xmlSecGCryptTransformRsaSha1GetKlass());
+}
+
+#endif /* XMLSEC_NO_SHA1 */
+
+#ifndef XMLSEC_NO_SHA256
+
+/**
+ * xmlSecGnuTLSTransformRsaSha256GetKlass:
+ *
+ * The RSA-SHA256 signature transform klass.
+ *
+ * Returns: RSA-SHA256 signature transform klass.
+ */
+xmlSecTransformId
+xmlSecGnuTLSTransformRsaSha256GetKlass(void) {
+ return (xmlSecGCryptTransformRsaSha256GetKlass());
+}
+
+#endif /* XMLSEC_NO_SHA256 */
+
+#ifndef XMLSEC_NO_SHA384
+
+/**
+ * xmlSecGnuTLSTransformRsaSha384GetKlass:
+ *
+ * The RSA-SHA384 signature transform klass.
+ *
+ * Returns: RSA-SHA384 signature transform klass.
+ */
+xmlSecTransformId
+xmlSecGnuTLSTransformRsaSha384GetKlass(void) {
+ return (xmlSecGCryptTransformRsaSha384GetKlass());
+}
+
+#endif /* XMLSEC_NO_SHA384 */
+
+#ifndef XMLSEC_NO_SHA512
+/**
+ * xmlSecGnuTLSTransformRsaSha512GetKlass:
+ *
+ * The RSA-SHA512 signature transform klass.
+ *
+ * Returns: RSA-SHA512 signature transform klass.
+ */
+xmlSecTransformId
+xmlSecGnuTLSTransformRsaSha512GetKlass(void) {
+ return (xmlSecGCryptTransformRsaSha512GetKlass());
+}
+
+#endif /* XMLSEC_NO_SHA512 */
+
+#endif /* XMLSEC_NO_RSA */
+
+
+
diff --git a/src/gnutls/symkeys.c b/src/gnutls/symkeys.c
new file mode 100644
index 00000000..b1521d62
--- /dev/null
+++ b/src/gnutls/symkeys.c
@@ -0,0 +1,125 @@
+/**
+ *
+ * XMLSec library
+ *
+ * DES Algorithm support
+ *
+ * This is free software; see Copyright file in the source
+ * distribution for preciese wording.
+ *
+ * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
+ */
+#include "globals.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <xmlsec/xmlsec.h>
+#include <xmlsec/xmltree.h>
+#include <xmlsec/keys.h>
+#include <xmlsec/keyinfo.h>
+#include <xmlsec/transforms.h>
+#include <xmlsec/errors.h>
+
+#include <xmlsec/gnutls/crypto.h>
+
+/**************************************************************************
+ *
+ * We use xmlsec-gcrypt for all the basic crypto ops
+ *
+ *****************************************************************************/
+#include <xmlsec/gcrypt/crypto.h>
+
+
+
+#ifndef XMLSEC_NO_AES
+/**
+ * xmlSecGnuTLSKeyDataAesGetKlass:
+ *
+ * The AES key data klass.
+ *
+ * Returns: AES key data klass.
+ */
+xmlSecKeyDataId
+xmlSecGnuTLSKeyDataAesGetKlass(void) {
+ return (xmlSecGCryptKeyDataAesGetKlass());
+}
+
+/**
+ * xmlSecGnuTLSKeyDataAesSet:
+ * @data: the pointer to AES key data.
+ * @buf: the pointer to key value.
+ * @bufSize: the key value size (in bytes).
+ *
+ * Sets the value of AES key data.
+ *
+ * Returns: 0 on success or a negative value if an error occurs.
+ */
+int
+xmlSecGnuTLSKeyDataAesSet(xmlSecKeyDataPtr data, const xmlSecByte* buf, xmlSecSize bufSize) {
+ return (xmlSecGCryptKeyDataAesSet(data, buf, bufSize));
+}
+#endif /* XMLSEC_NO_AES */
+
+#ifndef XMLSEC_NO_DES
+/**
+ * xmlSecGnuTLSKeyDataDesGetKlass:
+ *
+ * The DES key data klass.
+ *
+ * Returns: DES key data klass.
+ */
+xmlSecKeyDataId
+xmlSecGnuTLSKeyDataDesGetKlass(void) {
+ return (xmlSecGCryptKeyDataDesGetKlass());
+}
+
+/**
+ * xmlSecGnuTLSKeyDataDesSet:
+ * @data: the pointer to DES key data.
+ * @buf: the pointer to key value.
+ * @bufSize: the key value size (in bytes).
+ *
+ * Sets the value of DES key data.
+ *
+ * Returns: 0 on success or a negative value if an error occurs.
+ */
+int
+xmlSecGnuTLSKeyDataDesSet(xmlSecKeyDataPtr data, const xmlSecByte* buf, xmlSecSize bufSize) {
+ return (xmlSecGCryptKeyDataDesSet(data, buf, bufSize));
+}
+
+#endif /* XMLSEC_NO_DES */
+
+#ifndef XMLSEC_NO_HMAC
+
+/**
+ * xmlSecGnuTLSKeyDataHmacGetKlass:
+ *
+ * The HMAC key data klass.
+ *
+ * Returns: HMAC key data klass.
+ */
+xmlSecKeyDataId
+xmlSecGnuTLSKeyDataHmacGetKlass(void) {
+ return (xmlSecGCryptKeyDataHmacGetKlass());
+}
+
+/**
+ * xmlSecGnuTLSKeyDataHmacSet:
+ * @data: the pointer to HMAC key data.
+ * @buf: the pointer to key value.
+ * @bufSize: the key value size (in bytes).
+ *
+ * Sets the value of HMAC key data.
+ *
+ * Returns: 0 on success or a negative value if an error occurs.
+ */
+int
+xmlSecGnuTLSKeyDataHmacSet(xmlSecKeyDataPtr data, const xmlSecByte* buf, xmlSecSize bufSize) {
+ return (xmlSecGCryptKeyDataHmacSet(data, buf, bufSize));
+}
+
+#endif /* XMLSEC_NO_HMAC */
+
diff --git a/src/gnutls/x509.c b/src/gnutls/x509.c
new file mode 100644
index 00000000..52d46ab4
--- /dev/null
+++ b/src/gnutls/x509.c
@@ -0,0 +1,1960 @@
+/**
+ * XMLSec library
+ *
+ * X509 support
+ *
+ *
+ * This is free software; see Copyright file in the source
+ * distribution for preciese wording.
+ *
+ * Copyright (C) 2010 Aleksey Sanin <aleksey@aleksey.com>
+ */
+#include "globals.h"
+
+#ifndef XMLSEC_NO_X509
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <time.h>
+
+#include <libxml/tree.h>
+
+#include <xmlsec/xmlsec.h>
+#include <xmlsec/xmltree.h>
+#include <xmlsec/keys.h>
+#include <xmlsec/keyinfo.h>
+#include <xmlsec/keysmngr.h>
+#include <xmlsec/x509.h>
+#include <xmlsec/base64.h>
+#include <xmlsec/errors.h>
+#include <xmlsec/private.h>
+
+#include <xmlsec/gnutls/crypto.h>
+#include <xmlsec/gnutls/x509.h>
+
+#include "x509utils.h"
+
+/*************************************************************************
+ *
+ * X509 utility functions
+ *
+ ************************************************************************/
+static int xmlSecGnuTLSX509DataNodeRead (xmlSecKeyDataPtr data,
+ xmlNodePtr node,
+ xmlSecKeyInfoCtxPtr keyInfoCtx);
+static int xmlSecGnuTLSX509CertificateNodeRead (xmlSecKeyDataPtr data,
+ xmlNodePtr node,
+ xmlSecKeyInfoCtxPtr keyInfoCtx);
+static int xmlSecGnuTLSX509CertificateNodeWrite (gnutls_x509_crt_t cert,
+ xmlNodePtr node,
+ xmlSecKeyInfoCtxPtr keyInfoCtx);
+static int xmlSecGnuTLSX509SubjectNameNodeRead (xmlSecKeyDataPtr data,
+ xmlNodePtr node,
+ xmlSecKeyInfoCtxPtr keyInfoCtx);
+static int xmlSecGnuTLSX509SubjectNameNodeWrite (gnutls_x509_crt_t cert,
+ xmlNodePtr node,
+ xmlSecKeyInfoCtxPtr keyInfoCtx);
+static int xmlSecGnuTLSX509IssuerSerialNodeRead (xmlSecKeyDataPtr data,
+ xmlNodePtr node,
+ xmlSecKeyInfoCtxPtr keyInfoCtx);
+static int xmlSecGnuTLSX509IssuerSerialNodeWrite (gnutls_x509_crt_t cert,
+ xmlNodePtr node,
+ xmlSecKeyInfoCtxPtr keyInfoCtx);
+static int xmlSecGnuTLSX509SKINodeRead (xmlSecKeyDataPtr data,
+ xmlNodePtr node,
+ xmlSecKeyInfoCtxPtr keyInfoCtx);
+static int xmlSecGnuTLSX509SKINodeWrite (gnutls_x509_crt_t cert,
+ xmlNodePtr node,
+ xmlSecKeyInfoCtxPtr keyInfoCtx);
+static int xmlSecGnuTLSX509CRLNodeRead (xmlSecKeyDataPtr data,
+ xmlNodePtr node,
+ xmlSecKeyInfoCtxPtr keyInfoCtx);
+static int xmlSecGnuTLSX509CRLNodeWrite (gnutls_x509_crl_t crl,
+ xmlNodePtr node,
+ xmlSecKeyInfoCtxPtr keyInfoCtx);
+static int xmlSecGnuTLSKeyDataX509VerifyAndExtractKey(xmlSecKeyDataPtr data,
+ xmlSecKeyPtr key,
+ xmlSecKeyInfoCtxPtr keyInfoCtx);
+
+/*************************************************************************
+ *
+ * Internal GnuTLS X509 data CTX
+ *
+ ************************************************************************/
+typedef struct _xmlSecGnuTLSX509DataCtx xmlSecGnuTLSX509DataCtx,
+ *xmlSecGnuTLSX509DataCtxPtr;
+struct _xmlSecGnuTLSX509DataCtx {
+ gnutls_x509_crt_t keyCert;
+ xmlSecPtrList certsList;
+ xmlSecPtrList crlsList;
+};
+
+
+/**************************************************************************
+ *
+ * <dsig:X509Data> processing
+ *
+ *
+ * The X509Data Element (http://www.w3.org/TR/xmldsig-core/#sec-X509Data)
+ *
+ * An X509Data element within KeyInfo contains one or more identifiers of keys
+ * or X509 certificates (or certificates' identifiers or a revocation list).
+ * The content of X509Data is:
+ *
+ * 1. At least one element, from the following set of element types; any of these may appear together or more than once iff (if and only if) each instance describes or is related to the same certificate:
+ * 2.
+ * * The X509IssuerSerial element, which contains an X.509 issuer
+ * distinguished name/serial number pair that SHOULD be compliant
+ * with RFC2253 [LDAP-DN],
+ * * The X509SubjectName element, which contains an X.509 subject
+ * distinguished name that SHOULD be compliant with RFC2253 [LDAP-DN],
+ * * The X509SKI element, which contains the base64 encoded plain (i.e.
+ * non-DER-encoded) value of a X509 V.3 SubjectKeyIdentifier extension.
+ * * The X509Certificate element, which contains a base64-encoded [X509v3]
+ * certificate, and
+ * * Elements from an external namespace which accompanies/complements any
+ * of the elements above.
+ * * The X509CRL element, which contains a base64-encoded certificate
+ * revocation list (CRL) [X509v3].
+ *
+ * Any X509IssuerSerial, X509SKI, and X509SubjectName elements that appear
+ * MUST refer to the certificate or certificates containing the validation key.
+ * All such elements that refer to a particular individual certificate MUST be
+ * grouped inside a single X509Data element and if the certificate to which
+ * they refer appears, it MUST also be in that X509Data element.
+ *
+ * Any X509IssuerSerial, X509SKI, and X509SubjectName elements that relate to
+ * the same key but different certificates MUST be grouped within a single
+ * KeyInfo but MAY occur in multiple X509Data elements.
+ *
+ * All certificates appearing in an X509Data element MUST relate to the
+ * validation key by either containing it or being part of a certification
+ * chain that terminates in a certificate containing the validation key.
+ *
+ * No ordering is implied by the above constraints.
+ *
+ * Note, there is no direct provision for a PKCS#7 encoded "bag" of
+ * certificates or CRLs. However, a set of certificates and CRLs can occur
+ * within an X509Data element and multiple X509Data elements can occur in a
+ * KeyInfo. Whenever multiple certificates occur in an X509Data element, at
+ * least one such certificate must contain the public key which verifies the
+ * signature.
+ *
+ * Schema Definition
+ *
+ * <element name="X509Data" type="ds:X509DataType"/>
+ * <complexType name="X509DataType">
+ * <sequence maxOccurs="unbounded">
+ * <choice>
+ * <element name="X509IssuerSerial" type="ds:X509IssuerSerialType"/>
+ * <element name="X509SKI" type="base64Binary"/>
+ * <element name="X509SubjectName" type="string"/>
+ * <element name="X509Certificate" type="base64Binary"/>
+ * <element name="X509CRL" type="base64Binary"/>
+ * <any namespace="##other" processContents="lax"/>
+ * </choice>
+ * </sequence>
+ * </complexType>
+ * <complexType name="X509IssuerSerialType">
+ * <sequence>
+ * <element name="X509IssuerName" type="string"/>
+ * <element name="X509SerialNumber" type="integer"/>
+ * </sequence>
+ * </complexType>
+ *
+ * DTD
+ *
+ * <!ELEMENT X509Data ((X509IssuerSerial | X509SKI | X509SubjectName |
+ * X509Certificate | X509CRL)+ %X509.ANY;)>
+ * <!ELEMENT X509IssuerSerial (X509IssuerName, X509SerialNumber) >
+ * <!ELEMENT X509IssuerName (#PCDATA) >
+ * <!ELEMENT X509SubjectName (#PCDATA) >
+ * <!ELEMENT X509SerialNumber (#PCDATA) >
+ * <!ELEMENT X509SKI (#PCDATA) >
+ * <!ELEMENT X509Certificate (#PCDATA) >
+ * <!ELEMENT X509CRL (#PCDATA) >
+ *
+ * -----------------------------------------------------------------------
+ *
+ * xmlSecGnuTLSX509DataCtx is located after xmlSecTransform
+ *
+ *************************************************************************/
+#define xmlSecGnuTLSX509DataSize \
+ (sizeof(xmlSecKeyData) + sizeof(xmlSecGnuTLSX509DataCtx))
+#define xmlSecGnuTLSX509DataGetCtx(data) \
+ ((xmlSecGnuTLSX509DataCtxPtr)(((xmlSecByte*)(data)) + sizeof(xmlSecKeyData)))
+
+static int xmlSecGnuTLSKeyDataX509Initialize (xmlSecKeyDataPtr data);
+static int xmlSecGnuTLSKeyDataX509Duplicate (xmlSecKeyDataPtr dst,
+ xmlSecKeyDataPtr src);
+static void xmlSecGnuTLSKeyDataX509Finalize (xmlSecKeyDataPtr data);
+static int xmlSecGnuTLSKeyDataX509XmlRead (xmlSecKeyDataId id,
+ xmlSecKeyPtr key,
+ xmlNodePtr node,
+ xmlSecKeyInfoCtxPtr keyInfoCtx);
+static int xmlSecGnuTLSKeyDataX509XmlWrite (xmlSecKeyDataId id,
+ xmlSecKeyPtr key,
+ xmlNodePtr node,
+ xmlSecKeyInfoCtxPtr keyInfoCtx);
+static xmlSecKeyDataType xmlSecGnuTLSKeyDataX509GetType (xmlSecKeyDataPtr data);
+static const xmlChar* xmlSecGnuTLSKeyDataX509GetIdentifier (xmlSecKeyDataPtr data);
+
+static void xmlSecGnuTLSKeyDataX509DebugDump (xmlSecKeyDataPtr data,
+ FILE* output);
+static void xmlSecGnuTLSKeyDataX509DebugXmlDump (xmlSecKeyDataPtr data,
+ FILE* output);
+
+
+
+static xmlSecKeyDataKlass xmlSecGnuTLSKeyDataX509Klass = {
+ sizeof(xmlSecKeyDataKlass),
+ xmlSecGnuTLSX509DataSize,
+
+ /* data */
+ xmlSecNameX509Data,
+ xmlSecKeyDataUsageKeyInfoNode | xmlSecKeyDataUsageRetrievalMethodNodeXml,
+ /* xmlSecKeyDataUsage usage; */
+ xmlSecHrefX509Data, /* const xmlChar* href; */
+ xmlSecNodeX509Data, /* const xmlChar* dataNodeName; */
+ xmlSecDSigNs, /* const xmlChar* dataNodeNs; */
+
+ /* constructors/destructor */
+ xmlSecGnuTLSKeyDataX509Initialize, /* xmlSecKeyDataInitializeMethod initialize; */
+ xmlSecGnuTLSKeyDataX509Duplicate, /* xmlSecKeyDataDuplicateMethod duplicate; */
+ xmlSecGnuTLSKeyDataX509Finalize, /* xmlSecKeyDataFinalizeMethod finalize; */
+ NULL, /* xmlSecKeyDataGenerateMethod generate; */
+
+ /* get info */
+ xmlSecGnuTLSKeyDataX509GetType, /* xmlSecKeyDataGetTypeMethod getType; */
+ NULL, /* xmlSecKeyDataGetSizeMethod getSize; */
+ xmlSecGnuTLSKeyDataX509GetIdentifier, /* xmlSecKeyDataGetIdentifier getIdentifier; */
+
+ /* read/write */
+ xmlSecGnuTLSKeyDataX509XmlRead, /* xmlSecKeyDataXmlReadMethod xmlRead; */
+ xmlSecGnuTLSKeyDataX509XmlWrite, /* xmlSecKeyDataXmlWriteMethod xmlWrite; */
+ NULL, /* xmlSecKeyDataBinReadMethod binRead; */
+ NULL, /* xmlSecKeyDataBinWriteMethod binWrite; */
+
+ /* debug */
+ xmlSecGnuTLSKeyDataX509DebugDump, /* xmlSecKeyDataDebugDumpMethod debugDump; */
+ xmlSecGnuTLSKeyDataX509DebugXmlDump, /* xmlSecKeyDataDebugDumpMethod debugXmlDump; */
+
+ /* reserved for the future */
+ NULL, /* void* reserved0; */
+ NULL, /* void* reserved1; */
+};
+
+/**
+ * xmlSecGnuTLSKeyDataX509GetKlass:
+ *
+ * The GnuTLS X509 key data klass (http://www.w3.org/TR/xmldsig-core/#sec-X509Data).
+ *
+ * Returns: the X509 data klass.
+ */
+xmlSecKeyDataId
+xmlSecGnuTLSKeyDataX509GetKlass(void) {
+ return(&xmlSecGnuTLSKeyDataX509Klass);
+}
+
+/**
+ * xmlSecGnuTLSKeyDataX509GetKeyCert:
+ * @data: the pointer to X509 key data.
+ *
+ * Gets the certificate from which the key was extracted.
+ *
+ * Returns: the key's certificate or NULL if key data was not used for key
+ * extraction or an error occurs.
+ */
+gnutls_x509_crt_t
+xmlSecGnuTLSKeyDataX509GetKeyCert(xmlSecKeyDataPtr data) {
+ xmlSecGnuTLSX509DataCtxPtr ctx;
+
+ xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id), NULL);
+
+ ctx = xmlSecGnuTLSX509DataGetCtx(data);
+ xmlSecAssert2(ctx != NULL, NULL);
+
+ return(ctx->keyCert);
+}
+
+/**
+ * xmlSecGnuTLSKeyDataX509AdoptKeyCert:
+ * @data: the pointer to X509 key data.
+ * @cert: the pointer to GnuTLS X509 certificate.
+ *
+ * Sets the key's certificate in @data.
+ *
+ * Returns: 0 on success or a negative value if an error occurs.
+ */
+int
+xmlSecGnuTLSKeyDataX509AdoptKeyCert(xmlSecKeyDataPtr data, gnutls_x509_crt_t cert) {
+ xmlSecGnuTLSX509DataCtxPtr ctx;
+
+ xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id), -1);
+ xmlSecAssert2(cert != NULL, -1);
+
+ ctx = xmlSecGnuTLSX509DataGetCtx(data);
+ xmlSecAssert2(ctx != NULL, -1);
+
+ if(ctx->keyCert != NULL) {
+ gnutls_x509_crt_deinit(ctx->keyCert);
+ }
+ ctx->keyCert = cert;
+ return(0);
+}
+
+/**
+ * xmlSecGnuTLSKeyDataX509AdoptCert:
+ * @data: the pointer to X509 key data.
+ * @cert: the pointer to GnuTLS X509 certificate.
+ *
+ * Adds certificate to the X509 key data.
+ *
+ * Returns: 0 on success or a negative value if an error occurs.
+ */
+int
+xmlSecGnuTLSKeyDataX509AdoptCert(xmlSecKeyDataPtr data, gnutls_x509_crt_t cert) {
+ xmlSecGnuTLSX509DataCtxPtr ctx;
+ int ret;
+
+ xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id), -1);
+ xmlSecAssert2(cert != NULL, -1);
+
+ ctx = xmlSecGnuTLSX509DataGetCtx(data);
+ xmlSecAssert2(ctx != NULL, -1);
+
+ ret = xmlSecPtrListAdd(&(ctx->certsList), cert);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ "xmlSecPtrListAdd",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ return(0);
+}
+
+/**
+ * xmlSecGnuTLSKeyDataX509GetCert:
+ * @data: the pointer to X509 key data.
+ * @pos: the desired certificate position.
+ *
+ * Gets a certificate from X509 key data.
+ *
+ * Returns: the pointer to certificate or NULL if @pos is larger than the
+ * number of certificates in @data or an error occurs.
+ */
+gnutls_x509_crt_t
+xmlSecGnuTLSKeyDataX509GetCert(xmlSecKeyDataPtr data, xmlSecSize pos) {
+ xmlSecGnuTLSX509DataCtxPtr ctx;
+
+ xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id), NULL);
+
+ ctx = xmlSecGnuTLSX509DataGetCtx(data);
+ xmlSecAssert2(ctx != NULL, NULL);
+
+ return(xmlSecPtrListGetItem(&(ctx->certsList), pos));
+}
+
+/**
+ * xmlSecGnuTLSKeyDataX509GetCertsSize:
+ * @data: the pointer to X509 key data.
+ *
+ * Gets the number of certificates in @data.
+ *
+ * Returns: te number of certificates in @data.
+ */
+xmlSecSize
+xmlSecGnuTLSKeyDataX509GetCertsSize(xmlSecKeyDataPtr data) {
+ xmlSecGnuTLSX509DataCtxPtr ctx;
+
+ xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id), 0);
+
+ ctx = xmlSecGnuTLSX509DataGetCtx(data);
+ xmlSecAssert2(ctx != NULL, 0);
+
+ return(xmlSecPtrListGetSize(&(ctx->certsList)));
+}
+
+/**
+ * xmlSecGnuTLSKeyDataX509AdoptCrl:
+ * @data: the pointer to X509 key data.
+ * @crl: the pointer to GnuTLS X509 crl.
+ *
+ * Adds crl to the X509 key data.
+ *
+ * Returns: 0 on success or a negative value if an error occurs.
+ */
+int
+xmlSecGnuTLSKeyDataX509AdoptCrl(xmlSecKeyDataPtr data, gnutls_x509_crl_t crl) {
+ xmlSecGnuTLSX509DataCtxPtr ctx;
+ int ret;
+
+ xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id), -1);
+ xmlSecAssert2(crl != NULL, -1);
+
+ ctx = xmlSecGnuTLSX509DataGetCtx(data);
+ xmlSecAssert2(ctx != NULL, -1);
+
+ ret = xmlSecPtrListAdd(&(ctx->crlsList), crl);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ "xmlSecPtrListAdd",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ return(0);
+}
+
+/**
+ * xmlSecGnuTLSKeyDataX509GetCrl:
+ * @data: the pointer to X509 key data.
+ * @pos: the desired crl position.
+ *
+ * Gets a crl from X509 key data.
+ *
+ * Returns: the pointer to crl or NULL if @pos is larger than the
+ * number of crls in @data or an error occurs.
+ */
+gnutls_x509_crl_t
+xmlSecGnuTLSKeyDataX509GetCrl(xmlSecKeyDataPtr data, xmlSecSize pos) {
+ xmlSecGnuTLSX509DataCtxPtr ctx;
+
+ xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id), NULL);
+
+ ctx = xmlSecGnuTLSX509DataGetCtx(data);
+ xmlSecAssert2(ctx != NULL, NULL);
+
+ return(xmlSecPtrListGetItem(&(ctx->crlsList), pos));
+}
+
+/**
+ * xmlSecGnuTLSKeyDataX509GetCrlsSize:
+ * @data: the pointer to X509 key data.
+ *
+ * Gets the number of crls in @data.
+ *
+ * Returns: te number of crls in @data.
+ */
+xmlSecSize
+xmlSecGnuTLSKeyDataX509GetCrlsSize(xmlSecKeyDataPtr data) {
+ xmlSecGnuTLSX509DataCtxPtr ctx;
+
+ xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id), 0);
+
+ ctx = xmlSecGnuTLSX509DataGetCtx(data);
+ xmlSecAssert2(ctx != NULL, 0);
+
+ return(xmlSecPtrListGetSize(&(ctx->crlsList)));
+}
+
+
+static int
+xmlSecGnuTLSKeyDataX509Initialize(xmlSecKeyDataPtr data) {
+ xmlSecGnuTLSX509DataCtxPtr ctx;
+ int ret;
+
+ xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id), -1);
+
+ ctx = xmlSecGnuTLSX509DataGetCtx(data);
+ xmlSecAssert2(ctx != NULL, -1);
+
+ memset(ctx, 0, sizeof(xmlSecGnuTLSX509DataCtx));
+
+ ret = xmlSecPtrListInitialize(&(ctx->certsList), xmlSecGnuTLSX509CrtListId);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ "xmlSecPtrListInitialize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "certsList");
+ return(-1);
+ }
+
+ ret = xmlSecPtrListInitialize(&(ctx->crlsList), xmlSecGnuTLSX509CrlListId);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ "xmlSecPtrListInitialize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "crlsList");
+ return(-1);
+ }
+
+ return(0);
+}
+
+static int
+xmlSecGnuTLSKeyDataX509Duplicate(xmlSecKeyDataPtr dst, xmlSecKeyDataPtr src) {
+ xmlSecGnuTLSX509DataCtxPtr ctxSrc;
+ xmlSecGnuTLSX509DataCtxPtr ctxDst;
+ int ret;
+
+ xmlSecAssert2(xmlSecKeyDataCheckId(dst, xmlSecGnuTLSKeyDataX509Id), -1);
+ xmlSecAssert2(xmlSecKeyDataCheckId(src, xmlSecGnuTLSKeyDataX509Id), -1);
+
+ ctxSrc = xmlSecGnuTLSX509DataGetCtx(src);
+ xmlSecAssert2(ctxSrc != NULL, 0);
+ ctxDst = xmlSecGnuTLSX509DataGetCtx(dst);
+ xmlSecAssert2(ctxDst != NULL, 0);
+
+ /* copy key cert if exist */
+ if(ctxDst->keyCert != NULL) {
+ gnutls_x509_crt_deinit(ctxDst->keyCert);
+ ctxDst->keyCert = NULL;
+ }
+ if(ctxSrc->keyCert != NULL) {
+ ctxDst->keyCert = xmlSecGnuTLSX509CertDup(ctxSrc->keyCert);
+ if(ctxDst->keyCert == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(src)),
+ "xmlSecGnuTLSX509CertDup",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ }
+
+ /* copy certsList if exists */
+ xmlSecPtrListEmpty(&(ctxDst->certsList));
+ ret = xmlSecPtrListCopy(&(ctxDst->certsList), &(ctxSrc->certsList));
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(src)),
+ "xmlSecPtrListCopy",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "certsList");
+ return(-1);
+ }
+
+ /* copy crlsList if exists */
+ xmlSecPtrListEmpty(&(ctxDst->crlsList));
+ ret = xmlSecPtrListCopy(&(ctxDst->crlsList), &(ctxSrc->crlsList));
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(src)),
+ "xmlSecPtrListCopy",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "crlsList");
+ return(-1);
+ }
+ /* done */
+ return(0);
+}
+
+static void
+xmlSecGnuTLSKeyDataX509Finalize(xmlSecKeyDataPtr data) {
+ xmlSecGnuTLSX509DataCtxPtr ctx;
+
+ xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id));
+
+ ctx = xmlSecGnuTLSX509DataGetCtx(data);
+ xmlSecAssert(ctx != NULL);
+
+ xmlSecPtrListFinalize(&(ctx->crlsList));
+ xmlSecPtrListFinalize(&(ctx->certsList));
+ if(ctx->keyCert != NULL) {
+ gnutls_x509_crt_deinit(ctx->keyCert);
+ }
+ memset(ctx, 0, sizeof(xmlSecGnuTLSX509DataCtx));
+}
+
+static int
+xmlSecGnuTLSKeyDataX509XmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
+ xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
+ xmlSecKeyDataPtr data;
+ int ret;
+
+ xmlSecAssert2(id == xmlSecGnuTLSKeyDataX509Id, -1);
+ xmlSecAssert2(key != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+ xmlSecAssert2(keyInfoCtx != NULL, -1);
+
+ data = xmlSecKeyEnsureData(key, id);
+ if(data == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecKeyEnsureData",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ ret = xmlSecGnuTLSX509DataNodeRead(data, node, keyInfoCtx);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecGnuTLSX509DataNodeRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_X509DATA_DONT_VERIFY_CERTS) == 0) {
+ ret = xmlSecGnuTLSKeyDataX509VerifyAndExtractKey(data, key, keyInfoCtx);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecGnuTLSKeyDataX509VerifyAndExtractKey",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ }
+ return(0);
+}
+
+static int
+xmlSecGnuTLSKeyDataX509XmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key,
+ xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
+ xmlSecKeyDataPtr data;
+ gnutls_x509_crt_t cert;
+ gnutls_x509_crl_t crl;
+ xmlSecSize size, pos;
+ int content;
+ int ret;
+
+ xmlSecAssert2(id == xmlSecGnuTLSKeyDataX509Id, -1);
+ xmlSecAssert2(key != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+ xmlSecAssert2(keyInfoCtx != NULL, -1);
+
+ content = xmlSecX509DataGetNodeContent (node, 1, keyInfoCtx);
+ if (content < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecX509DataGetNodeContent",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "content=%d", content);
+ return(-1);
+ } else if(content == 0) {
+ /* by default we are writing certificates and crls */
+ content = XMLSEC_X509DATA_DEFAULT;
+ }
+
+ /* get x509 data */
+ data = xmlSecKeyGetData(key, id);
+ if(data == NULL) {
+ /* no x509 data in the key */
+ return(0);
+ }
+
+ /* write certs */
+ size = xmlSecGnuTLSKeyDataX509GetCertsSize(data);
+ for(pos = 0; pos < size; ++pos) {
+ cert = xmlSecGnuTLSKeyDataX509GetCert(data, pos);
+ if(cert == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecGnuTLSKeyDataX509GetCert",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "pos=%d", pos);
+ return(-1);
+ }
+
+ if((content & XMLSEC_X509DATA_CERTIFICATE_NODE) != 0) {
+ ret = xmlSecGnuTLSX509CertificateNodeWrite(cert, node, keyInfoCtx);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecGnuTLSX509CertificateNodeWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "pos=%d", pos);
+ return(-1);
+ }
+ }
+
+ if((content & XMLSEC_X509DATA_SUBJECTNAME_NODE) != 0) {
+ ret = xmlSecGnuTLSX509SubjectNameNodeWrite(cert, node, keyInfoCtx);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecGnuTLSX509SubjectNameNodeWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "pos=%d", pos);
+ return(-1);
+ }
+ }
+
+ if((content & XMLSEC_X509DATA_ISSUERSERIAL_NODE) != 0) {
+ ret = xmlSecGnuTLSX509IssuerSerialNodeWrite(cert, node, keyInfoCtx);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecGnuTLSX509IssuerSerialNodeWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "pos=%d", pos);
+ return(-1);
+ }
+ }
+
+ if((content & XMLSEC_X509DATA_SKI_NODE) != 0) {
+ ret = xmlSecGnuTLSX509SKINodeWrite(cert, node, keyInfoCtx);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecGnuTLSX509SKINodeWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "pos=%d", pos);
+ return(-1);
+ }
+ }
+ }
+
+ /* write crls if needed */
+ if((content & XMLSEC_X509DATA_CRL_NODE) != 0) {
+ size = xmlSecGnuTLSKeyDataX509GetCrlsSize(data);
+ for(pos = 0; pos < size; ++pos) {
+ crl = xmlSecGnuTLSKeyDataX509GetCrl(data, pos);
+ if(crl == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecGnuTLSKeyDataX509GetCrl",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "pos=%d", pos);
+ return(-1);
+ }
+
+ ret = xmlSecGnuTLSX509CRLNodeWrite(crl, node, keyInfoCtx);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecGnuTLSX509CRLNodeWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "pos=%d", pos);
+ return(-1);
+ }
+ }
+ }
+
+ /* done */
+ return(0);
+}
+
+
+static xmlSecKeyDataType
+xmlSecGnuTLSKeyDataX509GetType(xmlSecKeyDataPtr data) {
+ xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id), xmlSecKeyDataTypeUnknown);
+
+ /* TODO: return verified/not verified status */
+ return(xmlSecKeyDataTypeUnknown);
+}
+
+static const xmlChar*
+xmlSecGnuTLSKeyDataX509GetIdentifier(xmlSecKeyDataPtr data) {
+ xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id), NULL);
+
+ /* TODO */
+ return(NULL);
+}
+
+static void
+xmlSecGnuTLSKeyDataX509DebugDump(xmlSecKeyDataPtr data, FILE* output) {
+ xmlSecSize size, pos;
+
+ xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id));
+ xmlSecAssert(output != NULL);
+
+ fprintf(output, "=== X509 Data:\n");
+
+ /* key cert */
+ {
+ gnutls_x509_crt_t cert;
+
+ cert = xmlSecGnuTLSKeyDataX509GetKeyCert(data);
+ if(cert != NULL) {
+ fprintf(output, "==== Key Certificate:\n");
+ xmlSecGnuTLSX509CertDebugDump(cert, output);
+ }
+ }
+
+ /* other certs */
+ size = xmlSecGnuTLSKeyDataX509GetCertsSize(data);
+ for(pos = 0; pos < size; ++pos) {
+ gnutls_x509_crt_t cert;
+
+ cert = xmlSecGnuTLSKeyDataX509GetCert(data, pos);
+ if(cert == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ "xmlSecGnuTLSKeyDataX509GetCert",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "pos=%d", pos);
+ return;
+ }
+ fprintf(output, "==== Certificate:\n");
+ xmlSecGnuTLSX509CertDebugDump(cert, output);
+ }
+
+ /* crls */
+ size = xmlSecGnuTLSKeyDataX509GetCrlsSize(data);
+ for(pos = 0; pos < size; ++pos) {
+ gnutls_x509_crl_t crl;
+
+ crl = xmlSecGnuTLSKeyDataX509GetCrl(data, pos);
+ if(crl == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ "xmlSecGnuTLSKeyDataX509GetCrl",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "pos=%d", pos);
+ return;
+ }
+ fprintf(output, "==== Crl:\n");
+ xmlSecGnuTLSX509CrlDebugDump(crl, output);
+ }
+}
+
+static void
+xmlSecGnuTLSKeyDataX509DebugXmlDump(xmlSecKeyDataPtr data, FILE* output) {
+ xmlSecSize size, pos;
+
+ xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id));
+ xmlSecAssert(output != NULL);
+
+ fprintf(output, "<X509Data>\n");
+
+ /* key cert */
+ {
+ gnutls_x509_crt_t cert;
+
+ cert = xmlSecGnuTLSKeyDataX509GetKeyCert(data);
+ if(cert != NULL) {
+ fprintf(output, "<KeyCertificate>\n");
+ xmlSecGnuTLSX509CertDebugXmlDump(cert, output);
+ fprintf(output, "</KeyCertificate>\n");
+ }
+ }
+
+ /* other certs */
+ size = xmlSecGnuTLSKeyDataX509GetCertsSize(data);
+ for(pos = 0; pos < size; ++pos) {
+ gnutls_x509_crt_t cert;
+
+ cert = xmlSecGnuTLSKeyDataX509GetCert(data, pos);
+ if(cert == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ "xmlSecGnuTLSKeyDataX509GetCert",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "pos=%d", pos);
+ return;
+ }
+ fprintf(output, "<Certificate>\n");
+ xmlSecGnuTLSX509CertDebugXmlDump(cert, output);
+ fprintf(output, "</Certificate>\n");
+ }
+
+ /* other crls */
+ size = xmlSecGnuTLSKeyDataX509GetCrlsSize(data);
+ for(pos = 0; pos < size; ++pos) {
+ gnutls_x509_crl_t crl;
+
+ crl = xmlSecGnuTLSKeyDataX509GetCrl(data, pos);
+ if(crl == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ "xmlSecGnuTLSKeyDataX509GetCrl",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "pos=%d", pos);
+ return;
+ }
+ fprintf(output, "<CRL>\n");
+ xmlSecGnuTLSX509CrlDebugXmlDump(crl, output);
+ fprintf(output, "</CRL>\n");
+ }
+
+ /* we don't print out crls */
+ fprintf(output, "</X509Data>\n");
+}
+
+static int
+xmlSecGnuTLSX509DataNodeRead(xmlSecKeyDataPtr data, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
+ xmlNodePtr cur;
+ int ret;
+
+ xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id), -1);
+ xmlSecAssert2(node != NULL, -1);
+ xmlSecAssert2(keyInfoCtx != NULL, -1);
+
+ for(cur = xmlSecGetNextElementNode(node->children);
+ cur != NULL;
+ cur = xmlSecGetNextElementNode(cur->next)) {
+
+ ret = 0;
+ if(xmlSecCheckNodeName(cur, xmlSecNodeX509Certificate, xmlSecDSigNs)) {
+ ret = xmlSecGnuTLSX509CertificateNodeRead(data, cur, keyInfoCtx);
+ } else if(xmlSecCheckNodeName(cur, xmlSecNodeX509SubjectName, xmlSecDSigNs)) {
+ ret = xmlSecGnuTLSX509SubjectNameNodeRead(data, cur, keyInfoCtx);
+ } else if(xmlSecCheckNodeName(cur, xmlSecNodeX509IssuerSerial, xmlSecDSigNs)) {
+ ret = xmlSecGnuTLSX509IssuerSerialNodeRead(data, cur, keyInfoCtx);
+ } else if(xmlSecCheckNodeName(cur, xmlSecNodeX509SKI, xmlSecDSigNs)) {
+ ret = xmlSecGnuTLSX509SKINodeRead(data, cur, keyInfoCtx);
+ } else if(xmlSecCheckNodeName(cur, xmlSecNodeX509CRL, xmlSecDSigNs)) {
+ ret = xmlSecGnuTLSX509CRLNodeRead(data, cur, keyInfoCtx);
+ } else if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_X509DATA_STOP_ON_UNKNOWN_CHILD) != 0) {
+ /* laxi schema validation: ignore unknown nodes */
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
+ XMLSEC_ERRORS_R_UNEXPECTED_NODE,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "read node failed");
+ return(-1);
+ }
+ }
+ return(0);
+}
+
+static int
+xmlSecGnuTLSX509CertificateNodeRead(xmlSecKeyDataPtr data, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
+ xmlChar *content;
+ gnutls_x509_crt_t cert;
+ int ret;
+
+ xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id), -1);
+ xmlSecAssert2(node != NULL, -1);
+ xmlSecAssert2(keyInfoCtx != NULL, -1);
+
+ content = xmlNodeGetContent(node);
+ if((content == NULL) || (xmlSecIsEmptyString(content) == 1)) {
+ if(content != NULL) {
+ xmlFree(content);
+ }
+ if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_STOP_ON_EMPTY_NODE) != 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ xmlSecErrorsSafeString(xmlSecNodeGetName(node)),
+ XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ return(0);
+ }
+
+ cert = xmlSecGnuTLSX509CertBase64DerRead(content);
+ if(cert == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ "xmlSecGnuTLSX509CertBase64DerRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlFree(content);
+ return(-1);
+ }
+
+ ret = xmlSecGnuTLSKeyDataX509AdoptCert(data, cert);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ "xmlSecGnuTLSKeyDataX509AdoptCert",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ gnutls_x509_crt_deinit(cert);
+ xmlFree(content);
+ return(-1);
+ }
+
+ xmlFree(content);
+ return(0);
+}
+
+static int
+xmlSecGnuTLSX509CertificateNodeWrite(gnutls_x509_crt_t cert, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
+ xmlChar* buf;
+ xmlNodePtr cur;
+
+ xmlSecAssert2(cert != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+ xmlSecAssert2(keyInfoCtx != NULL, -1);
+
+ /* set base64 lines size from context */
+ buf = xmlSecGnuTLSX509CertBase64DerWrite(cert, keyInfoCtx->base64LineSize);
+ if(buf == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSX509CertBase64DerWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ cur = xmlSecAddChild(node, xmlSecNodeX509Certificate, xmlSecDSigNs);
+ if(cur == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeX509Certificate));
+ xmlFree(buf);
+ return(-1);
+ }
+
+ /* todo: add \n around base64 data - from context */
+ /* todo: add errors check */
+ xmlNodeSetContent(cur, xmlSecStringCR);
+ xmlNodeSetContent(cur, buf);
+ xmlFree(buf);
+ return(0);
+}
+
+
+
+#define XMLSEC_GNUTLS_IS_SPACE(ch) \
+ (((ch) == ' ') || ((ch) == '\r') || ((ch) == '\n'))
+
+static void
+xmlSecGnuTLSX509Trim(xmlChar * str) {
+ xmlChar * p, * q;
+
+ xmlSecAssert(str != NULL);
+
+ /* skip spaces from the beggining */
+ p = str;
+ while(XMLSEC_GNUTLS_IS_SPACE(*p) && ((*p) != '\0')) ++p;
+ if(p != str) {
+ for(q = str; ; ++q, ++p) {
+ (*q) = (*p);
+ if((*p) == '\0') {
+ break;
+ }
+ }
+ }
+
+ /* skip spaces from the end */
+ for(p = str; (*p) != '\0'; ++p);
+ while((p > str) && (XMLSEC_GNUTLS_IS_SPACE(*(p - 1)))) *(--p) = '\0';
+}
+
+static int
+xmlSecGnuTLSX509SubjectNameNodeRead(xmlSecKeyDataPtr data, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
+ xmlSecKeyDataStorePtr x509Store;
+ xmlChar* subject;
+ gnutls_x509_crt_t cert;
+ gnutls_x509_crt_t cert2;
+ int ret;
+
+ xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id), -1);
+ xmlSecAssert2(node != NULL, -1);
+ xmlSecAssert2(keyInfoCtx != NULL, -1);
+ xmlSecAssert2(keyInfoCtx->keysMngr != NULL, -1);
+
+ x509Store = xmlSecKeysMngrGetDataStore(keyInfoCtx->keysMngr, xmlSecGnuTLSX509StoreId);
+ if(x509Store == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ "xmlSecKeysMngrGetDataStore",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ subject = xmlNodeGetContent(node);
+ if((subject == NULL) || (xmlSecIsEmptyString(subject) == 1)) {
+ if(subject != NULL) {
+ xmlFree(subject);
+ }
+ if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_STOP_ON_EMPTY_NODE) != 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ xmlSecErrorsSafeString(xmlSecNodeGetName(node)),
+ XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ return(0);
+ }
+
+ xmlSecGnuTLSX509Trim(subject);
+ cert = xmlSecGnuTLSX509StoreFindCert(x509Store, subject, NULL, NULL, NULL, keyInfoCtx);
+ if(cert == NULL){
+
+ if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_X509DATA_STOP_ON_UNKNOWN_CERT) != 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ NULL,
+ XMLSEC_ERRORS_R_CERT_NOT_FOUND,
+ "subject=%s",
+ xmlSecErrorsSafeString(subject));
+ xmlFree(subject);
+ return(-1);
+ }
+
+ xmlFree(subject);
+ return(0);
+ }
+
+ cert2 = xmlSecGnuTLSX509CertDup(cert);
+ if(cert2 == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ "xmlSecGnuTLSX509CertDup",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+
+ xmlFree(subject);
+ return(-1);
+ }
+
+ ret = xmlSecGnuTLSKeyDataX509AdoptCert(data, cert2);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ "xmlSecGnuTLSKeyDataX509AdoptCert",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ gnutls_x509_crt_deinit(cert2);
+ xmlFree(subject);
+ return(-1);
+ }
+
+ xmlFree(subject);
+ return(0);
+}
+
+static int
+xmlSecGnuTLSX509SubjectNameNodeWrite(gnutls_x509_crt_t cert, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx ATTRIBUTE_UNUSED) {
+ xmlChar* buf = NULL;
+ xmlNodePtr cur = NULL;
+
+ xmlSecAssert2(cert != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ /* add node */
+ cur = xmlSecAddChild(node, xmlSecNodeX509SubjectName, xmlSecDSigNs);
+ if(cur == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeX509SubjectName));
+ return(-1);
+ }
+
+ /* get subject */
+ buf = xmlSecGnuTLSX509CertGetSubjectDN(cert);
+ if(buf == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSX509CertGetSubjectDN",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* set value */
+ xmlSecNodeEncodeAndSetContent(cur, buf);
+
+ /* done */
+ xmlFree(buf);
+ return(0);
+}
+
+static int
+xmlSecGnuTLSX509IssuerSerialNodeRead(xmlSecKeyDataPtr data, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
+ xmlSecKeyDataStorePtr x509Store;
+ xmlNodePtr cur;
+ xmlChar *issuerName;
+ xmlChar *issuerSerial;
+ gnutls_x509_crt_t cert;
+ gnutls_x509_crt_t cert2;
+ int ret;
+
+ xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id), -1);
+ xmlSecAssert2(node != NULL, -1);
+ xmlSecAssert2(keyInfoCtx != NULL, -1);
+ xmlSecAssert2(keyInfoCtx->keysMngr != NULL, -1);
+
+ x509Store = xmlSecKeysMngrGetDataStore(keyInfoCtx->keysMngr, xmlSecGnuTLSX509StoreId);
+ if(x509Store == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ "xmlSecKeysMngrGetDataStore",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ cur = xmlSecGetNextElementNode(node->children);
+ if(cur == NULL) {
+ if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_STOP_ON_EMPTY_NODE) != 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ xmlSecErrorsSafeString(xmlSecNodeX509IssuerName),
+ XMLSEC_ERRORS_R_NODE_NOT_FOUND,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)));
+ return(-1);
+ }
+ return(0);
+ }
+
+ /* the first is required node X509IssuerName */
+ if(!xmlSecCheckNodeName(cur, xmlSecNodeX509IssuerName, xmlSecDSigNs)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ xmlSecErrorsSafeString(xmlSecNodeX509IssuerName),
+ XMLSEC_ERRORS_R_NODE_NOT_FOUND,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)));
+ return(-1);
+ }
+ issuerName = xmlNodeGetContent(cur);
+ if(issuerName == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
+ XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeX509IssuerName));
+ return(-1);
+ }
+ cur = xmlSecGetNextElementNode(cur->next);
+
+ /* next is required node X509SerialNumber */
+ if((cur == NULL) || !xmlSecCheckNodeName(cur, xmlSecNodeX509SerialNumber, xmlSecDSigNs)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
+ XMLSEC_ERRORS_R_NODE_NOT_FOUND,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeX509SerialNumber));
+ xmlFree(issuerName);
+ return(-1);
+ }
+ issuerSerial = xmlNodeGetContent(cur);
+ if(issuerSerial == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ xmlSecErrorsSafeString(xmlSecNodeX509SerialNumber),
+ XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)));
+ xmlFree(issuerName);
+ return(-1);
+ }
+ cur = xmlSecGetNextElementNode(cur->next);
+
+ if(cur != NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
+ XMLSEC_ERRORS_R_UNEXPECTED_NODE,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlFree(issuerSerial);
+ xmlFree(issuerName);
+ return(-1);
+ }
+
+ xmlSecGnuTLSX509Trim(issuerName);
+ xmlSecGnuTLSX509Trim(issuerSerial);
+ cert = xmlSecGnuTLSX509StoreFindCert(x509Store, NULL, issuerName, issuerSerial, NULL, keyInfoCtx);
+ if(cert == NULL){
+
+ if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_X509DATA_STOP_ON_UNKNOWN_CERT) != 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ NULL,
+ XMLSEC_ERRORS_R_CERT_NOT_FOUND,
+ "issuerName=%s;issuerSerial=%s",
+ xmlSecErrorsSafeString(issuerName),
+ xmlSecErrorsSafeString(issuerSerial));
+ xmlFree(issuerSerial);
+ xmlFree(issuerName);
+ return(-1);
+ }
+ xmlFree(issuerSerial);
+ xmlFree(issuerName);
+ return(0);
+ }
+
+ cert2 = xmlSecGnuTLSX509CertDup(cert);
+ if(cert2 == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ "xmlSecGnuTLSX509CertDup",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlFree(issuerSerial);
+ xmlFree(issuerName);
+ return(-1);
+ }
+
+ ret = xmlSecGnuTLSKeyDataX509AdoptCert(data, cert2);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ "xmlSecGnuTLSKeyDataX509AdoptCert",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ gnutls_x509_crt_deinit(cert2);
+ xmlFree(issuerSerial);
+ xmlFree(issuerName);
+ return(-1);
+ }
+
+ xmlFree(issuerSerial);
+ xmlFree(issuerName);
+ return(0);
+}
+
+static int
+xmlSecGnuTLSX509IssuerSerialNodeWrite(gnutls_x509_crt_t cert, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx ATTRIBUTE_UNUSED) {
+ xmlNodePtr cur;
+ xmlNodePtr issuerNameNode;
+ xmlNodePtr issuerNumberNode;
+ xmlChar* buf;
+
+ xmlSecAssert2(cert != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ /* create xml nodes */
+ cur = xmlSecAddChild(node, xmlSecNodeX509IssuerSerial, xmlSecDSigNs);
+ if(cur == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeX509IssuerSerial));
+ return(-1);
+ }
+
+ issuerNameNode = xmlSecAddChild(cur, xmlSecNodeX509IssuerName, xmlSecDSigNs);
+ if(issuerNameNode == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeX509IssuerName));
+ return(-1);
+ }
+
+ issuerNumberNode = xmlSecAddChild(cur, xmlSecNodeX509SerialNumber, xmlSecDSigNs);
+ if(issuerNumberNode == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeX509SerialNumber));
+ return(-1);
+ }
+
+ /* write data */
+ buf = xmlSecGnuTLSX509CertGetIssuerDN(cert);
+ if(buf == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSX509CertGetIssuerDN",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ xmlSecNodeEncodeAndSetContent(issuerNameNode, buf);
+ xmlFree(buf);
+
+ buf = xmlSecGnuTLSX509CertGetIssuerSerial(cert);
+ if(buf == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSX509CertGetIssuerSerial",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ xmlSecNodeEncodeAndSetContent(issuerNumberNode, buf);
+ xmlFree(buf);
+
+ return(0);
+}
+
+
+static int
+xmlSecGnuTLSX509SKINodeRead(xmlSecKeyDataPtr data, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
+ xmlSecKeyDataStorePtr x509Store;
+ xmlChar* ski;
+ gnutls_x509_crt_t cert;
+ gnutls_x509_crt_t cert2;
+ int ret;
+
+ xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id), -1);
+ xmlSecAssert2(node != NULL, -1);
+ xmlSecAssert2(keyInfoCtx != NULL, -1);
+ xmlSecAssert2(keyInfoCtx->keysMngr != NULL, -1);
+
+ x509Store = xmlSecKeysMngrGetDataStore(keyInfoCtx->keysMngr, xmlSecGnuTLSX509StoreId);
+ if(x509Store == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ "xmlSecKeysMngrGetDataStore",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ ski = xmlNodeGetContent(node);
+ if((ski == NULL) || (xmlSecIsEmptyString(ski) == 1)) {
+ if(ski != NULL) {
+ xmlFree(ski);
+ }
+ if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_STOP_ON_EMPTY_NODE) != 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ xmlSecErrorsSafeString(xmlSecNodeGetName(node)),
+ XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeX509SKI));
+ return(-1);
+ }
+ return(0);
+ }
+
+ xmlSecGnuTLSX509Trim(ski);
+ cert = xmlSecGnuTLSX509StoreFindCert(x509Store, NULL, NULL, NULL, ski, keyInfoCtx);
+ if(cert == NULL){
+ xmlFree(ski);
+
+ if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_X509DATA_STOP_ON_UNKNOWN_CERT) != 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ NULL,
+ XMLSEC_ERRORS_R_CERT_NOT_FOUND,
+ "ski=%s",
+ xmlSecErrorsSafeString(ski));
+ return(-1);
+ }
+ return(0);
+ }
+
+ cert2 = xmlSecGnuTLSX509CertDup(cert);
+ if(cert2 == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ "xmlSecGnuTLSX509CertDup",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlFree(ski);
+ return(-1);
+ }
+
+ ret = xmlSecGnuTLSKeyDataX509AdoptCert(data, cert2);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ "xmlSecGnuTLSKeyDataX509AdoptCert",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ gnutls_x509_crt_deinit(cert2);
+ xmlFree(ski);
+ return(-1);
+ }
+
+ xmlFree(ski);
+ return(0);
+}
+
+static int
+xmlSecGnuTLSX509SKINodeWrite(gnutls_x509_crt_t cert, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx ATTRIBUTE_UNUSED) {
+ xmlChar *buf = NULL;
+ xmlNodePtr cur = NULL;
+
+ xmlSecAssert2(cert != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ /* add node */
+ cur = xmlSecAddChild(node, xmlSecNodeX509SKI, xmlSecDSigNs);
+ if(cur == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "new_node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeX509SKI));
+ return(-1);
+ }
+
+ /* write value */
+ buf = xmlSecGnuTLSX509CertGetSKI(cert);
+ if(buf == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSX509CertGetSKI",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ xmlSecNodeEncodeAndSetContent(cur, buf);
+ xmlFree(buf);
+
+ return(0);
+}
+
+static int
+xmlSecGnuTLSX509CRLNodeRead(xmlSecKeyDataPtr data, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
+ xmlChar *content;
+ gnutls_x509_crl_t crl;
+ int ret;
+
+ xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id), -1);
+ xmlSecAssert2(node != NULL, -1);
+ xmlSecAssert2(keyInfoCtx != NULL, -1);
+
+ content = xmlNodeGetContent(node);
+ if((content == NULL) || (xmlSecIsEmptyString(content) == 1)) {
+ if(content != NULL) {
+ xmlFree(content);
+ }
+ if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_STOP_ON_EMPTY_NODE) != 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ xmlSecErrorsSafeString(xmlSecNodeGetName(node)),
+ XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ return(0);
+ }
+
+ crl = xmlSecGnuTLSX509CrlBase64DerRead(content);
+ if(crl == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ "xmlSecGnuTLSX509CrlBase64DerRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlFree(content);
+ return(-1);
+ }
+
+ ret = xmlSecGnuTLSKeyDataX509AdoptCrl(data, crl);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ "xmlSecGnuTLSKeyDataX509AdoptCrl",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ gnutls_x509_crl_deinit(crl);
+ xmlFree(content);
+ return(-1);
+ }
+
+ xmlFree(content);
+ return(0);
+}
+
+static int
+xmlSecGnuTLSX509CRLNodeWrite(gnutls_x509_crl_t crl, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
+ xmlChar* buf = NULL;
+ xmlNodePtr cur = NULL;
+
+ xmlSecAssert2(crl != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+ xmlSecAssert2(keyInfoCtx != NULL, -1);
+
+ /* set base64 lines size from context */
+ buf = xmlSecGnuTLSX509CrlBase64DerWrite(crl, keyInfoCtx->base64LineSize);
+ if(buf == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSX509CrlBase64DerWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ cur = xmlSecAddChild(node, xmlSecNodeX509CRL, xmlSecDSigNs);
+ if(cur == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "new_node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeX509CRL));
+ xmlFree(buf);
+ return(-1);
+ }
+ /* todo: add \n around base64 data - from context */
+ /* todo: add errors check */
+ xmlNodeSetContent(cur, xmlSecStringCR);
+ xmlNodeSetContent(cur, buf);
+ xmlFree(buf);
+
+ return(0);
+}
+
+
+static int
+xmlSecGnuTLSKeyDataX509VerifyAndExtractKey(xmlSecKeyDataPtr data, xmlSecKeyPtr key,
+ xmlSecKeyInfoCtxPtr keyInfoCtx) {
+ xmlSecGnuTLSX509DataCtxPtr ctx;
+ xmlSecKeyDataStorePtr x509Store;
+ int ret;
+
+ xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id), -1);
+ xmlSecAssert2(key != NULL, -1);
+ xmlSecAssert2(keyInfoCtx != NULL, -1);
+ xmlSecAssert2(keyInfoCtx->keysMngr != NULL, -1);
+
+ ctx = xmlSecGnuTLSX509DataGetCtx(data);
+ xmlSecAssert2(ctx != NULL, -1);
+
+ x509Store = xmlSecKeysMngrGetDataStore(keyInfoCtx->keysMngr, xmlSecGnuTLSX509StoreId);
+ if(x509Store == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ "xmlSecKeysMngrGetDataStore",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ if((ctx->keyCert == NULL) && (xmlSecPtrListGetSize(&(ctx->certsList)) > 0) && (xmlSecKeyGetValue(key) == NULL)) {
+ gnutls_x509_crt_t cert;
+
+ cert = xmlSecGnuTLSX509StoreVerify(x509Store, &(ctx->certsList), &(ctx->crlsList), keyInfoCtx);
+ if(cert != NULL) {
+ xmlSecKeyDataPtr keyValue;
+
+ ctx->keyCert = xmlSecGnuTLSX509CertDup(cert);
+ if(ctx->keyCert == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ "xmlSecGnuTLSX509CertDup",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ keyValue = xmlSecGnuTLSX509CertGetKey(ctx->keyCert);
+ if(keyValue == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ "xmlSecGnuTLSX509CertGetKey",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* verify that the key matches our expectations */
+ if(xmlSecKeyReqMatchKeyValue(&(keyInfoCtx->keyReq), keyValue) != 1) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ "xmlSecKeyReqMatchKeyValue",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecKeyDataDestroy(keyValue);
+ return(-1);
+ }
+
+ ret = xmlSecKeySetValue(key, keyValue);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ "xmlSecKeySetValue",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecKeyDataDestroy(keyValue);
+ return(-1);
+ }
+
+ /* get expiration time */
+ key->notValidBefore = gnutls_x509_crt_get_activation_time(ctx->keyCert);
+ if(key->notValidBefore == (time_t)-1) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ "gnutls_x509_crt_get_activation_time",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ key->notValidAfter = gnutls_x509_crt_get_expiration_time(ctx->keyCert);
+ if(key->notValidAfter == (time_t)-1) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ "gnutls_x509_crt_get_expiration_time",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ } else if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_X509DATA_STOP_ON_INVALID_CERT) != 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
+ NULL,
+ XMLSEC_ERRORS_R_CERT_NOT_FOUND,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ }
+ return(0);
+}
+
+/**
+ * xmlSecGnuTLSX509CertGetKey:
+ * @cert: the certificate.
+ *
+ * Extracts public key from the @cert.
+ *
+ * Returns: public key value or NULL if an error occurs.
+ */
+xmlSecKeyDataPtr
+xmlSecGnuTLSX509CertGetKey(gnutls_x509_crt_t cert) {
+ xmlSecKeyDataPtr data;
+ int alg;
+ unsigned int bits;
+ int err;
+ int ret;
+
+ xmlSecAssert2(cert != NULL, NULL);
+
+ alg = gnutls_x509_crt_get_pk_algorithm(cert, &bits);
+ if(alg < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_crt_get_pk_algorithm",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(alg));
+ return(NULL);
+ }
+
+ switch(alg) {
+#ifndef XMLSEC_NO_RSA
+ case GNUTLS_PK_RSA:
+ {
+ gnutls_datum_t m, e;
+
+ data = xmlSecKeyDataCreate(xmlSecGnuTLSKeyDataRsaId);
+ if(data == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyDataCreate",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "xmlSecGnuTLSKeyDataRsaId");
+ return(NULL);
+ }
+
+ err = gnutls_x509_crt_get_pk_rsa_raw(cert, &m, &e);
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_crt_get_pk_rsa_raw",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ return(NULL);
+ }
+
+ ret = xmlSecGnuTLSKeyDataRsaAdoptPublicKey(data, &m, &e);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSKeyDataRsaAdoptPublicKey",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ gnutls_free(m.data);
+ gnutls_free(e.data);
+ return(NULL);
+ }
+ /* m and e are owned by data now */
+ }
+ break;
+#endif /* XMLSEC_NO_RSA */
+
+#ifndef XMLSEC_NO_DSA
+ case GNUTLS_PK_DSA:
+ {
+ gnutls_datum_t p, q, g, y;
+
+ data = xmlSecKeyDataCreate(xmlSecGnuTLSKeyDataDsaId);
+ if(data == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyDataCreate",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "xmlSecGnuTLSKeyDataDsaId");
+ return(NULL);
+ }
+
+ err = gnutls_x509_crt_get_pk_dsa_raw(cert, &p, &q, &g, &y);
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_crt_get_pk_dsa_raw",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ return(NULL);
+ }
+
+ ret = xmlSecGnuTLSKeyDataDsaAdoptPublicKey(data, &p, &q, &g, &y);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSKeyDataDsaAdoptPublicKey",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ gnutls_free(p.data);
+ gnutls_free(q.data);
+ gnutls_free(g.data);
+ gnutls_free(y.data);
+ return(NULL);
+ }
+ /* p, q, g and y are owned by data now */
+ }
+ break;
+#endif /* XMLSEC_NO_DSA */
+
+ default:
+ {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_crt_get_pk_algorithm",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ "Unsupported algorithm %d", (int)alg);
+ return(NULL);
+ }
+ }
+
+ /* data */
+ return(data);
+}
+
+
+/**************************************************************************
+ *
+ * Raw X509 Certificate processing
+ *
+ *
+ *************************************************************************/
+static int xmlSecGnuTLSKeyDataRawX509CertBinRead (xmlSecKeyDataId id,
+ xmlSecKeyPtr key,
+ const xmlSecByte* buf,
+ xmlSecSize bufSize,
+ xmlSecKeyInfoCtxPtr keyInfoCtx);
+
+static xmlSecKeyDataKlass xmlSecGnuTLSKeyDataRawX509CertKlass = {
+ sizeof(xmlSecKeyDataKlass),
+ sizeof(xmlSecKeyData),
+
+ /* data */
+ xmlSecNameRawX509Cert,
+ xmlSecKeyDataUsageRetrievalMethodNodeBin,
+ /* xmlSecKeyDataUsage usage; */
+ xmlSecHrefRawX509Cert, /* const xmlChar* href; */
+ NULL, /* const xmlChar* dataNodeName; */
+ xmlSecDSigNs, /* const xmlChar* dataNodeNs; */
+
+ /* constructors/destructor */
+ NULL, /* xmlSecKeyDataInitializeMethod initialize; */
+ NULL, /* xmlSecKeyDataDuplicateMethod duplicate; */
+ NULL, /* xmlSecKeyDataFinalizeMethod finalize; */
+ NULL, /* xmlSecKeyDataGenerateMethod generate; */
+
+ /* get info */
+ NULL, /* xmlSecKeyDataGetTypeMethod getType; */
+ NULL, /* xmlSecKeyDataGetSizeMethod getSize; */
+ NULL, /* xmlSecKeyDataGetIdentifier getIdentifier; */
+
+ /* read/write */
+ NULL, /* xmlSecKeyDataXmlReadMethod xmlRead; */
+ NULL, /* xmlSecKeyDataXmlWriteMethod xmlWrite; */
+ xmlSecGnuTLSKeyDataRawX509CertBinRead, /* xmlSecKeyDataBinReadMethod binRead; */
+ NULL, /* xmlSecKeyDataBinWriteMethod binWrite; */
+
+ /* debug */
+ NULL, /* xmlSecKeyDataDebugDumpMethod debugDump; */
+ NULL, /* xmlSecKeyDataDebugDumpMethod debugXmlDump; */
+
+ /* reserved for the future */
+ NULL, /* void* reserved0; */
+ NULL, /* void* reserved1; */
+};
+
+/**
+ * xmlSecGnuTLSKeyDataRawX509CertGetKlass:
+ *
+ * The raw X509 certificates key data klass.
+ *
+ * Returns: raw X509 certificates key data klass.
+ */
+xmlSecKeyDataId
+xmlSecGnuTLSKeyDataRawX509CertGetKlass(void) {
+ return(&xmlSecGnuTLSKeyDataRawX509CertKlass);
+}
+
+static int
+xmlSecGnuTLSKeyDataRawX509CertBinRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
+ const xmlSecByte* buf, xmlSecSize bufSize,
+ xmlSecKeyInfoCtxPtr keyInfoCtx) {
+ xmlSecKeyDataPtr data;
+ gnutls_x509_crt_t cert;
+ int ret;
+
+ xmlSecAssert2(id == xmlSecGnuTLSKeyDataRawX509CertId, -1);
+ xmlSecAssert2(key != NULL, -1);
+ xmlSecAssert2(buf != NULL, -1);
+ xmlSecAssert2(bufSize > 0, -1);
+ xmlSecAssert2(keyInfoCtx != NULL, -1);
+
+ cert = xmlSecGnuTLSX509CertRead(buf, bufSize, xmlSecKeyDataFormatCertDer);
+ if(cert == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSX509CertRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ data = xmlSecKeyEnsureData(key, xmlSecGnuTLSKeyDataX509Id);
+ if(data == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecKeyEnsureData",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ gnutls_x509_crt_deinit(cert);
+ return(-1);
+ }
+
+ ret = xmlSecGnuTLSKeyDataX509AdoptCert(data, cert);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecGnuTLSKeyDataX509AdoptCert",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ gnutls_x509_crt_deinit(cert);
+ return(-1);
+ }
+
+ ret = xmlSecGnuTLSKeyDataX509VerifyAndExtractKey(data, key, keyInfoCtx);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
+ "xmlSecGnuTLSKeyDataX509VerifyAndExtractKey",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ return(0);
+}
+
+#endif /* XMLSEC_NO_X509 */
diff --git a/src/gnutls/x509utils.c b/src/gnutls/x509utils.c
new file mode 100644
index 00000000..0dc70003
--- /dev/null
+++ b/src/gnutls/x509utils.c
@@ -0,0 +1,1687 @@
+/**
+ * XMLSec library
+ *
+ * X509 support
+ *
+ *
+ * This is free software; see Copyright file in the source
+ * distribution for preciese wording.
+ *
+ * Copyright (C) 2010 Aleksey Sanin <aleksey@aleksey.com>
+ */
+#include "globals.h"
+
+#ifndef XMLSEC_NO_X509
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <time.h>
+
+#include <libxml/tree.h>
+
+
+
+#include <gnutls/gnutls.h>
+#include <gnutls/x509.h>
+#include <gnutls/pkcs12.h>
+
+#include <xmlsec/xmlsec.h>
+#include <xmlsec/xmltree.h>
+#include <xmlsec/keys.h>
+#include <xmlsec/keyinfo.h>
+#include <xmlsec/keysmngr.h>
+#include <xmlsec/x509.h>
+#include <xmlsec/base64.h>
+#include <xmlsec/errors.h>
+#include <xmlsec/private.h>
+
+#include <xmlsec/gnutls/crypto.h>
+#include <xmlsec/gnutls/x509.h>
+
+#include "x509utils.h"
+
+
+/**************************************************************************
+ *
+ * X509 crt list
+ *
+ *****************************************************************************/
+static xmlSecPtr xmlSecGnuTLSX509CrtListDuplicateItem (xmlSecPtr ptr);
+static void xmlSecGnuTLSX509CrtListDestroyItem (xmlSecPtr ptr);
+static void xmlSecGnuTLSX509CrtListDebugDumpItem (xmlSecPtr ptr,
+ FILE* output);
+static void xmlSecGnuTLSX509CrtListDebugXmlDumpItem (xmlSecPtr ptr,
+ FILE* output);
+
+static xmlSecPtrListKlass xmlSecGnuTLSX509CrtListKlass = {
+ BAD_CAST "gnutls-x509-crt-list",
+ xmlSecGnuTLSX509CrtListDuplicateItem, /* xmlSecPtrDuplicateItemMethod duplicateItem; */
+ xmlSecGnuTLSX509CrtListDestroyItem, /* xmlSecPtrDestroyItemMethod destroyItem; */
+ xmlSecGnuTLSX509CrtListDebugDumpItem, /* xmlSecPtrDebugDumpItemMethod debugDumpItem; */
+ xmlSecGnuTLSX509CrtListDebugXmlDumpItem, /* xmlSecPtrDebugDumpItemMethod debugXmlDumpItem; */
+};
+
+xmlSecPtrListId
+xmlSecGnuTLSX509CrtListGetKlass(void) {
+ return(&xmlSecGnuTLSX509CrtListKlass);
+}
+
+static xmlSecPtr
+xmlSecGnuTLSX509CrtListDuplicateItem(xmlSecPtr ptr) {
+ xmlSecAssert2(ptr != NULL, NULL);
+
+ return xmlSecGnuTLSX509CertDup((gnutls_x509_crt_t)ptr);
+}
+
+static void
+xmlSecGnuTLSX509CrtListDestroyItem(xmlSecPtr ptr) {
+ xmlSecAssert(ptr != NULL);
+
+ gnutls_x509_crt_deinit((gnutls_x509_crt_t)ptr);
+}
+
+static void
+xmlSecGnuTLSX509CrtListDebugDumpItem(xmlSecPtr ptr, FILE* output) {
+ xmlSecAssert(ptr != NULL);
+ xmlSecAssert(output != NULL);
+
+ xmlSecGnuTLSX509CertDebugDump((gnutls_x509_crt_t)ptr, output);
+}
+
+
+static void
+xmlSecGnuTLSX509CrtListDebugXmlDumpItem(xmlSecPtr ptr, FILE* output) {
+ xmlSecAssert(ptr != NULL);
+ xmlSecAssert(output != NULL);
+
+ xmlSecGnuTLSX509CertDebugXmlDump((gnutls_x509_crt_t)ptr, output);
+}
+
+/**************************************************************************
+ *
+ * X509 crl list
+ *
+ *****************************************************************************/
+static xmlSecPtr xmlSecGnuTLSX509CrlListDuplicateItem (xmlSecPtr ptr);
+static void xmlSecGnuTLSX509CrlListDestroyItem (xmlSecPtr ptr);
+static void xmlSecGnuTLSX509CrlListDebugDumpItem (xmlSecPtr ptr,
+ FILE* output);
+static void xmlSecGnuTLSX509CrlListDebugXmlDumpItem (xmlSecPtr ptr,
+ FILE* output);
+
+static xmlSecPtrListKlass xmlSecGnuTLSX509CrlListKlass = {
+ BAD_CAST "gnutls-x509-crl-list",
+ xmlSecGnuTLSX509CrlListDuplicateItem, /* xmlSecPtrDuplicateItemMethod duplicateItem; */
+ xmlSecGnuTLSX509CrlListDestroyItem, /* xmlSecPtrDestroyItemMethod destroyItem; */
+ xmlSecGnuTLSX509CrlListDebugDumpItem, /* xmlSecPtrDebugDumpItemMethod debugDumpItem; */
+ xmlSecGnuTLSX509CrlListDebugXmlDumpItem, /* xmlSecPtrDebugDumpItemMethod debugXmlDumpItem; */
+};
+
+xmlSecPtrListId
+xmlSecGnuTLSX509CrlListGetKlass(void) {
+ return(&xmlSecGnuTLSX509CrlListKlass);
+}
+
+static xmlSecPtr
+xmlSecGnuTLSX509CrlListDuplicateItem(xmlSecPtr ptr) {
+ xmlSecAssert2(ptr != NULL, NULL);
+
+ return xmlSecGnuTLSX509CrlDup((gnutls_x509_crl_t)ptr);
+}
+
+static void
+xmlSecGnuTLSX509CrlListDestroyItem(xmlSecPtr ptr) {
+ xmlSecAssert(ptr != NULL);
+
+ gnutls_x509_crl_deinit((gnutls_x509_crl_t)ptr);
+}
+
+static void
+xmlSecGnuTLSX509CrlListDebugDumpItem(xmlSecPtr ptr, FILE* output) {
+ xmlSecAssert(ptr != NULL);
+ xmlSecAssert(output != NULL);
+
+ xmlSecGnuTLSX509CrlDebugDump((gnutls_x509_crl_t)ptr, output);
+}
+
+
+static void
+xmlSecGnuTLSX509CrlListDebugXmlDumpItem(xmlSecPtr ptr, FILE* output) {
+ xmlSecAssert(ptr != NULL);
+ xmlSecAssert(output != NULL);
+
+ xmlSecGnuTLSX509CrlDebugXmlDump((gnutls_x509_crl_t)ptr, output);
+}
+
+/*************************************************************************
+ *
+ * x509 certs utils/helpers
+ *
+ ************************************************************************/
+
+/* HACK: gnutls doesn't have cert duplicate function, so we simply
+ write cert out and then read it back */
+gnutls_x509_crt_t
+xmlSecGnuTLSX509CertDup(gnutls_x509_crt_t src) {
+ xmlChar * buf = NULL;
+ gnutls_x509_crt_t res = NULL;
+
+ xmlSecAssert2(src != NULL, NULL);
+
+ buf = xmlSecGnuTLSX509CertBase64DerWrite(src, 0);
+ if(buf == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSX509CertBase64DerWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return (NULL);
+ }
+
+ res = xmlSecGnuTLSX509CertBase64DerRead(buf);
+ if(res == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSX509CertBase64DerRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlFree(buf);
+ return (NULL);
+ }
+
+ /* done */
+ xmlFree(buf);
+ return (res);
+}
+
+xmlChar *
+xmlSecGnuTLSX509CertGetSubjectDN(gnutls_x509_crt_t cert) {
+ char* buf = NULL;
+ size_t bufSize = 0;
+ int err;
+
+ xmlSecAssert2(cert != NULL, NULL);
+
+ /* get subject size */
+ err = gnutls_x509_crt_get_dn(cert, NULL, &bufSize);
+ if((err != GNUTLS_E_SHORT_MEMORY_BUFFER) || (bufSize <= 0)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_crt_get_dn",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ return(NULL);
+ }
+
+ /* allocate buffer */
+ buf = (char *)xmlMalloc(bufSize + 1);
+ if(buf == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlMalloc",
+ XMLSEC_ERRORS_R_MALLOC_FAILED,
+ "size=%d", (int)bufSize);
+ return(NULL);
+ }
+
+ /* finally write it out */
+ err = gnutls_x509_crt_get_dn(cert, buf, &bufSize);
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_crt_get_dn",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ xmlFree(buf);
+ return(NULL);
+ }
+
+ /* done */
+ return(BAD_CAST buf);
+}
+
+xmlChar *
+xmlSecGnuTLSX509CertGetIssuerDN(gnutls_x509_crt_t cert) {
+ char* buf = NULL;
+ size_t bufSize = 0;
+ int err;
+
+ xmlSecAssert2(cert != NULL, NULL);
+
+ /* get issuer size */
+ err = gnutls_x509_crt_get_issuer_dn(cert, NULL, &bufSize);
+ if((err != GNUTLS_E_SHORT_MEMORY_BUFFER) || (bufSize <= 0)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_crt_get_issuer_dn",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ return(NULL);
+ }
+
+ /* allocate buffer */
+ buf = (char *)xmlMalloc(bufSize + 1);
+ if(buf == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlMalloc",
+ XMLSEC_ERRORS_R_MALLOC_FAILED,
+ "size=%d", (int)bufSize);
+ return(NULL);
+ }
+
+ /* finally write it out */
+ err = gnutls_x509_crt_get_issuer_dn(cert, buf, &bufSize);
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_crt_get_issuer_dn",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ xmlFree(buf);
+ return(NULL);
+ }
+
+ /* done */
+ return(BAD_CAST buf);
+}
+
+xmlChar *
+xmlSecGnuTLSX509CertGetIssuerSerial(gnutls_x509_crt_t cert) {
+ xmlChar * res = NULL;
+ unsigned char* buf = NULL;
+ size_t bufSize = 0;
+ int err;
+
+ xmlSecAssert2(cert != NULL, NULL);
+
+ /* get issuer serial size */
+ err = gnutls_x509_crt_get_serial(cert, NULL, &bufSize);
+ if((err != GNUTLS_E_SHORT_MEMORY_BUFFER) || (bufSize <= 0)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_crt_get_serial",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ return(NULL);
+ }
+
+ /* allocate buffer */
+ buf = (unsigned char *)xmlMalloc(bufSize + 1);
+ if(buf == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlMalloc",
+ XMLSEC_ERRORS_R_MALLOC_FAILED,
+ "size=%d", (int)bufSize);
+ return(NULL);
+ }
+
+ /* write it out */
+ err = gnutls_x509_crt_get_serial(cert, buf, &bufSize);
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_crt_get_serial",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ xmlFree(buf);
+ return(NULL);
+ }
+
+ /* convert to string */
+ res = xmlSecGnuTLSASN1IntegerWrite(buf, bufSize);
+ if(res == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSASN1IntegerWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlFree(buf);
+ return(NULL);
+ }
+
+ /* done */
+ xmlFree(buf);
+ return(res);
+}
+
+xmlChar *
+xmlSecGnuTLSX509CertGetSKI(gnutls_x509_crt_t cert) {
+ xmlChar * res = NULL;
+ xmlSecByte* buf = NULL;
+ size_t bufSize = 0;
+ unsigned int critical = 0;
+ int err;
+
+ xmlSecAssert2(cert != NULL, NULL);
+
+ /* get ski size */
+ err = gnutls_x509_crt_get_subject_key_id(cert, NULL, &bufSize, &critical);
+ if((err != GNUTLS_E_SHORT_MEMORY_BUFFER) || (bufSize <= 0)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_crt_get_subject_key_id",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ return(NULL);
+ }
+
+ /* allocate buffer */
+ buf = (xmlSecByte *)xmlMalloc(bufSize + 1);
+ if(buf == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlMalloc",
+ XMLSEC_ERRORS_R_MALLOC_FAILED,
+ "size=%d", (int)bufSize);
+ return(NULL);
+ }
+
+ /* write it out */
+ err = gnutls_x509_crt_get_subject_key_id(cert, buf, &bufSize, &critical);
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_crt_get_subject_key_id",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ xmlFree(buf);
+ return(NULL);
+ }
+
+ /* convert to string */
+ res = xmlSecBase64Encode(buf, bufSize, 0);
+ if(res == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecBase64Encode",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlFree(buf);
+ return(NULL);
+ }
+
+ /* done */
+ xmlFree(buf);
+ return(res);
+}
+
+
+gnutls_x509_crt_t
+xmlSecGnuTLSX509CertBase64DerRead(xmlChar* buf) {
+ int ret;
+
+ xmlSecAssert2(buf != NULL, NULL);
+
+ /* usual trick with base64 decoding "in-place" */
+ ret = xmlSecBase64Decode(buf, (xmlSecByte*)buf, xmlStrlen(buf));
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecBase64Decode",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+
+ return(xmlSecGnuTLSX509CertRead((const xmlSecByte*)buf, ret, xmlSecKeyDataFormatCertDer));
+}
+
+gnutls_x509_crt_t
+xmlSecGnuTLSX509CertRead(const xmlSecByte* buf, xmlSecSize size, xmlSecKeyDataFormat format) {
+ gnutls_x509_crt_t cert = NULL;
+ gnutls_x509_crt_fmt_t fmt;
+ gnutls_datum_t data;
+ int err;
+
+ xmlSecAssert2(buf != NULL, NULL);
+ xmlSecAssert2(size > 0, NULL);
+
+ /* figure out format */
+ switch(format) {
+ case xmlSecKeyDataFormatPem:
+ case xmlSecKeyDataFormatCertPem:
+ fmt = GNUTLS_X509_FMT_PEM;
+ break;
+ case xmlSecKeyDataFormatDer:
+ case xmlSecKeyDataFormatCertDer:
+ fmt = GNUTLS_X509_FMT_DER;
+ break;
+ default:
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_INVALID_FORMAT,
+ "format=%d", format);
+ return(NULL);
+ }
+
+ /* read cert */
+ err = gnutls_x509_crt_init(&cert);
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_crt_init",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ return(NULL);
+ }
+
+ data.data = (unsigned char*)buf;
+ data.size = size;
+ err = gnutls_x509_crt_import(cert, &data, fmt);
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_crt_import",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ gnutls_x509_crt_deinit(cert);
+ return(NULL);
+ }
+
+ return(cert);
+}
+
+xmlChar*
+xmlSecGnuTLSX509CertBase64DerWrite(gnutls_x509_crt_t cert, int base64LineWrap) {
+ xmlChar * res = NULL;
+ xmlSecByte* buf = NULL;
+ size_t bufSize = 0;
+ int err;
+
+ xmlSecAssert2(cert != NULL, NULL);
+
+ /* get size */
+ err = gnutls_x509_crt_export(cert, GNUTLS_X509_FMT_DER, NULL, &bufSize);
+ if((err != GNUTLS_E_SHORT_MEMORY_BUFFER) || (bufSize <= 0)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_crt_export(GNUTLS_X509_FMT_DER)",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ return(NULL);
+ }
+
+ /* allocate buffer */
+ buf = (xmlSecByte *)xmlMalloc(bufSize + 1);
+ if(buf == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlMalloc",
+ XMLSEC_ERRORS_R_MALLOC_FAILED,
+ "size=%d", (int)bufSize);
+ return(NULL);
+ }
+
+ /* write it out */
+ err = gnutls_x509_crt_export(cert, GNUTLS_X509_FMT_DER, buf, &bufSize);
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_crt_export(GNUTLS_X509_FMT_DER)",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ xmlFree(buf);
+ return(NULL);
+ }
+
+ /* convert to string */
+ res = xmlSecBase64Encode(buf, bufSize, base64LineWrap);
+ if(res == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecBase64Encode",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlFree(buf);
+ return(NULL);
+ }
+
+ /* done */
+ xmlFree(buf);
+ return(res);
+}
+
+void
+xmlSecGnuTLSX509CertDebugDump(gnutls_x509_crt_t cert, FILE* output) {
+ xmlChar * buf;
+
+ xmlSecAssert(cert != NULL);
+ xmlSecAssert(output != NULL);
+
+ buf = xmlSecGnuTLSX509CertGetSubjectDN(cert);
+ if(buf != NULL) {
+ fprintf(output, "==== Subject Name: %s\n", buf);
+ xmlFree(buf);
+ } else {
+ fprintf(output, "==== Subject Name: unknown\n");
+ }
+
+ buf = xmlSecGnuTLSX509CertGetIssuerDN(cert);
+ if(buf != NULL) {
+ fprintf(output, "==== Issuer Name: %s\n", buf);
+ xmlFree(buf);
+ } else {
+ fprintf(output, "==== Issuer Name: unknown\n");
+ }
+
+ buf = xmlSecGnuTLSX509CertGetIssuerSerial(cert);
+ if(buf != NULL) {
+ fprintf(output, "==== Issuer Serial: %s\n", buf);
+ xmlFree(buf);
+ } else {
+ fprintf(output, "==== Issuer Serial: unknown\n");
+ }
+}
+
+void
+xmlSecGnuTLSX509CertDebugXmlDump(gnutls_x509_crt_t cert, FILE* output) {
+ xmlChar * buf;
+
+ xmlSecAssert(cert != NULL);
+ xmlSecAssert(output != NULL);
+
+ buf = xmlSecGnuTLSX509CertGetSubjectDN(cert);
+ if(buf != NULL) {
+ fprintf(output, "<SubjectName>%s</SubjectName>\n", buf);
+ xmlFree(buf);
+ } else {
+ fprintf(output, "<SubjectName>unknown</SubjectName>\n");
+ }
+
+ buf = xmlSecGnuTLSX509CertGetIssuerDN(cert);
+ if(buf != NULL) {
+ fprintf(output, "<IssuerName>%s</IssuerName>\n", buf);
+ xmlFree(buf);
+ } else {
+ fprintf(output, "<IssuerName>unknown</IssuerName>\n");
+ }
+
+ buf = xmlSecGnuTLSX509CertGetIssuerSerial(cert);
+ if(buf != NULL) {
+ fprintf(output, "<SerialNumber>%s</SerialNumber>\n", buf);
+ xmlFree(buf);
+ } else {
+ fprintf(output, "<SerialNumber>unknown</SerialNumber>\n");
+ }
+}
+
+/*************************************************************************
+ *
+ * x509 crls utils/helpers
+ *
+ ************************************************************************/
+
+/* HACK: gnutls doesn't have crl duplicate function, so we simply
+ write crl out and then read it back */
+gnutls_x509_crl_t
+xmlSecGnuTLSX509CrlDup(gnutls_x509_crl_t src) {
+ xmlChar * buf = NULL;
+ gnutls_x509_crl_t res = NULL;
+
+ xmlSecAssert2(src != NULL, NULL);
+
+ buf = xmlSecGnuTLSX509CrlBase64DerWrite(src, 0);
+ if(buf == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSX509CrlBase64DerWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return (NULL);
+ }
+
+ res = xmlSecGnuTLSX509CrlBase64DerRead(buf);
+ if(res == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSX509CrlBase64DerRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlFree(buf);
+ return (NULL);
+ }
+
+ /* done */
+ xmlFree(buf);
+ return (res);
+}
+
+xmlChar *
+xmlSecGnuTLSX509CrlGetIssuerDN(gnutls_x509_crl_t crl) {
+ char* buf = NULL;
+ size_t bufSize = 0;
+ int err;
+
+ xmlSecAssert2(crl != NULL, NULL);
+
+ /* get issuer size */
+ err = gnutls_x509_crl_get_issuer_dn(crl, NULL, &bufSize);
+ if((err != GNUTLS_E_SHORT_MEMORY_BUFFER) || (bufSize <= 0)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_crl_get_issuer_dn",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ return(NULL);
+ }
+
+ /* allocate buffer */
+ buf = (char *)xmlMalloc(bufSize + 1);
+ if(buf == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlMalloc",
+ XMLSEC_ERRORS_R_MALLOC_FAILED,
+ "size=%d", (int)bufSize);
+ return(NULL);
+ }
+
+ /* finally write it out */
+ err = gnutls_x509_crl_get_issuer_dn(crl, buf, &bufSize);
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_crl_get_issuer_dn",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ xmlFree(buf);
+ return(NULL);
+ }
+
+ /* done */
+ return(BAD_CAST buf);
+}
+
+gnutls_x509_crl_t
+xmlSecGnuTLSX509CrlBase64DerRead(xmlChar* buf) {
+ int ret;
+
+ xmlSecAssert2(buf != NULL, NULL);
+
+ /* usual trick with base64 decoding "in-place" */
+ ret = xmlSecBase64Decode(buf, (xmlSecByte*)buf, xmlStrlen(buf));
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecBase64Decode",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+
+ return(xmlSecGnuTLSX509CrlRead((const xmlSecByte*)buf, ret, xmlSecKeyDataFormatCertDer));
+}
+
+gnutls_x509_crl_t
+xmlSecGnuTLSX509CrlRead(const xmlSecByte* buf, xmlSecSize size, xmlSecKeyDataFormat format) {
+ gnutls_x509_crl_t crl = NULL;
+ gnutls_x509_crt_fmt_t fmt;
+ gnutls_datum_t data;
+ int err;
+
+ xmlSecAssert2(buf != NULL, NULL);
+ xmlSecAssert2(size > 0, NULL);
+
+ /* figure out format */
+ switch(format) {
+ case xmlSecKeyDataFormatPem:
+ case xmlSecKeyDataFormatCertPem:
+ fmt = GNUTLS_X509_FMT_PEM;
+ break;
+ case xmlSecKeyDataFormatDer:
+ case xmlSecKeyDataFormatCertDer:
+ fmt = GNUTLS_X509_FMT_DER;
+ break;
+ default:
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_INVALID_FORMAT,
+ "format=%d", format);
+ return(NULL);
+ }
+
+ /* read crl */
+ err = gnutls_x509_crl_init(&crl);
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_crl_init",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ return(NULL);
+ }
+
+ data.data = (unsigned char*)buf;
+ data.size = size;
+ err = gnutls_x509_crl_import(crl, &data, fmt);
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_crl_import",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ gnutls_x509_crl_deinit(crl);
+ return(NULL);
+ }
+
+ return(crl);
+}
+
+xmlChar*
+xmlSecGnuTLSX509CrlBase64DerWrite(gnutls_x509_crl_t crl, int base64LineWrap) {
+ xmlChar * res = NULL;
+ xmlSecByte* buf = NULL;
+ size_t bufSize = 0;
+ int err;
+
+ xmlSecAssert2(crl != NULL, NULL);
+
+ /* get size */
+ err = gnutls_x509_crl_export(crl, GNUTLS_X509_FMT_DER, NULL, &bufSize);
+ if((err != GNUTLS_E_SHORT_MEMORY_BUFFER) || (bufSize <= 0)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_crl_export(GNUTLS_X509_FMT_DER)",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ return(NULL);
+ }
+
+ /* allocate buffer */
+ buf = (xmlSecByte *)xmlMalloc(bufSize + 1);
+ if(buf == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlMalloc",
+ XMLSEC_ERRORS_R_MALLOC_FAILED,
+ "size=%d", (int)bufSize);
+ return(NULL);
+ }
+
+ /* write it out */
+ err = gnutls_x509_crl_export(crl, GNUTLS_X509_FMT_DER, buf, &bufSize);
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_crl_export(GNUTLS_X509_FMT_DER)",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ xmlFree(buf);
+ return(NULL);
+ }
+
+ /* convert to string */
+ res = xmlSecBase64Encode(buf, bufSize, base64LineWrap);
+ if(res == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecBase64Encode",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlFree(buf);
+ return(NULL);
+ }
+
+ /* done */
+ xmlFree(buf);
+ return(res);
+}
+
+void
+xmlSecGnuTLSX509CrlDebugDump(gnutls_x509_crl_t crl, FILE* output) {
+ xmlChar * buf;
+
+ xmlSecAssert(crl != NULL);
+ xmlSecAssert(output != NULL);
+
+ buf = xmlSecGnuTLSX509CrlGetIssuerDN(crl);
+ if(buf != NULL) {
+ fprintf(output, "==== Issuer Name: %s\n", buf);
+ xmlFree(buf);
+ } else {
+ fprintf(output, "==== Issuer Name: unknown\n");
+ }
+}
+
+void
+xmlSecGnuTLSX509CrlDebugXmlDump(gnutls_x509_crl_t crl, FILE* output) {
+ xmlChar * buf;
+
+ xmlSecAssert(crl != NULL);
+ xmlSecAssert(output != NULL);
+
+ buf = xmlSecGnuTLSX509CrlGetIssuerDN(crl);
+ if(buf != NULL) {
+ fprintf(output, "<IssuerName>%s</IssuerName>\n", buf);
+ xmlFree(buf);
+ } else {
+ fprintf(output, "<IssuerName>unknown</IssuerName>\n");
+ }
+}
+
+/*************************************************************************
+ *
+ * Misc. utils/helpers
+ *
+ ************************************************************************/
+xmlChar*
+xmlSecGnuTLSASN1IntegerWrite(const unsigned char * data, size_t len) {
+ xmlChar *res = NULL;
+ int resLen = 64; /* not more than 64 chars */
+ unsigned long long int val = 0;
+ size_t ii = 0;
+ int shift = 0;
+
+ xmlSecAssert2(data != NULL, NULL);
+ xmlSecAssert2(len <= 9, NULL);
+
+ /* HACK : to be fixed after GnuTLS provides a way to read opaque ASN1 integer */
+ for(ii = len; ii > 0; --ii, shift += 8) {
+ val |= ((unsigned long long)data[ii - 1]) << shift;
+ }
+
+ res = (xmlChar*)xmlMalloc(resLen + 1);
+ if(res == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlMalloc",
+ XMLSEC_ERRORS_R_MALLOC_FAILED,
+ "size=%d", (int)resLen);
+ return (NULL);
+ }
+
+ xmlSecStrPrintf(res, resLen, BAD_CAST "%llu", val);
+ return(res);
+}
+
+/*************************************************************************
+ *
+ * pkcs12 utils/helpers
+ *
+ ************************************************************************/
+int
+xmlSecGnuTLSPkcs12LoadMemory(const xmlSecByte* data, xmlSecSize dataSize,
+ const char *pwd,
+ gnutls_x509_privkey_t * priv_key,
+ gnutls_x509_crt_t * key_cert,
+ xmlSecPtrListPtr certsList)
+{
+ gnutls_pkcs12_t pkcs12 = NULL;
+ gnutls_pkcs12_bag_t bag = NULL;
+ gnutls_x509_crt_t cert = NULL;
+ gnutls_datum_t datum;
+ xmlSecSize certsSize;
+ int res = -1;
+ int idx;
+ int err;
+ int ret;
+
+ xmlSecAssert2(data != NULL, -1);
+ xmlSecAssert2(dataSize > 0, -1);
+ xmlSecAssert2(priv_key != NULL, -1);
+ xmlSecAssert2((*priv_key) == NULL, -1);
+ xmlSecAssert2(key_cert!= NULL, -1);
+ xmlSecAssert2((*key_cert) == NULL, -1);
+ xmlSecAssert2(certsList != NULL, -1);
+
+ /* read pkcs12 in internal structure */
+ err = gnutls_pkcs12_init(&pkcs12);
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_pkcs12_init",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ goto done;
+ }
+
+ datum.data = (unsigned char *)data;
+ datum.size = dataSize;
+ err = gnutls_pkcs12_import(pkcs12, &datum, GNUTLS_X509_FMT_DER, 0);
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_pkcs12_import",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ goto done;
+ }
+
+ /* verify */
+ err = gnutls_pkcs12_verify_mac(pkcs12, pwd);
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_pkcs12_verify_mac",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ goto done;
+ }
+
+ /* scan the pkcs structure and find the first private key */
+ for(idx = 0; ; ++idx) {
+ int bag_type;
+ int elements_in_bag;
+ int ii;
+
+ err = gnutls_pkcs12_bag_init(&bag);
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_pkcs12_bag_init",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ goto done;
+ }
+
+ err = gnutls_pkcs12_get_bag(pkcs12, idx, bag);
+ if(err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
+ /* scanned the whole pkcs12, stop */
+ break;
+ } else if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_pkcs12_get_bag",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ goto done;
+ }
+
+ /* check if we need to decrypt the bag */
+ bag_type = gnutls_pkcs12_bag_get_type(bag, 0);
+ if(bag_type < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_pkcs12_bag_get_type",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(bag_type));
+ goto done;
+ }
+ if(bag_type == GNUTLS_BAG_ENCRYPTED) {
+ err = gnutls_pkcs12_bag_decrypt(bag, pwd);
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_pkcs12_bag_decrypt",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ goto done;
+ }
+ }
+
+ /* scan elements in bag */
+ elements_in_bag = gnutls_pkcs12_bag_get_count(bag);
+ if(elements_in_bag < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_pkcs12_bag_get_count",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(bag_type));
+ goto done;
+ }
+ for(ii = 0; ii < elements_in_bag; ++ii) {
+ bag_type = gnutls_pkcs12_bag_get_type(bag, ii);
+ if(bag_type < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_pkcs12_bag_get_type",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(bag_type));
+ goto done;
+ }
+
+ err = gnutls_pkcs12_bag_get_data(bag, ii, &datum);
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_pkcs12_bag_get_data",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ goto done;
+ }
+
+ switch(bag_type) {
+ case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
+ case GNUTLS_BAG_PKCS8_KEY:
+ /* we want only the first private key */
+ if((*priv_key) == NULL) {
+ err = gnutls_x509_privkey_init(priv_key);
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_privkey_init",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ goto done;
+ }
+
+ err = gnutls_x509_privkey_import_pkcs8((*priv_key),
+ &datum, GNUTLS_X509_FMT_DER,
+ pwd,
+ (bag_type == GNUTLS_BAG_PKCS8_KEY) ? GNUTLS_PKCS_PLAIN : 0);
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_privkey_import_pkcs8",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ goto done;
+ }
+ }
+ break;
+ case GNUTLS_BAG_CERTIFICATE:
+ err = gnutls_x509_crt_init(&cert);
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_crt_init",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ goto done;
+ }
+
+ err = gnutls_x509_crt_import(cert, &datum, GNUTLS_X509_FMT_DER);
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_crt_import",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ goto done;
+ }
+
+ ret = xmlSecPtrListAdd(certsList, cert);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecPtrListAdd(certsList)",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+ cert = NULL; /* owned by certsList now */
+ break;
+ default:
+ /* ignore unknown bag element */
+ break;
+ }
+ }
+
+ /* done with bag */
+ gnutls_pkcs12_bag_deinit(bag);
+ bag = NULL;
+ }
+
+ /* check we have private key */
+ if((*priv_key) == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "Private key was not found in pkcs12 object");
+ goto done;
+ }
+
+ /* we will search for key cert using the key id */
+ certsSize = xmlSecPtrListGetSize(certsList);
+ if(certsSize > 0) {
+ size_t cert_id_size = 0;
+ size_t key_id_size = 0;
+ xmlSecByte cert_id[100];
+ xmlSecByte key_id[100];
+ xmlSecSize ii;
+
+ key_id_size = sizeof(key_id);
+ err = gnutls_x509_privkey_get_key_id((*priv_key), 0, key_id, &key_id_size);
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_privkey_get_key_id",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ goto done;
+ }
+ for(ii = 0; ii < certsSize; ++ii) {
+ gnutls_x509_crt_t tmp;
+
+ tmp = xmlSecPtrListGetItem(certsList, ii);
+ if(tmp == NULL) {
+ continue;
+ }
+
+ cert_id_size = sizeof(cert_id);
+ err = gnutls_x509_crt_get_key_id(tmp, 0, cert_id, &cert_id_size);
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_crt_get_key_id",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ goto done;
+ }
+
+ /* if key ids match, then this is THE key cert!!! */
+ if((key_id_size == cert_id_size) && (memcmp(key_id, cert_id, key_id_size) == 0)) {
+ (*key_cert) = xmlSecGnuTLSX509CertDup(tmp);
+ if((*key_cert) == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSX509CertDup",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+
+ break;
+ }
+ }
+
+ /* check we have key cert */
+ if((*key_cert) == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "Certificate for the private key was not found in pkcs12 object");
+ goto done;
+ }
+ }
+
+
+ /* success!!! */
+ res = 0;
+
+done:
+ if(cert != NULL) {
+ gnutls_x509_crt_deinit(cert);
+ }
+ if(bag != NULL) {
+ gnutls_pkcs12_bag_deinit(bag);
+ }
+ if(pkcs12 != NULL) {
+ gnutls_pkcs12_deinit(pkcs12);
+ }
+ return(res);
+}
+
+xmlSecKeyDataPtr
+xmlSecGnuTLSCreateKeyDataAndAdoptPrivKey(gnutls_x509_privkey_t priv_key) {
+ xmlSecKeyDataPtr res = NULL;
+ int key_alg;
+ int ret;
+
+ xmlSecAssert2(priv_key != NULL, NULL);
+
+ /* create key value data */
+ key_alg = gnutls_x509_privkey_get_pk_algorithm(priv_key);
+ if(key_alg < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_privkey_get_pk_algorithm",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(key_alg));
+ return (NULL);
+ }
+ switch(key_alg) {
+#ifndef XMLSEC_NO_RSA
+ case GNUTLS_PK_RSA:
+ res = xmlSecKeyDataCreate(xmlSecGnuTLSKeyDataRsaId);
+ if(res == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyDataCreate",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "xmlSecGnuTLSKeyDataRsaId");
+ return(NULL);
+ }
+
+ ret = xmlSecGnuTLSKeyDataRsaAdoptPrivateKey(res, priv_key);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSKeyDataRsaAdoptPrivateKey",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "xmlSecGnuTLSKeyDataRsaId");
+ xmlSecKeyDataDestroy(res);
+ return(NULL);
+ }
+ break;
+#endif /* XMLSEC_NO_RSA */
+
+#ifndef XMLSEC_NO_DSA
+ case GNUTLS_PK_DSA:
+ res = xmlSecKeyDataCreate(xmlSecGnuTLSKeyDataDsaId);
+ if(res == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyDataCreate",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "xmlSecGnuTLSKeyDataDsaId");
+ return(NULL);
+ }
+
+ ret = xmlSecGnuTLSKeyDataDsaAdoptPrivateKey(res, priv_key);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSKeyDataDsaAdoptPrivateKey",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "xmlSecGnuTLSKeyDataDsaId");
+ xmlSecKeyDataDestroy(res);
+ return(NULL);
+ }
+ break;
+#endif /* XMLSEC_NO_DSA */
+ default:
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_privkey_get_pk_algorithm",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ "Unsupported algorithm %d", (int)key_alg);
+ return(NULL);
+ }
+
+ /* done */
+ return(res);
+}
+
+/*************************************************************************
+ *
+ * LDAP DN parser
+ *
+ ************************************************************************/
+void
+xmlSecGnuTLSDnAttrsInitialize(xmlSecGnuTLSDnAttr * attrs, xmlSecSize attrsSize) {
+ xmlSecAssert(attrs != NULL);
+ xmlSecAssert(attrsSize > 0);
+
+ memset(attrs, 0, attrsSize * sizeof(xmlSecGnuTLSDnAttr));
+}
+
+void
+xmlSecGnuTLSDnAttrsDeinitialize(xmlSecGnuTLSDnAttr * attrs, xmlSecSize attrsSize) {
+ xmlSecSize ii;
+
+ xmlSecAssert(attrs != NULL);
+ xmlSecAssert(attrsSize > 0);
+
+ for(ii = 0; ii < attrsSize; ++ii) {
+ if(attrs[ii].key != NULL) {
+ xmlFree(attrs[ii].key);
+ }
+ if(attrs[ii].value != NULL) {
+ xmlFree(attrs[ii].value);
+ }
+ }
+ memset(attrs, 0, attrsSize * sizeof(xmlSecGnuTLSDnAttr));
+}
+
+const xmlSecGnuTLSDnAttr *
+xmlSecGnuTLSDnAttrrsFind(const xmlSecGnuTLSDnAttr * attrs,
+ xmlSecSize attrsSize,
+ const xmlChar * key)
+{
+ xmlSecSize ii;
+
+ xmlSecAssert2(attrs != NULL, NULL);
+ xmlSecAssert2(attrsSize > 0, NULL);
+ xmlSecAssert2(key != NULL, NULL);
+
+ for(ii = 0; ii < attrsSize; ++ii) {
+ /* simple case */
+ if(xmlStrcasecmp(key, attrs[ii].key) == 0) {
+ return(&(attrs[ii]));
+ }
+
+ /* special case for emailAddress (as usual) */
+ if((xmlStrcasecmp(key, BAD_CAST "emailAddress") == 0) &&
+ (xmlStrcasecmp(attrs[ii].key, BAD_CAST "email") == 0))
+ {
+ return(&(attrs[ii]));
+ }
+ if((xmlStrcasecmp(key, BAD_CAST "email") == 0) &&
+ (xmlStrcasecmp(attrs[ii].key, BAD_CAST "emailAddress") == 0))
+ {
+ return(&(attrs[ii]));
+ }
+ }
+
+ /* not found :( */
+ return(NULL);
+}
+
+int
+xmlSecGnuTLSDnAttrsEqual(const xmlSecGnuTLSDnAttr * ll, xmlSecSize llSize,
+ const xmlSecGnuTLSDnAttr * rr, xmlSecSize rrSize)
+{
+ xmlSecSize llNum = 0;
+ xmlSecSize rrNum = 0;
+ const xmlSecGnuTLSDnAttr * tmp;
+ xmlSecSize ii;
+
+ xmlSecAssert2(ll != NULL, -1);
+ xmlSecAssert2(llSize > 0, -1);
+ xmlSecAssert2(rr != NULL, -1);
+ xmlSecAssert2(rrSize > 0, -1);
+
+ /* compare number of non-nullattributes */
+ for(ii = 0; ii < llSize; ++ii) {
+ if(ll[ii].key != NULL) {
+ ++llNum;
+ }
+ }
+ for(ii = 0; ii < rrSize; ++ii) {
+ if(rr[ii].key != NULL) {
+ ++rrNum;
+ }
+ }
+ if(llNum != rrNum) {
+ return(0);
+ }
+
+ /* make sure that all ll attrs are equal to rr attrs */
+ for(ii = 0; ii < llSize; ++ii) {
+ if(ll[ii].key == NULL) {
+ continue;
+ }
+
+ tmp = xmlSecGnuTLSDnAttrrsFind(rr, rrSize, ll[ii].key);
+ if(tmp == NULL) {
+ return(0); /* attribute was not found */
+ }
+
+ if(!xmlStrEqual(ll[ii].value, tmp->value)) {
+ return(0); /* different values */
+ }
+ }
+
+ /* good!!! */
+ return(1);
+}
+
+/*
+Distinguished name syntax
+
+The formal syntax for a Distinguished Name (DN) is based on RFC 2253.
+The Backus Naur Form (BNF) syntax is defined as follows:
+
+ <name> ::= <name-component> ( <spaced-separator> )
+ | <name-component> <spaced-separator> <name>
+
+ <spaced-separator> ::= <optional-space>
+ <separator>
+ <optional-space>
+
+ <separator> ::= "," | ";"
+
+ <optional-space> ::= ( <CR> ) *( " " )
+
+ <name-component> ::= <attribute>
+ | <attribute> <optional-space> "+"
+ <optional-space> <name-component>
+
+ <attribute> ::= <string>
+ | <key> <optional-space> "=" <optional-space> <string>
+
+ <key> ::= 1*( <keychar> ) | "OID." <oid> | "oid." <oid>
+ <keychar> ::= letters, numbers, and space
+
+ <oid> ::= <digitstring> | <digitstring> "." <oid>
+ <digitstring> ::= 1*<digit>
+ <digit> ::= digits 0-9
+
+ <string> ::= *( <stringchar> | <pair> )
+ | '"' *( <stringchar> | <special> | <pair> ) '"'
+ | "#" <hex>
+
+
+ <special> ::= "," | "=" | <CR> | "+" | "<" | ">"
+ | "#" | ";"
+
+ <pair> ::= "\" ( <special> | "\" | '"')
+ <stringchar> ::= any character except <special> or "\" or '"'
+
+
+ <hex> ::= 2*<hexchar>
+ <hexchar> ::= 0-9, a-f, A-F
+
+A semicolon (;) character can be used to separate RDNs in a distinguished name,
+although the comma (,) character is the typical notation.
+
+White-space characters (spaces) might be present on either side of the comma or
+semicolon. The white-space characters are ignored, and the semicolon is replaced
+with a comma.
+
+In addition, space (' ' ASCII 32) characters may be present either before or
+after a '+' or '='. These space characters are ignored when parsing.
+*/
+enum xmlSecGnuTLSDnParseState {
+ xmlSecGnuTLSDnParseState_BeforeNameComponent = 0,
+ xmlSecGnuTLSDnParseState_Key,
+ xmlSecGnuTLSDnParseState_BeforeString,
+ xmlSecGnuTLSDnParseState_String,
+ xmlSecGnuTLSDnParseState_QuotedString,
+ xmlSecGnuTLSDnParseState_AfterQuotedString
+};
+
+#define XMLSEC_GNUTLS_IS_SPACE(ch) \
+ (((ch) == ' ') || ((ch) == '\n') || ((ch) == '\r'))
+
+int
+xmlSecGnuTLSDnAttrsParse(const xmlChar * dn,
+ xmlSecGnuTLSDnAttr * attrs, xmlSecSize attrsSize)
+{
+ xmlChar * tmp = NULL;
+ xmlChar * p;
+ xmlChar ch;
+ enum xmlSecGnuTLSDnParseState state;
+ int slash;
+ xmlSecSize pos;
+ int res = -1;
+
+ xmlSecAssert2(dn != NULL, -1);
+ xmlSecAssert2(attrs != NULL, -1);
+ xmlSecAssert2(attrsSize > 0, -1);
+
+ /* allocate buffer, we don't need more than string */
+ tmp = (xmlChar *)xmlMalloc(xmlStrlen(dn) + 1);
+ if(tmp == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlMalloc",
+ XMLSEC_ERRORS_R_MALLOC_FAILED,
+ "size=%d", (int)(xmlStrlen(dn) + 1));
+ goto done;
+ }
+
+ /* state machine */
+ state = xmlSecGnuTLSDnParseState_BeforeNameComponent;
+ slash = 0;
+ pos = 0;
+ p = tmp;
+ for(ch = (*dn); ; ch = *(++dn)) {
+ switch(state) {
+ case xmlSecGnuTLSDnParseState_BeforeNameComponent:
+ if(!XMLSEC_GNUTLS_IS_SPACE(ch)) {
+ *(p++) = ch; /* we are sure we have enough buffer */
+ state = xmlSecGnuTLSDnParseState_Key;
+ } else {
+ /* just skip space */
+ }
+ break;
+ case xmlSecGnuTLSDnParseState_Key:
+ /* we don't support
+ 1) <attribute><optional-space>"+"<optional-space><name-component>
+ 2) <attribute> ::= <string>
+ */
+ if(ch != '=') {
+ *(p++) = ch; /* we are sure we have enough buffer */
+ } else {
+ *(p) = '\0';
+ /* remove spaces back */
+ while((p > tmp) && (XMLSEC_GNUTLS_IS_SPACE(*(p - 1)))) {
+ *(--p) = '\0';
+ }
+
+ /* insert into the attrs */
+ if(pos >= attrsSize) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "Not enough space: size=%d", (int)attrsSize);
+ goto done;
+ }
+ attrs[pos].key = xmlStrdup(tmp);
+ if(attrs[pos].key == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlStrdup",
+ XMLSEC_ERRORS_R_MALLOC_FAILED,
+ "size=%d", (int)(xmlStrlen(tmp) + 1));
+ goto done;
+ }
+
+ state = xmlSecGnuTLSDnParseState_BeforeString;
+ p = tmp;
+ }
+ break;
+ case xmlSecGnuTLSDnParseState_BeforeString:
+ if(!XMLSEC_GNUTLS_IS_SPACE(ch)) {
+ if(ch != '\"') {
+ state = xmlSecGnuTLSDnParseState_String;
+ slash = 0;
+ --dn; /* small hack, so we can look at the same char
+ again with the correct state */
+ } else {
+ state = xmlSecGnuTLSDnParseState_QuotedString;
+ slash = 0;
+ }
+ } else {
+ /* just skip space */
+ }
+ break;
+ case xmlSecGnuTLSDnParseState_String:
+ if(slash == 1) {
+ *(p++) = ch; /* we are sure we have enough buffer */
+ slash = 0;
+ } else if(ch == '\\') {
+ slash = 1;
+ } else if((ch == ',') || (ch == ';') || (ch == '\0')) {
+ *(p) = '\0';
+ /* remove spaces back */
+ while((p > tmp) && (XMLSEC_GNUTLS_IS_SPACE(*(p - 1)))) {
+ *(--p) = '\0';
+ }
+
+ attrs[pos].value = xmlStrdup(tmp);
+ if(attrs[pos].value == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlStrdup",
+ XMLSEC_ERRORS_R_MALLOC_FAILED,
+ "size=%d", (int)(xmlStrlen(tmp) + 1));
+ goto done;
+ }
+ state = xmlSecGnuTLSDnParseState_BeforeNameComponent;
+ ++pos;
+ p = tmp;
+ } else {
+ *(p++) = ch; /* we are sure we have enough buffer */
+ }
+ break;
+ case xmlSecGnuTLSDnParseState_QuotedString:
+ if(slash == 1) {
+ *(p++) = ch; /* we are sure we have enough buffer */
+ slash = 0;
+ } else if(ch == '\\') {
+ slash = 1;
+ } else if(ch == '\"') {
+ *(p) = '\0';
+ /* don't remove spaces for quoted string */
+
+ attrs[pos].value = xmlStrdup(tmp);
+ if(attrs[pos].value == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlStrdup",
+ XMLSEC_ERRORS_R_MALLOC_FAILED,
+ "size=%d", (int)(xmlStrlen(tmp) + 1));
+ goto done;
+ }
+ state = xmlSecGnuTLSDnParseState_AfterQuotedString;
+ ++pos;
+ p = tmp;
+ } else {
+ *(p++) = ch; /* we are sure we have enough buffer */
+ }
+ break;
+ case xmlSecGnuTLSDnParseState_AfterQuotedString:
+ if(!XMLSEC_GNUTLS_IS_SPACE(ch)) {
+ if((ch == ',') || (ch == ';') || (ch == '\0')) {
+ state = xmlSecGnuTLSDnParseState_BeforeNameComponent;
+ } else {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "Unexpected character %c (expected space or ',' or ';')",
+ ch);
+ goto done;
+ }
+ } else {
+ /* just skip space */
+ }
+ break;
+ }
+
+ if(ch == '\0') {
+ /* done */
+ break;
+ }
+ }
+
+ /* check end state */
+ if(state != xmlSecGnuTLSDnParseState_BeforeNameComponent) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "Unexpected state %d at the end of parsing",
+ (int)state);
+ goto done;
+ }
+
+ /* debug
+ {
+ xmlSecSize ii;
+ for(ii = 0; ii < attrsSize; ++ii) {
+ if(attrs[ii].key != NULL) {
+ printf("DEBUG: attrs - %s=>%s\n", attrs[ii].key, attrs[ii].value);
+ }
+ }
+ }
+ */
+
+ /* done */
+ res = 0;
+
+done:
+ if(tmp != NULL) {
+ xmlFree(tmp);
+ }
+ return(res);
+}
+
+
+#endif /* XMLSEC_NO_X509 */
+
+
+
diff --git a/src/gnutls/x509utils.h b/src/gnutls/x509utils.h
new file mode 100644
index 00000000..b939b248
--- /dev/null
+++ b/src/gnutls/x509utils.h
@@ -0,0 +1,143 @@
+/*
+ * XML Security Library
+ *
+ * THIS IS A PRIVATE XMLSEC HEADER FILE
+ * DON'T USE IT IN YOUR APPLICATION
+ *
+ * This is free software; see Copyright file in the source
+ * distribution for preciese wording.
+ *
+ * Copyright (C) 2010 Aleksey Sanin <aleksey@aleksey.com>
+ */
+#ifndef __XMLSEC_GNUTLS_X509UTILS_H__
+#define __XMLSEC_GNUTLS_X509UTILS_H__
+
+#ifndef XMLSEC_PRIVATE
+#error "gnutls/x509utils.h file contains private xmlsec definitions and should not be used outside xmlsec or xmlsec-<crypto> libraries"
+#endif /* XMLSEC_PRIVATE */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#ifndef XMLSEC_NO_X509
+
+/**************************************************************************
+ *
+ * X509 certs list
+ *
+ *****************************************************************************/
+#define xmlSecGnuTLSX509CrtListId \
+ xmlSecGnuTLSX509CrtListGetKlass()
+xmlSecPtrListId xmlSecGnuTLSX509CrtListGetKlass (void);
+
+/**************************************************************************
+ *
+ * X509 crls list
+ *
+ *****************************************************************************/
+#define xmlSecGnuTLSX509CrlListId \
+ xmlSecGnuTLSX509CrlListGetKlass()
+xmlSecPtrListId xmlSecGnuTLSX509CrlListGetKlass (void);
+
+/*************************************************************************
+ *
+ * x509 certs utils/helpers
+ *
+ ************************************************************************/
+gnutls_x509_crt_t xmlSecGnuTLSX509CertDup (gnutls_x509_crt_t src);
+xmlChar * xmlSecGnuTLSX509CertGetSubjectDN (gnutls_x509_crt_t cert);
+xmlChar * xmlSecGnuTLSX509CertGetIssuerDN (gnutls_x509_crt_t cert);
+xmlChar * xmlSecGnuTLSX509CertGetIssuerSerial (gnutls_x509_crt_t cert);
+xmlChar * xmlSecGnuTLSX509CertGetSKI (gnutls_x509_crt_t cert);
+gnutls_x509_crt_t xmlSecGnuTLSX509CertRead (const xmlSecByte* buf,
+ xmlSecSize size,
+ xmlSecKeyDataFormat format);
+gnutls_x509_crt_t xmlSecGnuTLSX509CertBase64DerRead (xmlChar* buf);
+xmlChar* xmlSecGnuTLSX509CertBase64DerWrite (gnutls_x509_crt_t cert,
+ int base64LineWrap);
+void xmlSecGnuTLSX509CertDebugDump (gnutls_x509_crt_t cert,
+ FILE* output);
+void xmlSecGnuTLSX509CertDebugXmlDump (gnutls_x509_crt_t cert,
+ FILE* output);
+
+/*************************************************************************
+ *
+ * x509 crls utils/helpers
+ *
+ ************************************************************************/
+gnutls_x509_crl_t xmlSecGnuTLSX509CrlDup (gnutls_x509_crl_t src);
+xmlChar * xmlSecGnuTLSX509CrLGetIssuerDN (gnutls_x509_crl_t crl);
+gnutls_x509_crl_t xmlSecGnuTLSX509CrlRead (const xmlSecByte* buf,
+ xmlSecSize size,
+ xmlSecKeyDataFormat format);
+gnutls_x509_crl_t xmlSecGnuTLSX509CrlBase64DerRead (xmlChar* buf);
+xmlChar* xmlSecGnuTLSX509CrlBase64DerWrite (gnutls_x509_crl_t crl,
+ int base64LineWrap);
+void xmlSecGnuTLSX509CrlDebugDump (gnutls_x509_crl_t crl,
+ FILE* output);
+void xmlSecGnuTLSX509CrlDebugXmlDump (gnutls_x509_crl_t crl,
+ FILE* output);
+
+/*************************************************************************
+ *
+ * Misc. utils/helpers
+ *
+ ************************************************************************/
+xmlChar* xmlSecGnuTLSASN1IntegerWrite (const unsigned char * data,
+ size_t len);
+
+
+
+/*************************************************************************
+ *
+ * pkcs12 utils/helpers
+ *
+ ************************************************************************/
+int xmlSecGnuTLSPkcs12LoadMemory (const xmlSecByte* data,
+ xmlSecSize dataSize,
+ const char *pwd,
+ gnutls_x509_privkey_t * priv_key,
+ gnutls_x509_crt_t * key_cert,
+ xmlSecPtrListPtr certsList);
+
+/*************************************************************************
+ *
+ * keydata utils/helpers
+ *
+ ************************************************************************/
+xmlSecKeyDataPtr xmlSecGnuTLSCreateKeyDataAndAdoptPrivKey(gnutls_x509_privkey_t priv_key);
+
+
+/*************************************************************************
+ *
+ * LDAP DN parser
+ *
+ ************************************************************************/
+typedef struct _xmlSecGnuTLSDnAttr {
+ xmlChar * key;
+ xmlChar * value;
+} xmlSecGnuTLSDnAttr;
+
+void xmlSecGnuTLSDnAttrsInitialize (xmlSecGnuTLSDnAttr * attrs,
+ xmlSecSize attrsSize);
+void xmlSecGnuTLSDnAttrsDeinitialize (xmlSecGnuTLSDnAttr * attrs,
+ xmlSecSize attrsSize);
+const xmlSecGnuTLSDnAttr * xmlSecGnuTLSDnAttrrsFind (const xmlSecGnuTLSDnAttr * attrs,
+ xmlSecSize attrsSize,
+ const xmlChar * key);
+int xmlSecGnuTLSDnAttrsEqual (const xmlSecGnuTLSDnAttr * ll,
+ xmlSecSize llSize,
+ const xmlSecGnuTLSDnAttr * rr,
+ xmlSecSize rrSize);
+int xmlSecGnuTLSDnAttrsParse (const xmlChar * dn,
+ xmlSecGnuTLSDnAttr * attrs,
+ xmlSecSize attrsSize);
+#endif /* XMLSEC_NO_X509 */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* ! __XMLSEC_GNUTLS_X509UTILS_H__ */
diff --git a/src/gnutls/x509vfy.c b/src/gnutls/x509vfy.c
new file mode 100644
index 00000000..fd15c5ac
--- /dev/null
+++ b/src/gnutls/x509vfy.c
@@ -0,0 +1,802 @@
+/**
+ * XMLSec library
+ *
+ * X509 support
+ *
+ *
+ * This is free software; see Copyright file in the source
+ * distribution for preciese wording.
+ *
+ * Copyright (C) 2010 Aleksey Sanin <aleksey@aleksey.com>
+ */
+#include "globals.h"
+
+#ifndef XMLSEC_NO_X509
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include <libxml/tree.h>
+
+#include <xmlsec/xmlsec.h>
+#include <xmlsec/xmltree.h>
+#include <xmlsec/keys.h>
+#include <xmlsec/keyinfo.h>
+#include <xmlsec/keysmngr.h>
+#include <xmlsec/base64.h>
+#include <xmlsec/errors.h>
+
+#include <xmlsec/gnutls/crypto.h>
+#include <xmlsec/gnutls/x509.h>
+
+#include "x509utils.h"
+
+/**************************************************************************
+ *
+ * Internal GnuTLS X509 store CTX
+ *
+ *************************************************************************/
+typedef struct _xmlSecGnuTLSX509StoreCtx xmlSecGnuTLSX509StoreCtx,
+ *xmlSecGnuTLSX509StoreCtxPtr;
+struct _xmlSecGnuTLSX509StoreCtx {
+ xmlSecPtrList certsTrusted;
+ xmlSecPtrList certsUntrusted;
+};
+
+/****************************************************************************
+ *
+ * xmlSecGnuTLSKeyDataStoreX509Id:
+ *
+ * xmlSecGnuTLSX509StoreCtx is located after xmlSecTransform
+ *
+ ***************************************************************************/
+#define xmlSecGnuTLSX509StoreGetCtx(store) \
+ ((xmlSecGnuTLSX509StoreCtxPtr)(((xmlSecByte*)(store)) + \
+ sizeof(xmlSecKeyDataStoreKlass)))
+#define xmlSecGnuTLSX509StoreSize \
+ (sizeof(xmlSecKeyDataStoreKlass) + sizeof(xmlSecGnuTLSX509StoreCtx))
+
+static int xmlSecGnuTLSX509StoreInitialize (xmlSecKeyDataStorePtr store);
+static void xmlSecGnuTLSX509StoreFinalize (xmlSecKeyDataStorePtr store);
+
+static xmlSecKeyDataStoreKlass xmlSecGnuTLSX509StoreKlass = {
+ sizeof(xmlSecKeyDataStoreKlass),
+ xmlSecGnuTLSX509StoreSize,
+
+ /* data */
+ xmlSecNameX509Store, /* const xmlChar* name; */
+
+ /* constructors/destructor */
+ xmlSecGnuTLSX509StoreInitialize, /* xmlSecKeyDataStoreInitializeMethod initialize; */
+ xmlSecGnuTLSX509StoreFinalize, /* xmlSecKeyDataStoreFinalizeMethod finalize; */
+
+ /* reserved for the future */
+ NULL, /* void* reserved0; */
+ NULL, /* void* reserved1; */
+};
+
+static gnutls_x509_crt_t xmlSecGnuTLSX509FindCert (xmlSecPtrListPtr certs,
+ const xmlChar *subjectName,
+ const xmlChar *issuerName,
+ const xmlChar *issuerSerial,
+ const xmlChar *ski);
+static gnutls_x509_crt_t xmlSecGnuTLSX509FindSignedCert (xmlSecPtrListPtr certs,
+ gnutls_x509_crt_t cert);
+static gnutls_x509_crt_t xmlSecGnuTLSX509FindSignerCert (xmlSecPtrListPtr certs,
+ gnutls_x509_crt_t cert);
+
+
+/**
+ * xmlSecGnuTLSX509StoreGetKlass:
+ *
+ * The GnuTLS X509 certificates key data store klass.
+ *
+ * Returns: pointer to GnuTLS X509 certificates key data store klass.
+ */
+xmlSecKeyDataStoreId
+xmlSecGnuTLSX509StoreGetKlass(void) {
+ return(&xmlSecGnuTLSX509StoreKlass);
+}
+
+/**
+ * xmlSecGnuTLSX509StoreFindCert:
+ * @store: the pointer to X509 key data store klass.
+ * @subjectName: the desired certificate name.
+ * @issuerName: the desired certificate issuer name.
+ * @issuerSerial: the desired certificate issuer serial number.
+ * @ski: the desired certificate SKI.
+ * @keyInfoCtx: the pointer to <dsig:KeyInfo/> element processing context.
+ *
+ * Searches @store for a certificate that matches given criteria.
+ *
+ * Returns: pointer to found certificate or NULL if certificate is not found
+ * or an error occurs.
+ */
+gnutls_x509_crt_t
+xmlSecGnuTLSX509StoreFindCert(xmlSecKeyDataStorePtr store,
+ const xmlChar *subjectName,
+ const xmlChar *issuerName,
+ const xmlChar *issuerSerial,
+ const xmlChar *ski,
+ const xmlSecKeyInfoCtx* keyInfoCtx) {
+ xmlSecGnuTLSX509StoreCtxPtr ctx;
+ gnutls_x509_crt_t res = NULL;
+
+ xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecGnuTLSX509StoreId), NULL);
+ xmlSecAssert2(keyInfoCtx != NULL, NULL);
+
+ ctx = xmlSecGnuTLSX509StoreGetCtx(store);
+ xmlSecAssert2(ctx != NULL, NULL);
+
+ if(res == NULL) {
+ res = xmlSecGnuTLSX509FindCert(&(ctx->certsTrusted), subjectName, issuerName, issuerSerial, ski);
+ }
+ if(res == NULL) {
+ res = xmlSecGnuTLSX509FindCert(&(ctx->certsUntrusted), subjectName, issuerName, issuerSerial, ski);
+ }
+ return(res);
+}
+
+static int
+xmlSecGnuTLSX509CheckTime(const gnutls_x509_crt_t * cert_list,
+ xmlSecSize cert_list_length,
+ time_t ts)
+{
+ time_t notValidBefore, notValidAfter;
+ xmlSecSize ii;
+
+ xmlSecAssert2(cert_list != NULL, -1);
+
+ for(ii = 0; ii < cert_list_length; ++ii) {
+ const gnutls_x509_crt_t cert = cert_list[ii];
+ if(cert == NULL) {
+ continue;
+ }
+
+ /* get expiration times */
+ notValidBefore = gnutls_x509_crt_get_activation_time(cert);
+ if(notValidBefore == (time_t)-1) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_crt_get_activation_time",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ notValidAfter = gnutls_x509_crt_get_expiration_time(cert);
+ if(notValidAfter == (time_t)-1) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_crt_get_expiration_time",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* check */
+ if(ts < notValidBefore) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_CERT_NOT_YET_VALID,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(0);
+ }
+ if(ts > notValidAfter) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_CERT_HAS_EXPIRED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(0);
+ }
+ }
+
+ /* GOOD! */
+ return(1);
+}
+
+/**
+ * xmlSecGnuTLSX509StoreVerify:
+ * @store: the pointer to X509 key data store klass.
+ * @certs: the untrusted certificates.
+ * @crls: the crls.
+ * @keyInfoCtx: the pointer to <dsig:KeyInfo/> element processing context.
+ *
+ * Verifies @certs list.
+ *
+ * Returns: pointer to the first verified certificate from @certs.
+ */
+gnutls_x509_crt_t
+xmlSecGnuTLSX509StoreVerify(xmlSecKeyDataStorePtr store,
+ xmlSecPtrListPtr certs,
+ xmlSecPtrListPtr crls,
+ const xmlSecKeyInfoCtx* keyInfoCtx) {
+ xmlSecGnuTLSX509StoreCtxPtr ctx;
+ gnutls_x509_crt_t res = NULL;
+ xmlSecSize certs_size = 0;
+ gnutls_x509_crt_t * cert_list = NULL;
+ xmlSecSize cert_list_length;
+ gnutls_x509_crl_t * crl_list = NULL;
+ xmlSecSize crl_list_length;
+ gnutls_x509_crt_t * ca_list = NULL;
+ xmlSecSize ca_list_length;
+ time_t verification_time;
+ unsigned int flags = 0;
+ xmlSecSize ii;
+ int ret;
+ int err;
+
+ xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecGnuTLSX509StoreId), NULL);
+ xmlSecAssert2(certs != NULL, NULL);
+ xmlSecAssert2(crls != NULL, NULL);
+ xmlSecAssert2(keyInfoCtx != NULL, NULL);
+
+ certs_size = xmlSecPtrListGetSize(certs);
+ if(certs_size <= 0) {
+ /* nothing to do */
+ return(NULL);
+ }
+
+ ctx = xmlSecGnuTLSX509StoreGetCtx(store);
+ xmlSecAssert2(ctx != NULL, NULL);
+
+ /* Prepare */
+ cert_list_length = certs_size + xmlSecPtrListGetSize(&(ctx->certsUntrusted));
+ if(cert_list_length > 0) {
+ cert_list = (gnutls_x509_crt_t *)xmlMalloc(sizeof(gnutls_x509_crt_t) * cert_list_length);
+ if(cert_list == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ "xmlMalloc",
+ XMLSEC_ERRORS_R_MALLOC_FAILED,
+ "size=%d", (int)(sizeof(gnutls_x509_crt_t) * cert_list_length));
+ goto done;
+ }
+ }
+ crl_list_length = xmlSecPtrListGetSize(crls);
+ if(crl_list_length > 0) {
+ crl_list = (gnutls_x509_crl_t *)xmlMalloc(sizeof(gnutls_x509_crl_t) * crl_list_length);
+ if(crl_list == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ "xmlMalloc",
+ XMLSEC_ERRORS_R_MALLOC_FAILED,
+ "size=%d", (int)(sizeof(gnutls_x509_crl_t) * crl_list_length));
+ goto done;
+ }
+ for(ii = 0; ii < crl_list_length; ++ii) {
+ crl_list[ii] = xmlSecPtrListGetItem(crls, ii);
+ if(crl_list[ii] == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ "xmlSecPtrListGetItem(crls)",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+ }
+ }
+
+ ca_list_length = xmlSecPtrListGetSize(&(ctx->certsTrusted));
+ if(ca_list_length > 0) {
+ ca_list = (gnutls_x509_crt_t *)xmlMalloc(sizeof(gnutls_x509_crt_t) * ca_list_length);
+ if(ca_list == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ "xmlMalloc",
+ XMLSEC_ERRORS_R_MALLOC_FAILED,
+ "size=%d", (int)(sizeof(gnutls_x509_crt_t) * ca_list_length));
+ goto done;
+ }
+ for(ii = 0; ii < ca_list_length; ++ii) {
+ ca_list[ii] = xmlSecPtrListGetItem(&(ctx->certsTrusted), ii);
+ if(ca_list[ii] == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ "xmlSecPtrListGetItem(certsTrusted)",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+ }
+ }
+
+ /* gnutls doesn't allow to specify "verification" timestamp so
+ we have to do it ourselves */
+ verification_time = (keyInfoCtx->certsVerificationTime > 0) ?
+ keyInfoCtx->certsVerificationTime :
+ time(0);
+ flags |= GNUTLS_VERIFY_DISABLE_TIME_CHECKS;
+
+ if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_X509DATA_SKIP_STRICT_CHECKS) != 0) {
+ flags |= GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2;
+ flags |= GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5;
+ }
+
+ /* We are going to build all possible cert chains and try to verify them */
+ for(ii = 0; (ii < certs_size) && (res == NULL); ++ii) {
+ gnutls_x509_crt_t cert, cert2;
+ xmlSecSize cert_list_cur_length = 0;
+ unsigned int verify = 0;
+
+ cert = xmlSecPtrListGetItem(certs, ii);
+ if(cert == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ "xmlSecPtrListGetItem(certs)",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+
+ /* check if we are the "leaf" node in the certs chain */
+ if(xmlSecGnuTLSX509FindSignedCert(certs, cert) != NULL) {
+ continue;
+ }
+
+ /* build the chain */
+ for(cert2 = cert, cert_list_cur_length = 0;
+ (cert2 != NULL) && (cert_list_cur_length < cert_list_length);
+ ++cert_list_cur_length)
+ {
+ gnutls_x509_crt_t tmp;
+
+ /* store */
+ cert_list[cert_list_cur_length] = cert2;
+
+ /* find next */
+ tmp = xmlSecGnuTLSX509FindSignerCert(certs, cert2);
+ if(tmp == NULL) {
+ tmp = xmlSecGnuTLSX509FindSignerCert(&(ctx->certsUntrusted), cert2);
+ }
+ cert2 = tmp;
+ }
+
+ /* try to verify */
+ err = gnutls_x509_crt_list_verify(
+ cert_list, (int)cert_list_cur_length, /* certs chain */
+ ca_list, (int)ca_list_length, /* trusted cas */
+ crl_list, (int)crl_list_length, /* crls */
+ flags, /* flags */
+ &verify);
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_crt_list_verify",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ /* don't stop, continue! */
+ continue;
+ } else if(verify != 0){
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_crt_list_verify",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ "Verification failed: verify=%u", verify);
+ /* don't stop, continue! */
+ continue;
+ }
+
+ /* gnutls doesn't allow to specify "verification" timestamp so
+ we have to do it ourselves */
+ ret = xmlSecGnuTLSX509CheckTime(cert_list, cert_list_cur_length, verification_time);
+ if(ret != 1) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ "Time verification failed");
+ /* don't stop, continue! */
+ continue;
+ }
+
+ /* DONE! */
+ res = cert;
+ }
+
+done:
+ /* cleanup */
+ if(ca_list != NULL) {
+ xmlFree(ca_list);
+ }
+ if(crl_list != NULL) {
+ xmlFree(crl_list);
+ }
+ if(cert_list != NULL) {
+ xmlFree(cert_list);
+ }
+
+ return(res);
+}
+
+/**
+ * xmlSecGnuTLSX509StoreAdoptCert:
+ * @store: the pointer to X509 key data store klass.
+ * @cert: the pointer to GnuTLS X509 certificate.
+ * @type: the certificate type (trusted/untrusted).
+ *
+ * Adds trusted (root) or untrusted certificate to the store.
+ *
+ * Returns: 0 on success or a negative value if an error occurs.
+ */
+int
+xmlSecGnuTLSX509StoreAdoptCert(xmlSecKeyDataStorePtr store, gnutls_x509_crt_t cert, xmlSecKeyDataType type) {
+ xmlSecGnuTLSX509StoreCtxPtr ctx;
+ int ret;
+
+ xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecGnuTLSX509StoreId), -1);
+ xmlSecAssert2(cert != NULL, -1);
+
+ ctx = xmlSecGnuTLSX509StoreGetCtx(store);
+ xmlSecAssert2(ctx != NULL, -1);
+
+ if((type & xmlSecKeyDataTypeTrusted) != 0) {
+ ret = xmlSecPtrListAdd(&(ctx->certsTrusted), cert);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ "xmlSecPtrListAdd(trusted)",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ } else {
+ ret = xmlSecPtrListAdd(&(ctx->certsUntrusted), cert);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ "xmlSecPtrListAdd(untrusted)",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ }
+
+ /* done */
+ return(0);
+}
+
+static int
+xmlSecGnuTLSX509StoreInitialize(xmlSecKeyDataStorePtr store) {
+ xmlSecGnuTLSX509StoreCtxPtr ctx;
+ int ret;
+
+ xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecGnuTLSX509StoreId), -1);
+
+ ctx = xmlSecGnuTLSX509StoreGetCtx(store);
+ xmlSecAssert2(ctx != NULL, -1);
+
+ memset(ctx, 0, sizeof(xmlSecGnuTLSX509StoreCtx));
+
+ ret = xmlSecPtrListInitialize(&(ctx->certsTrusted), xmlSecGnuTLSX509CrtListId);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ "xmlSecPtrListInitialize(trusted)",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ ret = xmlSecPtrListInitialize(&(ctx->certsUntrusted), xmlSecGnuTLSX509CrtListId);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
+ "xmlSecPtrListInitialize(untrusted)",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ return(0);
+}
+
+static void
+xmlSecGnuTLSX509StoreFinalize(xmlSecKeyDataStorePtr store) {
+ xmlSecGnuTLSX509StoreCtxPtr ctx;
+ xmlSecAssert(xmlSecKeyDataStoreCheckId(store, xmlSecGnuTLSX509StoreId));
+
+ ctx = xmlSecGnuTLSX509StoreGetCtx(store);
+ xmlSecAssert(ctx != NULL);
+
+ xmlSecPtrListFinalize(&(ctx->certsTrusted));
+ xmlSecPtrListFinalize(&(ctx->certsUntrusted));
+
+ memset(ctx, 0, sizeof(xmlSecGnuTLSX509StoreCtx));
+}
+
+
+/*****************************************************************************
+ *
+ * Low-level x509 functions
+ *
+ *****************************************************************************/
+#define XMLSEC_GNUTLS_DN_ATTRS_SIZE 1024
+static int
+xmlSecGnuTLSX509DnsEqual(const xmlChar * ll, const xmlChar * rr) {
+ xmlSecGnuTLSDnAttr ll_attrs[XMLSEC_GNUTLS_DN_ATTRS_SIZE];
+ xmlSecGnuTLSDnAttr rr_attrs[XMLSEC_GNUTLS_DN_ATTRS_SIZE];
+ int ret;
+ int res = -1;
+
+ xmlSecAssert2(ll != NULL, -1);
+ xmlSecAssert2(rr != NULL, -1);
+
+ /* fast version first */
+ if(xmlStrEqual(ll, rr)) {
+ return(1);
+ }
+
+ /* prepare */
+ xmlSecGnuTLSDnAttrsInitialize(ll_attrs, XMLSEC_GNUTLS_DN_ATTRS_SIZE);
+ xmlSecGnuTLSDnAttrsInitialize(rr_attrs, XMLSEC_GNUTLS_DN_ATTRS_SIZE);
+
+ /* parse */
+ ret = xmlSecGnuTLSDnAttrsParse(ll, ll_attrs, XMLSEC_GNUTLS_DN_ATTRS_SIZE);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSDnAttrsParse(ll)",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+
+ ret = xmlSecGnuTLSDnAttrsParse(rr, rr_attrs, XMLSEC_GNUTLS_DN_ATTRS_SIZE);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSDnAttrsParse(rr)",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+
+ /* compare */
+ ret = xmlSecGnuTLSDnAttrsEqual(ll_attrs, XMLSEC_GNUTLS_DN_ATTRS_SIZE,
+ rr_attrs, XMLSEC_GNUTLS_DN_ATTRS_SIZE);
+ if(ret == 1) {
+ res = 1;
+ } else if(ret == 0) {
+ res = 0;
+ } else {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSDnAttrsEqual",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+
+done:
+ xmlSecGnuTLSDnAttrsDeinitialize(ll_attrs, XMLSEC_GNUTLS_DN_ATTRS_SIZE);
+ xmlSecGnuTLSDnAttrsDeinitialize(rr_attrs, XMLSEC_GNUTLS_DN_ATTRS_SIZE);
+ return(res);
+}
+
+static gnutls_x509_crt_t
+xmlSecGnuTLSX509FindCert(xmlSecPtrListPtr certs,
+ const xmlChar *subjectName,
+ const xmlChar *issuerName,
+ const xmlChar *issuerSerial,
+ const xmlChar *ski) {
+ xmlSecSize ii, sz;
+
+ xmlSecAssert2(certs != NULL, NULL);
+
+ /* todo: this is not the fastest way to search certs */
+ sz = xmlSecPtrListGetSize(certs);
+ for(ii = 0; (ii < sz); ++ii) {
+ gnutls_x509_crt_t cert = xmlSecPtrListGetItem(certs, ii);
+ if(cert == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecPtrListGetItem",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "pos=%i", (int)ii);
+ return(NULL);
+ }
+
+ if(subjectName != NULL) {
+ xmlChar * tmp;
+
+ tmp = xmlSecGnuTLSX509CertGetSubjectDN(cert);
+ if(tmp == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSX509CertGetSubjectDN",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "pos=%i", (int)ii);
+ return(NULL);
+ }
+
+ if(xmlSecGnuTLSX509DnsEqual(subjectName, tmp) == 1) {
+ xmlFree(tmp);
+ return(cert);
+ }
+ xmlFree(tmp);
+ } else if((issuerName != NULL) && (issuerSerial != NULL)) {
+ xmlChar * tmp1;
+ xmlChar * tmp2;
+
+ tmp1 = xmlSecGnuTLSX509CertGetIssuerDN(cert);
+ if(tmp1 == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSX509CertGetIssuerDN",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "pos=%i", (int)ii);
+ return(NULL);
+ }
+
+ tmp2 = xmlSecGnuTLSX509CertGetIssuerSerial(cert);
+ if(tmp2 == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSX509CertGetIssuerSerial",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "pos=%i", (int)ii);
+ xmlFree(tmp1);
+ return(NULL);
+ }
+
+ if((xmlSecGnuTLSX509DnsEqual(issuerName, tmp1) == 1) && xmlStrEqual(issuerSerial, tmp2)) {
+ xmlFree(tmp1);
+ xmlFree(tmp2);
+ return(cert);
+ }
+ xmlFree(tmp1);
+ xmlFree(tmp2);
+ } else if(ski != NULL) {
+ xmlChar * tmp;
+
+ tmp = xmlSecGnuTLSX509CertGetSKI(cert);
+ if(tmp == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSX509CertGetSKI",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "pos=%i", (int)ii);
+ return(NULL);
+ }
+
+ if(xmlStrEqual(ski, tmp)) {
+ xmlFree(tmp);
+ return(cert);
+ }
+ xmlFree(tmp);
+ }
+ }
+
+ return(NULL);
+}
+
+/* signed cert has issuer dn equal to our's subject dn */
+static gnutls_x509_crt_t
+xmlSecGnuTLSX509FindSignedCert(xmlSecPtrListPtr certs, gnutls_x509_crt_t cert) {
+ gnutls_x509_crt_t res = NULL;
+ xmlChar * subject = NULL;
+ xmlSecSize ii, sz;
+
+ xmlSecAssert2(certs != NULL, NULL);
+ xmlSecAssert2(cert != NULL, NULL);
+
+ /* get subject */
+ subject = xmlSecGnuTLSX509CertGetSubjectDN(cert);
+ if(subject == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSX509CertGetSubjectDN",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+
+ /* todo: this is not the fastest way to search certs */
+ sz = xmlSecPtrListGetSize(certs);
+ for(ii = 0; (ii < sz) && (res == NULL); ++ii) {
+ gnutls_x509_crt_t tmp;
+ xmlChar * issuer;
+
+ tmp = xmlSecPtrListGetItem(certs, ii);
+ if(tmp == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecPtrListGetItem",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "pos=%i", (int)ii);
+ goto done;
+ }
+
+ issuer = xmlSecGnuTLSX509CertGetIssuerDN(tmp);
+ if(issuer == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSX509CertGetIssuerDN",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "pos=%i", (int)ii);
+ goto done;
+ }
+
+ /* are we done? */
+ if(xmlSecGnuTLSX509DnsEqual(subject, issuer) == 1) {
+ res = tmp;
+ }
+ xmlFree(issuer);
+ }
+
+done:
+ if(subject != NULL) {
+ xmlFree(subject);
+ }
+ return(res);
+}
+
+/* signer cert has subject dn equal to our's issuer dn */
+static gnutls_x509_crt_t
+xmlSecGnuTLSX509FindSignerCert(xmlSecPtrListPtr certs, gnutls_x509_crt_t cert) {
+ gnutls_x509_crt_t res = NULL;
+ xmlChar * issuer = NULL;
+ xmlSecSize ii, sz;
+
+ xmlSecAssert2(certs != NULL, NULL);
+ xmlSecAssert2(cert != NULL, NULL);
+
+ /* get issuer */
+ issuer = xmlSecGnuTLSX509CertGetIssuerDN(cert);
+ if(issuer == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSX509CertGetIssuerDN",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+
+ /* todo: this is not the fastest way to search certs */
+ sz = xmlSecPtrListGetSize(certs);
+ for(ii = 0; (ii < sz) && (res == NULL); ++ii) {
+ gnutls_x509_crt_t tmp;
+ xmlChar * subject;
+
+ tmp = xmlSecPtrListGetItem(certs, ii);
+ if(tmp == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecPtrListGetItem",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "pos=%i", (int)ii);
+ goto done;
+ }
+
+ subject = xmlSecGnuTLSX509CertGetSubjectDN(tmp);
+ if(subject == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSX509CertGetSubjectDN",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "pos=%i", (int)ii);
+ goto done;
+ }
+
+ /* are we done? */
+ if((xmlSecGnuTLSX509DnsEqual(issuer, subject) == 1)) {
+ res = tmp;
+ }
+ xmlFree(subject);
+ }
+
+done:
+ if(issuer != NULL) {
+ xmlFree(issuer);
+ }
+ return(res);
+}
+
+#endif /* XMLSEC_NO_X509 */
+
+