fwknop-2.6.11/0000775000175000017500000000000014560546701010120 500000000000000fwknop-2.6.11/common/0000775000175000017500000000000014560546700011407 500000000000000fwknop-2.6.11/common/strlcpy.c0000664000175000017500000000452414560546213013177 00000000000000/** * \file common/strlcpy.c * * \brief Safer string copy routine. */ /* Copyright (c) 1998 Todd C. Miller * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************** */ #include "fko_common.h" #if !HAVE_STRLCPY /* * Copy src to string dst of size siz. At most siz-1 characters * will be copied. Always NUL terminates (unless siz == 0). * Returns strlen(src); if retval >= siz, truncation occurred. */ size_t strlcpy(char *dst, const char *src, size_t siz) { register char *d = dst; register const char *s = src; register size_t n = siz; /* Copy as many bytes as will fit */ if (n != 0 && --n != 0) { do { if ((*d++ = *s++) == 0) break; } while (--n != 0); } /* Not enough room in dst, add NUL and traverse rest of src */ if (n == 0) { if (siz != 0) *d = '\0'; /* NUL-terminate dst */ while (*s++) ; } return(s - src - 1); /* count does not include NUL */ } #endif /***EOF***/ fwknop-2.6.11/common/Makefile.am0000664000175000017500000000114614560546213013364 00000000000000AUTOMAKE_OPTIONS = subdir-objects noinst_LIBRARIES = libfko_util.a libfko_util_source_files = strlcpy.c strlcat.c fko_util.c fko_util.h if WANT_C_UNIT_TESTS libfko_util_source_files += cunit_common.c cunit_common.h endif libfko_util_a_SOURCES = $(libfko_util_source_files) if USE_MINGW EXTRA_libfko_util_a_SOURCES = ../win32/getlogin.c ../win32/getlogin.h libfko_util_a_LIBADD = -lwsock32 -lws2_32 endif AM_CPPFLAGS = $(GPGME_CFLAGS) -I $(top_srcdir)/common -I $(top_srcdir)/lib EXTRA_DIST = common.h netinet_common.h cunit_common.h cunit_common.c clean-local: rm -f *.gcno *.gcda fwknop-2.6.11/common/strlcat.c0000664000175000017500000000470514560546213013154 00000000000000/** * \file common/strlcat.c * * \brief Safer string concat routine. */ /* Copyright (c) 1998 Todd C. Miller * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************** */ #include "fko_common.h" #if !HAVE_STRLCAT /* * Appends src to string dst of size siz (unlike strncat, siz is the * full size of dst, not space left). At most siz-1 characters * will be copied. Always NUL terminates (unless siz <= strlen(dst)). * Returns strlen(src) + MIN(siz, strlen(initial dst)). * If retval >= siz, truncation occurred. */ size_t strlcat(char *dst, const char *src, size_t siz) { register char *d = dst; register const char *s = src; register size_t n = siz; size_t dlen; /* Find the end of dst and adjust bytes left but don't go past end */ while (n-- != 0 && *d != '\0') d++; dlen = d - dst; n = siz - dlen; if (n == 0) return(dlen + strlen(s)); while (*s != '\0') { if (n != 1) { *d++ = *s; n--; } s++; } *d = '\0'; return(dlen + (s - src)); /* count does not include NUL */ } #endif /***EOF***/ fwknop-2.6.11/common/cunit_common.h0000664000175000017500000000300614560546213014170 00000000000000/** * \file common/cunit_common.h * * \brief header file for CUnit tests */ #ifndef CUNIT_COMMON_H #define CUNIT_COMMON_H #include typedef struct c_unit_test { char description[128]; void (*func)(void); } c_unit_test_t; typedef struct c_unit_test_suite { char description[128]; int (*init_func)(void); int (*cleanup_func)(void); c_unit_test_t test_array[12]; int nb_c_unit_test; } c_unit_test_suite_t; #define UTEST_DESCR(name) ut_descr_##name #define UTEST_FCT(name) ut_##name #define TEST_SUITE(name) ts_##name #define TEST_SUITE_DESCR(name) ts_descr_##name #define TEST_SUITE_INIT(name) _ts_init_##name #define TEST_SUITE_CLEANUP(name) _ts_cleanup_##name #define DECLARE_TEST_SUITE(name, description) static const char ts_descr_##name[] = description; \ static c_unit_test_suite_t ts_##name; #define DECLARE_TEST_SUITE_INIT(name) int _ts_init_##name(void) #define DECLARE_TEST_SUITE_CLEANUP(name) int _ts_cleanup_##name(void) #define DECLARE_UTEST(name, description) static const char ut_descr_##name[] = description; \ static void ut_##name(void) void ts_init(c_unit_test_suite_t* ts, const char* description, int (*init)(void), int (*cleanup)(void)); void ts_add_utest(c_unit_test_suite_t* ts, void (*utest_func)(void), const char* utest_description); int register_ts(c_unit_test_suite_t *ts); #endif // CUNIT_COMMON_H fwknop-2.6.11/common/Makefile.in0000664000175000017500000005012314560546531013377 00000000000000# 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@ 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@ target_triplet = @target@ @WANT_C_UNIT_TESTS_TRUE@am__append_1 = cunit_common.c cunit_common.h subdir = common ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/gpgme.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.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 = LIBRARIES = $(noinst_LIBRARIES) ARFLAGS = cru AM_V_AR = $(am__v_AR_@AM_V@) am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) am__v_AR_0 = @echo " AR " $@; am__v_AR_1 = libfko_util_a_AR = $(AR) $(ARFLAGS) libfko_util_a_DEPENDENCIES = am__libfko_util_a_SOURCES_DIST = strlcpy.c strlcat.c fko_util.c \ fko_util.h cunit_common.c cunit_common.h @WANT_C_UNIT_TESTS_TRUE@am__objects_1 = cunit_common.$(OBJEXT) am__objects_2 = strlcpy.$(OBJEXT) strlcat.$(OBJEXT) fko_util.$(OBJEXT) \ $(am__objects_1) am_libfko_util_a_OBJECTS = $(am__objects_2) am__EXTRA_libfko_util_a_SOURCES_DIST = ../win32/getlogin.c \ ../win32/getlogin.h am__dirstamp = $(am__leading_dot)dirstamp libfko_util_a_OBJECTS = $(am_libfko_util_a_OBJECTS) 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)/config/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ../win32/$(DEPDIR)/getlogin.Po \ ./$(DEPDIR)/cunit_common.Po ./$(DEPDIR)/fko_util.Po \ ./$(DEPDIR)/strlcat.Po ./$(DEPDIR)/strlcpy.Po am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) 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 = 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 = $(libfko_util_a_SOURCES) $(EXTRA_libfko_util_a_SOURCES) DIST_SOURCES = $(am__libfko_util_a_SOURCES_DIST) \ $(am__EXTRA_libfko_util_a_SOURCES_DIST) 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)/config/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FIREWALLD_EXE = @FIREWALLD_EXE@ GPGME_CFLAGS = @GPGME_CFLAGS@ GPGME_CONFIG = @GPGME_CONFIG@ GPGME_LIBS = @GPGME_LIBS@ GPG_EXE = @GPG_EXE@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IPFW_EXE = @IPFW_EXE@ IPF_EXE = @IPF_EXE@ IPTABLES_EXE = @IPTABLES_EXE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PF_EXE = @PF_EXE@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ WGET_EXE = @WGET_EXE@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = subdir-objects noinst_LIBRARIES = libfko_util.a libfko_util_source_files = strlcpy.c strlcat.c fko_util.c fko_util.h \ $(am__append_1) libfko_util_a_SOURCES = $(libfko_util_source_files) @USE_MINGW_TRUE@EXTRA_libfko_util_a_SOURCES = ../win32/getlogin.c ../win32/getlogin.h @USE_MINGW_TRUE@libfko_util_a_LIBADD = -lwsock32 -lws2_32 AM_CPPFLAGS = $(GPGME_CFLAGS) -I $(top_srcdir)/common -I $(top_srcdir)/lib EXTRA_DIST = common.h netinet_common.h cunit_common.h cunit_common.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu common/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu common/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_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) ../win32/$(am__dirstamp): @$(MKDIR_P) ../win32 @: > ../win32/$(am__dirstamp) ../win32/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) ../win32/$(DEPDIR) @: > ../win32/$(DEPDIR)/$(am__dirstamp) ../win32/getlogin.$(OBJEXT): ../win32/$(am__dirstamp) \ ../win32/$(DEPDIR)/$(am__dirstamp) libfko_util.a: $(libfko_util_a_OBJECTS) $(libfko_util_a_DEPENDENCIES) $(EXTRA_libfko_util_a_DEPENDENCIES) $(AM_V_at)-rm -f libfko_util.a $(AM_V_AR)$(libfko_util_a_AR) libfko_util.a $(libfko_util_a_OBJECTS) $(libfko_util_a_LIBADD) $(AM_V_at)$(RANLIB) libfko_util.a mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f ../win32/*.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@../win32/$(DEPDIR)/getlogin.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cunit_common.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_util.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strlcat.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strlcpy.Po@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 $(LIBRARIES) 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) -rm -f ../win32/$(DEPDIR)/$(am__dirstamp) -rm -f ../win32/$(am__dirstamp) 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-local \ clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am -rm -f ../win32/$(DEPDIR)/getlogin.Po -rm -f ./$(DEPDIR)/cunit_common.Po -rm -f ./$(DEPDIR)/fko_util.Po -rm -f ./$(DEPDIR)/strlcat.Po -rm -f ./$(DEPDIR)/strlcpy.Po -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 ../win32/$(DEPDIR)/getlogin.Po -rm -f ./$(DEPDIR)/cunit_common.Po -rm -f ./$(DEPDIR)/fko_util.Po -rm -f ./$(DEPDIR)/strlcat.Po -rm -f ./$(DEPDIR)/strlcpy.Po -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-local clean-noinstLIBRARIES \ 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 clean-local: rm -f *.gcno *.gcda # 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: fwknop-2.6.11/common/fko_util.h0000664000175000017500000000677514560546213013332 00000000000000/** * \file common/fko_util.h * * \brief Header for utility functions used by libfko */ /* Fwknop is developed primarily by the people listed in the file 'AUTHORS'. * Copyright (C) 2009-2015 fwknop developers and contributors. For a full * list of contributors, see the file 'CREDITS'. * * License (GNU General Public License): * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #ifndef FKO_UTIL_H #define FKO_UTIL_H 1 #include "fko.h" #define MAX_CMDLINE_ARGS 30 /*!< should be way more than enough */ #define MAX_ARGS_LINE_LEN 1024 #define MAX_HOSTNAME_LEN 70 /* Function prototypes */ int is_valid_encoded_msg_len(const int len); int is_valid_pt_msg_len(const int len); int is_valid_ipv4_addr(const char * const ip_str, const int len); int is_valid_hostname(const char * const hostname_str, const int len); int is_base64(const unsigned char * const buf, const unsigned short int len); void hex_dump(const unsigned char *data, const int size); int enc_mode_strtoint(const char *enc_mode_str); short enc_mode_inttostr(int enc_mode, char* enc_mode_str, size_t enc_mode_size); int strtol_wrapper(const char * const str, const int min, const int max, const int exit_upon_err, int *is_err); short digest_strtoint(const char *dt_str); short digest_inttostr(int digest, char* digest_str, size_t digest_size); short hmac_digest_strtoint(const char *dt_str); short hmac_digest_inttostr(int digest, char* digest_str, size_t digest_size); int constant_runtime_cmp(const char *a, const char *b, int len); void chop_whitespace(char *buf); int zero_free(char *buf, int len); int zero_buf(char *buf, int len); const char * enc_type_inttostr(const int type); const char * msg_type_inttostr(const int type); void chop_newline(char *str); void chop_char(char *str, const char chop); void chop_spaces(char *str); /** * * \brief counts the occurrences of a character * * \return returns the number of chars found */ int count_characters(const char *str, const char match, int len); int strtoargv(const char * const args_str, char **argv_new, int *argc_new); void free_argv(char **argv_new, int *argc_new); int ipv4_resolve(const char *dns_str, char *ip_str); #if !HAVE_STRLCAT size_t strlcat(char *dst, const char *src, size_t siz); #endif #if !HAVE_STRLCPY size_t strlcpy(char *dst, const char *src, size_t siz); #endif #if defined(WIN32) || !defined(HAVE_STRNDUP) char * strndup( const char * s, size_t len ); #endif int dump_ctx_to_buffer(fko_ctx_t ctx, char *dump_buf, size_t dump_buf_len); #include #ifdef WIN32 #include #include #else #if HAVE_SYS_SOCKET_H #include #endif #include #endif #endif /* FKO_UTIL_H */ /***EOF***/ fwknop-2.6.11/common/netinet_common.h0000664000175000017500000001242414560546213014520 00000000000000/** * \file common/netinet_common.h * * \brief Header file for common network packet structures. We roll our * own (actually copy) here in an effort to reduce the cross- * platform "hoop-jumping" we would need to do. */ /* Fwknop is developed primarily by the people listed in the file 'AUTHORS'. * Copyright (C) 2009-2015 fwknop developers and contributors. For a full * list of contributors, see the file 'CREDITS'. * * License (GNU General Public License): * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #ifndef NETINET_COMMON_H #define NETINET_COMMON_H #ifdef WIN32 #include #include #else #if HAVE_SYS_SOCKET_H #include #endif #if HAVE_NETDB_H #include #endif #if HAVE_NETINET_IN_H #include #endif #if PLATFORM_NETBSD || PLATFORM_OPENBSD /* for autoconf net/if.h difficulties */ #include #include #include #ifndef ETHER_IS_VALID_LEN #define ETHER_IS_VALID_LEN(x) \ ((x) >= ETHER_MIN_LEN && (x) <= ETHER_MAX_LEN) #endif #endif #if HAVE_ARPA_INET_H #include #endif #if HAVE_NET_ETHERNET_H #include #elif HAVE_SYS_ETHERNET_H #include /* Seems to be where Solaris puts it. */ /* Also probably need to define ETHER_IS_VALID_LEN here */ #ifndef ETHER_IS_VALID_LEN #define ETHER_IS_VALID_LEN(x) \ ((x) >= ETHERMIN && (x) <= ETHERMAX) #endif #endif #endif /* We will roll our own packet header structs. */ /* The IP header */ struct iphdr { #if __BYTE_ORDER == __LITTLE_ENDIAN unsigned int ihl:4; unsigned int version:4; #elif __BYTE_ORDER == __BIG_ENDIAN unsigned int version:4; unsigned int ihl:4; #else #error "Please fix " #endif unsigned char tos; unsigned short tot_len; unsigned short id; unsigned short frag_off; unsigned char ttl; unsigned char protocol; unsigned short check; unsigned int saddr; unsigned int daddr; }; /* The TCP header */ struct tcphdr { unsigned short source; unsigned short dest; unsigned int seq; unsigned int ack_seq; #if __BYTE_ORDER == __LITTLE_ENDIAN unsigned short res1:4; unsigned short doff:4; unsigned short fin:1; unsigned short syn:1; unsigned short rst:1; unsigned short psh:1; unsigned short ack:1; unsigned short urg:1; unsigned short res2:2; #elif __BYTE_ORDER == __BIG_ENDIAN unsigned short doff:4; unsigned short res1:4; unsigned short res2:2; unsigned short urg:1; unsigned short ack:1; unsigned short psh:1; unsigned short rst:1; unsigned short syn:1; unsigned short fin:1; #else #error "Adjust your defines" #endif unsigned short window; unsigned short check; unsigned short urg_ptr; }; /* The UDP header */ struct udphdr { unsigned short source; /* source port */ unsigned short dest; /* destination port */ unsigned short len; /* udp length */ unsigned short check; /* udp checksum */ }; /* The ICMP header */ struct icmphdr { unsigned char type; /* message type */ unsigned char code; /* type sub-code */ unsigned short checksum; union { struct { unsigned short id; unsigned short sequence; } echo; /* echo datagram */ unsigned int gateway; /* gateway address */ struct { unsigned short __notused; unsigned short mtu; } frag; /* path mtu discovery */ } un; }; #define ICMP_ECHOREPLY 0 /* Echo Reply */ #define ICMP_DEST_UNREACH 3 /* Destination Unreachable */ #define ICMP_SOURCE_QUENCH 4 /* Source Quench */ #define ICMP_REDIRECT 5 /* Redirect (change route) */ #define ICMP_ECHO 8 /* Echo Request */ #define ICMP_TIME_EXCEEDED 11 /* Time Exceeded */ #define ICMP_PARAMETERPROB 12 /* Parameter Problem */ #define ICMP_TIMESTAMP 13 /* Timestamp Request */ #define ICMP_TIMESTAMPREPLY 14 /* Timestamp Reply */ #define ICMP_INFO_REQUEST 15 /* Information Request */ #define ICMP_INFO_REPLY 16 /* Information Reply */ #define ICMP_ADDRESS 17 /* Address Mask Request */ #define ICMP_ADDRESSREPLY 18 /* Address Mask Reply */ #endif /* NETINET_COMMON_H */ fwknop-2.6.11/common/common.h0000664000175000017500000001133714560546213012774 00000000000000/** * \file common/common.h * * \brief Common header file for fwknop client and server programs. */ /* Fwknop is developed primarily by the people listed in the file 'AUTHORS'. * Copyright (C) 2009-2015 fwknop developers and contributors. For a full * list of contributors, see the file 'CREDITS'. * * License (GNU General Public License): * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ****************************************************************************** */ #ifndef _COMMON_H #define _COMMON_H /* Common includes for our other fwknop client and server source files. */ #if HAVE_CONFIG_H #include "config.h" #endif #if HAVE_LIBFIU #include #include #endif /* Include cunit header if c unit testing support is enabled. */ #ifdef HAVE_C_UNIT_TESTS #include "CUnit/Basic.h" #include "cunit_common.h" #endif #include #if HAVE_SYS_TYPES_H #include #endif #if HAVE_ERRNO_H #include #endif #if STDC_HEADERS #include #include #elif HAVE_STRINGS_H #include #endif /* STDC_HEADERS*/ #if HAVE_UNISTD_H #include #endif #ifdef HAVE_SYS_STAT_H #include #endif #if HAVE_NETINET_IN_H #include #endif #if HAVE_CTYPE_H #include #endif #if HAVE_TIME_H #include #endif /* Some hoops for accommodating Windows */ #ifdef WIN32 #include #define strcasecmp _stricmp #define strncasecmp _strnicmp #define snprintf _snprintf #define unlink _unlink #define open _open #define fdopen _fdopen #define close _close #define write _write #define popen _popen #define pclose _pclose #define O_WRONLY _O_WRONLY #define O_RDONLY _O_RDONLY #define O_RDWR _O_RDWR #define O_CREAT _O_CREAT #define O_EXCL _O_EXCL #define S_IRUSR _S_IREAD #define S_IWUSR _S_IWRITE #define PATH_SEP '\\' // --DSS needed for VS versions before 2010 #ifndef __MINGW32__ typedef __int8 int8_t; #endif typedef unsigned __int8 uint8_t; typedef __int16 int16_t; typedef unsigned __int16 uint16_t; typedef __int32 int32_t; typedef unsigned __int32 uint32_t; typedef __int64 int64_t; typedef unsigned __int64 uint64_t; #else #include #define PATH_SEP '/' #endif #include "fko.h" #include "fko_limits.h" #include "fko_util.h" /* Get our program version from VERSION (defined in config.h). */ #define MY_VERSION VERSION enum { FKO_PROTO_UDP, FKO_PROTO_UDP_RAW, FKO_PROTO_TCP, FKO_PROTO_TCP_RAW, FKO_PROTO_ICMP, FKO_PROTO_HTTP, }; /* Other common defines */ #define FKO_DEFAULT_PROTO FKO_PROTO_UDP #define FKO_DEFAULT_PORT 62201 #define DEFAULT_NAT_PORT 55000 #define MIN_HIGH_PORT 10000 /* sensible minimum for SPA dest port */ #define ANY_PORT 0 /* used as a wildcard */ #define ANY_PROTO 0 /* used as a wildcard */ #define NAT_ANY_PORT ANY_PORT #define MAX_SERVER_STR_LEN 50 #define MAX_ICMP_TYPE 40 #define MAX_ICMP_CODE 15 #define RAW_SPA_TTL 255 #define MAX_LINE_LEN 1024 #define MAX_PATH_LEN 1024 #define MAX_GPG_KEY_ID 128 #define MAX_USERNAME_LEN 30 #define MAX_KEY_LEN 128 #define MAX_B64_KEY_LEN 180 #if HAVE_LIBFIU #define MAX_FAULT_TAG_LEN 128 #endif /* Some convenience macros */ /* Get the number of elements of an array */ #define ARRAY_SIZE(t) (sizeof(t) / sizeof(t[0])) /* Characters allowed between a config parameter and its value. */ #define IS_CONFIG_PARAM_DELIMITER(x) (x == ' ' || x == '\t' || x == '='); /* End of line characters. */ #define IS_LINE_END(x) (x == '\n' || x == '\r' || x == ';'); /* Characters in the first position of a line that make it considered * empty or otherwise non-interesting (like a comment). */ #define IS_EMPTY_LINE(x) ( \ x == '#' || x == '\n' || x == '\r' || x == ';' || x == '\0' \ ) /* Work-around for not having strnlen */ #if !HAVE_STRNLEN #define strnlen(s, l) (strlen(s) < l ? strlen(s) : l) #endif #endif /* _COMMON_H */ /***EOF***/ fwknop-2.6.11/common/cunit_common.c0000664000175000017500000000247114560546213014170 00000000000000/** * \file common/cunit_common.c * * \brief CUnit test functions */ #ifdef HAVE_C_UNIT_TESTS #include "cunit_common.h" #include "stdlib.h" #include "stdio.h" void ts_init(c_unit_test_suite_t* ts, const char* description, int (*init)(void), int (*cleanup)(void)) { memset(ts, 0x00, sizeof(c_unit_test_suite_t)); strcpy(ts->description, description); ts->init_func = init; ts->cleanup_func = cleanup; } void ts_add_utest(c_unit_test_suite_t* ts, void (*utest_func)(void), const char* utest_description) { c_unit_test_t* utest = &(ts->test_array[ts->nb_c_unit_test]); utest->func = utest_func; strcpy(utest->description, utest_description); (ts->nb_c_unit_test)++; } int register_ts(c_unit_test_suite_t *ts) { CU_pSuite pSuite = NULL; int ix_utest; pSuite = CU_add_suite(ts->description, ts->init_func, ts->cleanup_func); if (NULL == pSuite) { CU_cleanup_registry(); return CU_get_error(); } /* add the tests to the suite */ for (ix_utest=0 ; ix_utestnb_c_unit_test ; ix_utest++) { c_unit_test_t* utest = &(ts->test_array[ix_utest]); if (NULL == CU_add_test(pSuite, utest->description, utest->func)) { CU_cleanup_registry(); return CU_get_error(); } } return 0; } #endif /* HAVE_C_UNIT_TESTS */ fwknop-2.6.11/common/fko_util.c0000664000175000017500000011300514560546213013306 00000000000000/** * \file common/fko_util.c * * \brief Provide a set of common utility functions that fwknop can use. */ /* Fwknop is developed primarily by the people listed in the file 'AUTHORS'. * Copyright (C) 2009-2015 fwknop developers and contributors. For a full * list of contributors, see the file 'CREDITS'. * * License (GNU General Public License): * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #include "fko_common.h" #include "fko_util.h" #include #include #ifndef WIN32 /* for inet_aton() IP validation */ #include #include #include #endif /* Check for a FKO error returned by a function an return the error code */ #define RETURN_ON_FKO_ERROR(e, f) do { if (((e)=(f)) != FKO_SUCCESS) { return (e); } } while(0); #define FKO_ENCRYPTION_MODE_BUFSIZE 16 /*!< Maximum size of an encryption mode string */ #define FKO_ENC_MODE_SUPPORTED 0 /*!< Defined a supported fko encryption mode */ #define FKO_ENC_MODE_NOT_SUPPORTED !FKO_ENC_MODE_SUPPORTED /*!< Defined an unsupported fko encryption mode */ #define NULL_STRING "" /*!< String which represents a NULL buffer */ #ifdef HAVE_C_UNIT_TESTS /* LCOV_EXCL_START */ #include "cunit_common.h" DECLARE_TEST_SUITE(utils_test, "Utility functions test suite"); #endif /* LCOV_EXCL_STOP */ /** * Structure to handle an encryption mode string string and its associated integer value */ typedef struct fko_enc_mode_str { const char str[FKO_ENCRYPTION_MODE_BUFSIZE]; /*!< String which represents an encryption mode value for the FKO library */ int val; /*!< Value of the encryption mode according to the FKO library */ int supported; /*!< SUPPORTED or NOT_SUPPORTED */ } fko_enc_mode_str_t; /** * Array to associate all of encryption modes with their respective string */ static fko_enc_mode_str_t fko_enc_mode_strs[] = { { "CBC", FKO_ENC_MODE_CBC, FKO_ENC_MODE_SUPPORTED }, { "ECB", FKO_ENC_MODE_ECB, FKO_ENC_MODE_SUPPORTED }, { "CFB", FKO_ENC_MODE_CFB, FKO_ENC_MODE_SUPPORTED }, { "PCBC", FKO_ENC_MODE_PCBC, FKO_ENC_MODE_NOT_SUPPORTED }, { "OFB", FKO_ENC_MODE_OFB, FKO_ENC_MODE_SUPPORTED }, { "CTR", FKO_ENC_MODE_CTR, FKO_ENC_MODE_SUPPORTED }, { "Asymmetric", FKO_ENC_MODE_ASYMMETRIC, FKO_ENC_MODE_SUPPORTED }, { "legacy", FKO_ENC_MODE_CBC_LEGACY_IV, FKO_ENC_MODE_SUPPORTED } }; /* Compare all bytes with constant run time regardless of * input characteristics (i.e. don't return early if a difference * is found before comparing all bytes). This code was adapted * from YaSSL which is GPLv2 after a timing bug was reported by * Ryman through github (#85) */ int constant_runtime_cmp(const char *a, const char *b, int len) { int good = 0; int bad = 0; int i; for(i=0; i < len; i++) { if (a[i] == b[i]) good++; else bad++; } if (good == len) return 0; else return 0 - bad; } /* Validate encoded message length */ int is_valid_encoded_msg_len(const int len) { #if HAVE_LIBFIU fiu_return_on("is_valid_encoded_msg_len_val", 0); #endif if(len < MIN_SPA_ENCODED_MSG_SIZE || len >= MAX_SPA_ENCODED_MSG_SIZE) return(0); return(1); } /* Validate an IPv4 address */ int is_valid_ipv4_addr(const char * const ip_str, const int len) { const char *ndx = ip_str; char tmp_ip_str[MAX_IPV4_STR_LEN + 1] = {0}; int dot_ctr = 0, char_ctr = 0; int res = 1; #if HAVE_SYS_SOCKET_H struct in_addr in; #endif if(ip_str == NULL) return 0; if((len > MAX_IPV4_STR_LEN) || (len < MIN_IPV4_STR_LEN)) return 0; while(char_ctr < len) { /* If we've hit a null within the given length, then not valid regardless */ if(*ndx == '\0') return 0; char_ctr++; if(*ndx == '.') dot_ctr++; else if(isdigit((int)(unsigned char)*ndx) == 0) { res = 0; break; } ndx++; } if((res == 1) && (dot_ctr != 3)) res = 0; #if HAVE_SYS_SOCKET_H /* Stronger IP validation now that we have a candidate that looks * close enough */ if(res == 1) { strncpy(tmp_ip_str, ip_str, len); if (inet_aton(tmp_ip_str, &in) == 0) res = 0; } #endif return(res); } /* Validate a hostname */ int is_valid_hostname(const char * const hostname_str, const int len) { int label_size = 0, total_size = 0; const char *ndx = hostname_str; if (hostname_str == NULL) return 0; if (len > 254) return 0; while(total_size < len) { if (*ndx == '\0') return 0; if (label_size == 0) //More restrictions on first character of a label { if (!isalnum((int)(unsigned char)*ndx)) return 0; } else if (!(isalnum((int)(unsigned char)*ndx) | (*ndx == '.') | (*ndx == '-'))) return 0; if (*ndx == '.') { if (label_size > 63) return 0; if (!isalnum((int)(unsigned char)*(ndx-1))) //checks that previous character was not a . or - return 0; label_size = 0; } else { label_size++; } total_size++; ndx++; //move to next character } /* At this point, we're pointing at the null. Decrement ndx for simplicity */ ndx--; if (*ndx == '-') return 0; if (*ndx == '.') total_size--; if (label_size > 63) return 0; /* By now we've bailed if invalid */ return 1; } /* Convert a digest_type string to its integer value. */ short digest_strtoint(const char *dt_str) { if(strcasecmp(dt_str, "md5") == 0) return(FKO_DIGEST_MD5); else if(strcasecmp(dt_str, "sha1") == 0) return(FKO_DIGEST_SHA1); else if(strcasecmp(dt_str, "sha256") == 0) return(FKO_DIGEST_SHA256); else if(strcasecmp(dt_str, "sha384") == 0) return(FKO_DIGEST_SHA384); else if(strcasecmp(dt_str, "sha512") == 0) return(FKO_DIGEST_SHA512); else if(strcasecmp(dt_str, "sha3_256") == 0) return(FKO_DIGEST_SHA3_256); else if(strcasecmp(dt_str, "sha3_512") == 0) return(FKO_DIGEST_SHA3_512); else return(-1); } /** * \brief Return a digest string according to a digest integer value * * This function checks the digest integer is valid, and write the digest * string associated. * * \param digest Digest inetger value (FKO_DIGEST_MD5, FKO_DIGEST_SHA1 ...) * \param digest_str Buffer to write the digest string * \param digest_size size of the digest string buffer * * \return -1 if the digest integer value is not supported, 0 otherwise */ short digest_inttostr(int digest, char* digest_str, size_t digest_size) { short digest_not_valid = 0; memset(digest_str, 0, digest_size); switch (digest) { case FKO_DIGEST_MD5: strlcpy(digest_str, "MD5", digest_size); break; case FKO_DIGEST_SHA1: strlcpy(digest_str, "SHA1", digest_size); break; case FKO_DIGEST_SHA256: strlcpy(digest_str, "SHA256", digest_size); break; case FKO_DIGEST_SHA384: strlcpy(digest_str, "SHA384", digest_size); break; case FKO_DIGEST_SHA512: strlcpy(digest_str, "SHA512", digest_size); break; case FKO_DIGEST_SHA3_256: strlcpy(digest_str, "SHA3_256", digest_size); break; case FKO_DIGEST_SHA3_512: strlcpy(digest_str, "SHA3_512", digest_size); break; default: strlcpy(digest_str, "Unknown", digest_size); digest_not_valid = -1; break; } return digest_not_valid; } short hmac_digest_strtoint(const char *dt_str) { if(strcasecmp(dt_str, "md5") == 0) return(FKO_HMAC_MD5); else if(strcasecmp(dt_str, "sha1") == 0) return(FKO_HMAC_SHA1); else if(strcasecmp(dt_str, "sha256") == 0) return(FKO_HMAC_SHA256); else if(strcasecmp(dt_str, "sha384") == 0) return(FKO_HMAC_SHA384); else if(strcasecmp(dt_str, "sha512") == 0) return(FKO_HMAC_SHA512); else if(strcasecmp(dt_str, "sha3_256") == 0) return(FKO_HMAC_SHA3_256); else if(strcasecmp(dt_str, "sha3_512") == 0) return(FKO_HMAC_SHA3_512); else return(-1); } /* Return encryption type string representation */ const char * enc_type_inttostr(const int type) { if(type == FKO_ENC_MODE_UNKNOWN) return("Unknown encryption type"); else if(type == FKO_ENCRYPTION_RIJNDAEL) return("Rijndael"); else if(type == FKO_ENCRYPTION_GPG) return("GPG"); return("Unknown encryption type"); } /* Return message type string representation */ const char * msg_type_inttostr(const int type) { if(type == FKO_COMMAND_MSG) return("Command msg"); else if(type == FKO_ACCESS_MSG) return("Access msg"); else if(type == FKO_NAT_ACCESS_MSG) return("NAT access msg"); else if(type == FKO_CLIENT_TIMEOUT_ACCESS_MSG) return("Client timeout access msg"); else if(type == FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG) return("Client timeout NAT access msg"); else if(type == FKO_LOCAL_NAT_ACCESS_MSG) return("Local NAT access msg"); else if(type == FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG) return("Client timeout local NAT access msg"); return("Unknown message type"); } /** * \brief Return a hmac digest string according to a hmac digest integer value * * This function checks if the digest integer is valid, and write the digest * string associated. * * \param digest Digest inetger value (FKO_HMAC_MD5, FKO_HMAC_SHA1 ...) * \param digest_str Buffer to write the digest string * \param digest_size size of the digest string buffer * * \return -1 if the digest integer value is not supported, 0 otherwise */ short hmac_digest_inttostr(int digest, char* digest_str, size_t digest_size) { short digest_not_valid = 0; memset(digest_str, 0, digest_size); switch (digest) { case FKO_HMAC_MD5: strlcpy(digest_str, "MD5", digest_size); break; case FKO_HMAC_SHA1: strlcpy(digest_str, "SHA1", digest_size); break; case FKO_HMAC_SHA256: strlcpy(digest_str, "SHA256", digest_size); break; case FKO_HMAC_SHA384: strlcpy(digest_str, "SHA384", digest_size); break; case FKO_HMAC_SHA512: strlcpy(digest_str, "SHA512", digest_size); break; case FKO_HMAC_SHA3_256: strlcpy(digest_str, "SHA3_256", digest_size); break; case FKO_HMAC_SHA3_512: strlcpy(digest_str, "SHA3_512", digest_size); break; default: strlcpy(digest_str, "Unknown", digest_size); digest_not_valid = -1; break; } return digest_not_valid; } /* Validate plaintext input size */ int is_valid_pt_msg_len(const int len) { #if HAVE_LIBFIU fiu_return_on("is_valid_pt_msg_len_val", 0); #endif if(len < MIN_SPA_PLAINTEXT_MSG_SIZE || len >= MAX_SPA_PLAINTEXT_MSG_SIZE) return(0); return(1); } /** * @brief Convert an encryption mode string to its integer value. * * @param enc_mode_str Encryption mode string (CBC,ECB...) * * @return -1 if the encryption mode string is not supported, * otherwise the encryption mode value */ int enc_mode_strtoint(const char *enc_mode_str) { unsigned char ndx_enc_mode; int enc_mode_int = -1; /* Encryption mode integer value */ fko_enc_mode_str_t *enc_mode_str_pt; /* Look into the fko_enc_mode_strs array to find out the right encryption mode */ for (ndx_enc_mode = 0 ; ndx_enc_mode < ARRAY_SIZE(fko_enc_mode_strs) ; ndx_enc_mode++) { enc_mode_str_pt = &(fko_enc_mode_strs[ndx_enc_mode]); /* If the encryption mode matches, grab it */ if ( (strcasecmp(enc_mode_str, enc_mode_str_pt->str) == 0) && (enc_mode_str_pt->supported == FKO_ENC_MODE_SUPPORTED) ) { enc_mode_int = enc_mode_str_pt->val; break; } } return enc_mode_int; } /** * @brief Return an encryption mode string according to an enc_mode integer value * * This function checks if the encryption mode integer is valid, and write the * encryption mode string associated. * * @param enc_mode Encryption mode integer value (FKO_ENC_MODE_CBC, FKO_ENC_MODE_ECB ...) * @param enc_mode_str Buffer to write the encryption mode string to * @param enc_mode_size Size of the encryption mode string buffer * * @return -1 if the encryption mode integer value is not supported, 0 otherwise */ short enc_mode_inttostr(int enc_mode, char* enc_mode_str, size_t enc_mode_size) { short enc_mode_error = -1; unsigned char ndx_enc_mode; fko_enc_mode_str_t *enc_mode_str_pt; /* Initialize the protocol string */ memset(enc_mode_str, 0, enc_mode_size); /* Look into the fko_enc_mode_strs array to find out the right protocol */ for (ndx_enc_mode = 0 ; ndx_enc_mode < ARRAY_SIZE(fko_enc_mode_strs) ; ndx_enc_mode++) { enc_mode_str_pt = &(fko_enc_mode_strs[ndx_enc_mode]); /* If the encryption mode matches, grab it */ if ( (enc_mode_str_pt->val == enc_mode) && (enc_mode_str_pt->supported == FKO_ENC_MODE_SUPPORTED) ) { strlcpy(enc_mode_str, enc_mode_str_pt->str, enc_mode_size); enc_mode_error = 0; break; } } return enc_mode_error; } int strtol_wrapper(const char * const str, const int min, const int max, const int exit_upon_err, int *err) { int val; errno = 0; *err = FKO_SUCCESS; val = strtol(str, (char **) NULL, 10); if ((errno == ERANGE || (errno != 0 && val == 0))) { *err = errno; if(exit_upon_err == EXIT_UPON_ERR) { perror("strtol"); fprintf(stderr, "[*] Value %d out of range [(%d)-(%d)]\n", val, min, max); exit(EXIT_FAILURE); } } if(val < min) { *err = FKO_ERROR_INVALID_DATA_UTIL_STRTOL_LT_MIN; if(exit_upon_err == EXIT_UPON_ERR) { fprintf(stderr, "[*] Value %d out of range [(%d)-(%d)]\n", val, min, max); exit(EXIT_FAILURE); } } /* allow max == -1 to be an exception where we don't care about the * maximum - note that the ERANGE check is still in place above */ if((max >= 0) && (val > max)) { *err = FKO_ERROR_INVALID_DATA_UTIL_STRTOL_GT_MAX; if(exit_upon_err == EXIT_UPON_ERR) { fprintf(stderr, "[*] Value %d out of range [(%d)-(%d)]\n", val, min, max); exit(EXIT_FAILURE); } } #if HAVE_LIBFIU fiu_return_on("strtol_wrapper_lt_min", FKO_ERROR_INVALID_DATA_UTIL_STRTOL_LT_MIN); fiu_return_on("strtol_wrapper_gt_max", FKO_ERROR_INVALID_DATA_UTIL_STRTOL_GT_MAX); #endif return val; } /* Chop whitespace off the end of a string (must be NULL-terminated) */ void chop_whitespace(char *str) { int i; for (i=strlen(str)-1; i > 0; i--) { if (! isspace(str[i])) { if (i < strlen(str)-1) str[i+1] = 0x0; break; } } return; } /* zero out a buffer before free() */ int zero_free(char *buf, int len) { int res = FKO_SUCCESS; if(buf == NULL) return res; if(len == 0) { free(buf); /* always free() if buf != NULL */ return res; } res = zero_buf(buf, len); free(buf); #if HAVE_LIBFIU fiu_return_on("zero_free_err", FKO_ERROR_ZERO_OUT_DATA); #endif return res; } /* zero out sensitive information in a way that isn't optimized out by the compiler * since we force a comparison and return an error if there is a problem (though * the caller should do something with this information too). */ int zero_buf(char *buf, int len) { int i, res = FKO_SUCCESS; #if HAVE_LIBFIU fiu_return_on("zero_buf_err", FKO_ERROR_ZERO_OUT_DATA); #endif if(buf == NULL || len == 0) return res; if(len < 0 || len > MAX_SPA_ENCODED_MSG_SIZE) return FKO_ERROR_ZERO_OUT_DATA; for(i=0; i < len; i++) buf[i] = 0x0; for(i=0; i < len; i++) if(buf[i] != 0x0) res = FKO_ERROR_ZERO_OUT_DATA; return res; } #if defined(WIN32) || !defined(HAVE_STRNDUP) /* Windows does not have strndup, so we well implement it here. * This was the Public Domain C Library (PDCLib). */ char *strndup( const char * s, size_t len ) { char* ns = NULL; if(s) { ns = calloc(1, len + 1); if(ns) { ns[len] = 0; // strncpy to be pedantic about modification in multithreaded // applications return strncpy(ns, s, len); } } return ns; } #endif /** * @brief Add a printf style message to a buffer * * This function allows to append a printf style message to a buffer * and prevents buffer overflow by taking care of the size the buffer. * It returns the number of bytes really written to the buffer. * Thus if an error is encoutered during the process the number of bytes * written is set to 0. This way the user knows exactly how many bytes * can be appended afterwards. * * @param buf Buffer to write the formatted message to * @param buf_size Maximum number of bytes to write to the buffer * @param msg Message to format and to append to the buffer * * @return the number of bytes written to the buffer */ static int append_msg_to_buf(char *buf, size_t buf_size, const char* msg, ...) { int bytes_written = 0; /* Number of bytes written to buf */ va_list ap; /* Check if the buffer is valid */ if (buf_size > 0) { va_start(ap, msg); /* Format the message like a printf message */ bytes_written = vsnprintf(buf, buf_size, msg, ap); /* It looks like the message has been truncated or an error occurred*/ if (bytes_written < 0) bytes_written = 0; else if (bytes_written >= buf_size) bytes_written = buf_size; /* The messsage has been formatted correctly */ else; va_end(ap); } /* No valid buffer has been supplied, thus we do not write anything */ else; /* Return the number of bytes written to the buffer */ return bytes_written; } /* Determine if a buffer contains only characters from the base64 * encoding set */ int is_base64(const unsigned char * const buf, const unsigned short int len) { unsigned short int i; int rv = 1; for(i=0; i 0; i--) { if(str[i] != 0x20) break; str[i] = 0x0; } } return; } static int add_argv(char **argv_new, int *argc_new, const char *new_arg) { int buf_size = 0; buf_size = strlen(new_arg) + 1; argv_new[*argc_new] = calloc(1, buf_size); if(argv_new[*argc_new] == NULL) return 0; strlcpy(argv_new[*argc_new], new_arg, buf_size); *argc_new += 1; if(*argc_new >= MAX_CMDLINE_ARGS-1) return 0; argv_new[*argc_new] = NULL; return 1; } int strtoargv(const char * const args_str, char **argv_new, int *argc_new) { int current_arg_ctr = 0, i; char arg_tmp[MAX_ARGS_LINE_LEN] = {0}; for (i=0; i < (int)strlen(args_str); i++) { if (!isspace((int)(unsigned char)args_str[i])) { arg_tmp[current_arg_ctr] = args_str[i]; current_arg_ctr++; } else { if(current_arg_ctr > 0) { arg_tmp[current_arg_ctr] = '\0'; if (add_argv(argv_new, argc_new, arg_tmp) != 1) { free_argv(argv_new, argc_new); return 0; } current_arg_ctr = 0; } } } /* pick up the last argument in the string */ if(current_arg_ctr > 0) { arg_tmp[current_arg_ctr] = '\0'; if (add_argv(argv_new, argc_new, arg_tmp) != 1) { free_argv(argv_new, argc_new); return 0; } } return 1; } void free_argv(char **argv_new, int *argc_new) { int i; if(argv_new == NULL || *argv_new == NULL) return; for (i=0; i < *argc_new; i++) { if(argv_new[i] == NULL) break; else free(argv_new[i]); } return; } #define ASCII_LEN 16 /* Generic hex dump function. */ void hex_dump(const unsigned char *data, const int size) { int ln=0, i=0, j=0; char ascii_str[ASCII_LEN+1] = {0}; for(i=0; i 0x7e) ? '.' : data[i]; if(j == 8) printf(" "); } /* Remainder... */ ln = strlen(ascii_str); if(ln > 0) { for(i=0; i < ASCII_LEN-ln; i++) printf(" "); if(ln < 8) printf(" "); printf(" %s\n\n", ascii_str); } return; } /** * @brief Dump a FKO context to a buffer * * This function parses a FKO context and decodes each field to dump them to a * buffer in a comprehensible way. * * @param ctx FKO context to dump * @param dump_buf Buffer where to store the dump of the context * @param dump_buf_len Number of bytes available in the dump_buf array * * @return a FKO error code. FKO_SUCCESS if successful. */ int dump_ctx_to_buffer(fko_ctx_t ctx, char *dump_buf, size_t dump_buf_len) { int cp = 0; int err = FKO_LAST_ERROR; char *rand_val = NULL; char *username = NULL; char *version = NULL; char *spa_message = NULL; char *nat_access = NULL; char *server_auth = NULL; char *enc_data = NULL; char *hmac_data = NULL; char *spa_digest = NULL; #if HAVE_LIBGPGME char *gpg_signer = NULL; char *gpg_recip = NULL; char *gpg_sig_id = NULL; unsigned char gpg_sig_verify = 0; unsigned char gpg_ignore_verify = 0; char *gpg_sig_fpr = NULL; char *gpg_home_dir = NULL; char *gpg_exe = NULL; int gpg_sigsum = -1; int gpg_sig_stat = -1; #endif char *spa_data = NULL; char digest_str[24] = {0}; char hmac_str[24] = {0}; char enc_mode_str[FKO_ENCRYPTION_MODE_BUFSIZE] = {0}; time_t timestamp = 0; short msg_type = -1; short digest_type = -1; short hmac_type = -1; short encryption_type = -1; int encryption_mode = -1; int client_timeout = -1; /* Zero-ed the buffer */ memset(dump_buf, 0, dump_buf_len); /* Make sure the FKO context is initialized before printing it */ if(!CTX_INITIALIZED(ctx)) err = FKO_ERROR_CTX_NOT_INITIALIZED; else { /* Parse the FKO context and collect data */ RETURN_ON_FKO_ERROR(err, fko_get_rand_value(ctx, &rand_val)); RETURN_ON_FKO_ERROR(err, fko_get_username(ctx, &username)); RETURN_ON_FKO_ERROR(err, fko_get_timestamp(ctx, ×tamp)); RETURN_ON_FKO_ERROR(err, fko_get_version(ctx, &version)); RETURN_ON_FKO_ERROR(err, fko_get_spa_message_type(ctx, &msg_type)); RETURN_ON_FKO_ERROR(err, fko_get_spa_message(ctx, &spa_message)); RETURN_ON_FKO_ERROR(err, fko_get_spa_nat_access(ctx, &nat_access)); RETURN_ON_FKO_ERROR(err, fko_get_spa_server_auth(ctx, &server_auth)); RETURN_ON_FKO_ERROR(err, fko_get_spa_client_timeout(ctx, &client_timeout)); RETURN_ON_FKO_ERROR(err, fko_get_spa_digest_type(ctx, &digest_type)); RETURN_ON_FKO_ERROR(err, fko_get_spa_hmac_type(ctx, &hmac_type)); RETURN_ON_FKO_ERROR(err, fko_get_spa_encryption_type(ctx, &encryption_type)); RETURN_ON_FKO_ERROR(err, fko_get_spa_encryption_mode(ctx, &encryption_mode)); RETURN_ON_FKO_ERROR(err, fko_get_encoded_data(ctx, &enc_data)); RETURN_ON_FKO_ERROR(err, fko_get_spa_hmac(ctx, &hmac_data)); RETURN_ON_FKO_ERROR(err, fko_get_spa_digest(ctx, &spa_digest)); RETURN_ON_FKO_ERROR(err, fko_get_spa_data(ctx, &spa_data)); #if HAVE_LIBGPGME if(encryption_mode == FKO_ENC_MODE_ASYMMETRIC) { /* Populate GPG variables */ RETURN_ON_FKO_ERROR(err, fko_get_gpg_signer(ctx, &gpg_signer)); RETURN_ON_FKO_ERROR(err, fko_get_gpg_recipient(ctx, &gpg_recip)); RETURN_ON_FKO_ERROR(err, fko_get_gpg_signature_verify(ctx, &gpg_sig_verify)); RETURN_ON_FKO_ERROR(err, fko_get_gpg_ignore_verify_error(ctx, &gpg_ignore_verify)); RETURN_ON_FKO_ERROR(err, fko_get_gpg_home_dir(ctx, &gpg_home_dir)); RETURN_ON_FKO_ERROR(err, fko_get_gpg_exe(ctx, &gpg_exe)); if(fko_get_gpg_signature_id(ctx, &gpg_sig_id) != FKO_SUCCESS) gpg_sig_id = NULL; if(fko_get_gpg_signature_summary(ctx, &gpg_sigsum) != FKO_SUCCESS) gpg_sigsum = -1; if(fko_get_gpg_signature_status(ctx, &gpg_sig_stat) != FKO_SUCCESS) gpg_sig_stat = -1; if(fko_get_gpg_signature_fpr(ctx, &gpg_sig_fpr) != FKO_SUCCESS) gpg_sig_fpr = NULL; } #endif /* Convert the digest integer to a string */ if (digest_inttostr(digest_type, digest_str, sizeof(digest_str)) != 0) return (FKO_ERROR_INVALID_DIGEST_TYPE); /* Convert the encryption mode integer to a string */ if (enc_mode_inttostr(encryption_mode, enc_mode_str, sizeof(enc_mode_str)) != 0) return (FKO_ERROR_INVALID_ENCRYPTION_TYPE); /* Convert the HMAC digest integer to a string if a HMAC message is available */ if (ctx->msg_hmac_len != 0) { if (hmac_digest_inttostr(hmac_type, hmac_str, sizeof(hmac_str)) != 0) return (FKO_ERROR_UNSUPPORTED_HMAC_MODE); } /* Fill in the buffer to dump */ cp = append_msg_to_buf(dump_buf, dump_buf_len, "SPA Field Values:\n=================\n"); cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " Random Value: %s\n", rand_val == NULL ? NULL_STRING : rand_val); cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " Username: %s\n", username == NULL ? NULL_STRING : username); cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " Timestamp: %u\n", (unsigned int) timestamp); cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " FKO Version: %s\n", version == NULL ? NULL_STRING : version); cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " Message Type: %i (%s)\n", msg_type, msg_type_inttostr(msg_type)); cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " Message String: %s\n", spa_message == NULL ? NULL_STRING : spa_message); cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " Nat Access: %s\n", nat_access == NULL ? NULL_STRING : nat_access); cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " Server Auth: %s\n", server_auth == NULL ? NULL_STRING : server_auth); cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " Client Timeout: %u\n", client_timeout); cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " Digest Type: %u (%s)\n", digest_type, digest_str); cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " HMAC Type: %u (%s)\n", hmac_type, hmac_type == 0 ? "None" : hmac_str); cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "Encryption Type: %d (%s)\n", encryption_type, enc_type_inttostr(encryption_type)); cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "Encryption Mode: %d (%s)\n", encryption_mode, enc_mode_str); #if HAVE_LIBGPGME if(encryption_mode == FKO_ENC_MODE_ASYMMETRIC) { cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " GPG signer: %s\n", gpg_signer == NULL ? NULL_STRING : gpg_signer); cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " GPG recipient: %s\n", gpg_recip == NULL ? NULL_STRING : gpg_recip); cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " GPG sig verify: %s\n", gpg_sig_verify == 0 ? "No" : "Yes"); cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " GPG ignore sig: %s\n", gpg_ignore_verify == 0 ? "No" : "Yes"); cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " GPG sig ID: %s\n", gpg_sig_id == NULL ? NULL_STRING : gpg_sig_id); cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " GPG sig fpr: %s\n", gpg_sig_fpr == NULL ? NULL_STRING : gpg_sig_fpr); cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "GPG sig summary: %d\n", gpg_sigsum); cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " GPG sig status: %d\n", gpg_sig_stat); cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " GPG home dir: %s\n", gpg_home_dir == NULL ? NULL_STRING : gpg_home_dir); cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " GPG exe: %s\n", gpg_exe == NULL ? GPG_EXE : gpg_exe); } #endif cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " Encoded Data: %s\n", enc_data == NULL ? NULL_STRING : enc_data); cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "SPA Data Digest: %s\n", spa_digest == NULL ? NULL_STRING : spa_digest); cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " HMAC: %s\n", hmac_data == NULL ? NULL_STRING : hmac_data); append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " Final SPA Data: %s\n", spa_data); err = FKO_SUCCESS; } return (err); } /** * @brief Grab the sin address from the sockaddr structure. * * This function returns the sin address as a sockaddr_in or sockaddr_in6 * structure according to the family set (ipv4 or ipv6) in the sockaddr * structure. * * @param sa sockaddr strcuture * * @return the sin addr if the sa family is AF_INET or the sin6_addr otherwise. */ static void * get_in_addr(struct sockaddr *sa) { if (sa->sa_family == AF_INET) { return &(((struct sockaddr_in*)sa)->sin_addr); } else { return &(((struct sockaddr_in6*)sa)->sin6_addr); } } /** * @brief Resolve a domain name as an IP address. * * @param dns_str Name of the host to resolve. * @param hints Hints to reduce the number of result from getaddrinfo() * @param ip_str String where to store the resolve ip address * @param ip_bufsize Number of bytes available in the ip_str buffer * @param opts Client command line options * * @return 0 if successful, 1 if an error occurred. */ int ipv4_resolve(const char *dns_str, char *ip_str) { int error; /* Function error return code */ size_t ip_bufsize = MAX_IPV4_STR_LEN; struct addrinfo hints; struct addrinfo *result; /* Result of getaddrinfo() */ struct addrinfo *rp; /* Element of the linked list returned by getaddrinfo() */ #if WIN32 && WINVER <= 0x0600 struct sockaddr_in *in; char *win_ip; #else struct sockaddr_in *sai_remote; /* Remote host information as a sockaddr_in structure */ #endif #if WIN32 WSADATA wsa_data; error = WSAStartup( MAKEWORD(1,1), &wsa_data ); if( error != 0 ) { fprintf(stderr, "Winsock initialization error %d", error); return(error); } #endif memset(&hints, 0 , sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; /* Try to resolve the host name */ error = getaddrinfo(dns_str, NULL, &hints, &result); if (error != 0) fprintf(stderr, "ipv4_resolve() : %s\n", gai_strerror(error)); else { error = 1; /* Go through the linked list of addrinfo structures */ for (rp = result; rp != NULL; rp = rp->ai_next) { memset(ip_str, 0, ip_bufsize); #if WIN32 && WINVER <= 0x0600 /* On older Windows systems (anything before Vista?), * we use inet_ntoa for now. */ in = (struct sockaddr_in*)(rp->ai_addr); win_ip = inet_ntoa(in->sin_addr); if (win_ip != NULL && (strlcpy(ip_str, win_ip, ip_bufsize) > 0)) #else sai_remote = (struct sockaddr_in *)get_in_addr((struct sockaddr *)(rp->ai_addr)); if (inet_ntop(rp->ai_family, sai_remote, ip_str, ip_bufsize) != NULL) #endif { error = 0; break; } } /* Free our result from getaddrinfo() */ freeaddrinfo(result); } #if WIN32 WSACleanup(); #endif return error; } int count_characters(const char *str, const char match, int len) { int i, count = 0; for (i=0; i < len && str[i] != '\0'; i++) { if (str[i] == match) count++; } return count; } #ifdef HAVE_C_UNIT_TESTS /* LCOV_EXCL_START */ DECLARE_UTEST(test_hostname_validator, "test the is_valid_hostname function") { char test_hostname[300]; strcpy(test_hostname, "a"); CU_ASSERT(is_valid_hostname(test_hostname, strlen(test_hostname)) == 1); strcpy(test_hostname, "a.b"); CU_ASSERT(is_valid_hostname(test_hostname, strlen(test_hostname)) == 1); strcpy(test_hostname, "a.b."); CU_ASSERT(is_valid_hostname(test_hostname, strlen(test_hostname)) == 1); strcpy(test_hostname, "a."); CU_ASSERT(is_valid_hostname(test_hostname, strlen(test_hostname)) == 1); strcpy(test_hostname, "a..b"); CU_ASSERT(is_valid_hostname(test_hostname, strlen(test_hostname)) == 0); strcpy(test_hostname, ".a.b"); CU_ASSERT(is_valid_hostname(test_hostname, strlen(test_hostname)) == 0); strcpy(test_hostname, "a-.b"); CU_ASSERT(is_valid_hostname(test_hostname, strlen(test_hostname)) == 0); strcpy(test_hostname, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.b"); CU_ASSERT(is_valid_hostname(test_hostname, strlen(test_hostname)) == 0); } DECLARE_UTEST(test_ipv4_validator, "test the is_valid_ipv4_addr function") { char test_str[32]; strcpy(test_str, "1.2.3.4"); CU_ASSERT(is_valid_ipv4_addr(test_str, strlen(test_str))); strcpy(test_str, "127.0.0.2"); CU_ASSERT(is_valid_ipv4_addr(test_str, 9)); strcpy(test_str, "1.2.3.400"); CU_ASSERT(is_valid_ipv4_addr(test_str, strlen(test_str)) == 0); } DECLARE_UTEST(test_count_characters, "test the count_characters function") { char test_str[32]; strcpy(test_str, "abcd"); CU_ASSERT(count_characters(test_str, 'a', 4) == 1); strcpy(test_str, "aacd"); CU_ASSERT(count_characters(test_str, 'a', 4) == 2); strcpy(test_str, "a,b,c,d,"); CU_ASSERT(count_characters(test_str, ',', 4) == 2); strcpy(test_str, "a,b,c,d,"); CU_ASSERT(count_characters(test_str, ',', 8) == 4); strcpy(test_str, "aaaa"); CU_ASSERT(count_characters(test_str, 'a', 3) == 3); } int register_utils_test(void) { ts_init(&TEST_SUITE(utils_test), TEST_SUITE_DESCR(utils_test), NULL, NULL); ts_add_utest(&TEST_SUITE(utils_test), UTEST_FCT(test_count_characters), UTEST_DESCR(test_count_characters)); ts_add_utest(&TEST_SUITE(utils_test), UTEST_FCT(test_ipv4_validator), UTEST_DESCR(test_ipv4_validator)); ts_add_utest(&TEST_SUITE(utils_test), UTEST_FCT(test_hostname_validator), UTEST_DESCR(test_hostname_validator)); return register_ts(&TEST_SUITE(utils_test)); } #endif /* LCOV_EXCL_STOP */ /***EOF***/ fwknop-2.6.11/AUTHORS0000664000175000017500000000337314560546213011114 00000000000000Package: fwknop Maintainer: Damien Stuart , Michael Rash Bug reports: dstuart@dstuart.org, mbr@cipherdyne.org License: GPLv2, See the COPYING file Primary authors: Michael Rash - Creator of the fwknop project and wrote the original fwknop Perl implementation with contributions from open source developers. - Continued authorship and maintenance of fwknop code. Damien Stuart - Ported fwknop to C. - libfko, fwknop (client), fwknopd (server) - Continued authorship and maintenance of fwknop code. Significant contributions from individuals are listed in the CREDITS file, and a special thanks is due to: Jonathan Bennett (Major contributor, OpenWRT support, new Android client) Franck Joncourt (Major contributor and Debian package maintainer) Sebastien Jeanquier (Masters thesis analysis of Port Knocking and SPA) Hank Leininger (libfko error code patch, various architecture ideas) Max Kastanas (iPhone and Android clients) Gerry Reno (Android client development) Ozmart (various architecture ideas) Geoff Carstairs (various architecture ideas) Fernando Arnaboldi (vulnerability discovery and responsible disclosure) Sean Greven (FreeBSD port) Vlad Glagolev (OpenBSD port) Blair Zajac (PPC architecture fixes, various architecture ideas) Radostan Riedel (AppArmor policy) Copyright (C) 2009-2015 fwknop developers and contributors. For a full list of contributors, see the file 'CREDITS'. This file 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. fwknop-2.6.11/lib/0000775000175000017500000000000014560546700010665 500000000000000fwknop-2.6.11/lib/fko_utests.c0000664000175000017500000000206314560546213013137 00000000000000/** * \file lib/fko_utests.c * * \brief Main CUnit test function for libfko */ #include "fko.h" #include "fko_util.h" #include "CUnit/Basic.h" /** * Register test suites from FKO files. * * The module should fetch functions according to used modules. All of them follow the same * naming convention. */ static void register_test_suites(void) { register_ts_fko_decode(); register_ts_hmac_test(); register_ts_digest_test(); register_ts_aes_test(); register_utils_test(); register_base64_test(); } /* The main() function for setting up and running the tests. * Returns a CUE_SUCCESS on successful running, another * CUnit error code on failure. */ int main() { /* initialize the CUnit test registry */ if (CUE_SUCCESS != CU_initialize_registry()) return CU_get_error(); /* Register test suites from fko files */ register_test_suites(); /* RUN ALL TESTS USING THE CUNIT BASIC INTERFACE */ CU_basic_set_mode(CU_BRM_VERBOSE); CU_basic_run_tests(); CU_cleanup_registry(); return CU_get_error(); } fwknop-2.6.11/lib/fko_user.h0000664000175000017500000000245714560546213012602 00000000000000/** * \file lib/fko_user.h * * \brief Provide validation functions for SPA messages */ /* Fwknop is developed primarily by the people listed in the file 'AUTHORS'. * Copyright (C) 2009-2015 fwknop developers and contributors. For a full * list of contributors, see the file 'CREDITS'. * * License (GNU General Public License): * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #ifndef FKO_USER_H #define FKO_USER_H 1 /* SPA message format validation functions. */ int validate_username(const char *username); #endif /* FKO_USER_H */ /***EOF***/ fwknop-2.6.11/lib/fko_decode.c0000664000175000017500000005033014560546213013033 00000000000000/** * \file lib/fko_decode.c * * \brief Decode an FKO SPA message after decryption. */ /* Fwknop is developed primarily by the people listed in the file 'AUTHORS'. * Copyright (C) 2009-2015 fwknop developers and contributors. For a full * list of contributors, see the file 'CREDITS'. * * License (GNU General Public License): * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #include "fko_common.h" #include "fko.h" #include "cipher_funcs.h" #include "base64.h" #include "digest.h" #define FIELD_PARSERS 9 /* Char used to separate SPA fields in an SPA packet */ #define SPA_FIELD_SEPARATOR ":" #ifdef HAVE_C_UNIT_TESTS /* LCOV_EXCL_START */ DECLARE_TEST_SUITE(fko_decode, "FKO decode test suite"); #endif /* LCOV_EXCL_STOP */ static int num_fields(char *str) { int i=0; char *tmp = NULL; /* Count the number of remaining SPA packet fields */ for (i=0; i <= MAX_SPA_FIELDS+1; i++) { if ((tmp = strchr(str, ':')) == NULL) break; str = tmp + 1; } return i; } static int last_field(char *str) { int i=0, pos_last=0; char *tmp = NULL; /* Count the number of bytes to the last ':' char */ for (i=0; i <= MAX_SPA_FIELDS+1; i++) { if ((tmp = strchr(str, ':')) == NULL) break; pos_last += (tmp - str) + 1; str = tmp + 1; } return pos_last; } static int verify_digest(char *tbuf, int t_size, fko_ctx_t ctx) { #if AFL_FUZZING return FKO_SUCCESS; #endif switch(ctx->digest_type) { case FKO_DIGEST_MD5: md5_base64(tbuf, (unsigned char*)ctx->encoded_msg, ctx->encoded_msg_len); break; case FKO_DIGEST_SHA1: sha1_base64(tbuf, (unsigned char*)ctx->encoded_msg, ctx->encoded_msg_len); break; case FKO_DIGEST_SHA256: sha256_base64(tbuf, (unsigned char*)ctx->encoded_msg, ctx->encoded_msg_len); break; case FKO_DIGEST_SHA384: sha384_base64(tbuf, (unsigned char*)ctx->encoded_msg, ctx->encoded_msg_len); break; case FKO_DIGEST_SHA512: sha512_base64(tbuf, (unsigned char*)ctx->encoded_msg, ctx->encoded_msg_len); break; /* Note that we check SHA3_256 and SHA3_512 below because the * digest lengths for these are the same as SHA256 and SHA512 * respectively, and setting the digest type for an incoming * decrypted SPA packet is done initially by looking at the * length. */ default: /* Invalid or unsupported digest */ return(FKO_ERROR_INVALID_DIGEST_TYPE); } /* We give up here if the computed digest does not match the * digest in the message data. */ if(constant_runtime_cmp(ctx->digest, tbuf, t_size) != 0) { /* Could potentially also have been SHA3_256 or SHA3_512 */ if(ctx->digest_type == FKO_DIGEST_SHA256) { memset(tbuf, 0, FKO_ENCODE_TMP_BUF_SIZE); sha3_256_base64(tbuf, (unsigned char*)ctx->encoded_msg, ctx->encoded_msg_len); if(constant_runtime_cmp(ctx->digest, tbuf, t_size) != 0) { return(FKO_ERROR_DIGEST_VERIFICATION_FAILED); } else { ctx->digest_type = FKO_DIGEST_SHA3_256; ctx->digest_len = SHA3_256_B64_LEN; } } else if(ctx->digest_type == FKO_DIGEST_SHA512) { memset(tbuf, 0, FKO_ENCODE_TMP_BUF_SIZE); sha3_512_base64(tbuf, (unsigned char*)ctx->encoded_msg, ctx->encoded_msg_len); if(constant_runtime_cmp(ctx->digest, tbuf, t_size) != 0) { return(FKO_ERROR_DIGEST_VERIFICATION_FAILED); } else { ctx->digest_type = FKO_DIGEST_SHA3_512; ctx->digest_len = SHA3_512_B64_LEN; } } else return(FKO_ERROR_DIGEST_VERIFICATION_FAILED); } return FKO_SUCCESS; } static int is_valid_digest_len(int t_size, fko_ctx_t ctx) { switch(t_size) { case MD5_B64_LEN: ctx->digest_type = FKO_DIGEST_MD5; ctx->digest_len = MD5_B64_LEN; break; case SHA1_B64_LEN: ctx->digest_type = FKO_DIGEST_SHA1; ctx->digest_len = SHA1_B64_LEN; break; /* Could also match SHA3_256_B64_LEN, handled in verify_digest() */ case SHA256_B64_LEN: ctx->digest_type = FKO_DIGEST_SHA256; ctx->digest_len = SHA256_B64_LEN; break; case SHA384_B64_LEN: ctx->digest_type = FKO_DIGEST_SHA384; ctx->digest_len = SHA384_B64_LEN; break; /* Could also match SHA3_512_B64_LEN, handled in verify_digest() */ case SHA512_B64_LEN: ctx->digest_type = FKO_DIGEST_SHA512; ctx->digest_len = SHA512_B64_LEN; break; default: /* Invalid or unsupported digest */ return(FKO_ERROR_INVALID_DIGEST_TYPE); } if (ctx->encoded_msg_len - t_size < 0) return(FKO_ERROR_INVALID_DATA_DECODE_ENC_MSG_LEN_MT_T_SIZE); return FKO_SUCCESS; } static int parse_msg(char *tbuf, char **ndx, int *t_size, fko_ctx_t ctx) { if((*t_size = strcspn(*ndx, ":")) < 1) return(FKO_ERROR_INVALID_DATA_DECODE_MESSAGE_MISSING); if (*t_size > MAX_SPA_MESSAGE_SIZE) return(FKO_ERROR_INVALID_DATA_DECODE_MESSAGE_TOOBIG); strlcpy(tbuf, *ndx, *t_size+1); if(ctx->message != NULL) free(ctx->message); ctx->message = calloc(1, *t_size+1); /* Yes, more than we need */ if(ctx->message == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); if(b64_decode(tbuf, (unsigned char*)ctx->message) < 0) return(FKO_ERROR_INVALID_DATA_DECODE_MESSAGE_DECODEFAIL); if(ctx->message_type == FKO_COMMAND_MSG) { /* Require a message similar to: 1.2.3.4, */ if(validate_cmd_msg(ctx->message) != FKO_SUCCESS) { return(FKO_ERROR_INVALID_DATA_DECODE_MESSAGE_VALIDFAIL); } } else { /* Require a message similar to: 1.2.3.4,tcp/22 */ if(validate_access_msg(ctx->message) != FKO_SUCCESS) { return(FKO_ERROR_INVALID_DATA_DECODE_ACCESS_VALIDFAIL); } } *ndx += *t_size + 1; return FKO_SUCCESS; } static int parse_nat_msg(char *tbuf, char **ndx, int *t_size, fko_ctx_t ctx) { if( ctx->message_type == FKO_NAT_ACCESS_MSG || ctx->message_type == FKO_LOCAL_NAT_ACCESS_MSG || ctx->message_type == FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG || ctx->message_type == FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG) { if((*t_size = strcspn(*ndx, ":")) < 1) return(FKO_ERROR_INVALID_DATA_DECODE_NATACCESS_MISSING); if (*t_size > MAX_SPA_MESSAGE_SIZE) return(FKO_ERROR_INVALID_DATA_DECODE_NATACCESS_TOOBIG); strlcpy(tbuf, *ndx, *t_size+1); if(ctx->nat_access != NULL) free(ctx->nat_access); ctx->nat_access = calloc(1, *t_size+1); /* Yes, more than we need */ if(ctx->nat_access == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); if(b64_decode(tbuf, (unsigned char*)ctx->nat_access) < 0) return(FKO_ERROR_INVALID_DATA_DECODE_NATACCESS_DECODEFAIL); if(validate_nat_access_msg(ctx->nat_access) != FKO_SUCCESS) return(FKO_ERROR_INVALID_DATA_DECODE_NATACCESS_VALIDFAIL); *ndx += *t_size + 1; } return FKO_SUCCESS; } static int parse_server_auth(char *tbuf, char **ndx, int *t_size, fko_ctx_t ctx) { if((*t_size = strlen(*ndx)) > 0) { if (*t_size > MAX_SPA_MESSAGE_SIZE) { return(FKO_ERROR_INVALID_DATA_DECODE_SRVAUTH_MISSING); } } else return FKO_SUCCESS; if( ctx->message_type == FKO_CLIENT_TIMEOUT_ACCESS_MSG || ctx->message_type == FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG || ctx->message_type == FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG) { /* If we are here then we may still have a server_auth string, * or a timeout, or both. So we look for a ':' delimiter. If * it is there we have both, if not we check the message_type * again. */ if(strchr(*ndx, ':')) { *t_size = strcspn(*ndx, ":"); if (*t_size > MAX_SPA_MESSAGE_SIZE) return(FKO_ERROR_INVALID_DATA_DECODE_EXTRA_TOOBIG); strlcpy(tbuf, *ndx, *t_size+1); if(ctx->server_auth != NULL) free(ctx->server_auth); ctx->server_auth = calloc(1, *t_size+1); /* Yes, more than we need */ if(ctx->server_auth == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); if(b64_decode(tbuf, (unsigned char*)ctx->server_auth) < 0) return(FKO_ERROR_INVALID_DATA_DECODE_EXTRA_DECODEFAIL); *ndx += *t_size + 1; } } else { strlcpy(tbuf, *ndx, *t_size+1); if(ctx->server_auth != NULL) free(ctx->server_auth); ctx->server_auth = calloc(1, *t_size+1); /* Yes, more than we need */ if(ctx->server_auth == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); if(b64_decode(tbuf, (unsigned char*)ctx->server_auth) < 0) return(FKO_ERROR_INVALID_DATA_DECODE_SRVAUTH_DECODEFAIL); } return FKO_SUCCESS; } static int parse_client_timeout(char *tbuf, char **ndx, int *t_size, fko_ctx_t ctx) { int is_err; if( ctx->message_type == FKO_CLIENT_TIMEOUT_ACCESS_MSG || ctx->message_type == FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG || ctx->message_type == FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG) { if((*t_size = strlen(*ndx)) < 1) return(FKO_ERROR_INVALID_DATA_DECODE_TIMEOUT_MISSING); if (*t_size > MAX_SPA_MESSAGE_SIZE) return(FKO_ERROR_INVALID_DATA_DECODE_TIMEOUT_TOOBIG); /* Should be a number only. */ if(strspn(*ndx, "0123456789") != *t_size) return(FKO_ERROR_INVALID_DATA_DECODE_TIMEOUT_VALIDFAIL); ctx->client_timeout = (unsigned int) strtol_wrapper(*ndx, 0, (2 << 15), NO_EXIT_UPON_ERR, &is_err); if(is_err != FKO_SUCCESS) return(FKO_ERROR_INVALID_DATA_DECODE_TIMEOUT_DECODEFAIL); } return FKO_SUCCESS; } static int parse_msg_type(char *tbuf, char **ndx, int *t_size, fko_ctx_t ctx) { int is_err, remaining_fields; if((*t_size = strcspn(*ndx, ":")) < 1) return(FKO_ERROR_INVALID_DATA_DECODE_MSGTYPE_MISSING); if(*t_size > MAX_SPA_MESSAGE_TYPE_SIZE) return(FKO_ERROR_INVALID_DATA_DECODE_MSGTYPE_TOOBIG); strlcpy(tbuf, *ndx, *t_size+1); ctx->message_type = strtol_wrapper(tbuf, 0, FKO_LAST_MSG_TYPE-1, NO_EXIT_UPON_ERR, &is_err); if(is_err != FKO_SUCCESS) return(FKO_ERROR_INVALID_DATA_DECODE_MSGTYPE_DECODEFAIL); /* Now that we have a valid type, ensure that the total * number of SPA fields is also valid for the type */ remaining_fields = num_fields(*ndx); switch(ctx->message_type) { /* optional server_auth + digest */ case FKO_COMMAND_MSG: case FKO_ACCESS_MSG: if(remaining_fields > 2) return FKO_ERROR_INVALID_DATA_DECODE_WRONG_NUM_FIELDS; break; /* nat or client timeout + optional server_auth + digest */ case FKO_NAT_ACCESS_MSG: case FKO_LOCAL_NAT_ACCESS_MSG: case FKO_CLIENT_TIMEOUT_ACCESS_MSG: if(remaining_fields > 3) return FKO_ERROR_INVALID_DATA_DECODE_WRONG_NUM_FIELDS; break; /* client timeout + nat + optional server_auth + digest */ case FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG: case FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG: if(remaining_fields > 4) return FKO_ERROR_INVALID_DATA_DECODE_WRONG_NUM_FIELDS; break; default: /* Should not reach here */ return(FKO_ERROR_INVALID_DATA_DECODE_MSGTYPE_DECODEFAIL); } *ndx += *t_size + 1; return FKO_SUCCESS; } static int parse_version(char *tbuf, char **ndx, int *t_size, fko_ctx_t ctx) { if((*t_size = strcspn(*ndx, ":")) < 1) return(FKO_ERROR_INVALID_DATA_DECODE_VERSION_MISSING); if (*t_size > MAX_SPA_VERSION_SIZE) return(FKO_ERROR_INVALID_DATA_DECODE_VERSION_TOOBIG); if(ctx->version != NULL) free(ctx->version); ctx->version = calloc(1, *t_size+1); if(ctx->version == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); strlcpy(ctx->version, *ndx, *t_size+1); *ndx += *t_size + 1; return FKO_SUCCESS; } static int parse_timestamp(char *tbuf, char **ndx, int *t_size, fko_ctx_t ctx) { int is_err; if((*t_size = strcspn(*ndx, ":")) < 1) return(FKO_ERROR_INVALID_DATA_DECODE_TIMESTAMP_MISSING); if (*t_size > MAX_SPA_TIMESTAMP_SIZE) return(FKO_ERROR_INVALID_DATA_DECODE_TIMESTAMP_TOOBIG); strlcpy(tbuf, *ndx, *t_size+1); ctx->timestamp = (unsigned int) strtol_wrapper(tbuf, 0, -1, NO_EXIT_UPON_ERR, &is_err); if(is_err != FKO_SUCCESS) return(FKO_ERROR_INVALID_DATA_DECODE_TIMESTAMP_DECODEFAIL); *ndx += *t_size + 1; return FKO_SUCCESS; } static int parse_username(char *tbuf, char **ndx, int *t_size, fko_ctx_t ctx) { if((*t_size = strcspn(*ndx, ":")) < 1) return(FKO_ERROR_INVALID_DATA_DECODE_USERNAME_MISSING); if (*t_size > MAX_SPA_USERNAME_SIZE) return(FKO_ERROR_INVALID_DATA_DECODE_USERNAME_TOOBIG); strlcpy(tbuf, *ndx, *t_size+1); if(ctx->username != NULL) free(ctx->username); ctx->username = calloc(1, *t_size+1); /* Yes, more than we need */ if(ctx->username == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); if(b64_decode(tbuf, (unsigned char*)ctx->username) < 0) return(FKO_ERROR_INVALID_DATA_DECODE_USERNAME_DECODEFAIL); if(validate_username(ctx->username) != FKO_SUCCESS) return(FKO_ERROR_INVALID_DATA_DECODE_USERNAME_VALIDFAIL); *ndx += *t_size + 1; return FKO_SUCCESS; } static int parse_rand_val(char *tbuf, char **ndx, int *t_size, fko_ctx_t ctx) { if((*t_size = strcspn(*ndx, ":")) < FKO_RAND_VAL_SIZE) return(FKO_ERROR_INVALID_DATA_DECODE_RAND_MISSING); if(ctx->rand_val != NULL) free(ctx->rand_val); ctx->rand_val = calloc(1, FKO_RAND_VAL_SIZE+1); if(ctx->rand_val == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); ctx->rand_val = strncpy(ctx->rand_val, *ndx, FKO_RAND_VAL_SIZE); *ndx += *t_size + 1; return FKO_SUCCESS; } /* Decode the encoded SPA data. */ int fko_decode_spa_data(fko_ctx_t ctx) { char *tbuf, *ndx; int t_size, i, res; /* Array of function pointers to SPA field parsing functions */ int (*field_parser[FIELD_PARSERS])(char *tbuf, char **ndx, int *t_size, fko_ctx_t ctx) = { parse_rand_val, /* Extract random value */ parse_username, /* Extract username */ parse_timestamp, /* Client timestamp */ parse_version, /* SPA version */ parse_msg_type, /* SPA msg type */ parse_msg, /* SPA msg string */ parse_nat_msg, /* SPA NAT msg string */ parse_server_auth, /* optional server authentication method */ parse_client_timeout /* client defined timeout */ }; if (! is_valid_encoded_msg_len(ctx->encoded_msg_len)) return(FKO_ERROR_INVALID_DATA_DECODE_MSGLEN_VALIDFAIL); /* Make sure there are no non-ascii printable chars */ for (i=0; i < (int)strnlen(ctx->encoded_msg, MAX_SPA_ENCODED_MSG_SIZE); i++) if(isprint((int)(unsigned char)ctx->encoded_msg[i]) == 0) return(FKO_ERROR_INVALID_DATA_DECODE_NON_ASCII); /* Make sure there are enough fields in the SPA packet * delimited with ':' chars */ ndx = ctx->encoded_msg; if (num_fields(ndx) < MIN_SPA_FIELDS) return(FKO_ERROR_INVALID_DATA_DECODE_LT_MIN_FIELDS); ndx += last_field(ndx); t_size = strnlen(ndx, SHA512_B64_LEN+1); /* Validate digest length */ res = is_valid_digest_len(t_size, ctx); if(res != FKO_SUCCESS) return res; if(ctx->digest != NULL) free(ctx->digest); /* Copy the digest into the context and terminate the encoded data * at that point so the original digest is not part of the * encoded string. */ ctx->digest = strdup(ndx); if(ctx->digest == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); /* Chop the digest off of the encoded_msg bucket... */ bzero((ndx-1), t_size); ctx->encoded_msg_len -= t_size+1; /* Make a tmp bucket for processing base64 encoded data and * other general use. */ tbuf = calloc(1, FKO_ENCODE_TMP_BUF_SIZE); if(tbuf == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); /* Can now verify the digest. */ res = verify_digest(tbuf, t_size, ctx); if(res != FKO_SUCCESS) { free(tbuf); return(FKO_ERROR_DIGEST_VERIFICATION_FAILED); } /* Now we will work through the encoded data and extract (and base64- * decode where necessary), the SPA data fields and populate the context. */ ndx = ctx->encoded_msg; for (i=0; i < FIELD_PARSERS; i++) { res = (*field_parser[i])(tbuf, &ndx, &t_size, ctx); if(res != FKO_SUCCESS) { free(tbuf); return res; } } /* Done with the tmp buffer. */ free(tbuf); /* Call the context initialized. */ ctx->initval = FKO_CTX_INITIALIZED; FKO_SET_CTX_INITIALIZED(ctx); return(FKO_SUCCESS); } #ifdef HAVE_C_UNIT_TESTS /* LCOV_EXCL_START */ DECLARE_UTEST(num_fields, "Count the number of SPA fields in a SPA packet") { int ix_field=0; char spa_packet[(MAX_SPA_FIELDS+1)*3]; /* Zeroing the spa packet */ memset(spa_packet, 0, sizeof(spa_packet)); /* Check we are able to count the number of SPA fields */ for(ix_field=0 ; ix_field<=MAX_SPA_FIELDS+2 ; ix_field++) { strcat(spa_packet, "x"); CU_ASSERT(num_fields(spa_packet) == ix_field); strcat(spa_packet, SPA_FIELD_SEPARATOR); } /* Check for possible overflow */ strcat(spa_packet, "x"); CU_ASSERT(num_fields(spa_packet) == MAX_SPA_FIELDS + 2); strcat(spa_packet, "x"); strcat(spa_packet, SPA_FIELD_SEPARATOR); CU_ASSERT(num_fields(spa_packet) == MAX_SPA_FIELDS + 2); } DECLARE_UTEST(last_field, "Count the number of bytes to the last :") { int ix_field; char spa_packet[(MAX_SPA_FIELDS+1)*3]; /* Zeroing the spa packet */ memset(spa_packet, 0, sizeof(spa_packet)); /* Check for a valid count when the number of field is less than MAX_SPA_FIELDS */ CU_ASSERT(last_field("a:") == 2); CU_ASSERT(last_field("ab:abc:") == 7); CU_ASSERT(last_field("abc:abcd:") == 9); CU_ASSERT(last_field("abc:abcd:abc") == 9); /* */ for(ix_field=0 ; ix_field<=MAX_SPA_FIELDS+2 ; ix_field++) { strcat(spa_packet, "x"); strcat(spa_packet, SPA_FIELD_SEPARATOR); } CU_ASSERT(last_field(spa_packet) == ((MAX_SPA_FIELDS+2)*2)); } int register_ts_fko_decode(void) { ts_init(&TEST_SUITE(fko_decode), TEST_SUITE_DESCR(fko_decode), NULL, NULL); ts_add_utest(&TEST_SUITE(fko_decode), UTEST_FCT(num_fields), UTEST_DESCR(num_fields)); ts_add_utest(&TEST_SUITE(fko_decode), UTEST_FCT(last_field), UTEST_DESCR(last_field)); return register_ts(&TEST_SUITE(fko_decode)); } #endif /* HAVE_C_UNIT_TESTS */ /* LCOV_EXCL_STOP */ /***EOF***/ fwknop-2.6.11/lib/sha1.c0000664000175000017500000002324214560546213011607 00000000000000/** * \file lib/sha1.c * * \brief Implementation of the SHA1 message-digest algorithm for libfwknop. */ /* NIST Secure Hash Algorithm * Heavily modified by Uwe Hollerbach * from Peter C. Gutmann's implementation as found in * Applied Cryptography by Bruce Schneier * Further modifications to include the "UNRAVEL" stuff, below * * This code is in the public domain * ***************************************************************************** */ #include "sha1.h" #include "fko_common.h" /* SHA f()-functions */ #define f1(x,y,z) ((x & y) | (~x & z)) #define f2(x,y,z) (x ^ y ^ z) #define f3(x,y,z) ((x & y) | (x & z) | (y & z)) #define f4(x,y,z) (x ^ y ^ z) /* SHA constants */ #define CONST1 0x5a827999L #define CONST2 0x6ed9eba1L #define CONST3 0x8f1bbcdcL #define CONST4 0xca62c1d6L /* truncate to 32 bits -- should be a null op on 32-bit machines */ #define T32(x) ((x) & 0xffffffffL) /* 32-bit rotate */ #define R32(x,n) T32(((x << n) | (x >> (32 - n)))) /* the generic case, for when the overall rotation is not unraveled */ #define FG(n) \ T = T32(R32(A,5) + f##n(B,C,D) + E + *WP++ + CONST##n); \ E = D; D = C; C = R32(B,30); B = A; A = T /* specific cases, for when the overall rotation is unraveled */ #define FA(n) \ T = T32(R32(A,5) + f##n(B,C,D) + E + *WP++ + CONST##n); B = R32(B,30) #define FB(n) \ E = T32(R32(T,5) + f##n(A,B,C) + D + *WP++ + CONST##n); A = R32(A,30) #define FC(n) \ D = T32(R32(E,5) + f##n(T,A,B) + C + *WP++ + CONST##n); T = R32(T,30) #define FD(n) \ C = T32(R32(D,5) + f##n(E,T,A) + B + *WP++ + CONST##n); E = R32(E,30) #define FE(n) \ B = T32(R32(C,5) + f##n(D,E,T) + A + *WP++ + CONST##n); D = R32(D,30) #define FT(n) \ A = T32(R32(B,5) + f##n(C,D,E) + T + *WP++ + CONST##n); C = R32(C,30) void sha1_transform(SHA1_INFO *sha1_info) { int i; uint8_t *dp; uint32_t T, A, B, C, D, E, W[80], *WP; dp = sha1_info->data; #undef SWAP_DONE #if BYTEORDER == 1234 #define SWAP_DONE for (i = 0; i < 16; ++i) { T = *((uint32_t *) dp); dp += 4; W[i] = ((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) | ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff); } #endif #if BYTEORDER == 4321 #define SWAP_DONE for (i = 0; i < 16; ++i) { T = *((uint32_t *) dp); dp += 4; W[i] = TRUNC32(T); } #endif #if BYTEORDER == 12345678 #define SWAP_DONE for (i = 0; i < 16; i += 2) { T = *((uint32_t *) dp); dp += 8; W[i] = ((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) | ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff); T >>= 32; W[i+1] = ((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) | ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff); } #endif #if BYTEORDER == 87654321 #define SWAP_DONE for (i = 0; i < 16; i += 2) { T = *((uint32_t *) dp); dp += 8; W[i] = TRUNC32(T >> 32); W[i+1] = TRUNC32(T); } #endif #ifndef SWAP_DONE #define SWAP_DONE for (i = 0; i < 16; ++i) { T = *((uint32_t *) dp); dp += 4; W[i] = TRUNC32(T); } #ifndef WIN32 #warning Undetermined or unsupported Byte Order... We will try LITTLE_ENDIAN #endif #endif /* SWAP_DONE */ for (i = 16; i < 80; ++i) { W[i] = W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16]; W[i] = R32(W[i], 1); } A = sha1_info->digest[0]; B = sha1_info->digest[1]; C = sha1_info->digest[2]; D = sha1_info->digest[3]; E = sha1_info->digest[4]; WP = W; #ifdef UNRAVEL FA(1); FB(1); FC(1); FD(1); FE(1); FT(1); FA(1); FB(1); FC(1); FD(1); FE(1); FT(1); FA(1); FB(1); FC(1); FD(1); FE(1); FT(1); FA(1); FB(1); FC(2); FD(2); FE(2); FT(2); FA(2); FB(2); FC(2); FD(2); FE(2); FT(2); FA(2); FB(2); FC(2); FD(2); FE(2); FT(2); FA(2); FB(2); FC(2); FD(2); FE(3); FT(3); FA(3); FB(3); FC(3); FD(3); FE(3); FT(3); FA(3); FB(3); FC(3); FD(3); FE(3); FT(3); FA(3); FB(3); FC(3); FD(3); FE(3); FT(3); FA(4); FB(4); FC(4); FD(4); FE(4); FT(4); FA(4); FB(4); FC(4); FD(4); FE(4); FT(4); FA(4); FB(4); FC(4); FD(4); FE(4); FT(4); FA(4); FB(4); sha1_info->digest[0] = T32(sha1_info->digest[0] + E); sha1_info->digest[1] = T32(sha1_info->digest[1] + T); sha1_info->digest[2] = T32(sha1_info->digest[2] + A); sha1_info->digest[3] = T32(sha1_info->digest[3] + B); sha1_info->digest[4] = T32(sha1_info->digest[4] + C); #else /* !UNRAVEL */ #ifdef UNROLL_LOOPS FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); #else /* !UNROLL_LOOPS */ for (i = 0; i < 20; ++i) { FG(1); } for (i = 20; i < 40; ++i) { FG(2); } for (i = 40; i < 60; ++i) { FG(3); } for (i = 60; i < 80; ++i) { FG(4); } #endif /* !UNROLL_LOOPS */ sha1_info->digest[0] = T32(sha1_info->digest[0] + A); sha1_info->digest[1] = T32(sha1_info->digest[1] + B); sha1_info->digest[2] = T32(sha1_info->digest[2] + C); sha1_info->digest[3] = T32(sha1_info->digest[3] + D); sha1_info->digest[4] = T32(sha1_info->digest[4] + E); #endif /* !UNRAVEL */ } /* initialize the SHA digest */ void sha1_init(SHA1_INFO *sha1_info) { sha1_info->digest[0] = 0x67452301L; sha1_info->digest[1] = 0xefcdab89L; sha1_info->digest[2] = 0x98badcfeL; sha1_info->digest[3] = 0x10325476L; sha1_info->digest[4] = 0xc3d2e1f0L; sha1_info->count_lo = 0L; sha1_info->count_hi = 0L; sha1_info->local = 0; } /* update the SHA digest */ void sha1_update(SHA1_INFO *sha1_info, uint8_t *buffer, int count) { int i; uint32_t clo; clo = T32(sha1_info->count_lo + ((uint32_t) count << 3)); if (clo < sha1_info->count_lo) { ++sha1_info->count_hi; } sha1_info->count_lo = clo; sha1_info->count_hi += (uint32_t) count >> 29; if (sha1_info->local) { i = SHA1_BLOCKSIZE - sha1_info->local; if (i > count) { i = count; } memcpy(((uint8_t *) sha1_info->data) + sha1_info->local, buffer, i); count -= i; buffer += i; sha1_info->local += i; if (sha1_info->local == SHA1_BLOCKSIZE) { sha1_transform(sha1_info); } else { return; } } while (count >= SHA1_BLOCKSIZE) { memcpy(sha1_info->data, buffer, SHA1_BLOCKSIZE); buffer += SHA1_BLOCKSIZE; count -= SHA1_BLOCKSIZE; sha1_transform(sha1_info); } memcpy(sha1_info->data, buffer, count); sha1_info->local = count; } void sha1_transform_and_copy(unsigned char digest[20], SHA1_INFO *sha1_info) { sha1_transform(sha1_info); digest[ 0] = (unsigned char) ((sha1_info->digest[0] >> 24) & 0xff); digest[ 1] = (unsigned char) ((sha1_info->digest[0] >> 16) & 0xff); digest[ 2] = (unsigned char) ((sha1_info->digest[0] >> 8) & 0xff); digest[ 3] = (unsigned char) ((sha1_info->digest[0] ) & 0xff); digest[ 4] = (unsigned char) ((sha1_info->digest[1] >> 24) & 0xff); digest[ 5] = (unsigned char) ((sha1_info->digest[1] >> 16) & 0xff); digest[ 6] = (unsigned char) ((sha1_info->digest[1] >> 8) & 0xff); digest[ 7] = (unsigned char) ((sha1_info->digest[1] ) & 0xff); digest[ 8] = (unsigned char) ((sha1_info->digest[2] >> 24) & 0xff); digest[ 9] = (unsigned char) ((sha1_info->digest[2] >> 16) & 0xff); digest[10] = (unsigned char) ((sha1_info->digest[2] >> 8) & 0xff); digest[11] = (unsigned char) ((sha1_info->digest[2] ) & 0xff); digest[12] = (unsigned char) ((sha1_info->digest[3] >> 24) & 0xff); digest[13] = (unsigned char) ((sha1_info->digest[3] >> 16) & 0xff); digest[14] = (unsigned char) ((sha1_info->digest[3] >> 8) & 0xff); digest[15] = (unsigned char) ((sha1_info->digest[3] ) & 0xff); digest[16] = (unsigned char) ((sha1_info->digest[4] >> 24) & 0xff); digest[17] = (unsigned char) ((sha1_info->digest[4] >> 16) & 0xff); digest[18] = (unsigned char) ((sha1_info->digest[4] >> 8) & 0xff); digest[19] = (unsigned char) ((sha1_info->digest[4] ) & 0xff); } /* finish computing the SHA digest */ void sha1_final(uint8_t digest[20], SHA1_INFO *sha1_info) { int count; uint32_t lo_bit_count, hi_bit_count; lo_bit_count = sha1_info->count_lo; hi_bit_count = sha1_info->count_hi; count = (int) ((lo_bit_count >> 3) & 0x3f); ((uint8_t *) sha1_info->data)[count++] = 0x80; if (count > SHA1_BLOCKSIZE - 8) { memset(((uint8_t *) sha1_info->data) + count, 0, SHA1_BLOCKSIZE - count); sha1_transform(sha1_info); memset((uint8_t *) sha1_info->data, 0, SHA1_BLOCKSIZE - 8); } else { memset(((uint8_t *) sha1_info->data) + count, 0, SHA1_BLOCKSIZE - 8 - count); } sha1_info->data[56] = (uint8_t)((hi_bit_count >> 24) & 0xff); sha1_info->data[57] = (uint8_t)((hi_bit_count >> 16) & 0xff); sha1_info->data[58] = (uint8_t)((hi_bit_count >> 8) & 0xff); sha1_info->data[59] = (uint8_t)((hi_bit_count >> 0) & 0xff); sha1_info->data[60] = (uint8_t)((lo_bit_count >> 24) & 0xff); sha1_info->data[61] = (uint8_t)((lo_bit_count >> 16) & 0xff); sha1_info->data[62] = (uint8_t)((lo_bit_count >> 8) & 0xff); sha1_info->data[63] = (uint8_t)((lo_bit_count >> 0) & 0xff); sha1_transform_and_copy(digest, sha1_info); } /***EOF***/ fwknop-2.6.11/lib/cipher_funcs.c0000664000175000017500000005715214560546213013432 00000000000000/** * \file lib/cipher_funcs.c * * \brief Cipher functions used by fwknop */ /* Fwknop is developed primarily by the people listed in the file 'AUTHORS'. * Copyright (C) 2009-2015 fwknop developers and contributors. For a full * list of contributors, see the file 'CREDITS'. * * License (GNU General Public License): * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #include #include #ifdef WIN32 #include #include #include #else #include #endif #include "fko_common.h" #include "cipher_funcs.h" #include "digest.h" #ifndef WIN32 #ifndef RAND_FILE #define RAND_FILE "/dev/urandom" #endif #endif #ifdef HAVE_C_UNIT_TESTS /* LCOV_EXCL_START */ DECLARE_TEST_SUITE(digest_test, "Cipher functions test suite"); #endif /* LCOV_EXCL_STOP */ /* Get random data. */ void get_random_data(unsigned char *data, const size_t len) { uint32_t i; #ifdef WIN32 int rnum; struct _timeb tb; _ftime_s(&tb); srand((uint32_t)(tb.time*1000)+tb.millitm); for(i=0; isalt, (data+SALT_LEN), SALT_LEN); } else { /* Generate a random 8-byte salt. */ get_random_data(ctx->salt, SALT_LEN); } /* Now generate the key and initialization vector. * (again it is the perl Crypt::CBC way, with a touch of * fwknop). */ memcpy(tmp_buf+MD5_DIGEST_LEN, pw_buf, final_key_len); memcpy(tmp_buf+MD5_DIGEST_LEN+final_key_len, ctx->salt, SALT_LEN); while(kiv_len < sizeof(kiv_buf)) { if(kiv_len == 0) md5(md5_buf, tmp_buf+MD5_DIGEST_LEN, final_key_len+SALT_LEN); else md5(md5_buf, tmp_buf, MD5_DIGEST_LEN+final_key_len+SALT_LEN); memcpy(tmp_buf, md5_buf, MD5_DIGEST_LEN); memcpy(kiv_buf + kiv_len, md5_buf, MD5_DIGEST_LEN); kiv_len += MD5_DIGEST_LEN; } memcpy(ctx->key, kiv_buf, RIJNDAEL_MAX_KEYSIZE); memcpy(ctx->iv, kiv_buf+RIJNDAEL_MAX_KEYSIZE, RIJNDAEL_BLOCKSIZE); } /* Initialization entry point. */ static void rijndael_init(RIJNDAEL_context *ctx, const char *key, const int key_len, const unsigned char *data, int encryption_mode) { /* The default is Rijndael in CBC mode */ if(encryption_mode == FKO_ENC_MODE_CBC || encryption_mode == FKO_ENC_MODE_CBC_LEGACY_IV) ctx->mode = MODE_CBC; else if(encryption_mode == FKO_ENC_MODE_CTR) ctx->mode = MODE_CTR; else if(encryption_mode == FKO_ENC_MODE_PCBC) ctx->mode = MODE_PCBC; else if(encryption_mode == FKO_ENC_MODE_OFB) ctx->mode = MODE_OFB; else if(encryption_mode == FKO_ENC_MODE_CFB) ctx->mode = MODE_CFB; else if(encryption_mode == FKO_ENC_MODE_ECB) ctx->mode = MODE_ECB; else /* shouldn't get this far */ ctx->mode = encryption_mode; /* Generate the salt and initialization vector. */ rij_salt_and_iv(ctx, key, key_len, data, encryption_mode); /* Intialize our Rijndael context. */ rijndael_setup(ctx, RIJNDAEL_MAX_KEYSIZE, ctx->key); } /* Take a chunk of data, encrypt it in the same way OpenSSL would * (with a default of AES in CBC mode). */ size_t rij_encrypt(unsigned char *in, size_t in_len, const char *key, const int key_len, unsigned char *out, int encryption_mode) { RIJNDAEL_context ctx; int i, pad_val; unsigned char *ondx = out; rijndael_init(&ctx, key, key_len, NULL, encryption_mode); /* Prepend the salt to the ciphertext... */ memcpy(ondx, "Salted__", SALT_LEN); ondx+=SALT_LEN; memcpy(ondx, ctx.salt, SALT_LEN); ondx+=SALT_LEN; /* Add padding to the original plaintext to ensure that it is a * multiple of the Rijndael block size */ pad_val = RIJNDAEL_BLOCKSIZE - (in_len % RIJNDAEL_BLOCKSIZE); for (i = (int)in_len; i < ((int)in_len+pad_val); i++) in[i] = pad_val; block_encrypt(&ctx, in, in_len+pad_val, ondx, ctx.iv); ondx += in_len+pad_val; zero_buf((char *)ctx.key, RIJNDAEL_MAX_KEYSIZE); zero_buf((char *)ctx.iv, RIJNDAEL_BLOCKSIZE); zero_buf((char *)ctx.salt, SALT_LEN); return(ondx - out); } /* Decrypt the given data. */ size_t rij_decrypt(unsigned char *in, size_t in_len, const char *key, const int key_len, unsigned char *out, int encryption_mode) { RIJNDAEL_context ctx; int i, pad_val, pad_err = 0; unsigned char *pad_s; unsigned char *ondx = out; if(in == NULL || key == NULL || out == NULL) return 0; rijndael_init(&ctx, key, key_len, in, encryption_mode); /* Remove the first block since it contains the salt (it was consumed * by the rijndael_init() function above). */ in_len -= RIJNDAEL_BLOCKSIZE; memmove(in, in+RIJNDAEL_BLOCKSIZE, in_len); block_decrypt(&ctx, in, in_len, out, ctx.iv); ondx += in_len; /* Find and remove padding. */ pad_val = *(ondx-1); if(pad_val >= 0 && pad_val <= RIJNDAEL_BLOCKSIZE) { pad_s = ondx - pad_val; for(i=0; i < (ondx-pad_s); i++) { if(*(pad_s+i) != pad_val) pad_err++; } if(pad_err == 0) ondx -= pad_val; } *ondx = '\0'; zero_buf((char *)ctx.key, RIJNDAEL_MAX_KEYSIZE); zero_buf((char *)ctx.iv, RIJNDAEL_BLOCKSIZE); zero_buf((char *)ctx.salt, SALT_LEN); return(ondx - out); } /* See if we need to add the "Salted__" string to the front of the * encrypted data. */ int add_salted_str(fko_ctx_t ctx) { char *tbuf; #if AFL_FUZZING ctx->added_salted_str = 1; return(FKO_SUCCESS); #endif /* We only add the base64 encoded salt to data that is already base64 * encoded */ if(is_base64((unsigned char *)ctx->encrypted_msg, ctx->encrypted_msg_len) == 0) return(FKO_ERROR_INVALID_DATA_ENCODE_NOTBASE64); if(constant_runtime_cmp(ctx->encrypted_msg, B64_RIJNDAEL_SALT, B64_RIJNDAEL_SALT_STR_LEN) != 0) { /* We need to realloc space for the salt. */ tbuf = realloc(ctx->encrypted_msg, ctx->encrypted_msg_len + B64_RIJNDAEL_SALT_STR_LEN+1); if(tbuf == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); memmove(tbuf+B64_RIJNDAEL_SALT_STR_LEN, tbuf, ctx->encrypted_msg_len); ctx->encrypted_msg = memcpy(tbuf, B64_RIJNDAEL_SALT, B64_RIJNDAEL_SALT_STR_LEN); /* Adjust the encoded msg len for added SALT value and Make sure we * are still a properly NULL-terminated string (Ubuntu was one system * for which this was an issue). */ ctx->encrypted_msg_len += B64_RIJNDAEL_SALT_STR_LEN; tbuf[ctx->encrypted_msg_len] = '\0'; ctx->added_salted_str = 1; } return(FKO_SUCCESS); } /* See if we need to add the "hQ" string to the front of the * encrypted data. */ int add_gpg_prefix(fko_ctx_t ctx) { char *tbuf; /* We only add the base64 encoded salt to data that is already base64 * encoded */ if(is_base64((unsigned char *)ctx->encrypted_msg, ctx->encrypted_msg_len) == 0) return(FKO_ERROR_INVALID_DATA_ENCODE_NOTBASE64); if(constant_runtime_cmp(ctx->encrypted_msg, B64_GPG_PREFIX, B64_GPG_PREFIX_STR_LEN) != 0) { /* We need to realloc space for the prefix. */ tbuf = realloc(ctx->encrypted_msg, ctx->encrypted_msg_len + B64_GPG_PREFIX_STR_LEN+1); if(tbuf == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); memmove(tbuf+B64_GPG_PREFIX_STR_LEN, tbuf, ctx->encrypted_msg_len); ctx->encrypted_msg = memcpy(tbuf, B64_GPG_PREFIX, B64_GPG_PREFIX_STR_LEN); /* Adjust the encoded msg len for added SALT value and Make sure we * are still a properly NULL-terminated string (Ubuntu was one system * for which this was an issue). */ ctx->encrypted_msg_len += B64_GPG_PREFIX_STR_LEN; tbuf[ctx->encrypted_msg_len] = '\0'; ctx->added_gpg_prefix = 1; } return(FKO_SUCCESS); } #ifdef HAVE_C_UNIT_TESTS /* LCOV_EXCL_START */ DECLARE_UTEST(test_aes_ecb_128, "aes ecb 128 test vectors") //http://www.inconteam.com/software-development/41-encryption/55-aes-test-vectors#aes-cbc-128 { RIJNDAEL_context ctx; unsigned char in[1024] = {0}; unsigned char out[1024] = {0}; unsigned char expected_out1[1024] = {0}; unsigned char expected_out2[1024] = {0}; unsigned char expected_out3[1024] = {0}; unsigned char expected_out4[1024] = {0}; memcpy(expected_out1, "\x3a\xd7\x7b\xb4\x0d\x7a\x36\x60\xa8\x9e\xca\xf3\x24\x66\xef\x97", 16); memcpy(expected_out2, "\xf5\xd3\xd5\x85\x03\xb9\x69\x9d\xe7\x85\x89\x5a\x96\xfd\xba\xaf", 16); memcpy(expected_out3, "\x43\xb1\xcd\x7f\x59\x8e\xce\x23\x88\x1b\x00\xe3\xed\x03\x06\x88", 16); memcpy(expected_out4, "\x7b\x0c\x78\x5e\x27\xe8\xad\x3f\x82\x23\x20\x71\x04\x72\x5d\xd4", 16); memcpy(ctx.key, "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", 16); rijndael_setup(&ctx, 16, ctx.key); memcpy(in, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16); rijndael_encrypt(&ctx, in, out); CU_ASSERT(memcmp(out, expected_out1, 16) == 0); memcpy(in, "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 16); rijndael_encrypt(&ctx, in, out); CU_ASSERT(memcmp(out, expected_out2, 16) == 0); memcpy(in, "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", 16); rijndael_encrypt(&ctx, in, out); CU_ASSERT(memcmp(out, expected_out3, 16) == 0); memcpy(in, "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 16); rijndael_encrypt(&ctx, in, out); CU_ASSERT(memcmp(out, expected_out4, 16) == 0); } DECLARE_UTEST(test_aes_ecb_192, "aes ecb 192 test vectors") //http://www.inconteam.com/software-development/41-encryption/55-aes-test-vectors#aes-cbc-128 { RIJNDAEL_context ctx; unsigned char in[1024] = {0}; unsigned char out[1024] = {0}; unsigned char expected_out1[1024] = {0}; unsigned char expected_out2[1024] = {0}; unsigned char expected_out3[1024] = {0}; unsigned char expected_out4[1024] = {0}; memcpy(expected_out1, "\xbd\x33\x4f\x1d\x6e\x45\xf2\x5f\xf7\x12\xa2\x14\x57\x1f\xa5\xcc", 16); memcpy(expected_out2, "\x97\x41\x04\x84\x6d\x0a\xd3\xad\x77\x34\xec\xb3\xec\xee\x4e\xef", 16); memcpy(expected_out3, "\xef\x7a\xfd\x22\x70\xe2\xe6\x0a\xdc\xe0\xba\x2f\xac\xe6\x44\x4e", 16); memcpy(expected_out4, "\x9a\x4b\x41\xba\x73\x8d\x6c\x72\xfb\x16\x69\x16\x03\xc1\x8e\x0e", 16); memcpy(ctx.key, "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b", 24); rijndael_setup(&ctx, 24, ctx.key); memcpy(in, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16); rijndael_encrypt(&ctx, in, out); CU_ASSERT(memcmp(out, expected_out1, 16) == 0); memcpy(in, "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 16); rijndael_encrypt(&ctx, in, out); CU_ASSERT(memcmp(out, expected_out2, 16) == 0); memcpy(in, "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", 16); rijndael_encrypt(&ctx, in, out); CU_ASSERT(memcmp(out, expected_out3, 16) == 0); memcpy(in, "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 16); rijndael_encrypt(&ctx, in, out); CU_ASSERT(memcmp(out, expected_out4, 16) == 0); } DECLARE_UTEST(test_aes_ecb_256, "aes ecb 256 test vectors") //http://www.inconteam.com/software-development/41-encryption/55-aes-test-vectors#aes-cbc-128 { RIJNDAEL_context ctx; unsigned char in[1024] = {0}; unsigned char out[1024] = {0}; unsigned char expected_out1[1024] = {0}; unsigned char expected_out2[1024] = {0}; unsigned char expected_out3[1024] = {0}; unsigned char expected_out4[1024] = {0}; memcpy(expected_out1, "\xf3\xee\xd1\xbd\xb5\xd2\xa0\x3c\x06\x4b\x5a\x7e\x3d\xb1\x81\xf8", 16); memcpy(expected_out2, "\x59\x1c\xcb\x10\xd4\x10\xed\x26\xdc\x5b\xa7\x4a\x31\x36\x28\x70", 16); memcpy(expected_out3, "\xb6\xed\x21\xb9\x9c\xa6\xf4\xf9\xf1\x53\xe7\xb1\xbe\xaf\xed\x1d", 16); memcpy(expected_out4, "\x23\x30\x4b\x7a\x39\xf9\xf3\xff\x06\x7d\x8d\x8f\x9e\x24\xec\xc7", 16); memcpy(ctx.key, "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4", 32); rijndael_setup(&ctx, 32, ctx.key); memcpy(in, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16); rijndael_encrypt(&ctx, in, out); CU_ASSERT(memcmp(out, expected_out1, 16) == 0); memcpy(in, "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 16); rijndael_encrypt(&ctx, in, out); CU_ASSERT(memcmp(out, expected_out2, 16) == 0); memcpy(in, "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", 16); rijndael_encrypt(&ctx, in, out); CU_ASSERT(memcmp(out, expected_out3, 16) == 0); memcpy(in, "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 16); rijndael_encrypt(&ctx, in, out); CU_ASSERT(memcmp(out, expected_out4, 16) == 0); } DECLARE_UTEST(test_aes_cbc_128, "aes cbc 128 test vectors") //http://www.inconteam.com/software-development/41-encryption/55-aes-test-vectors#aes-cbc-128 { //would like to test rij_encrypt against known test vectors, but the method of generating the key and iv make this impossible. RIJNDAEL_context ctx; unsigned char in[1024] = {0}; unsigned char out[1024] = {0}; unsigned char expected_out1[1024] = {0}; unsigned char expected_out2[1024] = {0}; unsigned char expected_out3[1024] = {0}; unsigned char expected_out4[1024] = {0}; memcpy(ctx.key, "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", 16); memcpy(expected_out1, "\x76\x49\xab\xac\x81\x19\xb2\x46\xce\xe9\x8e\x9b\x12\xe9\x19\x7d", 16); memcpy(expected_out2, "\x50\x86\xcb\x9b\x50\x72\x19\xee\x95\xdb\x11\x3a\x91\x76\x78\xb2", 16); memcpy(expected_out3, "\x73\xbe\xd6\xb8\xe3\xc1\x74\x3b\x71\x16\xe6\x9e\x22\x22\x95\x16", 16); memcpy(expected_out4, "\x3f\xf1\xca\xa1\x68\x1f\xac\x09\x12\x0e\xca\x30\x75\x86\xe1\xa7", 16); ctx.mode = MODE_CBC; rijndael_setup(&ctx, 16, ctx.key); memcpy(ctx.iv, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 16); memcpy(in, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16); block_encrypt(&ctx, in, 16, out, ctx.iv); CU_ASSERT(memcmp(out, expected_out1, 16) == 0); memcpy(ctx.iv, "\x76\x49\xAB\xAC\x81\x19\xB2\x46\xCE\xE9\x8E\x9B\x12\xE9\x19\x7D", 16); memcpy(in, "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 16); block_encrypt(&ctx, in, 16, out, ctx.iv); CU_ASSERT(memcmp(out, expected_out2, 16) == 0); memcpy(ctx.iv, "\x50\x86\xCB\x9B\x50\x72\x19\xEE\x95\xDB\x11\x3A\x91\x76\x78\xB2", 16); memcpy(in, "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", 16); block_encrypt(&ctx, in, 16, out, ctx.iv); CU_ASSERT(memcmp(out, expected_out3, 16) == 0); memcpy(ctx.iv, "\x73\xBE\xD6\xB8\xE3\xC1\x74\x3B\x71\x16\xE6\x9E\x22\x22\x95\x16", 16); memcpy(in, "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 16); block_encrypt(&ctx, in, 16, out, ctx.iv); CU_ASSERT(memcmp(out, expected_out4, 16) == 0); } DECLARE_UTEST(test_aes_cbc_192, "aes cbc 192 test vectors") //http://www.inconteam.com/software-development/41-encryption/55-aes-test-vectors#aes-cbc-128 { //would like to test rij_encrypt against known test vectors, but the method of generating the key and iv make this impossible. RIJNDAEL_context ctx; unsigned char in[1024] = {0}; unsigned char out[1024] = {0}; unsigned char expected_out1[1024] = {0}; unsigned char expected_out2[1024] = {0}; unsigned char expected_out3[1024] = {0}; unsigned char expected_out4[1024] = {0}; memcpy(ctx.key, "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b", 24); memcpy(expected_out1, "\x4f\x02\x1d\xb2\x43\xbc\x63\x3d\x71\x78\x18\x3a\x9f\xa0\x71\xe8", 16); memcpy(expected_out2, "\xb4\xd9\xad\xa9\xad\x7d\xed\xf4\xe5\xe7\x38\x76\x3f\x69\x14\x5a", 16); memcpy(expected_out3, "\x57\x1b\x24\x20\x12\xfb\x7a\xe0\x7f\xa9\xba\xac\x3d\xf1\x02\xe0", 16); memcpy(expected_out4, "\x08\xb0\xe2\x79\x88\x59\x88\x81\xd9\x20\xa9\xe6\x4f\x56\x15\xcd", 16); ctx.mode = MODE_CBC; rijndael_setup(&ctx, 24, ctx.key); memcpy(ctx.iv, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 16); memcpy(in, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16); block_encrypt(&ctx, in, 16, out, ctx.iv); CU_ASSERT(memcmp(out, expected_out1, 16) == 0); memcpy(ctx.iv, out, 16); memcpy(in, "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 16); block_encrypt(&ctx, in, 16, out, ctx.iv); CU_ASSERT(memcmp(out, expected_out2, 16) == 0); memcpy(ctx.iv, out, 16); memcpy(in, "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", 16); block_encrypt(&ctx, in, 16, out, ctx.iv); CU_ASSERT(memcmp(out, expected_out3, 16) == 0); memcpy(ctx.iv, out, 16); memcpy(in, "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 16); block_encrypt(&ctx, in, 16, out, ctx.iv); CU_ASSERT(memcmp(out, expected_out4, 16) == 0); } DECLARE_UTEST(test_aes_cbc_256, "aes cbc 256 test vectors") //http://www.inconteam.com/software-development/41-encryption/55-aes-test-vectors#aes-cbc-128 { //would like to test rij_encrypt against known test vectors, but the method of generating the key and iv make this impossible. RIJNDAEL_context ctx; unsigned char in[1024] = {0}; unsigned char out[1024] = {0}; unsigned char expected_out1[1024] = {0}; unsigned char expected_out2[1024] = {0}; unsigned char expected_out3[1024] = {0}; unsigned char expected_out4[1024] = {0}; memcpy(ctx.key, "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4", 32); memcpy(expected_out1, "\xf5\x8c\x4c\x04\xd6\xe5\xf1\xba\x77\x9e\xab\xfb\x5f\x7b\xfb\xd6", 16); memcpy(expected_out2, "\x9c\xfc\x4e\x96\x7e\xdb\x80\x8d\x67\x9f\x77\x7b\xc6\x70\x2c\x7d", 16); memcpy(expected_out3, "\x39\xf2\x33\x69\xa9\xd9\xba\xcf\xa5\x30\xe2\x63\x04\x23\x14\x61", 16); memcpy(expected_out4, "\xb2\xeb\x05\xe2\xc3\x9b\xe9\xfc\xda\x6c\x19\x07\x8c\x6a\x9d\x1b", 16); ctx.mode = MODE_CBC; rijndael_setup(&ctx, 32, ctx.key); memcpy(ctx.iv, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 16); memcpy(in, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16); block_encrypt(&ctx, in, 16, out, ctx.iv); CU_ASSERT(memcmp(out, expected_out1, 16) == 0); memcpy(ctx.iv, out, 16); memcpy(in, "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 16); block_encrypt(&ctx, in, 16, out, ctx.iv); CU_ASSERT(memcmp(out, expected_out2, 16) == 0); memcpy(ctx.iv, out, 16); memcpy(in, "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", 16); block_encrypt(&ctx, in, 16, out, ctx.iv); CU_ASSERT(memcmp(out, expected_out3, 16) == 0); memcpy(ctx.iv, out, 16); memcpy(in, "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 16); block_encrypt(&ctx, in, 16, out, ctx.iv); CU_ASSERT(memcmp(out, expected_out4, 16) == 0); } int register_ts_aes_test(void) { ts_init(&TEST_SUITE(digest_test), TEST_SUITE_DESCR(digest_test), NULL, NULL); ts_add_utest(&TEST_SUITE(digest_test), UTEST_FCT(test_aes_ecb_128), UTEST_DESCR(test_aes_ecb_128)); ts_add_utest(&TEST_SUITE(digest_test), UTEST_FCT(test_aes_ecb_192), UTEST_DESCR(test_aes_ecb_192)); ts_add_utest(&TEST_SUITE(digest_test), UTEST_FCT(test_aes_ecb_256), UTEST_DESCR(test_aes_ecb_256)); ts_add_utest(&TEST_SUITE(digest_test), UTEST_FCT(test_aes_cbc_128), UTEST_DESCR(test_aes_cbc_128)); ts_add_utest(&TEST_SUITE(digest_test), UTEST_FCT(test_aes_cbc_192), UTEST_DESCR(test_aes_cbc_192)); ts_add_utest(&TEST_SUITE(digest_test), UTEST_FCT(test_aes_cbc_256), UTEST_DESCR(test_aes_cbc_256)); return register_ts(&TEST_SUITE(digest_test)); } #endif /* LCOV_EXCL_STOP */ /***EOF***/ fwknop-2.6.11/lib/digest.h0000664000175000017500000000427614560546213012245 00000000000000/** * \file lib/digest.h * * \brief Header for the fwknop digest.c. */ /* Fwknop is developed primarily by the people listed in the file 'AUTHORS'. * Copyright (C) 2009-2015 fwknop developers and contributors. For a full * list of contributors, see the file 'CREDITS'. * * License (GNU General Public License): * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #ifndef DIGEST_H #define DIGEST_H 1 #include "md5.h" #include "sha1.h" #include "sha2.h" #include "sha3.h" /* Size calculation macros */ #define MD_HEX_SIZE(x) x * 2 void md5(unsigned char* out, unsigned char* in, size_t size); void md5_base64(char* out, unsigned char* in, size_t size); void sha1(unsigned char* out, unsigned char* in, size_t size); void sha1_base64(char* out, unsigned char* in, size_t size); void sha256(unsigned char* out, unsigned char* in, size_t size); void sha256_base64(char* out, unsigned char* in, size_t size); void sha384(unsigned char* out, unsigned char* in, size_t size); void sha384_base64(char* out, unsigned char* in, size_t size); void sha512(unsigned char* out, unsigned char* in, size_t size); void sha512_base64(char* out, unsigned char* in, size_t size); void sha3_256(unsigned char* out, unsigned char* in, size_t size); void sha3_256_base64(char* out, unsigned char* in, size_t size); void sha3_512(unsigned char* out, unsigned char* in, size_t size); void sha3_512_base64(char* out, unsigned char* in, size_t size); #endif /* DIGEST_H */ /***EOF***/ fwknop-2.6.11/lib/fko_state.h0000664000175000017500000000654314560546213012744 00000000000000/** * \file lib/fko_state.h * * \brief Defines various states and flags for libfko operations. */ /* Fwknop is developed primarily by the people listed in the file 'AUTHORS'. * Copyright (C) 2009-2015 fwknop developers and contributors. For a full * list of contributors, see the file 'CREDITS'. * * License (GNU General Public License): * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #ifndef FKO_STATE_H #define FKO_STATE_H 1 /* General state flag bit values. */ typedef enum { FKO_CTX_SET = 1, /* Set when ctx is initialized */ FKO_DATA_MODIFIED = 1 << 1, FKO_STATE_RESERVED_2 = 1 << 2, STATE_RESERVED_3 = 1 << 3, STATE_RESERVED_4 = 1 << 4, STATE_RESERVED_5 = 1 << 5, FKO_SPA_MSG_TYPE_MODIFIED = 1 << 6, FKO_CTX_SET_2 = 1 << 7, /* Set when ctx is initialized */ STATE_RESERVED_8 = 1 << 8, STATE_RESERVED_9 = 1 << 9, STATE_RESERVED_10 = 1 << 10, STATE_RESERVED_11 = 1 << 11, FKO_DIGEST_TYPE_MODIFIED = 1 << 12, FKO_ENCRYPT_TYPE_MODIFIED = 1 << 13, STATE_RESERVED_14 = 1 << 14, FKO_BACKWARD_COMPATIBLE = 1 << 15, FKO_ENCRYPT_MODE_MODIFIED = 1 << 16, FKO_HMAC_MODE_MODIFIED = 1 << 17 } fko_state_flags_t; /* This is used in conjunction with the ctx->initial value as a means to * determine if the ctx has been properly initialized. However, this * may not work 100% of the time as it is possible (though not likely) * an ctx may have values that match both the flags and the ctx->initial * value. */ #define FKO_CTX_INITIALIZED (FKO_CTX_SET|FKO_CTX_SET_2) #define FKO_SET_CTX_INITIALIZED(ctx) \ (ctx->state |= (FKO_CTX_INITIALIZED)) #define FKO_CLEAR_CTX_INITIALIZED(ctx) \ (ctx->state &= (0xffff & ~FKO_CTX_INITIALIZED)) /* Consolidate all SPA data modified flags. */ #define FKO_SPA_DATA_MODIFIED ( \ FKO_DATA_MODIFIED | FKO_SPA_MSG_TYPE_MODIFIED \ | FKO_DIGEST_TYPE_MODIFIED | FKO_ENCRYPT_TYPE_MODIFIED ) /* This should return true if any SPA data field has been modifed since the * last encode/encrypt. */ #define FKO_IS_SPA_DATA_MODIFIED(ctx) (ctx->state & FKO_SPA_DATA_MODIFIED) /* Clear all SPA data modified flags. This is normally called after a * successful encode/digest/encryption cycle. */ #define FKO_CLEAR_SPA_DATA_MODIFIED(ctx) \ (ctx->state &= (0xffff & ~FKO_SPA_DATA_MODIFIED)) /* Macros used for determining ctx initialization state. */ #define CTX_INITIALIZED(ctx) (ctx != NULL && ctx->initval == FKO_CTX_INITIALIZED) #endif /* FKO_STATE_H */ /***EOF***/ fwknop-2.6.11/lib/rijndael.h0000664000175000017500000001062614560546213012552 00000000000000/** * \file lib/rijndael.h * * \brief rijndael - An implementation of the Rijndael cipher. */ /* * Copyright (C) 2000, 2001 Rafael R. Sevilla * * Currently maintained by brian d foy, * * License (GNU General Public License): * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ /* * Rijndael is a 128/192/256-bit block cipher that accepts key sizes of * 128, 192, or 256 bits, designed by Joan Daemen and Vincent Rijmen. See * http://www.esat.kuleuven.ac.be/~rijmen/rijndael/ for details. */ #ifndef RIJNDAEL_H #define RIJNDAEL_H 1 #include "common.h" /* Other block sizes and key lengths are possible, but in the context of * the ssh protocols, 256 bits is the default. */ #define RIJNDAEL_BLOCKSIZE 16 #define RIJNDAEL_KEYSIZE 32 #define RIJNDAEL_MIN_KEYSIZE 16 #define RIJNDAEL_MAX_KEYSIZE 32 #define SALT_LEN 8 #define MODE_ECB 1 /* Are we ciphering in ECB mode? */ #define MODE_CBC 2 /* Are we ciphering in CBC mode? */ #define MODE_CFB 3 /* Are we ciphering in 128-bit CFB mode? */ #define MODE_PCBC 4 /* Are we ciphering in PCBC mode? */ #define MODE_OFB 5 /* Are we ciphering in 128-bit OFB mode? */ #define MODE_CTR 6 /* Are we ciphering in counter mode? */ /* Allow keys of size 128 <= bits <= 256 */ typedef struct { uint32_t keys[60]; /* maximum size of key schedule */ uint32_t ikeys[60]; /* inverse key schedule */ int nrounds; /* number of rounds to use for our key size */ int mode; /* encryption mode */ /* Added by DSS */ uint8_t key[RIJNDAEL_MAX_KEYSIZE]; uint8_t iv[RIJNDAEL_BLOCKSIZE]; uint8_t salt[SALT_LEN]; } RIJNDAEL_context; /** * \brief initialize a Rijndael context with key * * This basically performs Rijndael's key scheduling algorithm, as it's the * only initialization required anyhow. The key size is specified in bytes, * but the only valid values are 16 (128 bits), 24 (192 bits), and 32 (256 * bits). If a value other than these three is specified, the key will be * truncated to the closest value less than the key size specified, e.g. * specifying 7 will use only the first 6 bytes of the key given. DO NOT * PASS A VALUE LESS THAN 16 TO KEYSIZE! */ void rijndael_setup(RIJNDAEL_context *ctx, const size_t keysize, const uint8_t *key); /* * rijndael_encrypt() * * Encrypt 16 bytes of data with the Rijndael algorithm. Before this * function can be used, rijndael_setup must be used in order to initialize * Rijndael's key schedule. * * This function always encrypts 16 bytes of plaintext to 16 bytes of * ciphertext. The memory areas of the plaintext and the ciphertext can * overlap. */ void rijndael_encrypt(RIJNDAEL_context *context, const uint8_t *plaintext, uint8_t *ciphertext); /* * rijndael_decrypt() * * Decrypt 16 bytes of data with the Rijndael algorithm. * * Before this function can be used, rijndael_setup() must be used in order * to set up the key schedule required for the decryption algorithm. * * This function always decrypts 16 bytes of ciphertext to 16 bytes of * plaintext. The memory areas of the plaintext and the ciphertext can * overlap. */ void rijndael_decrypt(RIJNDAEL_context *context, const uint8_t *ciphertext, uint8_t *plaintext); /* Encrypt a block of plaintext in a mode specified in the context */ void block_encrypt(RIJNDAEL_context *ctx, uint8_t *input, int inputlen, uint8_t *output, uint8_t *iv); /* Decrypt a block of plaintext in a mode specified in the context */ void block_decrypt(RIJNDAEL_context *ctx, uint8_t *input, int inputlen, uint8_t *output, uint8_t *iv); #endif /* RIJNDAEL_H */ fwknop-2.6.11/lib/digest.c0000664000175000017500000005131014560546213012227 00000000000000/** * \file lib/digest.c * * \brief Roll-up of the digests used by fwknop. */ /* Fwknop is developed primarily by the people listed in the file 'AUTHORS'. * Copyright (C) 2009-2015 fwknop developers and contributors. For a full * list of contributors, see the file 'CREDITS'. * * License (GNU General Public License): * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA */ #include "fko_common.h" #include "digest.h" #include "base64.h" #ifdef HAVE_C_UNIT_TESTS /* LCOV_EXCL_START */ DECLARE_TEST_SUITE(digest_test, "digest functions test suite"); #endif /* LCOV_EXCL_STOP */ /* Compute MD5 hash on in and store result in out. */ void md5(unsigned char *out, unsigned char *in, size_t size) { MD5Context ctx; MD5Init(&ctx); MD5Update(&ctx, (unsigned char*)in, size); MD5Final(out, &ctx); } /* Compute MD5 hash on in and store the base64 string result in out. */ void md5_base64(char *out, unsigned char *in, size_t size) { uint8_t md[MD5_DIGEST_LEN]; md5(md, in, size); b64_encode(md, out, MD5_DIGEST_LEN); strip_b64_eq(out); } /* Compute SHA1 hash on in and store result in out. */ void sha1(unsigned char *out, unsigned char *in, size_t size) { SHA1_INFO sha1_info; sha1_init(&sha1_info); sha1_update(&sha1_info, (uint8_t*)in, size); sha1_final(out, &sha1_info); } /* Compute SHA1 hash on in and store the base64 string result in out. */ void sha1_base64(char *out, unsigned char *in, size_t size) { uint8_t md[SHA1_DIGEST_LEN]; sha1(md, in, size); b64_encode(md, out, SHA1_DIGEST_LEN); strip_b64_eq(out); } /* Compute SHA256 hash on in and store the hex string result in out. */ void sha256(unsigned char *out, unsigned char *in, size_t size) { SHA256_CTX sha256_ctx; SHA256_Init(&sha256_ctx); SHA256_Update(&sha256_ctx, (const uint8_t*)in, size); SHA256_Final(out, &sha256_ctx); } /* Compute SHA256 hash on in and store the base64 string result in out. */ void sha256_base64(char *out, unsigned char *in, size_t size) { uint8_t md[SHA256_DIGEST_LEN]; sha256(md, in, size); b64_encode(md, out, SHA256_DIGEST_LEN); strip_b64_eq(out); } /* Compute SHA384 hash on in and store the hex string result in out. */ void sha384(unsigned char *out, unsigned char *in, size_t size) { SHA384_CTX sha384_ctx; SHA384_Init(&sha384_ctx); SHA384_Update(&sha384_ctx, (const uint8_t*)in, size); SHA384_Final(out, &sha384_ctx); } /* Compute SHA384 hash on in and store the base64 string result in out. */ void sha384_base64(char *out, unsigned char *in, size_t size) { uint8_t md[SHA384_DIGEST_LEN]; sha384(md, in, size); b64_encode(md, out, SHA384_DIGEST_LEN); strip_b64_eq(out); } /* Compute SHA512 hash on in and store the hex string result in out. */ void sha512(unsigned char *out, unsigned char *in, size_t size) { SHA512_CTX sha512_ctx; SHA512_Init(&sha512_ctx); SHA512_Update(&sha512_ctx, (const uint8_t*)in, size); SHA512_Final(out, &sha512_ctx); } /* Compute SHA512 hash on in and store the base64 string result in out. */ void sha512_base64(char *out, unsigned char *in, size_t size) { uint8_t md[SHA512_DIGEST_LEN]; sha512(md, in, size); b64_encode(md, out, SHA512_DIGEST_LEN); strip_b64_eq(out); } void sha3_256(unsigned char *out, unsigned char *in, size_t size) { FIPS202_SHA3_256(in, size, out); } void sha3_256_base64(char *out, unsigned char *in, size_t size) { uint8_t md[SHA3_256_DIGEST_LEN]; FIPS202_SHA3_256(in, size, md); b64_encode(md, out, SHA3_256_DIGEST_LEN); strip_b64_eq(out); } void sha3_512(unsigned char *out, unsigned char *in, size_t size) { FIPS202_SHA3_512(in, size, out); } void sha3_512_base64(char *out, unsigned char *in, size_t size) { uint8_t md[SHA3_512_DIGEST_LEN]; FIPS202_SHA3_512(in, size, md); b64_encode(md, out, SHA3_512_DIGEST_LEN); strip_b64_eq(out); } #ifdef HAVE_C_UNIT_TESTS /* LCOV_EXCL_START */ DECLARE_UTEST(test_md5, "md5 test vectors") //https://tools.ietf.org/html/rfc1321.html { char msg[1024] = {0}; unsigned char digest[1024] = {0}; char digest_txt[1024] = {0}; char expected_digest1[1024] = {0}; char expected_digest2[1024] = {0}; char expected_digest3[1024] = {0}; char expected_digest4[1024] = {0}; char expected_digest5[1024] = {0}; char expected_digest6[1024] = {0}; char expected_digest7[1024] = {0}; int i = 0; strcpy(expected_digest1, "d41d8cd98f00b204e9800998ecf8427e"); strcpy(expected_digest2, "0cc175b9c0f1b6a831c399e269772661"); strcpy(expected_digest3, "900150983cd24fb0d6963f7d28e17f72"); strcpy(expected_digest4, "f96b697d7cb7938d525a2f31aaf161d0"); strcpy(expected_digest5, "c3fcd3d76192e4007dfb496cca67e13b"); strcpy(expected_digest6, "d174ab98d277d9f5a5611c2c9f419d9f"); strcpy(expected_digest7, "57edf4a22be3c955ac49da2e2107b67a"); strcpy(msg, ""); md5(digest, (unsigned char *)msg, strlen(msg)); for ( i = 0; i < MD5_DIGEST_LEN; i++) { sprintf(digest_txt + (2 * i), "%02x", digest[i]); } CU_ASSERT(memcmp(digest_txt, expected_digest1, MD5_DIGEST_LEN) == 0); strcpy(msg, "a"); md5(digest, (unsigned char *)msg, strlen(msg)); for ( i = 0; i < MD5_DIGEST_LEN; i++) { sprintf(digest_txt + (2 * i), "%02x", digest[i]); } CU_ASSERT(memcmp(digest_txt, expected_digest2, MD5_DIGEST_LEN) == 0); strcpy(msg, "abc"); md5(digest, (unsigned char *)msg, strlen(msg)); for ( i = 0; i < MD5_DIGEST_LEN; i++) { sprintf(digest_txt + (2 * i), "%02x", digest[i]); } CU_ASSERT(memcmp(digest_txt, expected_digest3, MD5_DIGEST_LEN) == 0); strcpy(msg, "message digest"); md5(digest, (unsigned char *)msg, strlen(msg)); for ( i = 0; i < MD5_DIGEST_LEN; i++) { sprintf(digest_txt + (2 * i), "%02x", digest[i]); } CU_ASSERT(memcmp(digest_txt, expected_digest4, MD5_DIGEST_LEN) == 0); strcpy(msg, "abcdefghijklmnopqrstuvwxyz"); md5(digest, (unsigned char *)msg, strlen(msg)); for ( i = 0; i < MD5_DIGEST_LEN; i++) { sprintf(digest_txt + (2 * i), "%02x", digest[i]); } CU_ASSERT(memcmp(digest_txt, expected_digest5, MD5_DIGEST_LEN) == 0); strcpy(msg, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); md5(digest, (unsigned char *)msg, strlen(msg)); for ( i = 0; i < MD5_DIGEST_LEN; i++) { sprintf(digest_txt + (2 * i), "%02x", digest[i]); } CU_ASSERT(memcmp(digest_txt, expected_digest6, MD5_DIGEST_LEN) == 0); strcpy(msg, "12345678901234567890123456789012345678901234567890123456789012345678901234567890"); md5(digest, (unsigned char *)msg, strlen(msg)); for ( i = 0; i < MD5_DIGEST_LEN; i++) { sprintf(digest_txt + (2 * i), "%02x", digest[i]); } CU_ASSERT(memcmp(digest_txt, expected_digest7, MD5_DIGEST_LEN) == 0); } DECLARE_UTEST(test_sha1, "sha1 test vectors") //http://www.di-mgt.com.au/sha_testvectors.html { char msg[1024] = {0}; unsigned char digest[1024] = {0}; char digest_txt[1024] = {0}; char expected_digest1[1024] = {0}; char expected_digest2[1024] = {0}; char expected_digest3[1024] = {0}; char expected_digest4[1024] = {0}; int i = 0; strcpy(msg, "abc"); strcpy(expected_digest1, "a9993e364706816aba3e25717850c26c9cd0d89d"); sha1(digest, (unsigned char *)msg, strlen(msg)); for ( i = 0; i < SHA1_DIGEST_LEN; i++) { sprintf(digest_txt + (2 * i), "%02x", digest[i]); } CU_ASSERT(memcmp(digest_txt, expected_digest1, SHA1_DIGEST_LEN) == 0); strcpy(msg, ""); strcpy(expected_digest2, "da39a3ee5e6b4b0d3255bfef95601890afd80709"); sha1(digest, (unsigned char *)msg, strlen(msg)); for ( i = 0; i < SHA1_DIGEST_LEN; i++) { sprintf(digest_txt + (2 * i), "%02x", digest[i]); } CU_ASSERT(memcmp(digest_txt, expected_digest2, SHA1_DIGEST_LEN) == 0); strcpy(msg, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"); strcpy(expected_digest3, "84983e441c3bd26ebaae4aa1f95129e5e54670f1"); sha1(digest, (unsigned char *)msg, strlen(msg)); for ( i = 0; i < SHA1_DIGEST_LEN; i++) { sprintf(digest_txt + (2 * i), "%02x", digest[i]); } CU_ASSERT(memcmp(digest_txt, expected_digest3, SHA1_DIGEST_LEN) == 0); strcpy(msg, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"); strcpy(expected_digest4, "a49b2446a02c645bf419f995b67091253a04a259"); sha1(digest, (unsigned char *)msg, strlen(msg)); for ( i = 0; i < SHA1_DIGEST_LEN; i++) { sprintf(digest_txt + (2 * i), "%02x", digest[i]); } CU_ASSERT(memcmp(digest_txt, expected_digest4, SHA1_DIGEST_LEN) == 0); } DECLARE_UTEST(test_sha256, "sha-256 test vectors") //http://www.di-mgt.com.au/sha_testvectors.html { char msg[1024] = {0}; unsigned char digest[1024] = {0}; char digest_txt[1024] = {0}; char expected_digest1[1024] = {0}; char expected_digest2[1024] = {0}; char expected_digest3[1024] = {0}; char expected_digest4[1024] = {0}; int i = 0; strcpy(msg, "abc"); strcpy(expected_digest1, "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"); sha256(digest, (unsigned char *)msg, strlen(msg)); for ( i = 0; i < SHA256_DIGEST_LEN; i++) { sprintf(digest_txt + (2 * i), "%02x", digest[i]); } CU_ASSERT(memcmp(digest_txt, expected_digest1, SHA256_DIGEST_LEN) == 0); strcpy(msg, ""); strcpy(expected_digest2, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"); sha256(digest, (unsigned char *)msg, strlen(msg)); for ( i = 0; i < SHA256_DIGEST_LEN; i++) { sprintf(digest_txt + (2 * i), "%02x", digest[i]); } CU_ASSERT(memcmp(digest_txt, expected_digest2, SHA256_DIGEST_LEN) == 0); strcpy(msg, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"); strcpy(expected_digest3, "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1"); sha256(digest, (unsigned char *)msg, strlen(msg)); for ( i = 0; i < SHA256_DIGEST_LEN; i++) { sprintf(digest_txt + (2 * i), "%02x", digest[i]); } CU_ASSERT(memcmp(digest_txt, expected_digest3, SHA256_DIGEST_LEN) == 0); strcpy(msg, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"); strcpy(expected_digest4, "cf5b16a778af8380036ce59e7b0492370b249b11e8f07a51afac45037afee9d1"); sha256(digest, (unsigned char *)msg, strlen(msg)); for ( i = 0; i < SHA256_DIGEST_LEN; i++) { sprintf(digest_txt + (2 * i), "%02x", digest[i]); } CU_ASSERT(memcmp(digest_txt, expected_digest4, SHA256_DIGEST_LEN) == 0); } DECLARE_UTEST(test_sha384, "sha-384 test vectors") //http://www.di-mgt.com.au/sha_testvectors.html { char msg[1024] = {0}; unsigned char digest[1024] = {0}; char digest_txt[1024] = {0}; char expected_digest1[1024] = {0}; char expected_digest2[1024] = {0}; char expected_digest3[1024] = {0}; char expected_digest4[1024] = {0}; int i = 0; strcpy(msg, "abc"); strcpy(expected_digest1, "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7"); sha384(digest, (unsigned char *)msg, strlen(msg)); for ( i = 0; i < SHA384_DIGEST_LEN; i++) { sprintf(digest_txt + (2 * i), "%02x", digest[i]); } CU_ASSERT(memcmp(digest_txt, expected_digest1, SHA384_DIGEST_LEN) == 0); strcpy(msg, ""); strcpy(expected_digest2, "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b"); sha384(digest, (unsigned char *)msg, strlen(msg)); for ( i = 0; i < SHA384_DIGEST_LEN; i++) { sprintf(digest_txt + (2 * i), "%02x", digest[i]); } CU_ASSERT(memcmp(digest_txt, expected_digest2, SHA384_DIGEST_LEN) == 0); strcpy(msg, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"); strcpy(expected_digest3, "3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b"); sha384(digest, (unsigned char *)msg, strlen(msg)); for ( i = 0; i < SHA384_DIGEST_LEN; i++) { sprintf(digest_txt + (2 * i), "%02x", digest[i]); } CU_ASSERT(memcmp(digest_txt, expected_digest3, SHA384_DIGEST_LEN) == 0); strcpy(msg, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"); strcpy(expected_digest4, "09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712fcc7c71a557e2db966c3e9fa91746039"); sha384(digest, (unsigned char *)msg, strlen(msg)); for ( i = 0; i < SHA384_DIGEST_LEN; i++) { sprintf(digest_txt + (2 * i), "%02x", digest[i]); } CU_ASSERT(memcmp(digest_txt, expected_digest4, SHA384_DIGEST_LEN) == 0); } DECLARE_UTEST(test_sha512, "sha-512 test vectors") //http://www.di-mgt.com.au/sha_testvectors.html { char msg[1024] = {0}; unsigned char digest[1024] = {0}; char digest_txt[1024] = {0}; char expected_digest1[1024] = {0}; char expected_digest2[1024] = {0}; char expected_digest3[1024] = {0}; char expected_digest4[1024] = {0}; int i = 0; strcpy(msg, "abc"); strcpy(expected_digest1, "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"); sha512(digest, (unsigned char *)msg, strlen(msg)); for ( i = 0; i < SHA512_DIGEST_LEN; i++) { sprintf(digest_txt + (2 * i), "%02x", digest[i]); } CU_ASSERT(memcmp(digest_txt, expected_digest1, SHA512_DIGEST_LEN) == 0); strcpy(msg, ""); strcpy(expected_digest2, "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e"); sha512(digest, (unsigned char *)msg, strlen(msg)); for ( i = 0; i < SHA512_DIGEST_LEN; i++) { sprintf(digest_txt + (2 * i), "%02x", digest[i]); } CU_ASSERT(memcmp(digest_txt, expected_digest2, SHA512_DIGEST_LEN) == 0); strcpy(msg, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"); strcpy(expected_digest3, "204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445"); sha512(digest, (unsigned char *)msg, strlen(msg)); for ( i = 0; i < SHA512_DIGEST_LEN; i++) { sprintf(digest_txt + (2 * i), "%02x", digest[i]); } CU_ASSERT(memcmp(digest_txt, expected_digest3, SHA512_DIGEST_LEN) == 0); strcpy(msg, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"); strcpy(expected_digest4, "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909"); sha512(digest, (unsigned char *)msg, strlen(msg)); for ( i = 0; i < SHA512_DIGEST_LEN; i++) { sprintf(digest_txt + (2 * i), "%02x", digest[i]); } CU_ASSERT(memcmp(digest_txt, expected_digest4, SHA512_DIGEST_LEN) == 0); } DECLARE_UTEST(test_sha3_256, "sha3_256 test vectors") //http://www.di-mgt.com.au/sha_testvectors.html { char msg[1024] = {0}; unsigned char digest[1024] = {0}; char digest_txt[1024] = {0}; char expected_digest1[1024] = {0}; char expected_digest2[1024] = {0}; char expected_digest3[1024] = {0}; char expected_digest4[1024] = {0}; int i = 0; strcpy(msg, "abc"); strcpy(expected_digest1, "3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532"); sha3_256(digest, (unsigned char *)msg, strlen(msg)); for ( i = 0; i < SHA3_256_DIGEST_LEN; i++) { sprintf(digest_txt + (2 * i), "%02x", digest[i]); } CU_ASSERT(memcmp(digest_txt, expected_digest1, SHA3_256_DIGEST_LEN) == 0); strcpy(msg, ""); strcpy(expected_digest2, "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a"); sha3_256(digest, (unsigned char *)msg, strlen(msg)); for ( i = 0; i < SHA3_256_DIGEST_LEN; i++) { sprintf(digest_txt + (2 * i), "%02x", digest[i]); } CU_ASSERT(memcmp(digest_txt, expected_digest2, SHA3_256_DIGEST_LEN) == 0); strcpy(msg, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"); strcpy(expected_digest3, "41c0dba2a9d6240849100376a8235e2c82e1b9998a999e21db32dd97496d3376"); sha3_256(digest, (unsigned char *)msg, strlen(msg)); for ( i = 0; i < SHA3_256_DIGEST_LEN; i++) { sprintf(digest_txt + (2 * i), "%02x", digest[i]); } CU_ASSERT(memcmp(digest_txt, expected_digest3, SHA3_256_DIGEST_LEN) == 0); strcpy(msg, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"); strcpy(expected_digest4, "916f6061fe879741ca6469b43971dfdb28b1a32dc36cb3254e812be27aad1d18"); sha3_256(digest, (unsigned char *)msg, strlen(msg)); for ( i = 0; i < SHA3_256_DIGEST_LEN; i++) { sprintf(digest_txt + (2 * i), "%02x", digest[i]); } CU_ASSERT(memcmp(digest_txt, expected_digest4, SHA3_256_DIGEST_LEN) == 0); } DECLARE_UTEST(test_sha3_512, "sha3_512 test vectors") //http://www.di-mgt.com.au/sha_testvectors.html { char msg[1024] = {0}; unsigned char digest[1024] = {0}; char digest_txt[1024] = {0}; char expected_digest1[1024] = {0}; char expected_digest2[1024] = {0}; char expected_digest3[1024] = {0}; char expected_digest4[1024] = {0}; int i = 0; strcpy(msg, "abc"); strcpy(expected_digest1, "b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0"); sha3_512(digest, (unsigned char *)msg, strlen(msg)); for ( i = 0; i < SHA3_512_DIGEST_LEN; i++) { sprintf(digest_txt + (2 * i), "%02x", digest[i]); } CU_ASSERT(memcmp(digest_txt, expected_digest1, SHA3_512_DIGEST_LEN) == 0); strcpy(msg, ""); strcpy(expected_digest2, "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26"); sha3_512(digest, (unsigned char *)msg, strlen(msg)); for ( i = 0; i < SHA3_512_DIGEST_LEN; i++) { sprintf(digest_txt + (2 * i), "%02x", digest[i]); } CU_ASSERT(memcmp(digest_txt, expected_digest2, SHA3_512_DIGEST_LEN) == 0); strcpy(msg, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"); strcpy(expected_digest3, "04a371e84ecfb5b8b77cb48610fca8182dd457ce6f326a0fd3d7ec2f1e91636dee691fbe0c985302ba1b0d8dc78c086346b533b49c030d99a27daf1139d6e75e"); sha3_512(digest, (unsigned char *)msg, strlen(msg)); for ( i = 0; i < SHA3_512_DIGEST_LEN; i++) { sprintf(digest_txt + (2 * i), "%02x", digest[i]); } CU_ASSERT(memcmp(digest_txt, expected_digest3, SHA3_512_DIGEST_LEN) == 0); strcpy(msg, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"); strcpy(expected_digest4, "afebb2ef542e6579c50cad06d2e578f9f8dd6881d7dc824d26360feebf18a4fa73e3261122948efcfd492e74e82e2189ed0fb440d187f382270cb455f21dd185"); sha3_512(digest, (unsigned char *)msg, strlen(msg)); for ( i = 0; i < SHA3_512_DIGEST_LEN; i++) { sprintf(digest_txt + (2 * i), "%02x", digest[i]); } CU_ASSERT(memcmp(digest_txt, expected_digest4, SHA3_512_DIGEST_LEN) == 0); } int register_ts_digest_test(void) { ts_init(&TEST_SUITE(digest_test), TEST_SUITE_DESCR(digest_test), NULL, NULL); ts_add_utest(&TEST_SUITE(digest_test), UTEST_FCT(test_md5), UTEST_DESCR(test_md5)); ts_add_utest(&TEST_SUITE(digest_test), UTEST_FCT(test_sha1), UTEST_DESCR(test_sha1)); ts_add_utest(&TEST_SUITE(digest_test), UTEST_FCT(test_sha256), UTEST_DESCR(test_sha256)); ts_add_utest(&TEST_SUITE(digest_test), UTEST_FCT(test_sha384), UTEST_DESCR(test_sha384)); ts_add_utest(&TEST_SUITE(digest_test), UTEST_FCT(test_sha512), UTEST_DESCR(test_sha512)); ts_add_utest(&TEST_SUITE(digest_test), UTEST_FCT(test_sha3_256), UTEST_DESCR(test_sha3_256)); ts_add_utest(&TEST_SUITE(digest_test), UTEST_FCT(test_sha3_512), UTEST_DESCR(test_sha3_512)); return register_ts(&TEST_SUITE(digest_test)); } #endif /* HAVE_C_UNIT_TESTS */ /* LCOV_EXCL_STOP */ /***EOF***/ fwknop-2.6.11/lib/fko_timestamp.c0000664000175000017500000000452014560546213013613 00000000000000/** * \file lib/fko_timestamp.c * * \brief Get the current timestamp with optional offset applied. */ /* Fwknop is developed primarily by the people listed in the file 'AUTHORS'. * Copyright (C) 2009-2015 fwknop developers and contributors. For a full * list of contributors, see the file 'CREDITS'. * * License (GNU General Public License): * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #include "fko_common.h" #include "fko.h" /* Set the timestamp. */ int fko_set_timestamp(fko_ctx_t ctx, const int offset) { time_t ts; #if HAVE_LIBFIU fiu_return_on("fko_set_timestamp_init", FKO_ERROR_CTX_NOT_INITIALIZED); #endif /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return FKO_ERROR_CTX_NOT_INITIALIZED; ts = time(NULL) + offset; #if HAVE_LIBFIU fiu_return_on("fko_set_timestamp_val", FKO_ERROR_INVALID_DATA_TIMESTAMP_VALIDFAIL); #endif if(ts < 0) return(FKO_ERROR_INVALID_DATA_TIMESTAMP_VALIDFAIL); ctx->timestamp = ts; ctx->state |= FKO_DATA_MODIFIED; return(FKO_SUCCESS); } /* Return the current timestamp. */ int fko_get_timestamp(fko_ctx_t ctx, time_t *timestamp) { #if HAVE_LIBFIU fiu_return_on("fko_get_timestamp_init", FKO_ERROR_CTX_NOT_INITIALIZED); #endif /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); if(timestamp == NULL) return(FKO_ERROR_INVALID_DATA); #if HAVE_LIBFIU fiu_return_on("fko_get_timestamp_val", FKO_ERROR_INVALID_DATA); #endif *timestamp = ctx->timestamp; return(FKO_SUCCESS); } /***EOF***/ fwknop-2.6.11/lib/cipher_funcs.h0000664000175000017500000000361314560546213013430 00000000000000/** * \file lib/cipher_funcs.h * * \brief Header for the fwknop cipher_funcs.c. */ /* Fwknop is developed primarily by the people listed in the file 'AUTHORS'. * Copyright (C) 2009-2015 fwknop developers and contributors. For a full * list of contributors, see the file 'CREDITS'. * * License (GNU General Public License): * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #ifndef CIPHER_FUNCS_H #define CIPHER_FUNCS_H 1 #include "rijndael.h" #include "gpgme_funcs.h" /* Provide the predicted encrypted data size for given input data based * on a 16-byte block size (for Rijndael implementation,this also accounts * for the 16-byte salt as well). */ #define PREDICT_ENCSIZE(x) (1+(x>>4)+(x&0xf?1:0))<<4 void get_random_data(unsigned char *data, const size_t len); size_t rij_encrypt(unsigned char *in, size_t len, const char *key, const int key_len, unsigned char *out, int encryption_mode); size_t rij_decrypt(unsigned char *in, size_t len, const char *key, const int key_len, unsigned char *out, int encryption_mode); int add_salted_str(fko_ctx_t ctx); int add_gpg_prefix(fko_ctx_t ctx); #endif /* CIPHER_FUNCS_H */ /***EOF***/ fwknop-2.6.11/lib/fko_common.h0000664000175000017500000001065414560546213013112 00000000000000/** * \file lib/fko_common.h * * \brief Common header for libfko source files. */ /* Fwknop is developed primarily by the people listed in the file 'AUTHORS'. * Copyright (C) 2009-2015 fwknop developers and contributors. For a full * list of contributors, see the file 'CREDITS'. * * License (GNU General Public License): * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #ifndef FKO_COMMON_H #define FKO_COMMON_H 1 #if HAVE_CONFIG_H #include "config.h" #endif #if HAVE_LIBFIU #include #endif #include #include #if STDC_HEADERS #include #include #elif HAVE_STRINGS_H #include #endif /*STDC_HEADERS*/ #if HAVE_UNISTD_H #include #endif #if HAVE_CTYPE_H #include /* Using this for isdigit() */ #else /* Fall-back does not account for locale */ #define isdigit(c) (c >= 48 && c <= 57) #endif #ifdef WIN32 #include #define strcasecmp _stricmp #define strncasecmp _strnicmp #define snprintf _snprintf #define strdup _strdup #define unlink _unlink #define open _open #define close _close #define write _write #define O_WRONLY _O_WRONLY #define O_RDONLY _O_RDONLY #define O_RDWR _O_RDWR #define O_CREAT _O_CREAT #define O_EXCL _O_EXCL #define S_IRUSR _S_IREAD #define S_IWUSR _S_IWRITE #define PATH_SEP '\\' /* These are needed for the digest code under windows. */ typedef unsigned __int8 uint8_t; typedef unsigned __int32 uint32_t; typedef unsigned __int64 uint64_t; #else #if HAVE_STDINT_H #include #endif #endif /* Work out endianness */ #ifdef HAVE_ENDIAN_H #include #if defined(BYTE_ORDER) /* POSIX proposal */ #define BYTEORDER BYTE_ORDER #elif defined(__BYTE_ORDER) /* older systems? */ #define BYTEORDER __BYTE_ORDER #endif #elif HAVE_SYS_ENDIAN_H /* FreeBSD has a sys/endian.h */ #include #define BYTEORDER _BYTE_ORDER #elif HAVE_SYS_BYTEORDER_H /* Solaris (v10 at least) seems to have this */ #include #if defined(_BIG_ENDIAN) #define BYTEORDER 4321 #elif defined(_LITTLE_ENDIAN) #define BYTEORDER 1234 #endif #endif #ifndef BYTEORDER #if defined(__BYTE_ORDER) #define BYTEORDER __BYTE_ORDER #elif defined(_BYTE_ORDER) #define BYTEORDER _BYTE_ORDER #elif defined(BYTE_ORDER) #define BYTEORDER BYTE_ORDER #endif #endif #ifndef BYTEORDER #if defined(_BIG_ENDIAN) || defined(__BIG_ENDIAN__) #define BYTEORDER 4321 #elif defined(_LITTLE_ENDIAN) || defined(__LITTLE_ENDIAN__) || defined(WIN32) #define BYTEORDER 1234 #endif #endif #ifndef BYTEORDER #error unable to determine BYTEORDER #endif #ifdef WIN32 #include #else #ifdef HAVE_SYS_TIME_H #include #ifdef TIME_WITH_SYS_TIME #include #endif #endif #endif /* Convenient macros for wrapping sections in 'extern "C" {' constructs. */ #ifdef __cplusplus #define BEGIN_C_DECLS extern "C" { #define END_C_DECLS } #else /* !__cplusplus */ #define BEGIN_C_DECLS #define END_C_DECLS #endif /* __cplusplus */ #include "fko_util.h" #include "fko_limits.h" #include "fko_state.h" #include "fko_context.h" #include "fko_message.h" #include "fko_user.h" /* Try to cover for those that do not have bzero. */ #if !HAVE_BZERO && HAVE_MEMSET #define bzero(buf, bytes) ((void) memset (buf, 0, bytes)) #endif /* Work-around for not having strnlen */ #if !HAVE_STRNLEN #define strnlen(s, l) (strlen(s) < l ? strlen(s) : l) #endif /* Get the number of elements of an array */ #define ARRAY_SIZE(t) (sizeof(t) / sizeof(t[0])) #endif /* FKO_COMMON_H */ /***EOF***/ fwknop-2.6.11/lib/sha1.h0000664000175000017500000000352114560546213011612 00000000000000/** * \file lib/sha1.h * * \brief Header for sha1.c */ /* sha - An implementation of the NIST SHA1 Message Digest * algorithm. * * Copyright (C) 2001 Rafael R. Sevilla * * License (GNU General Public License): * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #ifndef SHA1_H #define SHA1_H 1 #include "common.h" #ifdef WIN32 #define BYTEORDER 1234 #endif /* Truncate to 32 bits -- should be a null op on 32-bit machines */ #ifndef TRUNC32 #define TRUNC32(x) ((x) & 0xffffffffL) #endif #define SHA1_BLOCKSIZE 64 #define SHA1_BLOCK_LEN SHA1_BLOCKSIZE #define SHA1_DIGEST_LEN 20 #define SHA1_DIGEST_STR_LEN (SHA1_DIGEST_LEN * 2 + 1) #define SHA1_B64_LEN 27 typedef struct { uint32_t digest[8]; uint32_t count_lo, count_hi; uint8_t data[SHA1_BLOCKSIZE]; int local; } SHA1_INFO; /* SHA1 prototypes. */ void sha1_init(SHA1_INFO *sha1_info); void sha1_update(SHA1_INFO *sha1_info, uint8_t *buffer, int count); void sha1_final(uint8_t digest[SHA1_DIGEST_LEN], SHA1_INFO *sha1_info); #endif /* SHA1_H */ fwknop-2.6.11/lib/sha3.c0000664000175000017500000003060014560546213011605 00000000000000/** * \file lib/sha3.c * * \brief Implementation of SHA3 */ /* Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, Joan Daemen, Michael Peeters, Gilles Van Assche and Ronny Van Keer, hereby denoted as "the implementer". For more information, feedback or questions, please refer to our websites: http://keccak.noekeon.org/ http://keyak.noekeon.org/ http://ketje.noekeon.org/ To the extent possible under law, the implementer has waived all copyright and related or neighboring rights to the source code in this file. http://creativecommons.org/publicdomain/zero/1.0/ */ /* ================================================================ The purpose of this source file is to demonstrate a readable and compact implementation of all the Keccak instances approved in the FIPS 202 standard, including the hash functions and the extendable-output functions (XOFs). We focused on clarity and on source-code compactness, rather than on the performance. The advantages of this implementation are: + The source code is compact, after removing the comments, that is. :-) + There are no tables with arbitrary constants. + For clarity, the comments link the operations to the specifications using the same notation as much as possible. + There is no restriction in cryptographic features. In particular, the SHAKE128 and SHAKE256 XOFs can produce any output length. + The code does not use much RAM, as all operations are done in place. The drawbacks of this implementation are: - There is no message queue. The whole message must be ready in a buffer. - It is not optimized for peformance. The implementation is even simpler on a little endian platform. Just define the LITTLE_ENDIAN symbol in that case. For a more complete set of implementations, please refer to the Keccak Code Package at https://github.com/gvanas/KeccakCodePackage For more information, please refer to: * [Keccak Reference] http://keccak.noekeon.org/Keccak-reference-3.0.pdf * [Keccak Specifications Summary] http://keccak.noekeon.org/specs_summary.html This file uses UTF-8 encoding, as some comments use Greek letters. ================================================================ */ /** * Function to compute the Keccak[r, c] sponge function over a given input. * @param rate The value of the rate r. * @param capacity The value of the capacity c. * @param input Pointer to the input message. * @param inputByteLen The number of input bytes provided in the input message. * @param delimitedSuffix Bits that will be automatically appended to the end * of the input message, as in domain separation. * This is a byte containing from 0 to 7 bits * These n bits must be in the least significant bit positions * and must be delimited with a bit 1 at position n * (counting from 0=LSB to 7=MSB) and followed by bits 0 * from position n+1 to position 7. * Some examples: * - If no bits are to be appended, then @a delimitedSuffix must be 0x01. * - If the 2-bit sequence 0,1 is to be appended (as for SHA3-*), @a delimitedSuffix must be 0x06. * - If the 4-bit sequence 1,1,1,1 is to be appended (as for SHAKE*), @a delimitedSuffix must be 0x1F. * - If the 7-bit sequence 1,1,0,1,0,0,0 is to be absorbed, @a delimitedSuffix must be 0x8B. * @param output Pointer to the buffer where to store the output. * @param outputByteLen The number of output bytes desired. * @pre One must have r+c=1600 and the rate a multiple of 8 bits in this implementation. */ //void Keccak(unsigned int rate, unsigned int capacity, const unsigned char *input, unsigned long long int inputByteLen, unsigned char delimitedSuffix, unsigned char *output, unsigned long long int outputByteLen); /** * Function to compute SHAKE128 on the input message with any output length. */ #include "sha3.h" /* void FIPS202_SHAKE128(const unsigned char *input, unsigned int inputByteLen, unsigned char *output, int outputByteLen) { Keccak(1344, 256, input, inputByteLen, 0x1F, output, outputByteLen); } */ /** * Function to compute SHAKE256 on the input message with any output length. void FIPS202_SHAKE256(const unsigned char *input, unsigned int inputByteLen, unsigned char *output, int outputByteLen) { Keccak(1088, 512, input, inputByteLen, 0x1F, output, outputByteLen); } */ /** * Function to compute SHA3-224 on the input message. The output length is fixed to 28 bytes. void FIPS202_SHA3_224(const unsigned char *input, unsigned int inputByteLen, unsigned char *output) { Keccak(1152, 448, input, inputByteLen, 0x06, output, 28); } */ /** * Function to compute SHA3-256 on the input message. The output length is fixed to 32 bytes. */ void FIPS202_SHA3_256(const unsigned char *input, unsigned int inputByteLen, unsigned char *output) { Keccak(1088, 512, input, inputByteLen, 0x06, output, 32); } /** * Function to compute SHA3-384 on the input message. The output length is fixed to 48 bytes. void FIPS202_SHA3_384(const unsigned char *input, unsigned int inputByteLen, unsigned char *output) { Keccak(832, 768, input, inputByteLen, 0x06, output, 48); } */ /** * Function to compute SHA3-512 on the input message. The output length is fixed to 64 bytes. */ void FIPS202_SHA3_512(const unsigned char *input, unsigned int inputByteLen, unsigned char *output) { Keccak(576, 1024, input, inputByteLen, 0x06, output, 64); } /* ================================================================ Technicalities ================================================================ */ typedef unsigned char UINT8; typedef unsigned long long int UINT64; typedef UINT64 tKeccakLane; #ifndef LITTLE_ENDIAN /** Function to load a 64-bit value using the little-endian (LE) convention. * On a LE platform, this could be greatly simplified using a cast. */ static UINT64 load64(const UINT8 *x) { int i; UINT64 u=0; for(i=7; i>=0; --i) { u <<= 8; u |= x[i]; } return u; } /** Function to store a 64-bit value using the little-endian (LE) convention. * On a LE platform, this could be greatly simplified using a cast. */ static void store64(UINT8 *x, UINT64 u) { unsigned int i; for(i=0; i<8; ++i) { x[i] = u; u >>= 8; } } /** Function to XOR into a 64-bit value using the little-endian (LE) convention. * On a LE platform, this could be greatly simplified using a cast. */ static void xor64(UINT8 *x, UINT64 u) { unsigned int i; for(i=0; i<8; ++i) { x[i] ^= u; u >>= 8; } } #endif /* ================================================================ A readable and compact implementation of the Keccak-f[1600] permutation. ================================================================ */ #define ROL64(a, offset) ((((UINT64)a) << offset) ^ (((UINT64)a) >> (64-offset))) #define i(x, y) ((x)+5*(y)) #ifdef LITTLE_ENDIAN #define readLane(x, y) (((tKeccakLane*)state)[i(x, y)]) #define writeLane(x, y, lane) (((tKeccakLane*)state)[i(x, y)]) = (lane) #define XORLane(x, y, lane) (((tKeccakLane*)state)[i(x, y)]) ^= (lane) #else #define readLane(x, y) load64((UINT8*)state+sizeof(tKeccakLane)*i(x, y)) #define writeLane(x, y, lane) store64((UINT8*)state+sizeof(tKeccakLane)*i(x, y), lane) #define XORLane(x, y, lane) xor64((UINT8*)state+sizeof(tKeccakLane)*i(x, y), lane) #endif /** * Function that computes the linear feedback shift register (LFSR) used to * define the round constants (see [Keccak Reference, Section 1.2]). */ int LFSR86540(UINT8 *LFSR) { int result = ((*LFSR) & 0x01) != 0; if (((*LFSR) & 0x80) != 0) // Primitive polynomial over GF(2): x^8+x^6+x^5+x^4+1 (*LFSR) = ((*LFSR) << 1) ^ 0x71; else (*LFSR) <<= 1; return result; } /** * Function that computes the Keccak-f[1600] permutation on the given state. */ void KeccakF1600_StatePermute(void *state) { unsigned int round, x, y, j, t; UINT8 LFSRstate = 0x01; for(round=0; round<24; round++) { { // === Theta step (see [Keccak Reference, Section 2.3.2]) === tKeccakLane C[5], D; // Compute the parity of the columns for(x=0; x<5; x++) C[x] = readLane(x, 0) ^ readLane(x, 1) ^ readLane(x, 2) ^ readLane(x, 3) ^ readLane(x, 4); for(x=0; x<5; x++) { // Compute the theta effect for a given column D = C[(x+4)%5] ^ ROL64(C[(x+1)%5], 1); // Add the theta effect to the whole column for (y=0; y<5; y++) XORLane(x, y, D); } } { // === rho and pi steps (see [Keccak Reference, Sections 2.3.3 and 2.3.4]) === tKeccakLane current, temp; // Start at coordinates (1 0) x = 1; y = 0; current = readLane(x, y); // Iterate over ((0 1)(2 3))^t * (1 0) for 0 <= t <= 23 for(t=0; t<24; t++) { // Compute the rotation constant r = (t+1)(t+2)/2 unsigned int r = ((t+1)*(t+2)/2)%64; // Compute ((0 1)(2 3)) * (x y) unsigned int Y = (2*x+3*y)%5; x = y; y = Y; // Swap current and state(x,y), and rotate temp = readLane(x, y); writeLane(x, y, ROL64(current, r)); current = temp; } } { // === chi step (see [Keccak Reference, Section 2.3.1]) === tKeccakLane temp[5]; for(y=0; y<5; y++) { // Take a copy of the plane for(x=0; x<5; x++) temp[x] = readLane(x, y); // Compute chi on the plane for(x=0; x<5; x++) writeLane(x, y, temp[x] ^((~temp[(x+1)%5]) & temp[(x+2)%5])); } } { // === iota step (see [Keccak Reference, Section 2.3.5]) === for(j=0; j<7; j++) { unsigned int bitPosition = (1< #define MIN(a, b) ((a) < (b) ? (a) : (b)) void Keccak(unsigned int rate, unsigned int capacity, const unsigned char *input, unsigned long long int inputByteLen, unsigned char delimitedSuffix, unsigned char *output, unsigned long long int outputByteLen) { UINT8 state[200]; unsigned int rateInBytes = rate/8; unsigned int blockSize = 0; unsigned int i; if (((rate + capacity) != 1600) || ((rate % 8) != 0)) return; // === Initialize the state === memset(state, 0, sizeof(state)); // === Absorb all the input blocks === while(inputByteLen > 0) { blockSize = MIN(inputByteLen, rateInBytes); for(i=0; i 0) { blockSize = MIN(outputByteLen, rateInBytes); memcpy(output, state, blockSize); output += blockSize; outputByteLen -= blockSize; if (outputByteLen > 0) KeccakF1600_StatePermute(state); } } fwknop-2.6.11/lib/fko_encode.c0000664000175000017500000002161414560546213013050 00000000000000/** * \file lib/fko_encode.c * * \brief Encodes some pieces of the spa data then puts together all of * the necessary pieces to gether to create the single encoded * message string. */ /* Fwknop is developed primarily by the people listed in the file 'AUTHORS'. * Copyright (C) 2009-2015 fwknop developers and contributors. For a full * list of contributors, see the file 'CREDITS'. * * License (GNU General Public License): * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #include "fko_common.h" #include "fko.h" #include "base64.h" #include "digest.h" /* Take a given string, base64-encode it and append it to the given * buffer. */ static int append_b64(char* tbuf, char *str) { int len = strnlen(str, MAX_SPA_ENCODED_MSG_SIZE); char *bs; #if HAVE_LIBFIU fiu_return_on("append_b64_toobig", FKO_ERROR_INVALID_DATA_ENCODE_MESSAGE_TOOBIG); #endif if(len >= MAX_SPA_ENCODED_MSG_SIZE) return(FKO_ERROR_INVALID_DATA_ENCODE_MESSAGE_TOOBIG); #if HAVE_LIBFIU fiu_return_on("append_b64_calloc", FKO_ERROR_MEMORY_ALLOCATION); #endif bs = calloc(1, ((len/3)*4)+8); if(bs == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); b64_encode((unsigned char*)str, bs, len); /* --DSS XXX: make sure to check here if later decoding * becomes a problem. */ strip_b64_eq(bs); strlcat(tbuf, bs, FKO_ENCODE_TMP_BUF_SIZE); free(bs); return(FKO_SUCCESS); } /* Set the SPA encryption type. */ int fko_encode_spa_data(fko_ctx_t ctx) { int res, offset = 0; char *tbuf; #if HAVE_LIBFIU fiu_return_on("fko_encode_spa_data_init", FKO_ERROR_CTX_NOT_INITIALIZED); #endif /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); /* Check prerequisites. * --DSS XXX: Needs review. Also, we could make this more robust (or * (at leaset expand the error reporting for the missing * data). */ #if HAVE_LIBFIU fiu_return_on("fko_encode_spa_data_valid", FKO_ERROR_INCOMPLETE_SPA_DATA); #endif if( validate_username(ctx->username) != FKO_SUCCESS || ctx->version == NULL || strnlen(ctx->version, MAX_SPA_VERSION_SIZE) == 0 || ctx->message == NULL || strnlen(ctx->message, MAX_SPA_MESSAGE_SIZE) == 0) { return(FKO_ERROR_INCOMPLETE_SPA_DATA); } if(ctx->message_type == FKO_NAT_ACCESS_MSG) { if(ctx->nat_access == NULL || strnlen(ctx->nat_access, MAX_SPA_MESSAGE_SIZE) == 0) return(FKO_ERROR_INCOMPLETE_SPA_DATA); } #if HAVE_LIBFIU fiu_return_on("fko_encode_spa_data_calloc", FKO_ERROR_MEMORY_ALLOCATION); #endif /* Allocate our initial tmp buffer. */ tbuf = calloc(1, FKO_ENCODE_TMP_BUF_SIZE); if(tbuf == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); /* Put it together a piece at a time, starting with the rand val. */ strlcpy(tbuf, ctx->rand_val, FKO_ENCODE_TMP_BUF_SIZE); /* Add the base64-encoded username. */ strlcat(tbuf, ":", FKO_ENCODE_TMP_BUF_SIZE); if((res = append_b64(tbuf, ctx->username)) != FKO_SUCCESS) { free(tbuf); return(res); } /* Add the timestamp. */ offset = strlen(tbuf); snprintf(((char*)tbuf+offset), FKO_ENCODE_TMP_BUF_SIZE - offset, ":%u:", (unsigned int) ctx->timestamp); /* Add the version string. */ strlcat(tbuf, ctx->version, FKO_ENCODE_TMP_BUF_SIZE); /* Before we add the message type value, we will once again * check for whether or not a client_timeout was specified * since the message_type was set. If this is the case, then * we want to adjust the message_type first. The easy way * to do this is simply call fko_set_spa_client_timeout and set * it to its current value. This will force a re-check and * possible reset of the message type. * */ fko_set_spa_client_timeout(ctx, ctx->client_timeout); /* Add the message type value. */ offset = strlen(tbuf); snprintf(((char*)tbuf+offset), FKO_ENCODE_TMP_BUF_SIZE - offset, ":%i:", ctx->message_type); /* Add the base64-encoded SPA message. */ if((res = append_b64(tbuf, ctx->message)) != FKO_SUCCESS) { free(tbuf); return(res); } /* If a nat_access message was given, add it to the SPA * message. */ if(ctx->nat_access != NULL) { strlcat(tbuf, ":", FKO_ENCODE_TMP_BUF_SIZE); if((res = append_b64(tbuf, ctx->nat_access)) != FKO_SUCCESS) { free(tbuf); return(res); } } /* If we have a server_auth field set. Add it here. * */ if(ctx->server_auth != NULL) { strlcat(tbuf, ":", FKO_ENCODE_TMP_BUF_SIZE); if((res = append_b64(tbuf, ctx->server_auth)) != FKO_SUCCESS) { free(tbuf); return(res); } } /* If a client timeout is specified and we are not dealing with a * SPA command message, add the timeout here. */ if(ctx->client_timeout > 0 && ctx->message_type != FKO_COMMAND_MSG) { offset = strlen(tbuf); snprintf(((char*)tbuf+offset), FKO_ENCODE_TMP_BUF_SIZE - offset, ":%i", ctx->client_timeout); } /* If encoded_msg is not null, then we assume it needs to * be freed before re-assignment. */ if(ctx->encoded_msg != NULL) free(ctx->encoded_msg); /* Copy our encoded data into the context. */ ctx->encoded_msg = strdup(tbuf); free(tbuf); if(ctx->encoded_msg == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); ctx->encoded_msg_len = strnlen(ctx->encoded_msg, MAX_SPA_ENCODED_MSG_SIZE); if(! is_valid_encoded_msg_len(ctx->encoded_msg_len)) return(FKO_ERROR_INVALID_DATA_ENCODE_MSGLEN_VALIDFAIL); /* At this point we can compute the digest for this SPA data. */ if((res = fko_set_spa_digest(ctx)) != FKO_SUCCESS) return(res); /* Here we can clear the modified flags on the SPA data fields. */ FKO_CLEAR_SPA_DATA_MODIFIED(ctx); return(FKO_SUCCESS); } /* Return the fko SPA encrypted data. */ int fko_get_encoded_data(fko_ctx_t ctx, char **enc_msg) { /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); if(enc_msg == NULL) return(FKO_ERROR_INVALID_DATA); *enc_msg = ctx->encoded_msg; return(FKO_SUCCESS); } /* Set the fko SPA encoded data (this is a convenience * function mostly used for tests that involve fuzzing). */ #if FUZZING_INTERFACES int fko_set_encoded_data(fko_ctx_t ctx, const char * const encoded_msg, const int msg_len, const int require_digest, const int digest_type) { char *tbuf = NULL; int res = FKO_SUCCESS, mlen; /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); if(encoded_msg == NULL) return(FKO_ERROR_INVALID_DATA); ctx->encoded_msg = strdup(encoded_msg); ctx->state |= FKO_DATA_MODIFIED; if(ctx->encoded_msg == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); /* allow arbitrary length (i.e. let the decode routines validate * SPA message length). */ ctx->encoded_msg_len = msg_len; if(require_digest) { fko_set_spa_digest_type(ctx, digest_type); if((res = fko_set_spa_digest(ctx)) != FKO_SUCCESS) { return res; } /* append the digest to the encoded message buffer */ mlen = ctx->encoded_msg_len + ctx->digest_len + 2; tbuf = calloc(1, mlen); if(tbuf == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); /* memcpy since the provided encoded buffer might * have an embedded NULL? */ mlen = snprintf(tbuf, mlen, "%s:%s", ctx->encoded_msg, ctx->digest); if(ctx->encoded_msg != NULL) free(ctx->encoded_msg); ctx->encoded_msg = strdup(tbuf); free(tbuf); if(ctx->encoded_msg == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); ctx->encoded_msg_len = mlen; } FKO_CLEAR_SPA_DATA_MODIFIED(ctx); return(FKO_SUCCESS); } #endif /***EOF***/ fwknop-2.6.11/lib/Makefile.am0000664000175000017500000000364614560546213012651 00000000000000lib_LTLIBRARIES = libfko.la libfko_source_files = \ base64.c base64.h cipher_funcs.c cipher_funcs.h digest.c digest.h \ fko_client_timeout.c fko_common.h fko_digest.c fko_encode.c \ fko_decode.c fko_encryption.c fko_error.c fko_funcs.c fko_message.c \ fko_message.h fko_nat_access.c fko_rand_value.c fko_server_auth.c \ fko.h fko_limits.h fko_timestamp.c fko_hmac.c hmac.c hmac.h \ fko_user.c fko_user.h md5.c md5.h rijndael.c rijndael.h sha1.c \ sha1.h sha2.c sha2.h sha3.c sha3.h fko_context.h fko_state.h \ gpgme_funcs.c gpgme_funcs.h if WANT_C_UNIT_TESTS noinst_PROGRAMS = fko_utests fko_utests_SOURCES = fko_utests.c $(libfko_source_files) fko_utests_CPPFLAGS = -I $(top_builddir)/lib -I $(top_builddir)/common $(GPGME_CFLAGS) fko_utests_LDADD = $(top_builddir)/lib/libfko.la $(top_builddir)/common/libfko_util.a fko_utests_LDFLAGS = -lcunit $(GPGME_LIBS) libfko_la_LDFLAGS = -version-info 3:0:0 $(GPGME_LIBS) -export-symbols-regex '^fko_' \ -Wl,--whole-archive,$(top_builddir)/common/libfko_util.a,--no-whole-archive else if APPLE_PLATFORM libfko_la_LDFLAGS = -version-info 3:0:0 $(GPGME_LIBS) -export-symbols-regex '^fko_' \ -Wl,-force_load,$(top_builddir)/common/libfko_util.a else if USE_MINGW libfko_la_LDFLAGS = -version-info 3:0:0 $(GPGME_LIBS) \ -export-symbols-regex '^fko_' -no-undefined \ -Wl,--whole-archive,$(top_builddir)/common/libfko_util.a,--no-whole-archive,-lwsock32,-lws2_32 else libfko_la_LDFLAGS = -version-info 3:0:0 $(GPGME_LIBS) \ -export-symbols-regex '^fko_' \ -Wl,--whole-archive,$(top_builddir)/common/libfko_util.a,--no-whole-archive endif endif endif libfko_la_SOURCES = $(libfko_source_files) AM_CPPFLAGS = $(GPGME_CFLAGS) -I $(top_srcdir)/common include_HEADERS = fko.h clean-local: rm -f fko_utests *.gcno *.gcda fwknop-2.6.11/lib/fko_error.c0000664000175000017500000005175514560546213012755 00000000000000/** * \file lib/fko_error.c * * \brief Error handling functions for libfko */ /* Fwknop is developed primarily by the people listed in the file 'AUTHORS'. * Copyright (C) 2009-2015 fwknop developers and contributors. For a full * list of contributors, see the file 'CREDITS'. * * License (GNU General Public License): * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #include "fko_common.h" #include "fko.h" #if HAVE_LIBGPGME #include #endif const char* fko_errstr(const int err_code) { switch (err_code) { /* Start base FKO errors */ case FKO_SUCCESS: return("Success"); case FKO_ERROR_CTX_NOT_INITIALIZED: return("FKO Context is not initialized"); case FKO_ERROR_MEMORY_ALLOCATION: return("Unable to allocate memory"); case FKO_ERROR_FILESYSTEM_OPERATION: return("Read/write bytes mismatch"); case FKO_ERROR_INVALID_DATA: return("Args contain invalid data"); case FKO_ERROR_INVALID_DATA_CLIENT_TIMEOUT_NEGATIVE: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_CLIENT_TIMEOUT_NEGATIVE"); case FKO_ERROR_INVALID_DATA_DECODE_MSGLEN_VALIDFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_MSGLEN_VALIDFAIL"); case FKO_ERROR_INVALID_DATA_DECODE_NON_ASCII: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_NON_ASCII"); case FKO_ERROR_INVALID_DATA_DECODE_LT_MIN_FIELDS: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_LT_MIN_FIELDS"); case FKO_ERROR_INVALID_DATA_DECODE_GT_MAX_FIELDS: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_GT_MAX_FIELDS"); case FKO_ERROR_INVALID_DATA_DECODE_WRONG_NUM_FIELDS: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_WRONG_NUM_FIELDS"); case FKO_ERROR_INVALID_DATA_DECODE_ENC_MSG_LEN_MT_T_SIZE: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_ENC_MSG_LEN_MT_T_SIZE"); case FKO_ERROR_INVALID_DATA_DECODE_RAND_MISSING: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_RAND_MISSING"); case FKO_ERROR_INVALID_DATA_DECODE_USERNAME_MISSING: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_USERNAME_MISSING"); case FKO_ERROR_INVALID_DATA_DECODE_USERNAME_TOOBIG: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_USERNAME_TOOBIG"); case FKO_ERROR_INVALID_DATA_DECODE_USERNAME_DECODEFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_USERNAME_DECODEFAIL"); case FKO_ERROR_INVALID_DATA_DECODE_USERNAME_VALIDFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_USERNAME_VALIDFAIL"); case FKO_ERROR_INVALID_DATA_DECODE_TIMESTAMP_MISSING: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_TIMESTAMP_MISSING"); case FKO_ERROR_INVALID_DATA_DECODE_TIMESTAMP_TOOBIG: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_TIMESTAMP_TOOBIG"); case FKO_ERROR_INVALID_DATA_DECODE_TIMESTAMP_DECODEFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_TIMESTAMP_DECODEFAIL"); case FKO_ERROR_INVALID_DATA_DECODE_VERSION_MISSING: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_VERSION_MISSING"); case FKO_ERROR_INVALID_DATA_DECODE_VERSION_TOOBIG: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_VERSION_TOOBIG"); case FKO_ERROR_INVALID_DATA_DECODE_MSGTYPE_MISSING: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_MSGTYPE_MISSING"); case FKO_ERROR_INVALID_DATA_DECODE_MSGTYPE_TOOBIG: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_MSGTYPE_TOOBIG"); case FKO_ERROR_INVALID_DATA_DECODE_MSGTYPE_DECODEFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_MSGTYPE_DECODEFAIL"); case FKO_ERROR_INVALID_DATA_DECODE_MESSAGE_MISSING: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_MESSAGE_MISSING"); case FKO_ERROR_INVALID_DATA_DECODE_MESSAGE_TOOBIG: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_MESSAGE_TOOBIG"); case FKO_ERROR_INVALID_DATA_DECODE_MESSAGE_DECODEFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_MESSAGE_DECODEFAIL"); case FKO_ERROR_INVALID_DATA_DECODE_MESSAGE_VALIDFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_MESSAGE_VALIDFAIL"); case FKO_ERROR_INVALID_DATA_DECODE_ACCESS_VALIDFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_ACCESS_VALIDFAIL"); case FKO_ERROR_INVALID_DATA_DECODE_NATACCESS_MISSING: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_NATACCESS_MISSING"); case FKO_ERROR_INVALID_DATA_DECODE_NATACCESS_TOOBIG: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_NATACCESS_TOOBIG"); case FKO_ERROR_INVALID_DATA_DECODE_NATACCESS_DECODEFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_NATACCESS_DECODEFAIL"); case FKO_ERROR_INVALID_DATA_DECODE_NATACCESS_VALIDFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_NATACCESS_VALIDFAIL"); case FKO_ERROR_INVALID_DATA_DECODE_SRVAUTH_MISSING: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_SRVAUTH_MISSING"); case FKO_ERROR_INVALID_DATA_DECODE_SRVAUTH_DECODEFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_SRVAUTH_DECODEFAIL"); case FKO_ERROR_INVALID_DATA_DECODE_SPA_EXTRA_TOOBIG: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_SPA_EXTRA_TOOBIG"); case FKO_ERROR_INVALID_DATA_DECODE_EXTRA_TOOBIG: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_EXTRA_TOOBIG"); case FKO_ERROR_INVALID_DATA_DECODE_EXTRA_DECODEFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_EXTRA_DECODEFAIL"); case FKO_ERROR_INVALID_DATA_DECODE_TIMEOUT_MISSING: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_TIMEOUT_MISSING"); case FKO_ERROR_INVALID_DATA_DECODE_TIMEOUT_TOOBIG: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_TIMEOUT_TOOBIG"); case FKO_ERROR_INVALID_DATA_DECODE_TIMEOUT_VALIDFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_TIMEOUT_VALIDFAIL"); case FKO_ERROR_INVALID_DATA_DECODE_TIMEOUT_DECODEFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_TIMEOUT_DECODEFAIL"); case FKO_ERROR_INVALID_DATA_ENCODE_MESSAGE_TOOBIG: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCODE_MESSAGE_TOOBIG"); case FKO_ERROR_INVALID_DATA_ENCODE_MSGLEN_VALIDFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCODE_MSGLEN_VALIDFAIL"); case FKO_ERROR_INVALID_DATA_ENCODE_DIGEST_VALIDFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCODE_DIGEST_VALIDFAIL"); case FKO_ERROR_INVALID_DATA_ENCODE_DIGEST_TOOBIG: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCODE_DIGEST_TOOBIG"); case FKO_ERROR_INVALID_DATA_ENCODE_NOTBASE64: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCODE_NOTBASE64"); case FKO_ERROR_INVALID_DATA_ENCRYPT_MSGLEN_VALIDFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCRYPT_MSGLEN_VALIDFAIL"); case FKO_ERROR_INVALID_DATA_ENCRYPT_DIGESTLEN_VALIDFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCRYPT_DIGESTLEN_VALIDFAIL"); case FKO_ERROR_INVALID_DATA_ENCRYPT_PTLEN_VALIDFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCRYPT_PTLEN_VALIDFAIL"); case FKO_ERROR_INVALID_DATA_ENCRYPT_RESULT_MSGLEN_VALIDFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCRYPT_RESULT_MSGLEN_VALIDFAIL"); case FKO_ERROR_INVALID_DATA_ENCRYPT_CIPHERLEN_DECODEFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCRYPT_CIPHERLEN_DECODEFAIL"); case FKO_ERROR_INVALID_DATA_ENCRYPT_CIPHERLEN_VALIDFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCRYPT_CIPHERLEN_VALIDFAIL"); case FKO_ERROR_INVALID_DATA_ENCRYPT_DECRYPTED_MESSAGE_MISSING: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCRYPT_DECRYPTED_MESSAGE_MISSING"); case FKO_ERROR_INVALID_DATA_ENCRYPT_DECRYPTED_MSGLEN_VALIDFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCRYPT_DECRYPTED_MSGLEN_VALIDFAIL"); case FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_MESSAGE_VALIDFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_MESSAGE_VALIDFAIL"); case FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_DIGEST_VALIDFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_DIGEST_VALIDFAIL"); case FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_MSGLEN_VALIDFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_MSGLEN_VALIDFAIL"); case FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_RESULT_MSGLEN_VALIDFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_RESULT_MSGLEN_VALIDFAIL"); case FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_CIPHER_DECODEFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_CIPHER_DECODEFAIL"); case FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_ENCODEDMSG_NULL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_ENCODEDMSG_NULL"); case FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_ENCODEDMSGLEN_VALIDFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_ENCODEDMSGLEN_VALIDFAIL"); case FKO_ERROR_INVALID_DATA_ENCRYPT_TYPE_VALIDFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCRYPT_TYPE_VALIDFAIL"); case FKO_ERROR_INVALID_DATA_ENCRYPT_MODE_VALIDFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCRYPT_MODE_VALIDFAIL"); case FKO_ERROR_INVALID_DATA_ENCRYPT_TYPE_UNKNOWN: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCRYPT_TYPE_UNKNOWN"); case FKO_ERROR_INVALID_DATA_FUNCS_NEW_ENCMSG_MISSING: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_FUNCS_NEW_ENCMSG_MISSING"); case FKO_ERROR_INVALID_DATA_FUNCS_NEW_MSGLEN_VALIDFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_FUNCS_NEW_MSGLEN_VALIDFAIL"); case FKO_ERROR_INVALID_DATA_FUNCS_GEN_KEYLEN_VALIDFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_FUNCS_GEN_KEYLEN_VALIDFAIL"); case FKO_ERROR_INVALID_DATA_FUNCS_GEN_HMACLEN_VALIDFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_FUNCS_GEN_HMACLEN_VALIDFAIL"); case FKO_ERROR_INVALID_DATA_FUNCS_GEN_KEY_ENCODEFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_FUNCS_GEN_KEY_ENCODEFAIL"); case FKO_ERROR_INVALID_DATA_FUNCS_GEN_HMAC_ENCODEFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_FUNCS_GEN_HMAC_ENCODEFAIL"); case FKO_ERROR_INVALID_DATA_FUNCS_SET_MSGLEN_VALIDFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_FUNCS_SET_MSGLEN_VALIDFAIL"); case FKO_ERROR_INVALID_DATA_HMAC_MSGLEN_VALIDFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_HMAC_MSGLEN_VALIDFAIL"); case FKO_ERROR_INVALID_DATA_HMAC_ENCMSGLEN_VALIDFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_HMAC_ENCMSGLEN_VALIDFAIL"); case FKO_ERROR_INVALID_DATA_HMAC_COMPAREFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_HMAC_COMPAREFAIL"); case FKO_ERROR_INVALID_DATA_HMAC_TYPE_VALIDFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_HMAC_TYPE_VALIDFAIL"); case FKO_ERROR_INVALID_DATA_HMAC_LEN_VALIDFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_HMAC_LEN_VALIDFAIL"); case FKO_ERROR_INVALID_DATA_MESSAGE_PORT_MISSING: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_MESSAGE_PORT_MISSING"); case FKO_ERROR_INVALID_DATA_MESSAGE_TYPE_VALIDFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_MESSAGE_TYPE_VALIDFAIL"); case FKO_ERROR_INVALID_DATA_MESSAGE_EMPTY: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_MESSAGE_EMPTY"); case FKO_ERROR_INVALID_DATA_MESSAGE_CMD_MISSING: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_MESSAGE_CMD_MISSING"); case FKO_ERROR_INVALID_DATA_MESSAGE_ACCESS_MISSING: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_MESSAGE_ACCESS_MISSING"); case FKO_ERROR_INVALID_DATA_MESSAGE_NAT_MISSING: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_MESSAGE_NAT_MISSING"); case FKO_ERROR_INVALID_DATA_MESSAGE_PORTPROTO_MISSING: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_MESSAGE_PORTPROTO_MISSING"); case FKO_ERROR_INVALID_DATA_NAT_EMPTY: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_NAT_EMPTY"); case FKO_ERROR_INVALID_DATA_RAND_LEN_VALIDFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_RAND_LEN_VALIDFAIL"); case FKO_ERROR_INVALID_DATA_SRVAUTH_MISSING: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_SRVAUTH_MISSING"); case FKO_ERROR_INVALID_DATA_TIMESTAMP_VALIDFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_TIMESTAMP_VALIDFAIL"); case FKO_ERROR_INVALID_DATA_USER_MISSING: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_USER_MISSING"); case FKO_ERROR_INVALID_DATA_USER_FIRSTCHAR_VALIDFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_USER_FIRSTCHAR_VALIDFAIL"); case FKO_ERROR_INVALID_DATA_USER_REMCHAR_VALIDFAIL: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_USER_REMCHAR_VALIDFAIL"); case FKO_ERROR_INVALID_DATA_UTIL_STRTOL_LT_MIN: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_UTIL_STRTOL_LT_MIN"); case FKO_ERROR_INVALID_DATA_UTIL_STRTOL_GT_MAX: return("Args contain invalid data: FKO_ERROR_INVALID_DATA_UTIL_STRTOL_GT_MAX"); case FKO_ERROR_DATA_TOO_LARGE: return("Value or Size of the data exceeded the max allowed"); case FKO_ERROR_INVALID_KEY_LEN: return("Invalid key length"); case FKO_ERROR_USERNAME_UNKNOWN: return("Unable to determine username"); case FKO_ERROR_INCOMPLETE_SPA_DATA: return("Missing or incomplete SPA data"); case FKO_ERROR_MISSING_ENCODED_DATA: return("There is no encoded data to process"); case FKO_ERROR_INVALID_DIGEST_TYPE: return("Invalid digest type"); case FKO_ERROR_INVALID_ALLOW_IP: return("Invalid allow IP address in the SPA message data"); case FKO_ERROR_INVALID_SPA_COMMAND_MSG: return("Invalid SPA command message format"); case FKO_ERROR_INVALID_SPA_ACCESS_MSG: return("Invalid SPA access message format"); case FKO_ERROR_INVALID_SPA_NAT_ACCESS_MSG: return("Invalid SPA nat_access message format"); case FKO_ERROR_INVALID_ENCRYPTION_TYPE: return("Invalid encryption type"); case FKO_ERROR_WRONG_ENCRYPTION_TYPE: return("Wrong or inappropriate encryption type for this operation"); case FKO_ERROR_DECRYPTION_SIZE: return("Unexpected or invalid size for decrypted data"); case FKO_ERROR_DECRYPTION_FAILURE: return("Decryption failed or decrypted data is invalid"); case FKO_ERROR_DIGEST_VERIFICATION_FAILED: return("The computed digest did not match the digest in the spa data"); case FKO_ERROR_INVALID_HMAC_KEY_LEN: return("Invalid HMAC key length"); case FKO_ERROR_UNSUPPORTED_HMAC_MODE: return("Unsupported HMAC mode (default: SHA256)"); case FKO_ERROR_UNSUPPORTED_FEATURE: return("Unsupported or unimplemented feature or function"); case FKO_ERROR_ZERO_OUT_DATA: return("Could not zero out sensitive data"); case FKO_ERROR_UNKNOWN: return("Unknown/Unclassified error"); #if HAVE_LIBGPGME /* Start GPGME-related errors */ case FKO_ERROR_MISSING_GPG_KEY_DATA: return("Missing GPG key data (signer or recipient not set)"); case FKO_ERROR_GPGME_NO_OPENPGP: return("This GPGME implementation does not support OpenPGP"); case FKO_ERROR_GPGME_CONTEXT: return("Unable to create GPGME context"); case FKO_ERROR_GPGME_PLAINTEXT_DATA_OBJ: return("Error creating the plaintext data object"); case FKO_ERROR_GPGME_SET_PROTOCOL: return("Unable to set GPGME to use OpenPGP protocol"); case FKO_ERROR_GPGME_CIPHER_DATA_OBJ: return("Error creating the encrypted data data object"); case FKO_ERROR_GPGME_BAD_PASSPHRASE: return("The GPG passphrase was not valid"); case FKO_ERROR_GPGME_ENCRYPT_SIGN: return("Error during the encrypt and sign operation"); case FKO_ERROR_GPGME_CONTEXT_SIGNER_KEY: return("Unable to create GPGME context for the signer key"); case FKO_ERROR_GPGME_SIGNER_KEYLIST_START: return("Error from signer keylist start operation"); case FKO_ERROR_GPGME_SIGNER_KEY_NOT_FOUND: return("The key for the given signer was not found"); case FKO_ERROR_GPGME_SIGNER_KEY_AMBIGUOUS: return("Ambiguous name/id for the signer key (multiple matches)"); case FKO_ERROR_GPGME_ADD_SIGNER: return("Error adding the signer key to the gpgme context"); case FKO_ERROR_GPGME_CONTEXT_RECIPIENT_KEY: return("Unable to create GPGME context for the recipient key"); case FKO_ERROR_GPGME_RECIPIENT_KEYLIST_START: return("Error from signer keylist start operation"); case FKO_ERROR_GPGME_RECIPIENT_KEY_NOT_FOUND: return("The key for the given recipient was not found"); case FKO_ERROR_GPGME_RECIPIENT_KEY_AMBIGUOUS: return("Ambiguous name/id for the recipient key (multiple matches)"); case FKO_ERROR_GPGME_DECRYPT_FAILED: return("Decryption operation failed"); case FKO_ERROR_GPGME_DECRYPT_UNSUPPORTED_ALGORITHM: return("Decryption operation failed due to unsupported algorithm"); case FKO_ERROR_GPGME_BAD_GPG_EXE: return("Unable to stat the given GPG executable"); case FKO_ERROR_GPGME_BAD_HOME_DIR: return("Unable to stat the given GPG home directory"); case FKO_ERROR_GPGME_SET_HOME_DIR: return("Unable to set the given GPG home directory"); case FKO_ERROR_GPGME_NO_SIGNATURE: return("Missing GPG signature"); case FKO_ERROR_GPGME_BAD_SIGNATURE: return("Bad GPG signature"); case FKO_ERROR_GPGME_SIGNATURE_VERIFY_DISABLED: return("Trying to check signature with verification disabled"); #endif /* HAVE_LIBGPGME */ } #if !HAVE_LIBGPGME if(err_code > GPGME_ERR_START && err_code < FKO_LAST_ERROR) return("GPG-related error code given, but GPG is not supported"); #endif return("Undefined Error"); } const char* fko_gpg_errstr(fko_ctx_t ctx) { #if HAVE_LIBGPGME /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(""); if(ctx->gpg_err) return(gpgme_strerror(ctx->gpg_err)); #endif /* HAVE_LIBGPGME */ return(""); } /***EOF***/ fwknop-2.6.11/lib/fko_message.h0000664000175000017500000000267414560546213013251 00000000000000/** * \file lib/fko_message.h * * \brief Provide validation functions for SPA messages */ /* Fwknop is developed primarily by the people listed in the file 'AUTHORS'. * Copyright (C) 2009-2015 fwknop developers and contributors. For a full * list of contributors, see the file 'CREDITS'. * * License (GNU General Public License): * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #ifndef FKO_MESSAGE_H #define FKO_MESSAGE_H 1 /* SPA message format validation functions. */ int validate_cmd_msg(const char *msg); int validate_access_msg(const char *msg); int validate_nat_access_msg(const char *msg); int validate_proto_port_spec(const char *msg); #endif /* FKO_MESSAGE_H */ /***EOF***/ fwknop-2.6.11/lib/fko_user.c0000664000175000017500000001401714560546213012570 00000000000000/** * \file lib/fko_user.c * * \brief Set/Get the current username. */ /* Fwknop is developed primarily by the people listed in the file 'AUTHORS'. * Copyright (C) 2009-2015 fwknop developers and contributors. For a full * list of contributors, see the file 'CREDITS'. * * License (GNU General Public License): * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #include "fko_common.h" #include "fko.h" #ifdef __MINGW32__ #include "../win32/getlogin.h" #elif WIN32 #include #endif /* Get or Set the username for the fko context spa data. */ int fko_set_username(fko_ctx_t ctx, const char * const spoof_user) { char *username = NULL; int res = FKO_SUCCESS, is_user_heap_allocated=0; #if HAVE_LIBFIU fiu_return_on("fko_set_username_init", FKO_ERROR_CTX_NOT_INITIALIZED); #endif /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return FKO_ERROR_CTX_NOT_INITIALIZED; /* If spoof_user was not passed in, check for a SPOOF_USER environment * variable. If it is set, use its value. */ if(spoof_user != NULL && spoof_user[0] != '\0') { #if HAVE_LIBFIU fiu_return_on("fko_set_username_strdup", FKO_ERROR_MEMORY_ALLOCATION); #endif username = strdup(spoof_user); if(username == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); is_user_heap_allocated = 1; } else username = getenv("SPOOF_USER"); /* Try to get the username from the system. */ if(username == NULL) { /* Since we've already tried looking at an env variable, try * LOGNAME next (and the cuserid() man page recommends this) */ if((username = getenv("LOGNAME")) == NULL) { #ifdef _XOPEN_SOURCE /* cuserid will return the effective user (i.e. su or setuid). */ username = cuserid(NULL); #else username = getlogin(); #endif /* if we still didn't get a username, continue falling back */ if(username == NULL) { if((username = getenv("USER")) == NULL) { username = strdup("NO_USER"); if(username == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); is_user_heap_allocated = 1; } } } } /* Truncate the username if it is too long. */ if(strnlen(username, MAX_SPA_USERNAME_SIZE) == MAX_SPA_USERNAME_SIZE) *(username + MAX_SPA_USERNAME_SIZE - 1) = '\0'; if((res = validate_username(username)) != FKO_SUCCESS) { if(is_user_heap_allocated == 1) free(username); #if HAVE_LIBFIU fiu_return_on("fko_set_username_valuser", FKO_ERROR_INVALID_DATA); #endif return res; } /* Just in case this is a subsequent call to this function. We * do not want to be leaking memory. */ if(ctx->username != NULL) free(ctx->username); ctx->username = strdup(username); ctx->state |= FKO_DATA_MODIFIED; if(is_user_heap_allocated == 1) free(username); if(ctx->username == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); return(FKO_SUCCESS); } /* Return the current username for this fko context. */ int fko_get_username(fko_ctx_t ctx, char **username) { #if HAVE_LIBFIU fiu_return_on("fko_get_username_init", FKO_ERROR_CTX_NOT_INITIALIZED); #endif /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); if(username == NULL) return(FKO_ERROR_INVALID_DATA); #if HAVE_LIBFIU fiu_return_on("fko_get_username_val", FKO_ERROR_INVALID_DATA); #endif *username = ctx->username; return(FKO_SUCCESS); } int validate_username(const char *username) { int i; if(username == NULL || strnlen(username, MAX_SPA_USERNAME_SIZE) == 0) return(FKO_ERROR_INVALID_DATA_USER_MISSING); /* Exclude a few chars - this list is consistent with MS guidance since * libfko runs on Windows: * http://technet.microsoft.com/en-us/library/bb726984.aspx */ for (i=0; i < (int)strnlen(username, MAX_SPA_USERNAME_SIZE); i++) { if((isalnum((int)(unsigned char)username[i]) == 0) && ((username[i] < 0x20 || username[i] > 0x7e) /* Not allowed chars: " / \ [ ] : ; | = , + * ? < > */ || (username[i] == 0x22 || username[i] == 0x2f || username[i] == 0x5c || username[i] == 0x5b || username[i] == 0x5d || username[i] == 0x3a || username[i] == 0x3b || username[i] == 0x7c || username[i] == 0x3d || username[i] == 0x2c || username[i] == 0x2b || username[i] == 0x2a || username[i] == 0x3f || username[i] == 0x3c || username[i] == 0x3e))) { if(i == 0) { return(FKO_ERROR_INVALID_DATA_USER_FIRSTCHAR_VALIDFAIL); } else { return(FKO_ERROR_INVALID_DATA_USER_REMCHAR_VALIDFAIL); } } } return FKO_SUCCESS; } /***EOF***/ fwknop-2.6.11/lib/Makefile.in0000664000175000017500000024623114560546531012664 00000000000000# 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@ 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@ target_triplet = @target@ @WANT_C_UNIT_TESTS_TRUE@noinst_PROGRAMS = fko_utests$(EXEEXT) subdir = lib ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/gpgme.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(include_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = PROGRAMS = $(noinst_PROGRAMS) am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" LTLIBRARIES = $(lib_LTLIBRARIES) libfko_la_LIBADD = am__objects_1 = base64.lo cipher_funcs.lo digest.lo \ fko_client_timeout.lo fko_digest.lo fko_encode.lo \ fko_decode.lo fko_encryption.lo fko_error.lo fko_funcs.lo \ fko_message.lo fko_nat_access.lo fko_rand_value.lo \ fko_server_auth.lo fko_timestamp.lo fko_hmac.lo hmac.lo \ fko_user.lo md5.lo rijndael.lo sha1.lo sha2.lo sha3.lo \ gpgme_funcs.lo am_libfko_la_OBJECTS = $(am__objects_1) libfko_la_OBJECTS = $(am_libfko_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 = libfko_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libfko_la_LDFLAGS) $(LDFLAGS) -o $@ am__fko_utests_SOURCES_DIST = fko_utests.c base64.c base64.h \ cipher_funcs.c cipher_funcs.h digest.c digest.h \ fko_client_timeout.c fko_common.h fko_digest.c fko_encode.c \ fko_decode.c fko_encryption.c fko_error.c fko_funcs.c \ fko_message.c fko_message.h fko_nat_access.c fko_rand_value.c \ fko_server_auth.c fko.h fko_limits.h fko_timestamp.c \ fko_hmac.c hmac.c hmac.h fko_user.c fko_user.h md5.c md5.h \ rijndael.c rijndael.h sha1.c sha1.h sha2.c sha2.h sha3.c \ sha3.h fko_context.h fko_state.h gpgme_funcs.c gpgme_funcs.h am__objects_2 = fko_utests-base64.$(OBJEXT) \ fko_utests-cipher_funcs.$(OBJEXT) fko_utests-digest.$(OBJEXT) \ fko_utests-fko_client_timeout.$(OBJEXT) \ fko_utests-fko_digest.$(OBJEXT) \ fko_utests-fko_encode.$(OBJEXT) \ fko_utests-fko_decode.$(OBJEXT) \ fko_utests-fko_encryption.$(OBJEXT) \ fko_utests-fko_error.$(OBJEXT) fko_utests-fko_funcs.$(OBJEXT) \ fko_utests-fko_message.$(OBJEXT) \ fko_utests-fko_nat_access.$(OBJEXT) \ fko_utests-fko_rand_value.$(OBJEXT) \ fko_utests-fko_server_auth.$(OBJEXT) \ fko_utests-fko_timestamp.$(OBJEXT) \ fko_utests-fko_hmac.$(OBJEXT) fko_utests-hmac.$(OBJEXT) \ fko_utests-fko_user.$(OBJEXT) fko_utests-md5.$(OBJEXT) \ fko_utests-rijndael.$(OBJEXT) fko_utests-sha1.$(OBJEXT) \ fko_utests-sha2.$(OBJEXT) fko_utests-sha3.$(OBJEXT) \ fko_utests-gpgme_funcs.$(OBJEXT) @WANT_C_UNIT_TESTS_TRUE@am_fko_utests_OBJECTS = \ @WANT_C_UNIT_TESTS_TRUE@ fko_utests-fko_utests.$(OBJEXT) \ @WANT_C_UNIT_TESTS_TRUE@ $(am__objects_2) fko_utests_OBJECTS = $(am_fko_utests_OBJECTS) @WANT_C_UNIT_TESTS_TRUE@fko_utests_DEPENDENCIES = \ @WANT_C_UNIT_TESTS_TRUE@ $(top_builddir)/lib/libfko.la \ @WANT_C_UNIT_TESTS_TRUE@ $(top_builddir)/common/libfko_util.a fko_utests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(fko_utests_LDFLAGS) $(LDFLAGS) -o $@ 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)/config/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/base64.Plo \ ./$(DEPDIR)/cipher_funcs.Plo ./$(DEPDIR)/digest.Plo \ ./$(DEPDIR)/fko_client_timeout.Plo ./$(DEPDIR)/fko_decode.Plo \ ./$(DEPDIR)/fko_digest.Plo ./$(DEPDIR)/fko_encode.Plo \ ./$(DEPDIR)/fko_encryption.Plo ./$(DEPDIR)/fko_error.Plo \ ./$(DEPDIR)/fko_funcs.Plo ./$(DEPDIR)/fko_hmac.Plo \ ./$(DEPDIR)/fko_message.Plo ./$(DEPDIR)/fko_nat_access.Plo \ ./$(DEPDIR)/fko_rand_value.Plo ./$(DEPDIR)/fko_server_auth.Plo \ ./$(DEPDIR)/fko_timestamp.Plo ./$(DEPDIR)/fko_user.Plo \ ./$(DEPDIR)/fko_utests-base64.Po \ ./$(DEPDIR)/fko_utests-cipher_funcs.Po \ ./$(DEPDIR)/fko_utests-digest.Po \ ./$(DEPDIR)/fko_utests-fko_client_timeout.Po \ ./$(DEPDIR)/fko_utests-fko_decode.Po \ ./$(DEPDIR)/fko_utests-fko_digest.Po \ ./$(DEPDIR)/fko_utests-fko_encode.Po \ ./$(DEPDIR)/fko_utests-fko_encryption.Po \ ./$(DEPDIR)/fko_utests-fko_error.Po \ ./$(DEPDIR)/fko_utests-fko_funcs.Po \ ./$(DEPDIR)/fko_utests-fko_hmac.Po \ ./$(DEPDIR)/fko_utests-fko_message.Po \ ./$(DEPDIR)/fko_utests-fko_nat_access.Po \ ./$(DEPDIR)/fko_utests-fko_rand_value.Po \ ./$(DEPDIR)/fko_utests-fko_server_auth.Po \ ./$(DEPDIR)/fko_utests-fko_timestamp.Po \ ./$(DEPDIR)/fko_utests-fko_user.Po \ ./$(DEPDIR)/fko_utests-fko_utests.Po \ ./$(DEPDIR)/fko_utests-gpgme_funcs.Po \ ./$(DEPDIR)/fko_utests-hmac.Po ./$(DEPDIR)/fko_utests-md5.Po \ ./$(DEPDIR)/fko_utests-rijndael.Po \ ./$(DEPDIR)/fko_utests-sha1.Po ./$(DEPDIR)/fko_utests-sha2.Po \ ./$(DEPDIR)/fko_utests-sha3.Po ./$(DEPDIR)/gpgme_funcs.Plo \ ./$(DEPDIR)/hmac.Plo ./$(DEPDIR)/md5.Plo \ ./$(DEPDIR)/rijndael.Plo ./$(DEPDIR)/sha1.Plo \ ./$(DEPDIR)/sha2.Plo ./$(DEPDIR)/sha3.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 = $(libfko_la_SOURCES) $(fko_utests_SOURCES) DIST_SOURCES = $(libfko_la_SOURCES) $(am__fko_utests_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(include_HEADERS) 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)/config/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FIREWALLD_EXE = @FIREWALLD_EXE@ GPGME_CFLAGS = @GPGME_CFLAGS@ GPGME_CONFIG = @GPGME_CONFIG@ GPGME_LIBS = @GPGME_LIBS@ GPG_EXE = @GPG_EXE@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IPFW_EXE = @IPFW_EXE@ IPF_EXE = @IPF_EXE@ IPTABLES_EXE = @IPTABLES_EXE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PF_EXE = @PF_EXE@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ WGET_EXE = @WGET_EXE@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ lib_LTLIBRARIES = libfko.la libfko_source_files = \ base64.c base64.h cipher_funcs.c cipher_funcs.h digest.c digest.h \ fko_client_timeout.c fko_common.h fko_digest.c fko_encode.c \ fko_decode.c fko_encryption.c fko_error.c fko_funcs.c fko_message.c \ fko_message.h fko_nat_access.c fko_rand_value.c fko_server_auth.c \ fko.h fko_limits.h fko_timestamp.c fko_hmac.c hmac.c hmac.h \ fko_user.c fko_user.h md5.c md5.h rijndael.c rijndael.h sha1.c \ sha1.h sha2.c sha2.h sha3.c sha3.h fko_context.h fko_state.h \ gpgme_funcs.c gpgme_funcs.h @WANT_C_UNIT_TESTS_TRUE@fko_utests_SOURCES = fko_utests.c $(libfko_source_files) @WANT_C_UNIT_TESTS_TRUE@fko_utests_CPPFLAGS = -I $(top_builddir)/lib -I $(top_builddir)/common $(GPGME_CFLAGS) @WANT_C_UNIT_TESTS_TRUE@fko_utests_LDADD = $(top_builddir)/lib/libfko.la $(top_builddir)/common/libfko_util.a @WANT_C_UNIT_TESTS_TRUE@fko_utests_LDFLAGS = -lcunit $(GPGME_LIBS) @APPLE_PLATFORM_FALSE@@USE_MINGW_FALSE@@WANT_C_UNIT_TESTS_FALSE@libfko_la_LDFLAGS = -version-info 3:0:0 $(GPGME_LIBS) \ @APPLE_PLATFORM_FALSE@@USE_MINGW_FALSE@@WANT_C_UNIT_TESTS_FALSE@ -export-symbols-regex '^fko_' \ @APPLE_PLATFORM_FALSE@@USE_MINGW_FALSE@@WANT_C_UNIT_TESTS_FALSE@ -Wl,--whole-archive,$(top_builddir)/common/libfko_util.a,--no-whole-archive @APPLE_PLATFORM_FALSE@@USE_MINGW_TRUE@@WANT_C_UNIT_TESTS_FALSE@libfko_la_LDFLAGS = -version-info 3:0:0 $(GPGME_LIBS) \ @APPLE_PLATFORM_FALSE@@USE_MINGW_TRUE@@WANT_C_UNIT_TESTS_FALSE@ -export-symbols-regex '^fko_' -no-undefined \ @APPLE_PLATFORM_FALSE@@USE_MINGW_TRUE@@WANT_C_UNIT_TESTS_FALSE@ -Wl,--whole-archive,$(top_builddir)/common/libfko_util.a,--no-whole-archive,-lwsock32,-lws2_32 @APPLE_PLATFORM_TRUE@@WANT_C_UNIT_TESTS_FALSE@libfko_la_LDFLAGS = -version-info 3:0:0 $(GPGME_LIBS) -export-symbols-regex '^fko_' \ @APPLE_PLATFORM_TRUE@@WANT_C_UNIT_TESTS_FALSE@ -Wl,-force_load,$(top_builddir)/common/libfko_util.a @WANT_C_UNIT_TESTS_TRUE@libfko_la_LDFLAGS = -version-info 3:0:0 $(GPGME_LIBS) -export-symbols-regex '^fko_' \ @WANT_C_UNIT_TESTS_TRUE@ -Wl,--whole-archive,$(top_builddir)/common/libfko_util.a,--no-whole-archive libfko_la_SOURCES = $(libfko_source_files) AM_CPPFLAGS = $(GPGME_CFLAGS) -I $(top_srcdir)/common include_HEADERS = fko.h all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/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_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstPROGRAMS: @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ 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}; \ } libfko.la: $(libfko_la_OBJECTS) $(libfko_la_DEPENDENCIES) $(EXTRA_libfko_la_DEPENDENCIES) $(AM_V_CCLD)$(libfko_la_LINK) -rpath $(libdir) $(libfko_la_OBJECTS) $(libfko_la_LIBADD) $(LIBS) fko_utests$(EXEEXT): $(fko_utests_OBJECTS) $(fko_utests_DEPENDENCIES) $(EXTRA_fko_utests_DEPENDENCIES) @rm -f fko_utests$(EXEEXT) $(AM_V_CCLD)$(fko_utests_LINK) $(fko_utests_OBJECTS) $(fko_utests_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/base64.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher_funcs.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/digest.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_client_timeout.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_decode.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_digest.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_encode.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_encryption.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_error.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_funcs.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_hmac.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_message.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_nat_access.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_rand_value.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_server_auth.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_timestamp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_user.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_utests-base64.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_utests-cipher_funcs.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_utests-digest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_utests-fko_client_timeout.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_utests-fko_decode.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_utests-fko_digest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_utests-fko_encode.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_utests-fko_encryption.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_utests-fko_error.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_utests-fko_funcs.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_utests-fko_hmac.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_utests-fko_message.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_utests-fko_nat_access.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_utests-fko_rand_value.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_utests-fko_server_auth.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_utests-fko_timestamp.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_utests-fko_user.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_utests-fko_utests.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_utests-gpgme_funcs.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_utests-hmac.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_utests-md5.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_utests-rijndael.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_utests-sha1.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_utests-sha2.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fko_utests-sha3.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpgme_funcs.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hmac.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rijndael.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha1.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha2.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha3.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 $@ $< fko_utests-fko_utests.o: fko_utests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-fko_utests.o -MD -MP -MF $(DEPDIR)/fko_utests-fko_utests.Tpo -c -o fko_utests-fko_utests.o `test -f 'fko_utests.c' || echo '$(srcdir)/'`fko_utests.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-fko_utests.Tpo $(DEPDIR)/fko_utests-fko_utests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fko_utests.c' object='fko_utests-fko_utests.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-fko_utests.o `test -f 'fko_utests.c' || echo '$(srcdir)/'`fko_utests.c fko_utests-fko_utests.obj: fko_utests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-fko_utests.obj -MD -MP -MF $(DEPDIR)/fko_utests-fko_utests.Tpo -c -o fko_utests-fko_utests.obj `if test -f 'fko_utests.c'; then $(CYGPATH_W) 'fko_utests.c'; else $(CYGPATH_W) '$(srcdir)/fko_utests.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-fko_utests.Tpo $(DEPDIR)/fko_utests-fko_utests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fko_utests.c' object='fko_utests-fko_utests.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-fko_utests.obj `if test -f 'fko_utests.c'; then $(CYGPATH_W) 'fko_utests.c'; else $(CYGPATH_W) '$(srcdir)/fko_utests.c'; fi` fko_utests-base64.o: base64.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-base64.o -MD -MP -MF $(DEPDIR)/fko_utests-base64.Tpo -c -o fko_utests-base64.o `test -f 'base64.c' || echo '$(srcdir)/'`base64.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-base64.Tpo $(DEPDIR)/fko_utests-base64.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='base64.c' object='fko_utests-base64.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-base64.o `test -f 'base64.c' || echo '$(srcdir)/'`base64.c fko_utests-base64.obj: base64.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-base64.obj -MD -MP -MF $(DEPDIR)/fko_utests-base64.Tpo -c -o fko_utests-base64.obj `if test -f 'base64.c'; then $(CYGPATH_W) 'base64.c'; else $(CYGPATH_W) '$(srcdir)/base64.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-base64.Tpo $(DEPDIR)/fko_utests-base64.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='base64.c' object='fko_utests-base64.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-base64.obj `if test -f 'base64.c'; then $(CYGPATH_W) 'base64.c'; else $(CYGPATH_W) '$(srcdir)/base64.c'; fi` fko_utests-cipher_funcs.o: cipher_funcs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-cipher_funcs.o -MD -MP -MF $(DEPDIR)/fko_utests-cipher_funcs.Tpo -c -o fko_utests-cipher_funcs.o `test -f 'cipher_funcs.c' || echo '$(srcdir)/'`cipher_funcs.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-cipher_funcs.Tpo $(DEPDIR)/fko_utests-cipher_funcs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cipher_funcs.c' object='fko_utests-cipher_funcs.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-cipher_funcs.o `test -f 'cipher_funcs.c' || echo '$(srcdir)/'`cipher_funcs.c fko_utests-cipher_funcs.obj: cipher_funcs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-cipher_funcs.obj -MD -MP -MF $(DEPDIR)/fko_utests-cipher_funcs.Tpo -c -o fko_utests-cipher_funcs.obj `if test -f 'cipher_funcs.c'; then $(CYGPATH_W) 'cipher_funcs.c'; else $(CYGPATH_W) '$(srcdir)/cipher_funcs.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-cipher_funcs.Tpo $(DEPDIR)/fko_utests-cipher_funcs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cipher_funcs.c' object='fko_utests-cipher_funcs.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-cipher_funcs.obj `if test -f 'cipher_funcs.c'; then $(CYGPATH_W) 'cipher_funcs.c'; else $(CYGPATH_W) '$(srcdir)/cipher_funcs.c'; fi` fko_utests-digest.o: digest.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-digest.o -MD -MP -MF $(DEPDIR)/fko_utests-digest.Tpo -c -o fko_utests-digest.o `test -f 'digest.c' || echo '$(srcdir)/'`digest.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-digest.Tpo $(DEPDIR)/fko_utests-digest.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='digest.c' object='fko_utests-digest.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-digest.o `test -f 'digest.c' || echo '$(srcdir)/'`digest.c fko_utests-digest.obj: digest.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-digest.obj -MD -MP -MF $(DEPDIR)/fko_utests-digest.Tpo -c -o fko_utests-digest.obj `if test -f 'digest.c'; then $(CYGPATH_W) 'digest.c'; else $(CYGPATH_W) '$(srcdir)/digest.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-digest.Tpo $(DEPDIR)/fko_utests-digest.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='digest.c' object='fko_utests-digest.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-digest.obj `if test -f 'digest.c'; then $(CYGPATH_W) 'digest.c'; else $(CYGPATH_W) '$(srcdir)/digest.c'; fi` fko_utests-fko_client_timeout.o: fko_client_timeout.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-fko_client_timeout.o -MD -MP -MF $(DEPDIR)/fko_utests-fko_client_timeout.Tpo -c -o fko_utests-fko_client_timeout.o `test -f 'fko_client_timeout.c' || echo '$(srcdir)/'`fko_client_timeout.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-fko_client_timeout.Tpo $(DEPDIR)/fko_utests-fko_client_timeout.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fko_client_timeout.c' object='fko_utests-fko_client_timeout.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-fko_client_timeout.o `test -f 'fko_client_timeout.c' || echo '$(srcdir)/'`fko_client_timeout.c fko_utests-fko_client_timeout.obj: fko_client_timeout.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-fko_client_timeout.obj -MD -MP -MF $(DEPDIR)/fko_utests-fko_client_timeout.Tpo -c -o fko_utests-fko_client_timeout.obj `if test -f 'fko_client_timeout.c'; then $(CYGPATH_W) 'fko_client_timeout.c'; else $(CYGPATH_W) '$(srcdir)/fko_client_timeout.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-fko_client_timeout.Tpo $(DEPDIR)/fko_utests-fko_client_timeout.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fko_client_timeout.c' object='fko_utests-fko_client_timeout.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-fko_client_timeout.obj `if test -f 'fko_client_timeout.c'; then $(CYGPATH_W) 'fko_client_timeout.c'; else $(CYGPATH_W) '$(srcdir)/fko_client_timeout.c'; fi` fko_utests-fko_digest.o: fko_digest.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-fko_digest.o -MD -MP -MF $(DEPDIR)/fko_utests-fko_digest.Tpo -c -o fko_utests-fko_digest.o `test -f 'fko_digest.c' || echo '$(srcdir)/'`fko_digest.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-fko_digest.Tpo $(DEPDIR)/fko_utests-fko_digest.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fko_digest.c' object='fko_utests-fko_digest.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-fko_digest.o `test -f 'fko_digest.c' || echo '$(srcdir)/'`fko_digest.c fko_utests-fko_digest.obj: fko_digest.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-fko_digest.obj -MD -MP -MF $(DEPDIR)/fko_utests-fko_digest.Tpo -c -o fko_utests-fko_digest.obj `if test -f 'fko_digest.c'; then $(CYGPATH_W) 'fko_digest.c'; else $(CYGPATH_W) '$(srcdir)/fko_digest.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-fko_digest.Tpo $(DEPDIR)/fko_utests-fko_digest.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fko_digest.c' object='fko_utests-fko_digest.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-fko_digest.obj `if test -f 'fko_digest.c'; then $(CYGPATH_W) 'fko_digest.c'; else $(CYGPATH_W) '$(srcdir)/fko_digest.c'; fi` fko_utests-fko_encode.o: fko_encode.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-fko_encode.o -MD -MP -MF $(DEPDIR)/fko_utests-fko_encode.Tpo -c -o fko_utests-fko_encode.o `test -f 'fko_encode.c' || echo '$(srcdir)/'`fko_encode.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-fko_encode.Tpo $(DEPDIR)/fko_utests-fko_encode.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fko_encode.c' object='fko_utests-fko_encode.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-fko_encode.o `test -f 'fko_encode.c' || echo '$(srcdir)/'`fko_encode.c fko_utests-fko_encode.obj: fko_encode.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-fko_encode.obj -MD -MP -MF $(DEPDIR)/fko_utests-fko_encode.Tpo -c -o fko_utests-fko_encode.obj `if test -f 'fko_encode.c'; then $(CYGPATH_W) 'fko_encode.c'; else $(CYGPATH_W) '$(srcdir)/fko_encode.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-fko_encode.Tpo $(DEPDIR)/fko_utests-fko_encode.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fko_encode.c' object='fko_utests-fko_encode.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-fko_encode.obj `if test -f 'fko_encode.c'; then $(CYGPATH_W) 'fko_encode.c'; else $(CYGPATH_W) '$(srcdir)/fko_encode.c'; fi` fko_utests-fko_decode.o: fko_decode.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-fko_decode.o -MD -MP -MF $(DEPDIR)/fko_utests-fko_decode.Tpo -c -o fko_utests-fko_decode.o `test -f 'fko_decode.c' || echo '$(srcdir)/'`fko_decode.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-fko_decode.Tpo $(DEPDIR)/fko_utests-fko_decode.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fko_decode.c' object='fko_utests-fko_decode.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-fko_decode.o `test -f 'fko_decode.c' || echo '$(srcdir)/'`fko_decode.c fko_utests-fko_decode.obj: fko_decode.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-fko_decode.obj -MD -MP -MF $(DEPDIR)/fko_utests-fko_decode.Tpo -c -o fko_utests-fko_decode.obj `if test -f 'fko_decode.c'; then $(CYGPATH_W) 'fko_decode.c'; else $(CYGPATH_W) '$(srcdir)/fko_decode.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-fko_decode.Tpo $(DEPDIR)/fko_utests-fko_decode.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fko_decode.c' object='fko_utests-fko_decode.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-fko_decode.obj `if test -f 'fko_decode.c'; then $(CYGPATH_W) 'fko_decode.c'; else $(CYGPATH_W) '$(srcdir)/fko_decode.c'; fi` fko_utests-fko_encryption.o: fko_encryption.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-fko_encryption.o -MD -MP -MF $(DEPDIR)/fko_utests-fko_encryption.Tpo -c -o fko_utests-fko_encryption.o `test -f 'fko_encryption.c' || echo '$(srcdir)/'`fko_encryption.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-fko_encryption.Tpo $(DEPDIR)/fko_utests-fko_encryption.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fko_encryption.c' object='fko_utests-fko_encryption.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-fko_encryption.o `test -f 'fko_encryption.c' || echo '$(srcdir)/'`fko_encryption.c fko_utests-fko_encryption.obj: fko_encryption.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-fko_encryption.obj -MD -MP -MF $(DEPDIR)/fko_utests-fko_encryption.Tpo -c -o fko_utests-fko_encryption.obj `if test -f 'fko_encryption.c'; then $(CYGPATH_W) 'fko_encryption.c'; else $(CYGPATH_W) '$(srcdir)/fko_encryption.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-fko_encryption.Tpo $(DEPDIR)/fko_utests-fko_encryption.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fko_encryption.c' object='fko_utests-fko_encryption.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-fko_encryption.obj `if test -f 'fko_encryption.c'; then $(CYGPATH_W) 'fko_encryption.c'; else $(CYGPATH_W) '$(srcdir)/fko_encryption.c'; fi` fko_utests-fko_error.o: fko_error.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-fko_error.o -MD -MP -MF $(DEPDIR)/fko_utests-fko_error.Tpo -c -o fko_utests-fko_error.o `test -f 'fko_error.c' || echo '$(srcdir)/'`fko_error.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-fko_error.Tpo $(DEPDIR)/fko_utests-fko_error.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fko_error.c' object='fko_utests-fko_error.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-fko_error.o `test -f 'fko_error.c' || echo '$(srcdir)/'`fko_error.c fko_utests-fko_error.obj: fko_error.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-fko_error.obj -MD -MP -MF $(DEPDIR)/fko_utests-fko_error.Tpo -c -o fko_utests-fko_error.obj `if test -f 'fko_error.c'; then $(CYGPATH_W) 'fko_error.c'; else $(CYGPATH_W) '$(srcdir)/fko_error.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-fko_error.Tpo $(DEPDIR)/fko_utests-fko_error.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fko_error.c' object='fko_utests-fko_error.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-fko_error.obj `if test -f 'fko_error.c'; then $(CYGPATH_W) 'fko_error.c'; else $(CYGPATH_W) '$(srcdir)/fko_error.c'; fi` fko_utests-fko_funcs.o: fko_funcs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-fko_funcs.o -MD -MP -MF $(DEPDIR)/fko_utests-fko_funcs.Tpo -c -o fko_utests-fko_funcs.o `test -f 'fko_funcs.c' || echo '$(srcdir)/'`fko_funcs.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-fko_funcs.Tpo $(DEPDIR)/fko_utests-fko_funcs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fko_funcs.c' object='fko_utests-fko_funcs.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-fko_funcs.o `test -f 'fko_funcs.c' || echo '$(srcdir)/'`fko_funcs.c fko_utests-fko_funcs.obj: fko_funcs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-fko_funcs.obj -MD -MP -MF $(DEPDIR)/fko_utests-fko_funcs.Tpo -c -o fko_utests-fko_funcs.obj `if test -f 'fko_funcs.c'; then $(CYGPATH_W) 'fko_funcs.c'; else $(CYGPATH_W) '$(srcdir)/fko_funcs.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-fko_funcs.Tpo $(DEPDIR)/fko_utests-fko_funcs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fko_funcs.c' object='fko_utests-fko_funcs.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-fko_funcs.obj `if test -f 'fko_funcs.c'; then $(CYGPATH_W) 'fko_funcs.c'; else $(CYGPATH_W) '$(srcdir)/fko_funcs.c'; fi` fko_utests-fko_message.o: fko_message.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-fko_message.o -MD -MP -MF $(DEPDIR)/fko_utests-fko_message.Tpo -c -o fko_utests-fko_message.o `test -f 'fko_message.c' || echo '$(srcdir)/'`fko_message.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-fko_message.Tpo $(DEPDIR)/fko_utests-fko_message.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fko_message.c' object='fko_utests-fko_message.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-fko_message.o `test -f 'fko_message.c' || echo '$(srcdir)/'`fko_message.c fko_utests-fko_message.obj: fko_message.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-fko_message.obj -MD -MP -MF $(DEPDIR)/fko_utests-fko_message.Tpo -c -o fko_utests-fko_message.obj `if test -f 'fko_message.c'; then $(CYGPATH_W) 'fko_message.c'; else $(CYGPATH_W) '$(srcdir)/fko_message.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-fko_message.Tpo $(DEPDIR)/fko_utests-fko_message.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fko_message.c' object='fko_utests-fko_message.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-fko_message.obj `if test -f 'fko_message.c'; then $(CYGPATH_W) 'fko_message.c'; else $(CYGPATH_W) '$(srcdir)/fko_message.c'; fi` fko_utests-fko_nat_access.o: fko_nat_access.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-fko_nat_access.o -MD -MP -MF $(DEPDIR)/fko_utests-fko_nat_access.Tpo -c -o fko_utests-fko_nat_access.o `test -f 'fko_nat_access.c' || echo '$(srcdir)/'`fko_nat_access.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-fko_nat_access.Tpo $(DEPDIR)/fko_utests-fko_nat_access.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fko_nat_access.c' object='fko_utests-fko_nat_access.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-fko_nat_access.o `test -f 'fko_nat_access.c' || echo '$(srcdir)/'`fko_nat_access.c fko_utests-fko_nat_access.obj: fko_nat_access.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-fko_nat_access.obj -MD -MP -MF $(DEPDIR)/fko_utests-fko_nat_access.Tpo -c -o fko_utests-fko_nat_access.obj `if test -f 'fko_nat_access.c'; then $(CYGPATH_W) 'fko_nat_access.c'; else $(CYGPATH_W) '$(srcdir)/fko_nat_access.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-fko_nat_access.Tpo $(DEPDIR)/fko_utests-fko_nat_access.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fko_nat_access.c' object='fko_utests-fko_nat_access.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-fko_nat_access.obj `if test -f 'fko_nat_access.c'; then $(CYGPATH_W) 'fko_nat_access.c'; else $(CYGPATH_W) '$(srcdir)/fko_nat_access.c'; fi` fko_utests-fko_rand_value.o: fko_rand_value.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-fko_rand_value.o -MD -MP -MF $(DEPDIR)/fko_utests-fko_rand_value.Tpo -c -o fko_utests-fko_rand_value.o `test -f 'fko_rand_value.c' || echo '$(srcdir)/'`fko_rand_value.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-fko_rand_value.Tpo $(DEPDIR)/fko_utests-fko_rand_value.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fko_rand_value.c' object='fko_utests-fko_rand_value.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-fko_rand_value.o `test -f 'fko_rand_value.c' || echo '$(srcdir)/'`fko_rand_value.c fko_utests-fko_rand_value.obj: fko_rand_value.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-fko_rand_value.obj -MD -MP -MF $(DEPDIR)/fko_utests-fko_rand_value.Tpo -c -o fko_utests-fko_rand_value.obj `if test -f 'fko_rand_value.c'; then $(CYGPATH_W) 'fko_rand_value.c'; else $(CYGPATH_W) '$(srcdir)/fko_rand_value.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-fko_rand_value.Tpo $(DEPDIR)/fko_utests-fko_rand_value.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fko_rand_value.c' object='fko_utests-fko_rand_value.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-fko_rand_value.obj `if test -f 'fko_rand_value.c'; then $(CYGPATH_W) 'fko_rand_value.c'; else $(CYGPATH_W) '$(srcdir)/fko_rand_value.c'; fi` fko_utests-fko_server_auth.o: fko_server_auth.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-fko_server_auth.o -MD -MP -MF $(DEPDIR)/fko_utests-fko_server_auth.Tpo -c -o fko_utests-fko_server_auth.o `test -f 'fko_server_auth.c' || echo '$(srcdir)/'`fko_server_auth.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-fko_server_auth.Tpo $(DEPDIR)/fko_utests-fko_server_auth.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fko_server_auth.c' object='fko_utests-fko_server_auth.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-fko_server_auth.o `test -f 'fko_server_auth.c' || echo '$(srcdir)/'`fko_server_auth.c fko_utests-fko_server_auth.obj: fko_server_auth.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-fko_server_auth.obj -MD -MP -MF $(DEPDIR)/fko_utests-fko_server_auth.Tpo -c -o fko_utests-fko_server_auth.obj `if test -f 'fko_server_auth.c'; then $(CYGPATH_W) 'fko_server_auth.c'; else $(CYGPATH_W) '$(srcdir)/fko_server_auth.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-fko_server_auth.Tpo $(DEPDIR)/fko_utests-fko_server_auth.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fko_server_auth.c' object='fko_utests-fko_server_auth.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-fko_server_auth.obj `if test -f 'fko_server_auth.c'; then $(CYGPATH_W) 'fko_server_auth.c'; else $(CYGPATH_W) '$(srcdir)/fko_server_auth.c'; fi` fko_utests-fko_timestamp.o: fko_timestamp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-fko_timestamp.o -MD -MP -MF $(DEPDIR)/fko_utests-fko_timestamp.Tpo -c -o fko_utests-fko_timestamp.o `test -f 'fko_timestamp.c' || echo '$(srcdir)/'`fko_timestamp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-fko_timestamp.Tpo $(DEPDIR)/fko_utests-fko_timestamp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fko_timestamp.c' object='fko_utests-fko_timestamp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-fko_timestamp.o `test -f 'fko_timestamp.c' || echo '$(srcdir)/'`fko_timestamp.c fko_utests-fko_timestamp.obj: fko_timestamp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-fko_timestamp.obj -MD -MP -MF $(DEPDIR)/fko_utests-fko_timestamp.Tpo -c -o fko_utests-fko_timestamp.obj `if test -f 'fko_timestamp.c'; then $(CYGPATH_W) 'fko_timestamp.c'; else $(CYGPATH_W) '$(srcdir)/fko_timestamp.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-fko_timestamp.Tpo $(DEPDIR)/fko_utests-fko_timestamp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fko_timestamp.c' object='fko_utests-fko_timestamp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-fko_timestamp.obj `if test -f 'fko_timestamp.c'; then $(CYGPATH_W) 'fko_timestamp.c'; else $(CYGPATH_W) '$(srcdir)/fko_timestamp.c'; fi` fko_utests-fko_hmac.o: fko_hmac.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-fko_hmac.o -MD -MP -MF $(DEPDIR)/fko_utests-fko_hmac.Tpo -c -o fko_utests-fko_hmac.o `test -f 'fko_hmac.c' || echo '$(srcdir)/'`fko_hmac.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-fko_hmac.Tpo $(DEPDIR)/fko_utests-fko_hmac.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fko_hmac.c' object='fko_utests-fko_hmac.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-fko_hmac.o `test -f 'fko_hmac.c' || echo '$(srcdir)/'`fko_hmac.c fko_utests-fko_hmac.obj: fko_hmac.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-fko_hmac.obj -MD -MP -MF $(DEPDIR)/fko_utests-fko_hmac.Tpo -c -o fko_utests-fko_hmac.obj `if test -f 'fko_hmac.c'; then $(CYGPATH_W) 'fko_hmac.c'; else $(CYGPATH_W) '$(srcdir)/fko_hmac.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-fko_hmac.Tpo $(DEPDIR)/fko_utests-fko_hmac.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fko_hmac.c' object='fko_utests-fko_hmac.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-fko_hmac.obj `if test -f 'fko_hmac.c'; then $(CYGPATH_W) 'fko_hmac.c'; else $(CYGPATH_W) '$(srcdir)/fko_hmac.c'; fi` fko_utests-hmac.o: hmac.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-hmac.o -MD -MP -MF $(DEPDIR)/fko_utests-hmac.Tpo -c -o fko_utests-hmac.o `test -f 'hmac.c' || echo '$(srcdir)/'`hmac.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-hmac.Tpo $(DEPDIR)/fko_utests-hmac.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hmac.c' object='fko_utests-hmac.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-hmac.o `test -f 'hmac.c' || echo '$(srcdir)/'`hmac.c fko_utests-hmac.obj: hmac.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-hmac.obj -MD -MP -MF $(DEPDIR)/fko_utests-hmac.Tpo -c -o fko_utests-hmac.obj `if test -f 'hmac.c'; then $(CYGPATH_W) 'hmac.c'; else $(CYGPATH_W) '$(srcdir)/hmac.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-hmac.Tpo $(DEPDIR)/fko_utests-hmac.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hmac.c' object='fko_utests-hmac.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-hmac.obj `if test -f 'hmac.c'; then $(CYGPATH_W) 'hmac.c'; else $(CYGPATH_W) '$(srcdir)/hmac.c'; fi` fko_utests-fko_user.o: fko_user.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-fko_user.o -MD -MP -MF $(DEPDIR)/fko_utests-fko_user.Tpo -c -o fko_utests-fko_user.o `test -f 'fko_user.c' || echo '$(srcdir)/'`fko_user.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-fko_user.Tpo $(DEPDIR)/fko_utests-fko_user.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fko_user.c' object='fko_utests-fko_user.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-fko_user.o `test -f 'fko_user.c' || echo '$(srcdir)/'`fko_user.c fko_utests-fko_user.obj: fko_user.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-fko_user.obj -MD -MP -MF $(DEPDIR)/fko_utests-fko_user.Tpo -c -o fko_utests-fko_user.obj `if test -f 'fko_user.c'; then $(CYGPATH_W) 'fko_user.c'; else $(CYGPATH_W) '$(srcdir)/fko_user.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-fko_user.Tpo $(DEPDIR)/fko_utests-fko_user.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fko_user.c' object='fko_utests-fko_user.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-fko_user.obj `if test -f 'fko_user.c'; then $(CYGPATH_W) 'fko_user.c'; else $(CYGPATH_W) '$(srcdir)/fko_user.c'; fi` fko_utests-md5.o: md5.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-md5.o -MD -MP -MF $(DEPDIR)/fko_utests-md5.Tpo -c -o fko_utests-md5.o `test -f 'md5.c' || echo '$(srcdir)/'`md5.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-md5.Tpo $(DEPDIR)/fko_utests-md5.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='md5.c' object='fko_utests-md5.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-md5.o `test -f 'md5.c' || echo '$(srcdir)/'`md5.c fko_utests-md5.obj: md5.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-md5.obj -MD -MP -MF $(DEPDIR)/fko_utests-md5.Tpo -c -o fko_utests-md5.obj `if test -f 'md5.c'; then $(CYGPATH_W) 'md5.c'; else $(CYGPATH_W) '$(srcdir)/md5.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-md5.Tpo $(DEPDIR)/fko_utests-md5.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='md5.c' object='fko_utests-md5.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-md5.obj `if test -f 'md5.c'; then $(CYGPATH_W) 'md5.c'; else $(CYGPATH_W) '$(srcdir)/md5.c'; fi` fko_utests-rijndael.o: rijndael.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-rijndael.o -MD -MP -MF $(DEPDIR)/fko_utests-rijndael.Tpo -c -o fko_utests-rijndael.o `test -f 'rijndael.c' || echo '$(srcdir)/'`rijndael.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-rijndael.Tpo $(DEPDIR)/fko_utests-rijndael.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rijndael.c' object='fko_utests-rijndael.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-rijndael.o `test -f 'rijndael.c' || echo '$(srcdir)/'`rijndael.c fko_utests-rijndael.obj: rijndael.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-rijndael.obj -MD -MP -MF $(DEPDIR)/fko_utests-rijndael.Tpo -c -o fko_utests-rijndael.obj `if test -f 'rijndael.c'; then $(CYGPATH_W) 'rijndael.c'; else $(CYGPATH_W) '$(srcdir)/rijndael.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-rijndael.Tpo $(DEPDIR)/fko_utests-rijndael.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rijndael.c' object='fko_utests-rijndael.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-rijndael.obj `if test -f 'rijndael.c'; then $(CYGPATH_W) 'rijndael.c'; else $(CYGPATH_W) '$(srcdir)/rijndael.c'; fi` fko_utests-sha1.o: sha1.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-sha1.o -MD -MP -MF $(DEPDIR)/fko_utests-sha1.Tpo -c -o fko_utests-sha1.o `test -f 'sha1.c' || echo '$(srcdir)/'`sha1.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-sha1.Tpo $(DEPDIR)/fko_utests-sha1.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sha1.c' object='fko_utests-sha1.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-sha1.o `test -f 'sha1.c' || echo '$(srcdir)/'`sha1.c fko_utests-sha1.obj: sha1.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-sha1.obj -MD -MP -MF $(DEPDIR)/fko_utests-sha1.Tpo -c -o fko_utests-sha1.obj `if test -f 'sha1.c'; then $(CYGPATH_W) 'sha1.c'; else $(CYGPATH_W) '$(srcdir)/sha1.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-sha1.Tpo $(DEPDIR)/fko_utests-sha1.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sha1.c' object='fko_utests-sha1.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-sha1.obj `if test -f 'sha1.c'; then $(CYGPATH_W) 'sha1.c'; else $(CYGPATH_W) '$(srcdir)/sha1.c'; fi` fko_utests-sha2.o: sha2.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-sha2.o -MD -MP -MF $(DEPDIR)/fko_utests-sha2.Tpo -c -o fko_utests-sha2.o `test -f 'sha2.c' || echo '$(srcdir)/'`sha2.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-sha2.Tpo $(DEPDIR)/fko_utests-sha2.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sha2.c' object='fko_utests-sha2.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-sha2.o `test -f 'sha2.c' || echo '$(srcdir)/'`sha2.c fko_utests-sha2.obj: sha2.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-sha2.obj -MD -MP -MF $(DEPDIR)/fko_utests-sha2.Tpo -c -o fko_utests-sha2.obj `if test -f 'sha2.c'; then $(CYGPATH_W) 'sha2.c'; else $(CYGPATH_W) '$(srcdir)/sha2.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-sha2.Tpo $(DEPDIR)/fko_utests-sha2.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sha2.c' object='fko_utests-sha2.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-sha2.obj `if test -f 'sha2.c'; then $(CYGPATH_W) 'sha2.c'; else $(CYGPATH_W) '$(srcdir)/sha2.c'; fi` fko_utests-sha3.o: sha3.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-sha3.o -MD -MP -MF $(DEPDIR)/fko_utests-sha3.Tpo -c -o fko_utests-sha3.o `test -f 'sha3.c' || echo '$(srcdir)/'`sha3.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-sha3.Tpo $(DEPDIR)/fko_utests-sha3.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sha3.c' object='fko_utests-sha3.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-sha3.o `test -f 'sha3.c' || echo '$(srcdir)/'`sha3.c fko_utests-sha3.obj: sha3.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-sha3.obj -MD -MP -MF $(DEPDIR)/fko_utests-sha3.Tpo -c -o fko_utests-sha3.obj `if test -f 'sha3.c'; then $(CYGPATH_W) 'sha3.c'; else $(CYGPATH_W) '$(srcdir)/sha3.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-sha3.Tpo $(DEPDIR)/fko_utests-sha3.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sha3.c' object='fko_utests-sha3.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-sha3.obj `if test -f 'sha3.c'; then $(CYGPATH_W) 'sha3.c'; else $(CYGPATH_W) '$(srcdir)/sha3.c'; fi` fko_utests-gpgme_funcs.o: gpgme_funcs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-gpgme_funcs.o -MD -MP -MF $(DEPDIR)/fko_utests-gpgme_funcs.Tpo -c -o fko_utests-gpgme_funcs.o `test -f 'gpgme_funcs.c' || echo '$(srcdir)/'`gpgme_funcs.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-gpgme_funcs.Tpo $(DEPDIR)/fko_utests-gpgme_funcs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gpgme_funcs.c' object='fko_utests-gpgme_funcs.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-gpgme_funcs.o `test -f 'gpgme_funcs.c' || echo '$(srcdir)/'`gpgme_funcs.c fko_utests-gpgme_funcs.obj: gpgme_funcs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fko_utests-gpgme_funcs.obj -MD -MP -MF $(DEPDIR)/fko_utests-gpgme_funcs.Tpo -c -o fko_utests-gpgme_funcs.obj `if test -f 'gpgme_funcs.c'; then $(CYGPATH_W) 'gpgme_funcs.c'; else $(CYGPATH_W) '$(srcdir)/gpgme_funcs.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fko_utests-gpgme_funcs.Tpo $(DEPDIR)/fko_utests-gpgme_funcs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gpgme_funcs.c' object='fko_utests-gpgme_funcs.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fko_utests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fko_utests-gpgme_funcs.obj `if test -f 'gpgme_funcs.c'; then $(CYGPATH_W) 'gpgme_funcs.c'; else $(CYGPATH_W) '$(srcdir)/gpgme_funcs.c'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-includeHEADERS: $(include_HEADERS) @$(NORMAL_INSTALL) @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ done uninstall-includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) 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 $(PROGRAMS) $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: 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-libLTLIBRARIES clean-libtool clean-local \ clean-noinstPROGRAMS mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/base64.Plo -rm -f ./$(DEPDIR)/cipher_funcs.Plo -rm -f ./$(DEPDIR)/digest.Plo -rm -f ./$(DEPDIR)/fko_client_timeout.Plo -rm -f ./$(DEPDIR)/fko_decode.Plo -rm -f ./$(DEPDIR)/fko_digest.Plo -rm -f ./$(DEPDIR)/fko_encode.Plo -rm -f ./$(DEPDIR)/fko_encryption.Plo -rm -f ./$(DEPDIR)/fko_error.Plo -rm -f ./$(DEPDIR)/fko_funcs.Plo -rm -f ./$(DEPDIR)/fko_hmac.Plo -rm -f ./$(DEPDIR)/fko_message.Plo -rm -f ./$(DEPDIR)/fko_nat_access.Plo -rm -f ./$(DEPDIR)/fko_rand_value.Plo -rm -f ./$(DEPDIR)/fko_server_auth.Plo -rm -f ./$(DEPDIR)/fko_timestamp.Plo -rm -f ./$(DEPDIR)/fko_user.Plo -rm -f ./$(DEPDIR)/fko_utests-base64.Po -rm -f ./$(DEPDIR)/fko_utests-cipher_funcs.Po -rm -f ./$(DEPDIR)/fko_utests-digest.Po -rm -f ./$(DEPDIR)/fko_utests-fko_client_timeout.Po -rm -f ./$(DEPDIR)/fko_utests-fko_decode.Po -rm -f ./$(DEPDIR)/fko_utests-fko_digest.Po -rm -f ./$(DEPDIR)/fko_utests-fko_encode.Po -rm -f ./$(DEPDIR)/fko_utests-fko_encryption.Po -rm -f ./$(DEPDIR)/fko_utests-fko_error.Po -rm -f ./$(DEPDIR)/fko_utests-fko_funcs.Po -rm -f ./$(DEPDIR)/fko_utests-fko_hmac.Po -rm -f ./$(DEPDIR)/fko_utests-fko_message.Po -rm -f ./$(DEPDIR)/fko_utests-fko_nat_access.Po -rm -f ./$(DEPDIR)/fko_utests-fko_rand_value.Po -rm -f ./$(DEPDIR)/fko_utests-fko_server_auth.Po -rm -f ./$(DEPDIR)/fko_utests-fko_timestamp.Po -rm -f ./$(DEPDIR)/fko_utests-fko_user.Po -rm -f ./$(DEPDIR)/fko_utests-fko_utests.Po -rm -f ./$(DEPDIR)/fko_utests-gpgme_funcs.Po -rm -f ./$(DEPDIR)/fko_utests-hmac.Po -rm -f ./$(DEPDIR)/fko_utests-md5.Po -rm -f ./$(DEPDIR)/fko_utests-rijndael.Po -rm -f ./$(DEPDIR)/fko_utests-sha1.Po -rm -f ./$(DEPDIR)/fko_utests-sha2.Po -rm -f ./$(DEPDIR)/fko_utests-sha3.Po -rm -f ./$(DEPDIR)/gpgme_funcs.Plo -rm -f ./$(DEPDIR)/hmac.Plo -rm -f ./$(DEPDIR)/md5.Plo -rm -f ./$(DEPDIR)/rijndael.Plo -rm -f ./$(DEPDIR)/sha1.Plo -rm -f ./$(DEPDIR)/sha2.Plo -rm -f ./$(DEPDIR)/sha3.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-includeHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-libLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/base64.Plo -rm -f ./$(DEPDIR)/cipher_funcs.Plo -rm -f ./$(DEPDIR)/digest.Plo -rm -f ./$(DEPDIR)/fko_client_timeout.Plo -rm -f ./$(DEPDIR)/fko_decode.Plo -rm -f ./$(DEPDIR)/fko_digest.Plo -rm -f ./$(DEPDIR)/fko_encode.Plo -rm -f ./$(DEPDIR)/fko_encryption.Plo -rm -f ./$(DEPDIR)/fko_error.Plo -rm -f ./$(DEPDIR)/fko_funcs.Plo -rm -f ./$(DEPDIR)/fko_hmac.Plo -rm -f ./$(DEPDIR)/fko_message.Plo -rm -f ./$(DEPDIR)/fko_nat_access.Plo -rm -f ./$(DEPDIR)/fko_rand_value.Plo -rm -f ./$(DEPDIR)/fko_server_auth.Plo -rm -f ./$(DEPDIR)/fko_timestamp.Plo -rm -f ./$(DEPDIR)/fko_user.Plo -rm -f ./$(DEPDIR)/fko_utests-base64.Po -rm -f ./$(DEPDIR)/fko_utests-cipher_funcs.Po -rm -f ./$(DEPDIR)/fko_utests-digest.Po -rm -f ./$(DEPDIR)/fko_utests-fko_client_timeout.Po -rm -f ./$(DEPDIR)/fko_utests-fko_decode.Po -rm -f ./$(DEPDIR)/fko_utests-fko_digest.Po -rm -f ./$(DEPDIR)/fko_utests-fko_encode.Po -rm -f ./$(DEPDIR)/fko_utests-fko_encryption.Po -rm -f ./$(DEPDIR)/fko_utests-fko_error.Po -rm -f ./$(DEPDIR)/fko_utests-fko_funcs.Po -rm -f ./$(DEPDIR)/fko_utests-fko_hmac.Po -rm -f ./$(DEPDIR)/fko_utests-fko_message.Po -rm -f ./$(DEPDIR)/fko_utests-fko_nat_access.Po -rm -f ./$(DEPDIR)/fko_utests-fko_rand_value.Po -rm -f ./$(DEPDIR)/fko_utests-fko_server_auth.Po -rm -f ./$(DEPDIR)/fko_utests-fko_timestamp.Po -rm -f ./$(DEPDIR)/fko_utests-fko_user.Po -rm -f ./$(DEPDIR)/fko_utests-fko_utests.Po -rm -f ./$(DEPDIR)/fko_utests-gpgme_funcs.Po -rm -f ./$(DEPDIR)/fko_utests-hmac.Po -rm -f ./$(DEPDIR)/fko_utests-md5.Po -rm -f ./$(DEPDIR)/fko_utests-rijndael.Po -rm -f ./$(DEPDIR)/fko_utests-sha1.Po -rm -f ./$(DEPDIR)/fko_utests-sha2.Po -rm -f ./$(DEPDIR)/fko_utests-sha3.Po -rm -f ./$(DEPDIR)/gpgme_funcs.Plo -rm -f ./$(DEPDIR)/hmac.Plo -rm -f ./$(DEPDIR)/md5.Plo -rm -f ./$(DEPDIR)/rijndael.Plo -rm -f ./$(DEPDIR)/sha1.Plo -rm -f ./$(DEPDIR)/sha2.Plo -rm -f ./$(DEPDIR)/sha3.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: uninstall-includeHEADERS uninstall-libLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libLTLIBRARIES clean-libtool clean-local \ clean-noinstPROGRAMS 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-includeHEADERS install-info \ install-info-am install-libLTLIBRARIES install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-includeHEADERS \ uninstall-libLTLIBRARIES .PRECIOUS: Makefile clean-local: rm -f fko_utests *.gcno *.gcda # 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: fwknop-2.6.11/lib/fko_digest.c0000664000175000017500000002055114560546213013071 00000000000000/** * \file lib/fko_digest.c * * \brief Create the base64-encoded digest for the current spa data. The * digest used is determined by the digest_type setting in the * fko context. */ /* Fwknop is developed primarily by the people listed in the file 'AUTHORS'. * Copyright (C) 2009-2015 fwknop developers and contributors. For a full * list of contributors, see the file 'CREDITS'. * * License (GNU General Public License): * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #include "fko_common.h" #include "fko.h" #include "digest.h" /* Set the SPA digest type. */ static int set_spa_digest_type(fko_ctx_t ctx, short *digest_type_field, const short digest_type) { #if HAVE_LIBFIU fiu_return_on("set_spa_digest_type_init", FKO_ERROR_CTX_NOT_INITIALIZED); #endif /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); #if HAVE_LIBFIU fiu_return_on("set_spa_digest_type_val", FKO_ERROR_INVALID_DATA_ENCODE_DIGEST_VALIDFAIL); #endif if(digest_type < 1 || digest_type >= FKO_LAST_DIGEST_TYPE) return(FKO_ERROR_INVALID_DATA_ENCODE_DIGEST_VALIDFAIL); *digest_type_field = digest_type; ctx->state |= FKO_DIGEST_TYPE_MODIFIED; return(FKO_SUCCESS); } int fko_set_spa_digest_type(fko_ctx_t ctx, const short digest_type) { return set_spa_digest_type(ctx, &ctx->digest_type, digest_type); } int fko_set_raw_spa_digest_type(fko_ctx_t ctx, const short raw_digest_type) { return set_spa_digest_type(ctx, &ctx->raw_digest_type, raw_digest_type); } /* Return the SPA digest type. */ int fko_get_spa_digest_type(fko_ctx_t ctx, short *digest_type) { #if HAVE_LIBFIU fiu_return_on("fko_get_spa_digest_type_init", FKO_ERROR_CTX_NOT_INITIALIZED); #endif /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); #if HAVE_LIBFIU fiu_return_on("fko_get_spa_digest_type_val", FKO_ERROR_INVALID_DATA); #endif if(digest_type == NULL) return(FKO_ERROR_INVALID_DATA); *digest_type = ctx->digest_type; return(FKO_SUCCESS); } /* Return the SPA digest type. */ int fko_get_raw_spa_digest_type(fko_ctx_t ctx, short *raw_digest_type) { #if HAVE_LIBFIU fiu_return_on("fko_get_raw_spa_digest_type_init", FKO_ERROR_CTX_NOT_INITIALIZED); #endif /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); if(raw_digest_type == NULL) return(FKO_ERROR_INVALID_DATA); *raw_digest_type = ctx->raw_digest_type; return(FKO_SUCCESS); } static int set_digest(char *data, char **digest, short digest_type, int *digest_len) { char *md = NULL; int data_len; data_len = strnlen(data, MAX_SPA_ENCODED_MSG_SIZE); #if HAVE_LIBFIU fiu_return_on("set_digest_toobig", FKO_ERROR_INVALID_DATA_ENCODE_DIGEST_TOOBIG); #endif if(data_len == MAX_SPA_ENCODED_MSG_SIZE) return(FKO_ERROR_INVALID_DATA_ENCODE_DIGEST_TOOBIG); #if HAVE_LIBFIU fiu_return_on("set_digest_invalidtype", FKO_ERROR_INVALID_DIGEST_TYPE); fiu_return_on("set_digest_calloc", FKO_ERROR_MEMORY_ALLOCATION); #endif switch(digest_type) { case FKO_DIGEST_MD5: md = calloc(1, MD_HEX_SIZE(MD5_DIGEST_LEN)+1); if(md == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); md5_base64(md, (unsigned char*)data, data_len); *digest_len = MD5_B64_LEN; break; case FKO_DIGEST_SHA1: md = calloc(1, MD_HEX_SIZE(SHA1_DIGEST_LEN)+1); if(md == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); sha1_base64(md, (unsigned char*)data, data_len); *digest_len = SHA1_B64_LEN; break; case FKO_DIGEST_SHA256: md = calloc(1, MD_HEX_SIZE(SHA256_DIGEST_LEN)+1); if(md == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); sha256_base64(md, (unsigned char*)data, data_len); *digest_len = SHA256_B64_LEN; break; case FKO_DIGEST_SHA384: md = calloc(1, MD_HEX_SIZE(SHA384_DIGEST_LEN)+1); if(md == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); sha384_base64(md, (unsigned char*)data, data_len); *digest_len = SHA384_B64_LEN; break; case FKO_DIGEST_SHA512: md = calloc(1, MD_HEX_SIZE(SHA512_DIGEST_LEN)+1); if(md == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); sha512_base64(md, (unsigned char*)data, data_len); *digest_len = SHA512_B64_LEN; break; case FKO_DIGEST_SHA3_256: md = calloc(1, MD_HEX_SIZE(SHA3_256_DIGEST_LEN)+1); if(md == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); sha3_256_base64(md, (unsigned char*)data, data_len); *digest_len = SHA3_256_B64_LEN; break; case FKO_DIGEST_SHA3_512: md = calloc(1, MD_HEX_SIZE(SHA3_512_DIGEST_LEN)+1); if(md == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); sha3_512_base64(md, (unsigned char*)data, data_len); *digest_len = SHA3_512_B64_LEN; break; default: return(FKO_ERROR_INVALID_DIGEST_TYPE); } /* Just in case this is a subsequent call to this function. We * do not want to be leaking memory. */ if(*digest != NULL) free(*digest); *digest = md; return(FKO_SUCCESS); } int fko_set_spa_digest(fko_ctx_t ctx) { #if HAVE_LIBFIU fiu_return_on("fko_set_spa_digest_init", FKO_ERROR_CTX_NOT_INITIALIZED); #endif /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); /* Must have encoded message data to start with. */ if(ctx->encoded_msg == NULL) return(FKO_ERROR_MISSING_ENCODED_DATA); #if HAVE_LIBFIU fiu_return_on("fko_set_spa_digest_encoded", FKO_ERROR_MISSING_ENCODED_DATA); #endif return set_digest(ctx->encoded_msg, &ctx->digest, ctx->digest_type, &ctx->digest_len); } int fko_set_raw_spa_digest(fko_ctx_t ctx) { #if HAVE_LIBFIU fiu_return_on("fko_set_raw_spa_digest_init", FKO_ERROR_CTX_NOT_INITIALIZED); #endif /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); /* Must have encoded message data to start with. */ if(ctx->encrypted_msg == NULL) return(FKO_ERROR_MISSING_ENCODED_DATA); #if HAVE_LIBFIU fiu_return_on("fko_set_raw_spa_digest_val", FKO_ERROR_MISSING_ENCODED_DATA); #endif return set_digest(ctx->encrypted_msg, &ctx->raw_digest, ctx->raw_digest_type, &ctx->raw_digest_len); } int fko_get_spa_digest(fko_ctx_t ctx, char **md) { #if HAVE_LIBFIU fiu_return_on("fko_get_spa_digest_init", FKO_ERROR_CTX_NOT_INITIALIZED); #endif /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); #if HAVE_LIBFIU fiu_return_on("fko_get_spa_digest_val", FKO_ERROR_INVALID_DATA); #endif if(md == NULL) return(FKO_ERROR_INVALID_DATA); *md = ctx->digest; return(FKO_SUCCESS); } int fko_get_raw_spa_digest(fko_ctx_t ctx, char **md) { #if HAVE_LIBFIU fiu_return_on("fko_get_raw_spa_digest_init", FKO_ERROR_CTX_NOT_INITIALIZED); #endif /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); *md = ctx->raw_digest; return(FKO_SUCCESS); } /***EOF***/ fwknop-2.6.11/lib/sha2.h0000664000175000017500000001323314560546213011614 00000000000000/** * \file lib/sha2.h * * \brief Header for sha2.c - Implementation of the SHA 26/384/512 digests. */ /* AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/ * * Copyright (c) 2000-2001, Aaron D. Gifford * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holder nor the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ***************************************************************************** */ #ifndef __SHA2_H__ #define __SHA2_H__ #ifdef __cplusplus extern "C" { #endif #include "common.h" /* * Import u_intXX_t size_t type definitions from system headers. You * may need to change this, or define these things yourself in this * file. */ #include #if HAVE_INTTYPES_H #define SHA2_USE_INTTYPES_H #endif #ifdef SHA2_USE_INTTYPES_H #include #endif /* SHA2_USE_INTTYPES_H */ /* Make sure we keep this below the check above. */ #ifdef WIN32 #define SHA2_USE_INTTYPES_H 1 #endif /*** SHA-256/384/512 Various Length Definitions ***********************/ #define SHA256_BLOCK_LEN 64 #define SHA256_DIGEST_LEN 32 #define SHA256_DIGEST_STR_LEN (SHA256_DIGEST_LEN * 2 + 1) #define SHA256_B64_LEN 43 #define SHA384_BLOCK_LEN 128 #define SHA384_DIGEST_LEN 48 #define SHA384_DIGEST_STR_LEN (SHA384_DIGEST_LEN * 2 + 1) #define SHA384_B64_LEN 64 #define SHA512_BLOCK_LEN 128 #define SHA512_DIGEST_LEN 64 #define SHA512_DIGEST_STR_LEN (SHA512_DIGEST_LEN * 2 + 1) #define SHA512_B64_LEN 86 /*** SHA-256/384/512 Context Structures *******************************/ /* NOTE: If your architecture does not define either u_intXX_t types or * uintXX_t (from inttypes.h), you may need to define things by hand * for your system: */ #if 0 typedef unsigned char u_int8_t; /* 1-byte (8-bits) */ typedef unsigned int u_int32_t; /* 4-bytes (32-bits) */ typedef unsigned long long u_int64_t; /* 8-bytes (64-bits) */ #endif /* * Most BSD systems already define u_intXX_t types, as does Linux. * Some systems, however, like Compaq's Tru64 Unix instead can use * uintXX_t types defined by very recent ANSI C standards and included * in the file: * * #include * * If you choose to use then please define: * * #define SHA2_USE_INTTYPES_H * * Or on the command line during compile: * * cc -DSHA2_USE_INTTYPES_H ... */ #ifdef SHA2_USE_INTTYPES_H typedef struct _SHA256_CTX { uint32_t state[8]; uint64_t bitcount; uint8_t buffer[SHA256_BLOCK_LEN]; } SHA256_CTX; typedef struct _SHA512_CTX { uint64_t state[8]; uint64_t bitcount[2]; uint8_t buffer[SHA512_BLOCK_LEN]; } SHA512_CTX; #else /* SHA2_USE_INTTYPES_H */ typedef struct _SHA256_CTX { u_int32_t state[8]; u_int64_t bitcount; u_int8_t buffer[SHA256_BLOCK_LEN]; } SHA256_CTX; typedef struct _SHA512_CTX { u_int64_t state[8]; u_int64_t bitcount[2]; u_int8_t buffer[SHA512_BLOCK_LEN]; } SHA512_CTX; #endif /* SHA2_USE_INTTYPES_H */ typedef SHA512_CTX SHA384_CTX; /*** SHA-256/384/512 Function Prototypes ******************************/ #ifndef NOPROTO #ifdef SHA2_USE_INTTYPES_H void SHA256_Init(SHA256_CTX *); void SHA256_Update(SHA256_CTX*, const uint8_t*, size_t); void SHA256_Final(uint8_t[SHA256_DIGEST_LEN], SHA256_CTX*); void SHA384_Init(SHA384_CTX*); void SHA384_Update(SHA384_CTX*, const uint8_t*, size_t); void SHA384_Final(uint8_t[SHA384_DIGEST_LEN], SHA384_CTX*); void SHA512_Init(SHA512_CTX*); void SHA512_Update(SHA512_CTX*, const uint8_t*, size_t); void SHA512_Final(uint8_t[SHA512_DIGEST_LEN], SHA512_CTX*); #else /* SHA2_USE_INTTYPES_H */ void SHA256_Init(SHA256_CTX *); void SHA256_Update(SHA256_CTX*, const u_int8_t*, size_t); void SHA256_Final(u_int8_t[SHA256_DIGEST_LEN], SHA256_CTX*); void SHA384_Init(SHA384_CTX*); void SHA384_Update(SHA384_CTX*, const u_int8_t*, size_t); void SHA384_Final(u_int8_t[SHA384_DIGEST_LEN], SHA384_CTX*); void SHA512_Init(SHA512_CTX*); void SHA512_Update(SHA512_CTX*, const u_int8_t*, size_t); void SHA512_Final(u_int8_t[SHA512_DIGEST_LEN], SHA512_CTX*); #endif /* SHA2_USE_INTTYPES_H */ #else /* NOPROTO */ void SHA256_Init(); void SHA256_Update(); void SHA256_Final(); void SHA384_Init(); void SHA384_Update(); void SHA384_Final(); void SHA512_Init(); void SHA512_Update(); void SHA512_Final(); #endif /* NOPROTO */ #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* __SHA2_H__ */ fwknop-2.6.11/lib/md5.c0000664000175000017500000002115014560546213011434 00000000000000/** * \file lib/md5.c * * \brief Implementation of the MD5 message-digest algorithm for libfwknop. */ /* This code implements the MD5 message-digest algorithm. * * The algorithm is due to Ron Rivest. This code was * written by Colin Plumb in 1993, no copyright is claimed. * This code is in the public domain; do with it what you wish. * * Equivalent code is available from RSA Data Security, Inc. * This code has been tested against that, and is equivalent, * except that you don't need to include two pages of legalese * with every copy. * * To compute the message digest of a chunk of bytes, declare an * MD5Context structure, pass it to MD5Init, call MD5Update as * needed on buffers full of bytes, and then call MD5Final, which * will fill a supplied 16-byte array with the digest. * * This program 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. * ***************************************************************************** */ #include "md5.h" #include "fko_common.h" #if BYTEORDER == 1234 #define byteReverse(buf, len) /* Nothing */ #elif BYTEORDER == 4321 /* Note: this code is harmless on little-endian machines. */ void byteReverse(unsigned char *buf, unsigned longs) { uint32_t t; do { t = (uint32_t) ((unsigned) buf[3] << 8 | buf[2]) << 16 | ((unsigned) buf[1] << 8 | buf[0]); *(uint32_t *) buf = t; buf += 4; } while (--longs); } #else #define byteReverse(buf, len) /* Nothing */ #ifndef WIN32 #warning Undetermined or unsupported Byte Order... We will try LITTLE_ENDIAN #endif #endif /* * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious * initialization constants. */ void MD5Init(MD5Context *ctx) { ctx->buf[0] = 0x67452301; ctx->buf[1] = 0xefcdab89; ctx->buf[2] = 0x98badcfe; ctx->buf[3] = 0x10325476; ctx->bits[0] = 0; ctx->bits[1] = 0; } /* Update context to reflect the concatenation of another buffer full * of bytes. */ void MD5Update(MD5Context *ctx, unsigned char *buf, unsigned len) { uint32_t t; /* Update bitcount */ t = ctx->bits[0]; if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t) ctx->bits[1]++; /* Carry from low to high */ ctx->bits[1] += len >> 29; t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ /* Handle any leading odd-sized chunks */ if (t) { unsigned char *p = (unsigned char *) ctx->in + t; t = 64 - t; if (len < t) { memcpy(p, buf, len); return; } memcpy(p, buf, t); byteReverse(ctx->in, 16); MD5Transform(ctx->buf, (uint32_t *) ctx->in); buf += t; len -= t; } /* Process data in 64-byte chunks */ while (len >= 64) { memcpy(ctx->in, buf, 64); byteReverse(ctx->in, 16); MD5Transform(ctx->buf, (uint32_t *) ctx->in); buf += 64; len -= 64; } /* Handle any remaining bytes of data. */ memcpy(ctx->in, buf, len); } /* Final wrapup - pad to 64-byte boundary with the bit pattern * 1 0* (64-bit count of bits processed, MSB-first) */ void MD5Final(unsigned char digest[16], MD5Context *ctx) { unsigned count; unsigned char *p; /* Compute number of bytes mod 64 */ count = (ctx->bits[0] >> 3) & 0x3F; /* Set the first char of padding to 0x80. This is safe since there is * always at least one byte free */ p = ctx->in + count; *p++ = 0x80; /* Bytes of padding needed to make 64 bytes */ count = 64 - 1 - count; /* Pad out to 56 mod 64 */ if (count < 8) { /* Two lots of padding: Pad the first block to 64 bytes */ memset(p, 0, count); byteReverse(ctx->in, 16); MD5Transform(ctx->buf, (uint32_t *) ctx->in); /* Now fill the next block with 56 bytes */ memset(ctx->in, 0, 56); } else { /* Pad block to 56 bytes */ memset(p, 0, count - 8); } byteReverse(ctx->in, 14); /* Append length in bits and transform */ memcpy(&(ctx->in[56]), &(ctx->bits[0]), sizeof(uint32_t)); memcpy(&(ctx->in[60]), &(ctx->bits[1]), sizeof(uint32_t)); MD5Transform(ctx->buf, (uint32_t *) ctx->in); byteReverse((unsigned char *) ctx->buf, 4); memcpy(digest, ctx->buf, 16); memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ } /* The four core functions */ #define F1(x, y, z) (z ^ (x & (y ^ z))) #define F2(x, y, z) F1(z, x, y) #define F3(x, y, z) (x ^ y ^ z) #define F4(x, y, z) (y ^ (x | ~z)) /* This is the central step in the MD5 algorithm. */ #define MD5STEP(f, w, x, y, z, data, s) \ ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) /* The core of the MD5 algorithm, this alters an existing MD5 hash to * reflect the addition of 16 longwords of new data. MD5Update blocks * the data and converts bytes into longwords for this routine. */ void MD5Transform(uint32_t buf[4], uint32_t in[16]) { register uint32_t a, b, c, d; a = buf[0]; b = buf[1]; c = buf[2]; d = buf[3]; MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); buf[0] += a; buf[1] += b; buf[2] += c; buf[3] += d; } /***EOF***/ fwknop-2.6.11/lib/fko_hmac.c0000664000175000017500000002356114560546213012526 00000000000000/** * \file lib/fko_hmac.c * * \brief Provide HMAC support to SPA communications */ /* Fwknop is developed primarily by the people listed in the file 'AUTHORS'. * Copyright (C) 2009-2015 fwknop developers and contributors. For a full * list of contributors, see the file 'CREDITS'. * * License (GNU General Public License): * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #include "fko_common.h" #include "fko.h" #include "cipher_funcs.h" #include "hmac.h" #include "base64.h" int fko_verify_hmac(fko_ctx_t ctx, const char * const hmac_key, const int hmac_key_len) { char *hmac_digest_from_data = NULL; char *tbuf = NULL; int res = FKO_SUCCESS; int hmac_b64_digest_len = 0, zero_free_rv = FKO_SUCCESS; /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); if(hmac_key == NULL) return(FKO_ERROR_INVALID_DATA); if (! is_valid_encoded_msg_len(ctx->encrypted_msg_len)) return(FKO_ERROR_INVALID_DATA_HMAC_MSGLEN_VALIDFAIL); if(hmac_key_len < 0 || hmac_key_len > MAX_DIGEST_BLOCK_LEN) return(FKO_ERROR_INVALID_HMAC_KEY_LEN); if(ctx->hmac_type == FKO_HMAC_MD5) hmac_b64_digest_len = MD5_B64_LEN; else if(ctx->hmac_type == FKO_HMAC_SHA1) hmac_b64_digest_len = SHA1_B64_LEN; else if(ctx->hmac_type == FKO_HMAC_SHA256) hmac_b64_digest_len = SHA256_B64_LEN; else if(ctx->hmac_type == FKO_HMAC_SHA384) hmac_b64_digest_len = SHA384_B64_LEN; else if(ctx->hmac_type == FKO_HMAC_SHA512) hmac_b64_digest_len = SHA512_B64_LEN; else if(ctx->hmac_type == FKO_HMAC_SHA3_256) hmac_b64_digest_len = SHA3_256_B64_LEN; else if(ctx->hmac_type == FKO_HMAC_SHA3_512) hmac_b64_digest_len = SHA3_512_B64_LEN; else return(FKO_ERROR_UNSUPPORTED_HMAC_MODE); if((ctx->encrypted_msg_len - hmac_b64_digest_len) < MIN_SPA_ENCODED_MSG_SIZE) return(FKO_ERROR_INVALID_DATA_HMAC_ENCMSGLEN_VALIDFAIL); /* Get digest value */ hmac_digest_from_data = strndup((ctx->encrypted_msg + ctx->encrypted_msg_len - hmac_b64_digest_len), hmac_b64_digest_len); if(hmac_digest_from_data == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); /* Now we chop the HMAC digest off of the encrypted msg */ tbuf = strndup(ctx->encrypted_msg, ctx->encrypted_msg_len - hmac_b64_digest_len); if(tbuf == NULL) { if(zero_free(hmac_digest_from_data, strnlen(hmac_digest_from_data, MAX_SPA_ENCODED_MSG_SIZE)) == FKO_SUCCESS) return(FKO_ERROR_MEMORY_ALLOCATION); else return(FKO_ERROR_ZERO_OUT_DATA); } if(zero_free(ctx->encrypted_msg, ctx->encrypted_msg_len) != FKO_SUCCESS) zero_free_rv = FKO_ERROR_ZERO_OUT_DATA; ctx->encrypted_msg = tbuf; ctx->encrypted_msg_len -= hmac_b64_digest_len; if(ctx->encryption_mode == FKO_ENC_MODE_ASYMMETRIC) { /* See if we need to add the "hQ" string to the front of the * encrypted data. */ if(! ctx->added_gpg_prefix) { res = add_gpg_prefix(ctx); } } else { /* See if we need to add the "Salted__" string to the front of the * encrypted data. */ if(! ctx->added_salted_str) { res = add_salted_str(ctx); } } if (res != FKO_SUCCESS) { if(zero_free(hmac_digest_from_data, strnlen(hmac_digest_from_data, MAX_SPA_ENCODED_MSG_SIZE)) != FKO_SUCCESS) zero_free_rv = FKO_ERROR_ZERO_OUT_DATA; if(zero_free_rv == FKO_SUCCESS) return(res); else return(zero_free_rv); } /* Calculate the HMAC from the encrypted data and then * compare */ res = fko_set_spa_hmac_type(ctx, ctx->hmac_type); if(res == FKO_SUCCESS) { res = fko_set_spa_hmac(ctx, hmac_key, hmac_key_len); if(res == FKO_SUCCESS) { if(constant_runtime_cmp(hmac_digest_from_data, ctx->msg_hmac, hmac_b64_digest_len) != 0) { res = FKO_ERROR_INVALID_DATA_HMAC_COMPAREFAIL; } } } if(zero_free(hmac_digest_from_data, strnlen(hmac_digest_from_data, MAX_SPA_ENCODED_MSG_SIZE)) != FKO_SUCCESS) zero_free_rv = FKO_ERROR_ZERO_OUT_DATA; if(res == FKO_SUCCESS) return(zero_free_rv); else return(res); } /* Return the fko HMAC data */ int fko_get_spa_hmac(fko_ctx_t ctx, char **hmac_data) { /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); if(hmac_data == NULL) return(FKO_ERROR_INVALID_DATA); *hmac_data = ctx->msg_hmac; return(FKO_SUCCESS); } /* Set the HMAC type */ int fko_set_spa_hmac_type(fko_ctx_t ctx, const short hmac_type) { #if HAVE_LIBFIU fiu_return_on("fko_set_spa_hmac_type_init", FKO_ERROR_CTX_NOT_INITIALIZED); #endif /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); #if HAVE_LIBFIU fiu_return_on("fko_set_spa_hmac_type_val", FKO_ERROR_INVALID_DATA_HMAC_TYPE_VALIDFAIL); #endif if(hmac_type < 0 || hmac_type >= FKO_LAST_HMAC_MODE) return(FKO_ERROR_INVALID_DATA_HMAC_TYPE_VALIDFAIL); ctx->hmac_type = hmac_type; ctx->state |= FKO_HMAC_MODE_MODIFIED; return(FKO_SUCCESS); } /* Return the fko HMAC type */ int fko_get_spa_hmac_type(fko_ctx_t ctx, short *hmac_type) { /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); if(hmac_type == NULL) return(FKO_ERROR_INVALID_DATA); *hmac_type = ctx->hmac_type; return(FKO_SUCCESS); } int fko_set_spa_hmac(fko_ctx_t ctx, const char * const hmac_key, const int hmac_key_len) { unsigned char hmac[SHA512_DIGEST_STR_LEN] = {0}; char *hmac_base64 = NULL; int hmac_digest_str_len = 0; int hmac_digest_len = 0; int res = FKO_ERROR_UNKNOWN ; /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); if(hmac_key == NULL) return(FKO_ERROR_INVALID_DATA); if(hmac_key_len < 0 || hmac_key_len > MAX_DIGEST_BLOCK_LEN) return(FKO_ERROR_INVALID_HMAC_KEY_LEN); if(ctx->hmac_type == FKO_HMAC_MD5) { res = hmac_md5(ctx->encrypted_msg, ctx->encrypted_msg_len, hmac, hmac_key, hmac_key_len); hmac_digest_len = MD5_DIGEST_LEN; hmac_digest_str_len = MD5_DIGEST_STR_LEN; } else if(ctx->hmac_type == FKO_HMAC_SHA1) { res = hmac_sha1(ctx->encrypted_msg, ctx->encrypted_msg_len, hmac, hmac_key, hmac_key_len); hmac_digest_len = SHA1_DIGEST_LEN; hmac_digest_str_len = SHA1_DIGEST_STR_LEN; } else if(ctx->hmac_type == FKO_HMAC_SHA256) { res = hmac_sha256(ctx->encrypted_msg, ctx->encrypted_msg_len, hmac, hmac_key, hmac_key_len); hmac_digest_len = SHA256_DIGEST_LEN; hmac_digest_str_len = SHA256_DIGEST_STR_LEN; } else if(ctx->hmac_type == FKO_HMAC_SHA384) { res = hmac_sha384(ctx->encrypted_msg, ctx->encrypted_msg_len, hmac, hmac_key, hmac_key_len); hmac_digest_len = SHA384_DIGEST_LEN; hmac_digest_str_len = SHA384_DIGEST_STR_LEN; } else if(ctx->hmac_type == FKO_HMAC_SHA512) { res = hmac_sha512(ctx->encrypted_msg, ctx->encrypted_msg_len, hmac, hmac_key, hmac_key_len); hmac_digest_len = SHA512_DIGEST_LEN; hmac_digest_str_len = SHA512_DIGEST_STR_LEN; } else if(ctx->hmac_type == FKO_HMAC_SHA3_256) { res = hmac_sha3_256(ctx->encrypted_msg, ctx->encrypted_msg_len, hmac, hmac_key, hmac_key_len); hmac_digest_len = SHA3_256_DIGEST_LEN; hmac_digest_str_len = SHA3_256_DIGEST_STR_LEN; } else if(ctx->hmac_type == FKO_HMAC_SHA3_512) { res = hmac_sha3_512(ctx->encrypted_msg, ctx->encrypted_msg_len, hmac, hmac_key, hmac_key_len); hmac_digest_len = SHA3_512_DIGEST_LEN; hmac_digest_str_len = SHA3_512_DIGEST_STR_LEN; } if (res != FKO_SUCCESS) return res; hmac_base64 = calloc(1, MD_HEX_SIZE(hmac_digest_len)+1); if (hmac_base64 == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); b64_encode(hmac, hmac_base64, hmac_digest_len); strip_b64_eq(hmac_base64); if(ctx->msg_hmac != NULL) free(ctx->msg_hmac); ctx->msg_hmac = strdup(hmac_base64); free(hmac_base64); if(ctx->msg_hmac == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); ctx->msg_hmac_len = strnlen(ctx->msg_hmac, hmac_digest_str_len); switch(ctx->msg_hmac_len) { case MD5_B64_LEN: break; case SHA1_B64_LEN: break; case SHA256_B64_LEN: break; case SHA384_B64_LEN: break; case SHA512_B64_LEN: break; default: return(FKO_ERROR_INVALID_DATA_HMAC_LEN_VALIDFAIL); } return FKO_SUCCESS; } /***EOF***/ fwknop-2.6.11/lib/fko_rand_value.c0000664000175000017500000001113014560546213013723 00000000000000/** * \file lib/fko_rand_value.c * * \ Generate a 16-byte random numeric value. */ /* Fwknop is developed primarily by the people listed in the file 'AUTHORS'. * Copyright (C) 2009-2015 fwknop developers and contributors. For a full * list of contributors, see the file 'CREDITS'. * * License (GNU General Public License): * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #include "fko_common.h" #include "fko.h" #ifdef WIN32 #include #include #else #ifdef HAVE_SYS_TIME_H #include #ifdef TIME_WITH_SYS_TIME #include #endif #endif #define RAND_FILE "/dev/urandom" #endif /* Set/Generate the SPA data random value string. */ int fko_set_rand_value(fko_ctx_t ctx, const char * const new_val) { #ifdef WIN32 struct _timeb tb; #else FILE *rfd; struct timeval tv; size_t amt_read; #endif unsigned long seed; char *tmp_buf; #if HAVE_LIBFIU fiu_return_on("fko_set_rand_value_init", FKO_ERROR_CTX_NOT_INITIALIZED); #endif /* Context must be initialized. */ if(!CTX_INITIALIZED(ctx)) return FKO_ERROR_CTX_NOT_INITIALIZED; /* If a valid value was given, use it and return happy. */ if(new_val != NULL) { #if HAVE_LIBFIU fiu_return_on("fko_set_rand_value_lenval", FKO_ERROR_INVALID_DATA_RAND_LEN_VALIDFAIL); #endif if(strnlen(new_val, FKO_RAND_VAL_SIZE+1) != FKO_RAND_VAL_SIZE) return(FKO_ERROR_INVALID_DATA_RAND_LEN_VALIDFAIL); if(ctx->rand_val != NULL) free(ctx->rand_val); #if HAVE_LIBFIU fiu_return_on("fko_set_rand_value_strdup", FKO_ERROR_MEMORY_ALLOCATION); #endif ctx->rand_val = strdup(new_val); if(ctx->rand_val == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); ctx->state |= FKO_DATA_MODIFIED; return(FKO_SUCCESS); } #ifdef WIN32 _ftime_s(&tb); seed = ((tb.time * 1000) + tb.millitm) & 0xFFFFFFFF; #else /* Attempt to read seed data from /dev/urandom. If that does not * work, then fall back to a time-based method (less secure, but * probably more portable). */ if((rfd = fopen(RAND_FILE, "r")) != NULL) { /* Read seed from /dev/urandom */ amt_read = fread(&seed, 4, 1, rfd); fclose(rfd); #if HAVE_LIBFIU fiu_return_on("fko_set_rand_value_read", FKO_ERROR_FILESYSTEM_OPERATION); #endif if (amt_read != 1) return(FKO_ERROR_FILESYSTEM_OPERATION); } else { /* Seed based on time (current usecs). */ gettimeofday(&tv, NULL); seed = tv.tv_usec; } #endif srand(seed); if(ctx->rand_val != NULL) free(ctx->rand_val); #if HAVE_LIBFIU fiu_return_on("fko_set_rand_value_calloc1", FKO_ERROR_MEMORY_ALLOCATION); #endif ctx->rand_val = calloc(1, FKO_RAND_VAL_SIZE+1); if(ctx->rand_val == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); #if HAVE_LIBFIU fiu_return_on("fko_set_rand_value_calloc2", FKO_ERROR_MEMORY_ALLOCATION); #endif tmp_buf = calloc(1, FKO_RAND_VAL_SIZE+1); if(tmp_buf == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); snprintf(ctx->rand_val, FKO_RAND_VAL_SIZE, "%u", rand()); while(strnlen(ctx->rand_val, FKO_RAND_VAL_SIZE+1) < FKO_RAND_VAL_SIZE) { snprintf(tmp_buf, FKO_RAND_VAL_SIZE, "%u", rand()); strlcat(ctx->rand_val, tmp_buf, FKO_RAND_VAL_SIZE+1); } free(tmp_buf); ctx->state |= FKO_DATA_MODIFIED; return(FKO_SUCCESS); } /* Return the current rand value. */ int fko_get_rand_value(fko_ctx_t ctx, char **rand_value) { /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); if(rand_value == NULL) return(FKO_ERROR_INVALID_DATA); *rand_value = ctx->rand_val; return(FKO_SUCCESS); } /***EOF***/ fwknop-2.6.11/lib/fko_nat_access.c0000664000175000017500000000726614560546213013725 00000000000000/** * \file lib/fko_nat_access.c * * \brief Set/Get the spa nat access request data. */ /* Fwknop is developed primarily by the people listed in the file 'AUTHORS'. * Copyright (C) 2009-2015 fwknop developers and contributors. For a full * list of contributors, see the file 'CREDITS'. * * License (GNU General Public License): * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #include "fko_common.h" #include "fko.h" /* Set the SPA Nat Access data */ int fko_set_spa_nat_access(fko_ctx_t ctx, const char * const msg) { int res = FKO_SUCCESS; #if HAVE_LIBFIU fiu_return_on("fko_set_spa_nat_access_init", FKO_ERROR_CTX_NOT_INITIALIZED); #endif /* Context must be initialized. */ if(!CTX_INITIALIZED(ctx)) return FKO_ERROR_CTX_NOT_INITIALIZED; /* Gotta have a valid string. */ if(msg == NULL || strnlen(msg, MAX_SPA_NAT_ACCESS_SIZE) == 0) return(FKO_ERROR_INVALID_DATA_NAT_EMPTY); #if HAVE_LIBFIU fiu_return_on("fko_set_spa_nat_access_empty", FKO_ERROR_INVALID_DATA_NAT_EMPTY); #endif /* --DSS XXX: Bail out for now. But consider just * truncating in the future... */ if(strnlen(msg, MAX_SPA_NAT_ACCESS_SIZE) == MAX_SPA_NAT_ACCESS_SIZE) return(FKO_ERROR_DATA_TOO_LARGE); #if HAVE_LIBFIU fiu_return_on("fko_set_spa_nat_access_large", FKO_ERROR_DATA_TOO_LARGE); #endif if((res = validate_nat_access_msg(msg)) != FKO_SUCCESS) return(res); /* Just in case this is a subsequent call to this function. We * do not want to be leaking memory. */ if(ctx->nat_access != NULL) free(ctx->nat_access); ctx->nat_access = strdup(msg); ctx->state |= FKO_DATA_MODIFIED; if(ctx->nat_access == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); /* If we set the nat_access message Then we force the message_type * as well. Technically, the message type should be set already. * This will serve a half-protective measure. * --DSS XXX: should do this better. */ if(ctx->client_timeout > 0) { if(ctx->message_type != FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG) ctx->message_type = FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG; } else if(ctx->message_type != FKO_LOCAL_NAT_ACCESS_MSG && ctx->message_type != FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG) ctx->message_type = FKO_NAT_ACCESS_MSG; return(FKO_SUCCESS); } /* Return the SPA message data. */ int fko_get_spa_nat_access(fko_ctx_t ctx, char **nat_access) { #if HAVE_LIBFIU fiu_return_on("fko_get_spa_nat_access_init", FKO_ERROR_CTX_NOT_INITIALIZED); #endif /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); if(nat_access == NULL) return(FKO_ERROR_INVALID_DATA); #if HAVE_LIBFIU fiu_return_on("fko_get_spa_nat_access_val", FKO_ERROR_INVALID_DATA); #endif *nat_access = ctx->nat_access; return(FKO_SUCCESS); } /***EOF***/ fwknop-2.6.11/lib/sha3.h0000664000175000017500000000362214560546213011616 00000000000000/** * \file lib/sha3.h * * \brief header file for SHA3 routines */ #define SHA3_256_DIGEST_LEN 32 #define SHA3_512_DIGEST_LEN 64 #define SHA3_256_BLOCK_LEN 136 #define SHA3_512_BLOCK_LEN 72 #define SHA3_256_B64_LEN 43 #define SHA3_512_B64_LEN 86 #define SHA3_256_DIGEST_STR_LEN (SHA3_256_DIGEST_LEN * 2 + 1) #define SHA3_512_DIGEST_STR_LEN (SHA3_512_DIGEST_LEN * 2 + 1) void Keccak(unsigned int rate, unsigned int capacity, const unsigned char *input, unsigned long long int inputByteLen, unsigned char delimitedSuffix, unsigned char *output, unsigned long long int outputByteLen); /** * \brief Function to compute SHAKE128 on the input message with any output length. * * Not currently in use void FIPS202_SHAKE128(const unsigned char *input, unsigned int inputByteLen, unsigned char *output, int outputByteLen); */ /** * \brief Function to compute SHAKE256 on the input message with any output length. * * Not currently in use void FIPS202_SHAKE256(const unsigned char *input, unsigned int inputByteLen, unsigned char *output, int outputByteLen); */ /** * \brief Function to compute SHA3-224 on the input message. The output length is fixed to 28 bytes. void FIPS202_SHA3_224(const unsigned char *input, unsigned int inputByteLen, unsigned char *output); */ /** * \brief Function to compute SHA3-256 on the input message. The output length is fixed to 32 bytes. */ void FIPS202_SHA3_256(const unsigned char *input, unsigned int inputByteLen, unsigned char *output); /** * \brief Function to compute SHA3-384 on the input message. The output length is fixed to 48 bytes. void FIPS202_SHA3_384(const unsigned char *input, unsigned int inputByteLen, unsigned char *output); */ /** * \brief Function to compute SHA3-512 on the input message. The output length is fixed to 64 bytes. */ void FIPS202_SHA3_512(const unsigned char *input, unsigned int inputByteLen, unsigned char *output); fwknop-2.6.11/lib/rijndael.c0000664000175000017500000006075114560546213012551 00000000000000/** * \file lib/rijndael.c * * \brief rijndael - An implementation of the Rijndael cipher. */ /* Copyright (C) 2000, 2001 Rafael R. Sevilla * * Currently maintained by brian d foy, * * License (GNU General Public License): * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #include "fko_common.h" #include "rijndael.h" #include #include #include /* These tables combine both the S-boxes and the mixcolumn transformation, so that we can perform a round's encryption or by means of four table lookups and four XOR's per column of state. They were generated by the makertbls.pl script. */ uint32_t dtbl[] = { 0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, 0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591, 0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56, 0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec, 0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, 0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb, 0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, 0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b, 0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c, 0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83, 0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9, 0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a, 0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d, 0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f, 0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, 0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34, 0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b, 0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, 0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413, 0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1, 0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, 0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972, 0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85, 0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, 0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511, 0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe, 0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b, 0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05, 0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1, 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, 0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf, 0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3, 0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e, 0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, 0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3, 0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b, 0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428, 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad, 0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, 0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8, 0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, 0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2, 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, 0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf, 0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810, 0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c, 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697, 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, 0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, 0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc, 0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c, 0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, 0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27, 0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122, 0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433, 0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9, 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5, 0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, 0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0, 0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e, 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c, }; uint32_t itbl[] = { 0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a, 0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b, 0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5, 0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5, 0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d, 0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b, 0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295, 0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e, 0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927, 0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d, 0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362, 0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9, 0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52, 0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566, 0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3, 0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed, 0x2b1ccf8a, 0x92b479a7, 0xf0f207f3, 0xa1e2694e, 0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4, 0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4, 0x39ec830b, 0xaaef6040, 0x069f715e, 0x51106ebd, 0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d, 0xb58d5491, 0x055dc471, 0x6fd40604, 0xff155060, 0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967, 0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879, 0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000, 0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c, 0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36, 0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624, 0xb1670a0c, 0x0fe75793, 0xd296eeb4, 0x9e919b1b, 0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c, 0x0aba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12, 0x0b0d090e, 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14, 0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3, 0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b, 0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8, 0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684, 0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7, 0x4b2f9e1d, 0xf330b2dc, 0xec52860d, 0xd0e3c177, 0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947, 0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322, 0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498, 0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f, 0xe49d3a2c, 0x0d927850, 0x9bcc5f6a, 0x62467e54, 0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382, 0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf, 0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb, 0x097826cd, 0xf418596e, 0x01b79aec, 0xa89a4f83, 0x656e95e6, 0x7ee6ffaa, 0x08cfbc21, 0xe6e815ef, 0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029, 0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235, 0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733, 0x4a9804f1, 0xf7daec41, 0x0e50cd7f, 0x2ff69117, 0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4, 0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546, 0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb, 0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d, 0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb, 0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a, 0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773, 0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478, 0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2, 0x72c31d16, 0x0c25e2bc, 0x8b493c28, 0x41950dff, 0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664, 0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0, }; /* Needed only for the key schedule and for final rounds */ uint8_t sbox[256] = { 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168, 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210, 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115, 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22, }; uint8_t isbox[256] = { 82, 9, 106, 213, 48, 54, 165, 56, 191, 64, 163, 158, 129, 243, 215, 251, 124, 227, 57, 130, 155, 47, 255, 135, 52, 142, 67, 68, 196, 222, 233, 203, 84, 123, 148, 50, 166, 194, 35, 61, 238, 76, 149, 11, 66, 250, 195, 78, 8, 46, 161, 102, 40, 217, 36, 178, 118, 91, 162, 73, 109, 139, 209, 37, 114, 248, 246, 100, 134, 104, 152, 22, 212, 164, 92, 204, 93, 101, 182, 146, 108, 112, 72, 80, 253, 237, 185, 218, 94, 21, 70, 87, 167, 141, 157, 132, 144, 216, 171, 0, 140, 188, 211, 10, 247, 228, 88, 5, 184, 179, 69, 6, 208, 44, 30, 143, 202, 63, 15, 2, 193, 175, 189, 3, 1, 19, 138, 107, 58, 145, 17, 65, 79, 103, 220, 234, 151, 242, 207, 206, 240, 180, 230, 115, 150, 172, 116, 34, 231, 173, 53, 133, 226, 249, 55, 232, 28, 117, 223, 110, 71, 241, 26, 113, 29, 41, 197, 137, 111, 183, 98, 14, 170, 24, 190, 27, 252, 86, 62, 75, 198, 210, 121, 32, 154, 219, 192, 254, 120, 205, 90, 244, 31, 221, 168, 51, 136, 7, 199, 49, 177, 18, 16, 89, 39, 128, 236, 95, 96, 81, 127, 169, 25, 181, 74, 13, 45, 229, 122, 159, 147, 201, 156, 239, 160, 224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83, 153, 97, 23, 43, 4, 126, 186, 119, 214, 38, 225, 105, 20, 99, 85, 33, 12, 125, }; /* Used only by the key schedule */ uint8_t Logtable[256] = { 0, 0, 25, 1, 50, 2, 26, 198, 75, 199, 27, 104, 51, 238, 223, 3, 100, 4, 224, 14, 52, 141, 129, 239, 76, 113, 8, 200, 248, 105, 28, 193, 125, 194, 29, 181, 249, 185, 39, 106, 77, 228, 166, 114, 154, 201, 9, 120, 101, 47, 138, 5, 33, 15, 225, 36, 18, 240, 130, 69, 53, 147, 218, 142, 150, 143, 219, 189, 54, 208, 206, 148, 19, 92, 210, 241, 64, 70, 131, 56, 102, 221, 253, 48, 191, 6, 139, 98, 179, 37, 226, 152, 34, 136, 145, 16, 126, 110, 72, 195, 163, 182, 30, 66, 58, 107, 40, 84, 250, 133, 61, 186, 43, 121, 10, 21, 155, 159, 94, 202, 78, 212, 172, 229, 243, 115, 167, 87, 175, 88, 168, 80, 244, 234, 214, 116, 79, 174, 233, 213, 231, 230, 173, 232, 44, 215, 117, 122, 235, 22, 11, 245, 89, 203, 95, 176, 156, 169, 81, 160, 127, 12, 246, 111, 23, 196, 73, 236, 216, 67, 31, 45, 164, 118, 123, 183, 204, 187, 62, 90, 251, 96, 177, 134, 59, 82, 161, 108, 170, 85, 41, 157, 151, 178, 135, 144, 97, 190, 220, 252, 188, 149, 207, 205, 55, 63, 91, 209, 83, 57, 132, 60, 65, 162, 109, 71, 20, 42, 158, 93, 86, 242, 211, 171, 68, 17, 146, 217, 35, 32, 46, 137, 180, 124, 184, 38, 119, 153, 227, 165, 103, 74, 237, 222, 197, 49, 254, 24, 13, 99, 140, 128, 192, 247, 112, 7, }; uint8_t Alogtable[256] = { 1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 19, 53, 95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10, 30, 34, 102, 170, 229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217, 112, 144, 171, 230, 49, 83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104, 184, 211, 110, 178, 205, 76, 212, 103, 169, 224, 59, 77, 215, 98, 166, 241, 8, 24, 40, 120, 136, 131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154, 181, 196, 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163, 254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32, 96, 160, 251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86, 250, 21, 63, 65, 195, 94, 226, 61, 71, 201, 64, 192, 91, 237, 44, 116, 156, 191, 218, 117, 159, 186, 213, 100, 172, 239, 42, 126, 130, 157, 188, 223, 122, 142, 137, 128, 155, 182, 193, 88, 232, 35, 101, 175, 234, 37, 111, 177, 200, 67, 197, 84, 252, 31, 33, 99, 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202, 69, 207, 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14, 18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242, 13, 23, 57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180, 199, 82, 246, 1, }; #define ROTBYTE(x) (((x) >> 8) | (((x) & 0xff) << 24)) #define ROTRBYTE(x) (((x) << 8) | (((x) >> 24) & 0xff)) #define SUBBYTE(x, box) (((box)[((x) & 0xff)]) | \ ((box)[(((x) >> 8) & 0xff)] << 8) | \ ((box)[(((x) >> 16) & 0xff)] << 16) | \ ((box)[(((x) >> 24) & 0xff)] << 24)) static uint8_t xtime(uint8_t a) { uint8_t b; b = (a & 0x80) ? 0x1b : 0; a<<=1; a^=b; return(a); } static uint8_t mul(uint8_t a, uint8_t b) { if (a && b) return Alogtable[(Logtable[a] + Logtable[b])%255]; else return 0; } static void inv_mix_column(uint32_t *a, uint32_t *b) { uint8_t c[4][4]; int i, j; for(j = 0; j < 4; j++) { for(i = 0; i < 4; i++) { c[j][i] = mul(0xe, (a[j] >> i*8) & 0xff) ^ mul(0xb, (a[j] >> ((i+1)%4)*8) & 0xff) ^ mul(0xd, (a[j] >> ((i+2)%4)*8) & 0xff) ^ mul(0x9, (a[j] >> ((i+3)%4)*8) & 0xff); } } for(i = 0; i < 4; i++) { b[i] = 0; for(j = 0; j < 4; j++) b[i] |= c[i][j] << (j*8); } } void rijndael_setup(RIJNDAEL_context *ctx, const size_t keysize, const uint8_t *key) { int nk, nr, i, lastkey; uint32_t temp, rcon; /* Truncate keysizes to the valid key sizes provided by Rijndael */ if (keysize >= RIJNDAEL_MAX_KEYSIZE) { nk = 8; nr = 14; } else if (keysize >= 24) { nk = 6; nr = 12; } else { /* must be 16 or more */ nk = 4; nr = 10; } lastkey = (RIJNDAEL_BLOCKSIZE/4) * (nr + 1); ctx->nrounds = nr; rcon = 1; for (i=0; ikeys[i] = key[i*4] + (key[i*4+1]<<8) + (key[i*4+2]<<16) + (key[i*4+3]<<24); } for (i=nk; ikeys[i-1]; if (i % nk == 0) { temp = SUBBYTE(ROTBYTE(temp), sbox) ^ rcon; rcon = (uint32_t)xtime((uint8_t)rcon&0xff); } else if (nk > 6 && (i%nk) == 4) { temp = SUBBYTE(temp, sbox); } ctx->keys[i] = ctx->keys[i-nk] ^ temp; } /* Generate the inverse keys */ for (i=0; i<4; i++) { ctx->ikeys[i] = ctx->keys[i]; ctx->ikeys[lastkey-4 + i] = ctx->keys[lastkey-4 + i]; } for (i=4; ikeys[i]), &(ctx->ikeys[i])); } /* Key addition that also packs every byte in the key to a word rep. */ static void key_addition_8to32(const uint8_t *txt, uint32_t *keys, uint32_t *out) { const uint8_t *ptr; int i, j; uint32_t val; ptr = txt; for (i=0; i<4; i++) { val = 0; for (j=0; j<4; j++) val |= (*ptr++ << 8*j); out[i] = keys[i]^val; } } static void key_addition32(const uint32_t *txt, uint32_t *keys, uint32_t *out) { int i; for (i=0; i<4; i++) out[i] = keys[i] ^ txt[i]; } static void key_addition32to8(const uint32_t *txt, uint32_t *keys, uint8_t *out) { uint8_t *ptr; int i, j; uint32_t val; ptr = out; for (i=0; i<4; i++) { val = txt[i] ^ keys[i]; for (j=0; j<4; j++) *ptr++ = (val >> 8*j) & 0xff; } } static int idx[4][4] = { { 0, 1, 2, 3 }, { 1, 2, 3, 0 }, { 2, 3, 0, 1 }, { 3, 0, 1, 2 } }; void rijndael_encrypt(RIJNDAEL_context *ctx, const uint8_t *plaintext, uint8_t *ciphertext) { int r, j; uint32_t wtxt[4], t[4]; /* working ciphertext */ uint32_t e; key_addition_8to32(plaintext, &(ctx->keys[0]), wtxt); for (r=1; rnrounds; r++) { for (j=0; j<4; j++) { t[j] = dtbl[wtxt[j] & 0xff] ^ ROTRBYTE(dtbl[(wtxt[idx[1][j]] >> 8) & 0xff]^ ROTRBYTE(dtbl[(wtxt[idx[2][j]] >> 16) & 0xff] ^ ROTRBYTE(dtbl[(wtxt[idx[3][j]] >> 24) & 0xff]))); } key_addition32(t, &(ctx->keys[r*4]), wtxt); } /* last round is special: there is no mixcolumn, so we can't use the big tables. */ for (j=0; j<4; j++) { e = wtxt[j] & 0xff; e |= (wtxt[idx[1][j]]) & (0xff << 8 ); e |= (wtxt[idx[2][j]]) & (0xff << 16); e |= (wtxt[idx[3][j]]) & (0xffU << 24); t[j] = e; } for (j=0; j<4; j++) t[j] = SUBBYTE(t[j], sbox); key_addition32to8(t, &(ctx->keys[4*ctx->nrounds]), ciphertext); } static int iidx[4][4] = { { 0, 1, 2, 3 }, { 3, 0, 1, 2 }, { 2, 3, 0, 1 }, { 1, 2, 3, 0 } }; void rijndael_decrypt(RIJNDAEL_context *ctx, const uint8_t *ciphertext, uint8_t *plaintext) { int r, j; uint32_t wtxt[4], t[4]; /* working ciphertext */ uint32_t e; key_addition_8to32(ciphertext, &(ctx->ikeys[4*ctx->nrounds]), wtxt); for (r=ctx->nrounds-1; r> 0; r--) { for (j=0; j<4; j++) { t[j] = itbl[wtxt[j] & 0xff] ^ ROTRBYTE(itbl[(wtxt[iidx[1][j]] >> 8) & 0xff]^ ROTRBYTE(itbl[(wtxt[iidx[2][j]] >> 16) & 0xff] ^ ROTRBYTE(itbl[(wtxt[iidx[3][j]] >> 24) & 0xff]))); } key_addition32(t, &(ctx->ikeys[r*4]), wtxt); } /* last round is special: there is no mixcolumn, so we can't use the big tables. */ for (j=0; j<4; j++) { e = wtxt[j] & 0xff; e |= (wtxt[iidx[1][j]]) & (0xff << 8); e |= (wtxt[iidx[2][j]]) & (0xff << 16); e |= (wtxt[iidx[3][j]]) & (0xffU << 24); t[j] = e; } for (j=0; j<4; j++) t[j] = SUBBYTE(t[j], isbox); key_addition32to8(t, &(ctx->ikeys[0]), plaintext); } void block_encrypt(RIJNDAEL_context *ctx, uint8_t *input, int inputlen, uint8_t *output, uint8_t *iv) { int i, j, nblocks, carry_flg; uint8_t block[RIJNDAEL_BLOCKSIZE], block2[RIJNDAEL_BLOCKSIZE];//, oldptxt; nblocks = inputlen / RIJNDAEL_BLOCKSIZE; switch (ctx->mode) { case MODE_ECB: /* electronic code book */ for (i = 0; i=0; j--) { if (carry_flg) { block[j]++; carry_flg = block[j] != 0 ? 0 : 1; } else break; } } break; default: break; } } void block_decrypt(RIJNDAEL_context *ctx, uint8_t *input, int inputlen, uint8_t *output, uint8_t *iv) { int i, j, nblocks, carry_flg; uint8_t block[RIJNDAEL_BLOCKSIZE], block2[RIJNDAEL_BLOCKSIZE]; nblocks = inputlen / RIJNDAEL_BLOCKSIZE; switch (ctx->mode) { case MODE_ECB: for (i = 0; i=0; j--) { if (carry_flg) { block[j]++; carry_flg = block[j] != 0 ? 0 : 1; } else break; } } break; default: break; } } /***EOF***/ fwknop-2.6.11/lib/gpgme_funcs.c0000664000175000017500000003360714560546213013256 00000000000000/** * \file lib/gpgme_funcs.c * * \brief gpgme-related functions for GPG encryptions support in libfko. */ /* Fwknop is developed primarily by the people listed in the file 'AUTHORS'. * Copyright (C) 2009-2015 fwknop developers and contributors. For a full * list of contributors, see the file 'CREDITS'. * * License (GNU General Public License): * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #include "fko_common.h" #include "fko.h" #if HAVE_LIBGPGME #include "gpgme_funcs.h" int init_gpgme(fko_ctx_t fko_ctx) { gpgme_error_t err; /* If we already have a context, we are done. */ if(fko_ctx->have_gpgme_context) return(FKO_SUCCESS); /* Because the gpgme manual says you should. */ gpgme_check_version(NULL); /* Check for OpenPGP support */ err = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP); if(gpg_err_code(err) != GPG_ERR_NO_ERROR) { /* GPG engine is not available. */ fko_ctx->gpg_err = err; return(FKO_ERROR_GPGME_NO_OPENPGP); } /* Extract the current gpgme engine information. */ gpgme_set_engine_info( GPGME_PROTOCOL_OpenPGP, (fko_ctx->gpg_exe != NULL) ? fko_ctx->gpg_exe : GPG_EXE, fko_ctx->gpg_home_dir /* If this is NULL, the default is used */ ); /* Create our gpgme context */ err = gpgme_new(&(fko_ctx->gpg_ctx)); if(gpg_err_code(err) != GPG_ERR_NO_ERROR) { fko_ctx->gpg_err = err; return(FKO_ERROR_GPGME_CONTEXT); } fko_ctx->have_gpgme_context = 1; return(FKO_SUCCESS); } /* Callback function that supplies the password when gpgme needs it. */ gpgme_error_t my_passphrase_cb( void *pw, const char *uid_hint, const char *passphrase_info, int prev_was_bad, int fd) { /* We only need to try once as it is fed by the program * (for now --DSS). */ if(prev_was_bad) return(GPG_ERR_CANCELED); if(write(fd, (const char*)pw, strlen((const char*)pw)) != strlen((const char*)pw)) return(GPG_ERR_SYSTEM_ERROR); /* Must be a GPG error, but which one? */ if(write(fd, "\n", 1) != 1) return(GPG_ERR_SYSTEM_ERROR); /* Must be a GPG error, but which one? */ return 0; } /* Verify gpg signatures in a verify_result set. */ static int process_sigs(fko_ctx_t fko_ctx, gpgme_verify_result_t vres) { unsigned int sig_cnt = 0; gpgme_signature_t sig = vres->signatures; fko_gpg_sig_t fgs; /* only want to see one signature (for now). */ if(!sig) return(FKO_ERROR_GPGME_NO_SIGNATURE); /* Iterate over the sigs and store the info we are interested in * to the context. * * NOTE: At present, we support only a single signature. However, * that may change in a future release. We go a head and * grab all signatures even though we will only use the first * one. --DSS */ while(sig != NULL) { fgs = calloc(1, sizeof(struct fko_gpg_sig)); if(fgs == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); /* Grab the summary and status values. */ fgs->summary = sig->summary; fgs->status = sig->status; fgs->validity = sig->validity; /* Grab the signature fingerprint. */ if(sig->fpr != NULL) { fgs->fpr = strdup(sig->fpr); if(fgs->fpr == NULL) { free(fgs); return(FKO_ERROR_MEMORY_ALLOCATION); } } if(sig_cnt == 0) fko_ctx->gpg_sigs = fgs; else fko_ctx->gpg_sigs->next = fgs; sig_cnt++; sig = sig->next; } /* If we are ignoring bad signatures, return success here. */ if(fko_ctx->ignore_gpg_sig_error != 0) return(FKO_SUCCESS); /* Otherwise, we check them here and respond accordingly. */ fgs = fko_ctx->gpg_sigs; if(fgs->status != GPG_ERR_NO_ERROR || fgs->validity < 3) { fko_ctx->gpg_err = fgs->status; return(FKO_ERROR_GPGME_BAD_SIGNATURE); } return(FKO_SUCCESS); } /* Get the GPG key for the given name or ID. */ int get_gpg_key(fko_ctx_t fko_ctx, gpgme_key_t *mykey, const int signer) { int res; const char *name; gpgme_ctx_t list_ctx = NULL; gpgme_key_t key = NULL; gpgme_key_t key2 = NULL; gpgme_error_t err; /* Create a gpgme context for the list */ /* Initialize gpgme */ res = init_gpgme(fko_ctx); if(res != FKO_SUCCESS) { if(signer) return(FKO_ERROR_GPGME_CONTEXT_SIGNER_KEY); else return(FKO_ERROR_GPGME_CONTEXT_RECIPIENT_KEY); } list_ctx = fko_ctx->gpg_ctx; if(signer) name = fko_ctx->gpg_signer; else name = fko_ctx->gpg_recipient; err = gpgme_op_keylist_start(list_ctx, name, signer); if (err) { gpgme_release(list_ctx); fko_ctx->gpg_err = err; if(signer) return(FKO_ERROR_GPGME_SIGNER_KEYLIST_START); else return(FKO_ERROR_GPGME_RECIPIENT_KEYLIST_START); } /* Grab the first key in the list (we hope it is the only one). */ err = gpgme_op_keylist_next(list_ctx, &key); if(gpg_err_code(err) != GPG_ERR_NO_ERROR) { /* Key not found */ fko_ctx->gpg_err = err; if(signer) return(FKO_ERROR_GPGME_SIGNER_KEY_NOT_FOUND); else return(FKO_ERROR_GPGME_RECIPIENT_KEY_NOT_FOUND); } /* We try to get the next key match. If we do, then the name is * ambiguous, so we return an error. */ err = gpgme_op_keylist_next(list_ctx, &key2); if(gpg_err_code(err) == GPG_ERR_NO_ERROR) /* Note: look for NO error */ { /* Ambiguous specfication of key */ gpgme_key_unref(key); gpgme_key_unref(key2); fko_ctx->gpg_err = err; if(signer) return(FKO_ERROR_GPGME_SIGNER_KEY_AMBIGUOUS); else return(FKO_ERROR_GPGME_RECIPIENT_KEY_AMBIGUOUS); } gpgme_op_keylist_end(list_ctx); gpgme_key_unref(key2); *mykey = key; return(FKO_SUCCESS); } /* The main GPG encryption routine for libfko. */ int gpgme_encrypt(fko_ctx_t fko_ctx, unsigned char *indata, size_t in_len, const char *pw, unsigned char **out, size_t *out_len) { char *tmp_buf; int res; gpgme_ctx_t gpg_ctx = NULL; gpgme_data_t cipher = NULL; gpgme_data_t plaintext = NULL; gpgme_key_t key[2] = { NULL, NULL }; gpgme_error_t err; /* Initialize gpgme */ res = init_gpgme(fko_ctx); if(res != FKO_SUCCESS) return(res); gpg_ctx = fko_ctx->gpg_ctx; /* Initialize the plaintext data (place into gpgme_data object) */ err = gpgme_data_new_from_mem(&plaintext, (char*)indata, in_len, 1); if(gpg_err_code(err) != GPG_ERR_NO_ERROR) { gpgme_release(gpg_ctx); fko_ctx->gpg_ctx = NULL; fko_ctx->gpg_err = err; return(FKO_ERROR_GPGME_PLAINTEXT_DATA_OBJ); } /* Set protocol */ err = gpgme_set_protocol(gpg_ctx, GPGME_PROTOCOL_OpenPGP); if(gpg_err_code(err) != GPG_ERR_NO_ERROR) { gpgme_data_release(plaintext); gpgme_release(gpg_ctx); fko_ctx->gpg_ctx = NULL; fko_ctx->gpg_err = err; return(FKO_ERROR_GPGME_SET_PROTOCOL); } /* Set ascii-armor off (we will be base64-encoding the encrypted data * ourselves. */ gpgme_set_armor(gpg_ctx, 0); /* The gpgme_encrypt.... functions take a recipient key array, so we add * our single key here. */ key[0] = fko_ctx->recipient_key; /* Create the buffer for our encrypted data. */ err = gpgme_data_new(&cipher); if(gpg_err_code(err) != GPG_ERR_NO_ERROR) { gpgme_data_release(plaintext); gpgme_release(gpg_ctx); fko_ctx->gpg_ctx = NULL; fko_ctx->gpg_err = err; return(FKO_ERROR_GPGME_CIPHER_DATA_OBJ); } /* Here we add the signer to the gpgme context if there is one. */ if(fko_ctx->gpg_signer != NULL) { gpgme_signers_clear(gpg_ctx); err = gpgme_signers_add(gpg_ctx, fko_ctx->signer_key); if(gpg_err_code(err) != GPG_ERR_NO_ERROR) { gpgme_data_release(plaintext); gpgme_data_release(cipher); gpgme_release(gpg_ctx); fko_ctx->gpg_ctx = NULL; fko_ctx->gpg_err = err; return(FKO_ERROR_GPGME_ADD_SIGNER); } } /* Set the passphrase callback. */ gpgme_set_passphrase_cb(gpg_ctx, my_passphrase_cb, (void*)pw); /* Encrypt and sign (if a sig was provided) the SPA data. */ if(fko_ctx->gpg_signer == NULL) err = gpgme_op_encrypt( gpg_ctx, key, GPGME_ENCRYPT_ALWAYS_TRUST, plaintext, cipher ); else err = gpgme_op_encrypt_sign( gpg_ctx, key, GPGME_ENCRYPT_ALWAYS_TRUST, plaintext, cipher ); if(gpg_err_code(err) != GPG_ERR_NO_ERROR) { gpgme_data_release(plaintext); gpgme_data_release(cipher); gpgme_release(gpg_ctx); fko_ctx->gpg_ctx = NULL; fko_ctx->gpg_err = err; if(gpgme_err_code(err) == GPG_ERR_CANCELED) return(FKO_ERROR_GPGME_BAD_PASSPHRASE); return(FKO_ERROR_GPGME_ENCRYPT_SIGN); } /* Done with the plaintext. */ gpgme_data_release(plaintext); /* Get the encrypted data and its length from the gpgme data object. * BTW, this does free the memory used by cipher. */ tmp_buf = gpgme_data_release_and_get_mem(cipher, out_len); *out = calloc(1, *out_len); /* This is freed upon fko_ctx destruction. */ if(*out == NULL) res = FKO_ERROR_MEMORY_ALLOCATION; else { memcpy(*out, tmp_buf, *out_len); res = FKO_SUCCESS; } gpgme_free(tmp_buf); return(res); } /* The main GPG decryption routine for libfko. */ int gpgme_decrypt(fko_ctx_t fko_ctx, unsigned char *indata, size_t in_len, const char *pw, unsigned char **out, size_t *out_len) { char *tmp_buf; int res; gpgme_ctx_t gpg_ctx = NULL; gpgme_data_t cipher = NULL; gpgme_data_t plaintext = NULL; gpgme_error_t err; gpgme_decrypt_result_t decrypt_res; gpgme_verify_result_t verify_res; /* Initialize gpgme */ res = init_gpgme(fko_ctx); if(res != FKO_SUCCESS) return(res); gpg_ctx = fko_ctx->gpg_ctx; err = gpgme_data_new(&plaintext); if(gpg_err_code(err) != GPG_ERR_NO_ERROR) { gpgme_release(gpg_ctx); fko_ctx->gpg_ctx = NULL; fko_ctx->gpg_err = err; return(FKO_ERROR_GPGME_PLAINTEXT_DATA_OBJ); } /* Initialize the cipher data (place into gpgme_data object) */ err = gpgme_data_new_from_mem(&cipher, (char*)indata, in_len, 0); if(gpg_err_code(err) != GPG_ERR_NO_ERROR) { gpgme_data_release(plaintext); gpgme_release(gpg_ctx); fko_ctx->gpg_ctx = NULL; fko_ctx->gpg_err = err; return(FKO_ERROR_GPGME_CIPHER_DATA_OBJ); } /* Set the passphrase callback. */ gpgme_set_passphrase_cb(gpg_ctx, my_passphrase_cb, (void*)pw); /* Now decrypt and verify. */ err = gpgme_op_decrypt_verify(gpg_ctx, cipher, plaintext); if(gpg_err_code(err) != GPG_ERR_NO_ERROR) { gpgme_data_release(plaintext); gpgme_data_release(cipher); gpgme_release(gpg_ctx); fko_ctx->gpg_ctx = NULL; fko_ctx->gpg_err = err; return(FKO_ERROR_GPGME_DECRYPT_FAILED); } /* Done with the cipher text. */ gpgme_data_release(cipher); /* We check the "usupported_algorithm" flag in the decrypt result. */ decrypt_res = gpgme_op_decrypt_result(gpg_ctx); if(decrypt_res->unsupported_algorithm) { gpgme_data_release(plaintext); gpgme_release(gpg_ctx); fko_ctx->gpg_ctx = NULL; return(FKO_ERROR_GPGME_DECRYPT_UNSUPPORTED_ALGORITHM); } /* Now verify the signatures if so configured. */ if(fko_ctx->verify_gpg_sigs) { verify_res = gpgme_op_verify_result(gpg_ctx); res = process_sigs(fko_ctx, verify_res); if(res != FKO_SUCCESS) { gpgme_data_release(plaintext); gpgme_release(gpg_ctx); fko_ctx->gpg_ctx = NULL; return(res); } } /* Get the encrypted data and its length from the gpgme data object. */ tmp_buf = gpgme_data_release_and_get_mem(plaintext, out_len); /* Use calloc here with an extra byte because I am not sure if all systems * will include the terminating NULL with the decrypted data (which is * expected to be a string). */ *out = calloc(1, *out_len+1); /* This is freed upon fko_ctx destruction. */ if(*out == NULL) res = FKO_ERROR_MEMORY_ALLOCATION; else { memcpy(*out, tmp_buf, *out_len); res = FKO_SUCCESS; } gpgme_free(tmp_buf); return(res); } #endif /* HAVE_LIBGPGME */ /***EOF***/ fwknop-2.6.11/lib/fko_client_timeout.c0000664000175000017500000000670014560546213014636 00000000000000/** * \file lib/fko_client_timeout.c * * \brief Set/Get the spa client timeout data */ /* Fwknop is developed primarily by the people listed in the file 'AUTHORS'. * Copyright (C) 2009-2015 fwknop developers and contributors. For a full * list of contributors, see the file 'CREDITS'. * * License (GNU General Public License): * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #include "fko_common.h" #include "fko.h" /* Set the SPA Client Timeout data */ int fko_set_spa_client_timeout(fko_ctx_t ctx, const int timeout) { int old_msg_type; /* Context must be initialized. */ if(!CTX_INITIALIZED(ctx)) return FKO_ERROR_CTX_NOT_INITIALIZED; /* The timeout should not be negative */ if(timeout < 0) return(FKO_ERROR_INVALID_DATA_CLIENT_TIMEOUT_NEGATIVE); old_msg_type = ctx->message_type; ctx->client_timeout = timeout; ctx->state |= FKO_DATA_MODIFIED; /* If a timeout is set, then we may need to verify/change message * type accordingly. */ if(ctx->client_timeout > 0) { switch(ctx->message_type) { case FKO_ACCESS_MSG: ctx->message_type = FKO_CLIENT_TIMEOUT_ACCESS_MSG; break; case FKO_NAT_ACCESS_MSG: ctx->message_type = FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG; break; case FKO_LOCAL_NAT_ACCESS_MSG: ctx->message_type = FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG; break; } } else /* Timeout is 0, which means ignore it. */ { switch(ctx->message_type) { case FKO_CLIENT_TIMEOUT_ACCESS_MSG: ctx->message_type = FKO_ACCESS_MSG; break; case FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG: ctx->message_type = FKO_NAT_ACCESS_MSG; break; case FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG: ctx->message_type = FKO_LOCAL_NAT_ACCESS_MSG; break; } } if(ctx->message_type != old_msg_type) ctx->state |= FKO_SPA_MSG_TYPE_MODIFIED; return(FKO_SUCCESS); } /* Return the SPA message data. */ int fko_get_spa_client_timeout(fko_ctx_t ctx, int *timeout) { #if HAVE_LIBFIU fiu_return_on("fko_get_spa_client_timeout_init", FKO_ERROR_CTX_NOT_INITIALIZED); #endif /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); if(timeout == NULL) return(FKO_ERROR_INVALID_DATA); #if HAVE_LIBFIU fiu_return_on("fko_get_spa_client_timeout_val", FKO_ERROR_INVALID_DATA); #endif *timeout = ctx->client_timeout; return(FKO_SUCCESS); } /***EOF***/ fwknop-2.6.11/lib/hmac.c0000664000175000017500000013511514560546213011666 00000000000000/** * \file lib/hmac.c * * \brief Provide HMAC support to SPA communications */ /* Fwknop is developed primarily by the people listed in the file 'AUTHORS'. * Copyright (C) 2009-2015 fwknop developers and contributors. For a full * list of contributors, see the file 'CREDITS'. * * License (GNU General Public License): * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #include "hmac.h" #ifdef HAVE_C_UNIT_TESTS /* LCOV_EXCL_START */ DECLARE_TEST_SUITE(hmac_test, "hmac functions test suite"); #endif /* LCOV_EXCL_STOP */ /** * /brief populate the inner and outer pads * * */ static void pad_init(unsigned char *inner_pad, unsigned char *outer_pad, const unsigned char * const key, const int key_len) { int i = 0; for (i=0; i < MAX_DIGEST_BLOCK_LEN && i < key_len; i++) { inner_pad[i] = key[i] ^ 0x36; outer_pad[i] = key[i] ^ 0x5c; } if(i < MAX_DIGEST_BLOCK_LEN) { while(i < MAX_DIGEST_BLOCK_LEN) { inner_pad[i] = 0x36; outer_pad[i] = 0x5c; i++; } } return; } int hmac_md5(const char *msg, const unsigned int msg_len, unsigned char *hmac, const char *hmac_key, const int hmac_key_len) { unsigned char inner_hash[MD5_DIGEST_LEN] = {0}; unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN] = {0}; unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN] = {0}; unsigned char final_key[MAX_DIGEST_BLOCK_LEN] = {0}; unsigned char padded_hash[MD5_BLOCK_LEN + MD5_DIGEST_LEN + 1] = {0}; unsigned char *padded_msg = calloc(1, msg_len + MAX_DIGEST_BLOCK_LEN + 1); int final_len = hmac_key_len; if (padded_msg == NULL) return FKO_ERROR_MEMORY_ALLOCATION; if(MD5_BLOCK_LEN < hmac_key_len) { /* Calculate the digest of the key */ md5(final_key, (unsigned char *)hmac_key, final_len); final_len = MD5_DIGEST_LEN; } else { memcpy(final_key, hmac_key, hmac_key_len); } pad_init(block_inner_pad, block_outer_pad, final_key, final_len); //The first step is to hash the inner_pad + message memcpy(padded_msg, block_inner_pad, MD5_BLOCK_LEN); memcpy(padded_msg + MD5_BLOCK_LEN, msg, msg_len); //Calculate the inner hash md5(inner_hash, padded_msg, msg_len + MD5_BLOCK_LEN); //Then hash the outer pad + inner hash memcpy(padded_hash, block_outer_pad, MD5_BLOCK_LEN); memcpy(padded_hash + MD5_BLOCK_LEN, inner_hash, MD5_DIGEST_LEN); //the outer hash is the final hmac md5(hmac, padded_hash, MD5_BLOCK_LEN + MD5_DIGEST_LEN); free(padded_msg); return FKO_SUCCESS; } int hmac_sha1(const char *msg, const unsigned int msg_len, unsigned char *hmac, const char *hmac_key, const int hmac_key_len) { unsigned char inner_hash[SHA1_DIGEST_LEN] = {0}; unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN] = {0}; unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN] = {0}; unsigned char final_key[MAX_DIGEST_BLOCK_LEN] = {0}; unsigned char padded_hash[SHA1_BLOCK_LEN + SHA1_DIGEST_LEN + 1] = {0}; unsigned char *padded_msg = calloc(1, msg_len + MAX_DIGEST_BLOCK_LEN + 1); int final_len = hmac_key_len; if (padded_msg == NULL) return FKO_ERROR_MEMORY_ALLOCATION; if(SHA1_BLOCK_LEN < hmac_key_len) { /* Calculate the digest of the key */ sha1(final_key, (unsigned char *)hmac_key, final_len); final_len = SHA1_DIGEST_LEN; } else { memcpy(final_key, hmac_key, hmac_key_len); } pad_init(block_inner_pad, block_outer_pad, final_key, final_len); //The first step is to hash the inner_pad + message memcpy(padded_msg, block_inner_pad, SHA1_BLOCK_LEN); memcpy(padded_msg + SHA1_BLOCK_LEN, msg, msg_len); //Calculate the inner hash sha1(inner_hash, padded_msg, msg_len + SHA1_BLOCK_LEN); //Then hash the outer pad + inner hash memcpy(padded_hash, block_outer_pad, SHA1_BLOCK_LEN); memcpy(padded_hash + SHA1_BLOCK_LEN, inner_hash, SHA1_DIGEST_LEN); //the outer hash is the final hmac sha1(hmac, padded_hash, SHA1_BLOCK_LEN + SHA1_DIGEST_LEN); free(padded_msg); return FKO_SUCCESS; } int hmac_sha256(const char *msg, const unsigned int msg_len, unsigned char *hmac, const char *hmac_key, const int hmac_key_len) { unsigned char inner_hash[SHA256_DIGEST_LEN] = {0}; unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN] = {0}; unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN] = {0}; unsigned char final_key[MAX_DIGEST_BLOCK_LEN] = {0}; unsigned char padded_hash[SHA256_BLOCK_LEN + SHA256_DIGEST_LEN + 1] = {0}; unsigned char *padded_msg = calloc(1, msg_len + MAX_DIGEST_BLOCK_LEN + 1); int final_len = hmac_key_len; if (padded_msg == NULL) return FKO_ERROR_MEMORY_ALLOCATION; if(SHA256_BLOCK_LEN < hmac_key_len) { /* Calculate the digest of the key */ sha256(final_key, (unsigned char *)hmac_key, final_len); final_len = SHA256_DIGEST_LEN; } else { memcpy(final_key, hmac_key, hmac_key_len); } pad_init(block_inner_pad, block_outer_pad, final_key, final_len); //The first step is to hash the inner_pad + message memcpy(padded_msg, block_inner_pad, SHA256_BLOCK_LEN); memcpy(padded_msg + SHA256_BLOCK_LEN, msg, msg_len); //Calculate the inner hash sha256(inner_hash, padded_msg, msg_len + SHA256_BLOCK_LEN); //Then hash the outer pad + inner hash memcpy(padded_hash, block_outer_pad, SHA256_BLOCK_LEN); memcpy(padded_hash + SHA256_BLOCK_LEN, inner_hash, SHA256_DIGEST_LEN); //the outer hash is the final hmac sha256(hmac, padded_hash, SHA256_BLOCK_LEN + SHA256_DIGEST_LEN); free(padded_msg); return FKO_SUCCESS; } int hmac_sha384(const char *msg, const unsigned int msg_len, unsigned char *hmac, const char *hmac_key, const int hmac_key_len) { unsigned char inner_hash[SHA384_DIGEST_LEN] = {0}; unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN] = {0}; unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN] = {0}; unsigned char final_key[MAX_DIGEST_BLOCK_LEN] = {0}; unsigned char padded_hash[SHA384_BLOCK_LEN + SHA384_DIGEST_LEN + 1] = {0}; unsigned char *padded_msg = calloc(1, msg_len + MAX_DIGEST_BLOCK_LEN + 1); int final_len = hmac_key_len; if (padded_msg == NULL) return FKO_ERROR_MEMORY_ALLOCATION; if(SHA384_BLOCK_LEN < hmac_key_len) { /* Calculate the digest of the key */ sha384(final_key, (unsigned char *)hmac_key, final_len); final_len = SHA384_DIGEST_LEN; } else { memcpy(final_key, hmac_key, hmac_key_len); } pad_init(block_inner_pad, block_outer_pad, final_key, final_len); //The first step is to hash the inner_pad + message memcpy(padded_msg, block_inner_pad, SHA384_BLOCK_LEN); memcpy(padded_msg + SHA384_BLOCK_LEN, msg, msg_len); //Calculate the inner hash sha384(inner_hash, padded_msg, msg_len + SHA384_BLOCK_LEN); //Then hash the outer pad + inner hash memcpy(padded_hash, block_outer_pad, SHA384_BLOCK_LEN); memcpy(padded_hash + SHA384_BLOCK_LEN, inner_hash, SHA384_DIGEST_LEN); //the outer hash is the final hmac sha384(hmac, padded_hash, SHA384_BLOCK_LEN + SHA384_DIGEST_LEN); free(padded_msg); return FKO_SUCCESS; } int hmac_sha512(const char *msg, const unsigned int msg_len, unsigned char *hmac, const char *hmac_key, const int hmac_key_len) { unsigned char inner_hash[SHA512_DIGEST_LEN] = {0}; unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN] = {0}; unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN] = {0}; unsigned char final_key[MAX_DIGEST_BLOCK_LEN] = {0}; unsigned char padded_hash[SHA512_BLOCK_LEN + SHA512_DIGEST_LEN + 1] = {0}; unsigned char *padded_msg = calloc(1, msg_len + MAX_DIGEST_BLOCK_LEN + 1); int final_len = hmac_key_len; if (padded_msg == NULL) return FKO_ERROR_MEMORY_ALLOCATION; if(SHA512_BLOCK_LEN < hmac_key_len) { /* Calculate the digest of the key */ sha512(final_key, (unsigned char *)hmac_key, final_len); final_len = SHA512_DIGEST_LEN; } else { memcpy(final_key, hmac_key, hmac_key_len); } pad_init(block_inner_pad, block_outer_pad, final_key, final_len); //The first step is to hash the inner_pad + message memcpy(padded_msg, block_inner_pad, SHA512_BLOCK_LEN); memcpy(padded_msg + SHA512_BLOCK_LEN, msg, msg_len); //Calculate the inner hash sha512(inner_hash, padded_msg, msg_len + SHA512_BLOCK_LEN); //Then hash the outer pad + inner hash memcpy(padded_hash, block_outer_pad, SHA512_BLOCK_LEN); memcpy(padded_hash + SHA512_BLOCK_LEN, inner_hash, SHA512_DIGEST_LEN); //the outer hash is the final hmac sha512(hmac, padded_hash, SHA512_BLOCK_LEN + SHA512_DIGEST_LEN); free(padded_msg); return FKO_SUCCESS; } int hmac_sha3_256(const char *msg, const unsigned int msg_len, unsigned char *hmac, const char *hmac_key, const int hmac_key_len) { unsigned char inner_hash[SHA3_256_DIGEST_LEN] = {0}; unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN] = {0}; unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN] = {0}; unsigned char final_key[MAX_DIGEST_BLOCK_LEN] = {0}; unsigned char padded_hash[SHA3_256_BLOCK_LEN + SHA3_256_DIGEST_LEN + 1] = {0}; unsigned char *padded_msg = calloc(1, msg_len + MAX_DIGEST_BLOCK_LEN + 1); int final_len = hmac_key_len; if (padded_msg == NULL) return FKO_ERROR_MEMORY_ALLOCATION; if(SHA3_256_BLOCK_LEN < hmac_key_len) { /* Calculate the digest of the key */ FIPS202_SHA3_256((unsigned char *)hmac_key, final_len, final_key); final_len = SHA3_256_DIGEST_LEN; } else { memcpy(final_key, hmac_key, hmac_key_len); } pad_init(block_inner_pad, block_outer_pad, final_key, final_len); //The first step is to hash the inner_pad + message memcpy(padded_msg, block_inner_pad, SHA3_256_BLOCK_LEN); memcpy(padded_msg + SHA3_256_BLOCK_LEN, msg, msg_len); //Calculate the inner hash FIPS202_SHA3_256(padded_msg, msg_len + SHA3_256_BLOCK_LEN, inner_hash); //Then hash the outer pad + inner hash memcpy(padded_hash, block_outer_pad, SHA3_256_BLOCK_LEN); memcpy(padded_hash + SHA3_256_BLOCK_LEN, inner_hash, SHA3_256_DIGEST_LEN); //the outer hash is the final hmac FIPS202_SHA3_256(padded_hash, SHA3_256_BLOCK_LEN + SHA3_256_DIGEST_LEN, hmac); free(padded_msg); return FKO_SUCCESS; } int hmac_sha3_512(const char *msg, const unsigned int msg_len, unsigned char *hmac, const char *hmac_key, const int hmac_key_len) { unsigned char inner_hash[SHA3_512_DIGEST_LEN] = {0}; unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN] = {0}; unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN] = {0}; unsigned char final_key[MAX_DIGEST_BLOCK_LEN] = {0}; unsigned char padded_hash[SHA3_512_BLOCK_LEN + SHA3_512_DIGEST_LEN + 1] = {0}; unsigned char *padded_msg = calloc(1, msg_len + MAX_DIGEST_BLOCK_LEN + 1); int final_len = hmac_key_len; if (padded_msg == NULL) return FKO_ERROR_MEMORY_ALLOCATION; if(SHA3_512_BLOCK_LEN < hmac_key_len) { /* Calculate the digest of the key */ FIPS202_SHA3_512((unsigned char *)hmac_key, final_len, final_key); final_len = SHA3_512_DIGEST_LEN; } else { memcpy(final_key, hmac_key, hmac_key_len); } pad_init(block_inner_pad, block_outer_pad, final_key, final_len); //The first step is to hash the inner_pad + message memcpy(padded_msg, block_inner_pad, SHA3_512_BLOCK_LEN); memcpy(padded_msg + SHA3_512_BLOCK_LEN, msg, msg_len); //Calculate the inner hash FIPS202_SHA3_512(padded_msg, msg_len + SHA3_512_BLOCK_LEN, inner_hash); //Then hash the outer pad + inner hash memcpy(padded_hash, block_outer_pad, SHA3_512_BLOCK_LEN); memcpy(padded_hash + SHA3_512_BLOCK_LEN, inner_hash, SHA3_512_DIGEST_LEN); //the outer hash is the final hmac FIPS202_SHA3_512(padded_hash, SHA3_512_BLOCK_LEN + SHA3_512_DIGEST_LEN, hmac); free(padded_msg); return FKO_SUCCESS; } #ifdef HAVE_C_UNIT_TESTS /* LCOV_EXCL_START */ DECLARE_UTEST(test_hmac_md5, "hmac_md5 test vectors") // https://tools.ietf.org/html/rfc2202 { char msg[1024] = {0}; unsigned char hmac[1024] = {0}; char hmac_txt[1024] = {0}; char hmac_key[1024] = {0}; char expected_hmac1[1024] = {0}; char expected_hmac2[1024] = {0}; char expected_hmac3[1024] = {0}; char expected_hmac4[1024] = {0}; char expected_hmac5[1024] = {0}; char expected_hmac6[1024] = {0}; char expected_hmac7[1024] = {0}; int msg_len, key_len; int i = 0; //vector 1 for ( i = 0; i < 16; i++) { hmac_key[i] = 0x0b; } key_len = 16; strcpy(msg, "Hi There"); msg_len = 8; strcpy(expected_hmac1, "9294727a3638bb1c13f48ef8158bfc9d"); hmac_md5(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < MD5_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac1, MD5_DIGEST_LEN) == 0); //vector 2 strcpy(hmac_key, "Jefe"); key_len = 4; strcpy(msg, "what do ya want for nothing?"); msg_len = 28; strcpy(expected_hmac2, "750c783e6ab0b503eaa86e310a5db738"); hmac_md5(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA3_256_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac2, MD5_DIGEST_LEN) == 0); //vector 3 for ( i = 0; i < 16; i++) { hmac_key[i] = 0xaa; } key_len = 16; for ( i = 0; i < 50; i++) { msg[i] = 0xdd; } msg_len = 50; strcpy(expected_hmac3, "56be34521d144c88dbb8c733f0e8b3f6"); hmac_md5(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA3_256_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac3, MD5_DIGEST_LEN) == 0); //vector 4 strcpy(hmac_key, "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19"); key_len = 25; for ( i = 0; i < 50; i++) { msg[i] = 0xcd; } msg_len = 50; strcpy(expected_hmac4, "697eaf0aca3a3aea3a75164746ffaa79"); hmac_md5(msg, 50, (unsigned char *)hmac, hmac_key, strlen(hmac_key)); for ( i = 0; i < SHA3_256_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac4, MD5_DIGEST_LEN) == 0); //vector 5 for ( i = 0; i < 16; i++) { hmac_key[i] = 0x0c; } key_len = 16; strcpy(msg, "Test With Truncation"); msg_len = 20; strcpy(expected_hmac5, "56461ef2342edc00f9bab995690efd4c"); hmac_md5(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA3_256_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac5, MD5_DIGEST_LEN) == 0); //vector 6 for ( i = 0; i < 80; i++) { hmac_key[i] = 0xaa; } key_len = 80; strcpy(msg, "Test Using Larger Than Block-Size Key - Hash Key First"); msg_len = 54; strcpy(expected_hmac6, "6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd"); hmac_md5(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA3_256_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac6, MD5_DIGEST_LEN) == 0); //vector 7 for ( i = 0; i < 80; i++) { hmac_key[i] = 0xaa; } key_len = 80; strcpy(msg, "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data"); msg_len = 73; strcpy(expected_hmac7, "6f630fad67cda0ee1fb1f562db3aa53e"); hmac_md5(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA3_256_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac7, MD5_DIGEST_LEN) == 0); } DECLARE_UTEST(test_hmac_sha1, "hmac_sha1 test vectors") // https://tools.ietf.org/html/rfc2202 { char msg[1024] = {0}; unsigned char hmac[1024] = {0}; char hmac_txt[1024] = {0}; char hmac_key[1024] = {0}; char expected_hmac1[1024] = {0}; char expected_hmac2[1024] = {0}; char expected_hmac3[1024] = {0}; char expected_hmac4[1024] = {0}; char expected_hmac5[1024] = {0}; char expected_hmac6[1024] = {0}; char expected_hmac7[1024] = {0}; int msg_len, key_len; int i = 0; //vector 1 for ( i = 0; i < 20; i++) { hmac_key[i] = 0x0b; } key_len = 20; strcpy(msg, "Hi There"); msg_len = 8; strcpy(expected_hmac1, "b617318655057264e28bc0b6fb378c8ef146be00"); hmac_sha1(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA1_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac1, SHA1_DIGEST_LEN) == 0); //vector 2 strcpy(hmac_key, "Jefe"); key_len = 4; strcpy(msg, "what do ya want for nothing?"); msg_len = 28; strcpy(expected_hmac2, "effcdf6ae5eb2fa2d27416d5f184df9c259a7c79"); hmac_sha1(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA1_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac2, SHA1_DIGEST_LEN) == 0); //vector 3 for ( i = 0; i < 20; i++) { hmac_key[i] = 0xaa; } key_len = 20; for ( i = 0; i < 50; i++) { msg[i] = 0xdd; } msg_len = 50; strcpy(expected_hmac3, "125d7342b9ac11cd91a39af48aa17b4f63f175d3"); hmac_sha1(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA1_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac3, SHA1_DIGEST_LEN) == 0); //vector 4 strcpy(hmac_key, "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19"); key_len = 25; for ( i = 0; i < 50; i++) { msg[i] = 0xcd; } msg_len = 50; strcpy(expected_hmac4, "4c9007f4026250c6bc8414f9bf50c86c2d7235da"); hmac_sha1(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA1_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac4, SHA1_DIGEST_LEN) == 0); //vector 5 for ( i = 0; i < 20; i++) { hmac_key[i] = 0x0c; } key_len = 20; strcpy(msg, "Test With Truncation"); msg_len = 20; strcpy(expected_hmac5, "4c1a03424b55e07fe7f27be1d58bb9324a9a5a04"); hmac_sha1(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA1_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac5, SHA1_DIGEST_LEN) == 0); //vector 6 for ( i = 0; i < 80; i++) { hmac_key[i] = 0xaa; } key_len = 80; strcpy(msg, "Test Using Larger Than Block-Size Key - Hash Key First"); msg_len = 54; strcpy(expected_hmac6, "aa4ae5e15272d00e95705637ce8a3b55ed402112"); hmac_sha1(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA1_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac6, SHA1_DIGEST_LEN) == 0); //vector 7 for ( i = 0; i < 80; i++) { hmac_key[i] = 0xaa; } key_len = 80; strcpy(msg, "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data"); msg_len = 73; strcpy(expected_hmac7, "e8e99d0f45237d786d6bbaa7965c7808bbff1a91"); hmac_sha1(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA1_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac7, SHA1_DIGEST_LEN) == 0); } DECLARE_UTEST(test_hmac_sha256, "hmac_sha256 test vectors") // https://tools.ietf.org/html/rfc4231 { char msg[1024] = {0}; unsigned char hmac[1024] = {0}; char hmac_txt[1024] = {0}; char hmac_key[1024] = {0}; char expected_hmac1[1024] = {0}; char expected_hmac2[1024] = {0}; char expected_hmac3[1024] = {0}; char expected_hmac4[1024] = {0}; char expected_hmac5[1024] = {0}; char expected_hmac6[1024] = {0}; char expected_hmac7[1024] = {0}; int msg_len, key_len; int i = 0; //vector 1 for ( i = 0; i < 20; i++) { hmac_key[i] = 0x0b; } key_len = 20; strcpy(msg, "Hi There"); msg_len = 8; strcpy(expected_hmac1, "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7"); hmac_sha256(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA256_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac1, SHA256_DIGEST_LEN) == 0); //vector 2 strcpy(hmac_key, "Jefe"); key_len = 4; strcpy(msg, "what do ya want for nothing?"); msg_len = 28; strcpy(expected_hmac2, "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843"); hmac_sha256(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA256_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac2, SHA256_DIGEST_LEN) == 0); //vector 3 for ( i = 0; i < 20; i++) { hmac_key[i] = 0xaa; } key_len = 20; for ( i = 0; i < 50; i++) { msg[i] = 0xdd; } msg_len = 50; strcpy(expected_hmac3, "773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe"); hmac_sha256(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA256_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac3, SHA256_DIGEST_LEN) == 0); //vector 4 strcpy(hmac_key, "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19"); key_len = 25; for ( i = 0; i < 50; i++) { msg[i] = 0xcd; } msg_len = 50; strcpy(expected_hmac4, "82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b"); hmac_sha256(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA256_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac4, SHA256_DIGEST_LEN) == 0); //vector 5 for ( i = 0; i < 20; i++) { hmac_key[i] = 0x0c; } key_len = 20; strcpy(msg, "Test With Truncation"); msg_len = 20; strcpy(expected_hmac5, "a3b6167473100ee06e0c796c2955552b"); hmac_sha256(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < 16; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac5, 16) == 0); //test specifies truncated output //vector 6 for ( i = 0; i < 131; i++) { hmac_key[i] = 0xaa; } key_len = 131; strcpy(msg, "Test Using Larger Than Block-Size Key - Hash Key First"); msg_len = 54; strcpy(expected_hmac6, "60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54"); hmac_sha256(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA256_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac6, SHA256_DIGEST_LEN) == 0); //vector 7 for ( i = 0; i < 131; i++) { hmac_key[i] = 0xaa; } key_len = 131; strcpy(msg, "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm."); msg_len = strlen(msg); strcpy(expected_hmac7, "9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2"); hmac_sha256(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA256_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac7, SHA256_DIGEST_LEN) == 0); } DECLARE_UTEST(test_hmac_sha384, "hmac_sha384 test vectors") { char msg[1024] = {0}; unsigned char hmac[1024] = {0}; char hmac_txt[1024] = {0}; char hmac_key[1024] = {0}; char expected_hmac1[1024] = {0}; char expected_hmac2[1024] = {0}; char expected_hmac3[1024] = {0}; char expected_hmac4[1024] = {0}; char expected_hmac5[1024] = {0}; char expected_hmac6[1024] = {0}; char expected_hmac7[1024] = {0}; int msg_len, key_len; int i = 0; //vector 1 for ( i = 0; i < 20; i++) { hmac_key[i] = 0x0b; } key_len = 20; strcpy(msg, "Hi There"); msg_len = 8; strcpy(expected_hmac1, "afd03944d84895626b0825f4ab46907f15f9dadbe4101ec682aa034c7cebc59cfaea9ea9076ede7f4af152e8b2fa9cb6"); hmac_sha384(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA384_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac1, SHA384_DIGEST_LEN) == 0); //vector 2 strcpy(hmac_key, "Jefe"); key_len = 4; strcpy(msg, "what do ya want for nothing?"); msg_len = 28; strcpy(expected_hmac2, "af45d2e376484031617f78d2b58a6b1b9c7ef464f5a01b47e42ec3736322445e8e2240ca5e69e2c78b3239ecfab21649"); hmac_sha384(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA384_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac2, SHA384_DIGEST_LEN) == 0); //vector 3 for ( i = 0; i < 20; i++) { hmac_key[i] = 0xaa; } key_len = 20; for ( i = 0; i < 50; i++) { msg[i] = 0xdd; } msg_len = 50; strcpy(expected_hmac3, "88062608d3e6ad8a0aa2ace014c8a86f0aa635d947ac9febe83ef4e55966144b2a5ab39dc13814b94e3ab6e101a34f27"); hmac_sha384(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA384_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac3, SHA384_DIGEST_LEN) == 0); //vector 4 strcpy(hmac_key, "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19"); key_len = 25; for ( i = 0; i < 50; i++) { msg[i] = 0xcd; } msg_len = 50; strcpy(expected_hmac4, "3e8a69b7783c25851933ab6290af6ca77a9981480850009cc5577c6e1f573b4e6801dd23c4a7d679ccf8a386c674cffb"); hmac_sha384(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA384_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac4, SHA384_DIGEST_LEN) == 0); //vector 5 for ( i = 0; i < 20; i++) { hmac_key[i] = 0x0c; } key_len = 20; strcpy(msg, "Test With Truncation"); msg_len = 20; strcpy(expected_hmac5, "3abf34c3503b2a23a46efc619baef897"); hmac_sha384(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < 16; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac5, 16) == 0); //test specifies truncated output //vector 6 for ( i = 0; i < 131; i++) { hmac_key[i] = 0xaa; } key_len = 131; strcpy(msg, "Test Using Larger Than Block-Size Key - Hash Key First"); msg_len = 54; strcpy(expected_hmac6, "4ece084485813e9088d2c63a041bc5b44f9ef1012a2b588f3cd11f05033ac4c60c2ef6ab4030fe8296248df163f44952"); hmac_sha384(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA384_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac6, SHA384_DIGEST_LEN) == 0); //vector 7 for ( i = 0; i < 131; i++) { hmac_key[i] = 0xaa; } key_len = 131; strcpy(msg, "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm."); msg_len = strlen(msg); strcpy(expected_hmac7, "6617178e941f020d351e2f254e8fd32c602420feb0b8fb9adccebb82461e99c5a678cc31e799176d3860e6110c46523e"); hmac_sha384(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA384_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac7, SHA384_DIGEST_LEN) == 0); } DECLARE_UTEST(test_hmac_sha512, "hmac_sha512 test vectors") { char msg[1024] = {0}; unsigned char hmac[1024] = {0}; char hmac_txt[1024] = {0}; char hmac_key[1024] = {0}; char expected_hmac1[1024] = {0}; char expected_hmac2[1024] = {0}; char expected_hmac3[1024] = {0}; char expected_hmac4[1024] = {0}; char expected_hmac5[1024] = {0}; char expected_hmac6[1024] = {0}; char expected_hmac7[1024] = {0}; int msg_len, key_len; int i = 0; //vector 1 for ( i = 0; i < 20; i++) { hmac_key[i] = 0x0b; } key_len = 20; strcpy(msg, "Hi There"); msg_len = 8; strcpy(expected_hmac1, "87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a126854"); hmac_sha512(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA512_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac1, SHA512_DIGEST_LEN) == 0); //vector 2 strcpy(hmac_key, "Jefe"); key_len = 4; strcpy(msg, "what do ya want for nothing?"); msg_len = 28; strcpy(expected_hmac2, "164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737"); hmac_sha512(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA512_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac2, SHA512_DIGEST_LEN) == 0); //vector 3 for ( i = 0; i < 20; i++) { hmac_key[i] = 0xaa; } key_len = 20; for ( i = 0; i < 50; i++) { msg[i] = 0xdd; } msg_len = 50; strcpy(expected_hmac3, "fa73b0089d56a284efb0f0756c890be9b1b5dbdd8ee81a3655f83e33b2279d39bf3e848279a722c806b485a47e67c807b946a337bee8942674278859e13292fb"); hmac_sha512(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA512_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac3, SHA512_DIGEST_LEN) == 0); //vector 4 strcpy(hmac_key, "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19"); key_len = 25; for ( i = 0; i < 50; i++) { msg[i] = 0xcd; } msg_len = 50; strcpy(expected_hmac4, "b0ba465637458c6990e5a8c5f61d4af7e576d97ff94b872de76f8050361ee3dba91ca5c11aa25eb4d679275cc5788063a5f19741120c4f2de2adebeb10a298dd"); hmac_sha512(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA512_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac4, SHA512_DIGEST_LEN) == 0); //vector 5 for ( i = 0; i < 20; i++) { hmac_key[i] = 0x0c; } key_len = 20; strcpy(msg, "Test With Truncation"); msg_len = 20; strcpy(expected_hmac5, "415fad6271580a531d4179bc891d87a6"); hmac_sha512(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < 16; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac5, 16) == 0); //test specifies truncated output //vector 6 for ( i = 0; i < 131; i++) { hmac_key[i] = 0xaa; } key_len = 131; strcpy(msg, "Test Using Larger Than Block-Size Key - Hash Key First"); msg_len = 54; strcpy(expected_hmac6, "80b24263c7c1a3ebb71493c1dd7be8b49b46d1f41b4aeec1121b013783f8f3526b56d037e05f2598bd0fd2215d6a1e5295e64f73f63f0aec8b915a985d786598"); hmac_sha512(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA512_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac6, SHA512_DIGEST_LEN) == 0); //vector 7 for ( i = 0; i < 131; i++) { hmac_key[i] = 0xaa; } key_len = 131; strcpy(msg, "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm."); msg_len = strlen(msg); strcpy(expected_hmac7, "e37b6a775dc87dbaa4dfa9f96e5e3ffddebd71f8867289865df5a32d20cdc944b6022cac3c4982b10d5eeb55c3e4de15134676fb6de0446065c97440fa8c6a58"); hmac_sha512(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA512_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac7, SHA512_DIGEST_LEN) == 0); } DECLARE_UTEST(test_hmac_sha3_256, "hmac_sha3_256 test vectors") //http://wolfgang-ehrhardt.de/hmac-sha3-testvectors.html { char msg[1024] = {0}; unsigned char hmac[1024] = {0}; char hmac_txt[1024] = {0}; char hmac_key[1024] = {0}; char expected_hmac1[1024] = {0}; char expected_hmac2[1024] = {0}; char expected_hmac3[1024] = {0}; char expected_hmac4[1024] = {0}; char expected_hmac5[1024] = {0}; char expected_hmac6[1024] = {0}; char expected_hmac6a[1024] = {0}; char expected_hmac7[1024] = {0}; char expected_hmac7a[1024] = {0}; int msg_len, key_len; int i = 0; //vector 1 for ( i = 0; i < 20; i++) { hmac_key[i] = 0x0b; } key_len = 20; strcpy(msg, "Hi There"); msg_len = 8; strcpy(expected_hmac1, "ba85192310dffa96e2a3a40e69774351140bb7185e1202cdcc917589f95e16bb"); hmac_sha3_256(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA3_256_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac1, SHA3_256_DIGEST_LEN) == 0); //vector 2 strcpy(hmac_key, "Jefe"); key_len = 4; strcpy(msg, "what do ya want for nothing?"); msg_len = 28; strcpy(expected_hmac2, "c7d4072e788877ae3596bbb0da73b887c9171f93095b294ae857fbe2645e1ba5"); hmac_sha3_256(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA3_256_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac2, SHA3_256_DIGEST_LEN) == 0); //vector 3 for ( i = 0; i < 20; i++) { hmac_key[i] = 0xaa; } key_len = 20; for ( i = 0; i < 50; i++) { msg[i] = 0xdd; } msg_len = 50; strcpy(expected_hmac3, "84ec79124a27107865cedd8bd82da9965e5ed8c37b0ac98005a7f39ed58a4207"); hmac_sha3_256(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA3_256_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac3, SHA3_256_DIGEST_LEN) == 0); //vector 4 strcpy(hmac_key, "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19"); key_len = 25; for ( i = 0; i < 50; i++) { msg[i] = 0xcd; } msg_len = 50; strcpy(expected_hmac4, "57366a45e2305321a4bc5aa5fe2ef8a921f6af8273d7fe7be6cfedb3f0aea6d7"); hmac_sha3_256(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA3_256_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac4, SHA3_256_DIGEST_LEN) == 0); //vector 5 for ( i = 0; i < 20; i++) { hmac_key[i] = 0x0c; } key_len = 20; strcpy(msg, "Test With Truncation"); msg_len = 20; strcpy(expected_hmac5, "6e02c64537fb118057abb7fb66a23b3c"); hmac_sha3_256(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA3_256_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac5, 16) == 0); //test specifies truncated output //vector 6 for ( i = 0; i < 131; i++) { hmac_key[i] = 0xaa; } key_len = 131; strcpy(msg, "Test Using Larger Than Block-Size Key - Hash Key First"); msg_len = 54; strcpy(expected_hmac6, "ed73a374b96c005235f948032f09674a58c0ce555cfc1f223b02356560312c3b"); hmac_sha3_256(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA3_256_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac6, SHA3_256_DIGEST_LEN) == 0); //vector 6a for ( i = 0; i < 147; i++) { hmac_key[i] = 0xaa; } key_len = 147; strcpy(msg, "Test Using Larger Than Block-Size Key - Hash Key First"); msg_len = 54; strcpy(expected_hmac6a, "a6072f86de52b38bb349fe84cd6d97fb6a37c4c0f62aae93981193a7229d3467"); hmac_sha3_256(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA3_256_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac6a, SHA3_256_DIGEST_LEN) == 0); //vector 7 for ( i = 0; i < 131; i++) { hmac_key[i] = 0xaa; } key_len = 131; strcpy(msg, "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm."); msg_len = strlen(msg); strcpy(expected_hmac7, "65c5b06d4c3de32a7aef8763261e49adb6e2293ec8e7c61e8de61701fc63e123"); hmac_sha3_256(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA3_256_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac7, SHA3_256_DIGEST_LEN) == 0); //vector 7a for ( i = 0; i < 147; i++) { hmac_key[i] = 0xaa; } key_len = 147; strcpy(msg, "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm."); msg_len = strlen(msg); strcpy(expected_hmac7a, "e6a36d9b915f86a093cac7d110e9e04cf1d6100d30475509c2475f571b758b5a"); hmac_sha3_256(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA3_256_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac7a, SHA3_256_DIGEST_LEN) == 0); } DECLARE_UTEST(test_hmac_sha3_512, "hmac_sha3_512 test vectors") { char msg[1024] = {0}; unsigned char hmac[1024] = {0}; char hmac_txt[1024] = {0}; char hmac_key[1024] = {0}; char expected_hmac1[1024] = {0}; char expected_hmac2[1024] = {0}; char expected_hmac3[1024] = {0}; char expected_hmac4[1024] = {0}; char expected_hmac5[1024] = {0}; char expected_hmac6[1024] = {0}; char expected_hmac6a[1024] = {0}; char expected_hmac7[1024] = {0}; char expected_hmac7a[1024] = {0}; int msg_len, key_len; int i = 0; //vector 1 for ( i = 0; i < 20; i++) { hmac_key[i] = 0x0b; } key_len = 20; strcpy(msg, "Hi There"); msg_len = 8; strcpy(expected_hmac1, "eb3fbd4b2eaab8f5c504bd3a41465aacec15770a7cabac531e482f860b5ec7ba47ccb2c6f2afce8f88d22b6dc61380f23a668fd3888bb80537c0a0b86407689e"); hmac_sha3_512(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA3_512_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac1, SHA3_512_DIGEST_LEN) == 0); //vector 2 strcpy(hmac_key, "Jefe"); key_len = 4; strcpy(msg, "what do ya want for nothing?"); msg_len = 28; strcpy(expected_hmac2, "5a4bfeab6166427c7a3647b747292b8384537cdb89afb3bf5665e4c5e709350b287baec921fd7ca0ee7a0c31d022a95e1fc92ba9d77df883960275beb4e62024"); hmac_sha3_512(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA3_512_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac2, SHA3_512_DIGEST_LEN) == 0); //vector 3 for ( i = 0; i < 20; i++) { hmac_key[i] = 0xaa; } key_len = 20; for ( i = 0; i < 50; i++) { msg[i] = 0xdd; } msg_len = 50; strcpy(expected_hmac3, "309e99f9ec075ec6c6d475eda1180687fcf1531195802a99b5677449a8625182851cb332afb6a89c411325fbcbcd42afcb7b6e5aab7ea42c660f97fd8584bf03"); hmac_sha3_512(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA3_512_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac3, SHA3_512_DIGEST_LEN) == 0); //vector 4 strcpy(hmac_key, "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19"); key_len = 25; for ( i = 0; i < 50; i++) { msg[i] = 0xcd; } msg_len = 50; strcpy(expected_hmac4, "b27eab1d6e8d87461c29f7f5739dd58e98aa35f8e823ad38c5492a2088fa0281993bbfff9a0e9c6bf121ae9ec9bb09d84a5ebac817182ea974673fb133ca0d1d"); hmac_sha3_512(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA3_512_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac4, SHA3_512_DIGEST_LEN) == 0); //vector 5 for ( i = 0; i < 20; i++) { hmac_key[i] = 0x0c; } key_len = 20; strcpy(msg, "Test With Truncation"); msg_len = 20; strcpy(expected_hmac5, "0fa7475948f43f48ca0516671e18978c"); hmac_sha3_512(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < 16; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac5, 16) == 0); //test specifies truncated output //vector 6 for ( i = 0; i < 131; i++) { hmac_key[i] = 0xaa; } key_len = 131; strcpy(msg, "Test Using Larger Than Block-Size Key - Hash Key First"); msg_len = 54; strcpy(expected_hmac6, "00f751a9e50695b090ed6911a4b65524951cdc15a73a5d58bb55215ea2cd839ac79d2b44a39bafab27e83fde9e11f6340b11d991b1b91bf2eee7fc872426c3a4"); hmac_sha3_512(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA3_512_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac6, SHA3_512_DIGEST_LEN) == 0); //vector 6a for ( i = 0; i < 147; i++) { hmac_key[i] = 0xaa; } key_len = 147; strcpy(msg, "Test Using Larger Than Block-Size Key - Hash Key First"); msg_len = 54; strcpy(expected_hmac6a, "b14835c819a290efb010ace6d8568dc6b84de60bc49b004c3b13eda763589451e5dd74292884d1bdce64e6b919dd61dc9c56a282a81c0bd14f1f365b49b83a5b"); hmac_sha3_512(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA3_512_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac6a, SHA3_512_DIGEST_LEN) == 0); //vector 7 for ( i = 0; i < 131; i++) { hmac_key[i] = 0xaa; } key_len = 131; strcpy(msg, "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm."); msg_len = strlen(msg); strcpy(expected_hmac7, "38a456a004bd10d32c9ab8336684112862c3db61adcca31829355eaf46fd5c73d06a1f0d13fec9a652fb3811b577b1b1d1b9789f97ae5b83c6f44dfcf1d67eba"); hmac_sha3_512(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA3_512_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac7, SHA3_512_DIGEST_LEN) == 0); //vector 7a for ( i = 0; i < 147; i++) { hmac_key[i] = 0xaa; } key_len = 147; strcpy(msg, "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm."); msg_len = strlen(msg); strcpy(expected_hmac7a, "dc030ee7887034f32cf402df34622f311f3e6cf04860c6bbd7fa488674782b4659fdbdf3fd877852885cfe6e22185fe7b2ee952043629bc9d5f3298a41d02c66"); hmac_sha3_512(msg, msg_len, (unsigned char *)hmac, hmac_key, key_len); for ( i = 0; i < SHA3_512_DIGEST_LEN; i++) { sprintf(hmac_txt + (2 * i), "%02x", hmac[i]); } CU_ASSERT(memcmp(hmac_txt, expected_hmac7a, SHA3_512_DIGEST_LEN) == 0); } int register_ts_hmac_test(void) { ts_init(&TEST_SUITE(hmac_test), TEST_SUITE_DESCR(hmac_test), NULL, NULL); ts_add_utest(&TEST_SUITE(hmac_test), UTEST_FCT(test_hmac_md5), UTEST_DESCR(test_hmac_md5)); ts_add_utest(&TEST_SUITE(hmac_test), UTEST_FCT(test_hmac_sha1), UTEST_DESCR(test_hmac_sha1)); ts_add_utest(&TEST_SUITE(hmac_test), UTEST_FCT(test_hmac_sha256), UTEST_DESCR(test_hmac_sha256)); ts_add_utest(&TEST_SUITE(hmac_test), UTEST_FCT(test_hmac_sha384), UTEST_DESCR(test_hmac_sha384)); ts_add_utest(&TEST_SUITE(hmac_test), UTEST_FCT(test_hmac_sha512), UTEST_DESCR(test_hmac_sha512)); ts_add_utest(&TEST_SUITE(hmac_test), UTEST_FCT(test_hmac_sha3_256), UTEST_DESCR(test_hmac_sha3_256)); ts_add_utest(&TEST_SUITE(hmac_test), UTEST_FCT(test_hmac_sha3_512), UTEST_DESCR(test_hmac_sha3_512)); return register_ts(&TEST_SUITE(hmac_test)); } #endif /* HAVE_C_UNIT_TESTS */ /* LCOV_EXCL_STOP */ fwknop-2.6.11/lib/fko_message.c0000664000175000017500000002316314560546213013240 00000000000000/** * \file lib/fko_message.c * * \brief Set/Get the spa message (access req/command/etc) based on the current spa data. */ /* Fwknop is developed primarily by the people listed in the file 'AUTHORS'. * Copyright (C) 2009-2015 fwknop developers and contributors. For a full * list of contributors, see the file 'CREDITS'. * * License (GNU General Public License): * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #include "fko_common.h" #include "fko_message.h" #include "fko.h" static int have_allow_ip(const char *msg) { const char *ndx = msg; char ip_str[MAX_IPV4_STR_LEN]; int dot_ctr = 0, char_ctr = 0; int res = FKO_SUCCESS; while(*ndx != ',' && *ndx != '\0') { ip_str[char_ctr] = *ndx; char_ctr++; if(char_ctr >= MAX_IPV4_STR_LEN) { res = FKO_ERROR_INVALID_ALLOW_IP; break; } if(*ndx == '.') dot_ctr++; else if(isdigit((int)(unsigned char)*ndx) == 0) { res = FKO_ERROR_INVALID_ALLOW_IP; break; } ndx++; } if(char_ctr < MAX_IPV4_STR_LEN) ip_str[char_ctr] = '\0'; else res = FKO_ERROR_INVALID_ALLOW_IP; if(res == FKO_SUCCESS) if (! is_valid_ipv4_addr(ip_str, strlen(ip_str))) res = FKO_ERROR_INVALID_ALLOW_IP; return(res); } static int have_port(const char *msg) { const char *ndx = msg; char port_str[MAX_PORT_STR_LEN+1] = {0}; int startlen = strnlen(msg, MAX_SPA_MESSAGE_SIZE); int port_str_len=0, i=0, is_err; if(startlen == MAX_SPA_MESSAGE_SIZE) return(FKO_ERROR_INVALID_DATA_MESSAGE_PORT_MISSING); /* Must have at least one digit for the port number */ if(isdigit((int)(unsigned char)*ndx) == 0) return(FKO_ERROR_INVALID_SPA_ACCESS_MSG); while(*ndx != '\0' && *ndx != ',') { port_str_len++; if((isdigit((int)(unsigned char)*ndx) == 0) || (port_str_len > MAX_PORT_STR_LEN)) return(FKO_ERROR_INVALID_SPA_ACCESS_MSG); port_str[i] = *ndx; ndx++; i++; } port_str[i] = '\0'; strtol_wrapper(port_str, 1, MAX_PORT, NO_EXIT_UPON_ERR, &is_err); if(is_err != FKO_SUCCESS) return(FKO_ERROR_INVALID_SPA_ACCESS_MSG); return FKO_SUCCESS; } /* Set the SPA message type. */ int fko_set_spa_message_type(fko_ctx_t ctx, const short msg_type) { #if HAVE_LIBFIU fiu_return_on("fko_set_spa_message_type_init", FKO_ERROR_CTX_NOT_INITIALIZED); #endif /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return FKO_ERROR_CTX_NOT_INITIALIZED; #if HAVE_LIBFIU fiu_return_on("fko_set_spa_message_type_val", FKO_ERROR_INVALID_DATA_MESSAGE_TYPE_VALIDFAIL); #endif if(msg_type < 0 || msg_type >= FKO_LAST_MSG_TYPE) return(FKO_ERROR_INVALID_DATA_MESSAGE_TYPE_VALIDFAIL); ctx->message_type = msg_type; ctx->state |= FKO_SPA_MSG_TYPE_MODIFIED; return(FKO_SUCCESS); } /* Return the SPA message type. */ int fko_get_spa_message_type(fko_ctx_t ctx, short *msg_type) { #if HAVE_LIBFIU fiu_return_on("fko_get_spa_message_type_init", FKO_ERROR_CTX_NOT_INITIALIZED); #endif /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return FKO_ERROR_CTX_NOT_INITIALIZED; if(msg_type == NULL) return(FKO_ERROR_INVALID_DATA); #if HAVE_LIBFIU fiu_return_on("fko_get_spa_message_type_val", FKO_ERROR_INVALID_DATA); #endif *msg_type = ctx->message_type; return(FKO_SUCCESS); } /* Set the SPA MESSAGE data */ int fko_set_spa_message(fko_ctx_t ctx, const char * const msg) { int res = FKO_ERROR_UNKNOWN; /* Context must be initialized. */ if(!CTX_INITIALIZED(ctx)) return FKO_ERROR_CTX_NOT_INITIALIZED; /* Gotta have a valid string. */ if(msg == NULL || strnlen(msg, MAX_SPA_MESSAGE_SIZE) == 0) return(FKO_ERROR_INVALID_DATA_MESSAGE_EMPTY); /* --DSS XXX: Bail out for now. But consider just * truncating in the future... */ if(strnlen(msg, MAX_SPA_MESSAGE_SIZE) == MAX_SPA_MESSAGE_SIZE) return(FKO_ERROR_DATA_TOO_LARGE); /* Basic message type and format checking... */ if(ctx->message_type == FKO_COMMAND_MSG) res = validate_cmd_msg(msg); else res = validate_access_msg(msg); if(res != FKO_SUCCESS) return(res); /* Just in case this is a subsequent call to this function. We * do not want to be leaking memory. */ if(ctx->message != NULL) free(ctx->message); ctx->message = strdup(msg); ctx->state |= FKO_DATA_MODIFIED; if(ctx->message == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); return(FKO_SUCCESS); } /* Return the SPA message data. */ int fko_get_spa_message(fko_ctx_t ctx, char **msg) { #if HAVE_LIBFIU fiu_return_on("fko_get_spa_message_init", FKO_ERROR_CTX_NOT_INITIALIZED); #endif /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); if(msg == NULL) return(FKO_ERROR_INVALID_DATA); #if HAVE_LIBFIU fiu_return_on("fko_get_spa_message_val", FKO_ERROR_INVALID_DATA); #endif *msg = ctx->message; return(FKO_SUCCESS); } /* Validate a command message format. */ int validate_cmd_msg(const char *msg) { const char *ndx; int res = FKO_SUCCESS; int startlen = strnlen(msg, MAX_SPA_CMD_LEN); if(startlen == MAX_SPA_CMD_LEN) return(FKO_ERROR_INVALID_DATA_MESSAGE_CMD_MISSING); /* Should always have a valid allow IP regardless of message type */ if((res = have_allow_ip(msg)) != FKO_SUCCESS) return(FKO_ERROR_INVALID_SPA_COMMAND_MSG); /* Commands are fairly free-form so all we can really verify is * there is something at all. Get past the IP and comma, and make * sure we have some string leftover... */ ndx = strchr(msg, ','); if(ndx == NULL || (1+(ndx - msg)) >= startlen) return(FKO_ERROR_INVALID_SPA_COMMAND_MSG); return(FKO_SUCCESS); } int validate_access_msg(const char *msg) { const char *ndx; int res = FKO_SUCCESS; int startlen = strnlen(msg, MAX_SPA_MESSAGE_SIZE); if(startlen == MAX_SPA_MESSAGE_SIZE) return(FKO_ERROR_INVALID_DATA_MESSAGE_ACCESS_MISSING); /* Should always have a valid allow IP regardless of message type */ if((res = have_allow_ip(msg)) != FKO_SUCCESS) return(res); /* Position ourselves beyond the allow IP and make sure we are * still good. */ ndx = strchr(msg, ','); if(ndx == NULL || (1+(ndx - msg)) >= startlen) return(FKO_ERROR_INVALID_SPA_ACCESS_MSG); /* Look for a comma to see if this is a multi-part access request. */ do { ndx++; res = validate_proto_port_spec(ndx); if(res != FKO_SUCCESS) break; } while((ndx = strchr(ndx, ','))); return(res); } int validate_nat_access_msg(const char *msg) { const char *ndx; int host_len; int res = FKO_SUCCESS; int startlen = strnlen(msg, MAX_SPA_MESSAGE_SIZE); if(startlen == MAX_SPA_MESSAGE_SIZE) return(FKO_ERROR_INVALID_DATA_MESSAGE_NAT_MISSING); /* must have exactly one comma here */ if(count_characters(msg, ',', startlen) != 1) return(FKO_ERROR_INVALID_SPA_NAT_ACCESS_MSG); /* Must not be longer than the max hostname length */ host_len = strcspn(msg, ","); if(host_len > MAX_HOSTNAME_LEN) return(FKO_ERROR_INVALID_SPA_NAT_ACCESS_MSG); /* Check for some invalid characters */ if(strcspn(msg, " /?\"\'\\") < host_len) return(FKO_ERROR_INVALID_SPA_NAT_ACCESS_MSG); /* Position ourselves beyond the allow IP and make sure we have * a single port value */ ndx = strchr(msg, ','); if(ndx == NULL || (1+(ndx - msg)) >= startlen) return(FKO_ERROR_INVALID_SPA_NAT_ACCESS_MSG); ndx++; if((res = have_port(ndx)) != FKO_SUCCESS) return(FKO_ERROR_INVALID_SPA_NAT_ACCESS_MSG); if(msg[startlen-1] == ',') return(FKO_ERROR_INVALID_SPA_NAT_ACCESS_MSG); return(res); } int validate_proto_port_spec(const char *msg) { int startlen = strnlen(msg, MAX_SPA_MESSAGE_SIZE); const char *ndx = msg; if(startlen == MAX_SPA_MESSAGE_SIZE) return(FKO_ERROR_INVALID_DATA_MESSAGE_PORTPROTO_MISSING); /* Now check for proto/port string. */ if(strncmp(ndx, "tcp", 3) && strncmp(ndx, "udp", 3) && strncmp(ndx, "icmp", 4) && strncmp(ndx, "none", 4)) return(FKO_ERROR_INVALID_SPA_ACCESS_MSG); ndx = strchr(ndx, '/'); if(ndx == NULL || ((1+(ndx - msg)) > MAX_PROTO_STR_LEN)) return(FKO_ERROR_INVALID_SPA_ACCESS_MSG); /* Skip over the '/' and make sure we only have digits. */ ndx++; return have_port(ndx); } /***EOF***/ fwknop-2.6.11/lib/fko_context.h0000664000175000017500000000724314560546213013306 00000000000000/** * \file lib/fko_context.h * * \brief fko context definition. */ /* * Fwknop is developed primarily by the people listed in the file 'AUTHORS'. * Copyright (C) 2009-2015 fwknop developers and contributors. For a full * list of contributors, see the file 'CREDITS'. * * License (GNU General Public License): * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #ifndef FKO_CONTEXT_H #define FKO_CONTEXT_H 1 #include "fko_common.h" #if HAVE_LIBGPGME #include #endif #if HAVE_LIBGPGME || DOXYGEN /** * * \struct fko_gpg_sig * * \brief Structure to hold a list of the gpg signature information we are interested in. */ struct fko_gpg_sig { struct fko_gpg_sig *next; /**< link to next member */ gpgme_sigsum_t summary; gpgme_error_t status; gpgme_validity_t validity; char *fpr; }; typedef struct fko_gpg_sig *fko_gpg_sig_t; #endif /* HAVE_LIBGPGME */ /** * * \struct fko_context * * \brief The pieces we need to make an FKO SPA data packet. */ struct fko_context { /** \name FKO SPA user-definable message data */ /*@{*/ char *rand_val; char *username; time_t timestamp; short message_type; char *message; char *nat_access; char *server_auth; unsigned int client_timeout; /*@}*/ /** \name FKO SPA user-settable message encoding types */ /*@{*/ short digest_type; short encryption_type; int encryption_mode; short hmac_type; /*@}*/ /** \name Computed or predefined data */ /*@{*/ char *version; char *digest; int digest_len; /*@}*/ /** \name Digest of raw encrypted/base64 data * This is used for replay attack detection */ /*@{*/ char *raw_digest; short raw_digest_type; int raw_digest_len; /*@}*/ /** \name Computed processed data (encodings, etc.) */ /*@{*/ char *encoded_msg; int encoded_msg_len; char *encrypted_msg; int encrypted_msg_len; char *msg_hmac; int msg_hmac_len; int added_salted_str; int added_gpg_prefix; /*@}*/ /** \name State info */ /*@{*/ unsigned int state; unsigned char initval; /*@}*/ #if HAVE_LIBGPGME /** \name For gpgme support */ /*@{*/ char *gpg_exe; char *gpg_recipient; char *gpg_signer; char *gpg_home_dir; unsigned char have_gpgme_context; gpgme_ctx_t gpg_ctx; gpgme_key_t recipient_key; gpgme_key_t signer_key; unsigned char verify_gpg_sigs; unsigned char ignore_gpg_sig_error; fko_gpg_sig_t gpg_sigs; gpgme_error_t gpg_err; /*@}*/ #endif /* HAVE_LIBGPGME */ }; #endif /* FKO_CONTEXT_H */ /***EOF***/ fwknop-2.6.11/lib/fko.h0000664000175000017500000016276214560546213011552 00000000000000/** * \file lib/fko.h * * \brief Header for libfko */ /* * Fwknop is developed primarily by the people listed in the file 'AUTHORS'. * Copyright (C) 2009-2015 fwknop developers and contributors. For a full * list of contributors, see the file 'CREDITS'. * * License (GNU General Public License): * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #ifndef FKO_H #define FKO_H 1 #include #ifdef __cplusplus extern "C" { #endif #ifdef WIN32 #ifdef DLL_EXPORTS #define DLL_API __declspec(dllexport) #else #ifdef DLL_IMPORTS #define DLL_API __declspec(dllimport) #else #define DLL_API #endif #endif #else #define DLL_API #endif /* General params */ #define FKO_PROTOCOL_VERSION "3.0.0" /**< The fwknop protocol version */ /** * * \enum fko_message_type_t * * \brief Supported FKO Message types... */ typedef enum { FKO_COMMAND_MSG = 0, /**< Command message */ FKO_ACCESS_MSG, /**< Access message */ FKO_NAT_ACCESS_MSG, /**< NAT Access message */ FKO_CLIENT_TIMEOUT_ACCESS_MSG, /**< Access message with timeout */ FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG, /**< NAT Access with timeout */ FKO_LOCAL_NAT_ACCESS_MSG, /**< Local NAT access */ FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG, /**< Local NAT access with timeout */ FKO_LAST_MSG_TYPE /**< Always leave this as the last one */ } fko_message_type_t; /** * * \enum fko_digest_type_t * * \brief Supported digest types... */ typedef enum { FKO_DIGEST_INVALID_DATA = -1, /**< Invalid digest type*/ FKO_DIGEST_UNKNOWN = 0, /**< Unknown digest type*/ FKO_DIGEST_MD5, /**< MD5 digest type*/ FKO_DIGEST_SHA1, /**< SHA1 digest type*/ FKO_DIGEST_SHA256, /**< SHA256 digest type*/ FKO_DIGEST_SHA384, /**< SHA384 digest type*/ FKO_DIGEST_SHA512, /**< SHA512 digest type*/ FKO_DIGEST_SHA3_256, /**< SHA3 256 digest type*/ FKO_DIGEST_SHA3_512, /**< SHA3 512 digest type*/ FKO_LAST_DIGEST_TYPE /**< Always leave this as the last one */ } fko_digest_type_t; /** * * \enum fko_hmac_type_t * * \brief Supported hmac digest types... */ typedef enum { FKO_HMAC_INVALID_DATA = -1, /**< Invalid HMAC type*/ FKO_HMAC_UNKNOWN = 0, /**< Unknown HMAC type*/ FKO_HMAC_MD5, /**< MD5 HMAC type*/ FKO_HMAC_SHA1, /**< SHA1 HMAC type*/ FKO_HMAC_SHA256, /**< SHA256 HMAC type*/ FKO_HMAC_SHA384, /**< SHA384 HMAC type*/ FKO_HMAC_SHA512, /**< SHA512 HMAC type*/ FKO_HMAC_SHA3_256, /**< SHA3 256 HMAC type */ FKO_HMAC_SHA3_512, /**< SHA3 512 HMAC type*/ FKO_LAST_HMAC_MODE /**< Always leave this as the last one */ } fko_hmac_type_t; /** * * \enum fko_encryption_type_t * * \brief Supported encryption types... */ typedef enum { FKO_ENCRYPTION_INVALID_DATA = -1, /**< Invalid encryption type*/ FKO_ENCRYPTION_UNKNOWN = 0, /**< Unknown encryption type*/ FKO_ENCRYPTION_RIJNDAEL, /**< AES encryption type*/ FKO_ENCRYPTION_GPG, /**< GPG encryption type*/ FKO_LAST_ENCRYPTION_TYPE /**< Always leave this as the last one */ } fko_encryption_type_t; /** * * \enum fko_encryption_mode_t * * \brief Symmetric encryption modes to correspond to rijndael.h */ typedef enum { FKO_ENC_MODE_UNKNOWN = 0, /**< Unknown encryption mode*/ FKO_ENC_MODE_ECB, /**< Electronic Code Book encryption mode*/ FKO_ENC_MODE_CBC, /**< Cipher Block Chaining encryption mode*/ FKO_ENC_MODE_CFB, /**< Cipher Feedback encryption mode*/ FKO_ENC_MODE_PCBC, /**< Propagating Cipher Block Chaining encryption mode*/ FKO_ENC_MODE_OFB, /**< Output Feedback encryption mode*/ FKO_ENC_MODE_CTR, /**< Counter encryption mode*/ FKO_ENC_MODE_ASYMMETRIC, /**< placeholder when GPG is used */ FKO_ENC_MODE_CBC_LEGACY_IV, /**< for the old zero-padding strategy */ FKO_LAST_ENC_MODE /**< Always leave this as the last one */ } fko_encryption_mode_t; /** * * \enum fko_error_codes_t * * \brief FKO ERROR_CODES * * Note: If you change this list in any way, please be sure to make the * appropriate corresponding change to the error message list in * fko_error.c. */ typedef enum { FKO_SUCCESS = 0, /**< Success*/ FKO_ERROR_CTX_NOT_INITIALIZED, /**< FKO Context is not initialized*/ FKO_ERROR_MEMORY_ALLOCATION, /**< Unable to allocate memory*/ FKO_ERROR_FILESYSTEM_OPERATION, /**< Read/write bytes mismatch*/ /* Invalid data errors */ FKO_ERROR_INVALID_DATA, /**< Args contain invalid data*/ FKO_ERROR_INVALID_DATA_CLIENT_TIMEOUT_NEGATIVE, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_CLIENT_TIMEOUT_NEGATIVE*/ FKO_ERROR_INVALID_DATA_DECODE_MSGLEN_VALIDFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_MSGLEN_VALIDFAIL*/ FKO_ERROR_INVALID_DATA_DECODE_NON_ASCII, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_NON_ASCII*/ FKO_ERROR_INVALID_DATA_DECODE_LT_MIN_FIELDS, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_LT_MIN_FIELDS*/ FKO_ERROR_INVALID_DATA_DECODE_GT_MAX_FIELDS, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_GT_MAX_FIELDS*/ FKO_ERROR_INVALID_DATA_DECODE_WRONG_NUM_FIELDS, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_WRONG_NUM_FIELDS*/ FKO_ERROR_INVALID_DATA_DECODE_ENC_MSG_LEN_MT_T_SIZE, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_ENC_MSG_LEN_MT_T_SIZE*/ FKO_ERROR_INVALID_DATA_DECODE_RAND_MISSING, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_RAND_MISSING*/ FKO_ERROR_INVALID_DATA_DECODE_USERNAME_MISSING, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_USERNAME_MISSING*/ FKO_ERROR_INVALID_DATA_DECODE_USERNAME_TOOBIG, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_USERNAME_TOOBIG*/ FKO_ERROR_INVALID_DATA_DECODE_USERNAME_DECODEFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_USERNAME_DECODEFAIL*/ FKO_ERROR_INVALID_DATA_DECODE_USERNAME_VALIDFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_USERNAME_VALIDFAIL*/ FKO_ERROR_INVALID_DATA_DECODE_TIMESTAMP_MISSING, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_TIMESTAMP_MISSING*/ FKO_ERROR_INVALID_DATA_DECODE_TIMESTAMP_TOOBIG, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_TIMESTAMP_TOOBIG*/ FKO_ERROR_INVALID_DATA_DECODE_TIMESTAMP_DECODEFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_TIMESTAMP_DECODEFAIL*/ FKO_ERROR_INVALID_DATA_DECODE_VERSION_MISSING, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_VERSION_MISSING*/ FKO_ERROR_INVALID_DATA_DECODE_VERSION_TOOBIG, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_VERSION_TOOBIG*/ FKO_ERROR_INVALID_DATA_DECODE_MSGTYPE_MISSING, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_MSGTYPE_MISSING*/ FKO_ERROR_INVALID_DATA_DECODE_MSGTYPE_TOOBIG, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_MSGTYPE_TOOBIG*/ FKO_ERROR_INVALID_DATA_DECODE_MSGTYPE_DECODEFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_MSGTYPE_DECODEFAIL*/ FKO_ERROR_INVALID_DATA_DECODE_MESSAGE_MISSING, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_MESSAGE_MISSING*/ FKO_ERROR_INVALID_DATA_DECODE_MESSAGE_TOOBIG, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_MESSAGE_TOOBIG*/ FKO_ERROR_INVALID_DATA_DECODE_MESSAGE_DECODEFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_MESSAGE_DECODEFAIL*/ FKO_ERROR_INVALID_DATA_DECODE_MESSAGE_VALIDFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_MESSAGE_VALIDFAIL*/ FKO_ERROR_INVALID_DATA_DECODE_ACCESS_VALIDFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_ACCESS_VALIDFAIL*/ FKO_ERROR_INVALID_DATA_DECODE_NATACCESS_MISSING, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_NATACCESS_MISSING*/ FKO_ERROR_INVALID_DATA_DECODE_NATACCESS_TOOBIG, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_NATACCESS_TOOBIG*/ FKO_ERROR_INVALID_DATA_DECODE_NATACCESS_DECODEFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_NATACCESS_DECODEFAIL*/ FKO_ERROR_INVALID_DATA_DECODE_NATACCESS_VALIDFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_NATACCESS_VALIDFAIL*/ FKO_ERROR_INVALID_DATA_DECODE_SRVAUTH_MISSING, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_SRVAUTH_MISSING*/ FKO_ERROR_INVALID_DATA_DECODE_SRVAUTH_DECODEFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_SRVAUTH_DECODEFAIL*/ FKO_ERROR_INVALID_DATA_DECODE_SPA_EXTRA_TOOBIG, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_SPA_EXTRA_TOOBIG*/ FKO_ERROR_INVALID_DATA_DECODE_EXTRA_TOOBIG, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_EXTRA_TOOBIG*/ FKO_ERROR_INVALID_DATA_DECODE_EXTRA_DECODEFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_EXTRA_DECODEFAIL*/ FKO_ERROR_INVALID_DATA_DECODE_TIMEOUT_MISSING, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_TIMEOUT_MISSING*/ FKO_ERROR_INVALID_DATA_DECODE_TIMEOUT_TOOBIG, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_TIMEOUT_TOOBIG*/ FKO_ERROR_INVALID_DATA_DECODE_TIMEOUT_VALIDFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_TIMEOUT_VALIDFAIL*/ FKO_ERROR_INVALID_DATA_DECODE_TIMEOUT_DECODEFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_DECODE_TIMEOUT_DECODEFAIL*/ FKO_ERROR_INVALID_DATA_ENCODE_MESSAGE_TOOBIG, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCODE_MESSAGE_TOOBIG*/ FKO_ERROR_INVALID_DATA_ENCODE_MSGLEN_VALIDFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCODE_MSGLEN_VALIDFAIL*/ FKO_ERROR_INVALID_DATA_ENCODE_DIGEST_VALIDFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCODE_DIGEST_VALIDFAIL*/ FKO_ERROR_INVALID_DATA_ENCODE_DIGEST_TOOBIG, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCODE_DIGEST_TOOBIG*/ FKO_ERROR_INVALID_DATA_ENCODE_NOTBASE64, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCODE_NOTBASE64*/ FKO_ERROR_INVALID_DATA_ENCRYPT_MSGLEN_VALIDFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCRYPT_MSGLEN_VALIDFAIL*/ FKO_ERROR_INVALID_DATA_ENCRYPT_DIGESTLEN_VALIDFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCRYPT_DIGESTLEN_VALIDFAIL*/ FKO_ERROR_INVALID_DATA_ENCRYPT_PTLEN_VALIDFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCRYPT_PTLEN_VALIDFAIL*/ FKO_ERROR_INVALID_DATA_ENCRYPT_RESULT_MSGLEN_VALIDFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCRYPT_RESULT_MSGLEN_VALIDFAIL*/ FKO_ERROR_INVALID_DATA_ENCRYPT_CIPHERLEN_DECODEFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCRYPT_CIPHERLEN_DECODEFAIL*/ FKO_ERROR_INVALID_DATA_ENCRYPT_CIPHERLEN_VALIDFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCRYPT_CIPHERLEN_VALIDFAIL*/ FKO_ERROR_INVALID_DATA_ENCRYPT_DECRYPTED_MESSAGE_MISSING, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCRYPT_DECRYPTED_MESSAGE_MISSING*/ FKO_ERROR_INVALID_DATA_ENCRYPT_DECRYPTED_MSGLEN_VALIDFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCRYPT_DECRYPTED_MSGLEN_VALIDFAIL*/ FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_MESSAGE_VALIDFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_MESSAGE_VALIDFAIL*/ FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_DIGEST_VALIDFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_DIGEST_VALIDFAIL*/ FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_MSGLEN_VALIDFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_MSGLEN_VALIDFAIL*/ FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_RESULT_MSGLEN_VALIDFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_RESULT_MSGLEN_VALIDFAIL*/ FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_CIPHER_DECODEFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_CIPHER_DECODEFAIL*/ FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_ENCODEDMSG_NULL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_ENCODEDMSG_NULL*/ FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_ENCODEDMSGLEN_VALIDFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_ENCODEDMSGLEN_VALIDFAIL*/ FKO_ERROR_INVALID_DATA_ENCRYPT_TYPE_VALIDFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCRYPT_TYPE_VALIDFAIL*/ FKO_ERROR_INVALID_DATA_ENCRYPT_MODE_VALIDFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCRYPT_MODE_VALIDFAIL*/ FKO_ERROR_INVALID_DATA_ENCRYPT_TYPE_UNKNOWN, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_ENCRYPT_TYPE_UNKNOWN*/ FKO_ERROR_INVALID_DATA_FUNCS_NEW_ENCMSG_MISSING, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_FUNCS_NEW_ENCMSG_MISSING*/ FKO_ERROR_INVALID_DATA_FUNCS_NEW_MSGLEN_VALIDFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_FUNCS_NEW_MSGLEN_VALIDFAIL*/ FKO_ERROR_INVALID_DATA_FUNCS_GEN_KEYLEN_VALIDFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_FUNCS_GEN_KEYLEN_VALIDFAIL*/ FKO_ERROR_INVALID_DATA_FUNCS_GEN_HMACLEN_VALIDFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_FUNCS_GEN_HMACLEN_VALIDFAIL*/ FKO_ERROR_INVALID_DATA_FUNCS_GEN_KEY_ENCODEFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_FUNCS_GEN_KEY_ENCODEFAIL*/ FKO_ERROR_INVALID_DATA_FUNCS_GEN_HMAC_ENCODEFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_FUNCS_GEN_HMAC_ENCODEFAIL*/ FKO_ERROR_INVALID_DATA_FUNCS_SET_MSGLEN_VALIDFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_FUNCS_SET_MSGLEN_VALIDFAIL*/ FKO_ERROR_INVALID_DATA_HMAC_MSGLEN_VALIDFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_HMAC_MSGLEN_VALIDFAIL*/ FKO_ERROR_INVALID_DATA_HMAC_ENCMSGLEN_VALIDFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_HMAC_ENCMSGLEN_VALIDFAIL*/ FKO_ERROR_INVALID_DATA_HMAC_COMPAREFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_HMAC_COMPAREFAIL*/ FKO_ERROR_INVALID_DATA_HMAC_TYPE_VALIDFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_HMAC_TYPE_VALIDFAIL*/ FKO_ERROR_INVALID_DATA_HMAC_LEN_VALIDFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_HMAC_LEN_VALIDFAIL*/ FKO_ERROR_INVALID_DATA_MESSAGE_PORT_MISSING, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_MESSAGE_PORT_MISSING*/ FKO_ERROR_INVALID_DATA_MESSAGE_TYPE_VALIDFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_MESSAGE_TYPE_VALIDFAIL*/ FKO_ERROR_INVALID_DATA_MESSAGE_EMPTY, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_MESSAGE_EMPTY*/ FKO_ERROR_INVALID_DATA_MESSAGE_CMD_MISSING, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_MESSAGE_CMD_MISSING*/ FKO_ERROR_INVALID_DATA_MESSAGE_ACCESS_MISSING, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_MESSAGE_ACCESS_MISSING*/ FKO_ERROR_INVALID_DATA_MESSAGE_NAT_MISSING, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_MESSAGE_NAT_MISSING*/ FKO_ERROR_INVALID_DATA_MESSAGE_PORTPROTO_MISSING, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_MESSAGE_PORTPROTO_MISSING*/ FKO_ERROR_INVALID_DATA_NAT_EMPTY, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_NAT_EMPTY*/ FKO_ERROR_INVALID_DATA_RAND_LEN_VALIDFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_RAND_LEN_VALIDFAIL*/ FKO_ERROR_INVALID_DATA_SRVAUTH_MISSING, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_SRVAUTH_MISSING*/ FKO_ERROR_INVALID_DATA_TIMESTAMP_VALIDFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_TIMESTAMP_VALIDFAIL*/ FKO_ERROR_INVALID_DATA_USER_MISSING, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_USER_MISSING*/ FKO_ERROR_INVALID_DATA_USER_FIRSTCHAR_VALIDFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_USER_FIRSTCHAR_VALIDFAIL*/ FKO_ERROR_INVALID_DATA_USER_REMCHAR_VALIDFAIL, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_USER_REMCHAR_VALIDFAIL*/ FKO_ERROR_INVALID_DATA_UTIL_STRTOL_LT_MIN, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_UTIL_STRTOL_LT_MIN*/ FKO_ERROR_INVALID_DATA_UTIL_STRTOL_GT_MAX, /**< Args contain invalid data: FKO_ERROR_INVALID_DATA_UTIL_STRTOL_GT_MAX*/ FKO_ERROR_DATA_TOO_LARGE, /**< Value or Size of the data exceeded the max allowed*/ FKO_ERROR_INVALID_KEY_LEN, /**< Invalid key length*/ FKO_ERROR_USERNAME_UNKNOWN, /**< Unable to determine username*/ FKO_ERROR_INCOMPLETE_SPA_DATA, /**< Missing or incomplete SPA data*/ FKO_ERROR_MISSING_ENCODED_DATA, /**< There is no encoded data to process*/ FKO_ERROR_INVALID_DIGEST_TYPE, /**< Invalid digest type*/ FKO_ERROR_INVALID_ALLOW_IP, /**< Invalid allow IP address in the SPA message data*/ FKO_ERROR_INVALID_SPA_COMMAND_MSG, /**< Invalid SPA command message format*/ FKO_ERROR_INVALID_SPA_ACCESS_MSG, /**< Invalid SPA access message format*/ FKO_ERROR_INVALID_SPA_NAT_ACCESS_MSG, /**< Invalid SPA nat_access message format*/ FKO_ERROR_INVALID_ENCRYPTION_TYPE, /**< Invalid encryption type*/ FKO_ERROR_WRONG_ENCRYPTION_TYPE, /**< Wrong or inappropriate encryption type for this operation*/ FKO_ERROR_DECRYPTION_SIZE, /**< Unexpected or invalid size for decrypted data*/ FKO_ERROR_DECRYPTION_FAILURE, /**< Decryption failed or decrypted data is invalid*/ FKO_ERROR_DIGEST_VERIFICATION_FAILED, /**< The computed digest did not match the digest in the spa data*/ FKO_ERROR_INVALID_HMAC_KEY_LEN, /**< Invalid HMAC key length*/ FKO_ERROR_UNSUPPORTED_HMAC_MODE, /**< Unsupported HMAC mode (default: SHA256)*/ FKO_ERROR_UNSUPPORTED_FEATURE, /**< Unsupported or unimplemented feature or function*/ FKO_ERROR_ZERO_OUT_DATA, /**< Could not zero out sensitive data*/ FKO_ERROR_UNKNOWN, /**< Unknown/Unclassified error*/ /* Start GPGME-related errors (NOTE: Do not put non-GPG-related error * below this point). */ GPGME_ERR_START, /**< Not a real error, marker for start of GPG errors*/ FKO_ERROR_MISSING_GPG_KEY_DATA, /**< Missing GPG key data (signer or recipient not set)*/ FKO_ERROR_GPGME_NO_OPENPGP, /**< This GPGME implementation does not support OpenPGP*/ FKO_ERROR_GPGME_CONTEXT, /**< Unable to create GPGME context*/ FKO_ERROR_GPGME_PLAINTEXT_DATA_OBJ, /**< Error creating the plaintext data object*/ FKO_ERROR_GPGME_SET_PROTOCOL, /**< Unable to set GPGME to use OpenPGP protocol*/ FKO_ERROR_GPGME_CIPHER_DATA_OBJ, /**< Error creating the encrypted data data object*/ FKO_ERROR_GPGME_BAD_PASSPHRASE, /**< The GPG passphrase was not valid*/ FKO_ERROR_GPGME_ENCRYPT_SIGN, /**< Error during the encrypt and sign operation*/ FKO_ERROR_GPGME_CONTEXT_SIGNER_KEY, /**< Unable to create GPGME context for the signer key*/ FKO_ERROR_GPGME_SIGNER_KEYLIST_START, /**< Error from signer keylist start operation*/ FKO_ERROR_GPGME_SIGNER_KEY_NOT_FOUND, /**< The key for the given signer was not found*/ FKO_ERROR_GPGME_SIGNER_KEY_AMBIGUOUS, /**< Ambiguous name/id for the signer key (multiple matches)*/ FKO_ERROR_GPGME_ADD_SIGNER, /**< Error adding the signer key to the gpgme context*/ FKO_ERROR_GPGME_CONTEXT_RECIPIENT_KEY, /**< Unable to create GPGME context for the recipient key*/ FKO_ERROR_GPGME_RECIPIENT_KEYLIST_START, /**< Error from signer keylist start operation*/ FKO_ERROR_GPGME_RECIPIENT_KEY_NOT_FOUND, /**< The key for the given recipient was not found*/ FKO_ERROR_GPGME_RECIPIENT_KEY_AMBIGUOUS, /**< Ambiguous name/id for the recipient key (multiple matches)*/ FKO_ERROR_GPGME_DECRYPT_FAILED, /**< Decryption operation failed*/ FKO_ERROR_GPGME_DECRYPT_UNSUPPORTED_ALGORITHM, /**< Decryption operation failed due to unsupported algorithm*/ FKO_ERROR_GPGME_BAD_GPG_EXE, /**< Unable to stat the given GPG executable*/ FKO_ERROR_GPGME_BAD_HOME_DIR, /**< Unable to stat the given GPG home directory*/ FKO_ERROR_GPGME_SET_HOME_DIR, /**< Unable to set the given GPG home directory*/ FKO_ERROR_GPGME_NO_SIGNATURE, /**< Missing GPG signature*/ FKO_ERROR_GPGME_BAD_SIGNATURE, /**< Bad GPG signature*/ FKO_ERROR_GPGME_SIGNATURE_VERIFY_DISABLED, /**< Trying to check signature with verification disabled*/ FKO_LAST_ERROR /**< Not a real error, must be last of enum*/ } fko_error_codes_t; /** Macro that returns true if the given error code is a gpg-related error. */ #define IS_GPG_ERROR(x) (x > GPGME_ERR_START && x < FKO_LAST_ERROR) /* General Defaults */ #define FKO_DEFAULT_MSG_TYPE FKO_ACCESS_MSG #define FKO_DEFAULT_DIGEST FKO_DIGEST_SHA256 #define FKO_DEFAULT_ENCRYPTION FKO_ENCRYPTION_RIJNDAEL #define FKO_DEFAULT_ENC_MODE FKO_ENC_MODE_CBC #define FKO_DEFAULT_KEY_LEN 0 #define FKO_DEFAULT_HMAC_KEY_LEN 0 #define FKO_DEFAULT_HMAC_MODE FKO_HMAC_SHA256 /* Define the consistent prefixes or salt on some encryption schemes. */ #define B64_RIJNDAEL_SALT "U2FsdGVkX1" #define B64_RIJNDAEL_SALT_STR_LEN 10 #define B64_GPG_PREFIX "hQ" #define B64_GPG_PREFIX_STR_LEN 2 /* Specify whether libfko is allowed to call exit() */ #define EXIT_UPON_ERR 1 #define NO_EXIT_UPON_ERR 0 /* The context holds the global state and config options, as * well as some intermediate results during processing. This * is an opaque pointer. */ struct fko_context; typedef struct fko_context *fko_ctx_t; /* Some gpg-specifc data types and constants. */ #if HAVE_LIBGPGME enum { FKO_GPG_NO_SIG_VERIFY_SIGS = 0x01, FKO_GPG_ALLOW_BAD_SIG = 0x02, FKO_GPG_NO_SIG_INFO = 0x04, FKO_GPG_ALLOW_EXPIRED_SIG = 0x08, FKO_GPG_ALLOW_REVOKED_SIG = 0x10 }; #define FKO_GPG_GOOD_SIGSUM 3 #endif /* HAVE_LIBGPGME */ /* Function prototypes */ /* General API calls */ /** * \brief Initialize a new FKO context * * This function initializes an FKO context, and sets some default values. * The FKO context must first be declared, ex: fko_ctx_t ctx; * The pointer to the context should then be passed into fko_new. * * \param ctx Pointer to the FKO context to be initialized * * \return FKO_SUCCESS if successful, returns an error code otherwise. */ DLL_API int fko_new(fko_ctx_t *ctx); /** * \brief Initialize a new FKO context with data * * The function 'fko_new_with_data' sets up and initializes a new * 'fko_ctx_t' context, but instead of initializing default values, it * stores the encrypted message data and makes it ready for parsing. * This can be done in one of two ways. One is to pass 'NULL' for the * third argument. The context will be created and the data will be * stored, but no decryption or decoding takes place. In this case, * you will need to call 'fko_decrypt_spa_data' at a later time. The * other way to do it is to supply the KEY value (decryption * passphrase) and assocated length. In this case, the context is * created, the SPA data is decrypted, decoded, parsed, and stored in * the context ready for retrieval. If an HMAC is also desired or * required, then the HMAC_KEY and associated length can be passed in. * This will cause libfko to authenticate the SPA data before * decryption is attempted, and this is strongly recommended to do. * * \param ctx Pointer to the FKO context to be initialized * \param enc_msg Pointer to the message to be decoded, should be null terminated * \param dec_key Pointer to the decryption key. Expects either text or unsigned char. * \param dec_key_len Size of the decryption key. * \param encryption_mode Describes the mode of encryption used. Most common is FKO_ENC_MODE_CBC, which is AES in CBC mode. * \param hmac_key This is the pointer to the HMAC key. Expected to be either text or unsigned char. * \param hmac_key_len Size of the HMAC key * \param hmac_type Describes which hash function to use for the HMAC. * * \return FKO_SUCCESS if successful, returns an error code otherwise. */ DLL_API int fko_new_with_data(fko_ctx_t *ctx, const char * const enc_msg, const char * const dec_key, const int dec_key_len, int encryption_mode, const char * const hmac_key, const int hmac_key_len, const int hmac_type); /** * \brief Clean up the fko context * * The function 'fko_destroy' destroys the context with the handle CTX * and releases all associated resources. * * \param Pointer to the context to destroy. * * \return FKO_SUCCESS if successful, returns an error code otherwise. */ DLL_API int fko_destroy(fko_ctx_t ctx); /** * \brief Final encoding of SPA data * * This function is the final step in creating a complete encrypted * SPA data string suitable for transmission to an fwknop server. It * does require all of the requisite SPA data fields be set, otherwise * it will fail with an appropriate error code. * * \param ctx The fko context containing the fields to be encoded and encrypted * \param enc_key The encryption key to be used * \param enc_key_len The size of the encryption key * \param hmac_key The HMAC key to be used * \param hmac_key_len The size of the HMAC key * * \return FKO_SUCCESS if successful, returns an error code otherwise. */ DLL_API int fko_spa_data_final(fko_ctx_t ctx, const char * const enc_key, const int enc_key_len, const char * const hmac_key, const int hmac_key_len); /* Set context data functions */ /** * \brief Set or Generate random nonce * * Set the random value portion of the spa data to the given value * (VAL). The given value must be a pointer to a 16-character decimal * numeric string or NULL. If the value is NULL, the function generate * a new random value. If a string value is provided, it must be a * 16-character decimal string. Otherwise, the function will return * 'FKO_ERROR_INVALID_DATA'. * * \param ctx The FKO context to modify * \param val The 16 digits of random value, may be null * * \return FKO_SUCCESS if successful, returns an error code otherwise. */ DLL_API int fko_set_rand_value(fko_ctx_t ctx, const char * const val); /** * \brief Set FKO username * * Set the username field of the SPA data. If USERNAME is NULL, * libfko will first look for the environment variable 'SPOOF_USER' * and use its value if found. Otherwise, it will try to determine * the username itself using various methods starting with 'cuser' or * 'getlogin', then fallback to the environment variables 'LOGNAME' or * 'USER'. If none of those work, the function will return * 'FKO_ERROR_USERNAME_UNKNOWN'. * * \param ctx the FKO context to modify * \param spoof_user The username to set in the FKO context * * \return FKO_SUCCESS if successful, returns an error code otherwise. */ DLL_API int fko_set_username(fko_ctx_t ctx, const char * const spoof_user); /** * \brief Sets the SPA timestamp value. * * Sets the timestamp value of the SPA data to the current time plus * the offset value. The time is measured in seconds. * * \param ctx The FKO context to modify * \param offset The time offset in seconds. This value may be negative. * * \return FKO_SUCCESS if successful, returns an error code otherwise. */ DLL_API int fko_set_timestamp(fko_ctx_t ctx, const int offset); /** * \brief Sets the message type for the SPA data. * * \param ctx The FKO context to modify * \param ctx msg_type The message type to be set, one of [these options](@ref fko_message_type_t) * * \return FKO_SUCCESS if successful, returns an error code otherwise. */ DLL_API int fko_set_spa_message_type(fko_ctx_t ctx, const short msg_type); /** * \brief Set the SPA message string to the given value. * * If this string does not conform to the required 'spa_nat_access' format, the function * will return 'FKO_ERROR_INVALID_DATA'. * * \param ctx The FKO context to modify * \param msg_string The null terminated string to be pushed into the context * * \return FKO_SUCCESS if successful, returns an error code otherwise. */ DLL_API int fko_set_spa_message(fko_ctx_t ctx, const char * const msg_string); /** * \brief Set the optional SPA nat access string to the given value. * * If this string does not conform to the required 'spa_nat_access' format, * the function will return 'FKO_ERROR_INVALID_DATA'. * * \param ctx The FKO context to modify * \param nat_access The null terminated string to be pushed into the context * * \return FKO_SUCCESS if successful, returns an error code otherwise. */ DLL_API int fko_set_spa_nat_access(fko_ctx_t ctx, const char * const nat_access); /** * \brief Set the optional SPA server auth feature to the given value. * * This parameter is very seldom used and may become deprecated. * * \todo finish the function's description * * \param ctx The FKO context to modify * \param server_auth * * \return FKO_SUCCESS if successful, returns an error code otherwise. */ DLL_API int fko_set_spa_server_auth(fko_ctx_t ctx, const char * const server_auth); /** * \brief Sets the SPA client timeout value. * * If the timeout is set to a value greater than 0, it is assumed the * 'spa_message_type' setting should be one of the "TIMEOUT" variants. * This function will change the 'message_type' to the appropriate setting if necessary. * However, it is recommended you set the correct 'message_type' ahead of time. * * \param ctx The FKO context to modify * \param timeout The timeout value in seconds to be pushed into the FKO context * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_set_spa_client_timeout(fko_ctx_t ctx, const int timeout); /** * \brief Set the message digest type. * *If a value other than the those that are supported is given, * the function will return 'FKO_ERROR_INVALID_DATA'. * * \param ctx The FKO context to modify * \param digest_type a message type as defined in [fko_digest_type](@ref fko_digest_type_t). * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_set_spa_digest_type(fko_ctx_t ctx, const short digest_type); /** * \brief Trigger calculation of message digest * * Initiates a calculation (or recalculation) of the message digest hash for the current * SPA data. If the required data fields are not set this function will return * 'FKO_ERROR_MISSING_ENCODED_DATA'. * *Note*: It should not be necessary to call this function directly * as it will be called automatically by other functions during * normal processing (most notably '[fko_spa_data_final](\ref fko_spa_data_final)'). * * \param ctx The FKO context to modify * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_set_spa_digest(fko_ctx_t ctx); /** * \brief set the raw digest type * * \todo complete documentation for this function * * \param ctx The FKO context to modify * \param raw_digest_type * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_set_raw_spa_digest_type(fko_ctx_t ctx, const short raw_digest_type); /** * \brief set the raw digest * * \todo complete documentation for this function * * \param ctx The FKO context to modify * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_set_raw_spa_digest(fko_ctx_t ctx); /** * \brief Set the encrytion algorithm * * Set the encrytion algorithm to use when ecrypting the final SPA * data. Valid values can be found in [FKO_ENCRYPTION_TYPE_T](\ref FKO_ENCRYPTION_TYPE_T) * of this manual. For example: * * rc = fko_set_spa_encryption_type(ctx, FKO_ENCRYPTION_RIJNDAEL); * * \param ctx The FKO context to modify * \param the encryption type to use * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_set_spa_encryption_type(fko_ctx_t ctx, const short encrypt_type); /** * \brief Set encryption mode * * \param ctx The FKO context to modify * \param encryption mode, must be one of [fko_encryption_mode_t](\ref fko_encryption_mode_t) * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_set_spa_encryption_mode(fko_ctx_t ctx, const int encrypt_mode); /** * \brief place encrypted SPA data into a newly created empty context * * This function is used to place encrypted SPA data into a newly * created empty context (i.e. with 'fko_new'). In most cases, you * would use 'fko_new_with_data' so you wouldn't have to take the * extra step to use this function. However, some may find a reason * to do it in this way. * * \param ctx The FKO context to modify * \param enc_msg The encrypted message to push into the fko context * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_set_spa_data(fko_ctx_t ctx, const char * const enc_msg); #if AFL_FUZZING DLL_API int fko_afl_set_spa_data(fko_ctx_t ctx, const char * const enc_msg, const int enc_msg_len); #endif /** * \brief Set the message hmac type. * * \param ctx The FKO context to modify * \param The hmac_type, must be one of [fko_hmac_type_t](\ref fko_hmac_type_t) * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_set_spa_hmac_type(fko_ctx_t ctx, const short hmac_type); /* Data processing and misc utility functions */ /** * \brief Return error in string form * * The function 'fko_errstr' returns a pointer to a statically * allocated string containing the description of the error. * * \param err_code The error code to convert * * \return Returns a pointer to the error string */ DLL_API const char* fko_errstr(const int err_code); /** * \brief Return the assumed encryption type based on the raw encrypted data. * * \param The encrypted data to process * * \return Returns a value from [fko_encryption_type_t](\ref fko_encryption_type_t) */ DLL_API int fko_encryption_type(const char * const enc_data); /** * \brief generates random keys * * \param key_base64 pass a pointer into the function to be filled with the generated key * \param key_len Length of key to generate, use FKO_DEFAULT_KEY_LEN for default length * \param hmac_key_base64 pass a pointer into the function to be filled with the generated hmac key * \param hmac_key_len Length of hmac key to generate, use FKO_DEFAULT_HMAC_KEY_LEN for default length * \param hmac_type used to determine the default HMAC length, must be one of [fko_hmac_type_t](\ref fko_hmac_type_t) * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_key_gen(char * const key_base64, const int key_len, char * const hmac_key_base64, const int hmac_key_len, const int hmac_type); /** * \brief Encodes text or binary data into base64 * * Function takes text or binary data and returns a base64 encoded string. * This implements base64 encoding as per rfc 4648. * (This is not the url safe encoding scheme) * * \param in Pointer to input data. May be text or binary data * \param out Pointer to the base64 encoded data * \param in_length Size in bytes of the input * * \return Returns length of base64 encoded output * \todo add CUnit test of base64 encoding: https://tools.ietf.org/html/rfc4648 */ DLL_API int fko_base64_encode(unsigned char * const in, char * const out, int in_len); /** * \brief Decodes base64 into text or binary data * * Function takes a base64 encoded string and returns the resulting text or binary data * This implements base64 decoding as per rfc 4648. * (This is not the url safe encoding scheme) * * \param in Pointer to input data. Must be Base64 encoded * \param out Pointer to the resulting data * * \return Returns length in bytes of decoded output * \todo add CUnit test of base64 decoding: https://tools.ietf.org/html/rfc4648 */ DLL_API int fko_base64_decode(const char * const in, unsigned char *out); /** * \brief Encodes data in SPA context * * Performs the base64 encoding of those SPA data fields that need to be encoded, * performs some data validation, and calls 'fkp_set_spa_digest' to recompute * the SPA message digest. It is normally not called directly as it is called * from 'fko_encrypt_spa_data' (which is in turn called from 'fko_spa_data_final'). * * \param ctx The FKO context to process * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_encode_spa_data(fko_ctx_t ctx); /** * \brief Decodes data in an SPA context * * This function performs the decoding, parsing, validation of the SPA * data that was just decrypted. It is normally not called directly * as it is called from 'fko_decrypt_spa_data' (which is in turn * called from 'fko_new_with_data' if a password is supplied to it). * * \param ctx The FKO context to decode * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_decode_spa_data(fko_ctx_t ctx); /** * \brief encrypt the date in the FKO context * * Encrypts the intermediate encoded SPA data stored in the context. * This function will call 'fko_encode' if necessary. It is normally * not called directly as it is called from 'fko_spa_data_final'. * * \param ctx The FKO context to encrypt * \param enc_key The encryption key to use * \param enc_key_len the length of the encryption key * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_encrypt_spa_data(fko_ctx_t ctx, const char * const enc_key, const int enc_key_len); /** * \brief decrypts and decodes the SPA message * * When given the correct KEY (password), this function decrypts, * decodes, and parses the encrypted SPA data that was supplied to the * context via the 'fko_new_with_data' function that was also called * without the KEY value. Once the data is decrypted, this function * will also call 'fko_decode_spa_data' to decode, parse, validate, * and store the data fields in the context for later retrieval. * * \param ctx The FKO context to decrypt * \param dec_key the key to use when decrypting * \param dec_key_len the size of kec_key * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_decrypt_spa_data(fko_ctx_t ctx, const char * const dec_key, const int dec_key_len); /** * \brief verifies the HMAC signature for a received message * * \param ctx The FKO context that has the message loaded * \param hmac_key The expected HMAC key to verify * \param hmac_key_len The size of hmac_key * * \return FKO_SUCCESS if the message verifies, returns an error code otherwise */ DLL_API int fko_verify_hmac(fko_ctx_t ctx, const char * const hmac_key, const int hmac_key_len); /** * \brief Set and calculate the HMAC * * Initiates a calculation (or recalculation) of the message HMAC for * the current SPA data. *Note*: It should not be necessary to call * this function directly as it will be called automatically by other * functions during normal processing (most notably 'fko_spa_data_final'). * * \param ctx The FKO context to modify * \param hmac_key the HMAC key to use * \param hmac_key_len the size of hmac_key * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_set_spa_hmac(fko_ctx_t ctx, const char * const hmac_key, const int hmac_key_len); /** * \brief get a pointer to the HMAC value from FKO context * * Assigns the pointer to the string holding the the fko SPA HMAC value * associated with the current context to the address SPA_HMAC is pointing to. * * \param ctx The FKO context to use * \param enc_data Pointer to the pointer to be assigned * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_get_spa_hmac(fko_ctx_t ctx, char **enc_data); /** * \brief get a pointer to the SPA data * * Assigns the pointer to the string holding the the encoded SPA data * (before encryption) associated with the current context to the * address ENC_MSG is pointing to. This is intermediate data that * would not normally be of use unless debugging the library. * * \param ctx The FKO context to use * \param enc_data Pointer to the pointer to be assigned * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_get_encoded_data(fko_ctx_t ctx, char **enc_data); #if FUZZING_INTERFACES DLL_API int fko_set_encoded_data(fko_ctx_t ctx, const char * const encoded_msg, const int msg_len, const int do_digest, const int digest_type); #endif /* Get context data functions */ /** * \brief get nonce from FKO context * * Assigns the pointer to the string holding the random 16-character * decimal number ('rand_val') associated with the current context to * the address RAND_VAL is pointing to. * * \param ctx The FKO context to access * \param rand_val Pointer to the pointer to be assigned * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_get_rand_value(fko_ctx_t ctx, char **rand_val); /** * \brief get username from FKO context * * Assigns the pointer to the string holding the username associated * with the current context to the address RAND_VAL is pointing to. * * \param ctx The FKO context to access * \param Pointer to the pointer to be assigned * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_get_username(fko_ctx_t ctx, char **username); /** * \brief get timestamp from FKO context * * Sets the value of the TIMESTAMP variable to the timestamp value * associated with the current context. * * \param ctx The FKO context to access * \param ts Pointer to variable that will be set to the timestamp * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_get_timestamp(fko_ctx_t ctx, time_t *ts); /** * \brief get message type from FKO context * * Sets the value of the MSG_TYPE variable to the SPA message type * value associated with the current context. This value can be * checked against the list of valid message_types listed in [fko_message_type_t](\ref fko_message_type_t) * For example: * ~~~ short msg_type; rc = fko_get_spa_message_type(ctx, &msg_type); switch(msg_type) { case FKO_ACCESS_MSG: process_access_msg(...); break; case FKO_NAT_ACCESS_MSG: process_nat_access_msg(...); break; //...and so on... } ~~~ * * \param ctx The FKO context to access * \param spa_msg pointer to variable that will be set with the message type value * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_get_spa_message_type(fko_ctx_t ctx, short *spa_msg); /** * \brief get spa message from FKO context * * Assigns the pointer to the string holding the the fko SPA request message * associated with the current context to the address SPA_MSG is pointing to. * * \param ctx The FKO context to access * \param spa_message Pointer to the pointer to be assigned * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_get_spa_message(fko_ctx_t ctx, char **spa_message); /** * \brief get nat access string from FKO context * * Assigns the pointer to the string holding the the fko SPA nat * access message associated with the current context to the address * NAT_ACCESS is pointing to. * * \param ctx The FKO context to access * \param nat_access Pointer to the pointer to be assigned * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_get_spa_nat_access(fko_ctx_t ctx, char **nat_access); /** * \brief get server auth string from FKO context * * Assigns the pointer to the string holding the the fko SPA server * auth message associated with the current context to the address * SERVER_AUTH is pointing to. * * \param ctx The FKO context to access * \param server_auth Pointer to the pointer to be assigned * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_get_spa_server_auth(fko_ctx_t ctx, char **server_auth); /** * \brief get client timeout from FKO context * * Sets the value of the CLIENT_TIMEOUT variable to the client_timeout * value associated with the current context. * * \param ctx The FKO context to access * \param client_timeout Pointer to the pointer to be assigned * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_get_spa_client_timeout(fko_ctx_t ctx, int *client_timeout); /** * \brief get digest type from the FKO context * * Sets the value of the DIGEST_TYPE variable to the digest type value * associated with the current context. This value can be checked * against the list of valid digest_types listed in [fko_digest_type_t] (\ref fko_digest_type_t) * * \param ctx The FKO context to access * \param spa_digest_type pointer to the variable to fill with the digest type * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_get_spa_digest_type(fko_ctx_t ctx, short *spa_digest_type); /** * \brief get the raw digest type * * \param ctx The FKO context to access * \param raw_spa_digest_type * * \todo finish documentation for this function * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_get_raw_spa_digest_type(fko_ctx_t ctx, short *raw_spa_digest_type); /** * \brief get the hmac type from the FKO context * * Sets the value of the HMAC_TYPE variable to the HMAC type value * associated with the current context. This value can be checked * against the list of valid hmac_types listed in [fko_hmac_type_t](\ref fko_hmac_type_t) * * \param ctx The FKO context to access * \param spa_hmac_type pointer to the variable to fill with the hmac type * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_get_spa_hmac_type(fko_ctx_t ctx, short *spa_hmac_type); /** * \brief get the digest value from the FKO context * * Assigns the pointer to the string holding the the fko SPA digest * value associated with the current context to the address SPA_DIGEST * is pointing to. * * \param ctx The FKO context to access * \param spa_digest Pointer to the pointer to be assigned * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_get_spa_digest(fko_ctx_t ctx, char **spa_digest); /** * \brief get raw spa digest * * \todo Finish the documentation for this function * * \param ctx The FKO context to access * \param raw_spa_digest Pointer to the pointer to be assigned * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_get_raw_spa_digest(fko_ctx_t ctx, char **raw_spa_digest); /** * \brief get the encryption type from the SPA context * * Sets the value of the ENC_TYPE variable to the encryption type * value associated with the current context. This value can be * checked against the list of valid encryption types listed in [fko_encryption_type_t](\ref fko_encryption_type_t) * * \param ctx The FKO context to access * \param spa_enc_type pointer to the variable to fill with the encryption type * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_get_spa_encryption_type(fko_ctx_t ctx, short *spa_enc_type); /** * \brief get the encryption mode from the FKO context * * Sets the value of the ENC_MODE variable to the encryption mode associated * with the current context. This value can be checked against the list of * valid encryption modes listed in [fko_encryption_mode_t](\ref fko_encryption_mode_t) * * \param ctx The FKO context to access * \param spa_enc_mode pointer to the variable to fill with the encryption mode * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_get_spa_encryption_mode(fko_ctx_t ctx, int *spa_enc_mode); /** * \brief get the encrypted SPA data from the SPA context * * Assigns the pointer to the string holding the final encrypted SPA * data to the address SPA_DATA is pointing to. This is the data that * would be packaged into a packet and sent to an fwknop server. * * \param ctx The FKO context to access * \param spa_data Pointer to the pointer to be assigned * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_get_spa_data(fko_ctx_t ctx, char **spa_data); /** * \brief get SPA version from SPA context * * Assigns the pointer to the string holding the the SPA version value * associated with the current context to the address FKO_VERSION is * pointing to. This is a static value for SPA data that is being * created in a new context. For data parsed from an external source, * the version string will be whatever version the sending client used. * * \param ctx The FKO context to access * \param version Pointer to the pointer to be assigned * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_get_version(fko_ctx_t ctx, char **version); /* GPG-related functions */ /** * \brief set the GPG executable * * Sets the path to the GPG executable that _gpgme_ will use. By * default, _libfko_ forces _gpgme_ to use 'gpg' in case _gpgme_ was * compiled to use 'gpg2' as its default engine. You can use this * function to override and set what GPG executable _gpgme_ will use. * * \param ctx The FKO context to modify * \param The path to the GPG executable * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_set_gpg_exe(fko_ctx_t ctx, const char * const gpg_exe); /** * \brief gets the GPG executable from the FKO context * * Assigns the pointer to the string holding the the GPG executable * path associated with the current context to the address GPG_EXE is * pointing to. * * \param ctx The FKO context to access * \param gpg_exe Pointer to the pointer to assign to the executable name * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_get_gpg_exe(fko_ctx_t ctx, char **gpg_exe); /** * \brief set the recipient GPG key * * Sets the GPG key for the recipient. This would be the recipient's * public key used to encyrpt the SPA data. You can use the user name * ("recip@the.dest.com") or the key ID ("5EXXXXCC"). At present, * multiple recipients are not supported. * * \param ctx The FKO context to modify * \param recip The key to set * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_set_gpg_recipient(fko_ctx_t ctx, const char * const recip); /** * \brief get the GPG recipient ID from the FKO context * * Assigns the pointer to the string holding the the GPG recipient ID * associated with the current context to the address RECIPIENT is * pointing to. * * \param ctx The FKO context to access * \param Pointer to the pointer to assign the value * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_get_gpg_recipient(fko_ctx_t ctx, char **recip); /** * \brief Set the GPG signing key * * Sets the GPG key for signing the data. This would be the sender's * key used to sign the SPA data. You can use the user name or key * ID. * * \param ctx The FKO context to modify * \param The GPG key to use for signing * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_set_gpg_signer(fko_ctx_t ctx, const char * const signer); /** * \brief Get the GPG signing key * * Assigns the pointer to the string holding the the GPG signer ID * associated with the current context to the address SIGNER is * pointing to. * * \param ctx The FKO context to access * \param signer pointer to the pointer to assign the value * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_get_gpg_signer(fko_ctx_t ctx, char **signer); /** * \brief set the GPG home directory * * Sets the GPG home directory for the current gpgme context. This * allows for using alternate keyrings, gpg configurations, etc. * * \param ctx The FKO context to modify * \param gpg_home_dir The path to set * * \return */ DLL_API int fko_set_gpg_home_dir(fko_ctx_t ctx, const char * const gpg_home_dir); /** * \brief get the GPG home directory from the FKO context * * Assigns the pointer to the string holding the the GPG home * directory associated with the current context to the address * GPG_DIR is pointing to. * * \param ctx The FKO context to access * \param gpg_home_dir Pointer to the pointer to assign the value * * \return */ DLL_API int fko_get_gpg_home_dir(fko_ctx_t ctx, char **gpg_home_dir); /** * \brief gets the text value of the current gpg error * * \param ctx The FKO context to access * * \return Returns the gpg error string */ DLL_API const char* fko_gpg_errstr(fko_ctx_t ctx); /** * \brief Set the GPG verify signature flag * * Sets the verify GPG signature flag. When set to a true value, the * GPG signature is extracted and checked for validity during the * decryption/decoding phase. When set to false, no attempt is made * to access or check the signature. This flag is set to true by default. * * \param ctx The FKO context to modify * \param val Set TRUE or FALSE to set flag * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_set_gpg_signature_verify(fko_ctx_t ctx, const unsigned char val); /** * \brief Get the value of the GPG signature verify flag * * Sets the value of the VAL variable to the current * gpg_signature_verify flag value associated with the current * context. * * \param ctx The FKO context to access * \param Pointer where flag value will be set * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_get_gpg_signature_verify(fko_ctx_t ctx, unsigned char * const val); /** * \brief set ignore signature verify error flag * * Sets the ignore signature verify error flag. When set to a true * value. Any signature verification errors are ignored (but still * captured) and the decoding process will continue. The default * value of this flag is false. * * \param ctx The FKO context to modify * \param val Set TRUE or FALSE to set the flag * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_set_gpg_ignore_verify_error(fko_ctx_t ctx, const unsigned char val); /** * \brief get the ignore_verify_error flag * * Sets the value of the VAL variable to the current * ignore_verify_error flag value associated with the current context. * * \param ctx The FKO context to access * \param val Pointer where the flag value will be set * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_get_gpg_ignore_verify_error(fko_ctx_t ctx, unsigned char * const val); /** * \brief get GPG signature id * * Assigns the pointer to the string holding the the GPG signature ID * associated with the current context to the address SIG_ID is * pointing to. * * \param ctx The FKO context to access * \param Pointer to the pointer where to set the value * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_get_gpg_signature_id(fko_ctx_t ctx, char **sig_id); /** * \brief get GPG signature fingerprint * * Assigns the pointer to the string holding the the GPG signature * fingerprint associated with the current context to the address * SIG_FPR is pointing to. * * \param ctx The FKO context to access * \param sig_fpr Pointer to the pointer where to set the value * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_get_gpg_signature_fpr(fko_ctx_t ctx, char **sig_fpr); /** * \brief get GPG signature summary * * Sets the value of the SIG_SUM variable to the GPG signature summary * value associated with the current context. * * \param ctx The FKO context to access * \param sigsum Pointer where to set the summary * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_get_gpg_signature_summary(fko_ctx_t ctx, int *sigsum); /** * \brief get the SIG_STAT * * Sets the value of the SIG_STAT variable to the GPG signature error * status value associated with the current context. * * \param ctx The FKO context to access * \param sigstat The pointer where to set the status * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_get_gpg_signature_status(fko_ctx_t ctx, int *sigstat); /** * \brief Query whether IDs match * * Sets the value of the ID_MATCH variable to true (1) if the value of * ID matches the ID of the GPG signature associated with the current * context. Otherwise, ID_MATCH is set to false (0). * * \param ctx The FKO context to access * \param id The id to compare * \param result Pointer where the result is stored * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_gpg_signature_id_match(fko_ctx_t ctx, const char * const id, unsigned char * const result); /** * \brief Compare GPG fingerprints * * Sets the value of the FPR_MATCH variable to true (1) if the value * of FPR matches the fingerprint of the GPG signature associated with * the current context. Otherwise, FPR_MATCH is set to false (0). * * \param ctx The FKO context to access * \param fpr The fingerprint to compare * \param result Pointer where the result is stored * * \return FKO_SUCCESS if successful, returns an error code otherwise */ DLL_API int fko_gpg_signature_fpr_match(fko_ctx_t ctx, const char * const fpr, unsigned char * const result); #ifdef __cplusplus } #endif #ifdef HAVE_C_UNIT_TESTS int register_ts_fko_decode(void); int register_ts_hmac_test(void); int register_ts_digest_test(void); int register_ts_aes_test(void); int register_utils_test(void); int register_base64_test(void); #endif #endif /* FKO_H */ /***EOF***/ fwknop-2.6.11/lib/gpgme_funcs.h0000664000175000017500000000315114560546213013252 00000000000000/** * \file lib/gpgme_funcs.h * * \brief Header for the fwknop gpgme_funcs.c. */ /* Fwknop is developed primarily by the people listed in the file 'AUTHORS'. * Copyright (C) 2009-2015 fwknop developers and contributors. For a full * list of contributors, see the file 'CREDITS'. * * License (GNU General Public License): * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #ifndef GPGME_FUNCS_H #define GPGME_FUNCS_H 1 #if HAVE_LIBGPGME #include #endif #include "fko.h" int gpgme_encrypt(fko_ctx_t ctx, unsigned char *in, size_t len, const char *pw, unsigned char **out, size_t *out_len); int gpgme_decrypt(fko_ctx_t ctx, unsigned char *in, size_t len, const char *pw, unsigned char **out, size_t *out_len); #if HAVE_LIBGPGME int get_gpg_key(fko_ctx_t fko_ctx, gpgme_key_t *mykey, const int signer); #endif #endif /* GPGME_FUNCS_H */ /***EOF***/ fwknop-2.6.11/lib/fko_limits.h0000664000175000017500000000465614560546213013130 00000000000000/** * \file lib/fko_limits.h * * \brief #defines for libfko limits */ /* Fwknop is developed primarily by the people listed in the file 'AUTHORS'. * Copyright (C) 2009-2015 fwknop developers and contributors. For a full * list of contributors, see the file 'CREDITS'. * * License (GNU General Public License): * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #ifndef FKO_LIMITS_H #define FKO_LIMITS_H 1 /* How much space we allow for the fko context error message buffer. */ #define MAX_FKO_ERR_MSG_SIZE 128 /* Define some limits (--DSS XXX: These sizes need to be reviewed) */ #define MAX_SPA_ENCRYPTED_SIZE 1500 #define MAX_SPA_CMD_LEN 1400 #define MAX_SPA_USERNAME_SIZE 64 #define MAX_SPA_MESSAGE_SIZE 256 #define MAX_SPA_NAT_ACCESS_SIZE 128 #define MAX_SPA_SERVER_AUTH_SIZE 64 #define MAX_SPA_TIMESTAMP_SIZE 12 #define MAX_SPA_VERSION_SIZE 8 /* 12.34.56 */ #define MAX_SPA_MESSAGE_TYPE_SIZE 2 #define MIN_SPA_ENCODED_MSG_SIZE 36 /* Somewhat arbitrary */ #define MAX_SPA_ENCODED_MSG_SIZE MAX_SPA_ENCRYPTED_SIZE #define MIN_SPA_PLAINTEXT_MSG_SIZE MIN_SPA_ENCODED_MSG_SIZE #define MAX_SPA_PLAINTEXT_MSG_SIZE MAX_SPA_ENCODED_MSG_SIZE #define MIN_GNUPG_MSG_SIZE 400 #define MIN_SPA_FIELDS 6 #define MAX_SPA_FIELDS 9 #define MAX_IPV4_STR_LEN 16 #define MIN_IPV4_STR_LEN 7 #define MAX_PROTO_STR_LEN 4 /* tcp, udp, icmp for now */ #define MAX_PORT_STR_LEN 5 #define MAX_PORT 65535 /* Misc. */ #define FKO_ENCODE_TMP_BUF_SIZE 1024 #define FKO_RAND_VAL_SIZE 16 #endif /* FKO_LIMITS_H */ /***EOF***/ fwknop-2.6.11/lib/sha2.c0000664000175000017500000007232514560546213011616 00000000000000/** * \file lib/sha2.c * * \brief An implementation of the SHA 26/384/512 digests. */ /* AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/ * * Copyright (c) 2000-2001, Aaron D. Gifford * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holder nor the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ***************************************************************************** */ #include /* memcpy()/memset() or bcopy()/bzero() */ #include /* assert() */ #include "sha2.h" #if HAVE_SYS_BYTEORDER_H #include #endif /* * ASSERT NOTE: * Some sanity checking code is included using assert(). On my FreeBSD * system, this additional code can be removed by compiling with NDEBUG * defined. Check your own systems manpage on assert() to see how to * compile WITHOUT the sanity checking code on your system. * * UNROLLED TRANSFORM LOOP NOTE: * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform * loop version for the hash transform rounds (defined using macros * later in this file). Either define on the command line, for example: * * cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c * * or define below: * * #define SHA2_UNROLL_TRANSFORM * */ /*** SHA-256/384/512 Machine Architecture Definitions *****************/ /* * BYTE_ORDER NOTE: * * Please make sure that your system defines BYTE_ORDER. If your * architecture is little-endian, make sure it also defines * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are * equivalent. * * If your system does not define the above, then you can do so by * hand like this: * * #define LITTLE_ENDIAN 1234 * #define BIG_ENDIAN 4321 * * And for little-endian machines, add: * * #define BYTE_ORDER LITTLE_ENDIAN * * Or for big-endian machines: * * #define BYTE_ORDER BIG_ENDIAN * * The FreeBSD machine this was written on defines BYTE_ORDER * appropriately by including (which in turn includes * where the appropriate definitions are actually * made). */ #ifndef BYTE_ORDER #ifdef WIN32 #define BYTE_ORDER BIG_ENDIAN #elif defined(_BIG_ENDIAN) #define BYTE_ORDER BIG_ENDIAN #elif defined(_LITTLE_ENDIAN) #define BYTE_ORDER LITTLE_ENDIAN #endif #endif #if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN) #error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN #endif /* * Define the followingsha2_* types to types of the correct length on * the native archtecture. Most BSD systems and Linux define u_intXX_t * types. Machines with very recent ANSI C headers, can use the * uintXX_t definintions from inttypes.h by defining SHA2_USE_INTTYPES_H * during compile or in the sha.h header file. * * Machines that support neither u_intXX_t nor inttypes.h's uintXX_t * will need to define these three typedefs below (and the appropriate * ones in sha.h too) by hand according to their system architecture. * * Thank you, Jun-ichiro itojun Hagino, for suggesting using u_intXX_t * types and pointing out recent ANSI C support for uintXX_t in inttypes.h. */ #ifdef SHA2_USE_INTTYPES_H typedef uint8_t sha2_byte; /* Exactly 1 byte */ typedef uint32_t sha2_word32; /* Exactly 4 bytes */ typedef uint64_t sha2_word64; /* Exactly 8 bytes */ #else /* SHA2_USE_INTTYPES_H */ typedef u_int8_t sha2_byte; /* Exactly 1 byte */ typedef u_int32_t sha2_word32; /* Exactly 4 bytes */ typedef u_int64_t sha2_word64; /* Exactly 8 bytes */ #endif /* SHA2_USE_INTTYPES_H */ /*** SHA-256/384/512 Various Length Definitions ***********************/ /* NOTE: Most of these are in sha2.h */ #define SHA256_SHORT_BLOCK_LEN (SHA256_BLOCK_LEN - 8) #define SHA384_SHORT_BLOCK_LEN (SHA384_BLOCK_LEN - 16) #define SHA512_SHORT_BLOCK_LEN (SHA512_BLOCK_LEN - 16) /*** ENDIAN REVERSAL MACROS *******************************************/ #if BYTE_ORDER == LITTLE_ENDIAN #define REVERSE32(w,x) { \ sha2_word32 tmp = (w); \ tmp = (tmp >> 16) | (tmp << 16); \ (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \ } #define REVERSE64(w,x) { \ sha2_word64 tmp = (w); \ tmp = (tmp >> 32) | (tmp << 32); \ tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \ ((tmp & 0x00ff00ff00ff00ffULL) << 8); \ (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \ ((tmp & 0x0000ffff0000ffffULL) << 16); \ } #endif /* BYTE_ORDER == LITTLE_ENDIAN */ /* * Macro for incrementally adding the unsigned 64-bit integer n to the * unsigned 128-bit integer (represented using a two-element array of * 64-bit words): */ #define ADDINC128(w,n) { \ (w)[0] += (sha2_word64)(n); \ if ((w)[0] < (n)) { \ (w)[1]++; \ } \ } /* * Macros for copying blocks of memory and for zeroing out ranges * of memory. Using these macros makes it easy to switch from * using memset()/memcpy() and using bzero()/bcopy(). * * Please define either SHA2_USE_MEMSET_MEMCPY or define * SHA2_USE_BZERO_BCOPY depending on which function set you * choose to use: */ #if !defined(SHA2_USE_MEMSET_MEMCPY) && !defined(SHA2_USE_BZERO_BCOPY) /* Default to memset()/memcpy() if no option is specified */ #define SHA2_USE_MEMSET_MEMCPY 1 #endif #if defined(SHA2_USE_MEMSET_MEMCPY) && defined(SHA2_USE_BZERO_BCOPY) /* Abort with an error if BOTH options are defined */ #error Define either SHA2_USE_MEMSET_MEMCPY or SHA2_USE_BZERO_BCOPY, not both! #endif #ifdef SHA2_USE_MEMSET_MEMCPY #define MEMSET_BZERO(p,l) memset((p), 0, (l)) #define MEMCPY_BCOPY(d,s,l) memcpy((d), (s), (l)) #endif #ifdef SHA2_USE_BZERO_BCOPY #define MEMSET_BZERO(p,l) bzero((p), (l)) #define MEMCPY_BCOPY(d,s,l) bcopy((s), (d), (l)) #endif /*** THE SIX LOGICAL FUNCTIONS ****************************************/ /* * Bit shifting and rotation (used by the six SHA-XYZ logical functions: * * NOTE: The naming of R and S appears backwards here (R is a SHIFT and * S is a ROTATION) because the SHA-256/384/512 description document * (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this * same "backwards" definition. */ /* Shift-right (used in SHA-256, SHA-384, and SHA-512): */ #define R(b,x) ((x) >> (b)) /* 32-bit Rotate-right (used in SHA-256): */ #define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b)))) /* 64-bit Rotate-right (used in SHA-384 and SHA-512): */ #define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b)))) /* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */ #define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) #define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) /* Four of six logical functions used in SHA-256: */ #define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x))) #define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x))) #define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x))) #define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x))) /* Four of six logical functions used in SHA-384 and SHA-512: */ #define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x))) #define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x))) #define sigma0_512(x) (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7, (x))) #define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R( 6, (x))) /*** INTERNAL FUNCTION PROTOTYPES *************************************/ /* NOTE: These should not be accessed directly from outside this * library -- they are intended for private internal visibility/use * only. */ void SHA512_Last(SHA512_CTX*); void SHA256_Transform(SHA256_CTX*, const sha2_word32*); void SHA512_Transform(SHA512_CTX*, const sha2_word64*); /*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/ /* Hash constant words K for SHA-256: */ const static sha2_word32 K256[64] = { 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL }; /* Initial hash value H for SHA-256: */ const static sha2_word32 sha256_initial_hash_value[8] = { 0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, 0xa54ff53aUL, 0x510e527fUL, 0x9b05688cUL, 0x1f83d9abUL, 0x5be0cd19UL }; /* Hash constant words K for SHA-384 and SHA-512: */ const static sha2_word64 K512[80] = { 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL }; /* Initial hash value H for SHA-384 */ const static sha2_word64 sha384_initial_hash_value[8] = { 0xcbbb9d5dc1059ed8ULL, 0x629a292a367cd507ULL, 0x9159015a3070dd17ULL, 0x152fecd8f70e5939ULL, 0x67332667ffc00b31ULL, 0x8eb44a8768581511ULL, 0xdb0c2e0d64f98fa7ULL, 0x47b5481dbefa4fa4ULL }; /* Initial hash value H for SHA-512 */ const static sha2_word64 sha512_initial_hash_value[8] = { 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL }; /*** SHA-256: *********************************************************/ void SHA256_Init(SHA256_CTX* context) { if (context == (SHA256_CTX*)0) { return; } MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LEN); MEMSET_BZERO(context->buffer, SHA256_BLOCK_LEN); context->bitcount = 0; } #ifdef SHA2_UNROLL_TRANSFORM /* Unrolled SHA-256 round macros: */ #if BYTE_ORDER == LITTLE_ENDIAN #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ REVERSE32(*data++, W256[j]); \ T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ K256[j] + W256[j]; \ (d) += T1; \ (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ j++ #else /* BYTE_ORDER == LITTLE_ENDIAN */ #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ K256[j] + (W256[j] = *data++); \ (d) += T1; \ (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ j++ #endif /* BYTE_ORDER == LITTLE_ENDIAN */ #define ROUND256(a,b,c,d,e,f,g,h) \ s0 = W256[(j+1)&0x0f]; \ s0 = sigma0_256(s0); \ s1 = W256[(j+14)&0x0f]; \ s1 = sigma1_256(s1); \ T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \ (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \ (d) += T1; \ (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ j++ void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) { sha2_word32 a, b, c, d, e, f, g, h, s0, s1; sha2_word32 T1, *W256; int j; W256 = (sha2_word32*)context->buffer; /* Initialize registers with the prev. intermediate value */ a = context->state[0]; b = context->state[1]; c = context->state[2]; d = context->state[3]; e = context->state[4]; f = context->state[5]; g = context->state[6]; h = context->state[7]; j = 0; do { /* Rounds 0 to 15 (unrolled): */ ROUND256_0_TO_15(a,b,c,d,e,f,g,h); ROUND256_0_TO_15(h,a,b,c,d,e,f,g); ROUND256_0_TO_15(g,h,a,b,c,d,e,f); ROUND256_0_TO_15(f,g,h,a,b,c,d,e); ROUND256_0_TO_15(e,f,g,h,a,b,c,d); ROUND256_0_TO_15(d,e,f,g,h,a,b,c); ROUND256_0_TO_15(c,d,e,f,g,h,a,b); ROUND256_0_TO_15(b,c,d,e,f,g,h,a); } while (j < 16); /* Now for the remaining rounds to 64: */ do { ROUND256(a,b,c,d,e,f,g,h); ROUND256(h,a,b,c,d,e,f,g); ROUND256(g,h,a,b,c,d,e,f); ROUND256(f,g,h,a,b,c,d,e); ROUND256(e,f,g,h,a,b,c,d); ROUND256(d,e,f,g,h,a,b,c); ROUND256(c,d,e,f,g,h,a,b); ROUND256(b,c,d,e,f,g,h,a); } while (j < 64); /* Compute the current intermediate hash value */ context->state[0] += a; context->state[1] += b; context->state[2] += c; context->state[3] += d; context->state[4] += e; context->state[5] += f; context->state[6] += g; context->state[7] += h; /* Clean up */ a = b = c = d = e = f = g = h = T1 = 0; } #else /* SHA2_UNROLL_TRANSFORM */ void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) { sha2_word32 a, b, c, d, e, f, g, h, s0, s1; sha2_word32 T1, T2, *W256; int j; W256 = (sha2_word32*)context->buffer; /* Initialize registers with the prev. intermediate value */ a = context->state[0]; b = context->state[1]; c = context->state[2]; d = context->state[3]; e = context->state[4]; f = context->state[5]; g = context->state[6]; h = context->state[7]; j = 0; do { #if BYTE_ORDER == LITTLE_ENDIAN /* Copy data while converting to host byte order */ REVERSE32(*data++,W256[j]); /* Apply the SHA-256 compression function to update a..h */ T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j]; #else /* BYTE_ORDER == LITTLE_ENDIAN */ /* Apply the SHA-256 compression function to update a..h with copy */ T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++); #endif /* BYTE_ORDER == LITTLE_ENDIAN */ T2 = Sigma0_256(a) + Maj(a, b, c); h = g; g = f; f = e; e = d + T1; d = c; c = b; b = a; a = T1 + T2; j++; } while (j < 16); do { /* Part of the message block expansion: */ s0 = W256[(j+1)&0x0f]; s0 = sigma0_256(s0); s1 = W256[(j+14)&0x0f]; s1 = sigma1_256(s1); /* Apply the SHA-256 compression function to update a..h */ T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); T2 = Sigma0_256(a) + Maj(a, b, c); h = g; g = f; f = e; e = d + T1; d = c; c = b; b = a; a = T1 + T2; j++; } while (j < 64); /* Compute the current intermediate hash value */ context->state[0] += a; context->state[1] += b; context->state[2] += c; context->state[3] += d; context->state[4] += e; context->state[5] += f; context->state[6] += g; context->state[7] += h; /* Clean up */ a = b = c = d = e = f = g = h = T1 = T2 = 0; } #endif /* SHA2_UNROLL_TRANSFORM */ void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) { unsigned int freespace, usedspace; if (len == 0) { /* Calling with no data is valid - we do nothing */ return; } /* Sanity check: */ assert(context != (SHA256_CTX*)0 && data != (sha2_byte*)0); usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LEN; if (usedspace > 0) { /* Calculate how much free space is available in the buffer */ freespace = SHA256_BLOCK_LEN - usedspace; if (len >= freespace) { /* Fill the buffer completely and process it */ MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); context->bitcount += freespace << 3; len -= freespace; data += freespace; SHA256_Transform(context, (sha2_word32*)context->buffer); } else { /* The buffer is not yet full */ MEMCPY_BCOPY(&context->buffer[usedspace], data, len); context->bitcount += len << 3; /* Clean up: */ usedspace = freespace = 0; return; } } while (len >= SHA256_BLOCK_LEN) { /* Process as many complete blocks as we can */ SHA256_Transform(context, (sha2_word32*)data); context->bitcount += SHA256_BLOCK_LEN << 3; len -= SHA256_BLOCK_LEN; data += SHA256_BLOCK_LEN; } if (len > 0) { /* There's left-overs, so save 'em */ MEMCPY_BCOPY(context->buffer, data, len); context->bitcount += len << 3; } /* Clean up: */ usedspace = freespace = 0; } void SHA256_Final(sha2_byte digest[], SHA256_CTX* context) { sha2_word32 *d = (sha2_word32*)digest; unsigned int usedspace; /* Sanity check: */ assert(context != (SHA256_CTX*)0); /* If no digest buffer is passed, we don't bother doing this: */ if (digest != (sha2_byte*)0) { usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LEN; #if BYTE_ORDER == LITTLE_ENDIAN /* Convert FROM host byte order */ REVERSE64(context->bitcount,context->bitcount); #endif if (usedspace > 0) { /* Begin padding with a 1 bit: */ context->buffer[usedspace++] = 0x80; if (usedspace <= SHA256_SHORT_BLOCK_LEN) { /* Set-up for the last transform: */ MEMSET_BZERO(&context->buffer[usedspace], SHA256_SHORT_BLOCK_LEN - usedspace); } else { if (usedspace < SHA256_BLOCK_LEN) { MEMSET_BZERO(&context->buffer[usedspace], SHA256_BLOCK_LEN - usedspace); } /* Do second-to-last transform: */ SHA256_Transform(context, (sha2_word32*)context->buffer); /* And set-up for the last transform: */ MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LEN); } } else { /* Set-up for the last transform: */ MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LEN); /* Begin padding with a 1 bit: */ *context->buffer = 0x80; } /* Set the bit count: */ memcpy(&(context->buffer[SHA256_SHORT_BLOCK_LEN]), &(context->bitcount), sizeof(sha2_word64)); /* Final transform: */ SHA256_Transform(context, (sha2_word32*)context->buffer); #if BYTE_ORDER == LITTLE_ENDIAN { /* Convert TO host byte order */ int j; for (j = 0; j < 8; j++) { REVERSE32(context->state[j],context->state[j]); *d++ = context->state[j]; } } #else MEMCPY_BCOPY(d, context->state, SHA256_DIGEST_LEN); #endif } /* Clean up state data: */ MEMSET_BZERO(context, sizeof(*context)); usedspace = 0; } /*** SHA-512: *********************************************************/ void SHA512_Init(SHA512_CTX* context) { if (context == (SHA512_CTX*)0) { return; } MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LEN); MEMSET_BZERO(context->buffer, SHA512_BLOCK_LEN); context->bitcount[0] = context->bitcount[1] = 0; } #ifdef SHA2_UNROLL_TRANSFORM /* Unrolled SHA-512 round macros: */ #if BYTE_ORDER == LITTLE_ENDIAN #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ REVERSE64(*data++, W512[j]); \ T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ K512[j] + W512[j]; \ (d) += T1, \ (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \ j++ #else /* BYTE_ORDER == LITTLE_ENDIAN */ #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ K512[j] + (W512[j] = *data++); \ (d) += T1; \ (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ j++ #endif /* BYTE_ORDER == LITTLE_ENDIAN */ #define ROUND512(a,b,c,d,e,f,g,h) \ s0 = W512[(j+1)&0x0f]; \ s0 = sigma0_512(s0); \ s1 = W512[(j+14)&0x0f]; \ s1 = sigma1_512(s1); \ T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \ (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \ (d) += T1; \ (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ j++ void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { sha2_word64 a, b, c, d, e, f, g, h, s0, s1; sha2_word64 T1, *W512 = (sha2_word64*)context->buffer; int j; /* Initialize registers with the prev. intermediate value */ a = context->state[0]; b = context->state[1]; c = context->state[2]; d = context->state[3]; e = context->state[4]; f = context->state[5]; g = context->state[6]; h = context->state[7]; j = 0; do { ROUND512_0_TO_15(a,b,c,d,e,f,g,h); ROUND512_0_TO_15(h,a,b,c,d,e,f,g); ROUND512_0_TO_15(g,h,a,b,c,d,e,f); ROUND512_0_TO_15(f,g,h,a,b,c,d,e); ROUND512_0_TO_15(e,f,g,h,a,b,c,d); ROUND512_0_TO_15(d,e,f,g,h,a,b,c); ROUND512_0_TO_15(c,d,e,f,g,h,a,b); ROUND512_0_TO_15(b,c,d,e,f,g,h,a); } while (j < 16); /* Now for the remaining rounds up to 79: */ do { ROUND512(a,b,c,d,e,f,g,h); ROUND512(h,a,b,c,d,e,f,g); ROUND512(g,h,a,b,c,d,e,f); ROUND512(f,g,h,a,b,c,d,e); ROUND512(e,f,g,h,a,b,c,d); ROUND512(d,e,f,g,h,a,b,c); ROUND512(c,d,e,f,g,h,a,b); ROUND512(b,c,d,e,f,g,h,a); } while (j < 80); /* Compute the current intermediate hash value */ context->state[0] += a; context->state[1] += b; context->state[2] += c; context->state[3] += d; context->state[4] += e; context->state[5] += f; context->state[6] += g; context->state[7] += h; /* Clean up */ a = b = c = d = e = f = g = h = T1 = 0; } #else /* SHA2_UNROLL_TRANSFORM */ void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { sha2_word64 a, b, c, d, e, f, g, h, s0, s1; sha2_word64 T1, T2, *W512 = (sha2_word64*)context->buffer; int j; /* Initialize registers with the prev. intermediate value */ a = context->state[0]; b = context->state[1]; c = context->state[2]; d = context->state[3]; e = context->state[4]; f = context->state[5]; g = context->state[6]; h = context->state[7]; j = 0; do { #if BYTE_ORDER == LITTLE_ENDIAN /* Convert TO host byte order */ REVERSE64(*data++, W512[j]); /* Apply the SHA-512 compression function to update a..h */ T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j]; #else /* BYTE_ORDER == LITTLE_ENDIAN */ /* Apply the SHA-512 compression function to update a..h with copy */ T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++); #endif /* BYTE_ORDER == LITTLE_ENDIAN */ T2 = Sigma0_512(a) + Maj(a, b, c); h = g; g = f; f = e; e = d + T1; d = c; c = b; b = a; a = T1 + T2; j++; } while (j < 16); do { /* Part of the message block expansion: */ s0 = W512[(j+1)&0x0f]; s0 = sigma0_512(s0); s1 = W512[(j+14)&0x0f]; s1 = sigma1_512(s1); /* Apply the SHA-512 compression function to update a..h */ T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); T2 = Sigma0_512(a) + Maj(a, b, c); h = g; g = f; f = e; e = d + T1; d = c; c = b; b = a; a = T1 + T2; j++; } while (j < 80); /* Compute the current intermediate hash value */ context->state[0] += a; context->state[1] += b; context->state[2] += c; context->state[3] += d; context->state[4] += e; context->state[5] += f; context->state[6] += g; context->state[7] += h; /* Clean up */ a = b = c = d = e = f = g = h = T1 = T2 = 0; } #endif /* SHA2_UNROLL_TRANSFORM */ void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) { unsigned int freespace, usedspace; if (len == 0) { /* Calling with no data is valid - we do nothing */ return; } /* Sanity check: */ assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0); usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LEN; if (usedspace > 0) { /* Calculate how much free space is available in the buffer */ freespace = SHA512_BLOCK_LEN - usedspace; if (len >= freespace) { /* Fill the buffer completely and process it */ MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); ADDINC128(context->bitcount, freespace << 3); len -= freespace; data += freespace; SHA512_Transform(context, (sha2_word64*)context->buffer); } else { /* The buffer is not yet full */ MEMCPY_BCOPY(&context->buffer[usedspace], data, len); ADDINC128(context->bitcount, len << 3); /* Clean up: */ usedspace = freespace = 0; return; } } while (len >= SHA512_BLOCK_LEN) { /* Process as many complete blocks as we can */ SHA512_Transform(context, (sha2_word64*)data); ADDINC128(context->bitcount, SHA512_BLOCK_LEN << 3); len -= SHA512_BLOCK_LEN; data += SHA512_BLOCK_LEN; } if (len > 0) { /* There's left-overs, so save 'em */ MEMCPY_BCOPY(context->buffer, data, len); ADDINC128(context->bitcount, len << 3); } /* Clean up: */ usedspace = freespace = 0; } void SHA512_Last(SHA512_CTX* context) { unsigned int usedspace; usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LEN; #if BYTE_ORDER == LITTLE_ENDIAN /* Convert FROM host byte order */ REVERSE64(context->bitcount[0],context->bitcount[0]); REVERSE64(context->bitcount[1],context->bitcount[1]); #endif if (usedspace > 0) { /* Begin padding with a 1 bit: */ context->buffer[usedspace++] = 0x80; if (usedspace <= SHA512_SHORT_BLOCK_LEN) { /* Set-up for the last transform: */ MEMSET_BZERO(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LEN - usedspace); } else { if (usedspace < SHA512_BLOCK_LEN) { MEMSET_BZERO(&context->buffer[usedspace], SHA512_BLOCK_LEN - usedspace); } /* Do second-to-last transform: */ SHA512_Transform(context, (sha2_word64*)context->buffer); /* And set-up for the last transform: */ MEMSET_BZERO(context->buffer, SHA512_BLOCK_LEN - 2); } } else { /* Prepare for final transform: */ MEMSET_BZERO(context->buffer, SHA512_SHORT_BLOCK_LEN); /* Begin padding with a 1 bit: */ *context->buffer = 0x80; } /* Store the length of input data (in bits): */ memcpy(&(context->buffer[SHA512_SHORT_BLOCK_LEN]), &(context->bitcount[1]), sizeof(sha2_word64)); memcpy(&(context->buffer[SHA512_SHORT_BLOCK_LEN+8]), &(context->bitcount[0]), sizeof(sha2_word64)); /* Final transform: */ SHA512_Transform(context, (sha2_word64*)context->buffer); } void SHA512_Final(sha2_byte digest[], SHA512_CTX* context) { sha2_word64 *d = (sha2_word64*)digest; /* Sanity check: */ assert(context != (SHA512_CTX*)0); /* If no digest buffer is passed, we don't bother doing this: */ if (digest != (sha2_byte*)0) { SHA512_Last(context); /* Save the hash data for output: */ #if BYTE_ORDER == LITTLE_ENDIAN { /* Convert TO host byte order */ int j; for (j = 0; j < 8; j++) { REVERSE64(context->state[j],context->state[j]); *d++ = context->state[j]; } } #else MEMCPY_BCOPY(d, context->state, SHA512_DIGEST_LEN); #endif } /* Zero out state data */ MEMSET_BZERO(context, sizeof(*context)); } /*** SHA-384: *********************************************************/ void SHA384_Init(SHA384_CTX* context) { if (context == (SHA384_CTX*)0) { return; } MEMCPY_BCOPY(context->state, sha384_initial_hash_value, SHA512_DIGEST_LEN); MEMSET_BZERO(context->buffer, SHA384_BLOCK_LEN); context->bitcount[0] = context->bitcount[1] = 0; } void SHA384_Update(SHA384_CTX* context, const sha2_byte* data, size_t len) { SHA512_Update((SHA512_CTX*)context, data, len); } void SHA384_Final(sha2_byte digest[], SHA384_CTX* context) { sha2_word64 *d = (sha2_word64*)digest; /* Sanity check: */ assert(context != (SHA384_CTX*)0); /* If no digest buffer is passed, we don't bother doing this: */ if (digest != (sha2_byte*)0) { SHA512_Last((SHA512_CTX*)context); /* Save the hash data for output: */ #if BYTE_ORDER == LITTLE_ENDIAN { /* Convert TO host byte order */ int j; for (j = 0; j < 6; j++) { REVERSE64(context->state[j],context->state[j]); *d++ = context->state[j]; } } #else MEMCPY_BCOPY(d, context->state, SHA384_DIGEST_LEN); #endif } /* Zero out state data */ MEMSET_BZERO(context, sizeof(*context)); } fwknop-2.6.11/lib/base64.h0000664000175000017500000000253114560546213012042 00000000000000/** * \file lib/base64.h * * \brief Header for the fwknop base64.c */ /* Fwknop is developed primarily by the people listed in the file 'AUTHORS'. * Copyright (C) 2009-2015 fwknop developers and contributors. For a full * list of contributors, see the file 'CREDITS'. * * License (GNU General Public License): * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #ifndef BASE64_H #define BASE64_H 1 /* Prototypes */ int b64_encode(unsigned char *in, char *out, int in_len); int b64_decode(const char *in, unsigned char *out); void strip_b64_eq(char *data); #endif /* BASE64_H */ /***EOF***/ fwknop-2.6.11/lib/fko_server_auth.c0000664000175000017500000000615614560546213014146 00000000000000/** * \file lib/fko_server_auth.c * * \brief Set/Get the spa server auth data. */ /* Fwknop is developed primarily by the people listed in the file 'AUTHORS'. * Copyright (C) 2009-2015 fwknop developers and contributors. For a full * list of contributors, see the file 'CREDITS'. * * License (GNU General Public License): * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #include "fko_common.h" #include "fko.h" /* Set the SPA Server Auth data */ int fko_set_spa_server_auth(fko_ctx_t ctx, const char * const msg) { /**************************************** * --DSS This is not supported yet **************************************** */ //return(FKO_ERROR_UNSUPPORTED_FEATURE); #if HAVE_LIBFIU fiu_return_on("fko_set_spa_server_auth_init", FKO_ERROR_CTX_NOT_INITIALIZED); #endif /* Context must be initialized. */ if(!CTX_INITIALIZED(ctx)) return FKO_ERROR_CTX_NOT_INITIALIZED; /* Gotta have a valid string. */ if(msg == NULL || strnlen(msg, MAX_SPA_SERVER_AUTH_SIZE) == 0) return(FKO_ERROR_INVALID_DATA_SRVAUTH_MISSING); /* --DSS XXX: Bail out for now. But consider just * truncating in the future... */ if(strnlen(msg, MAX_SPA_SERVER_AUTH_SIZE) == MAX_SPA_SERVER_AUTH_SIZE) return(FKO_ERROR_DATA_TOO_LARGE); /* --DSS TODO: ??? * Do we want to add message type and format checking here * or continue to leave it to the implementor? */ /**/ /* Just in case this is a subsequent call to this function. We * do not want to be leaking memory. */ if(ctx->server_auth != NULL) free(ctx->server_auth); ctx->server_auth = strdup(msg); ctx->state |= FKO_DATA_MODIFIED; if(ctx->server_auth == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); return(FKO_SUCCESS); } /* Return the SPA message data. */ int fko_get_spa_server_auth(fko_ctx_t ctx, char **server_auth) { #if HAVE_LIBFIU fiu_return_on("fko_get_spa_server_auth_init", FKO_ERROR_CTX_NOT_INITIALIZED); #endif /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); if(server_auth == NULL) return(FKO_ERROR_INVALID_DATA); #if HAVE_LIBFIU fiu_return_on("fko_get_spa_server_auth_val", FKO_ERROR_INVALID_DATA); #endif *server_auth = ctx->server_auth; return(FKO_SUCCESS); } /***EOF***/ fwknop-2.6.11/lib/fko_funcs.c0000664000175000017500000003715714560546213012742 00000000000000/** * \file lib/fko_funcs.c * * \brief General utility functions for libfko */ /* Fwknop is developed primarily by the people listed in the file 'AUTHORS'. * Copyright (C) 2009-2015 fwknop developers and contributors. For a full * list of contributors, see the file 'CREDITS'. * * License (GNU General Public License): * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #include "fko_common.h" #include "fko.h" #include "cipher_funcs.h" #include "base64.h" #include "digest.h" /* Initialize an fko context. */ int fko_new(fko_ctx_t *r_ctx) { fko_ctx_t ctx = NULL; int res; char *ver; #if HAVE_LIBFIU fiu_return_on("fko_new_calloc", FKO_ERROR_MEMORY_ALLOCATION); #endif ctx = calloc(1, sizeof *ctx); if(ctx == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); /* Set default values and state. * * Note: We initialize the context early so that the fko_set_xxx * functions can operate properly. If there are any problems during * initialization, then fko_destroy() is called which will clean up * the context. */ ctx->initval = FKO_CTX_INITIALIZED; /* Set the version string. */ ver = strdup(FKO_PROTOCOL_VERSION); if(ver == NULL) { fko_destroy(ctx); ctx = NULL; return(FKO_ERROR_MEMORY_ALLOCATION); } ctx->version = ver; /* Rand value. */ res = fko_set_rand_value(ctx, NULL); if(res != FKO_SUCCESS) { fko_destroy(ctx); ctx = NULL; return res; } /* Username. */ res = fko_set_username(ctx, NULL); if(res != FKO_SUCCESS) { fko_destroy(ctx); ctx = NULL; return res; } /* Timestamp. */ res = fko_set_timestamp(ctx, 0); if(res != FKO_SUCCESS) { fko_destroy(ctx); ctx = NULL; return res; } /* Default Digest Type. */ res = fko_set_spa_digest_type(ctx, FKO_DEFAULT_DIGEST); if(res != FKO_SUCCESS) { fko_destroy(ctx); ctx = NULL; return res; } /* Default Message Type. */ res = fko_set_spa_message_type(ctx, FKO_DEFAULT_MSG_TYPE); if(res != FKO_SUCCESS) { fko_destroy(ctx); ctx = NULL; return res; } /* Default Encryption Type. */ res = fko_set_spa_encryption_type(ctx, FKO_DEFAULT_ENCRYPTION); if(res != FKO_SUCCESS) { fko_destroy(ctx); ctx = NULL; return res; } /* Default is Rijndael in CBC mode */ res = fko_set_spa_encryption_mode(ctx, FKO_DEFAULT_ENC_MODE); if(res != FKO_SUCCESS) { fko_destroy(ctx); ctx = NULL; return res; } #if HAVE_LIBGPGME /* Set gpg signature verify on. */ ctx->verify_gpg_sigs = 1; #endif /* HAVE_LIBGPGME */ FKO_SET_CTX_INITIALIZED(ctx); *r_ctx = ctx; return(FKO_SUCCESS); } /* Initialize an fko context with external (encrypted/encoded) data. * This is used to create a context with the purpose of decoding * and parsing the provided data into the context data. */ int fko_new_with_data(fko_ctx_t *r_ctx, const char * const enc_msg, const char * const dec_key, const int dec_key_len, int encryption_mode, const char * const hmac_key, const int hmac_key_len, const int hmac_type) { fko_ctx_t ctx = NULL; int res = FKO_SUCCESS; /* Are we optimistic or what? */ int enc_msg_len; #if HAVE_LIBFIU fiu_return_on("fko_new_with_data_msg", FKO_ERROR_INVALID_DATA_FUNCS_NEW_ENCMSG_MISSING); #endif if(enc_msg == NULL) return(FKO_ERROR_INVALID_DATA_FUNCS_NEW_ENCMSG_MISSING); #if HAVE_LIBFIU fiu_return_on("fko_new_with_data_keylen", FKO_ERROR_INVALID_KEY_LEN); #endif if(dec_key_len < 0 || hmac_key_len < 0) return(FKO_ERROR_INVALID_KEY_LEN); ctx = calloc(1, sizeof *ctx); if(ctx == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); enc_msg_len = strnlen(enc_msg, MAX_SPA_ENCODED_MSG_SIZE); if(! is_valid_encoded_msg_len(enc_msg_len)) { free(ctx); return(FKO_ERROR_INVALID_DATA_FUNCS_NEW_MSGLEN_VALIDFAIL); } /* First, add the data to the context. */ ctx->encrypted_msg = strdup(enc_msg); ctx->encrypted_msg_len = enc_msg_len; if(ctx->encrypted_msg == NULL) { free(ctx); return(FKO_ERROR_MEMORY_ALLOCATION); } /* Default Encryption Mode (Rijndael in CBC mode) */ ctx->initval = FKO_CTX_INITIALIZED; res = fko_set_spa_encryption_mode(ctx, encryption_mode); if(res != FKO_SUCCESS) { fko_destroy(ctx); ctx = NULL; return res; } /* HMAC digest type */ res = fko_set_spa_hmac_type(ctx, hmac_type); if(res != FKO_SUCCESS) { fko_destroy(ctx); ctx = NULL; return res; } /* Check HMAC if the access stanza had an HMAC key */ if(hmac_key_len > 0 && hmac_key != NULL) res = fko_verify_hmac(ctx, hmac_key, hmac_key_len); if(res != FKO_SUCCESS) { fko_destroy(ctx); ctx = NULL; return res; } /* Consider it initialized here. */ FKO_SET_CTX_INITIALIZED(ctx); /* If a decryption key is provided, go ahead and decrypt and decode. */ if(dec_key != NULL) { res = fko_decrypt_spa_data(ctx, dec_key, dec_key_len); if(res != FKO_SUCCESS) { fko_destroy(ctx); ctx = NULL; *r_ctx = NULL; /* Make sure the caller ctx is null just in case */ return(res); } } #if HAVE_LIBGPGME /* Set gpg signature verify on. */ ctx->verify_gpg_sigs = 1; #endif /* HAVE_LIBGPGME */ *r_ctx = ctx; return(res); } /* Destroy a context and free its resources */ int fko_destroy(fko_ctx_t ctx) { int zero_free_rv = FKO_SUCCESS; #if HAVE_LIBGPGME fko_gpg_sig_t gsig, tgsig; #endif if(!CTX_INITIALIZED(ctx)) return(zero_free_rv); if(ctx->rand_val != NULL) free(ctx->rand_val); if(ctx->username != NULL) free(ctx->username); if(ctx->version != NULL) free(ctx->version); if(ctx->message != NULL) free(ctx->message); if(ctx->nat_access != NULL) free(ctx->nat_access); if(ctx->server_auth != NULL) free(ctx->server_auth); if(ctx->digest != NULL) if(zero_free(ctx->digest, ctx->digest_len) != FKO_SUCCESS) zero_free_rv = FKO_ERROR_ZERO_OUT_DATA; if(ctx->raw_digest != NULL) if(zero_free(ctx->raw_digest, ctx->raw_digest_len) != FKO_SUCCESS) zero_free_rv = FKO_ERROR_ZERO_OUT_DATA; if(ctx->encoded_msg != NULL) if(zero_free(ctx->encoded_msg, ctx->encoded_msg_len) != FKO_SUCCESS) zero_free_rv = FKO_ERROR_ZERO_OUT_DATA; if(ctx->encrypted_msg != NULL) if(zero_free(ctx->encrypted_msg, ctx->encrypted_msg_len) != FKO_SUCCESS) zero_free_rv = FKO_ERROR_ZERO_OUT_DATA; if(ctx->msg_hmac != NULL) if(zero_free(ctx->msg_hmac, ctx->msg_hmac_len) != FKO_SUCCESS) zero_free_rv = FKO_ERROR_ZERO_OUT_DATA; #if HAVE_LIBGPGME if(ctx->gpg_exe != NULL) free(ctx->gpg_exe); if(ctx->gpg_home_dir != NULL) free(ctx->gpg_home_dir); if(ctx->gpg_recipient != NULL) free(ctx->gpg_recipient); if(ctx->gpg_signer != NULL) free(ctx->gpg_signer); if(ctx->recipient_key != NULL) gpgme_key_unref(ctx->recipient_key); if(ctx->signer_key != NULL) gpgme_key_unref(ctx->signer_key); if(ctx->gpg_ctx != NULL) gpgme_release(ctx->gpg_ctx); gsig = ctx->gpg_sigs; while(gsig != NULL) { if(gsig->fpr != NULL) free(gsig->fpr); tgsig = gsig; gsig = gsig->next; free(tgsig); } #endif /* HAVE_LIBGPGME */ memset(ctx, 0x0, sizeof(*ctx)); free(ctx); return(zero_free_rv); } /* Generate Rijndael and HMAC keys from /dev/random and base64 * encode them */ int fko_key_gen(char * const key_base64, const int key_len, char * const hmac_key_base64, const int hmac_key_len, const int hmac_type) { unsigned char key[RIJNDAEL_MAX_KEYSIZE]; unsigned char hmac_key[SHA512_BLOCK_LEN]; int klen = key_len; int hmac_klen = hmac_key_len; int b64_len = 0; if(key_len == FKO_DEFAULT_KEY_LEN) klen = RIJNDAEL_MAX_KEYSIZE; if(hmac_key_len == FKO_DEFAULT_KEY_LEN) { if(hmac_type == FKO_DEFAULT_HMAC_MODE || hmac_type == FKO_HMAC_SHA256) hmac_klen = SHA256_BLOCK_LEN; else if(hmac_type == FKO_HMAC_MD5) hmac_klen = MD5_DIGEST_LEN; else if(hmac_type == FKO_HMAC_SHA1) hmac_klen = SHA1_DIGEST_LEN; else if(hmac_type == FKO_HMAC_SHA384) hmac_klen = SHA384_BLOCK_LEN; else if(hmac_type == FKO_HMAC_SHA512) hmac_klen = SHA512_BLOCK_LEN; } if((klen < 1) || (klen > RIJNDAEL_MAX_KEYSIZE)) return(FKO_ERROR_INVALID_DATA_FUNCS_GEN_KEYLEN_VALIDFAIL); if((hmac_klen < 1) || (hmac_klen > SHA512_BLOCK_LEN)) return(FKO_ERROR_INVALID_DATA_FUNCS_GEN_HMACLEN_VALIDFAIL); get_random_data(key, klen); get_random_data(hmac_key, hmac_klen); b64_len = b64_encode(key, key_base64, klen); if(b64_len < klen) return(FKO_ERROR_INVALID_DATA_FUNCS_GEN_KEY_ENCODEFAIL); b64_len = b64_encode(hmac_key, hmac_key_base64, hmac_klen); if(b64_len < hmac_klen) return(FKO_ERROR_INVALID_DATA_FUNCS_GEN_HMAC_ENCODEFAIL); return(FKO_SUCCESS); } /* Provide an FKO wrapper around base64 encode/decode functions */ int fko_base64_encode(unsigned char * const in, char * const out, int in_len) { return b64_encode(in, out, in_len); } int fko_base64_decode(const char * const in, unsigned char *out) { return b64_decode(in, out); } /* Return the fko version */ int fko_get_version(fko_ctx_t ctx, char **version) { #if HAVE_LIBFIU fiu_return_on("fko_get_version_init", FKO_ERROR_CTX_NOT_INITIALIZED); #endif /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); if(version == NULL) return(FKO_ERROR_INVALID_DATA); #if HAVE_LIBFIU fiu_return_on("fko_get_version_val", FKO_ERROR_INVALID_DATA); #endif *version = ctx->version; return(FKO_SUCCESS); } /* Final update and encoding of data in the context. * This does require all requisite fields be properly * set. */ int fko_spa_data_final(fko_ctx_t ctx, const char * const enc_key, const int enc_key_len, const char * const hmac_key, const int hmac_key_len) { char *tbuf; int res = 0, data_with_hmac_len = 0; /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); if(enc_key_len < 0) return(FKO_ERROR_INVALID_KEY_LEN); res = fko_encrypt_spa_data(ctx, enc_key, enc_key_len); /* Now calculate hmac if so configured */ if (res == FKO_SUCCESS && ctx->hmac_type != FKO_HMAC_UNKNOWN) { if(hmac_key_len < 0) return(FKO_ERROR_INVALID_KEY_LEN); if(hmac_key == NULL) return(FKO_ERROR_INVALID_KEY_LEN); res = fko_set_spa_hmac(ctx, hmac_key, hmac_key_len); if (res == FKO_SUCCESS) { /* Now that we have the hmac, append it to the * encrypted data (which has already been base64-encoded * and the trailing '=' chars stripped off). */ data_with_hmac_len = ctx->encrypted_msg_len+1+ctx->msg_hmac_len+1; tbuf = realloc(ctx->encrypted_msg, data_with_hmac_len); if (tbuf == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); strlcat(tbuf, ctx->msg_hmac, data_with_hmac_len); ctx->encrypted_msg = tbuf; ctx->encrypted_msg_len = data_with_hmac_len; } } return res; } /* Return the fko SPA encrypted data. */ int fko_get_spa_data(fko_ctx_t ctx, char **spa_data) { #if HAVE_LIBFIU fiu_return_on("fko_get_spa_data_init", FKO_ERROR_CTX_NOT_INITIALIZED); #endif /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); if(spa_data == NULL) return(FKO_ERROR_INVALID_DATA); #if HAVE_LIBFIU fiu_return_on("fko_get_spa_data_val", FKO_ERROR_INVALID_DATA); #endif /* We expect to have encrypted data to process. If not, we bail. */ if(ctx->encrypted_msg == NULL || ! is_valid_encoded_msg_len( strnlen(ctx->encrypted_msg, MAX_SPA_ENCODED_MSG_SIZE))) return(FKO_ERROR_MISSING_ENCODED_DATA); #if HAVE_LIBFIU fiu_return_on("fko_get_spa_data_encoded", FKO_ERROR_MISSING_ENCODED_DATA); #endif *spa_data = ctx->encrypted_msg; /* Notice we omit the first 10 bytes if Rijndael encryption is * used (to eliminate the consistent 'Salted__' string), and * in GnuPG mode we eliminate the consistent 'hQ' base64 encoded * prefix */ if(ctx->encryption_type == FKO_ENCRYPTION_RIJNDAEL) *spa_data += B64_RIJNDAEL_SALT_STR_LEN; else if(ctx->encryption_type == FKO_ENCRYPTION_GPG) *spa_data += B64_GPG_PREFIX_STR_LEN; return(FKO_SUCCESS); } /* Set the fko SPA encrypted data. */ int fko_set_spa_data(fko_ctx_t ctx, const char * const enc_msg) { int enc_msg_len; /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return FKO_ERROR_CTX_NOT_INITIALIZED; if(enc_msg == NULL) return(FKO_ERROR_INVALID_DATA_FUNCS_SET_MSGLEN_VALIDFAIL); enc_msg_len = strnlen(enc_msg, MAX_SPA_ENCODED_MSG_SIZE); if(! is_valid_encoded_msg_len(enc_msg_len)) return(FKO_ERROR_INVALID_DATA_FUNCS_SET_MSGLEN_VALIDFAIL); if(ctx->encrypted_msg != NULL) free(ctx->encrypted_msg); /* First, add the data to the context. */ ctx->encrypted_msg = strdup(enc_msg); ctx->encrypted_msg_len = enc_msg_len; if(ctx->encrypted_msg == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); return(FKO_SUCCESS); } #if AFL_FUZZING /* provide a way to set the encrypted data directly without base64 encoding. * This allows direct AFL fuzzing against decryption routines. */ int fko_afl_set_spa_data(fko_ctx_t ctx, const char * const enc_msg, const int enc_msg_len) { /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return FKO_ERROR_CTX_NOT_INITIALIZED; if(enc_msg == NULL) return(FKO_ERROR_INVALID_DATA_FUNCS_SET_MSGLEN_VALIDFAIL); if(! is_valid_encoded_msg_len(enc_msg_len)) return(FKO_ERROR_INVALID_DATA_FUNCS_SET_MSGLEN_VALIDFAIL); if(ctx->encrypted_msg != NULL) free(ctx->encrypted_msg); /* Copy the raw encrypted data into the context */ ctx->encrypted_msg = calloc(1, enc_msg_len); if(ctx->encrypted_msg == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); memcpy(ctx->encrypted_msg, enc_msg, enc_msg_len); ctx->encrypted_msg_len = enc_msg_len; return(FKO_SUCCESS); } #endif /***EOF***/ fwknop-2.6.11/lib/fko_encryption.c0000664000175000017500000007545414560546213014020 00000000000000/** * \file lib/fko_encryption.c * * \brief Set/Get the spa encryption type. */ /* Fwknop is developed primarily by the people listed in the file 'AUTHORS'. * Copyright (C) 2009-2015 fwknop developers and contributors. For a full * list of contributors, see the file 'CREDITS'. * * License (GNU General Public License): * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #include "fko_common.h" #include "fko.h" #include "cipher_funcs.h" #include "base64.h" #include "digest.h" #if HAVE_LIBGPGME #include "gpgme_funcs.h" #if HAVE_SYS_STAT_H #include /* Taken from cURL for win32 build */ #if !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG) #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) #endif #if !defined(S_ISDIR) && defined(S_IFMT) && defined(S_IFDIR) #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) #endif #if !defined(S_IFLNK) #define S_IFLNK 0xA000 #endif #if !defined(S_ISLNK) && defined(S_IFMT) #define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) #endif #endif #endif /* Prep and encrypt using Rijndael */ static int _rijndael_encrypt(fko_ctx_t ctx, const char *enc_key, const int enc_key_len) { char *plaintext; char *b64ciphertext; unsigned char *ciphertext; int cipher_len; int pt_len; int zero_free_rv = FKO_SUCCESS; if(enc_key_len < 0 || enc_key_len > RIJNDAEL_MAX_KEYSIZE) return(FKO_ERROR_INVALID_KEY_LEN); if (! is_valid_encoded_msg_len(ctx->encoded_msg_len)) return(FKO_ERROR_INVALID_DATA_ENCRYPT_MSGLEN_VALIDFAIL); switch(ctx->digest_len) { case MD5_B64_LEN: break; case SHA1_B64_LEN: break; case SHA256_B64_LEN: break; case SHA384_B64_LEN: break; case SHA512_B64_LEN: break; default: return(FKO_ERROR_INVALID_DATA_ENCRYPT_DIGESTLEN_VALIDFAIL); } pt_len = ctx->encoded_msg_len + ctx->digest_len + RIJNDAEL_BLOCKSIZE + 2; /* Make a bucket big enough to hold the enc msg + digest (plaintext) * and populate it appropriately. */ plaintext = calloc(1, pt_len); if(plaintext == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); pt_len = snprintf(plaintext, pt_len, "%s:%s", ctx->encoded_msg, ctx->digest); if(! is_valid_pt_msg_len(pt_len)) { if(zero_free(plaintext, pt_len) == FKO_SUCCESS) return(FKO_ERROR_INVALID_DATA_ENCRYPT_PTLEN_VALIDFAIL); else return(FKO_ERROR_ZERO_OUT_DATA); } /* Make a bucket for the encrypted version and populate it. */ ciphertext = calloc(1, pt_len + 32); /* Plus padding for salt and Block */ if(ciphertext == NULL) { if(zero_free(plaintext, pt_len) == FKO_SUCCESS) return(FKO_ERROR_MEMORY_ALLOCATION); else return(FKO_ERROR_ZERO_OUT_DATA); } cipher_len = rij_encrypt( (unsigned char*)plaintext, pt_len, (char*)enc_key, enc_key_len, ciphertext, ctx->encryption_mode ); /* Now make a bucket for the base64-encoded version and populate it. */ b64ciphertext = calloc(1, ((cipher_len / 3) * 4) + 8); if(b64ciphertext == NULL) { if(zero_free((char *) ciphertext, pt_len+32) == FKO_SUCCESS && zero_free(plaintext, pt_len) == FKO_SUCCESS) return(FKO_ERROR_MEMORY_ALLOCATION); else return(FKO_ERROR_ZERO_OUT_DATA); } b64_encode(ciphertext, b64ciphertext, cipher_len); strip_b64_eq(b64ciphertext); if(ctx->encrypted_msg != NULL) zero_free_rv = zero_free(ctx->encrypted_msg, strnlen(ctx->encrypted_msg, MAX_SPA_ENCODED_MSG_SIZE)); ctx->encrypted_msg = strdup(b64ciphertext); /* Clean-up */ if(zero_free(plaintext, pt_len) != FKO_SUCCESS) zero_free_rv = FKO_ERROR_ZERO_OUT_DATA; if(zero_free((char *) ciphertext, pt_len+32) != FKO_SUCCESS) zero_free_rv = FKO_ERROR_ZERO_OUT_DATA; if(zero_free(b64ciphertext, strnlen(b64ciphertext, MAX_SPA_ENCODED_MSG_SIZE)) != FKO_SUCCESS) zero_free_rv = FKO_ERROR_ZERO_OUT_DATA; if(ctx->encrypted_msg == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); ctx->encrypted_msg_len = strnlen(ctx->encrypted_msg, MAX_SPA_ENCODED_MSG_SIZE); if(! is_valid_encoded_msg_len(ctx->encrypted_msg_len)) return(FKO_ERROR_INVALID_DATA_ENCRYPT_RESULT_MSGLEN_VALIDFAIL); return(zero_free_rv); } /* Decode, decrypt, and parse SPA data into the context. */ static int _rijndael_decrypt(fko_ctx_t ctx, const char *dec_key, const int key_len, int encryption_mode) { unsigned char *ndx; unsigned char *cipher; int cipher_len=0, pt_len, i, err = 0, res = FKO_SUCCESS; int zero_free_rv = FKO_SUCCESS; if(key_len < 0 || key_len > RIJNDAEL_MAX_KEYSIZE) return(FKO_ERROR_INVALID_KEY_LEN); /* Now see if we need to add the "Salted__" string to the front of the * encrypted data. */ if(! ctx->added_salted_str) { res = add_salted_str(ctx); if(res != FKO_SUCCESS) return res; } /* Create a bucket for the (base64) decoded encrypted data and get the * raw cipher data. */ cipher = calloc(1, ctx->encrypted_msg_len); if(cipher == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); #if AFL_FUZZING cipher_len = ctx->encrypted_msg_len; memcpy(cipher, ctx->encrypted_msg, ctx->encrypted_msg_len); #else if((cipher_len = b64_decode(ctx->encrypted_msg, cipher)) < 0) { if(zero_free((char *)cipher, ctx->encrypted_msg_len) == FKO_SUCCESS) return(FKO_ERROR_INVALID_DATA_ENCRYPT_CIPHERLEN_DECODEFAIL); else return(FKO_ERROR_ZERO_OUT_DATA); } #endif /* Since we're using AES, make sure the incoming data is a multiple of * the blocksize */ if((cipher_len % RIJNDAEL_BLOCKSIZE) != 0) { if(zero_free((char *)cipher, ctx->encrypted_msg_len) == FKO_SUCCESS) return(FKO_ERROR_INVALID_DATA_ENCRYPT_CIPHERLEN_VALIDFAIL); else return(FKO_ERROR_ZERO_OUT_DATA); } if(ctx->encoded_msg != NULL) zero_free_rv = zero_free(ctx->encoded_msg, strnlen(ctx->encoded_msg, MAX_SPA_ENCODED_MSG_SIZE)); /* Create a bucket for the plaintext data and decrypt the message * data into it. */ ctx->encoded_msg = calloc(1, cipher_len); if(ctx->encoded_msg == NULL) { if(zero_free((char *)cipher, ctx->encrypted_msg_len) == FKO_SUCCESS) return(FKO_ERROR_MEMORY_ALLOCATION); else return(FKO_ERROR_ZERO_OUT_DATA); } pt_len = rij_decrypt(cipher, cipher_len, dec_key, key_len, (unsigned char*)ctx->encoded_msg, encryption_mode); /* Done with cipher... */ if(zero_free((char *)cipher, ctx->encrypted_msg_len) != FKO_SUCCESS) zero_free_rv = FKO_ERROR_ZERO_OUT_DATA; /* The length of the decrypted data should be within 32 bytes of the * length of the encrypted version. */ if(pt_len < (cipher_len - 32) || pt_len <= 0) return(FKO_ERROR_DECRYPTION_SIZE); if(ctx->encoded_msg == NULL) return(FKO_ERROR_MISSING_ENCODED_DATA); if(! is_valid_encoded_msg_len(pt_len)) return(FKO_ERROR_INVALID_DATA_DECODE_MSGLEN_VALIDFAIL); if(zero_free_rv != FKO_SUCCESS) return(zero_free_rv); ctx->encoded_msg_len = pt_len; /* At this point we can check the data to see if we have a good * decryption by ensuring the first field (16-digit random decimal * value) is valid and is followed by a colon. Additional checks * are made in fko_decode_spa_data(). */ ndx = (unsigned char *)ctx->encoded_msg; for(i=0; i 0 || *ndx != ':') return(FKO_ERROR_DECRYPTION_FAILURE); /* Call fko_decode and return the results. */ return(fko_decode_spa_data(ctx)); } #if HAVE_LIBGPGME /* Prep and encrypt using gpgme */ static int gpg_encrypt(fko_ctx_t ctx, const char *enc_key) { int res; char *plain; int pt_len, zero_free_rv = FKO_SUCCESS; char *b64cipher; unsigned char *cipher = NULL; size_t cipher_len; char *empty_key = ""; if (! is_valid_encoded_msg_len(ctx->encoded_msg_len)) return(FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_MESSAGE_VALIDFAIL); switch(ctx->digest_len) { case MD5_B64_LEN: break; case SHA1_B64_LEN: break; case SHA256_B64_LEN: break; case SHA384_B64_LEN: break; case SHA512_B64_LEN: break; default: return(FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_DIGEST_VALIDFAIL); } /* First make sure we have a recipient key set. */ if(ctx->gpg_recipient == NULL) return(FKO_ERROR_MISSING_GPG_KEY_DATA); pt_len = ctx->encoded_msg_len + ctx->digest_len + 2; /* Make a bucket big enough to hold the enc msg + digest (plaintext) * and populate it appropriately. */ plain = calloc(1, pt_len); if(plain == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); pt_len = snprintf(plain, pt_len, "%s:%s", ctx->encoded_msg, ctx->digest); if(! is_valid_pt_msg_len(pt_len)) { if(zero_free(plain, pt_len) == FKO_SUCCESS) return(FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_MSGLEN_VALIDFAIL); else return(FKO_ERROR_ZERO_OUT_DATA); } if (enc_key != NULL) { res = gpgme_encrypt(ctx, (unsigned char*)plain, pt_len, enc_key, &cipher, &cipher_len ); } else { res = gpgme_encrypt(ctx, (unsigned char*)plain, pt_len, empty_key, &cipher, &cipher_len ); } /* --DSS XXX: Better parsing of what went wrong would be nice :) */ if(res != FKO_SUCCESS) { zero_free_rv = zero_free(plain, pt_len); if(cipher != NULL) if(zero_free((char *) cipher, cipher_len) != FKO_SUCCESS) zero_free_rv = FKO_ERROR_ZERO_OUT_DATA; if(zero_free_rv == FKO_SUCCESS) return(res); else return(zero_free_rv); } /* Now make a bucket for the base64-encoded version and populate it. */ b64cipher = calloc(1, ((cipher_len / 3) * 4) + 8); if(b64cipher == NULL) { if(zero_free(plain, pt_len) != FKO_SUCCESS) zero_free_rv = FKO_ERROR_ZERO_OUT_DATA; if(cipher != NULL) if(zero_free((char *) cipher, cipher_len) != FKO_SUCCESS) zero_free_rv = FKO_ERROR_ZERO_OUT_DATA; if(zero_free_rv == FKO_SUCCESS) return(FKO_ERROR_MEMORY_ALLOCATION); else return(zero_free_rv); } b64_encode(cipher, b64cipher, cipher_len); strip_b64_eq(b64cipher); if(ctx->encrypted_msg != NULL) zero_free_rv = zero_free(ctx->encrypted_msg, strnlen(ctx->encrypted_msg, MAX_SPA_ENCODED_MSG_SIZE)); ctx->encrypted_msg = strdup(b64cipher); /* Clean-up */ if(zero_free(plain, pt_len) != FKO_SUCCESS) zero_free_rv = FKO_ERROR_ZERO_OUT_DATA; if(zero_free((char *) cipher, cipher_len) != FKO_SUCCESS) zero_free_rv = FKO_ERROR_ZERO_OUT_DATA; if(zero_free(b64cipher, strnlen(b64cipher, MAX_SPA_ENCODED_MSG_SIZE)) != FKO_SUCCESS) zero_free_rv = FKO_ERROR_ZERO_OUT_DATA; if(ctx->encrypted_msg == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); ctx->encrypted_msg_len = strnlen(ctx->encrypted_msg, MAX_SPA_ENCODED_MSG_SIZE); if(! is_valid_encoded_msg_len(ctx->encrypted_msg_len)) return(FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_RESULT_MSGLEN_VALIDFAIL); return(zero_free_rv); } /* Prep and decrypt using gpgme */ static int gpg_decrypt(fko_ctx_t ctx, const char *dec_key) { unsigned char *cipher; size_t cipher_len; int res, pt_len, b64_decode_len; /* Now see if we need to add the "hQ" string to the front of the * base64-encoded-GPG-encrypted data. */ if(! ctx->added_gpg_prefix) add_gpg_prefix(ctx); /* Create a bucket for the (base64) decoded encrypted data and get the * raw cipher data. */ cipher = calloc(1, ctx->encrypted_msg_len); if(cipher == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); if((b64_decode_len = b64_decode(ctx->encrypted_msg, cipher)) < 0) { if(zero_free((char *) cipher, ctx->encrypted_msg_len) == FKO_SUCCESS) return(FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_CIPHER_DECODEFAIL); else return(FKO_ERROR_ZERO_OUT_DATA); } cipher_len = b64_decode_len; /* Create a bucket for the plaintext data and decrypt the message * data into it. */ /* --DSS Actually, the needed memory will be malloced in the gpgme_decrypt // function. Just leaving this here for reference (for now). //ctx->encoded_msg = malloc(cipher_len); //if(ctx->encoded_msg == NULL) // return(FKO_ERROR_MEMORY_ALLOCATION); */ res = gpgme_decrypt(ctx, cipher, cipher_len, dec_key, (unsigned char**)&ctx->encoded_msg, &cipher_len ); /* Done with cipher... */ if(zero_free((char *) cipher, ctx->encrypted_msg_len) != FKO_SUCCESS) return(FKO_ERROR_ZERO_OUT_DATA); else if(res != FKO_SUCCESS) /* bail if there was some other problem */ return(res); if(ctx->encoded_msg == NULL) return(FKO_ERROR_INVALID_DATA_ENCRYPT_DECRYPTED_MESSAGE_MISSING); pt_len = strnlen(ctx->encoded_msg, MAX_SPA_ENCODED_MSG_SIZE); if(! is_valid_encoded_msg_len(pt_len)) return(FKO_ERROR_INVALID_DATA_ENCRYPT_DECRYPTED_MSGLEN_VALIDFAIL); ctx->encoded_msg_len = pt_len; /* Call fko_decode and return the results. */ return(fko_decode_spa_data(ctx)); } #endif /* HAVE_LIBGPGME */ /* Set the SPA encryption type. */ int fko_set_spa_encryption_type(fko_ctx_t ctx, const short encrypt_type) { #if HAVE_LIBFIU fiu_return_on("fko_set_spa_encryption_type_init", FKO_ERROR_CTX_NOT_INITIALIZED); #endif /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); #if HAVE_LIBFIU fiu_return_on("fko_set_spa_encryption_type_val", FKO_ERROR_INVALID_DATA_ENCRYPT_TYPE_VALIDFAIL); #endif if(encrypt_type < 0 || encrypt_type >= FKO_LAST_ENCRYPTION_TYPE) return(FKO_ERROR_INVALID_DATA_ENCRYPT_TYPE_VALIDFAIL); ctx->encryption_type = encrypt_type; ctx->state |= FKO_ENCRYPT_TYPE_MODIFIED; return(FKO_SUCCESS); } /* Return the SPA encryption type. */ int fko_get_spa_encryption_type(fko_ctx_t ctx, short *enc_type) { /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); *enc_type = ctx->encryption_type; return(FKO_SUCCESS); } /* Set the SPA encryption mode. */ int fko_set_spa_encryption_mode(fko_ctx_t ctx, const int encrypt_mode) { #if HAVE_LIBFIU fiu_return_on("fko_set_spa_encryption_mode_init", FKO_ERROR_CTX_NOT_INITIALIZED); #endif /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); #if HAVE_LIBFIU fiu_return_on("fko_set_spa_encryption_mode_val", FKO_ERROR_INVALID_DATA_ENCRYPT_MODE_VALIDFAIL); #endif if(encrypt_mode < 0 || encrypt_mode >= FKO_LAST_ENC_MODE) return(FKO_ERROR_INVALID_DATA_ENCRYPT_MODE_VALIDFAIL); ctx->encryption_mode = encrypt_mode; ctx->state |= FKO_ENCRYPT_MODE_MODIFIED; return(FKO_SUCCESS); } /* Return the SPA encryption mode. */ int fko_get_spa_encryption_mode(fko_ctx_t ctx, int *enc_mode) { /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); if(enc_mode == NULL) return(FKO_ERROR_INVALID_DATA); *enc_mode = ctx->encryption_mode; return(FKO_SUCCESS); } /* Encrypt the encoded SPA data. */ int fko_encrypt_spa_data(fko_ctx_t ctx, const char * const enc_key, const int enc_key_len) { int res = 0; /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); if(enc_key_len < 0) return(FKO_ERROR_INVALID_KEY_LEN); /* If there is no encoded data or the SPA data has been modified, * go ahead and re-encode here. */ if(ctx->encoded_msg == NULL || FKO_IS_SPA_DATA_MODIFIED(ctx)) res = fko_encode_spa_data(ctx); if(res != FKO_SUCCESS) return(res); /* Croak on invalid encoded message as well. At present this is a * check for a somewhat arbitrary minimum length for the encoded * data. */ if (! is_valid_encoded_msg_len(ctx->encoded_msg_len)) return(FKO_ERROR_MISSING_ENCODED_DATA); /* Encrypt according to type and return... */ if(ctx->encryption_type == FKO_ENCRYPTION_RIJNDAEL) { if(enc_key == NULL) return(FKO_ERROR_INVALID_KEY_LEN); res = _rijndael_encrypt(ctx, enc_key, enc_key_len); } else if(ctx->encryption_type == FKO_ENCRYPTION_GPG) #if HAVE_LIBGPGME res = gpg_encrypt(ctx, enc_key); #else res = FKO_ERROR_UNSUPPORTED_FEATURE; #endif else res = FKO_ERROR_INVALID_ENCRYPTION_TYPE; return(res); } /* Decode, decrypt, and parse SPA data into the context. */ int fko_decrypt_spa_data(fko_ctx_t ctx, const char * const dec_key, const int key_len) { int enc_type, res; if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); if(key_len < 0) return(FKO_ERROR_INVALID_KEY_LEN); /* Get the (assumed) type of encryption used. This will also provide * some data validation. */ enc_type = fko_encryption_type(ctx->encrypted_msg); if(enc_type == FKO_ENCRYPTION_GPG && ctx->encryption_mode == FKO_ENC_MODE_ASYMMETRIC) { ctx->encryption_type = FKO_ENCRYPTION_GPG; #if HAVE_LIBGPGME res = gpg_decrypt(ctx, dec_key); #else res = FKO_ERROR_UNSUPPORTED_FEATURE; #endif } else if(enc_type == FKO_ENCRYPTION_RIJNDAEL) { ctx->encryption_type = FKO_ENCRYPTION_RIJNDAEL; res = _rijndael_decrypt(ctx, dec_key, key_len, ctx->encryption_mode); } else return(FKO_ERROR_INVALID_DATA_ENCRYPT_TYPE_UNKNOWN); return(res); } /* Return the assumed encryption type based on the raw encrypted data. */ int fko_encryption_type(const char * const enc_data) { int enc_data_len; /* Sanity check the data. */ if(enc_data == NULL) return(FKO_ENCRYPTION_INVALID_DATA); enc_data_len = strnlen(enc_data, MAX_SPA_ENCODED_MSG_SIZE); if(! is_valid_encoded_msg_len(enc_data_len)) return(FKO_ENCRYPTION_UNKNOWN); if(enc_data_len >= MIN_GNUPG_MSG_SIZE) return(FKO_ENCRYPTION_GPG); else if(enc_data_len < MIN_GNUPG_MSG_SIZE && enc_data_len >= MIN_SPA_ENCODED_MSG_SIZE) return(FKO_ENCRYPTION_RIJNDAEL); else return(FKO_ENCRYPTION_UNKNOWN); } /* Set the GPG recipient key name. */ int fko_set_gpg_recipient(fko_ctx_t ctx, const char * const recip) { #if HAVE_LIBGPGME int res; gpgme_key_t key = NULL; /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); if(ctx->encryption_type != FKO_ENCRYPTION_GPG) return(FKO_ERROR_WRONG_ENCRYPTION_TYPE); if(ctx->gpg_recipient != NULL) free(ctx->gpg_recipient); ctx->gpg_recipient = strdup(recip); if(ctx->gpg_recipient == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); /* Get the key. */ res = get_gpg_key(ctx, &key, 0); if(res != FKO_SUCCESS) { free(ctx->gpg_recipient); ctx->gpg_recipient = NULL; return(res); } ctx->recipient_key = key; ctx->state |= FKO_DATA_MODIFIED; return(FKO_SUCCESS); #else return(FKO_ERROR_UNSUPPORTED_FEATURE); #endif /* HAVE_LIBGPGME */ } /* Set the GPG home dir. */ int fko_set_gpg_exe(fko_ctx_t ctx, const char * const gpg_exe) { #if HAVE_LIBGPGME struct stat st; /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); /* If we are unable to stat the given path/file and determine if it * is a regular file or symbolic link, then return with error. */ if(stat(gpg_exe, &st) != 0) return(FKO_ERROR_GPGME_BAD_GPG_EXE); if(!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode)) return(FKO_ERROR_GPGME_BAD_GPG_EXE); if(ctx->gpg_exe != NULL) free(ctx->gpg_exe); ctx->gpg_exe = strdup(gpg_exe); if(ctx->gpg_exe == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); return(FKO_SUCCESS); #else return(FKO_ERROR_UNSUPPORTED_FEATURE); #endif /* HAVE_LIBGPGME */ } /* Get the GPG home dir. */ int fko_get_gpg_exe(fko_ctx_t ctx, char **gpg_exe) { #if HAVE_LIBGPGME /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); *gpg_exe = ctx->gpg_exe; return(FKO_SUCCESS); #else return(FKO_ERROR_UNSUPPORTED_FEATURE); #endif /* HAVE_LIBGPGME */ } /* Get the GPG recipient key name. */ int fko_get_gpg_recipient(fko_ctx_t ctx, char **recipient) { #if HAVE_LIBGPGME /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); *recipient = ctx->gpg_recipient; return(FKO_SUCCESS); #else return(FKO_ERROR_UNSUPPORTED_FEATURE); #endif /* HAVE_LIBGPGME */ } /* Set the GPG signer key name. */ int fko_set_gpg_signer(fko_ctx_t ctx, const char * const signer) { #if HAVE_LIBGPGME int res; gpgme_key_t key = NULL; /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); if(ctx->encryption_type != FKO_ENCRYPTION_GPG) return(FKO_ERROR_WRONG_ENCRYPTION_TYPE); if(ctx->gpg_signer != NULL) free(ctx->gpg_signer); ctx->gpg_signer = strdup(signer); if(ctx->gpg_signer == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); /* Get the key. */ res = get_gpg_key(ctx, &key, 1); if(res != FKO_SUCCESS) { free(ctx->gpg_signer); ctx->gpg_signer = NULL; return(res); } ctx->signer_key = key; ctx->state |= FKO_DATA_MODIFIED; return(FKO_SUCCESS); #else return(FKO_ERROR_UNSUPPORTED_FEATURE); #endif /* HAVE_LIBGPGME */ } /* Get the GPG signer key name. */ int fko_get_gpg_signer(fko_ctx_t ctx, char **signer) { #if HAVE_LIBGPGME /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); *signer = ctx->gpg_signer; return(FKO_SUCCESS); #else return(FKO_ERROR_UNSUPPORTED_FEATURE); #endif /* HAVE_LIBGPGME */ } /* Set the GPG home dir. */ int fko_set_gpg_home_dir(fko_ctx_t ctx, const char * const gpg_home_dir) { #if HAVE_LIBGPGME struct stat st; /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); /* If we are unable to stat the given dir, then return with error. */ if(stat(gpg_home_dir, &st) != 0) return(FKO_ERROR_GPGME_BAD_HOME_DIR); if(!S_ISDIR(st.st_mode)) return(FKO_ERROR_GPGME_BAD_HOME_DIR); if(ctx->gpg_home_dir != NULL) free(ctx->gpg_home_dir); ctx->gpg_home_dir = strdup(gpg_home_dir); if(ctx->gpg_home_dir == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); return(FKO_SUCCESS); #else return(FKO_ERROR_UNSUPPORTED_FEATURE); #endif /* HAVE_LIBGPGME */ } /* Get the GPG home dir. */ int fko_get_gpg_home_dir(fko_ctx_t ctx, char **home_dir) { #if HAVE_LIBGPGME /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); *home_dir = ctx->gpg_home_dir; return(FKO_SUCCESS); #else return(FKO_ERROR_UNSUPPORTED_FEATURE); #endif /* HAVE_LIBGPGME */ } int fko_set_gpg_signature_verify(fko_ctx_t ctx, const unsigned char val) { #if HAVE_LIBGPGME /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); ctx->verify_gpg_sigs = (val != 0) ? 1 : 0; return(FKO_SUCCESS); #else return(FKO_ERROR_UNSUPPORTED_FEATURE); #endif /* HAVE_LIBGPGME */ } int fko_get_gpg_signature_verify(fko_ctx_t ctx, unsigned char * const val) { #if HAVE_LIBGPGME /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); *val = ctx->verify_gpg_sigs; return(FKO_SUCCESS); #else return(FKO_ERROR_UNSUPPORTED_FEATURE); #endif /* HAVE_LIBGPGME */ } int fko_set_gpg_ignore_verify_error(fko_ctx_t ctx, const unsigned char val) { #if HAVE_LIBGPGME /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); ctx->ignore_gpg_sig_error = (val != 0) ? 1 : 0; return(FKO_SUCCESS); #else return(FKO_ERROR_UNSUPPORTED_FEATURE); #endif /* HAVE_LIBGPGME */ } int fko_get_gpg_ignore_verify_error(fko_ctx_t ctx, unsigned char * const val) { #if HAVE_LIBGPGME /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); *val = ctx->ignore_gpg_sig_error; return(FKO_SUCCESS); #else return(FKO_ERROR_UNSUPPORTED_FEATURE); #endif /* HAVE_LIBGPGME */ } int fko_get_gpg_signature_fpr(fko_ctx_t ctx, char **fpr) { #if HAVE_LIBGPGME /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); /* Must be using GPG encryption. */ if(ctx->encryption_type != FKO_ENCRYPTION_GPG) return(FKO_ERROR_WRONG_ENCRYPTION_TYPE); /* Make sure we are supposed to verify signatures. */ if(ctx->verify_gpg_sigs == 0) return(FKO_ERROR_GPGME_SIGNATURE_VERIFY_DISABLED); /* Make sure we have a signature to work with. */ if(ctx->gpg_sigs == NULL) return(FKO_ERROR_GPGME_NO_SIGNATURE); *fpr = ctx->gpg_sigs->fpr; return(FKO_SUCCESS); #else return(FKO_ERROR_UNSUPPORTED_FEATURE); #endif /* HAVE_LIBGPGME */ } int fko_get_gpg_signature_id(fko_ctx_t ctx, char **id) { #if HAVE_LIBGPGME /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); /* Must be using GPG encryption. */ if(ctx->encryption_type != FKO_ENCRYPTION_GPG) return(FKO_ERROR_WRONG_ENCRYPTION_TYPE); /* Make sure we are supposed to verify signatures. */ if(ctx->verify_gpg_sigs == 0) return(FKO_ERROR_GPGME_SIGNATURE_VERIFY_DISABLED); /* Make sure we have a signature to work with. */ if(ctx->gpg_sigs == NULL) return(FKO_ERROR_GPGME_NO_SIGNATURE); *id = ctx->gpg_sigs->fpr + strlen(ctx->gpg_sigs->fpr) - 8; return(FKO_SUCCESS); #else return(FKO_ERROR_UNSUPPORTED_FEATURE); #endif /* HAVE_LIBGPGME */ } int fko_get_gpg_signature_summary(fko_ctx_t ctx, int *sigsum) { #if HAVE_LIBGPGME /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); /* Must be using GPG encryption. */ if(ctx->encryption_type != FKO_ENCRYPTION_GPG) return(FKO_ERROR_WRONG_ENCRYPTION_TYPE); /* Make sure we are supposed to verify signatures. */ if(ctx->verify_gpg_sigs == 0) return(FKO_ERROR_GPGME_SIGNATURE_VERIFY_DISABLED); /* Make sure we have a signature to work with. */ if(ctx->gpg_sigs == NULL) return(FKO_ERROR_GPGME_NO_SIGNATURE); *sigsum = ctx->gpg_sigs->summary; return(FKO_SUCCESS); #else return(FKO_ERROR_UNSUPPORTED_FEATURE); #endif /* HAVE_LIBGPGME */ } int fko_get_gpg_signature_status(fko_ctx_t ctx, int *sigstat) { #if HAVE_LIBGPGME /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); /* Must be using GPG encryption. */ if(ctx->encryption_type != FKO_ENCRYPTION_GPG) return(FKO_ERROR_WRONG_ENCRYPTION_TYPE); /* Make sure we are supposed to verify signatures. */ if(ctx->verify_gpg_sigs == 0) return(FKO_ERROR_GPGME_SIGNATURE_VERIFY_DISABLED); /* Make sure we have a signature to work with. */ if(ctx->gpg_sigs == NULL) return(FKO_ERROR_GPGME_NO_SIGNATURE); *sigstat = ctx->gpg_sigs->status; return(FKO_SUCCESS); #else return(FKO_ERROR_UNSUPPORTED_FEATURE); #endif /* HAVE_LIBGPGME */ } int fko_gpg_signature_id_match(fko_ctx_t ctx, const char * const id, unsigned char * const result) { #if HAVE_LIBGPGME char *curr_id; int rv = FKO_SUCCESS; /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); /* Must be using GPG encryption. */ if(ctx->encryption_type != FKO_ENCRYPTION_GPG) return(FKO_ERROR_WRONG_ENCRYPTION_TYPE); /* Make sure we are supposed to verify signatures. */ if(ctx->verify_gpg_sigs == 0) return(FKO_ERROR_GPGME_SIGNATURE_VERIFY_DISABLED); /* Make sure we have a signature to work with. */ if(ctx->gpg_sigs == NULL) return(FKO_ERROR_GPGME_NO_SIGNATURE); rv = fko_get_gpg_signature_id(ctx, &curr_id); if(rv != FKO_SUCCESS) return rv; *result = strcmp(id, curr_id) == 0 ? 1 : 0; return(FKO_SUCCESS); #else return(FKO_ERROR_UNSUPPORTED_FEATURE); #endif /* HAVE_LIBGPGME */ } int fko_gpg_signature_fpr_match(fko_ctx_t ctx, const char * const id, unsigned char * const result) { #if HAVE_LIBGPGME /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); /* Must be using GPG encryption. */ if(ctx->encryption_type != FKO_ENCRYPTION_GPG) return(FKO_ERROR_WRONG_ENCRYPTION_TYPE); /* Make sure we are supposed to verify signatures. */ if(ctx->verify_gpg_sigs == 0) return(FKO_ERROR_GPGME_SIGNATURE_VERIFY_DISABLED); /* Make sure we have a signature to work with. */ if(ctx->gpg_sigs == NULL) return(FKO_ERROR_GPGME_NO_SIGNATURE); *result = strcmp(id, ctx->gpg_sigs->fpr) == 0 ? 1 : 0; return(FKO_SUCCESS); #else return(FKO_ERROR_UNSUPPORTED_FEATURE); #endif /* HAVE_LIBGPGME */ } /***EOF***/ fwknop-2.6.11/lib/md5.h0000664000175000017500000000335414560546213011447 00000000000000/** * \file lib/md5.h * * \brief Header for the fwknop md5.c. */ /* MD5 Message Digest Algorithm (RFC1321). * * Derived from cryptoapi implementation, originally based on the * public domain implementation written by Colin Plumb in 1993. * * Copyright (c) Cryptoapi developers. * Copyright (c) 2002 James Morris * * License (GNU General Public License): * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #ifndef MD5_H #define MD5_H 1 #include "common.h" #define MD5_BLOCK_LEN 64 #define MD5_DIGEST_LEN 16 #define MD5_DIGEST_STR_LEN (MD5_DIGEST_LEN * 2 + 1) #define MD5_B64_LEN 22 typedef struct _MD5Context { uint32_t buf[4]; uint32_t bits[2]; unsigned char in[64]; } MD5Context; void MD5Init(MD5Context*); void MD5Update(MD5Context *ctx, unsigned char *buf, unsigned len); void MD5Final(unsigned char digest[16], MD5Context *ctx); void MD5Transform(uint32_t buf[4], uint32_t in[16]); #endif /* MD5_H */ /***EOF***/ fwknop-2.6.11/lib/base64.c0000664000175000017500000001720714560546213012043 00000000000000/** * \file lib/base64.c * * \brief Implementation of the Base64 encode/decode algorithim. */ /* This code was derived from the base64.c part of FFmpeg written * by Ryan Martell. (rdm4@martellventures.com). * * Copyright (C) Ryan Martell. (rdm4@martellventures.com) * * Fwknop is developed primarily by the people listed in the file 'AUTHORS'. * Copyright (C) 2009-2015 fwknop developers and contributors. For a full * list of contributors, see the file 'CREDITS'. * * License (GNU General Public License): * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #include "base64.h" #include "fko_common.h" #if !AFL_FUZZING static unsigned char map2[] = { 0x3e, 0xff, 0xff, 0xff, 0x3f, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33 }; #endif #ifdef HAVE_C_UNIT_TESTS /* LCOV_EXCL_START */ #include "cunit_common.h" DECLARE_TEST_SUITE(base64_test, "Utility functions test suite"); #endif /* LCOV_EXCL_STOP */ int b64_decode(const char *in, unsigned char *out) { int i; unsigned char *dst = out; #if ! AFL_FUZZING int v; #endif #if AFL_FUZZING /* short circuit base64 decoding in AFL fuzzing mode - just copy * data as-is. */ for (i = 0; in[i]; i++) *dst++ = in[i]; #else v = 0; for (i = 0; in[i] && in[i] != '='; i++) { unsigned int index= in[i]-43; if (index>=(sizeof(map2)/sizeof(map2[0])) || map2[index] == 0xff) return(-1); v = (v << 6) + map2[index]; if (i & 3) *dst++ = v >> (6 - 2 * (i & 3)); } #endif *dst = '\0'; return(dst - out); } /***************************************************************************** * b64_encode: Stolen from VLC's http.c * Simplified by michael * fixed edge cases and made it work from data (vs. strings) by ryan. ***************************************************************************** */ int b64_encode(unsigned char *in, char *out, int in_len) { static const char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; unsigned i_bits = 0; int i_shift = 0; int bytes_remaining = in_len; char *dst = out; if (in_len > 0) { /* Special edge case, what should we really do here? */ while (bytes_remaining) { i_bits = (i_bits << 8) + *in++; bytes_remaining--; i_shift += 8; do { *dst++ = b64[(i_bits << 6 >> i_shift) & 0x3f]; i_shift -= 6; } while (i_shift > 6 || (bytes_remaining == 0 && i_shift > 0)); } while ((dst - out) & 3) *dst++ = '='; } *dst = '\0'; return(dst - out); } /* Strip trailing equals ("=") charcters from a base64-encoded * message digest. */ void strip_b64_eq(char *data) { char *ndx; if((ndx = strchr(data, '=')) != NULL) *ndx = '\0'; } #ifdef HAVE_C_UNIT_TESTS /* LCOV_EXCL_START */ DECLARE_UTEST(test_base64_encode, "test base64 encoding functions") { char test_str[32] = {0}; char test_out[32] = {0}; char expected_out1[32] = {0}; char expected_out2[32] = {0}; char expected_out3[32] = {0}; char expected_out4[32] = {0}; char expected_out5[32] = {0}; char expected_out6[32] = {0}; char expected_out7[32] = {0}; strcpy(expected_out1, ""); strcpy(expected_out2, "Zg=="); strcpy(expected_out3, "Zm8="); strcpy(expected_out4, "Zm9v"); strcpy(expected_out5, "Zm9vYg=="); strcpy(expected_out6, "Zm9vYmE="); strcpy(expected_out7, "Zm9vYmFy"); strcpy(test_str, ""); b64_encode((unsigned char *)test_str, test_out, strlen(test_str)); CU_ASSERT(strcmp(test_out, expected_out1) == 0); strcpy(test_str, "f"); b64_encode((unsigned char *)test_str, test_out, strlen(test_str)); CU_ASSERT(strcmp(test_out, expected_out2) == 0); strcpy(test_str, "fo"); b64_encode((unsigned char *)test_str, test_out, strlen(test_str)); CU_ASSERT(strcmp(test_out, expected_out3) == 0); strcpy(test_str, "foo"); b64_encode((unsigned char *)test_str, test_out, strlen(test_str)); CU_ASSERT(strcmp(test_out, expected_out4) == 0); strcpy(test_str, "foob"); b64_encode((unsigned char *)test_str, test_out, strlen(test_str)); CU_ASSERT(strcmp(test_out, expected_out5) == 0); strcpy(test_str, "fooba"); b64_encode((unsigned char *)test_str, test_out, strlen(test_str)); CU_ASSERT(strcmp(test_out, expected_out6) == 0); strcpy(test_str, "foobar"); b64_encode((unsigned char *)test_str, test_out, strlen(test_str)); CU_ASSERT(strcmp(test_out, expected_out7) == 0); } DECLARE_UTEST(test_base64_decode, "test base64 decoding functions") { char test_str[32] = {0}; char test_out[32] = {0}; char expected_out1[32] = {0}; char expected_out2[32] = {0}; char expected_out3[32] = {0}; char expected_out4[32] = {0}; char expected_out5[32] = {0}; char expected_out6[32] = {0}; char expected_out7[32] = {0}; strcpy(expected_out1, ""); strcpy(expected_out2, "f"); strcpy(expected_out3, "fo"); strcpy(expected_out4, "foo"); strcpy(expected_out5, "foob"); strcpy(expected_out6, "fooba"); strcpy(expected_out7, "foobar"); strcpy(test_str, ""); b64_decode(test_str, (unsigned char *)test_out); CU_ASSERT(strcmp(test_out, expected_out1) == 0); strcpy(test_str, "Zg=="); b64_decode(test_str, (unsigned char *)test_out); CU_ASSERT(strcmp(test_out, expected_out2) == 0); strcpy(test_str, "Zm8="); b64_decode(test_str, (unsigned char *)test_out); CU_ASSERT(strcmp(test_out, expected_out3) == 0); strcpy(test_str, "Zm9v"); b64_decode(test_str, (unsigned char *)test_out); CU_ASSERT(strcmp(test_out, expected_out4) == 0); strcpy(test_str, "Zm9vYg=="); b64_decode(test_str, (unsigned char *)test_out); CU_ASSERT(strcmp(test_out, expected_out5) == 0); strcpy(test_str, "Zm9vYmE="); b64_decode(test_str, (unsigned char *)test_out); CU_ASSERT(strcmp(test_out, expected_out6) == 0); strcpy(test_str, "Zm9vYmFy"); b64_decode(test_str, (unsigned char *)test_out); CU_ASSERT(strcmp(test_out, expected_out7) == 0); } int register_base64_test(void) { ts_init(&TEST_SUITE(base64_test), TEST_SUITE_DESCR(base64_test), NULL, NULL); ts_add_utest(&TEST_SUITE(base64_test), UTEST_FCT(test_base64_encode), UTEST_DESCR(test_base64_encode)); ts_add_utest(&TEST_SUITE(base64_test), UTEST_FCT(test_base64_decode), UTEST_DESCR(test_base64_decode)); return register_ts(&TEST_SUITE(base64_test)); } #endif /* LCOV_EXCL_STOP */ /***EOF***/ fwknop-2.6.11/lib/hmac.h0000664000175000017500000001310014560546213011660 00000000000000/** * \file lib/hmac.h * * \brief Provide HMAC support for SPA communications */ /* Fwknop is developed primarily by the people listed in the file 'AUTHORS'. * Copyright (C) 2009-2015 fwknop developers and contributors. For a full * list of contributors, see the file 'CREDITS'. * * License (GNU General Public License): * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #ifndef HMAC_H #define HMAC_H 1 #include "digest.h" #define MAX_DIGEST_BLOCK_LEN SHA3_256_BLOCK_LEN /**< The longest block length is from SHA3_256 */ /** * \brief Generate MD5 based HMAC * * This function generates an HMAC verification hash, based on MD5 * * \param msg Pointer to the message to be signed * \param msg_len size of the message string * \param hmac Pointer to the hmac buffer, where the final hmac will be stored * \param hmac_key Pointer to the key to be used for generating the hmac * \param hmac_key_len Size of the hmac key * * \return FKO_SUCCESS if successful, returns an error code otherwise. */ int hmac_md5(const char *msg, const unsigned int msg_len, unsigned char *hmac, const char *hmac_key, const int hmac_key_len); /** * \brief Generate SHA1 based HMAC * * This function generates an HMAC verification hash, based on SHA1 * * \param msg Pointer to the message to be signed * \param msg_len size of the message string * \param hmac Pointer to the hmac buffer, where the final hmac will be stored * \param hmac_key Pointer to the key to be used for generating the hmac * \param hmac_key_len Size of the hmac key * * \return FKO_SUCCESS if successful, returns an error code otherwise. */ int hmac_sha1(const char *msg, const unsigned int msg_len, unsigned char *hmac, const char *hmac_key, const int hmac_key_len); /** * \brief Generate SHA256 based HMAC * * This function generates an HMAC verification hash, based on SHA256 * * \param msg Pointer to the message to be signed * \param msg_len size of the message string * \param hmac Pointer to the hmac buffer, where the final hmac will be stored * \param hmac_key Pointer to the key to be used for generating the hmac * \param hmac_key_len Size of the hmac key * * \return FKO_SUCCESS if successful, returns an error code otherwise. */ int hmac_sha256(const char *msg, const unsigned int msg_len, unsigned char *hmac, const char *hmac_key, const int hmac_key_len); /** * \brief Generate SHA384 based HMAC * * This function generates an HMAC verification hash, based on SHA384 * * \param msg Pointer to the message to be signed * \param msg_len size of the message string * \param hmac Pointer to the hmac buffer, where the final hmac will be stored * \param hmac_key Pointer to the key to be used for generating the hmac * \param hmac_key_len Size of the hmac key * * \return FKO_SUCCESS if successful, returns an error code otherwise. */ int hmac_sha384(const char *msg, const unsigned int msg_len, unsigned char *hmac, const char *hmac_key, const int hmac_key_len); /** * \brief Generate SHA512 based HMAC * * This function generates an HMAC verification hash, based on SHA512 * * \param msg Pointer to the message to be signed * \param msg_len size of the message string * \param hmac Pointer to the hmac buffer, where the final hmac will be stored * \param hmac_key Pointer to the key to be used for generating the hmac * \param hmac_key_len Size of the hmac key * * \return FKO_SUCCESS if successful, returns an error code otherwise. */ int hmac_sha512(const char *msg, const unsigned int msg_len, unsigned char *hmac, const char *hmac_key, const int hmac_key_len); /** * \brief Generate SHA3-256 based HMAC * * This function generates an HMAC verification hash, based on SHA3-256 * * \param msg Pointer to the message to be signed * \param msg_len size of the message string * \param hmac Pointer to the hmac buffer, where the final hmac will be stored * \param hmac_key Pointer to the key to be used for generating the hmac * \param hmac_key_len Size of the hmac key * * \return FKO_SUCCESS if successful, returns an error code otherwise. */ int hmac_sha3_256(const char *msg, const unsigned int msg_len, unsigned char *hmac, const char *hmac_key, const int hmac_key_len); /** * \brief Generate SHA3-512 based HMAC * * This function generates an HMAC verification hash, based on SHA3-512 * * \param msg Pointer to the message to be signed * \param msg_len size of the message string * \param hmac Pointer to the hmac buffer, where the final hmac will be stored * \param hmac_key Pointer to the key to be used for generating the hmac * \param hmac_key_len Size of the hmac key * * \return FKO_SUCCESS if successful, returns an error code otherwise. */ int hmac_sha3_512(const char *msg, const unsigned int msg_len, unsigned char *hmac, const char *hmac_key, const int hmac_key_len); #endif /* HMAC_H */ /***EOF***/ fwknop-2.6.11/client/0000775000175000017500000000000014560546701011376 500000000000000fwknop-2.6.11/client/fwknop_common.h0000664000175000017500000001247714560546213014354 00000000000000/** * \file client/fwknop_common.h * * \brief Header file for fwknop config_init. */ /* Fwknop is developed primarily by the people listed in the file 'AUTHORS'. * Copyright (C) 2009-2015 fwknop developers and contributors. For a full * list of contributors, see the file 'CREDITS'. * * License (GNU General Public License): * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ****************************************************************************** */ #ifndef FWKNOP_COMMON_H #define FWKNOP_COMMON_H #include "common.h" #include "log_msg.h" /* My Name and Version */ #define MY_NAME "fwknop" #define MY_DESC "Single Packet Authorization client" /* Get our program version from VERSION (defined in config.h). */ #define MY_VERSION VERSION /* Default config path, can override with -c */ #define DEF_CONFIG_FILE MY_NAME".conf" /* For time offset handling */ #define MAX_TIME_STR_LEN 9 #define TIME_OFFSET_SECONDS 1 #define TIME_OFFSET_MINUTES 60 #define TIME_OFFSET_HOURS 3600 #define TIME_OFFSET_DAYS 86400 /* For resolving allow IP - the default is to do this via HTTPS with * wget to https://www.cipherdyne.org/cgi-bin/myip, and if the user * permit it, to fall back to the same URL but via HTTP. */ #define HTTP_RESOLVE_HOST "www.cipherdyne.org" #define HTTP_BACKUP_RESOLVE_HOST "www.cipherdyne.com" #define HTTP_RESOLVE_URL "/cgi-bin/myip" #define WGET_RESOLVE_URL_SSL "https://" HTTP_RESOLVE_HOST HTTP_RESOLVE_URL #define HTTP_MAX_REQUEST_LEN 2000 #define HTTP_MAX_RESPONSE_LEN 2000 #define HTTP_MAX_USER_AGENT_LEN 100 #define MAX_URL_HOST_LEN 256 #define MAX_URL_PATH_LEN 1024 /* fwknop client configuration parameters and values */ typedef struct fko_cli_options { char config_file[MAX_PATH_LEN]; char access_str[MAX_PATH_LEN]; char rc_file[MAX_PATH_LEN]; char key_gen_file[MAX_PATH_LEN]; char server_command[MAX_LINE_LEN]; char get_key_file[MAX_PATH_LEN]; char get_hmac_key_file[MAX_PATH_LEN]; char save_packet_file[MAX_PATH_LEN]; int save_packet_file_append; int show_last_command; int run_last_command; char args_save_file[MAX_PATH_LEN]; int no_save_args; int use_hmac; char spa_server_str[MAX_SERVER_STR_LEN]; /* may be a hostname */ char allow_ip_str[MAX_IPV4_STR_LEN]; char spoof_ip_src_str[MAX_IPV4_STR_LEN]; char spoof_user[MAX_USERNAME_LEN]; int rand_port; char gpg_recipient_key[MAX_GPG_KEY_ID]; char gpg_signer_key[MAX_GPG_KEY_ID]; char gpg_home_dir[MAX_PATH_LEN]; char gpg_exe[MAX_PATH_LEN]; #if HAVE_LIBFIU char fault_injection_tag[MAX_FAULT_TAG_LEN]; #endif /* Encryption keys read from a .fwknoprc stanza */ char key[MAX_KEY_LEN+1]; char key_base64[MAX_B64_KEY_LEN+1]; int key_len; char hmac_key[MAX_KEY_LEN+1]; char hmac_key_base64[MAX_B64_KEY_LEN+1]; int hmac_key_len; int have_key; int have_base64_key; int have_hmac_key; int have_hmac_base64_key; int hmac_type; /* NAT access */ char nat_access_str[MAX_PATH_LEN]; int nat_local; int nat_port; int nat_rand_port; /* External IP resolution via HTTP */ int resolve_ip_http_https; int resolve_http_only; char *resolve_url; char http_user_agent[HTTP_MAX_USER_AGENT_LEN]; unsigned char use_wget_user_agent; char *wget_bin; /* HTTP proxy support */ char http_proxy[HTTP_MAX_REQUEST_LEN]; /* SPA packet transmission port and protocol */ int spa_proto; unsigned int spa_dst_port; unsigned int spa_src_port; /* only used with --source-port */ short digest_type; int encryption_mode; int spa_icmp_type; /* only used in '-P icmp' mode */ int spa_icmp_code; /* only used in '-P icmp' mode */ /* Various command-line flags */ unsigned char verbose; /* --verbose mode */ unsigned char version; /* --version */ unsigned char test; unsigned char use_gpg; unsigned char use_gpg_agent; unsigned char gpg_no_signing_pw; unsigned char key_gen; int time_offset_plus; int time_offset_minus; int fw_timeout; unsigned char no_home_dir; unsigned char no_rc_file; char use_rc_stanza[MAX_LINE_LEN]; unsigned char got_named_stanza; unsigned char save_rc_stanza; unsigned char force_save_rc_stanza; unsigned char stanza_list; int spa_server_resolve_ipv4; int input_fd; //char config_file[MAX_PATH_LEN]; } fko_cli_options_t; void free_configs(fko_cli_options_t *opts); #endif /* FWKNOP_COMMON_H */ /***EOF***/ fwknop-2.6.11/client/getpasswd.c0000664000175000017500000002060214560546213013461 00000000000000/** * \file client/getpasswd.c * * \brief Routines for obtaining a password from a user. */ /* Fwknop is developed primarily by the people listed in the file 'AUTHORS'. * Copyright (C) 2009-2015 fwknop developers and contributors. For a full * list of contributors, see the file 'CREDITS'. * * License (GNU General Public License): * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * ***************************************************************************** */ #include #include #ifdef WIN32 #include #else #include #endif #include "fwknop_common.h" #include "getpasswd.h" #include "utils.h" #define PW_BUFSIZE 128 /*!< Maximum number of chars an encryption key or a password can contain */ #define PW_BREAK_CHAR 0x03 /*!< Ascii code for the Ctrl-C char */ #define PW_BS_CHAR 0x08 /*!< Ascii code for the backspace char */ #define PW_LF_CHAR 0x0A /*!< Ascii code for the \n char */ #define PW_CR_CHAR 0x0D /*!< Ascii code for the \r char */ #define PW_CLEAR_CHAR 0x15 /*!< Ascii code for the Ctrl-U char */ #define ARRAY_FIRST_ELT_ADR(t) &((t)[0]) /*!< Macro to get the first element of an array */ #define ARRAY_LAST_ELT_ADR(t) &((t)[sizeof(t)-1]) /*!< Macro to get the last element of an array */ /** * @brief Read a password from a stream object * * @param stream Pointer to a FILE object that identifies an input stream. * * @return The password buffer or NULL if not set */ static char * read_passwd_from_stream(FILE *stream) { static char password[PW_BUFSIZE] = {0}; int c; char *ptr; ptr = ARRAY_FIRST_ELT_ADR(password); if(stream == NULL) return password; #ifdef WIN32 while((c = _getch()) != PW_CR_CHAR) #else while( ((c = getc(stream)) != EOF) && (c != PW_LF_CHAR) && (c != PW_BREAK_CHAR) ) #endif { /* Handle a backspace without backing up too far. */ if (c == PW_BS_CHAR) { if (ptr != ARRAY_FIRST_ELT_ADR(password)) ptr--; } /* Handle a Ctrl-U to clear the password entry and start over */ else if (c == PW_CLEAR_CHAR) ptr = ARRAY_FIRST_ELT_ADR(password); /* Fill in the password buffer until it reaches the last -1 char. * The last char is used to NULL terminate the string. */ else if (ptr < ARRAY_LAST_ELT_ADR(password)) { *ptr++ = c; } /* Discard char */ else; } /* A CTRL-C char has been detected, we discard the password */ if (c == PW_BREAK_CHAR) password[0] = '\0'; /* Otherwise we NULL terminate the string here. Overflows are handled * previously, so we can add the char without worrying */ else *ptr = '\0'; return password; } /** * @brief Function for accepting password input from users * * The functions reads chars from a buffered stream and store them in a buffer of * chars. If a file descriptor is supplied then, the password is read from * the associated stream, otherwise a new buffered stream is created and a * prompt is displayed to the user. * * @param prompt String displayed on the terminal to prompt the user for a * password or an encryption key * @param fd File descriptor to use to read the pasword from. If fd is set * to FD_INVALID, then a new stream is opened. * * @return NULL if a problem occurred or the user killed the terminal (Ctrl-C)\n * otherwise the password - empty password is accepted. */ char* getpasswd(const char *prompt, int fd) { char *ptr = NULL; FILE *fp = NULL; #ifndef WIN32 sigset_t sig, old_sig; struct termios ts; tcflag_t old_c_lflag = 0; #else /* Force stdin on windows. */ fd = 0; #endif /* If a valid file descriptor is supplied, we try to open a stream from it */ if (FD_IS_VALID(fd)) { fp = fdopen(fd, "r"); if (fp == NULL) { log_msg(LOG_VERBOSITY_ERROR, "getpasswd() - " "Unable to create a stream from the file descriptor : %s", strerror(errno)); return(NULL); } } #ifndef WIN32 /* Otherwise we are going to open a new stream */ else { if((fp = fopen(ctermid(NULL), "r+")) == NULL) return(NULL); setbuf(fp, NULL); /* Setup blocks for SIGINT and SIGTSTP and save the original signal * mask. */ sigemptyset(&sig); sigaddset(&sig, SIGINT); sigaddset(&sig, SIGTSTP); sigprocmask(SIG_BLOCK, &sig, &old_sig); /* * Save current tty state for later restoration after we : * - disable echo of characters to the tty * - disable signal generation * - disable canonical mode (input read line by line mode) */ tcgetattr(fileno(fp), &ts); old_c_lflag = ts.c_lflag; ts.c_lflag &= ~(ECHO | ICANON | ISIG); tcsetattr(fileno(fp), TCSAFLUSH, &ts); fputs(prompt, fp); } #else _cputs(prompt); #endif /* Read the password */ ptr = read_passwd_from_stream(fp); #ifdef WIN32 /* In Windows, it would be a CR-LF */ _putch(PW_CR_CHAR); _putch(PW_LF_CHAR); #else if(! FD_IS_VALID(fd)) { /* Reset terminal settings */ fputs("\n", fp); ts.c_lflag = old_c_lflag; tcsetattr(fileno(fp), TCSAFLUSH, &ts); } #endif fclose(fp); return (ptr); } /* Function for accepting password input from a file */ int get_key_file(char *key, int *key_len, const char *key_file, fko_ctx_t ctx, const fko_cli_options_t *options) { FILE *pwfile_ptr; unsigned int i = 0, found_dst; char conf_line_buf[MAX_LINE_LEN] = {0}; char tmp_char_buf[MAX_LINE_LEN] = {0}; char *lptr; memset(key, 0x00, MAX_KEY_LEN+1); if ((pwfile_ptr = fopen(key_file, "r")) == NULL) { log_msg(LOG_VERBOSITY_ERROR, "Could not open config file: %s", key_file); return 0; } while ((fgets(conf_line_buf, MAX_LINE_LEN, pwfile_ptr)) != NULL) { conf_line_buf[MAX_LINE_LEN-1] = '\0'; lptr = conf_line_buf; memset(tmp_char_buf, 0x0, MAX_LINE_LEN); while (*lptr == ' ' || *lptr == '\t' || *lptr == '=') lptr++; /* Get past comments and empty lines. */ if (*lptr == '#' || *lptr == '\n' || *lptr == '\r' || *lptr == '\0' || *lptr == ';') continue; /* Look for a line like ": " - this allows * multiple keys to be placed within the same file, and the client will * reference the matching one for the SPA server we are contacting */ found_dst = 1; for (i=0; i < strlen(options->spa_server_str); i++) if (*lptr++ != options->spa_server_str[i]) found_dst = 0; if (! found_dst) continue; if (*lptr == ':') lptr++; else continue; /* Skip whitespace until we get to the password */ while (*lptr == ' ' || *lptr == '\t' || *lptr == '=') lptr++; i = 0; while (*lptr != '\0' && *lptr != '\n') { key[i] = *lptr; lptr++; i++; } key[i] = '\0'; } fclose(pwfile_ptr); if (key[0] == '\0') { log_msg(LOG_VERBOSITY_ERROR, "Could not get key for IP: %s from: %s", options->spa_server_str, key_file); return 0; } *key_len = strlen(key); return 1; } /***EOF***/ fwknop-2.6.11/client/fwknop.8.in0000664000175000017500000016414514560546213013331 00000000000000'\" t .\" Title: fwknop .\" Author: [see the "AUTHORS" section] .\" Generator: DocBook XSL Stylesheets v1.79.1 .\" Date: 08/06/2018 .\" Manual: Fwknop Client .\" Source: Fwknop Client .\" Language: English .\" .TH "FWKNOP" "8" "08/06/2018" "Fwknop Client" "Fwknop Client" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" fwknop \- Firewall Knock Operator .SH "SYNOPSIS" .sp \fBfwknop\fR \fB\-A\fR <\*(Aqproto/ports\*(Aq> \fB\-R\fR|\fB\-a\fR|\fB\-s \-D\fR <\*(Aqhost\*(Aq> [\fIoptions\fR] .SH "DESCRIPTION" .sp \fBfwknop\fR implements an authorization scheme known as Single Packet Authorization (SPA) for strong service concealment\&. SPA requires only a single packet which is encrypted, non\-replayable, and authenticated via an HMAC in order to communicate desired access to a service that is hidden behind a firewall in a default\-drop filtering stance\&. The main application of SPA is to use a firewall to drop all attempts to connect to services such as \fISSH\fR in order to make the exploitation of vulnerabilities (both 0\-day and unpatched code) more difficult\&. Any service that is concealed by SPA naturally cannot be scanned for with \fINmap\fR\&. The fwknop project natively supports four different firewalls: \fIiptables\fR, \fIfirewalld\fR, \fIPF\fR, and \fIipfw\fR across Linux, OpenBSD, FreeBSD, and Mac OS X\&. There is also support for custom scripts so that fwknop can be made to support other infrastructure such as \fIipset\fR or \fInftables\fR\&. .sp SPA is essentially next generation Port Knocking (PK), but solves many of the limitations exhibited by PK while retaining its core benefits\&. PK limitations include a general difficulty in protecting against replay attacks, asymmetric ciphers and HMAC schemes are not usually possible to reliably support, and it is trivially easy to mount a DoS attack against a PK server just by spoofing an additional packet into a PK sequence as it traverses the network (thereby convincing the PK server that the client doesn\(cqt know the proper sequence)\&. All of these limitation are solved by SPA\&. At the same time, SPA hides services behind a default\-drop firewall policy, acquires SPA data passively (usually via libpcap or other means), and implements standard cryptographic operations for SPA packet authentication and encryption/decryption\&. .sp This is the manual page for the \fBfwknop\fR client which is responsible for constructing SPA packets and sending them over the network\&. The server side is implemented by the \fBfwknopd\fR daemon which sniffs the network for SPA packets and interacts with the local firewall to allow SPA authenticated connections\&. It is recommended to read the \fIfwknopd(8)\fR manual page as well\&. Further detailed information may be found in the tutorial \(lqSingle Packet Authorization: A Comprehensive Guide to Strong Service Concealment with fwknop\(rq available online (see: \fIhttp://www\&.cipherdyne\&.org/fwknop/docs/fwknop\-tutorial\&.html\fR)\&. .sp SPA packets generated by \fBfwknop\fR leverage HMAC for authenticated encryption in the encrypt\-then\-authenticate model\&. Although the usage of an HMAC is currently optional (enabled via the \fB\-\-use\-hmac\fR command line switch), it is highly recommended for three reasons: \fI1)\fR without an HMAC, cryptographically strong authentication is not possible with \fBfwknop\fR unless GnuPG is used, but even then an HMAC should still be applied, \fI2)\fR an HMAC applied after encryption protects against cryptanalytic CBC\-mode padding oracle attacks such as the Vaudenay attack and related trickery (like the more recent "Lucky 13" attack against SSL), and \fI3)\fR the code required by the \fBfwknopd\fR daemon to verify an HMAC is much more simplistic than the code required to decrypt an SPA packet, so an SPA packet without a proper HMAC isn\(cqt even sent through the decryption routines\&. Reason \fI3)\fR is why an HMAC should still be used even when SPA packets are encrypted with GnuPG due to the fact that SPA data is not sent through \fBlibgpgme\fR functions unless the HMAC checks out first\&. GnuPG and libgpgme are relatively complex bodies of code, and therefore limiting the ability of a potential attacker to interact with this code through an HMAC operation helps to maintain a stronger security stance\&. Generating an HMAC for SPA communications requires a dedicated key in addition to the normal encryption key, and both can be generated with the \fB\-\-key\-gen\fR option\&. .sp \fBfwknop\fR encrypts SPA packets either with the \fIRijndael\fR block cipher or via \fIGnuPG\fR and associated asymmetric cipher\&. If the symmetric encryption method is chosen, then as usual the encryption key is shared between the client and server (see the \fBfwknopd\fR \fI@sysconfdir@/fwknop/access\&.conf\fR file for details)\&. The actual encryption key used for Rijndael encryption is generated via the standard PBKDF1 key derivation algorithm, and CBC mode is set\&. If the GnuPG method is chosen, then the encryption keys are derived from GnuPG key rings\&. SPA packets generated by fwknop running as a client adhere to the following format (before encryption and the HMAC is applied): .sp .if n \{\ .RS 4 .\} .nf random data (16 digits) username timestamp software version mode (command mode (0) or access mode (1)) if command mode => command to execute else access mode => IP,proto,port message digest (SHA512 / SHA384 / SHA256 / SHA1 / MD5 / SHA3_256 / SHA3_512) .fi .if n \{\ .RE .\} .sp Each of the above fields are separated by a ":" character due to the variable length of several of the fields, and those that might contain ":" characters are base64 encoded\&. The message digest (\fBSHA256\fR by default) is part of the data to be encrypted and is independent of the HMAC which is appended to the SPA packet data after encryption\&. The 16 digits of random data (about 53 bits) ensures that no two SPA packets are identical, and this is in addition to and independent of using PBKDF1 for key derivation for Rijndael in CBC mode (which uses an 8\-byte random "salt" value)\&. Because \fBfwknopd\fR tracks the SHA256 digest of all incoming valid SPA packets and throws out duplicates, replay attacks are not feasible against \fBfwknop\fR\&. Syslog alerts are generated if a replay is detected\&. .sp By default, the \fBfwknop\fR client sends authorization packets over UDP port 62201, but this can be altered with the \fB\-\-server\-port\fR argument (this requires \fBfwknopd\fR to be configured to acquire SPA data over the selected port)\&. Also, \fBfwknop\fR can send the SPA packet over a random port via the \fB\-\-rand\-port\fR argument\&. See \fIfwknopd(8)\fR for further details\&. See the \fBEXAMPLES\fR section for example invocations of the \fBfwknop\fR client\&. .sp The \fBfwknop\fR client is quite portable, and is known to run on various Linux distributions (all major distros and embedded ones such as OpenWRT as well), FreeBSD, OpenBSD, Mac OS X, and Cygwin on Windows\&. There is also a library \fBlibfko\fR that both \fBfwknop\fR and \fBfwknopd\fR use for SPA packet encryption/decryption and HMAC authentication operations\&. This library can be used to allow third party applications to use SPA subject to the terms of the GNU General Public License (GPL v2+)\&. .SH "REQUIRED ARGUMENTS" .sp These required arguments can be specified via command\-line or from within the \fI~/\&.fwknoprc\fR file (see \fI\-n, \-\-named\-config\fR option and the FWKNOPRC FILE section below)\&. .PP \fB\-A, \-\-access\fR=\fI\fR .RS 4 Provide a list of ports and protocols to access on a remote computer running \fBfwknopd\fR\&. The format of this list is \(lq+/\&.../+\(rq, e\&.g\&. \(lqtcp/22,udp/53\(rq\&. \fBNOTE:\fR The vast majority of usages for \fBfwknop\fR require the \fB\-A\fR argument, but sending full commands with the \fB\-\-server\-cmd\fR argument via an SPA packet to be executed by \fBfwknopd\fR does not require this argument\&. .RE .PP \fB\-D, \-\-destination\fR=\fI\fR .RS 4 Direct the \fBfwknop\fR client to authenticate with the \fBfwknopd\fR daemon/service at the specified destination hostname or IP address\&. The connection mode is discovered by the \fBfwknopd\fR daemon/service when it decrypts and parses the authentication packet\&. .RE .PP \fB\-R|\-a|\-s\fR .RS 4 One of these options (see below) is required to tell the remote \fBfwknopd\fR daemon what IP should be allowed through the firewall\&. It is recommend to use the \fB\-R\fR or \fB\-a\fR options instead of \fB\-s\fR in order to harden SPA communications against possible \fIMan\-In\-The\-Middle\fR (MITM) attacks, and on the server side set \fIREQUIRE_SOURCE_ADDRESS\fR variable in the \fI@sysconfdir@/fwknop/access\&.conf\fR file\&. Note that the most secure option is \fB\-a\fR so that \fBfwknop\fR does not have to issue any HTTPS request to \fIhttps://www\&.cipherdyne\&.org/cgi\-bin/myip\fR in order to resolve the externally routable IP address\&. Using \fB\-a\fR requires that the user already knows what the external IP is for the network where fwknop is running\&. .RE .SH "GENERAL OPTIONS" .PP \fB\-h, \-\-help\fR .RS 4 Print a usage summary message and exit\&. .RE .PP \fB\-G, \-\-get\-key\fR=\fI\fR .RS 4 Load an encryption key/password from the specified file\&. The key file contains a line for each destination hostname or IP address, a colon (":"), optional space and the password, followed by a newline\&. Note that the last line has to have a terminating newline character\&. Also note: though this is a convenience, having a file on your system with clear text passwords is not a good idea and is not recommended\&. Having the \fBfwknop\fR client prompt you for the key is generally more secure\&. Note also that if a key is stored on disk, the \fBfwknop\fR rc file is a more powerful mechanism for specifying not only the key but other options as well\&. .RE .PP \fB\-\-stdin\fR .RS 4 Read the encryption key/password from stdin\&. This can be used to send the data via a pipe for example\&. This command is similar to \-\-fd 0\&. .RE .PP \fB\-\-fd\fR=\fI\fR .RS 4 Specify the file descriptor number to read the key/password from\&. This command avoids the user being prompted for a password if none has been found in the user specific stanza, or none has been supplied on the command line\&. A file descriptor set to 0 is similar to the stdin command\&. .RE .PP \fB\-\-get\-hmac\-key\fR=\fI\fR .RS 4 Load an HMAC key/password from the specified file\&. Similarly to the format for the \fB\-\-get\-key\fR option, the HMAC key file contains a line for each destination hostname or IP address, a colon (":"), optional space and the password, followed by a newline\&. Note that the last line has to have a terminating newline character\&. Also note: though this is a convenience, having a file on your system with clear text passwords is not a good idea and is not recommended\&. Having the \fBfwknop\fR client prompt you for the HMAC key is generally more secure\&. Note also that if a key is stored on disk, the \fBfwknop\fR rc file is a more powerful mechanism for specifying not only the HMAC key but other options as well\&. .RE .PP \fB\-\-key\-gen\fR .RS 4 Have \fBfwknop\fR generate both Rijndael and HMAC keys that can be used for SPA packet encryption and authentication\&. These keys are derived from /dev/urandom and then base64 encoded before being printed to stdout, and are meant to be included within the \(lq$HOME/\&.fwknoprc\(rq file (or the file referenced by \fB\-\-get\-key\fR)\&. Such keys are generally more secure than passphrases that are typed in from the command line\&. .RE .PP \fB\-\-key\-gen\-file\fR=\fI\fR .RS 4 Write generated keys to the specified file\&. Note that the file is overwritten if it already exists\&. If this option is not given, then \fB\-\-key\-gen\fR writes the keys to stdout\&. .RE .PP \fB\-\-key\-len\fR=\fI\fR .RS 4 Specify the number of bytes for a generated Rijndael key\&. The maximum size is currently 128 bytes\&. .RE .PP \fB\-\-hmac\-key\-len\fR=\fI\fR .RS 4 Specify the number of bytes for a generated HMAC key\&. The maximum size is currently 128 bytes\&. .RE .PP \fB\-l, \-\-last\-cmd\fR .RS 4 Execute \fBfwknop\fR with the command\-line arguments from the previous invocation (if any)\&. The previous arguments are parsed out of the \fI~/\&.fwknop\&.run\fR file\&. .RE .PP \fB\-n, \-\-named\-config\fR=\fI\fR .RS 4 Specify the name of the configuration stanza in the \(lq$HOME/\&.fwknoprc\(rq file to pull configuration and command directives\&. These named stanzas alleviate the need for remembering the various command\-line arguments for frequently used invocations of \fBfwknop\fR\&. See the section labeled, FWKNOPRC FILE below for a list of the valid configuration directives in the \fI\&.fwknoprc\fR file\&. .RE .PP \fB\-\-key\-rijndael\fR=\fI\fR .RS 4 Specify the Rijndael key on the command line\&. Since the key may be visible to utilities such as \fIps\fR under Unix, this form should only be used where security is not critical\&. Having the \fBfwknop\fR client either prompt you for the key or acquire via the \(lq$HOME/\&.fwknoprc\(rq file is generally more secure\&. .RE .PP \fB\-\-key\-base64\-rijndael\fR=\fI\fR .RS 4 Specify the base64 encoded Rijndael key\&. Since the key may be visible to utilities such as \fIps\fR under Unix, this form should only be used where security is not critical\&. Having the \fBfwknop\fR client either prompt you for the key or acquire via the \(lq$HOME/\&.fwknoprc\(rq file is generally more secure\&. .RE .PP \fB\-\-key\-base64\-hmac\fR=\fI\fR .RS 4 Specify the base64 encoded HMAC key\&. Since the key may be visible to utilities such as \fIps\fR under Unix, this form should only be used where security is not critical\&. Having the \fBfwknop\fR client either prompt you for the key or acquire via the \(lq$HOME/\&.fwknoprc\(rq file is generally more secure\&. .RE .PP \fB\-\-key\-hmac\fR=\fI\fR .RS 4 Specify the raw HMAC key (not base64 encoded)\&. Since the key may be visible to utilities such as \fIps\fR under Unix, this form should only be used where security is not critical\&. Having the \fBfwknop\fR client either prompt you for the key or acquire via the \(lq$HOME/\&.fwknoprc\(rq file is generally more secure\&. .RE .PP \fB\-\-rc\-file\fR=\fI\fR .RS 4 Specify path to the \fBfwknop\fR rc file (default is \(lq$HOME/\&.fwknoprc\(rq)\&. .RE .PP \fB\-\-no\-rc\-file\fR .RS 4 Perform \fBfwknop\fR client operations without referencing the \(lq$HOME/\&.fwknoprc\(rq file\&. .RE .PP \fB\-\-no\-home\-dir\fR .RS 4 Do not allow the \fBfwknop\fR client to look for the home directory associated with the user\&. .RE .PP \fB\-\-save\-rc\-stanza\fR=\fI\fR .RS 4 Save command line arguments to the \(lq$HOME/\&.fwknoprc\(rq stanza specified with the \fB\-n\fR option\&. If the \fB\-n\fR option is omitted, then the stanza name will default to the destination server value (hostname or IP) given with the \fB\-D\fR argument\&. .RE .PP \fB\-\-force\-stanza\fR .RS 4 Used with \fB\-\-save\-rc\-stanza\fR to overwrite all of the variables for the specified stanza .RE .PP \fB\-\-stanza\-list\fR .RS 4 Dump a list of the stanzas found in \(lq$HOME/\&.fwknoprc\(rq\&. .RE .PP \fB\-\-show\-last\fR .RS 4 Display the last command\-line arguments used by \fBfwknop\fR\&. .RE .PP \fB\-E, \-\-save\-args\-file\fR=\fI\fR .RS 4 Save command line arguments to a specified file path\&. Without this option, and when \fB\-\-no\-save\-args\fR is not also specified, then the default save args path is \fI~/\&.fwknop\&.run\fR\&. .RE .PP \fB\-\-no\-save\-args\fR .RS 4 Do not save the command line arguments given when \fBfwknop\fR is executed\&. .RE .PP \fB\-T, \-\-test\fR .RS 4 Test mode\&. Generate the SPA packet data, but do not send it\&. Instead, print a break\-down of the SPA data fields, then run the data through the decryption and decoding process and print the break\-down again\&. This is primarily a debugging feature\&. .RE .PP \fB\-B, \-\-save\-packet\fR=\fI\fR .RS 4 Instruct the \fBfwknop\fR client to write a newly created SPA packet out to the specified file so that it can be examined off\-line\&. .RE .PP \fB\-b, \-\-save\-packet\-append\fR .RS 4 Append the generated packet data to the file specified with the \fB\-B\fR option\&. .RE .PP \fB\-\-fault\-injection\-tag\fR=\fI\fR .RS 4 This option is only used for fault injection testing when \fBfwknop\fR is compiled to support the libfiu library (see: \fIhttp://blitiri\&.com\&.ar/p/libfiu/\fR)\&. Under normal circumstances this option is not used, and any packaged version of fwknop will not have code compiled in so this capability is not enabled at run time\&. It is documented here for completeness\&. .RE .PP \fB\-v, \-\-verbose\fR .RS 4 Run the \fBfwknop\fR client in verbose mode\&. This causes \fBfwknop\fR to print some extra information about the current command and the resulting SPA data\&. .RE .PP \fB\-V, \-\-version\fR .RS 4 Display version information and exit\&. .RE .SH "SPA OPTIONS" .PP \fB\-\-use\-hmac\fR .RS 4 Set HMAC mode for authenticated encryption of SPA communications\&. As of \fBfwknop\fR 2\&.5, this is an optional feature, but this will become the default in a future release\&. .RE .PP \fB\-a, \-\-allow\-ip\fR=\fI\fR .RS 4 Specify IP address that should be permitted through the destination \fBfwknopd\fR server firewall (this IP is encrypted within the SPA packet itself)\&. This is useful to prevent a MITM attack where a SPA packet can be intercepted en\-route and sent from a different IP than the original\&. Hence, if the \fBfwknopd\fR server trusts the source address on the SPA packet IP header then the attacker gains access\&. The \fB\-a\fR option puts the source address within the encrypted SPA packet, and so thwarts this attack\&. The \fB\-a\fR option is also useful to specify the IP that will be granted access when the SPA packet itself is spoofed with the \fB\-\-spoof\-src\fR option\&. Another related option is \fB\-R\fR (see below) which instructs the \fBfwknop\fR client to automatically resolve the externally routable IP address the local system is connected to by querying \fIhttps://www\&.cipherdyne\&.org/cgi\-bin/myip\fR\&. This returns the actual IP address it sees from the calling system\&. .RE .PP \fB\-g, \-\-gpg\-encryption\fR .RS 4 Use GPG encryption on the SPA packet (default if not specified is Rijndael)\&. \fBNote:\fR Use of this option will also require a GPG recipient (see \fB\-\-gpg\-recipient\fR along with other GPG\-related options below)\&. .RE .PP \fB\-\-hmac\-digest\-type\fR=\fI\fR .RS 4 Set the HMAC digest algorithm for authenticated encryption of SPA packets\&. Choices are: \fBMD5\fR, \fBSHA1\fR, \fBSHA256\fR (the default), \fBSHA384\fR, \fBSHA512\fR, \fBSHA3_256\fR, and \fBSHA3_512\fR\&. .RE .PP \fB\-N, \-\-nat\-access\fR=\fI\fR .RS 4 The \fBfwknopd\fR server offers the ability to provide SPA access through an iptables firewall to an internal service by interfacing with the iptables NAT capabilities\&. So, if the \fBfwknopd\fR server is protecting an internal network on an RFC\-1918 address space, an external \fBfwknop\fR client can request that the server port forward an external port to an internal IP, i\&.e\&. \(lq+\-\-NAT\-access 192\&.168\&.10\&.2,55000+\(rq\&. In this case, access will be granted to 192\&.168\&.10\&.2 via port 55000 to whatever service is requested via the \fB\-\-access\fR argument (usually tcp/22)\&. Hence, after sending such an SPA packet, one would then do \(lqssh \-p 55000 user@host\(rq and the connection would be forwarded on through to the internal 192\&.168\&.10\&.2 system automatically\&. Note that the port \(lq55000\(rq can be randomly generated via the \fB\-\-nat\-rand\-port\fR argument (described later)\&. .RE .PP \fB\-\-nat\-local\fR .RS 4 On the \fBfwknopd\fR server, a NAT operation can apply to the local system instead of being forwarded through the system\&. That is, for iptables firewalls, a connection to, say, port 55,000 can be translated to port 22 on the local system\&. By making use of the \fB\-\-nat\-local\fR argument, the \fBfwknop\fR client can be made to request such access\&. This means that any external attacker would only see a connection over port 55,000 instead of the expected port 22 after the SPA packet is sent\&. .RE .PP \fB\-\-nat\-port\fR .RS 4 Usually \fBfwknop\fR is used to request access to a specific port such as tcp/22 on a system running \fBfwknopd\fR\&. However, by using the \fB\-\-nat\-port\fR argument, it is possible to request access to a (again, such as tcp/22), but have this access granted via the specified port (so, the \fB\-p\fR argument would then be used on the \fISSH\fR client command line)\&. See the \fB\-\-nat\-local\fR and \fB\-\-nat\-access\fR command line arguments to \fBfwknop\fR for additional details on gaining access to services via a NAT operation\&. .RE .PP \fB\-\-nat\-rand\-port\fR .RS 4 Usually \fBfwknop\fR is used to request access to a specific port such as tcp/22 on a system running \fBfwknopd\fR\&. However, by using the \fB\-\-nat\-rand\-port\fR argument, it is possible to request access to a particular service (again, such as tcp/22), but have this access granted via a random translated port\&. That is, once the \fBfwknop\fR client has been executed in this mode and the random port selected by \fBfwknop\fR is displayed, the destination port used by the follow\-on client must be changed to match this random port\&. For \fISSH\fR, this is accomplished via the \fB\-p\fR argument\&. See the \fB\-\-nat\-local\fR and \fB\-\-nat\-access\fR command line arguments to \fBfwknop\fR for additional details on gaining access to services via a NAT operation\&. .RE .PP \fB\-p, \-\-server\-port\fR=\fI\fR .RS 4 Specify the port number where \fBfwknopd\fR accepts packets via libpcap or ulogd pcap writer\&. By default \fBfwknopd\fR looks for authorization packets over UDP port 62201\&. .RE .PP \fB\-P, \-\-server\-proto\fR=\fI\fR .RS 4 Set the protocol (udp, tcp, http, udpraw, tcpraw, or icmp) for the outgoing SPA packet\&. Note: The \fBudpraw\fR, \fBtcpraw\fR, and \fBicmp\fR modes use raw sockets and thus require root access to run\&. Also note: The \fBtcp\fR mode expects to establish a TCP connection to the server before sending the SPA packet\&. This is not normally done, but is useful for compatibility with the Tor for strong anonymity; see \fIhttp://tor\&.eff\&.org/\fR\&. In this case, the \fBfwknopd\fR server will need to be configured to listen on the target TCP port (which is 62201 by default)\&. .RE .PP \fB\-Q, \-\-spoof\-src\fR=\fI\fR .RS 4 Spoof the source address from which the \fBfwknop\fR client sends SPA packets\&. This requires root on the client side access since a raw socket is required to accomplish this\&. Note that the \fB\-\-spoof\-user\fR argument can be given in this mode in order to pass any \fBREQUIRE_USERNAME\fR keyword that might be specified in \fI@sysconfdir@/fwknop/access\&.conf\fR\&. .RE .PP \fB\-r, \-\-rand\-port\fR .RS 4 Instruct the \fBfwknop\fR client to send an SPA packet over a random destination port between 10,000 and 65535\&. The \fBfwknopd\fR server must use a \fBPCAP_FILTER\fR variable that is configured to accept such packets\&. For example, the \fBPCAP_FILTER\fR variable could be set to: \(lq+udp dst portrange 10000\-65535+\(rq\&. .RE .PP \fB\-R, \-\-resolve\-ip\-https\fR .RS 4 This is an important option, and instructs the \fBfwknop\fR client to issue an HTTPS request to a script running on \fIcipherdyne\&.org\fR that returns the client\(cqs IP address (as seen by the web server)\&. In some cases, this is needed to determine the IP address that should be allowed through the firewall policy at the remote \fBfwknopd\fR server side\&. This option is useful if the \fBfwknop\fR client is being used on a system that is behind an obscure NAT address, and the external Internet facing IP is not known to the user\&. The full resolution URL is: \fIhttps://www\&.cipherdyne\&.org/cgi\-bin/myip\fR, and is accessed by \fBfwknop\fR via \fIwget\fR in \fB\-\-secure\-protocol\fR mode\&. Note that it is generally more secure to use the \fB\-a\fR option if the externally routable IP address for the client is already known to the user since this eliminates the need for \fBfwknop\fR to issue any sort of HTTPS request\&. .RE .PP \fB\-\-resolve\-url\fR \fI\fR .RS 4 Override the default URL used for resolving the source IP address\&. For best results, the URL specified here should point to a web service that provides just an IP address in the body of the HTTP response\&. .RE .PP \fB\-\-resolve\-http\-only\fR .RS 4 This option forces the \fBfwknop\fR client to resolve the external IP via HTTP instead of HTTPS\&. There are some circumstances where this might be necessary such as when \fIwget\fR is not available (or hasn\(cqt been compiled with SSL support), but generally this is not recommended since it opens the possibility of a MITM attack through manipulation of the IP resolution HTTP response\&. Either specify the IP manually with \fB\-a\fR, or use \fB\-R\fR and omit this option\&. .RE .PP \fB\-w, \-\-wget\-cmd\fR=\fI\fR .RS 4 Manually set the full path to the \fIwget\fR command\&. Normally the \fIconfigure\fR script finds the \fIwget\fR command, but this option can be used to specify the path if it is located in a non\-standard place\&. .RE .PP \fB\-s, \-\-source\-ip\fR .RS 4 Instruct the \fBfwknop\fR client to form an SPA packet that contains the special\-case IP address \(lq+0\&.0\&.0\&.0+\(rq which will inform the destination \fBfwknopd\fR SPA server to use the source IP address from which the SPA packet originates as the IP that will be allowed through upon modification of the firewall ruleset\&. This option is useful if the \fBfwknop\fR client is deployed on a machine that is behind a NAT device and the external IP is not known\&. However, usage of this option is not recommended, and either the \fB\-a\fR or \fB\-R\fR options should be used instead\&. The permit\-address options \fB\-s\fR, \fB\-R\fR and \fB\-a\fR are mutually exclusive\&. .RE .PP \fB\-S, \-\-source\-port\fR=\fI\fR .RS 4 Set the source port for outgoing SPA packet\&. .RE .PP \fB\-\-server\-resolve\-ipv4\fR .RS 4 This option forces the \fBfwknop\fR client to only accept an IPv4 address from DNS when a hostname is used for the SPA server\&. This is necessary in some cases where DNS may return both IPv6 and IPv4 addresses\&. .RE .PP \fB\-f, \-\-fw\-timeout\fR=\fI\fR .RS 4 Specify the length of time (seconds) that the remote firewall rule that grants access to a service is to remain active\&. The default maintained by \fBfwknopd\fR is 30 seconds, but any established connection can be kept open after the initial accept rule is deleted through the use of a connection tracking mechanism that may be offered by the firewall\&. .RE .PP \fB\-C, \-\-server\-cmd\fR=\fI\fR .RS 4 Instead of requesting access to a service with an SPA packet, the \fB\-\-server\-cmd\fR argument specifies a command that will be executed by the \fBfwknopd\fR server\&. The command is encrypted within the SPA packet and sniffed off the wire (as usual) by the \fBfwknopd\fR server\&. .RE .PP \fB\-H, \-\-http\-proxy\fR=\fI[:port]\fR .RS 4 Specify an HTTP proxy that the \fBfwknop\fR client will use to send the SPA packet through\&. Using this option will automatically set the SPA packet transmission mode (usually set via the \fB\-\-server\-proto\fR argument) to "http"\&. You can also specify the proxy port by adding ":" to the proxy host name or ip\&. .RE .PP \fB\-m, \-\-digest\-type\fR=\fI\fR .RS 4 Specify the message digest algorithm to use in the SPA data\&. Choices are: \fBMD5\fR, \fBSHA1\fR, \fBSHA256\fR (the default), \fBSHA384\fR, and \fBSHA512\fR, \fBSHA3_256\fR, and \fBSHA3_512\fR\&. .RE .PP \fB\-M, \-\-encryption\-mode\fR=\fI\fR .RS 4 Specify the encryption mode when AES is used for encrypting SPA packets\&. The default is CBC mode, but others can be chosen such as CFB or OFB as long as this is also specified in the \fI@sysconfdir@/fwknop/access\&.conf\fR file on the server side via the ENCRYPTION_MODE variable\&. In general, it is recommended to not include this argument and let the default (CBC) apply\&. Note that the string \(lqlegacy\(rq can be specified in order to generate SPA packets with the old initialization vector strategy used by versions of \fBfwknop\fR prior to 2\&.5\&. With the 2\&.5 release, \fBfwknop\fR generates initialization vectors in a manner that is compatible with OpenSSL via the PBKDF1 algorithm\&. .RE .PP \fB\-\-time\-offset\-plus\fR=\fI