summaryrefslogtreecommitdiffstats
path: root/lib/minitasn1
diff options
context:
space:
mode:
Diffstat (limited to 'lib/minitasn1')
-rw-r--r--lib/minitasn1/Makefile.am34
-rw-r--r--lib/minitasn1/Makefile.in2418
-rw-r--r--lib/minitasn1/coding.c1413
-rw-r--r--lib/minitasn1/decoding.c2478
-rw-r--r--lib/minitasn1/element.c1111
-rw-r--r--lib/minitasn1/element.h40
-rw-r--r--lib/minitasn1/errors.c100
-rw-r--r--lib/minitasn1/gstr.c74
-rw-r--r--lib/minitasn1/gstr.h47
-rw-r--r--lib/minitasn1/int.h221
-rw-r--r--lib/minitasn1/libtasn1.h637
-rw-r--r--lib/minitasn1/parser_aux.c1173
-rw-r--r--lib/minitasn1/parser_aux.h172
-rw-r--r--lib/minitasn1/structure.c1220
-rw-r--r--lib/minitasn1/structure.h45
-rw-r--r--lib/minitasn1/version.c51
16 files changed, 11234 insertions, 0 deletions
diff --git a/lib/minitasn1/Makefile.am b/lib/minitasn1/Makefile.am
new file mode 100644
index 0000000..9b67697
--- /dev/null
+++ b/lib/minitasn1/Makefile.am
@@ -0,0 +1,34 @@
+## Process this file with automake to produce Makefile.in
+# Copyright (C) 2002-2010, 2012 Free Software Foundation, Inc.
+#
+# Author: Nikos Mavrogiannopoulos
+#
+# This file is part of GnuTLS.
+#
+# The GnuTLS is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public License
+# as published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# The GnuTLS is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with GnuTLS; if not, write to the Free
+# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA
+
+include $(top_srcdir)/lib/common.mk
+
+AM_CPPFLAGS = -DASN1_BUILDING \
+ -I$(srcdir)/../../gl \
+ -I$(builddir)/../../gl \
+ -I$(srcdir)/..
+
+noinst_LTLIBRARIES = libminitasn1.la
+
+libminitasn1_la_SOURCES = libtasn1.h gstr.h int.h parser_aux.h \
+ structure.h element.h decoding.c gstr.c errors.c parser_aux.c \
+ structure.c element.c coding.c version.c
diff --git a/lib/minitasn1/Makefile.in b/lib/minitasn1/Makefile.in
new file mode 100644
index 0000000..499bcfd
--- /dev/null
+++ b/lib/minitasn1/Makefile.in
@@ -0,0 +1,2418 @@
+# Makefile.in generated by automake 1.16.5 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Copyright (C) 2002-2010, 2012 Free Software Foundation, Inc.
+#
+# Author: Nikos Mavrogiannopoulos
+#
+# This file is part of GnuTLS.
+#
+# The GnuTLS is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public License
+# as published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# The GnuTLS is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with GnuTLS; if not, write to the Free
+# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = lib/minitasn1
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/lib/unistring/m4/gnulib-comp.m4 \
+ $(top_srcdir)/lib/unistring/m4/inline.m4 \
+ $(top_srcdir)/lib/unistring/m4/libunistring-base.m4 \
+ $(top_srcdir)/src/gl/m4/atoll.m4 \
+ $(top_srcdir)/src/gl/m4/bison.m4 \
+ $(top_srcdir)/src/gl/m4/calloc.m4 \
+ $(top_srcdir)/src/gl/m4/clock_time.m4 \
+ $(top_srcdir)/src/gl/m4/codeset.m4 \
+ $(top_srcdir)/src/gl/m4/ctype_h.m4 \
+ $(top_srcdir)/src/gl/m4/environ.m4 \
+ $(top_srcdir)/src/gl/m4/error.m4 \
+ $(top_srcdir)/src/gl/m4/fdopen.m4 \
+ $(top_srcdir)/src/gl/m4/flexmember.m4 \
+ $(top_srcdir)/src/gl/m4/fpending.m4 \
+ $(top_srcdir)/src/gl/m4/fpieee.m4 \
+ $(top_srcdir)/src/gl/m4/fseek.m4 \
+ $(top_srcdir)/src/gl/m4/ftruncate.m4 \
+ $(top_srcdir)/src/gl/m4/getaddrinfo.m4 \
+ $(top_srcdir)/src/gl/m4/getcwd.m4 \
+ $(top_srcdir)/src/gl/m4/getpagesize.m4 \
+ $(top_srcdir)/src/gl/m4/getpass.m4 \
+ $(top_srcdir)/src/gl/m4/getprogname.m4 \
+ $(top_srcdir)/src/gl/m4/gettime.m4 \
+ $(top_srcdir)/src/gl/m4/gnulib-comp.m4 \
+ $(top_srcdir)/src/gl/m4/hostent.m4 \
+ $(top_srcdir)/src/gl/m4/intl-thread-locale.m4 \
+ $(top_srcdir)/src/gl/m4/inttostr.m4 \
+ $(top_srcdir)/src/gl/m4/ioctl.m4 \
+ $(top_srcdir)/src/gl/m4/isblank.m4 \
+ $(top_srcdir)/src/gl/m4/langinfo_h.m4 \
+ $(top_srcdir)/src/gl/m4/lcmessage.m4 \
+ $(top_srcdir)/src/gl/m4/locale-fr.m4 \
+ $(top_srcdir)/src/gl/m4/locale-ja.m4 \
+ $(top_srcdir)/src/gl/m4/locale-tr.m4 \
+ $(top_srcdir)/src/gl/m4/locale-zh.m4 \
+ $(top_srcdir)/src/gl/m4/locale_h.m4 \
+ $(top_srcdir)/src/gl/m4/localename.m4 \
+ $(top_srcdir)/src/gl/m4/lstat.m4 \
+ $(top_srcdir)/src/gl/m4/mktime.m4 \
+ $(top_srcdir)/src/gl/m4/nanosleep.m4 \
+ $(top_srcdir)/src/gl/m4/nstrftime.m4 \
+ $(top_srcdir)/src/gl/m4/parse-datetime.m4 \
+ $(top_srcdir)/src/gl/m4/perror.m4 \
+ $(top_srcdir)/src/gl/m4/pipe.m4 \
+ $(top_srcdir)/src/gl/m4/pthread-thread.m4 \
+ $(top_srcdir)/src/gl/m4/pthread_h.m4 \
+ $(top_srcdir)/src/gl/m4/pthread_sigmask.m4 \
+ $(top_srcdir)/src/gl/m4/putenv.m4 \
+ $(top_srcdir)/src/gl/m4/raise.m4 \
+ $(top_srcdir)/src/gl/m4/reallocarray.m4 \
+ $(top_srcdir)/src/gl/m4/sched_h.m4 \
+ $(top_srcdir)/src/gl/m4/sched_yield.m4 \
+ $(top_srcdir)/src/gl/m4/select.m4 \
+ $(top_srcdir)/src/gl/m4/semaphore.m4 \
+ $(top_srcdir)/src/gl/m4/servent.m4 \
+ $(top_srcdir)/src/gl/m4/setenv.m4 \
+ $(top_srcdir)/src/gl/m4/setlocale.m4 \
+ $(top_srcdir)/src/gl/m4/setlocale_null.m4 \
+ $(top_srcdir)/src/gl/m4/sigaction.m4 \
+ $(top_srcdir)/src/gl/m4/signal_h.m4 \
+ $(top_srcdir)/src/gl/m4/signalblocking.m4 \
+ $(top_srcdir)/src/gl/m4/sleep.m4 \
+ $(top_srcdir)/src/gl/m4/sockets.m4 \
+ $(top_srcdir)/src/gl/m4/strerror.m4 \
+ $(top_srcdir)/src/gl/m4/strerror_r.m4 \
+ $(top_srcdir)/src/gl/m4/strtoll.m4 \
+ $(top_srcdir)/src/gl/m4/symlink.m4 \
+ $(top_srcdir)/src/gl/m4/sys_ioctl_h.m4 \
+ $(top_srcdir)/src/gl/m4/sys_select_h.m4 \
+ $(top_srcdir)/src/gl/m4/thread.m4 \
+ $(top_srcdir)/src/gl/m4/time_rz.m4 \
+ $(top_srcdir)/src/gl/m4/timegm.m4 \
+ $(top_srcdir)/src/gl/m4/timespec.m4 \
+ $(top_srcdir)/src/gl/m4/tm_gmtoff.m4 \
+ $(top_srcdir)/src/gl/m4/tzset.m4 \
+ $(top_srcdir)/src/gl/m4/usleep.m4 \
+ $(top_srcdir)/src/gl/m4/visibility.m4 \
+ $(top_srcdir)/src/gl/m4/xalloc.m4 \
+ $(top_srcdir)/src/gl/m4/yield.m4 $(top_srcdir)/m4/00gnulib.m4 \
+ $(top_srcdir)/m4/__inline.m4 \
+ $(top_srcdir)/m4/absolute-header.m4 $(top_srcdir)/m4/alloca.m4 \
+ $(top_srcdir)/m4/arpa_inet_h.m4 \
+ $(top_srcdir)/m4/ax_ac_append_to_file.m4 \
+ $(top_srcdir)/m4/ax_ac_print_to_file.m4 \
+ $(top_srcdir)/m4/ax_add_am_macro_static.m4 \
+ $(top_srcdir)/m4/ax_am_macros_static.m4 \
+ $(top_srcdir)/m4/ax_check_gnu_make.m4 \
+ $(top_srcdir)/m4/ax_code_coverage.m4 \
+ $(top_srcdir)/m4/ax_file_escapes.m4 \
+ $(top_srcdir)/m4/builtin-expect.m4 \
+ $(top_srcdir)/m4/byteswap.m4 $(top_srcdir)/m4/close.m4 \
+ $(top_srcdir)/m4/double-slash-root.m4 $(top_srcdir)/m4/dup2.m4 \
+ $(top_srcdir)/m4/eealloc.m4 $(top_srcdir)/m4/errno_h.m4 \
+ $(top_srcdir)/m4/explicit_bzero.m4 \
+ $(top_srcdir)/m4/exponentd.m4 $(top_srcdir)/m4/extensions.m4 \
+ $(top_srcdir)/m4/extern-inline.m4 $(top_srcdir)/m4/fcntl-o.m4 \
+ $(top_srcdir)/m4/fcntl.m4 $(top_srcdir)/m4/fcntl_h.m4 \
+ $(top_srcdir)/m4/float_h.m4 $(top_srcdir)/m4/fopen.m4 \
+ $(top_srcdir)/m4/free.m4 $(top_srcdir)/m4/fseeko.m4 \
+ $(top_srcdir)/m4/fstat.m4 $(top_srcdir)/m4/ftell.m4 \
+ $(top_srcdir)/m4/ftello.m4 $(top_srcdir)/m4/func.m4 \
+ $(top_srcdir)/m4/getdelim.m4 $(top_srcdir)/m4/getdtablesize.m4 \
+ $(top_srcdir)/m4/getline.m4 $(top_srcdir)/m4/gettext.m4 \
+ $(top_srcdir)/m4/gettimeofday.m4 \
+ $(top_srcdir)/m4/gnulib-common.m4 \
+ $(top_srcdir)/m4/gnulib-comp.m4 $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/guile.m4 $(top_srcdir)/m4/hooks.m4 \
+ $(top_srcdir)/m4/host-cpu-c-abi.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/include_next.m4 $(top_srcdir)/m4/inet_ntop.m4 \
+ $(top_srcdir)/m4/inet_pton.m4 $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/intmax_t.m4 $(top_srcdir)/m4/inttypes.m4 \
+ $(top_srcdir)/m4/inttypes_h.m4 $(top_srcdir)/m4/largefile.m4 \
+ $(top_srcdir)/m4/ld-output-def.m4 \
+ $(top_srcdir)/m4/ld-version-script.m4 $(top_srcdir)/m4/ldd.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/limits-h.m4 $(top_srcdir)/m4/lock.m4 \
+ $(top_srcdir)/m4/lseek.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/malloc.m4 \
+ $(top_srcdir)/m4/malloca.m4 $(top_srcdir)/m4/manywarnings.m4 \
+ $(top_srcdir)/m4/memchr.m4 $(top_srcdir)/m4/memmem.m4 \
+ $(top_srcdir)/m4/minmax.m4 $(top_srcdir)/m4/mmap-anon.m4 \
+ $(top_srcdir)/m4/mode_t.m4 $(top_srcdir)/m4/msvc-inval.m4 \
+ $(top_srcdir)/m4/msvc-nothrow.m4 $(top_srcdir)/m4/multiarch.m4 \
+ $(top_srcdir)/m4/netdb_h.m4 $(top_srcdir)/m4/netinet_in_h.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/off_t.m4 \
+ $(top_srcdir)/m4/open-cloexec.m4 \
+ $(top_srcdir)/m4/open-slash.m4 $(top_srcdir)/m4/open.m4 \
+ $(top_srcdir)/m4/pathmax.m4 $(top_srcdir)/m4/pkg.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/printf.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/pthread_rwlock_rdlock.m4 \
+ $(top_srcdir)/m4/read-file.m4 $(top_srcdir)/m4/realloc.m4 \
+ $(top_srcdir)/m4/secure_getenv.m4 $(top_srcdir)/m4/size_max.m4 \
+ $(top_srcdir)/m4/snprintf.m4 $(top_srcdir)/m4/socketlib.m4 \
+ $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sockpfaf.m4 \
+ $(top_srcdir)/m4/ssize_t.m4 $(top_srcdir)/m4/stat-time.m4 \
+ $(top_srcdir)/m4/stat.m4 $(top_srcdir)/m4/stdalign.m4 \
+ $(top_srcdir)/m4/stdbool.m4 $(top_srcdir)/m4/stddef_h.m4 \
+ $(top_srcdir)/m4/stdint.m4 $(top_srcdir)/m4/stdint_h.m4 \
+ $(top_srcdir)/m4/stdio_h.m4 $(top_srcdir)/m4/stdlib_h.m4 \
+ $(top_srcdir)/m4/stpcpy.m4 $(top_srcdir)/m4/strcase.m4 \
+ $(top_srcdir)/m4/strdup.m4 $(top_srcdir)/m4/string_h.m4 \
+ $(top_srcdir)/m4/strings_h.m4 $(top_srcdir)/m4/strndup.m4 \
+ $(top_srcdir)/m4/strnlen.m4 $(top_srcdir)/m4/strtok_r.m4 \
+ $(top_srcdir)/m4/strverscmp.m4 \
+ $(top_srcdir)/m4/sys_socket_h.m4 \
+ $(top_srcdir)/m4/sys_stat_h.m4 $(top_srcdir)/m4/sys_time_h.m4 \
+ $(top_srcdir)/m4/sys_types_h.m4 $(top_srcdir)/m4/sys_uio_h.m4 \
+ $(top_srcdir)/m4/threadlib.m4 $(top_srcdir)/m4/time_h.m4 \
+ $(top_srcdir)/m4/time_r.m4 $(top_srcdir)/m4/ungetc.m4 \
+ $(top_srcdir)/m4/unistd_h.m4 \
+ $(top_srcdir)/m4/valgrind-tests.m4 \
+ $(top_srcdir)/m4/vasnprintf.m4 $(top_srcdir)/m4/vasprintf.m4 \
+ $(top_srcdir)/m4/vsnprintf.m4 $(top_srcdir)/m4/warn-on-use.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/m4/wchar_h.m4 \
+ $(top_srcdir)/m4/wchar_t.m4 $(top_srcdir)/m4/wint_t.m4 \
+ $(top_srcdir)/m4/xsize.m4 $(top_srcdir)/m4/zzgnulib.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libminitasn1_la_LIBADD =
+am_libminitasn1_la_OBJECTS = decoding.lo gstr.lo errors.lo \
+ parser_aux.lo structure.lo element.lo coding.lo version.lo
+libminitasn1_la_OBJECTS = $(am_libminitasn1_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/coding.Plo ./$(DEPDIR)/decoding.Plo \
+ ./$(DEPDIR)/element.Plo ./$(DEPDIR)/errors.Plo \
+ ./$(DEPDIR)/gstr.Plo ./$(DEPDIR)/parser_aux.Plo \
+ ./$(DEPDIR)/structure.Plo ./$(DEPDIR)/version.Plo
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(libminitasn1_la_SOURCES)
+DIST_SOURCES = $(libminitasn1_la_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+am__DIST_COMMON = $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp $(top_srcdir)/lib/common.mk
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+AARCH64_CCASFLAGS = @AARCH64_CCASFLAGS@
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+ALLOCA_H = @ALLOCA_H@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AM_VALGRINDFLAGS = @AM_VALGRINDFLAGS@
+APPLE_UNIVERSAL_BUILD = @APPLE_UNIVERSAL_BUILD@
+AR = @AR@
+ARFLAGS = @ARFLAGS@
+ASN1PARSER = @ASN1PARSER@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BITSIZEOF_PTRDIFF_T = @BITSIZEOF_PTRDIFF_T@
+BITSIZEOF_SIG_ATOMIC_T = @BITSIZEOF_SIG_ATOMIC_T@
+BITSIZEOF_SIZE_T = @BITSIZEOF_SIZE_T@
+BITSIZEOF_WCHAR_T = @BITSIZEOF_WCHAR_T@
+BITSIZEOF_WINT_T = @BITSIZEOF_WINT_T@
+BYTESWAP_H = @BYTESWAP_H@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CFLAG_VISIBILITY = @CFLAG_VISIBILITY@
+CMOCKA_CFLAGS = @CMOCKA_CFLAGS@
+CMOCKA_LIBS = @CMOCKA_LIBS@
+CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@
+CODE_COVERAGE_CPPFLAGS = @CODE_COVERAGE_CPPFLAGS@
+CODE_COVERAGE_CXXFLAGS = @CODE_COVERAGE_CXXFLAGS@
+CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@
+CODE_COVERAGE_LIBS = @CODE_COVERAGE_LIBS@
+CONFIG_INCLUDE = @CONFIG_INCLUDE@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYWRAP_PATCHLEVEL = @CRYWRAP_PATCHLEVEL@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CXX_LT_AGE = @CXX_LT_AGE@
+CXX_LT_CURRENT = @CXX_LT_CURRENT@
+CXX_LT_REVISION = @CXX_LT_REVISION@
+CYGPATH_W = @CYGPATH_W@
+DEFAULT_VALGRINDFLAGS = @DEFAULT_VALGRINDFLAGS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DLL_SSL_VERSION = @DLL_SSL_VERSION@
+DLL_VERSION = @DLL_VERSION@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EMULTIHOP_HIDDEN = @EMULTIHOP_HIDDEN@
+EMULTIHOP_VALUE = @EMULTIHOP_VALUE@
+ENABLE_PADLOCK = @ENABLE_PADLOCK@
+ENOLINK_HIDDEN = @ENOLINK_HIDDEN@
+ENOLINK_VALUE = @ENOLINK_VALUE@
+EOVERFLOW_HIDDEN = @EOVERFLOW_HIDDEN@
+EOVERFLOW_VALUE = @EOVERFLOW_VALUE@
+ERRNO_H = @ERRNO_H@
+ETAGS = @ETAGS@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FILECMD = @FILECMD@
+FIPS140_LIBS = @FIPS140_LIBS@
+FLOAT_H = @FLOAT_H@
+GCOV = @GCOV@
+GENHTML = @GENHTML@
+GETADDRINFO_LIB = @GETADDRINFO_LIB@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GL_GGL_GNULIB_ACCEPT = @GL_GGL_GNULIB_ACCEPT@
+GL_GGL_GNULIB_ACCEPT4 = @GL_GGL_GNULIB_ACCEPT4@
+GL_GGL_GNULIB_ACCESS = @GL_GGL_GNULIB_ACCESS@
+GL_GGL_GNULIB_ALIGNED_ALLOC = @GL_GGL_GNULIB_ALIGNED_ALLOC@
+GL_GGL_GNULIB_ATOLL = @GL_GGL_GNULIB_ATOLL@
+GL_GGL_GNULIB_BIND = @GL_GGL_GNULIB_BIND@
+GL_GGL_GNULIB_BTOWC = @GL_GGL_GNULIB_BTOWC@
+GL_GGL_GNULIB_CALLOC_POSIX = @GL_GGL_GNULIB_CALLOC_POSIX@
+GL_GGL_GNULIB_CANONICALIZE_FILE_NAME = @GL_GGL_GNULIB_CANONICALIZE_FILE_NAME@
+GL_GGL_GNULIB_CHDIR = @GL_GGL_GNULIB_CHDIR@
+GL_GGL_GNULIB_CHOWN = @GL_GGL_GNULIB_CHOWN@
+GL_GGL_GNULIB_CLOSE = @GL_GGL_GNULIB_CLOSE@
+GL_GGL_GNULIB_CONNECT = @GL_GGL_GNULIB_CONNECT@
+GL_GGL_GNULIB_COPY_FILE_RANGE = @GL_GGL_GNULIB_COPY_FILE_RANGE@
+GL_GGL_GNULIB_CREAT = @GL_GGL_GNULIB_CREAT@
+GL_GGL_GNULIB_CTIME = @GL_GGL_GNULIB_CTIME@
+GL_GGL_GNULIB_DPRINTF = @GL_GGL_GNULIB_DPRINTF@
+GL_GGL_GNULIB_DUP = @GL_GGL_GNULIB_DUP@
+GL_GGL_GNULIB_DUP2 = @GL_GGL_GNULIB_DUP2@
+GL_GGL_GNULIB_DUP3 = @GL_GGL_GNULIB_DUP3@
+GL_GGL_GNULIB_DUPLOCALE = @GL_GGL_GNULIB_DUPLOCALE@
+GL_GGL_GNULIB_ENVIRON = @GL_GGL_GNULIB_ENVIRON@
+GL_GGL_GNULIB_EUIDACCESS = @GL_GGL_GNULIB_EUIDACCESS@
+GL_GGL_GNULIB_EXECL = @GL_GGL_GNULIB_EXECL@
+GL_GGL_GNULIB_EXECLE = @GL_GGL_GNULIB_EXECLE@
+GL_GGL_GNULIB_EXECLP = @GL_GGL_GNULIB_EXECLP@
+GL_GGL_GNULIB_EXECV = @GL_GGL_GNULIB_EXECV@
+GL_GGL_GNULIB_EXECVE = @GL_GGL_GNULIB_EXECVE@
+GL_GGL_GNULIB_EXECVP = @GL_GGL_GNULIB_EXECVP@
+GL_GGL_GNULIB_EXECVPE = @GL_GGL_GNULIB_EXECVPE@
+GL_GGL_GNULIB_EXPLICIT_BZERO = @GL_GGL_GNULIB_EXPLICIT_BZERO@
+GL_GGL_GNULIB_FACCESSAT = @GL_GGL_GNULIB_FACCESSAT@
+GL_GGL_GNULIB_FCHDIR = @GL_GGL_GNULIB_FCHDIR@
+GL_GGL_GNULIB_FCHMODAT = @GL_GGL_GNULIB_FCHMODAT@
+GL_GGL_GNULIB_FCHOWNAT = @GL_GGL_GNULIB_FCHOWNAT@
+GL_GGL_GNULIB_FCLOSE = @GL_GGL_GNULIB_FCLOSE@
+GL_GGL_GNULIB_FCNTL = @GL_GGL_GNULIB_FCNTL@
+GL_GGL_GNULIB_FDATASYNC = @GL_GGL_GNULIB_FDATASYNC@
+GL_GGL_GNULIB_FDOPEN = @GL_GGL_GNULIB_FDOPEN@
+GL_GGL_GNULIB_FFLUSH = @GL_GGL_GNULIB_FFLUSH@
+GL_GGL_GNULIB_FFS = @GL_GGL_GNULIB_FFS@
+GL_GGL_GNULIB_FFSL = @GL_GGL_GNULIB_FFSL@
+GL_GGL_GNULIB_FFSLL = @GL_GGL_GNULIB_FFSLL@
+GL_GGL_GNULIB_FGETC = @GL_GGL_GNULIB_FGETC@
+GL_GGL_GNULIB_FGETS = @GL_GGL_GNULIB_FGETS@
+GL_GGL_GNULIB_FOPEN = @GL_GGL_GNULIB_FOPEN@
+GL_GGL_GNULIB_FPRINTF = @GL_GGL_GNULIB_FPRINTF@
+GL_GGL_GNULIB_FPRINTF_POSIX = @GL_GGL_GNULIB_FPRINTF_POSIX@
+GL_GGL_GNULIB_FPURGE = @GL_GGL_GNULIB_FPURGE@
+GL_GGL_GNULIB_FPUTC = @GL_GGL_GNULIB_FPUTC@
+GL_GGL_GNULIB_FPUTS = @GL_GGL_GNULIB_FPUTS@
+GL_GGL_GNULIB_FREAD = @GL_GGL_GNULIB_FREAD@
+GL_GGL_GNULIB_FREE_POSIX = @GL_GGL_GNULIB_FREE_POSIX@
+GL_GGL_GNULIB_FREOPEN = @GL_GGL_GNULIB_FREOPEN@
+GL_GGL_GNULIB_FSCANF = @GL_GGL_GNULIB_FSCANF@
+GL_GGL_GNULIB_FSEEK = @GL_GGL_GNULIB_FSEEK@
+GL_GGL_GNULIB_FSEEKO = @GL_GGL_GNULIB_FSEEKO@
+GL_GGL_GNULIB_FSTAT = @GL_GGL_GNULIB_FSTAT@
+GL_GGL_GNULIB_FSTATAT = @GL_GGL_GNULIB_FSTATAT@
+GL_GGL_GNULIB_FSYNC = @GL_GGL_GNULIB_FSYNC@
+GL_GGL_GNULIB_FTELL = @GL_GGL_GNULIB_FTELL@
+GL_GGL_GNULIB_FTELLO = @GL_GGL_GNULIB_FTELLO@
+GL_GGL_GNULIB_FTRUNCATE = @GL_GGL_GNULIB_FTRUNCATE@
+GL_GGL_GNULIB_FUTIMENS = @GL_GGL_GNULIB_FUTIMENS@
+GL_GGL_GNULIB_FWRITE = @GL_GGL_GNULIB_FWRITE@
+GL_GGL_GNULIB_GETADDRINFO = @GL_GGL_GNULIB_GETADDRINFO@
+GL_GGL_GNULIB_GETC = @GL_GGL_GNULIB_GETC@
+GL_GGL_GNULIB_GETCHAR = @GL_GGL_GNULIB_GETCHAR@
+GL_GGL_GNULIB_GETCWD = @GL_GGL_GNULIB_GETCWD@
+GL_GGL_GNULIB_GETDELIM = @GL_GGL_GNULIB_GETDELIM@
+GL_GGL_GNULIB_GETDOMAINNAME = @GL_GGL_GNULIB_GETDOMAINNAME@
+GL_GGL_GNULIB_GETDTABLESIZE = @GL_GGL_GNULIB_GETDTABLESIZE@
+GL_GGL_GNULIB_GETENTROPY = @GL_GGL_GNULIB_GETENTROPY@
+GL_GGL_GNULIB_GETGROUPS = @GL_GGL_GNULIB_GETGROUPS@
+GL_GGL_GNULIB_GETHOSTNAME = @GL_GGL_GNULIB_GETHOSTNAME@
+GL_GGL_GNULIB_GETLINE = @GL_GGL_GNULIB_GETLINE@
+GL_GGL_GNULIB_GETLOADAVG = @GL_GGL_GNULIB_GETLOADAVG@
+GL_GGL_GNULIB_GETLOGIN = @GL_GGL_GNULIB_GETLOGIN@
+GL_GGL_GNULIB_GETLOGIN_R = @GL_GGL_GNULIB_GETLOGIN_R@
+GL_GGL_GNULIB_GETOPT_POSIX = @GL_GGL_GNULIB_GETOPT_POSIX@
+GL_GGL_GNULIB_GETPAGESIZE = @GL_GGL_GNULIB_GETPAGESIZE@
+GL_GGL_GNULIB_GETPASS = @GL_GGL_GNULIB_GETPASS@
+GL_GGL_GNULIB_GETPEERNAME = @GL_GGL_GNULIB_GETPEERNAME@
+GL_GGL_GNULIB_GETSOCKNAME = @GL_GGL_GNULIB_GETSOCKNAME@
+GL_GGL_GNULIB_GETSOCKOPT = @GL_GGL_GNULIB_GETSOCKOPT@
+GL_GGL_GNULIB_GETSUBOPT = @GL_GGL_GNULIB_GETSUBOPT@
+GL_GGL_GNULIB_GETTIMEOFDAY = @GL_GGL_GNULIB_GETTIMEOFDAY@
+GL_GGL_GNULIB_GETUMASK = @GL_GGL_GNULIB_GETUMASK@
+GL_GGL_GNULIB_GETUSERSHELL = @GL_GGL_GNULIB_GETUSERSHELL@
+GL_GGL_GNULIB_GRANTPT = @GL_GGL_GNULIB_GRANTPT@
+GL_GGL_GNULIB_GROUP_MEMBER = @GL_GGL_GNULIB_GROUP_MEMBER@
+GL_GGL_GNULIB_IMAXABS = @GL_GGL_GNULIB_IMAXABS@
+GL_GGL_GNULIB_IMAXDIV = @GL_GGL_GNULIB_IMAXDIV@
+GL_GGL_GNULIB_INET_NTOP = @GL_GGL_GNULIB_INET_NTOP@
+GL_GGL_GNULIB_INET_PTON = @GL_GGL_GNULIB_INET_PTON@
+GL_GGL_GNULIB_IOCTL = @GL_GGL_GNULIB_IOCTL@
+GL_GGL_GNULIB_ISATTY = @GL_GGL_GNULIB_ISATTY@
+GL_GGL_GNULIB_ISBLANK = @GL_GGL_GNULIB_ISBLANK@
+GL_GGL_GNULIB_LCHMOD = @GL_GGL_GNULIB_LCHMOD@
+GL_GGL_GNULIB_LCHOWN = @GL_GGL_GNULIB_LCHOWN@
+GL_GGL_GNULIB_LINK = @GL_GGL_GNULIB_LINK@
+GL_GGL_GNULIB_LINKAT = @GL_GGL_GNULIB_LINKAT@
+GL_GGL_GNULIB_LISTEN = @GL_GGL_GNULIB_LISTEN@
+GL_GGL_GNULIB_LOCALECONV = @GL_GGL_GNULIB_LOCALECONV@
+GL_GGL_GNULIB_LOCALENAME = @GL_GGL_GNULIB_LOCALENAME@
+GL_GGL_GNULIB_LOCALTIME = @GL_GGL_GNULIB_LOCALTIME@
+GL_GGL_GNULIB_LSEEK = @GL_GGL_GNULIB_LSEEK@
+GL_GGL_GNULIB_LSTAT = @GL_GGL_GNULIB_LSTAT@
+GL_GGL_GNULIB_MALLOC_POSIX = @GL_GGL_GNULIB_MALLOC_POSIX@
+GL_GGL_GNULIB_MBRLEN = @GL_GGL_GNULIB_MBRLEN@
+GL_GGL_GNULIB_MBRTOWC = @GL_GGL_GNULIB_MBRTOWC@
+GL_GGL_GNULIB_MBSCASECMP = @GL_GGL_GNULIB_MBSCASECMP@
+GL_GGL_GNULIB_MBSCASESTR = @GL_GGL_GNULIB_MBSCASESTR@
+GL_GGL_GNULIB_MBSCHR = @GL_GGL_GNULIB_MBSCHR@
+GL_GGL_GNULIB_MBSCSPN = @GL_GGL_GNULIB_MBSCSPN@
+GL_GGL_GNULIB_MBSINIT = @GL_GGL_GNULIB_MBSINIT@
+GL_GGL_GNULIB_MBSLEN = @GL_GGL_GNULIB_MBSLEN@
+GL_GGL_GNULIB_MBSNCASECMP = @GL_GGL_GNULIB_MBSNCASECMP@
+GL_GGL_GNULIB_MBSNLEN = @GL_GGL_GNULIB_MBSNLEN@
+GL_GGL_GNULIB_MBSNRTOWCS = @GL_GGL_GNULIB_MBSNRTOWCS@
+GL_GGL_GNULIB_MBSPBRK = @GL_GGL_GNULIB_MBSPBRK@
+GL_GGL_GNULIB_MBSPCASECMP = @GL_GGL_GNULIB_MBSPCASECMP@
+GL_GGL_GNULIB_MBSRCHR = @GL_GGL_GNULIB_MBSRCHR@
+GL_GGL_GNULIB_MBSRTOWCS = @GL_GGL_GNULIB_MBSRTOWCS@
+GL_GGL_GNULIB_MBSSEP = @GL_GGL_GNULIB_MBSSEP@
+GL_GGL_GNULIB_MBSSPN = @GL_GGL_GNULIB_MBSSPN@
+GL_GGL_GNULIB_MBSSTR = @GL_GGL_GNULIB_MBSSTR@
+GL_GGL_GNULIB_MBSTOK_R = @GL_GGL_GNULIB_MBSTOK_R@
+GL_GGL_GNULIB_MBTOWC = @GL_GGL_GNULIB_MBTOWC@
+GL_GGL_GNULIB_MDA_ACCESS = @GL_GGL_GNULIB_MDA_ACCESS@
+GL_GGL_GNULIB_MDA_CHDIR = @GL_GGL_GNULIB_MDA_CHDIR@
+GL_GGL_GNULIB_MDA_CHMOD = @GL_GGL_GNULIB_MDA_CHMOD@
+GL_GGL_GNULIB_MDA_CLOSE = @GL_GGL_GNULIB_MDA_CLOSE@
+GL_GGL_GNULIB_MDA_CREAT = @GL_GGL_GNULIB_MDA_CREAT@
+GL_GGL_GNULIB_MDA_DUP = @GL_GGL_GNULIB_MDA_DUP@
+GL_GGL_GNULIB_MDA_DUP2 = @GL_GGL_GNULIB_MDA_DUP2@
+GL_GGL_GNULIB_MDA_ECVT = @GL_GGL_GNULIB_MDA_ECVT@
+GL_GGL_GNULIB_MDA_EXECL = @GL_GGL_GNULIB_MDA_EXECL@
+GL_GGL_GNULIB_MDA_EXECLE = @GL_GGL_GNULIB_MDA_EXECLE@
+GL_GGL_GNULIB_MDA_EXECLP = @GL_GGL_GNULIB_MDA_EXECLP@
+GL_GGL_GNULIB_MDA_EXECV = @GL_GGL_GNULIB_MDA_EXECV@
+GL_GGL_GNULIB_MDA_EXECVE = @GL_GGL_GNULIB_MDA_EXECVE@
+GL_GGL_GNULIB_MDA_EXECVP = @GL_GGL_GNULIB_MDA_EXECVP@
+GL_GGL_GNULIB_MDA_EXECVPE = @GL_GGL_GNULIB_MDA_EXECVPE@
+GL_GGL_GNULIB_MDA_FCLOSEALL = @GL_GGL_GNULIB_MDA_FCLOSEALL@
+GL_GGL_GNULIB_MDA_FCVT = @GL_GGL_GNULIB_MDA_FCVT@
+GL_GGL_GNULIB_MDA_FDOPEN = @GL_GGL_GNULIB_MDA_FDOPEN@
+GL_GGL_GNULIB_MDA_FILENO = @GL_GGL_GNULIB_MDA_FILENO@
+GL_GGL_GNULIB_MDA_GCVT = @GL_GGL_GNULIB_MDA_GCVT@
+GL_GGL_GNULIB_MDA_GETCWD = @GL_GGL_GNULIB_MDA_GETCWD@
+GL_GGL_GNULIB_MDA_GETPID = @GL_GGL_GNULIB_MDA_GETPID@
+GL_GGL_GNULIB_MDA_GETW = @GL_GGL_GNULIB_MDA_GETW@
+GL_GGL_GNULIB_MDA_ISATTY = @GL_GGL_GNULIB_MDA_ISATTY@
+GL_GGL_GNULIB_MDA_LSEEK = @GL_GGL_GNULIB_MDA_LSEEK@
+GL_GGL_GNULIB_MDA_MEMCCPY = @GL_GGL_GNULIB_MDA_MEMCCPY@
+GL_GGL_GNULIB_MDA_MKDIR = @GL_GGL_GNULIB_MDA_MKDIR@
+GL_GGL_GNULIB_MDA_MKTEMP = @GL_GGL_GNULIB_MDA_MKTEMP@
+GL_GGL_GNULIB_MDA_OPEN = @GL_GGL_GNULIB_MDA_OPEN@
+GL_GGL_GNULIB_MDA_PUTENV = @GL_GGL_GNULIB_MDA_PUTENV@
+GL_GGL_GNULIB_MDA_PUTW = @GL_GGL_GNULIB_MDA_PUTW@
+GL_GGL_GNULIB_MDA_READ = @GL_GGL_GNULIB_MDA_READ@
+GL_GGL_GNULIB_MDA_RMDIR = @GL_GGL_GNULIB_MDA_RMDIR@
+GL_GGL_GNULIB_MDA_STRDUP = @GL_GGL_GNULIB_MDA_STRDUP@
+GL_GGL_GNULIB_MDA_SWAB = @GL_GGL_GNULIB_MDA_SWAB@
+GL_GGL_GNULIB_MDA_TEMPNAM = @GL_GGL_GNULIB_MDA_TEMPNAM@
+GL_GGL_GNULIB_MDA_TZSET = @GL_GGL_GNULIB_MDA_TZSET@
+GL_GGL_GNULIB_MDA_UMASK = @GL_GGL_GNULIB_MDA_UMASK@
+GL_GGL_GNULIB_MDA_UNLINK = @GL_GGL_GNULIB_MDA_UNLINK@
+GL_GGL_GNULIB_MDA_WCSDUP = @GL_GGL_GNULIB_MDA_WCSDUP@
+GL_GGL_GNULIB_MDA_WRITE = @GL_GGL_GNULIB_MDA_WRITE@
+GL_GGL_GNULIB_MEMCHR = @GL_GGL_GNULIB_MEMCHR@
+GL_GGL_GNULIB_MEMMEM = @GL_GGL_GNULIB_MEMMEM@
+GL_GGL_GNULIB_MEMPCPY = @GL_GGL_GNULIB_MEMPCPY@
+GL_GGL_GNULIB_MEMRCHR = @GL_GGL_GNULIB_MEMRCHR@
+GL_GGL_GNULIB_MKDIR = @GL_GGL_GNULIB_MKDIR@
+GL_GGL_GNULIB_MKDIRAT = @GL_GGL_GNULIB_MKDIRAT@
+GL_GGL_GNULIB_MKDTEMP = @GL_GGL_GNULIB_MKDTEMP@
+GL_GGL_GNULIB_MKFIFO = @GL_GGL_GNULIB_MKFIFO@
+GL_GGL_GNULIB_MKFIFOAT = @GL_GGL_GNULIB_MKFIFOAT@
+GL_GGL_GNULIB_MKNOD = @GL_GGL_GNULIB_MKNOD@
+GL_GGL_GNULIB_MKNODAT = @GL_GGL_GNULIB_MKNODAT@
+GL_GGL_GNULIB_MKOSTEMP = @GL_GGL_GNULIB_MKOSTEMP@
+GL_GGL_GNULIB_MKOSTEMPS = @GL_GGL_GNULIB_MKOSTEMPS@
+GL_GGL_GNULIB_MKSTEMP = @GL_GGL_GNULIB_MKSTEMP@
+GL_GGL_GNULIB_MKSTEMPS = @GL_GGL_GNULIB_MKSTEMPS@
+GL_GGL_GNULIB_MKTIME = @GL_GGL_GNULIB_MKTIME@
+GL_GGL_GNULIB_NANOSLEEP = @GL_GGL_GNULIB_NANOSLEEP@
+GL_GGL_GNULIB_NL_LANGINFO = @GL_GGL_GNULIB_NL_LANGINFO@
+GL_GGL_GNULIB_NONBLOCKING = @GL_GGL_GNULIB_NONBLOCKING@
+GL_GGL_GNULIB_OBSTACK_PRINTF = @GL_GGL_GNULIB_OBSTACK_PRINTF@
+GL_GGL_GNULIB_OBSTACK_PRINTF_POSIX = @GL_GGL_GNULIB_OBSTACK_PRINTF_POSIX@
+GL_GGL_GNULIB_OPEN = @GL_GGL_GNULIB_OPEN@
+GL_GGL_GNULIB_OPENAT = @GL_GGL_GNULIB_OPENAT@
+GL_GGL_GNULIB_OVERRIDES_STRUCT_STAT = @GL_GGL_GNULIB_OVERRIDES_STRUCT_STAT@
+GL_GGL_GNULIB_PCLOSE = @GL_GGL_GNULIB_PCLOSE@
+GL_GGL_GNULIB_PERROR = @GL_GGL_GNULIB_PERROR@
+GL_GGL_GNULIB_PIPE = @GL_GGL_GNULIB_PIPE@
+GL_GGL_GNULIB_PIPE2 = @GL_GGL_GNULIB_PIPE2@
+GL_GGL_GNULIB_POPEN = @GL_GGL_GNULIB_POPEN@
+GL_GGL_GNULIB_POSIX_MEMALIGN = @GL_GGL_GNULIB_POSIX_MEMALIGN@
+GL_GGL_GNULIB_POSIX_OPENPT = @GL_GGL_GNULIB_POSIX_OPENPT@
+GL_GGL_GNULIB_PREAD = @GL_GGL_GNULIB_PREAD@
+GL_GGL_GNULIB_PRINTF = @GL_GGL_GNULIB_PRINTF@
+GL_GGL_GNULIB_PRINTF_POSIX = @GL_GGL_GNULIB_PRINTF_POSIX@
+GL_GGL_GNULIB_PSELECT = @GL_GGL_GNULIB_PSELECT@
+GL_GGL_GNULIB_PTHREAD_COND = @GL_GGL_GNULIB_PTHREAD_COND@
+GL_GGL_GNULIB_PTHREAD_MUTEX = @GL_GGL_GNULIB_PTHREAD_MUTEX@
+GL_GGL_GNULIB_PTHREAD_MUTEX_TIMEDLOCK = @GL_GGL_GNULIB_PTHREAD_MUTEX_TIMEDLOCK@
+GL_GGL_GNULIB_PTHREAD_ONCE = @GL_GGL_GNULIB_PTHREAD_ONCE@
+GL_GGL_GNULIB_PTHREAD_RWLOCK = @GL_GGL_GNULIB_PTHREAD_RWLOCK@
+GL_GGL_GNULIB_PTHREAD_SIGMASK = @GL_GGL_GNULIB_PTHREAD_SIGMASK@
+GL_GGL_GNULIB_PTHREAD_SPIN = @GL_GGL_GNULIB_PTHREAD_SPIN@
+GL_GGL_GNULIB_PTHREAD_THREAD = @GL_GGL_GNULIB_PTHREAD_THREAD@
+GL_GGL_GNULIB_PTHREAD_TSS = @GL_GGL_GNULIB_PTHREAD_TSS@
+GL_GGL_GNULIB_PTSNAME = @GL_GGL_GNULIB_PTSNAME@
+GL_GGL_GNULIB_PTSNAME_R = @GL_GGL_GNULIB_PTSNAME_R@
+GL_GGL_GNULIB_PUTC = @GL_GGL_GNULIB_PUTC@
+GL_GGL_GNULIB_PUTCHAR = @GL_GGL_GNULIB_PUTCHAR@
+GL_GGL_GNULIB_PUTENV = @GL_GGL_GNULIB_PUTENV@
+GL_GGL_GNULIB_PUTS = @GL_GGL_GNULIB_PUTS@
+GL_GGL_GNULIB_PWRITE = @GL_GGL_GNULIB_PWRITE@
+GL_GGL_GNULIB_QSORT_R = @GL_GGL_GNULIB_QSORT_R@
+GL_GGL_GNULIB_RAISE = @GL_GGL_GNULIB_RAISE@
+GL_GGL_GNULIB_RANDOM = @GL_GGL_GNULIB_RANDOM@
+GL_GGL_GNULIB_RANDOM_R = @GL_GGL_GNULIB_RANDOM_R@
+GL_GGL_GNULIB_RAWMEMCHR = @GL_GGL_GNULIB_RAWMEMCHR@
+GL_GGL_GNULIB_READ = @GL_GGL_GNULIB_READ@
+GL_GGL_GNULIB_READLINK = @GL_GGL_GNULIB_READLINK@
+GL_GGL_GNULIB_READLINKAT = @GL_GGL_GNULIB_READLINKAT@
+GL_GGL_GNULIB_REALLOCARRAY = @GL_GGL_GNULIB_REALLOCARRAY@
+GL_GGL_GNULIB_REALLOC_POSIX = @GL_GGL_GNULIB_REALLOC_POSIX@
+GL_GGL_GNULIB_REALPATH = @GL_GGL_GNULIB_REALPATH@
+GL_GGL_GNULIB_RECV = @GL_GGL_GNULIB_RECV@
+GL_GGL_GNULIB_RECVFROM = @GL_GGL_GNULIB_RECVFROM@
+GL_GGL_GNULIB_REMOVE = @GL_GGL_GNULIB_REMOVE@
+GL_GGL_GNULIB_RENAME = @GL_GGL_GNULIB_RENAME@
+GL_GGL_GNULIB_RENAMEAT = @GL_GGL_GNULIB_RENAMEAT@
+GL_GGL_GNULIB_RMDIR = @GL_GGL_GNULIB_RMDIR@
+GL_GGL_GNULIB_RPMATCH = @GL_GGL_GNULIB_RPMATCH@
+GL_GGL_GNULIB_SCANF = @GL_GGL_GNULIB_SCANF@
+GL_GGL_GNULIB_SCHED_YIELD = @GL_GGL_GNULIB_SCHED_YIELD@
+GL_GGL_GNULIB_SECURE_GETENV = @GL_GGL_GNULIB_SECURE_GETENV@
+GL_GGL_GNULIB_SELECT = @GL_GGL_GNULIB_SELECT@
+GL_GGL_GNULIB_SEND = @GL_GGL_GNULIB_SEND@
+GL_GGL_GNULIB_SENDTO = @GL_GGL_GNULIB_SENDTO@
+GL_GGL_GNULIB_SETENV = @GL_GGL_GNULIB_SETENV@
+GL_GGL_GNULIB_SETHOSTNAME = @GL_GGL_GNULIB_SETHOSTNAME@
+GL_GGL_GNULIB_SETLOCALE = @GL_GGL_GNULIB_SETLOCALE@
+GL_GGL_GNULIB_SETLOCALE_NULL = @GL_GGL_GNULIB_SETLOCALE_NULL@
+GL_GGL_GNULIB_SETSOCKOPT = @GL_GGL_GNULIB_SETSOCKOPT@
+GL_GGL_GNULIB_SHUTDOWN = @GL_GGL_GNULIB_SHUTDOWN@
+GL_GGL_GNULIB_SIGABBREV_NP = @GL_GGL_GNULIB_SIGABBREV_NP@
+GL_GGL_GNULIB_SIGACTION = @GL_GGL_GNULIB_SIGACTION@
+GL_GGL_GNULIB_SIGDESCR_NP = @GL_GGL_GNULIB_SIGDESCR_NP@
+GL_GGL_GNULIB_SIGNAL_H_SIGPIPE = @GL_GGL_GNULIB_SIGNAL_H_SIGPIPE@
+GL_GGL_GNULIB_SIGPROCMASK = @GL_GGL_GNULIB_SIGPROCMASK@
+GL_GGL_GNULIB_SLEEP = @GL_GGL_GNULIB_SLEEP@
+GL_GGL_GNULIB_SNPRINTF = @GL_GGL_GNULIB_SNPRINTF@
+GL_GGL_GNULIB_SOCKET = @GL_GGL_GNULIB_SOCKET@
+GL_GGL_GNULIB_SPRINTF_POSIX = @GL_GGL_GNULIB_SPRINTF_POSIX@
+GL_GGL_GNULIB_STAT = @GL_GGL_GNULIB_STAT@
+GL_GGL_GNULIB_STDIO_H_NONBLOCKING = @GL_GGL_GNULIB_STDIO_H_NONBLOCKING@
+GL_GGL_GNULIB_STDIO_H_SIGPIPE = @GL_GGL_GNULIB_STDIO_H_SIGPIPE@
+GL_GGL_GNULIB_STPCPY = @GL_GGL_GNULIB_STPCPY@
+GL_GGL_GNULIB_STPNCPY = @GL_GGL_GNULIB_STPNCPY@
+GL_GGL_GNULIB_STRCASESTR = @GL_GGL_GNULIB_STRCASESTR@
+GL_GGL_GNULIB_STRCHRNUL = @GL_GGL_GNULIB_STRCHRNUL@
+GL_GGL_GNULIB_STRDUP = @GL_GGL_GNULIB_STRDUP@
+GL_GGL_GNULIB_STRERROR = @GL_GGL_GNULIB_STRERROR@
+GL_GGL_GNULIB_STRERRORNAME_NP = @GL_GGL_GNULIB_STRERRORNAME_NP@
+GL_GGL_GNULIB_STRERROR_R = @GL_GGL_GNULIB_STRERROR_R@
+GL_GGL_GNULIB_STRFTIME = @GL_GGL_GNULIB_STRFTIME@
+GL_GGL_GNULIB_STRNCAT = @GL_GGL_GNULIB_STRNCAT@
+GL_GGL_GNULIB_STRNDUP = @GL_GGL_GNULIB_STRNDUP@
+GL_GGL_GNULIB_STRNLEN = @GL_GGL_GNULIB_STRNLEN@
+GL_GGL_GNULIB_STRPBRK = @GL_GGL_GNULIB_STRPBRK@
+GL_GGL_GNULIB_STRPTIME = @GL_GGL_GNULIB_STRPTIME@
+GL_GGL_GNULIB_STRSEP = @GL_GGL_GNULIB_STRSEP@
+GL_GGL_GNULIB_STRSIGNAL = @GL_GGL_GNULIB_STRSIGNAL@
+GL_GGL_GNULIB_STRSTR = @GL_GGL_GNULIB_STRSTR@
+GL_GGL_GNULIB_STRTOD = @GL_GGL_GNULIB_STRTOD@
+GL_GGL_GNULIB_STRTOIMAX = @GL_GGL_GNULIB_STRTOIMAX@
+GL_GGL_GNULIB_STRTOK_R = @GL_GGL_GNULIB_STRTOK_R@
+GL_GGL_GNULIB_STRTOL = @GL_GGL_GNULIB_STRTOL@
+GL_GGL_GNULIB_STRTOLD = @GL_GGL_GNULIB_STRTOLD@
+GL_GGL_GNULIB_STRTOLL = @GL_GGL_GNULIB_STRTOLL@
+GL_GGL_GNULIB_STRTOUL = @GL_GGL_GNULIB_STRTOUL@
+GL_GGL_GNULIB_STRTOULL = @GL_GGL_GNULIB_STRTOULL@
+GL_GGL_GNULIB_STRTOUMAX = @GL_GGL_GNULIB_STRTOUMAX@
+GL_GGL_GNULIB_STRVERSCMP = @GL_GGL_GNULIB_STRVERSCMP@
+GL_GGL_GNULIB_SYMLINK = @GL_GGL_GNULIB_SYMLINK@
+GL_GGL_GNULIB_SYMLINKAT = @GL_GGL_GNULIB_SYMLINKAT@
+GL_GGL_GNULIB_SYSTEM_POSIX = @GL_GGL_GNULIB_SYSTEM_POSIX@
+GL_GGL_GNULIB_TIMEGM = @GL_GGL_GNULIB_TIMEGM@
+GL_GGL_GNULIB_TIMESPEC_GET = @GL_GGL_GNULIB_TIMESPEC_GET@
+GL_GGL_GNULIB_TIME_R = @GL_GGL_GNULIB_TIME_R@
+GL_GGL_GNULIB_TIME_RZ = @GL_GGL_GNULIB_TIME_RZ@
+GL_GGL_GNULIB_TMPFILE = @GL_GGL_GNULIB_TMPFILE@
+GL_GGL_GNULIB_TRUNCATE = @GL_GGL_GNULIB_TRUNCATE@
+GL_GGL_GNULIB_TTYNAME_R = @GL_GGL_GNULIB_TTYNAME_R@
+GL_GGL_GNULIB_TZSET = @GL_GGL_GNULIB_TZSET@
+GL_GGL_GNULIB_UNISTD_H_NONBLOCKING = @GL_GGL_GNULIB_UNISTD_H_NONBLOCKING@
+GL_GGL_GNULIB_UNISTD_H_SIGPIPE = @GL_GGL_GNULIB_UNISTD_H_SIGPIPE@
+GL_GGL_GNULIB_UNLINK = @GL_GGL_GNULIB_UNLINK@
+GL_GGL_GNULIB_UNLINKAT = @GL_GGL_GNULIB_UNLINKAT@
+GL_GGL_GNULIB_UNLOCKPT = @GL_GGL_GNULIB_UNLOCKPT@
+GL_GGL_GNULIB_UNSETENV = @GL_GGL_GNULIB_UNSETENV@
+GL_GGL_GNULIB_USLEEP = @GL_GGL_GNULIB_USLEEP@
+GL_GGL_GNULIB_UTIMENSAT = @GL_GGL_GNULIB_UTIMENSAT@
+GL_GGL_GNULIB_VASPRINTF = @GL_GGL_GNULIB_VASPRINTF@
+GL_GGL_GNULIB_VDPRINTF = @GL_GGL_GNULIB_VDPRINTF@
+GL_GGL_GNULIB_VFPRINTF = @GL_GGL_GNULIB_VFPRINTF@
+GL_GGL_GNULIB_VFPRINTF_POSIX = @GL_GGL_GNULIB_VFPRINTF_POSIX@
+GL_GGL_GNULIB_VFSCANF = @GL_GGL_GNULIB_VFSCANF@
+GL_GGL_GNULIB_VPRINTF = @GL_GGL_GNULIB_VPRINTF@
+GL_GGL_GNULIB_VPRINTF_POSIX = @GL_GGL_GNULIB_VPRINTF_POSIX@
+GL_GGL_GNULIB_VSCANF = @GL_GGL_GNULIB_VSCANF@
+GL_GGL_GNULIB_VSNPRINTF = @GL_GGL_GNULIB_VSNPRINTF@
+GL_GGL_GNULIB_VSPRINTF_POSIX = @GL_GGL_GNULIB_VSPRINTF_POSIX@
+GL_GGL_GNULIB_WCPCPY = @GL_GGL_GNULIB_WCPCPY@
+GL_GGL_GNULIB_WCPNCPY = @GL_GGL_GNULIB_WCPNCPY@
+GL_GGL_GNULIB_WCRTOMB = @GL_GGL_GNULIB_WCRTOMB@
+GL_GGL_GNULIB_WCSCASECMP = @GL_GGL_GNULIB_WCSCASECMP@
+GL_GGL_GNULIB_WCSCAT = @GL_GGL_GNULIB_WCSCAT@
+GL_GGL_GNULIB_WCSCHR = @GL_GGL_GNULIB_WCSCHR@
+GL_GGL_GNULIB_WCSCMP = @GL_GGL_GNULIB_WCSCMP@
+GL_GGL_GNULIB_WCSCOLL = @GL_GGL_GNULIB_WCSCOLL@
+GL_GGL_GNULIB_WCSCPY = @GL_GGL_GNULIB_WCSCPY@
+GL_GGL_GNULIB_WCSCSPN = @GL_GGL_GNULIB_WCSCSPN@
+GL_GGL_GNULIB_WCSDUP = @GL_GGL_GNULIB_WCSDUP@
+GL_GGL_GNULIB_WCSFTIME = @GL_GGL_GNULIB_WCSFTIME@
+GL_GGL_GNULIB_WCSLEN = @GL_GGL_GNULIB_WCSLEN@
+GL_GGL_GNULIB_WCSNCASECMP = @GL_GGL_GNULIB_WCSNCASECMP@
+GL_GGL_GNULIB_WCSNCAT = @GL_GGL_GNULIB_WCSNCAT@
+GL_GGL_GNULIB_WCSNCMP = @GL_GGL_GNULIB_WCSNCMP@
+GL_GGL_GNULIB_WCSNCPY = @GL_GGL_GNULIB_WCSNCPY@
+GL_GGL_GNULIB_WCSNLEN = @GL_GGL_GNULIB_WCSNLEN@
+GL_GGL_GNULIB_WCSNRTOMBS = @GL_GGL_GNULIB_WCSNRTOMBS@
+GL_GGL_GNULIB_WCSPBRK = @GL_GGL_GNULIB_WCSPBRK@
+GL_GGL_GNULIB_WCSRCHR = @GL_GGL_GNULIB_WCSRCHR@
+GL_GGL_GNULIB_WCSRTOMBS = @GL_GGL_GNULIB_WCSRTOMBS@
+GL_GGL_GNULIB_WCSSPN = @GL_GGL_GNULIB_WCSSPN@
+GL_GGL_GNULIB_WCSSTR = @GL_GGL_GNULIB_WCSSTR@
+GL_GGL_GNULIB_WCSTOK = @GL_GGL_GNULIB_WCSTOK@
+GL_GGL_GNULIB_WCSWIDTH = @GL_GGL_GNULIB_WCSWIDTH@
+GL_GGL_GNULIB_WCSXFRM = @GL_GGL_GNULIB_WCSXFRM@
+GL_GGL_GNULIB_WCTOB = @GL_GGL_GNULIB_WCTOB@
+GL_GGL_GNULIB_WCTOMB = @GL_GGL_GNULIB_WCTOMB@
+GL_GGL_GNULIB_WCWIDTH = @GL_GGL_GNULIB_WCWIDTH@
+GL_GGL_GNULIB_WMEMCHR = @GL_GGL_GNULIB_WMEMCHR@
+GL_GGL_GNULIB_WMEMCMP = @GL_GGL_GNULIB_WMEMCMP@
+GL_GGL_GNULIB_WMEMCPY = @GL_GGL_GNULIB_WMEMCPY@
+GL_GGL_GNULIB_WMEMMOVE = @GL_GGL_GNULIB_WMEMMOVE@
+GL_GGL_GNULIB_WMEMPCPY = @GL_GGL_GNULIB_WMEMPCPY@
+GL_GGL_GNULIB_WMEMSET = @GL_GGL_GNULIB_WMEMSET@
+GL_GGL_GNULIB_WRITE = @GL_GGL_GNULIB_WRITE@
+GL_GGL_GNULIB__EXIT = @GL_GGL_GNULIB__EXIT@
+GL_GNULIB_ACCEPT = @GL_GNULIB_ACCEPT@
+GL_GNULIB_ACCEPT4 = @GL_GNULIB_ACCEPT4@
+GL_GNULIB_ACCESS = @GL_GNULIB_ACCESS@
+GL_GNULIB_ALIGNED_ALLOC = @GL_GNULIB_ALIGNED_ALLOC@
+GL_GNULIB_ATOLL = @GL_GNULIB_ATOLL@
+GL_GNULIB_BIND = @GL_GNULIB_BIND@
+GL_GNULIB_BTOWC = @GL_GNULIB_BTOWC@
+GL_GNULIB_CALLOC_POSIX = @GL_GNULIB_CALLOC_POSIX@
+GL_GNULIB_CANONICALIZE_FILE_NAME = @GL_GNULIB_CANONICALIZE_FILE_NAME@
+GL_GNULIB_CHDIR = @GL_GNULIB_CHDIR@
+GL_GNULIB_CHOWN = @GL_GNULIB_CHOWN@
+GL_GNULIB_CLOSE = @GL_GNULIB_CLOSE@
+GL_GNULIB_CONNECT = @GL_GNULIB_CONNECT@
+GL_GNULIB_COPY_FILE_RANGE = @GL_GNULIB_COPY_FILE_RANGE@
+GL_GNULIB_CREAT = @GL_GNULIB_CREAT@
+GL_GNULIB_CTIME = @GL_GNULIB_CTIME@
+GL_GNULIB_DPRINTF = @GL_GNULIB_DPRINTF@
+GL_GNULIB_DUP = @GL_GNULIB_DUP@
+GL_GNULIB_DUP2 = @GL_GNULIB_DUP2@
+GL_GNULIB_DUP3 = @GL_GNULIB_DUP3@
+GL_GNULIB_ENVIRON = @GL_GNULIB_ENVIRON@
+GL_GNULIB_EUIDACCESS = @GL_GNULIB_EUIDACCESS@
+GL_GNULIB_EXECL = @GL_GNULIB_EXECL@
+GL_GNULIB_EXECLE = @GL_GNULIB_EXECLE@
+GL_GNULIB_EXECLP = @GL_GNULIB_EXECLP@
+GL_GNULIB_EXECV = @GL_GNULIB_EXECV@
+GL_GNULIB_EXECVE = @GL_GNULIB_EXECVE@
+GL_GNULIB_EXECVP = @GL_GNULIB_EXECVP@
+GL_GNULIB_EXECVPE = @GL_GNULIB_EXECVPE@
+GL_GNULIB_EXPLICIT_BZERO = @GL_GNULIB_EXPLICIT_BZERO@
+GL_GNULIB_FACCESSAT = @GL_GNULIB_FACCESSAT@
+GL_GNULIB_FCHDIR = @GL_GNULIB_FCHDIR@
+GL_GNULIB_FCHMODAT = @GL_GNULIB_FCHMODAT@
+GL_GNULIB_FCHOWNAT = @GL_GNULIB_FCHOWNAT@
+GL_GNULIB_FCLOSE = @GL_GNULIB_FCLOSE@
+GL_GNULIB_FCNTL = @GL_GNULIB_FCNTL@
+GL_GNULIB_FDATASYNC = @GL_GNULIB_FDATASYNC@
+GL_GNULIB_FDOPEN = @GL_GNULIB_FDOPEN@
+GL_GNULIB_FFLUSH = @GL_GNULIB_FFLUSH@
+GL_GNULIB_FFS = @GL_GNULIB_FFS@
+GL_GNULIB_FFSL = @GL_GNULIB_FFSL@
+GL_GNULIB_FFSLL = @GL_GNULIB_FFSLL@
+GL_GNULIB_FGETC = @GL_GNULIB_FGETC@
+GL_GNULIB_FGETS = @GL_GNULIB_FGETS@
+GL_GNULIB_FOPEN = @GL_GNULIB_FOPEN@
+GL_GNULIB_FPRINTF = @GL_GNULIB_FPRINTF@
+GL_GNULIB_FPRINTF_POSIX = @GL_GNULIB_FPRINTF_POSIX@
+GL_GNULIB_FPURGE = @GL_GNULIB_FPURGE@
+GL_GNULIB_FPUTC = @GL_GNULIB_FPUTC@
+GL_GNULIB_FPUTS = @GL_GNULIB_FPUTS@
+GL_GNULIB_FREAD = @GL_GNULIB_FREAD@
+GL_GNULIB_FREE_POSIX = @GL_GNULIB_FREE_POSIX@
+GL_GNULIB_FREOPEN = @GL_GNULIB_FREOPEN@
+GL_GNULIB_FSCANF = @GL_GNULIB_FSCANF@
+GL_GNULIB_FSEEK = @GL_GNULIB_FSEEK@
+GL_GNULIB_FSEEKO = @GL_GNULIB_FSEEKO@
+GL_GNULIB_FSTAT = @GL_GNULIB_FSTAT@
+GL_GNULIB_FSTATAT = @GL_GNULIB_FSTATAT@
+GL_GNULIB_FSYNC = @GL_GNULIB_FSYNC@
+GL_GNULIB_FTELL = @GL_GNULIB_FTELL@
+GL_GNULIB_FTELLO = @GL_GNULIB_FTELLO@
+GL_GNULIB_FTRUNCATE = @GL_GNULIB_FTRUNCATE@
+GL_GNULIB_FUTIMENS = @GL_GNULIB_FUTIMENS@
+GL_GNULIB_FWRITE = @GL_GNULIB_FWRITE@
+GL_GNULIB_GETADDRINFO = @GL_GNULIB_GETADDRINFO@
+GL_GNULIB_GETC = @GL_GNULIB_GETC@
+GL_GNULIB_GETCHAR = @GL_GNULIB_GETCHAR@
+GL_GNULIB_GETCWD = @GL_GNULIB_GETCWD@
+GL_GNULIB_GETDELIM = @GL_GNULIB_GETDELIM@
+GL_GNULIB_GETDOMAINNAME = @GL_GNULIB_GETDOMAINNAME@
+GL_GNULIB_GETDTABLESIZE = @GL_GNULIB_GETDTABLESIZE@
+GL_GNULIB_GETENTROPY = @GL_GNULIB_GETENTROPY@
+GL_GNULIB_GETGROUPS = @GL_GNULIB_GETGROUPS@
+GL_GNULIB_GETHOSTNAME = @GL_GNULIB_GETHOSTNAME@
+GL_GNULIB_GETLINE = @GL_GNULIB_GETLINE@
+GL_GNULIB_GETLOADAVG = @GL_GNULIB_GETLOADAVG@
+GL_GNULIB_GETLOGIN = @GL_GNULIB_GETLOGIN@
+GL_GNULIB_GETLOGIN_R = @GL_GNULIB_GETLOGIN_R@
+GL_GNULIB_GETOPT_POSIX = @GL_GNULIB_GETOPT_POSIX@
+GL_GNULIB_GETPAGESIZE = @GL_GNULIB_GETPAGESIZE@
+GL_GNULIB_GETPASS = @GL_GNULIB_GETPASS@
+GL_GNULIB_GETPEERNAME = @GL_GNULIB_GETPEERNAME@
+GL_GNULIB_GETSOCKNAME = @GL_GNULIB_GETSOCKNAME@
+GL_GNULIB_GETSOCKOPT = @GL_GNULIB_GETSOCKOPT@
+GL_GNULIB_GETSUBOPT = @GL_GNULIB_GETSUBOPT@
+GL_GNULIB_GETTIMEOFDAY = @GL_GNULIB_GETTIMEOFDAY@
+GL_GNULIB_GETUMASK = @GL_GNULIB_GETUMASK@
+GL_GNULIB_GETUSERSHELL = @GL_GNULIB_GETUSERSHELL@
+GL_GNULIB_GRANTPT = @GL_GNULIB_GRANTPT@
+GL_GNULIB_GROUP_MEMBER = @GL_GNULIB_GROUP_MEMBER@
+GL_GNULIB_IMAXABS = @GL_GNULIB_IMAXABS@
+GL_GNULIB_IMAXDIV = @GL_GNULIB_IMAXDIV@
+GL_GNULIB_INET_NTOP = @GL_GNULIB_INET_NTOP@
+GL_GNULIB_INET_PTON = @GL_GNULIB_INET_PTON@
+GL_GNULIB_ISATTY = @GL_GNULIB_ISATTY@
+GL_GNULIB_LCHMOD = @GL_GNULIB_LCHMOD@
+GL_GNULIB_LCHOWN = @GL_GNULIB_LCHOWN@
+GL_GNULIB_LINK = @GL_GNULIB_LINK@
+GL_GNULIB_LINKAT = @GL_GNULIB_LINKAT@
+GL_GNULIB_LISTEN = @GL_GNULIB_LISTEN@
+GL_GNULIB_LOCALTIME = @GL_GNULIB_LOCALTIME@
+GL_GNULIB_LSEEK = @GL_GNULIB_LSEEK@
+GL_GNULIB_LSTAT = @GL_GNULIB_LSTAT@
+GL_GNULIB_MALLOC_POSIX = @GL_GNULIB_MALLOC_POSIX@
+GL_GNULIB_MBRLEN = @GL_GNULIB_MBRLEN@
+GL_GNULIB_MBRTOWC = @GL_GNULIB_MBRTOWC@
+GL_GNULIB_MBSCASECMP = @GL_GNULIB_MBSCASECMP@
+GL_GNULIB_MBSCASESTR = @GL_GNULIB_MBSCASESTR@
+GL_GNULIB_MBSCHR = @GL_GNULIB_MBSCHR@
+GL_GNULIB_MBSCSPN = @GL_GNULIB_MBSCSPN@
+GL_GNULIB_MBSINIT = @GL_GNULIB_MBSINIT@
+GL_GNULIB_MBSLEN = @GL_GNULIB_MBSLEN@
+GL_GNULIB_MBSNCASECMP = @GL_GNULIB_MBSNCASECMP@
+GL_GNULIB_MBSNLEN = @GL_GNULIB_MBSNLEN@
+GL_GNULIB_MBSNRTOWCS = @GL_GNULIB_MBSNRTOWCS@
+GL_GNULIB_MBSPBRK = @GL_GNULIB_MBSPBRK@
+GL_GNULIB_MBSPCASECMP = @GL_GNULIB_MBSPCASECMP@
+GL_GNULIB_MBSRCHR = @GL_GNULIB_MBSRCHR@
+GL_GNULIB_MBSRTOWCS = @GL_GNULIB_MBSRTOWCS@
+GL_GNULIB_MBSSEP = @GL_GNULIB_MBSSEP@
+GL_GNULIB_MBSSPN = @GL_GNULIB_MBSSPN@
+GL_GNULIB_MBSSTR = @GL_GNULIB_MBSSTR@
+GL_GNULIB_MBSTOK_R = @GL_GNULIB_MBSTOK_R@
+GL_GNULIB_MBTOWC = @GL_GNULIB_MBTOWC@
+GL_GNULIB_MDA_ACCESS = @GL_GNULIB_MDA_ACCESS@
+GL_GNULIB_MDA_CHDIR = @GL_GNULIB_MDA_CHDIR@
+GL_GNULIB_MDA_CHMOD = @GL_GNULIB_MDA_CHMOD@
+GL_GNULIB_MDA_CLOSE = @GL_GNULIB_MDA_CLOSE@
+GL_GNULIB_MDA_CREAT = @GL_GNULIB_MDA_CREAT@
+GL_GNULIB_MDA_DUP = @GL_GNULIB_MDA_DUP@
+GL_GNULIB_MDA_DUP2 = @GL_GNULIB_MDA_DUP2@
+GL_GNULIB_MDA_ECVT = @GL_GNULIB_MDA_ECVT@
+GL_GNULIB_MDA_EXECL = @GL_GNULIB_MDA_EXECL@
+GL_GNULIB_MDA_EXECLE = @GL_GNULIB_MDA_EXECLE@
+GL_GNULIB_MDA_EXECLP = @GL_GNULIB_MDA_EXECLP@
+GL_GNULIB_MDA_EXECV = @GL_GNULIB_MDA_EXECV@
+GL_GNULIB_MDA_EXECVE = @GL_GNULIB_MDA_EXECVE@
+GL_GNULIB_MDA_EXECVP = @GL_GNULIB_MDA_EXECVP@
+GL_GNULIB_MDA_EXECVPE = @GL_GNULIB_MDA_EXECVPE@
+GL_GNULIB_MDA_FCLOSEALL = @GL_GNULIB_MDA_FCLOSEALL@
+GL_GNULIB_MDA_FCVT = @GL_GNULIB_MDA_FCVT@
+GL_GNULIB_MDA_FDOPEN = @GL_GNULIB_MDA_FDOPEN@
+GL_GNULIB_MDA_FILENO = @GL_GNULIB_MDA_FILENO@
+GL_GNULIB_MDA_GCVT = @GL_GNULIB_MDA_GCVT@
+GL_GNULIB_MDA_GETCWD = @GL_GNULIB_MDA_GETCWD@
+GL_GNULIB_MDA_GETPID = @GL_GNULIB_MDA_GETPID@
+GL_GNULIB_MDA_GETW = @GL_GNULIB_MDA_GETW@
+GL_GNULIB_MDA_ISATTY = @GL_GNULIB_MDA_ISATTY@
+GL_GNULIB_MDA_LSEEK = @GL_GNULIB_MDA_LSEEK@
+GL_GNULIB_MDA_MEMCCPY = @GL_GNULIB_MDA_MEMCCPY@
+GL_GNULIB_MDA_MKDIR = @GL_GNULIB_MDA_MKDIR@
+GL_GNULIB_MDA_MKTEMP = @GL_GNULIB_MDA_MKTEMP@
+GL_GNULIB_MDA_OPEN = @GL_GNULIB_MDA_OPEN@
+GL_GNULIB_MDA_PUTENV = @GL_GNULIB_MDA_PUTENV@
+GL_GNULIB_MDA_PUTW = @GL_GNULIB_MDA_PUTW@
+GL_GNULIB_MDA_READ = @GL_GNULIB_MDA_READ@
+GL_GNULIB_MDA_RMDIR = @GL_GNULIB_MDA_RMDIR@
+GL_GNULIB_MDA_STRDUP = @GL_GNULIB_MDA_STRDUP@
+GL_GNULIB_MDA_SWAB = @GL_GNULIB_MDA_SWAB@
+GL_GNULIB_MDA_TEMPNAM = @GL_GNULIB_MDA_TEMPNAM@
+GL_GNULIB_MDA_TZSET = @GL_GNULIB_MDA_TZSET@
+GL_GNULIB_MDA_UMASK = @GL_GNULIB_MDA_UMASK@
+GL_GNULIB_MDA_UNLINK = @GL_GNULIB_MDA_UNLINK@
+GL_GNULIB_MDA_WCSDUP = @GL_GNULIB_MDA_WCSDUP@
+GL_GNULIB_MDA_WRITE = @GL_GNULIB_MDA_WRITE@
+GL_GNULIB_MEMCHR = @GL_GNULIB_MEMCHR@
+GL_GNULIB_MEMMEM = @GL_GNULIB_MEMMEM@
+GL_GNULIB_MEMPCPY = @GL_GNULIB_MEMPCPY@
+GL_GNULIB_MEMRCHR = @GL_GNULIB_MEMRCHR@
+GL_GNULIB_MKDIR = @GL_GNULIB_MKDIR@
+GL_GNULIB_MKDIRAT = @GL_GNULIB_MKDIRAT@
+GL_GNULIB_MKDTEMP = @GL_GNULIB_MKDTEMP@
+GL_GNULIB_MKFIFO = @GL_GNULIB_MKFIFO@
+GL_GNULIB_MKFIFOAT = @GL_GNULIB_MKFIFOAT@
+GL_GNULIB_MKNOD = @GL_GNULIB_MKNOD@
+GL_GNULIB_MKNODAT = @GL_GNULIB_MKNODAT@
+GL_GNULIB_MKOSTEMP = @GL_GNULIB_MKOSTEMP@
+GL_GNULIB_MKOSTEMPS = @GL_GNULIB_MKOSTEMPS@
+GL_GNULIB_MKSTEMP = @GL_GNULIB_MKSTEMP@
+GL_GNULIB_MKSTEMPS = @GL_GNULIB_MKSTEMPS@
+GL_GNULIB_MKTIME = @GL_GNULIB_MKTIME@
+GL_GNULIB_NANOSLEEP = @GL_GNULIB_NANOSLEEP@
+GL_GNULIB_NONBLOCKING = @GL_GNULIB_NONBLOCKING@
+GL_GNULIB_OBSTACK_PRINTF = @GL_GNULIB_OBSTACK_PRINTF@
+GL_GNULIB_OBSTACK_PRINTF_POSIX = @GL_GNULIB_OBSTACK_PRINTF_POSIX@
+GL_GNULIB_OPEN = @GL_GNULIB_OPEN@
+GL_GNULIB_OPENAT = @GL_GNULIB_OPENAT@
+GL_GNULIB_OVERRIDES_STRUCT_STAT = @GL_GNULIB_OVERRIDES_STRUCT_STAT@
+GL_GNULIB_PCLOSE = @GL_GNULIB_PCLOSE@
+GL_GNULIB_PERROR = @GL_GNULIB_PERROR@
+GL_GNULIB_PIPE = @GL_GNULIB_PIPE@
+GL_GNULIB_PIPE2 = @GL_GNULIB_PIPE2@
+GL_GNULIB_POPEN = @GL_GNULIB_POPEN@
+GL_GNULIB_POSIX_MEMALIGN = @GL_GNULIB_POSIX_MEMALIGN@
+GL_GNULIB_POSIX_OPENPT = @GL_GNULIB_POSIX_OPENPT@
+GL_GNULIB_PREAD = @GL_GNULIB_PREAD@
+GL_GNULIB_PRINTF = @GL_GNULIB_PRINTF@
+GL_GNULIB_PRINTF_POSIX = @GL_GNULIB_PRINTF_POSIX@
+GL_GNULIB_PTSNAME = @GL_GNULIB_PTSNAME@
+GL_GNULIB_PTSNAME_R = @GL_GNULIB_PTSNAME_R@
+GL_GNULIB_PUTC = @GL_GNULIB_PUTC@
+GL_GNULIB_PUTCHAR = @GL_GNULIB_PUTCHAR@
+GL_GNULIB_PUTENV = @GL_GNULIB_PUTENV@
+GL_GNULIB_PUTS = @GL_GNULIB_PUTS@
+GL_GNULIB_PWRITE = @GL_GNULIB_PWRITE@
+GL_GNULIB_QSORT_R = @GL_GNULIB_QSORT_R@
+GL_GNULIB_RANDOM = @GL_GNULIB_RANDOM@
+GL_GNULIB_RANDOM_R = @GL_GNULIB_RANDOM_R@
+GL_GNULIB_RAWMEMCHR = @GL_GNULIB_RAWMEMCHR@
+GL_GNULIB_READ = @GL_GNULIB_READ@
+GL_GNULIB_READLINK = @GL_GNULIB_READLINK@
+GL_GNULIB_READLINKAT = @GL_GNULIB_READLINKAT@
+GL_GNULIB_REALLOCARRAY = @GL_GNULIB_REALLOCARRAY@
+GL_GNULIB_REALLOC_POSIX = @GL_GNULIB_REALLOC_POSIX@
+GL_GNULIB_REALPATH = @GL_GNULIB_REALPATH@
+GL_GNULIB_RECV = @GL_GNULIB_RECV@
+GL_GNULIB_RECVFROM = @GL_GNULIB_RECVFROM@
+GL_GNULIB_REMOVE = @GL_GNULIB_REMOVE@
+GL_GNULIB_RENAME = @GL_GNULIB_RENAME@
+GL_GNULIB_RENAMEAT = @GL_GNULIB_RENAMEAT@
+GL_GNULIB_RMDIR = @GL_GNULIB_RMDIR@
+GL_GNULIB_RPMATCH = @GL_GNULIB_RPMATCH@
+GL_GNULIB_SCANF = @GL_GNULIB_SCANF@
+GL_GNULIB_SECURE_GETENV = @GL_GNULIB_SECURE_GETENV@
+GL_GNULIB_SEND = @GL_GNULIB_SEND@
+GL_GNULIB_SENDTO = @GL_GNULIB_SENDTO@
+GL_GNULIB_SETENV = @GL_GNULIB_SETENV@
+GL_GNULIB_SETHOSTNAME = @GL_GNULIB_SETHOSTNAME@
+GL_GNULIB_SETSOCKOPT = @GL_GNULIB_SETSOCKOPT@
+GL_GNULIB_SHUTDOWN = @GL_GNULIB_SHUTDOWN@
+GL_GNULIB_SIGABBREV_NP = @GL_GNULIB_SIGABBREV_NP@
+GL_GNULIB_SIGDESCR_NP = @GL_GNULIB_SIGDESCR_NP@
+GL_GNULIB_SLEEP = @GL_GNULIB_SLEEP@
+GL_GNULIB_SNPRINTF = @GL_GNULIB_SNPRINTF@
+GL_GNULIB_SOCKET = @GL_GNULIB_SOCKET@
+GL_GNULIB_SPRINTF_POSIX = @GL_GNULIB_SPRINTF_POSIX@
+GL_GNULIB_STAT = @GL_GNULIB_STAT@
+GL_GNULIB_STDIO_H_NONBLOCKING = @GL_GNULIB_STDIO_H_NONBLOCKING@
+GL_GNULIB_STDIO_H_SIGPIPE = @GL_GNULIB_STDIO_H_SIGPIPE@
+GL_GNULIB_STPCPY = @GL_GNULIB_STPCPY@
+GL_GNULIB_STPNCPY = @GL_GNULIB_STPNCPY@
+GL_GNULIB_STRCASESTR = @GL_GNULIB_STRCASESTR@
+GL_GNULIB_STRCHRNUL = @GL_GNULIB_STRCHRNUL@
+GL_GNULIB_STRDUP = @GL_GNULIB_STRDUP@
+GL_GNULIB_STRERROR = @GL_GNULIB_STRERROR@
+GL_GNULIB_STRERRORNAME_NP = @GL_GNULIB_STRERRORNAME_NP@
+GL_GNULIB_STRERROR_R = @GL_GNULIB_STRERROR_R@
+GL_GNULIB_STRFTIME = @GL_GNULIB_STRFTIME@
+GL_GNULIB_STRNCAT = @GL_GNULIB_STRNCAT@
+GL_GNULIB_STRNDUP = @GL_GNULIB_STRNDUP@
+GL_GNULIB_STRNLEN = @GL_GNULIB_STRNLEN@
+GL_GNULIB_STRPBRK = @GL_GNULIB_STRPBRK@
+GL_GNULIB_STRPTIME = @GL_GNULIB_STRPTIME@
+GL_GNULIB_STRSEP = @GL_GNULIB_STRSEP@
+GL_GNULIB_STRSIGNAL = @GL_GNULIB_STRSIGNAL@
+GL_GNULIB_STRSTR = @GL_GNULIB_STRSTR@
+GL_GNULIB_STRTOD = @GL_GNULIB_STRTOD@
+GL_GNULIB_STRTOIMAX = @GL_GNULIB_STRTOIMAX@
+GL_GNULIB_STRTOK_R = @GL_GNULIB_STRTOK_R@
+GL_GNULIB_STRTOL = @GL_GNULIB_STRTOL@
+GL_GNULIB_STRTOLD = @GL_GNULIB_STRTOLD@
+GL_GNULIB_STRTOLL = @GL_GNULIB_STRTOLL@
+GL_GNULIB_STRTOUL = @GL_GNULIB_STRTOUL@
+GL_GNULIB_STRTOULL = @GL_GNULIB_STRTOULL@
+GL_GNULIB_STRTOUMAX = @GL_GNULIB_STRTOUMAX@
+GL_GNULIB_STRVERSCMP = @GL_GNULIB_STRVERSCMP@
+GL_GNULIB_SYMLINK = @GL_GNULIB_SYMLINK@
+GL_GNULIB_SYMLINKAT = @GL_GNULIB_SYMLINKAT@
+GL_GNULIB_SYSTEM_POSIX = @GL_GNULIB_SYSTEM_POSIX@
+GL_GNULIB_TIMEGM = @GL_GNULIB_TIMEGM@
+GL_GNULIB_TIMESPEC_GET = @GL_GNULIB_TIMESPEC_GET@
+GL_GNULIB_TIME_R = @GL_GNULIB_TIME_R@
+GL_GNULIB_TIME_RZ = @GL_GNULIB_TIME_RZ@
+GL_GNULIB_TMPFILE = @GL_GNULIB_TMPFILE@
+GL_GNULIB_TRUNCATE = @GL_GNULIB_TRUNCATE@
+GL_GNULIB_TTYNAME_R = @GL_GNULIB_TTYNAME_R@
+GL_GNULIB_TZSET = @GL_GNULIB_TZSET@
+GL_GNULIB_UNISTD_H_NONBLOCKING = @GL_GNULIB_UNISTD_H_NONBLOCKING@
+GL_GNULIB_UNISTD_H_SIGPIPE = @GL_GNULIB_UNISTD_H_SIGPIPE@
+GL_GNULIB_UNLINK = @GL_GNULIB_UNLINK@
+GL_GNULIB_UNLINKAT = @GL_GNULIB_UNLINKAT@
+GL_GNULIB_UNLOCKPT = @GL_GNULIB_UNLOCKPT@
+GL_GNULIB_UNSETENV = @GL_GNULIB_UNSETENV@
+GL_GNULIB_USLEEP = @GL_GNULIB_USLEEP@
+GL_GNULIB_UTIMENSAT = @GL_GNULIB_UTIMENSAT@
+GL_GNULIB_VASPRINTF = @GL_GNULIB_VASPRINTF@
+GL_GNULIB_VDPRINTF = @GL_GNULIB_VDPRINTF@
+GL_GNULIB_VFPRINTF = @GL_GNULIB_VFPRINTF@
+GL_GNULIB_VFPRINTF_POSIX = @GL_GNULIB_VFPRINTF_POSIX@
+GL_GNULIB_VFSCANF = @GL_GNULIB_VFSCANF@
+GL_GNULIB_VPRINTF = @GL_GNULIB_VPRINTF@
+GL_GNULIB_VPRINTF_POSIX = @GL_GNULIB_VPRINTF_POSIX@
+GL_GNULIB_VSCANF = @GL_GNULIB_VSCANF@
+GL_GNULIB_VSNPRINTF = @GL_GNULIB_VSNPRINTF@
+GL_GNULIB_VSPRINTF_POSIX = @GL_GNULIB_VSPRINTF_POSIX@
+GL_GNULIB_WCPCPY = @GL_GNULIB_WCPCPY@
+GL_GNULIB_WCPNCPY = @GL_GNULIB_WCPNCPY@
+GL_GNULIB_WCRTOMB = @GL_GNULIB_WCRTOMB@
+GL_GNULIB_WCSCASECMP = @GL_GNULIB_WCSCASECMP@
+GL_GNULIB_WCSCAT = @GL_GNULIB_WCSCAT@
+GL_GNULIB_WCSCHR = @GL_GNULIB_WCSCHR@
+GL_GNULIB_WCSCMP = @GL_GNULIB_WCSCMP@
+GL_GNULIB_WCSCOLL = @GL_GNULIB_WCSCOLL@
+GL_GNULIB_WCSCPY = @GL_GNULIB_WCSCPY@
+GL_GNULIB_WCSCSPN = @GL_GNULIB_WCSCSPN@
+GL_GNULIB_WCSDUP = @GL_GNULIB_WCSDUP@
+GL_GNULIB_WCSFTIME = @GL_GNULIB_WCSFTIME@
+GL_GNULIB_WCSLEN = @GL_GNULIB_WCSLEN@
+GL_GNULIB_WCSNCASECMP = @GL_GNULIB_WCSNCASECMP@
+GL_GNULIB_WCSNCAT = @GL_GNULIB_WCSNCAT@
+GL_GNULIB_WCSNCMP = @GL_GNULIB_WCSNCMP@
+GL_GNULIB_WCSNCPY = @GL_GNULIB_WCSNCPY@
+GL_GNULIB_WCSNLEN = @GL_GNULIB_WCSNLEN@
+GL_GNULIB_WCSNRTOMBS = @GL_GNULIB_WCSNRTOMBS@
+GL_GNULIB_WCSPBRK = @GL_GNULIB_WCSPBRK@
+GL_GNULIB_WCSRCHR = @GL_GNULIB_WCSRCHR@
+GL_GNULIB_WCSRTOMBS = @GL_GNULIB_WCSRTOMBS@
+GL_GNULIB_WCSSPN = @GL_GNULIB_WCSSPN@
+GL_GNULIB_WCSSTR = @GL_GNULIB_WCSSTR@
+GL_GNULIB_WCSTOK = @GL_GNULIB_WCSTOK@
+GL_GNULIB_WCSWIDTH = @GL_GNULIB_WCSWIDTH@
+GL_GNULIB_WCSXFRM = @GL_GNULIB_WCSXFRM@
+GL_GNULIB_WCTOB = @GL_GNULIB_WCTOB@
+GL_GNULIB_WCTOMB = @GL_GNULIB_WCTOMB@
+GL_GNULIB_WCWIDTH = @GL_GNULIB_WCWIDTH@
+GL_GNULIB_WMEMCHR = @GL_GNULIB_WMEMCHR@
+GL_GNULIB_WMEMCMP = @GL_GNULIB_WMEMCMP@
+GL_GNULIB_WMEMCPY = @GL_GNULIB_WMEMCPY@
+GL_GNULIB_WMEMMOVE = @GL_GNULIB_WMEMMOVE@
+GL_GNULIB_WMEMPCPY = @GL_GNULIB_WMEMPCPY@
+GL_GNULIB_WMEMSET = @GL_GNULIB_WMEMSET@
+GL_GNULIB_WRITE = @GL_GNULIB_WRITE@
+GL_GNULIB__EXIT = @GL_GNULIB__EXIT@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_LIBS = @GMP_LIBS@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GNULIBHEADERS_OVERRIDE_WINT_T = @GNULIBHEADERS_OVERRIDE_WINT_T@
+GNULIB_GETTIMEOFDAY = @GNULIB_GETTIMEOFDAY@
+GNUTLS_LIBS_PRIVATE = @GNUTLS_LIBS_PRIVATE@
+GNUTLS_REQUIRES_PRIVATE = @GNUTLS_REQUIRES_PRIVATE@
+GPERF = @GPERF@
+GREP = @GREP@
+GTKDOC_CHECK = @GTKDOC_CHECK@
+GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@
+GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
+GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
+GTKDOC_MKPDF = @GTKDOC_MKPDF@
+GTKDOC_REBASE = @GTKDOC_REBASE@
+GUILD = @GUILD@
+GUILE = @GUILE@
+GUILE_CFLAGS = @GUILE_CFLAGS@
+GUILE_CONFIG = @GUILE_CONFIG@
+GUILE_EFFECTIVE_VERSION = @GUILE_EFFECTIVE_VERSION@
+GUILE_EXTENSION = @GUILE_EXTENSION@
+GUILE_LDFLAGS = @GUILE_LDFLAGS@
+GUILE_LIBS = @GUILE_LIBS@
+GUILE_LTLIBS = @GUILE_LTLIBS@
+GUILE_SITE = @GUILE_SITE@
+GUILE_SITE_CCACHE = @GUILE_SITE_CCACHE@
+GUILE_TOOLS = @GUILE_TOOLS@
+HAVE_ACCEPT4 = @HAVE_ACCEPT4@
+HAVE_ALIGNED_ALLOC = @HAVE_ALIGNED_ALLOC@
+HAVE_ALLOCA_H = @HAVE_ALLOCA_H@
+HAVE_ARPA_INET_H = @HAVE_ARPA_INET_H@
+HAVE_ATOLL = @HAVE_ATOLL@
+HAVE_BTOWC = @HAVE_BTOWC@
+HAVE_C99_STDINT_H = @HAVE_C99_STDINT_H@
+HAVE_CANONICALIZE_FILE_NAME = @HAVE_CANONICALIZE_FILE_NAME@
+HAVE_CHOWN = @HAVE_CHOWN@
+HAVE_COPY_FILE_RANGE = @HAVE_COPY_FILE_RANGE@
+HAVE_CRTDEFS_H = @HAVE_CRTDEFS_H@
+HAVE_DECL_ECVT = @HAVE_DECL_ECVT@
+HAVE_DECL_ENVIRON = @HAVE_DECL_ENVIRON@
+HAVE_DECL_EXECVPE = @HAVE_DECL_EXECVPE@
+HAVE_DECL_FCHDIR = @HAVE_DECL_FCHDIR@
+HAVE_DECL_FCLOSEALL = @HAVE_DECL_FCLOSEALL@
+HAVE_DECL_FCVT = @HAVE_DECL_FCVT@
+HAVE_DECL_FDATASYNC = @HAVE_DECL_FDATASYNC@
+HAVE_DECL_FPURGE = @HAVE_DECL_FPURGE@
+HAVE_DECL_FREEADDRINFO = @HAVE_DECL_FREEADDRINFO@
+HAVE_DECL_FSEEKO = @HAVE_DECL_FSEEKO@
+HAVE_DECL_FTELLO = @HAVE_DECL_FTELLO@
+HAVE_DECL_GAI_STRERROR = @HAVE_DECL_GAI_STRERROR@
+HAVE_DECL_GCVT = @HAVE_DECL_GCVT@
+HAVE_DECL_GETADDRINFO = @HAVE_DECL_GETADDRINFO@
+HAVE_DECL_GETDELIM = @HAVE_DECL_GETDELIM@
+HAVE_DECL_GETDOMAINNAME = @HAVE_DECL_GETDOMAINNAME@
+HAVE_DECL_GETLINE = @HAVE_DECL_GETLINE@
+HAVE_DECL_GETLOADAVG = @HAVE_DECL_GETLOADAVG@
+HAVE_DECL_GETLOGIN = @HAVE_DECL_GETLOGIN@
+HAVE_DECL_GETLOGIN_R = @HAVE_DECL_GETLOGIN_R@
+HAVE_DECL_GETNAMEINFO = @HAVE_DECL_GETNAMEINFO@
+HAVE_DECL_GETPAGESIZE = @HAVE_DECL_GETPAGESIZE@
+HAVE_DECL_GETUSERSHELL = @HAVE_DECL_GETUSERSHELL@
+HAVE_DECL_IMAXABS = @HAVE_DECL_IMAXABS@
+HAVE_DECL_IMAXDIV = @HAVE_DECL_IMAXDIV@
+HAVE_DECL_INET_NTOP = @HAVE_DECL_INET_NTOP@
+HAVE_DECL_INET_PTON = @HAVE_DECL_INET_PTON@
+HAVE_DECL_INITSTATE = @HAVE_DECL_INITSTATE@
+HAVE_DECL_LOCALTIME_R = @HAVE_DECL_LOCALTIME_R@
+HAVE_DECL_MEMMEM = @HAVE_DECL_MEMMEM@
+HAVE_DECL_MEMRCHR = @HAVE_DECL_MEMRCHR@
+HAVE_DECL_OBSTACK_PRINTF = @HAVE_DECL_OBSTACK_PRINTF@
+HAVE_DECL_SETENV = @HAVE_DECL_SETENV@
+HAVE_DECL_SETHOSTNAME = @HAVE_DECL_SETHOSTNAME@
+HAVE_DECL_SETSTATE = @HAVE_DECL_SETSTATE@
+HAVE_DECL_SNPRINTF = @HAVE_DECL_SNPRINTF@
+HAVE_DECL_STRDUP = @HAVE_DECL_STRDUP@
+HAVE_DECL_STRERROR_R = @HAVE_DECL_STRERROR_R@
+HAVE_DECL_STRNCASECMP = @HAVE_DECL_STRNCASECMP@
+HAVE_DECL_STRNDUP = @HAVE_DECL_STRNDUP@
+HAVE_DECL_STRNLEN = @HAVE_DECL_STRNLEN@
+HAVE_DECL_STRSIGNAL = @HAVE_DECL_STRSIGNAL@
+HAVE_DECL_STRTOIMAX = @HAVE_DECL_STRTOIMAX@
+HAVE_DECL_STRTOK_R = @HAVE_DECL_STRTOK_R@
+HAVE_DECL_STRTOUMAX = @HAVE_DECL_STRTOUMAX@
+HAVE_DECL_TRUNCATE = @HAVE_DECL_TRUNCATE@
+HAVE_DECL_TTYNAME_R = @HAVE_DECL_TTYNAME_R@
+HAVE_DECL_UNSETENV = @HAVE_DECL_UNSETENV@
+HAVE_DECL_VSNPRINTF = @HAVE_DECL_VSNPRINTF@
+HAVE_DECL_WCSDUP = @HAVE_DECL_WCSDUP@
+HAVE_DECL_WCTOB = @HAVE_DECL_WCTOB@
+HAVE_DECL_WCWIDTH = @HAVE_DECL_WCWIDTH@
+HAVE_DPRINTF = @HAVE_DPRINTF@
+HAVE_DUP3 = @HAVE_DUP3@
+HAVE_DUPLOCALE = @HAVE_DUPLOCALE@
+HAVE_EUIDACCESS = @HAVE_EUIDACCESS@
+HAVE_EXECVPE = @HAVE_EXECVPE@
+HAVE_EXPLICIT_BZERO = @HAVE_EXPLICIT_BZERO@
+HAVE_FACCESSAT = @HAVE_FACCESSAT@
+HAVE_FCHDIR = @HAVE_FCHDIR@
+HAVE_FCHMODAT = @HAVE_FCHMODAT@
+HAVE_FCHOWNAT = @HAVE_FCHOWNAT@
+HAVE_FCNTL = @HAVE_FCNTL@
+HAVE_FDATASYNC = @HAVE_FDATASYNC@
+HAVE_FEATURES_H = @HAVE_FEATURES_H@
+HAVE_FFS = @HAVE_FFS@
+HAVE_FFSL = @HAVE_FFSL@
+HAVE_FFSLL = @HAVE_FFSLL@
+HAVE_FREELOCALE = @HAVE_FREELOCALE@
+HAVE_FSEEKO = @HAVE_FSEEKO@
+HAVE_FSTATAT = @HAVE_FSTATAT@
+HAVE_FSYNC = @HAVE_FSYNC@
+HAVE_FTELLO = @HAVE_FTELLO@
+HAVE_FTRUNCATE = @HAVE_FTRUNCATE@
+HAVE_FUTIMENS = @HAVE_FUTIMENS@
+HAVE_GETDTABLESIZE = @HAVE_GETDTABLESIZE@
+HAVE_GETENTROPY = @HAVE_GETENTROPY@
+HAVE_GETGROUPS = @HAVE_GETGROUPS@
+HAVE_GETHOSTNAME = @HAVE_GETHOSTNAME@
+HAVE_GETLOGIN = @HAVE_GETLOGIN@
+HAVE_GETPAGESIZE = @HAVE_GETPAGESIZE@
+HAVE_GETPASS = @HAVE_GETPASS@
+HAVE_GETSUBOPT = @HAVE_GETSUBOPT@
+HAVE_GETTIMEOFDAY = @HAVE_GETTIMEOFDAY@
+HAVE_GETUMASK = @HAVE_GETUMASK@
+HAVE_GRANTPT = @HAVE_GRANTPT@
+HAVE_GROUP_MEMBER = @HAVE_GROUP_MEMBER@
+HAVE_IMAXDIV_T = @HAVE_IMAXDIV_T@
+HAVE_INITSTATE = @HAVE_INITSTATE@
+HAVE_INTTYPES_H = @HAVE_INTTYPES_H@
+HAVE_ISBLANK = @HAVE_ISBLANK@
+HAVE_LANGINFO_ALTMON = @HAVE_LANGINFO_ALTMON@
+HAVE_LANGINFO_CODESET = @HAVE_LANGINFO_CODESET@
+HAVE_LANGINFO_ERA = @HAVE_LANGINFO_ERA@
+HAVE_LANGINFO_H = @HAVE_LANGINFO_H@
+HAVE_LANGINFO_T_FMT_AMPM = @HAVE_LANGINFO_T_FMT_AMPM@
+HAVE_LANGINFO_YESEXPR = @HAVE_LANGINFO_YESEXPR@
+HAVE_LCHMOD = @HAVE_LCHMOD@
+HAVE_LCHOWN = @HAVE_LCHOWN@
+HAVE_LIBCRYPTO = @HAVE_LIBCRYPTO@
+HAVE_LIBDL = @HAVE_LIBDL@
+HAVE_LIBEV = @HAVE_LIBEV@
+HAVE_LIBPTHREAD = @HAVE_LIBPTHREAD@
+HAVE_LIBRT = @HAVE_LIBRT@
+HAVE_LIBSECCOMP = @HAVE_LIBSECCOMP@
+HAVE_LIBZ = @HAVE_LIBZ@
+HAVE_LINK = @HAVE_LINK@
+HAVE_LINKAT = @HAVE_LINKAT@
+HAVE_LSTAT = @HAVE_LSTAT@
+HAVE_MAX_ALIGN_T = @HAVE_MAX_ALIGN_T@
+HAVE_MBRLEN = @HAVE_MBRLEN@
+HAVE_MBRTOWC = @HAVE_MBRTOWC@
+HAVE_MBSINIT = @HAVE_MBSINIT@
+HAVE_MBSLEN = @HAVE_MBSLEN@
+HAVE_MBSNRTOWCS = @HAVE_MBSNRTOWCS@
+HAVE_MBSRTOWCS = @HAVE_MBSRTOWCS@
+HAVE_MBTOWC = @HAVE_MBTOWC@
+HAVE_MEMPCPY = @HAVE_MEMPCPY@
+HAVE_MKDIRAT = @HAVE_MKDIRAT@
+HAVE_MKDTEMP = @HAVE_MKDTEMP@
+HAVE_MKFIFO = @HAVE_MKFIFO@
+HAVE_MKFIFOAT = @HAVE_MKFIFOAT@
+HAVE_MKNOD = @HAVE_MKNOD@
+HAVE_MKNODAT = @HAVE_MKNODAT@
+HAVE_MKOSTEMP = @HAVE_MKOSTEMP@
+HAVE_MKOSTEMPS = @HAVE_MKOSTEMPS@
+HAVE_MKSTEMP = @HAVE_MKSTEMP@
+HAVE_MKSTEMPS = @HAVE_MKSTEMPS@
+HAVE_MSVC_INVALID_PARAMETER_HANDLER = @HAVE_MSVC_INVALID_PARAMETER_HANDLER@
+HAVE_NANOSLEEP = @HAVE_NANOSLEEP@
+HAVE_NETDB_H = @HAVE_NETDB_H@
+HAVE_NETINET_IN_H = @HAVE_NETINET_IN_H@
+HAVE_NEWLOCALE = @HAVE_NEWLOCALE@
+HAVE_NL_LANGINFO = @HAVE_NL_LANGINFO@
+HAVE_OPENAT = @HAVE_OPENAT@
+HAVE_OS_H = @HAVE_OS_H@
+HAVE_PCLOSE = @HAVE_PCLOSE@
+HAVE_PIPE = @HAVE_PIPE@
+HAVE_PIPE2 = @HAVE_PIPE2@
+HAVE_POPEN = @HAVE_POPEN@
+HAVE_POSIX_MEMALIGN = @HAVE_POSIX_MEMALIGN@
+HAVE_POSIX_OPENPT = @HAVE_POSIX_OPENPT@
+HAVE_POSIX_SIGNALBLOCKING = @HAVE_POSIX_SIGNALBLOCKING@
+HAVE_PREAD = @HAVE_PREAD@
+HAVE_PSELECT = @HAVE_PSELECT@
+HAVE_PTHREAD_ATTR_DESTROY = @HAVE_PTHREAD_ATTR_DESTROY@
+HAVE_PTHREAD_ATTR_GETDETACHSTATE = @HAVE_PTHREAD_ATTR_GETDETACHSTATE@
+HAVE_PTHREAD_ATTR_INIT = @HAVE_PTHREAD_ATTR_INIT@
+HAVE_PTHREAD_ATTR_SETDETACHSTATE = @HAVE_PTHREAD_ATTR_SETDETACHSTATE@
+HAVE_PTHREAD_CONDATTR_DESTROY = @HAVE_PTHREAD_CONDATTR_DESTROY@
+HAVE_PTHREAD_CONDATTR_INIT = @HAVE_PTHREAD_CONDATTR_INIT@
+HAVE_PTHREAD_COND_BROADCAST = @HAVE_PTHREAD_COND_BROADCAST@
+HAVE_PTHREAD_COND_DESTROY = @HAVE_PTHREAD_COND_DESTROY@
+HAVE_PTHREAD_COND_INIT = @HAVE_PTHREAD_COND_INIT@
+HAVE_PTHREAD_COND_SIGNAL = @HAVE_PTHREAD_COND_SIGNAL@
+HAVE_PTHREAD_COND_TIMEDWAIT = @HAVE_PTHREAD_COND_TIMEDWAIT@
+HAVE_PTHREAD_COND_WAIT = @HAVE_PTHREAD_COND_WAIT@
+HAVE_PTHREAD_CREATE = @HAVE_PTHREAD_CREATE@
+HAVE_PTHREAD_CREATE_DETACHED = @HAVE_PTHREAD_CREATE_DETACHED@
+HAVE_PTHREAD_DETACH = @HAVE_PTHREAD_DETACH@
+HAVE_PTHREAD_EQUAL = @HAVE_PTHREAD_EQUAL@
+HAVE_PTHREAD_EXIT = @HAVE_PTHREAD_EXIT@
+HAVE_PTHREAD_GETSPECIFIC = @HAVE_PTHREAD_GETSPECIFIC@
+HAVE_PTHREAD_H = @HAVE_PTHREAD_H@
+HAVE_PTHREAD_JOIN = @HAVE_PTHREAD_JOIN@
+HAVE_PTHREAD_KEY_CREATE = @HAVE_PTHREAD_KEY_CREATE@
+HAVE_PTHREAD_KEY_DELETE = @HAVE_PTHREAD_KEY_DELETE@
+HAVE_PTHREAD_MUTEXATTR_DESTROY = @HAVE_PTHREAD_MUTEXATTR_DESTROY@
+HAVE_PTHREAD_MUTEXATTR_GETROBUST = @HAVE_PTHREAD_MUTEXATTR_GETROBUST@
+HAVE_PTHREAD_MUTEXATTR_GETTYPE = @HAVE_PTHREAD_MUTEXATTR_GETTYPE@
+HAVE_PTHREAD_MUTEXATTR_INIT = @HAVE_PTHREAD_MUTEXATTR_INIT@
+HAVE_PTHREAD_MUTEXATTR_SETROBUST = @HAVE_PTHREAD_MUTEXATTR_SETROBUST@
+HAVE_PTHREAD_MUTEXATTR_SETTYPE = @HAVE_PTHREAD_MUTEXATTR_SETTYPE@
+HAVE_PTHREAD_MUTEX_DESTROY = @HAVE_PTHREAD_MUTEX_DESTROY@
+HAVE_PTHREAD_MUTEX_INIT = @HAVE_PTHREAD_MUTEX_INIT@
+HAVE_PTHREAD_MUTEX_LOCK = @HAVE_PTHREAD_MUTEX_LOCK@
+HAVE_PTHREAD_MUTEX_RECURSIVE = @HAVE_PTHREAD_MUTEX_RECURSIVE@
+HAVE_PTHREAD_MUTEX_ROBUST = @HAVE_PTHREAD_MUTEX_ROBUST@
+HAVE_PTHREAD_MUTEX_TIMEDLOCK = @HAVE_PTHREAD_MUTEX_TIMEDLOCK@
+HAVE_PTHREAD_MUTEX_TRYLOCK = @HAVE_PTHREAD_MUTEX_TRYLOCK@
+HAVE_PTHREAD_MUTEX_UNLOCK = @HAVE_PTHREAD_MUTEX_UNLOCK@
+HAVE_PTHREAD_ONCE = @HAVE_PTHREAD_ONCE@
+HAVE_PTHREAD_PROCESS_SHARED = @HAVE_PTHREAD_PROCESS_SHARED@
+HAVE_PTHREAD_RWLOCKATTR_DESTROY = @HAVE_PTHREAD_RWLOCKATTR_DESTROY@
+HAVE_PTHREAD_RWLOCKATTR_INIT = @HAVE_PTHREAD_RWLOCKATTR_INIT@
+HAVE_PTHREAD_RWLOCK_DESTROY = @HAVE_PTHREAD_RWLOCK_DESTROY@
+HAVE_PTHREAD_RWLOCK_INIT = @HAVE_PTHREAD_RWLOCK_INIT@
+HAVE_PTHREAD_RWLOCK_RDLOCK = @HAVE_PTHREAD_RWLOCK_RDLOCK@
+HAVE_PTHREAD_RWLOCK_TIMEDRDLOCK = @HAVE_PTHREAD_RWLOCK_TIMEDRDLOCK@
+HAVE_PTHREAD_RWLOCK_TIMEDWRLOCK = @HAVE_PTHREAD_RWLOCK_TIMEDWRLOCK@
+HAVE_PTHREAD_RWLOCK_TRYRDLOCK = @HAVE_PTHREAD_RWLOCK_TRYRDLOCK@
+HAVE_PTHREAD_RWLOCK_TRYWRLOCK = @HAVE_PTHREAD_RWLOCK_TRYWRLOCK@
+HAVE_PTHREAD_RWLOCK_UNLOCK = @HAVE_PTHREAD_RWLOCK_UNLOCK@
+HAVE_PTHREAD_RWLOCK_WRLOCK = @HAVE_PTHREAD_RWLOCK_WRLOCK@
+HAVE_PTHREAD_SELF = @HAVE_PTHREAD_SELF@
+HAVE_PTHREAD_SETSPECIFIC = @HAVE_PTHREAD_SETSPECIFIC@
+HAVE_PTHREAD_SIGMASK = @HAVE_PTHREAD_SIGMASK@
+HAVE_PTHREAD_SPINLOCK_T = @HAVE_PTHREAD_SPINLOCK_T@
+HAVE_PTHREAD_SPIN_DESTROY = @HAVE_PTHREAD_SPIN_DESTROY@
+HAVE_PTHREAD_SPIN_INIT = @HAVE_PTHREAD_SPIN_INIT@
+HAVE_PTHREAD_SPIN_LOCK = @HAVE_PTHREAD_SPIN_LOCK@
+HAVE_PTHREAD_SPIN_TRYLOCK = @HAVE_PTHREAD_SPIN_TRYLOCK@
+HAVE_PTHREAD_SPIN_UNLOCK = @HAVE_PTHREAD_SPIN_UNLOCK@
+HAVE_PTHREAD_T = @HAVE_PTHREAD_T@
+HAVE_PTSNAME = @HAVE_PTSNAME@
+HAVE_PTSNAME_R = @HAVE_PTSNAME_R@
+HAVE_PWRITE = @HAVE_PWRITE@
+HAVE_QSORT_R = @HAVE_QSORT_R@
+HAVE_RAISE = @HAVE_RAISE@
+HAVE_RANDOM = @HAVE_RANDOM@
+HAVE_RANDOM_H = @HAVE_RANDOM_H@
+HAVE_RANDOM_R = @HAVE_RANDOM_R@
+HAVE_RAWMEMCHR = @HAVE_RAWMEMCHR@
+HAVE_READLINK = @HAVE_READLINK@
+HAVE_READLINKAT = @HAVE_READLINKAT@
+HAVE_REALLOCARRAY = @HAVE_REALLOCARRAY@
+HAVE_REALPATH = @HAVE_REALPATH@
+HAVE_RENAMEAT = @HAVE_RENAMEAT@
+HAVE_RPMATCH = @HAVE_RPMATCH@
+HAVE_SA_FAMILY_T = @HAVE_SA_FAMILY_T@
+HAVE_SCHED_H = @HAVE_SCHED_H@
+HAVE_SCHED_YIELD = @HAVE_SCHED_YIELD@
+HAVE_SECURE_GETENV = @HAVE_SECURE_GETENV@
+HAVE_SETENV = @HAVE_SETENV@
+HAVE_SETHOSTNAME = @HAVE_SETHOSTNAME@
+HAVE_SETSTATE = @HAVE_SETSTATE@
+HAVE_SIGABBREV_NP = @HAVE_SIGABBREV_NP@
+HAVE_SIGACTION = @HAVE_SIGACTION@
+HAVE_SIGDESCR_NP = @HAVE_SIGDESCR_NP@
+HAVE_SIGHANDLER_T = @HAVE_SIGHANDLER_T@
+HAVE_SIGINFO_T = @HAVE_SIGINFO_T@
+HAVE_SIGNED_SIG_ATOMIC_T = @HAVE_SIGNED_SIG_ATOMIC_T@
+HAVE_SIGNED_WCHAR_T = @HAVE_SIGNED_WCHAR_T@
+HAVE_SIGNED_WINT_T = @HAVE_SIGNED_WINT_T@
+HAVE_SIGSET_T = @HAVE_SIGSET_T@
+HAVE_SLEEP = @HAVE_SLEEP@
+HAVE_STDINT_H = @HAVE_STDINT_H@
+HAVE_STPCPY = @HAVE_STPCPY@
+HAVE_STPNCPY = @HAVE_STPNCPY@
+HAVE_STRCASECMP = @HAVE_STRCASECMP@
+HAVE_STRCASESTR = @HAVE_STRCASESTR@
+HAVE_STRCHRNUL = @HAVE_STRCHRNUL@
+HAVE_STRERRORNAME_NP = @HAVE_STRERRORNAME_NP@
+HAVE_STRINGS_H = @HAVE_STRINGS_H@
+HAVE_STRPBRK = @HAVE_STRPBRK@
+HAVE_STRPTIME = @HAVE_STRPTIME@
+HAVE_STRSEP = @HAVE_STRSEP@
+HAVE_STRTOD = @HAVE_STRTOD@
+HAVE_STRTOL = @HAVE_STRTOL@
+HAVE_STRTOLD = @HAVE_STRTOLD@
+HAVE_STRTOLL = @HAVE_STRTOLL@
+HAVE_STRTOUL = @HAVE_STRTOUL@
+HAVE_STRTOULL = @HAVE_STRTOULL@
+HAVE_STRUCT_ADDRINFO = @HAVE_STRUCT_ADDRINFO@
+HAVE_STRUCT_RANDOM_DATA = @HAVE_STRUCT_RANDOM_DATA@
+HAVE_STRUCT_SCHED_PARAM = @HAVE_STRUCT_SCHED_PARAM@
+HAVE_STRUCT_SIGACTION_SA_SIGACTION = @HAVE_STRUCT_SIGACTION_SA_SIGACTION@
+HAVE_STRUCT_SOCKADDR_STORAGE = @HAVE_STRUCT_SOCKADDR_STORAGE@
+HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY = @HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY@
+HAVE_STRUCT_TIMEVAL = @HAVE_STRUCT_TIMEVAL@
+HAVE_STRVERSCMP = @HAVE_STRVERSCMP@
+HAVE_SYMLINK = @HAVE_SYMLINK@
+HAVE_SYMLINKAT = @HAVE_SYMLINKAT@
+HAVE_SYS_BITYPES_H = @HAVE_SYS_BITYPES_H@
+HAVE_SYS_CDEFS_H = @HAVE_SYS_CDEFS_H@
+HAVE_SYS_INTTYPES_H = @HAVE_SYS_INTTYPES_H@
+HAVE_SYS_IOCTL_H = @HAVE_SYS_IOCTL_H@
+HAVE_SYS_LOADAVG_H = @HAVE_SYS_LOADAVG_H@
+HAVE_SYS_PARAM_H = @HAVE_SYS_PARAM_H@
+HAVE_SYS_SELECT_H = @HAVE_SYS_SELECT_H@
+HAVE_SYS_SOCKET_H = @HAVE_SYS_SOCKET_H@
+HAVE_SYS_TIME_H = @HAVE_SYS_TIME_H@
+HAVE_SYS_TYPES_H = @HAVE_SYS_TYPES_H@
+HAVE_SYS_UIO_H = @HAVE_SYS_UIO_H@
+HAVE_TIMEGM = @HAVE_TIMEGM@
+HAVE_TIMESPEC_GET = @HAVE_TIMESPEC_GET@
+HAVE_TIMEZONE_T = @HAVE_TIMEZONE_T@
+HAVE_TYPE_VOLATILE_SIG_ATOMIC_T = @HAVE_TYPE_VOLATILE_SIG_ATOMIC_T@
+HAVE_UNISTD_H = @HAVE_UNISTD_H@
+HAVE_UNLINKAT = @HAVE_UNLINKAT@
+HAVE_UNLOCKPT = @HAVE_UNLOCKPT@
+HAVE_USLEEP = @HAVE_USLEEP@
+HAVE_UTIMENSAT = @HAVE_UTIMENSAT@
+HAVE_VASPRINTF = @HAVE_VASPRINTF@
+HAVE_VDPRINTF = @HAVE_VDPRINTF@
+HAVE_VISIBILITY = @HAVE_VISIBILITY@
+HAVE_WCHAR_H = @HAVE_WCHAR_H@
+HAVE_WCHAR_T = @HAVE_WCHAR_T@
+HAVE_WCPCPY = @HAVE_WCPCPY@
+HAVE_WCPNCPY = @HAVE_WCPNCPY@
+HAVE_WCRTOMB = @HAVE_WCRTOMB@
+HAVE_WCSCASECMP = @HAVE_WCSCASECMP@
+HAVE_WCSCAT = @HAVE_WCSCAT@
+HAVE_WCSCHR = @HAVE_WCSCHR@
+HAVE_WCSCMP = @HAVE_WCSCMP@
+HAVE_WCSCOLL = @HAVE_WCSCOLL@
+HAVE_WCSCPY = @HAVE_WCSCPY@
+HAVE_WCSCSPN = @HAVE_WCSCSPN@
+HAVE_WCSDUP = @HAVE_WCSDUP@
+HAVE_WCSFTIME = @HAVE_WCSFTIME@
+HAVE_WCSLEN = @HAVE_WCSLEN@
+HAVE_WCSNCASECMP = @HAVE_WCSNCASECMP@
+HAVE_WCSNCAT = @HAVE_WCSNCAT@
+HAVE_WCSNCMP = @HAVE_WCSNCMP@
+HAVE_WCSNCPY = @HAVE_WCSNCPY@
+HAVE_WCSNLEN = @HAVE_WCSNLEN@
+HAVE_WCSNRTOMBS = @HAVE_WCSNRTOMBS@
+HAVE_WCSPBRK = @HAVE_WCSPBRK@
+HAVE_WCSRCHR = @HAVE_WCSRCHR@
+HAVE_WCSRTOMBS = @HAVE_WCSRTOMBS@
+HAVE_WCSSPN = @HAVE_WCSSPN@
+HAVE_WCSSTR = @HAVE_WCSSTR@
+HAVE_WCSTOK = @HAVE_WCSTOK@
+HAVE_WCSWIDTH = @HAVE_WCSWIDTH@
+HAVE_WCSXFRM = @HAVE_WCSXFRM@
+HAVE_WINSOCK2_H = @HAVE_WINSOCK2_H@
+HAVE_WINT_T = @HAVE_WINT_T@
+HAVE_WMEMCHR = @HAVE_WMEMCHR@
+HAVE_WMEMCMP = @HAVE_WMEMCMP@
+HAVE_WMEMCPY = @HAVE_WMEMCPY@
+HAVE_WMEMMOVE = @HAVE_WMEMMOVE@
+HAVE_WMEMPCPY = @HAVE_WMEMPCPY@
+HAVE_WMEMSET = @HAVE_WMEMSET@
+HAVE_WS2TCPIP_H = @HAVE_WS2TCPIP_H@
+HAVE_XLOCALE_H = @HAVE_XLOCALE_H@
+HAVE__BOOL = @HAVE__BOOL@
+HAVE__EXIT = @HAVE__EXIT@
+HOGWEED_CFLAGS = @HOGWEED_CFLAGS@
+HOGWEED_LIBS = @HOGWEED_LIBS@
+HOSTENT_LIB = @HOSTENT_LIB@
+HTML_DIR = @HTML_DIR@
+INCLUDE_NEXT = @INCLUDE_NEXT@
+INCLUDE_NEXT_AS_FIRST_DIRECTIVE = @INCLUDE_NEXT_AS_FIRST_DIRECTIVE@
+INET_NTOP_LIB = @INET_NTOP_LIB@
+INET_PTON_LIB = @INET_PTON_LIB@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INT32_MAX_LT_INTMAX_MAX = @INT32_MAX_LT_INTMAX_MAX@
+INT64_MAX_EQ_LONG_MAX = @INT64_MAX_EQ_LONG_MAX@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LCOV = @LCOV@
+LD = @LD@
+LDDPOSTPROC = @LDDPOSTPROC@
+LDDPROG = @LDDPROG@
+LDFLAGS = @LDFLAGS@
+LIBATOMIC_LIBS = @LIBATOMIC_LIBS@
+LIBBROTLIDEC_CFLAGS = @LIBBROTLIDEC_CFLAGS@
+LIBBROTLIDEC_LIBS = @LIBBROTLIDEC_LIBS@
+LIBBROTLIENC_CFLAGS = @LIBBROTLIENC_CFLAGS@
+LIBBROTLIENC_LIBS = @LIBBROTLIENC_LIBS@
+LIBCRYPTO = @LIBCRYPTO@
+LIBCRYPTO_PREFIX = @LIBCRYPTO_PREFIX@
+LIBDL = @LIBDL@
+LIBDL_PREFIX = @LIBDL_PREFIX@
+LIBEV = @LIBEV@
+LIBEV_LIBS = @LIBEV_LIBS@
+LIBEV_PREFIX = @LIBEV_PREFIX@
+LIBGNUTLS_CFLAGS = @LIBGNUTLS_CFLAGS@
+LIBGNUTLS_LIBS = @LIBGNUTLS_LIBS@
+LIBICONV = @LIBICONV@
+LIBIDN2_CFLAGS = @LIBIDN2_CFLAGS@
+LIBIDN2_LIBS = @LIBIDN2_LIBS@
+LIBINTL = @LIBINTL@
+LIBKCAPI_CFLAGS = @LIBKCAPI_CFLAGS@
+LIBKCAPI_LIBS = @LIBKCAPI_LIBS@
+LIBMULTITHREAD = @LIBMULTITHREAD@
+LIBOBJS = @LIBOBJS@
+LIBPMULTITHREAD = @LIBPMULTITHREAD@
+LIBPTHREAD = @LIBPTHREAD@
+LIBPTHREAD_PREFIX = @LIBPTHREAD_PREFIX@
+LIBRT = @LIBRT@
+LIBRT_PREFIX = @LIBRT_PREFIX@
+LIBS = @LIBS@
+LIBSECCOMP = @LIBSECCOMP@
+LIBSECCOMP_PREFIX = @LIBSECCOMP_PREFIX@
+LIBSOCKET = @LIBSOCKET@
+LIBSTDTHREAD = @LIBSTDTHREAD@
+LIBTASN1_CFLAGS = @LIBTASN1_CFLAGS@
+LIBTASN1_LIBS = @LIBTASN1_LIBS@
+LIBTESTS_LIBDEPS = @LIBTESTS_LIBDEPS@
+LIBTHREAD = @LIBTHREAD@
+LIBTOOL = @LIBTOOL@
+LIBUNISTRING = @LIBUNISTRING@
+LIBUNISTRING_UNICTYPE_H = @LIBUNISTRING_UNICTYPE_H@
+LIBUNISTRING_UNINORM_H = @LIBUNISTRING_UNINORM_H@
+LIBUNISTRING_UNISTR_H = @LIBUNISTRING_UNISTR_H@
+LIBUNISTRING_UNITYPES_H = @LIBUNISTRING_UNITYPES_H@
+LIBZ = @LIBZ@
+LIBZSTD_CFLAGS = @LIBZSTD_CFLAGS@
+LIBZSTD_LIBS = @LIBZSTD_LIBS@
+LIBZ_PC = @LIBZ_PC@
+LIBZ_PREFIX = @LIBZ_PREFIX@
+LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@
+LIB_NANOSLEEP = @LIB_NANOSLEEP@
+LIB_PTHREAD = @LIB_PTHREAD@
+LIB_PTHREAD_SIGMASK = @LIB_PTHREAD_SIGMASK@
+LIB_SCHED_YIELD = @LIB_SCHED_YIELD@
+LIB_SELECT = @LIB_SELECT@
+LIB_SEMAPHORE = @LIB_SEMAPHORE@
+LIB_SETLOCALE = @LIB_SETLOCALE@
+LIB_SETLOCALE_NULL = @LIB_SETLOCALE_NULL@
+LIMITS_H = @LIMITS_H@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LOCALENAME_ENHANCE_LOCALE_FUNCS = @LOCALENAME_ENHANCE_LOCALE_FUNCS@
+LOCALE_FR = @LOCALE_FR@
+LOCALE_FR_UTF8 = @LOCALE_FR_UTF8@
+LOCALE_JA = @LOCALE_JA@
+LOCALE_TR_UTF8 = @LOCALE_TR_UTF8@
+LOCALE_ZH_CN = @LOCALE_ZH_CN@
+LOG_VALGRIND = @LOG_VALGRIND@
+LTALLOCA = @LTALLOCA@
+LTLIBCRYPTO = @LTLIBCRYPTO@
+LTLIBDL = @LTLIBDL@
+LTLIBEV = @LTLIBEV@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBMULTITHREAD = @LTLIBMULTITHREAD@
+LTLIBOBJS = @LTLIBOBJS@
+LTLIBPTHREAD = @LTLIBPTHREAD@
+LTLIBRT = @LTLIBRT@
+LTLIBSECCOMP = @LTLIBSECCOMP@
+LTLIBTHREAD = @LTLIBTHREAD@
+LTLIBZ = @LTLIBZ@
+LT_AGE = @LT_AGE@
+LT_CURRENT = @LT_CURRENT@
+LT_DANE_AGE = @LT_DANE_AGE@
+LT_DANE_CURRENT = @LT_DANE_CURRENT@
+LT_DANE_REVISION = @LT_DANE_REVISION@
+LT_REVISION = @LT_REVISION@
+LT_SSL_AGE = @LT_SSL_AGE@
+LT_SSL_CURRENT = @LT_SSL_CURRENT@
+LT_SSL_REVISION = @LT_SSL_REVISION@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+LT_XSSL_AGE = @LT_XSSL_AGE@
+LT_XSSL_CURRENT = @LT_XSSL_CURRENT@
+LT_XSSL_REVISION = @LT_XSSL_REVISION@
+MAINT = @MAINT@
+MAJOR_VERSION = @MAJOR_VERSION@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MINOR_VERSION = @MINOR_VERSION@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGMERGE = @MSGMERGE@
+MSGMERGE_FOR_MSGFMT_OPTION = @MSGMERGE_FOR_MSGFMT_OPTION@
+NETINET_IN_H = @NETINET_IN_H@
+NETTLE_CFLAGS = @NETTLE_CFLAGS@
+NETTLE_LIBS = @NETTLE_LIBS@
+NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@
+NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@
+NEXT_AS_FIRST_DIRECTIVE_CTYPE_H = @NEXT_AS_FIRST_DIRECTIVE_CTYPE_H@
+NEXT_AS_FIRST_DIRECTIVE_ERRNO_H = @NEXT_AS_FIRST_DIRECTIVE_ERRNO_H@
+NEXT_AS_FIRST_DIRECTIVE_FCNTL_H = @NEXT_AS_FIRST_DIRECTIVE_FCNTL_H@
+NEXT_AS_FIRST_DIRECTIVE_FLOAT_H = @NEXT_AS_FIRST_DIRECTIVE_FLOAT_H@
+NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H = @NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H@
+NEXT_AS_FIRST_DIRECTIVE_LANGINFO_H = @NEXT_AS_FIRST_DIRECTIVE_LANGINFO_H@
+NEXT_AS_FIRST_DIRECTIVE_LIMITS_H = @NEXT_AS_FIRST_DIRECTIVE_LIMITS_H@
+NEXT_AS_FIRST_DIRECTIVE_LOCALE_H = @NEXT_AS_FIRST_DIRECTIVE_LOCALE_H@
+NEXT_AS_FIRST_DIRECTIVE_NETDB_H = @NEXT_AS_FIRST_DIRECTIVE_NETDB_H@
+NEXT_AS_FIRST_DIRECTIVE_NETINET_IN_H = @NEXT_AS_FIRST_DIRECTIVE_NETINET_IN_H@
+NEXT_AS_FIRST_DIRECTIVE_PTHREAD_H = @NEXT_AS_FIRST_DIRECTIVE_PTHREAD_H@
+NEXT_AS_FIRST_DIRECTIVE_SCHED_H = @NEXT_AS_FIRST_DIRECTIVE_SCHED_H@
+NEXT_AS_FIRST_DIRECTIVE_SIGNAL_H = @NEXT_AS_FIRST_DIRECTIVE_SIGNAL_H@
+NEXT_AS_FIRST_DIRECTIVE_STDDEF_H = @NEXT_AS_FIRST_DIRECTIVE_STDDEF_H@
+NEXT_AS_FIRST_DIRECTIVE_STDINT_H = @NEXT_AS_FIRST_DIRECTIVE_STDINT_H@
+NEXT_AS_FIRST_DIRECTIVE_STDIO_H = @NEXT_AS_FIRST_DIRECTIVE_STDIO_H@
+NEXT_AS_FIRST_DIRECTIVE_STDLIB_H = @NEXT_AS_FIRST_DIRECTIVE_STDLIB_H@
+NEXT_AS_FIRST_DIRECTIVE_STRINGS_H = @NEXT_AS_FIRST_DIRECTIVE_STRINGS_H@
+NEXT_AS_FIRST_DIRECTIVE_STRING_H = @NEXT_AS_FIRST_DIRECTIVE_STRING_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_IOCTL_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_IOCTL_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_SELECT_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_SELECT_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_SOCKET_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_SOCKET_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_STAT_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_STAT_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_TIME_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_TIME_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_TYPES_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_TYPES_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_UIO_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_UIO_H@
+NEXT_AS_FIRST_DIRECTIVE_TIME_H = @NEXT_AS_FIRST_DIRECTIVE_TIME_H@
+NEXT_AS_FIRST_DIRECTIVE_UNISTD_H = @NEXT_AS_FIRST_DIRECTIVE_UNISTD_H@
+NEXT_AS_FIRST_DIRECTIVE_WCHAR_H = @NEXT_AS_FIRST_DIRECTIVE_WCHAR_H@
+NEXT_CTYPE_H = @NEXT_CTYPE_H@
+NEXT_ERRNO_H = @NEXT_ERRNO_H@
+NEXT_FCNTL_H = @NEXT_FCNTL_H@
+NEXT_FLOAT_H = @NEXT_FLOAT_H@
+NEXT_INTTYPES_H = @NEXT_INTTYPES_H@
+NEXT_LANGINFO_H = @NEXT_LANGINFO_H@
+NEXT_LIMITS_H = @NEXT_LIMITS_H@
+NEXT_LOCALE_H = @NEXT_LOCALE_H@
+NEXT_NETDB_H = @NEXT_NETDB_H@
+NEXT_NETINET_IN_H = @NEXT_NETINET_IN_H@
+NEXT_PTHREAD_H = @NEXT_PTHREAD_H@
+NEXT_SCHED_H = @NEXT_SCHED_H@
+NEXT_SIGNAL_H = @NEXT_SIGNAL_H@
+NEXT_STDDEF_H = @NEXT_STDDEF_H@
+NEXT_STDINT_H = @NEXT_STDINT_H@
+NEXT_STDIO_H = @NEXT_STDIO_H@
+NEXT_STDLIB_H = @NEXT_STDLIB_H@
+NEXT_STRINGS_H = @NEXT_STRINGS_H@
+NEXT_STRING_H = @NEXT_STRING_H@
+NEXT_SYS_IOCTL_H = @NEXT_SYS_IOCTL_H@
+NEXT_SYS_SELECT_H = @NEXT_SYS_SELECT_H@
+NEXT_SYS_SOCKET_H = @NEXT_SYS_SOCKET_H@
+NEXT_SYS_STAT_H = @NEXT_SYS_STAT_H@
+NEXT_SYS_TIME_H = @NEXT_SYS_TIME_H@
+NEXT_SYS_TYPES_H = @NEXT_SYS_TYPES_H@
+NEXT_SYS_UIO_H = @NEXT_SYS_UIO_H@
+NEXT_TIME_H = @NEXT_TIME_H@
+NEXT_UNISTD_H = @NEXT_UNISTD_H@
+NEXT_WCHAR_H = @NEXT_WCHAR_H@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NUMBER_VERSION = @NUMBER_VERSION@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+P11_KIT_CFLAGS = @P11_KIT_CFLAGS@
+P11_KIT_LIBS = @P11_KIT_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PARSE_DATETIME_BISON = @PARSE_DATETIME_BISON@
+PATCH_VERSION = @PATCH_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKCS12_ITER_COUNT = @PKCS12_ITER_COUNT@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PMCCABE = @PMCCABE@
+POSUB = @POSUB@
+PRAGMA_COLUMNS = @PRAGMA_COLUMNS@
+PRAGMA_SYSTEM_HEADER = @PRAGMA_SYSTEM_HEADER@
+PRIPTR_PREFIX = @PRIPTR_PREFIX@
+PTHREAD_H_DEFINES_STRUCT_TIMESPEC = @PTHREAD_H_DEFINES_STRUCT_TIMESPEC@
+PTRDIFF_T_SUFFIX = @PTRDIFF_T_SUFFIX@
+PYTHON = @PYTHON@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+RANLIB = @RANLIB@
+REPLACE_ACCESS = @REPLACE_ACCESS@
+REPLACE_ALIGNED_ALLOC = @REPLACE_ALIGNED_ALLOC@
+REPLACE_BTOWC = @REPLACE_BTOWC@
+REPLACE_CALLOC = @REPLACE_CALLOC@
+REPLACE_CANONICALIZE_FILE_NAME = @REPLACE_CANONICALIZE_FILE_NAME@
+REPLACE_CHOWN = @REPLACE_CHOWN@
+REPLACE_CLOSE = @REPLACE_CLOSE@
+REPLACE_CREAT = @REPLACE_CREAT@
+REPLACE_CTIME = @REPLACE_CTIME@
+REPLACE_DPRINTF = @REPLACE_DPRINTF@
+REPLACE_DUP = @REPLACE_DUP@
+REPLACE_DUP2 = @REPLACE_DUP2@
+REPLACE_DUPLOCALE = @REPLACE_DUPLOCALE@
+REPLACE_EXECL = @REPLACE_EXECL@
+REPLACE_EXECLE = @REPLACE_EXECLE@
+REPLACE_EXECLP = @REPLACE_EXECLP@
+REPLACE_EXECV = @REPLACE_EXECV@
+REPLACE_EXECVE = @REPLACE_EXECVE@
+REPLACE_EXECVP = @REPLACE_EXECVP@
+REPLACE_EXECVPE = @REPLACE_EXECVPE@
+REPLACE_FACCESSAT = @REPLACE_FACCESSAT@
+REPLACE_FCHMODAT = @REPLACE_FCHMODAT@
+REPLACE_FCHOWNAT = @REPLACE_FCHOWNAT@
+REPLACE_FCLOSE = @REPLACE_FCLOSE@
+REPLACE_FCNTL = @REPLACE_FCNTL@
+REPLACE_FDOPEN = @REPLACE_FDOPEN@
+REPLACE_FFLUSH = @REPLACE_FFLUSH@
+REPLACE_FFSLL = @REPLACE_FFSLL@
+REPLACE_FOPEN = @REPLACE_FOPEN@
+REPLACE_FPRINTF = @REPLACE_FPRINTF@
+REPLACE_FPURGE = @REPLACE_FPURGE@
+REPLACE_FREE = @REPLACE_FREE@
+REPLACE_FREELOCALE = @REPLACE_FREELOCALE@
+REPLACE_FREOPEN = @REPLACE_FREOPEN@
+REPLACE_FSEEK = @REPLACE_FSEEK@
+REPLACE_FSEEKO = @REPLACE_FSEEKO@
+REPLACE_FSTAT = @REPLACE_FSTAT@
+REPLACE_FSTATAT = @REPLACE_FSTATAT@
+REPLACE_FTELL = @REPLACE_FTELL@
+REPLACE_FTELLO = @REPLACE_FTELLO@
+REPLACE_FTRUNCATE = @REPLACE_FTRUNCATE@
+REPLACE_FUTIMENS = @REPLACE_FUTIMENS@
+REPLACE_GAI_STRERROR = @REPLACE_GAI_STRERROR@
+REPLACE_GETADDRINFO = @REPLACE_GETADDRINFO@
+REPLACE_GETCWD = @REPLACE_GETCWD@
+REPLACE_GETDELIM = @REPLACE_GETDELIM@
+REPLACE_GETDOMAINNAME = @REPLACE_GETDOMAINNAME@
+REPLACE_GETDTABLESIZE = @REPLACE_GETDTABLESIZE@
+REPLACE_GETGROUPS = @REPLACE_GETGROUPS@
+REPLACE_GETLINE = @REPLACE_GETLINE@
+REPLACE_GETLOGIN_R = @REPLACE_GETLOGIN_R@
+REPLACE_GETPAGESIZE = @REPLACE_GETPAGESIZE@
+REPLACE_GETPASS = @REPLACE_GETPASS@
+REPLACE_GETTIMEOFDAY = @REPLACE_GETTIMEOFDAY@
+REPLACE_GMTIME = @REPLACE_GMTIME@
+REPLACE_INET_NTOP = @REPLACE_INET_NTOP@
+REPLACE_INET_PTON = @REPLACE_INET_PTON@
+REPLACE_INITSTATE = @REPLACE_INITSTATE@
+REPLACE_IOCTL = @REPLACE_IOCTL@
+REPLACE_ISATTY = @REPLACE_ISATTY@
+REPLACE_ITOLD = @REPLACE_ITOLD@
+REPLACE_LCHOWN = @REPLACE_LCHOWN@
+REPLACE_LINK = @REPLACE_LINK@
+REPLACE_LINKAT = @REPLACE_LINKAT@
+REPLACE_LOCALECONV = @REPLACE_LOCALECONV@
+REPLACE_LOCALTIME = @REPLACE_LOCALTIME@
+REPLACE_LOCALTIME_R = @REPLACE_LOCALTIME_R@
+REPLACE_LSEEK = @REPLACE_LSEEK@
+REPLACE_LSTAT = @REPLACE_LSTAT@
+REPLACE_MALLOC = @REPLACE_MALLOC@
+REPLACE_MBRLEN = @REPLACE_MBRLEN@
+REPLACE_MBRTOWC = @REPLACE_MBRTOWC@
+REPLACE_MBSINIT = @REPLACE_MBSINIT@
+REPLACE_MBSNRTOWCS = @REPLACE_MBSNRTOWCS@
+REPLACE_MBSRTOWCS = @REPLACE_MBSRTOWCS@
+REPLACE_MBSTATE_T = @REPLACE_MBSTATE_T@
+REPLACE_MBTOWC = @REPLACE_MBTOWC@
+REPLACE_MEMCHR = @REPLACE_MEMCHR@
+REPLACE_MEMMEM = @REPLACE_MEMMEM@
+REPLACE_MKDIR = @REPLACE_MKDIR@
+REPLACE_MKFIFO = @REPLACE_MKFIFO@
+REPLACE_MKFIFOAT = @REPLACE_MKFIFOAT@
+REPLACE_MKNOD = @REPLACE_MKNOD@
+REPLACE_MKNODAT = @REPLACE_MKNODAT@
+REPLACE_MKSTEMP = @REPLACE_MKSTEMP@
+REPLACE_MKTIME = @REPLACE_MKTIME@
+REPLACE_NANOSLEEP = @REPLACE_NANOSLEEP@
+REPLACE_NEWLOCALE = @REPLACE_NEWLOCALE@
+REPLACE_NL_LANGINFO = @REPLACE_NL_LANGINFO@
+REPLACE_NULL = @REPLACE_NULL@
+REPLACE_OBSTACK_PRINTF = @REPLACE_OBSTACK_PRINTF@
+REPLACE_OPEN = @REPLACE_OPEN@
+REPLACE_OPENAT = @REPLACE_OPENAT@
+REPLACE_PERROR = @REPLACE_PERROR@
+REPLACE_POPEN = @REPLACE_POPEN@
+REPLACE_POSIX_MEMALIGN = @REPLACE_POSIX_MEMALIGN@
+REPLACE_PREAD = @REPLACE_PREAD@
+REPLACE_PRINTF = @REPLACE_PRINTF@
+REPLACE_PSELECT = @REPLACE_PSELECT@
+REPLACE_PTHREAD_ATTR_DESTROY = @REPLACE_PTHREAD_ATTR_DESTROY@
+REPLACE_PTHREAD_ATTR_GETDETACHSTATE = @REPLACE_PTHREAD_ATTR_GETDETACHSTATE@
+REPLACE_PTHREAD_ATTR_INIT = @REPLACE_PTHREAD_ATTR_INIT@
+REPLACE_PTHREAD_ATTR_SETDETACHSTATE = @REPLACE_PTHREAD_ATTR_SETDETACHSTATE@
+REPLACE_PTHREAD_CONDATTR_DESTROY = @REPLACE_PTHREAD_CONDATTR_DESTROY@
+REPLACE_PTHREAD_CONDATTR_INIT = @REPLACE_PTHREAD_CONDATTR_INIT@
+REPLACE_PTHREAD_COND_BROADCAST = @REPLACE_PTHREAD_COND_BROADCAST@
+REPLACE_PTHREAD_COND_DESTROY = @REPLACE_PTHREAD_COND_DESTROY@
+REPLACE_PTHREAD_COND_INIT = @REPLACE_PTHREAD_COND_INIT@
+REPLACE_PTHREAD_COND_SIGNAL = @REPLACE_PTHREAD_COND_SIGNAL@
+REPLACE_PTHREAD_COND_TIMEDWAIT = @REPLACE_PTHREAD_COND_TIMEDWAIT@
+REPLACE_PTHREAD_COND_WAIT = @REPLACE_PTHREAD_COND_WAIT@
+REPLACE_PTHREAD_CREATE = @REPLACE_PTHREAD_CREATE@
+REPLACE_PTHREAD_DETACH = @REPLACE_PTHREAD_DETACH@
+REPLACE_PTHREAD_EQUAL = @REPLACE_PTHREAD_EQUAL@
+REPLACE_PTHREAD_EXIT = @REPLACE_PTHREAD_EXIT@
+REPLACE_PTHREAD_GETSPECIFIC = @REPLACE_PTHREAD_GETSPECIFIC@
+REPLACE_PTHREAD_JOIN = @REPLACE_PTHREAD_JOIN@
+REPLACE_PTHREAD_KEY_CREATE = @REPLACE_PTHREAD_KEY_CREATE@
+REPLACE_PTHREAD_KEY_DELETE = @REPLACE_PTHREAD_KEY_DELETE@
+REPLACE_PTHREAD_MUTEXATTR_DESTROY = @REPLACE_PTHREAD_MUTEXATTR_DESTROY@
+REPLACE_PTHREAD_MUTEXATTR_GETROBUST = @REPLACE_PTHREAD_MUTEXATTR_GETROBUST@
+REPLACE_PTHREAD_MUTEXATTR_GETTYPE = @REPLACE_PTHREAD_MUTEXATTR_GETTYPE@
+REPLACE_PTHREAD_MUTEXATTR_INIT = @REPLACE_PTHREAD_MUTEXATTR_INIT@
+REPLACE_PTHREAD_MUTEXATTR_SETROBUST = @REPLACE_PTHREAD_MUTEXATTR_SETROBUST@
+REPLACE_PTHREAD_MUTEXATTR_SETTYPE = @REPLACE_PTHREAD_MUTEXATTR_SETTYPE@
+REPLACE_PTHREAD_MUTEX_DESTROY = @REPLACE_PTHREAD_MUTEX_DESTROY@
+REPLACE_PTHREAD_MUTEX_INIT = @REPLACE_PTHREAD_MUTEX_INIT@
+REPLACE_PTHREAD_MUTEX_LOCK = @REPLACE_PTHREAD_MUTEX_LOCK@
+REPLACE_PTHREAD_MUTEX_TIMEDLOCK = @REPLACE_PTHREAD_MUTEX_TIMEDLOCK@
+REPLACE_PTHREAD_MUTEX_TRYLOCK = @REPLACE_PTHREAD_MUTEX_TRYLOCK@
+REPLACE_PTHREAD_MUTEX_UNLOCK = @REPLACE_PTHREAD_MUTEX_UNLOCK@
+REPLACE_PTHREAD_ONCE = @REPLACE_PTHREAD_ONCE@
+REPLACE_PTHREAD_RWLOCKATTR_DESTROY = @REPLACE_PTHREAD_RWLOCKATTR_DESTROY@
+REPLACE_PTHREAD_RWLOCKATTR_INIT = @REPLACE_PTHREAD_RWLOCKATTR_INIT@
+REPLACE_PTHREAD_RWLOCK_DESTROY = @REPLACE_PTHREAD_RWLOCK_DESTROY@
+REPLACE_PTHREAD_RWLOCK_INIT = @REPLACE_PTHREAD_RWLOCK_INIT@
+REPLACE_PTHREAD_RWLOCK_RDLOCK = @REPLACE_PTHREAD_RWLOCK_RDLOCK@
+REPLACE_PTHREAD_RWLOCK_TIMEDRDLOCK = @REPLACE_PTHREAD_RWLOCK_TIMEDRDLOCK@
+REPLACE_PTHREAD_RWLOCK_TIMEDWRLOCK = @REPLACE_PTHREAD_RWLOCK_TIMEDWRLOCK@
+REPLACE_PTHREAD_RWLOCK_TRYRDLOCK = @REPLACE_PTHREAD_RWLOCK_TRYRDLOCK@
+REPLACE_PTHREAD_RWLOCK_TRYWRLOCK = @REPLACE_PTHREAD_RWLOCK_TRYWRLOCK@
+REPLACE_PTHREAD_RWLOCK_UNLOCK = @REPLACE_PTHREAD_RWLOCK_UNLOCK@
+REPLACE_PTHREAD_RWLOCK_WRLOCK = @REPLACE_PTHREAD_RWLOCK_WRLOCK@
+REPLACE_PTHREAD_SELF = @REPLACE_PTHREAD_SELF@
+REPLACE_PTHREAD_SETSPECIFIC = @REPLACE_PTHREAD_SETSPECIFIC@
+REPLACE_PTHREAD_SIGMASK = @REPLACE_PTHREAD_SIGMASK@
+REPLACE_PTHREAD_SPIN_DESTROY = @REPLACE_PTHREAD_SPIN_DESTROY@
+REPLACE_PTHREAD_SPIN_INIT = @REPLACE_PTHREAD_SPIN_INIT@
+REPLACE_PTHREAD_SPIN_LOCK = @REPLACE_PTHREAD_SPIN_LOCK@
+REPLACE_PTHREAD_SPIN_TRYLOCK = @REPLACE_PTHREAD_SPIN_TRYLOCK@
+REPLACE_PTHREAD_SPIN_UNLOCK = @REPLACE_PTHREAD_SPIN_UNLOCK@
+REPLACE_PTSNAME = @REPLACE_PTSNAME@
+REPLACE_PTSNAME_R = @REPLACE_PTSNAME_R@
+REPLACE_PUTENV = @REPLACE_PUTENV@
+REPLACE_PWRITE = @REPLACE_PWRITE@
+REPLACE_QSORT_R = @REPLACE_QSORT_R@
+REPLACE_RAISE = @REPLACE_RAISE@
+REPLACE_RANDOM = @REPLACE_RANDOM@
+REPLACE_RANDOM_R = @REPLACE_RANDOM_R@
+REPLACE_READ = @REPLACE_READ@
+REPLACE_READLINK = @REPLACE_READLINK@
+REPLACE_READLINKAT = @REPLACE_READLINKAT@
+REPLACE_REALLOC = @REPLACE_REALLOC@
+REPLACE_REALLOCARRAY = @REPLACE_REALLOCARRAY@
+REPLACE_REALPATH = @REPLACE_REALPATH@
+REPLACE_REMOVE = @REPLACE_REMOVE@
+REPLACE_RENAME = @REPLACE_RENAME@
+REPLACE_RENAMEAT = @REPLACE_RENAMEAT@
+REPLACE_RMDIR = @REPLACE_RMDIR@
+REPLACE_SCHED_YIELD = @REPLACE_SCHED_YIELD@
+REPLACE_SELECT = @REPLACE_SELECT@
+REPLACE_SETENV = @REPLACE_SETENV@
+REPLACE_SETLOCALE = @REPLACE_SETLOCALE@
+REPLACE_SETSTATE = @REPLACE_SETSTATE@
+REPLACE_SLEEP = @REPLACE_SLEEP@
+REPLACE_SNPRINTF = @REPLACE_SNPRINTF@
+REPLACE_SPRINTF = @REPLACE_SPRINTF@
+REPLACE_STAT = @REPLACE_STAT@
+REPLACE_STDIO_READ_FUNCS = @REPLACE_STDIO_READ_FUNCS@
+REPLACE_STDIO_WRITE_FUNCS = @REPLACE_STDIO_WRITE_FUNCS@
+REPLACE_STPNCPY = @REPLACE_STPNCPY@
+REPLACE_STRCASESTR = @REPLACE_STRCASESTR@
+REPLACE_STRCHRNUL = @REPLACE_STRCHRNUL@
+REPLACE_STRDUP = @REPLACE_STRDUP@
+REPLACE_STRERROR = @REPLACE_STRERROR@
+REPLACE_STRERRORNAME_NP = @REPLACE_STRERRORNAME_NP@
+REPLACE_STRERROR_R = @REPLACE_STRERROR_R@
+REPLACE_STRFTIME = @REPLACE_STRFTIME@
+REPLACE_STRNCAT = @REPLACE_STRNCAT@
+REPLACE_STRNDUP = @REPLACE_STRNDUP@
+REPLACE_STRNLEN = @REPLACE_STRNLEN@
+REPLACE_STRSIGNAL = @REPLACE_STRSIGNAL@
+REPLACE_STRSTR = @REPLACE_STRSTR@
+REPLACE_STRTOD = @REPLACE_STRTOD@
+REPLACE_STRTOIMAX = @REPLACE_STRTOIMAX@
+REPLACE_STRTOK_R = @REPLACE_STRTOK_R@
+REPLACE_STRTOL = @REPLACE_STRTOL@
+REPLACE_STRTOLD = @REPLACE_STRTOLD@
+REPLACE_STRTOLL = @REPLACE_STRTOLL@
+REPLACE_STRTOUL = @REPLACE_STRTOUL@
+REPLACE_STRTOULL = @REPLACE_STRTOULL@
+REPLACE_STRTOUMAX = @REPLACE_STRTOUMAX@
+REPLACE_STRUCT_LCONV = @REPLACE_STRUCT_LCONV@
+REPLACE_STRUCT_TIMEVAL = @REPLACE_STRUCT_TIMEVAL@
+REPLACE_SYMLINK = @REPLACE_SYMLINK@
+REPLACE_SYMLINKAT = @REPLACE_SYMLINKAT@
+REPLACE_TIMEGM = @REPLACE_TIMEGM@
+REPLACE_TMPFILE = @REPLACE_TMPFILE@
+REPLACE_TRUNCATE = @REPLACE_TRUNCATE@
+REPLACE_TTYNAME_R = @REPLACE_TTYNAME_R@
+REPLACE_TZSET = @REPLACE_TZSET@
+REPLACE_UNLINK = @REPLACE_UNLINK@
+REPLACE_UNLINKAT = @REPLACE_UNLINKAT@
+REPLACE_UNSETENV = @REPLACE_UNSETENV@
+REPLACE_USLEEP = @REPLACE_USLEEP@
+REPLACE_UTIMENSAT = @REPLACE_UTIMENSAT@
+REPLACE_VASPRINTF = @REPLACE_VASPRINTF@
+REPLACE_VDPRINTF = @REPLACE_VDPRINTF@
+REPLACE_VFPRINTF = @REPLACE_VFPRINTF@
+REPLACE_VPRINTF = @REPLACE_VPRINTF@
+REPLACE_VSNPRINTF = @REPLACE_VSNPRINTF@
+REPLACE_VSPRINTF = @REPLACE_VSPRINTF@
+REPLACE_WCRTOMB = @REPLACE_WCRTOMB@
+REPLACE_WCSFTIME = @REPLACE_WCSFTIME@
+REPLACE_WCSNRTOMBS = @REPLACE_WCSNRTOMBS@
+REPLACE_WCSRTOMBS = @REPLACE_WCSRTOMBS@
+REPLACE_WCSTOK = @REPLACE_WCSTOK@
+REPLACE_WCSWIDTH = @REPLACE_WCSWIDTH@
+REPLACE_WCTOB = @REPLACE_WCTOB@
+REPLACE_WCTOMB = @REPLACE_WCTOMB@
+REPLACE_WCWIDTH = @REPLACE_WCWIDTH@
+REPLACE_WRITE = @REPLACE_WRITE@
+SED = @SED@
+SERVENT_LIB = @SERVENT_LIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SIG_ATOMIC_T_SUFFIX = @SIG_ATOMIC_T_SUFFIX@
+SIZE_T_SUFFIX = @SIZE_T_SUFFIX@
+STDALIGN_H = @STDALIGN_H@
+STDBOOL_H = @STDBOOL_H@
+STDDEF_H = @STDDEF_H@
+STDINT_H = @STDINT_H@
+STRIP = @STRIP@
+SYS_IOCTL_H_HAVE_WINSOCK2_H = @SYS_IOCTL_H_HAVE_WINSOCK2_H@
+SYS_IOCTL_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS = @SYS_IOCTL_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS@
+SYS_TIME_H_DEFINES_STRUCT_TIMESPEC = @SYS_TIME_H_DEFINES_STRUCT_TIMESPEC@
+TIME_H_DEFINES_STRUCT_TIMESPEC = @TIME_H_DEFINES_STRUCT_TIMESPEC@
+TIME_H_DEFINES_TIME_UTC = @TIME_H_DEFINES_TIME_UTC@
+TROUSERS_LIB = @TROUSERS_LIB@
+TSS2_CFLAGS = @TSS2_CFLAGS@
+TSS2_LIBS = @TSS2_LIBS@
+TSS_CFLAGS = @TSS_CFLAGS@
+TSS_LIBS = @TSS_LIBS@
+UINT32_MAX_LT_UINTMAX_MAX = @UINT32_MAX_LT_UINTMAX_MAX@
+UINT64_MAX_EQ_ULONG_MAX = @UINT64_MAX_EQ_ULONG_MAX@
+UNBOUND_CFLAGS = @UNBOUND_CFLAGS@
+UNBOUND_LIBS = @UNBOUND_LIBS@
+UNDEFINE_STRTOK_R = @UNDEFINE_STRTOK_R@
+UNISTD_H_DEFINES_STRUCT_TIMESPEC = @UNISTD_H_DEFINES_STRUCT_TIMESPEC@
+UNISTD_H_HAVE_SYS_RANDOM_H = @UNISTD_H_HAVE_SYS_RANDOM_H@
+UNISTD_H_HAVE_WINSOCK2_H = @UNISTD_H_HAVE_WINSOCK2_H@
+UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS = @UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS@
+USE_NLS = @USE_NLS@
+VALGRIND = @VALGRIND@
+VALGRINDFLAGS = @VALGRINDFLAGS@
+VALGRIND_PROGRAM = @VALGRIND_PROGRAM@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+WCHAR_T_SUFFIX = @WCHAR_T_SUFFIX@
+WERROR_CFLAGS = @WERROR_CFLAGS@
+WINDOWS_64_BIT_OFF_T = @WINDOWS_64_BIT_OFF_T@
+WINDOWS_64_BIT_ST_SIZE = @WINDOWS_64_BIT_ST_SIZE@
+WINDOWS_STAT_INODES = @WINDOWS_STAT_INODES@
+WINDOWS_STAT_TIMESPEC = @WINDOWS_STAT_TIMESPEC@
+WINT_T_SUFFIX = @WINT_T_SUFFIX@
+WSTACK_CFLAGS = @WSTACK_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+YIELD_LIB = @YIELD_LIB@
+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_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_cv_sizeof_time_t = @ac_cv_sizeof_time_t@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+ggl_LIBOBJS = @ggl_LIBOBJS@
+ggl_LTLIBOBJS = @ggl_LTLIBOBJS@
+ggltests_LIBOBJS = @ggltests_LIBOBJS@
+ggltests_LTLIBOBJS = @ggltests_LTLIBOBJS@
+ggltests_WITNESS = @ggltests_WITNESS@
+gl_LIBOBJS = @gl_LIBOBJS@
+gl_LTLIBOBJS = @gl_LTLIBOBJS@
+gltests_LIBOBJS = @gltests_LIBOBJS@
+gltests_LTLIBOBJS = @gltests_LTLIBOBJS@
+gltests_WITNESS = @gltests_WITNESS@
+gnutls_so = @gnutls_so@
+guile_snarf = @guile_snarf@
+guileextensiondir = @guileextensiondir@
+guilesiteccachedir = @guilesiteccachedir@
+guilesitedir = @guilesitedir@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+ifGNUmake = @ifGNUmake@
+ifnGNUmake = @ifnGNUmake@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+maybe_guileextensiondir = @maybe_guileextensiondir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+unistring_LIBOBJS = @unistring_LIBOBJS@
+unistring_LTLIBOBJS = @unistring_LTLIBOBJS@
+unistringtests_LIBOBJS = @unistringtests_LIBOBJS@
+unistringtests_LTLIBOBJS = @unistringtests_LTLIBOBJS@
+unistringtests_WITNESS = @unistringtests_WITNESS@
+AM_CFLAGS = $(WERROR_CFLAGS) $(WSTACK_CFLAGS) $(WARN_CFLAGS) $(NETTLE_CFLAGS) \
+ $(LIBTASN1_CFLAGS) $(LIBIDN2_CFLAGS) $(P11_KIT_CFLAGS) $(LIBZSTD_CFLAGS) \
+ $(CODE_COVERAGE_CFLAGS)
+
+COMMON_LINK_FLAGS = $(CODE_COVERAGE_LDFLAGS)
+V_GPERF = $(V_GPERF_@AM_V@)
+V_GPERF_ = $(V_GPERF_@AM_DEFAULT_V@)
+V_GPERF_0 = @echo " GPERF " $@;
+AM_CPPFLAGS = -DASN1_BUILDING \
+ -I$(srcdir)/../../gl \
+ -I$(builddir)/../../gl \
+ -I$(srcdir)/..
+
+noinst_LTLIBRARIES = libminitasn1.la
+libminitasn1_la_SOURCES = libtasn1.h gstr.h int.h parser_aux.h \
+ structure.h element.h decoding.c gstr.c errors.c parser_aux.c \
+ structure.c element.c coding.c version.c
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/lib/common.mk $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/minitasn1/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign lib/minitasn1/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+$(top_srcdir)/lib/common.mk $(am__empty):
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+libminitasn1.la: $(libminitasn1_la_OBJECTS) $(libminitasn1_la_DEPENDENCIES) $(EXTRA_libminitasn1_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) $(libminitasn1_la_OBJECTS) $(libminitasn1_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coding.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/decoding.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/element.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/errors.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gstr.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parser_aux.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/structure.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/coding.Plo
+ -rm -f ./$(DEPDIR)/decoding.Plo
+ -rm -f ./$(DEPDIR)/element.Plo
+ -rm -f ./$(DEPDIR)/errors.Plo
+ -rm -f ./$(DEPDIR)/gstr.Plo
+ -rm -f ./$(DEPDIR)/parser_aux.Plo
+ -rm -f ./$(DEPDIR)/structure.Plo
+ -rm -f ./$(DEPDIR)/version.Plo
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/coding.Plo
+ -rm -f ./$(DEPDIR)/decoding.Plo
+ -rm -f ./$(DEPDIR)/element.Plo
+ -rm -f ./$(DEPDIR)/errors.Plo
+ -rm -f ./$(DEPDIR)/gstr.Plo
+ -rm -f ./$(DEPDIR)/parser_aux.Plo
+ -rm -f ./$(DEPDIR)/structure.Plo
+ -rm -f ./$(DEPDIR)/version.Plo
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
+ clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ cscopelist-am ctags ctags-am distclean distclean-compile \
+ distclean-generic distclean-libtool distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/lib/minitasn1/coding.c b/lib/minitasn1/coding.c
new file mode 100644
index 0000000..5a947a7
--- /dev/null
+++ b/lib/minitasn1/coding.c
@@ -0,0 +1,1413 @@
+/*
+ * Copyright (C) 2002-2021 Free Software Foundation, Inc.
+ *
+ * This file is part of LIBTASN1.
+ *
+ * The LIBTASN1 library is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ */
+
+
+/*****************************************************/
+/* File: coding.c */
+/* Description: Functions to create a DER coding of */
+/* an ASN1 type. */
+/*****************************************************/
+
+#include <int.h>
+#include "parser_aux.h"
+#include <gstr.h>
+#include "element.h"
+#include "minmax.h"
+#include <structure.h>
+
+#define MAX_TAG_LEN 16
+
+/******************************************************/
+/* Function : _asn1_error_description_value_not_found */
+/* Description: creates the ErrorDescription string */
+/* for the ASN1_VALUE_NOT_FOUND error. */
+/* Parameters: */
+/* node: node of the tree where the value is NULL. */
+/* ErrorDescription: string returned. */
+/* Return: */
+/******************************************************/
+static void
+_asn1_error_description_value_not_found (asn1_node node,
+ char *ErrorDescription)
+{
+
+ if (ErrorDescription == NULL)
+ return;
+
+ Estrcpy (ErrorDescription, ":: value of element '");
+ _asn1_hierarchical_name (node, ErrorDescription + strlen (ErrorDescription),
+ ASN1_MAX_ERROR_DESCRIPTION_SIZE - 40);
+ Estrcat (ErrorDescription, "' not found");
+
+}
+
+/**
+ * asn1_length_der:
+ * @len: value to convert.
+ * @der: buffer to hold the returned encoding (may be %NULL).
+ * @der_len: number of meaningful bytes of ANS (der[0]..der[der_len-1]).
+ *
+ * Creates the DER encoding of the provided length value.
+ * The @der buffer must have enough room for the output. The maximum
+ * length this function will encode is %ASN1_MAX_LENGTH_SIZE.
+ *
+ * To know the size of the DER encoding use a %NULL value for @der.
+ **/
+void
+asn1_length_der (unsigned long int len, unsigned char *der, int *der_len)
+{
+ int k;
+ unsigned char temp[ASN1_MAX_LENGTH_SIZE];
+#if SIZEOF_UNSIGNED_LONG_INT > 8
+ len &= 0xFFFFFFFFFFFFFFFF;
+#endif
+
+ if (len < 128)
+ {
+ /* short form */
+ if (der != NULL)
+ der[0] = (unsigned char) len;
+ *der_len = 1;
+ }
+ else
+ {
+ /* Long form */
+ k = 0;
+ while (len)
+ {
+ temp[k++] = len & 0xFF;
+ len = len >> 8;
+ }
+ *der_len = k + 1;
+ if (der != NULL)
+ {
+ der[0] = ((unsigned char) k & 0x7F) + 128;
+ while (k--)
+ der[*der_len - 1 - k] = temp[k];
+ }
+ }
+}
+
+/******************************************************/
+/* Function : _asn1_tag_der */
+/* Description: creates the DER coding for the CLASS */
+/* and TAG parameters. */
+/* It is limited by the ASN1_MAX_TAG_SIZE variable */
+/* Parameters: */
+/* class: value to convert. */
+/* tag_value: value to convert. */
+/* ans: string returned. */
+/* ans_len: number of meaningful bytes of ANS */
+/* (ans[0]..ans[ans_len-1]). */
+/* Return: */
+/******************************************************/
+static void
+_asn1_tag_der (unsigned char class, unsigned int tag_value,
+ unsigned char ans[ASN1_MAX_TAG_SIZE], int *ans_len)
+{
+ int k;
+ unsigned char temp[ASN1_MAX_TAG_SIZE];
+
+ if (tag_value < 31)
+ {
+ /* short form */
+ ans[0] = (class & 0xE0) + ((unsigned char) (tag_value & 0x1F));
+ *ans_len = 1;
+ }
+ else
+ {
+ /* Long form */
+ ans[0] = (class & 0xE0) + 31;
+ k = 0;
+ while (tag_value != 0)
+ {
+ temp[k++] = tag_value & 0x7F;
+ tag_value >>= 7;
+
+ if (k > ASN1_MAX_TAG_SIZE - 1)
+ break; /* will not encode larger tags */
+ }
+ *ans_len = k + 1;
+ while (k--)
+ ans[*ans_len - 1 - k] = temp[k] + 128;
+ ans[*ans_len - 1] -= 128;
+ }
+}
+
+/**
+ * asn1_octet_der:
+ * @str: the input data.
+ * @str_len: STR length (str[0]..str[*str_len-1]).
+ * @der: encoded string returned.
+ * @der_len: number of meaningful bytes of DER (der[0]..der[der_len-1]).
+ *
+ * Creates a length-value DER encoding for the input data.
+ * The DER encoding of the input data will be placed in the @der variable.
+ *
+ * Note that the OCTET STRING tag is not included in the output.
+ *
+ * This function does not return any value because it is expected
+ * that @der_len will contain enough bytes to store the string
+ * plus the DER encoding. The DER encoding size can be obtained using
+ * asn1_length_der().
+ **/
+void
+asn1_octet_der (const unsigned char *str, int str_len,
+ unsigned char *der, int *der_len)
+{
+ int len_len;
+
+ if (der == NULL || str_len < 0)
+ return;
+
+ asn1_length_der (str_len, der, &len_len);
+ memcpy (der + len_len, str, str_len);
+ *der_len = str_len + len_len;
+}
+
+
+/**
+ * asn1_encode_simple_der:
+ * @etype: The type of the string to be encoded (ASN1_ETYPE_)
+ * @str: the string data.
+ * @str_len: the string length
+ * @tl: the encoded tag and length
+ * @tl_len: the bytes of the @tl field
+ *
+ * Creates the DER encoding for various simple ASN.1 types like strings etc.
+ * It stores the tag and length in @tl, which should have space for at least
+ * %ASN1_MAX_TL_SIZE bytes. Initially @tl_len should contain the size of @tl.
+ *
+ * The complete DER encoding should consist of the value in @tl appended
+ * with the provided @str.
+ *
+ * Returns: %ASN1_SUCCESS if successful or an error value.
+ **/
+int
+asn1_encode_simple_der (unsigned int etype, const unsigned char *str,
+ unsigned int str_len, unsigned char *tl,
+ unsigned int *tl_len)
+{
+ int tag_len, len_len;
+ unsigned tlen;
+ unsigned char der_tag[ASN1_MAX_TAG_SIZE];
+ unsigned char der_length[ASN1_MAX_LENGTH_SIZE];
+ unsigned char *p;
+
+ if (str == NULL)
+ return ASN1_VALUE_NOT_VALID;
+
+ if (ETYPE_OK (etype) == 0)
+ return ASN1_VALUE_NOT_VALID;
+
+ /* doesn't handle constructed classes */
+ if (ETYPE_CLASS (etype) != ASN1_CLASS_UNIVERSAL)
+ return ASN1_VALUE_NOT_VALID;
+
+ _asn1_tag_der (ETYPE_CLASS (etype), ETYPE_TAG (etype), der_tag, &tag_len);
+
+ asn1_length_der (str_len, der_length, &len_len);
+
+ if (tag_len <= 0 || len_len <= 0)
+ return ASN1_VALUE_NOT_VALID;
+
+ tlen = tag_len + len_len;
+
+ if (*tl_len < tlen)
+ return ASN1_MEM_ERROR;
+
+ p = tl;
+ memcpy (p, der_tag, tag_len);
+ p += tag_len;
+ memcpy (p, der_length, len_len);
+
+ *tl_len = tlen;
+
+ return ASN1_SUCCESS;
+}
+
+/******************************************************/
+/* Function : _asn1_time_der */
+/* Description: creates the DER coding for a TIME */
+/* type (length included). */
+/* Parameters: */
+/* str: TIME null-terminated string. */
+/* der: string returned. */
+/* der_len: number of meaningful bytes of DER */
+/* (der[0]..der[ans_len-1]). Initially it */
+/* if must store the lenght of DER. */
+/* Return: */
+/* ASN1_MEM_ERROR when DER isn't big enough */
+/* ASN1_SUCCESS otherwise */
+/******************************************************/
+static int
+_asn1_time_der (unsigned char *str, int str_len, unsigned char *der,
+ int *der_len)
+{
+ int len_len;
+ int max_len;
+
+ max_len = *der_len;
+
+ asn1_length_der (str_len, (max_len > 0) ? der : NULL, &len_len);
+
+ if ((len_len + str_len) <= max_len)
+ memcpy (der + len_len, str, str_len);
+ *der_len = len_len + str_len;
+
+ if ((*der_len) > max_len)
+ return ASN1_MEM_ERROR;
+
+ return ASN1_SUCCESS;
+}
+
+
+/*
+void
+_asn1_get_utctime_der(unsigned char *der,int *der_len,unsigned char *str)
+{
+ int len_len,str_len;
+ char temp[20];
+
+ if(str==NULL) return;
+ str_len=asn1_get_length_der(der,*der_len,&len_len);
+ if (str_len<0) return;
+ memcpy(temp,der+len_len,str_len);
+ *der_len=str_len+len_len;
+ switch(str_len)
+ {
+ case 11:
+ temp[10]=0;
+ strcat(temp,"00+0000");
+ break;
+ case 13:
+ temp[12]=0;
+ strcat(temp,"+0000");
+ break;
+ case 15:
+ temp[15]=0;
+ memmove(temp+12,temp+10,6);
+ temp[10]=temp[11]='0';
+ break;
+ case 17:
+ temp[17]=0;
+ break;
+ default:
+ return;
+ }
+ strcpy(str,temp);
+}
+*/
+
+static
+void encode_val(uint64_t val, unsigned char *der, int max_len, int *der_len)
+{
+ int first, k;
+ unsigned char bit7;
+
+ first = 0;
+ for (k = sizeof(val); k >= 0; k--)
+ {
+ bit7 = (val >> (k * 7)) & 0x7F;
+ if (bit7 || first || !k)
+ {
+ if (k)
+ bit7 |= 0x80;
+ if (max_len > (*der_len))
+ der[*der_len] = bit7;
+ (*der_len)++;
+ first = 1;
+ }
+ }
+}
+
+/******************************************************/
+/* Function : _asn1_object_id_der */
+/* Description: creates the DER coding for an */
+/* OBJECT IDENTIFIER type (length included). */
+/* Parameters: */
+/* str: OBJECT IDENTIFIER null-terminated string. */
+/* der: string returned. */
+/* der_len: number of meaningful bytes of DER */
+/* (der[0]..der[ans_len-1]). Initially it */
+/* must store the length of DER. */
+/* Return: */
+/* ASN1_MEM_ERROR when DER isn't big enough */
+/* ASN1_SUCCESS if succesful */
+/* or an error value. */
+/******************************************************/
+static int
+_asn1_object_id_der (const char *str, unsigned char *der, int *der_len)
+{
+ int len_len, counter, max_len;
+ char *temp, *n_end, *n_start;
+ uint64_t val, val1 = 0;
+ int str_len = _asn1_strlen (str);
+
+ max_len = *der_len;
+ *der_len = 0;
+
+ if (der == NULL && max_len > 0)
+ return ASN1_VALUE_NOT_VALID;
+
+ temp = malloc (str_len + 2);
+ if (temp == NULL)
+ return ASN1_MEM_ALLOC_ERROR;
+
+ memcpy (temp, str, str_len);
+ temp[str_len] = '.';
+ temp[str_len + 1] = 0;
+
+ counter = 0;
+ n_start = temp;
+ while ((n_end = strchr (n_start, '.')))
+ {
+ *n_end = 0;
+ val = _asn1_strtou64 (n_start, NULL, 10);
+ counter++;
+
+ if (counter == 1)
+ {
+ val1 = val;
+ }
+ else if (counter == 2)
+ {
+ uint64_t val0;
+
+ if (val1 > 2)
+ {
+ free(temp);
+ return ASN1_VALUE_NOT_VALID;
+ }
+ else if ((val1 == 0 || val1 == 1) && val > 39)
+ {
+ free(temp);
+ return ASN1_VALUE_NOT_VALID;
+ }
+
+ val0 = 40 * val1 + val;
+ encode_val(val0, der, max_len, der_len);
+ }
+ else
+ {
+ encode_val(val, der, max_len, der_len);
+ }
+ n_start = n_end + 1;
+ }
+
+ asn1_length_der (*der_len, NULL, &len_len);
+ if (max_len >= (*der_len + len_len))
+ {
+ memmove (der + len_len, der, *der_len);
+ asn1_length_der (*der_len, der, &len_len);
+ }
+ *der_len += len_len;
+
+ free (temp);
+
+ if (max_len < (*der_len))
+ return ASN1_MEM_ERROR;
+
+ return ASN1_SUCCESS;
+}
+
+/**
+ * asn1_object_id_der:
+ * @str: An object identifier in numeric, dot format.
+ * @der: buffer to hold the returned encoding (may be %NULL).
+ * @der_len: initially the size of @der; will hold the final size.
+ * @flags: must be zero
+ *
+ * Creates the DER encoding of the provided object identifier.
+ *
+ * Returns: %ASN1_SUCCESS if DER encoding was OK, %ASN1_VALUE_NOT_VALID
+ * if @str is not a valid OID, %ASN1_MEM_ERROR if the @der
+ * vector isn't big enough and in this case @der_len will contain the
+ * length needed.
+ **/
+int asn1_object_id_der(const char *str, unsigned char *der, int *der_len, unsigned flags)
+{
+ unsigned char tag_der[MAX_TAG_LEN];
+ int tag_len = 0, r;
+ int max_len = *der_len;
+
+ *der_len = 0;
+
+ _asn1_tag_der (ETYPE_CLASS (ASN1_ETYPE_OBJECT_ID), ETYPE_TAG (ASN1_ETYPE_OBJECT_ID),
+ tag_der, &tag_len);
+
+ if (max_len > tag_len)
+ {
+ memcpy(der, tag_der, tag_len);
+ }
+ max_len -= tag_len;
+ der += tag_len;
+
+ r = _asn1_object_id_der (str, der, &max_len);
+ if (r == ASN1_MEM_ERROR || r == ASN1_SUCCESS)
+ {
+ *der_len = max_len + tag_len;
+ }
+
+ return r;
+}
+
+static const unsigned char bit_mask[] =
+ { 0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80 };
+
+/**
+ * asn1_bit_der:
+ * @str: BIT string.
+ * @bit_len: number of meaningful bits in STR.
+ * @der: string returned.
+ * @der_len: number of meaningful bytes of DER
+ * (der[0]..der[ans_len-1]).
+ *
+ * Creates a length-value DER encoding for the input data
+ * as it would have been for a BIT STRING.
+ * The DER encoded data will be copied in @der.
+ *
+ * Note that the BIT STRING tag is not included in the output.
+ *
+ * This function does not return any value because it is expected
+ * that @der_len will contain enough bytes to store the string
+ * plus the DER encoding. The DER encoding size can be obtained using
+ * asn1_length_der().
+ **/
+void
+asn1_bit_der (const unsigned char *str, int bit_len,
+ unsigned char *der, int *der_len)
+{
+ int len_len, len_byte, len_pad;
+
+ if (der == NULL)
+ return;
+
+ len_byte = bit_len >> 3;
+ len_pad = 8 - (bit_len & 7);
+ if (len_pad == 8)
+ len_pad = 0;
+ else
+ len_byte++;
+ asn1_length_der (len_byte + 1, der, &len_len);
+ der[len_len] = len_pad;
+
+ if (str)
+ memcpy (der + len_len + 1, str, len_byte);
+ der[len_len + len_byte] &= bit_mask[len_pad];
+ *der_len = len_byte + len_len + 1;
+}
+
+
+/******************************************************/
+/* Function : _asn1_complete_explicit_tag */
+/* Description: add the length coding to the EXPLICIT */
+/* tags. */
+/* Parameters: */
+/* node: pointer to the tree element. */
+/* der: string with the DER coding of the whole tree*/
+/* counter: number of meaningful bytes of DER */
+/* (der[0]..der[*counter-1]). */
+/* max_len: size of der vector */
+/* Return: */
+/* ASN1_MEM_ERROR if der vector isn't big enough, */
+/* otherwise ASN1_SUCCESS. */
+/******************************************************/
+static int
+_asn1_complete_explicit_tag (asn1_node node, unsigned char *der,
+ int *counter, int *max_len)
+{
+ asn1_node p;
+ int is_tag_implicit, len2, len3;
+ unsigned char temp[SIZEOF_UNSIGNED_INT];
+
+ if (der == NULL && *max_len > 0)
+ return ASN1_VALUE_NOT_VALID;
+
+ is_tag_implicit = 0;
+
+ if (node->type & CONST_TAG)
+ {
+ p = node->down;
+ if (p == NULL)
+ return ASN1_DER_ERROR;
+ /* When there are nested tags we must complete them reverse to
+ the order they were created. This is because completing a tag
+ modifies all data within it, including the incomplete tags
+ which store buffer positions -- simon@josefsson.org 2002-09-06
+ */
+ while (p->right)
+ p = p->right;
+ while (p && p != node->down->left)
+ {
+ if (type_field (p->type) == ASN1_ETYPE_TAG)
+ {
+ if (p->type & CONST_EXPLICIT)
+ {
+ len2 = strtol (p->name, NULL, 10);
+ _asn1_set_name (p, NULL);
+
+ asn1_length_der (*counter - len2, temp, &len3);
+ if (len3 <= (*max_len))
+ {
+ memmove (der + len2 + len3, der + len2,
+ *counter - len2);
+ memcpy (der + len2, temp, len3);
+ }
+ *max_len -= len3;
+ *counter += len3;
+ is_tag_implicit = 0;
+ }
+ else
+ { /* CONST_IMPLICIT */
+ if (!is_tag_implicit)
+ {
+ is_tag_implicit = 1;
+ }
+ }
+ }
+ p = p->left;
+ }
+ }
+
+ if (*max_len < 0)
+ return ASN1_MEM_ERROR;
+
+ return ASN1_SUCCESS;
+}
+
+const tag_and_class_st _asn1_tags[] = {
+ [ASN1_ETYPE_GENERALSTRING] =
+ {ASN1_TAG_GENERALSTRING, ASN1_CLASS_UNIVERSAL, "type:GENERALSTRING"},
+ [ASN1_ETYPE_NUMERIC_STRING] =
+ {ASN1_TAG_NUMERIC_STRING, ASN1_CLASS_UNIVERSAL, "type:NUMERIC_STR"},
+ [ASN1_ETYPE_IA5_STRING] =
+ {ASN1_TAG_IA5_STRING, ASN1_CLASS_UNIVERSAL, "type:IA5_STR"},
+ [ASN1_ETYPE_TELETEX_STRING] =
+ {ASN1_TAG_TELETEX_STRING, ASN1_CLASS_UNIVERSAL, "type:TELETEX_STR"},
+ [ASN1_ETYPE_PRINTABLE_STRING] =
+ {ASN1_TAG_PRINTABLE_STRING, ASN1_CLASS_UNIVERSAL, "type:PRINTABLE_STR"},
+ [ASN1_ETYPE_UNIVERSAL_STRING] =
+ {ASN1_TAG_UNIVERSAL_STRING, ASN1_CLASS_UNIVERSAL, "type:UNIVERSAL_STR"},
+ [ASN1_ETYPE_BMP_STRING] =
+ {ASN1_TAG_BMP_STRING, ASN1_CLASS_UNIVERSAL, "type:BMP_STR"},
+ [ASN1_ETYPE_UTF8_STRING] =
+ {ASN1_TAG_UTF8_STRING, ASN1_CLASS_UNIVERSAL, "type:UTF8_STR"},
+ [ASN1_ETYPE_VISIBLE_STRING] =
+ {ASN1_TAG_VISIBLE_STRING, ASN1_CLASS_UNIVERSAL, "type:VISIBLE_STR"},
+ [ASN1_ETYPE_OCTET_STRING] =
+ {ASN1_TAG_OCTET_STRING, ASN1_CLASS_UNIVERSAL, "type:OCT_STR"},
+ [ASN1_ETYPE_BIT_STRING] =
+ {ASN1_TAG_BIT_STRING, ASN1_CLASS_UNIVERSAL, "type:BIT_STR"},
+ [ASN1_ETYPE_OBJECT_ID] =
+ {ASN1_TAG_OBJECT_ID, ASN1_CLASS_UNIVERSAL, "type:OBJ_ID"},
+ [ASN1_ETYPE_NULL] = {ASN1_TAG_NULL, ASN1_CLASS_UNIVERSAL, "type:NULL"},
+ [ASN1_ETYPE_BOOLEAN] =
+ {ASN1_TAG_BOOLEAN, ASN1_CLASS_UNIVERSAL, "type:BOOLEAN"},
+ [ASN1_ETYPE_INTEGER] =
+ {ASN1_TAG_INTEGER, ASN1_CLASS_UNIVERSAL, "type:INTEGER"},
+ [ASN1_ETYPE_ENUMERATED] =
+ {ASN1_TAG_ENUMERATED, ASN1_CLASS_UNIVERSAL, "type:ENUMERATED"},
+ [ASN1_ETYPE_SEQUENCE] =
+ {ASN1_TAG_SEQUENCE, ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
+ "type:SEQUENCE"},
+ [ASN1_ETYPE_SEQUENCE_OF] =
+ {ASN1_TAG_SEQUENCE, ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
+ "type:SEQ_OF"},
+ [ASN1_ETYPE_SET] =
+ {ASN1_TAG_SET, ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED, "type:SET"},
+ [ASN1_ETYPE_SET_OF] =
+ {ASN1_TAG_SET, ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
+ "type:SET_OF"},
+ [ASN1_ETYPE_GENERALIZED_TIME] =
+ {ASN1_TAG_GENERALIZEDTime, ASN1_CLASS_UNIVERSAL, "type:GENERALIZED_TIME"},
+ [ASN1_ETYPE_UTC_TIME] =
+ {ASN1_TAG_UTCTime, ASN1_CLASS_UNIVERSAL, "type:UTC_TIME"},
+};
+
+unsigned int _asn1_tags_size = sizeof (_asn1_tags) / sizeof (_asn1_tags[0]);
+
+/******************************************************/
+/* Function : _asn1_insert_tag_der */
+/* Description: creates the DER coding of tags of one */
+/* NODE. */
+/* Parameters: */
+/* node: pointer to the tree element. */
+/* der: string returned */
+/* counter: number of meaningful bytes of DER */
+/* (counter[0]..der[*counter-1]). */
+/* max_len: size of der vector */
+/* Return: */
+/* ASN1_GENERIC_ERROR if the type is unknown, */
+/* ASN1_MEM_ERROR if der vector isn't big enough, */
+/* otherwise ASN1_SUCCESS. */
+/******************************************************/
+static int
+_asn1_insert_tag_der (asn1_node node, unsigned char *der, int *counter,
+ int *max_len)
+{
+ asn1_node p;
+ int tag_len, is_tag_implicit;
+ unsigned char class, class_implicit = 0, temp[MAX(SIZEOF_UNSIGNED_INT * 3 + 1, LTOSTR_MAX_SIZE)];
+ unsigned long tag_implicit = 0;
+ unsigned char tag_der[MAX_TAG_LEN];
+
+ is_tag_implicit = 0;
+
+ if (node->type & CONST_TAG)
+ {
+ p = node->down;
+ while (p)
+ {
+ if (type_field (p->type) == ASN1_ETYPE_TAG)
+ {
+ if (p->type & CONST_APPLICATION)
+ class = ASN1_CLASS_APPLICATION;
+ else if (p->type & CONST_UNIVERSAL)
+ class = ASN1_CLASS_UNIVERSAL;
+ else if (p->type & CONST_PRIVATE)
+ class = ASN1_CLASS_PRIVATE;
+ else
+ class = ASN1_CLASS_CONTEXT_SPECIFIC;
+
+ if (p->type & CONST_EXPLICIT)
+ {
+ if (is_tag_implicit)
+ _asn1_tag_der (class_implicit, tag_implicit, tag_der,
+ &tag_len);
+ else
+ _asn1_tag_der (class | ASN1_CLASS_STRUCTURED,
+ _asn1_strtoul (p->value, NULL, 10),
+ tag_der, &tag_len);
+
+ *max_len -= tag_len;
+ if (der && *max_len >= 0)
+ memcpy (der + *counter, tag_der, tag_len);
+ *counter += tag_len;
+
+ _asn1_ltostr (*counter, (char *) temp);
+ _asn1_set_name (p, (const char *) temp);
+
+ is_tag_implicit = 0;
+ }
+ else
+ { /* CONST_IMPLICIT */
+ if (!is_tag_implicit)
+ {
+ if ((type_field (node->type) == ASN1_ETYPE_SEQUENCE) ||
+ (type_field (node->type) == ASN1_ETYPE_SEQUENCE_OF)
+ || (type_field (node->type) == ASN1_ETYPE_SET)
+ || (type_field (node->type) == ASN1_ETYPE_SET_OF))
+ class |= ASN1_CLASS_STRUCTURED;
+ class_implicit = class;
+ tag_implicit = _asn1_strtoul (p->value, NULL, 10);
+ is_tag_implicit = 1;
+ }
+ }
+ }
+ p = p->right;
+ }
+ }
+
+ if (is_tag_implicit)
+ {
+ _asn1_tag_der (class_implicit, tag_implicit, tag_der, &tag_len);
+ }
+ else
+ {
+ unsigned type = type_field (node->type);
+ switch (type)
+ {
+ CASE_HANDLED_ETYPES:
+ _asn1_tag_der (_asn1_tags[type].class, _asn1_tags[type].tag,
+ tag_der, &tag_len);
+ break;
+ case ASN1_ETYPE_TAG:
+ case ASN1_ETYPE_CHOICE:
+ case ASN1_ETYPE_ANY:
+ tag_len = 0;
+ break;
+ default:
+ return ASN1_GENERIC_ERROR;
+ }
+ }
+
+ *max_len -= tag_len;
+ if (der && *max_len >= 0)
+ memcpy (der + *counter, tag_der, tag_len);
+ *counter += tag_len;
+
+ if (*max_len < 0)
+ return ASN1_MEM_ERROR;
+
+ return ASN1_SUCCESS;
+}
+
+/******************************************************/
+/* Function : _asn1_ordering_set */
+/* Description: puts the elements of a SET type in */
+/* the correct order according to DER rules. */
+/* Parameters: */
+/* der: string with the DER coding. */
+/* node: pointer to the SET element. */
+/* Return: */
+/* ASN1_SUCCESS if successful */
+/* or an error value. */
+/******************************************************/
+static int
+_asn1_ordering_set (unsigned char *der, int der_len, asn1_node node)
+{
+ struct vet
+ {
+ int end;
+ unsigned long value;
+ struct vet *next, *prev;
+ };
+
+ int counter, len, len2;
+ struct vet *first, *last, *p_vet, *p2_vet;
+ asn1_node p;
+ unsigned char class, *temp;
+ unsigned long tag, t;
+ int err;
+
+ counter = 0;
+
+ if (type_field (node->type) != ASN1_ETYPE_SET)
+ return ASN1_VALUE_NOT_VALID;
+
+ p = node->down;
+ while (p && ((type_field (p->type) == ASN1_ETYPE_TAG) ||
+ (type_field (p->type) == ASN1_ETYPE_SIZE)))
+ p = p->right;
+
+ if ((p == NULL) || (p->right == NULL))
+ return ASN1_SUCCESS;
+
+ first = last = NULL;
+ while (p)
+ {
+ p_vet = malloc (sizeof (struct vet));
+ if (p_vet == NULL)
+ {
+ err = ASN1_MEM_ALLOC_ERROR;
+ goto error;
+ }
+
+ p_vet->next = NULL;
+ p_vet->prev = last;
+ if (first == NULL)
+ first = p_vet;
+ else
+ last->next = p_vet;
+ last = p_vet;
+
+ /* tag value calculation */
+ err = asn1_get_tag_der (der + counter, der_len - counter, &class, &len2,
+ &tag);
+ if (err != ASN1_SUCCESS)
+ goto error;
+
+ t = ((unsigned int)class) << 24;
+ p_vet->value = t | tag;
+ counter += len2;
+
+ /* extraction and length */
+ len2 = asn1_get_length_der (der + counter, der_len - counter, &len);
+ if (len2 < 0)
+ {
+ err = ASN1_DER_ERROR;
+ goto error;
+ }
+ counter += len + len2;
+
+ p_vet->end = counter;
+ p = p->right;
+ }
+
+ p_vet = first;
+
+ while (p_vet)
+ {
+ p2_vet = p_vet->next;
+ counter = 0;
+ while (p2_vet)
+ {
+ if (p_vet->value > p2_vet->value)
+ {
+ /* change position */
+ temp = malloc (p_vet->end - counter);
+ if (temp == NULL)
+ {
+ err = ASN1_MEM_ALLOC_ERROR;
+ goto error;
+ }
+
+ memcpy (temp, der + counter, p_vet->end - counter);
+ memcpy (der + counter, der + p_vet->end,
+ p2_vet->end - p_vet->end);
+ memcpy (der + counter + p2_vet->end - p_vet->end, temp,
+ p_vet->end - counter);
+ free (temp);
+
+ tag = p_vet->value;
+ p_vet->value = p2_vet->value;
+ p2_vet->value = tag;
+
+ p_vet->end = counter + (p2_vet->end - p_vet->end);
+ }
+ counter = p_vet->end;
+
+ p2_vet = p2_vet->next;
+ p_vet = p_vet->next;
+ }
+
+ if (p_vet != first)
+ p_vet->prev->next = NULL;
+ else
+ first = NULL;
+ free (p_vet);
+ p_vet = first;
+ }
+ return ASN1_SUCCESS;
+
+error:
+ while (first != NULL)
+ {
+ p_vet = first;
+ first = first->next;
+ free(p_vet);
+ }
+ return err;
+}
+
+struct vet
+{
+ unsigned char *ptr;
+ int size;
+};
+
+static int setof_compar(const void *_e1, const void *_e2)
+{
+ unsigned length;
+ const struct vet *e1 = _e1, *e2 = _e2;
+ int rval;
+
+ /* The encodings of the component values of a set-of value shall
+ * appear in ascending order, the encodings being compared
+ * as octet strings with the shorter components being
+ * padded at their trailing end with 0-octets.
+ * The padding octets are for comparison purposes and
+ * do not appear in the encodings.
+ */
+ length = MIN(e1->size, e2->size);
+
+ rval = memcmp(e1->ptr, e2->ptr, length);
+ if (rval == 0 && e1->size != e2->size)
+ {
+ if (e1->size > e2->size)
+ rval = 1;
+ else if (e2->size > e1->size)
+ rval = -1;
+ }
+
+ return rval;
+}
+
+/******************************************************/
+/* Function : _asn1_ordering_set_of */
+/* Description: puts the elements of a SET OF type in */
+/* the correct order according to DER rules. */
+/* Parameters: */
+/* der: string with the DER coding. */
+/* node: pointer to the SET OF element. */
+/* Return: */
+/* ASN1_SUCCESS if successful */
+/* or an error value. */
+/******************************************************/
+static int
+_asn1_ordering_set_of (unsigned char *der, int der_len, asn1_node node)
+{
+ int counter, len, len2;
+ struct vet *list = NULL, *tlist;
+ unsigned list_size = 0;
+ struct vet *p_vet;
+ asn1_node p;
+ unsigned char class;
+ unsigned i;
+ unsigned char *out = NULL;
+ int err;
+
+ counter = 0;
+
+ if (type_field (node->type) != ASN1_ETYPE_SET_OF)
+ return ASN1_VALUE_NOT_VALID;
+
+ p = node->down;
+ while (p && ((type_field (p->type) == ASN1_ETYPE_TAG) ||
+ (type_field (p->type) == ASN1_ETYPE_SIZE)))
+ p = p->right;
+ if (p == NULL)
+ return ASN1_VALUE_NOT_VALID;
+ p = p->right;
+
+ if ((p == NULL) || (p->right == NULL))
+ return ASN1_SUCCESS;
+
+ while (p)
+ {
+ list_size++;
+ tlist = realloc (list, list_size*sizeof(struct vet));
+ if (tlist == NULL)
+ {
+ err = ASN1_MEM_ALLOC_ERROR;
+ goto error;
+ }
+ list = tlist;
+ p_vet = &list[list_size-1];
+
+ p_vet->ptr = der+counter;
+ p_vet->size = 0;
+
+ /* extraction of tag and length */
+ if (der_len - counter > 0)
+ {
+ err = asn1_get_tag_der (der + counter, der_len - counter, &class,
+ &len, NULL);
+ if (err != ASN1_SUCCESS)
+ goto error;
+ counter += len;
+ p_vet->size += len;
+
+ len2 = asn1_get_length_der (der + counter, der_len - counter, &len);
+ if (len2 < 0)
+ {
+ err = ASN1_DER_ERROR;
+ goto error;
+ }
+ counter += len + len2;
+ p_vet->size += len + len2;
+
+ }
+ else
+ {
+ err = ASN1_DER_ERROR;
+ goto error;
+ }
+ p = p->right;
+ }
+
+ if (counter > der_len)
+ {
+ err = ASN1_DER_ERROR;
+ goto error;
+ }
+
+ qsort(list, list_size, sizeof(struct vet), setof_compar);
+
+ out = malloc(der_len);
+ if (out == NULL)
+ {
+ err = ASN1_MEM_ERROR;
+ goto error;
+ }
+
+ /* the sum of p_vet->size == der_len */
+ counter = 0;
+ for (i = 0; i < list_size; i++)
+ {
+ p_vet = &list[i];
+ memcpy(out+counter, p_vet->ptr, p_vet->size);
+ counter += p_vet->size;
+ }
+ memcpy(der, out, der_len);
+ free(out);
+
+ err = ASN1_SUCCESS;
+
+error:
+ free(list);
+ return err;
+}
+
+/**
+ * asn1_der_coding:
+ * @element: pointer to an ASN1 element
+ * @name: the name of the structure you want to encode (it must be
+ * inside *POINTER).
+ * @ider: vector that will contain the DER encoding. DER must be a
+ * pointer to memory cells already allocated.
+ * @len: number of bytes of *@ider: @ider[0]..@ider[len-1], Initialy
+ * holds the sizeof of der vector.
+ * @ErrorDescription: return the error description or an empty
+ * string if success.
+ *
+ * Creates the DER encoding for the NAME structure (inside *POINTER
+ * structure).
+ *
+ * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
+ * if @name is not a valid element, %ASN1_VALUE_NOT_FOUND if there
+ * is an element without a value, %ASN1_MEM_ERROR if the @ider
+ * vector isn't big enough and in this case @len will contain the
+ * length needed.
+ **/
+int
+asn1_der_coding (asn1_node_const element, const char *name, void *ider, int *len,
+ char *ErrorDescription)
+{
+ asn1_node node, p, p2;
+ unsigned char temp[MAX(LTOSTR_MAX_SIZE, SIZEOF_UNSIGNED_LONG_INT * 3 + 1)];
+ int counter, counter_old, len2, len3, move, max_len, max_len_old;
+ int err;
+ unsigned char *der = ider;
+ unsigned char dummy;
+
+ if (ErrorDescription)
+ ErrorDescription[0] = 0;
+
+ node = asn1_find_node (element, name);
+ if (node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ /* Node is now a locally allocated variable.
+ * That is because in some point we modify the
+ * structure, and I don't know why! --nmav
+ */
+ node = _asn1_copy_structure3 (node);
+ if (node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ max_len = *len;
+
+ if (der == NULL && max_len > 0)
+ {
+ err = ASN1_VALUE_NOT_VALID;
+ goto error;
+ }
+
+ counter = 0;
+ move = DOWN;
+ p = node;
+
+ while (1)
+ {
+
+ counter_old = counter;
+ max_len_old = max_len;
+ if (move != UP)
+ {
+ p->start = counter;
+ err = _asn1_insert_tag_der (p, der, &counter, &max_len);
+ if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
+ goto error;
+ }
+ switch (type_field (p->type))
+ {
+ case ASN1_ETYPE_NULL:
+ max_len--;
+ if (der != NULL && max_len >= 0)
+ der[counter] = 0;
+ counter++;
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_BOOLEAN:
+ if ((p->type & CONST_DEFAULT) && (p->value == NULL))
+ {
+ counter = counter_old;
+ max_len = max_len_old;
+ }
+ else
+ {
+ if (p->value == NULL)
+ {
+ _asn1_error_description_value_not_found (p,
+ ErrorDescription);
+ err = ASN1_VALUE_NOT_FOUND;
+ goto error;
+ }
+ max_len -= 2;
+ if (der != NULL && max_len >= 0)
+ {
+ der[counter++] = 1;
+ if (p->value[0] == 'F')
+ der[counter++] = 0;
+ else
+ der[counter++] = 0xFF;
+ }
+ else
+ counter += 2;
+ }
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_INTEGER:
+ case ASN1_ETYPE_ENUMERATED:
+ if ((p->type & CONST_DEFAULT) && (p->value == NULL))
+ {
+ counter = counter_old;
+ max_len = max_len_old;
+ }
+ else
+ {
+ if (p->value == NULL)
+ {
+ _asn1_error_description_value_not_found (p,
+ ErrorDescription);
+ err = ASN1_VALUE_NOT_FOUND;
+ goto error;
+ }
+ len2 = asn1_get_length_der (p->value, p->value_len, &len3);
+ if (len2 < 0)
+ {
+ err = ASN1_DER_ERROR;
+ goto error;
+ }
+ max_len -= len2 + len3;
+ if (der != NULL && max_len >= 0)
+ memcpy (der + counter, p->value, len3 + len2);
+ counter += len3 + len2;
+ }
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_OBJECT_ID:
+ if ((p->type & CONST_DEFAULT) && (p->value == NULL))
+ {
+ counter = counter_old;
+ max_len = max_len_old;
+ }
+ else
+ {
+ if (p->value == NULL)
+ {
+ _asn1_error_description_value_not_found (p,
+ ErrorDescription);
+ err = ASN1_VALUE_NOT_FOUND;
+ goto error;
+ }
+ len2 = max_len;
+ err = _asn1_object_id_der ((char*)p->value, der ? der + counter : &dummy, &len2);
+ if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
+ goto error;
+
+ max_len -= len2;
+ counter += len2;
+ }
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_GENERALIZED_TIME:
+ case ASN1_ETYPE_UTC_TIME:
+ if (p->value == NULL)
+ {
+ _asn1_error_description_value_not_found (p, ErrorDescription);
+ err = ASN1_VALUE_NOT_FOUND;
+ goto error;
+ }
+ len2 = max_len;
+ err = _asn1_time_der (p->value, p->value_len, der ? der + counter : &dummy, &len2);
+ if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
+ goto error;
+
+ max_len -= len2;
+ counter += len2;
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_OCTET_STRING:
+ case ASN1_ETYPE_GENERALSTRING:
+ case ASN1_ETYPE_NUMERIC_STRING:
+ case ASN1_ETYPE_IA5_STRING:
+ case ASN1_ETYPE_TELETEX_STRING:
+ case ASN1_ETYPE_PRINTABLE_STRING:
+ case ASN1_ETYPE_UNIVERSAL_STRING:
+ case ASN1_ETYPE_BMP_STRING:
+ case ASN1_ETYPE_UTF8_STRING:
+ case ASN1_ETYPE_VISIBLE_STRING:
+ case ASN1_ETYPE_BIT_STRING:
+ if (p->value == NULL)
+ {
+ _asn1_error_description_value_not_found (p, ErrorDescription);
+ err = ASN1_VALUE_NOT_FOUND;
+ goto error;
+ }
+ len2 = asn1_get_length_der (p->value, p->value_len, &len3);
+ if (len2 < 0)
+ {
+ err = ASN1_DER_ERROR;
+ goto error;
+ }
+ max_len -= len2 + len3;
+ if (der != NULL && max_len >= 0)
+ memcpy (der + counter, p->value, len3 + len2);
+ counter += len3 + len2;
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_SEQUENCE:
+ case ASN1_ETYPE_SET:
+ if (move != UP)
+ {
+ p->tmp_ival = counter;
+ if (p->down == NULL)
+ {
+ move = UP;
+ continue;
+ }
+ else
+ {
+ p2 = p->down;
+ while (p2 && (type_field (p2->type) == ASN1_ETYPE_TAG))
+ p2 = p2->right;
+ if (p2)
+ {
+ p = p2;
+ move = RIGHT;
+ continue;
+ }
+ move = UP;
+ continue;
+ }
+ }
+ else
+ { /* move==UP */
+ len2 = p->tmp_ival;
+ p->tmp_ival = 0;
+ if ((type_field (p->type) == ASN1_ETYPE_SET) && (max_len >= 0))
+ {
+ err = _asn1_ordering_set (der ? der + len2 : &dummy, counter - len2, p);
+ if (err != ASN1_SUCCESS)
+ goto error;
+ }
+ asn1_length_der (counter - len2, temp, &len3);
+ max_len -= len3;
+ if (der != NULL && max_len >= 0)
+ {
+ memmove (der + len2 + len3, der + len2, counter - len2);
+ memcpy (der + len2, temp, len3);
+ }
+ counter += len3;
+ move = RIGHT;
+ }
+ break;
+ case ASN1_ETYPE_SEQUENCE_OF:
+ case ASN1_ETYPE_SET_OF:
+ if (move != UP)
+ {
+ p->tmp_ival = counter;
+ p = p->down;
+ while ((type_field (p->type) == ASN1_ETYPE_TAG)
+ || (type_field (p->type) == ASN1_ETYPE_SIZE))
+ p = p->right;
+ if (p->right)
+ {
+ p = p->right;
+ move = RIGHT;
+ continue;
+ }
+ else
+ p = _asn1_find_up (p);
+ move = UP;
+ }
+ if (move == UP)
+ {
+ len2 = p->tmp_ival;
+ p->tmp_ival = 0;
+ if ((type_field (p->type) == ASN1_ETYPE_SET_OF)
+ && (counter - len2 > 0) && (max_len >= 0))
+ {
+ err = _asn1_ordering_set_of (der ? der + len2 : &dummy, counter - len2, p);
+ if (err != ASN1_SUCCESS)
+ goto error;
+ }
+ asn1_length_der (counter - len2, temp, &len3);
+ max_len -= len3;
+ if (der != NULL && max_len >= 0)
+ {
+ memmove (der + len2 + len3, der + len2, counter - len2);
+ memcpy (der + len2, temp, len3);
+ }
+ counter += len3;
+ move = RIGHT;
+ }
+ break;
+ case ASN1_ETYPE_ANY:
+ if (p->value == NULL)
+ {
+ _asn1_error_description_value_not_found (p, ErrorDescription);
+ err = ASN1_VALUE_NOT_FOUND;
+ goto error;
+ }
+ len2 = asn1_get_length_der (p->value, p->value_len, &len3);
+ if (len2 < 0)
+ {
+ err = ASN1_DER_ERROR;
+ goto error;
+ }
+ max_len -= len2;
+ if (der != NULL && max_len >= 0)
+ memcpy (der + counter, p->value + len3, len2);
+ counter += len2;
+ move = RIGHT;
+ break;
+ default:
+ move = (move == UP) ? RIGHT : DOWN;
+ break;
+ }
+
+ if ((move != DOWN) && (counter != counter_old))
+ {
+ p->end = counter - 1;
+ err = _asn1_complete_explicit_tag (p, der, &counter, &max_len);
+ if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
+ goto error;
+ }
+
+ if (p == node && move != DOWN)
+ break;
+
+ if (move == DOWN)
+ {
+ if (p->down)
+ p = p->down;
+ else
+ move = RIGHT;
+ }
+ if (move == RIGHT)
+ {
+ if (p->right)
+ p = p->right;
+ else
+ move = UP;
+ }
+ if (move == UP)
+ p = _asn1_find_up (p);
+ }
+
+ *len = counter;
+
+ if (max_len < 0)
+ {
+ err = ASN1_MEM_ERROR;
+ goto error;
+ }
+
+ err = ASN1_SUCCESS;
+
+error:
+ asn1_delete_structure (&node);
+ return err;
+}
diff --git a/lib/minitasn1/decoding.c b/lib/minitasn1/decoding.c
new file mode 100644
index 0000000..378219c
--- /dev/null
+++ b/lib/minitasn1/decoding.c
@@ -0,0 +1,2478 @@
+/*
+ * Copyright (C) 2002-2021 Free Software Foundation, Inc.
+ *
+ * This file is part of LIBTASN1.
+ *
+ * The LIBTASN1 library is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ */
+
+
+/*****************************************************/
+/* File: decoding.c */
+/* Description: Functions to manage DER decoding */
+/*****************************************************/
+
+#include <int.h>
+#include <parser_aux.h>
+#include <gstr.h>
+#include <structure.h>
+#include <element.h>
+#include <limits.h>
+#include <intprops.h>
+#include "c-ctype.h"
+
+#ifdef DEBUG
+# define warn() fprintf(stderr, "%s: %d\n", __func__, __LINE__)
+#else
+# define warn()
+#endif
+
+#define IS_ERR(len, flags) (len < -1 || ((flags & ASN1_DECODE_FLAG_STRICT_DER) && len < 0))
+
+#define HAVE_TWO(x) (x>=2?1:0)
+
+/* Decoding flags (dflags) used in several decoding functions.
+ * DECODE_FLAG_HAVE_TAG: The provided buffer includes a tag
+ * DECODE_FLAG_CONSTRUCTED: The provided buffer is of indefinite encoding (useful
+ * when no tags are present).
+ * DECODE_FLAG_LEVEL1: Internal flag to indicate a level of recursion for BER strings.
+ * DECODE_FLAG_LEVEL2: Internal flag to indicate two levels of recursion for BER strings.
+ * DECODE_FLAG_LEVEL3: Internal flag to indicate three levels of recursion for BER strings.
+ * This is the maximum levels of recursion possible to prevent stack
+ * exhaustion.
+ */
+
+#define DECODE_FLAG_HAVE_TAG 1
+#define DECODE_FLAG_CONSTRUCTED (1<<1)
+#define DECODE_FLAG_LEVEL1 (1<<2)
+#define DECODE_FLAG_LEVEL2 (1<<3)
+#define DECODE_FLAG_LEVEL3 (1<<4)
+
+#define DECR_LEN(l, s) do { \
+ l -= s; \
+ if (l < 0) { \
+ warn(); \
+ result = ASN1_DER_ERROR; \
+ goto cleanup; \
+ } \
+ } while (0)
+
+static int
+_asn1_get_indefinite_length_string (const unsigned char *der, int der_len, int *len);
+
+static int
+_asn1_decode_simple_ber (unsigned int etype, const unsigned char *der,
+ unsigned int _der_len, unsigned char **str,
+ unsigned int *str_len, unsigned int *ber_len,
+ unsigned dflags);
+
+static int
+_asn1_decode_simple_der (unsigned int etype, const unsigned char *der,
+ unsigned int _der_len, const unsigned char **str,
+ unsigned int *str_len, unsigned dflags);
+
+static void
+_asn1_error_description_tag_error (asn1_node node, char *ErrorDescription)
+{
+
+ Estrcpy (ErrorDescription, ":: tag error near element '");
+ _asn1_hierarchical_name (node, ErrorDescription + strlen (ErrorDescription),
+ ASN1_MAX_ERROR_DESCRIPTION_SIZE - 40);
+ Estrcat (ErrorDescription, "'");
+
+}
+
+/**
+ * asn1_get_length_der:
+ * @der: DER data to decode.
+ * @der_len: Length of DER data to decode.
+ * @len: Output variable containing the length of the DER length field.
+ *
+ * Extract a length field from DER data.
+ *
+ * Returns: Return the decoded length value, or -1 on indefinite
+ * length, or -2 when the value was too big to fit in a int, or -4
+ * when the decoded length value plus @len would exceed @der_len.
+ **/
+long
+asn1_get_length_der (const unsigned char *der, int der_len, int *len)
+{
+ unsigned int ans;
+ int k, punt, sum;
+
+ *len = 0;
+ if (der_len <= 0)
+ return 0;
+
+ if (!(der[0] & 128))
+ {
+ /* short form */
+ *len = 1;
+ ans = der[0];
+ }
+ else
+ {
+ /* Long form */
+ k = der[0] & 0x7F;
+ punt = 1;
+ if (k)
+ { /* definite length method */
+ ans = 0;
+ while (punt <= k && punt < der_len)
+ {
+ if (INT_MULTIPLY_OVERFLOW (ans, 256))
+ return -2;
+ ans *= 256;
+
+ if (INT_ADD_OVERFLOW (ans, ((unsigned) der[punt])))
+ return -2;
+ ans += der[punt];
+ punt++;
+ }
+ }
+ else
+ { /* indefinite length method */
+ *len = punt;
+ return -1;
+ }
+
+ *len = punt;
+ }
+
+ sum = ans;
+ if (ans >= INT_MAX || INT_ADD_OVERFLOW (sum, (*len)))
+ return -2;
+ sum += *len;
+
+ if (sum > der_len)
+ return -4;
+
+ return ans;
+}
+
+/**
+ * asn1_get_tag_der:
+ * @der: DER data to decode.
+ * @der_len: Length of DER data to decode.
+ * @cls: Output variable containing decoded class.
+ * @len: Output variable containing the length of the DER TAG data.
+ * @tag: Output variable containing the decoded tag (may be %NULL).
+ *
+ * Decode the class and TAG from DER code.
+ *
+ * Returns: Returns %ASN1_SUCCESS on success, or an error.
+ **/
+int
+asn1_get_tag_der (const unsigned char *der, int der_len,
+ unsigned char *cls, int *len, unsigned long *tag)
+{
+ unsigned int ris;
+ int punt;
+
+ if (der == NULL || der_len < 2 || len == NULL)
+ return ASN1_DER_ERROR;
+
+ *cls = der[0] & 0xE0;
+ if ((der[0] & 0x1F) != 0x1F)
+ {
+ /* short form */
+ *len = 1;
+ ris = der[0] & 0x1F;
+ }
+ else
+ {
+ /* Long form */
+ punt = 1;
+ ris = 0;
+ while (punt < der_len && der[punt] & 128)
+ {
+
+ if (INT_MULTIPLY_OVERFLOW (ris, 128))
+ return ASN1_DER_ERROR;
+ ris *= 128;
+
+ if (INT_ADD_OVERFLOW (ris, ((unsigned) (der[punt] & 0x7F))))
+ return ASN1_DER_ERROR;
+ ris += (der[punt] & 0x7F);
+ punt++;
+ }
+
+ if (punt >= der_len)
+ return ASN1_DER_ERROR;
+
+ if (INT_MULTIPLY_OVERFLOW (ris, 128))
+ return ASN1_DER_ERROR;
+ ris *= 128;
+
+ if (INT_ADD_OVERFLOW (ris, ((unsigned) (der[punt] & 0x7F))))
+ return ASN1_DER_ERROR;
+ ris += (der[punt] & 0x7F);
+ punt++;
+
+ *len = punt;
+ }
+
+ if (tag)
+ *tag = ris;
+ return ASN1_SUCCESS;
+}
+
+/**
+ * asn1_get_length_ber:
+ * @ber: BER data to decode.
+ * @ber_len: Length of BER data to decode.
+ * @len: Output variable containing the length of the BER length field.
+ *
+ * Extract a length field from BER data. The difference to
+ * asn1_get_length_der() is that this function will return a length
+ * even if the value has indefinite encoding.
+ *
+ * Returns: Return the decoded length value, or negative value when
+ * the value was too big.
+ *
+ * Since: 2.0
+ **/
+long
+asn1_get_length_ber (const unsigned char *ber, int ber_len, int *len)
+{
+ int ret;
+ long err;
+
+ ret = asn1_get_length_der (ber, ber_len, len);
+
+ if (ret == -1 && ber_len > 1)
+ { /* indefinite length method */
+ err = _asn1_get_indefinite_length_string (ber + 1, ber_len-1, &ret);
+ if (err != ASN1_SUCCESS)
+ return -3;
+ }
+
+ return ret;
+}
+
+/**
+ * asn1_get_octet_der:
+ * @der: DER data to decode containing the OCTET SEQUENCE.
+ * @der_len: The length of the @der data to decode.
+ * @ret_len: Output variable containing the encoded length of the DER data.
+ * @str: Pre-allocated output buffer to put decoded OCTET SEQUENCE in.
+ * @str_size: Length of pre-allocated output buffer.
+ * @str_len: Output variable containing the length of the contents of the OCTET SEQUENCE.
+ *
+ * Extract an OCTET SEQUENCE from DER data. Note that this function
+ * expects the DER data past the tag field, i.e., the length and
+ * content octets.
+ *
+ * Returns: Returns %ASN1_SUCCESS on success, or an error.
+ **/
+int
+asn1_get_octet_der (const unsigned char *der, int der_len,
+ int *ret_len, unsigned char *str, int str_size,
+ int *str_len)
+{
+ int len_len = 0;
+
+ if (der_len <= 0)
+ return ASN1_GENERIC_ERROR;
+
+ *str_len = asn1_get_length_der (der, der_len, &len_len);
+
+ if (*str_len < 0)
+ return ASN1_DER_ERROR;
+
+ *ret_len = *str_len + len_len;
+ if (str_size >= *str_len)
+ {
+ if (*str_len > 0 && str != NULL)
+ memcpy (str, der + len_len, *str_len);
+ }
+ else
+ {
+ return ASN1_MEM_ERROR;
+ }
+
+ return ASN1_SUCCESS;
+}
+
+
+/*-
+ * _asn1_get_time_der:
+ * @type: %ASN1_ETYPE_GENERALIZED_TIME or %ASN1_ETYPE_UTC_TIME
+ * @der: DER data to decode containing the time
+ * @der_len: Length of DER data to decode.
+ * @ret_len: Output variable containing the length of the DER data.
+ * @str: Pre-allocated output buffer to put the textual time in.
+ * @str_size: Length of pre-allocated output buffer.
+ * @flags: Zero or %ASN1_DECODE_FLAG_STRICT_DER
+ *
+ * Performs basic checks in the DER encoded time object and returns its textual form.
+ * The textual form will be in the YYYYMMDD000000Z format for GeneralizedTime
+ * and YYMMDD000000Z for UTCTime.
+ *
+ * Returns: %ASN1_SUCCESS on success, or an error.
+ -*/
+static int
+_asn1_get_time_der (unsigned type, const unsigned char *der, int der_len, int *ret_len,
+ char *str, int str_size, unsigned flags)
+{
+ int len_len, str_len;
+ unsigned i;
+ unsigned sign_count = 0;
+ unsigned dot_count = 0;
+ const unsigned char *p;
+
+ if (der_len <= 0 || str == NULL)
+ return ASN1_DER_ERROR;
+
+ str_len = asn1_get_length_der (der, der_len, &len_len);
+ if (str_len <= 0 || str_size < str_len)
+ return ASN1_DER_ERROR;
+
+ /* perform some sanity checks on the data */
+ if (str_len < 8)
+ {
+ warn();
+ return ASN1_TIME_ENCODING_ERROR;
+ }
+
+ if ((flags & ASN1_DECODE_FLAG_STRICT_DER) && !(flags & ASN1_DECODE_FLAG_ALLOW_INCORRECT_TIME))
+ {
+ p = &der[len_len];
+ for (i=0;i<(unsigned)(str_len-1);i++)
+ {
+ if (c_isdigit(p[i]) == 0)
+ {
+ if (type == ASN1_ETYPE_GENERALIZED_TIME)
+ {
+ /* tolerate lax encodings */
+ if (p[i] == '.' && dot_count == 0)
+ {
+ dot_count++;
+ continue;
+ }
+
+ /* This is not really valid DER, but there are
+ * structures using that */
+ if (!(flags & ASN1_DECODE_FLAG_STRICT_DER) &&
+ (p[i] == '+' || p[i] == '-') && sign_count == 0)
+ {
+ sign_count++;
+ continue;
+ }
+ }
+
+ warn();
+ return ASN1_TIME_ENCODING_ERROR;
+ }
+ }
+
+ if (sign_count == 0 && p[str_len-1] != 'Z')
+ {
+ warn();
+ return ASN1_TIME_ENCODING_ERROR;
+ }
+ }
+ memcpy (str, der + len_len, str_len);
+ str[str_len] = 0;
+ *ret_len = str_len + len_len;
+
+ return ASN1_SUCCESS;
+}
+
+/**
+ * asn1_get_object_id_der:
+ * @der: DER data to decode containing the OBJECT IDENTIFIER
+ * @der_len: Length of DER data to decode.
+ * @ret_len: Output variable containing the length of the DER data.
+ * @str: Pre-allocated output buffer to put the textual object id in.
+ * @str_size: Length of pre-allocated output buffer.
+ *
+ * Converts a DER encoded object identifier to its textual form. This
+ * function expects the DER object identifier without the tag.
+ *
+ * Returns: %ASN1_SUCCESS on success, or an error.
+ **/
+int
+asn1_get_object_id_der (const unsigned char *der, int der_len, int *ret_len,
+ char *str, int str_size)
+{
+ int len_len, len, k;
+ int leading, parsed;
+ char temp[LTOSTR_MAX_SIZE];
+ uint64_t val, val1, val0;
+
+ *ret_len = 0;
+ if (str && str_size > 0)
+ str[0] = 0; /* no oid */
+
+ if (str == NULL || der_len <= 0)
+ return ASN1_GENERIC_ERROR;
+
+ len = asn1_get_length_der (der, der_len, &len_len);
+
+ if (len <= 0 || len + len_len > der_len)
+ return ASN1_DER_ERROR;
+
+ /* leading octet can never be 0x80 */
+ if (der[len_len] == 0x80)
+ return ASN1_DER_ERROR;
+
+ val0 = 0;
+
+ for (k = 0; k < len; k++)
+ {
+ if (INT_LEFT_SHIFT_OVERFLOW (val0, 7))
+ return ASN1_DER_ERROR;
+
+ val0 <<= 7;
+ val0 |= der[len_len + k] & 0x7F;
+ if (!(der[len_len + k] & 0x80))
+ break;
+ }
+ parsed = ++k;
+
+ /* val0 = (X*40) + Y, X={0,1,2}, Y<=39 when X={0,1} */
+ /* X = val, Y = val1 */
+
+ /* check if X == 0 */
+ val = 0;
+ val1 = val0;
+ if (val1 > 39)
+ {
+ val = 1;
+ val1 = val0 - 40;
+ if (val1 > 39)
+ {
+ val = 2;
+ val1 = val0 - 80;
+ }
+ }
+
+ _asn1_str_cpy (str, str_size, _asn1_ltostr (val, temp));
+ _asn1_str_cat (str, str_size, ".");
+ _asn1_str_cat (str, str_size, _asn1_ltostr (val1, temp));
+
+ val = 0;
+ leading = 1;
+ for (k = parsed; k < len; k++)
+ {
+ /* X.690 mandates that the leading byte must never be 0x80
+ */
+ if (leading != 0 && der[len_len + k] == 0x80)
+ return ASN1_DER_ERROR;
+ leading = 0;
+
+ /* check for wrap around */
+ if (INT_LEFT_SHIFT_OVERFLOW (val, 7))
+ return ASN1_DER_ERROR;
+
+ val = val << 7;
+ val |= der[len_len + k] & 0x7F;
+
+ if (!(der[len_len + k] & 0x80))
+ {
+ _asn1_str_cat (str, str_size, ".");
+ _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp));
+ val = 0;
+ leading = 1;
+ }
+ }
+
+ if (INT_ADD_OVERFLOW (len, len_len))
+ return ASN1_DER_ERROR;
+
+ *ret_len = len + len_len;
+
+ return ASN1_SUCCESS;
+}
+
+/**
+ * asn1_get_bit_der:
+ * @der: DER data to decode containing the BIT SEQUENCE.
+ * @der_len: Length of DER data to decode.
+ * @ret_len: Output variable containing the length of the DER data.
+ * @str: Pre-allocated output buffer to put decoded BIT SEQUENCE in.
+ * @str_size: Length of pre-allocated output buffer.
+ * @bit_len: Output variable containing the size of the BIT SEQUENCE.
+ *
+ * Extract a BIT SEQUENCE from DER data.
+ *
+ * Returns: %ASN1_SUCCESS on success, or an error.
+ **/
+int
+asn1_get_bit_der (const unsigned char *der, int der_len,
+ int *ret_len, unsigned char *str, int str_size,
+ int *bit_len)
+{
+ int len_len = 0, len_byte;
+
+ if (der_len <= 0)
+ return ASN1_GENERIC_ERROR;
+
+ len_byte = asn1_get_length_der (der, der_len, &len_len) - 1;
+ if (len_byte < 0)
+ return ASN1_DER_ERROR;
+
+ *ret_len = len_byte + len_len + 1;
+ *bit_len = len_byte * 8 - der[len_len];
+
+ if (*bit_len < 0)
+ return ASN1_DER_ERROR;
+
+ if (str_size >= len_byte)
+ {
+ if (len_byte > 0 && str)
+ memcpy (str, der + len_len + 1, len_byte);
+ }
+ else
+ {
+ return ASN1_MEM_ERROR;
+ }
+
+ return ASN1_SUCCESS;
+}
+
+/* tag_len: the total tag length (explicit+inner)
+ * inner_tag_len: the inner_tag length
+ */
+static int
+_asn1_extract_tag_der (asn1_node node, const unsigned char *der, int der_len,
+ int *tag_len, int *inner_tag_len, unsigned flags)
+{
+ asn1_node p;
+ int counter, len2, len3, is_tag_implicit;
+ int result;
+ unsigned long tag, tag_implicit = 0;
+ unsigned char class, class2, class_implicit = 0;
+
+ if (der_len <= 0)
+ return ASN1_GENERIC_ERROR;
+
+ counter = is_tag_implicit = 0;
+
+ if (node->type & CONST_TAG)
+ {
+ p = node->down;
+ while (p)
+ {
+ if (type_field (p->type) == ASN1_ETYPE_TAG)
+ {
+ if (p->type & CONST_APPLICATION)
+ class2 = ASN1_CLASS_APPLICATION;
+ else if (p->type & CONST_UNIVERSAL)
+ class2 = ASN1_CLASS_UNIVERSAL;
+ else if (p->type & CONST_PRIVATE)
+ class2 = ASN1_CLASS_PRIVATE;
+ else
+ class2 = ASN1_CLASS_CONTEXT_SPECIFIC;
+
+ if (p->type & CONST_EXPLICIT)
+ {
+ if (asn1_get_tag_der
+ (der + counter, der_len, &class, &len2,
+ &tag) != ASN1_SUCCESS)
+ return ASN1_DER_ERROR;
+
+ DECR_LEN(der_len, len2);
+ counter += len2;
+
+ if (flags & ASN1_DECODE_FLAG_STRICT_DER)
+ len3 =
+ asn1_get_length_der (der + counter, der_len,
+ &len2);
+ else
+ len3 =
+ asn1_get_length_ber (der + counter, der_len,
+ &len2);
+ if (len3 < 0)
+ return ASN1_DER_ERROR;
+
+ DECR_LEN(der_len, len2);
+ counter += len2;
+
+ if (!is_tag_implicit)
+ {
+ if ((class != (class2 | ASN1_CLASS_STRUCTURED)) ||
+ (tag != strtoul ((char *) p->value, NULL, 10)))
+ return ASN1_TAG_ERROR;
+ }
+ else
+ { /* ASN1_TAG_IMPLICIT */
+ if ((class != class_implicit) || (tag != tag_implicit))
+ return ASN1_TAG_ERROR;
+ }
+ is_tag_implicit = 0;
+ }
+ else
+ { /* ASN1_TAG_IMPLICIT */
+ if (!is_tag_implicit)
+ {
+ if ((type_field (node->type) == ASN1_ETYPE_SEQUENCE) ||
+ (type_field (node->type) == ASN1_ETYPE_SEQUENCE_OF)
+ || (type_field (node->type) == ASN1_ETYPE_SET)
+ || (type_field (node->type) == ASN1_ETYPE_SET_OF))
+ class2 |= ASN1_CLASS_STRUCTURED;
+ class_implicit = class2;
+ tag_implicit = strtoul ((char *) p->value, NULL, 10);
+ is_tag_implicit = 1;
+ }
+ }
+ }
+ p = p->right;
+ }
+ }
+
+ if (is_tag_implicit)
+ {
+ if (asn1_get_tag_der
+ (der + counter, der_len, &class, &len2,
+ &tag) != ASN1_SUCCESS)
+ return ASN1_DER_ERROR;
+
+ DECR_LEN(der_len, len2);
+
+ if ((class != class_implicit) || (tag != tag_implicit))
+ {
+ if (type_field (node->type) == ASN1_ETYPE_OCTET_STRING)
+ {
+ class_implicit |= ASN1_CLASS_STRUCTURED;
+ if ((class != class_implicit) || (tag != tag_implicit))
+ return ASN1_TAG_ERROR;
+ }
+ else
+ return ASN1_TAG_ERROR;
+ }
+ }
+ else
+ {
+ unsigned type = type_field (node->type);
+ if (type == ASN1_ETYPE_TAG)
+ {
+ *tag_len = 0;
+ if (inner_tag_len)
+ *inner_tag_len = 0;
+ return ASN1_SUCCESS;
+ }
+
+ if (asn1_get_tag_der
+ (der + counter, der_len, &class, &len2,
+ &tag) != ASN1_SUCCESS)
+ return ASN1_DER_ERROR;
+
+ DECR_LEN(der_len, len2);
+
+ switch (type)
+ {
+ case ASN1_ETYPE_NULL:
+ case ASN1_ETYPE_BOOLEAN:
+ case ASN1_ETYPE_INTEGER:
+ case ASN1_ETYPE_ENUMERATED:
+ case ASN1_ETYPE_OBJECT_ID:
+ case ASN1_ETYPE_GENERALSTRING:
+ case ASN1_ETYPE_NUMERIC_STRING:
+ case ASN1_ETYPE_IA5_STRING:
+ case ASN1_ETYPE_TELETEX_STRING:
+ case ASN1_ETYPE_PRINTABLE_STRING:
+ case ASN1_ETYPE_UNIVERSAL_STRING:
+ case ASN1_ETYPE_BMP_STRING:
+ case ASN1_ETYPE_UTF8_STRING:
+ case ASN1_ETYPE_VISIBLE_STRING:
+ case ASN1_ETYPE_BIT_STRING:
+ case ASN1_ETYPE_SEQUENCE:
+ case ASN1_ETYPE_SEQUENCE_OF:
+ case ASN1_ETYPE_SET:
+ case ASN1_ETYPE_SET_OF:
+ case ASN1_ETYPE_GENERALIZED_TIME:
+ case ASN1_ETYPE_UTC_TIME:
+ if ((class != _asn1_tags[type].class)
+ || (tag != _asn1_tags[type].tag))
+ return ASN1_DER_ERROR;
+ break;
+
+ case ASN1_ETYPE_OCTET_STRING:
+ /* OCTET STRING is handled differently to allow
+ * BER encodings (structured class). */
+ if (((class != ASN1_CLASS_UNIVERSAL)
+ && (class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED)))
+ || (tag != ASN1_TAG_OCTET_STRING))
+ return ASN1_DER_ERROR;
+ break;
+ case ASN1_ETYPE_ANY:
+ counter -= len2;
+ break;
+ case ASN1_ETYPE_CHOICE:
+ counter -= len2;
+ break;
+ default:
+ return ASN1_DER_ERROR;
+ break;
+ }
+ }
+
+ counter += len2;
+ *tag_len = counter;
+ if (inner_tag_len)
+ *inner_tag_len = len2;
+ return ASN1_SUCCESS;
+
+cleanup:
+ return result;
+}
+
+static int
+extract_tag_der_recursive(asn1_node node, const unsigned char *der, int der_len,
+ int *ret_len, int *inner_len, unsigned flags)
+{
+asn1_node p;
+int ris = ASN1_DER_ERROR;
+
+ if (type_field (node->type) == ASN1_ETYPE_CHOICE)
+ {
+ p = node->down;
+ while (p)
+ {
+ ris = _asn1_extract_tag_der (p, der, der_len, ret_len, inner_len, flags);
+ if (ris == ASN1_SUCCESS)
+ break;
+ p = p->right;
+ }
+
+ *ret_len = 0;
+ return ris;
+ }
+ else
+ return _asn1_extract_tag_der (node, der, der_len, ret_len, inner_len, flags);
+}
+
+static int
+_asn1_delete_not_used (asn1_node node)
+{
+ asn1_node p, p2;
+
+ if (node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ p = node;
+ while (p)
+ {
+ if (p->type & CONST_NOT_USED)
+ {
+ p2 = NULL;
+ if (p != node)
+ {
+ p2 = _asn1_find_left (p);
+ if (!p2)
+ p2 = _asn1_find_up (p);
+ }
+ asn1_delete_structure (&p);
+ p = p2;
+ }
+
+ if (!p)
+ break; /* reach node */
+
+ if (p->down)
+ {
+ p = p->down;
+ }
+ else
+ {
+ if (p == node)
+ p = NULL;
+ else if (p->right)
+ p = p->right;
+ else
+ {
+ while (1)
+ {
+ p = _asn1_find_up (p);
+ if (p == node)
+ {
+ p = NULL;
+ break;
+ }
+ if (p->right)
+ {
+ p = p->right;
+ break;
+ }
+ }
+ }
+ }
+ }
+ return ASN1_SUCCESS;
+}
+
+static int
+_asn1_get_indefinite_length_string (const unsigned char *der,
+ int der_len, int *len)
+{
+ int len2, len3, counter, indefinite;
+ int result;
+ unsigned long tag;
+ unsigned char class;
+
+ counter = indefinite = 0;
+
+ while (1)
+ {
+ if (HAVE_TWO(der_len) && (der[counter] == 0) && (der[counter + 1] == 0))
+ {
+ counter += 2;
+ DECR_LEN(der_len, 2);
+
+ indefinite--;
+ if (indefinite <= 0)
+ break;
+ else
+ continue;
+ }
+
+ if (asn1_get_tag_der
+ (der + counter, der_len, &class, &len2,
+ &tag) != ASN1_SUCCESS)
+ return ASN1_DER_ERROR;
+
+ DECR_LEN(der_len, len2);
+ counter += len2;
+
+ len2 = asn1_get_length_der (der + counter, der_len, &len3);
+ if (len2 < -1)
+ return ASN1_DER_ERROR;
+
+ if (len2 == -1)
+ {
+ indefinite++;
+ counter += 1;
+ DECR_LEN(der_len, 1);
+ }
+ else
+ {
+ counter += len2 + len3;
+ DECR_LEN(der_len, len2+len3);
+ }
+ }
+
+ *len = counter;
+ return ASN1_SUCCESS;
+
+cleanup:
+ return result;
+}
+
+static void delete_unneeded_choice_fields(asn1_node p)
+{
+ asn1_node p2;
+
+ while (p->right)
+ {
+ p2 = p->right;
+ asn1_delete_structure (&p2);
+ }
+}
+
+
+/**
+ * asn1_der_decoding2
+ * @element: pointer to an ASN1 structure.
+ * @ider: vector that contains the DER encoding.
+ * @max_ider_len: pointer to an integer giving the information about the
+ * maximal number of bytes occupied by *@ider. The real size of the DER
+ * encoding is returned through this pointer.
+ * @flags: flags controlling the behaviour of the function.
+ * @errorDescription: null-terminated string contains details when an
+ * error occurred.
+ *
+ * Fill the structure *@element with values of a DER encoding string. The
+ * structure must just be created with function asn1_create_element().
+ *
+ * If %ASN1_DECODE_FLAG_ALLOW_PADDING flag is set then the function will ignore
+ * padding after the decoded DER data. Upon a successful return the value of
+ * *@max_ider_len will be set to the number of bytes decoded.
+ *
+ * If %ASN1_DECODE_FLAG_STRICT_DER flag is set then the function will
+ * not decode any BER-encoded elements.
+ *
+ * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
+ * if @ELEMENT is %NULL, and %ASN1_TAG_ERROR or
+ * %ASN1_DER_ERROR if the der encoding doesn't match the structure
+ * name (*@ELEMENT deleted).
+ **/
+int
+asn1_der_decoding2 (asn1_node *element, const void *ider, int *max_ider_len,
+ unsigned int flags, char *errorDescription)
+{
+ asn1_node node, p, p2, p3;
+ char temp[128];
+ int counter, len2, len3, len4, move, ris, tlen;
+ struct node_tail_cache_st tcache = {NULL, NULL};
+ unsigned char class;
+ unsigned long tag;
+ int tag_len;
+ int indefinite, result, total_len = *max_ider_len, ider_len = *max_ider_len;
+ int inner_tag_len;
+ unsigned char *ptmp;
+ const unsigned char *ptag;
+ const unsigned char *der = ider;
+
+ node = *element;
+
+ if (errorDescription != NULL)
+ errorDescription[0] = 0;
+
+ if (node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ if (node->type & CONST_OPTION)
+ {
+ result = ASN1_GENERIC_ERROR;
+ warn();
+ goto cleanup;
+ }
+
+ counter = 0;
+ move = DOWN;
+ p = node;
+ while (1)
+ {
+ tag_len = 0;
+ inner_tag_len = 0;
+ ris = ASN1_SUCCESS;
+ if (move != UP)
+ {
+ if (p->type & CONST_SET)
+ {
+ p2 = _asn1_find_up (p);
+ len2 = p2->tmp_ival;
+ if (len2 == -1)
+ {
+ if (HAVE_TWO(ider_len) && !der[counter] && !der[counter + 1])
+ {
+ p = p2;
+ move = UP;
+ counter += 2;
+ DECR_LEN(ider_len, 2);
+ continue;
+ }
+ }
+ else if (counter == len2)
+ {
+ p = p2;
+ move = UP;
+ continue;
+ }
+ else if (counter > len2)
+ {
+ result = ASN1_DER_ERROR;
+ warn();
+ goto cleanup;
+ }
+ p2 = p2->down;
+ while (p2)
+ {
+ if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
+ {
+ ris =
+ extract_tag_der_recursive (p2, der + counter,
+ ider_len, &len2, NULL, flags);
+ if (ris == ASN1_SUCCESS)
+ {
+ p2->type &= ~CONST_NOT_USED;
+ p = p2;
+ break;
+ }
+ }
+ p2 = p2->right;
+ }
+ if (p2 == NULL)
+ {
+ result = ASN1_DER_ERROR;
+ warn();
+ goto cleanup;
+ }
+ }
+
+ /* the position in the DER structure this starts */
+ p->start = counter;
+ p->end = total_len - 1;
+
+ if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
+ {
+ p2 = _asn1_find_up (p);
+ len2 = p2->tmp_ival;
+ if (counter == len2)
+ {
+ if (p->right)
+ {
+ p2 = p->right;
+ move = RIGHT;
+ }
+ else
+ move = UP;
+
+ if (p->type & CONST_OPTION)
+ asn1_delete_structure (&p);
+
+ p = p2;
+ continue;
+ }
+ }
+
+ if (type_field (p->type) == ASN1_ETYPE_CHOICE)
+ {
+ while (p->down)
+ {
+ ris =
+ extract_tag_der_recursive (p->down, der + counter,
+ ider_len, &len2, NULL, flags);
+
+ if (ris == ASN1_SUCCESS)
+ {
+ delete_unneeded_choice_fields(p->down);
+ break;
+ }
+ else if (ris == ASN1_ERROR_TYPE_ANY)
+ {
+ result = ASN1_ERROR_TYPE_ANY;
+ warn();
+ goto cleanup;
+ }
+ else
+ {
+ p2 = p->down;
+ asn1_delete_structure (&p2);
+ }
+ }
+
+ if (p->down == NULL)
+ {
+ if (!(p->type & CONST_OPTION))
+ {
+ result = ASN1_DER_ERROR;
+ warn();
+ goto cleanup;
+ }
+ }
+ else if (type_field (p->type) != ASN1_ETYPE_CHOICE)
+ p = p->down;
+
+ p->start = counter;
+ }
+
+ if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
+ {
+ p2 = _asn1_find_up (p);
+ len2 = p2->tmp_ival;
+
+ if ((len2 != -1) && (counter > len2))
+ ris = ASN1_TAG_ERROR;
+ }
+
+ if (ris == ASN1_SUCCESS)
+ ris =
+ extract_tag_der_recursive (p, der + counter, ider_len,
+ &tag_len, &inner_tag_len, flags);
+
+ if (ris != ASN1_SUCCESS)
+ {
+ if (p->type & CONST_OPTION)
+ {
+ p->type |= CONST_NOT_USED;
+ move = RIGHT;
+ }
+ else if (p->type & CONST_DEFAULT)
+ {
+ _asn1_set_value (p, NULL, 0);
+ move = RIGHT;
+ }
+ else
+ {
+ if (errorDescription != NULL)
+ _asn1_error_description_tag_error (p, errorDescription);
+
+ result = ASN1_TAG_ERROR;
+ warn();
+ goto cleanup;
+ }
+ }
+ else
+ {
+ DECR_LEN(ider_len, tag_len);
+ counter += tag_len;
+ }
+ }
+
+ if (ris == ASN1_SUCCESS)
+ {
+ switch (type_field (p->type))
+ {
+ case ASN1_ETYPE_NULL:
+ DECR_LEN(ider_len, 1);
+ if (der[counter])
+ {
+ result = ASN1_DER_ERROR;
+ warn();
+ goto cleanup;
+ }
+ counter++;
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_BOOLEAN:
+ DECR_LEN(ider_len, 2);
+
+ if (der[counter++] != 1)
+ {
+ result = ASN1_DER_ERROR;
+ warn();
+ goto cleanup;
+ }
+ if (der[counter++] == 0)
+ _asn1_set_value (p, "F", 1);
+ else
+ _asn1_set_value (p, "T", 1);
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_INTEGER:
+ case ASN1_ETYPE_ENUMERATED:
+ len2 =
+ asn1_get_length_der (der + counter, ider_len, &len3);
+ if (len2 < 0)
+ {
+ result = ASN1_DER_ERROR;
+ warn();
+ goto cleanup;
+ }
+
+ DECR_LEN(ider_len, len3+len2);
+
+ _asn1_set_value (p, der + counter, len3 + len2);
+ counter += len3 + len2;
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_OBJECT_ID:
+ result =
+ asn1_get_object_id_der (der + counter, ider_len, &len2,
+ temp, sizeof (temp));
+ if (result != ASN1_SUCCESS)
+ {
+ warn();
+ goto cleanup;
+ }
+
+ DECR_LEN(ider_len, len2);
+
+ tlen = strlen (temp);
+ if (tlen > 0)
+ _asn1_set_value (p, temp, tlen + 1);
+
+ counter += len2;
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_GENERALIZED_TIME:
+ case ASN1_ETYPE_UTC_TIME:
+ result =
+ _asn1_get_time_der (type_field (p->type), der + counter, ider_len, &len2, temp,
+ sizeof (temp) - 1, flags);
+ if (result != ASN1_SUCCESS)
+ {
+ warn();
+ goto cleanup;
+ }
+
+ DECR_LEN(ider_len, len2);
+
+ tlen = strlen (temp);
+ if (tlen > 0)
+ _asn1_set_value (p, temp, tlen);
+
+ counter += len2;
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_OCTET_STRING:
+ if (counter < inner_tag_len)
+ {
+ result = ASN1_DER_ERROR;
+ warn();
+ goto cleanup;
+ }
+
+ ptag = der + counter - inner_tag_len;
+ if ((flags & ASN1_DECODE_FLAG_STRICT_DER) || !(ptag[0] & ASN1_CLASS_STRUCTURED))
+ {
+ if (ptag[0] & ASN1_CLASS_STRUCTURED)
+ {
+ result = ASN1_DER_ERROR;
+ warn();
+ goto cleanup;
+ }
+
+ len2 =
+ asn1_get_length_der (der + counter, ider_len, &len3);
+ if (len2 < 0)
+ {
+ result = ASN1_DER_ERROR;
+ warn();
+ goto cleanup;
+ }
+
+ DECR_LEN(ider_len, len3+len2);
+
+ _asn1_set_value (p, der + counter, len3 + len2);
+ counter += len3 + len2;
+ }
+ else
+ {
+ unsigned dflags = 0, vlen, ber_len;
+
+ if (ptag[0] & ASN1_CLASS_STRUCTURED)
+ dflags |= DECODE_FLAG_CONSTRUCTED;
+
+ result = _asn1_decode_simple_ber(type_field (p->type), der+counter, ider_len, &ptmp, &vlen, &ber_len, dflags);
+ if (result != ASN1_SUCCESS)
+ {
+ warn();
+ goto cleanup;
+ }
+
+ DECR_LEN(ider_len, ber_len);
+
+ _asn1_set_value_lv (p, ptmp, vlen);
+
+ counter += ber_len;
+ free(ptmp);
+ }
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_GENERALSTRING:
+ case ASN1_ETYPE_NUMERIC_STRING:
+ case ASN1_ETYPE_IA5_STRING:
+ case ASN1_ETYPE_TELETEX_STRING:
+ case ASN1_ETYPE_PRINTABLE_STRING:
+ case ASN1_ETYPE_UNIVERSAL_STRING:
+ case ASN1_ETYPE_BMP_STRING:
+ case ASN1_ETYPE_UTF8_STRING:
+ case ASN1_ETYPE_VISIBLE_STRING:
+ case ASN1_ETYPE_BIT_STRING:
+ len2 =
+ asn1_get_length_der (der + counter, ider_len, &len3);
+ if (len2 < 0)
+ {
+ result = ASN1_DER_ERROR;
+ warn();
+ goto cleanup;
+ }
+
+ DECR_LEN(ider_len, len3+len2);
+
+ _asn1_set_value (p, der + counter, len3 + len2);
+ counter += len3 + len2;
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_SEQUENCE:
+ case ASN1_ETYPE_SET:
+ if (move == UP)
+ {
+ len2 = p->tmp_ival;
+ p->tmp_ival = 0;
+ if (len2 == -1)
+ { /* indefinite length method */
+ DECR_LEN(ider_len, 2);
+ if ((der[counter]) || der[counter + 1])
+ {
+ result = ASN1_DER_ERROR;
+ warn();
+ goto cleanup;
+ }
+ counter += 2;
+ }
+ else
+ { /* definite length method */
+ if (len2 != counter)
+ {
+ result = ASN1_DER_ERROR;
+ warn();
+ goto cleanup;
+ }
+ }
+ move = RIGHT;
+ }
+ else
+ { /* move==DOWN || move==RIGHT */
+ len3 =
+ asn1_get_length_der (der + counter, ider_len, &len2);
+ if (IS_ERR(len3, flags))
+ {
+ result = ASN1_DER_ERROR;
+ warn();
+ goto cleanup;
+ }
+
+ DECR_LEN(ider_len, len2);
+ counter += len2;
+
+ if (len3 > 0)
+ {
+ p->tmp_ival = counter + len3;
+ move = DOWN;
+ }
+ else if (len3 == 0)
+ {
+ p2 = p->down;
+ while (p2)
+ {
+ if (type_field (p2->type) != ASN1_ETYPE_TAG)
+ {
+ p3 = p2->right;
+ asn1_delete_structure (&p2);
+ p2 = p3;
+ }
+ else
+ p2 = p2->right;
+ }
+ move = RIGHT;
+ }
+ else
+ { /* indefinite length method */
+ p->tmp_ival = -1;
+ move = DOWN;
+ }
+ }
+ break;
+ case ASN1_ETYPE_SEQUENCE_OF:
+ case ASN1_ETYPE_SET_OF:
+ if (move == UP)
+ {
+ len2 = p->tmp_ival;
+ if (len2 == -1)
+ { /* indefinite length method */
+ if (!HAVE_TWO(ider_len) || ((der[counter]) || der[counter + 1]))
+ {
+ result = _asn1_append_sequence_set (p, &tcache);
+ if (result != 0)
+ {
+ warn();
+ goto cleanup;
+ }
+ p = tcache.tail;
+ move = RIGHT;
+ continue;
+ }
+
+ p->tmp_ival = 0;
+ tcache.tail = NULL; /* finished decoding this structure */
+ tcache.head = NULL;
+ DECR_LEN(ider_len, 2);
+ counter += 2;
+ }
+ else
+ { /* definite length method */
+ if (len2 > counter)
+ {
+ result = _asn1_append_sequence_set (p, &tcache);
+ if (result != 0)
+ {
+ warn();
+ goto cleanup;
+ }
+ p = tcache.tail;
+ move = RIGHT;
+ continue;
+ }
+
+ p->tmp_ival = 0;
+ tcache.tail = NULL; /* finished decoding this structure */
+ tcache.head = NULL;
+
+ if (len2 != counter)
+ {
+ result = ASN1_DER_ERROR;
+ warn();
+ goto cleanup;
+ }
+ }
+ }
+ else
+ { /* move==DOWN || move==RIGHT */
+ len3 =
+ asn1_get_length_der (der + counter, ider_len, &len2);
+ if (IS_ERR(len3, flags))
+ {
+ result = ASN1_DER_ERROR;
+ warn();
+ goto cleanup;
+ }
+
+ DECR_LEN(ider_len, len2);
+ counter += len2;
+ if (len3)
+ {
+ if (len3 > 0)
+ { /* definite length method */
+ p->tmp_ival = counter + len3;
+ }
+ else
+ { /* indefinite length method */
+ p->tmp_ival = -1;
+ }
+
+ p2 = p->down;
+ if (p2 == NULL)
+ {
+ result = ASN1_DER_ERROR;
+ warn();
+ goto cleanup;
+ }
+
+ while ((type_field (p2->type) == ASN1_ETYPE_TAG)
+ || (type_field (p2->type) == ASN1_ETYPE_SIZE))
+ p2 = p2->right;
+ if (p2->right == NULL)
+ {
+ result = _asn1_append_sequence_set (p, &tcache);
+ if (result != 0)
+ {
+ warn();
+ goto cleanup;
+ }
+ }
+ p = p2;
+ }
+ }
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_ANY:
+ /* Check indefinite lenth method in an EXPLICIT TAG */
+
+ if (!(flags & ASN1_DECODE_FLAG_STRICT_DER) && (p->type & CONST_TAG) &&
+ tag_len == 2 && (der[counter - 1] == 0x80))
+ indefinite = 1;
+ else
+ indefinite = 0;
+
+ if (asn1_get_tag_der
+ (der + counter, ider_len, &class, &len2,
+ &tag) != ASN1_SUCCESS)
+ {
+ result = ASN1_DER_ERROR;
+ warn();
+ goto cleanup;
+ }
+
+ DECR_LEN(ider_len, len2);
+
+ len4 =
+ asn1_get_length_der (der + counter + len2,
+ ider_len, &len3);
+ if (IS_ERR(len4, flags))
+ {
+ result = ASN1_DER_ERROR;
+ warn();
+ goto cleanup;
+ }
+ if (len4 != -1) /* definite */
+ {
+ len2 += len4;
+
+ DECR_LEN(ider_len, len4+len3);
+ _asn1_set_value_lv (p, der + counter, len2 + len3);
+ counter += len2 + len3;
+ }
+ else /* == -1 */
+ { /* indefinite length */
+ ider_len += len2; /* undo DECR_LEN */
+
+ if (counter == 0)
+ {
+ result = ASN1_DER_ERROR;
+ warn();
+ goto cleanup;
+ }
+
+ result =
+ _asn1_get_indefinite_length_string (der + counter, ider_len, &len2);
+ if (result != ASN1_SUCCESS)
+ {
+ warn();
+ goto cleanup;
+ }
+
+ DECR_LEN(ider_len, len2);
+ _asn1_set_value_lv (p, der + counter, len2);
+ counter += len2;
+
+ }
+
+ /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
+ an indefinite length method. */
+ if (indefinite)
+ {
+ DECR_LEN(ider_len, 2);
+ if (!der[counter] && !der[counter + 1])
+ {
+ counter += 2;
+ }
+ else
+ {
+ result = ASN1_DER_ERROR;
+ warn();
+ goto cleanup;
+ }
+ }
+
+ move = RIGHT;
+ break;
+ default:
+ move = (move == UP) ? RIGHT : DOWN;
+ break;
+ }
+ }
+
+ if (p)
+ {
+ p->end = counter - 1;
+ }
+
+ if (p == node && move != DOWN)
+ break;
+
+ if (move == DOWN)
+ {
+ if (p->down)
+ p = p->down;
+ else
+ move = RIGHT;
+ }
+ if ((move == RIGHT) && !(p->type & CONST_SET))
+ {
+ if (p->right)
+ p = p->right;
+ else
+ move = UP;
+ }
+ if (move == UP)
+ p = _asn1_find_up (p);
+ }
+
+ _asn1_delete_not_used (*element);
+
+ if ((ider_len < 0) ||
+ (!(flags & ASN1_DECODE_FLAG_ALLOW_PADDING) && (ider_len != 0)))
+ {
+ warn();
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+
+ *max_ider_len = total_len - ider_len;
+
+ return ASN1_SUCCESS;
+
+cleanup:
+ asn1_delete_structure (element);
+ return result;
+}
+
+
+/**
+ * asn1_der_decoding:
+ * @element: pointer to an ASN1 structure.
+ * @ider: vector that contains the DER encoding.
+ * @ider_len: number of bytes of *@ider: @ider[0]..@ider[len-1].
+ * @errorDescription: null-terminated string contains details when an
+ * error occurred.
+ *
+ * Fill the structure *@element with values of a DER encoding
+ * string. The structure must just be created with function
+ * asn1_create_element().
+ *
+ * Note that the *@element variable is provided as a pointer for
+ * historical reasons.
+ *
+ * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
+ * if @ELEMENT is %NULL, and %ASN1_TAG_ERROR or
+ * %ASN1_DER_ERROR if the der encoding doesn't match the structure
+ * name (*@ELEMENT deleted).
+ **/
+int
+asn1_der_decoding (asn1_node * element, const void *ider, int ider_len,
+ char *errorDescription)
+{
+ return asn1_der_decoding2 (element, ider, &ider_len, 0, errorDescription);
+}
+
+/**
+ * asn1_der_decoding_element:
+ * @structure: pointer to an ASN1 structure
+ * @elementName: name of the element to fill
+ * @ider: vector that contains the DER encoding of the whole structure.
+ * @len: number of bytes of *der: der[0]..der[len-1]
+ * @errorDescription: null-terminated string contains details when an
+ * error occurred.
+ *
+ * Fill the element named @ELEMENTNAME with values of a DER encoding
+ * string. The structure must just be created with function
+ * asn1_create_element(). The DER vector must contain the encoding
+ * string of the whole @STRUCTURE. If an error occurs during the
+ * decoding procedure, the *@STRUCTURE is deleted and set equal to
+ * %NULL.
+ *
+ * This function is deprecated and may just be an alias to asn1_der_decoding
+ * in future versions. Use asn1_der_decoding() instead.
+ *
+ * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
+ * if ELEMENT is %NULL or @elementName == NULL, and
+ * %ASN1_TAG_ERROR or %ASN1_DER_ERROR if the der encoding doesn't
+ * match the structure @structure (*ELEMENT deleted).
+ **/
+int
+asn1_der_decoding_element (asn1_node * structure, const char *elementName,
+ const void *ider, int len, char *errorDescription)
+{
+ return asn1_der_decoding(structure, ider, len, errorDescription);
+}
+
+/**
+ * asn1_der_decoding_startEnd:
+ * @element: pointer to an ASN1 element
+ * @ider: vector that contains the DER encoding.
+ * @ider_len: number of bytes of *@ider: @ider[0]..@ider[len-1]
+ * @name_element: an element of NAME structure.
+ * @start: the position of the first byte of NAME_ELEMENT decoding
+ * (@ider[*start])
+ * @end: the position of the last byte of NAME_ELEMENT decoding
+ * (@ider[*end])
+ *
+ * Find the start and end point of an element in a DER encoding
+ * string. I mean that if you have a der encoding and you have already
+ * used the function asn1_der_decoding() to fill a structure, it may
+ * happen that you want to find the piece of string concerning an
+ * element of the structure.
+ *
+ * One example is the sequence "tbsCertificate" inside an X509
+ * certificate.
+ *
+ * Note that since libtasn1 3.7 the @ider and @ider_len parameters
+ * can be omitted, if the element is already decoded using asn1_der_decoding().
+ *
+ * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
+ * if ELEMENT is %asn1_node EMPTY or @name_element is not a valid
+ * element, %ASN1_TAG_ERROR or %ASN1_DER_ERROR if the der encoding
+ * doesn't match the structure ELEMENT.
+ **/
+int
+asn1_der_decoding_startEnd (asn1_node element, const void *ider, int ider_len,
+ const char *name_element, int *start, int *end)
+{
+ asn1_node node, node_to_find;
+ int result = ASN1_DER_ERROR;
+
+ node = element;
+
+ if (node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ node_to_find = asn1_find_node (node, name_element);
+
+ if (node_to_find == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ *start = node_to_find->start;
+ *end = node_to_find->end;
+
+ if (*start == 0 && *end == 0)
+ {
+ if (ider == NULL || ider_len == 0)
+ return ASN1_GENERIC_ERROR;
+
+ /* it seems asn1_der_decoding() wasn't called before. Do it now */
+ result = asn1_der_decoding (&node, ider, ider_len, NULL);
+ if (result != ASN1_SUCCESS)
+ {
+ warn();
+ return result;
+ }
+
+ node_to_find = asn1_find_node (node, name_element);
+ if (node_to_find == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ *start = node_to_find->start;
+ *end = node_to_find->end;
+ }
+
+ if (*end < *start)
+ return ASN1_GENERIC_ERROR;
+
+ return ASN1_SUCCESS;
+}
+
+/**
+ * asn1_expand_any_defined_by:
+ * @definitions: ASN1 definitions
+ * @element: pointer to an ASN1 structure
+ *
+ * Expands every "ANY DEFINED BY" element of a structure created from
+ * a DER decoding process (asn1_der_decoding function). The element
+ * ANY must be defined by an OBJECT IDENTIFIER. The type used to
+ * expand the element ANY is the first one following the definition of
+ * the actual value of the OBJECT IDENTIFIER.
+ *
+ * Returns: %ASN1_SUCCESS if Substitution OK, %ASN1_ERROR_TYPE_ANY if
+ * some "ANY DEFINED BY" element couldn't be expanded due to a
+ * problem in OBJECT_ID -> TYPE association, or other error codes
+ * depending on DER decoding.
+ **/
+int
+asn1_expand_any_defined_by (asn1_node_const definitions, asn1_node * element)
+{
+ char name[2 * ASN1_MAX_NAME_SIZE + 2],
+ value[ASN1_MAX_NAME_SIZE];
+ int retCode = ASN1_SUCCESS, result;
+ int len, len2, len3;
+ asn1_node_const p2;
+ asn1_node p, p3, aux = NULL;
+ char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
+ const char *definitionsName;
+
+ if ((definitions == NULL) || (*element == NULL))
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ definitionsName = definitions->name;
+
+ p = *element;
+ while (p)
+ {
+
+ switch (type_field (p->type))
+ {
+ case ASN1_ETYPE_ANY:
+ if ((p->type & CONST_DEFINED_BY) && (p->value))
+ {
+ /* search the "DEF_BY" element */
+ p2 = p->down;
+ while ((p2) && (type_field (p2->type) != ASN1_ETYPE_CONSTANT))
+ p2 = p2->right;
+
+ if (!p2)
+ {
+ retCode = ASN1_ERROR_TYPE_ANY;
+ break;
+ }
+
+ p3 = _asn1_find_up (p);
+
+ if (!p3)
+ {
+ retCode = ASN1_ERROR_TYPE_ANY;
+ break;
+ }
+
+ p3 = p3->down;
+ while (p3)
+ {
+ if (!(strcmp (p3->name, p2->name)))
+ break;
+ p3 = p3->right;
+ }
+
+ if ((!p3) || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID) ||
+ (p3->value == NULL))
+ {
+
+ p3 = _asn1_find_up (p);
+ p3 = _asn1_find_up (p3);
+
+ if (!p3)
+ {
+ retCode = ASN1_ERROR_TYPE_ANY;
+ break;
+ }
+
+ p3 = p3->down;
+
+ while (p3)
+ {
+ if (!(strcmp (p3->name, p2->name)))
+ break;
+ p3 = p3->right;
+ }
+
+ if ((!p3) || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID)
+ || (p3->value == NULL))
+ {
+ retCode = ASN1_ERROR_TYPE_ANY;
+ break;
+ }
+ }
+
+ /* search the OBJECT_ID into definitions */
+ p2 = definitions->down;
+ while (p2)
+ {
+ if ((type_field (p2->type) == ASN1_ETYPE_OBJECT_ID) &&
+ (p2->type & CONST_ASSIGN))
+ {
+ snprintf(name, sizeof(name), "%s.%s", definitionsName, p2->name);
+
+ len = ASN1_MAX_NAME_SIZE;
+ result =
+ asn1_read_value (definitions, name, value, &len);
+
+ if ((result == ASN1_SUCCESS)
+ && (!_asn1_strcmp (p3->value, value)))
+ {
+ p2 = p2->right; /* pointer to the structure to
+ use for expansion */
+ while ((p2) && (p2->type & CONST_ASSIGN))
+ p2 = p2->right;
+
+ if (p2)
+ {
+ snprintf(name, sizeof(name), "%s.%s", definitionsName, p2->name);
+
+ result =
+ asn1_create_element (definitions, name, &aux);
+ if (result == ASN1_SUCCESS)
+ {
+ _asn1_cpy_name (aux, p);
+ len2 =
+ asn1_get_length_der (p->value,
+ p->value_len, &len3);
+ if (len2 < 0)
+ return ASN1_DER_ERROR;
+
+ result =
+ asn1_der_decoding (&aux, p->value + len3,
+ len2,
+ errorDescription);
+ if (result == ASN1_SUCCESS)
+ {
+
+ _asn1_set_right (aux, p->right);
+ _asn1_set_right (p, aux);
+
+ result = asn1_delete_structure (&p);
+ if (result == ASN1_SUCCESS)
+ {
+ p = aux;
+ aux = NULL;
+ break;
+ }
+ else
+ { /* error with asn1_delete_structure */
+ asn1_delete_structure (&aux);
+ retCode = result;
+ break;
+ }
+ }
+ else
+ { /* error with asn1_der_decoding */
+ retCode = result;
+ break;
+ }
+ }
+ else
+ { /* error with asn1_create_element */
+ retCode = result;
+ break;
+ }
+ }
+ else
+ { /* error with the pointer to the structure to exapand */
+ retCode = ASN1_ERROR_TYPE_ANY;
+ break;
+ }
+ }
+ }
+ p2 = p2->right;
+ } /* end while */
+
+ if (!p2)
+ {
+ retCode = ASN1_ERROR_TYPE_ANY;
+ break;
+ }
+
+ }
+ break;
+ default:
+ break;
+ }
+
+
+ if (p->down)
+ {
+ p = p->down;
+ }
+ else if (p == *element)
+ {
+ p = NULL;
+ break;
+ }
+ else if (p->right)
+ p = p->right;
+ else
+ {
+ while (1)
+ {
+ p = _asn1_find_up (p);
+ if (p == *element)
+ {
+ p = NULL;
+ break;
+ }
+ if (p->right)
+ {
+ p = p->right;
+ break;
+ }
+ }
+ }
+ }
+
+ return retCode;
+}
+
+/**
+ * asn1_expand_octet_string:
+ * @definitions: ASN1 definitions
+ * @element: pointer to an ASN1 structure
+ * @octetName: name of the OCTECT STRING field to expand.
+ * @objectName: name of the OBJECT IDENTIFIER field to use to define
+ * the type for expansion.
+ *
+ * Expands an "OCTET STRING" element of a structure created from a DER
+ * decoding process (the asn1_der_decoding() function). The type used
+ * for expansion is the first one following the definition of the
+ * actual value of the OBJECT IDENTIFIER indicated by OBJECTNAME.
+ *
+ * Returns: %ASN1_SUCCESS if substitution OK, %ASN1_ELEMENT_NOT_FOUND
+ * if @objectName or @octetName are not correct,
+ * %ASN1_VALUE_NOT_VALID if it wasn't possible to find the type to
+ * use for expansion, or other errors depending on DER decoding.
+ **/
+int
+asn1_expand_octet_string (asn1_node_const definitions, asn1_node * element,
+ const char *octetName, const char *objectName)
+{
+ char name[2 * ASN1_MAX_NAME_SIZE + 1], value[ASN1_MAX_NAME_SIZE];
+ int retCode = ASN1_SUCCESS, result;
+ int len, len2, len3;
+ asn1_node_const p2;
+ asn1_node aux = NULL;
+ asn1_node octetNode = NULL, objectNode = NULL;
+ char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
+
+ if ((definitions == NULL) || (*element == NULL))
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ octetNode = asn1_find_node (*element, octetName);
+ if (octetNode == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+ if (type_field (octetNode->type) != ASN1_ETYPE_OCTET_STRING)
+ return ASN1_ELEMENT_NOT_FOUND;
+ if (octetNode->value == NULL)
+ return ASN1_VALUE_NOT_FOUND;
+
+ objectNode = asn1_find_node (*element, objectName);
+ if (objectNode == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ if (type_field (objectNode->type) != ASN1_ETYPE_OBJECT_ID)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ if (objectNode->value == NULL)
+ return ASN1_VALUE_NOT_FOUND;
+
+
+ /* search the OBJECT_ID into definitions */
+ p2 = definitions->down;
+ while (p2)
+ {
+ if ((type_field (p2->type) == ASN1_ETYPE_OBJECT_ID) &&
+ (p2->type & CONST_ASSIGN))
+ {
+ strcpy (name, definitions->name);
+ strcat (name, ".");
+ strcat (name, p2->name);
+
+ len = sizeof (value);
+ result = asn1_read_value (definitions, name, value, &len);
+
+ if ((result == ASN1_SUCCESS)
+ && (!_asn1_strcmp (objectNode->value, value)))
+ {
+
+ p2 = p2->right; /* pointer to the structure to
+ use for expansion */
+ while ((p2) && (p2->type & CONST_ASSIGN))
+ p2 = p2->right;
+
+ if (p2)
+ {
+ strcpy (name, definitions->name);
+ strcat (name, ".");
+ strcat (name, p2->name);
+
+ result = asn1_create_element (definitions, name, &aux);
+ if (result == ASN1_SUCCESS)
+ {
+ _asn1_cpy_name (aux, octetNode);
+ len2 =
+ asn1_get_length_der (octetNode->value,
+ octetNode->value_len, &len3);
+ if (len2 < 0)
+ return ASN1_DER_ERROR;
+
+ result =
+ asn1_der_decoding (&aux, octetNode->value + len3,
+ len2, errorDescription);
+ if (result == ASN1_SUCCESS)
+ {
+
+ _asn1_set_right (aux, octetNode->right);
+ _asn1_set_right (octetNode, aux);
+
+ result = asn1_delete_structure (&octetNode);
+ if (result == ASN1_SUCCESS)
+ {
+ aux = NULL;
+ break;
+ }
+ else
+ { /* error with asn1_delete_structure */
+ asn1_delete_structure (&aux);
+ retCode = result;
+ break;
+ }
+ }
+ else
+ { /* error with asn1_der_decoding */
+ retCode = result;
+ break;
+ }
+ }
+ else
+ { /* error with asn1_create_element */
+ retCode = result;
+ break;
+ }
+ }
+ else
+ { /* error with the pointer to the structure to exapand */
+ retCode = ASN1_VALUE_NOT_VALID;
+ break;
+ }
+ }
+ }
+
+ p2 = p2->right;
+
+ }
+
+ if (!p2)
+ retCode = ASN1_VALUE_NOT_VALID;
+
+ return retCode;
+}
+
+/*-
+ * _asn1_decode_simple_der:
+ * @etype: The type of the string to be encoded (ASN1_ETYPE_)
+ * @der: the encoded string
+ * @_der_len: the bytes of the encoded string
+ * @str: a pointer to the data
+ * @str_len: the length of the data
+ * @dflags: DECODE_FLAG_*
+ *
+ * Decodes a simple DER encoded type (e.g. a string, which is not constructed).
+ * The output is a pointer inside the @der.
+ *
+ * Returns: %ASN1_SUCCESS if successful or an error value.
+ -*/
+static int
+_asn1_decode_simple_der (unsigned int etype, const unsigned char *der,
+ unsigned int _der_len, const unsigned char **str,
+ unsigned int *str_len, unsigned dflags)
+{
+ int tag_len, len_len;
+ const unsigned char *p;
+ int der_len = _der_len;
+ unsigned char class;
+ unsigned long tag;
+ long ret;
+
+ if (der == NULL || der_len == 0)
+ return ASN1_VALUE_NOT_VALID;
+
+ if (ETYPE_OK (etype) == 0 || ETYPE_IS_STRING(etype) == 0)
+ return ASN1_VALUE_NOT_VALID;
+
+ /* doesn't handle constructed classes */
+ class = ETYPE_CLASS(etype);
+ if (class != ASN1_CLASS_UNIVERSAL)
+ return ASN1_VALUE_NOT_VALID;
+
+ p = der;
+
+ if (dflags & DECODE_FLAG_HAVE_TAG)
+ {
+ ret = asn1_get_tag_der (p, der_len, &class, &tag_len, &tag);
+ if (ret != ASN1_SUCCESS)
+ return ret;
+
+ if (class != ETYPE_CLASS (etype) || tag != ETYPE_TAG (etype))
+ {
+ warn();
+ return ASN1_DER_ERROR;
+ }
+
+ p += tag_len;
+ der_len -= tag_len;
+ if (der_len <= 0)
+ return ASN1_DER_ERROR;
+ }
+
+ ret = asn1_get_length_der (p, der_len, &len_len);
+ if (ret < 0)
+ return ASN1_DER_ERROR;
+
+ p += len_len;
+ der_len -= len_len;
+ if (der_len <= 0)
+ return ASN1_DER_ERROR;
+
+ *str_len = ret;
+ *str = p;
+
+ return ASN1_SUCCESS;
+}
+
+/**
+ * asn1_decode_simple_der:
+ * @etype: The type of the string to be encoded (ASN1_ETYPE_)
+ * @der: the encoded string
+ * @_der_len: the bytes of the encoded string
+ * @str: a pointer to the data
+ * @str_len: the length of the data
+ *
+ * Decodes a simple DER encoded type (e.g. a string, which is not constructed).
+ * The output is a pointer inside the @der.
+ *
+ * Returns: %ASN1_SUCCESS if successful or an error value.
+ **/
+int
+asn1_decode_simple_der (unsigned int etype, const unsigned char *der,
+ unsigned int _der_len, const unsigned char **str,
+ unsigned int *str_len)
+{
+ return _asn1_decode_simple_der(etype, der, _der_len, str, str_len, DECODE_FLAG_HAVE_TAG);
+}
+
+static int append(uint8_t **dst, unsigned *dst_size, const unsigned char *src, unsigned src_size)
+{
+ if (src_size == 0)
+ return ASN1_SUCCESS;
+
+ *dst = _asn1_realloc(*dst, *dst_size+src_size);
+ if (*dst == NULL)
+ return ASN1_MEM_ALLOC_ERROR;
+ memcpy(*dst + *dst_size, src, src_size);
+ *dst_size += src_size;
+ return ASN1_SUCCESS;
+}
+
+/*-
+ * _asn1_decode_simple_ber:
+ * @etype: The type of the string to be encoded (ASN1_ETYPE_)
+ * @der: the encoded string
+ * @_der_len: the bytes of the encoded string
+ * @str: a pointer to the data
+ * @str_len: the length of the data
+ * @ber_len: the total length occupied by BER (may be %NULL)
+ * @have_tag: whether a DER tag is included
+ *
+ * Decodes a BER encoded type. The output is an allocated value
+ * of the data. This decodes BER STRINGS only. Other types are
+ * decoded as DER.
+ *
+ * Returns: %ASN1_SUCCESS if successful or an error value.
+ -*/
+static int
+_asn1_decode_simple_ber (unsigned int etype, const unsigned char *der,
+ unsigned int _der_len, unsigned char **str,
+ unsigned int *str_len, unsigned int *ber_len,
+ unsigned dflags)
+{
+ int tag_len, len_len;
+ const unsigned char *p;
+ int der_len = _der_len;
+ uint8_t *total = NULL;
+ unsigned total_size = 0;
+ unsigned char class;
+ unsigned long tag;
+ unsigned char *out = NULL;
+ const unsigned char *cout = NULL;
+ unsigned out_len;
+ long result;
+
+ if (ber_len) *ber_len = 0;
+
+ if (der == NULL || der_len == 0)
+ {
+ warn();
+ return ASN1_VALUE_NOT_VALID;
+ }
+
+ if (ETYPE_OK (etype) == 0)
+ {
+ warn();
+ return ASN1_VALUE_NOT_VALID;
+ }
+
+ /* doesn't handle constructed + definite classes */
+ class = ETYPE_CLASS (etype);
+ if (class != ASN1_CLASS_UNIVERSAL)
+ {
+ warn();
+ return ASN1_VALUE_NOT_VALID;
+ }
+
+ p = der;
+
+ if (dflags & DECODE_FLAG_HAVE_TAG)
+ {
+ result = asn1_get_tag_der (p, der_len, &class, &tag_len, &tag);
+ if (result != ASN1_SUCCESS)
+ {
+ warn();
+ return result;
+ }
+
+ if (tag != ETYPE_TAG (etype))
+ {
+ warn();
+ return ASN1_DER_ERROR;
+ }
+
+ p += tag_len;
+
+ DECR_LEN(der_len, tag_len);
+
+ if (ber_len) *ber_len += tag_len;
+ }
+
+ /* indefinite constructed */
+ if ((((dflags & DECODE_FLAG_CONSTRUCTED) || class == ASN1_CLASS_STRUCTURED) && ETYPE_IS_STRING(etype)) &&
+ !(dflags & DECODE_FLAG_LEVEL3))
+ {
+ if (der_len == 0)
+ {
+ warn();
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+
+ if (der_len > 0 && p[0] == 0x80) /* indefinite */
+ {
+ len_len = 1;
+ DECR_LEN(der_len, len_len);
+ p += len_len;
+
+ if (ber_len) *ber_len += len_len;
+
+ /* decode the available octet strings */
+ do
+ {
+ unsigned tmp_len;
+ unsigned flags = DECODE_FLAG_HAVE_TAG;
+
+ if (dflags & DECODE_FLAG_LEVEL1)
+ flags |= DECODE_FLAG_LEVEL2;
+ else if (dflags & DECODE_FLAG_LEVEL2)
+ flags |= DECODE_FLAG_LEVEL3;
+ else
+ flags |= DECODE_FLAG_LEVEL1;
+
+ result = _asn1_decode_simple_ber(etype, p, der_len, &out, &out_len, &tmp_len,
+ flags);
+ if (result != ASN1_SUCCESS)
+ {
+ warn();
+ goto cleanup;
+ }
+
+ p += tmp_len;
+ DECR_LEN(der_len, tmp_len);
+
+ if (ber_len) *ber_len += tmp_len;
+
+ DECR_LEN(der_len, 2); /* we need the EOC */
+
+ result = append(&total, &total_size, out, out_len);
+ if (result != ASN1_SUCCESS)
+ {
+ warn();
+ goto cleanup;
+ }
+
+ free(out);
+ out = NULL;
+
+ if (p[0] == 0 && p[1] == 0) /* EOC */
+ {
+ if (ber_len) *ber_len += 2;
+ break;
+ }
+
+ /* no EOC */
+ der_len += 2;
+
+ if (der_len == 2)
+ {
+ warn();
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+ }
+ while(1);
+ }
+ else /* constructed */
+ {
+ long const_len;
+
+ result = asn1_get_length_ber(p, der_len, &len_len);
+ if (result < 0)
+ {
+ warn();
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+
+ DECR_LEN(der_len, len_len);
+ p += len_len;
+
+ const_len = result;
+
+ if (ber_len) *ber_len += len_len;
+
+ /* decode the available octet strings */
+ while(const_len > 0)
+ {
+ unsigned tmp_len;
+ unsigned flags = DECODE_FLAG_HAVE_TAG;
+
+ if (dflags & DECODE_FLAG_LEVEL1)
+ flags |= DECODE_FLAG_LEVEL2;
+ else if (dflags & DECODE_FLAG_LEVEL2)
+ flags |= DECODE_FLAG_LEVEL3;
+ else
+ flags |= DECODE_FLAG_LEVEL1;
+
+ result = _asn1_decode_simple_ber(etype, p, der_len, &out, &out_len, &tmp_len,
+ flags);
+ if (result != ASN1_SUCCESS)
+ {
+ warn();
+ goto cleanup;
+ }
+
+ p += tmp_len;
+ DECR_LEN(der_len, tmp_len);
+ DECR_LEN(const_len, tmp_len);
+
+ if (ber_len) *ber_len += tmp_len;
+
+ result = append(&total, &total_size, out, out_len);
+ if (result != ASN1_SUCCESS)
+ {
+ warn();
+ goto cleanup;
+ }
+
+ free(out);
+ out = NULL;
+ }
+ }
+ }
+ else if (class == ETYPE_CLASS(etype))
+ {
+ if (ber_len)
+ {
+ result = asn1_get_length_der (p, der_len, &len_len);
+ if (result < 0)
+ {
+ warn();
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+ *ber_len += result + len_len;
+ }
+
+ /* non-string values are decoded as DER */
+ result = _asn1_decode_simple_der(etype, der, _der_len, &cout, &out_len, dflags);
+ if (result != ASN1_SUCCESS)
+ {
+ warn();
+ goto cleanup;
+ }
+
+ result = append(&total, &total_size, cout, out_len);
+ if (result != ASN1_SUCCESS)
+ {
+ warn();
+ goto cleanup;
+ }
+ }
+ else
+ {
+ warn();
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+
+ *str = total;
+ *str_len = total_size;
+
+ return ASN1_SUCCESS;
+cleanup:
+ free(out);
+ free(total);
+ return result;
+}
+
+/**
+ * asn1_decode_simple_ber:
+ * @etype: The type of the string to be encoded (ASN1_ETYPE_)
+ * @der: the encoded string
+ * @_der_len: the bytes of the encoded string
+ * @str: a pointer to the data
+ * @str_len: the length of the data
+ * @ber_len: the total length occupied by BER (may be %NULL)
+ *
+ * Decodes a BER encoded type. The output is an allocated value
+ * of the data. This decodes BER STRINGS only. Other types are
+ * decoded as DER.
+ *
+ * Returns: %ASN1_SUCCESS if successful or an error value.
+ **/
+int
+asn1_decode_simple_ber (unsigned int etype, const unsigned char *der,
+ unsigned int _der_len, unsigned char **str,
+ unsigned int *str_len, unsigned int *ber_len)
+{
+ return _asn1_decode_simple_ber(etype, der, _der_len, str, str_len, ber_len, DECODE_FLAG_HAVE_TAG);
+}
diff --git a/lib/minitasn1/element.c b/lib/minitasn1/element.c
new file mode 100644
index 0000000..550fdb2
--- /dev/null
+++ b/lib/minitasn1/element.c
@@ -0,0 +1,1111 @@
+/*
+ * Copyright (C) 2000-2021 Free Software Foundation, Inc.
+ *
+ * This file is part of LIBTASN1.
+ *
+ * The LIBTASN1 library is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ */
+
+/*****************************************************/
+/* File: element.c */
+/* Description: Functions with the read and write */
+/* functions. */
+/*****************************************************/
+
+
+#include <int.h>
+#include "parser_aux.h"
+#include <gstr.h>
+#include "structure.h"
+#include "c-ctype.h"
+#include "element.h"
+
+void
+_asn1_hierarchical_name (asn1_node_const node, char *name, int name_size)
+{
+ asn1_node_const p;
+ char tmp_name[64];
+
+ p = node;
+
+ name[0] = 0;
+
+ while (p != NULL)
+ {
+ if (p->name[0] != 0)
+ {
+ _asn1_str_cpy (tmp_name, sizeof (tmp_name), name),
+ _asn1_str_cpy (name, name_size, p->name);
+ _asn1_str_cat (name, name_size, ".");
+ _asn1_str_cat (name, name_size, tmp_name);
+ }
+ p = _asn1_find_up (p);
+ }
+
+ if (name[0] == 0)
+ _asn1_str_cpy (name, name_size, "ROOT");
+}
+
+
+/******************************************************************/
+/* Function : _asn1_convert_integer */
+/* Description: converts an integer from a null terminated string */
+/* to der decoding. The convertion from a null */
+/* terminated string to an integer is made with */
+/* the 'strtol' function. */
+/* Parameters: */
+/* value: null terminated string to convert. */
+/* value_out: convertion result (memory must be already */
+/* allocated). */
+/* value_out_size: number of bytes of value_out. */
+/* len: number of significant byte of value_out. */
+/* Return: ASN1_MEM_ERROR or ASN1_SUCCESS */
+/******************************************************************/
+int
+_asn1_convert_integer (const unsigned char *value, unsigned char *value_out,
+ int value_out_size, int *len)
+{
+ char negative;
+ unsigned char val[SIZEOF_UNSIGNED_LONG_INT];
+ long valtmp;
+ int k, k2;
+
+ valtmp = _asn1_strtol (value, NULL, 10);
+
+ for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++)
+ {
+ val[SIZEOF_UNSIGNED_LONG_INT - k - 1] = (valtmp >> (8 * k)) & 0xFF;
+ }
+
+ if (val[0] & 0x80)
+ negative = 1;
+ else
+ negative = 0;
+
+ for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT - 1; k++)
+ {
+ if (negative && (val[k] != 0xFF))
+ break;
+ else if (!negative && val[k])
+ break;
+ }
+
+ if ((negative && !(val[k] & 0x80)) || (!negative && (val[k] & 0x80)))
+ k--;
+
+ *len = SIZEOF_UNSIGNED_LONG_INT - k;
+
+ if (SIZEOF_UNSIGNED_LONG_INT - k > value_out_size)
+ /* VALUE_OUT is too short to contain the value conversion */
+ return ASN1_MEM_ERROR;
+
+ if (value_out != NULL)
+ {
+ for (k2 = k; k2 < SIZEOF_UNSIGNED_LONG_INT; k2++)
+ value_out[k2 - k] = val[k2];
+ }
+
+#if 0
+ printf ("_asn1_convert_integer: valueIn=%s, lenOut=%d", value, *len);
+ for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++)
+ printf (", vOut[%d]=%d", k, value_out[k]);
+ printf ("\n");
+#endif
+
+ return ASN1_SUCCESS;
+}
+
+/* Appends a new element into the sequence (or set) defined by this
+ * node. The new element will have a name of '?number', where number
+ * is a monotonically increased serial number.
+ *
+ * The last element in the list may be provided in @pcache, to avoid
+ * traversing the list, an expensive operation in long lists.
+ *
+ * On success it returns in @pcache the added element (which is the
+ * tail in the list of added elements).
+ */
+int
+_asn1_append_sequence_set (asn1_node node, struct node_tail_cache_st *pcache)
+{
+ asn1_node p, p2;
+ char temp[LTOSTR_MAX_SIZE+1];
+ long n;
+
+ if (!node || !(node->down))
+ return ASN1_GENERIC_ERROR;
+
+ p = node->down;
+ while ((type_field (p->type) == ASN1_ETYPE_TAG)
+ || (type_field (p->type) == ASN1_ETYPE_SIZE))
+ p = p->right;
+
+ p2 = _asn1_copy_structure3 (p);
+ if (p2 == NULL)
+ return ASN1_GENERIC_ERROR;
+
+ if (pcache == NULL || pcache->tail == NULL || pcache->head != node)
+ {
+ while (p->right)
+ {
+ p = p->right;
+ }
+ }
+ else
+ {
+ p = pcache->tail;
+ }
+
+ _asn1_set_right (p, p2);
+ if (pcache)
+ {
+ pcache->head = node;
+ pcache->tail = p2;
+ }
+
+ if (p->name[0] == 0)
+ _asn1_str_cpy (temp, sizeof (temp), "?1");
+ else
+ {
+ n = strtol (p->name + 1, NULL, 0);
+ n++;
+ temp[0] = '?';
+ _asn1_ltostr (n, temp + 1);
+ }
+ _asn1_set_name (p2, temp);
+ /* p2->type |= CONST_OPTION; */
+
+ return ASN1_SUCCESS;
+}
+
+
+/**
+ * asn1_write_value:
+ * @node_root: pointer to a structure
+ * @name: the name of the element inside the structure that you want to set.
+ * @ivalue: vector used to specify the value to set. If len is >0,
+ * VALUE must be a two's complement form integer. if len=0 *VALUE
+ * must be a null terminated string with an integer value.
+ * @len: number of bytes of *value to use to set the value:
+ * value[0]..value[len-1] or 0 if value is a null terminated string
+ *
+ * Set the value of one element inside a structure.
+ *
+ * If an element is OPTIONAL and you want to delete it, you must use
+ * the value=NULL and len=0. Using "pkix.asn":
+ *
+ * result=asn1_write_value(cert, "tbsCertificate.issuerUniqueID",
+ * NULL, 0);
+ *
+ * Description for each type:
+ *
+ * INTEGER: VALUE must contain a two's complement form integer.
+ *
+ * value[0]=0xFF , len=1 -> integer=-1.
+ * value[0]=0xFF value[1]=0xFF , len=2 -> integer=-1.
+ * value[0]=0x01 , len=1 -> integer= 1.
+ * value[0]=0x00 value[1]=0x01 , len=2 -> integer= 1.
+ * value="123" , len=0 -> integer= 123.
+ *
+ * ENUMERATED: As INTEGER (but only with not negative numbers).
+ *
+ * BOOLEAN: VALUE must be the null terminated string "TRUE" or
+ * "FALSE" and LEN != 0.
+ *
+ * value="TRUE" , len=1 -> boolean=TRUE.
+ * value="FALSE" , len=1 -> boolean=FALSE.
+ *
+ * OBJECT IDENTIFIER: VALUE must be a null terminated string with
+ * each number separated by a dot (e.g. "1.2.3.543.1"). LEN != 0.
+ *
+ * value="1 2 840 10040 4 3" , len=1 -> OID=dsa-with-sha.
+ *
+ * UTCTime: VALUE must be a null terminated string in one of these
+ * formats: "YYMMDDhhmmssZ", "YYMMDDhhmmssZ",
+ * "YYMMDDhhmmss+hh'mm'", "YYMMDDhhmmss-hh'mm'",
+ * "YYMMDDhhmm+hh'mm'", or "YYMMDDhhmm-hh'mm'". LEN != 0.
+ *
+ * value="9801011200Z" , len=1 -> time=Jannuary 1st, 1998
+ * at 12h 00m Greenwich Mean Time
+ *
+ * GeneralizedTime: VALUE must be in one of this format:
+ * "YYYYMMDDhhmmss.sZ", "YYYYMMDDhhmmss.sZ",
+ * "YYYYMMDDhhmmss.s+hh'mm'", "YYYYMMDDhhmmss.s-hh'mm'",
+ * "YYYYMMDDhhmm+hh'mm'", or "YYYYMMDDhhmm-hh'mm'" where ss.s
+ * indicates the seconds with any precision like "10.1" or "01.02".
+ * LEN != 0
+ *
+ * value="2001010112001.12-0700" , len=1 -> time=Jannuary
+ * 1st, 2001 at 12h 00m 01.12s Pacific Daylight Time
+ *
+ * OCTET STRING: VALUE contains the octet string and LEN is the
+ * number of octets.
+ *
+ * value="$\backslash$x01$\backslash$x02$\backslash$x03" ,
+ * len=3 -> three bytes octet string
+ *
+ * GeneralString: VALUE contains the generalstring and LEN is the
+ * number of octets.
+ *
+ * value="$\backslash$x01$\backslash$x02$\backslash$x03" ,
+ * len=3 -> three bytes generalstring
+ *
+ * BIT STRING: VALUE contains the bit string organized by bytes and
+ * LEN is the number of bits.
+ *
+ * value="$\backslash$xCF" , len=6 -> bit string="110011" (six
+ * bits)
+ *
+ * CHOICE: if NAME indicates a choice type, VALUE must specify one of
+ * the alternatives with a null terminated string. LEN != 0. Using
+ * "pkix.asn"\:
+ *
+ * result=asn1_write_value(cert,
+ * "certificate1.tbsCertificate.subject", "rdnSequence",
+ * 1);
+ *
+ * ANY: VALUE indicates the der encoding of a structure. LEN != 0.
+ *
+ * SEQUENCE OF: VALUE must be the null terminated string "NEW" and
+ * LEN != 0. With this instruction another element is appended in
+ * the sequence. The name of this element will be "?1" if it's the
+ * first one, "?2" for the second and so on.
+ *
+ * Using "pkix.asn"\:
+ *
+ * result=asn1_write_value(cert,
+ * "certificate1.tbsCertificate.subject.rdnSequence", "NEW", 1);
+ *
+ * SET OF: the same as SEQUENCE OF. Using "pkix.asn":
+ *
+ * result=asn1_write_value(cert,
+ * "tbsCertificate.subject.rdnSequence.?LAST", "NEW", 1);
+ *
+ * Returns: %ASN1_SUCCESS if the value was set,
+ * %ASN1_ELEMENT_NOT_FOUND if @name is not a valid element, and
+ * %ASN1_VALUE_NOT_VALID if @ivalue has a wrong format.
+ **/
+int
+asn1_write_value (asn1_node node_root, const char *name,
+ const void *ivalue, int len)
+{
+ asn1_node node, p, p2;
+ unsigned char *temp, *value_temp = NULL, *default_temp = NULL;
+ int len2, k, k2, negative;
+ size_t i;
+ const unsigned char *value = ivalue;
+ unsigned int type;
+
+ node = asn1_find_node (node_root, name);
+ if (node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ if ((node->type & CONST_OPTION) && (value == NULL) && (len == 0))
+ {
+ asn1_delete_structure (&node);
+ return ASN1_SUCCESS;
+ }
+
+ type = type_field (node->type);
+
+ if ((type == ASN1_ETYPE_SEQUENCE_OF || type == ASN1_ETYPE_SET_OF) && (value == NULL) && (len == 0))
+ {
+ p = node->down;
+ while ((type_field (p->type) == ASN1_ETYPE_TAG)
+ || (type_field (p->type) == ASN1_ETYPE_SIZE))
+ p = p->right;
+
+ while (p->right)
+ asn1_delete_structure (&p->right);
+
+ return ASN1_SUCCESS;
+ }
+
+ /* Don't allow element deletion for other types */
+ if (value == NULL)
+ {
+ return ASN1_VALUE_NOT_VALID;
+ }
+
+ switch (type)
+ {
+ case ASN1_ETYPE_BOOLEAN:
+ if (!_asn1_strcmp (value, "TRUE"))
+ {
+ if (node->type & CONST_DEFAULT)
+ {
+ p = node->down;
+ while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
+ p = p->right;
+ if (p->type & CONST_TRUE)
+ _asn1_set_value (node, NULL, 0);
+ else
+ _asn1_set_value (node, "T", 1);
+ }
+ else
+ _asn1_set_value (node, "T", 1);
+ }
+ else if (!_asn1_strcmp (value, "FALSE"))
+ {
+ if (node->type & CONST_DEFAULT)
+ {
+ p = node->down;
+ while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
+ p = p->right;
+ if (p->type & CONST_FALSE)
+ _asn1_set_value (node, NULL, 0);
+ else
+ _asn1_set_value (node, "F", 1);
+ }
+ else
+ _asn1_set_value (node, "F", 1);
+ }
+ else
+ return ASN1_VALUE_NOT_VALID;
+ break;
+ case ASN1_ETYPE_INTEGER:
+ case ASN1_ETYPE_ENUMERATED:
+ if (len == 0)
+ {
+ if ((c_isdigit (value[0])) || (value[0] == '-'))
+ {
+ value_temp = malloc (SIZEOF_UNSIGNED_LONG_INT);
+ if (value_temp == NULL)
+ return ASN1_MEM_ALLOC_ERROR;
+
+ _asn1_convert_integer (value, value_temp,
+ SIZEOF_UNSIGNED_LONG_INT, &len);
+ }
+ else
+ { /* is an identifier like v1 */
+ if (!(node->type & CONST_LIST))
+ return ASN1_VALUE_NOT_VALID;
+ p = node->down;
+ while (p)
+ {
+ if (type_field (p->type) == ASN1_ETYPE_CONSTANT)
+ {
+ if (!_asn1_strcmp (p->name, value))
+ {
+ value_temp = malloc (SIZEOF_UNSIGNED_LONG_INT);
+ if (value_temp == NULL)
+ return ASN1_MEM_ALLOC_ERROR;
+
+ _asn1_convert_integer (p->value,
+ value_temp,
+ SIZEOF_UNSIGNED_LONG_INT,
+ &len);
+ break;
+ }
+ }
+ p = p->right;
+ }
+ if (p == NULL)
+ return ASN1_VALUE_NOT_VALID;
+ }
+ }
+ else
+ { /* len != 0 */
+ value_temp = malloc (len);
+ if (value_temp == NULL)
+ return ASN1_MEM_ALLOC_ERROR;
+ memcpy (value_temp, value, len);
+ }
+
+ if (value_temp[0] & 0x80)
+ negative = 1;
+ else
+ negative = 0;
+
+ if (negative && (type_field (node->type) == ASN1_ETYPE_ENUMERATED))
+ {
+ free (value_temp);
+ return ASN1_VALUE_NOT_VALID;
+ }
+
+ for (k = 0; k < len - 1; k++)
+ if (negative && (value_temp[k] != 0xFF))
+ break;
+ else if (!negative && value_temp[k])
+ break;
+
+ if ((negative && !(value_temp[k] & 0x80)) ||
+ (!negative && (value_temp[k] & 0x80)))
+ k--;
+
+ _asn1_set_value_lv (node, value_temp + k, len - k);
+
+ if (node->type & CONST_DEFAULT)
+ {
+ p = node->down;
+ while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
+ p = p->right;
+ if ((c_isdigit (p->value[0])) || (p->value[0] == '-'))
+ {
+ default_temp = malloc (SIZEOF_UNSIGNED_LONG_INT);
+ if (default_temp == NULL)
+ {
+ free (value_temp);
+ return ASN1_MEM_ALLOC_ERROR;
+ }
+
+ _asn1_convert_integer (p->value, default_temp,
+ SIZEOF_UNSIGNED_LONG_INT, &len2);
+ }
+ else
+ { /* is an identifier like v1 */
+ if (!(node->type & CONST_LIST))
+ {
+ free (value_temp);
+ return ASN1_VALUE_NOT_VALID;
+ }
+ p2 = node->down;
+ while (p2)
+ {
+ if (type_field (p2->type) == ASN1_ETYPE_CONSTANT)
+ {
+ if (!_asn1_strcmp (p2->name, p->value))
+ {
+ default_temp = malloc (SIZEOF_UNSIGNED_LONG_INT);
+ if (default_temp == NULL)
+ {
+ free (value_temp);
+ return ASN1_MEM_ALLOC_ERROR;
+ }
+
+ _asn1_convert_integer (p2->value,
+ default_temp,
+ SIZEOF_UNSIGNED_LONG_INT,
+ &len2);
+ break;
+ }
+ }
+ p2 = p2->right;
+ }
+ if (p2 == NULL)
+ {
+ free (value_temp);
+ return ASN1_VALUE_NOT_VALID;
+ }
+ }
+
+
+ if ((len - k) == len2)
+ {
+ for (k2 = 0; k2 < len2; k2++)
+ if (value_temp[k + k2] != default_temp[k2])
+ {
+ break;
+ }
+ if (k2 == len2)
+ _asn1_set_value (node, NULL, 0);
+ }
+ free (default_temp);
+ }
+ free (value_temp);
+ break;
+ case ASN1_ETYPE_OBJECT_ID:
+ for (i = 0; i < _asn1_strlen (value); i++)
+ if ((!c_isdigit (value[i])) && (value[i] != '.') && (value[i] != '+'))
+ return ASN1_VALUE_NOT_VALID;
+ if (node->type & CONST_DEFAULT)
+ {
+ p = node->down;
+ while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
+ p = p->right;
+ if (!_asn1_strcmp (value, p->value))
+ {
+ _asn1_set_value (node, NULL, 0);
+ break;
+ }
+ }
+ _asn1_set_value (node, value, _asn1_strlen (value) + 1);
+ break;
+ case ASN1_ETYPE_UTC_TIME:
+ {
+ len = _asn1_strlen (value);
+ if (len < 11)
+ return ASN1_VALUE_NOT_VALID;
+ for (k = 0; k < 10; k++)
+ if (!c_isdigit (value[k]))
+ return ASN1_VALUE_NOT_VALID;
+ switch (len)
+ {
+ case 11:
+ if (value[10] != 'Z')
+ return ASN1_VALUE_NOT_VALID;
+ break;
+ case 13:
+ if ((!c_isdigit (value[10])) || (!c_isdigit (value[11])) ||
+ (value[12] != 'Z'))
+ return ASN1_VALUE_NOT_VALID;
+ break;
+ case 15:
+ if ((value[10] != '+') && (value[10] != '-'))
+ return ASN1_VALUE_NOT_VALID;
+ for (k = 11; k < 15; k++)
+ if (!c_isdigit (value[k]))
+ return ASN1_VALUE_NOT_VALID;
+ break;
+ case 17:
+ if ((!c_isdigit (value[10])) || (!c_isdigit (value[11])))
+ return ASN1_VALUE_NOT_VALID;
+ if ((value[12] != '+') && (value[12] != '-'))
+ return ASN1_VALUE_NOT_VALID;
+ for (k = 13; k < 17; k++)
+ if (!c_isdigit (value[k]))
+ return ASN1_VALUE_NOT_VALID;
+ break;
+ default:
+ return ASN1_VALUE_NOT_FOUND;
+ }
+ _asn1_set_value (node, value, len);
+ }
+ break;
+ case ASN1_ETYPE_GENERALIZED_TIME:
+ len = _asn1_strlen (value);
+ _asn1_set_value (node, value, len);
+ break;
+ case ASN1_ETYPE_OCTET_STRING:
+ case ASN1_ETYPE_GENERALSTRING:
+ case ASN1_ETYPE_NUMERIC_STRING:
+ case ASN1_ETYPE_IA5_STRING:
+ case ASN1_ETYPE_TELETEX_STRING:
+ case ASN1_ETYPE_PRINTABLE_STRING:
+ case ASN1_ETYPE_UNIVERSAL_STRING:
+ case ASN1_ETYPE_BMP_STRING:
+ case ASN1_ETYPE_UTF8_STRING:
+ case ASN1_ETYPE_VISIBLE_STRING:
+ if (len == 0)
+ len = _asn1_strlen (value);
+ _asn1_set_value_lv (node, value, len);
+ break;
+ case ASN1_ETYPE_BIT_STRING:
+ if (len == 0)
+ len = _asn1_strlen (value);
+ asn1_length_der ((len >> 3) + 2, NULL, &len2);
+ temp = malloc ((len >> 3) + 2 + len2);
+ if (temp == NULL)
+ return ASN1_MEM_ALLOC_ERROR;
+
+ asn1_bit_der (value, len, temp, &len2);
+ _asn1_set_value_m (node, temp, len2);
+ temp = NULL;
+ break;
+ case ASN1_ETYPE_CHOICE:
+ p = node->down;
+ while (p)
+ {
+ if (!_asn1_strcmp (p->name, value))
+ {
+ p2 = node->down;
+ while (p2)
+ {
+ if (p2 != p)
+ {
+ asn1_delete_structure (&p2);
+ p2 = node->down;
+ }
+ else
+ p2 = p2->right;
+ }
+ break;
+ }
+ p = p->right;
+ }
+ if (!p)
+ return ASN1_ELEMENT_NOT_FOUND;
+ break;
+ case ASN1_ETYPE_ANY:
+ _asn1_set_value_lv (node, value, len);
+ break;
+ case ASN1_ETYPE_SEQUENCE_OF:
+ case ASN1_ETYPE_SET_OF:
+ if (_asn1_strcmp (value, "NEW"))
+ return ASN1_VALUE_NOT_VALID;
+ _asn1_append_sequence_set (node, NULL);
+ break;
+ default:
+ return ASN1_ELEMENT_NOT_FOUND;
+ break;
+ }
+
+ return ASN1_SUCCESS;
+}
+
+
+#define PUT_VALUE( ptr, ptr_size, data, data_size) \
+ *len = data_size; \
+ if (ptr_size < data_size) { \
+ return ASN1_MEM_ERROR; \
+ } else { \
+ if (ptr && data_size > 0) \
+ memcpy (ptr, data, data_size); \
+ }
+
+#define PUT_STR_VALUE( ptr, ptr_size, data) \
+ *len = _asn1_strlen (data) + 1; \
+ if (ptr_size < *len) { \
+ return ASN1_MEM_ERROR; \
+ } else { \
+ /* this strcpy is checked */ \
+ if (ptr) { \
+ _asn1_strcpy (ptr, data); \
+ } \
+ }
+
+#define PUT_AS_STR_VALUE( ptr, ptr_size, data, data_size) \
+ *len = data_size + 1; \
+ if (ptr_size < *len) { \
+ return ASN1_MEM_ERROR; \
+ } else { \
+ /* this strcpy is checked */ \
+ if (ptr) { \
+ if (data_size > 0) \
+ memcpy (ptr, data, data_size); \
+ ptr[data_size] = 0; \
+ } \
+ }
+
+#define ADD_STR_VALUE( ptr, ptr_size, data) \
+ *len += _asn1_strlen(data); \
+ if (ptr_size < (int) *len) { \
+ (*len)++; \
+ return ASN1_MEM_ERROR; \
+ } else { \
+ /* this strcat is checked */ \
+ if (ptr) _asn1_strcat (ptr, data); \
+ }
+
+/**
+ * asn1_read_value:
+ * @root: pointer to a structure.
+ * @name: the name of the element inside a structure that you want to read.
+ * @ivalue: vector that will contain the element's content, must be a
+ * pointer to memory cells already allocated (may be %NULL).
+ * @len: number of bytes of *value: value[0]..value[len-1]. Initialy
+ * holds the sizeof value.
+ *
+ * Returns the value of one element inside a structure.
+ * If an element is OPTIONAL and this returns
+ * %ASN1_ELEMENT_NOT_FOUND, it means that this element wasn't present
+ * in the der encoding that created the structure. The first element
+ * of a SEQUENCE_OF or SET_OF is named "?1". The second one "?2" and
+ * so on. If the @root provided is a node to specific sequence element,
+ * then the keyword "?CURRENT" is also acceptable and indicates the
+ * current sequence element of this node.
+ *
+ * Note that there can be valid values with length zero. In these case
+ * this function will succeed and @len will be zero.
+ *
+ * INTEGER: VALUE will contain a two's complement form integer.
+ *
+ * integer=-1 -> value[0]=0xFF , len=1.
+ * integer=1 -> value[0]=0x01 , len=1.
+ *
+ * ENUMERATED: As INTEGER (but only with not negative numbers).
+ *
+ * BOOLEAN: VALUE will be the null terminated string "TRUE" or
+ * "FALSE" and LEN=5 or LEN=6.
+ *
+ * OBJECT IDENTIFIER: VALUE will be a null terminated string with
+ * each number separated by a dot (i.e. "1.2.3.543.1").
+ *
+ * LEN = strlen(VALUE)+1
+ *
+ * UTCTime: VALUE will be a null terminated string in one of these
+ * formats: "YYMMDDhhmmss+hh'mm'" or "YYMMDDhhmmss-hh'mm'".
+ * LEN=strlen(VALUE)+1.
+ *
+ * GeneralizedTime: VALUE will be a null terminated string in the
+ * same format used to set the value.
+ *
+ * OCTET STRING: VALUE will contain the octet string and LEN will be
+ * the number of octets.
+ *
+ * GeneralString: VALUE will contain the generalstring and LEN will
+ * be the number of octets.
+ *
+ * BIT STRING: VALUE will contain the bit string organized by bytes
+ * and LEN will be the number of bits.
+ *
+ * CHOICE: If NAME indicates a choice type, VALUE will specify the
+ * alternative selected.
+ *
+ * ANY: If NAME indicates an any type, VALUE will indicate the DER
+ * encoding of the structure actually used.
+ *
+ * Returns: %ASN1_SUCCESS if value is returned,
+ * %ASN1_ELEMENT_NOT_FOUND if @name is not a valid element,
+ * %ASN1_VALUE_NOT_FOUND if there isn't any value for the element
+ * selected, and %ASN1_MEM_ERROR if The value vector isn't big enough
+ * to store the result, and in this case @len will contain the number of
+ * bytes needed. On the occasion that the stored data are of zero-length
+ * this function may return %ASN1_SUCCESS even if the provided @len is zero.
+ **/
+int
+asn1_read_value (asn1_node_const root, const char *name, void *ivalue, int *len)
+{
+ return asn1_read_value_type (root, name, ivalue, len, NULL);
+}
+
+/**
+ * asn1_read_value_type:
+ * @root: pointer to a structure.
+ * @name: the name of the element inside a structure that you want to read.
+ * @ivalue: vector that will contain the element's content, must be a
+ * pointer to memory cells already allocated (may be %NULL).
+ * @len: number of bytes of *value: value[0]..value[len-1]. Initialy
+ * holds the sizeof value.
+ * @etype: The type of the value read (ASN1_ETYPE)
+ *
+ * Returns the type and value of one element inside a structure.
+ * If an element is OPTIONAL and this returns
+ * %ASN1_ELEMENT_NOT_FOUND, it means that this element wasn't present
+ * in the der encoding that created the structure. The first element
+ * of a SEQUENCE_OF or SET_OF is named "?1". The second one "?2" and
+ * so on. If the @root provided is a node to specific sequence element,
+ * then the keyword "?CURRENT" is also acceptable and indicates the
+ * current sequence element of this node.
+ *
+ * Note that there can be valid values with length zero. In these case
+ * this function will succeed and @len will be zero.
+ *
+ *
+ * INTEGER: VALUE will contain a two's complement form integer.
+ *
+ * integer=-1 -> value[0]=0xFF , len=1.
+ * integer=1 -> value[0]=0x01 , len=1.
+ *
+ * ENUMERATED: As INTEGER (but only with not negative numbers).
+ *
+ * BOOLEAN: VALUE will be the null terminated string "TRUE" or
+ * "FALSE" and LEN=5 or LEN=6.
+ *
+ * OBJECT IDENTIFIER: VALUE will be a null terminated string with
+ * each number separated by a dot (i.e. "1.2.3.543.1").
+ *
+ * LEN = strlen(VALUE)+1
+ *
+ * UTCTime: VALUE will be a null terminated string in one of these
+ * formats: "YYMMDDhhmmss+hh'mm'" or "YYMMDDhhmmss-hh'mm'".
+ * LEN=strlen(VALUE)+1.
+ *
+ * GeneralizedTime: VALUE will be a null terminated string in the
+ * same format used to set the value.
+ *
+ * OCTET STRING: VALUE will contain the octet string and LEN will be
+ * the number of octets.
+ *
+ * GeneralString: VALUE will contain the generalstring and LEN will
+ * be the number of octets.
+ *
+ * BIT STRING: VALUE will contain the bit string organized by bytes
+ * and LEN will be the number of bits.
+ *
+ * CHOICE: If NAME indicates a choice type, VALUE will specify the
+ * alternative selected.
+ *
+ * ANY: If NAME indicates an any type, VALUE will indicate the DER
+ * encoding of the structure actually used.
+ *
+ * Returns: %ASN1_SUCCESS if value is returned,
+ * %ASN1_ELEMENT_NOT_FOUND if @name is not a valid element,
+ * %ASN1_VALUE_NOT_FOUND if there isn't any value for the element
+ * selected, and %ASN1_MEM_ERROR if The value vector isn't big enough
+ * to store the result, and in this case @len will contain the number of
+ * bytes needed. On the occasion that the stored data are of zero-length
+ * this function may return %ASN1_SUCCESS even if the provided @len is zero.
+ **/
+int
+asn1_read_value_type (asn1_node_const root, const char *name, void *ivalue,
+ int *len, unsigned int *etype)
+{
+ asn1_node_const node, p, p2;
+ int len2, len3, result;
+ int value_size = *len;
+ unsigned char *value = ivalue;
+ unsigned type;
+
+ node = asn1_find_node (root, name);
+ if (node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ type = type_field (node->type);
+
+ if ((type != ASN1_ETYPE_NULL) &&
+ (type != ASN1_ETYPE_CHOICE) &&
+ !(node->type & CONST_DEFAULT) && !(node->type & CONST_ASSIGN) &&
+ (node->value == NULL))
+ return ASN1_VALUE_NOT_FOUND;
+
+ if (etype)
+ *etype = type;
+ switch (type)
+ {
+ case ASN1_ETYPE_NULL:
+ PUT_STR_VALUE (value, value_size, "NULL");
+ break;
+ case ASN1_ETYPE_BOOLEAN:
+ if ((node->type & CONST_DEFAULT) && (node->value == NULL))
+ {
+ p = node->down;
+ while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
+ p = p->right;
+ if (p->type & CONST_TRUE)
+ {
+ PUT_STR_VALUE (value, value_size, "TRUE");
+ }
+ else
+ {
+ PUT_STR_VALUE (value, value_size, "FALSE");
+ }
+ }
+ else if (node->value[0] == 'T')
+ {
+ PUT_STR_VALUE (value, value_size, "TRUE");
+ }
+ else
+ {
+ PUT_STR_VALUE (value, value_size, "FALSE");
+ }
+ break;
+ case ASN1_ETYPE_INTEGER:
+ case ASN1_ETYPE_ENUMERATED:
+ if ((node->type & CONST_DEFAULT) && (node->value == NULL))
+ {
+ p = node->down;
+ while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
+ p = p->right;
+ if ((c_isdigit (p->value[0])) || (p->value[0] == '-')
+ || (p->value[0] == '+'))
+ {
+ result = _asn1_convert_integer
+ (p->value, value, value_size, len);
+ if (result != ASN1_SUCCESS)
+ return result;
+ }
+ else
+ { /* is an identifier like v1 */
+ p2 = node->down;
+ while (p2)
+ {
+ if (type_field (p2->type) == ASN1_ETYPE_CONSTANT)
+ {
+ if (!_asn1_strcmp (p2->name, p->value))
+ {
+ result = _asn1_convert_integer
+ (p2->value, value, value_size,
+ len);
+ if (result != ASN1_SUCCESS)
+ return result;
+ break;
+ }
+ }
+ p2 = p2->right;
+ }
+ }
+ }
+ else
+ {
+ len2 = -1;
+ result = asn1_get_octet_der
+ (node->value, node->value_len, &len2, value, value_size,
+ len);
+ if (result != ASN1_SUCCESS)
+ return result;
+ }
+ break;
+ case ASN1_ETYPE_OBJECT_ID:
+ if (node->type & CONST_ASSIGN)
+ {
+ *len = 0;
+ if (value)
+ value[0] = 0;
+ p = node->down;
+ while (p)
+ {
+ if (type_field (p->type) == ASN1_ETYPE_CONSTANT)
+ {
+ ADD_STR_VALUE (value, value_size, p->value);
+ if (p->right)
+ {
+ ADD_STR_VALUE (value, value_size, ".");
+ }
+ }
+ p = p->right;
+ }
+ (*len)++;
+ }
+ else if ((node->type & CONST_DEFAULT) && (node->value == NULL))
+ {
+ p = node->down;
+ while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
+ p = p->right;
+ PUT_STR_VALUE (value, value_size, p->value);
+ }
+ else
+ {
+ PUT_STR_VALUE (value, value_size, node->value);
+ }
+ break;
+ case ASN1_ETYPE_GENERALIZED_TIME:
+ case ASN1_ETYPE_UTC_TIME:
+ PUT_AS_STR_VALUE (value, value_size, node->value, node->value_len);
+ break;
+ case ASN1_ETYPE_OCTET_STRING:
+ case ASN1_ETYPE_GENERALSTRING:
+ case ASN1_ETYPE_NUMERIC_STRING:
+ case ASN1_ETYPE_IA5_STRING:
+ case ASN1_ETYPE_TELETEX_STRING:
+ case ASN1_ETYPE_PRINTABLE_STRING:
+ case ASN1_ETYPE_UNIVERSAL_STRING:
+ case ASN1_ETYPE_BMP_STRING:
+ case ASN1_ETYPE_UTF8_STRING:
+ case ASN1_ETYPE_VISIBLE_STRING:
+ len2 = -1;
+ result = asn1_get_octet_der
+ (node->value, node->value_len, &len2, value, value_size,
+ len);
+ if (result != ASN1_SUCCESS)
+ return result;
+ break;
+ case ASN1_ETYPE_BIT_STRING:
+ len2 = -1;
+ result = asn1_get_bit_der
+ (node->value, node->value_len, &len2, value, value_size,
+ len);
+ if (result != ASN1_SUCCESS)
+ return result;
+ break;
+ case ASN1_ETYPE_CHOICE:
+ PUT_STR_VALUE (value, value_size, node->down->name);
+ break;
+ case ASN1_ETYPE_ANY:
+ len3 = -1;
+ len2 = asn1_get_length_der (node->value, node->value_len, &len3);
+ if (len2 < 0)
+ return ASN1_DER_ERROR;
+ PUT_VALUE (value, value_size, node->value + len3, len2);
+ break;
+ default:
+ return ASN1_ELEMENT_NOT_FOUND;
+ break;
+ }
+ return ASN1_SUCCESS;
+}
+
+
+/**
+ * asn1_read_tag:
+ * @root: pointer to a structure
+ * @name: the name of the element inside a structure.
+ * @tagValue: variable that will contain the TAG value.
+ * @classValue: variable that will specify the TAG type.
+ *
+ * Returns the TAG and the CLASS of one element inside a structure.
+ * CLASS can have one of these constants: %ASN1_CLASS_APPLICATION,
+ * %ASN1_CLASS_UNIVERSAL, %ASN1_CLASS_PRIVATE or
+ * %ASN1_CLASS_CONTEXT_SPECIFIC.
+ *
+ * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if
+ * @name is not a valid element.
+ **/
+int
+asn1_read_tag (asn1_node_const root, const char *name, int *tagValue,
+ int *classValue)
+{
+ asn1_node node, p, pTag;
+
+ node = asn1_find_node (root, name);
+ if (node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ p = node->down;
+
+ /* pTag will points to the IMPLICIT TAG */
+ pTag = NULL;
+ if (node->type & CONST_TAG)
+ {
+ while (p)
+ {
+ if (type_field (p->type) == ASN1_ETYPE_TAG)
+ {
+ if ((p->type & CONST_IMPLICIT) && (pTag == NULL))
+ pTag = p;
+ else if (p->type & CONST_EXPLICIT)
+ pTag = NULL;
+ }
+ p = p->right;
+ }
+ }
+
+ if (pTag)
+ {
+ *tagValue = _asn1_strtoul (pTag->value, NULL, 10);
+
+ if (pTag->type & CONST_APPLICATION)
+ *classValue = ASN1_CLASS_APPLICATION;
+ else if (pTag->type & CONST_UNIVERSAL)
+ *classValue = ASN1_CLASS_UNIVERSAL;
+ else if (pTag->type & CONST_PRIVATE)
+ *classValue = ASN1_CLASS_PRIVATE;
+ else
+ *classValue = ASN1_CLASS_CONTEXT_SPECIFIC;
+ }
+ else
+ {
+ unsigned type = type_field (node->type);
+ *classValue = ASN1_CLASS_UNIVERSAL;
+
+ switch (type)
+ {
+ CASE_HANDLED_ETYPES:
+ *tagValue = _asn1_tags[type].tag;
+ break;
+ case ASN1_ETYPE_TAG:
+ case ASN1_ETYPE_CHOICE:
+ case ASN1_ETYPE_ANY:
+ *tagValue = -1;
+ break;
+ default:
+ break;
+ }
+ }
+
+ return ASN1_SUCCESS;
+}
+
+/**
+ * asn1_read_node_value:
+ * @node: pointer to a node.
+ * @data: a point to a asn1_data_node_st
+ *
+ * Returns the value a data node inside a asn1_node structure.
+ * The data returned should be handled as constant values.
+ *
+ * Returns: %ASN1_SUCCESS if the node exists.
+ **/
+int
+asn1_read_node_value (asn1_node_const node, asn1_data_node_st * data)
+{
+ data->name = node->name;
+ data->value = node->value;
+ data->value_len = node->value_len;
+ data->type = type_field (node->type);
+
+ return ASN1_SUCCESS;
+}
diff --git a/lib/minitasn1/element.h b/lib/minitasn1/element.h
new file mode 100644
index 0000000..717bfaf
--- /dev/null
+++ b/lib/minitasn1/element.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2000-2021 Free Software Foundation, Inc.
+ *
+ * This file is part of LIBTASN1.
+ *
+ * The LIBTASN1 library is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ */
+
+#ifndef _ELEMENT_H
+#define _ELEMENT_H
+
+
+struct node_tail_cache_st
+{
+ asn1_node head; /* the first element of the sequence */
+ asn1_node tail;
+};
+
+int _asn1_append_sequence_set (asn1_node node, struct node_tail_cache_st *pcached);
+
+int _asn1_convert_integer (const unsigned char *value,
+ unsigned char *value_out,
+ int value_out_size, int *len);
+
+void _asn1_hierarchical_name (asn1_node_const node, char *name, int name_size);
+
+#endif
diff --git a/lib/minitasn1/errors.c b/lib/minitasn1/errors.c
new file mode 100644
index 0000000..a3daad4
--- /dev/null
+++ b/lib/minitasn1/errors.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2002-2021 Free Software Foundation, Inc.
+ *
+ * This file is part of LIBTASN1.
+ *
+ * The LIBTASN1 library is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ */
+
+#include <int.h>
+#ifdef STDC_HEADERS
+#include <stdarg.h>
+#endif
+
+#define LIBTASN1_ERROR_ENTRY(name) { #name, name }
+
+struct libtasn1_error_entry
+{
+ const char *name;
+ int number;
+};
+typedef struct libtasn1_error_entry libtasn1_error_entry;
+
+static const libtasn1_error_entry error_algorithms[] = {
+ LIBTASN1_ERROR_ENTRY (ASN1_SUCCESS),
+ LIBTASN1_ERROR_ENTRY (ASN1_FILE_NOT_FOUND),
+ LIBTASN1_ERROR_ENTRY (ASN1_ELEMENT_NOT_FOUND),
+ LIBTASN1_ERROR_ENTRY (ASN1_IDENTIFIER_NOT_FOUND),
+ LIBTASN1_ERROR_ENTRY (ASN1_DER_ERROR),
+ LIBTASN1_ERROR_ENTRY (ASN1_VALUE_NOT_FOUND),
+ LIBTASN1_ERROR_ENTRY (ASN1_GENERIC_ERROR),
+ LIBTASN1_ERROR_ENTRY (ASN1_VALUE_NOT_VALID),
+ LIBTASN1_ERROR_ENTRY (ASN1_TAG_ERROR),
+ LIBTASN1_ERROR_ENTRY (ASN1_TAG_IMPLICIT),
+ LIBTASN1_ERROR_ENTRY (ASN1_ERROR_TYPE_ANY),
+ LIBTASN1_ERROR_ENTRY (ASN1_SYNTAX_ERROR),
+ LIBTASN1_ERROR_ENTRY (ASN1_MEM_ERROR),
+ LIBTASN1_ERROR_ENTRY (ASN1_MEM_ALLOC_ERROR),
+ LIBTASN1_ERROR_ENTRY (ASN1_DER_OVERFLOW),
+ LIBTASN1_ERROR_ENTRY (ASN1_NAME_TOO_LONG),
+ LIBTASN1_ERROR_ENTRY (ASN1_ARRAY_ERROR),
+ LIBTASN1_ERROR_ENTRY (ASN1_ELEMENT_NOT_EMPTY),
+ LIBTASN1_ERROR_ENTRY (ASN1_TIME_ENCODING_ERROR),
+ LIBTASN1_ERROR_ENTRY (ASN1_RECURSION),
+ {0, 0}
+};
+
+/**
+ * asn1_perror:
+ * @error: is an error returned by a libtasn1 function.
+ *
+ * Prints a string to stderr with a description of an error. This
+ * function is like perror(). The only difference is that it accepts
+ * an error returned by a libtasn1 function.
+ *
+ * Since: 1.6
+ **/
+void
+asn1_perror (int error)
+{
+ const char *str = asn1_strerror (error);
+ fprintf (stderr, "LIBTASN1 ERROR: %s\n", str ? str : "(null)");
+}
+
+/**
+ * asn1_strerror:
+ * @error: is an error returned by a libtasn1 function.
+ *
+ * Returns a string with a description of an error. This function is
+ * similar to strerror. The only difference is that it accepts an
+ * error (number) returned by a libtasn1 function.
+ *
+ * Returns: Pointer to static zero-terminated string describing error
+ * code.
+ *
+ * Since: 1.6
+ **/
+const char *
+asn1_strerror (int error)
+{
+ const libtasn1_error_entry *p;
+
+ for (p = error_algorithms; p->name != NULL; p++)
+ if (p->number == error)
+ return p->name + sizeof ("ASN1_") - 1;
+
+ return NULL;
+}
diff --git a/lib/minitasn1/gstr.c b/lib/minitasn1/gstr.c
new file mode 100644
index 0000000..1475ed5
--- /dev/null
+++ b/lib/minitasn1/gstr.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2002-2021 Free Software Foundation, Inc.
+ *
+ * This file is part of LIBTASN1.
+ *
+ * The LIBTASN1 library is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ */
+
+#include <int.h>
+#include "gstr.h"
+
+/* These function are like strcat, strcpy. They only
+ * do bounds checking (they shouldn't cause buffer overruns),
+ * and they always produce null terminated strings.
+ *
+ * They should be used only with null terminated strings.
+ */
+void
+_asn1_str_cat (char *dest, size_t dest_tot_size, const char *src)
+{
+ size_t str_size = strlen (src);
+ size_t dest_size = strlen (dest);
+
+ if (dest_tot_size - dest_size > str_size)
+ {
+ strcat (dest, src);
+ }
+ else
+ {
+ if (dest_tot_size > dest_size)
+ {
+ strncat (dest, src, (dest_tot_size - dest_size) - 1);
+ dest[dest_tot_size - 1] = 0;
+ }
+ }
+}
+
+/* Returns the bytes copied (not including the null terminator) */
+unsigned int
+_asn1_str_cpy (char *dest, size_t dest_tot_size, const char *src)
+{
+ size_t str_size = strlen (src);
+
+ if (dest_tot_size > str_size)
+ {
+ strcpy (dest, src);
+ return str_size;
+ }
+ else
+ {
+ if (dest_tot_size > 0)
+ {
+ str_size = dest_tot_size - 1;
+ memcpy (dest, src, str_size);
+ dest[str_size] = 0;
+ return str_size;
+ }
+ else
+ return 0;
+ }
+}
diff --git a/lib/minitasn1/gstr.h b/lib/minitasn1/gstr.h
new file mode 100644
index 0000000..e549c77
--- /dev/null
+++ b/lib/minitasn1/gstr.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2002-2021 Free Software Foundation, Inc.
+ *
+ * This file is part of LIBTASN1.
+ *
+ * The LIBTASN1 library is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ */
+
+#ifndef GSTR_H
+# define GSTR_H
+
+unsigned int _asn1_str_cpy (char *dest, size_t dest_tot_size,
+ const char *src);
+void _asn1_str_cat (char *dest, size_t dest_tot_size, const char *src);
+
+#define Estrcpy(x,y) _asn1_str_cpy(x,ASN1_MAX_ERROR_DESCRIPTION_SIZE,y)
+#define Estrcat(x,y) _asn1_str_cat(x,ASN1_MAX_ERROR_DESCRIPTION_SIZE,y)
+
+inline static
+void safe_memset(void *data, int c, size_t size)
+{
+ volatile unsigned volatile_zero = 0;
+ volatile char *vdata = (volatile char*)data;
+
+ /* This is based on a nice trick for safe memset,
+ * sent by David Jacobson in the openssl-dev mailing list.
+ */
+
+ if (size > 0) do {
+ memset(data, c, size);
+ } while(vdata[volatile_zero] != c);
+}
+
+#endif /* GSTR_H */
diff --git a/lib/minitasn1/int.h b/lib/minitasn1/int.h
new file mode 100644
index 0000000..57f1efd
--- /dev/null
+++ b/lib/minitasn1/int.h
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2002-2021 Free Software Foundation, Inc.
+ *
+ * This file is part of LIBTASN1.
+ *
+ * The LIBTASN1 library is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ */
+
+#ifndef INT_H
+#define INT_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include <libtasn1.h>
+
+#define ASN1_SMALL_VALUE_SIZE 16
+
+/* This structure is also in libtasn1.h, but then contains less
+ fields. You cannot make any modifications to these first fields
+ without breaking ABI. */
+struct asn1_node_st
+{
+ /* public fields: */
+ char name[ASN1_MAX_NAME_SIZE + 1]; /* Node name */
+ unsigned int name_hash;
+ unsigned int type; /* Node type */
+ unsigned char *value; /* Node value */
+ int value_len;
+ asn1_node down; /* Pointer to the son node */
+ asn1_node right; /* Pointer to the brother node */
+ asn1_node left; /* Pointer to the next list element */
+ /* private fields: */
+ unsigned char small_value[ASN1_SMALL_VALUE_SIZE]; /* For small values */
+
+ /* values used during decoding/coding */
+ int tmp_ival;
+ unsigned start; /* the start of the DER sequence - if decoded */
+ unsigned end; /* the end of the DER sequence - if decoded */
+};
+
+typedef struct tag_and_class_st
+{
+ unsigned tag;
+ unsigned class;
+ const char *desc;
+} tag_and_class_st;
+
+/* the types that are handled in _asn1_tags */
+#define CASE_HANDLED_ETYPES \
+ case ASN1_ETYPE_NULL: \
+ case ASN1_ETYPE_BOOLEAN: \
+ case ASN1_ETYPE_INTEGER: \
+ case ASN1_ETYPE_ENUMERATED: \
+ case ASN1_ETYPE_OBJECT_ID: \
+ case ASN1_ETYPE_OCTET_STRING: \
+ case ASN1_ETYPE_GENERALSTRING: \
+ case ASN1_ETYPE_NUMERIC_STRING: \
+ case ASN1_ETYPE_IA5_STRING: \
+ case ASN1_ETYPE_TELETEX_STRING: \
+ case ASN1_ETYPE_PRINTABLE_STRING: \
+ case ASN1_ETYPE_UNIVERSAL_STRING: \
+ case ASN1_ETYPE_BMP_STRING: \
+ case ASN1_ETYPE_UTF8_STRING: \
+ case ASN1_ETYPE_VISIBLE_STRING: \
+ case ASN1_ETYPE_BIT_STRING: \
+ case ASN1_ETYPE_SEQUENCE: \
+ case ASN1_ETYPE_SEQUENCE_OF: \
+ case ASN1_ETYPE_SET: \
+ case ASN1_ETYPE_UTC_TIME: \
+ case ASN1_ETYPE_GENERALIZED_TIME: \
+ case ASN1_ETYPE_SET_OF
+
+#define ETYPE_TAG(etype) (_asn1_tags[etype].tag)
+#define ETYPE_CLASS(etype) (_asn1_tags[etype].class)
+#define ETYPE_OK(etype) (((etype) != ASN1_ETYPE_INVALID && \
+ (etype) <= _asn1_tags_size && \
+ _asn1_tags[(etype)].desc != NULL)?1:0)
+
+#define ETYPE_IS_STRING(etype) ((etype == ASN1_ETYPE_GENERALSTRING || \
+ etype == ASN1_ETYPE_NUMERIC_STRING || etype == ASN1_ETYPE_IA5_STRING || \
+ etype == ASN1_ETYPE_TELETEX_STRING || etype == ASN1_ETYPE_PRINTABLE_STRING || \
+ etype == ASN1_ETYPE_UNIVERSAL_STRING || etype == ASN1_ETYPE_BMP_STRING || \
+ etype == ASN1_ETYPE_UTF8_STRING || etype == ASN1_ETYPE_VISIBLE_STRING || \
+ etype == ASN1_ETYPE_OCTET_STRING)?1:0)
+
+extern unsigned int _asn1_tags_size;
+extern const tag_and_class_st _asn1_tags[];
+
+#define _asn1_strlen(s) strlen((const char *) s)
+#define _asn1_strtol(n,e,b) strtol((const char *) n, e, b)
+#define _asn1_strtoul(n,e,b) strtoul((const char *) n, e, b)
+#define _asn1_strcmp(a,b) strcmp((const char *)a, (const char *)b)
+#define _asn1_strcpy(a,b) strcpy((char *)a, (const char *)b)
+#define _asn1_strcat(a,b) strcat((char *)a, (const char *)b)
+
+#if SIZEOF_UNSIGNED_LONG_INT == 8
+# define _asn1_strtou64(n,e,b) strtoul((const char *) n, e, b)
+#else
+# define _asn1_strtou64(n,e,b) strtoull((const char *) n, e, b)
+#endif
+
+#define MAX_LOG_SIZE 1024 /* maximum number of characters of a log message */
+
+/* Define used for visiting trees. */
+#define UP 1
+#define RIGHT 2
+#define DOWN 3
+
+/***********************************************************************/
+/* List of constants to better specify the type of typedef asn1_node_st. */
+/***********************************************************************/
+/* Used with TYPE_TAG */
+#define CONST_UNIVERSAL (1U<<8)
+#define CONST_PRIVATE (1U<<9)
+#define CONST_APPLICATION (1U<<10)
+#define CONST_EXPLICIT (1U<<11)
+#define CONST_IMPLICIT (1U<<12)
+
+#define CONST_TAG (1U<<13) /* Used in ASN.1 assignement */
+#define CONST_OPTION (1U<<14)
+#define CONST_DEFAULT (1U<<15)
+#define CONST_TRUE (1U<<16)
+#define CONST_FALSE (1U<<17)
+
+#define CONST_LIST (1U<<18) /* Used with TYPE_INTEGER and TYPE_BIT_STRING */
+#define CONST_MIN_MAX (1U<<19)
+
+#define CONST_1_PARAM (1U<<20)
+
+#define CONST_SIZE (1U<<21)
+
+#define CONST_DEFINED_BY (1U<<22)
+
+/* Those two are deprecated and used for backwards compatibility */
+#define CONST_GENERALIZED (1U<<23)
+#define CONST_UTC (1U<<24)
+
+/* #define CONST_IMPORTS (1U<<25) */
+
+#define CONST_NOT_USED (1U<<26)
+#define CONST_SET (1U<<27)
+#define CONST_ASSIGN (1U<<28)
+
+#define CONST_DOWN (1U<<29)
+#define CONST_RIGHT (1U<<30)
+
+
+#define ASN1_ETYPE_TIME 17
+/****************************************/
+/* Returns the first 8 bits. */
+/* Used with the field type of asn1_node_st */
+/****************************************/
+inline static unsigned int
+type_field (unsigned int ntype)
+{
+ return (ntype & 0xff);
+}
+
+/* To convert old types from a static structure */
+inline static unsigned int
+convert_old_type (unsigned int ntype)
+{
+ unsigned int type = ntype & 0xff;
+ if (type == ASN1_ETYPE_TIME)
+ {
+ if (ntype & CONST_UTC)
+ type = ASN1_ETYPE_UTC_TIME;
+ else
+ type = ASN1_ETYPE_GENERALIZED_TIME;
+
+ ntype &= ~(CONST_UTC | CONST_GENERALIZED);
+ ntype &= 0xffffff00;
+ ntype |= type;
+
+ return ntype;
+ }
+ else
+ return ntype;
+}
+
+static inline
+void *_asn1_realloc(void *ptr, size_t size)
+{
+ void *ret;
+
+ if (size == 0)
+ return ptr;
+
+ ret = realloc(ptr, size);
+ if (ret == NULL)
+ {
+ free(ptr);
+ }
+ return ret;
+}
+
+#endif /* INT_H */
diff --git a/lib/minitasn1/libtasn1.h b/lib/minitasn1/libtasn1.h
new file mode 100644
index 0000000..c7c937f
--- /dev/null
+++ b/lib/minitasn1/libtasn1.h
@@ -0,0 +1,637 @@
+/*
+ * Copyright (C) 2002-2021 Free Software Foundation, Inc.
+ *
+ * This file is part of LIBTASN1.
+ *
+ * LIBTASN1 is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * LIBTASN1 is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with LIBTASN1; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+/**
+ * SECTION:libtasn1
+ * @short_description: GNU ASN.1 library
+ *
+ * The Libtasn1 library provides Abstract Syntax Notation One (ASN.1, as
+ * specified by the X.680 ITU-T recommendation) parsing and structures
+ * management, and Distinguished Encoding Rules (DER, as per X.690)
+ * encoding and decoding functions.
+ */
+
+
+#ifndef LIBTASN1_H
+#define LIBTASN1_H
+
+#ifndef ASN1_API
+#if defined ASN1_BUILDING && defined HAVE_VISIBILITY && HAVE_VISIBILITY
+#define ASN1_API __attribute__((__visibility__("default")))
+#elif defined ASN1_BUILDING && defined _MSC_VER && ! defined ASN1_STATIC
+#define ASN1_API __declspec(dllexport)
+#elif defined _MSC_VER && ! defined ASN1_STATIC
+#define ASN1_API __declspec(dllimport)
+#else
+#define ASN1_API
+#endif
+#endif
+
+#ifdef __GNUC__
+# define __LIBTASN1_CONST__ __attribute__((const))
+# define __LIBTASN1_PURE__ __attribute__((pure))
+#else
+# define __LIBTASN1_CONST__
+# define __LIBTASN1_PURE__
+#endif
+
+#include <sys/types.h>
+#include <time.h>
+#include <stdio.h> /* for FILE* */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * ASN1_VERSION:
+ *
+ * Version of the library as a string.
+ */
+#define ASN1_VERSION "4.17.0"
+
+/**
+ * ASN1_VERSION_MAJOR:
+ *
+ * Major version number of the library.
+ */
+#define ASN1_VERSION_MAJOR @MAJOR_VERSION@
+
+/**
+ * ASN1_VERSION_MINOR:
+ *
+ * Minor version number of the library.
+ */
+#define ASN1_VERSION_MINOR @MINOR_VERSION@
+
+/**
+ * ASN1_VERSION_PATCH:
+ *
+ * Patch version number of the library.
+ */
+#define ASN1_VERSION_PATCH @PATCH_VERSION@
+
+/**
+ * ASN1_VERSION_NUMBER:
+ *
+ * Version number of the library as a number.
+ */
+#define ASN1_VERSION_NUMBER @NUMBER_VERSION@
+
+
+#if defined __GNUC__ && !defined ASN1_INTERNAL_BUILD
+# define _ASN1_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
+# if _ASN1_GCC_VERSION >= 30100
+# define _ASN1_GCC_ATTR_DEPRECATED __attribute__ ((__deprecated__))
+# endif
+#endif
+
+#ifndef _ASN1_GCC_ATTR_DEPRECATED
+#define _ASN1_GCC_ATTR_DEPRECATED
+#endif
+
+/*****************************************/
+/* Errors returned by libtasn1 functions */
+/*****************************************/
+#define ASN1_SUCCESS 0
+#define ASN1_FILE_NOT_FOUND 1
+#define ASN1_ELEMENT_NOT_FOUND 2
+#define ASN1_IDENTIFIER_NOT_FOUND 3
+#define ASN1_DER_ERROR 4
+#define ASN1_VALUE_NOT_FOUND 5
+#define ASN1_GENERIC_ERROR 6
+#define ASN1_VALUE_NOT_VALID 7
+#define ASN1_TAG_ERROR 8
+#define ASN1_TAG_IMPLICIT 9
+#define ASN1_ERROR_TYPE_ANY 10
+#define ASN1_SYNTAX_ERROR 11
+#define ASN1_MEM_ERROR 12
+#define ASN1_MEM_ALLOC_ERROR 13
+#define ASN1_DER_OVERFLOW 14
+#define ASN1_NAME_TOO_LONG 15
+#define ASN1_ARRAY_ERROR 16
+#define ASN1_ELEMENT_NOT_EMPTY 17
+#define ASN1_TIME_ENCODING_ERROR 18
+#define ASN1_RECURSION 19
+
+/*************************************/
+/* Constants used in asn1_visit_tree */
+/*************************************/
+#define ASN1_PRINT_NAME 1
+#define ASN1_PRINT_NAME_TYPE 2
+#define ASN1_PRINT_NAME_TYPE_VALUE 3
+#define ASN1_PRINT_ALL 4
+
+/*****************************************/
+/* Constants returned by asn1_read_tag */
+/*****************************************/
+#define ASN1_CLASS_UNIVERSAL 0x00 /* old: 1 */
+#define ASN1_CLASS_APPLICATION 0x40 /* old: 2 */
+#define ASN1_CLASS_CONTEXT_SPECIFIC 0x80 /* old: 3 */
+#define ASN1_CLASS_PRIVATE 0xC0 /* old: 4 */
+#define ASN1_CLASS_STRUCTURED 0x20
+
+/*****************************************/
+/* Constants returned by asn1_read_tag */
+/*****************************************/
+#define ASN1_TAG_BOOLEAN 0x01
+#define ASN1_TAG_INTEGER 0x02
+#define ASN1_TAG_SEQUENCE 0x10
+#define ASN1_TAG_SET 0x11
+#define ASN1_TAG_OCTET_STRING 0x04
+#define ASN1_TAG_BIT_STRING 0x03
+#define ASN1_TAG_UTCTime 0x17
+#define ASN1_TAG_GENERALIZEDTime 0x18
+#define ASN1_TAG_OBJECT_ID 0x06
+#define ASN1_TAG_ENUMERATED 0x0A
+#define ASN1_TAG_NULL 0x05
+#define ASN1_TAG_GENERALSTRING 0x1B
+#define ASN1_TAG_NUMERIC_STRING 0x12
+#define ASN1_TAG_IA5_STRING 0x16
+#define ASN1_TAG_TELETEX_STRING 0x14
+#define ASN1_TAG_PRINTABLE_STRING 0x13
+#define ASN1_TAG_UNIVERSAL_STRING 0x1C
+#define ASN1_TAG_BMP_STRING 0x1E
+#define ASN1_TAG_UTF8_STRING 0x0C
+#define ASN1_TAG_VISIBLE_STRING 0x1A
+
+/**
+ * asn1_node:
+ *
+ * Structure definition used for the node of the tree
+ * that represents an ASN.1 DEFINITION.
+ */
+typedef struct asn1_node_st asn1_node_st;
+
+typedef asn1_node_st *asn1_node;
+typedef const asn1_node_st *asn1_node_const;
+
+/**
+ * ASN1_MAX_NAME_SIZE:
+ *
+ * Maximum number of characters of a name
+ * inside a file with ASN1 definitions.
+ */
+#define ASN1_MAX_NAME_SIZE 64
+
+
+/**
+ * asn1_static_node:
+ * @name: Node name
+ * @type: Node typ
+ * @value: Node value
+ *
+ * For the on-disk format of ASN.1 trees, created by asn1_parser2array().
+ */
+typedef struct asn1_static_node_st
+{
+ const char *name; /* Node name */
+ unsigned int type; /* Node type */
+ const void *value; /* Node value */
+} asn1_static_node;
+
+/* List of constants for field type of asn1_static_node */
+#define ASN1_ETYPE_INVALID 0
+#define ASN1_ETYPE_CONSTANT 1
+#define ASN1_ETYPE_IDENTIFIER 2
+#define ASN1_ETYPE_INTEGER 3
+#define ASN1_ETYPE_BOOLEAN 4
+#define ASN1_ETYPE_SEQUENCE 5
+#define ASN1_ETYPE_BIT_STRING 6
+#define ASN1_ETYPE_OCTET_STRING 7
+#define ASN1_ETYPE_TAG 8
+#define ASN1_ETYPE_DEFAULT 9
+#define ASN1_ETYPE_SIZE 10
+#define ASN1_ETYPE_SEQUENCE_OF 11
+#define ASN1_ETYPE_OBJECT_ID 12
+#define ASN1_ETYPE_ANY 13
+#define ASN1_ETYPE_SET 14
+#define ASN1_ETYPE_SET_OF 15
+#define ASN1_ETYPE_DEFINITIONS 16
+#define ASN1_ETYPE_CHOICE 18
+#define ASN1_ETYPE_IMPORTS 19
+#define ASN1_ETYPE_NULL 20
+#define ASN1_ETYPE_ENUMERATED 21
+#define ASN1_ETYPE_GENERALSTRING 27
+#define ASN1_ETYPE_NUMERIC_STRING 28
+#define ASN1_ETYPE_IA5_STRING 29
+#define ASN1_ETYPE_TELETEX_STRING 30
+#define ASN1_ETYPE_PRINTABLE_STRING 31
+#define ASN1_ETYPE_UNIVERSAL_STRING 32
+#define ASN1_ETYPE_BMP_STRING 33
+#define ASN1_ETYPE_UTF8_STRING 34
+#define ASN1_ETYPE_VISIBLE_STRING 35
+#define ASN1_ETYPE_UTC_TIME 36
+#define ASN1_ETYPE_GENERALIZED_TIME 37
+
+/**
+ * ASN1_DELETE_FLAG_ZEROIZE:
+ *
+ * Used by: asn1_delete_structure2()
+ *
+ * Zeroize values prior to deinitialization.
+ */
+#define ASN1_DELETE_FLAG_ZEROIZE 1
+
+/**
+ * ASN1_DECODE_FLAG_ALLOW_PADDING:
+ *
+ * Used by: asn1_der_decoding2()
+ *
+ * This flag would allow arbitrary data past the DER data.
+ */
+#define ASN1_DECODE_FLAG_ALLOW_PADDING 1
+/**
+ * ASN1_DECODE_FLAG_STRICT_DER:
+ *
+ * Used by: asn1_der_decoding2()
+ *
+ * This flag would ensure that no BER decoding takes place.
+ */
+#define ASN1_DECODE_FLAG_STRICT_DER (1<<1)
+/**
+ * ASN1_DECODE_FLAG_ALLOW_INCORRECT_TIME:
+ *
+ * Used by: asn1_der_decoding2()
+ *
+ * This flag will tolerate Time encoding errors when in strict DER.
+ */
+#define ASN1_DECODE_FLAG_ALLOW_INCORRECT_TIME (1<<2)
+
+
+/**
+ * asn1_data_node_st:
+ * @name: Node name
+ * @value: Node value
+ * @value_len: Node value size
+ * @type: Node value type (ASN1_ETYPE_*)
+ *
+ * Data node inside a #asn1_node structure.
+ */
+struct asn1_data_node_st
+{
+ const char *name; /* Node name */
+ const void *value; /* Node value */
+ unsigned int value_len; /* Node value size */
+ unsigned int type; /* Node value type (ASN1_ETYPE_*) */
+};
+typedef struct asn1_data_node_st asn1_data_node_st;
+
+/***********************************/
+/* Fixed constants */
+/***********************************/
+
+/**
+ * ASN1_MAX_ERROR_DESCRIPTION_SIZE:
+ *
+ * Maximum number of characters
+ * of a description message
+ * (null character included).
+ */
+#define ASN1_MAX_ERROR_DESCRIPTION_SIZE 128
+
+/***********************************/
+/* Functions definitions */
+/***********************************/
+
+extern ASN1_API int
+ asn1_parser2tree (const char *file,
+ asn1_node * definitions, char *error_desc);
+
+extern ASN1_API int
+ asn1_parser2array (const char *inputFileName,
+ const char *outputFileName,
+ const char *vectorName, char *error_desc);
+
+extern ASN1_API int
+ asn1_array2tree (const asn1_static_node * array,
+ asn1_node * definitions, char *errorDescription);
+
+extern ASN1_API void
+ asn1_print_structure (FILE * out, asn1_node_const structure,
+ const char *name, int mode);
+
+extern ASN1_API int
+ asn1_create_element (asn1_node_const definitions,
+ const char *source_name, asn1_node * element);
+
+extern ASN1_API int asn1_delete_structure (asn1_node * structure);
+
+extern ASN1_API int asn1_delete_structure2 (asn1_node * structure, unsigned int flags);
+
+extern ASN1_API int
+ asn1_delete_element (asn1_node structure, const char *element_name);
+
+extern ASN1_API int
+ asn1_write_value (asn1_node node_root, const char *name,
+ const void *ivalue, int len);
+
+extern ASN1_API int
+ asn1_read_value (asn1_node_const root, const char *name,
+ void *ivalue, int *len);
+
+extern ASN1_API int
+ asn1_read_value_type (asn1_node_const root, const char *name,
+ void *ivalue, int *len, unsigned int *etype);
+
+extern ASN1_API int
+ asn1_read_node_value (asn1_node_const node, asn1_data_node_st * data);
+
+extern ASN1_API int
+ asn1_number_of_elements (asn1_node_const element, const char *name, int *num);
+
+extern ASN1_API int
+ asn1_der_coding (asn1_node_const element, const char *name,
+ void *ider, int *len, char *ErrorDescription);
+
+extern ASN1_API int
+ asn1_der_decoding2 (asn1_node *element, const void *ider,
+ int *max_ider_len, unsigned int flags,
+ char *errorDescription);
+
+extern ASN1_API int
+ asn1_der_decoding (asn1_node * element, const void *ider,
+ int ider_len, char *errorDescription);
+
+/* Do not use. Use asn1_der_decoding() instead. */
+extern ASN1_API int
+ asn1_der_decoding_element (asn1_node * structure,
+ const char *elementName,
+ const void *ider, int len,
+ char *errorDescription) _ASN1_GCC_ATTR_DEPRECATED;
+
+extern ASN1_API int
+ asn1_der_decoding_startEnd (asn1_node element,
+ const void *ider, int ider_len,
+ const char *name_element,
+ int *start, int *end);
+
+extern ASN1_API int
+ asn1_expand_any_defined_by (asn1_node_const definitions, asn1_node * element);
+
+extern ASN1_API int
+ asn1_expand_octet_string (asn1_node_const definitions,
+ asn1_node * element,
+ const char *octetName, const char *objectName);
+
+extern ASN1_API int
+ asn1_read_tag (asn1_node_const root, const char *name,
+ int *tagValue, int *classValue);
+
+extern ASN1_API const char *asn1_find_structure_from_oid (asn1_node_const
+ definitions,
+ const char
+ *oidValue);
+
+__LIBTASN1_PURE__
+extern ASN1_API const char *asn1_check_version (const char *req_version);
+
+__LIBTASN1_PURE__
+extern ASN1_API const char *asn1_strerror (int error);
+
+extern ASN1_API void asn1_perror (int error);
+
+#define ASN1_MAX_TAG_SIZE 4
+#define ASN1_MAX_LENGTH_SIZE 9
+#define ASN1_MAX_TL_SIZE (ASN1_MAX_TAG_SIZE+ASN1_MAX_LENGTH_SIZE)
+extern ASN1_API long
+ asn1_get_length_der (const unsigned char *der, int der_len, int *len);
+
+extern ASN1_API long
+ asn1_get_length_ber (const unsigned char *ber, int ber_len, int *len);
+
+extern ASN1_API void
+ asn1_length_der (unsigned long int len, unsigned char *der, int *der_len);
+
+/* Other utility functions. */
+
+extern ASN1_API
+ int asn1_decode_simple_der (unsigned int etype, const unsigned char *der,
+ unsigned int _der_len,
+ const unsigned char **str,
+ unsigned int *str_len);
+
+extern ASN1_API
+ int asn1_decode_simple_ber (unsigned int etype, const unsigned char *der,
+ unsigned int _der_len,
+ unsigned char **str,
+ unsigned int *str_len,
+ unsigned int *ber_len);
+
+extern ASN1_API int
+ asn1_encode_simple_der (unsigned int etype, const unsigned char *str,
+ unsigned int str_len, unsigned char *tl,
+ unsigned int *tl_len);
+
+extern ASN1_API asn1_node
+ asn1_find_node (asn1_node_const pointer, const char *name);
+
+extern ASN1_API int
+ asn1_copy_node (asn1_node dst, const char *dst_name,
+ asn1_node_const src, const char *src_name);
+extern ASN1_API asn1_node
+ asn1_dup_node (asn1_node_const src, const char *src_name);
+
+/* Internal and low-level DER utility functions. */
+
+extern ASN1_API int
+ asn1_get_tag_der (const unsigned char *der, int der_len,
+ unsigned char *cls, int *len, unsigned long *tag);
+
+extern ASN1_API void
+ asn1_octet_der (const unsigned char *str, int str_len,
+ unsigned char *der, int *der_len);
+
+extern ASN1_API int
+ asn1_get_octet_der (const unsigned char *der, int der_len,
+ int *ret_len, unsigned char *str,
+ int str_size, int *str_len);
+
+extern ASN1_API void asn1_bit_der (const unsigned char *str, int bit_len,
+ unsigned char *der, int *der_len);
+
+extern ASN1_API int
+ asn1_get_bit_der (const unsigned char *der, int der_len,
+ int *ret_len, unsigned char *str,
+ int str_size, int *bit_len);
+
+extern ASN1_API int
+ asn1_get_object_id_der (const unsigned char *der,
+ int der_len, int *ret_len,
+ char *str, int str_size);
+
+extern ASN1_API int
+ asn1_object_id_der (const char *str, unsigned char *der, int *der_len,
+ unsigned flags);
+
+/* Compatibility types */
+
+/**
+ * asn1_retCode:
+ *
+ * Type formerly returned by libtasn1 functions.
+ *
+ * Deprecated: 3.0: Use int instead.
+ */
+typedef int asn1_retCode _ASN1_GCC_ATTR_DEPRECATED;
+
+/**
+ * node_asn_struct:
+ *
+ * Compat #define.
+ *
+ * Deprecated: 3.0: Use #asn1_node instead.
+ */
+#ifndef ASN1_DISABLE_DEPRECATED
+#if _ASN1_GCC_VERSION >= 30100
+#define node_asn_struct _Pragma ("GCC warning \"'node_asn_struct' macro is deprecated, use 'asn1_node' instead.\"") asn1_node_st
+#else
+#define node_asn_struct asn1_node_st
+#endif
+#endif /* !ASN1_DISABLE_DEPRECATED */
+
+/**
+ * node_asn:
+ *
+ * Compat #define.
+ *
+ * Deprecated: 3.0: Use #asn1_node instead.
+ */
+#ifndef ASN1_DISABLE_DEPRECATED
+#if _ASN1_GCC_VERSION >= 30100
+#define node_asn _Pragma ("GCC warning \"'node_asn' macro is deprecated, use 'asn1_node' instead.\"") asn1_node_st
+#else
+#define node_asn asn1_node_st
+#endif
+#endif /* !ASN1_DISABLE_DEPRECATED */
+
+/**
+ * ASN1_TYPE:
+ *
+ * Compat #define.
+ *
+ * Deprecated: 3.0: Use #asn1_node instead.
+ */
+#ifndef ASN1_DISABLE_DEPRECATED
+#if _ASN1_GCC_VERSION >= 30100
+#define ASN1_TYPE _Pragma ("GCC warning \"'ASN1_TYPE' macro is deprecated, use 'asn1_node' instead.\"") asn1_node
+#else
+#define ASN1_TYPE asn1_node
+#endif
+#endif /* !ASN1_DISABLE_DEPRECATED */
+
+/**
+ * ASN1_TYPE_EMPTY:
+ *
+ * Compat #define.
+ *
+ * Deprecated: 3.0: Use NULL instead.
+ */
+#ifndef ASN1_DISABLE_DEPRECATED
+#if _ASN1_GCC_VERSION >= 30100
+#define ASN1_TYPE_EMPTY _Pragma ("GCC warning \"'ASN1_TYPE_EMPTY' macro is deprecated, use 'NULL' instead.\"") NULL
+#else
+#define ASN1_TYPE_EMPTY NULL
+#endif
+#endif /* !ASN1_DISABLE_DEPRECATED */
+
+/**
+ * static_struct_asn:
+ *
+ * Compat #define.
+ *
+ * Deprecated: 3.0: Use #asn1_static_node instead.
+ */
+#ifndef ASN1_DISABLE_DEPRECATED
+#if _ASN1_GCC_VERSION >= 30100
+#define static_struct_asn _Pragma ("GCC warning \"'static_struct_asn' macro is deprecated, use 'asn1_static_node_st' instead.\"") asn1_static_node_st
+#else
+#define static_struct_asn asn1_static_node_st
+#endif
+#endif /* !ASN1_DISABLE_DEPRECATED */
+
+/**
+ * ASN1_ARRAY_TYPE:
+ *
+ * Compat #define.
+ *
+ * Deprecated: 3.0: Use #asn1_static_node instead.
+ */
+#ifndef ASN1_DISABLE_DEPRECATED
+#if _ASN1_GCC_VERSION >= 30100
+#define ASN1_ARRAY_TYPE _Pragma ("GCC warning \"'ASN1_ARRAY_TYPE' macro is deprecated, use 'asn1_static_node' instead.\"") asn1_static_node
+#else
+#define ASN1_ARRAY_TYPE asn1_static_node
+#endif
+#endif /* !ASN1_DISABLE_DEPRECATED */
+
+/**
+ * asn1_static_node_t:
+ *
+ * Compat #define.
+ *
+ * Deprecated: 3.0: Use #asn1_static_node instead.
+ */
+#ifndef ASN1_DISABLE_DEPRECATED
+#if _ASN1_GCC_VERSION >= 30100
+#define asn1_static_node_t _Pragma ("GCC warning \"'asn1_static_node_t' macro is deprecated, use 'asn1_static_node' instead.\"") asn1_static_node
+#else
+#define asn1_static_node_t asn1_static_node
+#endif
+#endif /* !ASN1_DISABLE_DEPRECATED */
+
+/**
+ * node_data_struct:
+ *
+ * Compat #define.
+ *
+ * Deprecated: 3.0: Use #asn1_data_node_st instead.
+ */
+#ifndef ASN1_DISABLE_DEPRECATED
+#if _ASN1_GCC_VERSION >= 30100
+#define node_data_struct _Pragma ("GCC warning \"'node_data_struct' macro is deprecated, use 'asn1_data_node_st' instead.\"") asn1_data_node_st
+#else
+#define node_data_struct asn1_data_node_st
+#endif
+#endif /* !ASN1_DISABLE_DEPRECATED */
+
+/**
+ * ASN1_DATA_NODE:
+ *
+ * Compat #define.
+ *
+ * Deprecated: 3.0: Use #asn1_data_node_st instead.
+ */
+#ifndef ASN1_DISABLE_DEPRECATED
+#if _ASN1_GCC_VERSION >= 30100
+#define ASN1_DATA_NODE _Pragma ("GCC warning \"'asn1_static_node_t' macro is deprecated, use 'asn1_static_node' instead.\"") asn1_data_node_st
+#else
+#define ASN1_DATA_NODE asn1_data_node_st
+#endif
+#endif /* !ASN1_DISABLE_DEPRECATED */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBTASN1_H */
diff --git a/lib/minitasn1/parser_aux.c b/lib/minitasn1/parser_aux.c
new file mode 100644
index 0000000..bb88ab9
--- /dev/null
+++ b/lib/minitasn1/parser_aux.c
@@ -0,0 +1,1173 @@
+/*
+ * Copyright (C) 2000-2021 Free Software Foundation, Inc.
+ *
+ * This file is part of LIBTASN1.
+ *
+ * The LIBTASN1 library is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ */
+
+#include <limits.h> // WORD_BIT
+
+#include "int.h"
+#include "parser_aux.h"
+#include "gstr.h"
+#include "structure.h"
+#include "element.h"
+#include "c-ctype.h"
+
+char _asn1_identifierMissing[ASN1_MAX_NAME_SIZE + 1]; /* identifier name not found */
+
+/* Return a hash of the N bytes of X using the method described by
+ Bruno Haible in https://www.haible.de/bruno/hashfunc.html.
+ Note that while many hash functions reduce their result via modulo
+ to a 0..table_size-1 range, this function does not do that.
+
+ This implementation has been changed from size_t -> unsigned int. */
+
+#ifdef __clang__
+__attribute__((no_sanitize("integer")))
+#endif
+_GL_ATTRIBUTE_PURE
+static unsigned int
+_asn1_hash_name (const char *x)
+{
+ const unsigned char *s = (unsigned char *) x;
+ unsigned h = 0;
+
+ while (*s)
+ h = (*s++) + ((h << 9) | (h >> (WORD_BIT - 9)));
+
+ return h;
+}
+
+/******************************************************/
+/* Function : _asn1_add_static_node */
+/* Description: creates a new NODE_ASN element and */
+/* puts it in the list pointed by e_list. */
+/* Parameters: */
+/* e_list: of type list_type; must be NULL initially */
+/* type: type of the new element (see ASN1_ETYPE_ */
+/* and CONST_ constants). */
+/* Return: pointer to the new element. */
+/******************************************************/
+asn1_node
+_asn1_add_static_node (list_type **e_list, unsigned int type)
+{
+ list_type *p;
+ asn1_node punt;
+
+ punt = calloc (1, sizeof (struct asn1_node_st));
+ if (punt == NULL)
+ return NULL;
+
+ p = malloc (sizeof (list_type));
+ if (p == NULL)
+ {
+ free (punt);
+ return NULL;
+ }
+
+ p->node = punt;
+ p->next = *e_list;
+ *e_list = p;
+
+ punt->type = type;
+
+ return punt;
+}
+
+static
+int _asn1_add_static_node2 (list_type **e_list, asn1_node node)
+{
+ list_type *p;
+
+ p = malloc (sizeof (list_type));
+ if (p == NULL)
+ {
+ return -1;
+ }
+
+ p->node = node;
+ p->next = *e_list;
+ *e_list = p;
+
+ return 0;
+}
+
+/**
+ * asn1_find_node:
+ * @pointer: NODE_ASN element pointer.
+ * @name: null terminated string with the element's name to find.
+ *
+ * Searches for an element called @name starting from @pointer. The
+ * name is composed by different identifiers separated by dots. When
+ * *@pointer has a name, the first identifier must be the name of
+ * *@pointer, otherwise it must be the name of one child of *@pointer.
+ *
+ * Returns: the search result, or %NULL if not found.
+ **/
+asn1_node
+asn1_find_node (asn1_node_const pointer, const char *name)
+{
+ asn1_node_const p;
+ char *n_end, n[ASN1_MAX_NAME_SIZE + 1];
+ const char *n_start;
+ unsigned int nsize;
+ unsigned int nhash;
+
+ if (pointer == NULL)
+ return NULL;
+
+ if (name == NULL)
+ return NULL;
+
+ p = pointer;
+ n_start = name;
+
+ if (name[0] == '?' && name[1] == 'C' && p->name[0] == '?')
+ { /* ?CURRENT */
+ n_start = strchr(n_start, '.');
+ if (n_start)
+ n_start++;
+ }
+ else if (p->name[0] != 0)
+ { /* has *pointer got a name ? */
+ n_end = strchr (n_start, '.'); /* search the first dot */
+ if (n_end)
+ {
+ nsize = n_end - n_start;
+ if (nsize >= sizeof(n))
+ return NULL;
+
+ memcpy (n, n_start, nsize);
+ n[nsize] = 0;
+ n_start = n_end;
+ n_start++;
+
+ nhash = _asn1_hash_name (n);
+ }
+ else
+ {
+ _asn1_str_cpy (n, sizeof (n), n_start);
+ nhash = _asn1_hash_name (n);
+
+ n_start = NULL;
+ }
+
+ while (p)
+ {
+ if (nhash == p->name_hash && (!strcmp (p->name, n)))
+ break;
+ else
+ p = p->right;
+ } /* while */
+
+ if (p == NULL)
+ return NULL;
+ }
+ else
+ { /* *pointer doesn't have a name */
+ if (n_start[0] == 0)
+ return (asn1_node) p;
+ }
+
+ while (n_start)
+ { /* Has the end of NAME been reached? */
+ n_end = strchr (n_start, '.'); /* search the next dot */
+ if (n_end)
+ {
+ nsize = n_end - n_start;
+ if (nsize >= sizeof(n))
+ return NULL;
+
+ memcpy (n, n_start, nsize);
+ n[nsize] = 0;
+ n_start = n_end;
+ n_start++;
+
+ nhash = _asn1_hash_name (n);
+ }
+ else
+ {
+ _asn1_str_cpy (n, sizeof (n), n_start);
+ nhash = _asn1_hash_name (n);
+ n_start = NULL;
+ }
+
+ if (p->down == NULL)
+ return NULL;
+
+ p = p->down;
+ if (p == NULL)
+ return NULL;
+
+ /* The identifier "?LAST" indicates the last element
+ in the right chain. */
+ if (n[0] == '?' && n[1] == 'L') /* ?LAST */
+ {
+ while (p->right)
+ p = p->right;
+ }
+ else
+ { /* no "?LAST" */
+ while (p)
+ {
+ if (p->name_hash == nhash && !strcmp (p->name, n))
+ break;
+ else
+ p = p->right;
+ }
+ }
+ if (p == NULL)
+ return NULL;
+ } /* while */
+
+ return (asn1_node) p;
+}
+
+
+/******************************************************************/
+/* Function : _asn1_set_value */
+/* Description: sets the field VALUE in a NODE_ASN element. The */
+/* previous value (if exist) will be lost */
+/* Parameters: */
+/* node: element pointer. */
+/* value: pointer to the value that you want to set. */
+/* len: character number of value. */
+/* Return: pointer to the NODE_ASN element. */
+/******************************************************************/
+asn1_node
+_asn1_set_value (asn1_node node, const void *value, unsigned int len)
+{
+ if (node == NULL)
+ return node;
+ if (node->value)
+ {
+ if (node->value != node->small_value)
+ free (node->value);
+ node->value = NULL;
+ node->value_len = 0;
+ }
+
+ if (!len)
+ return node;
+
+ if (len < sizeof (node->small_value))
+ {
+ node->value = node->small_value;
+ }
+ else
+ {
+ node->value = malloc (len);
+ if (node->value == NULL)
+ return NULL;
+ }
+ node->value_len = len;
+
+ memcpy (node->value, value, len);
+ return node;
+}
+
+/******************************************************************/
+/* Function : _asn1_set_value_lv */
+/* Description: sets the field VALUE in a NODE_ASN element. The */
+/* previous value (if exist) will be lost. The value */
+/* given is stored as an length-value format (LV */
+/* Parameters: */
+/* node: element pointer. */
+/* value: pointer to the value that you want to set. */
+/* len: character number of value. */
+/* Return: pointer to the NODE_ASN element. */
+/******************************************************************/
+asn1_node
+_asn1_set_value_lv (asn1_node node, const void *value, unsigned int len)
+{
+ int len2;
+ void *temp;
+
+ if (node == NULL)
+ return node;
+
+ asn1_length_der (len, NULL, &len2);
+ temp = malloc (len + len2);
+ if (temp == NULL)
+ return NULL;
+
+ asn1_octet_der (value, len, temp, &len2);
+ return _asn1_set_value_m (node, temp, len2);
+}
+
+/* the same as _asn1_set_value except that it sets an already malloc'ed
+ * value.
+ */
+asn1_node
+_asn1_set_value_m (asn1_node node, void *value, unsigned int len)
+{
+ if (node == NULL)
+ return node;
+
+ if (node->value)
+ {
+ if (node->value != node->small_value)
+ free (node->value);
+ node->value = NULL;
+ node->value_len = 0;
+ }
+
+ if (!len)
+ return node;
+
+ node->value = value;
+ node->value_len = len;
+
+ return node;
+}
+
+/******************************************************************/
+/* Function : _asn1_append_value */
+/* Description: appends to the field VALUE in a NODE_ASN element. */
+/* */
+/* Parameters: */
+/* node: element pointer. */
+/* value: pointer to the value that you want to be appended. */
+/* len: character number of value. */
+/* Return: pointer to the NODE_ASN element. */
+/******************************************************************/
+asn1_node
+_asn1_append_value (asn1_node node, const void *value, unsigned int len)
+{
+ if (node == NULL)
+ return node;
+
+ if (node->value == NULL)
+ return _asn1_set_value (node, value, len);
+
+ if (len == 0)
+ return node;
+
+ if (node->value == node->small_value)
+ {
+ /* value is in node */
+ int prev_len = node->value_len;
+ node->value_len += len;
+ node->value = malloc (node->value_len);
+ if (node->value == NULL)
+ {
+ node->value_len = 0;
+ return NULL;
+ }
+
+ if (prev_len > 0)
+ memcpy (node->value, node->small_value, prev_len);
+
+ memcpy (&node->value[prev_len], value, len);
+
+ return node;
+ }
+ else /* if (node->value != NULL && node->value != node->small_value) */
+ {
+ /* value is allocated */
+ int prev_len = node->value_len;
+ node->value_len += len;
+
+ node->value = _asn1_realloc (node->value, node->value_len);
+ if (node->value == NULL)
+ {
+ node->value_len = 0;
+ return NULL;
+ }
+
+ memcpy (&node->value[prev_len], value, len);
+
+ return node;
+ }
+}
+
+/******************************************************************/
+/* Function : _asn1_set_name */
+/* Description: sets the field NAME in a NODE_ASN element. The */
+/* previous value (if exist) will be lost */
+/* Parameters: */
+/* node: element pointer. */
+/* name: a null terminated string with the name that you want */
+/* to set. */
+/* Return: pointer to the NODE_ASN element. */
+/******************************************************************/
+asn1_node
+_asn1_set_name (asn1_node node, const char *name)
+{
+ if (node == NULL)
+ return node;
+
+ _asn1_str_cpy (node->name, sizeof (node->name), name ? name : "");
+ node->name_hash = _asn1_hash_name (node->name);
+
+ return node;
+}
+
+/******************************************************************/
+/* Function : _asn1_cpy_name */
+/* Description: copies the field NAME in a NODE_ASN element. */
+/* Parameters: */
+/* dst: a dest element pointer. */
+/* src: a source element pointer. */
+/* Return: pointer to the NODE_ASN element. */
+/******************************************************************/
+asn1_node
+_asn1_cpy_name (asn1_node dst, asn1_node_const src)
+{
+ if (dst == NULL)
+ return dst;
+
+ if (src == NULL)
+ {
+ dst->name[0] = 0;
+ dst->name_hash = _asn1_hash_name (dst->name);
+ return dst;
+ }
+
+ _asn1_str_cpy (dst->name, sizeof (dst->name), src->name);
+ dst->name_hash = src->name_hash;
+
+ return dst;
+}
+
+/******************************************************************/
+/* Function : _asn1_set_right */
+/* Description: sets the field RIGHT in a NODE_ASN element. */
+/* Parameters: */
+/* node: element pointer. */
+/* right: pointer to a NODE_ASN element that you want be pointed*/
+/* by NODE. */
+/* Return: pointer to *NODE. */
+/******************************************************************/
+asn1_node
+_asn1_set_right (asn1_node node, asn1_node right)
+{
+ if (node == NULL)
+ return node;
+ node->right = right;
+ if (right)
+ right->left = node;
+ return node;
+}
+
+
+/******************************************************************/
+/* Function : _asn1_get_last_right */
+/* Description: return the last element along the right chain. */
+/* Parameters: */
+/* node: starting element pointer. */
+/* Return: pointer to the last element along the right chain. */
+/******************************************************************/
+asn1_node
+_asn1_get_last_right (asn1_node_const node)
+{
+ asn1_node_const p;
+
+ if (node == NULL)
+ return NULL;
+ p = node;
+ while (p->right)
+ p = p->right;
+ return (asn1_node) p;
+}
+
+/******************************************************************/
+/* Function : _asn1_remove_node */
+/* Description: gets free the memory allocated for an NODE_ASN */
+/* element (not the elements pointed by it). */
+/* Parameters: */
+/* node: NODE_ASN element pointer. */
+/* flags: ASN1_DELETE_FLAG_* */
+/******************************************************************/
+void
+_asn1_remove_node (asn1_node node, unsigned int flags)
+{
+ if (node == NULL)
+ return;
+
+ if (node->value != NULL)
+ {
+ if (flags & ASN1_DELETE_FLAG_ZEROIZE)
+ {
+ safe_memset(node->value, 0, node->value_len);
+ }
+
+ if (node->value != node->small_value)
+ free (node->value);
+ }
+ free (node);
+}
+
+/******************************************************************/
+/* Function : _asn1_find_up */
+/* Description: return the father of the NODE_ASN element. */
+/* Parameters: */
+/* node: NODE_ASN element pointer. */
+/* Return: Null if not found. */
+/******************************************************************/
+asn1_node
+_asn1_find_up (asn1_node_const node)
+{
+ asn1_node_const p;
+
+ if (node == NULL)
+ return NULL;
+
+ p = node;
+
+ while ((p->left != NULL) && (p->left->right == p))
+ p = p->left;
+
+ return p->left;
+}
+
+static
+unsigned _asn1_is_up (asn1_node_const up_cand, asn1_node_const down)
+{
+ asn1_node_const d, u;
+
+ if (up_cand == NULL || down == NULL)
+ return 0;
+
+ d = down;
+
+ while ((u = _asn1_find_up(d)) != NULL && u != d)
+ {
+ if (u == up_cand)
+ return 1;
+ d = u;
+ }
+
+ return 0;
+}
+
+/******************************************************************/
+/* Function : _asn1_delete_node_from_list */
+/* Description: deletes the list element given */
+/******************************************************************/
+void
+_asn1_delete_node_from_list (list_type *list, asn1_node node)
+{
+ list_type *p = list;
+
+ while (p)
+ {
+ if (p->node == node)
+ p->node = NULL;
+ p = p->next;
+ }
+}
+
+/******************************************************************/
+/* Function : _asn1_delete_list */
+/* Description: deletes the list elements (not the elements */
+/* pointed by them). */
+/******************************************************************/
+void
+_asn1_delete_list (list_type *e_list)
+{
+ list_type *p;
+
+ while (e_list)
+ {
+ p = e_list;
+ e_list = e_list->next;
+ free (p);
+ }
+}
+
+/******************************************************************/
+/* Function : _asn1_delete_list_and nodes */
+/* Description: deletes the list elements and the elements */
+/* pointed by them. */
+/******************************************************************/
+void
+_asn1_delete_list_and_nodes (list_type *e_list)
+{
+ list_type *p;
+
+ while (e_list)
+ {
+ p = e_list;
+ e_list = e_list->next;
+ _asn1_remove_node (p->node, 0);
+ free (p);
+ }
+}
+
+
+char *
+_asn1_ltostr (int64_t v, char str[LTOSTR_MAX_SIZE])
+{
+ uint64_t d, r;
+ char temp[LTOSTR_MAX_SIZE];
+ int count, k, start;
+ uint64_t val;
+
+ if (v < 0)
+ {
+ str[0] = '-';
+ start = 1;
+ val = -((uint64_t)v);
+ }
+ else
+ {
+ val = v;
+ start = 0;
+ }
+
+ count = 0;
+ do
+ {
+ d = val / 10;
+ r = val - d * 10;
+ temp[start + count] = '0' + (char) r;
+ count++;
+ val = d;
+ }
+ while (val && ((start+count) < LTOSTR_MAX_SIZE-1));
+
+ for (k = 0; k < count; k++)
+ str[k + start] = temp[start + count - k - 1];
+ str[count + start] = 0;
+ return str;
+}
+
+
+/******************************************************************/
+/* Function : _asn1_change_integer_value */
+/* Description: converts into DER coding the value assign to an */
+/* INTEGER constant. */
+/* Parameters: */
+/* node: root of an ASN1element. */
+/* Return: */
+/* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */
+/* otherwise ASN1_SUCCESS */
+/******************************************************************/
+int
+_asn1_change_integer_value (asn1_node node)
+{
+ asn1_node p;
+ unsigned char val[SIZEOF_UNSIGNED_LONG_INT];
+ unsigned char val2[SIZEOF_UNSIGNED_LONG_INT + 1];
+ int len;
+
+ if (node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ p = node;
+ while (p)
+ {
+ if ((type_field (p->type) == ASN1_ETYPE_INTEGER)
+ && (p->type & CONST_ASSIGN))
+ {
+ if (p->value)
+ {
+ _asn1_convert_integer (p->value, val, sizeof (val), &len);
+ asn1_octet_der (val, len, val2, &len);
+ _asn1_set_value (p, val2, len);
+ }
+ }
+
+ if (p->down)
+ {
+ p = p->down;
+ }
+ else
+ {
+ if (p == node)
+ p = NULL;
+ else if (p->right)
+ p = p->right;
+ else
+ {
+ while (1)
+ {
+ p = _asn1_find_up (p);
+ if (p == node)
+ {
+ p = NULL;
+ break;
+ }
+ if (p && p->right)
+ {
+ p = p->right;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return ASN1_SUCCESS;
+}
+
+#define MAX_CONSTANTS 1024
+/******************************************************************/
+/* Function : _asn1_expand_object_id */
+/* Description: expand the IDs of an OBJECT IDENTIFIER constant. */
+/* Parameters: */
+/* list: root of an object list */
+/* node: root of an ASN1 element. */
+/* Return: */
+/* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */
+/* otherwise ASN1_SUCCESS */
+/******************************************************************/
+int
+_asn1_expand_object_id (list_type **list, asn1_node node)
+{
+ asn1_node p, p2, p3, p4, p5;
+ char name_root[ASN1_MAX_NAME_SIZE], name2[2 * ASN1_MAX_NAME_SIZE + 1];
+ int move, tlen, tries;
+ unsigned max_constants;
+
+ if (node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ _asn1_str_cpy (name_root, sizeof (name_root), node->name);
+
+ p = node;
+ move = DOWN;
+ tries = 0;
+
+ while (!((p == node) && (move == UP)))
+ {
+ if (move != UP)
+ {
+ if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID)
+ && (p->type & CONST_ASSIGN))
+ {
+ p2 = p->down;
+ if (p2 && (type_field (p2->type) == ASN1_ETYPE_CONSTANT))
+ {
+ if (p2->value && !c_isdigit (p2->value[0]))
+ {
+ _asn1_str_cpy (name2, sizeof (name2), name_root);
+ _asn1_str_cat (name2, sizeof (name2), ".");
+ _asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
+ p3 = asn1_find_node (node, name2);
+ if (!p3 || _asn1_is_up(p2, p3) ||
+ (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID) ||
+ !(p3->type & CONST_ASSIGN))
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ _asn1_set_down (p, p2->right);
+ if (p2->down)
+ _asn1_delete_structure (*list, &p2->down, 0);
+ _asn1_delete_node_from_list(*list, p2);
+ _asn1_remove_node (p2, 0);
+ p2 = p;
+ p4 = p3->down;
+ max_constants = 0;
+ while (p4)
+ {
+ if (type_field (p4->type) == ASN1_ETYPE_CONSTANT)
+ {
+ max_constants++;
+ if (max_constants == MAX_CONSTANTS)
+ return ASN1_RECURSION;
+
+ p5 =
+ _asn1_add_single_node (ASN1_ETYPE_CONSTANT);
+ _asn1_set_name (p5, p4->name);
+ if (p4->value)
+ {
+ tlen = _asn1_strlen (p4->value);
+ if (tlen > 0)
+ _asn1_set_value (p5, p4->value, tlen + 1);
+ }
+ _asn1_add_static_node2(list, p5);
+
+ if (p2 == p)
+ {
+ _asn1_set_right (p5, p->down);
+ _asn1_set_down (p, p5);
+ }
+ else
+ {
+ _asn1_set_right (p5, p2->right);
+ _asn1_set_right (p2, p5);
+ }
+ p2 = p5;
+ }
+ p4 = p4->right;
+ }
+ move = DOWN;
+
+ tries++;
+ if (tries >= EXPAND_OBJECT_ID_MAX_RECURSION)
+ return ASN1_RECURSION;
+
+ continue;
+ }
+ }
+ }
+ move = DOWN;
+ }
+ else
+ move = RIGHT;
+
+ tries = 0;
+ if (move == DOWN)
+ {
+ if (p->down)
+ p = p->down;
+ else
+ move = RIGHT;
+ }
+
+ if (p == node)
+ {
+ move = UP;
+ continue;
+ }
+
+ if (move == RIGHT)
+ {
+ if (p && p->right)
+ p = p->right;
+ else
+ move = UP;
+ }
+ if (move == UP)
+ p = _asn1_find_up (p);
+ }
+
+ /*******************************/
+ /* expand DEFAULT */
+ /*******************************/
+ p = node;
+ move = DOWN;
+
+ while (!((p == node) && (move == UP)))
+ {
+ if (move != UP)
+ {
+ if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) &&
+ (p->type & CONST_DEFAULT))
+ {
+ p2 = p->down;
+ if (p2 && (type_field (p2->type) == ASN1_ETYPE_DEFAULT))
+ {
+ _asn1_str_cpy (name2, sizeof (name2), name_root);
+ _asn1_str_cat (name2, sizeof (name2), ".");
+ if (p2->value)
+ _asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
+ p3 = asn1_find_node (node, name2);
+ if (!p3 || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID)
+ || !(p3->type & CONST_ASSIGN))
+ return ASN1_ELEMENT_NOT_FOUND;
+ p4 = p3->down;
+ name2[0] = 0;
+ while (p4)
+ {
+ if (type_field (p4->type) == ASN1_ETYPE_CONSTANT)
+ {
+ if (p4->value == NULL)
+ return ASN1_VALUE_NOT_FOUND;
+
+ if (name2[0])
+ _asn1_str_cat (name2, sizeof (name2), ".");
+ _asn1_str_cat (name2, sizeof (name2),
+ (char *) p4->value);
+ }
+ p4 = p4->right;
+ }
+ tlen = strlen (name2);
+ if (tlen > 0)
+ _asn1_set_value (p2, name2, tlen + 1);
+ }
+ }
+ move = DOWN;
+ }
+ else
+ move = RIGHT;
+
+ if (move == DOWN)
+ {
+ if (p->down)
+ p = p->down;
+ else
+ move = RIGHT;
+ }
+
+ if (p == node)
+ {
+ move = UP;
+ continue;
+ }
+
+ if (move == RIGHT)
+ {
+ if (p && p->right)
+ p = p->right;
+ else
+ move = UP;
+ }
+ if (move == UP)
+ p = _asn1_find_up (p);
+ }
+
+ return ASN1_SUCCESS;
+}
+
+
+/******************************************************************/
+/* Function : _asn1_type_set_config */
+/* Description: sets the CONST_SET and CONST_NOT_USED properties */
+/* in the fields of the SET elements. */
+/* Parameters: */
+/* node: root of an ASN1 element. */
+/* Return: */
+/* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */
+/* otherwise ASN1_SUCCESS */
+/******************************************************************/
+int
+_asn1_type_set_config (asn1_node node)
+{
+ asn1_node p, p2;
+ int move;
+
+ if (node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ p = node;
+ move = DOWN;
+
+ while (!((p == node) && (move == UP)))
+ {
+ if (move != UP)
+ {
+ if (type_field (p->type) == ASN1_ETYPE_SET)
+ {
+ p2 = p->down;
+ while (p2)
+ {
+ if (type_field (p2->type) != ASN1_ETYPE_TAG)
+ p2->type |= CONST_SET | CONST_NOT_USED;
+ p2 = p2->right;
+ }
+ }
+ move = DOWN;
+ }
+ else
+ move = RIGHT;
+
+ if (move == DOWN)
+ {
+ if (p->down)
+ p = p->down;
+ else
+ move = RIGHT;
+ }
+
+ if (p == node)
+ {
+ move = UP;
+ continue;
+ }
+
+ if (move == RIGHT)
+ {
+ if (p && p->right)
+ p = p->right;
+ else
+ move = UP;
+ }
+ if (move == UP)
+ p = _asn1_find_up (p);
+ }
+
+ return ASN1_SUCCESS;
+}
+
+
+/******************************************************************/
+/* Function : _asn1_check_identifier */
+/* Description: checks the definitions of all the identifiers */
+/* and the first element of an OBJECT_ID (e.g. {pkix 0 4}). */
+/* The _asn1_identifierMissing global variable is filled if */
+/* necessary. */
+/* Parameters: */
+/* node: root of an ASN1 element. */
+/* Return: */
+/* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */
+/* ASN1_IDENTIFIER_NOT_FOUND if an identifier is not defined, */
+/* otherwise ASN1_SUCCESS */
+/******************************************************************/
+int
+_asn1_check_identifier (asn1_node_const node)
+{
+ asn1_node_const p, p2;
+ char name2[ASN1_MAX_NAME_SIZE * 2 + 2];
+
+ if (node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ p = node;
+ while (p)
+ {
+ if (p->value && type_field (p->type) == ASN1_ETYPE_IDENTIFIER)
+ {
+ _asn1_str_cpy (name2, sizeof (name2), node->name);
+ _asn1_str_cat (name2, sizeof (name2), ".");
+ _asn1_str_cat (name2, sizeof (name2), (char *) p->value);
+ p2 = asn1_find_node (node, name2);
+ if (p2 == NULL)
+ {
+ if (p->value)
+ _asn1_str_cpy (_asn1_identifierMissing, sizeof(_asn1_identifierMissing), (char*)p->value);
+ else
+ _asn1_strcpy (_asn1_identifierMissing, "(null)");
+ return ASN1_IDENTIFIER_NOT_FOUND;
+ }
+ }
+ else if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) &&
+ (p->type & CONST_DEFAULT))
+ {
+ p2 = p->down;
+ if (p2 && (type_field (p2->type) == ASN1_ETYPE_DEFAULT))
+ {
+ _asn1_str_cpy (name2, sizeof (name2), node->name);
+ if (p2->value)
+ {
+ _asn1_str_cat (name2, sizeof (name2), ".");
+ _asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
+ _asn1_str_cpy (_asn1_identifierMissing, sizeof(_asn1_identifierMissing), (char*)p2->value);
+ }
+ else
+ _asn1_strcpy (_asn1_identifierMissing, "(null)");
+
+ p2 = asn1_find_node (node, name2);
+ if (!p2 || (type_field (p2->type) != ASN1_ETYPE_OBJECT_ID) ||
+ !(p2->type & CONST_ASSIGN))
+ return ASN1_IDENTIFIER_NOT_FOUND;
+ else
+ _asn1_identifierMissing[0] = 0;
+ }
+ }
+ else if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) &&
+ (p->type & CONST_ASSIGN))
+ {
+ p2 = p->down;
+ if (p2 && (type_field (p2->type) == ASN1_ETYPE_CONSTANT))
+ {
+ if (p2->value && !c_isdigit (p2->value[0]))
+ {
+ _asn1_str_cpy (name2, sizeof (name2), node->name);
+ _asn1_str_cat (name2, sizeof (name2), ".");
+ _asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
+ _asn1_str_cpy (_asn1_identifierMissing, sizeof(_asn1_identifierMissing), (char*)p2->value);
+
+ p2 = asn1_find_node (node, name2);
+ if (!p2 || (type_field (p2->type) != ASN1_ETYPE_OBJECT_ID)
+ || !(p2->type & CONST_ASSIGN))
+ return ASN1_IDENTIFIER_NOT_FOUND;
+ else
+ _asn1_identifierMissing[0] = 0;
+ }
+ }
+ }
+
+ if (p->down)
+ {
+ p = p->down;
+ }
+ else if (p->right)
+ p = p->right;
+ else
+ {
+ while (p)
+ {
+ p = _asn1_find_up (p);
+ if (p == node)
+ {
+ p = NULL;
+ break;
+ }
+ if (p && p->right)
+ {
+ p = p->right;
+ break;
+ }
+ }
+ }
+ }
+
+ return ASN1_SUCCESS;
+}
+
+
+/******************************************************************/
+/* Function : _asn1_set_default_tag */
+/* Description: sets the default IMPLICIT or EXPLICIT property in */
+/* the tagged elements that don't have this declaration. */
+/* Parameters: */
+/* node: pointer to a DEFINITIONS element. */
+/* Return: */
+/* ASN1_ELEMENT_NOT_FOUND if NODE is NULL or not a pointer to */
+/* a DEFINITIONS element, */
+/* otherwise ASN1_SUCCESS */
+/******************************************************************/
+int
+_asn1_set_default_tag (asn1_node node)
+{
+ asn1_node p;
+
+ if ((node == NULL) || (type_field (node->type) != ASN1_ETYPE_DEFINITIONS))
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ p = node;
+ while (p)
+ {
+ if ((type_field (p->type) == ASN1_ETYPE_TAG) &&
+ !(p->type & CONST_EXPLICIT) && !(p->type & CONST_IMPLICIT))
+ {
+ if (node->type & CONST_EXPLICIT)
+ p->type |= CONST_EXPLICIT;
+ else
+ p->type |= CONST_IMPLICIT;
+ }
+
+ if (p->down)
+ {
+ p = p->down;
+ }
+ else if (p->right)
+ p = p->right;
+ else
+ {
+ while (1)
+ {
+ p = _asn1_find_up (p);
+ if (p == node)
+ {
+ p = NULL;
+ break;
+ }
+ if (p && p->right)
+ {
+ p = p->right;
+ break;
+ }
+ }
+ }
+ }
+
+ return ASN1_SUCCESS;
+}
diff --git a/lib/minitasn1/parser_aux.h b/lib/minitasn1/parser_aux.h
new file mode 100644
index 0000000..0e8621b
--- /dev/null
+++ b/lib/minitasn1/parser_aux.h
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2000-2021 Free Software Foundation, Inc.
+ *
+ * This file is part of LIBTASN1.
+ *
+ * The LIBTASN1 library is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ */
+
+#ifndef _PARSER_AUX_H
+#define _PARSER_AUX_H
+
+/***********************************************/
+/* Type: list_type */
+/* Description: type used in the list during */
+/* the structure creation. */
+/***********************************************/
+typedef struct list_struct
+{
+ asn1_node node;
+ struct list_struct *next;
+} list_type;
+
+/***************************************/
+/* Functions used by ASN.1 parser */
+/***************************************/
+asn1_node _asn1_add_static_node (list_type **e_list, unsigned int type);
+
+void _asn1_delete_list (list_type *e_list);
+
+void _asn1_delete_list_and_nodes (list_type *e_list);
+
+void _asn1_delete_node_from_list (list_type *list, asn1_node node);
+
+asn1_node
+_asn1_set_value (asn1_node node, const void *value, unsigned int len);
+
+asn1_node _asn1_set_value_m (asn1_node node, void *value, unsigned int len);
+
+asn1_node
+_asn1_set_value_lv (asn1_node node, const void *value, unsigned int len);
+
+asn1_node
+_asn1_append_value (asn1_node node, const void *value, unsigned int len);
+
+asn1_node _asn1_set_name (asn1_node node, const char *name);
+
+asn1_node _asn1_cpy_name (asn1_node dst, asn1_node_const src);
+
+asn1_node _asn1_set_right (asn1_node node, asn1_node right);
+
+asn1_node _asn1_get_last_right (asn1_node_const node);
+
+void _asn1_remove_node (asn1_node node, unsigned int flags);
+
+/* Max 64-bit integer length is 20 chars + 1 for sign + 1 for null termination */
+#define LTOSTR_MAX_SIZE 22
+char *_asn1_ltostr (int64_t v, char str[LTOSTR_MAX_SIZE]);
+
+asn1_node _asn1_find_up (asn1_node_const node);
+
+int _asn1_change_integer_value (asn1_node node);
+
+#define EXPAND_OBJECT_ID_MAX_RECURSION 16
+int _asn1_expand_object_id (list_type **list, asn1_node node);
+
+int _asn1_type_set_config (asn1_node node);
+
+int _asn1_check_identifier (asn1_node_const node);
+
+int _asn1_set_default_tag (asn1_node node);
+
+/******************************************************************/
+/* Function : _asn1_get_right */
+/* Description: returns the element pointed by the RIGHT field of */
+/* a NODE_ASN element. */
+/* Parameters: */
+/* node: NODE_ASN element pointer. */
+/* Return: field RIGHT of NODE. */
+/******************************************************************/
+inline static asn1_node
+_asn1_get_right (asn1_node_const node)
+{
+ if (node == NULL)
+ return NULL;
+ return node->right;
+}
+
+/******************************************************************/
+/* Function : _asn1_set_down */
+/* Description: sets the field DOWN in a NODE_ASN element. */
+/* Parameters: */
+/* node: element pointer. */
+/* down: pointer to a NODE_ASN element that you want be pointed */
+/* by NODE. */
+/* Return: pointer to *NODE. */
+/******************************************************************/
+inline static asn1_node
+_asn1_set_down (asn1_node node, asn1_node down)
+{
+ if (node == NULL)
+ return node;
+ node->down = down;
+ if (down)
+ down->left = node;
+ return node;
+}
+
+/******************************************************************/
+/* Function : _asn1_get_down */
+/* Description: returns the element pointed by the DOWN field of */
+/* a NODE_ASN element. */
+/* Parameters: */
+/* node: NODE_ASN element pointer. */
+/* Return: field DOWN of NODE. */
+/******************************************************************/
+inline static asn1_node
+_asn1_get_down (asn1_node_const node)
+{
+ if (node == NULL)
+ return NULL;
+ return node->down;
+}
+
+/******************************************************************/
+/* Function : _asn1_get_name */
+/* Description: returns the name of a NODE_ASN element. */
+/* Parameters: */
+/* node: NODE_ASN element pointer. */
+/* Return: a null terminated string. */
+/******************************************************************/
+inline static char *
+_asn1_get_name (asn1_node_const node)
+{
+ if (node == NULL)
+ return NULL;
+ return (char *) node->name;
+}
+
+/******************************************************************/
+/* Function : _asn1_mod_type */
+/* Description: change the field TYPE of an NODE_ASN element. */
+/* The new value is the old one | (bitwise or) the */
+/* paramener VALUE. */
+/* Parameters: */
+/* node: NODE_ASN element pointer. */
+/* value: the integer value that must be or-ed with the current */
+/* value of field TYPE. */
+/* Return: NODE pointer. */
+/******************************************************************/
+inline static asn1_node
+_asn1_mod_type (asn1_node node, unsigned int value)
+{
+ if (node == NULL)
+ return node;
+ node->type |= value;
+ return node;
+}
+
+#endif
diff --git a/lib/minitasn1/structure.c b/lib/minitasn1/structure.c
new file mode 100644
index 0000000..4f43335
--- /dev/null
+++ b/lib/minitasn1/structure.c
@@ -0,0 +1,1220 @@
+/*
+ * Copyright (C) 2002-2021 Free Software Foundation, Inc.
+ *
+ * This file is part of LIBTASN1.
+ *
+ * The LIBTASN1 library is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ */
+
+
+/*****************************************************/
+/* File: structure.c */
+/* Description: Functions to create and delete an */
+/* ASN1 tree. */
+/*****************************************************/
+
+
+#include <int.h>
+#include <structure.h>
+#include "parser_aux.h"
+#include <gstr.h>
+
+
+extern char _asn1_identifierMissing[];
+
+
+/******************************************************/
+/* Function : _asn1_add_single_node */
+/* Description: creates a new NODE_ASN element. */
+/* Parameters: */
+/* type: type of the new element (see ASN1_ETYPE_ */
+/* and CONST_ constants). */
+/* Return: pointer to the new element. */
+/******************************************************/
+asn1_node
+_asn1_add_single_node (unsigned int type)
+{
+ asn1_node punt;
+
+ punt = calloc (1, sizeof (struct asn1_node_st));
+ if (punt == NULL)
+ return NULL;
+
+ punt->type = type;
+
+ return punt;
+}
+
+
+/******************************************************************/
+/* Function : _asn1_find_left */
+/* Description: returns the NODE_ASN element with RIGHT field that*/
+/* points the element NODE. */
+/* Parameters: */
+/* node: NODE_ASN element pointer. */
+/* Return: NULL if not found. */
+/******************************************************************/
+asn1_node
+_asn1_find_left (asn1_node_const node)
+{
+ if ((node == NULL) || (node->left == NULL) || (node->left->down == node))
+ return NULL;
+
+ return node->left;
+}
+
+
+int
+_asn1_create_static_structure (asn1_node_const pointer, char *output_file_name,
+ char *vector_name)
+{
+ FILE *file;
+ asn1_node_const p;
+ unsigned long t;
+
+ file = fopen (output_file_name, "w");
+
+ if (file == NULL)
+ return ASN1_FILE_NOT_FOUND;
+
+ fprintf (file, "#if HAVE_CONFIG_H\n");
+ fprintf (file, "# include \"config.h\"\n");
+ fprintf (file, "#endif\n\n");
+
+ fprintf (file, "#include <libtasn1.h>\n\n");
+
+ fprintf (file, "const asn1_static_node %s[] = {\n", vector_name);
+
+ p = pointer;
+
+ while (p)
+ {
+ fprintf (file, " { ");
+
+ if (p->name[0] != 0)
+ fprintf (file, "\"%s\", ", p->name);
+ else
+ fprintf (file, "NULL, ");
+
+ t = p->type;
+ if (p->down)
+ t |= CONST_DOWN;
+ if (p->right)
+ t |= CONST_RIGHT;
+
+ fprintf (file, "%lu, ", t);
+
+ if (p->value)
+ fprintf (file, "\"%s\"},\n", p->value);
+ else
+ fprintf (file, "NULL },\n");
+
+ if (p->down)
+ {
+ p = p->down;
+ }
+ else if (p->right)
+ {
+ p = p->right;
+ }
+ else
+ {
+ while (1)
+ {
+ p = _asn1_find_up (p);
+ if (p == pointer)
+ {
+ p = NULL;
+ break;
+ }
+ if (p->right)
+ {
+ p = p->right;
+ break;
+ }
+ }
+ }
+ }
+
+ fprintf (file, " { NULL, 0, NULL }\n};\n");
+
+ fclose (file);
+
+ return ASN1_SUCCESS;
+}
+
+
+/**
+ * asn1_array2tree:
+ * @array: specify the array that contains ASN.1 declarations
+ * @definitions: return the pointer to the structure created by
+ * *ARRAY ASN.1 declarations
+ * @errorDescription: return the error description.
+ *
+ * Creates the structures needed to manage the ASN.1 definitions.
+ * @array is a vector created by asn1_parser2array().
+ *
+ * Returns: %ASN1_SUCCESS if structure was created correctly,
+ * %ASN1_ELEMENT_NOT_EMPTY if *@definitions not NULL,
+ * %ASN1_IDENTIFIER_NOT_FOUND if in the file there is an identifier
+ * that is not defined (see @errorDescription for more information),
+ * %ASN1_ARRAY_ERROR if the array pointed by @array is wrong.
+ **/
+int
+asn1_array2tree (const asn1_static_node * array, asn1_node * definitions,
+ char *errorDescription)
+{
+ asn1_node p, p_last = NULL;
+ unsigned long k;
+ int move;
+ int result;
+ unsigned int type;
+ list_type *e_list = NULL;
+
+ if (errorDescription)
+ errorDescription[0] = 0;
+
+ if (*definitions != NULL)
+ return ASN1_ELEMENT_NOT_EMPTY;
+
+ move = UP;
+
+ for (k = 0; array[k].value || array[k].type || array[k].name; k++)
+ {
+ type = convert_old_type (array[k].type);
+
+ p = _asn1_add_static_node (&e_list, type & (~CONST_DOWN));
+ if (array[k].name)
+ _asn1_set_name (p, array[k].name);
+ if (array[k].value)
+ _asn1_set_value (p, array[k].value, strlen (array[k].value) + 1);
+
+ if (*definitions == NULL)
+ *definitions = p;
+
+ if (move == DOWN)
+ {
+ if (p_last && p_last->down)
+ _asn1_delete_structure (e_list, &p_last->down, 0);
+ _asn1_set_down (p_last, p);
+ }
+ else if (move == RIGHT)
+ {
+ if (p_last && p_last->right)
+ _asn1_delete_structure (e_list, &p_last->right, 0);
+ _asn1_set_right (p_last, p);
+ }
+
+ p_last = p;
+
+ if (type & CONST_DOWN)
+ move = DOWN;
+ else if (type & CONST_RIGHT)
+ move = RIGHT;
+ else
+ {
+ while (p_last != *definitions)
+ {
+ p_last = _asn1_find_up (p_last);
+
+ if (p_last == NULL)
+ break;
+
+ if (p_last->type & CONST_RIGHT)
+ {
+ p_last->type &= ~CONST_RIGHT;
+ move = RIGHT;
+ break;
+ }
+ } /* while */
+ }
+ } /* while */
+
+ if (p_last == *definitions)
+ {
+ result = _asn1_check_identifier (*definitions);
+ if (result == ASN1_SUCCESS)
+ {
+ _asn1_change_integer_value (*definitions);
+ result = _asn1_expand_object_id (&e_list, *definitions);
+ }
+ }
+ else
+ {
+ result = ASN1_ARRAY_ERROR;
+ }
+
+ if (errorDescription != NULL)
+ {
+ if (result == ASN1_IDENTIFIER_NOT_FOUND)
+ {
+ Estrcpy (errorDescription, ":: identifier '");
+ Estrcat (errorDescription, _asn1_identifierMissing);
+ Estrcat (errorDescription, "' not found");
+ }
+ else
+ errorDescription[0] = 0;
+ }
+
+ if (result != ASN1_SUCCESS)
+ {
+ _asn1_delete_list_and_nodes (e_list);
+ *definitions = NULL;
+ }
+ else
+ _asn1_delete_list (e_list);
+
+ return result;
+}
+
+/**
+ * asn1_delete_structure:
+ * @structure: pointer to the structure that you want to delete.
+ *
+ * Deletes the structure *@structure. At the end, *@structure is set
+ * to NULL.
+ *
+ * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if
+ * *@structure was NULL.
+ **/
+int
+asn1_delete_structure (asn1_node * structure)
+{
+ return _asn1_delete_structure (NULL, structure, 0);
+}
+
+/**
+ * asn1_delete_structure2:
+ * @structure: pointer to the structure that you want to delete.
+ * @flags: additional flags (see %ASN1_DELETE_FLAG)
+ *
+ * Deletes the structure *@structure. At the end, *@structure is set
+ * to NULL.
+ *
+ * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if
+ * *@structure was NULL.
+ **/
+int
+asn1_delete_structure2 (asn1_node * structure, unsigned int flags)
+{
+ return _asn1_delete_structure (NULL, structure, flags);
+}
+
+int
+_asn1_delete_structure (list_type *e_list, asn1_node * structure, unsigned int flags)
+{
+ asn1_node p, p2, p3;
+
+ if (*structure == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ p = *structure;
+ while (p)
+ {
+ if (p->down)
+ {
+ p = p->down;
+ }
+ else
+ { /* no down */
+ p2 = p->right;
+ if (p != *structure)
+ {
+ p3 = _asn1_find_up (p);
+ _asn1_set_down (p3, p2);
+ if (e_list)
+ _asn1_delete_node_from_list (e_list, p);
+ _asn1_remove_node (p, flags);
+ p = p3;
+ }
+ else
+ { /* p==root */
+ p3 = _asn1_find_left (p);
+ if (!p3)
+ {
+ p3 = _asn1_find_up (p);
+ if (p3)
+ _asn1_set_down (p3, p2);
+ else
+ {
+ if (p->right)
+ p->right->left = NULL;
+ }
+ }
+ else
+ _asn1_set_right (p3, p2);
+ if (e_list)
+ _asn1_delete_node_from_list (e_list, p);
+ _asn1_remove_node (p, flags);
+ p = NULL;
+ }
+ }
+ }
+
+ *structure = NULL;
+ return ASN1_SUCCESS;
+}
+
+
+/**
+ * asn1_delete_element:
+ * @structure: pointer to the structure that contains the element you
+ * want to delete.
+ * @element_name: element's name you want to delete.
+ *
+ * Deletes the element named *@element_name inside *@structure.
+ *
+ * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if
+ * the @element_name was not found.
+ **/
+int
+asn1_delete_element (asn1_node structure, const char *element_name)
+{
+ asn1_node p2, p3, source_node;
+
+ source_node = asn1_find_node (structure, element_name);
+
+ if (source_node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ p2 = source_node->right;
+ p3 = _asn1_find_left (source_node);
+ if (!p3)
+ {
+ p3 = _asn1_find_up (source_node);
+ if (p3)
+ _asn1_set_down (p3, p2);
+ else if (source_node->right)
+ source_node->right->left = NULL;
+ }
+ else
+ _asn1_set_right (p3, p2);
+
+ return asn1_delete_structure (&source_node);
+}
+
+#ifndef __clang_analyzer__
+asn1_node
+_asn1_copy_structure3 (asn1_node_const source_node)
+{
+ asn1_node_const p_s;
+ asn1_node dest_node, p_d, p_d_prev;
+ int move;
+
+ if (source_node == NULL)
+ return NULL;
+
+ dest_node = _asn1_add_single_node (source_node->type);
+
+ p_s = source_node;
+ p_d = dest_node;
+
+ move = DOWN;
+
+ do
+ {
+ if (move != UP)
+ {
+ if (p_s->name[0] != 0)
+ _asn1_cpy_name (p_d, p_s);
+ if (p_s->value)
+ _asn1_set_value (p_d, p_s->value, p_s->value_len);
+ if (p_s->down)
+ {
+ p_s = p_s->down;
+ p_d_prev = p_d;
+ p_d = _asn1_add_single_node (p_s->type);
+ _asn1_set_down (p_d_prev, p_d);
+ continue;
+ }
+ p_d->start = p_s->start;
+ p_d->end = p_s->end;
+ }
+
+ if (p_s == source_node)
+ break;
+
+ if (p_s->right)
+ {
+ move = RIGHT;
+ p_s = p_s->right;
+ p_d_prev = p_d;
+ p_d = _asn1_add_single_node (p_s->type);
+ _asn1_set_right (p_d_prev, p_d);
+ }
+ else
+ {
+ move = UP;
+ p_s = _asn1_find_up (p_s);
+ p_d = _asn1_find_up (p_d);
+ }
+ }
+ while (p_s != source_node);
+ return dest_node;
+}
+#else
+
+/* Non-production code */
+asn1_node
+_asn1_copy_structure3 (asn1_node_const source_node)
+{
+ return NULL;
+}
+#endif /* __clang_analyzer__ */
+
+
+static asn1_node
+_asn1_copy_structure2 (asn1_node_const root, const char *source_name)
+{
+ asn1_node source_node;
+
+ source_node = asn1_find_node (root, source_name);
+
+ return _asn1_copy_structure3 (source_node);
+
+}
+
+
+static int
+_asn1_type_choice_config (asn1_node node)
+{
+ asn1_node p, p2, p3, p4;
+ int move, tlen;
+
+ if (node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ p = node;
+ move = DOWN;
+
+ while (!((p == node) && (move == UP)))
+ {
+ if (move != UP)
+ {
+ if ((type_field (p->type) == ASN1_ETYPE_CHOICE)
+ && (p->type & CONST_TAG))
+ {
+ p2 = p->down;
+ while (p2)
+ {
+ if (type_field (p2->type) != ASN1_ETYPE_TAG)
+ {
+ p2->type |= CONST_TAG;
+ p3 = _asn1_find_left (p2);
+ while (p3)
+ {
+ if (type_field (p3->type) == ASN1_ETYPE_TAG)
+ {
+ p4 = _asn1_add_single_node (p3->type);
+ tlen = _asn1_strlen (p3->value);
+ if (tlen > 0)
+ _asn1_set_value (p4, p3->value, tlen + 1);
+ _asn1_set_right (p4, p2->down);
+ _asn1_set_down (p2, p4);
+ }
+ p3 = _asn1_find_left (p3);
+ }
+ }
+ p2 = p2->right;
+ }
+ p->type &= ~(CONST_TAG);
+ p2 = p->down;
+ while (p2)
+ {
+ p3 = p2->right;
+ if (type_field (p2->type) == ASN1_ETYPE_TAG)
+ asn1_delete_structure (&p2);
+ p2 = p3;
+ }
+ }
+ move = DOWN;
+ }
+ else
+ move = RIGHT;
+
+ if (move == DOWN)
+ {
+ if (p->down)
+ p = p->down;
+ else
+ move = RIGHT;
+ }
+
+ if (p == node)
+ {
+ move = UP;
+ continue;
+ }
+
+ if (move == RIGHT)
+ {
+ if (p->right)
+ p = p->right;
+ else
+ move = UP;
+ }
+ if (move == UP)
+ p = _asn1_find_up (p);
+ }
+
+ return ASN1_SUCCESS;
+}
+
+
+static int
+_asn1_expand_identifier (asn1_node * node, asn1_node_const root)
+{
+ asn1_node p, p2, p3;
+ char name2[ASN1_MAX_NAME_SIZE + 2];
+ int move;
+
+ if (node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ p = *node;
+ move = DOWN;
+
+ while (!((p == *node) && (move == UP)))
+ {
+ if (move != UP)
+ {
+ if (type_field (p->type) == ASN1_ETYPE_IDENTIFIER)
+ {
+ snprintf (name2, sizeof (name2), "%s.%s", root->name, p->value);
+ p2 = _asn1_copy_structure2 (root, name2);
+ if (p2 == NULL)
+ {
+ return ASN1_IDENTIFIER_NOT_FOUND;
+ }
+ _asn1_cpy_name (p2, p);
+ p2->right = p->right;
+ p2->left = p->left;
+ if (p->right)
+ p->right->left = p2;
+ p3 = p->down;
+ if (p3)
+ {
+ while (p3->right)
+ p3 = p3->right;
+ _asn1_set_right (p3, p2->down);
+ _asn1_set_down (p2, p->down);
+ }
+
+ p3 = _asn1_find_left (p);
+ if (p3)
+ _asn1_set_right (p3, p2);
+ else
+ {
+ p3 = _asn1_find_up (p);
+ if (p3)
+ _asn1_set_down (p3, p2);
+ else
+ {
+ p2->left = NULL;
+ }
+ }
+
+ if (p->type & CONST_SIZE)
+ p2->type |= CONST_SIZE;
+ if (p->type & CONST_TAG)
+ p2->type |= CONST_TAG;
+ if (p->type & CONST_OPTION)
+ p2->type |= CONST_OPTION;
+ if (p->type & CONST_DEFAULT)
+ p2->type |= CONST_DEFAULT;
+ if (p->type & CONST_SET)
+ p2->type |= CONST_SET;
+ if (p->type & CONST_NOT_USED)
+ p2->type |= CONST_NOT_USED;
+
+ if (p == *node)
+ *node = p2;
+ _asn1_remove_node (p, 0);
+ p = p2;
+ move = DOWN;
+ continue;
+ }
+ move = DOWN;
+ }
+ else
+ move = RIGHT;
+
+ if (move == DOWN)
+ {
+ if (p->down)
+ p = p->down;
+ else
+ move = RIGHT;
+ }
+
+ if (p == *node)
+ {
+ move = UP;
+ continue;
+ }
+
+ if (move == RIGHT)
+ {
+ if (p->right)
+ p = p->right;
+ else
+ move = UP;
+ }
+ if (move == UP)
+ p = _asn1_find_up (p);
+ }
+
+ return ASN1_SUCCESS;
+}
+
+
+/**
+ * asn1_create_element:
+ * @definitions: pointer to the structure returned by "parser_asn1" function
+ * @source_name: the name of the type of the new structure (must be
+ * inside p_structure).
+ * @element: pointer to the structure created.
+ *
+ * Creates a structure of type @source_name. Example using
+ * "pkix.asn":
+ *
+ * rc = asn1_create_element(cert_def, "PKIX1.Certificate", certptr);
+ *
+ * Returns: %ASN1_SUCCESS if creation OK, %ASN1_ELEMENT_NOT_FOUND if
+ * @source_name is not known.
+ **/
+int
+asn1_create_element (asn1_node_const definitions, const char *source_name,
+ asn1_node * element)
+{
+ asn1_node dest_node;
+ int res;
+
+ dest_node = _asn1_copy_structure2 (definitions, source_name);
+
+ if (dest_node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ _asn1_set_name (dest_node, "");
+
+ res = _asn1_expand_identifier (&dest_node, definitions);
+ _asn1_type_choice_config (dest_node);
+
+ *element = dest_node;
+
+ return res;
+}
+
+
+/**
+ * asn1_print_structure:
+ * @out: pointer to the output file (e.g. stdout).
+ * @structure: pointer to the structure that you want to visit.
+ * @name: an element of the structure
+ * @mode: specify how much of the structure to print, can be
+ * %ASN1_PRINT_NAME, %ASN1_PRINT_NAME_TYPE,
+ * %ASN1_PRINT_NAME_TYPE_VALUE, or %ASN1_PRINT_ALL.
+ *
+ * Prints on the @out file descriptor the structure's tree starting
+ * from the @name element inside the structure @structure.
+ **/
+void
+asn1_print_structure (FILE * out, asn1_node_const structure, const char *name,
+ int mode)
+{
+ asn1_node_const p, root;
+ int k, indent = 0, len, len2, len3;
+
+ if (out == NULL)
+ return;
+
+ root = asn1_find_node (structure, name);
+
+ if (root == NULL)
+ return;
+
+ p = root;
+ while (p)
+ {
+ if (mode == ASN1_PRINT_ALL)
+ {
+ for (k = 0; k < indent; k++)
+ fprintf (out, " ");
+ fprintf (out, "name:");
+ if (p->name[0] != 0)
+ fprintf (out, "%s ", p->name);
+ else
+ fprintf (out, "NULL ");
+ }
+ else
+ {
+ switch (type_field (p->type))
+ {
+ case ASN1_ETYPE_CONSTANT:
+ case ASN1_ETYPE_TAG:
+ case ASN1_ETYPE_SIZE:
+ break;
+ default:
+ for (k = 0; k < indent; k++)
+ fprintf (out, " ");
+ fprintf (out, "name:");
+ if (p->name[0] != 0)
+ fprintf (out, "%s ", p->name);
+ else
+ fprintf (out, "NULL ");
+ }
+ }
+
+ if (mode != ASN1_PRINT_NAME)
+ {
+ unsigned type = type_field (p->type);
+ switch (type)
+ {
+ case ASN1_ETYPE_CONSTANT:
+ if (mode == ASN1_PRINT_ALL)
+ fprintf (out, "type:CONST");
+ break;
+ case ASN1_ETYPE_TAG:
+ if (mode == ASN1_PRINT_ALL)
+ fprintf (out, "type:TAG");
+ break;
+ case ASN1_ETYPE_SIZE:
+ if (mode == ASN1_PRINT_ALL)
+ fprintf (out, "type:SIZE");
+ break;
+ case ASN1_ETYPE_DEFAULT:
+ fprintf (out, "type:DEFAULT");
+ break;
+ case ASN1_ETYPE_IDENTIFIER:
+ fprintf (out, "type:IDENTIFIER");
+ break;
+ case ASN1_ETYPE_ANY:
+ fprintf (out, "type:ANY");
+ break;
+ case ASN1_ETYPE_CHOICE:
+ fprintf (out, "type:CHOICE");
+ break;
+ case ASN1_ETYPE_DEFINITIONS:
+ fprintf (out, "type:DEFINITIONS");
+ break;
+ CASE_HANDLED_ETYPES:
+ fprintf (out, "%s", _asn1_tags[type].desc);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if ((mode == ASN1_PRINT_NAME_TYPE_VALUE) || (mode == ASN1_PRINT_ALL))
+ {
+ switch (type_field (p->type))
+ {
+ case ASN1_ETYPE_CONSTANT:
+ if (mode == ASN1_PRINT_ALL)
+ if (p->value)
+ fprintf (out, " value:%s", p->value);
+ break;
+ case ASN1_ETYPE_TAG:
+ if (mode == ASN1_PRINT_ALL)
+ if (p->value)
+ fprintf (out, " value:%s", p->value);
+ break;
+ case ASN1_ETYPE_SIZE:
+ if (mode == ASN1_PRINT_ALL)
+ if (p->value)
+ fprintf (out, " value:%s", p->value);
+ break;
+ case ASN1_ETYPE_DEFAULT:
+ if (p->value)
+ fprintf (out, " value:%s", p->value);
+ else if (p->type & CONST_TRUE)
+ fprintf (out, " value:TRUE");
+ else if (p->type & CONST_FALSE)
+ fprintf (out, " value:FALSE");
+ break;
+ case ASN1_ETYPE_IDENTIFIER:
+ if (p->value)
+ fprintf (out, " value:%s", p->value);
+ break;
+ case ASN1_ETYPE_INTEGER:
+ if (p->value)
+ {
+ len2 = -1;
+ len = asn1_get_length_der (p->value, p->value_len, &len2);
+ fprintf (out, " value:0x");
+ if (len > 0)
+ for (k = 0; k < len; k++)
+ fprintf (out, "%02x", (unsigned) (p->value)[k + len2]);
+ }
+ break;
+ case ASN1_ETYPE_ENUMERATED:
+ if (p->value)
+ {
+ len2 = -1;
+ len = asn1_get_length_der (p->value, p->value_len, &len2);
+ fprintf (out, " value:0x");
+ if (len > 0)
+ for (k = 0; k < len; k++)
+ fprintf (out, "%02x", (unsigned) (p->value)[k + len2]);
+ }
+ break;
+ case ASN1_ETYPE_BOOLEAN:
+ if (p->value)
+ {
+ if (p->value[0] == 'T')
+ fprintf (out, " value:TRUE");
+ else if (p->value[0] == 'F')
+ fprintf (out, " value:FALSE");
+ }
+ break;
+ case ASN1_ETYPE_BIT_STRING:
+ if (p->value)
+ {
+ len2 = -1;
+ len = asn1_get_length_der (p->value, p->value_len, &len2);
+ if (len > 0)
+ {
+ fprintf (out, " value(%i):",
+ (len - 1) * 8 - (p->value[len2]));
+ for (k = 1; k < len; k++)
+ fprintf (out, "%02x", (unsigned) (p->value)[k + len2]);
+ }
+ }
+ break;
+ case ASN1_ETYPE_GENERALIZED_TIME:
+ case ASN1_ETYPE_UTC_TIME:
+ if (p->value)
+ {
+ fprintf (out, " value:");
+ for (k = 0; k < p->value_len; k++)
+ fprintf (out, "%c", (p->value)[k]);
+ }
+ break;
+ case ASN1_ETYPE_GENERALSTRING:
+ case ASN1_ETYPE_NUMERIC_STRING:
+ case ASN1_ETYPE_IA5_STRING:
+ case ASN1_ETYPE_TELETEX_STRING:
+ case ASN1_ETYPE_PRINTABLE_STRING:
+ case ASN1_ETYPE_UNIVERSAL_STRING:
+ case ASN1_ETYPE_UTF8_STRING:
+ case ASN1_ETYPE_VISIBLE_STRING:
+ if (p->value)
+ {
+ len2 = -1;
+ len = asn1_get_length_der (p->value, p->value_len, &len2);
+ fprintf (out, " value:");
+ if (len > 0)
+ for (k = 0; k < len; k++)
+ fprintf (out, "%c", (p->value)[k + len2]);
+ }
+ break;
+ case ASN1_ETYPE_BMP_STRING:
+ case ASN1_ETYPE_OCTET_STRING:
+ if (p->value)
+ {
+ len2 = -1;
+ len = asn1_get_length_der (p->value, p->value_len, &len2);
+ fprintf (out, " value:");
+ if (len > 0)
+ for (k = 0; k < len; k++)
+ fprintf (out, "%02x", (unsigned) (p->value)[k + len2]);
+ }
+ break;
+ case ASN1_ETYPE_OBJECT_ID:
+ if (p->value)
+ fprintf (out, " value:%s", p->value);
+ break;
+ case ASN1_ETYPE_ANY:
+ if (p->value)
+ {
+ len3 = -1;
+ len2 = asn1_get_length_der (p->value, p->value_len, &len3);
+ fprintf (out, " value:");
+ if (len2 > 0)
+ for (k = 0; k < len2; k++)
+ fprintf (out, "%02x", (unsigned) (p->value)[k + len3]);
+ }
+ break;
+ case ASN1_ETYPE_SET:
+ case ASN1_ETYPE_SET_OF:
+ case ASN1_ETYPE_CHOICE:
+ case ASN1_ETYPE_DEFINITIONS:
+ case ASN1_ETYPE_SEQUENCE_OF:
+ case ASN1_ETYPE_SEQUENCE:
+ case ASN1_ETYPE_NULL:
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (mode == ASN1_PRINT_ALL)
+ {
+ if (p->type & 0x1FFFFF00)
+ {
+ fprintf (out, " attr:");
+ if (p->type & CONST_UNIVERSAL)
+ fprintf (out, "UNIVERSAL,");
+ if (p->type & CONST_PRIVATE)
+ fprintf (out, "PRIVATE,");
+ if (p->type & CONST_APPLICATION)
+ fprintf (out, "APPLICATION,");
+ if (p->type & CONST_EXPLICIT)
+ fprintf (out, "EXPLICIT,");
+ if (p->type & CONST_IMPLICIT)
+ fprintf (out, "IMPLICIT,");
+ if (p->type & CONST_TAG)
+ fprintf (out, "TAG,");
+ if (p->type & CONST_DEFAULT)
+ fprintf (out, "DEFAULT,");
+ if (p->type & CONST_TRUE)
+ fprintf (out, "TRUE,");
+ if (p->type & CONST_FALSE)
+ fprintf (out, "FALSE,");
+ if (p->type & CONST_LIST)
+ fprintf (out, "LIST,");
+ if (p->type & CONST_MIN_MAX)
+ fprintf (out, "MIN_MAX,");
+ if (p->type & CONST_OPTION)
+ fprintf (out, "OPTION,");
+ if (p->type & CONST_1_PARAM)
+ fprintf (out, "1_PARAM,");
+ if (p->type & CONST_SIZE)
+ fprintf (out, "SIZE,");
+ if (p->type & CONST_DEFINED_BY)
+ fprintf (out, "DEF_BY,");
+ if (p->type & CONST_GENERALIZED)
+ fprintf (out, "GENERALIZED,");
+ if (p->type & CONST_UTC)
+ fprintf (out, "UTC,");
+ if (p->type & CONST_SET)
+ fprintf (out, "SET,");
+ if (p->type & CONST_NOT_USED)
+ fprintf (out, "NOT_USED,");
+ if (p->type & CONST_ASSIGN)
+ fprintf (out, "ASSIGNMENT,");
+ }
+ }
+
+ if (mode == ASN1_PRINT_ALL)
+ {
+ fprintf (out, "\n");
+ }
+ else
+ {
+ switch (type_field (p->type))
+ {
+ case ASN1_ETYPE_CONSTANT:
+ case ASN1_ETYPE_TAG:
+ case ASN1_ETYPE_SIZE:
+ break;
+ default:
+ fprintf (out, "\n");
+ }
+ }
+
+ if (p->down)
+ {
+ p = p->down;
+ indent += 2;
+ }
+ else if (p == root)
+ {
+ p = NULL;
+ break;
+ }
+ else if (p->right)
+ p = p->right;
+ else
+ {
+ while (1)
+ {
+ p = _asn1_find_up (p);
+ if (p == root)
+ {
+ p = NULL;
+ break;
+ }
+ indent -= 2;
+ if (p->right)
+ {
+ p = p->right;
+ break;
+ }
+ }
+ }
+ }
+}
+
+
+
+/**
+ * asn1_number_of_elements:
+ * @element: pointer to the root of an ASN1 structure.
+ * @name: the name of a sub-structure of ROOT.
+ * @num: pointer to an integer where the result will be stored
+ *
+ * Counts the number of elements of a sub-structure called NAME with
+ * names equal to "?1","?2", ...
+ *
+ * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if
+ * @name is not known, %ASN1_GENERIC_ERROR if pointer @num is %NULL.
+ **/
+int
+asn1_number_of_elements (asn1_node_const element, const char *name, int *num)
+{
+ asn1_node_const node, p;
+
+ if (num == NULL)
+ return ASN1_GENERIC_ERROR;
+
+ *num = 0;
+
+ node = asn1_find_node (element, name);
+ if (node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ p = node->down;
+
+ while (p)
+ {
+ if (p->name[0] == '?')
+ (*num)++;
+ p = p->right;
+ }
+
+ return ASN1_SUCCESS;
+}
+
+
+/**
+ * asn1_find_structure_from_oid:
+ * @definitions: ASN1 definitions
+ * @oidValue: value of the OID to search (e.g. "1.2.3.4").
+ *
+ * Search the structure that is defined just after an OID definition.
+ *
+ * Returns: %NULL when @oidValue not found, otherwise the pointer to a
+ * constant string that contains the element name defined just after
+ * the OID.
+ **/
+const char *
+asn1_find_structure_from_oid (asn1_node_const definitions, const char *oidValue)
+{
+ char name[2 * ASN1_MAX_NAME_SIZE + 2];
+ char value[ASN1_MAX_NAME_SIZE];
+ asn1_node p;
+ int len;
+ int result;
+ const char *definitionsName;
+
+ if ((definitions == NULL) || (oidValue == NULL))
+ return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
+
+ definitionsName = definitions->name;
+
+ /* search the OBJECT_ID into definitions */
+ p = definitions->down;
+ while (p)
+ {
+ if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) &&
+ (p->type & CONST_ASSIGN))
+ {
+ snprintf(name, sizeof(name), "%s.%s", definitionsName, p->name);
+
+ len = ASN1_MAX_NAME_SIZE;
+ result = asn1_read_value (definitions, name, value, &len);
+
+ if ((result == ASN1_SUCCESS) && (!strcmp (oidValue, value)))
+ {
+ p = p->right;
+ if (p == NULL) /* reach the end of ASN1 definitions */
+ return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
+
+ return p->name;
+ }
+ }
+ p = p->right;
+ }
+
+ return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
+}
+
+/**
+ * asn1_copy_node:
+ * @dst: Destination asn1 node.
+ * @dst_name: Field name in destination node.
+ * @src: Source asn1 node.
+ * @src_name: Field name in source node.
+ *
+ * Create a deep copy of a asn1_node variable. That
+ * function requires @dst to be expanded using asn1_create_element().
+ *
+ * Returns: Return %ASN1_SUCCESS on success.
+ **/
+int
+asn1_copy_node (asn1_node dst, const char *dst_name,
+ asn1_node_const src, const char *src_name)
+{
+ int result;
+ asn1_node dst_node;
+ void *data = NULL;
+ int size = 0;
+
+ result = asn1_der_coding (src, src_name, NULL, &size, NULL);
+ if (result != ASN1_MEM_ERROR)
+ return result;
+
+ data = malloc (size);
+ if (data == NULL)
+ return ASN1_MEM_ERROR;
+
+ result = asn1_der_coding (src, src_name, data, &size, NULL);
+ if (result != ASN1_SUCCESS)
+ {
+ free (data);
+ return result;
+ }
+
+ dst_node = asn1_find_node (dst, dst_name);
+ if (dst_node == NULL)
+ {
+ free (data);
+ return ASN1_ELEMENT_NOT_FOUND;
+ }
+
+ result = asn1_der_decoding (&dst_node, data, size, NULL);
+
+ free (data);
+
+ return result;
+}
+
+/**
+ * asn1_dup_node:
+ * @src: Source asn1 node.
+ * @src_name: Field name in source node.
+ *
+ * Create a deep copy of a asn1_node variable. This function
+ * will return an exact copy of the provided structure.
+ *
+ * Returns: Return %NULL on failure.
+ **/
+asn1_node
+asn1_dup_node (asn1_node_const src, const char *src_name)
+{
+ return _asn1_copy_structure2(src, src_name);
+}
diff --git a/lib/minitasn1/structure.h b/lib/minitasn1/structure.h
new file mode 100644
index 0000000..f06298f
--- /dev/null
+++ b/lib/minitasn1/structure.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2002-2021 Free Software Foundation, Inc.
+ *
+ * This file is part of LIBTASN1.
+ *
+ * The LIBTASN1 library is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ */
+
+/*************************************************/
+/* File: structure.h */
+/* Description: list of exported object by */
+/* "structure.c" */
+/*************************************************/
+
+#ifndef _STRUCTURE_H
+#define _STRUCTURE_H
+
+#include "parser_aux.h" // list_type
+
+int _asn1_create_static_structure (asn1_node_const pointer,
+ char *output_file_name, char *vector_name);
+
+asn1_node _asn1_copy_structure3 (asn1_node_const source_node);
+
+asn1_node _asn1_add_single_node (unsigned int type);
+
+asn1_node _asn1_find_left (asn1_node_const node);
+
+int
+_asn1_delete_structure (list_type *e_list, asn1_node *structure, unsigned int flags);
+
+#endif
diff --git a/lib/minitasn1/version.c b/lib/minitasn1/version.c
new file mode 100644
index 0000000..83e69d8
--- /dev/null
+++ b/lib/minitasn1/version.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2000-2021 Free Software Foundation, Inc.
+ *
+ * This file is part of LIBTASN1.
+ *
+ * The LIBTASN1 library is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h> /* for strverscmp */
+
+#include "libtasn1.h"
+
+/**
+ * asn1_check_version:
+ * @req_version: Required version number, or %NULL.
+ *
+ * Check that the version of the library is at minimum the
+ * requested one and return the version string; return %NULL if the
+ * condition is not satisfied. If a %NULL is passed to this function,
+ * no check is done, but the version string is simply returned.
+ *
+ * See %ASN1_VERSION for a suitable @req_version string.
+ *
+ * Returns: Version string of run-time library, or %NULL if the
+ * run-time library does not meet the required version number.
+ */
+const char *
+asn1_check_version (const char *req_version)
+{
+ if (!req_version || strverscmp (req_version, ASN1_VERSION) <= 0)
+ return ASN1_VERSION;
+
+ return NULL;
+}