diff options
Diffstat (limited to 'src/gnutls')
-rw-r--r-- | src/gnutls/Makefile.am | 58 | ||||
-rw-r--r-- | src/gnutls/Makefile.in | 786 | ||||
-rw-r--r-- | src/gnutls/README | 6 | ||||
-rw-r--r-- | src/gnutls/app.c | 998 | ||||
-rw-r--r-- | src/gnutls/asymkeys.c | 455 | ||||
-rw-r--r-- | src/gnutls/ciphers.c | 82 | ||||
-rw-r--r-- | src/gnutls/crypto.c | 351 | ||||
-rw-r--r-- | src/gnutls/digests.c | 112 | ||||
-rw-r--r-- | src/gnutls/globals.h | 31 | ||||
-rw-r--r-- | src/gnutls/hmac.c | 141 | ||||
-rw-r--r-- | src/gnutls/kw_aes.c | 72 | ||||
-rw-r--r-- | src/gnutls/kw_des.c | 51 | ||||
-rw-r--r-- | src/gnutls/signatures.c | 148 | ||||
-rw-r--r-- | src/gnutls/symkeys.c | 125 | ||||
-rw-r--r-- | src/gnutls/x509.c | 1960 | ||||
-rw-r--r-- | src/gnutls/x509utils.c | 1687 | ||||
-rw-r--r-- | src/gnutls/x509utils.h | 143 | ||||
-rw-r--r-- | src/gnutls/x509vfy.c | 802 |
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 */ + + |