diff options
Diffstat (limited to 'src/gnutls')
-rw-r--r-- | src/gnutls/Makefile.am | 12 | ||||
-rw-r--r-- | src/gnutls/Makefile.in | 244 | ||||
-rw-r--r-- | src/gnutls/README | 11 | ||||
-rw-r--r-- | src/gnutls/app.c | 1047 | ||||
-rw-r--r-- | src/gnutls/asymkeys.c | 455 | ||||
-rw-r--r-- | src/gnutls/ciphers.c | 824 | ||||
-rw-r--r-- | src/gnutls/crypto.c | 304 | ||||
-rw-r--r-- | src/gnutls/digests.c | 346 | ||||
-rw-r--r-- | src/gnutls/globals.h | 11 | ||||
-rw-r--r-- | src/gnutls/hmac.c | 584 | ||||
-rw-r--r-- | src/gnutls/kw_aes.c | 72 | ||||
-rw-r--r-- | src/gnutls/kw_des.c | 51 | ||||
-rw-r--r-- | src/gnutls/signatures.c | 148 | ||||
-rw-r--r-- | src/gnutls/symkeys.c | 379 | ||||
-rw-r--r-- | src/gnutls/x509.c | 1960 | ||||
-rw-r--r-- | src/gnutls/x509utils.c | 1687 | ||||
-rw-r--r-- | src/gnutls/x509utils.h | 143 | ||||
-rw-r--r-- | src/gnutls/x509vfy.c | 802 |
18 files changed, 6704 insertions, 2376 deletions
diff --git a/src/gnutls/Makefile.am b/src/gnutls/Makefile.am index 7d639a34..84ce637a 100644 --- a/src/gnutls/Makefile.am +++ b/src/gnutls/Makefile.am @@ -24,7 +24,15 @@ libxmlsec1_gnutls_la_SOURCES =\ crypto.c \ digests.c \ hmac.c \ + kw_aes.c \ + kw_des.c \ symkeys.c \ + asymkeys.c \ + signatures.c \ + x509utils.h \ + x509utils.c \ + x509.c \ + x509vfy.c \ globals.h \ $(NULL) @@ -32,11 +40,13 @@ if SHAREDLIB_HACK libxmlsec1_gnutls_la_SOURCES += ../strings.c endif +# xmlsec-gnutls library requires xmlsec-gcrypt libxmlsec1_gnutls_la_LIBADD = \ - ../libxmlsec1.la \ $(GNUTLS_LIBS) \ $(LIBXSLT_LIBS) \ $(LIBXML_LIBS) \ + ../libxmlsec1.la \ + ../gcrypt/libxmlsec1-gcrypt.la \ $(NULL) libxmlsec1_gnutls_la_DEPENDENCIES = \ diff --git a/src/gnutls/Makefile.in b/src/gnutls/Makefile.in index f07a4b49..f4351c16 100644 --- a/src/gnutls/Makefile.in +++ b/src/gnutls/Makefile.in @@ -1,9 +1,9 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.3 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. +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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. @@ -38,10 +38,13 @@ host_triplet = @host@ subdir = src/gnutls DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.in +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 = $(SHELL) $(top_srcdir)/mkinstalldirs +mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = @@ -66,35 +69,65 @@ am__nobase_list = $(am__nobase_strip_setup); \ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } am__installdirs = "$(DESTDIR)$(libdir)" LTLIBRARIES = $(lib_LTLIBRARIES) am__DEPENDENCIES_1 = am__libxmlsec1_gnutls_la_SOURCES_DIST = app.c ciphers.c crypto.c \ - digests.c hmac.c symkeys.c globals.h ../strings.c + digests.c hmac.c kw_aes.c kw_des.c symkeys.c asymkeys.c \ + signatures.c x509utils.h x509utils.c x509.c x509vfy.c \ + globals.h ../strings.c am__objects_1 = @SHAREDLIB_HACK_TRUE@am__objects_2 = libxmlsec1_gnutls_la-strings.lo am_libxmlsec1_gnutls_la_OBJECTS = libxmlsec1_gnutls_la-app.lo \ libxmlsec1_gnutls_la-ciphers.lo libxmlsec1_gnutls_la-crypto.lo \ libxmlsec1_gnutls_la-digests.lo libxmlsec1_gnutls_la-hmac.lo \ - libxmlsec1_gnutls_la-symkeys.lo $(am__objects_1) \ + libxmlsec1_gnutls_la-kw_aes.lo libxmlsec1_gnutls_la-kw_des.lo \ + libxmlsec1_gnutls_la-symkeys.lo \ + libxmlsec1_gnutls_la-asymkeys.lo \ + libxmlsec1_gnutls_la-signatures.lo \ + libxmlsec1_gnutls_la-x509utils.lo libxmlsec1_gnutls_la-x509.lo \ + libxmlsec1_gnutls_la-x509vfy.lo $(am__objects_1) \ $(am__objects_2) libxmlsec1_gnutls_la_OBJECTS = $(am_libxmlsec1_gnutls_la_OBJECTS) -libxmlsec1_gnutls_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(libxmlsec1_gnutls_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +libxmlsec1_gnutls_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(libxmlsec1_gnutls_la_LDFLAGS) \ + $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(libxmlsec1_gnutls_la_SOURCES) DIST_SOURCES = $(am__libxmlsec1_gnutls_la_SOURCES_DIST) ETAGS = etags @@ -102,6 +135,7 @@ CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ @@ -116,6 +150,7 @@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ @@ -124,6 +159,10 @@ 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@ @@ -154,6 +193,7 @@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MAN2HTML = @MAN2HTML@ +MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MOZILLA_MIN_VERSION = @MOZILLA_MIN_VERSION@ MSCRYPTO_CFLAGS = @MSCRYPTO_CFLAGS@ @@ -185,8 +225,10 @@ 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_ENABLED = @PKG_CONFIG_ENABLED@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RM = @RM@ SED = @SED@ @@ -194,7 +236,6 @@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TAR = @TAR@ -U = @U@ VERSION = @VERSION@ XMLSEC_APP_DEFINES = @XMLSEC_APP_DEFINES@ XMLSEC_CFLAGS = @XMLSEC_CFLAGS@ @@ -213,6 +254,8 @@ 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@ @@ -222,6 +265,7 @@ 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@ @@ -257,6 +301,7 @@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ @@ -289,7 +334,6 @@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ -lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ @@ -325,12 +369,17 @@ libxmlsec1_gnutls_la_CPPFLAGS = \ $(NULL) libxmlsec1_gnutls_la_SOURCES = app.c ciphers.c crypto.c digests.c \ - hmac.c symkeys.c globals.h $(NULL) $(am__append_1) + hmac.c kw_aes.c kw_des.c symkeys.c asymkeys.c signatures.c \ + x509utils.h x509utils.c x509.c x509vfy.c globals.h $(NULL) \ + $(am__append_1) + +# xmlsec-gnutls library requires xmlsec-gcrypt libxmlsec1_gnutls_la_LIBADD = \ - ../libxmlsec1.la \ $(GNUTLS_LIBS) \ $(LIBXSLT_LIBS) \ $(LIBXML_LIBS) \ + ../libxmlsec1.la \ + ../gcrypt/libxmlsec1-gcrypt.la \ $(NULL) libxmlsec1_gnutls_la_DEPENDENCIES = \ @@ -406,8 +455,8 @@ clean-libLTLIBRARIES: echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done -libxmlsec1-gnutls.la: $(libxmlsec1_gnutls_la_OBJECTS) $(libxmlsec1_gnutls_la_DEPENDENCIES) - $(libxmlsec1_gnutls_la_LINK) -rpath $(libdir) $(libxmlsec1_gnutls_la_OBJECTS) $(libxmlsec1_gnutls_la_LIBADD) $(LIBS) +libxmlsec1-gnutls.la: $(libxmlsec1_gnutls_la_OBJECTS) $(libxmlsec1_gnutls_la_DEPENDENCIES) $(EXTRA_libxmlsec1_gnutls_la_DEPENDENCIES) + $(AM_V_CCLD)$(libxmlsec1_gnutls_la_LINK) -rpath $(libdir) $(libxmlsec1_gnutls_la_OBJECTS) $(libxmlsec1_gnutls_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -416,82 +465,138 @@ distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxmlsec1_gnutls_la-app.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxmlsec1_gnutls_la-asymkeys.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxmlsec1_gnutls_la-ciphers.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxmlsec1_gnutls_la-crypto.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxmlsec1_gnutls_la-digests.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxmlsec1_gnutls_la-hmac.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxmlsec1_gnutls_la-kw_aes.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxmlsec1_gnutls_la-kw_des.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxmlsec1_gnutls_la-signatures.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxmlsec1_gnutls_la-strings.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxmlsec1_gnutls_la-symkeys.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxmlsec1_gnutls_la-x509.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxmlsec1_gnutls_la-x509utils.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxmlsec1_gnutls_la-x509vfy.Plo@am__quote@ .c.o: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< libxmlsec1_gnutls_la-app.lo: app.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxmlsec1_gnutls_la-app.lo -MD -MP -MF $(DEPDIR)/libxmlsec1_gnutls_la-app.Tpo -c -o libxmlsec1_gnutls_la-app.lo `test -f 'app.c' || echo '$(srcdir)/'`app.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libxmlsec1_gnutls_la-app.Tpo $(DEPDIR)/libxmlsec1_gnutls_la-app.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='app.c' object='libxmlsec1_gnutls_la-app.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxmlsec1_gnutls_la-app.lo -MD -MP -MF $(DEPDIR)/libxmlsec1_gnutls_la-app.Tpo -c -o libxmlsec1_gnutls_la-app.lo `test -f 'app.c' || echo '$(srcdir)/'`app.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libxmlsec1_gnutls_la-app.Tpo $(DEPDIR)/libxmlsec1_gnutls_la-app.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='app.c' object='libxmlsec1_gnutls_la-app.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxmlsec1_gnutls_la-app.lo `test -f 'app.c' || echo '$(srcdir)/'`app.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxmlsec1_gnutls_la-app.lo `test -f 'app.c' || echo '$(srcdir)/'`app.c libxmlsec1_gnutls_la-ciphers.lo: ciphers.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxmlsec1_gnutls_la-ciphers.lo -MD -MP -MF $(DEPDIR)/libxmlsec1_gnutls_la-ciphers.Tpo -c -o libxmlsec1_gnutls_la-ciphers.lo `test -f 'ciphers.c' || echo '$(srcdir)/'`ciphers.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libxmlsec1_gnutls_la-ciphers.Tpo $(DEPDIR)/libxmlsec1_gnutls_la-ciphers.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ciphers.c' object='libxmlsec1_gnutls_la-ciphers.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxmlsec1_gnutls_la-ciphers.lo -MD -MP -MF $(DEPDIR)/libxmlsec1_gnutls_la-ciphers.Tpo -c -o libxmlsec1_gnutls_la-ciphers.lo `test -f 'ciphers.c' || echo '$(srcdir)/'`ciphers.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libxmlsec1_gnutls_la-ciphers.Tpo $(DEPDIR)/libxmlsec1_gnutls_la-ciphers.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ciphers.c' object='libxmlsec1_gnutls_la-ciphers.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxmlsec1_gnutls_la-ciphers.lo `test -f 'ciphers.c' || echo '$(srcdir)/'`ciphers.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxmlsec1_gnutls_la-ciphers.lo `test -f 'ciphers.c' || echo '$(srcdir)/'`ciphers.c libxmlsec1_gnutls_la-crypto.lo: crypto.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxmlsec1_gnutls_la-crypto.lo -MD -MP -MF $(DEPDIR)/libxmlsec1_gnutls_la-crypto.Tpo -c -o libxmlsec1_gnutls_la-crypto.lo `test -f 'crypto.c' || echo '$(srcdir)/'`crypto.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libxmlsec1_gnutls_la-crypto.Tpo $(DEPDIR)/libxmlsec1_gnutls_la-crypto.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto.c' object='libxmlsec1_gnutls_la-crypto.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxmlsec1_gnutls_la-crypto.lo -MD -MP -MF $(DEPDIR)/libxmlsec1_gnutls_la-crypto.Tpo -c -o libxmlsec1_gnutls_la-crypto.lo `test -f 'crypto.c' || echo '$(srcdir)/'`crypto.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libxmlsec1_gnutls_la-crypto.Tpo $(DEPDIR)/libxmlsec1_gnutls_la-crypto.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='crypto.c' object='libxmlsec1_gnutls_la-crypto.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxmlsec1_gnutls_la-crypto.lo `test -f 'crypto.c' || echo '$(srcdir)/'`crypto.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxmlsec1_gnutls_la-crypto.lo `test -f 'crypto.c' || echo '$(srcdir)/'`crypto.c libxmlsec1_gnutls_la-digests.lo: digests.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxmlsec1_gnutls_la-digests.lo -MD -MP -MF $(DEPDIR)/libxmlsec1_gnutls_la-digests.Tpo -c -o libxmlsec1_gnutls_la-digests.lo `test -f 'digests.c' || echo '$(srcdir)/'`digests.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libxmlsec1_gnutls_la-digests.Tpo $(DEPDIR)/libxmlsec1_gnutls_la-digests.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='digests.c' object='libxmlsec1_gnutls_la-digests.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxmlsec1_gnutls_la-digests.lo -MD -MP -MF $(DEPDIR)/libxmlsec1_gnutls_la-digests.Tpo -c -o libxmlsec1_gnutls_la-digests.lo `test -f 'digests.c' || echo '$(srcdir)/'`digests.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libxmlsec1_gnutls_la-digests.Tpo $(DEPDIR)/libxmlsec1_gnutls_la-digests.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='digests.c' object='libxmlsec1_gnutls_la-digests.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxmlsec1_gnutls_la-digests.lo `test -f 'digests.c' || echo '$(srcdir)/'`digests.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxmlsec1_gnutls_la-digests.lo `test -f 'digests.c' || echo '$(srcdir)/'`digests.c libxmlsec1_gnutls_la-hmac.lo: hmac.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxmlsec1_gnutls_la-hmac.lo -MD -MP -MF $(DEPDIR)/libxmlsec1_gnutls_la-hmac.Tpo -c -o libxmlsec1_gnutls_la-hmac.lo `test -f 'hmac.c' || echo '$(srcdir)/'`hmac.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libxmlsec1_gnutls_la-hmac.Tpo $(DEPDIR)/libxmlsec1_gnutls_la-hmac.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='hmac.c' object='libxmlsec1_gnutls_la-hmac.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxmlsec1_gnutls_la-hmac.lo -MD -MP -MF $(DEPDIR)/libxmlsec1_gnutls_la-hmac.Tpo -c -o libxmlsec1_gnutls_la-hmac.lo `test -f 'hmac.c' || echo '$(srcdir)/'`hmac.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libxmlsec1_gnutls_la-hmac.Tpo $(DEPDIR)/libxmlsec1_gnutls_la-hmac.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hmac.c' object='libxmlsec1_gnutls_la-hmac.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxmlsec1_gnutls_la-hmac.lo `test -f 'hmac.c' || echo '$(srcdir)/'`hmac.c + +libxmlsec1_gnutls_la-kw_aes.lo: kw_aes.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxmlsec1_gnutls_la-kw_aes.lo -MD -MP -MF $(DEPDIR)/libxmlsec1_gnutls_la-kw_aes.Tpo -c -o libxmlsec1_gnutls_la-kw_aes.lo `test -f 'kw_aes.c' || echo '$(srcdir)/'`kw_aes.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libxmlsec1_gnutls_la-kw_aes.Tpo $(DEPDIR)/libxmlsec1_gnutls_la-kw_aes.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='kw_aes.c' object='libxmlsec1_gnutls_la-kw_aes.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxmlsec1_gnutls_la-kw_aes.lo `test -f 'kw_aes.c' || echo '$(srcdir)/'`kw_aes.c + +libxmlsec1_gnutls_la-kw_des.lo: kw_des.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxmlsec1_gnutls_la-kw_des.lo -MD -MP -MF $(DEPDIR)/libxmlsec1_gnutls_la-kw_des.Tpo -c -o libxmlsec1_gnutls_la-kw_des.lo `test -f 'kw_des.c' || echo '$(srcdir)/'`kw_des.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libxmlsec1_gnutls_la-kw_des.Tpo $(DEPDIR)/libxmlsec1_gnutls_la-kw_des.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='kw_des.c' object='libxmlsec1_gnutls_la-kw_des.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxmlsec1_gnutls_la-hmac.lo `test -f 'hmac.c' || echo '$(srcdir)/'`hmac.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxmlsec1_gnutls_la-kw_des.lo `test -f 'kw_des.c' || echo '$(srcdir)/'`kw_des.c libxmlsec1_gnutls_la-symkeys.lo: symkeys.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxmlsec1_gnutls_la-symkeys.lo -MD -MP -MF $(DEPDIR)/libxmlsec1_gnutls_la-symkeys.Tpo -c -o libxmlsec1_gnutls_la-symkeys.lo `test -f 'symkeys.c' || echo '$(srcdir)/'`symkeys.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libxmlsec1_gnutls_la-symkeys.Tpo $(DEPDIR)/libxmlsec1_gnutls_la-symkeys.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='symkeys.c' object='libxmlsec1_gnutls_la-symkeys.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxmlsec1_gnutls_la-symkeys.lo -MD -MP -MF $(DEPDIR)/libxmlsec1_gnutls_la-symkeys.Tpo -c -o libxmlsec1_gnutls_la-symkeys.lo `test -f 'symkeys.c' || echo '$(srcdir)/'`symkeys.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libxmlsec1_gnutls_la-symkeys.Tpo $(DEPDIR)/libxmlsec1_gnutls_la-symkeys.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='symkeys.c' object='libxmlsec1_gnutls_la-symkeys.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxmlsec1_gnutls_la-symkeys.lo `test -f 'symkeys.c' || echo '$(srcdir)/'`symkeys.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxmlsec1_gnutls_la-symkeys.lo `test -f 'symkeys.c' || echo '$(srcdir)/'`symkeys.c + +libxmlsec1_gnutls_la-asymkeys.lo: asymkeys.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxmlsec1_gnutls_la-asymkeys.lo -MD -MP -MF $(DEPDIR)/libxmlsec1_gnutls_la-asymkeys.Tpo -c -o libxmlsec1_gnutls_la-asymkeys.lo `test -f 'asymkeys.c' || echo '$(srcdir)/'`asymkeys.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libxmlsec1_gnutls_la-asymkeys.Tpo $(DEPDIR)/libxmlsec1_gnutls_la-asymkeys.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='asymkeys.c' object='libxmlsec1_gnutls_la-asymkeys.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxmlsec1_gnutls_la-asymkeys.lo `test -f 'asymkeys.c' || echo '$(srcdir)/'`asymkeys.c + +libxmlsec1_gnutls_la-signatures.lo: signatures.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxmlsec1_gnutls_la-signatures.lo -MD -MP -MF $(DEPDIR)/libxmlsec1_gnutls_la-signatures.Tpo -c -o libxmlsec1_gnutls_la-signatures.lo `test -f 'signatures.c' || echo '$(srcdir)/'`signatures.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libxmlsec1_gnutls_la-signatures.Tpo $(DEPDIR)/libxmlsec1_gnutls_la-signatures.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='signatures.c' object='libxmlsec1_gnutls_la-signatures.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxmlsec1_gnutls_la-signatures.lo `test -f 'signatures.c' || echo '$(srcdir)/'`signatures.c + +libxmlsec1_gnutls_la-x509utils.lo: x509utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxmlsec1_gnutls_la-x509utils.lo -MD -MP -MF $(DEPDIR)/libxmlsec1_gnutls_la-x509utils.Tpo -c -o libxmlsec1_gnutls_la-x509utils.lo `test -f 'x509utils.c' || echo '$(srcdir)/'`x509utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libxmlsec1_gnutls_la-x509utils.Tpo $(DEPDIR)/libxmlsec1_gnutls_la-x509utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='x509utils.c' object='libxmlsec1_gnutls_la-x509utils.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxmlsec1_gnutls_la-x509utils.lo `test -f 'x509utils.c' || echo '$(srcdir)/'`x509utils.c + +libxmlsec1_gnutls_la-x509.lo: x509.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxmlsec1_gnutls_la-x509.lo -MD -MP -MF $(DEPDIR)/libxmlsec1_gnutls_la-x509.Tpo -c -o libxmlsec1_gnutls_la-x509.lo `test -f 'x509.c' || echo '$(srcdir)/'`x509.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libxmlsec1_gnutls_la-x509.Tpo $(DEPDIR)/libxmlsec1_gnutls_la-x509.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='x509.c' object='libxmlsec1_gnutls_la-x509.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxmlsec1_gnutls_la-x509.lo `test -f 'x509.c' || echo '$(srcdir)/'`x509.c + +libxmlsec1_gnutls_la-x509vfy.lo: x509vfy.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxmlsec1_gnutls_la-x509vfy.lo -MD -MP -MF $(DEPDIR)/libxmlsec1_gnutls_la-x509vfy.Tpo -c -o libxmlsec1_gnutls_la-x509vfy.lo `test -f 'x509vfy.c' || echo '$(srcdir)/'`x509vfy.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libxmlsec1_gnutls_la-x509vfy.Tpo $(DEPDIR)/libxmlsec1_gnutls_la-x509vfy.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='x509vfy.c' object='libxmlsec1_gnutls_la-x509vfy.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxmlsec1_gnutls_la-x509vfy.lo `test -f 'x509vfy.c' || echo '$(srcdir)/'`x509vfy.c libxmlsec1_gnutls_la-strings.lo: ../strings.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxmlsec1_gnutls_la-strings.lo -MD -MP -MF $(DEPDIR)/libxmlsec1_gnutls_la-strings.Tpo -c -o libxmlsec1_gnutls_la-strings.lo `test -f '../strings.c' || echo '$(srcdir)/'`../strings.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libxmlsec1_gnutls_la-strings.Tpo $(DEPDIR)/libxmlsec1_gnutls_la-strings.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='../strings.c' object='libxmlsec1_gnutls_la-strings.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libxmlsec1_gnutls_la-strings.lo -MD -MP -MF $(DEPDIR)/libxmlsec1_gnutls_la-strings.Tpo -c -o libxmlsec1_gnutls_la-strings.lo `test -f '../strings.c' || echo '$(srcdir)/'`../strings.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libxmlsec1_gnutls_la-strings.Tpo $(DEPDIR)/libxmlsec1_gnutls_la-strings.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../strings.c' object='libxmlsec1_gnutls_la-strings.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxmlsec1_gnutls_la-strings.lo `test -f '../strings.c' || echo '$(srcdir)/'`../strings.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxmlsec1_gnutls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libxmlsec1_gnutls_la-strings.lo `test -f '../strings.c' || echo '$(srcdir)/'`../strings.c mostlyclean-libtool: -rm -f *.lo @@ -598,10 +703,15 @@ install-am: all-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 + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi mostlyclean-generic: clean-generic: diff --git a/src/gnutls/README b/src/gnutls/README index 02c5fbbf..404aa878 100644 --- a/src/gnutls/README +++ b/src/gnutls/README @@ -1,9 +1,6 @@ -The xmlsec-gnutls implementation is really limited and is not ready -for production use. The only supported crypto transforms are: +The xmlsec-gnutls uses both libgcrypt and libgnutls because GnuTLS +does not provide direct access to low-level crypto operations (digests, +hmac, aes, des, etc.). + - - HMAC - - Tripple DES - - AES [128|192|256] - - SHA1 -
\ No newline at end of file diff --git a/src/gnutls/app.c b/src/gnutls/app.c index 54da1999..856257f3 100644 --- a/src/gnutls/app.c +++ b/src/gnutls/app.c @@ -1,17 +1,15 @@ -/** +/** * XMLSec library * * This is free software; see Copyright file in the source * distribution for preciese wording. - * + * * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com> */ #include "globals.h" #include <string.h> -#include <gnutls/gnutls.h> - #include <xmlsec/xmlsec.h> #include <xmlsec/keys.h> #include <xmlsec/transforms.h> @@ -19,38 +17,56 @@ #include <xmlsec/gnutls/app.h> #include <xmlsec/gnutls/crypto.h> +#include <xmlsec/gnutls/x509.h> + +#include "x509utils.h" + +/************************************************************************** + * + * We use xmlsec-gcrypt for all the basic crypto ops + * + *****************************************************************************/ +#include <xmlsec/gcrypt/crypto.h> +#include <xmlsec/gcrypt/app.h> + +static xmlSecKeyPtr xmlSecGnuTLSAppKeyFromCertLoad (const char *filename, + xmlSecKeyDataFormat format); +static xmlSecKeyPtr xmlSecGnuTLSAppKeyFromCertLoadMemory (const xmlSecByte* data, + xmlSecSize dataSize, + xmlSecKeyDataFormat format); /** * xmlSecGnuTLSAppInit: - * @config: the path to GnuTLS configuration (unused). - * + * @config: the path to GnuTLS configuration (unused). + * * General crypto engine initialization. This function is used - * by XMLSec command line utility and called before + * by XMLSec command line utility and called before * @xmlSecInit function. * * Returns: 0 on success or a negative value otherwise. */ int -xmlSecGnuTLSAppInit(const char* config ATTRIBUTE_UNUSED) { - int ret; - - ret = gnutls_global_init(); - if(ret != 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "gnutls_global_init", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - "ret=%d", ret); - return(-1); +xmlSecGnuTLSAppInit(const char* config) { + int err; + + err = gnutls_global_init(); + if(err != GNUTLS_E_SUCCESS) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_global_init", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + return(-1); } - return(0); + + return(xmlSecGCryptAppInit(config)); } /** * xmlSecGnuTLSAppShutdown: - * + * * General crypto engine shutdown. This function is used - * by XMLSec command line utility and called after + * by XMLSec command line utility and called after * @xmlSecShutdown function. * * Returns: 0 on success or a negative value otherwise. @@ -58,304 +74,787 @@ xmlSecGnuTLSAppInit(const char* config ATTRIBUTE_UNUSED) { int xmlSecGnuTLSAppShutdown(void) { gnutls_global_deinit(); - return(0); + + return(xmlSecGCryptAppShutdown()); } /** * xmlSecGnuTLSAppKeyLoad: - * @filename: the key filename. - * @format: the key file format. - * @pwd: the key file password. - * @pwdCallback: the key password callback. - * @pwdCallbackCtx: the user context for password callback. + * @filename: the key filename. + * @format: the key file format. + * @pwd: the key file password. + * @pwdCallback: the key password callback. + * @pwdCallbackCtx: the user context for password callback. * - * Reads key from the a file (not implemented yet). + * Reads key from the a file. * * Returns: pointer to the key or NULL if an error occurs. */ xmlSecKeyPtr xmlSecGnuTLSAppKeyLoad(const char *filename, xmlSecKeyDataFormat format, - const char *pwd, - void* pwdCallback, - void* pwdCallbackCtx) { + const char *pwd, + void* pwdCallback, + void* pwdCallbackCtx) { + xmlSecKeyPtr key; + xmlSecAssert2(filename != NULL, NULL); xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, NULL); - - if (format == xmlSecKeyDataFormatPkcs12) { - return (xmlSecGnuTLSAppPkcs12Load(filename, pwd, pwdCallback, - pwdCallbackCtx)); + switch(format) { +#ifndef XMLSEC_NO_X509 + case xmlSecKeyDataFormatPkcs12: + key = xmlSecGnuTLSAppPkcs12Load(filename, pwd, pwdCallback, pwdCallbackCtx); + break; + case xmlSecKeyDataFormatCertPem: + case xmlSecKeyDataFormatCertDer: + key = xmlSecGnuTLSAppKeyFromCertLoad(filename, format); + break; +#endif /* XMLSEC_NO_X509 */ + default: + key = xmlSecGCryptAppKeyLoad(filename, format, pwd, pwdCallback, pwdCallbackCtx); + break; } - /* TODO */ - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecGnuTLSAppKeyLoad", - XMLSEC_ERRORS_R_NOT_IMPLEMENTED, - XMLSEC_ERRORS_NO_MESSAGE); - return(NULL); + return(key); } /** * xmlSecGnuTLSAppKeyLoadMemory: - * @data: the binary key data. - * @dataSize: the size of binary key. - * @format: the key file format. - * @pwd: the key file password. - * @pwdCallback: the key password callback. - * @pwdCallbackCtx: the user context for password callback. + * @data: the binary key data. + * @dataSize: the size of binary key. + * @format: the key file format. + * @pwd: the key file password. + * @pwdCallback: the key password callback. + * @pwdCallbackCtx: the user context for password callback. * - * Reads key from the memory buffer (not implemented yet). + * Reads key from the memory buffer. * * Returns: pointer to the key or NULL if an error occurs. */ xmlSecKeyPtr -xmlSecGnuTLSAppKeyLoadMemory(const xmlSecByte* data, xmlSecSize dataSize, - xmlSecKeyDataFormat format, const char *pwd, - void* pwdCallback, void* pwdCallbackCtx) { +xmlSecGnuTLSAppKeyLoadMemory(const xmlSecByte* data, xmlSecSize dataSize, + xmlSecKeyDataFormat format, const char *pwd, + void* pwdCallback, void* pwdCallbackCtx) { + xmlSecKeyPtr key; + xmlSecAssert2(data != NULL, NULL); xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, NULL); - if (format == xmlSecKeyDataFormatPkcs12) { - return (xmlSecGnuTLSAppPkcs12LoadMemory(data, dataSize, pwd, - pwdCallback, pwdCallbackCtx)); + switch(format) { +#ifndef XMLSEC_NO_X509 + case xmlSecKeyDataFormatPkcs12: + key = xmlSecGnuTLSAppPkcs12LoadMemory(data, dataSize, pwd, pwdCallback, pwdCallbackCtx); + break; + case xmlSecKeyDataFormatCertPem: + case xmlSecKeyDataFormatCertDer: + key = xmlSecGnuTLSAppKeyFromCertLoadMemory(data, dataSize, format); + break; +#endif /* XMLSEC_NO_X509 */ + default: + key = xmlSecGCryptAppKeyLoadMemory(data, dataSize, format, pwd, pwdCallback, pwdCallbackCtx); + break; } - - /* TODO */ - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecGnuTLSAppKeyLoadMemory", - XMLSEC_ERRORS_R_NOT_IMPLEMENTED, - XMLSEC_ERRORS_NO_MESSAGE); - return(NULL); + return(key); } #ifndef XMLSEC_NO_X509 /** * xmlSecGnuTLSAppKeyCertLoad: - * @key: the pointer to key. - * @filename: the certificate filename. - * @format: the certificate file format. + * @key: the pointer to key. + * @filename: the certificate filename. + * @format: the certificate file format. + * + * Reads the certificate from $@filename and adds it to key. * - * Reads the certificate from $@filename and adds it to key - * (not implemented yet). - * * Returns: 0 on success or a negative value otherwise. */ -int -xmlSecGnuTLSAppKeyCertLoad(xmlSecKeyPtr key, const char* filename, - xmlSecKeyDataFormat format) { +int +xmlSecGnuTLSAppKeyCertLoad(xmlSecKeyPtr key, const char* filename, + xmlSecKeyDataFormat format) { + xmlSecBuffer buffer; + int ret; + xmlSecAssert2(key != NULL, -1); xmlSecAssert2(filename != NULL, -1); xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, -1); - - /* TODO */ - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecGnuTLSAppKeyCertLoad", - XMLSEC_ERRORS_R_NOT_IMPLEMENTED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); + + ret = xmlSecBufferInitialize(&buffer, 4*1024); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBufferInitialize", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + ret = xmlSecBufferReadFile(&buffer, filename); + if((ret < 0) || (xmlSecBufferGetData(&buffer) == NULL) || (xmlSecBufferGetSize(&buffer) <= 0)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBufferReadFile", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "filename=%s", + xmlSecErrorsSafeString(filename)); + xmlSecBufferFinalize(&buffer); + return(-1); + } + + ret = xmlSecGnuTLSAppKeyCertLoadMemory(key, + xmlSecBufferGetData(&buffer), + xmlSecBufferGetSize(&buffer), + format); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSAppKeyCertLoadMemory", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "filename=%s", + xmlSecErrorsSafeString(filename)); + xmlSecBufferFinalize(&buffer); + return(-1); + } + + /* cleanup */ + xmlSecBufferFinalize(&buffer); + return(0); } /** * xmlSecGnuTLSAppKeyCertLoadMemory: - * @key: the pointer to key. - * @data: the certificate binary data. - * @dataSize: the certificate binary data size. - * @format: the certificate file format. + * @key: the pointer to key. + * @data: the certificate binary data. + * @dataSize: the certificate binary data size. + * @format: the certificate file format. + * + * Reads the certificate from memory buffer and adds it to key. * - * Reads the certificate from memory buffer and adds it to key (not implemented yet). - * * Returns: 0 on success or a negative value otherwise. */ -int -xmlSecGnuTLSAppKeyCertLoadMemory(xmlSecKeyPtr key, const xmlSecByte* data, xmlSecSize dataSize, - xmlSecKeyDataFormat format) { +int +xmlSecGnuTLSAppKeyCertLoadMemory(xmlSecKeyPtr key, + const xmlSecByte* data, + xmlSecSize dataSize, + xmlSecKeyDataFormat format) { + gnutls_x509_crt_t cert; + xmlSecKeyDataPtr keyData; + int ret; + xmlSecAssert2(key != NULL, -1); xmlSecAssert2(data != NULL, -1); + xmlSecAssert2(dataSize > 0, -1); xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, -1); - /* TODO */ - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecGnuTLSAppKeyCertLoadMemory", - XMLSEC_ERRORS_R_NOT_IMPLEMENTED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); + keyData = xmlSecKeyEnsureData(key, xmlSecGnuTLSKeyDataX509Id); + if(keyData == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeyEnsureData", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + cert = xmlSecGnuTLSX509CertRead(data, dataSize, format); + if(cert == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSX509CertRead", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + ret = xmlSecGnuTLSKeyDataX509AdoptCert(keyData, cert); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSKeyDataX509AdoptCert", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + gnutls_x509_crt_deinit(cert); + return(-1); + } + + return(0); } /** * xmlSecGnuTLSAppPkcs12Load: - * @filename: the PKCS12 key filename. - * @pwd: the PKCS12 file password. - * @pwdCallback: the password callback. - * @pwdCallbackCtx: the user context for password callback. + * @filename: the PKCS12 key filename. + * @pwd: the PKCS12 file password. + * @pwdCallback: the password callback. + * @pwdCallbackCtx: the user context for password callback. * - * Reads key and all associated certificates from the PKCS12 file - * (not implemented yet). + * Reads key and all associated certificates from the PKCS12 file. * For uniformity, call xmlSecGnuTLSAppKeyLoad instead of this function. Pass * in format=xmlSecKeyDataFormatPkcs12. * * Returns: pointer to the key or NULL if an error occurs. */ -xmlSecKeyPtr -xmlSecGnuTLSAppPkcs12Load(const char *filename, - const char *pwd ATTRIBUTE_UNUSED, - void* pwdCallback ATTRIBUTE_UNUSED, - void* pwdCallbackCtx ATTRIBUTE_UNUSED) { +xmlSecKeyPtr +xmlSecGnuTLSAppPkcs12Load(const char *filename, + const char *pwd, + void* pwdCallback, + void* pwdCallbackCtx) { + xmlSecKeyPtr key; + xmlSecBuffer buffer; + int ret; + xmlSecAssert2(filename != NULL, NULL); - /* TODO */ - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecGnuTLSAppPkcs12Load", - XMLSEC_ERRORS_R_NOT_IMPLEMENTED, - XMLSEC_ERRORS_NO_MESSAGE); - return(NULL); + ret = xmlSecBufferInitialize(&buffer, 4*1024); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBufferInitialize", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(NULL); + } + + ret = xmlSecBufferReadFile(&buffer, filename); + if((ret < 0) || (xmlSecBufferGetData(&buffer) == NULL) || (xmlSecBufferGetSize(&buffer) <= 0)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBufferReadFile", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "filename=%s", + xmlSecErrorsSafeString(filename)); + xmlSecBufferFinalize(&buffer); + return(NULL); + } + + key = xmlSecGnuTLSAppPkcs12LoadMemory(xmlSecBufferGetData(&buffer), + xmlSecBufferGetSize(&buffer), + pwd, pwdCallback, pwdCallbackCtx); + if(key == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSAppPkcs12LoadMemory", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "filename=%s", + xmlSecErrorsSafeString(filename)); + xmlSecBufferFinalize(&buffer); + return(NULL); + } + + /* cleanup */ + xmlSecBufferFinalize(&buffer); + return(key); } /** * xmlSecGnuTLSAppPkcs12LoadMemory: - * @data: the PKCS12 binary data. - * @dataSize: the PKCS12 binary data size. - * @pwd: the PKCS12 file password. - * @pwdCallback: the password callback. - * @pwdCallbackCtx: the user context for password callback. + * @data: the PKCS12 binary data. + * @dataSize: the PKCS12 binary data size. + * @pwd: the PKCS12 file password. + * @pwdCallback: the password callback. + * @pwdCallbackCtx: the user context for password callback. * * Reads key and all associated certificates from the PKCS12 data in memory buffer. * For uniformity, call xmlSecGnuTLSAppKeyLoadMemory instead of this function. Pass - * in format=xmlSecKeyDataFormatPkcs12 (not implemented yet). + * in format=xmlSecKeyDataFormatPkcs12. * * Returns: pointer to the key or NULL if an error occurs. */ -xmlSecKeyPtr -xmlSecGnuTLSAppPkcs12LoadMemory(const xmlSecByte* data, xmlSecSize dataSize, - const char *pwd, void* pwdCallback, - void* pwdCallbackCtx) { +xmlSecKeyPtr +xmlSecGnuTLSAppPkcs12LoadMemory(const xmlSecByte* data, xmlSecSize dataSize, + const char *pwd, + void* pwdCallback ATTRIBUTE_UNUSED, + void* pwdCallbackCtx ATTRIBUTE_UNUSED) +{ + xmlSecKeyPtr key = NULL; + xmlSecKeyPtr res = NULL; + xmlSecPtrList certsList; + xmlSecKeyDataPtr keyData = NULL; + xmlSecKeyDataPtr x509Data = NULL; + gnutls_x509_privkey_t priv_key = NULL; + gnutls_x509_crt_t key_cert = NULL; + xmlSecSize certsSize; + int ret; + xmlSecAssert2(data != NULL, NULL); - /* TODO */ - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecGnuTLSAppPkcs12LoadMemory", - XMLSEC_ERRORS_R_NOT_IMPLEMENTED, - XMLSEC_ERRORS_NO_MESSAGE); - return(NULL); + xmlSecAssert2(dataSize > 0, NULL); + + /* prepare */ + ret = xmlSecPtrListInitialize(&(certsList), xmlSecGnuTLSX509CrtListId); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecPtrListInitialize", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "certsList"); + return(NULL); + } + + /* load pkcs12 */ + ret = xmlSecGnuTLSPkcs12LoadMemory(data, dataSize, pwd, &priv_key, &key_cert, &certsList); + if((ret < 0) || (priv_key == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSPkcs12LoadMemory", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + goto done; + } + + /* create key */ + key = xmlSecKeyCreate(); + if(key == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeyCreate", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + goto done; + } + + /* create key value data */ + keyData = xmlSecGnuTLSCreateKeyDataAndAdoptPrivKey(priv_key); + if(keyData == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSCreateKeyDataAndAdoptPrivKey", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + goto done; + } + priv_key = NULL; /* owned by keyData now */ + + ret = xmlSecKeySetValue(key, keyData); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeySetValue", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "data=%s", + xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data))); + goto done; + } + keyData = NULL; /* owned by key now */ + + + /* create x509 certs data */ + certsSize = xmlSecPtrListGetSize(&certsList); + if((certsSize > 0) || (key_cert != NULL)) { + xmlSecSize ii; + + x509Data = xmlSecKeyDataCreate(xmlSecGnuTLSKeyDataX509Id); + if(x509Data == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeyDataCreate(xmlSecGnuTLSKeyDataX509Id)", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + goto done; + } + + /* set key's cert */ + if(key_cert != NULL) { + ret = xmlSecGnuTLSKeyDataX509AdoptKeyCert(x509Data, key_cert); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSKeyDataX509AdoptKeyCert", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + goto done; + } + key_cert = NULL; /* owned by x509Data now */ + } + + /* copy all other certs */ + for(ii = 0; ii < certsSize; ++ii) { + gnutls_x509_crt_t cert = xmlSecPtrListRemoveAndReturn(&certsList, ii); + if(cert == NULL) { + continue; + } + + ret = xmlSecGnuTLSKeyDataX509AdoptCert(x509Data, cert); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSKeyDataX509AdoptCert", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + gnutls_x509_crt_deinit(cert); + goto done; + } + } + + /* set in the key */ + ret = xmlSecKeyAdoptData(key, x509Data); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeyAdoptData", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "data=%s", + xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data))); + goto done; + } + x509Data = NULL; /* owned by key now */ + } + + /* success!!! */ + res = key; + key = NULL; + +done: + if(key_cert != NULL) { + gnutls_x509_crt_deinit(key_cert); + } + if(priv_key != NULL) { + gnutls_x509_privkey_deinit(priv_key); + } + if(keyData != NULL) { + xmlSecKeyDataDestroy(keyData); + } + if(x509Data != NULL) { + xmlSecKeyDataDestroy(x509Data); + } + if(key != NULL) { + xmlSecKeyDestroy(key); + } + xmlSecPtrListFinalize(&certsList); + return(res); +} + +static xmlSecKeyPtr +xmlSecGnuTLSAppKeyFromCertLoad(const char *filename, + xmlSecKeyDataFormat format) +{ + xmlSecKeyPtr key; + xmlSecBuffer buffer; + int ret; + + xmlSecAssert2(filename != NULL, NULL); + + ret = xmlSecBufferInitialize(&buffer, 4*1024); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBufferInitialize", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(NULL); + } + + ret = xmlSecBufferReadFile(&buffer, filename); + if((ret < 0) || (xmlSecBufferGetData(&buffer) == NULL) || (xmlSecBufferGetSize(&buffer) <= 0)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBufferReadFile", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "filename=%s", + xmlSecErrorsSafeString(filename)); + xmlSecBufferFinalize(&buffer); + return(NULL); + } + + key = xmlSecGnuTLSAppKeyFromCertLoadMemory( + xmlSecBufferGetData(&buffer), + xmlSecBufferGetSize(&buffer), + format); + if(key == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSAppKeyFromCertLoadMemory", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "filename=%s", + xmlSecErrorsSafeString(filename)); + xmlSecBufferFinalize(&buffer); + return(NULL); + } + + /* cleanup */ + xmlSecBufferFinalize(&buffer); + return(key); +} + +static xmlSecKeyPtr +xmlSecGnuTLSAppKeyFromCertLoadMemory(const xmlSecByte* data, + xmlSecSize dataSize, + xmlSecKeyDataFormat format) +{ + xmlSecKeyPtr key = NULL; + xmlSecKeyDataPtr keyData = NULL; + xmlSecKeyDataPtr x509Data = NULL; + gnutls_x509_crt_t cert = NULL; + xmlSecKeyPtr res = NULL; + int ret; + + xmlSecAssert2(data != NULL, NULL); + xmlSecAssert2(dataSize > 0, NULL); + xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, NULL); + + /* read cert */ + cert = xmlSecGnuTLSX509CertRead(data, dataSize, format); + if(cert == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSX509CertRead", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + goto done; + } + + /* create key */ + key = xmlSecKeyCreate(); + if(key == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeyCreate", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + goto done; + } + + /* create key value data */ + keyData = xmlSecGnuTLSX509CertGetKey(cert); + if(keyData == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSX509CertGetKey", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + goto done; + } + + ret = xmlSecKeySetValue(key, keyData); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeySetValue", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "data=%s", + xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data))); + goto done; + } + keyData = NULL; /* owned by key now */ + + /* create x509 data */ + x509Data = xmlSecKeyEnsureData(key, xmlSecGnuTLSKeyDataX509Id); + if(x509Data == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeyEnsureData", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + goto done; + } + ret = xmlSecGnuTLSKeyDataX509AdoptKeyCert(x509Data, cert); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSKeyDataX509AdoptKeyCert", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + goto done; + } + cert = NULL; /* owned by x509Data now */ + + /* success */ + res = key; + key = NULL; + +done: + if(cert != NULL) { + gnutls_x509_crt_deinit(cert); + } + if(keyData != NULL) { + xmlSecKeyDataDestroy(keyData); + } + if(key != NULL) { + xmlSecKeyDestroy(key); + } + return(res); } /** * xmlSecGnuTLSAppKeysMngrCertLoad: - * @mngr: the keys manager. - * @filename: the certificate file. - * @format: the certificate file format. - * @type: the flag that indicates is the certificate in @filename - * trusted or not. - * + * @mngr: the keys manager. + * @filename: the certificate file. + * @format: the certificate file format. + * @type: the flag that indicates is the certificate in @filename + * trusted or not. + * * Reads cert from @filename and adds to the list of trusted or known - * untrusted certs in @store (not implemented yet). + * untrusted certs in @store. * * Returns: 0 on success or a negative value otherwise. */ int -xmlSecGnuTLSAppKeysMngrCertLoad(xmlSecKeysMngrPtr mngr, const char *filename, - xmlSecKeyDataFormat format, - xmlSecKeyDataType type ATTRIBUTE_UNUSED) { +xmlSecGnuTLSAppKeysMngrCertLoad(xmlSecKeysMngrPtr mngr, + const char *filename, + xmlSecKeyDataFormat format, + xmlSecKeyDataType type) { + xmlSecBuffer buffer; + int ret; + xmlSecAssert2(mngr != NULL, -1); xmlSecAssert2(filename != NULL, -1); xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, -1); - /* TODO */ - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecGnuTLSAppKeysMngrCertLoad", - XMLSEC_ERRORS_R_NOT_IMPLEMENTED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); + ret = xmlSecBufferInitialize(&buffer, 4*1024); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBufferInitialize", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + ret = xmlSecBufferReadFile(&buffer, filename); + if((ret < 0) || (xmlSecBufferGetData(&buffer) == NULL) || (xmlSecBufferGetSize(&buffer) <= 0)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBufferReadFile", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "filename=%s", + xmlSecErrorsSafeString(filename)); + xmlSecBufferFinalize(&buffer); + return(-1); + } + + ret = xmlSecGnuTLSAppKeysMngrCertLoadMemory(mngr, + xmlSecBufferGetData(&buffer), + xmlSecBufferGetSize(&buffer), + format, + type); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSAppKeysMngrCertLoadMemory", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "filename=%s", + xmlSecErrorsSafeString(filename)); + xmlSecBufferFinalize(&buffer); + return(-1); + } + + /* cleanup */ + xmlSecBufferFinalize(&buffer); + return(0); } /** * xmlSecGnuTLSAppKeysMngrCertLoadMemory: - * @mngr: the keys manager. - * @data: the certificate binary data. - * @dataSize: the certificate binary data size. - * @format: the certificate file format. - * @type: the flag that indicates is the certificate trusted or not. - * + * @mngr: the keys manager. + * @data: the certificate binary data. + * @dataSize: the certificate binary data size. + * @format: the certificate file format. + * @type: the flag that indicates is the certificate trusted or not. + * * Reads cert from binary buffer @data and adds to the list of trusted or known - * untrusted certs in @store (not implemented yet). + * untrusted certs in @store. * * Returns: 0 on success or a negative value otherwise. */ int -xmlSecGnuTLSAppKeysMngrCertLoadMemory(xmlSecKeysMngrPtr mngr, const xmlSecByte* data, - xmlSecSize dataSize, xmlSecKeyDataFormat format, - xmlSecKeyDataType type) { +xmlSecGnuTLSAppKeysMngrCertLoadMemory(xmlSecKeysMngrPtr mngr, + const xmlSecByte* data, + xmlSecSize dataSize, + xmlSecKeyDataFormat format, + xmlSecKeyDataType type) { + xmlSecKeyDataStorePtr x509Store; + gnutls_x509_crt_t cert; + int ret; + xmlSecAssert2(mngr != NULL, -1); xmlSecAssert2(data != NULL, -1); + xmlSecAssert2(dataSize > 0, -1); xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, -1); - /* TODO */ - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecGnuTLSAppKeysMngrCertLoadMemory", - XMLSEC_ERRORS_R_NOT_IMPLEMENTED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); + x509Store = xmlSecKeysMngrGetDataStore(mngr, xmlSecGnuTLSX509StoreId); + if(x509Store == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeysMngrGetDataStore", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "xmlSecGnuTLSX509StoreId"); + return(-1); + } + + cert = xmlSecGnuTLSX509CertRead(data, dataSize, format); + if(cert == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSX509CertRead", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + ret = xmlSecGnuTLSX509StoreAdoptCert(x509Store, cert, type); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSX509StoreAdoptCert", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + gnutls_x509_crt_deinit(cert); + return(-1); + } + + return(0); } #endif /* XMLSEC_NO_X509 */ /** * xmlSecGnuTLSAppDefaultKeysMngrInit: - * @mngr: the pointer to keys manager. + * @mngr: the pointer to keys manager. * * Initializes @mngr with simple keys store #xmlSecSimpleKeysStoreId * and a default GnuTLS crypto key data stores. * * Returns: 0 on success or a negative value otherwise. - */ + */ int xmlSecGnuTLSAppDefaultKeysMngrInit(xmlSecKeysMngrPtr mngr) { int ret; - + xmlSecAssert2(mngr != NULL, -1); - /* create simple keys store if needed */ + /* create simple keys store if needed */ if(xmlSecKeysMngrGetKeysStore(mngr) == NULL) { - xmlSecKeyStorePtr keysStore; - - keysStore = xmlSecKeyStoreCreate(xmlSecSimpleKeysStoreId); - if(keysStore == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecKeyStoreCreate", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "xmlSecSimpleKeysStoreId"); - return(-1); - } - - ret = xmlSecKeysMngrAdoptKeysStore(mngr, keysStore); - if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecKeysMngrAdoptKeysStore", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - xmlSecKeyStoreDestroy(keysStore); - return(-1); - } - } - - ret = xmlSecGnuTLSKeysMngrInit(mngr); + xmlSecKeyStorePtr keysStore; + + keysStore = xmlSecKeyStoreCreate(xmlSecSimpleKeysStoreId); + if(keysStore == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeyStoreCreate", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "xmlSecSimpleKeysStoreId"); + return(-1); + } + + ret = xmlSecKeysMngrAdoptKeysStore(mngr, keysStore); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeysMngrAdoptKeysStore", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlSecKeyStoreDestroy(keysStore); + return(-1); + } + } + + ret = xmlSecGnuTLSKeysMngrInit(mngr); if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecGnuTLSKeysMngrInit", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSKeysMngrInit", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + /* TODO */ mngr->getKey = xmlSecKeysMngrGetKey; return(0); @@ -363,125 +862,125 @@ xmlSecGnuTLSAppDefaultKeysMngrInit(xmlSecKeysMngrPtr mngr) { /** * xmlSecGnuTLSAppDefaultKeysMngrAdoptKey: - * @mngr: the pointer to keys manager. - * @key: the pointer to key. + * @mngr: the pointer to keys manager. + * @key: the pointer to key. * * Adds @key to the keys manager @mngr created with #xmlSecGnuTLSAppDefaultKeysMngrInit * function. - * + * * Returns: 0 on success or a negative value otherwise. - */ -int + */ +int xmlSecGnuTLSAppDefaultKeysMngrAdoptKey(xmlSecKeysMngrPtr mngr, xmlSecKeyPtr key) { xmlSecKeyStorePtr store; int ret; - + xmlSecAssert2(mngr != NULL, -1); xmlSecAssert2(key != NULL, -1); - + store = xmlSecKeysMngrGetKeysStore(mngr); if(store == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecKeysMngrGetKeysStore", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeysMngrGetKeysStore", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + ret = xmlSecSimpleKeysStoreAdoptKey(store, key); if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecSimpleKeysStoreAdoptKey", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecSimpleKeysStoreAdoptKey", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + return(0); } /** * xmlSecGnuTLSAppDefaultKeysMngrLoad: - * @mngr: the pointer to keys manager. - * @uri: the uri. + * @mngr: the pointer to keys manager. + * @uri: the uri. * - * Loads XML keys file from @uri to the keys manager @mngr created + * Loads XML keys file from @uri to the keys manager @mngr created * with #xmlSecGnuTLSAppDefaultKeysMngrInit function. - * + * * Returns: 0 on success or a negative value otherwise. - */ -int + */ +int xmlSecGnuTLSAppDefaultKeysMngrLoad(xmlSecKeysMngrPtr mngr, const char* uri) { xmlSecKeyStorePtr store; int ret; - + xmlSecAssert2(mngr != NULL, -1); xmlSecAssert2(uri != NULL, -1); - + store = xmlSecKeysMngrGetKeysStore(mngr); if(store == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecKeysMngrGetKeysStore", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeysMngrGetKeysStore", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + ret = xmlSecSimpleKeysStoreLoad(store, uri, mngr); if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecSimpleKeysStoreLoad", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "uri=%s", xmlSecErrorsSafeString(uri)); - return(-1); - } - + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecSimpleKeysStoreLoad", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "uri=%s", xmlSecErrorsSafeString(uri)); + return(-1); + } + return(0); } /** * xmlSecGnuTLSAppDefaultKeysMngrSave: - * @mngr: the pointer to keys manager. - * @filename: the destination filename. - * @type: the type of keys to save (public/private/symmetric). + * @mngr: the pointer to keys manager. + * @filename: the destination filename. + * @type: the type of keys to save (public/private/symmetric). * * Saves keys from @mngr to XML keys file. - * + * * Returns: 0 on success or a negative value otherwise. - */ -int + */ +int xmlSecGnuTLSAppDefaultKeysMngrSave(xmlSecKeysMngrPtr mngr, const char* filename, xmlSecKeyDataType type) { xmlSecKeyStorePtr store; int ret; - + xmlSecAssert2(mngr != NULL, -1); xmlSecAssert2(filename != NULL, -1); - + store = xmlSecKeysMngrGetKeysStore(mngr); if(store == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecKeysMngrGetKeysStore", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeysMngrGetKeysStore", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + ret = xmlSecSimpleKeysStoreSave(store, filename, type); if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecSimpleKeysStoreSave", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "filename=%s", - xmlSecErrorsSafeString(filename)); - return(-1); - } - + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecSimpleKeysStoreSave", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "filename=%s", + xmlSecErrorsSafeString(filename)); + return(-1); + } + return(0); } diff --git a/src/gnutls/asymkeys.c b/src/gnutls/asymkeys.c new file mode 100644 index 00000000..6ac68a78 --- /dev/null +++ b/src/gnutls/asymkeys.c @@ -0,0 +1,455 @@ +/** + * XMLSec library + * + * This is free software; see Copyright file in the source + * distribution for preciese wording. + * + * Copyright (C) 2010 Aleksey Sanin <aleksey@aleksey.com> + */ +#include "globals.h" + +#include <string.h> + +#include <gnutls/gnutls.h> +#include <gnutls/x509.h> + +#include <xmlsec/xmlsec.h> +#include <xmlsec/xmltree.h> +#include <xmlsec/keys.h> +#include <xmlsec/base64.h> +#include <xmlsec/keyinfo.h> +#include <xmlsec/transforms.h> +#include <xmlsec/errors.h> + +#include <xmlsec/gnutls/crypto.h> + +/************************************************************************** + * + * We use xmlsec-gcrypt for all the basic crypto ops + * + *****************************************************************************/ +#include <xmlsec/gcrypt/crypto.h> +#include <gcrypt.h> + +static void xmlSecGnuTLSDestroyParams(gnutls_datum_t * params, xmlSecSize num) { + xmlSecSize ii; + + xmlSecAssert(params != NULL); + for(ii = 0; ii < num; ++ii) { + gnutls_free(params[ii].data); + } +} + +static void xmlSecGnuTLSDestroyMpis(gcry_mpi_t * mpis, xmlSecSize num) { + xmlSecSize ii; + + xmlSecAssert(mpis != NULL); + for(ii = 0; ii < num; ++ii) { + gcry_mpi_release(mpis[ii]); + } +} + +static int xmlSecGnuTLSConvertParamsToMpis(gnutls_datum_t * params, xmlSecSize paramsNum, + gcry_mpi_t * mpis, xmlSecSize mpisNum) { + + xmlSecSize ii; + int rc; + + xmlSecAssert2(params != NULL, -1); + xmlSecAssert2(mpis != NULL, -1); + xmlSecAssert2(paramsNum == mpisNum, -1); + + for(ii = 0; ii < paramsNum; ++ii) { + rc = gcry_mpi_scan(&(mpis[ii]), GCRYMPI_FMT_USG, params[ii].data, params[ii].size, NULL); + if((rc != GPG_ERR_NO_ERROR) || (mpis[ii] == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gcry_mpi_scan", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_GCRYPT_REPORT_ERROR(rc)); + xmlSecGnuTLSDestroyMpis(mpis, ii); /* destroy up to now */ + return(-1); + } + } + + /* done */ + return(0); +} + +#ifndef XMLSEC_NO_DSA + +/** + * xmlSecGnuTLSKeyDataDsaGetKlass: + * + * The DSA key data klass. + * + * Returns: pointer to DSA key data klass. + */ +xmlSecKeyDataId +xmlSecGnuTLSKeyDataDsaGetKlass(void) { + return (xmlSecGCryptKeyDataDsaGetKlass()); +} + +/** + * xmlSecGnuTLSKeyDataDsaAdoptPrivateKey: + * @data: the pointer to DSA key data. + * @dsa_key: the pointer to GnuTLS DSA private key. + * + * Sets the value of DSA key data. + * + * Returns: 0 on success or a negative value otherwise. + */ +int +xmlSecGnuTLSKeyDataDsaAdoptPrivateKey(xmlSecKeyDataPtr data, gnutls_x509_privkey_t dsa_key) { + gnutls_datum_t params[5]; + gcry_mpi_t mpis[5]; + gcry_sexp_t priv_key = NULL; + gcry_sexp_t pub_key = NULL; + int rc; + int err; + int ret; + + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataDsaId), -1); + xmlSecAssert2(dsa_key != NULL, -1); + xmlSecAssert2(gnutls_x509_privkey_get_pk_algorithm(dsa_key) == GNUTLS_PK_DSA, -1); + + /* get raw values */ + err = gnutls_x509_privkey_export_dsa_raw(dsa_key, + &(params[0]), &(params[1]), &(params[2]), + &(params[3]), &(params[4])); + if(err != GNUTLS_E_SUCCESS) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_x509_privkey_export_dsa_raw", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + return(-1); + } + + /* convert to mpis */ + ret = xmlSecGnuTLSConvertParamsToMpis( + params, sizeof(params)/sizeof(params[0]), + mpis, sizeof(mpis)/sizeof(mpis[0])); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSConvertParamsToMpis", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlSecGnuTLSDestroyParams(params, sizeof(params)/sizeof(params[0])); + return(-1); + } + xmlSecGnuTLSDestroyParams(params, sizeof(params)/sizeof(params[0])); + + /* build expressions */ + rc = gcry_sexp_build(&(priv_key), NULL, "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))", + mpis[0], mpis[1], mpis[2], mpis[3], mpis[4]); + if((rc != GPG_ERR_NO_ERROR) || (priv_key == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gcry_sexp_build(private/dsa)", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_GNUTLS_GCRYPT_REPORT_ERROR(rc)); + xmlSecGnuTLSDestroyMpis(mpis, sizeof(mpis)/sizeof(mpis[0])); + return(-1); + } + rc = gcry_sexp_build(&(pub_key), NULL, "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))", + mpis[0], mpis[1], mpis[2], mpis[3]); + if((rc != GPG_ERR_NO_ERROR) || (pub_key == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gcry_sexp_build(private/rsa)", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_GNUTLS_GCRYPT_REPORT_ERROR(rc)); + gcry_sexp_release(priv_key); + xmlSecGnuTLSDestroyMpis(mpis, sizeof(mpis)/sizeof(mpis[0])); + return(-1); + } + xmlSecGnuTLSDestroyMpis(mpis, sizeof(mpis)/sizeof(mpis[0])); + + ret = xmlSecGCryptKeyDataDsaAdoptKeyPair(data, pub_key, priv_key); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGCryptKeyDataDsaAdoptKeyPair", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + gcry_sexp_release(pub_key); + gcry_sexp_release(priv_key); + return(-1); + } + + /* done, we "adopted" the key - destroy it! */ + gnutls_x509_privkey_deinit(dsa_key); + return(0); +} + + +/** + * xmlSecGnuTLSKeyDataDsaAdoptPublicKey: + * @data: the pointer to DSA key data. + * @p: the pointer to p component of the DSA public key + * @q: the pointer to q component of the DSA public key + * @g: the pointer to g component of the DSA public key + * @y: the pointer to y component of the DSA public key + * + * Sets the value of DSA key data. + * + * Returns: 0 on success or a negative value otherwise. + */ +int +xmlSecGnuTLSKeyDataDsaAdoptPublicKey(xmlSecKeyDataPtr data, + gnutls_datum_t * p, gnutls_datum_t * q, + gnutls_datum_t * g, gnutls_datum_t * y) { + gnutls_datum_t params[4]; + gcry_mpi_t mpis[4]; + gcry_sexp_t pub_key = NULL; + int rc; + int ret; + + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataDsaId), -1); + xmlSecAssert2(p != NULL, -1); + xmlSecAssert2(q != NULL, -1); + xmlSecAssert2(g != NULL, -1); + xmlSecAssert2(y != NULL, -1); + + /* copy */ + memcpy(&(params[0]), p, sizeof(*p)); + memcpy(&(params[1]), q, sizeof(*q)); + memcpy(&(params[2]), g, sizeof(*g)); + memcpy(&(params[3]), y, sizeof(*y)); + + /* convert to mpis */ + ret = xmlSecGnuTLSConvertParamsToMpis( + params, sizeof(params)/sizeof(params[0]), + mpis, sizeof(mpis)/sizeof(mpis[0])); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSConvertParamsToMpis", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + /* don't destroy params - we got them from outside !!! */ + return(-1); + } + /* don't destroy params - we got them from outside !!! */ + + /* build expressions */ + rc = gcry_sexp_build(&(pub_key), NULL, "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))", + mpis[0], mpis[1], mpis[2], mpis[3]); + if((rc != GPG_ERR_NO_ERROR) || (pub_key == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gcry_sexp_build(private/rsa)", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_GNUTLS_GCRYPT_REPORT_ERROR(rc)); + xmlSecGnuTLSDestroyMpis(mpis, sizeof(mpis)/sizeof(mpis[0])); + return(-1); + } + xmlSecGnuTLSDestroyMpis(mpis, sizeof(mpis)/sizeof(mpis[0])); + + ret = xmlSecGCryptKeyDataDsaAdoptKeyPair(data, pub_key, NULL); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGCryptKeyDataDsaAdoptKeyPair", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + gcry_sexp_release(pub_key); + return(-1); + } + + /* done, we "adopted" the key - destroy it! */ + gnutls_free(p->data); + gnutls_free(q->data); + gnutls_free(g->data); + gnutls_free(y->data); + return(0); +} + +#endif /* XMLSEC_NO_DSA */ + + +#ifndef XMLSEC_NO_RSA + +/** + * xmlSecGnuTLSKeyDataRsaGetKlass: + * + * The GnuTLS RSA key data klass. + * + * Returns: pointer to GnuTLS RSA key data klass. + */ +xmlSecKeyDataId +xmlSecGnuTLSKeyDataRsaGetKlass(void) { + return (xmlSecGCryptKeyDataRsaGetKlass()); +} + +/** + * xmlSecGnuTLSKeyDataRsaAdoptPrivateKey: + * @data: the pointer to RSA key data. + * @rsa_key: the pointer to GnuTLS RSA private key. + * + * Sets the value of RSA key data. + * + * Returns: 0 on success or a negative value otherwise. + */ +int +xmlSecGnuTLSKeyDataRsaAdoptPrivateKey(xmlSecKeyDataPtr data, gnutls_x509_privkey_t rsa_key) { + gnutls_datum_t params[6]; + gcry_mpi_t mpis[6]; + gcry_sexp_t priv_key = NULL; + gcry_sexp_t pub_key = NULL; + int rc; + int err; + int ret; + + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataRsaId), -1); + xmlSecAssert2(rsa_key != NULL, -1); + xmlSecAssert2(gnutls_x509_privkey_get_pk_algorithm(rsa_key) == GNUTLS_PK_RSA, -1); + + /* get raw values */ + err = gnutls_x509_privkey_export_rsa_raw(rsa_key, + &(params[0]), &(params[1]), &(params[2]), + &(params[3]), &(params[4]), &(params[5])); + if(err != GNUTLS_E_SUCCESS) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_x509_privkey_export_rsa_raw", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + return(-1); + } + + /* convert to mpis */ + ret = xmlSecGnuTLSConvertParamsToMpis( + params, sizeof(params)/sizeof(params[0]), + mpis, sizeof(mpis)/sizeof(mpis[0])); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSConvertParamsToMpis", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlSecGnuTLSDestroyParams(params, sizeof(params)/sizeof(params[0])); + return(-1); + } + xmlSecGnuTLSDestroyParams(params, sizeof(params)/sizeof(params[0])); + + /* build expressions */ + rc = gcry_sexp_build(&(priv_key), NULL, "(private-key(rsa((n%m)(e%m)(d%m)(p%m)(q%m)(u%m))))", + mpis[0], mpis[1], mpis[2], + mpis[3], mpis[4], mpis[5]); + if((rc != GPG_ERR_NO_ERROR) || (priv_key == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gcry_sexp_build(private/rsa)", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_GNUTLS_GCRYPT_REPORT_ERROR(rc)); + xmlSecGnuTLSDestroyMpis(mpis, sizeof(mpis)/sizeof(mpis[0])); + return(-1); + } + rc = gcry_sexp_build(&(pub_key), NULL, "(public-key(rsa((n%m)(e%m))))", + mpis[0], mpis[1]); + if((rc != GPG_ERR_NO_ERROR) || (pub_key == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gcry_sexp_build(private/rsa)", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_GNUTLS_GCRYPT_REPORT_ERROR(rc)); + gcry_sexp_release(priv_key); + xmlSecGnuTLSDestroyMpis(mpis, sizeof(mpis)/sizeof(mpis[0])); + return(-1); + } + xmlSecGnuTLSDestroyMpis(mpis, sizeof(mpis)/sizeof(mpis[0])); + + ret = xmlSecGCryptKeyDataRsaAdoptKeyPair(data, pub_key, priv_key); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGCryptKeyDataRsaAdoptKeyPair", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + gcry_sexp_release(pub_key); + gcry_sexp_release(priv_key); + return(-1); + } + + /* done, we "adopted" the key - destroy it! */ + gnutls_x509_privkey_deinit(rsa_key); + return(0); +} + + +/** + * xmlSecGnuTLSKeyDataRsaAdoptPublicKey: + * @data: the pointer to RSA key data. + * @m: the pointer to m component of the RSA public key + * @e: the pointer to e component of the RSA public key + * + * Sets the value of RSA key data. + * + * Returns: 0 on success or a negative value otherwise. + */ +int +xmlSecGnuTLSKeyDataRsaAdoptPublicKey(xmlSecKeyDataPtr data, + gnutls_datum_t * m, gnutls_datum_t * e) { + gnutls_datum_t params[2]; + gcry_mpi_t mpis[2]; + gcry_sexp_t pub_key = NULL; + int rc; + int ret; + + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataRsaId), -1); + xmlSecAssert2(m != NULL, -1); + xmlSecAssert2(e != NULL, -1); + + /* copy */ + memcpy(&(params[0]), m, sizeof(*m)); + memcpy(&(params[1]), e, sizeof(*e)); + + /* convert to mpis */ + ret = xmlSecGnuTLSConvertParamsToMpis( + params, sizeof(params)/sizeof(params[0]), + mpis, sizeof(mpis)/sizeof(mpis[0])); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSConvertParamsToMpis", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + /* don't destroy params - we got them from outside !!! */ + return(-1); + } + /* don't destroy params - we got them from outside !!! */ + + /* build expressions */ + rc = gcry_sexp_build(&(pub_key), NULL, "(public-key(rsa((n%m)(e%m))))", + mpis[0], mpis[1]); + if((rc != GPG_ERR_NO_ERROR) || (pub_key == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gcry_sexp_build(private/rsa)", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_GNUTLS_GCRYPT_REPORT_ERROR(rc)); + xmlSecGnuTLSDestroyMpis(mpis, sizeof(mpis)/sizeof(mpis[0])); + return(-1); + } + xmlSecGnuTLSDestroyMpis(mpis, sizeof(mpis)/sizeof(mpis[0])); + + ret = xmlSecGCryptKeyDataRsaAdoptKeyPair(data, pub_key, NULL); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGCryptKeyDataRsaAdoptKeyPair", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + gcry_sexp_release(pub_key); + return(-1); + } + + /* done, we "adopted" the key - destroy it! */ + gnutls_free(m->data); + gnutls_free(e->data); + return(0); +} +#endif /* XMLSEC_NO_RSA */ diff --git a/src/gnutls/ciphers.c b/src/gnutls/ciphers.c index b9421597..eacfede6 100644 --- a/src/gnutls/ciphers.c +++ b/src/gnutls/ciphers.c @@ -1,18 +1,15 @@ -/** +/** * XMLSec library * * This is free software; see Copyright file in the source * distribution for preciese wording. - * + * * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com> */ #include "globals.h" #include <string.h> -#include <gnutls/gnutls.h> -#include <gcrypt.h> - #include <xmlsec/xmlsec.h> #include <xmlsec/keys.h> #include <xmlsec/transforms.h> @@ -22,839 +19,64 @@ /************************************************************************** * - * Internal GnuTLS Block cipher CTX - * - *****************************************************************************/ -typedef struct _xmlSecGnuTLSBlockCipherCtx xmlSecGnuTLSBlockCipherCtx, - *xmlSecGnuTLSBlockCipherCtxPtr; -struct _xmlSecGnuTLSBlockCipherCtx { - int cipher; - int mode; - GcryCipherHd cipherCtx; - xmlSecKeyDataId keyId; - int keyInitialized; - int ctxInitialized; -}; - -static int xmlSecGnuTLSBlockCipherCtxInit (xmlSecGnuTLSBlockCipherCtxPtr ctx, - xmlSecBufferPtr in, - xmlSecBufferPtr out, - int encrypt, - const xmlChar* cipherName, - xmlSecTransformCtxPtr transformCtx); -static int xmlSecGnuTLSBlockCipherCtxUpdate (xmlSecGnuTLSBlockCipherCtxPtr ctx, - xmlSecBufferPtr in, - xmlSecBufferPtr out, - int encrypt, - const xmlChar* cipherName, - xmlSecTransformCtxPtr transformCtx); -static int xmlSecGnuTLSBlockCipherCtxFinal (xmlSecGnuTLSBlockCipherCtxPtr ctx, - xmlSecBufferPtr in, - xmlSecBufferPtr out, - int encrypt, - const xmlChar* cipherName, - xmlSecTransformCtxPtr transformCtx); -static int -xmlSecGnuTLSBlockCipherCtxInit(xmlSecGnuTLSBlockCipherCtxPtr ctx, - xmlSecBufferPtr in, xmlSecBufferPtr out, - int encrypt, - const xmlChar* cipherName, - xmlSecTransformCtxPtr transformCtx) { - int blockLen; - int ret; - - xmlSecAssert2(ctx != NULL, -1); - xmlSecAssert2(ctx->cipher != 0, -1); - xmlSecAssert2(ctx->cipherCtx != NULL, -1); - xmlSecAssert2(ctx->keyInitialized != 0, -1); - xmlSecAssert2(ctx->ctxInitialized == 0, -1); - xmlSecAssert2(in != NULL, -1); - xmlSecAssert2(out != NULL, -1); - xmlSecAssert2(transformCtx != NULL, -1); - - /* iv len == block len */ - blockLen = gcry_cipher_get_algo_blklen(ctx->cipher); - xmlSecAssert2(blockLen > 0, -1); - - if(encrypt) { - xmlSecByte* iv; - xmlSecSize outSize; - - /* allocate space for IV */ - outSize = xmlSecBufferGetSize(out); - ret = xmlSecBufferSetSize(out, outSize + blockLen); - if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(cipherName), - "xmlSecBufferSetSize", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "size=%d", outSize + blockLen); - return(-1); - } - iv = xmlSecBufferGetData(out) + outSize; - - /* generate and use random iv */ - gcry_randomize(iv, blockLen, GCRY_STRONG_RANDOM); - ret = gcry_cipher_setiv(ctx->cipherCtx, iv, blockLen); - if(ret != 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(cipherName), - "gcry_cipher_setiv", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - "ret=%d", ret); - return(-1); - } - } else { - /* if we don't have enough data, exit and hope that - * we'll have iv next time */ - if(xmlSecBufferGetSize(in) < (xmlSecSize)blockLen) { - return(0); - } - xmlSecAssert2(xmlSecBufferGetData(in) != NULL, -1); - - /* set iv */ - ret = gcry_cipher_setiv(ctx->cipherCtx, xmlSecBufferGetData(in), blockLen); - if(ret != 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(cipherName), - "gcry_cipher_setiv", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - "ret=%d", ret); - return(-1); - } - - /* and remove from input */ - ret = xmlSecBufferRemoveHead(in, blockLen); - if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(cipherName), - "xmlSecBufferRemoveHead", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "size=%d", blockLen); - return(-1); - } - } - - ctx->ctxInitialized = 1; - return(0); -} - -static int -xmlSecGnuTLSBlockCipherCtxUpdate(xmlSecGnuTLSBlockCipherCtxPtr ctx, - xmlSecBufferPtr in, xmlSecBufferPtr out, - int encrypt, - const xmlChar* cipherName, - xmlSecTransformCtxPtr transformCtx) { - xmlSecSize inSize, inBlocks, outSize; - int blockLen; - xmlSecByte* outBuf; - int ret; - - xmlSecAssert2(ctx != NULL, -1); - xmlSecAssert2(ctx->cipher != 0, -1); - xmlSecAssert2(ctx->cipherCtx != NULL, -1); - xmlSecAssert2(ctx->ctxInitialized != 0, -1); - xmlSecAssert2(in != NULL, -1); - xmlSecAssert2(out != NULL, -1); - xmlSecAssert2(transformCtx != NULL, -1); - - blockLen = gcry_cipher_get_algo_blklen(ctx->cipher); - xmlSecAssert2(blockLen > 0, -1); - - inSize = xmlSecBufferGetSize(in); - outSize = xmlSecBufferGetSize(out); - - if(inSize < (xmlSecSize)blockLen) { - return(0); - } - - if(encrypt) { - inBlocks = inSize / ((xmlSecSize)blockLen); - } else { - /* we want to have the last block in the input buffer - * for padding check */ - inBlocks = (inSize - 1) / ((xmlSecSize)blockLen); - } - inSize = inBlocks * ((xmlSecSize)blockLen); - - /* we write out the input size plus may be one block */ - ret = xmlSecBufferSetMaxSize(out, outSize + inSize + blockLen); - if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(cipherName), - "xmlSecBufferSetMaxSize", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "size=%d", outSize + inSize + blockLen); - return(-1); - } - outBuf = xmlSecBufferGetData(out) + outSize; - - if(encrypt) { - ret = gcry_cipher_encrypt(ctx->cipherCtx, outBuf, inSize + blockLen, - xmlSecBufferGetData(in), inSize); - if(ret != 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(cipherName), - "gcry_cipher_encrypt", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - "ret=%d", ret); - return(-1); - } - } else { - ret = gcry_cipher_decrypt(ctx->cipherCtx, outBuf, inSize + blockLen, - xmlSecBufferGetData(in), inSize); - if(ret != 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(cipherName), - "gcry_cipher_decrypt", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - "ret=%d", ret); - return(-1); - } - } - - /* set correct output buffer size */ - ret = xmlSecBufferSetSize(out, outSize + inSize); - if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(cipherName), - "xmlSecBufferSetSize", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "size=%d", outSize + inSize); - return(-1); - } - - /* remove the processed block from input */ - ret = xmlSecBufferRemoveHead(in, inSize); - if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(cipherName), - "xmlSecBufferRemoveHead", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "size=%d", inSize); - return(-1); - } - return(0); -} - -static int -xmlSecGnuTLSBlockCipherCtxFinal(xmlSecGnuTLSBlockCipherCtxPtr ctx, - xmlSecBufferPtr in, - xmlSecBufferPtr out, - int encrypt, - const xmlChar* cipherName, - xmlSecTransformCtxPtr transformCtx) { - xmlSecSize inSize, outSize; - int blockLen, outLen = 0; - xmlSecByte* inBuf; - xmlSecByte* outBuf; - int ret; - - xmlSecAssert2(ctx != NULL, -1); - xmlSecAssert2(ctx->cipher != 0, -1); - xmlSecAssert2(ctx->cipherCtx != NULL, -1); - xmlSecAssert2(ctx->ctxInitialized != 0, -1); - xmlSecAssert2(in != NULL, -1); - xmlSecAssert2(out != NULL, -1); - xmlSecAssert2(transformCtx != NULL, -1); - - blockLen = gcry_cipher_get_algo_blklen(ctx->cipher); - xmlSecAssert2(blockLen > 0, -1); - - inSize = xmlSecBufferGetSize(in); - outSize = xmlSecBufferGetSize(out); - - if(encrypt != 0) { - xmlSecAssert2(inSize < (xmlSecSize)blockLen, -1); - - /* create padding */ - ret = xmlSecBufferSetMaxSize(in, blockLen); - if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(cipherName), - "xmlSecBufferSetMaxSize", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "size=%d", blockLen); - return(-1); - } - inBuf = xmlSecBufferGetData(in); - - /* create random padding */ - if((xmlSecSize)blockLen > (inSize + 1)) { - gcry_randomize(inBuf + inSize, blockLen - inSize - 1, - GCRY_STRONG_RANDOM); /* as usual, we are paranoid */ - } - inBuf[blockLen - 1] = blockLen - inSize; - inSize = blockLen; - } else { - if(inSize != (xmlSecSize)blockLen) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(cipherName), - NULL, - XMLSEC_ERRORS_R_INVALID_DATA, - "data=%d;block=%d", inSize, blockLen); - return(-1); - } - } - - /* process last block */ - ret = xmlSecBufferSetMaxSize(out, outSize + 2 * blockLen); - if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(cipherName), - "xmlSecBufferSetMaxSize", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "size=%d", outSize + 2 * blockLen); - return(-1); - } - outBuf = xmlSecBufferGetData(out) + outSize; - - if(encrypt) { - ret = gcry_cipher_encrypt(ctx->cipherCtx, outBuf, inSize + blockLen, - xmlSecBufferGetData(in), inSize); - if(ret != 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(cipherName), - "gcry_cipher_encrypt", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - "ret=%d", ret); - return(-1); - } - } else { - ret = gcry_cipher_decrypt(ctx->cipherCtx, outBuf, inSize + blockLen, - xmlSecBufferGetData(in), inSize); - if(ret != 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(cipherName), - "gcry_cipher_decrypt", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - "ret=%d", ret); - return(-1); - } - } - - if(encrypt == 0) { - /* check padding */ - if(inSize < outBuf[blockLen - 1]) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(cipherName), - NULL, - XMLSEC_ERRORS_R_INVALID_DATA, - "padding=%d;buffer=%d", - outBuf[blockLen - 1], inSize); - return(-1); - } - outLen = inSize - outBuf[blockLen - 1]; - } else { - outLen = inSize; - } - - /* set correct output buffer size */ - ret = xmlSecBufferSetSize(out, outSize + outLen); - if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(cipherName), - "xmlSecBufferSetSize", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "size=%d", outSize + outLen); - return(-1); - } - - /* remove the processed block from input */ - ret = xmlSecBufferRemoveHead(in, inSize); - if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(cipherName), - "xmlSecBufferRemoveHead", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "size=%d", inSize); - return(-1); - } - - - /* set correct output buffer size */ - ret = xmlSecBufferSetSize(out, outSize + outLen); - if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(cipherName), - "xmlSecBufferSetSize", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "size=%d", outSize + outLen); - return(-1); - } - - /* remove the processed block from input */ - ret = xmlSecBufferRemoveHead(in, inSize); - if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(cipherName), - "xmlSecBufferRemoveHead", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "size=%d", inSize); - return(-1); - } - - return(0); -} - - -/****************************************************************************** - * - * Block Cipher transforms + * We use xmlsec-gcrypt for all the basic crypto ops * - * xmlSecGnuTLSBlockCipherCtx block is located after xmlSecTransform structure - * *****************************************************************************/ -#define xmlSecGnuTLSBlockCipherSize \ - (sizeof(xmlSecTransform) + sizeof(xmlSecGnuTLSBlockCipherCtx)) -#define xmlSecGnuTLSBlockCipherGetCtx(transform) \ - ((xmlSecGnuTLSBlockCipherCtxPtr)(((xmlSecByte*)(transform)) + sizeof(xmlSecTransform))) - -static int xmlSecGnuTLSBlockCipherInitialize (xmlSecTransformPtr transform); -static void xmlSecGnuTLSBlockCipherFinalize (xmlSecTransformPtr transform); -static int xmlSecGnuTLSBlockCipherSetKeyReq (xmlSecTransformPtr transform, - xmlSecKeyReqPtr keyReq); -static int xmlSecGnuTLSBlockCipherSetKey (xmlSecTransformPtr transform, - xmlSecKeyPtr key); -static int xmlSecGnuTLSBlockCipherExecute (xmlSecTransformPtr transform, - int last, - xmlSecTransformCtxPtr transformCtx); -static int xmlSecGnuTLSBlockCipherCheckId (xmlSecTransformPtr transform); - - - -static int -xmlSecGnuTLSBlockCipherCheckId(xmlSecTransformPtr transform) { -#ifndef XMLSEC_NO_DES - if(xmlSecTransformCheckId(transform, xmlSecGnuTLSTransformDes3CbcId)) { - return(1); - } -#endif /* XMLSEC_NO_DES */ - -#ifndef XMLSEC_NO_AES - if(xmlSecTransformCheckId(transform, xmlSecGnuTLSTransformAes128CbcId) || - xmlSecTransformCheckId(transform, xmlSecGnuTLSTransformAes192CbcId) || - xmlSecTransformCheckId(transform, xmlSecGnuTLSTransformAes256CbcId)) { - - return(1); - } -#endif /* XMLSEC_NO_AES */ - - return(0); -} - -static int -xmlSecGnuTLSBlockCipherInitialize(xmlSecTransformPtr transform) { - xmlSecGnuTLSBlockCipherCtxPtr ctx; -#ifndef XMLSEC_GNUTLS_OLD - gpg_err_code_t ret; -#endif /* XMLSEC_GNUTLS_OLD */ - - xmlSecAssert2(xmlSecGnuTLSBlockCipherCheckId(transform), -1); - xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecGnuTLSBlockCipherSize), -1); - - ctx = xmlSecGnuTLSBlockCipherGetCtx(transform); - xmlSecAssert2(ctx != NULL, -1); - - memset(ctx, 0, sizeof(xmlSecGnuTLSBlockCipherCtx)); - -#ifndef XMLSEC_NO_DES - if(transform->id == xmlSecGnuTLSTransformDes3CbcId) { - ctx->cipher = GCRY_CIPHER_3DES; - ctx->mode = GCRY_CIPHER_MODE_CBC; - ctx->keyId = xmlSecGnuTLSKeyDataDesId; - } else -#endif /* XMLSEC_NO_DES */ - -#ifndef XMLSEC_NO_AES - if(transform->id == xmlSecGnuTLSTransformAes128CbcId) { - ctx->cipher = GCRY_CIPHER_AES128; - ctx->mode = GCRY_CIPHER_MODE_CBC; - ctx->keyId = xmlSecGnuTLSKeyDataAesId; - } else if(transform->id == xmlSecGnuTLSTransformAes192CbcId) { - ctx->cipher = GCRY_CIPHER_AES192; - ctx->mode = GCRY_CIPHER_MODE_CBC; - ctx->keyId = xmlSecGnuTLSKeyDataAesId; - } else if(transform->id == xmlSecGnuTLSTransformAes256CbcId) { - ctx->cipher = GCRY_CIPHER_AES256; - ctx->mode = GCRY_CIPHER_MODE_CBC; - ctx->keyId = xmlSecGnuTLSKeyDataAesId; - } else -#endif /* XMLSEC_NO_AES */ +#include <xmlsec/gcrypt/crypto.h> - if(1) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - NULL, - XMLSEC_ERRORS_R_INVALID_TRANSFORM, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } -#ifndef XMLSEC_GNUTLS_OLD - ret = gcry_cipher_open(&ctx->cipherCtx, ctx->cipher, ctx->mode, GCRY_CIPHER_SECURE); /* we are paranoid */ - if(ret != GPG_ERR_NO_ERROR) { -#else /* XMLSEC_GNUTLS_OLD */ - ctx->cipherCtx = gcry_cipher_open(ctx->cipher, ctx->mode, GCRY_CIPHER_SECURE); /* we are paranoid */ - if(ctx->cipherCtx == NULL) { -#endif /* XMLSEC_GNUTLS_OLD */ - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - "gcry_cipher_open", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - return(0); -} - -static void -xmlSecGnuTLSBlockCipherFinalize(xmlSecTransformPtr transform) { - xmlSecGnuTLSBlockCipherCtxPtr ctx; - - xmlSecAssert(xmlSecGnuTLSBlockCipherCheckId(transform)); - xmlSecAssert(xmlSecTransformCheckSize(transform, xmlSecGnuTLSBlockCipherSize)); - - ctx = xmlSecGnuTLSBlockCipherGetCtx(transform); - xmlSecAssert(ctx != NULL); - - if(ctx->cipherCtx != NULL) { - gcry_cipher_close(ctx->cipherCtx); - } - - memset(ctx, 0, sizeof(xmlSecGnuTLSBlockCipherCtx)); -} - -static int -xmlSecGnuTLSBlockCipherSetKeyReq(xmlSecTransformPtr transform, xmlSecKeyReqPtr keyReq) { - xmlSecGnuTLSBlockCipherCtxPtr ctx; - - xmlSecAssert2(xmlSecGnuTLSBlockCipherCheckId(transform), -1); - xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1); - xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecGnuTLSBlockCipherSize), -1); - xmlSecAssert2(keyReq != NULL, -1); - - ctx = xmlSecGnuTLSBlockCipherGetCtx(transform); - xmlSecAssert2(ctx != NULL, -1); - xmlSecAssert2(ctx->cipher != 0, -1); - xmlSecAssert2(ctx->keyId != NULL, -1); - - keyReq->keyId = ctx->keyId; - keyReq->keyType = xmlSecKeyDataTypeSymmetric; - if(transform->operation == xmlSecTransformOperationEncrypt) { - keyReq->keyUsage = xmlSecKeyUsageEncrypt; - } else { - keyReq->keyUsage = xmlSecKeyUsageDecrypt; - } - - keyReq->keyBitsSize = 8 * gcry_cipher_get_algo_keylen(ctx->cipher); - return(0); -} - -static int -xmlSecGnuTLSBlockCipherSetKey(xmlSecTransformPtr transform, xmlSecKeyPtr key) { - xmlSecGnuTLSBlockCipherCtxPtr ctx; - xmlSecBufferPtr buffer; - xmlSecSize keySize; - int ret; - - xmlSecAssert2(xmlSecGnuTLSBlockCipherCheckId(transform), -1); - xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1); - xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecGnuTLSBlockCipherSize), -1); - xmlSecAssert2(key != NULL, -1); - - ctx = xmlSecGnuTLSBlockCipherGetCtx(transform); - xmlSecAssert2(ctx != NULL, -1); - xmlSecAssert2(ctx->cipherCtx != NULL, -1); - xmlSecAssert2(ctx->cipher != 0, -1); - xmlSecAssert2(ctx->keyInitialized == 0, -1); - xmlSecAssert2(ctx->keyId != NULL, -1); - xmlSecAssert2(xmlSecKeyCheckId(key, ctx->keyId), -1); - - keySize = gcry_cipher_get_algo_keylen(ctx->cipher); - xmlSecAssert2(keySize > 0, -1); - - buffer = xmlSecKeyDataBinaryValueGetBuffer(xmlSecKeyGetValue(key)); - xmlSecAssert2(buffer != NULL, -1); - - if(xmlSecBufferGetSize(buffer) < keySize) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - NULL, - XMLSEC_ERRORS_R_INVALID_KEY_DATA_SIZE, - "keySize=%d;expected=%d", - xmlSecBufferGetSize(buffer), keySize); - return(-1); - } - - xmlSecAssert2(xmlSecBufferGetData(buffer) != NULL, -1); - ret = gcry_cipher_setkey(ctx->cipherCtx, xmlSecBufferGetData(buffer), keySize); - if(ret != 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - "gcry_cipher_setkey", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - "ret=%d", ret); - return(-1); - } - - ctx->keyInitialized = 1; - return(0); -} - -static int -xmlSecGnuTLSBlockCipherExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) { - xmlSecGnuTLSBlockCipherCtxPtr ctx; - xmlSecBufferPtr in, out; - int ret; - - xmlSecAssert2(xmlSecGnuTLSBlockCipherCheckId(transform), -1); - xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1); - xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecGnuTLSBlockCipherSize), -1); - xmlSecAssert2(transformCtx != NULL, -1); - - in = &(transform->inBuf); - out = &(transform->outBuf); - - ctx = xmlSecGnuTLSBlockCipherGetCtx(transform); - xmlSecAssert2(ctx != NULL, -1); - - if(transform->status == xmlSecTransformStatusNone) { - transform->status = xmlSecTransformStatusWorking; - } - - if(transform->status == xmlSecTransformStatusWorking) { - if(ctx->ctxInitialized == 0) { - ret = xmlSecGnuTLSBlockCipherCtxInit(ctx, in, out, - (transform->operation == xmlSecTransformOperationEncrypt) ? 1 : 0, - xmlSecTransformGetName(transform), transformCtx); - if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - "xmlSecGnuTLSBlockCipherCtxInit", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - } - if((ctx->ctxInitialized == 0) && (last != 0)) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - NULL, - XMLSEC_ERRORS_R_INVALID_DATA, - "not enough data to initialize transform"); - return(-1); - } - if(ctx->ctxInitialized != 0) { - ret = xmlSecGnuTLSBlockCipherCtxUpdate(ctx, in, out, - (transform->operation == xmlSecTransformOperationEncrypt) ? 1 : 0, - xmlSecTransformGetName(transform), transformCtx); - if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - "xmlSecGnuTLSBlockCipherCtxUpdate", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - } - - if(last) { - ret = xmlSecGnuTLSBlockCipherCtxFinal(ctx, in, out, - (transform->operation == xmlSecTransformOperationEncrypt) ? 1 : 0, - xmlSecTransformGetName(transform), transformCtx); - if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - "xmlSecGnuTLSBlockCipherCtxFinal", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - transform->status = xmlSecTransformStatusFinished; - } - } else if(transform->status == xmlSecTransformStatusFinished) { - /* the only way we can get here is if there is no input */ - xmlSecAssert2(xmlSecBufferGetSize(in) == 0, -1); - } else if(transform->status == xmlSecTransformStatusNone) { - /* the only way we can get here is if there is no enough data in the input */ - xmlSecAssert2(last == 0, -1); - } else { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - NULL, - XMLSEC_ERRORS_R_INVALID_STATUS, - "status=%d", transform->status); - return(-1); - } - - return(0); -} #ifndef XMLSEC_NO_AES -/********************************************************************* - * - * AES CBC cipher transforms - * - ********************************************************************/ -static xmlSecTransformKlass xmlSecGnuTLSAes128CbcKlass = { - /* klass/object sizes */ - sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */ - xmlSecGnuTLSBlockCipherSize, /* xmlSecSize objSize */ - - xmlSecNameAes128Cbc, /* const xmlChar* name; */ - xmlSecHrefAes128Cbc, /* const xmlChar* href; */ - xmlSecTransformUsageEncryptionMethod, /* xmlSecAlgorithmUsage usage; */ - - xmlSecGnuTLSBlockCipherInitialize, /* xmlSecTransformInitializeMethod initialize; */ - xmlSecGnuTLSBlockCipherFinalize, /* xmlSecTransformFinalizeMethod finalize; */ - NULL, /* xmlSecTransformNodeReadMethod readNode; */ - NULL, /* xmlSecTransformNodeWriteMethod writeNode; */ - xmlSecGnuTLSBlockCipherSetKeyReq, /* xmlSecTransformSetKeyMethod setKeyReq; */ - xmlSecGnuTLSBlockCipherSetKey, /* xmlSecTransformSetKeyMethod setKey; */ - NULL, /* xmlSecTransformValidateMethod validate; */ - xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */ - xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */ - xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */ - NULL, /* xmlSecTransformPushXmlMethod pushXml; */ - NULL, /* xmlSecTransformPopXmlMethod popXml; */ - xmlSecGnuTLSBlockCipherExecute, /* xmlSecTransformExecuteMethod execute; */ - - NULL, /* void* reserved0; */ - NULL, /* void* reserved1; */ -}; /** * xmlSecGnuTLSTransformAes128CbcGetKlass: - * + * * AES 128 CBC encryption transform klass. - * + * * Returns: pointer to AES 128 CBC encryption transform. - */ -xmlSecTransformId + */ +xmlSecTransformId xmlSecGnuTLSTransformAes128CbcGetKlass(void) { - return(&xmlSecGnuTLSAes128CbcKlass); + return (xmlSecGCryptTransformAes128CbcGetKlass()); } -static xmlSecTransformKlass xmlSecGnuTLSAes192CbcKlass = { - /* klass/object sizes */ - sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */ - xmlSecGnuTLSBlockCipherSize, /* xmlSecSize objSize */ - - xmlSecNameAes192Cbc, /* const xmlChar* name; */ - xmlSecHrefAes192Cbc, /* const xmlChar* href; */ - xmlSecTransformUsageEncryptionMethod, /* xmlSecAlgorithmUsage usage; */ - - xmlSecGnuTLSBlockCipherInitialize, /* xmlSecTransformInitializeMethod initialize; */ - xmlSecGnuTLSBlockCipherFinalize, /* xmlSecTransformFinalizeMethod finalize; */ - NULL, /* xmlSecTransformNodeReadMethod readNode; */ - NULL, /* xmlSecTransformNodeWriteMethod writeNode; */ - xmlSecGnuTLSBlockCipherSetKeyReq, /* xmlSecTransformSetKeyMethod setKeyReq; */ - xmlSecGnuTLSBlockCipherSetKey, /* xmlSecTransformSetKeyMethod setKey; */ - NULL, /* xmlSecTransformValidateMethod validate; */ - xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */ - xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */ - xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */ - NULL, /* xmlSecTransformPushXmlMethod pushXml; */ - NULL, /* xmlSecTransformPopXmlMethod popXml; */ - xmlSecGnuTLSBlockCipherExecute, /* xmlSecTransformExecuteMethod execute; */ - - NULL, /* void* reserved0; */ - NULL, /* void* reserved1; */ -}; - /** * xmlSecGnuTLSTransformAes192CbcGetKlass: - * + * * AES 192 CBC encryption transform klass. - * + * * Returns: pointer to AES 192 CBC encryption transform. - */ -xmlSecTransformId + */ +xmlSecTransformId xmlSecGnuTLSTransformAes192CbcGetKlass(void) { - return(&xmlSecGnuTLSAes192CbcKlass); + return (xmlSecGCryptTransformAes192CbcGetKlass()); } -static xmlSecTransformKlass xmlSecGnuTLSAes256CbcKlass = { - /* klass/object sizes */ - sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */ - xmlSecGnuTLSBlockCipherSize, /* xmlSecSize objSize */ - - xmlSecNameAes256Cbc, /* const xmlChar* name; */ - xmlSecHrefAes256Cbc, /* const xmlChar* href; */ - xmlSecTransformUsageEncryptionMethod, /* xmlSecAlgorithmUsage usage; */ - - xmlSecGnuTLSBlockCipherInitialize, /* xmlSecTransformInitializeMethod initialize; */ - xmlSecGnuTLSBlockCipherFinalize, /* xmlSecTransformFinalizeMethod finalize; */ - NULL, /* xmlSecTransformNodeReadMethod readNode; */ - NULL, /* xmlSecTransformNodeWriteMethod writeNode; */ - xmlSecGnuTLSBlockCipherSetKeyReq, /* xmlSecTransformSetKeyMethod setKeyReq; */ - xmlSecGnuTLSBlockCipherSetKey, /* xmlSecTransformSetKeyMethod setKey; */ - NULL, /* xmlSecTransformValidateMethod validate; */ - xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */ - xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */ - xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */ - NULL, /* xmlSecTransformPushXmlMethod pushXml; */ - NULL, /* xmlSecTransformPopXmlMethod popXml; */ - xmlSecGnuTLSBlockCipherExecute, /* xmlSecTransformExecuteMethod execute; */ - - NULL, /* void* reserved0; */ - NULL, /* void* reserved1; */ -}; - /** * xmlSecGnuTLSTransformAes256CbcGetKlass: - * + * * AES 256 CBC encryption transform klass. - * + * * Returns: pointer to AES 256 CBC encryption transform. - */ -xmlSecTransformId + */ +xmlSecTransformId xmlSecGnuTLSTransformAes256CbcGetKlass(void) { - return(&xmlSecGnuTLSAes256CbcKlass); + return (xmlSecGCryptTransformAes256CbcGetKlass()); } - #endif /* XMLSEC_NO_AES */ #ifndef XMLSEC_NO_DES -static xmlSecTransformKlass xmlSecGnuTLSDes3CbcKlass = { - /* klass/object sizes */ - sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */ - xmlSecGnuTLSBlockCipherSize, /* xmlSecSize objSize */ - - xmlSecNameDes3Cbc, /* const xmlChar* name; */ - xmlSecHrefDes3Cbc, /* const xmlChar* href; */ - xmlSecTransformUsageEncryptionMethod, /* xmlSecAlgorithmUsage usage; */ - - xmlSecGnuTLSBlockCipherInitialize, /* xmlSecTransformInitializeMethod initialize; */ - xmlSecGnuTLSBlockCipherFinalize, /* xmlSecTransformFinalizeMethod finalize; */ - NULL, /* xmlSecTransformNodeReadMethod readNode; */ - NULL, /* xmlSecTransformNodeWriteMethod writeNode; */ - xmlSecGnuTLSBlockCipherSetKeyReq, /* xmlSecTransformSetKeyMethod setKeyReq; */ - xmlSecGnuTLSBlockCipherSetKey, /* xmlSecTransformSetKeyMethod setKey; */ - NULL, /* xmlSecTransformValidateMethod validate; */ - xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */ - xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */ - xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */ - NULL, /* xmlSecTransformPushXmlMethod pushXml; */ - NULL, /* xmlSecTransformPopXmlMethod popXml; */ - xmlSecGnuTLSBlockCipherExecute, /* xmlSecTransformExecuteMethod execute; */ - - NULL, /* void* reserved0; */ - NULL, /* void* reserved1; */ -}; - -/** +/** * xmlSecGnuTLSTransformDes3CbcGetKlass: * * Triple DES CBC encryption transform klass. - * + * * Returns: pointer to Triple DES encryption transform. */ -xmlSecTransformId +xmlSecTransformId xmlSecGnuTLSTransformDes3CbcGetKlass(void) { - return(&xmlSecGnuTLSDes3CbcKlass); + return (xmlSecGCryptTransformDes3CbcGetKlass()); } #endif /* XMLSEC_NO_DES */ diff --git a/src/gnutls/crypto.c b/src/gnutls/crypto.c index dbf69f21..83175e69 100644 --- a/src/gnutls/crypto.c +++ b/src/gnutls/crypto.c @@ -1,16 +1,15 @@ -/** +/** * XMLSec library * * This is free software; see Copyright file in the source * distribution for preciese wording. - * + * * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com> */ #include "globals.h" #include <string.h> -#include <gnutls/gnutls.h> #include <gcrypt.h> #include <xmlsec/xmlsec.h> @@ -22,6 +21,7 @@ #include <xmlsec/gnutls/app.h> #include <xmlsec/gnutls/crypto.h> +#include <xmlsec/gnutls/x509.h> static xmlSecCryptoDLFunctionsPtr gXmlSecGnuTLSFunctions = NULL; @@ -35,79 +35,197 @@ static xmlSecCryptoDLFunctionsPtr gXmlSecGnuTLSFunctions = NULL; xmlSecCryptoDLFunctionsPtr xmlSecCryptoGetFunctions_gnutls(void) { static xmlSecCryptoDLFunctions functions; - + if(gXmlSecGnuTLSFunctions != NULL) { - return(gXmlSecGnuTLSFunctions); + return(gXmlSecGnuTLSFunctions); } memset(&functions, 0, sizeof(functions)); gXmlSecGnuTLSFunctions = &functions; - /** + /******************************************************************** + * * Crypto Init/shutdown - */ - gXmlSecGnuTLSFunctions->cryptoInit = xmlSecGnuTLSInit; - gXmlSecGnuTLSFunctions->cryptoShutdown = xmlSecGnuTLSShutdown; - gXmlSecGnuTLSFunctions->cryptoKeysMngrInit = xmlSecGnuTLSKeysMngrInit; + * + ********************************************************************/ + gXmlSecGnuTLSFunctions->cryptoInit = xmlSecGnuTLSInit; + gXmlSecGnuTLSFunctions->cryptoShutdown = xmlSecGnuTLSShutdown; + gXmlSecGnuTLSFunctions->cryptoKeysMngrInit = xmlSecGnuTLSKeysMngrInit; - /** + /******************************************************************** + * * Key data ids - */ -#ifndef XMLSEC_NO_AES - gXmlSecGnuTLSFunctions->keyDataAesGetKlass = xmlSecGnuTLSKeyDataAesGetKlass; + * + ********************************************************************/ +#ifndef XMLSEC_NO_AES + gXmlSecGnuTLSFunctions->keyDataAesGetKlass = xmlSecGnuTLSKeyDataAesGetKlass; #endif /* XMLSEC_NO_AES */ -#ifndef XMLSEC_NO_DES - gXmlSecGnuTLSFunctions->keyDataDesGetKlass = xmlSecGnuTLSKeyDataDesGetKlass; +#ifndef XMLSEC_NO_DES + gXmlSecGnuTLSFunctions->keyDataDesGetKlass = xmlSecGnuTLSKeyDataDesGetKlass; #endif /* XMLSEC_NO_DES */ -#ifndef XMLSEC_NO_HMAC - gXmlSecGnuTLSFunctions->keyDataHmacGetKlass = xmlSecGnuTLSKeyDataHmacGetKlass; -#endif /* XMLSEC_NO_HMAC */ +#ifndef XMLSEC_NO_DSA + gXmlSecGnuTLSFunctions->keyDataDsaGetKlass = xmlSecGnuTLSKeyDataDsaGetKlass; +#endif /* XMLSEC_NO_DSA */ + +#ifndef XMLSEC_NO_HMAC + gXmlSecGnuTLSFunctions->keyDataHmacGetKlass = xmlSecGnuTLSKeyDataHmacGetKlass; +#endif /* XMLSEC_NO_HMAC */ + +#ifndef XMLSEC_NO_RSA + gXmlSecGnuTLSFunctions->keyDataRsaGetKlass = xmlSecGnuTLSKeyDataRsaGetKlass; +#endif /* XMLSEC_NO_RSA */ - /** +#ifndef XMLSEC_NO_X509 + gXmlSecGnuTLSFunctions->keyDataX509GetKlass = xmlSecGnuTLSKeyDataX509GetKlass; + gXmlSecGnuTLSFunctions->keyDataRawX509CertGetKlass = xmlSecGnuTLSKeyDataRawX509CertGetKlass; +#endif /* XMLSEC_NO_X509 */ + + /******************************************************************** + * * Key data store ids - */ + * + ********************************************************************/ +#ifndef XMLSEC_NO_X509 + gXmlSecGnuTLSFunctions->x509StoreGetKlass = xmlSecGnuTLSX509StoreGetKlass; +#endif /* XMLSEC_NO_X509 */ - /** + /******************************************************************** + * * Crypto transforms ids - */ -#ifndef XMLSEC_NO_AES - gXmlSecGnuTLSFunctions->transformAes128CbcGetKlass = xmlSecGnuTLSTransformAes128CbcGetKlass; - gXmlSecGnuTLSFunctions->transformAes192CbcGetKlass = xmlSecGnuTLSTransformAes192CbcGetKlass; - gXmlSecGnuTLSFunctions->transformAes256CbcGetKlass = xmlSecGnuTLSTransformAes256CbcGetKlass; + * + ********************************************************************/ + + /******************************* AES ********************************/ +#ifndef XMLSEC_NO_AES + gXmlSecGnuTLSFunctions->transformAes128CbcGetKlass = xmlSecGnuTLSTransformAes128CbcGetKlass; + gXmlSecGnuTLSFunctions->transformAes192CbcGetKlass = xmlSecGnuTLSTransformAes192CbcGetKlass; + gXmlSecGnuTLSFunctions->transformAes256CbcGetKlass = xmlSecGnuTLSTransformAes256CbcGetKlass; + gXmlSecGnuTLSFunctions->transformKWAes128GetKlass = xmlSecGnuTLSTransformKWAes128GetKlass; + gXmlSecGnuTLSFunctions->transformKWAes192GetKlass = xmlSecGnuTLSTransformKWAes192GetKlass; + gXmlSecGnuTLSFunctions->transformKWAes256GetKlass = xmlSecGnuTLSTransformKWAes256GetKlass; #endif /* XMLSEC_NO_AES */ -#ifndef XMLSEC_NO_DES - gXmlSecGnuTLSFunctions->transformDes3CbcGetKlass = xmlSecGnuTLSTransformDes3CbcGetKlass; + /******************************* DES ********************************/ +#ifndef XMLSEC_NO_DES + gXmlSecGnuTLSFunctions->transformDes3CbcGetKlass = xmlSecGnuTLSTransformDes3CbcGetKlass; + gXmlSecGnuTLSFunctions->transformKWDes3GetKlass = xmlSecGnuTLSTransformKWDes3GetKlass; #endif /* XMLSEC_NO_DES */ + /******************************* DSA ********************************/ +#ifndef XMLSEC_NO_DSA + +#ifndef XMLSEC_NO_SHA1 + gXmlSecGnuTLSFunctions->transformDsaSha1GetKlass = xmlSecGnuTLSTransformDsaSha1GetKlass; +#endif /* XMLSEC_NO_SHA1 */ + +#endif /* XMLSEC_NO_DSA */ + + /******************************* HMAC ********************************/ #ifndef XMLSEC_NO_HMAC - gXmlSecGnuTLSFunctions->transformHmacSha1GetKlass = xmlSecGnuTLSTransformHmacSha1GetKlass; - gXmlSecGnuTLSFunctions->transformHmacRipemd160GetKlass = xmlSecGnuTLSTransformHmacRipemd160GetKlass; - gXmlSecGnuTLSFunctions->transformHmacMd5GetKlass = xmlSecGnuTLSTransformHmacMd5GetKlass; + +#ifndef XMLSEC_NO_MD5 + gXmlSecGnuTLSFunctions->transformHmacMd5GetKlass = xmlSecGnuTLSTransformHmacMd5GetKlass; +#endif /* XMLSEC_NO_MD5 */ + +#ifndef XMLSEC_NO_RIPEMD160 + gXmlSecGnuTLSFunctions->transformHmacRipemd160GetKlass = xmlSecGnuTLSTransformHmacRipemd160GetKlass; +#endif /* XMLSEC_NO_RIPEMD160 */ + +#ifndef XMLSEC_NO_SHA1 + gXmlSecGnuTLSFunctions->transformHmacSha1GetKlass = xmlSecGnuTLSTransformHmacSha1GetKlass; +#endif /* XMLSEC_NO_SHA1 */ + +#ifndef XMLSEC_NO_SHA256 + gXmlSecGnuTLSFunctions->transformHmacSha256GetKlass = xmlSecGnuTLSTransformHmacSha256GetKlass; +#endif /* XMLSEC_NO_SHA256 */ + +#ifndef XMLSEC_NO_SHA384 + gXmlSecGnuTLSFunctions->transformHmacSha384GetKlass = xmlSecGnuTLSTransformHmacSha384GetKlass; +#endif /* XMLSEC_NO_SHA384 */ + +#ifndef XMLSEC_NO_SHA512 + gXmlSecGnuTLSFunctions->transformHmacSha512GetKlass = xmlSecGnuTLSTransformHmacSha512GetKlass; +#endif /* XMLSEC_NO_SHA512 */ + #endif /* XMLSEC_NO_HMAC */ -#ifndef XMLSEC_NO_SHA1 - gXmlSecGnuTLSFunctions->transformSha1GetKlass = xmlSecGnuTLSTransformSha1GetKlass; + /******************************* MD5 ********************************/ +#ifndef XMLSEC_NO_MD5 + gXmlSecGnuTLSFunctions->transformMd5GetKlass = xmlSecGnuTLSTransformMd5GetKlass; +#endif /* XMLSEC_NO_MD5 */ + + /******************************* RIPEMD160 ********************************/ +#ifndef XMLSEC_NO_RIPEMD160 + gXmlSecGnuTLSFunctions->transformRipemd160GetKlass = xmlSecGnuTLSTransformRipemd160GetKlass; +#endif /* XMLSEC_NO_RIPEMD160 */ + + /******************************* RSA ********************************/ +#ifndef XMLSEC_NO_RSA + +#ifndef XMLSEC_NO_MD5 + gXmlSecGnuTLSFunctions->transformRsaMd5GetKlass = xmlSecGnuTLSTransformRsaMd5GetKlass; +#endif /* XMLSEC_NO_MD5 */ + +#ifndef XMLSEC_NO_RIPEMD160 + gXmlSecGnuTLSFunctions->transformRsaRipemd160GetKlass = xmlSecGnuTLSTransformRsaRipemd160GetKlass; +#endif /* XMLSEC_NO_RIPEMD160 */ + +#ifndef XMLSEC_NO_SHA1 + gXmlSecGnuTLSFunctions->transformRsaSha1GetKlass = xmlSecGnuTLSTransformRsaSha1GetKlass; +#endif /* XMLSEC_NO_SHA1 */ + +#ifndef XMLSEC_NO_SHA256 + gXmlSecGnuTLSFunctions->transformRsaSha256GetKlass = xmlSecGnuTLSTransformRsaSha256GetKlass; +#endif /* XMLSEC_NO_SHA256 */ + +#ifndef XMLSEC_NO_SHA384 + gXmlSecGnuTLSFunctions->transformRsaSha384GetKlass = xmlSecGnuTLSTransformRsaSha384GetKlass; +#endif /* XMLSEC_NO_SHA384 */ + +#ifndef XMLSEC_NO_SHA512 + gXmlSecGnuTLSFunctions->transformRsaSha512GetKlass = xmlSecGnuTLSTransformRsaSha512GetKlass; +#endif /* XMLSEC_NO_SHA512 */ + +#endif /* XMLSEC_NO_RSA */ + + /******************************* SHA ********************************/ +#ifndef XMLSEC_NO_SHA1 + gXmlSecGnuTLSFunctions->transformSha1GetKlass = xmlSecGnuTLSTransformSha1GetKlass; #endif /* XMLSEC_NO_SHA1 */ - /** +#ifndef XMLSEC_NO_SHA256 + gXmlSecGnuTLSFunctions->transformSha256GetKlass = xmlSecGnuTLSTransformSha256GetKlass; +#endif /* XMLSEC_NO_SHA256 */ + +#ifndef XMLSEC_NO_SHA384 + gXmlSecGnuTLSFunctions->transformSha384GetKlass = xmlSecGnuTLSTransformSha384GetKlass; +#endif /* XMLSEC_NO_SHA384 */ + +#ifndef XMLSEC_NO_SHA512 + gXmlSecGnuTLSFunctions->transformSha512GetKlass = xmlSecGnuTLSTransformSha512GetKlass; +#endif /* XMLSEC_NO_SHA512 */ + + + /******************************************************************** + * * High level routines form xmlsec command line utility - */ - gXmlSecGnuTLSFunctions->cryptoAppInit = xmlSecGnuTLSAppInit; - gXmlSecGnuTLSFunctions->cryptoAppShutdown = xmlSecGnuTLSAppShutdown; - gXmlSecGnuTLSFunctions->cryptoAppDefaultKeysMngrInit = xmlSecGnuTLSAppDefaultKeysMngrInit; - gXmlSecGnuTLSFunctions->cryptoAppDefaultKeysMngrAdoptKey = xmlSecGnuTLSAppDefaultKeysMngrAdoptKey; - gXmlSecGnuTLSFunctions->cryptoAppDefaultKeysMngrLoad = xmlSecGnuTLSAppDefaultKeysMngrLoad; - gXmlSecGnuTLSFunctions->cryptoAppDefaultKeysMngrSave = xmlSecGnuTLSAppDefaultKeysMngrSave; + * + ********************************************************************/ + gXmlSecGnuTLSFunctions->cryptoAppInit = xmlSecGnuTLSAppInit; + gXmlSecGnuTLSFunctions->cryptoAppShutdown = xmlSecGnuTLSAppShutdown; + gXmlSecGnuTLSFunctions->cryptoAppDefaultKeysMngrInit = xmlSecGnuTLSAppDefaultKeysMngrInit; + gXmlSecGnuTLSFunctions->cryptoAppDefaultKeysMngrAdoptKey = xmlSecGnuTLSAppDefaultKeysMngrAdoptKey; + gXmlSecGnuTLSFunctions->cryptoAppDefaultKeysMngrLoad = xmlSecGnuTLSAppDefaultKeysMngrLoad; + gXmlSecGnuTLSFunctions->cryptoAppDefaultKeysMngrSave = xmlSecGnuTLSAppDefaultKeysMngrSave; #ifndef XMLSEC_NO_X509 - gXmlSecGnuTLSFunctions->cryptoAppKeysMngrCertLoad = xmlSecGnuTLSAppKeysMngrCertLoad; - gXmlSecGnuTLSFunctions->cryptoAppPkcs12Load = xmlSecGnuTLSAppPkcs12Load; - gXmlSecGnuTLSFunctions->cryptoAppKeyCertLoad = xmlSecGnuTLSAppKeyCertLoad; + gXmlSecGnuTLSFunctions->cryptoAppKeysMngrCertLoad = xmlSecGnuTLSAppKeysMngrCertLoad; + gXmlSecGnuTLSFunctions->cryptoAppPkcs12Load = xmlSecGnuTLSAppPkcs12Load; + gXmlSecGnuTLSFunctions->cryptoAppKeyCertLoad = xmlSecGnuTLSAppKeyCertLoad; #endif /* XMLSEC_NO_X509 */ - gXmlSecGnuTLSFunctions->cryptoAppKeyLoad = xmlSecGnuTLSAppKeyLoad; - gXmlSecGnuTLSFunctions->cryptoAppDefaultPwdCallback = (void*)xmlSecGnuTLSAppGetDefaultPwdCallback(); + gXmlSecGnuTLSFunctions->cryptoAppKeyLoad = xmlSecGnuTLSAppKeyLoad; + gXmlSecGnuTLSFunctions->cryptoAppDefaultPwdCallback = (void*)xmlSecGnuTLSAppGetDefaultPwdCallback(); return(gXmlSecGnuTLSFunctions); } @@ -115,51 +233,51 @@ xmlSecCryptoGetFunctions_gnutls(void) { /** * xmlSecGnuTLSInit: - * - * XMLSec library specific crypto engine initialization. + * + * XMLSec library specific crypto engine initialization. * * Returns: 0 on success or a negative value otherwise. */ -int +int xmlSecGnuTLSInit (void) { /* Check loaded xmlsec library version */ if(xmlSecCheckVersionExact() != 1) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecCheckVersionExact", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecCheckVersionExact", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); } /* register our klasses */ if(xmlSecCryptoDLFunctionsRegisterKeyDataAndTransforms(xmlSecCryptoGetFunctions_gnutls()) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecCryptoDLFunctionsRegisterKeyDataAndTransforms", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecCryptoDLFunctionsRegisterKeyDataAndTransforms", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); } - + return(0); } /** * xmlSecGnuTLSShutdown: - * - * XMLSec library specific crypto engine shutdown. + * + * XMLSec library specific crypto engine shutdown. * * Returns: 0 on success or a negative value otherwise. */ -int +int xmlSecGnuTLSShutdown(void) { return(0); } /** * xmlSecGnuTLSKeysMngrInit: - * @mngr: the pointer to keys manager. + * @mngr: the pointer to keys manager. * * Adds GnuTLS specific key data stores in keys manager. * @@ -167,38 +285,66 @@ xmlSecGnuTLSShutdown(void) { */ int xmlSecGnuTLSKeysMngrInit(xmlSecKeysMngrPtr mngr) { + int ret; + xmlSecAssert2(mngr != NULL, -1); - /* TODO: add key data stores */ +#ifndef XMLSEC_NO_X509 + /* create x509 store if needed */ + if(xmlSecKeysMngrGetDataStore(mngr, xmlSecGnuTLSX509StoreId) == NULL) { + xmlSecKeyDataStorePtr x509Store; + + x509Store = xmlSecKeyDataStoreCreate(xmlSecGnuTLSX509StoreId); + if(x509Store == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeyDataStoreCreate", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "xmlSecGnuTLSX509StoreId"); + return(-1); + } + + ret = xmlSecKeysMngrAdoptDataStore(mngr, x509Store); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeysMngrAdoptDataStore", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlSecKeyDataStoreDestroy(x509Store); + return(-1); + } + } +#endif /* XMLSEC_NO_X509 */ return(0); } /** * xmlSecGnuTLSGenerateRandom: - * @buffer: the destination buffer. - * @size: the numer of bytes to generate. + * @buffer: the destination buffer. + * @size: the numer of bytes to generate. * * Generates @size random bytes and puts result in @buffer. * * Returns: 0 on success or a negative value otherwise. */ int -xmlSecGnuTLSGenerateRandom(xmlSecBufferPtr buffer, xmlSecSize size) { +xmlSecGnuTLSGenerateRandom(xmlSecBufferPtr buffer, xmlSecSize size) { int ret; - + xmlSecAssert2(buffer != NULL, -1); xmlSecAssert2(size > 0, -1); ret = xmlSecBufferSetSize(buffer, size); if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecBufferSetSize", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "size=%d", size); - return(-1); + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBufferSetSize", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "size=%d", size); + return(-1); } - + /* get random data */ gcry_randomize(xmlSecBufferGetData(buffer), size, GCRY_STRONG_RANDOM); return(0); diff --git a/src/gnutls/digests.c b/src/gnutls/digests.c index fb8109de..2df20706 100644 --- a/src/gnutls/digests.c +++ b/src/gnutls/digests.c @@ -1,18 +1,15 @@ -/** +/** * XMLSec library * * This is free software; see Copyright file in the source * distribution for preciese wording. - * + * * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com> */ #include "globals.h" #include <string.h> -#include <gnutls/gnutls.h> -#include <gcrypt.h> - #include <xmlsec/xmlsec.h> #include <xmlsec/keys.h> #include <xmlsec/transforms.h> @@ -21,298 +18,95 @@ #include <xmlsec/gnutls/app.h> #include <xmlsec/gnutls/crypto.h> -#define XMLSEC_GNUTLS_MAX_DIGEST_SIZE 32 - /************************************************************************** * - * Internal GNUTLS Digest CTX + * We use xmlsec-gcrypt for all the basic crypto ops * *****************************************************************************/ -typedef struct _xmlSecGnuTLSDigestCtx xmlSecGnuTLSDigestCtx, *xmlSecGnuTLSDigestCtxPtr; -struct _xmlSecGnuTLSDigestCtx { - int digest; - GcryMDHd digestCtx; - xmlSecByte dgst[XMLSEC_GNUTLS_MAX_DIGEST_SIZE]; - xmlSecSize dgstSize; /* dgst size in bytes */ -}; +#include <xmlsec/gcrypt/crypto.h> -/****************************************************************************** - * - * Digest transforms +#ifndef XMLSEC_NO_SHA1 +/** + * xmlSecGnuTLSTransformSha1GetKlass: * - * xmlSecGnuTLSDigestCtx is located after xmlSecTransform + * SHA-1 digest transform klass. * - *****************************************************************************/ -#define xmlSecGnuTLSDigestSize \ - (sizeof(xmlSecTransform) + sizeof(xmlSecGnuTLSDigestCtx)) -#define xmlSecGnuTLSDigestGetCtx(transform) \ - ((xmlSecGnuTLSDigestCtxPtr)(((xmlSecByte*)(transform)) + sizeof(xmlSecTransform))) - -static int xmlSecGnuTLSDigestInitialize (xmlSecTransformPtr transform); -static void xmlSecGnuTLSDigestFinalize (xmlSecTransformPtr transform); -static int xmlSecGnuTLSDigestVerify (xmlSecTransformPtr transform, - const xmlSecByte* data, - xmlSecSize dataSize, - xmlSecTransformCtxPtr transformCtx); -static int xmlSecGnuTLSDigestExecute (xmlSecTransformPtr transform, - int last, - xmlSecTransformCtxPtr transformCtx); -static int xmlSecGnuTLSDigestCheckId (xmlSecTransformPtr transform); - -static int -xmlSecGnuTLSDigestCheckId(xmlSecTransformPtr transform) { - -#ifndef XMLSEC_NO_SHA1 - if(xmlSecTransformCheckId(transform, xmlSecGnuTLSTransformSha1Id)) { - return(1); - } -#endif /* XMLSEC_NO_SHA1 */ - - return(0); + * Returns: pointer to SHA-1 digest transform klass. + */ +xmlSecTransformId +xmlSecGnuTLSTransformSha1GetKlass(void) { + return (xmlSecGCryptTransformSha1GetKlass()); } +#endif /* XMLSEC_NO_SHA1 */ -static int -xmlSecGnuTLSDigestInitialize(xmlSecTransformPtr transform) { - xmlSecGnuTLSDigestCtxPtr ctx; -#ifndef XMLSEC_GNUTLS_OLD - gpg_err_code_t ret; -#endif /* XMLSEC_GNUTLS_OLD */ - - xmlSecAssert2(xmlSecGnuTLSDigestCheckId(transform), -1); - xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecGnuTLSDigestSize), -1); - - ctx = xmlSecGnuTLSDigestGetCtx(transform); - xmlSecAssert2(ctx != NULL, -1); - - /* initialize context */ - memset(ctx, 0, sizeof(xmlSecGnuTLSDigestCtx)); - -#ifndef XMLSEC_NO_SHA1 - if(xmlSecTransformCheckId(transform, xmlSecGnuTLSTransformSha1Id)) { - ctx->digest = GCRY_MD_SHA1; - } else -#endif /* XMLSEC_NO_SHA1 */ - if(1) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - NULL, - XMLSEC_ERRORS_R_INVALID_TRANSFORM, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - -#ifndef XMLSEC_GNUTLS_OLD - ret = gcry_md_open(&ctx->digestCtx, ctx->digest, GCRY_MD_FLAG_SECURE); /* we are paranoid */ - if(ret != GPG_ERR_NO_ERROR) { -#else /* XMLSEC_GNUTLS_OLD */ - ctx->digestCtx = gcry_md_open(ctx->digest, GCRY_MD_FLAG_SECURE); /* we are paranoid */ - if(ctx->digestCtx == NULL) { -#endif /* XMLSEC_GNUTLS_OLD */ - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - "gcry_md_open", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - return(0); +#ifndef XMLSEC_NO_SHA256 +/** + * xmlSecGnuTLSTransformSha256GetKlass: + * + * SHA256 digest transform klass. + * + * Returns: pointer to SHA256 digest transform klass. + */ +xmlSecTransformId +xmlSecGnuTLSTransformSha256GetKlass(void) { + return (xmlSecGCryptTransformSha256GetKlass()); } +#endif /* XMLSEC_NO_SHA256 */ -static void -xmlSecGnuTLSDigestFinalize(xmlSecTransformPtr transform) { - xmlSecGnuTLSDigestCtxPtr ctx; - - xmlSecAssert(xmlSecGnuTLSDigestCheckId(transform)); - xmlSecAssert(xmlSecTransformCheckSize(transform, xmlSecGnuTLSDigestSize)); - - ctx = xmlSecGnuTLSDigestGetCtx(transform); - xmlSecAssert(ctx != NULL); - - if(ctx->digestCtx != NULL) { - gcry_md_close(ctx->digestCtx); - } - memset(ctx, 0, sizeof(xmlSecGnuTLSDigestCtx)); +#ifndef XMLSEC_NO_SHA384 +/** + * xmlSecGnuTLSTransformSha384GetKlass: + * + * SHA384 digest transform klass. + * + * Returns: pointer to SHA384 digest transform klass. + */ +xmlSecTransformId +xmlSecGnuTLSTransformSha384GetKlass(void) { + return (xmlSecGCryptTransformSha384GetKlass()); } +#endif /* XMLSEC_NO_SHA384 */ -static int -xmlSecGnuTLSDigestVerify(xmlSecTransformPtr transform, - const xmlSecByte* data, xmlSecSize dataSize, - xmlSecTransformCtxPtr transformCtx) { - xmlSecGnuTLSDigestCtxPtr ctx; - - xmlSecAssert2(xmlSecGnuTLSDigestCheckId(transform), -1); - xmlSecAssert2(transform->operation == xmlSecTransformOperationVerify, -1); - xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecGnuTLSDigestSize), -1); - xmlSecAssert2(transform->status == xmlSecTransformStatusFinished, -1); - xmlSecAssert2(data != NULL, -1); - xmlSecAssert2(transformCtx != NULL, -1); - - ctx = xmlSecGnuTLSDigestGetCtx(transform); - xmlSecAssert2(ctx != NULL, -1); - xmlSecAssert2(ctx->dgstSize > 0, -1); - - if(dataSize != ctx->dgstSize) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - NULL, - XMLSEC_ERRORS_R_INVALID_DATA, - "data and digest sizes are different (data=%d, dgst=%d)", - dataSize, ctx->dgstSize); - transform->status = xmlSecTransformStatusFail; - return(0); - } - - if(memcmp(ctx->dgst, data, dataSize) != 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - NULL, - XMLSEC_ERRORS_R_INVALID_DATA, - "data and digest do not match"); - transform->status = xmlSecTransformStatusFail; - return(0); - } - - transform->status = xmlSecTransformStatusOk; - return(0); +#ifndef XMLSEC_NO_SHA512 +/** + * xmlSecGnuTLSTransformSha512GetKlass: + * + * SHA512 digest transform klass. + * + * Returns: pointer to SHA512 digest transform klass. + */ +xmlSecTransformId +xmlSecGnuTLSTransformSha512GetKlass(void) { + return (xmlSecGCryptTransformSha512GetKlass()); } +#endif /* XMLSEC_NO_SHA512 */ -static int -xmlSecGnuTLSDigestExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) { - xmlSecGnuTLSDigestCtxPtr ctx; - xmlSecBufferPtr in, out; - int ret; - - xmlSecAssert2(xmlSecGnuTLSDigestCheckId(transform), -1); - xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1); - xmlSecAssert2(transformCtx != NULL, -1); - xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecGnuTLSDigestSize), -1); - - ctx = xmlSecGnuTLSDigestGetCtx(transform); - xmlSecAssert2(ctx != NULL, -1); - xmlSecAssert2(ctx->digest != GCRY_MD_NONE, -1); - xmlSecAssert2(ctx->digestCtx != NULL, -1); - - in = &(transform->inBuf); - out = &(transform->outBuf); - - if(transform->status == xmlSecTransformStatusNone) { - transform->status = xmlSecTransformStatusWorking; - } - - if(transform->status == xmlSecTransformStatusWorking) { - xmlSecSize inSize; - - inSize = xmlSecBufferGetSize(in); - if(inSize > 0) { - gcry_md_write(ctx->digestCtx, xmlSecBufferGetData(in), inSize); - - ret = xmlSecBufferRemoveHead(in, inSize); - if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - "xmlSecBufferRemoveHead", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "size=%d", inSize); - return(-1); - } - } - if(last) { - xmlSecByte* buf; - - /* get the final digest */ - gcry_md_final(ctx->digestCtx); - buf = gcry_md_read(ctx->digestCtx, ctx->digest); - if(buf == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - "gcry_md_read", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - - /* copy it to our internal buffer */ - ctx->dgstSize = gcry_md_get_algo_dlen(ctx->digest); - xmlSecAssert2(ctx->dgstSize > 0, -1); - xmlSecAssert2(ctx->dgstSize <= sizeof(ctx->dgst), -1); - memcpy(ctx->dgst, buf, ctx->dgstSize); - - /* and to the output if needed */ - if(transform->operation == xmlSecTransformOperationSign) { - ret = xmlSecBufferAppend(out, ctx->dgst, ctx->dgstSize); - if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - "xmlSecBufferAppend", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "size=%d", ctx->dgstSize); - return(-1); - } - } - transform->status = xmlSecTransformStatusFinished; - } - } else if(transform->status == xmlSecTransformStatusFinished) { - /* the only way we can get here is if there is no input */ - xmlSecAssert2(xmlSecBufferGetSize(&(transform->inBuf)) == 0, -1); - } else { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - NULL, - XMLSEC_ERRORS_R_INVALID_STATUS, - "status=%d", transform->status); - return(-1); - } - - return(0); -} +#ifndef XMLSEC_NO_MD5 -#ifndef XMLSEC_NO_SHA1 -/****************************************************************************** +/** + * xmlSecGnuTLSTransformMd5GetKlass: * - * SHA1 Digest transforms + * MD5 digest transform klass. * - *****************************************************************************/ -static xmlSecTransformKlass xmlSecGnuTLSSha1Klass = { - /* klass/object sizes */ - sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */ - xmlSecGnuTLSDigestSize, /* xmlSecSize objSize */ - - /* data */ - xmlSecNameSha1, /* const xmlChar* name; */ - xmlSecHrefSha1, /* const xmlChar* href; */ - xmlSecTransformUsageDigestMethod, /* xmlSecTransformUsage usage; */ - - /* methods */ - xmlSecGnuTLSDigestInitialize, /* xmlSecTransformInitializeMethod initialize; */ - xmlSecGnuTLSDigestFinalize, /* xmlSecTransformFinalizeMethod finalize; */ - NULL, /* xmlSecTransformNodeReadMethod readNode; */ - NULL, /* xmlSecTransformNodeWriteMethod writeNode; */ - NULL, /* xmlSecTransformSetKeyReqMethod setKeyReq; */ - NULL, /* xmlSecTransformSetKeyMethod setKey; */ - xmlSecGnuTLSDigestVerify, /* xmlSecTransformVerifyMethod verify; */ - xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */ - xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */ - xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */ - NULL, /* xmlSecTransformPushXmlMethod pushXml; */ - NULL, /* xmlSecTransformPopXmlMethod popXml; */ - xmlSecGnuTLSDigestExecute, /* xmlSecTransformExecuteMethod execute; */ - - NULL, /* void* reserved0; */ - NULL, /* void* reserved1; */ -}; + * Returns: pointer to MD5 digest transform klass. + */ +xmlSecTransformId +xmlSecGnuTLSTransformMd5GetKlass(void) { + return (xmlSecGCryptTransformMd5GetKlass()); +} +#endif /* XMLSEC_NO_MD5 */ -/** - * xmlSecGnuTLSTransformSha1GetKlass: +#ifndef XMLSEC_NO_RIPEMD160 +/** + * xmlSecGnuTLSTransformRipemd160GetKlass: * - * SHA-1 digest transform klass. + * RIPEMD160 digest transform klass. * - * Returns: pointer to SHA-1 digest transform klass. + * Returns: pointer to RIPEMD160 digest transform klass. */ -xmlSecTransformId -xmlSecGnuTLSTransformSha1GetKlass(void) { - return(&xmlSecGnuTLSSha1Klass); +xmlSecTransformId +xmlSecGnuTLSTransformRipemd160GetKlass(void) { + return (xmlSecGCryptTransformRipemd160GetKlass()); } -#endif /* XMLSEC_NO_SHA1 */ - - +#endif /* XMLSEC_NO_RIPEMD160 */ diff --git a/src/gnutls/globals.h b/src/gnutls/globals.h index 272a27b8..b49e2404 100644 --- a/src/gnutls/globals.h +++ b/src/gnutls/globals.h @@ -5,14 +5,14 @@ * * This is free software; see Copyright file in the source * distribution for preciese wording. - * + * * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com> */ #ifndef __XMLSEC_GLOBALS_H__ #define __XMLSEC_GLOBALS_H__ /** - * Use autoconf defines if present. + * Use autoconf defines if present. */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -21,4 +21,11 @@ #define IN_XMLSEC_CRYPTO #define XMLSEC_PRIVATE +#define XMLSEC_GNUTLS_GCRYPT_REPORT_ERROR(err) \ + "error code=%d; error message='%s'", \ + (int)err, xmlSecErrorsSafeString(gcry_strerror((err))) +#define XMLSEC_GNUTLS_REPORT_ERROR(err) \ + "error code=%d; error message='%s'", \ + (int)err, xmlSecErrorsSafeString(gnutls_strerror((err))) + #endif /* ! __XMLSEC_GLOBALS_H__ */ diff --git a/src/gnutls/hmac.c b/src/gnutls/hmac.c index bc106471..5d1acfc2 100644 --- a/src/gnutls/hmac.c +++ b/src/gnutls/hmac.c @@ -1,9 +1,9 @@ -/** +/** * XMLSec library * * This is free software; see Copyright file in the source * distribution for preciese wording. - * + * * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com> */ #ifndef XMLSEC_NO_HMAC @@ -11,9 +11,6 @@ #include <string.h> -#include <gnutls/gnutls.h> -#include <gcrypt.h> - #include <xmlsec/xmlsec.h> #include <xmlsec/xmltree.h> #include <xmlsec/keys.h> @@ -23,579 +20,122 @@ #include <xmlsec/gnutls/app.h> #include <xmlsec/gnutls/crypto.h> -/* sizes in bits */ -#define XMLSEC_GNUTLS_MIN_HMAC_SIZE 80 -#define XMLSEC_GNUTLS_MAX_HMAC_SIZE (128 * 8) - /************************************************************************** * - * Configuration + * We use xmlsec-gcrypt for all the basic crypto ops * *****************************************************************************/ -static int g_xmlsec_gnutls_hmac_min_length = XMLSEC_GNUTLS_MIN_HMAC_SIZE; +#include <xmlsec/gcrypt/crypto.h> /** - * xmlSecGnuTLSHmacGetMinOutputLength: - * + * xmlSecGnuTLSHmacGetMinOutputLength: + * * Gets the value of min HMAC length. - * + * * Returns: the min HMAC output length */ int xmlSecGnuTLSHmacGetMinOutputLength(void) { - return g_xmlsec_gnutls_hmac_min_length; + return xmlSecGCryptHmacGetMinOutputLength(); } /** - * xmlSecGnuTLSHmacSetMinOutputLength: - * @min_length: the new min length - * + * xmlSecGnuTLSHmacSetMinOutputLength: + * @min_length: the new min length + * * Sets the min HMAC output length */ void xmlSecGnuTLSHmacSetMinOutputLength(int min_length) { - g_xmlsec_gnutls_hmac_min_length = min_length; + xmlSecGCryptHmacSetMinOutputLength(min_length); } -/************************************************************************** - * - * Internal GNUTLS HMAC CTX - * - *****************************************************************************/ -typedef struct _xmlSecGnuTLSHmacCtx xmlSecGnuTLSHmacCtx, *xmlSecGnuTLSHmacCtxPtr; -struct _xmlSecGnuTLSHmacCtx { - int digest; - GcryMDHd digestCtx; - xmlSecByte dgst[XMLSEC_GNUTLS_MAX_HMAC_SIZE / 8]; - xmlSecSize dgstSize; /* dgst size in bits */ -}; -/****************************************************************************** - * - * HMAC transforms + +#ifndef XMLSEC_NO_SHA1 +/** + * xmlSecGnuTLSTransformHmacSha1GetKlass: * - * xmlSecGnuTLSHmacCtx is located after xmlSecTransform + * The HMAC-SHA1 transform klass. * - *****************************************************************************/ -#define xmlSecGnuTLSHmacGetCtx(transform) \ - ((xmlSecGnuTLSHmacCtxPtr)(((xmlSecByte*)(transform)) + sizeof(xmlSecTransform))) -#define xmlSecGnuTLSHmacSize \ - (sizeof(xmlSecTransform) + sizeof(xmlSecGnuTLSHmacCtx)) -#define xmlSecGnuTLSHmacCheckId(transform) \ - (xmlSecTransformCheckId((transform), xmlSecGnuTLSTransformHmacSha1Id) || \ - xmlSecTransformCheckId((transform), xmlSecGnuTLSTransformHmacMd5Id) || \ - xmlSecTransformCheckId((transform), xmlSecGnuTLSTransformHmacRipemd160Id)) - -static int xmlSecGnuTLSHmacInitialize (xmlSecTransformPtr transform); -static void xmlSecGnuTLSHmacFinalize (xmlSecTransformPtr transform); -static int xmlSecGnuTLSHmacNodeRead (xmlSecTransformPtr transform, - xmlNodePtr node, - xmlSecTransformCtxPtr transformCtx); -static int xmlSecGnuTLSHmacSetKeyReq (xmlSecTransformPtr transform, - xmlSecKeyReqPtr keyReq); -static int xmlSecGnuTLSHmacSetKey (xmlSecTransformPtr transform, - xmlSecKeyPtr key); -static int xmlSecGnuTLSHmacVerify (xmlSecTransformPtr transform, - const xmlSecByte* data, - xmlSecSize dataSize, - xmlSecTransformCtxPtr transformCtx); -static int xmlSecGnuTLSHmacExecute (xmlSecTransformPtr transform, - int last, - xmlSecTransformCtxPtr transformCtx); - -static int -xmlSecGnuTLSHmacInitialize(xmlSecTransformPtr transform) { - xmlSecGnuTLSHmacCtxPtr ctx; -#ifndef XMLSEC_GNUTLS_OLD - gpg_err_code_t ret; -#endif /* XMLSEC_GNUTLS_OLD */ - - xmlSecAssert2(xmlSecGnuTLSHmacCheckId(transform), -1); - xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecGnuTLSHmacSize), -1); - - ctx = xmlSecGnuTLSHmacGetCtx(transform); - xmlSecAssert2(ctx != NULL, -1); - - memset(ctx, 0, sizeof(xmlSecGnuTLSHmacCtx)); - if(xmlSecTransformCheckId(transform, xmlSecGnuTLSTransformHmacSha1Id)) { - ctx->digest = GCRY_MD_SHA1; - } else if(xmlSecTransformCheckId(transform, xmlSecGnuTLSTransformHmacMd5Id)) { - ctx->digest = GCRY_MD_MD5; - } else if(xmlSecTransformCheckId(transform, xmlSecGnuTLSTransformHmacRipemd160Id)) { - ctx->digest = GCRY_MD_RMD160; - } else { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - NULL, - XMLSEC_ERRORS_R_INVALID_TRANSFORM, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - -#ifndef XMLSEC_GNUTLS_OLD - ret = gcry_md_open(&ctx->digestCtx, ctx->digest, GCRY_MD_FLAG_HMAC | GCRY_MD_FLAG_SECURE); /* we are paranoid */ - if(ret != GPG_ERR_NO_ERROR) { -#else /* XMLSEC_GNUTLS_OLD */ - ctx->digestCtx = gcry_md_open(ctx->digest, GCRY_MD_FLAG_HMAC | GCRY_MD_FLAG_SECURE); /* we are paranoid */ - if(ctx->digestCtx == NULL) { -#endif /* XMLSEC_GNUTLS_OLD */ - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - "gcry_md_open", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - - return(0); -} - -static void -xmlSecGnuTLSHmacFinalize(xmlSecTransformPtr transform) { - xmlSecGnuTLSHmacCtxPtr ctx; - - xmlSecAssert(xmlSecGnuTLSHmacCheckId(transform)); - xmlSecAssert(xmlSecTransformCheckSize(transform, xmlSecGnuTLSHmacSize)); - - ctx = xmlSecGnuTLSHmacGetCtx(transform); - xmlSecAssert(ctx != NULL); - - if(ctx->digestCtx != NULL) { - gcry_md_close(ctx->digestCtx); - } - memset(ctx, 0, sizeof(xmlSecGnuTLSHmacCtx)); + * Returns: the HMAC-SHA1 transform klass. + */ +xmlSecTransformId +xmlSecGnuTLSTransformHmacSha1GetKlass(void) { + return (xmlSecGCryptTransformHmacSha1GetKlass()); } +#endif /* XMLSEC_NO_SHA1 */ +#ifndef XMLSEC_NO_SHA256 /** - * xmlSecGnuTLSHmacNodeRead: + * xmlSecGnuTLSTransformHmacSha256GetKlass: * - * HMAC (http://www.w3.org/TR/xmldsig-core/#sec-HMAC): + * The HMAC-SHA256 transform klass. * - * The HMAC algorithm (RFC2104 [HMAC]) takes the truncation length in bits - * as a parameter; if the parameter is not specified then all the bits of the - * hash are output. An example of an HMAC SignatureMethod element: - * <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1"> - * <HMACOutputLength>128</HMACOutputLength> - * </SignatureMethod> - * - * Schema Definition: - * - * <simpleType name="HMACOutputLengthType"> - * <restriction base="integer"/> - * </simpleType> - * - * DTD: - * - * <!ELEMENT HMACOutputLength (#PCDATA)> + * Returns: the HMAC-SHA256 transform klass. */ -static int -xmlSecGnuTLSHmacNodeRead(xmlSecTransformPtr transform, xmlNodePtr node, xmlSecTransformCtxPtr transformCtx) { - xmlSecGnuTLSHmacCtxPtr ctx; - xmlNodePtr cur; - - xmlSecAssert2(xmlSecGnuTLSHmacCheckId(transform), -1); - xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecGnuTLSHmacSize), -1); - xmlSecAssert2(node != NULL, -1); - xmlSecAssert2(transformCtx != NULL, -1); - - ctx = xmlSecGnuTLSHmacGetCtx(transform); - xmlSecAssert2(ctx != NULL, -1); - - cur = xmlSecGetNextElementNode(node->children); - if((cur != NULL) && xmlSecCheckNodeName(cur, xmlSecNodeHMACOutputLength, xmlSecDSigNs)) { - xmlChar *content; - - content = xmlNodeGetContent(cur); - if(content != NULL) { - ctx->dgstSize = atoi((char*)content); - xmlFree(content); - } - - /* Ensure that HMAC length is greater than min specified. - Otherwise, an attacker can set this lenght to 0 or very - small value - */ - if((int)ctx->dgstSize < xmlSecGnuTLSHmacGetMinOutputLength()) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - xmlSecErrorsSafeString(xmlSecNodeGetName(cur)), - XMLSEC_ERRORS_R_INVALID_NODE_ATTRIBUTE, - "HMAC output length is too small"); - return(-1); - } - - cur = xmlSecGetNextElementNode(cur->next); - } - - if(cur != NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - xmlSecErrorsSafeString(xmlSecNodeGetName(cur)), - XMLSEC_ERRORS_R_INVALID_NODE, - "no nodes expected"); - return(-1); - } - return(0); +xmlSecTransformId +xmlSecGnuTLSTransformHmacSha256GetKlass(void) { + return (xmlSecGCryptTransformHmacSha256GetKlass()); } +#endif /* XMLSEC_NO_SHA256 */ - -static int -xmlSecGnuTLSHmacSetKeyReq(xmlSecTransformPtr transform, xmlSecKeyReqPtr keyReq) { - xmlSecGnuTLSHmacCtxPtr ctx; - - xmlSecAssert2(xmlSecGnuTLSHmacCheckId(transform), -1); - xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1); - xmlSecAssert2(keyReq != NULL, -1); - xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecGnuTLSHmacSize), -1); - - ctx = xmlSecGnuTLSHmacGetCtx(transform); - xmlSecAssert2(ctx != NULL, -1); - - keyReq->keyId = xmlSecGnuTLSKeyDataHmacId; - keyReq->keyType= xmlSecKeyDataTypeSymmetric; - if(transform->operation == xmlSecTransformOperationSign) { - keyReq->keyUsage = xmlSecKeyUsageSign; - } else { - keyReq->keyUsage = xmlSecKeyUsageVerify; - } - - return(0); -} - -static int -xmlSecGnuTLSHmacSetKey(xmlSecTransformPtr transform, xmlSecKeyPtr key) { - xmlSecGnuTLSHmacCtxPtr ctx; - xmlSecKeyDataPtr value; - xmlSecBufferPtr buffer; - int ret; - - xmlSecAssert2(xmlSecGnuTLSHmacCheckId(transform), -1); - xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1); - xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecGnuTLSHmacSize), -1); - xmlSecAssert2(key != NULL, -1); - - ctx = xmlSecGnuTLSHmacGetCtx(transform); - xmlSecAssert2(ctx != NULL, -1); - xmlSecAssert2(ctx->digestCtx != NULL, -1); - - value = xmlSecKeyGetValue(key); - xmlSecAssert2(xmlSecKeyDataCheckId(value, xmlSecGnuTLSKeyDataHmacId), -1); - - buffer = xmlSecKeyDataBinaryValueGetBuffer(value); - xmlSecAssert2(buffer != NULL, -1); - - if(xmlSecBufferGetSize(buffer) == 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - NULL, - XMLSEC_ERRORS_R_INVALID_KEY_DATA_SIZE, - "key is empty"); - return(-1); - } - - ret = gcry_md_setkey(ctx->digestCtx, xmlSecBufferGetData(buffer), - xmlSecBufferGetSize(buffer)); - if(ret != 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - "gcry_md_setkey", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - "ret=%d", ret); - return(-1); - } - return(0); -} - -static int -xmlSecGnuTLSHmacVerify(xmlSecTransformPtr transform, - const xmlSecByte* data, xmlSecSize dataSize, - xmlSecTransformCtxPtr transformCtx) { - static xmlSecByte last_byte_masks[] = - { 0xFF, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE }; - - xmlSecGnuTLSHmacCtxPtr ctx; - xmlSecByte mask; - - xmlSecAssert2(xmlSecTransformIsValid(transform), -1); - xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecGnuTLSHmacSize), -1); - xmlSecAssert2(transform->operation == xmlSecTransformOperationVerify, -1); - xmlSecAssert2(transform->status == xmlSecTransformStatusFinished, -1); - xmlSecAssert2(data != NULL, -1); - xmlSecAssert2(transformCtx != NULL, -1); - - ctx = xmlSecGnuTLSHmacGetCtx(transform); - xmlSecAssert2(ctx != NULL, -1); - xmlSecAssert2(ctx->digestCtx != NULL, -1); - xmlSecAssert2(ctx->dgstSize > 0, -1); - - /* compare the digest size in bytes */ - if(dataSize != ((ctx->dgstSize + 7) / 8)){ - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - NULL, - XMLSEC_ERRORS_R_INVALID_SIZE, - "data=%d;dgst=%d", - dataSize, ((ctx->dgstSize + 7) / 8)); - transform->status = xmlSecTransformStatusFail; - return(0); - } - - /* we check the last byte separatelly */ - xmlSecAssert2(dataSize > 0, -1); - mask = last_byte_masks[ctx->dgstSize % 8]; - if((ctx->dgst[dataSize - 1] & mask) != (data[dataSize - 1] & mask)) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - NULL, - XMLSEC_ERRORS_R_DATA_NOT_MATCH, - "data and digest do not match (last byte)"); - transform->status = xmlSecTransformStatusFail; - return(0); - } - - /* now check the rest of the digest */ - if((dataSize > 1) && (memcmp(ctx->dgst, data, dataSize - 1) != 0)) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - NULL, - XMLSEC_ERRORS_R_DATA_NOT_MATCH, - "data and digest do not match"); - transform->status = xmlSecTransformStatusFail; - return(0); - } - - transform->status = xmlSecTransformStatusOk; - return(0); -} - -static int -xmlSecGnuTLSHmacExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) { - xmlSecGnuTLSHmacCtxPtr ctx; - xmlSecBufferPtr in, out; - xmlSecByte* dgst; - xmlSecSize dgstSize; - int ret; - - xmlSecAssert2(xmlSecGnuTLSHmacCheckId(transform), -1); - xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1); - xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecGnuTLSHmacSize), -1); - xmlSecAssert2(transformCtx != NULL, -1); - - ctx = xmlSecGnuTLSHmacGetCtx(transform); - xmlSecAssert2(ctx != NULL, -1); - xmlSecAssert2(ctx->digestCtx != NULL, -1); - - in = &(transform->inBuf); - out = &(transform->outBuf); - - if(transform->status == xmlSecTransformStatusNone) { - transform->status = xmlSecTransformStatusWorking; - } - - if(transform->status == xmlSecTransformStatusWorking) { - xmlSecSize inSize; - - inSize = xmlSecBufferGetSize(in); - if(inSize > 0) { - gcry_md_write(ctx->digestCtx, xmlSecBufferGetData(in), inSize); - - ret = xmlSecBufferRemoveHead(in, inSize); - if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - "xmlSecBufferRemoveHead", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "size=%d", inSize); - return(-1); - } - } - if(last) { - /* get the final digest */ - gcry_md_final(ctx->digestCtx); - dgst = gcry_md_read(ctx->digestCtx, ctx->digest); - if(dgst == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - "gcry_md_read", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - - /* copy it to our internal buffer */ - dgstSize = gcry_md_get_algo_dlen(ctx->digest); - xmlSecAssert2(dgstSize > 0, -1); - xmlSecAssert2(dgstSize <= sizeof(ctx->dgst), -1); - memcpy(ctx->dgst, dgst, dgstSize); - - /* check/set the result digest size */ - if(ctx->dgstSize == 0) { - ctx->dgstSize = dgstSize * 8; /* no dgst size specified, use all we have */ - } else if(ctx->dgstSize <= 8 * dgstSize) { - dgstSize = ((ctx->dgstSize + 7) / 8); /* we need to truncate result digest */ - } else { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - NULL, - XMLSEC_ERRORS_R_INVALID_SIZE, - "result-bits=%d;required-bits=%d", - 8 * dgstSize, ctx->dgstSize); - return(-1); - } - - if(transform->operation == xmlSecTransformOperationSign) { - ret = xmlSecBufferAppend(out, ctx->dgst, dgstSize); - if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - "xmlSecBufferAppend", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "size=%d", dgstSize); - return(-1); - } - } - transform->status = xmlSecTransformStatusFinished; - } - } else if(transform->status == xmlSecTransformStatusFinished) { - /* the only way we can get here is if there is no input */ - xmlSecAssert2(xmlSecBufferGetSize(&(transform->inBuf)) == 0, -1); - } else { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - NULL, - XMLSEC_ERRORS_R_INVALID_STATUS, - "size=%d", transform->status); - return(-1); - } - - return(0); -} - -/** - * HMAC SHA1 - */ -static xmlSecTransformKlass xmlSecGnuTLSHmacSha1Klass = { - /* klass/object sizes */ - sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */ - xmlSecGnuTLSHmacSize, /* xmlSecSize objSize */ - - xmlSecNameHmacSha1, /* const xmlChar* name; */ - xmlSecHrefHmacSha1, /* const xmlChar *href; */ - xmlSecTransformUsageSignatureMethod, /* xmlSecTransformUsage usage; */ - - xmlSecGnuTLSHmacInitialize, /* xmlSecTransformInitializeMethod initialize; */ - xmlSecGnuTLSHmacFinalize, /* xmlSecTransformFinalizeMethod finalize; */ - xmlSecGnuTLSHmacNodeRead, /* xmlSecTransformNodeReadMethod readNode; */ - NULL, /* xmlSecTransformNodeWriteMethod writeNode; */ - xmlSecGnuTLSHmacSetKeyReq, /* xmlSecTransformSetKeyReqMethod setKeyReq; */ - xmlSecGnuTLSHmacSetKey, /* xmlSecTransformSetKeyMethod setKey; */ - xmlSecGnuTLSHmacVerify, /* xmlSecTransformValidateMethod validate; */ - xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */ - xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */ - xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */ - NULL, /* xmlSecTransformPushXmlMethod pushXml; */ - NULL, /* xmlSecTransformPopXmlMethod popXml; */ - xmlSecGnuTLSHmacExecute, /* xmlSecTransformExecuteMethod execute; */ - - NULL, /* void* reserved0; */ - NULL, /* void* reserved1; */ -}; - -/** - * xmlSecGnuTLSTransformHmacSha1GetKlass: +#ifndef XMLSEC_NO_SHA384 +/** + * xmlSecGnuTLSTransformHmacSha384GetKlass: * - * The HMAC-SHA1 transform klass. + * The HMAC-SHA384 transform klass. * - * Returns: the HMAC-SHA1 transform klass. + * Returns: the HMAC-SHA384 transform klass. */ -xmlSecTransformId -xmlSecGnuTLSTransformHmacSha1GetKlass(void) { - return(&xmlSecGnuTLSHmacSha1Klass); +xmlSecTransformId +xmlSecGnuTLSTransformHmacSha384GetKlass(void) { + return (xmlSecGCryptTransformHmacSha384GetKlass()); } +#endif /* XMLSEC_NO_SHA384 */ -/** - * HMAC Ripemd160 +#ifndef XMLSEC_NO_SHA512 +/** + * xmlSecGnuTLSTransformHmacSha512GetKlass: + * + * The HMAC-SHA512 transform klass. + * + * Returns: the HMAC-SHA512 transform klass. */ -static xmlSecTransformKlass xmlSecGnuTLSHmacRipemd160Klass = { - /* klass/object sizes */ - sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */ - xmlSecGnuTLSHmacSize, /* xmlSecSize objSize */ +xmlSecTransformId +xmlSecGnuTLSTransformHmacSha512GetKlass(void) { + return (xmlSecGCryptTransformHmacSha512GetKlass()); +} +#endif /* XMLSEC_NO_SHA512 */ - xmlSecNameHmacRipemd160, /* const xmlChar* name; */ - xmlSecHrefHmacRipemd160, /* const xmlChar* href; */ - xmlSecTransformUsageSignatureMethod, /* xmlSecTransformUsage usage; */ - - xmlSecGnuTLSHmacInitialize, /* xmlSecTransformInitializeMethod initialize; */ - xmlSecGnuTLSHmacFinalize, /* xmlSecTransformFinalizeMethod finalize; */ - xmlSecGnuTLSHmacNodeRead, /* xmlSecTransformNodeReadMethod readNode; */ - NULL, /* xmlSecTransformNodeWriteMethod writeNode; */ - xmlSecGnuTLSHmacSetKeyReq, /* xmlSecTransformSetKeyReqMethod setKeyReq; */ - xmlSecGnuTLSHmacSetKey, /* xmlSecTransformSetKeyMethod setKey; */ - xmlSecGnuTLSHmacVerify, /* xmlSecTransformValidateMethod validate; */ - xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */ - xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */ - xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */ - NULL, /* xmlSecTransformPushXmlMethod pushXml; */ - NULL, /* xmlSecTransformPopXmlMethod popXml; */ - xmlSecGnuTLSHmacExecute, /* xmlSecTransformExecuteMethod execute; */ - - NULL, /* void* reserved0; */ - NULL, /* void* reserved1; */ -}; -/** +#ifndef XMLSEC_NO_RIPEMD160 +/** * xmlSecGnuTLSTransformHmacRipemd160GetKlass: * * The HMAC-RIPEMD160 transform klass. * * Returns: the HMAC-RIPEMD160 transform klass. */ -xmlSecTransformId +xmlSecTransformId xmlSecGnuTLSTransformHmacRipemd160GetKlass(void) { - return(&xmlSecGnuTLSHmacRipemd160Klass); + return (xmlSecGCryptTransformHmacRipemd160GetKlass()); } +#endif /* XMLSEC_NO_RIPEMD160 */ -/** - * HMAC Md5 - */ -static xmlSecTransformKlass xmlSecGnuTLSHmacMd5Klass = { - /* klass/object sizes */ - sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */ - xmlSecGnuTLSHmacSize, /* xmlSecSize objSize */ - - xmlSecNameHmacMd5, /* const xmlChar* name; */ - xmlSecHrefHmacMd5, /* const xmlChar* href; */ - xmlSecTransformUsageSignatureMethod, /* xmlSecTransformUsage usage; */ - - xmlSecGnuTLSHmacInitialize, /* xmlSecTransformInitializeMethod initialize; */ - xmlSecGnuTLSHmacFinalize, /* xmlSecTransformFinalizeMethod finalize; */ - xmlSecGnuTLSHmacNodeRead, /* xmlSecTransformNodeReadMethod readNode; */ - NULL, /* xmlSecTransformNodeWriteMethod writeNode; */ - xmlSecGnuTLSHmacSetKeyReq, /* xmlSecTransformSetKeyReqMethod setKeyReq; */ - xmlSecGnuTLSHmacSetKey, /* xmlSecTransformSetKeyMethod setKey; */ - xmlSecGnuTLSHmacVerify, /* xmlSecTransformValidateMethod validate; */ - xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */ - xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */ - xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */ - NULL, /* xmlSecTransformPushXmlMethod pushXml; */ - NULL, /* xmlSecTransformPopXmlMethod popXml; */ - xmlSecGnuTLSHmacExecute, /* xmlSecTransformExecuteMethod execute; */ - - NULL, /* void* reserved0; */ - NULL, /* void* reserved1; */ -}; - -/** +#ifndef XMLSEC_NO_MD5 +/** * xmlSecGnuTLSTransformHmacMd5GetKlass: * * The HMAC-MD5 transform klass. * * Returns: the HMAC-MD5 transform klass. */ -xmlSecTransformId +xmlSecTransformId xmlSecGnuTLSTransformHmacMd5GetKlass(void) { - return(&xmlSecGnuTLSHmacMd5Klass); + return (xmlSecGCryptTransformHmacMd5GetKlass()); } +#endif /* XMLSEC_NO_MD5 */ #endif /* XMLSEC_NO_HMAC */ diff --git a/src/gnutls/kw_aes.c b/src/gnutls/kw_aes.c new file mode 100644 index 00000000..63f8a6be --- /dev/null +++ b/src/gnutls/kw_aes.c @@ -0,0 +1,72 @@ +/** + * + * XMLSec library + * + * AES Algorithm support + * + * This is free software; see Copyright file in the source + * distribution for preciese wording. + * + * Copyright (C) 2010 Aleksey Sanin <aleksey@aleksey.com> + */ +#ifndef XMLSEC_NO_AES +#include "globals.h" + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include <xmlsec/xmlsec.h> +#include <xmlsec/xmltree.h> +#include <xmlsec/keys.h> +#include <xmlsec/transforms.h> +#include <xmlsec/errors.h> + +#include <xmlsec/gnutls/crypto.h> + +/************************************************************************** + * + * We use xmlsec-gcrypt for all the basic crypto ops + * + *****************************************************************************/ +#include <xmlsec/gcrypt/crypto.h> + + + +/** + * xmlSecGnuTLSTransformKWAes128GetKlass: + * + * The AES-128 kew wrapper transform klass. + * + * Returns: AES-128 kew wrapper transform klass. + */ +xmlSecTransformId +xmlSecGnuTLSTransformKWAes128GetKlass(void) { + return(xmlSecGCryptTransformKWAes128GetKlass()); +} + +/** + * xmlSecGnuTLSTransformKWAes192GetKlass: + * + * The AES-192 kew wrapper transform klass. + * + * Returns: AES-192 kew wrapper transform klass. + */ +xmlSecTransformId +xmlSecGnuTLSTransformKWAes192GetKlass(void) { + return(xmlSecGCryptTransformKWAes192GetKlass()); +} + +/** + * xmlSecGnuTLSTransformKWAes256GetKlass: + * + * The AES-256 kew wrapper transform klass. + * + * Returns: AES-256 kew wrapper transform klass. + */ +xmlSecTransformId +xmlSecGnuTLSTransformKWAes256GetKlass(void) { + return(xmlSecGCryptTransformKWAes256GetKlass()); +} + +#endif /* XMLSEC_NO_AES */ diff --git a/src/gnutls/kw_des.c b/src/gnutls/kw_des.c new file mode 100644 index 00000000..5d2a2e55 --- /dev/null +++ b/src/gnutls/kw_des.c @@ -0,0 +1,51 @@ +/** + * + * XMLSec library + * + * DES Algorithm support + * + * This is free software; see Copyright file in the source + * distribution for preciese wording. + * + * Copyright (C) 2010 Aleksey Sanin <aleksey@aleksey.com> + */ +#ifndef XMLSEC_NO_DES +#include "globals.h" + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include <gcrypt.h> + + +#include <xmlsec/xmlsec.h> +#include <xmlsec/xmltree.h> +#include <xmlsec/keys.h> +#include <xmlsec/transforms.h> +#include <xmlsec/errors.h> + +#include <xmlsec/gnutls/crypto.h> + +/************************************************************************** + * + * We use xmlsec-gcrypt for all the basic crypto ops + * + *****************************************************************************/ +#include <xmlsec/gcrypt/crypto.h> + + +/** + * xmlSecGnuTLSTransformKWDes3GetKlass: + * + * The Triple DES key wrapper transform klass. + * + * Returns: Triple DES key wrapper transform klass. + */ +xmlSecTransformId +xmlSecGnuTLSTransformKWDes3GetKlass(void) { + return(xmlSecGCryptTransformKWDes3GetKlass()); +} + +#endif /* XMLSEC_NO_DES */ + diff --git a/src/gnutls/signatures.c b/src/gnutls/signatures.c new file mode 100644 index 00000000..98d1f832 --- /dev/null +++ b/src/gnutls/signatures.c @@ -0,0 +1,148 @@ +/** + * XMLSec library + * + * This is free software; see Copyright file in the source + * distribution for preciese wording. + * + * Copyright (C) 2010 Aleksey Sanin <aleksey@aleksey.com> + */ +#include "globals.h" + +#include <string.h> + +#include <xmlsec/xmlsec.h> +#include <xmlsec/keys.h> +#include <xmlsec/transforms.h> +#include <xmlsec/errors.h> + +#include <xmlsec/gnutls/crypto.h> + +/************************************************************************** + * + * We use xmlsec-gcrypt for all the basic crypto ops + * + *****************************************************************************/ +#include <xmlsec/gcrypt/crypto.h> +#include <gcrypt.h> + + +#ifndef XMLSEC_NO_DSA + +#ifndef XMLSEC_NO_SHA1 + +/** + * xmlSecGnuTLSTransformDsaSha1GetKlass: + * + * The DSA-SHA1 signature transform klass. + * + * Returns: DSA-SHA1 signature transform klass. + */ +xmlSecTransformId +xmlSecGnuTLSTransformDsaSha1GetKlass(void) { + return (xmlSecGCryptTransformDsaSha1GetKlass()); +} + +#endif /* XMLSEC_NO_SHA1 */ + +#endif /* XMLSEC_NO_DSA */ + +#ifndef XMLSEC_NO_RSA + +#ifndef XMLSEC_NO_MD5 + +/** + * xmlSecGnuTLSTransformRsaMd5GetKlass: + * + * The RSA-MD5 signature transform klass. + * + * Returns: RSA-MD5 signature transform klass. + */ +xmlSecTransformId +xmlSecGnuTLSTransformRsaMd5GetKlass(void) { + return (xmlSecGCryptTransformRsaMd5GetKlass()); +} + +#endif /* XMLSEC_NO_MD5 */ + +#ifndef XMLSEC_NO_RIPEMD160 + +/** + * xmlSecGnuTLSTransformRsaRipemd160GetKlass: + * + * The RSA-RIPEMD160 signature transform klass. + * + * Returns: RSA-RIPEMD160 signature transform klass. + */ +xmlSecTransformId +xmlSecGnuTLSTransformRsaRipemd160GetKlass(void) { + return (xmlSecGCryptTransformRsaRipemd160GetKlass()); +} + +#endif /* XMLSEC_NO_RIPEMD160 */ + +#ifndef XMLSEC_NO_SHA1 +/** + * xmlSecGnuTLSTransformRsaSha1GetKlass: + * + * The RSA-SHA1 signature transform klass. + * + * Returns: RSA-SHA1 signature transform klass. + */ +xmlSecTransformId +xmlSecGnuTLSTransformRsaSha1GetKlass(void) { + return (xmlSecGCryptTransformRsaSha1GetKlass()); +} + +#endif /* XMLSEC_NO_SHA1 */ + +#ifndef XMLSEC_NO_SHA256 + +/** + * xmlSecGnuTLSTransformRsaSha256GetKlass: + * + * The RSA-SHA256 signature transform klass. + * + * Returns: RSA-SHA256 signature transform klass. + */ +xmlSecTransformId +xmlSecGnuTLSTransformRsaSha256GetKlass(void) { + return (xmlSecGCryptTransformRsaSha256GetKlass()); +} + +#endif /* XMLSEC_NO_SHA256 */ + +#ifndef XMLSEC_NO_SHA384 + +/** + * xmlSecGnuTLSTransformRsaSha384GetKlass: + * + * The RSA-SHA384 signature transform klass. + * + * Returns: RSA-SHA384 signature transform klass. + */ +xmlSecTransformId +xmlSecGnuTLSTransformRsaSha384GetKlass(void) { + return (xmlSecGCryptTransformRsaSha384GetKlass()); +} + +#endif /* XMLSEC_NO_SHA384 */ + +#ifndef XMLSEC_NO_SHA512 +/** + * xmlSecGnuTLSTransformRsaSha512GetKlass: + * + * The RSA-SHA512 signature transform klass. + * + * Returns: RSA-SHA512 signature transform klass. + */ +xmlSecTransformId +xmlSecGnuTLSTransformRsaSha512GetKlass(void) { + return (xmlSecGCryptTransformRsaSha512GetKlass()); +} + +#endif /* XMLSEC_NO_SHA512 */ + +#endif /* XMLSEC_NO_RSA */ + + + diff --git a/src/gnutls/symkeys.c b/src/gnutls/symkeys.c index 4a11d13a..b1521d62 100644 --- a/src/gnutls/symkeys.c +++ b/src/gnutls/symkeys.c @@ -1,12 +1,12 @@ -/** +/** * * XMLSec library - * + * * DES Algorithm support - * + * * This is free software; see Copyright file in the source * distribution for preciese wording. - * + * * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com> */ #include "globals.h" @@ -24,236 +24,33 @@ #include <xmlsec/gnutls/crypto.h> -/***************************************************************************** - * - * Symmetic (binary) keys - just a wrapper for xmlSecKeyDataBinary - * - ****************************************************************************/ -static int xmlSecGnuTLSSymKeyDataInitialize (xmlSecKeyDataPtr data); -static int xmlSecGnuTLSSymKeyDataDuplicate (xmlSecKeyDataPtr dst, - xmlSecKeyDataPtr src); -static void xmlSecGnuTLSSymKeyDataFinalize (xmlSecKeyDataPtr data); -static int xmlSecGnuTLSSymKeyDataXmlRead (xmlSecKeyDataId id, - xmlSecKeyPtr key, - xmlNodePtr node, - xmlSecKeyInfoCtxPtr keyInfoCtx); -static int xmlSecGnuTLSSymKeyDataXmlWrite (xmlSecKeyDataId id, - xmlSecKeyPtr key, - xmlNodePtr node, - xmlSecKeyInfoCtxPtr keyInfoCtx); -static int xmlSecGnuTLSSymKeyDataBinRead (xmlSecKeyDataId id, - xmlSecKeyPtr key, - const xmlSecByte* buf, - xmlSecSize bufSize, - xmlSecKeyInfoCtxPtr keyInfoCtx); -static int xmlSecGnuTLSSymKeyDataBinWrite (xmlSecKeyDataId id, - xmlSecKeyPtr key, - xmlSecByte** buf, - xmlSecSize* bufSize, - xmlSecKeyInfoCtxPtr keyInfoCtx); -static int xmlSecGnuTLSSymKeyDataGenerate (xmlSecKeyDataPtr data, - xmlSecSize sizeBits, - xmlSecKeyDataType type); - -static xmlSecKeyDataType xmlSecGnuTLSSymKeyDataGetType (xmlSecKeyDataPtr data); -static xmlSecSize xmlSecGnuTLSSymKeyDataGetSize (xmlSecKeyDataPtr data); -static void xmlSecGnuTLSSymKeyDataDebugDump (xmlSecKeyDataPtr data, - FILE* output); -static void xmlSecGnuTLSSymKeyDataDebugXmlDump (xmlSecKeyDataPtr data, - FILE* output); -static int xmlSecGnuTLSSymKeyDataKlassCheck (xmlSecKeyDataKlass* klass); - -#define xmlSecGnuTLSSymKeyDataCheckId(data) \ - (xmlSecKeyDataIsValid((data)) && \ - xmlSecGnuTLSSymKeyDataKlassCheck((data)->id)) - -static int -xmlSecGnuTLSSymKeyDataInitialize(xmlSecKeyDataPtr data) { - xmlSecAssert2(xmlSecGnuTLSSymKeyDataCheckId(data), -1); - - return(xmlSecKeyDataBinaryValueInitialize(data)); -} - -static int -xmlSecGnuTLSSymKeyDataDuplicate(xmlSecKeyDataPtr dst, xmlSecKeyDataPtr src) { - xmlSecAssert2(xmlSecGnuTLSSymKeyDataCheckId(dst), -1); - xmlSecAssert2(xmlSecGnuTLSSymKeyDataCheckId(src), -1); - xmlSecAssert2(dst->id == src->id, -1); - - return(xmlSecKeyDataBinaryValueDuplicate(dst, src)); -} - -static void -xmlSecGnuTLSSymKeyDataFinalize(xmlSecKeyDataPtr data) { - xmlSecAssert(xmlSecGnuTLSSymKeyDataCheckId(data)); - - xmlSecKeyDataBinaryValueFinalize(data); -} - -static int -xmlSecGnuTLSSymKeyDataXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key, - xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) { - xmlSecAssert2(xmlSecGnuTLSSymKeyDataKlassCheck(id), -1); - - return(xmlSecKeyDataBinaryValueXmlRead(id, key, node, keyInfoCtx)); -} - -static int -xmlSecGnuTLSSymKeyDataXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key, - xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) { - xmlSecAssert2(xmlSecGnuTLSSymKeyDataKlassCheck(id), -1); - - return(xmlSecKeyDataBinaryValueXmlWrite(id, key, node, keyInfoCtx)); -} - -static int -xmlSecGnuTLSSymKeyDataBinRead(xmlSecKeyDataId id, xmlSecKeyPtr key, - const xmlSecByte* buf, xmlSecSize bufSize, - xmlSecKeyInfoCtxPtr keyInfoCtx) { - xmlSecAssert2(xmlSecGnuTLSSymKeyDataKlassCheck(id), -1); - - return(xmlSecKeyDataBinaryValueBinRead(id, key, buf, bufSize, keyInfoCtx)); -} - -static int -xmlSecGnuTLSSymKeyDataBinWrite(xmlSecKeyDataId id, xmlSecKeyPtr key, - xmlSecByte** buf, xmlSecSize* bufSize, - xmlSecKeyInfoCtxPtr keyInfoCtx) { - xmlSecAssert2(xmlSecGnuTLSSymKeyDataKlassCheck(id), -1); - - return(xmlSecKeyDataBinaryValueBinWrite(id, key, buf, bufSize, keyInfoCtx)); -} - -static int -xmlSecGnuTLSSymKeyDataGenerate(xmlSecKeyDataPtr data, xmlSecSize sizeBits, xmlSecKeyDataType type ATTRIBUTE_UNUSED) { - xmlSecBufferPtr buffer; - - xmlSecAssert2(xmlSecGnuTLSSymKeyDataCheckId(data), -1); - xmlSecAssert2(sizeBits > 0, -1); - - buffer = xmlSecKeyDataBinaryValueGetBuffer(data); - xmlSecAssert2(buffer != NULL, -1); - - return(xmlSecGnuTLSGenerateRandom(buffer, (sizeBits + 7) / 8)); -} - -static xmlSecKeyDataType -xmlSecGnuTLSSymKeyDataGetType(xmlSecKeyDataPtr data) { - xmlSecBufferPtr buffer; - - xmlSecAssert2(xmlSecGnuTLSSymKeyDataCheckId(data), xmlSecKeyDataTypeUnknown); - - buffer = xmlSecKeyDataBinaryValueGetBuffer(data); - xmlSecAssert2(buffer != NULL, xmlSecKeyDataTypeUnknown); - - return((xmlSecBufferGetSize(buffer) > 0) ? xmlSecKeyDataTypeSymmetric : xmlSecKeyDataTypeUnknown); -} - -static xmlSecSize -xmlSecGnuTLSSymKeyDataGetSize(xmlSecKeyDataPtr data) { - xmlSecAssert2(xmlSecGnuTLSSymKeyDataCheckId(data), 0); - - return(xmlSecKeyDataBinaryValueGetSize(data)); -} - -static void -xmlSecGnuTLSSymKeyDataDebugDump(xmlSecKeyDataPtr data, FILE* output) { - xmlSecAssert(xmlSecGnuTLSSymKeyDataCheckId(data)); - - xmlSecKeyDataBinaryValueDebugDump(data, output); -} - -static void -xmlSecGnuTLSSymKeyDataDebugXmlDump(xmlSecKeyDataPtr data, FILE* output) { - xmlSecAssert(xmlSecGnuTLSSymKeyDataCheckId(data)); - - xmlSecKeyDataBinaryValueDebugXmlDump(data, output); -} - -static int -xmlSecGnuTLSSymKeyDataKlassCheck(xmlSecKeyDataKlass* klass) { -#ifndef XMLSEC_NO_DES - if(klass == xmlSecGnuTLSKeyDataDesId) { - return(1); - } -#endif /* XMLSEC_NO_DES */ - -#ifndef XMLSEC_NO_AES - if(klass == xmlSecGnuTLSKeyDataAesId) { - return(1); - } -#endif /* XMLSEC_NO_AES */ - -#ifndef XMLSEC_NO_HMAC - if(klass == xmlSecGnuTLSKeyDataHmacId) { - return(1); - } -#endif /* XMLSEC_NO_HMAC */ - - return(0); -} - -#ifndef XMLSEC_NO_AES /************************************************************************** * - * <xmlsec:AESKeyValue> processing + * We use xmlsec-gcrypt for all the basic crypto ops * - *************************************************************************/ -static xmlSecKeyDataKlass xmlSecGnuTLSKeyDataAesKlass = { - sizeof(xmlSecKeyDataKlass), - xmlSecKeyDataBinarySize, - - /* data */ - xmlSecNameAESKeyValue, - xmlSecKeyDataUsageKeyValueNode | xmlSecKeyDataUsageRetrievalMethodNodeXml, - /* xmlSecKeyDataUsage usage; */ - xmlSecHrefAESKeyValue, /* const xmlChar* href; */ - xmlSecNodeAESKeyValue, /* const xmlChar* dataNodeName; */ - xmlSecNs, /* const xmlChar* dataNodeNs; */ - - /* constructors/destructor */ - xmlSecGnuTLSSymKeyDataInitialize, /* xmlSecKeyDataInitializeMethod initialize; */ - xmlSecGnuTLSSymKeyDataDuplicate, /* xmlSecKeyDataDuplicateMethod duplicate; */ - xmlSecGnuTLSSymKeyDataFinalize, /* xmlSecKeyDataFinalizeMethod finalize; */ - xmlSecGnuTLSSymKeyDataGenerate, /* xmlSecKeyDataGenerateMethod generate; */ - - /* get info */ - xmlSecGnuTLSSymKeyDataGetType, /* xmlSecKeyDataGetTypeMethod getType; */ - xmlSecGnuTLSSymKeyDataGetSize, /* xmlSecKeyDataGetSizeMethod getSize; */ - NULL, /* xmlSecKeyDataGetIdentifier getIdentifier; */ - - /* read/write */ - xmlSecGnuTLSSymKeyDataXmlRead, /* xmlSecKeyDataXmlReadMethod xmlRead; */ - xmlSecGnuTLSSymKeyDataXmlWrite, /* xmlSecKeyDataXmlWriteMethod xmlWrite; */ - xmlSecGnuTLSSymKeyDataBinRead, /* xmlSecKeyDataBinReadMethod binRead; */ - xmlSecGnuTLSSymKeyDataBinWrite, /* xmlSecKeyDataBinWriteMethod binWrite; */ + *****************************************************************************/ +#include <xmlsec/gcrypt/crypto.h> - /* debug */ - xmlSecGnuTLSSymKeyDataDebugDump, /* xmlSecKeyDataDebugDumpMethod debugDump; */ - xmlSecGnuTLSSymKeyDataDebugXmlDump, /* xmlSecKeyDataDebugDumpMethod debugXmlDump; */ - /* reserved for the future */ - NULL, /* void* reserved0; */ - NULL, /* void* reserved1; */ -}; -/** +#ifndef XMLSEC_NO_AES +/** * xmlSecGnuTLSKeyDataAesGetKlass: - * + * * The AES key data klass. * * Returns: AES key data klass. */ -xmlSecKeyDataId +xmlSecKeyDataId xmlSecGnuTLSKeyDataAesGetKlass(void) { - return(&xmlSecGnuTLSKeyDataAesKlass); + return (xmlSecGCryptKeyDataAesGetKlass()); } /** * xmlSecGnuTLSKeyDataAesSet: - * @data: the pointer to AES key data. - * @buf: the pointer to key value. - * @bufSize: the key value size (in bytes). + * @data: the pointer to AES key data. + * @buf: the pointer to key value. + * @bufSize: the key value size (in bytes). * * Sets the value of AES key data. * @@ -261,80 +58,28 @@ xmlSecGnuTLSKeyDataAesGetKlass(void) { */ int xmlSecGnuTLSKeyDataAesSet(xmlSecKeyDataPtr data, const xmlSecByte* buf, xmlSecSize bufSize) { - xmlSecBufferPtr buffer; - - xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataAesId), -1); - xmlSecAssert2(buf != NULL, -1); - xmlSecAssert2(bufSize > 0, -1); - - buffer = xmlSecKeyDataBinaryValueGetBuffer(data); - xmlSecAssert2(buffer != NULL, -1); - - return(xmlSecBufferSetData(buffer, buf, bufSize)); + return (xmlSecGCryptKeyDataAesSet(data, buf, bufSize)); } #endif /* XMLSEC_NO_AES */ #ifndef XMLSEC_NO_DES -/************************************************************************** - * - * <xmlsec:DESKeyValue> processing - * - *************************************************************************/ -static xmlSecKeyDataKlass xmlSecGnuTLSKeyDataDesKlass = { - sizeof(xmlSecKeyDataKlass), - xmlSecKeyDataBinarySize, - - /* data */ - xmlSecNameDESKeyValue, - xmlSecKeyDataUsageKeyValueNode | xmlSecKeyDataUsageRetrievalMethodNodeXml, - /* xmlSecKeyDataUsage usage; */ - xmlSecHrefDESKeyValue, /* const xmlChar* href; */ - xmlSecNodeDESKeyValue, /* const xmlChar* dataNodeName; */ - xmlSecNs, /* const xmlChar* dataNodeNs; */ - - /* constructors/destructor */ - xmlSecGnuTLSSymKeyDataInitialize, /* xmlSecKeyDataInitializeMethod initialize; */ - xmlSecGnuTLSSymKeyDataDuplicate, /* xmlSecKeyDataDuplicateMethod duplicate; */ - xmlSecGnuTLSSymKeyDataFinalize, /* xmlSecKeyDataFinalizeMethod finalize; */ - xmlSecGnuTLSSymKeyDataGenerate, /* xmlSecKeyDataGenerateMethod generate; */ - - /* get info */ - xmlSecGnuTLSSymKeyDataGetType, /* xmlSecKeyDataGetTypeMethod getType; */ - xmlSecGnuTLSSymKeyDataGetSize, /* xmlSecKeyDataGetSizeMethod getSize; */ - NULL, /* xmlSecKeyDataGetIdentifier getIdentifier; */ - - /* read/write */ - xmlSecGnuTLSSymKeyDataXmlRead, /* xmlSecKeyDataXmlReadMethod xmlRead; */ - xmlSecGnuTLSSymKeyDataXmlWrite, /* xmlSecKeyDataXmlWriteMethod xmlWrite; */ - xmlSecGnuTLSSymKeyDataBinRead, /* xmlSecKeyDataBinReadMethod binRead; */ - xmlSecGnuTLSSymKeyDataBinWrite, /* xmlSecKeyDataBinWriteMethod binWrite; */ - - /* debug */ - xmlSecGnuTLSSymKeyDataDebugDump, /* xmlSecKeyDataDebugDumpMethod debugDump; */ - xmlSecGnuTLSSymKeyDataDebugXmlDump, /* xmlSecKeyDataDebugDumpMethod debugXmlDump; */ - - /* reserved for the future */ - NULL, /* void* reserved0; */ - NULL, /* void* reserved1; */ -}; - -/** +/** * xmlSecGnuTLSKeyDataDesGetKlass: - * + * * The DES key data klass. * * Returns: DES key data klass. */ -xmlSecKeyDataId +xmlSecKeyDataId xmlSecGnuTLSKeyDataDesGetKlass(void) { - return(&xmlSecGnuTLSKeyDataDesKlass); + return (xmlSecGCryptKeyDataDesGetKlass()); } /** * xmlSecGnuTLSKeyDataDesSet: - * @data: the pointer to DES key data. - * @buf: the pointer to key value. - * @bufSize: the key value size (in bytes). + * @data: the pointer to DES key data. + * @buf: the pointer to key value. + * @bufSize: the key value size (in bytes). * * Sets the value of DES key data. * @@ -342,81 +87,30 @@ xmlSecGnuTLSKeyDataDesGetKlass(void) { */ int xmlSecGnuTLSKeyDataDesSet(xmlSecKeyDataPtr data, const xmlSecByte* buf, xmlSecSize bufSize) { - xmlSecBufferPtr buffer; - - xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataDesId), -1); - xmlSecAssert2(buf != NULL, -1); - xmlSecAssert2(bufSize > 0, -1); - - buffer = xmlSecKeyDataBinaryValueGetBuffer(data); - xmlSecAssert2(buffer != NULL, -1); - - return(xmlSecBufferSetData(buffer, buf, bufSize)); + return (xmlSecGCryptKeyDataDesSet(data, buf, bufSize)); } #endif /* XMLSEC_NO_DES */ #ifndef XMLSEC_NO_HMAC -/************************************************************************** - * - * <xmlsec:HMACKeyValue> processing - * - *************************************************************************/ -static xmlSecKeyDataKlass xmlSecGnuTLSKeyDataHmacKlass = { - sizeof(xmlSecKeyDataKlass), - xmlSecKeyDataBinarySize, - - /* data */ - xmlSecNameHMACKeyValue, - xmlSecKeyDataUsageKeyValueNode | xmlSecKeyDataUsageRetrievalMethodNodeXml, - /* xmlSecKeyDataUsage usage; */ - xmlSecHrefHMACKeyValue, /* const xmlChar* href; */ - xmlSecNodeHMACKeyValue, /* const xmlChar* dataNodeName; */ - xmlSecNs, /* const xmlChar* dataNodeNs; */ - - /* constructors/destructor */ - xmlSecGnuTLSSymKeyDataInitialize, /* xmlSecKeyDataInitializeMethod initialize; */ - xmlSecGnuTLSSymKeyDataDuplicate, /* xmlSecKeyDataDuplicateMethod duplicate; */ - xmlSecGnuTLSSymKeyDataFinalize, /* xmlSecKeyDataFinalizeMethod finalize; */ - xmlSecGnuTLSSymKeyDataGenerate, /* xmlSecKeyDataGenerateMethod generate; */ - - /* get info */ - xmlSecGnuTLSSymKeyDataGetType, /* xmlSecKeyDataGetTypeMethod getType; */ - xmlSecGnuTLSSymKeyDataGetSize, /* xmlSecKeyDataGetSizeMethod getSize; */ - NULL, /* xmlSecKeyDataGetIdentifier getIdentifier; */ - - /* read/write */ - xmlSecGnuTLSSymKeyDataXmlRead, /* xmlSecKeyDataXmlReadMethod xmlRead; */ - xmlSecGnuTLSSymKeyDataXmlWrite, /* xmlSecKeyDataXmlWriteMethod xmlWrite; */ - xmlSecGnuTLSSymKeyDataBinRead, /* xmlSecKeyDataBinReadMethod binRead; */ - xmlSecGnuTLSSymKeyDataBinWrite, /* xmlSecKeyDataBinWriteMethod binWrite; */ - /* debug */ - xmlSecGnuTLSSymKeyDataDebugDump, /* xmlSecKeyDataDebugDumpMethod debugDump; */ - xmlSecGnuTLSSymKeyDataDebugXmlDump, /* xmlSecKeyDataDebugDumpMethod debugXmlDump; */ - - /* reserved for the future */ - NULL, /* void* reserved0; */ - NULL, /* void* reserved1; */ -}; - -/** +/** * xmlSecGnuTLSKeyDataHmacGetKlass: - * + * * The HMAC key data klass. * * Returns: HMAC key data klass. */ -xmlSecKeyDataId +xmlSecKeyDataId xmlSecGnuTLSKeyDataHmacGetKlass(void) { - return(&xmlSecGnuTLSKeyDataHmacKlass); + return (xmlSecGCryptKeyDataHmacGetKlass()); } /** * xmlSecGnuTLSKeyDataHmacSet: - * @data: the pointer to HMAC key data. - * @buf: the pointer to key value. - * @bufSize: the key value size (in bytes). + * @data: the pointer to HMAC key data. + * @buf: the pointer to key value. + * @bufSize: the key value size (in bytes). * * Sets the value of HMAC key data. * @@ -424,16 +118,7 @@ xmlSecGnuTLSKeyDataHmacGetKlass(void) { */ int xmlSecGnuTLSKeyDataHmacSet(xmlSecKeyDataPtr data, const xmlSecByte* buf, xmlSecSize bufSize) { - xmlSecBufferPtr buffer; - - xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataHmacId), -1); - xmlSecAssert2(buf != NULL, -1); - xmlSecAssert2(bufSize > 0, -1); - - buffer = xmlSecKeyDataBinaryValueGetBuffer(data); - xmlSecAssert2(buffer != NULL, -1); - - return(xmlSecBufferSetData(buffer, buf, bufSize)); + return (xmlSecGCryptKeyDataHmacSet(data, buf, bufSize)); } #endif /* XMLSEC_NO_HMAC */ diff --git a/src/gnutls/x509.c b/src/gnutls/x509.c new file mode 100644 index 00000000..52d46ab4 --- /dev/null +++ b/src/gnutls/x509.c @@ -0,0 +1,1960 @@ +/** + * XMLSec library + * + * X509 support + * + * + * This is free software; see Copyright file in the source + * distribution for preciese wording. + * + * Copyright (C) 2010 Aleksey Sanin <aleksey@aleksey.com> + */ +#include "globals.h" + +#ifndef XMLSEC_NO_X509 + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <errno.h> +#include <time.h> + +#include <libxml/tree.h> + +#include <xmlsec/xmlsec.h> +#include <xmlsec/xmltree.h> +#include <xmlsec/keys.h> +#include <xmlsec/keyinfo.h> +#include <xmlsec/keysmngr.h> +#include <xmlsec/x509.h> +#include <xmlsec/base64.h> +#include <xmlsec/errors.h> +#include <xmlsec/private.h> + +#include <xmlsec/gnutls/crypto.h> +#include <xmlsec/gnutls/x509.h> + +#include "x509utils.h" + +/************************************************************************* + * + * X509 utility functions + * + ************************************************************************/ +static int xmlSecGnuTLSX509DataNodeRead (xmlSecKeyDataPtr data, + xmlNodePtr node, + xmlSecKeyInfoCtxPtr keyInfoCtx); +static int xmlSecGnuTLSX509CertificateNodeRead (xmlSecKeyDataPtr data, + xmlNodePtr node, + xmlSecKeyInfoCtxPtr keyInfoCtx); +static int xmlSecGnuTLSX509CertificateNodeWrite (gnutls_x509_crt_t cert, + xmlNodePtr node, + xmlSecKeyInfoCtxPtr keyInfoCtx); +static int xmlSecGnuTLSX509SubjectNameNodeRead (xmlSecKeyDataPtr data, + xmlNodePtr node, + xmlSecKeyInfoCtxPtr keyInfoCtx); +static int xmlSecGnuTLSX509SubjectNameNodeWrite (gnutls_x509_crt_t cert, + xmlNodePtr node, + xmlSecKeyInfoCtxPtr keyInfoCtx); +static int xmlSecGnuTLSX509IssuerSerialNodeRead (xmlSecKeyDataPtr data, + xmlNodePtr node, + xmlSecKeyInfoCtxPtr keyInfoCtx); +static int xmlSecGnuTLSX509IssuerSerialNodeWrite (gnutls_x509_crt_t cert, + xmlNodePtr node, + xmlSecKeyInfoCtxPtr keyInfoCtx); +static int xmlSecGnuTLSX509SKINodeRead (xmlSecKeyDataPtr data, + xmlNodePtr node, + xmlSecKeyInfoCtxPtr keyInfoCtx); +static int xmlSecGnuTLSX509SKINodeWrite (gnutls_x509_crt_t cert, + xmlNodePtr node, + xmlSecKeyInfoCtxPtr keyInfoCtx); +static int xmlSecGnuTLSX509CRLNodeRead (xmlSecKeyDataPtr data, + xmlNodePtr node, + xmlSecKeyInfoCtxPtr keyInfoCtx); +static int xmlSecGnuTLSX509CRLNodeWrite (gnutls_x509_crl_t crl, + xmlNodePtr node, + xmlSecKeyInfoCtxPtr keyInfoCtx); +static int xmlSecGnuTLSKeyDataX509VerifyAndExtractKey(xmlSecKeyDataPtr data, + xmlSecKeyPtr key, + xmlSecKeyInfoCtxPtr keyInfoCtx); + +/************************************************************************* + * + * Internal GnuTLS X509 data CTX + * + ************************************************************************/ +typedef struct _xmlSecGnuTLSX509DataCtx xmlSecGnuTLSX509DataCtx, + *xmlSecGnuTLSX509DataCtxPtr; +struct _xmlSecGnuTLSX509DataCtx { + gnutls_x509_crt_t keyCert; + xmlSecPtrList certsList; + xmlSecPtrList crlsList; +}; + + +/************************************************************************** + * + * <dsig:X509Data> processing + * + * + * The X509Data Element (http://www.w3.org/TR/xmldsig-core/#sec-X509Data) + * + * An X509Data element within KeyInfo contains one or more identifiers of keys + * or X509 certificates (or certificates' identifiers or a revocation list). + * The content of X509Data is: + * + * 1. At least one element, from the following set of element types; any of these may appear together or more than once iff (if and only if) each instance describes or is related to the same certificate: + * 2. + * * The X509IssuerSerial element, which contains an X.509 issuer + * distinguished name/serial number pair that SHOULD be compliant + * with RFC2253 [LDAP-DN], + * * The X509SubjectName element, which contains an X.509 subject + * distinguished name that SHOULD be compliant with RFC2253 [LDAP-DN], + * * The X509SKI element, which contains the base64 encoded plain (i.e. + * non-DER-encoded) value of a X509 V.3 SubjectKeyIdentifier extension. + * * The X509Certificate element, which contains a base64-encoded [X509v3] + * certificate, and + * * Elements from an external namespace which accompanies/complements any + * of the elements above. + * * The X509CRL element, which contains a base64-encoded certificate + * revocation list (CRL) [X509v3]. + * + * Any X509IssuerSerial, X509SKI, and X509SubjectName elements that appear + * MUST refer to the certificate or certificates containing the validation key. + * All such elements that refer to a particular individual certificate MUST be + * grouped inside a single X509Data element and if the certificate to which + * they refer appears, it MUST also be in that X509Data element. + * + * Any X509IssuerSerial, X509SKI, and X509SubjectName elements that relate to + * the same key but different certificates MUST be grouped within a single + * KeyInfo but MAY occur in multiple X509Data elements. + * + * All certificates appearing in an X509Data element MUST relate to the + * validation key by either containing it or being part of a certification + * chain that terminates in a certificate containing the validation key. + * + * No ordering is implied by the above constraints. + * + * Note, there is no direct provision for a PKCS#7 encoded "bag" of + * certificates or CRLs. However, a set of certificates and CRLs can occur + * within an X509Data element and multiple X509Data elements can occur in a + * KeyInfo. Whenever multiple certificates occur in an X509Data element, at + * least one such certificate must contain the public key which verifies the + * signature. + * + * Schema Definition + * + * <element name="X509Data" type="ds:X509DataType"/> + * <complexType name="X509DataType"> + * <sequence maxOccurs="unbounded"> + * <choice> + * <element name="X509IssuerSerial" type="ds:X509IssuerSerialType"/> + * <element name="X509SKI" type="base64Binary"/> + * <element name="X509SubjectName" type="string"/> + * <element name="X509Certificate" type="base64Binary"/> + * <element name="X509CRL" type="base64Binary"/> + * <any namespace="##other" processContents="lax"/> + * </choice> + * </sequence> + * </complexType> + * <complexType name="X509IssuerSerialType"> + * <sequence> + * <element name="X509IssuerName" type="string"/> + * <element name="X509SerialNumber" type="integer"/> + * </sequence> + * </complexType> + * + * DTD + * + * <!ELEMENT X509Data ((X509IssuerSerial | X509SKI | X509SubjectName | + * X509Certificate | X509CRL)+ %X509.ANY;)> + * <!ELEMENT X509IssuerSerial (X509IssuerName, X509SerialNumber) > + * <!ELEMENT X509IssuerName (#PCDATA) > + * <!ELEMENT X509SubjectName (#PCDATA) > + * <!ELEMENT X509SerialNumber (#PCDATA) > + * <!ELEMENT X509SKI (#PCDATA) > + * <!ELEMENT X509Certificate (#PCDATA) > + * <!ELEMENT X509CRL (#PCDATA) > + * + * ----------------------------------------------------------------------- + * + * xmlSecGnuTLSX509DataCtx is located after xmlSecTransform + * + *************************************************************************/ +#define xmlSecGnuTLSX509DataSize \ + (sizeof(xmlSecKeyData) + sizeof(xmlSecGnuTLSX509DataCtx)) +#define xmlSecGnuTLSX509DataGetCtx(data) \ + ((xmlSecGnuTLSX509DataCtxPtr)(((xmlSecByte*)(data)) + sizeof(xmlSecKeyData))) + +static int xmlSecGnuTLSKeyDataX509Initialize (xmlSecKeyDataPtr data); +static int xmlSecGnuTLSKeyDataX509Duplicate (xmlSecKeyDataPtr dst, + xmlSecKeyDataPtr src); +static void xmlSecGnuTLSKeyDataX509Finalize (xmlSecKeyDataPtr data); +static int xmlSecGnuTLSKeyDataX509XmlRead (xmlSecKeyDataId id, + xmlSecKeyPtr key, + xmlNodePtr node, + xmlSecKeyInfoCtxPtr keyInfoCtx); +static int xmlSecGnuTLSKeyDataX509XmlWrite (xmlSecKeyDataId id, + xmlSecKeyPtr key, + xmlNodePtr node, + xmlSecKeyInfoCtxPtr keyInfoCtx); +static xmlSecKeyDataType xmlSecGnuTLSKeyDataX509GetType (xmlSecKeyDataPtr data); +static const xmlChar* xmlSecGnuTLSKeyDataX509GetIdentifier (xmlSecKeyDataPtr data); + +static void xmlSecGnuTLSKeyDataX509DebugDump (xmlSecKeyDataPtr data, + FILE* output); +static void xmlSecGnuTLSKeyDataX509DebugXmlDump (xmlSecKeyDataPtr data, + FILE* output); + + + +static xmlSecKeyDataKlass xmlSecGnuTLSKeyDataX509Klass = { + sizeof(xmlSecKeyDataKlass), + xmlSecGnuTLSX509DataSize, + + /* data */ + xmlSecNameX509Data, + xmlSecKeyDataUsageKeyInfoNode | xmlSecKeyDataUsageRetrievalMethodNodeXml, + /* xmlSecKeyDataUsage usage; */ + xmlSecHrefX509Data, /* const xmlChar* href; */ + xmlSecNodeX509Data, /* const xmlChar* dataNodeName; */ + xmlSecDSigNs, /* const xmlChar* dataNodeNs; */ + + /* constructors/destructor */ + xmlSecGnuTLSKeyDataX509Initialize, /* xmlSecKeyDataInitializeMethod initialize; */ + xmlSecGnuTLSKeyDataX509Duplicate, /* xmlSecKeyDataDuplicateMethod duplicate; */ + xmlSecGnuTLSKeyDataX509Finalize, /* xmlSecKeyDataFinalizeMethod finalize; */ + NULL, /* xmlSecKeyDataGenerateMethod generate; */ + + /* get info */ + xmlSecGnuTLSKeyDataX509GetType, /* xmlSecKeyDataGetTypeMethod getType; */ + NULL, /* xmlSecKeyDataGetSizeMethod getSize; */ + xmlSecGnuTLSKeyDataX509GetIdentifier, /* xmlSecKeyDataGetIdentifier getIdentifier; */ + + /* read/write */ + xmlSecGnuTLSKeyDataX509XmlRead, /* xmlSecKeyDataXmlReadMethod xmlRead; */ + xmlSecGnuTLSKeyDataX509XmlWrite, /* xmlSecKeyDataXmlWriteMethod xmlWrite; */ + NULL, /* xmlSecKeyDataBinReadMethod binRead; */ + NULL, /* xmlSecKeyDataBinWriteMethod binWrite; */ + + /* debug */ + xmlSecGnuTLSKeyDataX509DebugDump, /* xmlSecKeyDataDebugDumpMethod debugDump; */ + xmlSecGnuTLSKeyDataX509DebugXmlDump, /* xmlSecKeyDataDebugDumpMethod debugXmlDump; */ + + /* reserved for the future */ + NULL, /* void* reserved0; */ + NULL, /* void* reserved1; */ +}; + +/** + * xmlSecGnuTLSKeyDataX509GetKlass: + * + * The GnuTLS X509 key data klass (http://www.w3.org/TR/xmldsig-core/#sec-X509Data). + * + * Returns: the X509 data klass. + */ +xmlSecKeyDataId +xmlSecGnuTLSKeyDataX509GetKlass(void) { + return(&xmlSecGnuTLSKeyDataX509Klass); +} + +/** + * xmlSecGnuTLSKeyDataX509GetKeyCert: + * @data: the pointer to X509 key data. + * + * Gets the certificate from which the key was extracted. + * + * Returns: the key's certificate or NULL if key data was not used for key + * extraction or an error occurs. + */ +gnutls_x509_crt_t +xmlSecGnuTLSKeyDataX509GetKeyCert(xmlSecKeyDataPtr data) { + xmlSecGnuTLSX509DataCtxPtr ctx; + + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id), NULL); + + ctx = xmlSecGnuTLSX509DataGetCtx(data); + xmlSecAssert2(ctx != NULL, NULL); + + return(ctx->keyCert); +} + +/** + * xmlSecGnuTLSKeyDataX509AdoptKeyCert: + * @data: the pointer to X509 key data. + * @cert: the pointer to GnuTLS X509 certificate. + * + * Sets the key's certificate in @data. + * + * Returns: 0 on success or a negative value if an error occurs. + */ +int +xmlSecGnuTLSKeyDataX509AdoptKeyCert(xmlSecKeyDataPtr data, gnutls_x509_crt_t cert) { + xmlSecGnuTLSX509DataCtxPtr ctx; + + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id), -1); + xmlSecAssert2(cert != NULL, -1); + + ctx = xmlSecGnuTLSX509DataGetCtx(data); + xmlSecAssert2(ctx != NULL, -1); + + if(ctx->keyCert != NULL) { + gnutls_x509_crt_deinit(ctx->keyCert); + } + ctx->keyCert = cert; + return(0); +} + +/** + * xmlSecGnuTLSKeyDataX509AdoptCert: + * @data: the pointer to X509 key data. + * @cert: the pointer to GnuTLS X509 certificate. + * + * Adds certificate to the X509 key data. + * + * Returns: 0 on success or a negative value if an error occurs. + */ +int +xmlSecGnuTLSKeyDataX509AdoptCert(xmlSecKeyDataPtr data, gnutls_x509_crt_t cert) { + xmlSecGnuTLSX509DataCtxPtr ctx; + int ret; + + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id), -1); + xmlSecAssert2(cert != NULL, -1); + + ctx = xmlSecGnuTLSX509DataGetCtx(data); + xmlSecAssert2(ctx != NULL, -1); + + ret = xmlSecPtrListAdd(&(ctx->certsList), cert); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "xmlSecPtrListAdd", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + return(0); +} + +/** + * xmlSecGnuTLSKeyDataX509GetCert: + * @data: the pointer to X509 key data. + * @pos: the desired certificate position. + * + * Gets a certificate from X509 key data. + * + * Returns: the pointer to certificate or NULL if @pos is larger than the + * number of certificates in @data or an error occurs. + */ +gnutls_x509_crt_t +xmlSecGnuTLSKeyDataX509GetCert(xmlSecKeyDataPtr data, xmlSecSize pos) { + xmlSecGnuTLSX509DataCtxPtr ctx; + + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id), NULL); + + ctx = xmlSecGnuTLSX509DataGetCtx(data); + xmlSecAssert2(ctx != NULL, NULL); + + return(xmlSecPtrListGetItem(&(ctx->certsList), pos)); +} + +/** + * xmlSecGnuTLSKeyDataX509GetCertsSize: + * @data: the pointer to X509 key data. + * + * Gets the number of certificates in @data. + * + * Returns: te number of certificates in @data. + */ +xmlSecSize +xmlSecGnuTLSKeyDataX509GetCertsSize(xmlSecKeyDataPtr data) { + xmlSecGnuTLSX509DataCtxPtr ctx; + + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id), 0); + + ctx = xmlSecGnuTLSX509DataGetCtx(data); + xmlSecAssert2(ctx != NULL, 0); + + return(xmlSecPtrListGetSize(&(ctx->certsList))); +} + +/** + * xmlSecGnuTLSKeyDataX509AdoptCrl: + * @data: the pointer to X509 key data. + * @crl: the pointer to GnuTLS X509 crl. + * + * Adds crl to the X509 key data. + * + * Returns: 0 on success or a negative value if an error occurs. + */ +int +xmlSecGnuTLSKeyDataX509AdoptCrl(xmlSecKeyDataPtr data, gnutls_x509_crl_t crl) { + xmlSecGnuTLSX509DataCtxPtr ctx; + int ret; + + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id), -1); + xmlSecAssert2(crl != NULL, -1); + + ctx = xmlSecGnuTLSX509DataGetCtx(data); + xmlSecAssert2(ctx != NULL, -1); + + ret = xmlSecPtrListAdd(&(ctx->crlsList), crl); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "xmlSecPtrListAdd", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + return(0); +} + +/** + * xmlSecGnuTLSKeyDataX509GetCrl: + * @data: the pointer to X509 key data. + * @pos: the desired crl position. + * + * Gets a crl from X509 key data. + * + * Returns: the pointer to crl or NULL if @pos is larger than the + * number of crls in @data or an error occurs. + */ +gnutls_x509_crl_t +xmlSecGnuTLSKeyDataX509GetCrl(xmlSecKeyDataPtr data, xmlSecSize pos) { + xmlSecGnuTLSX509DataCtxPtr ctx; + + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id), NULL); + + ctx = xmlSecGnuTLSX509DataGetCtx(data); + xmlSecAssert2(ctx != NULL, NULL); + + return(xmlSecPtrListGetItem(&(ctx->crlsList), pos)); +} + +/** + * xmlSecGnuTLSKeyDataX509GetCrlsSize: + * @data: the pointer to X509 key data. + * + * Gets the number of crls in @data. + * + * Returns: te number of crls in @data. + */ +xmlSecSize +xmlSecGnuTLSKeyDataX509GetCrlsSize(xmlSecKeyDataPtr data) { + xmlSecGnuTLSX509DataCtxPtr ctx; + + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id), 0); + + ctx = xmlSecGnuTLSX509DataGetCtx(data); + xmlSecAssert2(ctx != NULL, 0); + + return(xmlSecPtrListGetSize(&(ctx->crlsList))); +} + + +static int +xmlSecGnuTLSKeyDataX509Initialize(xmlSecKeyDataPtr data) { + xmlSecGnuTLSX509DataCtxPtr ctx; + int ret; + + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id), -1); + + ctx = xmlSecGnuTLSX509DataGetCtx(data); + xmlSecAssert2(ctx != NULL, -1); + + memset(ctx, 0, sizeof(xmlSecGnuTLSX509DataCtx)); + + ret = xmlSecPtrListInitialize(&(ctx->certsList), xmlSecGnuTLSX509CrtListId); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "xmlSecPtrListInitialize", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "certsList"); + return(-1); + } + + ret = xmlSecPtrListInitialize(&(ctx->crlsList), xmlSecGnuTLSX509CrlListId); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "xmlSecPtrListInitialize", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "crlsList"); + return(-1); + } + + return(0); +} + +static int +xmlSecGnuTLSKeyDataX509Duplicate(xmlSecKeyDataPtr dst, xmlSecKeyDataPtr src) { + xmlSecGnuTLSX509DataCtxPtr ctxSrc; + xmlSecGnuTLSX509DataCtxPtr ctxDst; + int ret; + + xmlSecAssert2(xmlSecKeyDataCheckId(dst, xmlSecGnuTLSKeyDataX509Id), -1); + xmlSecAssert2(xmlSecKeyDataCheckId(src, xmlSecGnuTLSKeyDataX509Id), -1); + + ctxSrc = xmlSecGnuTLSX509DataGetCtx(src); + xmlSecAssert2(ctxSrc != NULL, 0); + ctxDst = xmlSecGnuTLSX509DataGetCtx(dst); + xmlSecAssert2(ctxDst != NULL, 0); + + /* copy key cert if exist */ + if(ctxDst->keyCert != NULL) { + gnutls_x509_crt_deinit(ctxDst->keyCert); + ctxDst->keyCert = NULL; + } + if(ctxSrc->keyCert != NULL) { + ctxDst->keyCert = xmlSecGnuTLSX509CertDup(ctxSrc->keyCert); + if(ctxDst->keyCert == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(src)), + "xmlSecGnuTLSX509CertDup", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + } + + /* copy certsList if exists */ + xmlSecPtrListEmpty(&(ctxDst->certsList)); + ret = xmlSecPtrListCopy(&(ctxDst->certsList), &(ctxSrc->certsList)); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(src)), + "xmlSecPtrListCopy", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "certsList"); + return(-1); + } + + /* copy crlsList if exists */ + xmlSecPtrListEmpty(&(ctxDst->crlsList)); + ret = xmlSecPtrListCopy(&(ctxDst->crlsList), &(ctxSrc->crlsList)); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(src)), + "xmlSecPtrListCopy", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "crlsList"); + return(-1); + } + /* done */ + return(0); +} + +static void +xmlSecGnuTLSKeyDataX509Finalize(xmlSecKeyDataPtr data) { + xmlSecGnuTLSX509DataCtxPtr ctx; + + xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id)); + + ctx = xmlSecGnuTLSX509DataGetCtx(data); + xmlSecAssert(ctx != NULL); + + xmlSecPtrListFinalize(&(ctx->crlsList)); + xmlSecPtrListFinalize(&(ctx->certsList)); + if(ctx->keyCert != NULL) { + gnutls_x509_crt_deinit(ctx->keyCert); + } + memset(ctx, 0, sizeof(xmlSecGnuTLSX509DataCtx)); +} + +static int +xmlSecGnuTLSKeyDataX509XmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key, + xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) { + xmlSecKeyDataPtr data; + int ret; + + xmlSecAssert2(id == xmlSecGnuTLSKeyDataX509Id, -1); + xmlSecAssert2(key != NULL, -1); + xmlSecAssert2(node != NULL, -1); + xmlSecAssert2(keyInfoCtx != NULL, -1); + + data = xmlSecKeyEnsureData(key, id); + if(data == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecKeyEnsureData", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + ret = xmlSecGnuTLSX509DataNodeRead(data, node, keyInfoCtx); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecGnuTLSX509DataNodeRead", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_X509DATA_DONT_VERIFY_CERTS) == 0) { + ret = xmlSecGnuTLSKeyDataX509VerifyAndExtractKey(data, key, keyInfoCtx); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecGnuTLSKeyDataX509VerifyAndExtractKey", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + } + return(0); +} + +static int +xmlSecGnuTLSKeyDataX509XmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key, + xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) { + xmlSecKeyDataPtr data; + gnutls_x509_crt_t cert; + gnutls_x509_crl_t crl; + xmlSecSize size, pos; + int content; + int ret; + + xmlSecAssert2(id == xmlSecGnuTLSKeyDataX509Id, -1); + xmlSecAssert2(key != NULL, -1); + xmlSecAssert2(node != NULL, -1); + xmlSecAssert2(keyInfoCtx != NULL, -1); + + content = xmlSecX509DataGetNodeContent (node, 1, keyInfoCtx); + if (content < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecX509DataGetNodeContent", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "content=%d", content); + return(-1); + } else if(content == 0) { + /* by default we are writing certificates and crls */ + content = XMLSEC_X509DATA_DEFAULT; + } + + /* get x509 data */ + data = xmlSecKeyGetData(key, id); + if(data == NULL) { + /* no x509 data in the key */ + return(0); + } + + /* write certs */ + size = xmlSecGnuTLSKeyDataX509GetCertsSize(data); + for(pos = 0; pos < size; ++pos) { + cert = xmlSecGnuTLSKeyDataX509GetCert(data, pos); + if(cert == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecGnuTLSKeyDataX509GetCert", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "pos=%d", pos); + return(-1); + } + + if((content & XMLSEC_X509DATA_CERTIFICATE_NODE) != 0) { + ret = xmlSecGnuTLSX509CertificateNodeWrite(cert, node, keyInfoCtx); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecGnuTLSX509CertificateNodeWrite", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "pos=%d", pos); + return(-1); + } + } + + if((content & XMLSEC_X509DATA_SUBJECTNAME_NODE) != 0) { + ret = xmlSecGnuTLSX509SubjectNameNodeWrite(cert, node, keyInfoCtx); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecGnuTLSX509SubjectNameNodeWrite", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "pos=%d", pos); + return(-1); + } + } + + if((content & XMLSEC_X509DATA_ISSUERSERIAL_NODE) != 0) { + ret = xmlSecGnuTLSX509IssuerSerialNodeWrite(cert, node, keyInfoCtx); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecGnuTLSX509IssuerSerialNodeWrite", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "pos=%d", pos); + return(-1); + } + } + + if((content & XMLSEC_X509DATA_SKI_NODE) != 0) { + ret = xmlSecGnuTLSX509SKINodeWrite(cert, node, keyInfoCtx); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecGnuTLSX509SKINodeWrite", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "pos=%d", pos); + return(-1); + } + } + } + + /* write crls if needed */ + if((content & XMLSEC_X509DATA_CRL_NODE) != 0) { + size = xmlSecGnuTLSKeyDataX509GetCrlsSize(data); + for(pos = 0; pos < size; ++pos) { + crl = xmlSecGnuTLSKeyDataX509GetCrl(data, pos); + if(crl == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecGnuTLSKeyDataX509GetCrl", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "pos=%d", pos); + return(-1); + } + + ret = xmlSecGnuTLSX509CRLNodeWrite(crl, node, keyInfoCtx); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecGnuTLSX509CRLNodeWrite", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "pos=%d", pos); + return(-1); + } + } + } + + /* done */ + return(0); +} + + +static xmlSecKeyDataType +xmlSecGnuTLSKeyDataX509GetType(xmlSecKeyDataPtr data) { + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id), xmlSecKeyDataTypeUnknown); + + /* TODO: return verified/not verified status */ + return(xmlSecKeyDataTypeUnknown); +} + +static const xmlChar* +xmlSecGnuTLSKeyDataX509GetIdentifier(xmlSecKeyDataPtr data) { + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id), NULL); + + /* TODO */ + return(NULL); +} + +static void +xmlSecGnuTLSKeyDataX509DebugDump(xmlSecKeyDataPtr data, FILE* output) { + xmlSecSize size, pos; + + xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id)); + xmlSecAssert(output != NULL); + + fprintf(output, "=== X509 Data:\n"); + + /* key cert */ + { + gnutls_x509_crt_t cert; + + cert = xmlSecGnuTLSKeyDataX509GetKeyCert(data); + if(cert != NULL) { + fprintf(output, "==== Key Certificate:\n"); + xmlSecGnuTLSX509CertDebugDump(cert, output); + } + } + + /* other certs */ + size = xmlSecGnuTLSKeyDataX509GetCertsSize(data); + for(pos = 0; pos < size; ++pos) { + gnutls_x509_crt_t cert; + + cert = xmlSecGnuTLSKeyDataX509GetCert(data, pos); + if(cert == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "xmlSecGnuTLSKeyDataX509GetCert", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "pos=%d", pos); + return; + } + fprintf(output, "==== Certificate:\n"); + xmlSecGnuTLSX509CertDebugDump(cert, output); + } + + /* crls */ + size = xmlSecGnuTLSKeyDataX509GetCrlsSize(data); + for(pos = 0; pos < size; ++pos) { + gnutls_x509_crl_t crl; + + crl = xmlSecGnuTLSKeyDataX509GetCrl(data, pos); + if(crl == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "xmlSecGnuTLSKeyDataX509GetCrl", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "pos=%d", pos); + return; + } + fprintf(output, "==== Crl:\n"); + xmlSecGnuTLSX509CrlDebugDump(crl, output); + } +} + +static void +xmlSecGnuTLSKeyDataX509DebugXmlDump(xmlSecKeyDataPtr data, FILE* output) { + xmlSecSize size, pos; + + xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id)); + xmlSecAssert(output != NULL); + + fprintf(output, "<X509Data>\n"); + + /* key cert */ + { + gnutls_x509_crt_t cert; + + cert = xmlSecGnuTLSKeyDataX509GetKeyCert(data); + if(cert != NULL) { + fprintf(output, "<KeyCertificate>\n"); + xmlSecGnuTLSX509CertDebugXmlDump(cert, output); + fprintf(output, "</KeyCertificate>\n"); + } + } + + /* other certs */ + size = xmlSecGnuTLSKeyDataX509GetCertsSize(data); + for(pos = 0; pos < size; ++pos) { + gnutls_x509_crt_t cert; + + cert = xmlSecGnuTLSKeyDataX509GetCert(data, pos); + if(cert == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "xmlSecGnuTLSKeyDataX509GetCert", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "pos=%d", pos); + return; + } + fprintf(output, "<Certificate>\n"); + xmlSecGnuTLSX509CertDebugXmlDump(cert, output); + fprintf(output, "</Certificate>\n"); + } + + /* other crls */ + size = xmlSecGnuTLSKeyDataX509GetCrlsSize(data); + for(pos = 0; pos < size; ++pos) { + gnutls_x509_crl_t crl; + + crl = xmlSecGnuTLSKeyDataX509GetCrl(data, pos); + if(crl == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "xmlSecGnuTLSKeyDataX509GetCrl", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "pos=%d", pos); + return; + } + fprintf(output, "<CRL>\n"); + xmlSecGnuTLSX509CrlDebugXmlDump(crl, output); + fprintf(output, "</CRL>\n"); + } + + /* we don't print out crls */ + fprintf(output, "</X509Data>\n"); +} + +static int +xmlSecGnuTLSX509DataNodeRead(xmlSecKeyDataPtr data, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) { + xmlNodePtr cur; + int ret; + + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id), -1); + xmlSecAssert2(node != NULL, -1); + xmlSecAssert2(keyInfoCtx != NULL, -1); + + for(cur = xmlSecGetNextElementNode(node->children); + cur != NULL; + cur = xmlSecGetNextElementNode(cur->next)) { + + ret = 0; + if(xmlSecCheckNodeName(cur, xmlSecNodeX509Certificate, xmlSecDSigNs)) { + ret = xmlSecGnuTLSX509CertificateNodeRead(data, cur, keyInfoCtx); + } else if(xmlSecCheckNodeName(cur, xmlSecNodeX509SubjectName, xmlSecDSigNs)) { + ret = xmlSecGnuTLSX509SubjectNameNodeRead(data, cur, keyInfoCtx); + } else if(xmlSecCheckNodeName(cur, xmlSecNodeX509IssuerSerial, xmlSecDSigNs)) { + ret = xmlSecGnuTLSX509IssuerSerialNodeRead(data, cur, keyInfoCtx); + } else if(xmlSecCheckNodeName(cur, xmlSecNodeX509SKI, xmlSecDSigNs)) { + ret = xmlSecGnuTLSX509SKINodeRead(data, cur, keyInfoCtx); + } else if(xmlSecCheckNodeName(cur, xmlSecNodeX509CRL, xmlSecDSigNs)) { + ret = xmlSecGnuTLSX509CRLNodeRead(data, cur, keyInfoCtx); + } else if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_X509DATA_STOP_ON_UNKNOWN_CHILD) != 0) { + /* laxi schema validation: ignore unknown nodes */ + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + xmlSecErrorsSafeString(xmlSecNodeGetName(cur)), + XMLSEC_ERRORS_R_UNEXPECTED_NODE, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + xmlSecErrorsSafeString(xmlSecNodeGetName(cur)), + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "read node failed"); + return(-1); + } + } + return(0); +} + +static int +xmlSecGnuTLSX509CertificateNodeRead(xmlSecKeyDataPtr data, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) { + xmlChar *content; + gnutls_x509_crt_t cert; + int ret; + + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id), -1); + xmlSecAssert2(node != NULL, -1); + xmlSecAssert2(keyInfoCtx != NULL, -1); + + content = xmlNodeGetContent(node); + if((content == NULL) || (xmlSecIsEmptyString(content) == 1)) { + if(content != NULL) { + xmlFree(content); + } + if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_STOP_ON_EMPTY_NODE) != 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + xmlSecErrorsSafeString(xmlSecNodeGetName(node)), + XMLSEC_ERRORS_R_INVALID_NODE_CONTENT, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + return(0); + } + + cert = xmlSecGnuTLSX509CertBase64DerRead(content); + if(cert == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "xmlSecGnuTLSX509CertBase64DerRead", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlFree(content); + return(-1); + } + + ret = xmlSecGnuTLSKeyDataX509AdoptCert(data, cert); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "xmlSecGnuTLSKeyDataX509AdoptCert", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + gnutls_x509_crt_deinit(cert); + xmlFree(content); + return(-1); + } + + xmlFree(content); + return(0); +} + +static int +xmlSecGnuTLSX509CertificateNodeWrite(gnutls_x509_crt_t cert, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) { + xmlChar* buf; + xmlNodePtr cur; + + xmlSecAssert2(cert != NULL, -1); + xmlSecAssert2(node != NULL, -1); + xmlSecAssert2(keyInfoCtx != NULL, -1); + + /* set base64 lines size from context */ + buf = xmlSecGnuTLSX509CertBase64DerWrite(cert, keyInfoCtx->base64LineSize); + if(buf == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSX509CertBase64DerWrite", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + cur = xmlSecAddChild(node, xmlSecNodeX509Certificate, xmlSecDSigNs); + if(cur == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecAddChild", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeX509Certificate)); + xmlFree(buf); + return(-1); + } + + /* todo: add \n around base64 data - from context */ + /* todo: add errors check */ + xmlNodeSetContent(cur, xmlSecStringCR); + xmlNodeSetContent(cur, buf); + xmlFree(buf); + return(0); +} + + + +#define XMLSEC_GNUTLS_IS_SPACE(ch) \ + (((ch) == ' ') || ((ch) == '\r') || ((ch) == '\n')) + +static void +xmlSecGnuTLSX509Trim(xmlChar * str) { + xmlChar * p, * q; + + xmlSecAssert(str != NULL); + + /* skip spaces from the beggining */ + p = str; + while(XMLSEC_GNUTLS_IS_SPACE(*p) && ((*p) != '\0')) ++p; + if(p != str) { + for(q = str; ; ++q, ++p) { + (*q) = (*p); + if((*p) == '\0') { + break; + } + } + } + + /* skip spaces from the end */ + for(p = str; (*p) != '\0'; ++p); + while((p > str) && (XMLSEC_GNUTLS_IS_SPACE(*(p - 1)))) *(--p) = '\0'; +} + +static int +xmlSecGnuTLSX509SubjectNameNodeRead(xmlSecKeyDataPtr data, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) { + xmlSecKeyDataStorePtr x509Store; + xmlChar* subject; + gnutls_x509_crt_t cert; + gnutls_x509_crt_t cert2; + int ret; + + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id), -1); + xmlSecAssert2(node != NULL, -1); + xmlSecAssert2(keyInfoCtx != NULL, -1); + xmlSecAssert2(keyInfoCtx->keysMngr != NULL, -1); + + x509Store = xmlSecKeysMngrGetDataStore(keyInfoCtx->keysMngr, xmlSecGnuTLSX509StoreId); + if(x509Store == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "xmlSecKeysMngrGetDataStore", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + subject = xmlNodeGetContent(node); + if((subject == NULL) || (xmlSecIsEmptyString(subject) == 1)) { + if(subject != NULL) { + xmlFree(subject); + } + if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_STOP_ON_EMPTY_NODE) != 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + xmlSecErrorsSafeString(xmlSecNodeGetName(node)), + XMLSEC_ERRORS_R_INVALID_NODE_CONTENT, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + return(0); + } + + xmlSecGnuTLSX509Trim(subject); + cert = xmlSecGnuTLSX509StoreFindCert(x509Store, subject, NULL, NULL, NULL, keyInfoCtx); + if(cert == NULL){ + + if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_X509DATA_STOP_ON_UNKNOWN_CERT) != 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + NULL, + XMLSEC_ERRORS_R_CERT_NOT_FOUND, + "subject=%s", + xmlSecErrorsSafeString(subject)); + xmlFree(subject); + return(-1); + } + + xmlFree(subject); + return(0); + } + + cert2 = xmlSecGnuTLSX509CertDup(cert); + if(cert2 == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "xmlSecGnuTLSX509CertDup", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + + xmlFree(subject); + return(-1); + } + + ret = xmlSecGnuTLSKeyDataX509AdoptCert(data, cert2); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "xmlSecGnuTLSKeyDataX509AdoptCert", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + gnutls_x509_crt_deinit(cert2); + xmlFree(subject); + return(-1); + } + + xmlFree(subject); + return(0); +} + +static int +xmlSecGnuTLSX509SubjectNameNodeWrite(gnutls_x509_crt_t cert, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx ATTRIBUTE_UNUSED) { + xmlChar* buf = NULL; + xmlNodePtr cur = NULL; + + xmlSecAssert2(cert != NULL, -1); + xmlSecAssert2(node != NULL, -1); + + /* add node */ + cur = xmlSecAddChild(node, xmlSecNodeX509SubjectName, xmlSecDSigNs); + if(cur == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecAddChild", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeX509SubjectName)); + return(-1); + } + + /* get subject */ + buf = xmlSecGnuTLSX509CertGetSubjectDN(cert); + if(buf == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSX509CertGetSubjectDN", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + /* set value */ + xmlSecNodeEncodeAndSetContent(cur, buf); + + /* done */ + xmlFree(buf); + return(0); +} + +static int +xmlSecGnuTLSX509IssuerSerialNodeRead(xmlSecKeyDataPtr data, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) { + xmlSecKeyDataStorePtr x509Store; + xmlNodePtr cur; + xmlChar *issuerName; + xmlChar *issuerSerial; + gnutls_x509_crt_t cert; + gnutls_x509_crt_t cert2; + int ret; + + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id), -1); + xmlSecAssert2(node != NULL, -1); + xmlSecAssert2(keyInfoCtx != NULL, -1); + xmlSecAssert2(keyInfoCtx->keysMngr != NULL, -1); + + x509Store = xmlSecKeysMngrGetDataStore(keyInfoCtx->keysMngr, xmlSecGnuTLSX509StoreId); + if(x509Store == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "xmlSecKeysMngrGetDataStore", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + cur = xmlSecGetNextElementNode(node->children); + if(cur == NULL) { + if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_STOP_ON_EMPTY_NODE) != 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + xmlSecErrorsSafeString(xmlSecNodeX509IssuerName), + XMLSEC_ERRORS_R_NODE_NOT_FOUND, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeGetName(cur))); + return(-1); + } + return(0); + } + + /* the first is required node X509IssuerName */ + if(!xmlSecCheckNodeName(cur, xmlSecNodeX509IssuerName, xmlSecDSigNs)) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + xmlSecErrorsSafeString(xmlSecNodeX509IssuerName), + XMLSEC_ERRORS_R_NODE_NOT_FOUND, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeGetName(cur))); + return(-1); + } + issuerName = xmlNodeGetContent(cur); + if(issuerName == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + xmlSecErrorsSafeString(xmlSecNodeGetName(cur)), + XMLSEC_ERRORS_R_INVALID_NODE_CONTENT, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeX509IssuerName)); + return(-1); + } + cur = xmlSecGetNextElementNode(cur->next); + + /* next is required node X509SerialNumber */ + if((cur == NULL) || !xmlSecCheckNodeName(cur, xmlSecNodeX509SerialNumber, xmlSecDSigNs)) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + xmlSecErrorsSafeString(xmlSecNodeGetName(cur)), + XMLSEC_ERRORS_R_NODE_NOT_FOUND, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeX509SerialNumber)); + xmlFree(issuerName); + return(-1); + } + issuerSerial = xmlNodeGetContent(cur); + if(issuerSerial == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + xmlSecErrorsSafeString(xmlSecNodeX509SerialNumber), + XMLSEC_ERRORS_R_INVALID_NODE_CONTENT, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeGetName(cur))); + xmlFree(issuerName); + return(-1); + } + cur = xmlSecGetNextElementNode(cur->next); + + if(cur != NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + xmlSecErrorsSafeString(xmlSecNodeGetName(cur)), + XMLSEC_ERRORS_R_UNEXPECTED_NODE, + XMLSEC_ERRORS_NO_MESSAGE); + xmlFree(issuerSerial); + xmlFree(issuerName); + return(-1); + } + + xmlSecGnuTLSX509Trim(issuerName); + xmlSecGnuTLSX509Trim(issuerSerial); + cert = xmlSecGnuTLSX509StoreFindCert(x509Store, NULL, issuerName, issuerSerial, NULL, keyInfoCtx); + if(cert == NULL){ + + if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_X509DATA_STOP_ON_UNKNOWN_CERT) != 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + NULL, + XMLSEC_ERRORS_R_CERT_NOT_FOUND, + "issuerName=%s;issuerSerial=%s", + xmlSecErrorsSafeString(issuerName), + xmlSecErrorsSafeString(issuerSerial)); + xmlFree(issuerSerial); + xmlFree(issuerName); + return(-1); + } + xmlFree(issuerSerial); + xmlFree(issuerName); + return(0); + } + + cert2 = xmlSecGnuTLSX509CertDup(cert); + if(cert2 == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "xmlSecGnuTLSX509CertDup", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlFree(issuerSerial); + xmlFree(issuerName); + return(-1); + } + + ret = xmlSecGnuTLSKeyDataX509AdoptCert(data, cert2); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "xmlSecGnuTLSKeyDataX509AdoptCert", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + gnutls_x509_crt_deinit(cert2); + xmlFree(issuerSerial); + xmlFree(issuerName); + return(-1); + } + + xmlFree(issuerSerial); + xmlFree(issuerName); + return(0); +} + +static int +xmlSecGnuTLSX509IssuerSerialNodeWrite(gnutls_x509_crt_t cert, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx ATTRIBUTE_UNUSED) { + xmlNodePtr cur; + xmlNodePtr issuerNameNode; + xmlNodePtr issuerNumberNode; + xmlChar* buf; + + xmlSecAssert2(cert != NULL, -1); + xmlSecAssert2(node != NULL, -1); + + /* create xml nodes */ + cur = xmlSecAddChild(node, xmlSecNodeX509IssuerSerial, xmlSecDSigNs); + if(cur == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecAddChild", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeX509IssuerSerial)); + return(-1); + } + + issuerNameNode = xmlSecAddChild(cur, xmlSecNodeX509IssuerName, xmlSecDSigNs); + if(issuerNameNode == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecAddChild", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeX509IssuerName)); + return(-1); + } + + issuerNumberNode = xmlSecAddChild(cur, xmlSecNodeX509SerialNumber, xmlSecDSigNs); + if(issuerNumberNode == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecAddChild", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeX509SerialNumber)); + return(-1); + } + + /* write data */ + buf = xmlSecGnuTLSX509CertGetIssuerDN(cert); + if(buf == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSX509CertGetIssuerDN", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + xmlSecNodeEncodeAndSetContent(issuerNameNode, buf); + xmlFree(buf); + + buf = xmlSecGnuTLSX509CertGetIssuerSerial(cert); + if(buf == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSX509CertGetIssuerSerial", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + xmlSecNodeEncodeAndSetContent(issuerNumberNode, buf); + xmlFree(buf); + + return(0); +} + + +static int +xmlSecGnuTLSX509SKINodeRead(xmlSecKeyDataPtr data, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) { + xmlSecKeyDataStorePtr x509Store; + xmlChar* ski; + gnutls_x509_crt_t cert; + gnutls_x509_crt_t cert2; + int ret; + + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id), -1); + xmlSecAssert2(node != NULL, -1); + xmlSecAssert2(keyInfoCtx != NULL, -1); + xmlSecAssert2(keyInfoCtx->keysMngr != NULL, -1); + + x509Store = xmlSecKeysMngrGetDataStore(keyInfoCtx->keysMngr, xmlSecGnuTLSX509StoreId); + if(x509Store == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "xmlSecKeysMngrGetDataStore", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + ski = xmlNodeGetContent(node); + if((ski == NULL) || (xmlSecIsEmptyString(ski) == 1)) { + if(ski != NULL) { + xmlFree(ski); + } + if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_STOP_ON_EMPTY_NODE) != 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + xmlSecErrorsSafeString(xmlSecNodeGetName(node)), + XMLSEC_ERRORS_R_INVALID_NODE_CONTENT, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeX509SKI)); + return(-1); + } + return(0); + } + + xmlSecGnuTLSX509Trim(ski); + cert = xmlSecGnuTLSX509StoreFindCert(x509Store, NULL, NULL, NULL, ski, keyInfoCtx); + if(cert == NULL){ + xmlFree(ski); + + if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_X509DATA_STOP_ON_UNKNOWN_CERT) != 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + NULL, + XMLSEC_ERRORS_R_CERT_NOT_FOUND, + "ski=%s", + xmlSecErrorsSafeString(ski)); + return(-1); + } + return(0); + } + + cert2 = xmlSecGnuTLSX509CertDup(cert); + if(cert2 == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "xmlSecGnuTLSX509CertDup", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlFree(ski); + return(-1); + } + + ret = xmlSecGnuTLSKeyDataX509AdoptCert(data, cert2); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "xmlSecGnuTLSKeyDataX509AdoptCert", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + gnutls_x509_crt_deinit(cert2); + xmlFree(ski); + return(-1); + } + + xmlFree(ski); + return(0); +} + +static int +xmlSecGnuTLSX509SKINodeWrite(gnutls_x509_crt_t cert, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx ATTRIBUTE_UNUSED) { + xmlChar *buf = NULL; + xmlNodePtr cur = NULL; + + xmlSecAssert2(cert != NULL, -1); + xmlSecAssert2(node != NULL, -1); + + /* add node */ + cur = xmlSecAddChild(node, xmlSecNodeX509SKI, xmlSecDSigNs); + if(cur == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecAddChild", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "new_node=%s", + xmlSecErrorsSafeString(xmlSecNodeX509SKI)); + return(-1); + } + + /* write value */ + buf = xmlSecGnuTLSX509CertGetSKI(cert); + if(buf == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSX509CertGetSKI", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + xmlSecNodeEncodeAndSetContent(cur, buf); + xmlFree(buf); + + return(0); +} + +static int +xmlSecGnuTLSX509CRLNodeRead(xmlSecKeyDataPtr data, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) { + xmlChar *content; + gnutls_x509_crl_t crl; + int ret; + + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id), -1); + xmlSecAssert2(node != NULL, -1); + xmlSecAssert2(keyInfoCtx != NULL, -1); + + content = xmlNodeGetContent(node); + if((content == NULL) || (xmlSecIsEmptyString(content) == 1)) { + if(content != NULL) { + xmlFree(content); + } + if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_STOP_ON_EMPTY_NODE) != 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + xmlSecErrorsSafeString(xmlSecNodeGetName(node)), + XMLSEC_ERRORS_R_INVALID_NODE_CONTENT, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + return(0); + } + + crl = xmlSecGnuTLSX509CrlBase64DerRead(content); + if(crl == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "xmlSecGnuTLSX509CrlBase64DerRead", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlFree(content); + return(-1); + } + + ret = xmlSecGnuTLSKeyDataX509AdoptCrl(data, crl); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "xmlSecGnuTLSKeyDataX509AdoptCrl", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + gnutls_x509_crl_deinit(crl); + xmlFree(content); + return(-1); + } + + xmlFree(content); + return(0); +} + +static int +xmlSecGnuTLSX509CRLNodeWrite(gnutls_x509_crl_t crl, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) { + xmlChar* buf = NULL; + xmlNodePtr cur = NULL; + + xmlSecAssert2(crl != NULL, -1); + xmlSecAssert2(node != NULL, -1); + xmlSecAssert2(keyInfoCtx != NULL, -1); + + /* set base64 lines size from context */ + buf = xmlSecGnuTLSX509CrlBase64DerWrite(crl, keyInfoCtx->base64LineSize); + if(buf == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSX509CrlBase64DerWrite", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + cur = xmlSecAddChild(node, xmlSecNodeX509CRL, xmlSecDSigNs); + if(cur == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecAddChild", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "new_node=%s", + xmlSecErrorsSafeString(xmlSecNodeX509CRL)); + xmlFree(buf); + return(-1); + } + /* todo: add \n around base64 data - from context */ + /* todo: add errors check */ + xmlNodeSetContent(cur, xmlSecStringCR); + xmlNodeSetContent(cur, buf); + xmlFree(buf); + + return(0); +} + + +static int +xmlSecGnuTLSKeyDataX509VerifyAndExtractKey(xmlSecKeyDataPtr data, xmlSecKeyPtr key, + xmlSecKeyInfoCtxPtr keyInfoCtx) { + xmlSecGnuTLSX509DataCtxPtr ctx; + xmlSecKeyDataStorePtr x509Store; + int ret; + + xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataX509Id), -1); + xmlSecAssert2(key != NULL, -1); + xmlSecAssert2(keyInfoCtx != NULL, -1); + xmlSecAssert2(keyInfoCtx->keysMngr != NULL, -1); + + ctx = xmlSecGnuTLSX509DataGetCtx(data); + xmlSecAssert2(ctx != NULL, -1); + + x509Store = xmlSecKeysMngrGetDataStore(keyInfoCtx->keysMngr, xmlSecGnuTLSX509StoreId); + if(x509Store == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "xmlSecKeysMngrGetDataStore", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + if((ctx->keyCert == NULL) && (xmlSecPtrListGetSize(&(ctx->certsList)) > 0) && (xmlSecKeyGetValue(key) == NULL)) { + gnutls_x509_crt_t cert; + + cert = xmlSecGnuTLSX509StoreVerify(x509Store, &(ctx->certsList), &(ctx->crlsList), keyInfoCtx); + if(cert != NULL) { + xmlSecKeyDataPtr keyValue; + + ctx->keyCert = xmlSecGnuTLSX509CertDup(cert); + if(ctx->keyCert == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "xmlSecGnuTLSX509CertDup", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + keyValue = xmlSecGnuTLSX509CertGetKey(ctx->keyCert); + if(keyValue == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "xmlSecGnuTLSX509CertGetKey", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + /* verify that the key matches our expectations */ + if(xmlSecKeyReqMatchKeyValue(&(keyInfoCtx->keyReq), keyValue) != 1) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "xmlSecKeyReqMatchKeyValue", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlSecKeyDataDestroy(keyValue); + return(-1); + } + + ret = xmlSecKeySetValue(key, keyValue); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "xmlSecKeySetValue", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlSecKeyDataDestroy(keyValue); + return(-1); + } + + /* get expiration time */ + key->notValidBefore = gnutls_x509_crt_get_activation_time(ctx->keyCert); + if(key->notValidBefore == (time_t)-1) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "gnutls_x509_crt_get_activation_time", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + key->notValidAfter = gnutls_x509_crt_get_expiration_time(ctx->keyCert); + if(key->notValidAfter == (time_t)-1) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + "gnutls_x509_crt_get_expiration_time", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + } else if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_X509DATA_STOP_ON_INVALID_CERT) != 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)), + NULL, + XMLSEC_ERRORS_R_CERT_NOT_FOUND, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + } + return(0); +} + +/** + * xmlSecGnuTLSX509CertGetKey: + * @cert: the certificate. + * + * Extracts public key from the @cert. + * + * Returns: public key value or NULL if an error occurs. + */ +xmlSecKeyDataPtr +xmlSecGnuTLSX509CertGetKey(gnutls_x509_crt_t cert) { + xmlSecKeyDataPtr data; + int alg; + unsigned int bits; + int err; + int ret; + + xmlSecAssert2(cert != NULL, NULL); + + alg = gnutls_x509_crt_get_pk_algorithm(cert, &bits); + if(alg < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_x509_crt_get_pk_algorithm", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(alg)); + return(NULL); + } + + switch(alg) { +#ifndef XMLSEC_NO_RSA + case GNUTLS_PK_RSA: + { + gnutls_datum_t m, e; + + data = xmlSecKeyDataCreate(xmlSecGnuTLSKeyDataRsaId); + if(data == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeyDataCreate", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "xmlSecGnuTLSKeyDataRsaId"); + return(NULL); + } + + err = gnutls_x509_crt_get_pk_rsa_raw(cert, &m, &e); + if(err != GNUTLS_E_SUCCESS) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_x509_crt_get_pk_rsa_raw", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + return(NULL); + } + + ret = xmlSecGnuTLSKeyDataRsaAdoptPublicKey(data, &m, &e); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSKeyDataRsaAdoptPublicKey", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + gnutls_free(m.data); + gnutls_free(e.data); + return(NULL); + } + /* m and e are owned by data now */ + } + break; +#endif /* XMLSEC_NO_RSA */ + +#ifndef XMLSEC_NO_DSA + case GNUTLS_PK_DSA: + { + gnutls_datum_t p, q, g, y; + + data = xmlSecKeyDataCreate(xmlSecGnuTLSKeyDataDsaId); + if(data == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeyDataCreate", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "xmlSecGnuTLSKeyDataDsaId"); + return(NULL); + } + + err = gnutls_x509_crt_get_pk_dsa_raw(cert, &p, &q, &g, &y); + if(err != GNUTLS_E_SUCCESS) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_x509_crt_get_pk_dsa_raw", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + return(NULL); + } + + ret = xmlSecGnuTLSKeyDataDsaAdoptPublicKey(data, &p, &q, &g, &y); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSKeyDataDsaAdoptPublicKey", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + gnutls_free(p.data); + gnutls_free(q.data); + gnutls_free(g.data); + gnutls_free(y.data); + return(NULL); + } + /* p, q, g and y are owned by data now */ + } + break; +#endif /* XMLSEC_NO_DSA */ + + default: + { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_x509_crt_get_pk_algorithm", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + "Unsupported algorithm %d", (int)alg); + return(NULL); + } + } + + /* data */ + return(data); +} + + +/************************************************************************** + * + * Raw X509 Certificate processing + * + * + *************************************************************************/ +static int xmlSecGnuTLSKeyDataRawX509CertBinRead (xmlSecKeyDataId id, + xmlSecKeyPtr key, + const xmlSecByte* buf, + xmlSecSize bufSize, + xmlSecKeyInfoCtxPtr keyInfoCtx); + +static xmlSecKeyDataKlass xmlSecGnuTLSKeyDataRawX509CertKlass = { + sizeof(xmlSecKeyDataKlass), + sizeof(xmlSecKeyData), + + /* data */ + xmlSecNameRawX509Cert, + xmlSecKeyDataUsageRetrievalMethodNodeBin, + /* xmlSecKeyDataUsage usage; */ + xmlSecHrefRawX509Cert, /* const xmlChar* href; */ + NULL, /* const xmlChar* dataNodeName; */ + xmlSecDSigNs, /* const xmlChar* dataNodeNs; */ + + /* constructors/destructor */ + NULL, /* xmlSecKeyDataInitializeMethod initialize; */ + NULL, /* xmlSecKeyDataDuplicateMethod duplicate; */ + NULL, /* xmlSecKeyDataFinalizeMethod finalize; */ + NULL, /* xmlSecKeyDataGenerateMethod generate; */ + + /* get info */ + NULL, /* xmlSecKeyDataGetTypeMethod getType; */ + NULL, /* xmlSecKeyDataGetSizeMethod getSize; */ + NULL, /* xmlSecKeyDataGetIdentifier getIdentifier; */ + + /* read/write */ + NULL, /* xmlSecKeyDataXmlReadMethod xmlRead; */ + NULL, /* xmlSecKeyDataXmlWriteMethod xmlWrite; */ + xmlSecGnuTLSKeyDataRawX509CertBinRead, /* xmlSecKeyDataBinReadMethod binRead; */ + NULL, /* xmlSecKeyDataBinWriteMethod binWrite; */ + + /* debug */ + NULL, /* xmlSecKeyDataDebugDumpMethod debugDump; */ + NULL, /* xmlSecKeyDataDebugDumpMethod debugXmlDump; */ + + /* reserved for the future */ + NULL, /* void* reserved0; */ + NULL, /* void* reserved1; */ +}; + +/** + * xmlSecGnuTLSKeyDataRawX509CertGetKlass: + * + * The raw X509 certificates key data klass. + * + * Returns: raw X509 certificates key data klass. + */ +xmlSecKeyDataId +xmlSecGnuTLSKeyDataRawX509CertGetKlass(void) { + return(&xmlSecGnuTLSKeyDataRawX509CertKlass); +} + +static int +xmlSecGnuTLSKeyDataRawX509CertBinRead(xmlSecKeyDataId id, xmlSecKeyPtr key, + const xmlSecByte* buf, xmlSecSize bufSize, + xmlSecKeyInfoCtxPtr keyInfoCtx) { + xmlSecKeyDataPtr data; + gnutls_x509_crt_t cert; + int ret; + + xmlSecAssert2(id == xmlSecGnuTLSKeyDataRawX509CertId, -1); + xmlSecAssert2(key != NULL, -1); + xmlSecAssert2(buf != NULL, -1); + xmlSecAssert2(bufSize > 0, -1); + xmlSecAssert2(keyInfoCtx != NULL, -1); + + cert = xmlSecGnuTLSX509CertRead(buf, bufSize, xmlSecKeyDataFormatCertDer); + if(cert == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSX509CertRead", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + data = xmlSecKeyEnsureData(key, xmlSecGnuTLSKeyDataX509Id); + if(data == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecKeyEnsureData", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + gnutls_x509_crt_deinit(cert); + return(-1); + } + + ret = xmlSecGnuTLSKeyDataX509AdoptCert(data, cert); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecGnuTLSKeyDataX509AdoptCert", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + gnutls_x509_crt_deinit(cert); + return(-1); + } + + ret = xmlSecGnuTLSKeyDataX509VerifyAndExtractKey(data, key, keyInfoCtx); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), + "xmlSecGnuTLSKeyDataX509VerifyAndExtractKey", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + return(0); +} + +#endif /* XMLSEC_NO_X509 */ diff --git a/src/gnutls/x509utils.c b/src/gnutls/x509utils.c new file mode 100644 index 00000000..0dc70003 --- /dev/null +++ b/src/gnutls/x509utils.c @@ -0,0 +1,1687 @@ +/** + * XMLSec library + * + * X509 support + * + * + * This is free software; see Copyright file in the source + * distribution for preciese wording. + * + * Copyright (C) 2010 Aleksey Sanin <aleksey@aleksey.com> + */ +#include "globals.h" + +#ifndef XMLSEC_NO_X509 + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <errno.h> +#include <time.h> + +#include <libxml/tree.h> + + + +#include <gnutls/gnutls.h> +#include <gnutls/x509.h> +#include <gnutls/pkcs12.h> + +#include <xmlsec/xmlsec.h> +#include <xmlsec/xmltree.h> +#include <xmlsec/keys.h> +#include <xmlsec/keyinfo.h> +#include <xmlsec/keysmngr.h> +#include <xmlsec/x509.h> +#include <xmlsec/base64.h> +#include <xmlsec/errors.h> +#include <xmlsec/private.h> + +#include <xmlsec/gnutls/crypto.h> +#include <xmlsec/gnutls/x509.h> + +#include "x509utils.h" + + +/************************************************************************** + * + * X509 crt list + * + *****************************************************************************/ +static xmlSecPtr xmlSecGnuTLSX509CrtListDuplicateItem (xmlSecPtr ptr); +static void xmlSecGnuTLSX509CrtListDestroyItem (xmlSecPtr ptr); +static void xmlSecGnuTLSX509CrtListDebugDumpItem (xmlSecPtr ptr, + FILE* output); +static void xmlSecGnuTLSX509CrtListDebugXmlDumpItem (xmlSecPtr ptr, + FILE* output); + +static xmlSecPtrListKlass xmlSecGnuTLSX509CrtListKlass = { + BAD_CAST "gnutls-x509-crt-list", + xmlSecGnuTLSX509CrtListDuplicateItem, /* xmlSecPtrDuplicateItemMethod duplicateItem; */ + xmlSecGnuTLSX509CrtListDestroyItem, /* xmlSecPtrDestroyItemMethod destroyItem; */ + xmlSecGnuTLSX509CrtListDebugDumpItem, /* xmlSecPtrDebugDumpItemMethod debugDumpItem; */ + xmlSecGnuTLSX509CrtListDebugXmlDumpItem, /* xmlSecPtrDebugDumpItemMethod debugXmlDumpItem; */ +}; + +xmlSecPtrListId +xmlSecGnuTLSX509CrtListGetKlass(void) { + return(&xmlSecGnuTLSX509CrtListKlass); +} + +static xmlSecPtr +xmlSecGnuTLSX509CrtListDuplicateItem(xmlSecPtr ptr) { + xmlSecAssert2(ptr != NULL, NULL); + + return xmlSecGnuTLSX509CertDup((gnutls_x509_crt_t)ptr); +} + +static void +xmlSecGnuTLSX509CrtListDestroyItem(xmlSecPtr ptr) { + xmlSecAssert(ptr != NULL); + + gnutls_x509_crt_deinit((gnutls_x509_crt_t)ptr); +} + +static void +xmlSecGnuTLSX509CrtListDebugDumpItem(xmlSecPtr ptr, FILE* output) { + xmlSecAssert(ptr != NULL); + xmlSecAssert(output != NULL); + + xmlSecGnuTLSX509CertDebugDump((gnutls_x509_crt_t)ptr, output); +} + + +static void +xmlSecGnuTLSX509CrtListDebugXmlDumpItem(xmlSecPtr ptr, FILE* output) { + xmlSecAssert(ptr != NULL); + xmlSecAssert(output != NULL); + + xmlSecGnuTLSX509CertDebugXmlDump((gnutls_x509_crt_t)ptr, output); +} + +/************************************************************************** + * + * X509 crl list + * + *****************************************************************************/ +static xmlSecPtr xmlSecGnuTLSX509CrlListDuplicateItem (xmlSecPtr ptr); +static void xmlSecGnuTLSX509CrlListDestroyItem (xmlSecPtr ptr); +static void xmlSecGnuTLSX509CrlListDebugDumpItem (xmlSecPtr ptr, + FILE* output); +static void xmlSecGnuTLSX509CrlListDebugXmlDumpItem (xmlSecPtr ptr, + FILE* output); + +static xmlSecPtrListKlass xmlSecGnuTLSX509CrlListKlass = { + BAD_CAST "gnutls-x509-crl-list", + xmlSecGnuTLSX509CrlListDuplicateItem, /* xmlSecPtrDuplicateItemMethod duplicateItem; */ + xmlSecGnuTLSX509CrlListDestroyItem, /* xmlSecPtrDestroyItemMethod destroyItem; */ + xmlSecGnuTLSX509CrlListDebugDumpItem, /* xmlSecPtrDebugDumpItemMethod debugDumpItem; */ + xmlSecGnuTLSX509CrlListDebugXmlDumpItem, /* xmlSecPtrDebugDumpItemMethod debugXmlDumpItem; */ +}; + +xmlSecPtrListId +xmlSecGnuTLSX509CrlListGetKlass(void) { + return(&xmlSecGnuTLSX509CrlListKlass); +} + +static xmlSecPtr +xmlSecGnuTLSX509CrlListDuplicateItem(xmlSecPtr ptr) { + xmlSecAssert2(ptr != NULL, NULL); + + return xmlSecGnuTLSX509CrlDup((gnutls_x509_crl_t)ptr); +} + +static void +xmlSecGnuTLSX509CrlListDestroyItem(xmlSecPtr ptr) { + xmlSecAssert(ptr != NULL); + + gnutls_x509_crl_deinit((gnutls_x509_crl_t)ptr); +} + +static void +xmlSecGnuTLSX509CrlListDebugDumpItem(xmlSecPtr ptr, FILE* output) { + xmlSecAssert(ptr != NULL); + xmlSecAssert(output != NULL); + + xmlSecGnuTLSX509CrlDebugDump((gnutls_x509_crl_t)ptr, output); +} + + +static void +xmlSecGnuTLSX509CrlListDebugXmlDumpItem(xmlSecPtr ptr, FILE* output) { + xmlSecAssert(ptr != NULL); + xmlSecAssert(output != NULL); + + xmlSecGnuTLSX509CrlDebugXmlDump((gnutls_x509_crl_t)ptr, output); +} + +/************************************************************************* + * + * x509 certs utils/helpers + * + ************************************************************************/ + +/* HACK: gnutls doesn't have cert duplicate function, so we simply + write cert out and then read it back */ +gnutls_x509_crt_t +xmlSecGnuTLSX509CertDup(gnutls_x509_crt_t src) { + xmlChar * buf = NULL; + gnutls_x509_crt_t res = NULL; + + xmlSecAssert2(src != NULL, NULL); + + buf = xmlSecGnuTLSX509CertBase64DerWrite(src, 0); + if(buf == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSX509CertBase64DerWrite", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return (NULL); + } + + res = xmlSecGnuTLSX509CertBase64DerRead(buf); + if(res == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSX509CertBase64DerRead", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlFree(buf); + return (NULL); + } + + /* done */ + xmlFree(buf); + return (res); +} + +xmlChar * +xmlSecGnuTLSX509CertGetSubjectDN(gnutls_x509_crt_t cert) { + char* buf = NULL; + size_t bufSize = 0; + int err; + + xmlSecAssert2(cert != NULL, NULL); + + /* get subject size */ + err = gnutls_x509_crt_get_dn(cert, NULL, &bufSize); + if((err != GNUTLS_E_SHORT_MEMORY_BUFFER) || (bufSize <= 0)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_x509_crt_get_dn", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + return(NULL); + } + + /* allocate buffer */ + buf = (char *)xmlMalloc(bufSize + 1); + if(buf == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlMalloc", + XMLSEC_ERRORS_R_MALLOC_FAILED, + "size=%d", (int)bufSize); + return(NULL); + } + + /* finally write it out */ + err = gnutls_x509_crt_get_dn(cert, buf, &bufSize); + if(err != GNUTLS_E_SUCCESS) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_x509_crt_get_dn", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + xmlFree(buf); + return(NULL); + } + + /* done */ + return(BAD_CAST buf); +} + +xmlChar * +xmlSecGnuTLSX509CertGetIssuerDN(gnutls_x509_crt_t cert) { + char* buf = NULL; + size_t bufSize = 0; + int err; + + xmlSecAssert2(cert != NULL, NULL); + + /* get issuer size */ + err = gnutls_x509_crt_get_issuer_dn(cert, NULL, &bufSize); + if((err != GNUTLS_E_SHORT_MEMORY_BUFFER) || (bufSize <= 0)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_x509_crt_get_issuer_dn", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + return(NULL); + } + + /* allocate buffer */ + buf = (char *)xmlMalloc(bufSize + 1); + if(buf == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlMalloc", + XMLSEC_ERRORS_R_MALLOC_FAILED, + "size=%d", (int)bufSize); + return(NULL); + } + + /* finally write it out */ + err = gnutls_x509_crt_get_issuer_dn(cert, buf, &bufSize); + if(err != GNUTLS_E_SUCCESS) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_x509_crt_get_issuer_dn", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + xmlFree(buf); + return(NULL); + } + + /* done */ + return(BAD_CAST buf); +} + +xmlChar * +xmlSecGnuTLSX509CertGetIssuerSerial(gnutls_x509_crt_t cert) { + xmlChar * res = NULL; + unsigned char* buf = NULL; + size_t bufSize = 0; + int err; + + xmlSecAssert2(cert != NULL, NULL); + + /* get issuer serial size */ + err = gnutls_x509_crt_get_serial(cert, NULL, &bufSize); + if((err != GNUTLS_E_SHORT_MEMORY_BUFFER) || (bufSize <= 0)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_x509_crt_get_serial", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + return(NULL); + } + + /* allocate buffer */ + buf = (unsigned char *)xmlMalloc(bufSize + 1); + if(buf == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlMalloc", + XMLSEC_ERRORS_R_MALLOC_FAILED, + "size=%d", (int)bufSize); + return(NULL); + } + + /* write it out */ + err = gnutls_x509_crt_get_serial(cert, buf, &bufSize); + if(err != GNUTLS_E_SUCCESS) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_x509_crt_get_serial", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + xmlFree(buf); + return(NULL); + } + + /* convert to string */ + res = xmlSecGnuTLSASN1IntegerWrite(buf, bufSize); + if(res == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSASN1IntegerWrite", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlFree(buf); + return(NULL); + } + + /* done */ + xmlFree(buf); + return(res); +} + +xmlChar * +xmlSecGnuTLSX509CertGetSKI(gnutls_x509_crt_t cert) { + xmlChar * res = NULL; + xmlSecByte* buf = NULL; + size_t bufSize = 0; + unsigned int critical = 0; + int err; + + xmlSecAssert2(cert != NULL, NULL); + + /* get ski size */ + err = gnutls_x509_crt_get_subject_key_id(cert, NULL, &bufSize, &critical); + if((err != GNUTLS_E_SHORT_MEMORY_BUFFER) || (bufSize <= 0)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_x509_crt_get_subject_key_id", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + return(NULL); + } + + /* allocate buffer */ + buf = (xmlSecByte *)xmlMalloc(bufSize + 1); + if(buf == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlMalloc", + XMLSEC_ERRORS_R_MALLOC_FAILED, + "size=%d", (int)bufSize); + return(NULL); + } + + /* write it out */ + err = gnutls_x509_crt_get_subject_key_id(cert, buf, &bufSize, &critical); + if(err != GNUTLS_E_SUCCESS) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_x509_crt_get_subject_key_id", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + xmlFree(buf); + return(NULL); + } + + /* convert to string */ + res = xmlSecBase64Encode(buf, bufSize, 0); + if(res == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBase64Encode", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlFree(buf); + return(NULL); + } + + /* done */ + xmlFree(buf); + return(res); +} + + +gnutls_x509_crt_t +xmlSecGnuTLSX509CertBase64DerRead(xmlChar* buf) { + int ret; + + xmlSecAssert2(buf != NULL, NULL); + + /* usual trick with base64 decoding "in-place" */ + ret = xmlSecBase64Decode(buf, (xmlSecByte*)buf, xmlStrlen(buf)); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBase64Decode", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(NULL); + } + + return(xmlSecGnuTLSX509CertRead((const xmlSecByte*)buf, ret, xmlSecKeyDataFormatCertDer)); +} + +gnutls_x509_crt_t +xmlSecGnuTLSX509CertRead(const xmlSecByte* buf, xmlSecSize size, xmlSecKeyDataFormat format) { + gnutls_x509_crt_t cert = NULL; + gnutls_x509_crt_fmt_t fmt; + gnutls_datum_t data; + int err; + + xmlSecAssert2(buf != NULL, NULL); + xmlSecAssert2(size > 0, NULL); + + /* figure out format */ + switch(format) { + case xmlSecKeyDataFormatPem: + case xmlSecKeyDataFormatCertPem: + fmt = GNUTLS_X509_FMT_PEM; + break; + case xmlSecKeyDataFormatDer: + case xmlSecKeyDataFormatCertDer: + fmt = GNUTLS_X509_FMT_DER; + break; + default: + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + NULL, + XMLSEC_ERRORS_R_INVALID_FORMAT, + "format=%d", format); + return(NULL); + } + + /* read cert */ + err = gnutls_x509_crt_init(&cert); + if(err != GNUTLS_E_SUCCESS) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_x509_crt_init", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + return(NULL); + } + + data.data = (unsigned char*)buf; + data.size = size; + err = gnutls_x509_crt_import(cert, &data, fmt); + if(err != GNUTLS_E_SUCCESS) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_x509_crt_import", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + gnutls_x509_crt_deinit(cert); + return(NULL); + } + + return(cert); +} + +xmlChar* +xmlSecGnuTLSX509CertBase64DerWrite(gnutls_x509_crt_t cert, int base64LineWrap) { + xmlChar * res = NULL; + xmlSecByte* buf = NULL; + size_t bufSize = 0; + int err; + + xmlSecAssert2(cert != NULL, NULL); + + /* get size */ + err = gnutls_x509_crt_export(cert, GNUTLS_X509_FMT_DER, NULL, &bufSize); + if((err != GNUTLS_E_SHORT_MEMORY_BUFFER) || (bufSize <= 0)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_x509_crt_export(GNUTLS_X509_FMT_DER)", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + return(NULL); + } + + /* allocate buffer */ + buf = (xmlSecByte *)xmlMalloc(bufSize + 1); + if(buf == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlMalloc", + XMLSEC_ERRORS_R_MALLOC_FAILED, + "size=%d", (int)bufSize); + return(NULL); + } + + /* write it out */ + err = gnutls_x509_crt_export(cert, GNUTLS_X509_FMT_DER, buf, &bufSize); + if(err != GNUTLS_E_SUCCESS) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_x509_crt_export(GNUTLS_X509_FMT_DER)", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + xmlFree(buf); + return(NULL); + } + + /* convert to string */ + res = xmlSecBase64Encode(buf, bufSize, base64LineWrap); + if(res == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBase64Encode", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlFree(buf); + return(NULL); + } + + /* done */ + xmlFree(buf); + return(res); +} + +void +xmlSecGnuTLSX509CertDebugDump(gnutls_x509_crt_t cert, FILE* output) { + xmlChar * buf; + + xmlSecAssert(cert != NULL); + xmlSecAssert(output != NULL); + + buf = xmlSecGnuTLSX509CertGetSubjectDN(cert); + if(buf != NULL) { + fprintf(output, "==== Subject Name: %s\n", buf); + xmlFree(buf); + } else { + fprintf(output, "==== Subject Name: unknown\n"); + } + + buf = xmlSecGnuTLSX509CertGetIssuerDN(cert); + if(buf != NULL) { + fprintf(output, "==== Issuer Name: %s\n", buf); + xmlFree(buf); + } else { + fprintf(output, "==== Issuer Name: unknown\n"); + } + + buf = xmlSecGnuTLSX509CertGetIssuerSerial(cert); + if(buf != NULL) { + fprintf(output, "==== Issuer Serial: %s\n", buf); + xmlFree(buf); + } else { + fprintf(output, "==== Issuer Serial: unknown\n"); + } +} + +void +xmlSecGnuTLSX509CertDebugXmlDump(gnutls_x509_crt_t cert, FILE* output) { + xmlChar * buf; + + xmlSecAssert(cert != NULL); + xmlSecAssert(output != NULL); + + buf = xmlSecGnuTLSX509CertGetSubjectDN(cert); + if(buf != NULL) { + fprintf(output, "<SubjectName>%s</SubjectName>\n", buf); + xmlFree(buf); + } else { + fprintf(output, "<SubjectName>unknown</SubjectName>\n"); + } + + buf = xmlSecGnuTLSX509CertGetIssuerDN(cert); + if(buf != NULL) { + fprintf(output, "<IssuerName>%s</IssuerName>\n", buf); + xmlFree(buf); + } else { + fprintf(output, "<IssuerName>unknown</IssuerName>\n"); + } + + buf = xmlSecGnuTLSX509CertGetIssuerSerial(cert); + if(buf != NULL) { + fprintf(output, "<SerialNumber>%s</SerialNumber>\n", buf); + xmlFree(buf); + } else { + fprintf(output, "<SerialNumber>unknown</SerialNumber>\n"); + } +} + +/************************************************************************* + * + * x509 crls utils/helpers + * + ************************************************************************/ + +/* HACK: gnutls doesn't have crl duplicate function, so we simply + write crl out and then read it back */ +gnutls_x509_crl_t +xmlSecGnuTLSX509CrlDup(gnutls_x509_crl_t src) { + xmlChar * buf = NULL; + gnutls_x509_crl_t res = NULL; + + xmlSecAssert2(src != NULL, NULL); + + buf = xmlSecGnuTLSX509CrlBase64DerWrite(src, 0); + if(buf == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSX509CrlBase64DerWrite", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return (NULL); + } + + res = xmlSecGnuTLSX509CrlBase64DerRead(buf); + if(res == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSX509CrlBase64DerRead", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlFree(buf); + return (NULL); + } + + /* done */ + xmlFree(buf); + return (res); +} + +xmlChar * +xmlSecGnuTLSX509CrlGetIssuerDN(gnutls_x509_crl_t crl) { + char* buf = NULL; + size_t bufSize = 0; + int err; + + xmlSecAssert2(crl != NULL, NULL); + + /* get issuer size */ + err = gnutls_x509_crl_get_issuer_dn(crl, NULL, &bufSize); + if((err != GNUTLS_E_SHORT_MEMORY_BUFFER) || (bufSize <= 0)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_x509_crl_get_issuer_dn", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + return(NULL); + } + + /* allocate buffer */ + buf = (char *)xmlMalloc(bufSize + 1); + if(buf == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlMalloc", + XMLSEC_ERRORS_R_MALLOC_FAILED, + "size=%d", (int)bufSize); + return(NULL); + } + + /* finally write it out */ + err = gnutls_x509_crl_get_issuer_dn(crl, buf, &bufSize); + if(err != GNUTLS_E_SUCCESS) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_x509_crl_get_issuer_dn", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + xmlFree(buf); + return(NULL); + } + + /* done */ + return(BAD_CAST buf); +} + +gnutls_x509_crl_t +xmlSecGnuTLSX509CrlBase64DerRead(xmlChar* buf) { + int ret; + + xmlSecAssert2(buf != NULL, NULL); + + /* usual trick with base64 decoding "in-place" */ + ret = xmlSecBase64Decode(buf, (xmlSecByte*)buf, xmlStrlen(buf)); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBase64Decode", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(NULL); + } + + return(xmlSecGnuTLSX509CrlRead((const xmlSecByte*)buf, ret, xmlSecKeyDataFormatCertDer)); +} + +gnutls_x509_crl_t +xmlSecGnuTLSX509CrlRead(const xmlSecByte* buf, xmlSecSize size, xmlSecKeyDataFormat format) { + gnutls_x509_crl_t crl = NULL; + gnutls_x509_crt_fmt_t fmt; + gnutls_datum_t data; + int err; + + xmlSecAssert2(buf != NULL, NULL); + xmlSecAssert2(size > 0, NULL); + + /* figure out format */ + switch(format) { + case xmlSecKeyDataFormatPem: + case xmlSecKeyDataFormatCertPem: + fmt = GNUTLS_X509_FMT_PEM; + break; + case xmlSecKeyDataFormatDer: + case xmlSecKeyDataFormatCertDer: + fmt = GNUTLS_X509_FMT_DER; + break; + default: + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + NULL, + XMLSEC_ERRORS_R_INVALID_FORMAT, + "format=%d", format); + return(NULL); + } + + /* read crl */ + err = gnutls_x509_crl_init(&crl); + if(err != GNUTLS_E_SUCCESS) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_x509_crl_init", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + return(NULL); + } + + data.data = (unsigned char*)buf; + data.size = size; + err = gnutls_x509_crl_import(crl, &data, fmt); + if(err != GNUTLS_E_SUCCESS) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_x509_crl_import", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + gnutls_x509_crl_deinit(crl); + return(NULL); + } + + return(crl); +} + +xmlChar* +xmlSecGnuTLSX509CrlBase64DerWrite(gnutls_x509_crl_t crl, int base64LineWrap) { + xmlChar * res = NULL; + xmlSecByte* buf = NULL; + size_t bufSize = 0; + int err; + + xmlSecAssert2(crl != NULL, NULL); + + /* get size */ + err = gnutls_x509_crl_export(crl, GNUTLS_X509_FMT_DER, NULL, &bufSize); + if((err != GNUTLS_E_SHORT_MEMORY_BUFFER) || (bufSize <= 0)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_x509_crl_export(GNUTLS_X509_FMT_DER)", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + return(NULL); + } + + /* allocate buffer */ + buf = (xmlSecByte *)xmlMalloc(bufSize + 1); + if(buf == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlMalloc", + XMLSEC_ERRORS_R_MALLOC_FAILED, + "size=%d", (int)bufSize); + return(NULL); + } + + /* write it out */ + err = gnutls_x509_crl_export(crl, GNUTLS_X509_FMT_DER, buf, &bufSize); + if(err != GNUTLS_E_SUCCESS) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_x509_crl_export(GNUTLS_X509_FMT_DER)", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + xmlFree(buf); + return(NULL); + } + + /* convert to string */ + res = xmlSecBase64Encode(buf, bufSize, base64LineWrap); + if(res == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBase64Encode", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlFree(buf); + return(NULL); + } + + /* done */ + xmlFree(buf); + return(res); +} + +void +xmlSecGnuTLSX509CrlDebugDump(gnutls_x509_crl_t crl, FILE* output) { + xmlChar * buf; + + xmlSecAssert(crl != NULL); + xmlSecAssert(output != NULL); + + buf = xmlSecGnuTLSX509CrlGetIssuerDN(crl); + if(buf != NULL) { + fprintf(output, "==== Issuer Name: %s\n", buf); + xmlFree(buf); + } else { + fprintf(output, "==== Issuer Name: unknown\n"); + } +} + +void +xmlSecGnuTLSX509CrlDebugXmlDump(gnutls_x509_crl_t crl, FILE* output) { + xmlChar * buf; + + xmlSecAssert(crl != NULL); + xmlSecAssert(output != NULL); + + buf = xmlSecGnuTLSX509CrlGetIssuerDN(crl); + if(buf != NULL) { + fprintf(output, "<IssuerName>%s</IssuerName>\n", buf); + xmlFree(buf); + } else { + fprintf(output, "<IssuerName>unknown</IssuerName>\n"); + } +} + +/************************************************************************* + * + * Misc. utils/helpers + * + ************************************************************************/ +xmlChar* +xmlSecGnuTLSASN1IntegerWrite(const unsigned char * data, size_t len) { + xmlChar *res = NULL; + int resLen = 64; /* not more than 64 chars */ + unsigned long long int val = 0; + size_t ii = 0; + int shift = 0; + + xmlSecAssert2(data != NULL, NULL); + xmlSecAssert2(len <= 9, NULL); + + /* HACK : to be fixed after GnuTLS provides a way to read opaque ASN1 integer */ + for(ii = len; ii > 0; --ii, shift += 8) { + val |= ((unsigned long long)data[ii - 1]) << shift; + } + + res = (xmlChar*)xmlMalloc(resLen + 1); + if(res == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlMalloc", + XMLSEC_ERRORS_R_MALLOC_FAILED, + "size=%d", (int)resLen); + return (NULL); + } + + xmlSecStrPrintf(res, resLen, BAD_CAST "%llu", val); + return(res); +} + +/************************************************************************* + * + * pkcs12 utils/helpers + * + ************************************************************************/ +int +xmlSecGnuTLSPkcs12LoadMemory(const xmlSecByte* data, xmlSecSize dataSize, + const char *pwd, + gnutls_x509_privkey_t * priv_key, + gnutls_x509_crt_t * key_cert, + xmlSecPtrListPtr certsList) +{ + gnutls_pkcs12_t pkcs12 = NULL; + gnutls_pkcs12_bag_t bag = NULL; + gnutls_x509_crt_t cert = NULL; + gnutls_datum_t datum; + xmlSecSize certsSize; + int res = -1; + int idx; + int err; + int ret; + + xmlSecAssert2(data != NULL, -1); + xmlSecAssert2(dataSize > 0, -1); + xmlSecAssert2(priv_key != NULL, -1); + xmlSecAssert2((*priv_key) == NULL, -1); + xmlSecAssert2(key_cert!= NULL, -1); + xmlSecAssert2((*key_cert) == NULL, -1); + xmlSecAssert2(certsList != NULL, -1); + + /* read pkcs12 in internal structure */ + err = gnutls_pkcs12_init(&pkcs12); + if(err != GNUTLS_E_SUCCESS) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_pkcs12_init", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + goto done; + } + + datum.data = (unsigned char *)data; + datum.size = dataSize; + err = gnutls_pkcs12_import(pkcs12, &datum, GNUTLS_X509_FMT_DER, 0); + if(err != GNUTLS_E_SUCCESS) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_pkcs12_import", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + goto done; + } + + /* verify */ + err = gnutls_pkcs12_verify_mac(pkcs12, pwd); + if(err != GNUTLS_E_SUCCESS) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_pkcs12_verify_mac", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + goto done; + } + + /* scan the pkcs structure and find the first private key */ + for(idx = 0; ; ++idx) { + int bag_type; + int elements_in_bag; + int ii; + + err = gnutls_pkcs12_bag_init(&bag); + if(err != GNUTLS_E_SUCCESS) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_pkcs12_bag_init", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + goto done; + } + + err = gnutls_pkcs12_get_bag(pkcs12, idx, bag); + if(err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { + /* scanned the whole pkcs12, stop */ + break; + } else if(err != GNUTLS_E_SUCCESS) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_pkcs12_get_bag", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + goto done; + } + + /* check if we need to decrypt the bag */ + bag_type = gnutls_pkcs12_bag_get_type(bag, 0); + if(bag_type < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_pkcs12_bag_get_type", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(bag_type)); + goto done; + } + if(bag_type == GNUTLS_BAG_ENCRYPTED) { + err = gnutls_pkcs12_bag_decrypt(bag, pwd); + if(err != GNUTLS_E_SUCCESS) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_pkcs12_bag_decrypt", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + goto done; + } + } + + /* scan elements in bag */ + elements_in_bag = gnutls_pkcs12_bag_get_count(bag); + if(elements_in_bag < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_pkcs12_bag_get_count", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(bag_type)); + goto done; + } + for(ii = 0; ii < elements_in_bag; ++ii) { + bag_type = gnutls_pkcs12_bag_get_type(bag, ii); + if(bag_type < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_pkcs12_bag_get_type", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(bag_type)); + goto done; + } + + err = gnutls_pkcs12_bag_get_data(bag, ii, &datum); + if(err != GNUTLS_E_SUCCESS) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_pkcs12_bag_get_data", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + goto done; + } + + switch(bag_type) { + case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY: + case GNUTLS_BAG_PKCS8_KEY: + /* we want only the first private key */ + if((*priv_key) == NULL) { + err = gnutls_x509_privkey_init(priv_key); + if(err != GNUTLS_E_SUCCESS) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_x509_privkey_init", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + goto done; + } + + err = gnutls_x509_privkey_import_pkcs8((*priv_key), + &datum, GNUTLS_X509_FMT_DER, + pwd, + (bag_type == GNUTLS_BAG_PKCS8_KEY) ? GNUTLS_PKCS_PLAIN : 0); + if(err != GNUTLS_E_SUCCESS) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_x509_privkey_import_pkcs8", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + goto done; + } + } + break; + case GNUTLS_BAG_CERTIFICATE: + err = gnutls_x509_crt_init(&cert); + if(err != GNUTLS_E_SUCCESS) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_x509_crt_init", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + goto done; + } + + err = gnutls_x509_crt_import(cert, &datum, GNUTLS_X509_FMT_DER); + if(err != GNUTLS_E_SUCCESS) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_x509_crt_import", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + goto done; + } + + ret = xmlSecPtrListAdd(certsList, cert); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecPtrListAdd(certsList)", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + goto done; + } + cert = NULL; /* owned by certsList now */ + break; + default: + /* ignore unknown bag element */ + break; + } + } + + /* done with bag */ + gnutls_pkcs12_bag_deinit(bag); + bag = NULL; + } + + /* check we have private key */ + if((*priv_key) == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + NULL, + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "Private key was not found in pkcs12 object"); + goto done; + } + + /* we will search for key cert using the key id */ + certsSize = xmlSecPtrListGetSize(certsList); + if(certsSize > 0) { + size_t cert_id_size = 0; + size_t key_id_size = 0; + xmlSecByte cert_id[100]; + xmlSecByte key_id[100]; + xmlSecSize ii; + + key_id_size = sizeof(key_id); + err = gnutls_x509_privkey_get_key_id((*priv_key), 0, key_id, &key_id_size); + if(err != GNUTLS_E_SUCCESS) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_x509_privkey_get_key_id", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + goto done; + } + for(ii = 0; ii < certsSize; ++ii) { + gnutls_x509_crt_t tmp; + + tmp = xmlSecPtrListGetItem(certsList, ii); + if(tmp == NULL) { + continue; + } + + cert_id_size = sizeof(cert_id); + err = gnutls_x509_crt_get_key_id(tmp, 0, cert_id, &cert_id_size); + if(err != GNUTLS_E_SUCCESS) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_x509_crt_get_key_id", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + goto done; + } + + /* if key ids match, then this is THE key cert!!! */ + if((key_id_size == cert_id_size) && (memcmp(key_id, cert_id, key_id_size) == 0)) { + (*key_cert) = xmlSecGnuTLSX509CertDup(tmp); + if((*key_cert) == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSX509CertDup", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + goto done; + } + + break; + } + } + + /* check we have key cert */ + if((*key_cert) == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + NULL, + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "Certificate for the private key was not found in pkcs12 object"); + goto done; + } + } + + + /* success!!! */ + res = 0; + +done: + if(cert != NULL) { + gnutls_x509_crt_deinit(cert); + } + if(bag != NULL) { + gnutls_pkcs12_bag_deinit(bag); + } + if(pkcs12 != NULL) { + gnutls_pkcs12_deinit(pkcs12); + } + return(res); +} + +xmlSecKeyDataPtr +xmlSecGnuTLSCreateKeyDataAndAdoptPrivKey(gnutls_x509_privkey_t priv_key) { + xmlSecKeyDataPtr res = NULL; + int key_alg; + int ret; + + xmlSecAssert2(priv_key != NULL, NULL); + + /* create key value data */ + key_alg = gnutls_x509_privkey_get_pk_algorithm(priv_key); + if(key_alg < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_x509_privkey_get_pk_algorithm", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(key_alg)); + return (NULL); + } + switch(key_alg) { +#ifndef XMLSEC_NO_RSA + case GNUTLS_PK_RSA: + res = xmlSecKeyDataCreate(xmlSecGnuTLSKeyDataRsaId); + if(res == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeyDataCreate", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "xmlSecGnuTLSKeyDataRsaId"); + return(NULL); + } + + ret = xmlSecGnuTLSKeyDataRsaAdoptPrivateKey(res, priv_key); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSKeyDataRsaAdoptPrivateKey", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "xmlSecGnuTLSKeyDataRsaId"); + xmlSecKeyDataDestroy(res); + return(NULL); + } + break; +#endif /* XMLSEC_NO_RSA */ + +#ifndef XMLSEC_NO_DSA + case GNUTLS_PK_DSA: + res = xmlSecKeyDataCreate(xmlSecGnuTLSKeyDataDsaId); + if(res == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecKeyDataCreate", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "xmlSecGnuTLSKeyDataDsaId"); + return(NULL); + } + + ret = xmlSecGnuTLSKeyDataDsaAdoptPrivateKey(res, priv_key); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSKeyDataDsaAdoptPrivateKey", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "xmlSecGnuTLSKeyDataDsaId"); + xmlSecKeyDataDestroy(res); + return(NULL); + } + break; +#endif /* XMLSEC_NO_DSA */ + default: + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_x509_privkey_get_pk_algorithm", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + "Unsupported algorithm %d", (int)key_alg); + return(NULL); + } + + /* done */ + return(res); +} + +/************************************************************************* + * + * LDAP DN parser + * + ************************************************************************/ +void +xmlSecGnuTLSDnAttrsInitialize(xmlSecGnuTLSDnAttr * attrs, xmlSecSize attrsSize) { + xmlSecAssert(attrs != NULL); + xmlSecAssert(attrsSize > 0); + + memset(attrs, 0, attrsSize * sizeof(xmlSecGnuTLSDnAttr)); +} + +void +xmlSecGnuTLSDnAttrsDeinitialize(xmlSecGnuTLSDnAttr * attrs, xmlSecSize attrsSize) { + xmlSecSize ii; + + xmlSecAssert(attrs != NULL); + xmlSecAssert(attrsSize > 0); + + for(ii = 0; ii < attrsSize; ++ii) { + if(attrs[ii].key != NULL) { + xmlFree(attrs[ii].key); + } + if(attrs[ii].value != NULL) { + xmlFree(attrs[ii].value); + } + } + memset(attrs, 0, attrsSize * sizeof(xmlSecGnuTLSDnAttr)); +} + +const xmlSecGnuTLSDnAttr * +xmlSecGnuTLSDnAttrrsFind(const xmlSecGnuTLSDnAttr * attrs, + xmlSecSize attrsSize, + const xmlChar * key) +{ + xmlSecSize ii; + + xmlSecAssert2(attrs != NULL, NULL); + xmlSecAssert2(attrsSize > 0, NULL); + xmlSecAssert2(key != NULL, NULL); + + for(ii = 0; ii < attrsSize; ++ii) { + /* simple case */ + if(xmlStrcasecmp(key, attrs[ii].key) == 0) { + return(&(attrs[ii])); + } + + /* special case for emailAddress (as usual) */ + if((xmlStrcasecmp(key, BAD_CAST "emailAddress") == 0) && + (xmlStrcasecmp(attrs[ii].key, BAD_CAST "email") == 0)) + { + return(&(attrs[ii])); + } + if((xmlStrcasecmp(key, BAD_CAST "email") == 0) && + (xmlStrcasecmp(attrs[ii].key, BAD_CAST "emailAddress") == 0)) + { + return(&(attrs[ii])); + } + } + + /* not found :( */ + return(NULL); +} + +int +xmlSecGnuTLSDnAttrsEqual(const xmlSecGnuTLSDnAttr * ll, xmlSecSize llSize, + const xmlSecGnuTLSDnAttr * rr, xmlSecSize rrSize) +{ + xmlSecSize llNum = 0; + xmlSecSize rrNum = 0; + const xmlSecGnuTLSDnAttr * tmp; + xmlSecSize ii; + + xmlSecAssert2(ll != NULL, -1); + xmlSecAssert2(llSize > 0, -1); + xmlSecAssert2(rr != NULL, -1); + xmlSecAssert2(rrSize > 0, -1); + + /* compare number of non-nullattributes */ + for(ii = 0; ii < llSize; ++ii) { + if(ll[ii].key != NULL) { + ++llNum; + } + } + for(ii = 0; ii < rrSize; ++ii) { + if(rr[ii].key != NULL) { + ++rrNum; + } + } + if(llNum != rrNum) { + return(0); + } + + /* make sure that all ll attrs are equal to rr attrs */ + for(ii = 0; ii < llSize; ++ii) { + if(ll[ii].key == NULL) { + continue; + } + + tmp = xmlSecGnuTLSDnAttrrsFind(rr, rrSize, ll[ii].key); + if(tmp == NULL) { + return(0); /* attribute was not found */ + } + + if(!xmlStrEqual(ll[ii].value, tmp->value)) { + return(0); /* different values */ + } + } + + /* good!!! */ + return(1); +} + +/* +Distinguished name syntax + +The formal syntax for a Distinguished Name (DN) is based on RFC 2253. +The Backus Naur Form (BNF) syntax is defined as follows: + + <name> ::= <name-component> ( <spaced-separator> ) + | <name-component> <spaced-separator> <name> + + <spaced-separator> ::= <optional-space> + <separator> + <optional-space> + + <separator> ::= "," | ";" + + <optional-space> ::= ( <CR> ) *( " " ) + + <name-component> ::= <attribute> + | <attribute> <optional-space> "+" + <optional-space> <name-component> + + <attribute> ::= <string> + | <key> <optional-space> "=" <optional-space> <string> + + <key> ::= 1*( <keychar> ) | "OID." <oid> | "oid." <oid> + <keychar> ::= letters, numbers, and space + + <oid> ::= <digitstring> | <digitstring> "." <oid> + <digitstring> ::= 1*<digit> + <digit> ::= digits 0-9 + + <string> ::= *( <stringchar> | <pair> ) + | '"' *( <stringchar> | <special> | <pair> ) '"' + | "#" <hex> + + + <special> ::= "," | "=" | <CR> | "+" | "<" | ">" + | "#" | ";" + + <pair> ::= "\" ( <special> | "\" | '"') + <stringchar> ::= any character except <special> or "\" or '"' + + + <hex> ::= 2*<hexchar> + <hexchar> ::= 0-9, a-f, A-F + +A semicolon (;) character can be used to separate RDNs in a distinguished name, +although the comma (,) character is the typical notation. + +White-space characters (spaces) might be present on either side of the comma or +semicolon. The white-space characters are ignored, and the semicolon is replaced +with a comma. + +In addition, space (' ' ASCII 32) characters may be present either before or +after a '+' or '='. These space characters are ignored when parsing. +*/ +enum xmlSecGnuTLSDnParseState { + xmlSecGnuTLSDnParseState_BeforeNameComponent = 0, + xmlSecGnuTLSDnParseState_Key, + xmlSecGnuTLSDnParseState_BeforeString, + xmlSecGnuTLSDnParseState_String, + xmlSecGnuTLSDnParseState_QuotedString, + xmlSecGnuTLSDnParseState_AfterQuotedString +}; + +#define XMLSEC_GNUTLS_IS_SPACE(ch) \ + (((ch) == ' ') || ((ch) == '\n') || ((ch) == '\r')) + +int +xmlSecGnuTLSDnAttrsParse(const xmlChar * dn, + xmlSecGnuTLSDnAttr * attrs, xmlSecSize attrsSize) +{ + xmlChar * tmp = NULL; + xmlChar * p; + xmlChar ch; + enum xmlSecGnuTLSDnParseState state; + int slash; + xmlSecSize pos; + int res = -1; + + xmlSecAssert2(dn != NULL, -1); + xmlSecAssert2(attrs != NULL, -1); + xmlSecAssert2(attrsSize > 0, -1); + + /* allocate buffer, we don't need more than string */ + tmp = (xmlChar *)xmlMalloc(xmlStrlen(dn) + 1); + if(tmp == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlMalloc", + XMLSEC_ERRORS_R_MALLOC_FAILED, + "size=%d", (int)(xmlStrlen(dn) + 1)); + goto done; + } + + /* state machine */ + state = xmlSecGnuTLSDnParseState_BeforeNameComponent; + slash = 0; + pos = 0; + p = tmp; + for(ch = (*dn); ; ch = *(++dn)) { + switch(state) { + case xmlSecGnuTLSDnParseState_BeforeNameComponent: + if(!XMLSEC_GNUTLS_IS_SPACE(ch)) { + *(p++) = ch; /* we are sure we have enough buffer */ + state = xmlSecGnuTLSDnParseState_Key; + } else { + /* just skip space */ + } + break; + case xmlSecGnuTLSDnParseState_Key: + /* we don't support + 1) <attribute><optional-space>"+"<optional-space><name-component> + 2) <attribute> ::= <string> + */ + if(ch != '=') { + *(p++) = ch; /* we are sure we have enough buffer */ + } else { + *(p) = '\0'; + /* remove spaces back */ + while((p > tmp) && (XMLSEC_GNUTLS_IS_SPACE(*(p - 1)))) { + *(--p) = '\0'; + } + + /* insert into the attrs */ + if(pos >= attrsSize) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "Not enough space: size=%d", (int)attrsSize); + goto done; + } + attrs[pos].key = xmlStrdup(tmp); + if(attrs[pos].key == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlStrdup", + XMLSEC_ERRORS_R_MALLOC_FAILED, + "size=%d", (int)(xmlStrlen(tmp) + 1)); + goto done; + } + + state = xmlSecGnuTLSDnParseState_BeforeString; + p = tmp; + } + break; + case xmlSecGnuTLSDnParseState_BeforeString: + if(!XMLSEC_GNUTLS_IS_SPACE(ch)) { + if(ch != '\"') { + state = xmlSecGnuTLSDnParseState_String; + slash = 0; + --dn; /* small hack, so we can look at the same char + again with the correct state */ + } else { + state = xmlSecGnuTLSDnParseState_QuotedString; + slash = 0; + } + } else { + /* just skip space */ + } + break; + case xmlSecGnuTLSDnParseState_String: + if(slash == 1) { + *(p++) = ch; /* we are sure we have enough buffer */ + slash = 0; + } else if(ch == '\\') { + slash = 1; + } else if((ch == ',') || (ch == ';') || (ch == '\0')) { + *(p) = '\0'; + /* remove spaces back */ + while((p > tmp) && (XMLSEC_GNUTLS_IS_SPACE(*(p - 1)))) { + *(--p) = '\0'; + } + + attrs[pos].value = xmlStrdup(tmp); + if(attrs[pos].value == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlStrdup", + XMLSEC_ERRORS_R_MALLOC_FAILED, + "size=%d", (int)(xmlStrlen(tmp) + 1)); + goto done; + } + state = xmlSecGnuTLSDnParseState_BeforeNameComponent; + ++pos; + p = tmp; + } else { + *(p++) = ch; /* we are sure we have enough buffer */ + } + break; + case xmlSecGnuTLSDnParseState_QuotedString: + if(slash == 1) { + *(p++) = ch; /* we are sure we have enough buffer */ + slash = 0; + } else if(ch == '\\') { + slash = 1; + } else if(ch == '\"') { + *(p) = '\0'; + /* don't remove spaces for quoted string */ + + attrs[pos].value = xmlStrdup(tmp); + if(attrs[pos].value == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlStrdup", + XMLSEC_ERRORS_R_MALLOC_FAILED, + "size=%d", (int)(xmlStrlen(tmp) + 1)); + goto done; + } + state = xmlSecGnuTLSDnParseState_AfterQuotedString; + ++pos; + p = tmp; + } else { + *(p++) = ch; /* we are sure we have enough buffer */ + } + break; + case xmlSecGnuTLSDnParseState_AfterQuotedString: + if(!XMLSEC_GNUTLS_IS_SPACE(ch)) { + if((ch == ',') || (ch == ';') || (ch == '\0')) { + state = xmlSecGnuTLSDnParseState_BeforeNameComponent; + } else { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "Unexpected character %c (expected space or ',' or ';')", + ch); + goto done; + } + } else { + /* just skip space */ + } + break; + } + + if(ch == '\0') { + /* done */ + break; + } + } + + /* check end state */ + if(state != xmlSecGnuTLSDnParseState_BeforeNameComponent) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "Unexpected state %d at the end of parsing", + (int)state); + goto done; + } + + /* debug + { + xmlSecSize ii; + for(ii = 0; ii < attrsSize; ++ii) { + if(attrs[ii].key != NULL) { + printf("DEBUG: attrs - %s=>%s\n", attrs[ii].key, attrs[ii].value); + } + } + } + */ + + /* done */ + res = 0; + +done: + if(tmp != NULL) { + xmlFree(tmp); + } + return(res); +} + + +#endif /* XMLSEC_NO_X509 */ + + + diff --git a/src/gnutls/x509utils.h b/src/gnutls/x509utils.h new file mode 100644 index 00000000..b939b248 --- /dev/null +++ b/src/gnutls/x509utils.h @@ -0,0 +1,143 @@ +/* + * XML Security Library + * + * THIS IS A PRIVATE XMLSEC HEADER FILE + * DON'T USE IT IN YOUR APPLICATION + * + * This is free software; see Copyright file in the source + * distribution for preciese wording. + * + * Copyright (C) 2010 Aleksey Sanin <aleksey@aleksey.com> + */ +#ifndef __XMLSEC_GNUTLS_X509UTILS_H__ +#define __XMLSEC_GNUTLS_X509UTILS_H__ + +#ifndef XMLSEC_PRIVATE +#error "gnutls/x509utils.h file contains private xmlsec definitions and should not be used outside xmlsec or xmlsec-<crypto> libraries" +#endif /* XMLSEC_PRIVATE */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef XMLSEC_NO_X509 + +/************************************************************************** + * + * X509 certs list + * + *****************************************************************************/ +#define xmlSecGnuTLSX509CrtListId \ + xmlSecGnuTLSX509CrtListGetKlass() +xmlSecPtrListId xmlSecGnuTLSX509CrtListGetKlass (void); + +/************************************************************************** + * + * X509 crls list + * + *****************************************************************************/ +#define xmlSecGnuTLSX509CrlListId \ + xmlSecGnuTLSX509CrlListGetKlass() +xmlSecPtrListId xmlSecGnuTLSX509CrlListGetKlass (void); + +/************************************************************************* + * + * x509 certs utils/helpers + * + ************************************************************************/ +gnutls_x509_crt_t xmlSecGnuTLSX509CertDup (gnutls_x509_crt_t src); +xmlChar * xmlSecGnuTLSX509CertGetSubjectDN (gnutls_x509_crt_t cert); +xmlChar * xmlSecGnuTLSX509CertGetIssuerDN (gnutls_x509_crt_t cert); +xmlChar * xmlSecGnuTLSX509CertGetIssuerSerial (gnutls_x509_crt_t cert); +xmlChar * xmlSecGnuTLSX509CertGetSKI (gnutls_x509_crt_t cert); +gnutls_x509_crt_t xmlSecGnuTLSX509CertRead (const xmlSecByte* buf, + xmlSecSize size, + xmlSecKeyDataFormat format); +gnutls_x509_crt_t xmlSecGnuTLSX509CertBase64DerRead (xmlChar* buf); +xmlChar* xmlSecGnuTLSX509CertBase64DerWrite (gnutls_x509_crt_t cert, + int base64LineWrap); +void xmlSecGnuTLSX509CertDebugDump (gnutls_x509_crt_t cert, + FILE* output); +void xmlSecGnuTLSX509CertDebugXmlDump (gnutls_x509_crt_t cert, + FILE* output); + +/************************************************************************* + * + * x509 crls utils/helpers + * + ************************************************************************/ +gnutls_x509_crl_t xmlSecGnuTLSX509CrlDup (gnutls_x509_crl_t src); +xmlChar * xmlSecGnuTLSX509CrLGetIssuerDN (gnutls_x509_crl_t crl); +gnutls_x509_crl_t xmlSecGnuTLSX509CrlRead (const xmlSecByte* buf, + xmlSecSize size, + xmlSecKeyDataFormat format); +gnutls_x509_crl_t xmlSecGnuTLSX509CrlBase64DerRead (xmlChar* buf); +xmlChar* xmlSecGnuTLSX509CrlBase64DerWrite (gnutls_x509_crl_t crl, + int base64LineWrap); +void xmlSecGnuTLSX509CrlDebugDump (gnutls_x509_crl_t crl, + FILE* output); +void xmlSecGnuTLSX509CrlDebugXmlDump (gnutls_x509_crl_t crl, + FILE* output); + +/************************************************************************* + * + * Misc. utils/helpers + * + ************************************************************************/ +xmlChar* xmlSecGnuTLSASN1IntegerWrite (const unsigned char * data, + size_t len); + + + +/************************************************************************* + * + * pkcs12 utils/helpers + * + ************************************************************************/ +int xmlSecGnuTLSPkcs12LoadMemory (const xmlSecByte* data, + xmlSecSize dataSize, + const char *pwd, + gnutls_x509_privkey_t * priv_key, + gnutls_x509_crt_t * key_cert, + xmlSecPtrListPtr certsList); + +/************************************************************************* + * + * keydata utils/helpers + * + ************************************************************************/ +xmlSecKeyDataPtr xmlSecGnuTLSCreateKeyDataAndAdoptPrivKey(gnutls_x509_privkey_t priv_key); + + +/************************************************************************* + * + * LDAP DN parser + * + ************************************************************************/ +typedef struct _xmlSecGnuTLSDnAttr { + xmlChar * key; + xmlChar * value; +} xmlSecGnuTLSDnAttr; + +void xmlSecGnuTLSDnAttrsInitialize (xmlSecGnuTLSDnAttr * attrs, + xmlSecSize attrsSize); +void xmlSecGnuTLSDnAttrsDeinitialize (xmlSecGnuTLSDnAttr * attrs, + xmlSecSize attrsSize); +const xmlSecGnuTLSDnAttr * xmlSecGnuTLSDnAttrrsFind (const xmlSecGnuTLSDnAttr * attrs, + xmlSecSize attrsSize, + const xmlChar * key); +int xmlSecGnuTLSDnAttrsEqual (const xmlSecGnuTLSDnAttr * ll, + xmlSecSize llSize, + const xmlSecGnuTLSDnAttr * rr, + xmlSecSize rrSize); +int xmlSecGnuTLSDnAttrsParse (const xmlChar * dn, + xmlSecGnuTLSDnAttr * attrs, + xmlSecSize attrsSize); +#endif /* XMLSEC_NO_X509 */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* ! __XMLSEC_GNUTLS_X509UTILS_H__ */ diff --git a/src/gnutls/x509vfy.c b/src/gnutls/x509vfy.c new file mode 100644 index 00000000..fd15c5ac --- /dev/null +++ b/src/gnutls/x509vfy.c @@ -0,0 +1,802 @@ +/** + * XMLSec library + * + * X509 support + * + * + * This is free software; see Copyright file in the source + * distribution for preciese wording. + * + * Copyright (C) 2010 Aleksey Sanin <aleksey@aleksey.com> + */ +#include "globals.h" + +#ifndef XMLSEC_NO_X509 + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <errno.h> + +#include <libxml/tree.h> + +#include <xmlsec/xmlsec.h> +#include <xmlsec/xmltree.h> +#include <xmlsec/keys.h> +#include <xmlsec/keyinfo.h> +#include <xmlsec/keysmngr.h> +#include <xmlsec/base64.h> +#include <xmlsec/errors.h> + +#include <xmlsec/gnutls/crypto.h> +#include <xmlsec/gnutls/x509.h> + +#include "x509utils.h" + +/************************************************************************** + * + * Internal GnuTLS X509 store CTX + * + *************************************************************************/ +typedef struct _xmlSecGnuTLSX509StoreCtx xmlSecGnuTLSX509StoreCtx, + *xmlSecGnuTLSX509StoreCtxPtr; +struct _xmlSecGnuTLSX509StoreCtx { + xmlSecPtrList certsTrusted; + xmlSecPtrList certsUntrusted; +}; + +/**************************************************************************** + * + * xmlSecGnuTLSKeyDataStoreX509Id: + * + * xmlSecGnuTLSX509StoreCtx is located after xmlSecTransform + * + ***************************************************************************/ +#define xmlSecGnuTLSX509StoreGetCtx(store) \ + ((xmlSecGnuTLSX509StoreCtxPtr)(((xmlSecByte*)(store)) + \ + sizeof(xmlSecKeyDataStoreKlass))) +#define xmlSecGnuTLSX509StoreSize \ + (sizeof(xmlSecKeyDataStoreKlass) + sizeof(xmlSecGnuTLSX509StoreCtx)) + +static int xmlSecGnuTLSX509StoreInitialize (xmlSecKeyDataStorePtr store); +static void xmlSecGnuTLSX509StoreFinalize (xmlSecKeyDataStorePtr store); + +static xmlSecKeyDataStoreKlass xmlSecGnuTLSX509StoreKlass = { + sizeof(xmlSecKeyDataStoreKlass), + xmlSecGnuTLSX509StoreSize, + + /* data */ + xmlSecNameX509Store, /* const xmlChar* name; */ + + /* constructors/destructor */ + xmlSecGnuTLSX509StoreInitialize, /* xmlSecKeyDataStoreInitializeMethod initialize; */ + xmlSecGnuTLSX509StoreFinalize, /* xmlSecKeyDataStoreFinalizeMethod finalize; */ + + /* reserved for the future */ + NULL, /* void* reserved0; */ + NULL, /* void* reserved1; */ +}; + +static gnutls_x509_crt_t xmlSecGnuTLSX509FindCert (xmlSecPtrListPtr certs, + const xmlChar *subjectName, + const xmlChar *issuerName, + const xmlChar *issuerSerial, + const xmlChar *ski); +static gnutls_x509_crt_t xmlSecGnuTLSX509FindSignedCert (xmlSecPtrListPtr certs, + gnutls_x509_crt_t cert); +static gnutls_x509_crt_t xmlSecGnuTLSX509FindSignerCert (xmlSecPtrListPtr certs, + gnutls_x509_crt_t cert); + + +/** + * xmlSecGnuTLSX509StoreGetKlass: + * + * The GnuTLS X509 certificates key data store klass. + * + * Returns: pointer to GnuTLS X509 certificates key data store klass. + */ +xmlSecKeyDataStoreId +xmlSecGnuTLSX509StoreGetKlass(void) { + return(&xmlSecGnuTLSX509StoreKlass); +} + +/** + * xmlSecGnuTLSX509StoreFindCert: + * @store: the pointer to X509 key data store klass. + * @subjectName: the desired certificate name. + * @issuerName: the desired certificate issuer name. + * @issuerSerial: the desired certificate issuer serial number. + * @ski: the desired certificate SKI. + * @keyInfoCtx: the pointer to <dsig:KeyInfo/> element processing context. + * + * Searches @store for a certificate that matches given criteria. + * + * Returns: pointer to found certificate or NULL if certificate is not found + * or an error occurs. + */ +gnutls_x509_crt_t +xmlSecGnuTLSX509StoreFindCert(xmlSecKeyDataStorePtr store, + const xmlChar *subjectName, + const xmlChar *issuerName, + const xmlChar *issuerSerial, + const xmlChar *ski, + const xmlSecKeyInfoCtx* keyInfoCtx) { + xmlSecGnuTLSX509StoreCtxPtr ctx; + gnutls_x509_crt_t res = NULL; + + xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecGnuTLSX509StoreId), NULL); + xmlSecAssert2(keyInfoCtx != NULL, NULL); + + ctx = xmlSecGnuTLSX509StoreGetCtx(store); + xmlSecAssert2(ctx != NULL, NULL); + + if(res == NULL) { + res = xmlSecGnuTLSX509FindCert(&(ctx->certsTrusted), subjectName, issuerName, issuerSerial, ski); + } + if(res == NULL) { + res = xmlSecGnuTLSX509FindCert(&(ctx->certsUntrusted), subjectName, issuerName, issuerSerial, ski); + } + return(res); +} + +static int +xmlSecGnuTLSX509CheckTime(const gnutls_x509_crt_t * cert_list, + xmlSecSize cert_list_length, + time_t ts) +{ + time_t notValidBefore, notValidAfter; + xmlSecSize ii; + + xmlSecAssert2(cert_list != NULL, -1); + + for(ii = 0; ii < cert_list_length; ++ii) { + const gnutls_x509_crt_t cert = cert_list[ii]; + if(cert == NULL) { + continue; + } + + /* get expiration times */ + notValidBefore = gnutls_x509_crt_get_activation_time(cert); + if(notValidBefore == (time_t)-1) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_x509_crt_get_activation_time", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + notValidAfter = gnutls_x509_crt_get_expiration_time(cert); + if(notValidAfter == (time_t)-1) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_x509_crt_get_expiration_time", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + /* check */ + if(ts < notValidBefore) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + NULL, + XMLSEC_ERRORS_R_CERT_NOT_YET_VALID, + XMLSEC_ERRORS_NO_MESSAGE); + return(0); + } + if(ts > notValidAfter) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + NULL, + XMLSEC_ERRORS_R_CERT_HAS_EXPIRED, + XMLSEC_ERRORS_NO_MESSAGE); + return(0); + } + } + + /* GOOD! */ + return(1); +} + +/** + * xmlSecGnuTLSX509StoreVerify: + * @store: the pointer to X509 key data store klass. + * @certs: the untrusted certificates. + * @crls: the crls. + * @keyInfoCtx: the pointer to <dsig:KeyInfo/> element processing context. + * + * Verifies @certs list. + * + * Returns: pointer to the first verified certificate from @certs. + */ +gnutls_x509_crt_t +xmlSecGnuTLSX509StoreVerify(xmlSecKeyDataStorePtr store, + xmlSecPtrListPtr certs, + xmlSecPtrListPtr crls, + const xmlSecKeyInfoCtx* keyInfoCtx) { + xmlSecGnuTLSX509StoreCtxPtr ctx; + gnutls_x509_crt_t res = NULL; + xmlSecSize certs_size = 0; + gnutls_x509_crt_t * cert_list = NULL; + xmlSecSize cert_list_length; + gnutls_x509_crl_t * crl_list = NULL; + xmlSecSize crl_list_length; + gnutls_x509_crt_t * ca_list = NULL; + xmlSecSize ca_list_length; + time_t verification_time; + unsigned int flags = 0; + xmlSecSize ii; + int ret; + int err; + + xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecGnuTLSX509StoreId), NULL); + xmlSecAssert2(certs != NULL, NULL); + xmlSecAssert2(crls != NULL, NULL); + xmlSecAssert2(keyInfoCtx != NULL, NULL); + + certs_size = xmlSecPtrListGetSize(certs); + if(certs_size <= 0) { + /* nothing to do */ + return(NULL); + } + + ctx = xmlSecGnuTLSX509StoreGetCtx(store); + xmlSecAssert2(ctx != NULL, NULL); + + /* Prepare */ + cert_list_length = certs_size + xmlSecPtrListGetSize(&(ctx->certsUntrusted)); + if(cert_list_length > 0) { + cert_list = (gnutls_x509_crt_t *)xmlMalloc(sizeof(gnutls_x509_crt_t) * cert_list_length); + if(cert_list == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), + "xmlMalloc", + XMLSEC_ERRORS_R_MALLOC_FAILED, + "size=%d", (int)(sizeof(gnutls_x509_crt_t) * cert_list_length)); + goto done; + } + } + crl_list_length = xmlSecPtrListGetSize(crls); + if(crl_list_length > 0) { + crl_list = (gnutls_x509_crl_t *)xmlMalloc(sizeof(gnutls_x509_crl_t) * crl_list_length); + if(crl_list == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), + "xmlMalloc", + XMLSEC_ERRORS_R_MALLOC_FAILED, + "size=%d", (int)(sizeof(gnutls_x509_crl_t) * crl_list_length)); + goto done; + } + for(ii = 0; ii < crl_list_length; ++ii) { + crl_list[ii] = xmlSecPtrListGetItem(crls, ii); + if(crl_list[ii] == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), + "xmlSecPtrListGetItem(crls)", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + goto done; + } + } + } + + ca_list_length = xmlSecPtrListGetSize(&(ctx->certsTrusted)); + if(ca_list_length > 0) { + ca_list = (gnutls_x509_crt_t *)xmlMalloc(sizeof(gnutls_x509_crt_t) * ca_list_length); + if(ca_list == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), + "xmlMalloc", + XMLSEC_ERRORS_R_MALLOC_FAILED, + "size=%d", (int)(sizeof(gnutls_x509_crt_t) * ca_list_length)); + goto done; + } + for(ii = 0; ii < ca_list_length; ++ii) { + ca_list[ii] = xmlSecPtrListGetItem(&(ctx->certsTrusted), ii); + if(ca_list[ii] == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), + "xmlSecPtrListGetItem(certsTrusted)", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + goto done; + } + } + } + + /* gnutls doesn't allow to specify "verification" timestamp so + we have to do it ourselves */ + verification_time = (keyInfoCtx->certsVerificationTime > 0) ? + keyInfoCtx->certsVerificationTime : + time(0); + flags |= GNUTLS_VERIFY_DISABLE_TIME_CHECKS; + + if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_X509DATA_SKIP_STRICT_CHECKS) != 0) { + flags |= GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2; + flags |= GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5; + } + + /* We are going to build all possible cert chains and try to verify them */ + for(ii = 0; (ii < certs_size) && (res == NULL); ++ii) { + gnutls_x509_crt_t cert, cert2; + xmlSecSize cert_list_cur_length = 0; + unsigned int verify = 0; + + cert = xmlSecPtrListGetItem(certs, ii); + if(cert == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), + "xmlSecPtrListGetItem(certs)", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + goto done; + } + + /* check if we are the "leaf" node in the certs chain */ + if(xmlSecGnuTLSX509FindSignedCert(certs, cert) != NULL) { + continue; + } + + /* build the chain */ + for(cert2 = cert, cert_list_cur_length = 0; + (cert2 != NULL) && (cert_list_cur_length < cert_list_length); + ++cert_list_cur_length) + { + gnutls_x509_crt_t tmp; + + /* store */ + cert_list[cert_list_cur_length] = cert2; + + /* find next */ + tmp = xmlSecGnuTLSX509FindSignerCert(certs, cert2); + if(tmp == NULL) { + tmp = xmlSecGnuTLSX509FindSignerCert(&(ctx->certsUntrusted), cert2); + } + cert2 = tmp; + } + + /* try to verify */ + err = gnutls_x509_crt_list_verify( + cert_list, (int)cert_list_cur_length, /* certs chain */ + ca_list, (int)ca_list_length, /* trusted cas */ + crl_list, (int)crl_list_length, /* crls */ + flags, /* flags */ + &verify); + if(err != GNUTLS_E_SUCCESS) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_x509_crt_list_verify", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_GNUTLS_REPORT_ERROR(err)); + /* don't stop, continue! */ + continue; + } else if(verify != 0){ + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "gnutls_x509_crt_list_verify", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + "Verification failed: verify=%u", verify); + /* don't stop, continue! */ + continue; + } + + /* gnutls doesn't allow to specify "verification" timestamp so + we have to do it ourselves */ + ret = xmlSecGnuTLSX509CheckTime(cert_list, cert_list_cur_length, verification_time); + if(ret != 1) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + "Time verification failed"); + /* don't stop, continue! */ + continue; + } + + /* DONE! */ + res = cert; + } + +done: + /* cleanup */ + if(ca_list != NULL) { + xmlFree(ca_list); + } + if(crl_list != NULL) { + xmlFree(crl_list); + } + if(cert_list != NULL) { + xmlFree(cert_list); + } + + return(res); +} + +/** + * xmlSecGnuTLSX509StoreAdoptCert: + * @store: the pointer to X509 key data store klass. + * @cert: the pointer to GnuTLS X509 certificate. + * @type: the certificate type (trusted/untrusted). + * + * Adds trusted (root) or untrusted certificate to the store. + * + * Returns: 0 on success or a negative value if an error occurs. + */ +int +xmlSecGnuTLSX509StoreAdoptCert(xmlSecKeyDataStorePtr store, gnutls_x509_crt_t cert, xmlSecKeyDataType type) { + xmlSecGnuTLSX509StoreCtxPtr ctx; + int ret; + + xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecGnuTLSX509StoreId), -1); + xmlSecAssert2(cert != NULL, -1); + + ctx = xmlSecGnuTLSX509StoreGetCtx(store); + xmlSecAssert2(ctx != NULL, -1); + + if((type & xmlSecKeyDataTypeTrusted) != 0) { + ret = xmlSecPtrListAdd(&(ctx->certsTrusted), cert); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), + "xmlSecPtrListAdd(trusted)", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + } else { + ret = xmlSecPtrListAdd(&(ctx->certsUntrusted), cert); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), + "xmlSecPtrListAdd(untrusted)", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + } + + /* done */ + return(0); +} + +static int +xmlSecGnuTLSX509StoreInitialize(xmlSecKeyDataStorePtr store) { + xmlSecGnuTLSX509StoreCtxPtr ctx; + int ret; + + xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecGnuTLSX509StoreId), -1); + + ctx = xmlSecGnuTLSX509StoreGetCtx(store); + xmlSecAssert2(ctx != NULL, -1); + + memset(ctx, 0, sizeof(xmlSecGnuTLSX509StoreCtx)); + + ret = xmlSecPtrListInitialize(&(ctx->certsTrusted), xmlSecGnuTLSX509CrtListId); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), + "xmlSecPtrListInitialize(trusted)", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + ret = xmlSecPtrListInitialize(&(ctx->certsUntrusted), xmlSecGnuTLSX509CrtListId); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), + "xmlSecPtrListInitialize(untrusted)", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + return(0); +} + +static void +xmlSecGnuTLSX509StoreFinalize(xmlSecKeyDataStorePtr store) { + xmlSecGnuTLSX509StoreCtxPtr ctx; + xmlSecAssert(xmlSecKeyDataStoreCheckId(store, xmlSecGnuTLSX509StoreId)); + + ctx = xmlSecGnuTLSX509StoreGetCtx(store); + xmlSecAssert(ctx != NULL); + + xmlSecPtrListFinalize(&(ctx->certsTrusted)); + xmlSecPtrListFinalize(&(ctx->certsUntrusted)); + + memset(ctx, 0, sizeof(xmlSecGnuTLSX509StoreCtx)); +} + + +/***************************************************************************** + * + * Low-level x509 functions + * + *****************************************************************************/ +#define XMLSEC_GNUTLS_DN_ATTRS_SIZE 1024 +static int +xmlSecGnuTLSX509DnsEqual(const xmlChar * ll, const xmlChar * rr) { + xmlSecGnuTLSDnAttr ll_attrs[XMLSEC_GNUTLS_DN_ATTRS_SIZE]; + xmlSecGnuTLSDnAttr rr_attrs[XMLSEC_GNUTLS_DN_ATTRS_SIZE]; + int ret; + int res = -1; + + xmlSecAssert2(ll != NULL, -1); + xmlSecAssert2(rr != NULL, -1); + + /* fast version first */ + if(xmlStrEqual(ll, rr)) { + return(1); + } + + /* prepare */ + xmlSecGnuTLSDnAttrsInitialize(ll_attrs, XMLSEC_GNUTLS_DN_ATTRS_SIZE); + xmlSecGnuTLSDnAttrsInitialize(rr_attrs, XMLSEC_GNUTLS_DN_ATTRS_SIZE); + + /* parse */ + ret = xmlSecGnuTLSDnAttrsParse(ll, ll_attrs, XMLSEC_GNUTLS_DN_ATTRS_SIZE); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSDnAttrsParse(ll)", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + goto done; + } + + ret = xmlSecGnuTLSDnAttrsParse(rr, rr_attrs, XMLSEC_GNUTLS_DN_ATTRS_SIZE); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSDnAttrsParse(rr)", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + goto done; + } + + /* compare */ + ret = xmlSecGnuTLSDnAttrsEqual(ll_attrs, XMLSEC_GNUTLS_DN_ATTRS_SIZE, + rr_attrs, XMLSEC_GNUTLS_DN_ATTRS_SIZE); + if(ret == 1) { + res = 1; + } else if(ret == 0) { + res = 0; + } else { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSDnAttrsEqual", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + goto done; + } + +done: + xmlSecGnuTLSDnAttrsDeinitialize(ll_attrs, XMLSEC_GNUTLS_DN_ATTRS_SIZE); + xmlSecGnuTLSDnAttrsDeinitialize(rr_attrs, XMLSEC_GNUTLS_DN_ATTRS_SIZE); + return(res); +} + +static gnutls_x509_crt_t +xmlSecGnuTLSX509FindCert(xmlSecPtrListPtr certs, + const xmlChar *subjectName, + const xmlChar *issuerName, + const xmlChar *issuerSerial, + const xmlChar *ski) { + xmlSecSize ii, sz; + + xmlSecAssert2(certs != NULL, NULL); + + /* todo: this is not the fastest way to search certs */ + sz = xmlSecPtrListGetSize(certs); + for(ii = 0; (ii < sz); ++ii) { + gnutls_x509_crt_t cert = xmlSecPtrListGetItem(certs, ii); + if(cert == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecPtrListGetItem", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "pos=%i", (int)ii); + return(NULL); + } + + if(subjectName != NULL) { + xmlChar * tmp; + + tmp = xmlSecGnuTLSX509CertGetSubjectDN(cert); + if(tmp == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSX509CertGetSubjectDN", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "pos=%i", (int)ii); + return(NULL); + } + + if(xmlSecGnuTLSX509DnsEqual(subjectName, tmp) == 1) { + xmlFree(tmp); + return(cert); + } + xmlFree(tmp); + } else if((issuerName != NULL) && (issuerSerial != NULL)) { + xmlChar * tmp1; + xmlChar * tmp2; + + tmp1 = xmlSecGnuTLSX509CertGetIssuerDN(cert); + if(tmp1 == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSX509CertGetIssuerDN", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "pos=%i", (int)ii); + return(NULL); + } + + tmp2 = xmlSecGnuTLSX509CertGetIssuerSerial(cert); + if(tmp2 == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSX509CertGetIssuerSerial", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "pos=%i", (int)ii); + xmlFree(tmp1); + return(NULL); + } + + if((xmlSecGnuTLSX509DnsEqual(issuerName, tmp1) == 1) && xmlStrEqual(issuerSerial, tmp2)) { + xmlFree(tmp1); + xmlFree(tmp2); + return(cert); + } + xmlFree(tmp1); + xmlFree(tmp2); + } else if(ski != NULL) { + xmlChar * tmp; + + tmp = xmlSecGnuTLSX509CertGetSKI(cert); + if(tmp == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSX509CertGetSKI", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "pos=%i", (int)ii); + return(NULL); + } + + if(xmlStrEqual(ski, tmp)) { + xmlFree(tmp); + return(cert); + } + xmlFree(tmp); + } + } + + return(NULL); +} + +/* signed cert has issuer dn equal to our's subject dn */ +static gnutls_x509_crt_t +xmlSecGnuTLSX509FindSignedCert(xmlSecPtrListPtr certs, gnutls_x509_crt_t cert) { + gnutls_x509_crt_t res = NULL; + xmlChar * subject = NULL; + xmlSecSize ii, sz; + + xmlSecAssert2(certs != NULL, NULL); + xmlSecAssert2(cert != NULL, NULL); + + /* get subject */ + subject = xmlSecGnuTLSX509CertGetSubjectDN(cert); + if(subject == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSX509CertGetSubjectDN", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + goto done; + } + + /* todo: this is not the fastest way to search certs */ + sz = xmlSecPtrListGetSize(certs); + for(ii = 0; (ii < sz) && (res == NULL); ++ii) { + gnutls_x509_crt_t tmp; + xmlChar * issuer; + + tmp = xmlSecPtrListGetItem(certs, ii); + if(tmp == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecPtrListGetItem", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "pos=%i", (int)ii); + goto done; + } + + issuer = xmlSecGnuTLSX509CertGetIssuerDN(tmp); + if(issuer == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSX509CertGetIssuerDN", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "pos=%i", (int)ii); + goto done; + } + + /* are we done? */ + if(xmlSecGnuTLSX509DnsEqual(subject, issuer) == 1) { + res = tmp; + } + xmlFree(issuer); + } + +done: + if(subject != NULL) { + xmlFree(subject); + } + return(res); +} + +/* signer cert has subject dn equal to our's issuer dn */ +static gnutls_x509_crt_t +xmlSecGnuTLSX509FindSignerCert(xmlSecPtrListPtr certs, gnutls_x509_crt_t cert) { + gnutls_x509_crt_t res = NULL; + xmlChar * issuer = NULL; + xmlSecSize ii, sz; + + xmlSecAssert2(certs != NULL, NULL); + xmlSecAssert2(cert != NULL, NULL); + + /* get issuer */ + issuer = xmlSecGnuTLSX509CertGetIssuerDN(cert); + if(issuer == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSX509CertGetIssuerDN", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + goto done; + } + + /* todo: this is not the fastest way to search certs */ + sz = xmlSecPtrListGetSize(certs); + for(ii = 0; (ii < sz) && (res == NULL); ++ii) { + gnutls_x509_crt_t tmp; + xmlChar * subject; + + tmp = xmlSecPtrListGetItem(certs, ii); + if(tmp == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecPtrListGetItem", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "pos=%i", (int)ii); + goto done; + } + + subject = xmlSecGnuTLSX509CertGetSubjectDN(tmp); + if(subject == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecGnuTLSX509CertGetSubjectDN", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "pos=%i", (int)ii); + goto done; + } + + /* are we done? */ + if((xmlSecGnuTLSX509DnsEqual(issuer, subject) == 1)) { + res = tmp; + } + xmlFree(subject); + } + +done: + if(issuer != NULL) { + xmlFree(issuer); + } + return(res); +} + +#endif /* XMLSEC_NO_X509 */ + + |