diff options
Diffstat (limited to 'apps')
-rw-r--r-- | apps/Makefile.am | 84 | ||||
-rw-r--r-- | apps/Makefile.in | 694 | ||||
-rw-r--r-- | apps/cmdline.c | 355 | ||||
-rw-r--r-- | apps/cmdline.h | 89 | ||||
-rw-r--r-- | apps/crypto.c | 396 | ||||
-rw-r--r-- | apps/crypto.h | 70 | ||||
-rw-r--r-- | apps/xmlsec.c | 3058 |
7 files changed, 4746 insertions, 0 deletions
diff --git a/apps/Makefile.am b/apps/Makefile.am new file mode 100644 index 00000000..278ddf49 --- /dev/null +++ b/apps/Makefile.am @@ -0,0 +1,84 @@ +NULL = + +bin_PROGRAMS = xmlsec1 + +XMLSEC_LIBS = $(top_builddir)/src/libxmlsec1.la + + +# check if we use dynamic loading for xmlsec-crypto or not +if XMLSEC_NO_APPS_CRYPTO_DYNAMIC_LOADING + +CRYPTO_DEPS = \ + $(top_builddir)/src/$(XMLSEC_CRYPTO)/lib$(XMLSEC_CRYPTO_LIB).la \ + $(NULL) + +CRYPTO_INCLUDES = \ + $(XMLSEC_CRYPTO_CFLAGS) \ + $(NULL) + +CRYPTO_LD_FLAGS = \ + $(NULL) + +CRYPTO_LD_ADD = \ + $(XMLSEC_CRYPTO_LIBS) \ + $(CRYPTO_DEPS) \ + $(NULL) + +else + +CRYPTO_DEPS = \ + $(NULL) + +CRYPTO_INCLUDES = \ + -DXMLSEC_CRYPTO_DYNAMIC_LOADING=1 + $(NULL) + +CRYPTO_LD_FLAGS = \ + $(NULL) + +CRYPTO_LD_ADD = \ + $(CRYPTO_DEPS) \ + $(NULL) + +endif + + +INCLUDES = \ + -DXMLSEC_CRYPTO=\"@XMLSEC_CRYPTO@\" \ + -DPACKAGE=\"@PACKAGE@\" \ + -I../include \ + -I$(top_srcdir)/include \ + $(XMLSEC_DEFINES) \ + $(XMLSEC_APP_DEFINES) \ + $(CRYPTO_INCLUDES) \ + $(LIBXSLT_CFLAGS) \ + $(LIBXML_CFLAGS) \ + $(XMLSEC_DL_INCLUDES) \ + $(NULL) + +# xmlsec command line utility +xmlsec1_SOURCES = \ + xmlsec.c \ + crypto.c crypto.h \ + cmdline.c cmdline.h \ + $(NULL) + + +xmlsec1_LDFLAGS = \ + $(CRYPTO_LD_FLAGS) \ + @XMLSEC_STATIC_BINARIES@ \ + $(NULL) + +xmlsec1_LDADD = \ + $(LIBXSLT_LIBS) \ + $(LIBXML_LIBS) \ + $(CRYPTO_LD_ADD) \ + $(XMLSEC_LIBS) \ + $(XMLSEC_DL_LIBS) \ + $(NULL) + +xmlsec1_DEPENDENCIES = \ + $(CRYPTO_DEPS) \ + $(XMLSEC_LIBS) \ + $(NULL) + diff --git a/apps/Makefile.in b/apps/Makefile.in new file mode 100644 index 00000000..82af5089 --- /dev/null +++ b/apps/Makefile.in @@ -0,0 +1,694 @@ +# 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@ +bin_PROGRAMS = xmlsec1$(EXEEXT) +subdir = apps +DIST_COMMON = $(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__installdirs = "$(DESTDIR)$(bindir)" +PROGRAMS = $(bin_PROGRAMS) +am__objects_1 = +am_xmlsec1_OBJECTS = xmlsec.$(OBJEXT) crypto.$(OBJEXT) \ + cmdline.$(OBJEXT) $(am__objects_1) +xmlsec1_OBJECTS = $(am_xmlsec1_OBJECTS) +am__DEPENDENCIES_1 = +@XMLSEC_NO_APPS_CRYPTO_DYNAMIC_LOADING_FALSE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) +@XMLSEC_NO_APPS_CRYPTO_DYNAMIC_LOADING_TRUE@am__DEPENDENCIES_2 = $(top_builddir)/src/$(XMLSEC_CRYPTO)/lib$(XMLSEC_CRYPTO_LIB).la \ +@XMLSEC_NO_APPS_CRYPTO_DYNAMIC_LOADING_TRUE@ $(am__DEPENDENCIES_1) +@XMLSEC_NO_APPS_CRYPTO_DYNAMIC_LOADING_FALSE@am__DEPENDENCIES_3 = $(am__DEPENDENCIES_2) \ +@XMLSEC_NO_APPS_CRYPTO_DYNAMIC_LOADING_FALSE@ $(am__DEPENDENCIES_1) +@XMLSEC_NO_APPS_CRYPTO_DYNAMIC_LOADING_TRUE@am__DEPENDENCIES_3 = $(am__DEPENDENCIES_1) \ +@XMLSEC_NO_APPS_CRYPTO_DYNAMIC_LOADING_TRUE@ $(am__DEPENDENCIES_2) \ +@XMLSEC_NO_APPS_CRYPTO_DYNAMIC_LOADING_TRUE@ $(am__DEPENDENCIES_1) +xmlsec1_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(xmlsec1_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 = $(xmlsec1_SOURCES) +DIST_SOURCES = $(xmlsec1_SOURCES) +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 = $(top_builddir)/src/libxmlsec1.la +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 = +@XMLSEC_NO_APPS_CRYPTO_DYNAMIC_LOADING_FALSE@CRYPTO_DEPS = \ +@XMLSEC_NO_APPS_CRYPTO_DYNAMIC_LOADING_FALSE@ $(NULL) + + +# check if we use dynamic loading for xmlsec-crypto or not +@XMLSEC_NO_APPS_CRYPTO_DYNAMIC_LOADING_TRUE@CRYPTO_DEPS = \ +@XMLSEC_NO_APPS_CRYPTO_DYNAMIC_LOADING_TRUE@ $(top_builddir)/src/$(XMLSEC_CRYPTO)/lib$(XMLSEC_CRYPTO_LIB).la \ +@XMLSEC_NO_APPS_CRYPTO_DYNAMIC_LOADING_TRUE@ $(NULL) + +@XMLSEC_NO_APPS_CRYPTO_DYNAMIC_LOADING_FALSE@CRYPTO_INCLUDES = \ +@XMLSEC_NO_APPS_CRYPTO_DYNAMIC_LOADING_FALSE@ -DXMLSEC_CRYPTO_DYNAMIC_LOADING=1 + +@XMLSEC_NO_APPS_CRYPTO_DYNAMIC_LOADING_TRUE@CRYPTO_INCLUDES = \ +@XMLSEC_NO_APPS_CRYPTO_DYNAMIC_LOADING_TRUE@ $(XMLSEC_CRYPTO_CFLAGS) \ +@XMLSEC_NO_APPS_CRYPTO_DYNAMIC_LOADING_TRUE@ $(NULL) + +@XMLSEC_NO_APPS_CRYPTO_DYNAMIC_LOADING_FALSE@CRYPTO_LD_FLAGS = \ +@XMLSEC_NO_APPS_CRYPTO_DYNAMIC_LOADING_FALSE@ $(NULL) + +@XMLSEC_NO_APPS_CRYPTO_DYNAMIC_LOADING_TRUE@CRYPTO_LD_FLAGS = \ +@XMLSEC_NO_APPS_CRYPTO_DYNAMIC_LOADING_TRUE@ $(NULL) + +@XMLSEC_NO_APPS_CRYPTO_DYNAMIC_LOADING_FALSE@CRYPTO_LD_ADD = \ +@XMLSEC_NO_APPS_CRYPTO_DYNAMIC_LOADING_FALSE@ $(CRYPTO_DEPS) \ +@XMLSEC_NO_APPS_CRYPTO_DYNAMIC_LOADING_FALSE@ $(NULL) + +@XMLSEC_NO_APPS_CRYPTO_DYNAMIC_LOADING_TRUE@CRYPTO_LD_ADD = \ +@XMLSEC_NO_APPS_CRYPTO_DYNAMIC_LOADING_TRUE@ $(XMLSEC_CRYPTO_LIBS) \ +@XMLSEC_NO_APPS_CRYPTO_DYNAMIC_LOADING_TRUE@ $(CRYPTO_DEPS) \ +@XMLSEC_NO_APPS_CRYPTO_DYNAMIC_LOADING_TRUE@ $(NULL) + +INCLUDES = \ + -DXMLSEC_CRYPTO=\"@XMLSEC_CRYPTO@\" \ + -DPACKAGE=\"@PACKAGE@\" \ + -I../include \ + -I$(top_srcdir)/include \ + $(XMLSEC_DEFINES) \ + $(XMLSEC_APP_DEFINES) \ + $(CRYPTO_INCLUDES) \ + $(LIBXSLT_CFLAGS) \ + $(LIBXML_CFLAGS) \ + $(XMLSEC_DL_INCLUDES) \ + $(NULL) + + +# xmlsec command line utility +xmlsec1_SOURCES = \ + xmlsec.c \ + crypto.c crypto.h \ + cmdline.c cmdline.h \ + $(NULL) + +xmlsec1_LDFLAGS = \ + $(CRYPTO_LD_FLAGS) \ + @XMLSEC_STATIC_BINARIES@ \ + $(NULL) + +xmlsec1_LDADD = \ + $(LIBXSLT_LIBS) \ + $(LIBXML_LIBS) \ + $(CRYPTO_LD_ADD) \ + $(XMLSEC_LIBS) \ + $(XMLSEC_DL_LIBS) \ + $(NULL) + +xmlsec1_DEPENDENCIES = \ + $(CRYPTO_DEPS) \ + $(XMLSEC_LIBS) \ + $(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 apps/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu apps/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-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p || test -f $$p1; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +xmlsec1$(EXEEXT): $(xmlsec1_OBJECTS) $(xmlsec1_DEPENDENCIES) + @rm -f xmlsec1$(EXEEXT) + $(xmlsec1_LINK) $(xmlsec1_OBJECTS) $(xmlsec1_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmdline.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypto.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmlsec.Po@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 $@ $< + +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 $(PROGRAMS) +installdirs: + for dir in "$(DESTDIR)$(bindir)"; 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-binPROGRAMS clean-generic 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-binPROGRAMS + +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-binPROGRAMS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ + clean-generic 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-binPROGRAMS install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am \ + uninstall-binPROGRAMS + +@XMLSEC_NO_APPS_CRYPTO_DYNAMIC_LOADING_FALSE@ $(NULL) + +# 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/apps/cmdline.c b/apps/cmdline.c new file mode 100644 index 00000000..b9ecafb5 --- /dev/null +++ b/apps/cmdline.c @@ -0,0 +1,355 @@ +/** + * + * XMLSec library + * + * + * See Copyright for the status of this software. + * + * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com> + */ +#if defined(_MSC_VER) +#define snprintf _snprintf +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <string.h> +#include <assert.h> + +#include "cmdline.h" + +static int xmlSecAppCmdLineMatchParam (const char* argvParam, + const char* paramName, + int canHaveNameString); +static xmlSecAppCmdLineParamPtr xmlSecAppCmdLineParamsListFind (xmlSecAppCmdLineParamPtr* params, + xmlSecAppCmdLineParamTopic topics, + const char* name); +static int xmlSecAppCmdLineParamRead (xmlSecAppCmdLineParamPtr param, + const char** argv, + int argc, + int pos); +static int xmlSecAppCmdLineTimeParamRead (const char* str, + time_t* t); + +int +xmlSecAppCmdLineParamIsSet(xmlSecAppCmdLineParamPtr param) { + return(((param != NULL) && (param->value != NULL)) ? 1 : 0); +} + +const char* +xmlSecAppCmdLineParamGetString(xmlSecAppCmdLineParamPtr param) { + if(param->type != xmlSecAppCmdLineParamTypeString) { + fprintf(stderr, "Error: parameter \"%s\" is not string.\n", param->fullName); + return(NULL); + } + return((param->value != NULL) ? param->value->strValue : NULL); +} + +const char* +xmlSecAppCmdLineParamGetStringList(xmlSecAppCmdLineParamPtr param) { + if(param->type != xmlSecAppCmdLineParamTypeStringList) { + fprintf(stderr, "Error: parameter \"%s\" is not string list.\n", param->fullName); + return(NULL); + } + return((param->value != NULL) ? param->value->strListValue : NULL); +} + +int +xmlSecAppCmdLineParamGetInt(xmlSecAppCmdLineParamPtr param, int def) { + if(param->type != xmlSecAppCmdLineParamTypeNumber) { + fprintf(stderr, "Error: parameter \"%s\" is not integer.\n", param->fullName); + return(def); + } + return((param->value != NULL) ? param->value->intValue : def); +} + +time_t +xmlSecAppCmdLineParamGetTime(xmlSecAppCmdLineParamPtr param, time_t def) { + if(param->type != xmlSecAppCmdLineParamTypeTime) { + fprintf(stderr, "Error: parameter \"%s\" is not time.\n", param->fullName); + return(def); + } + return((param->value != NULL) ? param->value->timeValue : def); +} + +int +xmlSecAppCmdLineParamsListParse(xmlSecAppCmdLineParamPtr* params, + xmlSecAppCmdLineParamTopic topics, + const char** argv, int argc, int pos) { + xmlSecAppCmdLineParamPtr param; + int ii; + int ret; + + assert(params != NULL); + assert(argv != NULL); + + while((pos < argc) && (argv[pos][0] == '-')) { + param = xmlSecAppCmdLineParamsListFind(params, topics, argv[pos]); + if(param == NULL) { + fprintf(stderr, "Error: parameter \"%s\" is not supported or the requested\nfeature might have been disabled during compilation.\n", argv[pos]); + return(-1); + } + + ret = xmlSecAppCmdLineParamRead(param, argv, argc, pos); + if(ret < pos) { + fprintf(stderr, "Error: failed to parse parameter \"%s\".\n", argv[pos]); + return(-1); + } + pos = ret + 1; + } + + /* check that all parameters at the end are filenames */ + for(ii = pos; (ii < argc); ++ii) { + if(argv[ii][0] == '-') { + fprintf(stderr, "Error: filename is expected instead of parameter \"%s\".\n", argv[ii]); + return(-1); + + } + } + + + + return(pos); +} + +void +xmlSecAppCmdLineParamsListClean(xmlSecAppCmdLineParamPtr* params) { + xmlSecAppCmdLineValuePtr tmp; + size_t i; + + assert(params != NULL); + + for(i = 0; params[i] != NULL; ++i) { + while(params[i]->value != NULL) { + tmp = params[i]->value; + params[i]->value = params[i]->value->next; + xmlSecAppCmdLineValueDestroy(tmp); + } + } +} + +void +xmlSecAppCmdLineParamsListPrint(xmlSecAppCmdLineParamPtr* params, + xmlSecAppCmdLineParamTopic topics, + FILE* output) { + size_t i; + + assert(params != NULL); + assert(output != NULL); + + for(i = 0; params[i] != NULL; ++i) { + if(((params[i]->topics & topics) != 0) && (params[i]->help != NULL)) { + fprintf(output, " %s\n", params[i]->help); + } + } +} + +xmlSecAppCmdLineValuePtr +xmlSecAppCmdLineValueCreate(xmlSecAppCmdLineParamPtr param, int pos) { + xmlSecAppCmdLineValuePtr value; + + assert(param != NULL); + value = (xmlSecAppCmdLineValuePtr) malloc(sizeof(xmlSecAppCmdLineValue)); + if(value == NULL) { + fprintf(stderr, "Error: malloc failed (%d bytes).\n", sizeof(xmlSecAppCmdLineValue)); + return(NULL); + } + memset(value, 0, sizeof(xmlSecAppCmdLineValue)); + + value->param = param; + value->pos = pos; + return(value); +} + +void +xmlSecAppCmdLineValueDestroy(xmlSecAppCmdLineValuePtr value) { + assert(value != NULL); + + if(value->strListValue != NULL) { + free((void*)value->strListValue); + } + free(value); +} + +static int +xmlSecAppCmdLineMatchParam(const char* argvParam, const char* paramName, + int canHaveNameString) { + assert(argvParam != NULL); + assert(paramName != NULL); + + if(canHaveNameString != 0) { + int len = strlen(paramName); + + if((strncmp(argvParam, paramName, len) == 0) && + ((argvParam[len] == '\0') || (argvParam[len] == ':'))) { + + return(1); + } + } else if(strcmp(argvParam, paramName) == 0) { + return(1); + } + return(0); +} + +static xmlSecAppCmdLineParamPtr +xmlSecAppCmdLineParamsListFind(xmlSecAppCmdLineParamPtr* params, xmlSecAppCmdLineParamTopic topics, + const char* name) { + size_t i; + int canHaveNameString; + + assert(params != NULL); + assert(name != NULL); + + for(i = 0; params[i] != NULL; ++i) { + if((params[i]->topics & topics) == 0) { + continue; + } + + canHaveNameString = ((params[i]->flags & xmlSecAppCmdLineParamFlagParamNameValue) != 0) ? 1 : 0; + if((params[i]->fullName != NULL) && + (xmlSecAppCmdLineMatchParam(name, params[i]->fullName, canHaveNameString) == 1)) { + + return(params[i]); + } + + if((params[i]->shortName != NULL) && + (xmlSecAppCmdLineMatchParam(name, params[i]->shortName, canHaveNameString) == 1)) { + + return(params[i]); + } + } + + return(NULL); +} + +static int +xmlSecAppCmdLineParamRead(xmlSecAppCmdLineParamPtr param, const char** argv, int argc, int pos) { + xmlSecAppCmdLineValuePtr value; + xmlSecAppCmdLineValuePtr prev = NULL; + char* buf; + + assert(param != NULL); + assert(argv != NULL); + assert(pos < argc); + + /* first find the previous value in the list */ + if((param->flags & xmlSecAppCmdLineParamFlagMultipleValues) != 0) { + prev = param->value; + while((prev != NULL) && (prev->next != NULL)) { + prev = prev->next; + } + } else if(param->value != NULL) { + fprintf(stderr, "Error: only one parameter \"%s\" is allowed.\n", argv[pos]); + return(-1); + } + + /* create new value and add to the list */ + value = xmlSecAppCmdLineValueCreate(param, pos); + if(value == NULL) { + fprintf(stderr, "Error: failed to create value for parameter \"%s\".\n", argv[pos]); + return(-1); + } + if(prev != NULL) { + assert(prev->next == NULL); + prev->next = value; + } else { + param->value = value; + } + + /* if we can have a string value after the name, parse it */ + if((param->flags & xmlSecAppCmdLineParamFlagParamNameValue) != 0) { + value->paramNameValue = strchr(argv[pos], ':'); + if(value->paramNameValue != NULL) { + ++value->paramNameValue; + } + } + + switch(param->type) { + case xmlSecAppCmdLineParamTypeFlag: + /* do nothing */ + break; + case xmlSecAppCmdLineParamTypeString: + if(pos + 1 >= argc) { + fprintf(stderr, "Error: string argument expected for parameter \"%s\".\n", argv[pos]); + return(-1); + } + value->strValue = argv[++pos]; + break; + case xmlSecAppCmdLineParamTypeStringList: + if(pos + 1 >= argc) { + fprintf(stderr, "Error: string list argument expected for parameter \"%s\".\n", argv[pos]); + return(-1); + } + value->strValue = argv[++pos]; + buf = (char*)malloc(strlen(value->strValue) + 2); + if(buf == NULL) { + fprintf(stderr, "Error: failed to allocate memory (%d bytes).\n", strlen(value->strValue) + 2); + return(-1); + } + memset(buf, 0, strlen(value->strValue) + 2); + memcpy(buf, value->strValue, strlen(value->strValue)); + value->strListValue = buf; + while((*buf) != '\0') { + if((*buf) == ',') { + (*buf) = '\0'; + } + ++buf; + } + break; + case xmlSecAppCmdLineParamTypeNumber: + if(pos + 1 >= argc) { + fprintf(stderr, "Error: integer argument expected for parameter \"%s\".\n", argv[pos]); + return(-1); + } + value->strValue = argv[++pos]; + if(sscanf(value->strValue, "%d", &(value->intValue)) != 1) { + fprintf(stderr, "Error: integer argument \"%s\" is invalid.\n", value->strValue); + return(-1); + } + break; + case xmlSecAppCmdLineParamTypeTime: + if(pos + 1 >= argc) { + fprintf(stderr, "Error: time argument expected for parameter \"%s\".\n", argv[pos]); + return(-1); + } + value->strValue = argv[++pos]; + if(xmlSecAppCmdLineTimeParamRead(value->strValue, &(value->timeValue)) < 0) { + fprintf(stderr, "Error: time argument \"%s\" is invalid, expected format is \"YYYY-MM-DD HH:MM:SS\").\n", value->strValue); + return(-1); + } + break; + } + return(pos); +} + +static int +xmlSecAppCmdLineTimeParamRead(const char* str, time_t* t) { + struct tm tm; + int n; + + if((str == NULL) || (t == NULL)) { + return(-1); + } + memset(&tm, 0, sizeof(tm)); + tm.tm_isdst = -1; + + n = sscanf(str, "%4d-%2d-%2d%*c%2d:%2d:%2d", + &tm.tm_year, &tm.tm_mon, &tm.tm_mday, + &tm.tm_hour, &tm.tm_min, &tm.tm_sec); + if((n != 6) || (tm.tm_year < 1900) + || (tm.tm_mon < 1) || (tm.tm_mon > 12) + || (tm.tm_mday < 1) || (tm.tm_mday > 31) + || (tm.tm_hour < 0) || (tm.tm_hour > 23) + || (tm.tm_min < 0) || (tm.tm_min > 59) + || (tm.tm_sec < 0) || (tm.tm_sec > 61)) { + return(-1); + } + + tm.tm_year -= 1900; /* tm relative format year */ + tm.tm_mon -= 1; /* tm relative format month */ + + (*t) = mktime(&tm); + return(0); +} + diff --git a/apps/cmdline.h b/apps/cmdline.h new file mode 100644 index 00000000..9466f972 --- /dev/null +++ b/apps/cmdline.h @@ -0,0 +1,89 @@ +/** + * XMLSec library + * + * Command line parsing routines + * + * See Copyright for the status of this software. + * + * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com> + */ +#ifndef __XMLSEC_APPS_CMDLINE_H__ +#define __XMLSEC_APPS_CMDLINE_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include <time.h> + +typedef struct _xmlSecAppCmdLineParam xmlSecAppCmdLineParam, + *xmlSecAppCmdLineParamPtr; +typedef struct _xmlSecAppCmdLineValue xmlSecAppCmdLineValue, + *xmlSecAppCmdLineValuePtr; +typedef unsigned int xmlSecAppCmdLineParamTopic; + +#define xmlSecAppCmdLineParamFlagNone 0x0000 +#define xmlSecAppCmdLineParamFlagParamNameValue 0x0001 +#define xmlSecAppCmdLineParamFlagMultipleValues 0x0002 + +typedef enum { + xmlSecAppCmdLineParamTypeFlag, + xmlSecAppCmdLineParamTypeString, + xmlSecAppCmdLineParamTypeStringList, + xmlSecAppCmdLineParamTypeNumber, + xmlSecAppCmdLineParamTypeTime +} xmlSecAppCmdLineParamType; + +struct _xmlSecAppCmdLineParam { + xmlSecAppCmdLineParamTopic topics; + const char* fullName; + const char* shortName; + const char* help; + xmlSecAppCmdLineParamType type; + int flags; + xmlSecAppCmdLineValuePtr value; +}; + +int xmlSecAppCmdLineParamIsSet (xmlSecAppCmdLineParamPtr param); +const char* xmlSecAppCmdLineParamGetString (xmlSecAppCmdLineParamPtr param); +const char* xmlSecAppCmdLineParamGetStringList (xmlSecAppCmdLineParamPtr param); +int xmlSecAppCmdLineParamGetInt (xmlSecAppCmdLineParamPtr param, + int def); +time_t xmlSecAppCmdLineParamGetTime (xmlSecAppCmdLineParamPtr param, + time_t def); + +int xmlSecAppCmdLineParamsListParse (xmlSecAppCmdLineParamPtr* params, + xmlSecAppCmdLineParamTopic topcis, + const char** argv, + int argc, + int pos); +void xmlSecAppCmdLineParamsListClean (xmlSecAppCmdLineParamPtr* params); +void xmlSecAppCmdLineParamsListPrint (xmlSecAppCmdLineParamPtr* params, + xmlSecAppCmdLineParamTopic topic, + FILE* output); + +struct _xmlSecAppCmdLineValue { + xmlSecAppCmdLineParamPtr param; + int pos; + const char* paramNameValue; + const char* strValue; + const char* strListValue; + int intValue; + time_t timeValue; + xmlSecAppCmdLineValuePtr next; +}; + + +xmlSecAppCmdLineValuePtr xmlSecAppCmdLineValueCreate (xmlSecAppCmdLineParamPtr param, + int pos); +void xmlSecAppCmdLineValueDestroy (xmlSecAppCmdLineValuePtr value); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __XMLSEC_APPS_CMDLINE_H__ */ + + + diff --git a/apps/crypto.c b/apps/crypto.c new file mode 100644 index 00000000..49dd127c --- /dev/null +++ b/apps/crypto.c @@ -0,0 +1,396 @@ +/** + * + * XMLSec library + * + * + * See Copyright for the status of this software. + * + * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com> + */ +#if defined(_MSC_VER) +#define snprintf _snprintf +#endif + +#include <string.h> + +#include <xmlsec/xmlsec.h> +#include <xmlsec/keys.h> +#include <xmlsec/transforms.h> +#include <xmlsec/errors.h> + +#include "crypto.h" + +int +xmlSecAppCryptoInit(const char* config) { + if(xmlSecCryptoAppInit(config) < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecCryptoAppInit", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + if(xmlSecCryptoInit() < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecCryptoInit", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + return(0); +} + +int +xmlSecAppCryptoShutdown(void) { + if(xmlSecCryptoShutdown() < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecCryptoShutdown", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + if(xmlSecCryptoAppShutdown() < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecCryptoAppShutdown", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + return(0); +} + +int +xmlSecAppCryptoSimpleKeysMngrInit(xmlSecKeysMngrPtr mngr) { + xmlSecAssert2(mngr != NULL, -1); + + return(xmlSecCryptoAppDefaultKeysMngrInit(mngr)); +} + +int +xmlSecAppCryptoSimpleKeysMngrLoad(xmlSecKeysMngrPtr mngr, const char *filename) { + xmlSecAssert2(mngr != NULL, -1); + xmlSecAssert2(filename != NULL, -1); + + return(xmlSecCryptoAppDefaultKeysMngrLoad(mngr, filename)); +} + +int +xmlSecAppCryptoSimpleKeysMngrSave(xmlSecKeysMngrPtr mngr, const char *filename, xmlSecKeyDataType type) { + xmlSecAssert2(mngr != NULL, -1); + xmlSecAssert2(filename != NULL, -1); + + return(xmlSecCryptoAppDefaultKeysMngrSave(mngr, filename, type)); +} + +int +xmlSecAppCryptoSimpleKeysMngrCertLoad(xmlSecKeysMngrPtr mngr, const char *filename, + xmlSecKeyDataFormat format, xmlSecKeyDataType type) { + xmlSecAssert2(mngr != NULL, -1); + xmlSecAssert2(filename != NULL, -1); + +#ifndef XMLSEC_NO_X509 + return(xmlSecCryptoAppKeysMngrCertLoad(mngr, filename, format, type)); +#else /* XMLSEC_NO_X509 */ + return(-1); +#endif /* XMLSEC_NO_X509 */ +} + +int +xmlSecAppCryptoSimpleKeysMngrKeyAndCertsLoad(xmlSecKeysMngrPtr mngr, + const char* files, const char* pwd, + const char* name, + xmlSecKeyDataFormat format) { + xmlSecKeyPtr key; + int ret; + + xmlSecAssert2(mngr != NULL, -1); + xmlSecAssert2(files != NULL, -1); + + /* first is the key file */ + key = xmlSecCryptoAppKeyLoad(files, format, pwd, + xmlSecCryptoAppGetDefaultPwdCallback(), (void*)files); + if(key == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecCryptoAppKeyLoad", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "uri=%s", + xmlSecErrorsSafeString(files)); + return(-1); + } + + if(name != NULL) { + ret = xmlSecKeySetName(key, BAD_CAST name); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeySetName", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "name=%s", + xmlSecErrorsSafeString(name)); + xmlSecKeyDestroy(key); + return(-1); + } + } + +#ifndef XMLSEC_NO_X509 + for(files += strlen(files) + 1; (files[0] != '\0'); files += strlen(files) + 1) { + ret = xmlSecCryptoAppKeyCertLoad(key, files, format); + if(ret < 0){ + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecCryptoAppKeyCertLoad", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "uri=%s", + xmlSecErrorsSafeString(files)); + xmlSecKeyDestroy(key); + return(-1); + } + } +#else /* XMLSEC_NO_X509 */ + files += strlen(files) + 1; + if(files[0] != '\0') { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "x509", + XMLSEC_ERRORS_R_DISABLED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } +#endif /* XMLSEC_NO_X509 */ + + ret = xmlSecCryptoAppDefaultKeysMngrAdoptKey(mngr, key); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecCryptoAppDefaultKeysMngrAdoptKey", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlSecKeyDestroy(key); + return(-1); + } + + return(0); +} + + +int +xmlSecAppCryptoSimpleKeysMngrPkcs12KeyLoad(xmlSecKeysMngrPtr mngr, const char *filename, const char* pwd, const char *name) { + xmlSecKeyPtr key; + int ret; + + xmlSecAssert2(mngr != NULL, -1); + xmlSecAssert2(filename != NULL, -1); + +#ifndef XMLSEC_NO_X509 + key = xmlSecCryptoAppKeyLoad(filename, xmlSecKeyDataFormatPkcs12, pwd, + xmlSecCryptoAppGetDefaultPwdCallback(), (void*)filename); + if(key == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecCryptoAppKeyLoad", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "filename=%s", + xmlSecErrorsSafeString(filename)); + return(-1); + } + + if(name != NULL) { + ret = xmlSecKeySetName(key, BAD_CAST name); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeySetName", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "name=%s", + xmlSecErrorsSafeString(name)); + xmlSecKeyDestroy(key); + return(-1); + } + } + + ret = xmlSecCryptoAppDefaultKeysMngrAdoptKey(mngr, key); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecCryptoAppDefaultKeysMngrAdoptKey", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlSecKeyDestroy(key); + return(-1); + } + + return(0); +#else /* XMLSEC_NO_X509 */ + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "x509", + XMLSEC_ERRORS_R_DISABLED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); +#endif /* XMLSEC_NO_X509 */ +} + +int +xmlSecAppCryptoSimpleKeysMngrBinaryKeyLoad(xmlSecKeysMngrPtr mngr, const char* keyKlass, const char *filename, const char *name) { + xmlSecKeyPtr key; + xmlSecKeyDataId dataId; + int ret; + + xmlSecAssert2(mngr != NULL, -1); + xmlSecAssert2(keyKlass != NULL, -1); + xmlSecAssert2(filename != NULL, -1); + + /* find requested data */ + dataId = xmlSecKeyDataIdListFindByName(xmlSecKeyDataIdsGet(), BAD_CAST keyKlass, + xmlSecKeyDataUsageAny); + if(dataId == xmlSecKeyDataIdUnknown) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeyDataIdListFindByName", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "name=%s", + xmlSecErrorsSafeString(keyKlass)); + return(-1); + } + + key = xmlSecKeyReadBinaryFile(dataId, filename); + if(key == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeyReadBinaryFile", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + ret = xmlSecKeySetName(key, BAD_CAST name); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeySetName", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "name=%s", + xmlSecErrorsSafeString(name)); + xmlSecKeyDestroy(key); + return(-1); + } + + /* finally add it to keys manager */ + ret = xmlSecCryptoAppDefaultKeysMngrAdoptKey(mngr, key); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecCryptoAppDefaultKeysMngrAdoptKey", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlSecKeyDestroy(key); + return(-1); + } + + return(0); +} + + +int +xmlSecAppCryptoSimpleKeysMngrKeyGenerate(xmlSecKeysMngrPtr mngr, const char* keyKlassAndSize, const char* name) { + xmlSecKeyPtr key; + int ret; + + xmlSecAssert2(mngr != NULL, -1); + xmlSecAssert2(keyKlassAndSize != NULL, -1); + + key = xmlSecAppCryptoKeyGenerate(keyKlassAndSize, name, xmlSecKeyDataTypePermanent); + if(key == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecAppCryptoSimpleKeysMngrKeyGenerate", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "name=%s", + xmlSecErrorsSafeString(name)); + return(-1); + } + + ret = xmlSecCryptoAppDefaultKeysMngrAdoptKey(mngr, key); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecCryptoAppDefaultKeysMngrAdoptKey", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlSecKeyDestroy(key); + return(-1); + } + return(0); +} + +xmlSecKeyPtr +xmlSecAppCryptoKeyGenerate(const char* keyKlassAndSize, const char* name, xmlSecKeyDataType type) { + xmlSecKeyPtr key; + char* buf; + char* p; + int size; + int ret; + + xmlSecAssert2(keyKlassAndSize != NULL, NULL); + + buf = (char*) xmlStrdup(BAD_CAST keyKlassAndSize); + if(buf == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + NULL, + XMLSEC_ERRORS_R_STRDUP_FAILED, + "name=%s", + xmlSecErrorsSafeString(name)); + return(NULL); + } + + /* separate key klass and size */ + p = strchr(buf, '-'); + if(p == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + NULL, + XMLSEC_ERRORS_R_INVALID_DATA, + "key size is not specified %s", + xmlSecErrorsSafeString(buf)); + xmlFree(buf); + return(NULL); + } + *(p++) = '\0'; + size = atoi(p); + + key = xmlSecKeyGenerateByName(BAD_CAST buf, size, type); + if(key == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeyGenerate", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "klass=%s;size=%d", + xmlSecErrorsSafeString(buf), + size); + xmlFree(buf); + return(NULL); + } + + ret = xmlSecKeySetName(key, BAD_CAST name); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeySetName", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "name=\"%s\"", + xmlSecErrorsSafeString(name)); + xmlSecKeyDestroy(key); + xmlFree(buf); + return(NULL); + } + + xmlFree(buf); + return(key); +} diff --git a/apps/crypto.h b/apps/crypto.h new file mode 100644 index 00000000..63a94a40 --- /dev/null +++ b/apps/crypto.h @@ -0,0 +1,70 @@ +/** + * XMLSec library + * + * + * See Copyright for the status of this software. + * + * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com> + */ +#ifndef __XMLSEC_APPS_CRYPTO_H__ +#define __XMLSEC_APPS_CRYPTO_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include <libxml/tree.h> +#include <xmlsec/xmlsec.h> +#include <xmlsec/keys.h> +#include <xmlsec/keyinfo.h> +#include <xmlsec/keysmngr.h> +#include <xmlsec/crypto.h> + +int xmlSecAppCryptoInit (const char* config); +int xmlSecAppCryptoShutdown (void); + +xmlSecKeyPtr xmlSecAppCryptoKeyGenerate (const char* keyKlassAndSize, + const char* name, + xmlSecKeyDataType type); + +/***************************************************************************** + * + * Simple keys manager + * + ****************************************************************************/ +int xmlSecAppCryptoSimpleKeysMngrInit (xmlSecKeysMngrPtr mngr); +int xmlSecAppCryptoSimpleKeysMngrLoad (xmlSecKeysMngrPtr mngr, + const char *filename); +int xmlSecAppCryptoSimpleKeysMngrSave (xmlSecKeysMngrPtr mngr, + const char *filename, + xmlSecKeyDataType type); +int xmlSecAppCryptoSimpleKeysMngrCertLoad (xmlSecKeysMngrPtr mngr, + const char *filename, + xmlSecKeyDataFormat format, + xmlSecKeyDataType type); +int xmlSecAppCryptoSimpleKeysMngrKeyAndCertsLoad (xmlSecKeysMngrPtr mngr, + const char *files, + const char* pwd, + const char* name, + xmlSecKeyDataFormat format); +int xmlSecAppCryptoSimpleKeysMngrPkcs12KeyLoad (xmlSecKeysMngrPtr mngr, + const char *filename, + const char* pwd, + const char *name); +int xmlSecAppCryptoSimpleKeysMngrBinaryKeyLoad (xmlSecKeysMngrPtr mngr, + const char* keyKlass, + const char* filename, + const char *name); +int xmlSecAppCryptoSimpleKeysMngrKeyGenerate (xmlSecKeysMngrPtr mngr, + const char* keyKlassAndSize, + const char* name); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __XMLSEC_APPS_CRYPTO_H__ */ + + + diff --git a/apps/xmlsec.c b/apps/xmlsec.c new file mode 100644 index 00000000..d551b5a6 --- /dev/null +++ b/apps/xmlsec.c @@ -0,0 +1,3058 @@ +/** + * XML Security standards test: XMLDSig + * + * See Copyright for the status of this software. + * + * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com> + */ +#include <stdlib.h> +#include <string.h> +#include <time.h> + +#if defined(_MSC_VER) +#define snprintf _snprintf +#endif + +#include <libxml/tree.h> +#include <libxml/xmlmemory.h> +#include <libxml/parser.h> +#include <libxml/xpath.h> +#include <libxml/xpathInternals.h> + +#ifndef XMLSEC_NO_XSLT +#include <libxslt/xslt.h> +#include <libxslt/extensions.h> +#include <libxslt/xsltInternals.h> +#include <libxslt/xsltutils.h> +#include <libxslt/security.h> +#include <libexslt/exslt.h> +#endif /* XMLSEC_NO_XSLT */ + +#include <xmlsec/xmlsec.h> +#include <xmlsec/xmltree.h> +#include <xmlsec/keys.h> +#include <xmlsec/keyinfo.h> +#include <xmlsec/keysmngr.h> +#include <xmlsec/transforms.h> +#include <xmlsec/xmldsig.h> +#include <xmlsec/xmlenc.h> +#include <xmlsec/xkms.h> +#include <xmlsec/parser.h> +#include <xmlsec/templates.h> +#include <xmlsec/errors.h> + +#include "crypto.h" +#include "cmdline.h" + +static const char copyright[] = + "Written by Aleksey Sanin <aleksey@aleksey.com>.\n\n" + "Copyright (C) 2002-2003 Aleksey Sanin.\n" + "This is free software: see the source for copying information.\n"; + +static const char bugs[] = + "Report bugs to http://www.aleksey.com/xmlsec/bugs.html\n"; + +static const char helpCommands1[] = + "Usage: xmlsec <command> [<options>] [<files>]\n" + "\n" + "xmlsec is a command line tool for signing, verifying, encrypting and\n" + "decrypting XML documents. The allowed <command> values are:\n" + " --help " "\tdisplay this help information and exit\n" + " --help-all " "\tdisplay help information for all commands/options and exit\n" + " --help-<cmd>" "\tdisplay help information for command <cmd> and exit\n" + " --version " "\tprint version information and exit\n" + " --keys " "\tkeys XML file manipulation\n"; + +static const char helpCommands2[] = +#ifndef XMLSEC_NO_XMLDSIG + " --sign " "\tsign data and output XML document\n" + " --verify " "\tverify signed document\n" +#ifndef XMLSEC_NO_TMPL_TEST + " --sign-tmpl " "\tcreate and sign dynamicaly generated signature template\n" +#endif /* XMLSEC_NO_TMPL_TEST */ +#endif /* XMLSEC_NO_XMLDSIG */ +#ifndef XMLSEC_NO_XMLENC + " --encrypt " "\tencrypt data and output XML document\n" + " --decrypt " "\tdecrypt data from XML document\n" +#endif /* XMLSEC_NO_XMLENC */ +#ifndef XMLSEC_NO_XKMS + " --xkms-server-request ""\tprocess data as XKMS server request\n" +#endif /* XMLSEC_NO_XKMS */ + ; + +static const char helpVersion[] = + "Usage: xmlsec version\n" + "Prints version information and exits\n"; + +static const char helpKeys[] = + "Usage: xmlsec keys [<options>] <file>\n" + "Creates a new XML keys file <file>\n"; + +static const char helpSign[] = + "Usage: xmlsec sign [<options>] <file>\n" + "Calculates XML Digital Signature using template file <file>\n"; + +static const char helpVerify[] = + "Usage: xmlsec verify [<options>] <file>\n" + "Verifies XML Digital Signature in the <file>\n"; + +static const char helpSignTmpl[] = + "Usage: xmlsec sign-tmpl [<options>]\n" + "Creates a simple dynamic template and calculates XML Digital Signature\n" + "(for testing only).\n"; + +static const char helpEncrypt[] = + "Usage: xmlsec encrypt [<options>] <file>\n" + "Encrypts data and creates XML Encryption using template file <file>\n"; + +static const char helpEncryptTmpl[] = + "Usage: xmlsec encrypt [<options>]\n" + "Creates a simple dynamic template and calculates XML Encryption\n"; + +static const char helpDecrypt[] = + "Usage: xmlsec decrypt [<options>] <file>\n" + "Decrypts XML Encryption data in the <file>\n"; + +static const char helpXkmsServerRequest[] = + "Usage: xmlsec xkms-server-request [<options>] <file>\n" + "Processes the <file> as XKMS server request and outputs the response\n"; + +static const char helpListKeyData[] = + "Usage: xmlsec list-key-data\n" + "Prints the list of known key data klasses\n"; + +static const char helpCheckKeyData[] = + "Usage: xmlsec check-key-data <key-data-name> [<key-data-name> ... ]\n" + "Checks the given key-data against the list of known key-data klasses\n"; + +static const char helpListTransforms[] = + "Usage: xmlsec list-transforms\n" + "Prints the list of known transform klasses\n"; + +static const char helpCheckTransforms[] = + "Usage: xmlsec check-transforms <transform-name> [<transform-name> ... ]\n" + "Checks the given transforms against the list of known transform klasses\n"; + +#define xmlSecAppCmdLineTopicGeneral 0x0001 +#define xmlSecAppCmdLineTopicDSigCommon 0x0002 +#define xmlSecAppCmdLineTopicDSigSign 0x0004 +#define xmlSecAppCmdLineTopicDSigVerify 0x0008 +#define xmlSecAppCmdLineTopicEncCommon 0x0010 +#define xmlSecAppCmdLineTopicEncEncrypt 0x0020 +#define xmlSecAppCmdLineTopicEncDecrypt 0x0040 +#define xmlSecAppCmdLineTopicXkmsCommon 0x0080 +#define xmlSecAppCmdLineTopicKeysMngr 0x1000 +#define xmlSecAppCmdLineTopicX509Certs 0x2000 +#define xmlSecAppCmdLineTopicVersion 0x4000 +#define xmlSecAppCmdLineTopicCryptoConfig 0x8000 +#define xmlSecAppCmdLineTopicAll 0xFFFF + +/**************************************************************** + * + * General configuration params + * + ***************************************************************/ +static xmlSecAppCmdLineParam helpParam = { + xmlSecAppCmdLineTopicGeneral, + "--help", + "-h", + "--help" + "\n\tprint help information about the command", + xmlSecAppCmdLineParamTypeFlag, + xmlSecAppCmdLineParamFlagNone, + NULL +}; + +static xmlSecAppCmdLineParam cryptoParam = { + xmlSecAppCmdLineTopicCryptoConfig, + "--crypto", + NULL, + "--crypto <name>" + "\n\tthe name of the crypto engine to use from the following" + "\n\tlist: openssl, mscrypto, nss, gnutls, gcrypt (if no crypto engine is" + "\n\tspecified then the default one is used)", + xmlSecAppCmdLineParamTypeString, + xmlSecAppCmdLineParamFlagNone, + NULL +}; + +static xmlSecAppCmdLineParam cryptoConfigParam = { + xmlSecAppCmdLineTopicCryptoConfig, + "--crypto-config", + NULL, + "--crypto-config <path>" + "\n\tpath to crypto engine configuration", + xmlSecAppCmdLineParamTypeString, + xmlSecAppCmdLineParamFlagNone, + NULL +}; + + +static xmlSecAppCmdLineParam repeatParam = { + xmlSecAppCmdLineTopicCryptoConfig, + "--repeat", + "-r", + "--repeat <number>" + "\n\trepeat the operation <number> times", + xmlSecAppCmdLineParamTypeNumber, + xmlSecAppCmdLineParamFlagNone, + NULL +}; + + +static xmlSecAppCmdLineParam disableErrorMsgsParam = { + xmlSecAppCmdLineTopicGeneral, + "--disable-error-msgs", + NULL, + "--disable-error-msgs" + "\n\tdo not print xmlsec error messages", + xmlSecAppCmdLineParamTypeFlag, + xmlSecAppCmdLineParamFlagNone, + NULL +}; + +static xmlSecAppCmdLineParam printCryptoErrorMsgsParam = { + xmlSecAppCmdLineTopicGeneral, + "--print-crypto-error-msgs", + NULL, + "--print-crypto-error-msgs" + "\n\tprint errors stack at the end", + xmlSecAppCmdLineParamTypeFlag, + xmlSecAppCmdLineParamFlagNone, + NULL +}; + +/**************************************************************** + * + * Keys Manager params + * + ***************************************************************/ +static xmlSecAppCmdLineParam genKeyParam = { + xmlSecAppCmdLineTopicKeysMngr, + "--gen-key", + "-g", + "--gen-key[:<name>] <keyKlass>-<keySize>" + "\n\tgenerate new <keyKlass> key of <keySize> bits size," + "\n\tset the key name to <name> and add the result to keys" + "\n\tmanager (for example, \"--gen:mykey rsa-1024\" generates" + "\n\ta new 1024 bits RSA key and sets it's name to \"mykey\")", + xmlSecAppCmdLineParamTypeString, + xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, + NULL +}; + +static xmlSecAppCmdLineParam keysFileParam = { + xmlSecAppCmdLineTopicKeysMngr, + "--keys-file", + "-k", + "--keys-file <file>" + "\n\tload keys from XML file", + xmlSecAppCmdLineParamTypeString, + xmlSecAppCmdLineParamFlagMultipleValues, + NULL +}; + +static xmlSecAppCmdLineParam privkeyParam = { + xmlSecAppCmdLineTopicKeysMngr, + "--privkey-pem", + "--privkey", + "--privkey-pem[:<name>] <file>[,<cafile>[,<cafile>[...]]]" + "\n\tload private key from PEM file and certificates" + "\n\tthat verify this key", + xmlSecAppCmdLineParamTypeStringList, + xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, + NULL +}; + +static xmlSecAppCmdLineParam privkeyDerParam = { + xmlSecAppCmdLineTopicKeysMngr, + "--privkey-der", + NULL, + "--privkey-der[:<name>] <file>[,<cafile>[,<cafile>[...]]]" + "\n\tload private key from DER file and certificates" + "\n\tthat verify this key", + xmlSecAppCmdLineParamTypeStringList, + xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, + NULL +}; + +static xmlSecAppCmdLineParam pkcs8PemParam = { + xmlSecAppCmdLineTopicKeysMngr, + "--pkcs8-pem", + "--privkey-p8-pem", + "--pkcs8-pem[:<name>] <file>[,<cafile>[,<cafile>[...]]]" + "\n\tload private key from PKCS8 PEM file and PEM certificates" + "\n\tthat verify this key", + xmlSecAppCmdLineParamTypeStringList, + xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, + NULL +}; + +static xmlSecAppCmdLineParam pkcs8DerParam = { + xmlSecAppCmdLineTopicKeysMngr, + "--pkcs8-der", + "--privkey-p8-der", + "--pkcs8-der[:<name>] <file>[,<cafile>[,<cafile>[...]]]" + "\n\tload private key from PKCS8 DER file and DER certificates" + "\n\tthat verify this key", + xmlSecAppCmdLineParamTypeStringList, + xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, + NULL +}; + +static xmlSecAppCmdLineParam pubkeyParam = { + xmlSecAppCmdLineTopicKeysMngr, + "--pubkey-pem", + "--pubkey", + "--pubkey-pem[:<name>] <file>" + "\n\tload public key from PEM file", + xmlSecAppCmdLineParamTypeStringList, + xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, + NULL +}; + +static xmlSecAppCmdLineParam pubkeyDerParam = { + xmlSecAppCmdLineTopicKeysMngr, + "--pubkey-der", + NULL, + "--pubkey-der[:<name>] <file>" + "\n\tload public key from DER file", + xmlSecAppCmdLineParamTypeStringList, + xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, + NULL +}; + + +#ifndef XMLSEC_NO_AES +static xmlSecAppCmdLineParam aeskeyParam = { + xmlSecAppCmdLineTopicKeysMngr, + "--aeskey", + NULL, + "--aeskey[:<name>] <file>" + "\n\tload AES key from binary file <file>", + xmlSecAppCmdLineParamTypeString, + xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, + NULL +}; +#endif /* XMLSEC_NO_AES */ + +#ifndef XMLSEC_NO_DES +static xmlSecAppCmdLineParam deskeyParam = { + xmlSecAppCmdLineTopicKeysMngr, + "--deskey", + NULL, + "--deskey[:<name>] <file>" + "\n\tload DES key from binary file <file>", + xmlSecAppCmdLineParamTypeString, + xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, + NULL +}; +#endif /* XMLSEC_NO_DES */ + +#ifndef XMLSEC_NO_HMAC +static xmlSecAppCmdLineParam hmackeyParam = { + xmlSecAppCmdLineTopicKeysMngr, + "--hmackey", + NULL, + "--hmackey[:<name>] <file>" + "\n\tload HMAC key from binary file <file>", + xmlSecAppCmdLineParamTypeString, + xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, + NULL +}; +#endif /* XMLSEC_NO_HMAC */ + +static xmlSecAppCmdLineParam pwdParam = { + xmlSecAppCmdLineTopicKeysMngr, + "--pwd", + NULL, + "--pwd <password>" + "\n\tthe password to use for reading keys and certs", + xmlSecAppCmdLineParamTypeString, + xmlSecAppCmdLineParamFlagNone, + NULL +}; + +static xmlSecAppCmdLineParam enabledKeyDataParam = { + xmlSecAppCmdLineTopicKeysMngr, + "--enabled-key-data", + NULL, + "--enabled-key-data <list>" + "\n\tcomma separated list of enabled key data (list of " + "\n\tregistered key data klasses is available with \"--list-key-data\"" + "\n\tcommand); by default, all registered key data are enabled", + xmlSecAppCmdLineParamTypeStringList, + xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, + NULL +}; + +static xmlSecAppCmdLineParam enabledRetrievalMethodUrisParam = { + xmlSecAppCmdLineTopicKeysMngr, + "--enabled-retrieval-method-uris", + NULL, + "--enabled-retrieval-uris <list>" + "\n\tcomma separated list of of the following values:" + "\n\t\"empty\", \"same-doc\", \"local\",\"remote\" to restrict possible URI" + "\n\tattribute values for the <dsig:RetrievalMethod> element.", + xmlSecAppCmdLineParamTypeStringList, + xmlSecAppCmdLineParamFlagNone, + NULL +}; + +/**************************************************************** + * + * Common params + * + ***************************************************************/ +static xmlSecAppCmdLineParam sessionKeyParam = { + xmlSecAppCmdLineTopicDSigSign | xmlSecAppCmdLineTopicEncEncrypt, + "--session-key", + NULL, + "--session-key <keyKlass>-<keySize>" + "\n\tgenerate new session <keyKlass> key of <keySize> bits size" + "\n\t(for example, \"--session des-192\" generates a new 192 bits" + "\n\tDES key for DES3 encryption)", + xmlSecAppCmdLineParamTypeString, + xmlSecAppCmdLineParamFlagNone, + NULL +}; + +static xmlSecAppCmdLineParam outputParam = { + xmlSecAppCmdLineTopicDSigCommon | + xmlSecAppCmdLineTopicEncCommon | + xmlSecAppCmdLineTopicXkmsCommon, + "--output", + "-o", + "--output <filename>" + "\n\twrite result document to file <filename>", + xmlSecAppCmdLineParamTypeString, + xmlSecAppCmdLineParamFlagNone, + NULL +}; + +static xmlSecAppCmdLineParam nodeIdParam = { + xmlSecAppCmdLineTopicDSigCommon | + xmlSecAppCmdLineTopicEncCommon | + xmlSecAppCmdLineTopicXkmsCommon, + "--node-id", + NULL, + "--node-id <id>" + "\n\tset the operation start point to the node with given <id>", + xmlSecAppCmdLineParamTypeString, + xmlSecAppCmdLineParamFlagNone, + NULL +}; + +static xmlSecAppCmdLineParam nodeNameParam = { + xmlSecAppCmdLineTopicDSigCommon | + xmlSecAppCmdLineTopicEncCommon | + xmlSecAppCmdLineTopicXkmsCommon, + "--node-name", + NULL, + "--node-name [<namespace-uri>:]<name>" + "\n\tset the operation start point to the first node" + "\n\twith given <name> and <namespace> URI", + xmlSecAppCmdLineParamTypeString, + xmlSecAppCmdLineParamFlagNone, + NULL +}; + +static xmlSecAppCmdLineParam nodeXPathParam = { + xmlSecAppCmdLineTopicDSigCommon | + xmlSecAppCmdLineTopicEncCommon | + xmlSecAppCmdLineTopicXkmsCommon, + "--node-xpath", + NULL, + "--node-xpath <expr>" + "\n\tset the operation start point to the first node" + "\n\tselected by the specified XPath expression", + xmlSecAppCmdLineParamTypeString, + xmlSecAppCmdLineParamFlagNone, + NULL +}; + +static xmlSecAppCmdLineParam dtdFileParam = { + xmlSecAppCmdLineTopicDSigCommon | + xmlSecAppCmdLineTopicEncCommon | + xmlSecAppCmdLineTopicXkmsCommon, + "--dtd-file", + NULL, + "--dtd-file <file>" + "\n\tload the specified file as the DTD", + xmlSecAppCmdLineParamTypeString, + xmlSecAppCmdLineParamFlagNone, + NULL +}; + +static xmlSecAppCmdLineParam printDebugParam = { + xmlSecAppCmdLineTopicDSigCommon | + xmlSecAppCmdLineTopicEncCommon | + xmlSecAppCmdLineTopicXkmsCommon, + "--print-debug", + NULL, + "--print-debug" + "\n\tprint debug information to stdout", + xmlSecAppCmdLineParamTypeFlag, + xmlSecAppCmdLineParamFlagNone, + NULL +}; + +static xmlSecAppCmdLineParam printXmlDebugParam = { + xmlSecAppCmdLineTopicDSigCommon | + xmlSecAppCmdLineTopicEncCommon | + xmlSecAppCmdLineTopicXkmsCommon, + "--print-xml-debug", + NULL, + "--print-xml-debug" + "\n\tprint debug information to stdout in xml format", + xmlSecAppCmdLineParamTypeFlag, + xmlSecAppCmdLineParamFlagNone, + NULL +}; + +static xmlSecAppCmdLineParam idAttrParam = { + xmlSecAppCmdLineTopicDSigCommon | + xmlSecAppCmdLineTopicEncCommon | + xmlSecAppCmdLineTopicXkmsCommon, + "--id-attr", + NULL, + "--id-attr[:<attr-name>] [<node-namespace-uri>:]<node-name>" + "\n\tadds attributes <attr-name> (default value \"id\") from all nodes" + "\n\twith<node-name> and namespace <node-namespace-uri> to the list of" + "\n\tknown ID attributes; this is a hack and if you can use DTD or schema" + "\n\tto declare ID attributes instead (see \"--dtd-file\" option)," + "\n\tI don't know what else might be broken in your application when" + "\n\tyou use this hack", + xmlSecAppCmdLineParamTypeString, + xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, + NULL +}; + + +/**************************************************************** + * + * Common dsig params + * + ***************************************************************/ +#ifndef XMLSEC_NO_XMLDSIG +static xmlSecAppCmdLineParam ignoreManifestsParam = { + xmlSecAppCmdLineTopicDSigCommon, + "--ignore-manifests", + NULL, + "--ignore-manifests" + "\n\tdo not process <dsig:Manifest> elements", + xmlSecAppCmdLineParamTypeFlag, + xmlSecAppCmdLineParamFlagNone, + NULL +}; + +static xmlSecAppCmdLineParam storeReferencesParam = { + xmlSecAppCmdLineTopicDSigCommon, + "--store-references", + NULL, + "--store-references" + "\n\tstore and print the result of <dsig:Reference/> element processing" + "\n\tjust before calculating digest", + xmlSecAppCmdLineParamTypeFlag, + xmlSecAppCmdLineParamFlagNone, + NULL +}; + +static xmlSecAppCmdLineParam storeSignaturesParam = { + xmlSecAppCmdLineTopicDSigCommon, + "--store-signatures", + NULL, + "--store-signatures" + "\n\tstore and print the result of <dsig:Signature> processing" + "\n\tjust before calculating signature", + xmlSecAppCmdLineParamTypeFlag, + xmlSecAppCmdLineParamFlagNone, + NULL +}; + +static xmlSecAppCmdLineParam enabledRefUrisParam = { + xmlSecAppCmdLineTopicDSigCommon, + "--enabled-reference-uris", + NULL, + "--enabled-reference-uris <list>" + "\n\tcomma separated list of of the following values:" + "\n\t\"empty\", \"same-doc\", \"local\",\"remote\" to restrict possible URI" + "\n\tattribute values for the <dsig:Reference> element", + xmlSecAppCmdLineParamTypeStringList, + xmlSecAppCmdLineParamFlagNone, + NULL +}; + +static xmlSecAppCmdLineParam enableVisa3DHackParam = { + xmlSecAppCmdLineTopicDSigCommon, + "--enable-visa3d-hack", + NULL, + "--enable-visa3d-hack" + "\n\tenables Visa3D protocol specific hack for URI attributes processing" + "\n\twhen we are trying not to use XPath/XPointer engine; this is a hack" + "\n\tand I don't know what else might be broken in your application when" + "\n\tyou use it (also check \"--id-attr\" option because you might need it)", + xmlSecAppCmdLineParamTypeFlag, + xmlSecAppCmdLineParamFlagNone, + NULL +}; + +#endif /* XMLSEC_NO_XMLDSIG */ + +/**************************************************************** + * + * Enc params + * + ***************************************************************/ +#ifndef XMLSEC_NO_XMLENC +static xmlSecAppCmdLineParam enabledCipherRefUrisParam = { + xmlSecAppCmdLineTopicEncCommon, + "--enabled-cipher-reference-uris", + NULL, + "--enabled-cipher-reference-uris <list>" + "\n\tcomma separated list of of the following values:" + "\n\t\"empty\", \"same-doc\", \"local\",\"remote\" to restrict possible URI" + "\n\tattribute values for the <enc:CipherReference> element", + xmlSecAppCmdLineParamTypeStringList, + xmlSecAppCmdLineParamFlagNone, + NULL +}; + +static xmlSecAppCmdLineParam binaryDataParam = { + xmlSecAppCmdLineTopicEncEncrypt, + "--binary-data", + "--binary", + "--binary-data <file>" + "\n\tbinary <file> to encrypt", + xmlSecAppCmdLineParamTypeString, + xmlSecAppCmdLineParamFlagNone, + NULL +}; + +static xmlSecAppCmdLineParam xmlDataParam = { + xmlSecAppCmdLineTopicEncEncrypt, + "--xml-data", + NULL, + "--xml-data <file>" + "\n\tXML <file> to encrypt", + xmlSecAppCmdLineParamTypeString, + xmlSecAppCmdLineParamFlagNone, + NULL +}; +#endif /* XMLSEC_NO_XMLENC */ + +/**************************************************************** + * + * XKMS params + * + ***************************************************************/ +#ifndef XMLSEC_NO_XKMS +static xmlSecAppCmdLineParam xkmsServiceParam = { + xmlSecAppCmdLineTopicXkmsCommon, + "--xkms-service", + NULL, + "--xkms-service <uri>" + "\n\tsets XKMS \"Service\" <uri>", + xmlSecAppCmdLineParamTypeString, + xmlSecAppCmdLineParamFlagNone, + NULL +}; + +static xmlSecAppCmdLineParam xkmsFormatParam = { + xmlSecAppCmdLineTopicXkmsCommon, + "--xkms-format", + NULL, + "--xkms-format <format>" + "\n\tsets the XKMS request/response format to one of the following values:" + "\n\t \"plain\" (default), \"soap-1.1\" or \"soap-1.2\"", + xmlSecAppCmdLineParamTypeString, + xmlSecAppCmdLineParamFlagNone, + NULL +}; + +static xmlSecAppCmdLineParam xkmsStopUnknownResponseMechanismParam = { + xmlSecAppCmdLineTopicXkmsCommon, /* todo: server */ + "--xkms-stop-on-unknown-response-mechanism", + NULL, + "--xkms-stop-on-unknown-response-mechanism" + "\n\tstop processing XKMS server request if unknown ResponseMechanism" + "\n\tvalue was found", + xmlSecAppCmdLineParamTypeFlag, + xmlSecAppCmdLineParamFlagNone, + NULL +}; + +static xmlSecAppCmdLineParam xkmsStopUnknownRespondWithParam = { + xmlSecAppCmdLineTopicXkmsCommon, /* todo: server */ + "--xkms-stop-on-unknown-respond-with", + NULL, + "--xkms-stop-on-unknown-respond-with" + "\n\tstop processing XKMS server request if unknown RespondWith" + "\n\tvalue was found", + xmlSecAppCmdLineParamTypeFlag, + xmlSecAppCmdLineParamFlagNone, + NULL +}; + +static xmlSecAppCmdLineParam xkmsStopUnknownKeyUsageParam = { + xmlSecAppCmdLineTopicXkmsCommon, /* todo: server */ + "--xkms-stop-on-unknown-key-usage", + NULL, + "--xkms-stop-on-unknown-key-usage" + "\n\tstop processing XKMS server request if unknown KeyUsage" + "\n\tvalue was found", + xmlSecAppCmdLineParamTypeFlag, + xmlSecAppCmdLineParamFlagNone, + NULL +}; + +#endif /* XMLSEC_NO_XKMS */ + +/**************************************************************** + * + * X509 params + * + ***************************************************************/ +#ifndef XMLSEC_NO_X509 +static xmlSecAppCmdLineParam pkcs12Param = { + xmlSecAppCmdLineTopicKeysMngr, + "--pkcs12", + NULL, + "--pkcs12[:<name>] <file>" + "\n\tload load private key from pkcs12 file <file>", + xmlSecAppCmdLineParamTypeString, + xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, + NULL +}; + +static xmlSecAppCmdLineParam pubkeyCertParam = { + xmlSecAppCmdLineTopicKeysMngr, + "--pubkey-cert-pem", + "--pubkey-cert", + "--pubkey-cert-pem[:<name>] <file>" + "\n\tload public key from PEM cert file", + xmlSecAppCmdLineParamTypeStringList, + xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, + NULL +}; + +static xmlSecAppCmdLineParam pubkeyCertDerParam = { + xmlSecAppCmdLineTopicKeysMngr, + "--pubkey-cert-der", + NULL, + "--pubkey-cert-der[:<name>] <file>" + "\n\tload public key from DER cert file", + xmlSecAppCmdLineParamTypeStringList, + xmlSecAppCmdLineParamFlagParamNameValue | xmlSecAppCmdLineParamFlagMultipleValues, + NULL +}; + +static xmlSecAppCmdLineParam trustedParam = { + xmlSecAppCmdLineTopicX509Certs, + "--trusted-pem", + "--trusted", + "--trusted-pem <file>" + "\n\tload trusted (root) certificate from PEM file <file>", + xmlSecAppCmdLineParamTypeString, + xmlSecAppCmdLineParamFlagMultipleValues, + NULL +}; + +static xmlSecAppCmdLineParam untrustedParam = { + xmlSecAppCmdLineTopicX509Certs, + "--untrusted-pem", + "--untrusted", + "--untrusted-pem <file>" + "\n\tload untrusted certificate from PEM file <file>", + xmlSecAppCmdLineParamTypeString, + xmlSecAppCmdLineParamFlagMultipleValues, + NULL +}; + +static xmlSecAppCmdLineParam trustedDerParam = { + xmlSecAppCmdLineTopicX509Certs, + "--trusted-der", + NULL, + "--trusted-der <file>" + "\n\tload trusted (root) certificate from DER file <file>", + xmlSecAppCmdLineParamTypeString, + xmlSecAppCmdLineParamFlagMultipleValues, + NULL +}; + +static xmlSecAppCmdLineParam untrustedDerParam = { + xmlSecAppCmdLineTopicX509Certs, + "--untrusted-der", + NULL, + "--untrusted-der <file>" + "\n\tload untrusted certificate from DER file <file>", + xmlSecAppCmdLineParamTypeString, + xmlSecAppCmdLineParamFlagMultipleValues, + NULL +}; + +static xmlSecAppCmdLineParam verificationTimeParam = { + xmlSecAppCmdLineTopicX509Certs, + "--verification-time", + NULL, + "--verification-time <time>" + "\n\tthe local time in \"YYYY-MM-DD HH:MM:SS\" format" + "\n\tused certificates verification", + xmlSecAppCmdLineParamTypeTime, + xmlSecAppCmdLineParamFlagNone, + NULL +}; + +static xmlSecAppCmdLineParam depthParam = { + xmlSecAppCmdLineTopicX509Certs, + "--depth", + NULL, + "--depth <number>" + "\n\tmaximum certificates chain depth", + xmlSecAppCmdLineParamTypeNumber, + xmlSecAppCmdLineParamFlagNone, + NULL +}; + +static xmlSecAppCmdLineParam X509SkipStrictChecksParam = { + xmlSecAppCmdLineTopicX509Certs, + "--X509-skip-strict-checks", + NULL, + "--X509-skip-strict-checks" + "\n\tskip strict checking of X509 data", + xmlSecAppCmdLineParamTypeFlag, + xmlSecAppCmdLineParamFlagNone, + NULL +}; +#endif /* XMLSEC_NO_X509 */ + +static xmlSecAppCmdLineParamPtr parameters[] = { + /* common dsig params */ +#ifndef XMLSEC_NO_XMLDSIG + &ignoreManifestsParam, + &storeReferencesParam, + &storeSignaturesParam, + &enabledRefUrisParam, + &enableVisa3DHackParam, +#endif /* XMLSEC_NO_XMLDSIG */ + + /* enc params */ +#ifndef XMLSEC_NO_XMLENC + &binaryDataParam, + &xmlDataParam, + &enabledCipherRefUrisParam, +#endif /* XMLSEC_NO_XMLENC */ + + /* xkms params */ +#ifndef XMLSEC_NO_XKMS + &xkmsServiceParam, + &xkmsFormatParam, + &xkmsStopUnknownResponseMechanismParam, + &xkmsStopUnknownRespondWithParam, + &xkmsStopUnknownKeyUsageParam, +#endif /* XMLSEC_NO_XKMS */ + + /* common dsig and enc parameters */ + &sessionKeyParam, + &outputParam, + &printDebugParam, + &printXmlDebugParam, + &dtdFileParam, + &nodeIdParam, + &nodeNameParam, + &nodeXPathParam, + &idAttrParam, + + /* Keys Manager params */ + &enabledKeyDataParam, + &enabledRetrievalMethodUrisParam, + &genKeyParam, + &keysFileParam, + &privkeyParam, + &privkeyDerParam, + &pkcs8PemParam, + &pkcs8DerParam, + &pubkeyParam, + &pubkeyDerParam, +#ifndef XMLSEC_NO_AES + &aeskeyParam, +#endif /* XMLSEC_NO_AES */ +#ifndef XMLSEC_NO_DES + &deskeyParam, +#endif /* XMLSEC_NO_DES */ +#ifndef XMLSEC_NO_HMAC + &hmackeyParam, +#endif /* XMLSEC_NO_HMAC */ + &pwdParam, +#ifndef XMLSEC_NO_X509 + &pkcs12Param, + &pubkeyCertParam, + &pubkeyCertDerParam, + &trustedParam, + &untrustedParam, + &trustedDerParam, + &untrustedDerParam, + &verificationTimeParam, + &depthParam, + &X509SkipStrictChecksParam, +#endif /* XMLSEC_NO_X509 */ + + /* General configuration params */ + &cryptoParam, + &cryptoConfigParam, + &repeatParam, + &disableErrorMsgsParam, + &printCryptoErrorMsgsParam, + &helpParam, + + /* MUST be the last one */ + NULL +}; + +typedef enum { + xmlSecAppCommandUnknown = 0, + xmlSecAppCommandHelp, + xmlSecAppCommandListKeyData, + xmlSecAppCommandCheckKeyData, + xmlSecAppCommandListTransforms, + xmlSecAppCommandCheckTransforms, + xmlSecAppCommandVersion, + xmlSecAppCommandKeys, + xmlSecAppCommandSign, + xmlSecAppCommandVerify, + xmlSecAppCommandSignTmpl, + xmlSecAppCommandEncrypt, + xmlSecAppCommandDecrypt, + xmlSecAppCommandEncryptTmpl, + xmlSecAppCommandXkmsServerRequest +} xmlSecAppCommand; + +typedef struct _xmlSecAppXmlData xmlSecAppXmlData, + *xmlSecAppXmlDataPtr; +struct _xmlSecAppXmlData { + xmlDocPtr doc; + xmlDtdPtr dtd; + xmlNodePtr startNode; +}; + +static xmlSecAppXmlDataPtr xmlSecAppXmlDataCreate (const char* filename, + const xmlChar* defStartNodeName, + const xmlChar* defStartNodeNs); +static void xmlSecAppXmlDataDestroy (xmlSecAppXmlDataPtr data); + + +static xmlSecAppCommand xmlSecAppParseCommand (const char* cmd, + xmlSecAppCmdLineParamTopic* topics, + xmlSecAppCommand* subCommand); +static void xmlSecAppPrintHelp (xmlSecAppCommand command, + xmlSecAppCmdLineParamTopic topics); +#define xmlSecAppPrintUsage() xmlSecAppPrintHelp(xmlSecAppCommandUnknown, 0) +static int xmlSecAppInit (void); +static void xmlSecAppShutdown (void); +static int xmlSecAppLoadKeys (void); +static int xmlSecAppPrepareKeyInfoReadCtx (xmlSecKeyInfoCtxPtr ctx); + +#ifndef XMLSEC_NO_XMLDSIG +static int xmlSecAppSignFile (const char* filename); +static int xmlSecAppVerifyFile (const char* filename); +#ifndef XMLSEC_NO_TMPL_TEST +static int xmlSecAppSignTmpl (void); +#endif /* XMLSEC_NO_TMPL_TEST */ +static int xmlSecAppPrepareDSigCtx (xmlSecDSigCtxPtr dsigCtx); +static void xmlSecAppPrintDSigCtx (xmlSecDSigCtxPtr dsigCtx); +#endif /* XMLSEC_NO_XMLDSIG */ + +#ifndef XMLSEC_NO_XMLENC +static int xmlSecAppEncryptFile (const char* filename); +static int xmlSecAppDecryptFile (const char* filename); +#ifndef XMLSEC_NO_TMPL_TEST +static int xmlSecAppEncryptTmpl (void); +#endif /* XMLSEC_NO_TMPL_TEST */ +static int xmlSecAppPrepareEncCtx (xmlSecEncCtxPtr encCtx); +static void xmlSecAppPrintEncCtx (xmlSecEncCtxPtr encCtx); +#endif /* XMLSEC_NO_XMLENC */ + +#ifndef XMLSEC_NO_XKMS +static int xmlSecAppXkmsServerProcess (const char* filename); +static int xmlSecAppPrepareXkmsServerCtx (xmlSecXkmsServerCtxPtr xkmsServerCtx); +static void xmlSecAppPrintXkmsServerCtx (xmlSecXkmsServerCtxPtr xkmsServerCtx); +#endif /* XMLSEC_NO_XKMS */ + +static void xmlSecAppListKeyData (void); +static int xmlSecAppCheckKeyData (const char * name); +static void xmlSecAppListTransforms (void); +static int xmlSecAppCheckTransform (const char * name); + +static xmlSecTransformUriType xmlSecAppGetUriType (const char* string); +static FILE* xmlSecAppOpenFile (const char* filename); +static void xmlSecAppCloseFile (FILE* file); +static int xmlSecAppWriteResult (xmlDocPtr doc, + xmlSecBufferPtr buffer); +static int xmlSecAppAddIDAttr (xmlNodePtr cur, + const xmlChar* attr, + const xmlChar* node, + const xmlChar* nsHref); + +xmlSecKeysMngrPtr gKeysMngr = NULL; +int repeats = 1; +int print_debug = 0; +clock_t total_time = 0; +const char* xmlsec_crypto = XMLSEC_CRYPTO; +const char* tmp = NULL; + +int main(int argc, const char **argv) { + xmlSecAppCmdLineParamTopic cmdLineTopics; + xmlSecAppCommand command, subCommand; + int pos, i; + int res = 1; + + /* read the command (first argument) */ + if(argc < 2) { + xmlSecAppPrintUsage(); + goto fail; + } + command = xmlSecAppParseCommand(argv[1], &cmdLineTopics, &subCommand); + if(command == xmlSecAppCommandUnknown) { + fprintf(stderr, "Error: unknown command \"%s\"\n", argv[1]); + xmlSecAppPrintUsage(); + goto fail; + } + + /* do as much as we can w/o initialization */ + if(command == xmlSecAppCommandHelp) { + xmlSecAppPrintHelp(subCommand, cmdLineTopics); + goto success; + } else if(command == xmlSecAppCommandVersion) { + fprintf(stdout, "%s %s (%s)\n", PACKAGE, XMLSEC_VERSION, xmlsec_crypto); + goto success; + } + + /* parse command line */ + pos = xmlSecAppCmdLineParamsListParse(parameters, cmdLineTopics, argv, argc, 2); + if(pos < 0) { + fprintf(stderr, "Error: invalid parameters\n"); + xmlSecAppPrintUsage(); + goto fail; + } + + /* is it a help request? */ + if(xmlSecAppCmdLineParamIsSet(&helpParam)) { + xmlSecAppPrintHelp(command, cmdLineTopics); + goto success; + } + + /* we need to have some files at the end */ + switch(command) { + case xmlSecAppCommandKeys: + case xmlSecAppCommandSign: + case xmlSecAppCommandVerify: + case xmlSecAppCommandEncrypt: + case xmlSecAppCommandDecrypt: + case xmlSecAppCommandXkmsServerRequest: + if(pos >= argc) { + fprintf(stderr, "Error: <file> parameter is requried for this command\n"); + xmlSecAppPrintUsage(); + goto fail; + } + break; + default: + break; + } + + /* now init the xmlsec and all other libs */ + /* ignore "--crypto" if we don't have dynamic loading */ + tmp = xmlSecAppCmdLineParamGetString(&cryptoParam); +#if !defined(XMLSEC_NO_CRYPTO_DYNAMIC_LOADING) && defined(XMLSEC_CRYPTO_DYNAMIC_LOADING) + if((tmp != NULL) && (strcmp(tmp, "default") != 0)) { + xmlsec_crypto = tmp; + } +#else /* !defined(XMLSEC_NO_CRYPTO_DYNAMIC_LOADING) && defined(XMLSEC_CRYPTO_DYNAMIC_LOADING) */ + if((tmp != NULL) && (strcmp(tmp, xmlsec_crypto) != 0)) { + fprintf(stderr, "Error: dynaimc crypto libraries loading is disabled and the only available crypto library is '%s'\n", xmlsec_crypto); + xmlSecAppPrintUsage(); + goto fail; + } +#endif /* !defined(XMLSEC_NO_CRYPTO_DYNAMIC_LOADING) && defined(XMLSEC_CRYPTO_DYNAMIC_LOADING) */ + + if(xmlSecAppInit() < 0) { + fprintf(stderr, "Error: initialization failed\n"); + xmlSecAppPrintUsage(); + goto fail; + } + + /* load keys */ + if(xmlSecAppLoadKeys() < 0) { + fprintf(stderr, "Error: keys manager creation failed\n"); + xmlSecAppPrintUsage(); + goto fail; + } + + /* get the "repeats" number */ + if(xmlSecAppCmdLineParamIsSet(&repeatParam) && + (xmlSecAppCmdLineParamGetInt(&repeatParam, 1) > 0)) { + + repeats = xmlSecAppCmdLineParamGetInt(&repeatParam, 1); + } + + /* execute requested number of times */ + for(; repeats > 0; --repeats) { + switch(command) { + case xmlSecAppCommandListKeyData: + xmlSecAppListKeyData(); + break; + case xmlSecAppCommandCheckKeyData: + for(i = pos; i < argc; ++i) { + if(xmlSecAppCheckKeyData(argv[i]) < 0) { + fprintf(stderr, "Error: key data \"%s\" not found\n", argv[i]); + goto fail; + } else { + fprintf(stdout, "Key data \"%s\" found\n", argv[i]); + } + } + break; + case xmlSecAppCommandListTransforms: + xmlSecAppListTransforms(); + break; + case xmlSecAppCommandCheckTransforms: + for(i = pos; i < argc; ++i) { + if(xmlSecAppCheckTransform(argv[i]) < 0) { + fprintf(stderr, "Error: transform \"%s\" not found\n", argv[i]); + goto fail; + } else { + fprintf(stdout, "Transforms \"%s\" found\n", argv[i]); + } + } + break; + case xmlSecAppCommandKeys: + for(i = pos; i < argc; ++i) { + if(xmlSecAppCryptoSimpleKeysMngrSave(gKeysMngr, argv[i], xmlSecKeyDataTypeAny) < 0) { + fprintf(stderr, "Error: failed to save keys to file \"%s\"\n", argv[i]); + goto fail; + } + } + break; +#ifndef XMLSEC_NO_XMLDSIG + case xmlSecAppCommandSign: + for(i = pos; i < argc; ++i) { + if(xmlSecAppSignFile(argv[i]) < 0) { + fprintf(stderr, "Error: failed to sign file \"%s\"\n", argv[i]); + goto fail; + } + } + break; + case xmlSecAppCommandVerify: + for(i = pos; i < argc; ++i) { + if(xmlSecAppVerifyFile(argv[i]) < 0) { + fprintf(stderr, "Error: failed to verify file \"%s\"\n", argv[i]); + goto fail; + } + } + break; +#ifndef XMLSEC_NO_TMPL_TEST + case xmlSecAppCommandSignTmpl: + if(xmlSecAppSignTmpl() < 0) { + fprintf(stderr, "Error: failed to create and sign template\n"); + goto fail; + } + break; +#endif /* XMLSEC_NO_TMPL_TEST */ +#endif /* XMLSEC_NO_XMLDSIG */ + +#ifndef XMLSEC_NO_XMLENC + case xmlSecAppCommandEncrypt: + for(i = pos; i < argc; ++i) { + if(xmlSecAppEncryptFile(argv[i]) < 0) { + fprintf(stderr, "Error: failed to encrypt file with template \"%s\"\n", argv[i]); + goto fail; + } + } + break; + case xmlSecAppCommandDecrypt: + for(i = pos; i < argc; ++i) { + if(xmlSecAppDecryptFile(argv[i]) < 0) { + fprintf(stderr, "Error: failed to decrypt file \"%s\"\n", argv[i]); + goto fail; + } + } + break; +#ifndef XMLSEC_NO_TMPL_TEST + case xmlSecAppCommandEncryptTmpl: + if(xmlSecAppEncryptTmpl() < 0) { + fprintf(stderr, "Error: failed to create and encrypt template\n"); + goto fail; + } + break; +#endif /* XMLSEC_NO_TMPL_TEST */ +#endif /* XMLSEC_NO_XMLENC */ + +#ifndef XMLSEC_NO_XKMS + case xmlSecAppCommandXkmsServerRequest: + for(i = pos; i < argc; ++i) { + if(xmlSecAppXkmsServerProcess(argv[i]) < 0) { + fprintf(stderr, "Error: failed to process XKMS server request from file \"%s\"\n", argv[i]); + goto fail; + } + } + break; +#endif /* XMLSEC_NO_XKMS */ + default: + fprintf(stderr, "Error: invalid command %d\n", command); + xmlSecAppPrintUsage(); + goto fail; + } + } + + /* print perf stats results */ + if(xmlSecAppCmdLineParamIsSet(&repeatParam) && + (xmlSecAppCmdLineParamGetInt(&repeatParam, 1) > 0)) { + + repeats = xmlSecAppCmdLineParamGetInt(&repeatParam, 1); + fprintf(stderr, "Executed %d tests in %ld msec\n", repeats, (1000 * total_time) / CLOCKS_PER_SEC); + } + + goto success; +success: + res = 0; +fail: + if(gKeysMngr != NULL) { + xmlSecKeysMngrDestroy(gKeysMngr); + gKeysMngr = NULL; + } + xmlSecAppShutdown(); + xmlSecAppCmdLineParamsListClean(parameters); + return(res); +} + + +#ifndef XMLSEC_NO_XMLDSIG +static int +xmlSecAppSignFile(const char* filename) { + xmlSecAppXmlDataPtr data = NULL; + xmlSecDSigCtx dsigCtx; + clock_t start_time; + int res = -1; + + if(filename == NULL) { + return(-1); + } + + if(xmlSecDSigCtxInitialize(&dsigCtx, gKeysMngr) < 0) { + fprintf(stderr, "Error: dsig context initialization failed\n"); + return(-1); + } + + if(xmlSecAppPrepareDSigCtx(&dsigCtx) < 0) { + fprintf(stderr, "Error: dsig context preparation failed\n"); + goto done; + } + + /* parse template and select start node */ + data = xmlSecAppXmlDataCreate(filename, xmlSecNodeSignature, xmlSecDSigNs); + if(data == NULL) { + fprintf(stderr, "Error: failed to load template \"%s\"\n", filename); + goto done; + } + + + /* sign */ + start_time = clock(); + if(xmlSecDSigCtxSign(&dsigCtx, data->startNode) < 0) { + fprintf(stderr,"Error: signature failed \n"); + goto done; + } + total_time += clock() - start_time; + + if(repeats <= 1) { + FILE* f; + + f = xmlSecAppOpenFile(xmlSecAppCmdLineParamGetString(&outputParam)); + if(f == NULL) { + fprintf(stderr,"Error: failed to open output file \"%s\"\n", + xmlSecAppCmdLineParamGetString(&outputParam)); + goto done; + } + xmlDocDump(f, data->doc); + xmlSecAppCloseFile(f); + } + + res = 0; +done: + /* print debug info if requested */ + if(repeats <= 1) { + xmlSecAppPrintDSigCtx(&dsigCtx); + } + xmlSecDSigCtxFinalize(&dsigCtx); + if(data != NULL) { + xmlSecAppXmlDataDestroy(data); + } + return(res); +} + +static int +xmlSecAppVerifyFile(const char* filename) { + xmlSecAppXmlDataPtr data = NULL; + xmlSecDSigCtx dsigCtx; + clock_t start_time; + int res = -1; + + if(filename == NULL) { + return(-1); + } + + if(xmlSecDSigCtxInitialize(&dsigCtx, gKeysMngr) < 0) { + fprintf(stderr, "Error: dsig context initialization failed\n"); + return(-1); + } + if(xmlSecAppPrepareDSigCtx(&dsigCtx) < 0) { + fprintf(stderr, "Error: dsig context preparation failed\n"); + goto done; + } + + /* parse template and select start node */ + data = xmlSecAppXmlDataCreate(filename, xmlSecNodeSignature, xmlSecDSigNs); + if(data == NULL) { + fprintf(stderr, "Error: failed to load document \"%s\"\n", filename); + goto done; + } + + /* sign */ + start_time = clock(); + if(xmlSecDSigCtxVerify(&dsigCtx, data->startNode) < 0) { + fprintf(stderr,"Error: signature failed \n"); + goto done; + } + total_time += clock() - start_time; + + if((repeats <= 1) && (dsigCtx.status != xmlSecDSigStatusSucceeded)){ + /* return an error if signature does not match */ + goto done; + } + + res = 0; +done: + /* print debug info if requested */ + if(repeats <= 1) { + xmlSecDSigReferenceCtxPtr dsigRefCtx; + xmlSecSize good, i, size; + FILE* f; + + f = xmlSecAppOpenFile(xmlSecAppCmdLineParamGetString(&outputParam)); + if(f == NULL) { + fprintf(stderr,"Error: failed to open output file \"%s\"\n", + xmlSecAppCmdLineParamGetString(&outputParam)); + goto done; + } + xmlSecAppCloseFile(f); + + switch(dsigCtx.status) { + case xmlSecDSigStatusUnknown: + fprintf(stderr, "ERROR\n"); + break; + case xmlSecDSigStatusSucceeded: + fprintf(stderr, "OK\n"); + break; + case xmlSecDSigStatusInvalid: + fprintf(stderr, "FAIL\n"); + break; + } + + /* print stats about # of good/bad references/manifests */ + size = xmlSecPtrListGetSize(&(dsigCtx.signedInfoReferences)); + for(i = good = 0; i < size; ++i) { + dsigRefCtx = (xmlSecDSigReferenceCtxPtr)xmlSecPtrListGetItem(&(dsigCtx.signedInfoReferences), i); + if(dsigRefCtx == NULL) { + fprintf(stderr,"Error: reference ctx is null\n"); + goto done; + } + if(dsigRefCtx->status == xmlSecDSigStatusSucceeded) { + ++good; + } + } + fprintf(stderr, "SignedInfo References (ok/all): %d/%d\n", good, size); + + size = xmlSecPtrListGetSize(&(dsigCtx.manifestReferences)); + for(i = good = 0; i < size; ++i) { + dsigRefCtx = (xmlSecDSigReferenceCtxPtr)xmlSecPtrListGetItem(&(dsigCtx.manifestReferences), i); + if(dsigRefCtx == NULL) { + fprintf(stderr,"Error: reference ctx is null\n"); + goto done; + } + if(dsigRefCtx->status == xmlSecDSigStatusSucceeded) { + ++good; + } + } + fprintf(stderr, "Manifests References (ok/all): %d/%d\n", good, size); + + xmlSecAppPrintDSigCtx(&dsigCtx); + } + xmlSecDSigCtxFinalize(&dsigCtx); + if(data != NULL) { + xmlSecAppXmlDataDestroy(data); + } + return(res); +} + +#ifndef XMLSEC_NO_TMPL_TEST +static int +xmlSecAppSignTmpl(void) { + xmlDocPtr doc = NULL; + xmlNodePtr cur; + xmlSecDSigCtx dsigCtx; + clock_t start_time; + int res = -1; + + if(xmlSecDSigCtxInitialize(&dsigCtx, gKeysMngr) < 0) { + fprintf(stderr, "Error: dsig context initialization failed\n"); + return(-1); + } + if(xmlSecAppPrepareDSigCtx(&dsigCtx) < 0) { + fprintf(stderr, "Error: dsig context preparation failed\n"); + goto done; + } + + /* prepare template */ + doc = xmlNewDoc(BAD_CAST "1.0"); + if(doc == NULL) { + fprintf(stderr, "Error: failed to create doc\n"); + goto done; + } + + cur = xmlSecTmplSignatureCreate(doc, xmlSecTransformInclC14NId, + xmlSecTransformHmacSha1Id, NULL); + if(cur == NULL) { + fprintf(stderr, "Error: failed to create Signature node\n"); + goto done; + } + xmlDocSetRootElement(doc, cur); + + /* set hmac signature length */ + cur = xmlSecTmplSignatureGetSignMethodNode(xmlDocGetRootElement(doc)); + if(cur == NULL) { + fprintf(stderr, "Error: failed to find SignatureMethod node\n"); + goto done; + } + if(xmlSecTmplTransformAddHmacOutputLength(cur, 93) < 0) { + fprintf(stderr, "Error: failed to set hmac length\n"); + goto done; + } + + cur = xmlSecTmplSignatureAddReference(xmlDocGetRootElement(doc), + xmlSecTransformSha1Id, + BAD_CAST "ref1", NULL, NULL); + if(cur == NULL) { + fprintf(stderr, "Error: failed to add Reference node\n"); + goto done; + } + + cur = xmlSecTmplReferenceAddTransform(cur, xmlSecTransformXPath2Id); + if(cur == NULL) { + fprintf(stderr, "Error: failed to add XPath transform\n"); + goto done; + } + + if(xmlSecTmplTransformAddXPath2(cur, BAD_CAST "intersect", + BAD_CAST "//*[@Id='object1']", NULL) < 0) { + fprintf(stderr, "Error: failed to set XPath expression\n"); + goto done; + } + + cur = xmlSecTmplSignatureAddObject(xmlDocGetRootElement(doc), + BAD_CAST "object1", NULL, NULL); + if(cur == NULL) { + fprintf(stderr, "Error: failed to add Object node\n"); + goto done; + } + xmlNodeSetContent(cur, BAD_CAST "This is signed data"); + + /* add key information */ + cur = xmlSecTmplSignatureEnsureKeyInfo(xmlDocGetRootElement(doc), NULL); + if(cur == NULL) { + fprintf(stderr, "Error: failed to add KeyInfo node\n"); + goto done; + } + if(xmlSecTmplKeyInfoAddKeyName(cur, NULL) == NULL) { + fprintf(stderr, "Error: failed to add KeyName node\n"); + goto done; + } + + /* sign */ + start_time = clock(); + if(xmlSecDSigCtxSign(&dsigCtx, xmlDocGetRootElement(doc)) < 0) { + fprintf(stderr,"Error: signature failed \n"); + goto done; + } + total_time += clock() - start_time; + + if(repeats <= 1) { + FILE* f; + + f = xmlSecAppOpenFile(xmlSecAppCmdLineParamGetString(&outputParam)); + if(f == NULL) { + fprintf(stderr,"Error: failed to open output file \"%s\"\n", + xmlSecAppCmdLineParamGetString(&outputParam)); + goto done; + } + xmlDocDump(f, doc); + xmlSecAppCloseFile(f); + } + + res = 0; +done: + /* print debug info if requested */ + if(repeats <= 1) { + xmlSecAppPrintDSigCtx(&dsigCtx); + } + xmlSecDSigCtxFinalize(&dsigCtx); + if(doc != NULL) { + xmlFreeDoc(doc); + } + return(res); +} +#endif /* XMLSEC_NO_TMPL_TEST */ + +static int +xmlSecAppPrepareDSigCtx(xmlSecDSigCtxPtr dsigCtx) { + if(dsigCtx == NULL) { + fprintf(stderr, "Error: dsig context is null\n"); + return(-1); + } + + /* set key info params */ + if(xmlSecAppPrepareKeyInfoReadCtx(&(dsigCtx->keyInfoReadCtx)) < 0) { + fprintf(stderr, "Error: failed to prepare key info context\n"); + return(-1); + } + + if(xmlSecAppCmdLineParamGetString(&sessionKeyParam) != NULL) { + dsigCtx->signKey = xmlSecAppCryptoKeyGenerate(xmlSecAppCmdLineParamGetString(&sessionKeyParam), + NULL, xmlSecKeyDataTypeSession); + if(dsigCtx->signKey == NULL) { + fprintf(stderr, "Error: failed to generate a session key \"%s\"\n", + xmlSecAppCmdLineParamGetString(&sessionKeyParam)); + return(-1); + } + } + + /* set dsig params */ + if(xmlSecAppCmdLineParamIsSet(&ignoreManifestsParam)) { + dsigCtx->flags |= XMLSEC_DSIG_FLAGS_IGNORE_MANIFESTS; + } + if(xmlSecAppCmdLineParamIsSet(&storeReferencesParam)) { + dsigCtx->flags |= XMLSEC_DSIG_FLAGS_STORE_SIGNEDINFO_REFERENCES | + XMLSEC_DSIG_FLAGS_STORE_MANIFEST_REFERENCES; + print_debug = 1; + } + if(xmlSecAppCmdLineParamIsSet(&storeSignaturesParam)) { + dsigCtx->flags |= XMLSEC_DSIG_FLAGS_STORE_SIGNATURE; + print_debug = 1; + } + if(xmlSecAppCmdLineParamIsSet(&enableVisa3DHackParam)) { + dsigCtx->flags |= XMLSEC_DSIG_FLAGS_USE_VISA3D_HACK; + } + + if(xmlSecAppCmdLineParamGetStringList(&enabledRefUrisParam) != NULL) { + dsigCtx->enabledReferenceUris = xmlSecAppGetUriType( + xmlSecAppCmdLineParamGetStringList(&enabledRefUrisParam)); + if(dsigCtx->enabledReferenceUris == xmlSecTransformUriTypeNone) { + fprintf(stderr, "Error: failed to parse \"%s\"\n", + xmlSecAppCmdLineParamGetStringList(&enabledRefUrisParam)); + return(-1); + } + } + + return(0); +} + +static void +xmlSecAppPrintDSigCtx(xmlSecDSigCtxPtr dsigCtx) { + if(dsigCtx == NULL) { + return; + } + + if(xmlSecAppCmdLineParamIsSet(&printDebugParam) || xmlSecAppCmdLineParamIsSet(&printXmlDebugParam)) { + print_debug = 0; + } + + /* print debug info if requested */ + if((print_debug != 0) || xmlSecAppCmdLineParamIsSet(&printDebugParam)) { + xmlSecDSigCtxDebugDump(dsigCtx, stdout); + } + + if(xmlSecAppCmdLineParamIsSet(&printXmlDebugParam)) { + xmlSecDSigCtxDebugXmlDump(dsigCtx, stdout); + } +} + +#endif /* XMLSEC_NO_XMLDSIG */ + +#ifndef XMLSEC_NO_XMLENC +static int +xmlSecAppEncryptFile(const char* filename) { + xmlSecAppXmlDataPtr data = NULL; + xmlSecEncCtx encCtx; + xmlDocPtr doc = NULL; + xmlNodePtr startTmplNode; + clock_t start_time; + int res = -1; + + if(filename == NULL) { + return(-1); + } + + if(xmlSecEncCtxInitialize(&encCtx, gKeysMngr) < 0) { + fprintf(stderr, "Error: enc context initialization failed\n"); + return(-1); + } + if(xmlSecAppPrepareEncCtx(&encCtx) < 0) { + fprintf(stderr, "Error: enc context preparation failed\n"); + goto done; + } + + /* parse doc and find template node */ + doc = xmlSecParseFile(filename); + if(doc == NULL) { + fprintf(stderr, "Error: failed to parse xml file \"%s\"\n", + filename); + goto done; + } + startTmplNode = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeEncryptedData, xmlSecEncNs); + if(startTmplNode == NULL) { + fprintf(stderr, "Error: failed to find default node with name=\"%s\"\n", + xmlSecNodeEncryptedData); + goto done; + } + + if(xmlSecAppCmdLineParamGetString(&binaryDataParam) != NULL) { + /* encrypt */ + start_time = clock(); + if(xmlSecEncCtxUriEncrypt(&encCtx, startTmplNode, BAD_CAST xmlSecAppCmdLineParamGetString(&binaryDataParam)) < 0) { + fprintf(stderr, "Error: failed to encrypt file \"%s\"\n", + xmlSecAppCmdLineParamGetString(&binaryDataParam)); + goto done; + } + total_time += clock() - start_time; + } else if(xmlSecAppCmdLineParamGetString(&xmlDataParam) != NULL) { + /* parse file and select node for encryption */ + data = xmlSecAppXmlDataCreate(xmlSecAppCmdLineParamGetString(&xmlDataParam), NULL, NULL); + if(data == NULL) { + fprintf(stderr, "Error: failed to load file \"%s\"\n", + xmlSecAppCmdLineParamGetString(&xmlDataParam)); + goto done; + } + + /* encrypt */ + start_time = clock(); + if(xmlSecEncCtxXmlEncrypt(&encCtx, startTmplNode, data->startNode) < 0) { + fprintf(stderr, "Error: failed to encrypt xml file \"%s\"\n", + xmlSecAppCmdLineParamGetString(&xmlDataParam)); + goto done; + } + total_time += clock() - start_time; + } else { + fprintf(stderr, "Error: encryption data not specified (use \"--xml\" or \"--binary\" options)\n"); + goto done; + } + + /* print out result only once per execution */ + if(repeats <= 1) { + if(encCtx.resultReplaced) { + if(xmlSecAppWriteResult((data != NULL) ? data->doc : doc, NULL) < 0) { + goto done; + } + } else { + if(xmlSecAppWriteResult(NULL, encCtx.result) < 0) { + goto done; + } + } + } + res = 0; + +done: + /* print debug info if requested */ + if(repeats <= 1) { + xmlSecAppPrintEncCtx(&encCtx); + } + xmlSecEncCtxFinalize(&encCtx); + + if(data != NULL) { + xmlSecAppXmlDataDestroy(data); + } + if(doc != NULL) { + xmlFreeDoc(doc); + } + return(res); +} + +static int +xmlSecAppDecryptFile(const char* filename) { + xmlSecAppXmlDataPtr data = NULL; + xmlSecEncCtx encCtx; + clock_t start_time; + int res = -1; + + if(filename == NULL) { + return(-1); + } + + if(xmlSecEncCtxInitialize(&encCtx, gKeysMngr) < 0) { + fprintf(stderr, "Error: enc context initialization failed\n"); + return(-1); + } + if(xmlSecAppPrepareEncCtx(&encCtx) < 0) { + fprintf(stderr, "Error: enc context preparation failed\n"); + goto done; + } + + /* parse template and select start node */ + data = xmlSecAppXmlDataCreate(filename, xmlSecNodeEncryptedData, xmlSecEncNs); + if(data == NULL) { + fprintf(stderr, "Error: failed to load template \"%s\"\n", filename); + goto done; + } + + start_time = clock(); + if(xmlSecEncCtxDecrypt(&encCtx, data->startNode) < 0) { + fprintf(stderr, "Error: failed to decrypt file\n"); + goto done; + } + total_time += clock() - start_time; + + /* print out result only once per execution */ + if(repeats <= 1) { + if(encCtx.resultReplaced) { + if(xmlSecAppWriteResult(data->doc, NULL) < 0) { + goto done; + } + } else { + if(xmlSecAppWriteResult(NULL, encCtx.result) < 0) { + goto done; + } + } + } + res = 0; + +done: + /* print debug info if requested */ + if(repeats <= 1) { + xmlSecAppPrintEncCtx(&encCtx); + } + xmlSecEncCtxFinalize(&encCtx); + + if(data != NULL) { + xmlSecAppXmlDataDestroy(data); + } + return(res); +} + +#ifndef XMLSEC_NO_TMPL_TEST +static int +xmlSecAppEncryptTmpl(void) { + const char* data = "Hello, World!"; + xmlSecEncCtx encCtx; + xmlDocPtr doc = NULL; + xmlNodePtr cur; + clock_t start_time; + int res = -1; + + if(xmlSecEncCtxInitialize(&encCtx, gKeysMngr) < 0) { + fprintf(stderr, "Error: enc context initialization failed\n"); + return(-1); + } + if(xmlSecAppPrepareEncCtx(&encCtx) < 0) { + fprintf(stderr, "Error: enc context preparation failed\n"); + goto done; + } + + /* prepare template */ + doc = xmlNewDoc(BAD_CAST "1.0"); + if(doc == NULL) { + fprintf(stderr, "Error: failed to create doc\n"); + goto done; + } + + cur = xmlSecTmplEncDataCreate(doc, xmlSecTransformDes3CbcId, + NULL, NULL, NULL, NULL); + if(cur == NULL) { + fprintf(stderr, "Error: failed to encryption template\n"); + goto done; + } + xmlDocSetRootElement(doc, cur); + + if(xmlSecTmplEncDataEnsureCipherValue(xmlDocGetRootElement(doc)) == NULL) { + fprintf(stderr, "Error: failed to add CipherValue node\n"); + goto done; + } + + /* add key information */ + cur = xmlSecTmplEncDataEnsureKeyInfo(xmlDocGetRootElement(doc), NULL); + if(cur == NULL) { + fprintf(stderr, "Error: failed to add KeyInfo node\n"); + goto done; + } + if(xmlSecTmplKeyInfoAddKeyName(cur, NULL) == NULL) { + fprintf(stderr, "Error: failed to add KeyName node\n"); + goto done; + } + + /* encrypt */ + start_time = clock(); + if(xmlSecEncCtxBinaryEncrypt(&encCtx, xmlDocGetRootElement(doc), + (const xmlSecByte*)data, strlen(data)) < 0) { + fprintf(stderr, "Error: failed to encrypt data\n"); + goto done; + } + total_time += clock() - start_time; + + /* print out result only once per execution */ + if(repeats <= 1) { + if(encCtx.resultReplaced) { + if(xmlSecAppWriteResult(doc, NULL) < 0) { + goto done; + } + } else { + if(xmlSecAppWriteResult(NULL, encCtx.result) < 0) { + goto done; + } + } + } + res = 0; + +done: + /* print debug info if requested */ + if(repeats <= 1) { + xmlSecAppPrintEncCtx(&encCtx); + } + xmlSecEncCtxFinalize(&encCtx); + if(doc != NULL) { + xmlFreeDoc(doc); + } + return(res); +} +#endif /* XMLSEC_NO_TMPL_TEST */ + +static int +xmlSecAppPrepareEncCtx(xmlSecEncCtxPtr encCtx) { + if(encCtx == NULL) { + fprintf(stderr, "Error: enc context is null\n"); + return(-1); + } + + /* set key info params */ + if(xmlSecAppPrepareKeyInfoReadCtx(&(encCtx->keyInfoReadCtx)) < 0) { + fprintf(stderr, "Error: failed to prepare key info context\n"); + return(-1); + } + + if(xmlSecAppCmdLineParamGetString(&sessionKeyParam) != NULL) { + encCtx->encKey = xmlSecAppCryptoKeyGenerate(xmlSecAppCmdLineParamGetString(&sessionKeyParam), + NULL, xmlSecKeyDataTypeSession); + if(encCtx->encKey == NULL) { + fprintf(stderr, "Error: failed to generate a session key \"%s\"\n", + xmlSecAppCmdLineParamGetString(&sessionKeyParam)); + return(-1); + } + } + + if(xmlSecAppCmdLineParamGetStringList(&enabledCipherRefUrisParam) != NULL) { + encCtx->transformCtx.enabledUris = xmlSecAppGetUriType( + xmlSecAppCmdLineParamGetStringList(&enabledCipherRefUrisParam)); + if(encCtx->transformCtx.enabledUris == xmlSecTransformUriTypeNone) { + fprintf(stderr, "Error: failed to parse \"%s\"\n", + xmlSecAppCmdLineParamGetStringList(&enabledCipherRefUrisParam)); + return(-1); + } + } + return(0); +} + +static void +xmlSecAppPrintEncCtx(xmlSecEncCtxPtr encCtx) { + if(encCtx == NULL) { + return; + } + + /* print debug info if requested */ + if((print_debug != 0) || xmlSecAppCmdLineParamIsSet(&printDebugParam)) { + xmlSecEncCtxDebugDump(encCtx, stdout); + } + + if(xmlSecAppCmdLineParamIsSet(&printXmlDebugParam)) { + xmlSecEncCtxDebugXmlDump(encCtx, stdout); + } +} + +#endif /* XMLSEC_NO_XMLENC */ + +#ifndef XMLSEC_NO_XKMS +static int +xmlSecAppXkmsServerProcess(const char* filename) { + xmlSecAppXmlDataPtr data = NULL; + xmlDocPtr doc = NULL; + xmlNodePtr result; + xmlSecXkmsServerCtx xkmsServerCtx; + xmlSecXkmsServerFormat format = xmlSecXkmsServerFormatPlain; + clock_t start_time; + int res = -1; + + if(filename == NULL) { + return(-1); + } + + if(xmlSecXkmsServerCtxInitialize(&xkmsServerCtx, gKeysMngr) < 0) { + fprintf(stderr, "Error: XKMS server context initialization failed\n"); + return(-1); + } + if(xmlSecAppPrepareXkmsServerCtx(&xkmsServerCtx) < 0) { + fprintf(stderr, "Error: XKMS server context preparation failed\n"); + goto done; + } + + /* get the input format */ + if(xmlSecAppCmdLineParamGetString(&xkmsFormatParam) != NULL) { + format = xmlSecXkmsServerFormatFromString(BAD_CAST xmlSecAppCmdLineParamGetString(&xkmsFormatParam)); + if(format == xmlSecXkmsServerFormatUnknown) { + fprintf(stderr, "Error: unknown format \"%s\"\n", + xmlSecAppCmdLineParamGetString(&xkmsFormatParam)); + return(-1); + } + } + + /* parse template and select start node, there are multiple options + * for start node thus we don't provide the default start node name */ + data = xmlSecAppXmlDataCreate(filename, NULL, NULL); + if(data == NULL) { + fprintf(stderr, "Error: failed to load request from file \"%s\"\n", filename); + goto done; + } + + /* prepare result document */ + doc = xmlNewDoc(BAD_CAST "1.0"); + if(doc == NULL) { + fprintf(stderr, "Error: failed to create doc\n"); + goto done; + } + + start_time = clock(); + result = xmlSecXkmsServerCtxProcess(&xkmsServerCtx, data->startNode, format, doc); + if(result == NULL) { + fprintf(stderr, "Error: failed to process xkms server request\n"); + goto done; + } + total_time += clock() - start_time; + + + /* print out result only once per execution */ + xmlDocSetRootElement(doc, result); + if(repeats <= 1) { + if(xmlSecAppWriteResult(doc, NULL) < 0) { + goto done; + } + } + + res = 0; + +done: + /* print debug info if requested */ + if(repeats <= 1) { + xmlSecAppPrintXkmsServerCtx(&xkmsServerCtx); + } + xmlSecXkmsServerCtxFinalize(&xkmsServerCtx); + + if(doc != NULL) { + xmlFreeDoc(doc); + } + if(data != NULL) { + xmlSecAppXmlDataDestroy(data); + } + return(res); +} + +static int +xmlSecAppPrepareXkmsServerCtx(xmlSecXkmsServerCtxPtr xkmsServerCtx) { + if(xkmsServerCtx == NULL) { + fprintf(stderr, "Error: XKMS context is null\n"); + return(-1); + } + + /* set key info params */ + if(xmlSecAppPrepareKeyInfoReadCtx(&(xkmsServerCtx->keyInfoReadCtx)) < 0) { + fprintf(stderr, "Error: failed to prepare key info context\n"); + return(-1); + } + + if(xmlSecAppCmdLineParamGetString(&xkmsServiceParam) != NULL) { + xkmsServerCtx->expectedService = xmlStrdup(BAD_CAST xmlSecAppCmdLineParamGetString(&xkmsServiceParam)); + if(xkmsServerCtx->expectedService == NULL) { + fprintf(stderr, "Error: failed to duplicate string \"%s\"\n", + xmlSecAppCmdLineParamGetString(&xkmsServiceParam)); + return(-1); + } + } + + if(xmlSecAppCmdLineParamIsSet(&xkmsStopUnknownResponseMechanismParam)) { + xkmsServerCtx->flags |= XMLSEC_XKMS_SERVER_FLAGS_STOP_ON_UNKNOWN_RESPONSE_MECHANISM; + } + if(xmlSecAppCmdLineParamIsSet(&xkmsStopUnknownRespondWithParam)) { + xkmsServerCtx->flags |= XMLSEC_XKMS_SERVER_FLAGS_STOP_ON_UNKNOWN_RESPOND_WITH; + } + if(xmlSecAppCmdLineParamIsSet(&xkmsStopUnknownKeyUsageParam)) { + xkmsServerCtx->flags |= XMLSEC_XKMS_SERVER_FLAGS_STOP_ON_UNKNOWN_KEY_USAGE; + } + return(0); +} + +static void +xmlSecAppPrintXkmsServerCtx(xmlSecXkmsServerCtxPtr xkmsServerCtx) { + if(xkmsServerCtx == NULL) { + return; + } + + /* print debug info if requested */ + if((print_debug != 0) || xmlSecAppCmdLineParamIsSet(&printDebugParam)) { + xmlSecXkmsServerCtxDebugDump(xkmsServerCtx, stdout); + } + + if(xmlSecAppCmdLineParamIsSet(&printXmlDebugParam)) { + xmlSecXkmsServerCtxDebugXmlDump(xkmsServerCtx, stdout); + } +} + +#endif /* XMLSEC_NO_XKMS */ + +static void +xmlSecAppListKeyData(void) { + fprintf(stdout, "Registered key data klasses:\n"); + xmlSecKeyDataIdListDebugDump(xmlSecKeyDataIdsGet(), stdout); +} + +static int +xmlSecAppCheckKeyData(const char * name) { + if(xmlSecKeyDataIdListFindByName(xmlSecKeyDataIdsGet(), BAD_CAST name, xmlSecKeyDataUsageAny) == xmlSecKeyDataIdUnknown) { + return -1; + } + return 0; +} + +static void +xmlSecAppListTransforms(void) { + fprintf(stdout, "Registered transform klasses:\n"); + xmlSecTransformIdListDebugDump(xmlSecTransformIdsGet(), stdout); +} + +static int +xmlSecAppCheckTransform(const char * name) { + if(xmlSecTransformIdListFindByName(xmlSecTransformIdsGet(), BAD_CAST name, xmlSecTransformUsageAny) == xmlSecTransformIdUnknown) { + return -1; + } + return 0; +} + +static int +xmlSecAppPrepareKeyInfoReadCtx(xmlSecKeyInfoCtxPtr keyInfoCtx) { + xmlSecAppCmdLineValuePtr value; + int ret; + + if(keyInfoCtx == NULL) { + fprintf(stderr, "Error: key info context is null\n"); + return(-1); + } + +#ifndef XMLSEC_NO_X509 + if(xmlSecAppCmdLineParamIsSet(&verificationTimeParam)) { + keyInfoCtx->certsVerificationTime = xmlSecAppCmdLineParamGetTime(&verificationTimeParam, 0); + } + if(xmlSecAppCmdLineParamIsSet(&depthParam)) { + keyInfoCtx->certsVerificationDepth = xmlSecAppCmdLineParamGetInt(&depthParam, 0); + } + if(xmlSecAppCmdLineParamIsSet(&X509SkipStrictChecksParam)) { + keyInfoCtx->flags |= XMLSEC_KEYINFO_FLAGS_X509DATA_SKIP_STRICT_CHECKS; + } +#endif /* XMLSEC_NO_X509 */ + + /* read enabled key data list */ + for(value = enabledKeyDataParam.value; value != NULL; value = value->next) { + if(value->strListValue == NULL) { + fprintf(stderr, "Error: invalid value for option \"%s\".\n", + enabledKeyDataParam.fullName); + return(-1); + } else { + xmlSecKeyDataId dataId; + const char* p; + + for(p = value->strListValue; (p != NULL) && ((*p) != '\0'); p += strlen(p)) { + dataId = xmlSecKeyDataIdListFindByName(xmlSecKeyDataIdsGet(), BAD_CAST p, xmlSecKeyDataUsageAny); + if(dataId == xmlSecKeyDataIdUnknown) { + fprintf(stderr, "Error: key data \"%s\" is unknown.\n", p); + return(-1); + } + ret = xmlSecPtrListAdd(&(keyInfoCtx->enabledKeyData), (const xmlSecPtr)dataId); + if(ret < 0) { + fprintf(stderr, "Error: failed to enable key data \"%s\".\n", p); + return(-1); + } + } + } + } + + /* read enabled RetrievalMethod uris */ + if(xmlSecAppCmdLineParamGetStringList(&enabledRetrievalMethodUrisParam) != NULL) { + keyInfoCtx->retrievalMethodCtx.enabledUris = xmlSecAppGetUriType( + xmlSecAppCmdLineParamGetStringList(&enabledRetrievalMethodUrisParam)); + if(keyInfoCtx->retrievalMethodCtx.enabledUris == xmlSecTransformUriTypeNone) { + fprintf(stderr, "Error: failed to parse \"%s\"\n", + xmlSecAppCmdLineParamGetStringList(&enabledRetrievalMethodUrisParam)); + return(-1); + } + } + + return(0); +} + +static int +xmlSecAppLoadKeys(void) { + xmlSecAppCmdLineValuePtr value; + + if(gKeysMngr != NULL) { + fprintf(stderr, "Error: keys manager already initialized.\n"); + return(-1); + } + + /* create and initialize keys manager */ + gKeysMngr = xmlSecKeysMngrCreate(); + if(gKeysMngr == NULL) { + fprintf(stderr, "Error: failed to create keys manager.\n"); + return(-1); + } + if(xmlSecAppCryptoSimpleKeysMngrInit(gKeysMngr) < 0) { + fprintf(stderr, "Error: failed to initialize keys manager.\n"); + return(-1); + } + + /* generate new key file */ + for(value = genKeyParam.value; value != NULL; value = value->next) { + if(value->strValue == NULL) { + fprintf(stderr, "Error: invalid value for option \"%s\".\n", genKeyParam.fullName); + return(-1); + } else if(xmlSecAppCryptoSimpleKeysMngrKeyGenerate(gKeysMngr, value->strValue, value->paramNameValue) < 0) { + fprintf(stderr, "Error: failed to generate key \"%s\".\n", value->strValue); + return(-1); + } + } + + /* read all xml key files */ + for(value = keysFileParam.value; value != NULL; value = value->next) { + if(value->strValue == NULL) { + fprintf(stderr, "Error: invalid value for option \"%s\".\n", keysFileParam.fullName); + return(-1); + } else if(xmlSecAppCryptoSimpleKeysMngrLoad(gKeysMngr, value->strValue) < 0) { + fprintf(stderr, "Error: failed to load xml keys file \"%s\".\n", value->strValue); + return(-1); + } + } + + /* read all private keys */ + for(value = privkeyParam.value; value != NULL; value = value->next) { + if(value->strValue == NULL) { + fprintf(stderr, "Error: invalid value for option \"%s\".\n", + privkeyParam.fullName); + return(-1); + } else if(xmlSecAppCryptoSimpleKeysMngrKeyAndCertsLoad(gKeysMngr, + value->strListValue, + xmlSecAppCmdLineParamGetString(&pwdParam), + value->paramNameValue, + xmlSecKeyDataFormatPem) < 0) { + fprintf(stderr, "Error: failed to load private key from \"%s\".\n", + value->strListValue); + return(-1); + } + } + + for(value = privkeyDerParam.value; value != NULL; value = value->next) { + if(value->strValue == NULL) { + fprintf(stderr, "Error: invalid value for option \"%s\".\n", + privkeyDerParam.fullName); + return(-1); + } else if(xmlSecAppCryptoSimpleKeysMngrKeyAndCertsLoad(gKeysMngr, + value->strListValue, + xmlSecAppCmdLineParamGetString(&pwdParam), + value->paramNameValue, + xmlSecKeyDataFormatDer) < 0) { + fprintf(stderr, "Error: failed to load private key from \"%s\".\n", + value->strListValue); + return(-1); + } + } + + for(value = pkcs8PemParam.value; value != NULL; value = value->next) { + if(value->strValue == NULL) { + fprintf(stderr, "Error: invalid value for option \"%s\".\n", + pkcs8PemParam.fullName); + return(-1); + } else if(xmlSecAppCryptoSimpleKeysMngrKeyAndCertsLoad(gKeysMngr, + value->strListValue, + xmlSecAppCmdLineParamGetString(&pwdParam), + value->paramNameValue, + xmlSecKeyDataFormatPkcs8Pem) < 0) { + fprintf(stderr, "Error: failed to load private key from \"%s\".\n", + value->strListValue); + return(-1); + } + } + + for(value = pkcs8DerParam.value; value != NULL; value = value->next) { + if(value->strValue == NULL) { + fprintf(stderr, "Error: invalid value for option \"%s\".\n", + pkcs8DerParam.fullName); + return(-1); + } else if(xmlSecAppCryptoSimpleKeysMngrKeyAndCertsLoad(gKeysMngr, + value->strListValue, + xmlSecAppCmdLineParamGetString(&pwdParam), + value->paramNameValue, + xmlSecKeyDataFormatPkcs8Der) < 0) { + fprintf(stderr, "Error: failed to load private key from \"%s\".\n", + value->strListValue); + return(-1); + } + } + + /* read all public keys */ + for(value = pubkeyParam.value; value != NULL; value = value->next) { + if(value->strValue == NULL) { + fprintf(stderr, "Error: invalid value for option \"%s\".\n", + pubkeyParam.fullName); + return(-1); + } else if(xmlSecAppCryptoSimpleKeysMngrKeyAndCertsLoad(gKeysMngr, + value->strListValue, + xmlSecAppCmdLineParamGetString(&pwdParam), + value->paramNameValue, + xmlSecKeyDataFormatPem) < 0) { + fprintf(stderr, "Error: failed to load public key from \"%s\".\n", + value->strListValue); + return(-1); + } + } + + for(value = pubkeyDerParam.value; value != NULL; value = value->next) { + if(value->strValue == NULL) { + fprintf(stderr, "Error: invalid value for option \"%s\".\n", + pubkeyDerParam.fullName); + return(-1); + } else if(xmlSecAppCryptoSimpleKeysMngrKeyAndCertsLoad(gKeysMngr, + value->strListValue, + xmlSecAppCmdLineParamGetString(&pwdParam), + value->paramNameValue, + xmlSecKeyDataFormatDer) < 0) { + fprintf(stderr, "Error: failed to load public key from \"%s\".\n", + value->strListValue); + return(-1); + } + } + +#ifndef XMLSEC_NO_AES + /* read all AES keys */ + for(value = aeskeyParam.value; value != NULL; value = value->next) { + if(value->strValue == NULL) { + fprintf(stderr, "Error: invalid value for option \"%s\".\n", + aeskeyParam.fullName); + return(-1); + } else if(xmlSecAppCryptoSimpleKeysMngrBinaryKeyLoad(gKeysMngr, + "aes", value->strValue, value->paramNameValue) < 0) { + fprintf(stderr, "Error: failed to load aes key from \"%s\".\n", + value->strValue); + return(-1); + } + } +#endif /* XMLSEC_NO_AES */ + +#ifndef XMLSEC_NO_DES + /* read all des keys */ + for(value = deskeyParam.value; value != NULL; value = value->next) { + if(value->strValue == NULL) { + fprintf(stderr, "Error: invalid value for option \"%s\".\n", + deskeyParam.fullName); + return(-1); + } else if(xmlSecAppCryptoSimpleKeysMngrBinaryKeyLoad(gKeysMngr, + "des", value->strValue, value->paramNameValue) < 0) { + fprintf(stderr, "Error: failed to load des key from \"%s\".\n", + value->strValue); + return(-1); + } + } +#endif /* XMLSEC_NO_DES */ + +#ifndef XMLSEC_NO_HMAC + /* read all hmac keys */ + for(value = hmackeyParam.value; value != NULL; value = value->next) { + if(value->strValue == NULL) { + fprintf(stderr, "Error: invalid value for option \"%s\".\n", + hmackeyParam.fullName); + return(-1); + } else if(xmlSecAppCryptoSimpleKeysMngrBinaryKeyLoad(gKeysMngr, + "hmac", value->strValue, value->paramNameValue) < 0) { + fprintf(stderr, "Error: failed to load hmac key from \"%s\".\n", + value->strValue); + return(-1); + } + } +#endif /* XMLSEC_NO_HMAC */ + +#ifndef XMLSEC_NO_X509 + /* read all pkcs12 files */ + for(value = pkcs12Param.value; value != NULL; value = value->next) { + if(value->strValue == NULL) { + fprintf(stderr, "Error: invalid value for option \"%s\".\n", pkcs12Param.fullName); + return(-1); + } else if(xmlSecAppCryptoSimpleKeysMngrPkcs12KeyLoad(gKeysMngr, + value->strValue, + xmlSecAppCmdLineParamGetString(&pwdParam), + value->paramNameValue) < 0) { + fprintf(stderr, "Error: failed to load pkcs12 key from \"%s\".\n", + value->strValue); + return(-1); + } + } + + /* read all trusted certs */ + for(value = trustedParam.value; value != NULL; value = value->next) { + if(value->strValue == NULL) { + fprintf(stderr, "Error: invalid value for option \"%s\".\n", trustedParam.fullName); + return(-1); + } else if(xmlSecAppCryptoSimpleKeysMngrCertLoad(gKeysMngr, + value->strValue, xmlSecKeyDataFormatPem, + xmlSecKeyDataTypeTrusted) < 0) { + fprintf(stderr, "Error: failed to load trusted cert from \"%s\".\n", + value->strValue); + return(-1); + } + } + for(value = trustedDerParam.value; value != NULL; value = value->next) { + if(value->strValue == NULL) { + fprintf(stderr, "Error: invalid value for option \"%s\".\n", trustedDerParam.fullName); + return(-1); + } else if(xmlSecAppCryptoSimpleKeysMngrCertLoad(gKeysMngr, + value->strValue, xmlSecKeyDataFormatDer, + xmlSecKeyDataTypeTrusted) < 0) { + fprintf(stderr, "Error: failed to load trusted cert from \"%s\".\n", + value->strValue); + return(-1); + } + } + + + /* read all public keys in certs */ + for(value = pubkeyCertParam.value; value != NULL; value = value->next) { + if(value->strValue == NULL) { + fprintf(stderr, "Error: invalid value for option \"%s\".\n", + pubkeyCertParam.fullName); + return(-1); + } else if(xmlSecAppCryptoSimpleKeysMngrKeyAndCertsLoad(gKeysMngr, + value->strListValue, + xmlSecAppCmdLineParamGetString(&pwdParam), + value->paramNameValue, + xmlSecKeyDataFormatCertPem) < 0) { + fprintf(stderr, "Error: failed to load public key from \"%s\".\n", + value->strListValue); + return(-1); + } + } + + for(value = pubkeyCertDerParam.value; value != NULL; value = value->next) { + if(value->strValue == NULL) { + fprintf(stderr, "Error: invalid value for option \"%s\".\n", + pubkeyCertDerParam.fullName); + return(-1); + } else if(xmlSecAppCryptoSimpleKeysMngrKeyAndCertsLoad(gKeysMngr, + value->strListValue, + xmlSecAppCmdLineParamGetString(&pwdParam), + value->paramNameValue, + xmlSecKeyDataFormatCertDer) < 0) { + fprintf(stderr, "Error: failed to load public key from \"%s\".\n", + value->strListValue); + return(-1); + } + } + + + /* read all untrusted certs */ + for(value = untrustedParam.value; value != NULL; value = value->next) { + if(value->strValue == NULL) { + fprintf(stderr, "Error: invalid value for option \"%s\".\n", untrustedParam.fullName); + return(-1); + } else if(xmlSecAppCryptoSimpleKeysMngrCertLoad(gKeysMngr, + value->strValue, xmlSecKeyDataFormatPem, + xmlSecKeyDataTypeNone) < 0) { + fprintf(stderr, "Error: failed to load untrusted cert from \"%s\".\n", + value->strValue); + return(-1); + } + } + for(value = untrustedDerParam.value; value != NULL; value = value->next) { + if(value->strValue == NULL) { + fprintf(stderr, "Error: invalid value for option \"%s\".\n", untrustedDerParam.fullName); + return(-1); + } else if(xmlSecAppCryptoSimpleKeysMngrCertLoad(gKeysMngr, + value->strValue, xmlSecKeyDataFormatDer, + xmlSecKeyDataTypeNone) < 0) { + fprintf(stderr, "Error: failed to load untrusted cert from \"%s\".\n", + value->strValue); + return(-1); + } + } + +#endif /* XMLSEC_NO_X509 */ + + return(0); +} + +static int intialized = 0; + +#ifndef XMLSEC_NO_XSLT +static xsltSecurityPrefsPtr xsltSecPrefs = NULL; +#endif /* XMLSEC_NO_XSLT */ + +static int +xmlSecAppInit(void) { + if(intialized != 0) { + return(0); + } + intialized = 1; + + /* Init libxml */ + xmlInitParser(); + LIBXML_TEST_VERSION + xmlTreeIndentString = "\t"; +#ifndef XMLSEC_NO_XSLT + xmlIndentTreeOutput = 1; +#endif /* XMLSEC_NO_XSLT */ + + + /* Init libxslt */ +#ifndef XMLSEC_NO_XSLT + /* disable everything */ + xsltSecPrefs = xsltNewSecurityPrefs(); + xsltSetSecurityPrefs(xsltSecPrefs, XSLT_SECPREF_READ_FILE, xsltSecurityForbid); + xsltSetSecurityPrefs(xsltSecPrefs, XSLT_SECPREF_WRITE_FILE, xsltSecurityForbid); + xsltSetSecurityPrefs(xsltSecPrefs, XSLT_SECPREF_CREATE_DIRECTORY, xsltSecurityForbid); + xsltSetSecurityPrefs(xsltSecPrefs, XSLT_SECPREF_READ_NETWORK, xsltSecurityForbid); + xsltSetSecurityPrefs(xsltSecPrefs, XSLT_SECPREF_WRITE_NETWORK, xsltSecurityForbid); + xsltSetDefaultSecurityPrefs(xsltSecPrefs); +#endif /* XMLSEC_NO_XSLT */ + + /* Init xmlsec */ + if(xmlSecInit() < 0) { + fprintf(stderr, "Error: xmlsec intialization failed.\n"); + return(-1); + } + if(xmlSecCheckVersion() != 1) { + fprintf(stderr, "Error: loaded xmlsec library version is not compatible.\n"); + return(-1); + } + +#if !defined(XMLSEC_NO_CRYPTO_DYNAMIC_LOADING) && defined(XMLSEC_CRYPTO_DYNAMIC_LOADING) + if(xmlSecCryptoDLLoadLibrary(BAD_CAST xmlsec_crypto) < 0) { + fprintf(stderr, "Error: unable to load xmlsec-%s library. Make sure that you have\n" + "this it installed, check shared libraries path (LD_LIBRARY_PATH)\n" + "envornment variable or use \"--crypto\" option to specify different\n" + "crypto engine.\n", xmlsec_crypto); + return(-1); + } +#endif /* !defined(XMLSEC_NO_CRYPTO_DYNAMIC_LOADING) && defined(XMLSEC_CRYPTO_DYNAMIC_LOADING) */ + + /* Init Crypto */ + if(xmlSecAppCryptoInit(xmlSecAppCmdLineParamGetString(&cryptoConfigParam)) < 0) { + fprintf(stderr, "Error: xmlsec crypto intialization failed.\n"); + return(-1); + } + return(0); +} + +static void +xmlSecAppShutdown(void) { + if(intialized == 0) { + return; + } + + /* Shutdown Crypto */ + if(xmlSecAppCryptoShutdown() < 0) { + fprintf(stderr, "Error: xmlsec crypto shutdown failed.\n"); + } + + /* Shutdown xmlsec */ + if(xmlSecShutdown() < 0) { + fprintf(stderr, "Error: xmlsec shutdown failed.\n"); + } + + /* Shutdown libxslt/libxml */ +#ifndef XMLSEC_NO_XSLT + xsltFreeSecurityPrefs(xsltSecPrefs); + xsltCleanupGlobals(); +#endif /* XMLSEC_NO_XSLT */ + xmlCleanupParser(); +} + +static xmlSecAppXmlDataPtr +xmlSecAppXmlDataCreate(const char* filename, const xmlChar* defStartNodeName, const xmlChar* defStartNodeNs) { + xmlSecAppCmdLineValuePtr value; + xmlSecAppXmlDataPtr data; + xmlNodePtr cur = NULL; + + if(filename == NULL) { + fprintf(stderr, "Error: xml filename is null\n"); + return(NULL); + } + + /* create object */ + data = (xmlSecAppXmlDataPtr) xmlMalloc(sizeof(xmlSecAppXmlData)); + if(data == NULL) { + fprintf(stderr, "Error: failed to create xml data\n"); + return(NULL); + } + memset(data, 0, sizeof(xmlSecAppXmlData)); + + /* parse doc */ + data->doc = xmlSecParseFile(filename); + if(data->doc == NULL) { + fprintf(stderr, "Error: failed to parse xml file \"%s\"\n", + filename); + xmlSecAppXmlDataDestroy(data); + return(NULL); + } + + /* load dtd and set default attrs and ids */ + if(xmlSecAppCmdLineParamGetString(&dtdFileParam) != NULL) { + xmlValidCtxt ctx; + + data->dtd = xmlParseDTD(NULL, BAD_CAST xmlSecAppCmdLineParamGetString(&dtdFileParam)); + if(data->dtd == NULL) { + fprintf(stderr, "Error: failed to parse dtd file \"%s\"\n", + xmlSecAppCmdLineParamGetString(&dtdFileParam)); + xmlSecAppXmlDataDestroy(data); + return(NULL); + } + + memset(&ctx, 0, sizeof(ctx)); + /* we don't care is doc actually valid or not */ + xmlValidateDtd(&ctx, data->doc, data->dtd); + } + + /* set ID attributes from command line */ + for(value = idAttrParam.value; value != NULL; value = value->next) { + if(value->strValue == NULL) { + fprintf(stderr, "Error: invalid value for option \"%s\".\n", + idAttrParam.fullName); + xmlSecAppXmlDataDestroy(data); + return(NULL); + } else { + xmlChar* attrName = (value->paramNameValue != NULL) ? BAD_CAST value->paramNameValue : BAD_CAST "id"; + xmlChar* nodeName; + xmlChar* nsHref; + xmlChar* buf; + + buf = xmlStrdup(BAD_CAST value->strValue); + if(buf == NULL) { + fprintf(stderr, "Error: failed to duplicate string \"%s\"\n", value->strValue); + xmlSecAppXmlDataDestroy(data); + return(NULL); + } + nodeName = (xmlChar*)strrchr((char*)buf, ':'); + if(nodeName != NULL) { + (*(nodeName++)) = '\0'; + nsHref = buf; + } else { + nodeName = buf; + nsHref = NULL; + } + + /* process children first because it does not matter much but does simplify code */ + cur = xmlSecGetNextElementNode(data->doc->children); + while(cur != NULL) { + if(xmlSecAppAddIDAttr(cur, attrName, nodeName, nsHref) < 0) { + fprintf(stderr, "Error: failed to add ID attribute \"%s\" for node \"%s\"\n", attrName, value->strValue); + xmlFree(buf); + xmlSecAppXmlDataDestroy(data); + return(NULL); + } + cur = xmlSecGetNextElementNode(cur->next); + } + + xmlFree(buf); + } + } + + + /* now find the start node */ + if(xmlSecAppCmdLineParamGetString(&nodeIdParam) != NULL) { + xmlAttrPtr attr; + + attr = xmlGetID(data->doc, BAD_CAST xmlSecAppCmdLineParamGetString(&nodeIdParam)); + if(attr == NULL) { + fprintf(stderr, "Error: failed to find node with id=\"%s\"\n", + xmlSecAppCmdLineParamGetString(&nodeIdParam)); + xmlSecAppXmlDataDestroy(data); + return(NULL); + } + cur = attr->parent; + } else if(xmlSecAppCmdLineParamGetString(&nodeNameParam) != NULL) { + xmlChar* buf; + xmlChar* name; + xmlChar* ns; + + buf = xmlStrdup(BAD_CAST xmlSecAppCmdLineParamGetString(&nodeNameParam)); + if(buf == NULL) { + fprintf(stderr, "Error: failed to duplicate node \"%s\"\n", + xmlSecAppCmdLineParamGetString(&nodeNameParam)); + xmlSecAppXmlDataDestroy(data); + return(NULL); + } + name = (xmlChar*)strrchr((char*)buf, ':'); + if(name != NULL) { + (*(name++)) = '\0'; + ns = buf; + } else { + name = buf; + ns = NULL; + } + + cur = xmlSecFindNode(xmlDocGetRootElement(data->doc), name, ns); + if(cur == NULL) { + fprintf(stderr, "Error: failed to find node with name=\"%s\"\n", + name); + xmlFree(buf); + xmlSecAppXmlDataDestroy(data); + return(NULL); + } + xmlFree(buf); + } else if(xmlSecAppCmdLineParamGetString(&nodeXPathParam) != NULL) { + xmlXPathContextPtr ctx = NULL; + xmlXPathObjectPtr obj = NULL; + xmlNodePtr rootNode; + xmlNsPtr ns; + int ret; + + rootNode = xmlDocGetRootElement(data->doc); + if(rootNode == NULL) { + fprintf(stderr, "Error: failed to find root node\n"); + xmlSecAppXmlDataDestroy(data); + return(NULL); + } + + ctx = xmlXPathNewContext(data->doc); + if(ctx == NULL) { + fprintf(stderr, "Error: failed to create xpath context\n"); + xmlSecAppXmlDataDestroy(data); + return(NULL); + } + + /* register namespaces from the root node */ + for(ns = rootNode->nsDef; ns != NULL; ns = ns->next) { + if(ns->prefix != NULL){ + ret = xmlXPathRegisterNs(ctx, ns->prefix, ns->href); + if(ret != 0) { + fprintf(stderr, "Error: failed to register namespace \"%s\"\n", ns->prefix); + xmlXPathFreeContext(ctx); + xmlSecAppXmlDataDestroy(data); + return(NULL); + } + } + } + + obj = xmlXPathEval(BAD_CAST xmlSecAppCmdLineParamGetString(&nodeXPathParam), ctx); + if(obj == NULL) { + fprintf(stderr, "Error: failed to evaluate xpath expression\n"); + xmlXPathFreeContext(ctx); + xmlSecAppXmlDataDestroy(data); + return(NULL); + } + + if((obj->nodesetval == NULL) || (obj->nodesetval->nodeNr != 1)) { + fprintf(stderr, "Error: xpath expression evaluation does not return a single node as expected\n"); + xmlXPathFreeObject(obj); + xmlXPathFreeContext(ctx); + xmlSecAppXmlDataDestroy(data); + return(NULL); + } + + cur = obj->nodesetval->nodeTab[0]; + xmlXPathFreeContext(ctx); + xmlXPathFreeObject(obj); + + } else { + cur = xmlDocGetRootElement(data->doc); + if(cur == NULL) { + fprintf(stderr, "Error: failed to get root element\n"); + xmlSecAppXmlDataDestroy(data); + return(NULL); + } + } + + if(defStartNodeName != NULL) { + data->startNode = xmlSecFindNode(cur, defStartNodeName, defStartNodeNs); + if(data->startNode == NULL) { + fprintf(stderr, "Error: failed to find default node with name=\"%s\"\n", + defStartNodeName); + xmlSecAppXmlDataDestroy(data); + return(NULL); + } + } else { + data->startNode = cur; + } + + return(data); +} + +static void +xmlSecAppXmlDataDestroy(xmlSecAppXmlDataPtr data) { + if(data == NULL) { + fprintf(stderr, "Error: xml data is null\n"); + return; + } + if(data->dtd != NULL) { + xmlFreeDtd(data->dtd); + } + if(data->doc != NULL) { + xmlFreeDoc(data->doc); + } + memset(data, 0, sizeof(xmlSecAppXmlData)); + xmlFree(data); +} + +static xmlSecAppCommand +xmlSecAppParseCommand(const char* cmd, xmlSecAppCmdLineParamTopic* cmdLineTopics, xmlSecAppCommand* subCommand) { + if(subCommand != NULL) { + (*subCommand) = xmlSecAppCommandUnknown; + } + + if((cmd == NULL) || (cmdLineTopics == NULL)) { + return(xmlSecAppCommandUnknown); + } else + + if((strcmp(cmd, "help") == 0) || (strcmp(cmd, "--help") == 0)) { + (*cmdLineTopics) = 0; + return(xmlSecAppCommandHelp); + } else + + if((strcmp(cmd, "help-all") == 0) || (strcmp(cmd, "--help-all") == 0)) { + (*cmdLineTopics) = xmlSecAppCmdLineTopicAll; + return(xmlSecAppCommandHelp); + } else + + if((strncmp(cmd, "help-", 5) == 0) || (strncmp(cmd, "--help-", 7) == 0)) { + cmd = (cmd[0] == '-') ? cmd + 7 : cmd + 5; + if(subCommand) { + (*subCommand) = xmlSecAppParseCommand(cmd, cmdLineTopics, NULL); + } else { + (*cmdLineTopics) = 0; + } + return(xmlSecAppCommandHelp); + } else + + if((strcmp(cmd, "version") == 0) || (strcmp(cmd, "--version") == 0)) { + (*cmdLineTopics) = xmlSecAppCmdLineTopicVersion; + return(xmlSecAppCommandVersion); + } else + + if((strcmp(cmd, "list-key-data") == 0) || (strcmp(cmd, "--list-key-data") == 0)) { + (*cmdLineTopics) = xmlSecAppCmdLineTopicCryptoConfig; + return(xmlSecAppCommandListKeyData); + } else + + if((strcmp(cmd, "check-key-data") == 0) || (strcmp(cmd, "--check-key-data") == 0)) { + (*cmdLineTopics) = xmlSecAppCmdLineTopicCryptoConfig; + return(xmlSecAppCommandCheckKeyData); + } else + + if((strcmp(cmd, "list-transforms") == 0) || (strcmp(cmd, "--list-transforms") == 0)) { + (*cmdLineTopics) = xmlSecAppCmdLineTopicCryptoConfig; + return(xmlSecAppCommandListTransforms); + } else + + if((strcmp(cmd, "check-transforms") == 0) || (strcmp(cmd, "--check-transforms") == 0)) { + (*cmdLineTopics) = xmlSecAppCmdLineTopicCryptoConfig; + return(xmlSecAppCommandCheckTransforms); + } else + + if((strcmp(cmd, "keys") == 0) || (strcmp(cmd, "--keys") == 0)) { + (*cmdLineTopics) = + xmlSecAppCmdLineTopicGeneral | + xmlSecAppCmdLineTopicCryptoConfig | + xmlSecAppCmdLineTopicKeysMngr | + xmlSecAppCmdLineTopicX509Certs; + return(xmlSecAppCommandKeys); + } else + +#ifndef XMLSEC_NO_XMLDSIG + if((strcmp(cmd, "sign") == 0) || (strcmp(cmd, "--sign") == 0)) { + (*cmdLineTopics) = + xmlSecAppCmdLineTopicGeneral | + xmlSecAppCmdLineTopicCryptoConfig | + xmlSecAppCmdLineTopicDSigCommon | + xmlSecAppCmdLineTopicDSigSign | + xmlSecAppCmdLineTopicKeysMngr | + xmlSecAppCmdLineTopicX509Certs; + return(xmlSecAppCommandSign); + } else + + if((strcmp(cmd, "verify") == 0) || (strcmp(cmd, "--verify") == 0)) { + (*cmdLineTopics) = + xmlSecAppCmdLineTopicGeneral | + xmlSecAppCmdLineTopicCryptoConfig | + xmlSecAppCmdLineTopicDSigCommon | + xmlSecAppCmdLineTopicDSigVerify | + xmlSecAppCmdLineTopicKeysMngr | + xmlSecAppCmdLineTopicX509Certs; + return(xmlSecAppCommandVerify); + } else +#ifndef XMLSEC_NO_TMPL_TEST + if((strcmp(cmd, "sign-tmpl") == 0) || (strcmp(cmd, "--sign-tmpl") == 0)) { + (*cmdLineTopics) = + xmlSecAppCmdLineTopicGeneral | + xmlSecAppCmdLineTopicCryptoConfig | + xmlSecAppCmdLineTopicDSigCommon | + xmlSecAppCmdLineTopicDSigSign | + xmlSecAppCmdLineTopicKeysMngr | + xmlSecAppCmdLineTopicX509Certs; + return(xmlSecAppCommandSignTmpl); + } else +#endif /* XMLSEC_NO_TMPL_TEST */ + +#endif /* XMLSEC_NO_XMLDSIG */ + +#ifndef XMLSEC_NO_XMLENC + if((strcmp(cmd, "encrypt") == 0) || (strcmp(cmd, "--encrypt") == 0)) { + (*cmdLineTopics) = + xmlSecAppCmdLineTopicGeneral | + xmlSecAppCmdLineTopicCryptoConfig | + xmlSecAppCmdLineTopicEncCommon | + xmlSecAppCmdLineTopicEncEncrypt | + xmlSecAppCmdLineTopicKeysMngr | + xmlSecAppCmdLineTopicX509Certs; + return(xmlSecAppCommandEncrypt); + } else + + if((strcmp(cmd, "decrypt") == 0) || (strcmp(cmd, "--decrypt") == 0)) { + (*cmdLineTopics) = + xmlSecAppCmdLineTopicGeneral | + xmlSecAppCmdLineTopicCryptoConfig | + xmlSecAppCmdLineTopicEncCommon | + xmlSecAppCmdLineTopicEncDecrypt | + xmlSecAppCmdLineTopicKeysMngr | + xmlSecAppCmdLineTopicX509Certs; + return(xmlSecAppCommandDecrypt); + } else + +#ifndef XMLSEC_NO_TMPL_TEST + if((strcmp(cmd, "encrypt-tmpl") == 0) || (strcmp(cmd, "--encrypt-tmpl") == 0)) { + (*cmdLineTopics) = + xmlSecAppCmdLineTopicGeneral | + xmlSecAppCmdLineTopicCryptoConfig | + xmlSecAppCmdLineTopicEncCommon | + xmlSecAppCmdLineTopicEncEncrypt | + xmlSecAppCmdLineTopicKeysMngr | + xmlSecAppCmdLineTopicX509Certs; + return(xmlSecAppCommandEncryptTmpl); + } else +#endif /* XMLSEC_NO_TMPL_TEST */ +#endif /* XMLSEC_NO_XMLENC */ + +#ifndef XMLSEC_NO_XKMS + if(strcmp(cmd, "--xkms-server-request") == 0) { + (*cmdLineTopics) = + xmlSecAppCmdLineTopicGeneral | + xmlSecAppCmdLineTopicCryptoConfig | + xmlSecAppCmdLineTopicXkmsCommon | + xmlSecAppCmdLineTopicKeysMngr | + xmlSecAppCmdLineTopicX509Certs; + return(xmlSecAppCommandXkmsServerRequest); + } else +#endif /* XMLSEC_NO_XKMS */ + + if(1) { + (*cmdLineTopics) = 0; + return(xmlSecAppCommandUnknown); + } +} + +static void +xmlSecAppPrintHelp(xmlSecAppCommand command, xmlSecAppCmdLineParamTopic topics) { + switch(command) { + case xmlSecAppCommandUnknown: + case xmlSecAppCommandHelp: + fprintf(stdout, "%s%s\n", helpCommands1, helpCommands2); + break; + case xmlSecAppCommandVersion: + fprintf(stdout, "%s\n", helpVersion); + break; + case xmlSecAppCommandListKeyData: + fprintf(stdout, "%s\n", helpListKeyData); + break; + case xmlSecAppCommandCheckKeyData: + fprintf(stdout, "%s\n", helpCheckKeyData); + break; + case xmlSecAppCommandListTransforms: + fprintf(stdout, "%s\n", helpListTransforms); + break; + case xmlSecAppCommandCheckTransforms: + fprintf(stdout, "%s\n", helpCheckTransforms); + break; + case xmlSecAppCommandKeys: + fprintf(stdout, "%s\n", helpKeys); + break; + case xmlSecAppCommandSign: + fprintf(stdout, "%s\n", helpSign); + break; + case xmlSecAppCommandVerify: + fprintf(stdout, "%s\n", helpVerify); + break; + case xmlSecAppCommandEncrypt: + fprintf(stdout, "%s\n", helpEncrypt); + break; + case xmlSecAppCommandDecrypt: + fprintf(stdout, "%s\n", helpDecrypt); + break; + case xmlSecAppCommandSignTmpl: + fprintf(stdout, "%s\n", helpSignTmpl); + break; + case xmlSecAppCommandEncryptTmpl: + fprintf(stdout, "%s\n", helpEncryptTmpl); + break; + case xmlSecAppCommandXkmsServerRequest: + fprintf(stdout, "%s\n", helpXkmsServerRequest); + break; + } + if(topics != 0) { + fprintf(stdout, "Options:\n"); + xmlSecAppCmdLineParamsListPrint(parameters, topics, stdout); + fprintf(stdout, "\n"); + } + fprintf(stdout, "\n%s\n", bugs); + fprintf(stdout, "%s\n", copyright); +} + +static xmlSecTransformUriType +xmlSecAppGetUriType(const char* string) { + xmlSecTransformUriType type = xmlSecTransformUriTypeNone; + + while((string != NULL) && (string[0] != '\0')) { + if(strcmp(string, "empty") == 0) { + type |= xmlSecTransformUriTypeEmpty; + } else if(strcmp(string, "same-doc") == 0) { + type |= xmlSecTransformUriTypeSameDocument; + } else if(strcmp(string, "local") == 0) { + type |= xmlSecTransformUriTypeLocal; + } else if(strcmp(string, "remote") == 0) { + type |= xmlSecTransformUriTypeRemote; + } else { + fprintf(stderr, "Error: invalid uri type: \"%s\"\n", string); + return(xmlSecTransformUriTypeNone); + } + string += strlen(string) + 1; + } + return(type); +} + +static FILE* +xmlSecAppOpenFile(const char* filename) { + FILE* file; + + if((filename == NULL) || (strcmp(filename, "-") == 0)) { + return(stdout); + } + file = fopen(filename, "wb"); + if(file == NULL) { + fprintf(stderr, "Error: failed to open file \"%s\"\n", filename); + return(NULL); + } + + return(file); +} + +static void +xmlSecAppCloseFile(FILE* file) { + if((file == NULL) || (file == stdout) || (file == stderr)) { + return; + } + + fclose(file); +} + +static int +xmlSecAppWriteResult(xmlDocPtr doc, xmlSecBufferPtr buffer) { + FILE* f; + + f = xmlSecAppOpenFile(xmlSecAppCmdLineParamGetString(&outputParam)); + if(f == NULL) { + return(-1); + } + if(doc != NULL) { + xmlDocDump(f, doc); + } else if((buffer != NULL) && (xmlSecBufferGetData(buffer) != NULL)) { + fwrite(xmlSecBufferGetData(buffer), xmlSecBufferGetSize(buffer), 1, f); + } else { + fprintf(stderr, "Error: both result doc and result buffer are null\n"); + xmlSecAppCloseFile(f); + return(-1); + } + xmlSecAppCloseFile(f); + return(0); +} + +static int +xmlSecAppAddIDAttr(xmlNodePtr node, const xmlChar* attrName, const xmlChar* nodeName, const xmlChar* nsHref) { + xmlAttrPtr attr, tmpAttr; + xmlNodePtr cur; + xmlChar* id; + + if((node == NULL) || (attrName == NULL) || (nodeName == NULL)) { + return(-1); + } + + /* process children first because it does not matter much but does simplify code */ + cur = xmlSecGetNextElementNode(node->children); + while(cur != NULL) { + if(xmlSecAppAddIDAttr(cur, attrName, nodeName, nsHref) < 0) { + return(-1); + } + cur = xmlSecGetNextElementNode(cur->next); + } + + /* node name must match */ + if(!xmlStrEqual(node->name, nodeName)) { + return(0); + } + + /* if nsHref is set then it also should match */ + if((nsHref != NULL) && (node->ns != NULL) && (!xmlStrEqual(nsHref, node->ns->href))) { + return(0); + } + + /* the attribute with name equal to attrName should exist */ + for(attr = node->properties; attr != NULL; attr = attr->next) { + if(xmlStrEqual(attr->name, attrName)) { + break; + } + } + if(attr == NULL) { + return(0); + } + + /* and this attr should have a value */ + id = xmlNodeListGetString(node->doc, attr->children, 1); + if(id == NULL) { + return(0); + } + + /* check that we don't have same ID already */ + tmpAttr = xmlGetID(node->doc, id); + if(tmpAttr == NULL) { + xmlAddID(NULL, node->doc, id, attr); + } else if(tmpAttr != attr) { + fprintf(stderr, "Error: duplicate ID attribute \"%s\"\n", id); + xmlFree(id); + return(-1); + } + xmlFree(id); + return(0); +} + + + |