diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 09:59:15 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 09:59:15 +0000 |
commit | 8de1ee1b2b676b0d07586f0752750dd6b0fb7511 (patch) | |
tree | dd46fd7dc3863045696cd0e48032d8a36fa0daf5 /kbx | |
parent | Initial commit. (diff) | |
download | gnupg2-8de1ee1b2b676b0d07586f0752750dd6b0fb7511.tar.xz gnupg2-8de1ee1b2b676b0d07586f0752750dd6b0fb7511.zip |
Adding upstream version 2.2.27.upstream/2.2.27upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'kbx')
-rw-r--r-- | kbx/Makefile.am | 67 | ||||
-rw-r--r-- | kbx/Makefile.in | 1306 | ||||
-rw-r--r-- | kbx/kbxutil.c | 644 | ||||
-rw-r--r-- | kbx/keybox-blob.c | 1057 | ||||
-rw-r--r-- | kbx/keybox-defs.h | 210 | ||||
-rw-r--r-- | kbx/keybox-dump.c | 915 | ||||
-rw-r--r-- | kbx/keybox-file.c | 190 | ||||
-rw-r--r-- | kbx/keybox-init.c | 332 | ||||
-rw-r--r-- | kbx/keybox-openpgp.c | 643 | ||||
-rw-r--r-- | kbx/keybox-search-desc.h | 86 | ||||
-rw-r--r-- | kbx/keybox-search.c | 1317 | ||||
-rw-r--r-- | kbx/keybox-update.c | 799 | ||||
-rw-r--r-- | kbx/keybox-util.c | 102 | ||||
-rw-r--r-- | kbx/keybox.h | 137 | ||||
-rwxr-xr-x | kbx/mkerrors | 70 |
15 files changed, 7875 insertions, 0 deletions
diff --git a/kbx/Makefile.am b/kbx/Makefile.am new file mode 100644 index 0000000..8fca24a --- /dev/null +++ b/kbx/Makefile.am @@ -0,0 +1,67 @@ +# Keybox Makefile +# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. +# +# This file is part of GnuPG. +# +# GnuPG 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 3 of the License, or +# (at your option) any later version. +# +# GnuPG 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, see <https://www.gnu.org/licenses/>. + +## Process this file with automake to produce Makefile.in + +EXTRA_DIST = mkerrors + +AM_CPPFLAGS = + +include $(top_srcdir)/am/cmacros.am + +AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(KSBA_CFLAGS) + +noinst_LIBRARIES = libkeybox.a libkeybox509.a +bin_PROGRAMS = kbxutil + +if HAVE_W32CE_SYSTEM +extra_libs = $(LIBASSUAN_LIBS) +else +extra_libs = +endif + +common_sources = \ + keybox.h keybox-defs.h keybox-search-desc.h \ + keybox-util.c \ + keybox-init.c \ + keybox-blob.c \ + keybox-file.c \ + keybox-search.c \ + keybox-update.c \ + keybox-openpgp.c \ + keybox-dump.c + + +libkeybox_a_SOURCES = $(common_sources) +libkeybox509_a_SOURCES = $(common_sources) + +libkeybox_a_CFLAGS = $(AM_CFLAGS) +libkeybox509_a_CFLAGS = $(AM_CFLAGS) -DKEYBOX_WITH_X509=1 + + +# We need W32SOCKLIBS because the init subsystem code in libcommon +# requires it - although we don't actually need it. It is easier +# to do it this way. +kbxutil_SOURCES = kbxutil.c $(common_sources) +kbxutil_CFLAGS = $(AM_CFLAGS) -DKEYBOX_WITH_X509=1 +kbxutil_LDADD = ../common/libcommon.a \ + $(KSBA_LIBS) $(LIBGCRYPT_LIBS) $(extra_libs) \ + $(GPG_ERROR_LIBS) $(LIBINTL) $(LIBICONV) $(W32SOCKLIBS) \ + $(NETLIBS) + +$(PROGRAMS) : ../common/libcommon.a diff --git a/kbx/Makefile.in b/kbx/Makefile.in new file mode 100644 index 0000000..752e728 --- /dev/null +++ b/kbx/Makefile.in @@ -0,0 +1,1306 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 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@ + +# Keybox Makefile +# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. +# +# This file is part of GnuPG. +# +# GnuPG 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 3 of the License, or +# (at your option) any later version. +# +# GnuPG 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, see <https://www.gnu.org/licenses/>. + +# cmacros.am - C macro definitions +# Copyright (C) 2004 Free Software Foundation, Inc. +# +# This file is part of GnuPG. +# +# GnuPG 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 3 of the License, or +# (at your option) any later version. +# +# GnuPG 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, see <https://www.gnu.org/licenses/>. + + +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@ +@HAVE_DOSISH_SYSTEM_FALSE@am__append_1 = -DGNUPG_BINDIR="\"$(bindir)\"" \ +@HAVE_DOSISH_SYSTEM_FALSE@ -DGNUPG_LIBEXECDIR="\"$(libexecdir)\"" \ +@HAVE_DOSISH_SYSTEM_FALSE@ -DGNUPG_LIBDIR="\"$(libdir)/@PACKAGE@\"" \ +@HAVE_DOSISH_SYSTEM_FALSE@ -DGNUPG_DATADIR="\"$(datadir)/@PACKAGE@\"" \ +@HAVE_DOSISH_SYSTEM_FALSE@ -DGNUPG_SYSCONFDIR="\"$(sysconfdir)/@PACKAGE@\"" \ +@HAVE_DOSISH_SYSTEM_FALSE@ -DGNUPG_LOCALSTATEDIR="\"$(localstatedir)\"" + + +# If a specific protect tool program has been defined, pass its name +# to cc. Note that these macros should not be used directly but via +# the gnupg_module_name function. +@GNUPG_AGENT_PGM_TRUE@am__append_2 = -DGNUPG_DEFAULT_AGENT="\"@GNUPG_AGENT_PGM@\"" +@GNUPG_PINENTRY_PGM_TRUE@am__append_3 = -DGNUPG_DEFAULT_PINENTRY="\"@GNUPG_PINENTRY_PGM@\"" +@GNUPG_SCDAEMON_PGM_TRUE@am__append_4 = -DGNUPG_DEFAULT_SCDAEMON="\"@GNUPG_SCDAEMON_PGM@\"" +@GNUPG_DIRMNGR_PGM_TRUE@am__append_5 = -DGNUPG_DEFAULT_DIRMNGR="\"@GNUPG_DIRMNGR_PGM@\"" +@GNUPG_PROTECT_TOOL_PGM_TRUE@am__append_6 = -DGNUPG_DEFAULT_PROTECT_TOOL="\"@GNUPG_PROTECT_TOOL_PGM@\"" +@GNUPG_DIRMNGR_LDAP_PGM_TRUE@am__append_7 = -DGNUPG_DEFAULT_DIRMNGR_LDAP="\"@GNUPG_DIRMNGR_LDAP_PGM@\"" +bin_PROGRAMS = kbxutil$(EXEEXT) +subdir = kbx +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/autobuild.m4 \ + $(top_srcdir)/m4/codeset.m4 $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/gpg-error.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/isc-posix.m4 $(top_srcdir)/m4/ksba.m4 \ + $(top_srcdir)/m4/lcmessage.m4 $(top_srcdir)/m4/ldap.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libassuan.m4 \ + $(top_srcdir)/m4/libgcrypt.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/npth.m4 $(top_srcdir)/m4/ntbtls.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/readline.m4 \ + $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \ + $(top_srcdir)/m4/tar-ustar.m4 $(top_srcdir)/acinclude.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 = $(SHELL) $(top_srcdir)/build-aux/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" +PROGRAMS = $(bin_PROGRAMS) +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 = +libkeybox_a_AR = $(AR) $(ARFLAGS) +libkeybox_a_LIBADD = +am__objects_1 = libkeybox_a-keybox-util.$(OBJEXT) \ + libkeybox_a-keybox-init.$(OBJEXT) \ + libkeybox_a-keybox-blob.$(OBJEXT) \ + libkeybox_a-keybox-file.$(OBJEXT) \ + libkeybox_a-keybox-search.$(OBJEXT) \ + libkeybox_a-keybox-update.$(OBJEXT) \ + libkeybox_a-keybox-openpgp.$(OBJEXT) \ + libkeybox_a-keybox-dump.$(OBJEXT) +am_libkeybox_a_OBJECTS = $(am__objects_1) +libkeybox_a_OBJECTS = $(am_libkeybox_a_OBJECTS) +libkeybox509_a_AR = $(AR) $(ARFLAGS) +libkeybox509_a_LIBADD = +am__objects_2 = libkeybox509_a-keybox-util.$(OBJEXT) \ + libkeybox509_a-keybox-init.$(OBJEXT) \ + libkeybox509_a-keybox-blob.$(OBJEXT) \ + libkeybox509_a-keybox-file.$(OBJEXT) \ + libkeybox509_a-keybox-search.$(OBJEXT) \ + libkeybox509_a-keybox-update.$(OBJEXT) \ + libkeybox509_a-keybox-openpgp.$(OBJEXT) \ + libkeybox509_a-keybox-dump.$(OBJEXT) +am_libkeybox509_a_OBJECTS = $(am__objects_2) +libkeybox509_a_OBJECTS = $(am_libkeybox509_a_OBJECTS) +am__objects_3 = kbxutil-keybox-util.$(OBJEXT) \ + kbxutil-keybox-init.$(OBJEXT) kbxutil-keybox-blob.$(OBJEXT) \ + kbxutil-keybox-file.$(OBJEXT) kbxutil-keybox-search.$(OBJEXT) \ + kbxutil-keybox-update.$(OBJEXT) \ + kbxutil-keybox-openpgp.$(OBJEXT) kbxutil-keybox-dump.$(OBJEXT) +am_kbxutil_OBJECTS = kbxutil-kbxutil.$(OBJEXT) $(am__objects_3) +kbxutil_OBJECTS = $(am_kbxutil_OBJECTS) +am__DEPENDENCIES_1 = +@HAVE_W32CE_SYSTEM_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) +kbxutil_DEPENDENCIES = ../common/libcommon.a $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +kbxutil_LINK = $(CCLD) $(kbxutil_CFLAGS) $(CFLAGS) $(AM_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)/build-aux/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/kbxutil-kbxutil.Po \ + ./$(DEPDIR)/kbxutil-keybox-blob.Po \ + ./$(DEPDIR)/kbxutil-keybox-dump.Po \ + ./$(DEPDIR)/kbxutil-keybox-file.Po \ + ./$(DEPDIR)/kbxutil-keybox-init.Po \ + ./$(DEPDIR)/kbxutil-keybox-openpgp.Po \ + ./$(DEPDIR)/kbxutil-keybox-search.Po \ + ./$(DEPDIR)/kbxutil-keybox-update.Po \ + ./$(DEPDIR)/kbxutil-keybox-util.Po \ + ./$(DEPDIR)/libkeybox509_a-keybox-blob.Po \ + ./$(DEPDIR)/libkeybox509_a-keybox-dump.Po \ + ./$(DEPDIR)/libkeybox509_a-keybox-file.Po \ + ./$(DEPDIR)/libkeybox509_a-keybox-init.Po \ + ./$(DEPDIR)/libkeybox509_a-keybox-openpgp.Po \ + ./$(DEPDIR)/libkeybox509_a-keybox-search.Po \ + ./$(DEPDIR)/libkeybox509_a-keybox-update.Po \ + ./$(DEPDIR)/libkeybox509_a-keybox-util.Po \ + ./$(DEPDIR)/libkeybox_a-keybox-blob.Po \ + ./$(DEPDIR)/libkeybox_a-keybox-dump.Po \ + ./$(DEPDIR)/libkeybox_a-keybox-file.Po \ + ./$(DEPDIR)/libkeybox_a-keybox-init.Po \ + ./$(DEPDIR)/libkeybox_a-keybox-openpgp.Po \ + ./$(DEPDIR)/libkeybox_a-keybox-search.Po \ + ./$(DEPDIR)/libkeybox_a-keybox-update.Po \ + ./$(DEPDIR)/libkeybox_a-keybox-util.Po +am__mv = mv -f +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 = +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 = $(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 = $(libkeybox_a_SOURCES) $(libkeybox509_a_SOURCES) \ + $(kbxutil_SOURCES) +DIST_SOURCES = $(libkeybox_a_SOURCES) $(libkeybox509_a_SOURCES) \ + $(kbxutil_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/am/cmacros.am \ + $(top_srcdir)/build-aux/depcomp \ + $(top_srcdir)/build-aux/mkinstalldirs +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@ +AWK_HEX_NUMBER_OPTION = @AWK_HEX_NUMBER_OPTION@ +BUILD_FILEVERSION = @BUILD_FILEVERSION@ +BUILD_HOSTNAME = @BUILD_HOSTNAME@ +BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@ +BUILD_REVISION = @BUILD_REVISION@ +BUILD_TIMESTAMP = @BUILD_TIMESTAMP@ +BUILD_VERSION = @BUILD_VERSION@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CC_FOR_BUILD = @CC_FOR_BUILD@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DL_LIBS = @DL_LIBS@ +DNSLIBS = @DNSLIBS@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENCFS = @ENCFS@ +EXEEXT = @EXEEXT@ +FUSERMOUNT = @FUSERMOUNT@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUPG_AGENT_PGM = @GNUPG_AGENT_PGM@ +GNUPG_DIRMNGR_LDAP_PGM = @GNUPG_DIRMNGR_LDAP_PGM@ +GNUPG_DIRMNGR_PGM = @GNUPG_DIRMNGR_PGM@ +GNUPG_PINENTRY_PGM = @GNUPG_PINENTRY_PGM@ +GNUPG_PROTECT_TOOL_PGM = @GNUPG_PROTECT_TOOL_PGM@ +GNUPG_SCDAEMON_PGM = @GNUPG_SCDAEMON_PGM@ +GPGKEYS_LDAP = @GPGKEYS_LDAP@ +GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@ +GPG_ERROR_CONFIG = @GPG_ERROR_CONFIG@ +GPG_ERROR_LIBS = @GPG_ERROR_LIBS@ +GPG_ERROR_MT_CFLAGS = @GPG_ERROR_MT_CFLAGS@ +GPG_ERROR_MT_LIBS = @GPG_ERROR_MT_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +KSBA_CFLAGS = @KSBA_CFLAGS@ +KSBA_CONFIG = @KSBA_CONFIG@ +KSBA_LIBS = @KSBA_LIBS@ +LBER_LIBS = @LBER_LIBS@ +LDAPLIBS = @LDAPLIBS@ +LDAP_CPPFLAGS = @LDAP_CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBASSUAN_CFLAGS = @LIBASSUAN_CFLAGS@ +LIBASSUAN_CONFIG = @LIBASSUAN_CONFIG@ +LIBASSUAN_LIBS = @LIBASSUAN_LIBS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBGNUTLS_CFLAGS = @LIBGNUTLS_CFLAGS@ +LIBGNUTLS_LIBS = @LIBGNUTLS_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBOBJS = @LIBOBJS@ +LIBREADLINE = @LIBREADLINE@ +LIBS = @LIBS@ +LIBUSB_CPPFLAGS = @LIBUSB_CPPFLAGS@ +LIBUSB_LIBS = @LIBUSB_LIBS@ +LIBUTIL_LIBS = @LIBUTIL_LIBS@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NETLIBS = @NETLIBS@ +NPTH_CFLAGS = @NPTH_CFLAGS@ +NPTH_CONFIG = @NPTH_CONFIG@ +NPTH_LIBS = @NPTH_LIBS@ +NTBTLS_CFLAGS = @NTBTLS_CFLAGS@ +NTBTLS_CONFIG = @NTBTLS_CONFIG@ +NTBTLS_LIBS = @NTBTLS_LIBS@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_GT = @PACKAGE_GT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +SENDMAIL = @SENDMAIL@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SHRED = @SHRED@ +SQLITE3_CFLAGS = @SQLITE3_CFLAGS@ +SQLITE3_LIBS = @SQLITE3_LIBS@ +STRIP = @STRIP@ +SYSROOT = @SYSROOT@ +SYS_SOCKET_H = @SYS_SOCKET_H@ +TAR = @TAR@ +USE_C99_CFLAGS = @USE_C99_CFLAGS@ +USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +W32SOCKLIBS = @W32SOCKLIBS@ +WINDRES = @WINDRES@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +YAT2M = @YAT2M@ +ZLIBS = @ZLIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +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 = $(datadir)/locale +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_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +EXTRA_DIST = mkerrors + +# NB: AM_CFLAGS may also be used by tools running on the build +# platform to create source files. +AM_CPPFLAGS = -DLOCALEDIR=\"$(localedir)\" $(am__append_1) \ + $(am__append_2) $(am__append_3) $(am__append_4) \ + $(am__append_5) $(am__append_6) $(am__append_7) +@HAVE_W32CE_SYSTEM_FALSE@extra_sys_libs = + +# Under Windows we use LockFileEx. WindowsCE provides this only on +# the WindowsMobile 6 platform and thus we need to use the coredll6 +# import library. We also want to use a stacksize of 256k instead of +# the 2MB which is the default with cegcc. 256k is the largest stack +# we use with pth. +@HAVE_W32CE_SYSTEM_TRUE@extra_sys_libs = -lcoredll6 +@HAVE_W32CE_SYSTEM_FALSE@extra_bin_ldflags = +@HAVE_W32CE_SYSTEM_TRUE@extra_bin_ldflags = -Wl,--stack=0x40000 +resource_objs = + +# Convenience macros +libcommon = ../common/libcommon.a +libcommonpth = ../common/libcommonpth.a +libcommontls = ../common/libcommontls.a +libcommontlsnpth = ../common/libcommontlsnpth.a +AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(KSBA_CFLAGS) +noinst_LIBRARIES = libkeybox.a libkeybox509.a +@HAVE_W32CE_SYSTEM_FALSE@extra_libs = +@HAVE_W32CE_SYSTEM_TRUE@extra_libs = $(LIBASSUAN_LIBS) +common_sources = \ + keybox.h keybox-defs.h keybox-search-desc.h \ + keybox-util.c \ + keybox-init.c \ + keybox-blob.c \ + keybox-file.c \ + keybox-search.c \ + keybox-update.c \ + keybox-openpgp.c \ + keybox-dump.c + +libkeybox_a_SOURCES = $(common_sources) +libkeybox509_a_SOURCES = $(common_sources) +libkeybox_a_CFLAGS = $(AM_CFLAGS) +libkeybox509_a_CFLAGS = $(AM_CFLAGS) -DKEYBOX_WITH_X509=1 + +# We need W32SOCKLIBS because the init subsystem code in libcommon +# requires it - although we don't actually need it. It is easier +# to do it this way. +kbxutil_SOURCES = kbxutil.c $(common_sources) +kbxutil_CFLAGS = $(AM_CFLAGS) -DKEYBOX_WITH_X509=1 +kbxutil_LDADD = ../common/libcommon.a \ + $(KSBA_LIBS) $(LIBGCRYPT_LIBS) $(extra_libs) \ + $(GPG_ERROR_LIBS) $(LIBINTL) $(LIBICONV) $(W32SOCKLIBS) \ + $(NETLIBS) + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj .rc +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/am/cmacros.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 kbx/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu kbx/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; +$(top_srcdir)/am/cmacros.am $(am__empty): + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) + +libkeybox.a: $(libkeybox_a_OBJECTS) $(libkeybox_a_DEPENDENCIES) $(EXTRA_libkeybox_a_DEPENDENCIES) + $(AM_V_at)-rm -f libkeybox.a + $(AM_V_AR)$(libkeybox_a_AR) libkeybox.a $(libkeybox_a_OBJECTS) $(libkeybox_a_LIBADD) + $(AM_V_at)$(RANLIB) libkeybox.a + +libkeybox509.a: $(libkeybox509_a_OBJECTS) $(libkeybox509_a_DEPENDENCIES) $(EXTRA_libkeybox509_a_DEPENDENCIES) + $(AM_V_at)-rm -f libkeybox509.a + $(AM_V_AR)$(libkeybox509_a_AR) libkeybox509.a $(libkeybox509_a_OBJECTS) $(libkeybox509_a_LIBADD) + $(AM_V_at)$(RANLIB) libkeybox509.a + +kbxutil$(EXEEXT): $(kbxutil_OBJECTS) $(kbxutil_DEPENDENCIES) $(EXTRA_kbxutil_DEPENDENCIES) + @rm -f kbxutil$(EXEEXT) + $(AM_V_CCLD)$(kbxutil_LINK) $(kbxutil_OBJECTS) $(kbxutil_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kbxutil-kbxutil.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kbxutil-keybox-blob.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kbxutil-keybox-dump.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kbxutil-keybox-file.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kbxutil-keybox-init.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kbxutil-keybox-openpgp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kbxutil-keybox-search.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kbxutil-keybox-update.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kbxutil-keybox-util.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libkeybox509_a-keybox-blob.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libkeybox509_a-keybox-dump.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libkeybox509_a-keybox-file.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libkeybox509_a-keybox-init.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libkeybox509_a-keybox-openpgp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libkeybox509_a-keybox-search.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libkeybox509_a-keybox-update.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libkeybox509_a-keybox-util.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libkeybox_a-keybox-blob.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libkeybox_a-keybox-dump.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libkeybox_a-keybox-file.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libkeybox_a-keybox-init.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libkeybox_a-keybox-openpgp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libkeybox_a-keybox-search.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libkeybox_a-keybox-update.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libkeybox_a-keybox-util.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)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +libkeybox_a-keybox-util.o: keybox-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox_a_CFLAGS) $(CFLAGS) -MT libkeybox_a-keybox-util.o -MD -MP -MF $(DEPDIR)/libkeybox_a-keybox-util.Tpo -c -o libkeybox_a-keybox-util.o `test -f 'keybox-util.c' || echo '$(srcdir)/'`keybox-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeybox_a-keybox-util.Tpo $(DEPDIR)/libkeybox_a-keybox-util.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-util.c' object='libkeybox_a-keybox-util.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox_a_CFLAGS) $(CFLAGS) -c -o libkeybox_a-keybox-util.o `test -f 'keybox-util.c' || echo '$(srcdir)/'`keybox-util.c + +libkeybox_a-keybox-util.obj: keybox-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox_a_CFLAGS) $(CFLAGS) -MT libkeybox_a-keybox-util.obj -MD -MP -MF $(DEPDIR)/libkeybox_a-keybox-util.Tpo -c -o libkeybox_a-keybox-util.obj `if test -f 'keybox-util.c'; then $(CYGPATH_W) 'keybox-util.c'; else $(CYGPATH_W) '$(srcdir)/keybox-util.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeybox_a-keybox-util.Tpo $(DEPDIR)/libkeybox_a-keybox-util.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-util.c' object='libkeybox_a-keybox-util.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox_a_CFLAGS) $(CFLAGS) -c -o libkeybox_a-keybox-util.obj `if test -f 'keybox-util.c'; then $(CYGPATH_W) 'keybox-util.c'; else $(CYGPATH_W) '$(srcdir)/keybox-util.c'; fi` + +libkeybox_a-keybox-init.o: keybox-init.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox_a_CFLAGS) $(CFLAGS) -MT libkeybox_a-keybox-init.o -MD -MP -MF $(DEPDIR)/libkeybox_a-keybox-init.Tpo -c -o libkeybox_a-keybox-init.o `test -f 'keybox-init.c' || echo '$(srcdir)/'`keybox-init.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeybox_a-keybox-init.Tpo $(DEPDIR)/libkeybox_a-keybox-init.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-init.c' object='libkeybox_a-keybox-init.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox_a_CFLAGS) $(CFLAGS) -c -o libkeybox_a-keybox-init.o `test -f 'keybox-init.c' || echo '$(srcdir)/'`keybox-init.c + +libkeybox_a-keybox-init.obj: keybox-init.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox_a_CFLAGS) $(CFLAGS) -MT libkeybox_a-keybox-init.obj -MD -MP -MF $(DEPDIR)/libkeybox_a-keybox-init.Tpo -c -o libkeybox_a-keybox-init.obj `if test -f 'keybox-init.c'; then $(CYGPATH_W) 'keybox-init.c'; else $(CYGPATH_W) '$(srcdir)/keybox-init.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeybox_a-keybox-init.Tpo $(DEPDIR)/libkeybox_a-keybox-init.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-init.c' object='libkeybox_a-keybox-init.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox_a_CFLAGS) $(CFLAGS) -c -o libkeybox_a-keybox-init.obj `if test -f 'keybox-init.c'; then $(CYGPATH_W) 'keybox-init.c'; else $(CYGPATH_W) '$(srcdir)/keybox-init.c'; fi` + +libkeybox_a-keybox-blob.o: keybox-blob.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox_a_CFLAGS) $(CFLAGS) -MT libkeybox_a-keybox-blob.o -MD -MP -MF $(DEPDIR)/libkeybox_a-keybox-blob.Tpo -c -o libkeybox_a-keybox-blob.o `test -f 'keybox-blob.c' || echo '$(srcdir)/'`keybox-blob.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeybox_a-keybox-blob.Tpo $(DEPDIR)/libkeybox_a-keybox-blob.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-blob.c' object='libkeybox_a-keybox-blob.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox_a_CFLAGS) $(CFLAGS) -c -o libkeybox_a-keybox-blob.o `test -f 'keybox-blob.c' || echo '$(srcdir)/'`keybox-blob.c + +libkeybox_a-keybox-blob.obj: keybox-blob.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox_a_CFLAGS) $(CFLAGS) -MT libkeybox_a-keybox-blob.obj -MD -MP -MF $(DEPDIR)/libkeybox_a-keybox-blob.Tpo -c -o libkeybox_a-keybox-blob.obj `if test -f 'keybox-blob.c'; then $(CYGPATH_W) 'keybox-blob.c'; else $(CYGPATH_W) '$(srcdir)/keybox-blob.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeybox_a-keybox-blob.Tpo $(DEPDIR)/libkeybox_a-keybox-blob.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-blob.c' object='libkeybox_a-keybox-blob.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox_a_CFLAGS) $(CFLAGS) -c -o libkeybox_a-keybox-blob.obj `if test -f 'keybox-blob.c'; then $(CYGPATH_W) 'keybox-blob.c'; else $(CYGPATH_W) '$(srcdir)/keybox-blob.c'; fi` + +libkeybox_a-keybox-file.o: keybox-file.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox_a_CFLAGS) $(CFLAGS) -MT libkeybox_a-keybox-file.o -MD -MP -MF $(DEPDIR)/libkeybox_a-keybox-file.Tpo -c -o libkeybox_a-keybox-file.o `test -f 'keybox-file.c' || echo '$(srcdir)/'`keybox-file.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeybox_a-keybox-file.Tpo $(DEPDIR)/libkeybox_a-keybox-file.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-file.c' object='libkeybox_a-keybox-file.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox_a_CFLAGS) $(CFLAGS) -c -o libkeybox_a-keybox-file.o `test -f 'keybox-file.c' || echo '$(srcdir)/'`keybox-file.c + +libkeybox_a-keybox-file.obj: keybox-file.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox_a_CFLAGS) $(CFLAGS) -MT libkeybox_a-keybox-file.obj -MD -MP -MF $(DEPDIR)/libkeybox_a-keybox-file.Tpo -c -o libkeybox_a-keybox-file.obj `if test -f 'keybox-file.c'; then $(CYGPATH_W) 'keybox-file.c'; else $(CYGPATH_W) '$(srcdir)/keybox-file.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeybox_a-keybox-file.Tpo $(DEPDIR)/libkeybox_a-keybox-file.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-file.c' object='libkeybox_a-keybox-file.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox_a_CFLAGS) $(CFLAGS) -c -o libkeybox_a-keybox-file.obj `if test -f 'keybox-file.c'; then $(CYGPATH_W) 'keybox-file.c'; else $(CYGPATH_W) '$(srcdir)/keybox-file.c'; fi` + +libkeybox_a-keybox-search.o: keybox-search.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox_a_CFLAGS) $(CFLAGS) -MT libkeybox_a-keybox-search.o -MD -MP -MF $(DEPDIR)/libkeybox_a-keybox-search.Tpo -c -o libkeybox_a-keybox-search.o `test -f 'keybox-search.c' || echo '$(srcdir)/'`keybox-search.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeybox_a-keybox-search.Tpo $(DEPDIR)/libkeybox_a-keybox-search.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-search.c' object='libkeybox_a-keybox-search.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox_a_CFLAGS) $(CFLAGS) -c -o libkeybox_a-keybox-search.o `test -f 'keybox-search.c' || echo '$(srcdir)/'`keybox-search.c + +libkeybox_a-keybox-search.obj: keybox-search.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox_a_CFLAGS) $(CFLAGS) -MT libkeybox_a-keybox-search.obj -MD -MP -MF $(DEPDIR)/libkeybox_a-keybox-search.Tpo -c -o libkeybox_a-keybox-search.obj `if test -f 'keybox-search.c'; then $(CYGPATH_W) 'keybox-search.c'; else $(CYGPATH_W) '$(srcdir)/keybox-search.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeybox_a-keybox-search.Tpo $(DEPDIR)/libkeybox_a-keybox-search.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-search.c' object='libkeybox_a-keybox-search.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox_a_CFLAGS) $(CFLAGS) -c -o libkeybox_a-keybox-search.obj `if test -f 'keybox-search.c'; then $(CYGPATH_W) 'keybox-search.c'; else $(CYGPATH_W) '$(srcdir)/keybox-search.c'; fi` + +libkeybox_a-keybox-update.o: keybox-update.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox_a_CFLAGS) $(CFLAGS) -MT libkeybox_a-keybox-update.o -MD -MP -MF $(DEPDIR)/libkeybox_a-keybox-update.Tpo -c -o libkeybox_a-keybox-update.o `test -f 'keybox-update.c' || echo '$(srcdir)/'`keybox-update.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeybox_a-keybox-update.Tpo $(DEPDIR)/libkeybox_a-keybox-update.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-update.c' object='libkeybox_a-keybox-update.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox_a_CFLAGS) $(CFLAGS) -c -o libkeybox_a-keybox-update.o `test -f 'keybox-update.c' || echo '$(srcdir)/'`keybox-update.c + +libkeybox_a-keybox-update.obj: keybox-update.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox_a_CFLAGS) $(CFLAGS) -MT libkeybox_a-keybox-update.obj -MD -MP -MF $(DEPDIR)/libkeybox_a-keybox-update.Tpo -c -o libkeybox_a-keybox-update.obj `if test -f 'keybox-update.c'; then $(CYGPATH_W) 'keybox-update.c'; else $(CYGPATH_W) '$(srcdir)/keybox-update.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeybox_a-keybox-update.Tpo $(DEPDIR)/libkeybox_a-keybox-update.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-update.c' object='libkeybox_a-keybox-update.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox_a_CFLAGS) $(CFLAGS) -c -o libkeybox_a-keybox-update.obj `if test -f 'keybox-update.c'; then $(CYGPATH_W) 'keybox-update.c'; else $(CYGPATH_W) '$(srcdir)/keybox-update.c'; fi` + +libkeybox_a-keybox-openpgp.o: keybox-openpgp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox_a_CFLAGS) $(CFLAGS) -MT libkeybox_a-keybox-openpgp.o -MD -MP -MF $(DEPDIR)/libkeybox_a-keybox-openpgp.Tpo -c -o libkeybox_a-keybox-openpgp.o `test -f 'keybox-openpgp.c' || echo '$(srcdir)/'`keybox-openpgp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeybox_a-keybox-openpgp.Tpo $(DEPDIR)/libkeybox_a-keybox-openpgp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-openpgp.c' object='libkeybox_a-keybox-openpgp.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox_a_CFLAGS) $(CFLAGS) -c -o libkeybox_a-keybox-openpgp.o `test -f 'keybox-openpgp.c' || echo '$(srcdir)/'`keybox-openpgp.c + +libkeybox_a-keybox-openpgp.obj: keybox-openpgp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox_a_CFLAGS) $(CFLAGS) -MT libkeybox_a-keybox-openpgp.obj -MD -MP -MF $(DEPDIR)/libkeybox_a-keybox-openpgp.Tpo -c -o libkeybox_a-keybox-openpgp.obj `if test -f 'keybox-openpgp.c'; then $(CYGPATH_W) 'keybox-openpgp.c'; else $(CYGPATH_W) '$(srcdir)/keybox-openpgp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeybox_a-keybox-openpgp.Tpo $(DEPDIR)/libkeybox_a-keybox-openpgp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-openpgp.c' object='libkeybox_a-keybox-openpgp.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox_a_CFLAGS) $(CFLAGS) -c -o libkeybox_a-keybox-openpgp.obj `if test -f 'keybox-openpgp.c'; then $(CYGPATH_W) 'keybox-openpgp.c'; else $(CYGPATH_W) '$(srcdir)/keybox-openpgp.c'; fi` + +libkeybox_a-keybox-dump.o: keybox-dump.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox_a_CFLAGS) $(CFLAGS) -MT libkeybox_a-keybox-dump.o -MD -MP -MF $(DEPDIR)/libkeybox_a-keybox-dump.Tpo -c -o libkeybox_a-keybox-dump.o `test -f 'keybox-dump.c' || echo '$(srcdir)/'`keybox-dump.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeybox_a-keybox-dump.Tpo $(DEPDIR)/libkeybox_a-keybox-dump.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-dump.c' object='libkeybox_a-keybox-dump.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox_a_CFLAGS) $(CFLAGS) -c -o libkeybox_a-keybox-dump.o `test -f 'keybox-dump.c' || echo '$(srcdir)/'`keybox-dump.c + +libkeybox_a-keybox-dump.obj: keybox-dump.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox_a_CFLAGS) $(CFLAGS) -MT libkeybox_a-keybox-dump.obj -MD -MP -MF $(DEPDIR)/libkeybox_a-keybox-dump.Tpo -c -o libkeybox_a-keybox-dump.obj `if test -f 'keybox-dump.c'; then $(CYGPATH_W) 'keybox-dump.c'; else $(CYGPATH_W) '$(srcdir)/keybox-dump.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeybox_a-keybox-dump.Tpo $(DEPDIR)/libkeybox_a-keybox-dump.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-dump.c' object='libkeybox_a-keybox-dump.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox_a_CFLAGS) $(CFLAGS) -c -o libkeybox_a-keybox-dump.obj `if test -f 'keybox-dump.c'; then $(CYGPATH_W) 'keybox-dump.c'; else $(CYGPATH_W) '$(srcdir)/keybox-dump.c'; fi` + +libkeybox509_a-keybox-util.o: keybox-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox509_a_CFLAGS) $(CFLAGS) -MT libkeybox509_a-keybox-util.o -MD -MP -MF $(DEPDIR)/libkeybox509_a-keybox-util.Tpo -c -o libkeybox509_a-keybox-util.o `test -f 'keybox-util.c' || echo '$(srcdir)/'`keybox-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeybox509_a-keybox-util.Tpo $(DEPDIR)/libkeybox509_a-keybox-util.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-util.c' object='libkeybox509_a-keybox-util.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox509_a_CFLAGS) $(CFLAGS) -c -o libkeybox509_a-keybox-util.o `test -f 'keybox-util.c' || echo '$(srcdir)/'`keybox-util.c + +libkeybox509_a-keybox-util.obj: keybox-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox509_a_CFLAGS) $(CFLAGS) -MT libkeybox509_a-keybox-util.obj -MD -MP -MF $(DEPDIR)/libkeybox509_a-keybox-util.Tpo -c -o libkeybox509_a-keybox-util.obj `if test -f 'keybox-util.c'; then $(CYGPATH_W) 'keybox-util.c'; else $(CYGPATH_W) '$(srcdir)/keybox-util.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeybox509_a-keybox-util.Tpo $(DEPDIR)/libkeybox509_a-keybox-util.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-util.c' object='libkeybox509_a-keybox-util.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox509_a_CFLAGS) $(CFLAGS) -c -o libkeybox509_a-keybox-util.obj `if test -f 'keybox-util.c'; then $(CYGPATH_W) 'keybox-util.c'; else $(CYGPATH_W) '$(srcdir)/keybox-util.c'; fi` + +libkeybox509_a-keybox-init.o: keybox-init.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox509_a_CFLAGS) $(CFLAGS) -MT libkeybox509_a-keybox-init.o -MD -MP -MF $(DEPDIR)/libkeybox509_a-keybox-init.Tpo -c -o libkeybox509_a-keybox-init.o `test -f 'keybox-init.c' || echo '$(srcdir)/'`keybox-init.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeybox509_a-keybox-init.Tpo $(DEPDIR)/libkeybox509_a-keybox-init.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-init.c' object='libkeybox509_a-keybox-init.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox509_a_CFLAGS) $(CFLAGS) -c -o libkeybox509_a-keybox-init.o `test -f 'keybox-init.c' || echo '$(srcdir)/'`keybox-init.c + +libkeybox509_a-keybox-init.obj: keybox-init.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox509_a_CFLAGS) $(CFLAGS) -MT libkeybox509_a-keybox-init.obj -MD -MP -MF $(DEPDIR)/libkeybox509_a-keybox-init.Tpo -c -o libkeybox509_a-keybox-init.obj `if test -f 'keybox-init.c'; then $(CYGPATH_W) 'keybox-init.c'; else $(CYGPATH_W) '$(srcdir)/keybox-init.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeybox509_a-keybox-init.Tpo $(DEPDIR)/libkeybox509_a-keybox-init.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-init.c' object='libkeybox509_a-keybox-init.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox509_a_CFLAGS) $(CFLAGS) -c -o libkeybox509_a-keybox-init.obj `if test -f 'keybox-init.c'; then $(CYGPATH_W) 'keybox-init.c'; else $(CYGPATH_W) '$(srcdir)/keybox-init.c'; fi` + +libkeybox509_a-keybox-blob.o: keybox-blob.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox509_a_CFLAGS) $(CFLAGS) -MT libkeybox509_a-keybox-blob.o -MD -MP -MF $(DEPDIR)/libkeybox509_a-keybox-blob.Tpo -c -o libkeybox509_a-keybox-blob.o `test -f 'keybox-blob.c' || echo '$(srcdir)/'`keybox-blob.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeybox509_a-keybox-blob.Tpo $(DEPDIR)/libkeybox509_a-keybox-blob.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-blob.c' object='libkeybox509_a-keybox-blob.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox509_a_CFLAGS) $(CFLAGS) -c -o libkeybox509_a-keybox-blob.o `test -f 'keybox-blob.c' || echo '$(srcdir)/'`keybox-blob.c + +libkeybox509_a-keybox-blob.obj: keybox-blob.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox509_a_CFLAGS) $(CFLAGS) -MT libkeybox509_a-keybox-blob.obj -MD -MP -MF $(DEPDIR)/libkeybox509_a-keybox-blob.Tpo -c -o libkeybox509_a-keybox-blob.obj `if test -f 'keybox-blob.c'; then $(CYGPATH_W) 'keybox-blob.c'; else $(CYGPATH_W) '$(srcdir)/keybox-blob.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeybox509_a-keybox-blob.Tpo $(DEPDIR)/libkeybox509_a-keybox-blob.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-blob.c' object='libkeybox509_a-keybox-blob.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox509_a_CFLAGS) $(CFLAGS) -c -o libkeybox509_a-keybox-blob.obj `if test -f 'keybox-blob.c'; then $(CYGPATH_W) 'keybox-blob.c'; else $(CYGPATH_W) '$(srcdir)/keybox-blob.c'; fi` + +libkeybox509_a-keybox-file.o: keybox-file.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox509_a_CFLAGS) $(CFLAGS) -MT libkeybox509_a-keybox-file.o -MD -MP -MF $(DEPDIR)/libkeybox509_a-keybox-file.Tpo -c -o libkeybox509_a-keybox-file.o `test -f 'keybox-file.c' || echo '$(srcdir)/'`keybox-file.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeybox509_a-keybox-file.Tpo $(DEPDIR)/libkeybox509_a-keybox-file.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-file.c' object='libkeybox509_a-keybox-file.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox509_a_CFLAGS) $(CFLAGS) -c -o libkeybox509_a-keybox-file.o `test -f 'keybox-file.c' || echo '$(srcdir)/'`keybox-file.c + +libkeybox509_a-keybox-file.obj: keybox-file.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox509_a_CFLAGS) $(CFLAGS) -MT libkeybox509_a-keybox-file.obj -MD -MP -MF $(DEPDIR)/libkeybox509_a-keybox-file.Tpo -c -o libkeybox509_a-keybox-file.obj `if test -f 'keybox-file.c'; then $(CYGPATH_W) 'keybox-file.c'; else $(CYGPATH_W) '$(srcdir)/keybox-file.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeybox509_a-keybox-file.Tpo $(DEPDIR)/libkeybox509_a-keybox-file.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-file.c' object='libkeybox509_a-keybox-file.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox509_a_CFLAGS) $(CFLAGS) -c -o libkeybox509_a-keybox-file.obj `if test -f 'keybox-file.c'; then $(CYGPATH_W) 'keybox-file.c'; else $(CYGPATH_W) '$(srcdir)/keybox-file.c'; fi` + +libkeybox509_a-keybox-search.o: keybox-search.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox509_a_CFLAGS) $(CFLAGS) -MT libkeybox509_a-keybox-search.o -MD -MP -MF $(DEPDIR)/libkeybox509_a-keybox-search.Tpo -c -o libkeybox509_a-keybox-search.o `test -f 'keybox-search.c' || echo '$(srcdir)/'`keybox-search.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeybox509_a-keybox-search.Tpo $(DEPDIR)/libkeybox509_a-keybox-search.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-search.c' object='libkeybox509_a-keybox-search.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox509_a_CFLAGS) $(CFLAGS) -c -o libkeybox509_a-keybox-search.o `test -f 'keybox-search.c' || echo '$(srcdir)/'`keybox-search.c + +libkeybox509_a-keybox-search.obj: keybox-search.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox509_a_CFLAGS) $(CFLAGS) -MT libkeybox509_a-keybox-search.obj -MD -MP -MF $(DEPDIR)/libkeybox509_a-keybox-search.Tpo -c -o libkeybox509_a-keybox-search.obj `if test -f 'keybox-search.c'; then $(CYGPATH_W) 'keybox-search.c'; else $(CYGPATH_W) '$(srcdir)/keybox-search.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeybox509_a-keybox-search.Tpo $(DEPDIR)/libkeybox509_a-keybox-search.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-search.c' object='libkeybox509_a-keybox-search.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox509_a_CFLAGS) $(CFLAGS) -c -o libkeybox509_a-keybox-search.obj `if test -f 'keybox-search.c'; then $(CYGPATH_W) 'keybox-search.c'; else $(CYGPATH_W) '$(srcdir)/keybox-search.c'; fi` + +libkeybox509_a-keybox-update.o: keybox-update.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox509_a_CFLAGS) $(CFLAGS) -MT libkeybox509_a-keybox-update.o -MD -MP -MF $(DEPDIR)/libkeybox509_a-keybox-update.Tpo -c -o libkeybox509_a-keybox-update.o `test -f 'keybox-update.c' || echo '$(srcdir)/'`keybox-update.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeybox509_a-keybox-update.Tpo $(DEPDIR)/libkeybox509_a-keybox-update.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-update.c' object='libkeybox509_a-keybox-update.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox509_a_CFLAGS) $(CFLAGS) -c -o libkeybox509_a-keybox-update.o `test -f 'keybox-update.c' || echo '$(srcdir)/'`keybox-update.c + +libkeybox509_a-keybox-update.obj: keybox-update.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox509_a_CFLAGS) $(CFLAGS) -MT libkeybox509_a-keybox-update.obj -MD -MP -MF $(DEPDIR)/libkeybox509_a-keybox-update.Tpo -c -o libkeybox509_a-keybox-update.obj `if test -f 'keybox-update.c'; then $(CYGPATH_W) 'keybox-update.c'; else $(CYGPATH_W) '$(srcdir)/keybox-update.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeybox509_a-keybox-update.Tpo $(DEPDIR)/libkeybox509_a-keybox-update.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-update.c' object='libkeybox509_a-keybox-update.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox509_a_CFLAGS) $(CFLAGS) -c -o libkeybox509_a-keybox-update.obj `if test -f 'keybox-update.c'; then $(CYGPATH_W) 'keybox-update.c'; else $(CYGPATH_W) '$(srcdir)/keybox-update.c'; fi` + +libkeybox509_a-keybox-openpgp.o: keybox-openpgp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox509_a_CFLAGS) $(CFLAGS) -MT libkeybox509_a-keybox-openpgp.o -MD -MP -MF $(DEPDIR)/libkeybox509_a-keybox-openpgp.Tpo -c -o libkeybox509_a-keybox-openpgp.o `test -f 'keybox-openpgp.c' || echo '$(srcdir)/'`keybox-openpgp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeybox509_a-keybox-openpgp.Tpo $(DEPDIR)/libkeybox509_a-keybox-openpgp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-openpgp.c' object='libkeybox509_a-keybox-openpgp.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox509_a_CFLAGS) $(CFLAGS) -c -o libkeybox509_a-keybox-openpgp.o `test -f 'keybox-openpgp.c' || echo '$(srcdir)/'`keybox-openpgp.c + +libkeybox509_a-keybox-openpgp.obj: keybox-openpgp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox509_a_CFLAGS) $(CFLAGS) -MT libkeybox509_a-keybox-openpgp.obj -MD -MP -MF $(DEPDIR)/libkeybox509_a-keybox-openpgp.Tpo -c -o libkeybox509_a-keybox-openpgp.obj `if test -f 'keybox-openpgp.c'; then $(CYGPATH_W) 'keybox-openpgp.c'; else $(CYGPATH_W) '$(srcdir)/keybox-openpgp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeybox509_a-keybox-openpgp.Tpo $(DEPDIR)/libkeybox509_a-keybox-openpgp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-openpgp.c' object='libkeybox509_a-keybox-openpgp.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox509_a_CFLAGS) $(CFLAGS) -c -o libkeybox509_a-keybox-openpgp.obj `if test -f 'keybox-openpgp.c'; then $(CYGPATH_W) 'keybox-openpgp.c'; else $(CYGPATH_W) '$(srcdir)/keybox-openpgp.c'; fi` + +libkeybox509_a-keybox-dump.o: keybox-dump.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox509_a_CFLAGS) $(CFLAGS) -MT libkeybox509_a-keybox-dump.o -MD -MP -MF $(DEPDIR)/libkeybox509_a-keybox-dump.Tpo -c -o libkeybox509_a-keybox-dump.o `test -f 'keybox-dump.c' || echo '$(srcdir)/'`keybox-dump.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeybox509_a-keybox-dump.Tpo $(DEPDIR)/libkeybox509_a-keybox-dump.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-dump.c' object='libkeybox509_a-keybox-dump.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox509_a_CFLAGS) $(CFLAGS) -c -o libkeybox509_a-keybox-dump.o `test -f 'keybox-dump.c' || echo '$(srcdir)/'`keybox-dump.c + +libkeybox509_a-keybox-dump.obj: keybox-dump.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox509_a_CFLAGS) $(CFLAGS) -MT libkeybox509_a-keybox-dump.obj -MD -MP -MF $(DEPDIR)/libkeybox509_a-keybox-dump.Tpo -c -o libkeybox509_a-keybox-dump.obj `if test -f 'keybox-dump.c'; then $(CYGPATH_W) 'keybox-dump.c'; else $(CYGPATH_W) '$(srcdir)/keybox-dump.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeybox509_a-keybox-dump.Tpo $(DEPDIR)/libkeybox509_a-keybox-dump.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-dump.c' object='libkeybox509_a-keybox-dump.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libkeybox509_a_CFLAGS) $(CFLAGS) -c -o libkeybox509_a-keybox-dump.obj `if test -f 'keybox-dump.c'; then $(CYGPATH_W) 'keybox-dump.c'; else $(CYGPATH_W) '$(srcdir)/keybox-dump.c'; fi` + +kbxutil-kbxutil.o: kbxutil.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kbxutil_CFLAGS) $(CFLAGS) -MT kbxutil-kbxutil.o -MD -MP -MF $(DEPDIR)/kbxutil-kbxutil.Tpo -c -o kbxutil-kbxutil.o `test -f 'kbxutil.c' || echo '$(srcdir)/'`kbxutil.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/kbxutil-kbxutil.Tpo $(DEPDIR)/kbxutil-kbxutil.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='kbxutil.c' object='kbxutil-kbxutil.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(kbxutil_CFLAGS) $(CFLAGS) -c -o kbxutil-kbxutil.o `test -f 'kbxutil.c' || echo '$(srcdir)/'`kbxutil.c + +kbxutil-kbxutil.obj: kbxutil.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kbxutil_CFLAGS) $(CFLAGS) -MT kbxutil-kbxutil.obj -MD -MP -MF $(DEPDIR)/kbxutil-kbxutil.Tpo -c -o kbxutil-kbxutil.obj `if test -f 'kbxutil.c'; then $(CYGPATH_W) 'kbxutil.c'; else $(CYGPATH_W) '$(srcdir)/kbxutil.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/kbxutil-kbxutil.Tpo $(DEPDIR)/kbxutil-kbxutil.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='kbxutil.c' object='kbxutil-kbxutil.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(kbxutil_CFLAGS) $(CFLAGS) -c -o kbxutil-kbxutil.obj `if test -f 'kbxutil.c'; then $(CYGPATH_W) 'kbxutil.c'; else $(CYGPATH_W) '$(srcdir)/kbxutil.c'; fi` + +kbxutil-keybox-util.o: keybox-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kbxutil_CFLAGS) $(CFLAGS) -MT kbxutil-keybox-util.o -MD -MP -MF $(DEPDIR)/kbxutil-keybox-util.Tpo -c -o kbxutil-keybox-util.o `test -f 'keybox-util.c' || echo '$(srcdir)/'`keybox-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/kbxutil-keybox-util.Tpo $(DEPDIR)/kbxutil-keybox-util.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-util.c' object='kbxutil-keybox-util.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(kbxutil_CFLAGS) $(CFLAGS) -c -o kbxutil-keybox-util.o `test -f 'keybox-util.c' || echo '$(srcdir)/'`keybox-util.c + +kbxutil-keybox-util.obj: keybox-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kbxutil_CFLAGS) $(CFLAGS) -MT kbxutil-keybox-util.obj -MD -MP -MF $(DEPDIR)/kbxutil-keybox-util.Tpo -c -o kbxutil-keybox-util.obj `if test -f 'keybox-util.c'; then $(CYGPATH_W) 'keybox-util.c'; else $(CYGPATH_W) '$(srcdir)/keybox-util.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/kbxutil-keybox-util.Tpo $(DEPDIR)/kbxutil-keybox-util.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-util.c' object='kbxutil-keybox-util.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(kbxutil_CFLAGS) $(CFLAGS) -c -o kbxutil-keybox-util.obj `if test -f 'keybox-util.c'; then $(CYGPATH_W) 'keybox-util.c'; else $(CYGPATH_W) '$(srcdir)/keybox-util.c'; fi` + +kbxutil-keybox-init.o: keybox-init.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kbxutil_CFLAGS) $(CFLAGS) -MT kbxutil-keybox-init.o -MD -MP -MF $(DEPDIR)/kbxutil-keybox-init.Tpo -c -o kbxutil-keybox-init.o `test -f 'keybox-init.c' || echo '$(srcdir)/'`keybox-init.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/kbxutil-keybox-init.Tpo $(DEPDIR)/kbxutil-keybox-init.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-init.c' object='kbxutil-keybox-init.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(kbxutil_CFLAGS) $(CFLAGS) -c -o kbxutil-keybox-init.o `test -f 'keybox-init.c' || echo '$(srcdir)/'`keybox-init.c + +kbxutil-keybox-init.obj: keybox-init.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kbxutil_CFLAGS) $(CFLAGS) -MT kbxutil-keybox-init.obj -MD -MP -MF $(DEPDIR)/kbxutil-keybox-init.Tpo -c -o kbxutil-keybox-init.obj `if test -f 'keybox-init.c'; then $(CYGPATH_W) 'keybox-init.c'; else $(CYGPATH_W) '$(srcdir)/keybox-init.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/kbxutil-keybox-init.Tpo $(DEPDIR)/kbxutil-keybox-init.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-init.c' object='kbxutil-keybox-init.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(kbxutil_CFLAGS) $(CFLAGS) -c -o kbxutil-keybox-init.obj `if test -f 'keybox-init.c'; then $(CYGPATH_W) 'keybox-init.c'; else $(CYGPATH_W) '$(srcdir)/keybox-init.c'; fi` + +kbxutil-keybox-blob.o: keybox-blob.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kbxutil_CFLAGS) $(CFLAGS) -MT kbxutil-keybox-blob.o -MD -MP -MF $(DEPDIR)/kbxutil-keybox-blob.Tpo -c -o kbxutil-keybox-blob.o `test -f 'keybox-blob.c' || echo '$(srcdir)/'`keybox-blob.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/kbxutil-keybox-blob.Tpo $(DEPDIR)/kbxutil-keybox-blob.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-blob.c' object='kbxutil-keybox-blob.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(kbxutil_CFLAGS) $(CFLAGS) -c -o kbxutil-keybox-blob.o `test -f 'keybox-blob.c' || echo '$(srcdir)/'`keybox-blob.c + +kbxutil-keybox-blob.obj: keybox-blob.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kbxutil_CFLAGS) $(CFLAGS) -MT kbxutil-keybox-blob.obj -MD -MP -MF $(DEPDIR)/kbxutil-keybox-blob.Tpo -c -o kbxutil-keybox-blob.obj `if test -f 'keybox-blob.c'; then $(CYGPATH_W) 'keybox-blob.c'; else $(CYGPATH_W) '$(srcdir)/keybox-blob.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/kbxutil-keybox-blob.Tpo $(DEPDIR)/kbxutil-keybox-blob.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-blob.c' object='kbxutil-keybox-blob.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(kbxutil_CFLAGS) $(CFLAGS) -c -o kbxutil-keybox-blob.obj `if test -f 'keybox-blob.c'; then $(CYGPATH_W) 'keybox-blob.c'; else $(CYGPATH_W) '$(srcdir)/keybox-blob.c'; fi` + +kbxutil-keybox-file.o: keybox-file.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kbxutil_CFLAGS) $(CFLAGS) -MT kbxutil-keybox-file.o -MD -MP -MF $(DEPDIR)/kbxutil-keybox-file.Tpo -c -o kbxutil-keybox-file.o `test -f 'keybox-file.c' || echo '$(srcdir)/'`keybox-file.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/kbxutil-keybox-file.Tpo $(DEPDIR)/kbxutil-keybox-file.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-file.c' object='kbxutil-keybox-file.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(kbxutil_CFLAGS) $(CFLAGS) -c -o kbxutil-keybox-file.o `test -f 'keybox-file.c' || echo '$(srcdir)/'`keybox-file.c + +kbxutil-keybox-file.obj: keybox-file.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kbxutil_CFLAGS) $(CFLAGS) -MT kbxutil-keybox-file.obj -MD -MP -MF $(DEPDIR)/kbxutil-keybox-file.Tpo -c -o kbxutil-keybox-file.obj `if test -f 'keybox-file.c'; then $(CYGPATH_W) 'keybox-file.c'; else $(CYGPATH_W) '$(srcdir)/keybox-file.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/kbxutil-keybox-file.Tpo $(DEPDIR)/kbxutil-keybox-file.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-file.c' object='kbxutil-keybox-file.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(kbxutil_CFLAGS) $(CFLAGS) -c -o kbxutil-keybox-file.obj `if test -f 'keybox-file.c'; then $(CYGPATH_W) 'keybox-file.c'; else $(CYGPATH_W) '$(srcdir)/keybox-file.c'; fi` + +kbxutil-keybox-search.o: keybox-search.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kbxutil_CFLAGS) $(CFLAGS) -MT kbxutil-keybox-search.o -MD -MP -MF $(DEPDIR)/kbxutil-keybox-search.Tpo -c -o kbxutil-keybox-search.o `test -f 'keybox-search.c' || echo '$(srcdir)/'`keybox-search.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/kbxutil-keybox-search.Tpo $(DEPDIR)/kbxutil-keybox-search.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-search.c' object='kbxutil-keybox-search.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(kbxutil_CFLAGS) $(CFLAGS) -c -o kbxutil-keybox-search.o `test -f 'keybox-search.c' || echo '$(srcdir)/'`keybox-search.c + +kbxutil-keybox-search.obj: keybox-search.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kbxutil_CFLAGS) $(CFLAGS) -MT kbxutil-keybox-search.obj -MD -MP -MF $(DEPDIR)/kbxutil-keybox-search.Tpo -c -o kbxutil-keybox-search.obj `if test -f 'keybox-search.c'; then $(CYGPATH_W) 'keybox-search.c'; else $(CYGPATH_W) '$(srcdir)/keybox-search.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/kbxutil-keybox-search.Tpo $(DEPDIR)/kbxutil-keybox-search.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-search.c' object='kbxutil-keybox-search.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(kbxutil_CFLAGS) $(CFLAGS) -c -o kbxutil-keybox-search.obj `if test -f 'keybox-search.c'; then $(CYGPATH_W) 'keybox-search.c'; else $(CYGPATH_W) '$(srcdir)/keybox-search.c'; fi` + +kbxutil-keybox-update.o: keybox-update.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kbxutil_CFLAGS) $(CFLAGS) -MT kbxutil-keybox-update.o -MD -MP -MF $(DEPDIR)/kbxutil-keybox-update.Tpo -c -o kbxutil-keybox-update.o `test -f 'keybox-update.c' || echo '$(srcdir)/'`keybox-update.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/kbxutil-keybox-update.Tpo $(DEPDIR)/kbxutil-keybox-update.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-update.c' object='kbxutil-keybox-update.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(kbxutil_CFLAGS) $(CFLAGS) -c -o kbxutil-keybox-update.o `test -f 'keybox-update.c' || echo '$(srcdir)/'`keybox-update.c + +kbxutil-keybox-update.obj: keybox-update.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kbxutil_CFLAGS) $(CFLAGS) -MT kbxutil-keybox-update.obj -MD -MP -MF $(DEPDIR)/kbxutil-keybox-update.Tpo -c -o kbxutil-keybox-update.obj `if test -f 'keybox-update.c'; then $(CYGPATH_W) 'keybox-update.c'; else $(CYGPATH_W) '$(srcdir)/keybox-update.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/kbxutil-keybox-update.Tpo $(DEPDIR)/kbxutil-keybox-update.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-update.c' object='kbxutil-keybox-update.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(kbxutil_CFLAGS) $(CFLAGS) -c -o kbxutil-keybox-update.obj `if test -f 'keybox-update.c'; then $(CYGPATH_W) 'keybox-update.c'; else $(CYGPATH_W) '$(srcdir)/keybox-update.c'; fi` + +kbxutil-keybox-openpgp.o: keybox-openpgp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kbxutil_CFLAGS) $(CFLAGS) -MT kbxutil-keybox-openpgp.o -MD -MP -MF $(DEPDIR)/kbxutil-keybox-openpgp.Tpo -c -o kbxutil-keybox-openpgp.o `test -f 'keybox-openpgp.c' || echo '$(srcdir)/'`keybox-openpgp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/kbxutil-keybox-openpgp.Tpo $(DEPDIR)/kbxutil-keybox-openpgp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-openpgp.c' object='kbxutil-keybox-openpgp.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(kbxutil_CFLAGS) $(CFLAGS) -c -o kbxutil-keybox-openpgp.o `test -f 'keybox-openpgp.c' || echo '$(srcdir)/'`keybox-openpgp.c + +kbxutil-keybox-openpgp.obj: keybox-openpgp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kbxutil_CFLAGS) $(CFLAGS) -MT kbxutil-keybox-openpgp.obj -MD -MP -MF $(DEPDIR)/kbxutil-keybox-openpgp.Tpo -c -o kbxutil-keybox-openpgp.obj `if test -f 'keybox-openpgp.c'; then $(CYGPATH_W) 'keybox-openpgp.c'; else $(CYGPATH_W) '$(srcdir)/keybox-openpgp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/kbxutil-keybox-openpgp.Tpo $(DEPDIR)/kbxutil-keybox-openpgp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-openpgp.c' object='kbxutil-keybox-openpgp.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(kbxutil_CFLAGS) $(CFLAGS) -c -o kbxutil-keybox-openpgp.obj `if test -f 'keybox-openpgp.c'; then $(CYGPATH_W) 'keybox-openpgp.c'; else $(CYGPATH_W) '$(srcdir)/keybox-openpgp.c'; fi` + +kbxutil-keybox-dump.o: keybox-dump.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kbxutil_CFLAGS) $(CFLAGS) -MT kbxutil-keybox-dump.o -MD -MP -MF $(DEPDIR)/kbxutil-keybox-dump.Tpo -c -o kbxutil-keybox-dump.o `test -f 'keybox-dump.c' || echo '$(srcdir)/'`keybox-dump.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/kbxutil-keybox-dump.Tpo $(DEPDIR)/kbxutil-keybox-dump.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-dump.c' object='kbxutil-keybox-dump.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(kbxutil_CFLAGS) $(CFLAGS) -c -o kbxutil-keybox-dump.o `test -f 'keybox-dump.c' || echo '$(srcdir)/'`keybox-dump.c + +kbxutil-keybox-dump.obj: keybox-dump.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kbxutil_CFLAGS) $(CFLAGS) -MT kbxutil-keybox-dump.obj -MD -MP -MF $(DEPDIR)/kbxutil-keybox-dump.Tpo -c -o kbxutil-keybox-dump.obj `if test -f 'keybox-dump.c'; then $(CYGPATH_W) 'keybox-dump.c'; else $(CYGPATH_W) '$(srcdir)/keybox-dump.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/kbxutil-keybox-dump.Tpo $(DEPDIR)/kbxutil-keybox-dump.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keybox-dump.c' object='kbxutil-keybox-dump.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) $(AM_CPPFLAGS) $(CPPFLAGS) $(kbxutil_CFLAGS) $(CFLAGS) -c -o kbxutil-keybox-dump.obj `if test -f 'keybox-dump.c'; then $(CYGPATH_W) 'keybox-dump.c'; else $(CYGPATH_W) '$(srcdir)/keybox-dump.c'; fi` + +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) $(LIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(bindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + 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-binPROGRAMS clean-generic clean-noinstLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/kbxutil-kbxutil.Po + -rm -f ./$(DEPDIR)/kbxutil-keybox-blob.Po + -rm -f ./$(DEPDIR)/kbxutil-keybox-dump.Po + -rm -f ./$(DEPDIR)/kbxutil-keybox-file.Po + -rm -f ./$(DEPDIR)/kbxutil-keybox-init.Po + -rm -f ./$(DEPDIR)/kbxutil-keybox-openpgp.Po + -rm -f ./$(DEPDIR)/kbxutil-keybox-search.Po + -rm -f ./$(DEPDIR)/kbxutil-keybox-update.Po + -rm -f ./$(DEPDIR)/kbxutil-keybox-util.Po + -rm -f ./$(DEPDIR)/libkeybox509_a-keybox-blob.Po + -rm -f ./$(DEPDIR)/libkeybox509_a-keybox-dump.Po + -rm -f ./$(DEPDIR)/libkeybox509_a-keybox-file.Po + -rm -f ./$(DEPDIR)/libkeybox509_a-keybox-init.Po + -rm -f ./$(DEPDIR)/libkeybox509_a-keybox-openpgp.Po + -rm -f ./$(DEPDIR)/libkeybox509_a-keybox-search.Po + -rm -f ./$(DEPDIR)/libkeybox509_a-keybox-update.Po + -rm -f ./$(DEPDIR)/libkeybox509_a-keybox-util.Po + -rm -f ./$(DEPDIR)/libkeybox_a-keybox-blob.Po + -rm -f ./$(DEPDIR)/libkeybox_a-keybox-dump.Po + -rm -f ./$(DEPDIR)/libkeybox_a-keybox-file.Po + -rm -f ./$(DEPDIR)/libkeybox_a-keybox-init.Po + -rm -f ./$(DEPDIR)/libkeybox_a-keybox-openpgp.Po + -rm -f ./$(DEPDIR)/libkeybox_a-keybox-search.Po + -rm -f ./$(DEPDIR)/libkeybox_a-keybox-update.Po + -rm -f ./$(DEPDIR)/libkeybox_a-keybox-util.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-binPROGRAMS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/kbxutil-kbxutil.Po + -rm -f ./$(DEPDIR)/kbxutil-keybox-blob.Po + -rm -f ./$(DEPDIR)/kbxutil-keybox-dump.Po + -rm -f ./$(DEPDIR)/kbxutil-keybox-file.Po + -rm -f ./$(DEPDIR)/kbxutil-keybox-init.Po + -rm -f ./$(DEPDIR)/kbxutil-keybox-openpgp.Po + -rm -f ./$(DEPDIR)/kbxutil-keybox-search.Po + -rm -f ./$(DEPDIR)/kbxutil-keybox-update.Po + -rm -f ./$(DEPDIR)/kbxutil-keybox-util.Po + -rm -f ./$(DEPDIR)/libkeybox509_a-keybox-blob.Po + -rm -f ./$(DEPDIR)/libkeybox509_a-keybox-dump.Po + -rm -f ./$(DEPDIR)/libkeybox509_a-keybox-file.Po + -rm -f ./$(DEPDIR)/libkeybox509_a-keybox-init.Po + -rm -f ./$(DEPDIR)/libkeybox509_a-keybox-openpgp.Po + -rm -f ./$(DEPDIR)/libkeybox509_a-keybox-search.Po + -rm -f ./$(DEPDIR)/libkeybox509_a-keybox-update.Po + -rm -f ./$(DEPDIR)/libkeybox509_a-keybox-util.Po + -rm -f ./$(DEPDIR)/libkeybox_a-keybox-blob.Po + -rm -f ./$(DEPDIR)/libkeybox_a-keybox-dump.Po + -rm -f ./$(DEPDIR)/libkeybox_a-keybox-file.Po + -rm -f ./$(DEPDIR)/libkeybox_a-keybox-init.Po + -rm -f ./$(DEPDIR)/libkeybox_a-keybox-openpgp.Po + -rm -f ./$(DEPDIR)/libkeybox_a-keybox-search.Po + -rm -f ./$(DEPDIR)/libkeybox_a-keybox-update.Po + -rm -f ./$(DEPDIR)/libkeybox_a-keybox-util.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-binPROGRAMS clean-generic clean-noinstLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-binPROGRAMS \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-binPROGRAMS + +.PRECIOUS: Makefile + + +@HAVE_W32_SYSTEM_TRUE@.rc.o: +@HAVE_W32_SYSTEM_TRUE@ $(WINDRES) $(DEFAULT_INCLUDES) $(INCLUDES) "$<" "$@" + +$(PROGRAMS) : ../common/libcommon.a + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/kbx/kbxutil.c b/kbx/kbxutil.c new file mode 100644 index 0000000..9e05de4 --- /dev/null +++ b/kbx/kbxutil.c @@ -0,0 +1,644 @@ +/* kbxutil.c - The Keybox utility + * Copyright (C) 2000, 2001, 2004, 2007, 2011 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG 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 3 of the License, or + * (at your option) any later version. + * + * GnuPG 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, see <https://www.gnu.org/licenses/>. + */ + +#include <config.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <sys/stat.h> +#include <unistd.h> +#include <limits.h> +#include <assert.h> + +#include <gpg-error.h> +#include "../common/logging.h" +#include "../common/argparse.h" +#include "../common/stringhelp.h" +#include "../common/utf8conv.h" +#include "../common/i18n.h" +#include "keybox-defs.h" +#include "../common/init.h" +#include <gcrypt.h> + + +enum cmd_and_opt_values { + aNull = 0, + oArmor = 'a', + oDryRun = 'n', + oOutput = 'o', + oQuiet = 'q', + oVerbose = 'v', + + aNoSuchCmd = 500, /* force other values not to be a letter */ + aFindByFpr, + aFindByKid, + aFindByUid, + aStats, + aImportOpenPGP, + aFindDups, + aCut, + + oDebug, + oDebugAll, + + oNoArmor, + oFrom, + oTo, + + aTest +}; + + +static ARGPARSE_OPTS opts[] = { + { 300, NULL, 0, N_("@Commands:\n ") }, + +/* { aFindByFpr, "find-by-fpr", 0, "|FPR| find key using it's fingerprnt" }, */ +/* { aFindByKid, "find-by-kid", 0, "|KID| find key using it's keyid" }, */ +/* { aFindByUid, "find-by-uid", 0, "|NAME| find key by user name" }, */ + { aStats, "stats", 0, "show key statistics" }, + { aImportOpenPGP, "import-openpgp", 0, "import OpenPGP keyblocks"}, + { aFindDups, "find-dups", 0, "find duplicates" }, + { aCut, "cut", 0, "export records" }, + + { 301, NULL, 0, N_("@\nOptions:\n ") }, + + { oFrom, "from", 4, "|N|first record to export" }, + { oTo, "to", 4, "|N|last record to export" }, +/* { oArmor, "armor", 0, N_("create ascii armored output")}, */ +/* { oArmor, "armour", 0, "@" }, */ +/* { oOutput, "output", 2, N_("use as output file")}, */ + { oVerbose, "verbose", 0, N_("verbose") }, + { oQuiet, "quiet", 0, N_("be somewhat more quiet") }, + { oDryRun, "dry-run", 0, N_("do not make any changes") }, + + { oDebug, "debug" ,4|16, N_("set debugging flags")}, + { oDebugAll, "debug-all" ,0, N_("enable full debugging")}, + + ARGPARSE_end () /* end of list */ +}; + + +void myexit (int rc); + +int keybox_errors_seen = 0; + + +static const char * +my_strusage( int level ) +{ + const char *p; + switch( level ) { + case 11: p = "kbxutil (@GNUPG@)"; + break; + case 13: p = VERSION; break; + case 17: p = PRINTABLE_OS_NAME; break; + case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break; + + case 1: + case 40: p = + _("Usage: kbxutil [options] [files] (-h for help)"); + break; + case 41: p = + _("Syntax: kbxutil [options] [files]\n" + "List, export, import Keybox data\n"); + break; + + + default: p = NULL; + } + return p; +} + + +/* Used by gcry for logging */ +static void +my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr) +{ + (void)dummy; + + /* Map the log levels. */ + switch (level) + { + case GCRY_LOG_CONT: level = GPGRT_LOG_CONT; break; + case GCRY_LOG_INFO: level = GPGRT_LOG_INFO; break; + case GCRY_LOG_WARN: level = GPGRT_LOG_WARN; break; + case GCRY_LOG_ERROR:level = GPGRT_LOG_ERROR; break; + case GCRY_LOG_FATAL:level = GPGRT_LOG_FATAL; break; + case GCRY_LOG_BUG: level = GPGRT_LOG_BUG; break; + case GCRY_LOG_DEBUG:level = GPGRT_LOG_DEBUG; break; + default: level = GPGRT_LOG_ERROR; break; + } + log_logv (level, fmt, arg_ptr); +} + + + +/* static void */ +/* wrong_args( const char *text ) */ +/* { */ +/* log_error("usage: kbxutil %s\n", text); */ +/* myexit ( 1 ); */ +/* } */ + + +#if 0 +static int +hextobyte( const byte *s ) +{ + int c; + + if( *s >= '0' && *s <= '9' ) + c = 16 * (*s - '0'); + else if( *s >= 'A' && *s <= 'F' ) + c = 16 * (10 + *s - 'A'); + else if( *s >= 'a' && *s <= 'f' ) + c = 16 * (10 + *s - 'a'); + else + return -1; + s++; + if( *s >= '0' && *s <= '9' ) + c += *s - '0'; + else if( *s >= 'A' && *s <= 'F' ) + c += 10 + *s - 'A'; + else if( *s >= 'a' && *s <= 'f' ) + c += 10 + *s - 'a'; + else + return -1; + return c; +} +#endif + +#if 0 +static char * +format_fingerprint ( const char *s ) +{ + int i, c; + byte fpr[20]; + + for (i=0; i < 20 && *s; ) { + if ( *s == ' ' || *s == '\t' ) { + s++; + continue; + } + c = hextobyte(s); + if (c == -1) { + return NULL; + } + fpr[i++] = c; + s += 2; + } + return gcry_xstrdup ( fpr ); +} +#endif + +#if 0 +static int +format_keyid ( const char *s, u32 *kid ) +{ + char helpbuf[9]; + switch ( strlen ( s ) ) { + case 8: + kid[0] = 0; + kid[1] = strtoul( s, NULL, 16 ); + return 10; + + case 16: + mem2str( helpbuf, s, 9 ); + kid[0] = strtoul( helpbuf, NULL, 16 ); + kid[1] = strtoul( s+8, NULL, 16 ); + return 11; + } + return 0; /* error */ +} +#endif + +static char * +read_file (const char *fname, size_t *r_length) +{ + FILE *fp; + char *buf; + size_t buflen; + + if (!strcmp (fname, "-")) + { + size_t nread, bufsize = 0; + + fp = stdin; + buf = NULL; + buflen = 0; +#define NCHUNK 8192 + do + { + bufsize += NCHUNK; + if (!buf) + buf = xtrymalloc (bufsize); + else + buf = xtryrealloc (buf, bufsize); + if (!buf) + log_fatal ("can't allocate buffer: %s\n", strerror (errno)); + + nread = fread (buf+buflen, 1, NCHUNK, fp); + if (nread < NCHUNK && ferror (fp)) + { + log_error ("error reading '[stdin]': %s\n", strerror (errno)); + xfree (buf); + return NULL; + } + buflen += nread; + } + while (nread == NCHUNK); +#undef NCHUNK + + } + else + { + struct stat st; + + fp = gnupg_fopen (fname, "rb"); + if (!fp) + { + log_error ("can't open '%s': %s\n", fname, strerror (errno)); + return NULL; + } + + if (fstat (fileno(fp), &st)) + { + log_error ("can't stat '%s': %s\n", fname, strerror (errno)); + fclose (fp); + return NULL; + } + + buflen = st.st_size; + buf = xtrymalloc (buflen+1); + if (!buf) + log_fatal ("can't allocate buffer: %s\n", strerror (errno)); + if (fread (buf, buflen, 1, fp) != 1) + { + log_error ("error reading '%s': %s\n", fname, strerror (errno)); + fclose (fp); + xfree (buf); + return NULL; + } + fclose (fp); + } + + *r_length = buflen; + return buf; +} + + +static void +dump_fpr (const unsigned char *buffer, size_t len) +{ + int i; + + for (i=0; i < len; i++, buffer++) + { + if (len == 20) + { + if (i == 10) + putchar (' '); + printf (" %02X%02X", buffer[0], buffer[1]); + i++; buffer++; + } + else + { + if (i && !(i % 8)) + putchar (' '); + printf (" %02X", buffer[0]); + } + } +} + + +static void +dump_grip (const unsigned char *buffer, size_t len) +{ + int i; + + for (i=0; i < len; i++, buffer++) + { + printf ("%02X", buffer[0]); + } +} + + +static void +dump_openpgp_key (keybox_openpgp_info_t info, const unsigned char *image) +{ + printf ("pub %2d %02X%02X%02X%02X", + info->primary.algo, + info->primary.keyid[4], info->primary.keyid[5], + info->primary.keyid[6], info->primary.keyid[7] ); + dump_fpr (info->primary.fpr, info->primary.fprlen); + putchar ('\n'); + fputs ("grp ", stdout); + dump_grip (info->primary.grip, 20); + putchar ('\n'); + if (info->nsubkeys) + { + struct _keybox_openpgp_key_info *k; + + k = &info->subkeys; + do + { + printf ("sub %2d %02X%02X%02X%02X", + k->algo, + k->keyid[4], k->keyid[5], + k->keyid[6], k->keyid[7] ); + dump_fpr (k->fpr, k->fprlen); + putchar ('\n'); + fputs ("grp ", stdout); + dump_grip (k->grip, 20); + putchar ('\n'); + k = k->next; + } + while (k); + } + if (info->nuids) + { + struct _keybox_openpgp_uid_info *u; + + u = &info->uids; + do + { + printf ("uid\t\t%.*s\n", (int)u->len, image + u->off); + u = u->next; + } + while (u); + } +} + + +static void +import_openpgp (const char *filename, int dryrun) +{ + gpg_error_t err; + char *buffer; + size_t buflen, nparsed; + unsigned char *p; + struct _keybox_openpgp_info info; + KEYBOXBLOB blob; + + buffer = read_file (filename, &buflen); + if (!buffer) + return; + p = (unsigned char *)buffer; + for (;;) + { + err = _keybox_parse_openpgp (p, buflen, &nparsed, &info); + assert (nparsed <= buflen); + if (err) + { + if (gpg_err_code (err) == GPG_ERR_NO_DATA) + break; + if (gpg_err_code (err) == GPG_ERR_UNSUPPORTED_ALGORITHM) + { + /* This is likely a v3 key packet with a non-RSA + algorithm. These are keys from very early versions + of GnuPG (pre-OpenPGP). */ + } + else + { + es_fflush (es_stdout); + log_info ("%s: failed to parse OpenPGP keyblock: %s\n", + filename, gpg_strerror (err)); + } + } + else + { + if (dryrun) + dump_openpgp_key (&info, p); + else + { + err = _keybox_create_openpgp_blob (&blob, &info, p, nparsed, 0); + if (err) + { + es_fflush (es_stdout); + log_error ("%s: failed to create OpenPGP keyblock: %s\n", + filename, gpg_strerror (err)); + } + else + { + err = _keybox_write_blob (blob, es_stdout, NULL); + _keybox_release_blob (blob); + if (err) + { + es_fflush (es_stdout); + log_error ("%s: failed to write OpenPGP keyblock: %s\n", + filename, gpg_strerror (err)); + } + } + } + + _keybox_destroy_openpgp_info (&info); + } + p += nparsed; + buflen -= nparsed; + } + xfree (buffer); +} + + + + +int +main( int argc, char **argv ) +{ + ARGPARSE_ARGS pargs; + enum cmd_and_opt_values cmd = 0; + unsigned long from = 0; + unsigned long to = ULONG_MAX; + int dry_run = 0; + + early_system_init (); + set_strusage( my_strusage ); + gcry_control (GCRYCTL_DISABLE_SECMEM); + log_set_prefix ("kbxutil", GPGRT_LOG_WITH_PREFIX); + + /* Make sure that our subsystems are ready. */ + i18n_init (); + init_common_subsystems (&argc, &argv); + + gcry_set_log_handler (my_gcry_logger, NULL); + + /*create_dotlock(NULL); register locking cleanup */ + + /* We need to use the gcry malloc function because jnlib uses them. */ + ksba_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free ); + + + pargs.argc = &argc; + pargs.argv = &argv; + pargs.flags= ARGPARSE_FLAG_KEEP; + while (gnupg_argparse (NULL, &pargs, opts)) + { + switch (pargs.r_opt) + { + case oVerbose: + /*opt.verbose++;*/ + /*gcry_control( GCRYCTL_SET_VERBOSITY, (int)opt.verbose );*/ + break; + case oDebug: + /*opt.debug |= pargs.r.ret_ulong; */ + break; + case oDebugAll: + /*opt.debug = ~0;*/ + break; + + case aFindByFpr: + case aFindByKid: + case aFindByUid: + case aStats: + case aImportOpenPGP: + case aFindDups: + case aCut: + cmd = pargs.r_opt; + break; + + case oFrom: from = pargs.r.ret_ulong; break; + case oTo: to = pargs.r.ret_ulong; break; + + case oDryRun: dry_run = 1; break; + + default: + pargs.err = 2; + break; + } + } + + gnupg_argparse (NULL, &pargs, NULL); + + if (to < from) + log_error ("record number of \"--to\" is lower than \"--from\" one\n"); + + + if (log_get_errorcount(0) ) + myexit(2); + + if (!cmd) + { /* Default is to list a KBX file */ + if (!argc) + _keybox_dump_file (NULL, 0, stdout); + else + { + for (; argc; argc--, argv++) + _keybox_dump_file (*argv, 0, stdout); + } + } + else if (cmd == aStats ) + { + if (!argc) + _keybox_dump_file (NULL, 1, stdout); + else + { + for (; argc; argc--, argv++) + _keybox_dump_file (*argv, 1, stdout); + } + } + else if (cmd == aFindDups ) + { + if (!argc) + _keybox_dump_find_dups (NULL, 0, stdout); + else + { + for (; argc; argc--, argv++) + _keybox_dump_find_dups (*argv, 0, stdout); + } + } + else if (cmd == aCut ) + { + if (!argc) + _keybox_dump_cut_records (NULL, from, to, stdout); + else + { + for (; argc; argc--, argv++) + _keybox_dump_cut_records (*argv, from, to, stdout); + } + } + else if (cmd == aImportOpenPGP) + { + if (!argc) + import_openpgp ("-", dry_run); + else + { + for (; argc; argc--, argv++) + import_openpgp (*argv, dry_run); + } + } +#if 0 + else if ( cmd == aFindByFpr ) + { + char *fpr; + if ( argc != 2 ) + wrong_args ("kbxfile foingerprint"); + fpr = format_fingerprint ( argv[1] ); + if ( !fpr ) + log_error ("invalid formatted fingerprint\n"); + else + { + kbxfile_search_by_fpr ( argv[0], fpr ); + gcry_free ( fpr ); + } + } + else if ( cmd == aFindByKid ) + { + u32 kid[2]; + int mode; + + if ( argc != 2 ) + wrong_args ("kbxfile short-or-long-keyid"); + mode = format_keyid ( argv[1], kid ); + if ( !mode ) + log_error ("invalid formatted keyID\n"); + else + { + kbxfile_search_by_kid ( argv[0], kid, mode ); + } + } + else if ( cmd == aFindByUid ) + { + if ( argc != 2 ) + wrong_args ("kbxfile userID"); + kbxfile_search_by_uid ( argv[0], argv[1] ); + } +#endif + else + log_error ("unsupported action\n"); + + myexit(0); + return 8; /*NEVER REACHED*/ +} + + +void +myexit( int rc ) +{ + /* if( opt.debug & DBG_MEMSTAT_VALUE ) {*/ +/* gcry_control( GCRYCTL_DUMP_MEMORY_STATS ); */ +/* gcry_control( GCRYCTL_DUMP_RANDOM_STATS ); */ + /* }*/ +/* if( opt.debug ) */ +/* gcry_control( GCRYCTL_DUMP_SECMEM_STATS ); */ + rc = rc? rc : log_get_errorcount(0)? 2 : + keybox_errors_seen? 1 : 0; + exit(rc ); +} diff --git a/kbx/keybox-blob.c b/kbx/keybox-blob.c new file mode 100644 index 0000000..ac259ea --- /dev/null +++ b/kbx/keybox-blob.c @@ -0,0 +1,1057 @@ +/* keybox-blob.c - KBX Blob handling + * Copyright (C) 2000, 2001, 2002, 2003, 2008 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG 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 3 of the License, or + * (at your option) any later version. + * + * GnuPG 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, see <https://www.gnu.org/licenses/>. + */ + +/* +* The keybox data format + + The KeyBox uses an augmented OpenPGP/X.509 key format. This makes + random access to a keyblock/certificate easier and also gives the + opportunity to store additional information (e.g. the fingerprint) + along with the key. All integers are stored in network byte order, + offsets are counted from the beginning of the Blob. + +** Overview of blob types + + | Byte 4 | Blob type | + |--------+--------------| + | 0 | Empty blob | + | 1 | First blob | + | 2 | OpenPGP blob | + | 3 | X.509 blob | + +** The First blob + + The first blob of a plain KBX file has a special format: + + - u32 Length of this blob + - byte Blob type (1) + - byte Version number (1) + - u16 Header flags + bit 0 - RFU + bit 1 - Is being or has been used for OpenPGP blobs + - b4 Magic 'KBXf' + - u32 RFU + - u32 file_created_at + - u32 last_maintenance_run + - u32 RFU + - u32 RFU + +** The OpenPGP and X.509 blobs + + The OpenPGP and X.509 blobs are very similar, things which are + X.509 specific are noted like [X.509: xxx] + + - u32 Length of this blob (including these 4 bytes) + - byte Blob type + 2 = OpenPGP + 3 = X509 + - byte Version number of this blob type + 1 = The only defined value + - u16 Blob flags + bit 0 = contains secret key material (not used) + bit 1 = ephemeral blob (e.g. used while querying external resources) + - u32 Offset to the OpenPGP keyblock or the X.509 DER encoded + certificate + - u32 The length of the keyblock or certificate + - u16 [NKEYS] Number of keys (at least 1!) [X509: always 1] + - u16 Size of the key information structure (at least 28). + - NKEYS times: + - b20 The fingerprint of the key. + Fingerprints are always 20 bytes, MD5 left padded with zeroes. + - u32 Offset to the n-th key's keyID (a keyID is always 8 byte) + or 0 if not known which is the case only for X.509. + - u16 Key flags + bit 0 = qualified signature (not yet implemented} + - u16 RFU + - bN Optional filler up to the specified length of this + structure. + - u16 Size of the serial number (may be zero) + - bN The serial number. N as giiven above. + - u16 Number of user IDs + - u16 [NUIDS] Size of user ID information structure + - NUIDS times: + + For X509, the first user ID is the Issuer, the second the + Subject and the others are subjectAltNames. For OpenPGP we only + store the information from UserID packets here. + + - u32 Blob offset to the n-th user ID + - u32 Length of this user ID. + - u16 User ID flags. + (not yet used) + - byte Validity + - byte RFU + + - u16 [NSIGS] Number of signatures + - u16 Size of signature information (4) + - NSIGS times: + - u32 Expiration time of signature with some special values. + Since version 2.1.20 these special valuesare not anymore + used for OpenPGP: + - 0x00000000 = not checked + - 0x00000001 = missing key + - 0x00000002 = bad signature + - 0x10000000 = valid and expires at some date in 1978. + - 0xffffffff = valid and does not expire + - u8 Assigned ownertrust [X509: not used] + - u8 All_Validity + OpenPGP: See ../g10/trustdb/TRUST_* [not yet used] + X509: Bit 4 set := key has been revoked. + Note that this value matches TRUST_FLAG_REVOKED + - u16 RFU + - u32 Recheck_after + - u32 Latest timestamp in the keyblock (useful for KS synchronization?) + - u32 Blob created at + - u32 [NRES] Size of reserved space (not including this field) + - bN Reserved space of size NRES for future use. + - bN Arbitrary space for example used to store data which is not + part of the keyblock or certificate. For example the v3 key + IDs go here. + - bN Space for the keyblock or certificate. + - bN RFU. This is the remaining space after keyblock and before + the checksum. It is not covered by the checksum. + - b20 SHA-1 checksum (useful for KS synchronization?) + Note, that KBX versions before GnuPG 2.1 used an MD5 + checksum. However it was only created but never checked. + Thus we do not expect problems if we switch to SHA-1. If + the checksum fails and the first 4 bytes are zero, we can + try again with MD5. SHA-1 has the advantage that it is + faster on CPUs with dedicated SHA-1 support. + + +*/ + + +#include <config.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <assert.h> +#include <time.h> + +#include "keybox-defs.h" +#include <gcrypt.h> + +#ifdef KEYBOX_WITH_X509 +#include <ksba.h> +#endif + + +#include "../common/gettime.h" + + +/* special values of the signature status */ +#define SF_NONE(a) ( !(a) ) +#define SF_NOKEY(a) ((a) & (1<<0)) +#define SF_BAD(a) ((a) & (1<<1)) +#define SF_VALID(a) ((a) & (1<<29)) + + +struct membuf { + size_t len; + size_t size; + char *buf; + int out_of_core; +}; + + +/* #if MAX_FINGERPRINT_LEN < 20 */ +/* #error fingerprints are 20 bytes */ +/* #endif */ + +struct keyboxblob_key { + char fpr[20]; + u32 off_kid; + ulong off_kid_addr; + u16 flags; +}; +struct keyboxblob_uid { + u32 off; + ulong off_addr; + char *name; /* used only with x509 */ + u32 len; + u16 flags; + byte validity; +}; + +struct keyid_list { + struct keyid_list *next; + int seqno; + byte kid[8]; +}; + +struct fixup_list { + struct fixup_list *next; + u32 off; + u32 val; +}; + + +struct keyboxblob { + byte *blob; + size_t bloblen; + off_t fileoffset; + + /* stuff used only by keybox_create_blob */ + unsigned char *serialbuf; + const unsigned char *serial; + size_t seriallen; + int nkeys; + struct keyboxblob_key *keys; + int nuids; + struct keyboxblob_uid *uids; + int nsigs; + u32 *sigs; + struct fixup_list *fixups; + int fixup_out_of_core; + + struct keyid_list *temp_kids; + struct membuf bufbuf; /* temporary store for the blob */ + struct membuf *buf; +}; + + + +/* A simple implementation of a dynamic buffer. Use init_membuf() to + create a buffer, put_membuf to append bytes and get_membuf to + release and return the buffer. Allocation errors are detected but + only returned at the final get_membuf(), this helps not to clutter + the code with out of core checks. */ + +static void +init_membuf (struct membuf *mb, int initiallen) +{ + mb->len = 0; + mb->size = initiallen; + mb->out_of_core = 0; + mb->buf = xtrymalloc (initiallen); + if (!mb->buf) + mb->out_of_core = 1; +} + +static void +put_membuf (struct membuf *mb, const void *buf, size_t len) +{ + if (mb->out_of_core) + return; + + if (mb->len + len >= mb->size) + { + char *p; + + mb->size += len + 1024; + p = xtryrealloc (mb->buf, mb->size); + if (!p) + { + mb->out_of_core = 1; + return; + } + mb->buf = p; + } + if (buf) + memcpy (mb->buf + mb->len, buf, len); + else + memset (mb->buf + mb->len, 0, len); + mb->len += len; +} + +static void * +get_membuf (struct membuf *mb, size_t *len) +{ + char *p; + + if (mb->out_of_core) + { + xfree (mb->buf); + mb->buf = NULL; + return NULL; + } + + p = mb->buf; + *len = mb->len; + mb->buf = NULL; + mb->out_of_core = 1; /* don't allow a reuse */ + return p; +} + + +static void +put8 (struct membuf *mb, byte a ) +{ + put_membuf (mb, &a, 1); +} + +static void +put16 (struct membuf *mb, u16 a ) +{ + unsigned char tmp[2]; + tmp[0] = a>>8; + tmp[1] = a; + put_membuf (mb, tmp, 2); +} + +static void +put32 (struct membuf *mb, u32 a ) +{ + unsigned char tmp[4]; + tmp[0] = a>>24; + tmp[1] = a>>16; + tmp[2] = a>>8; + tmp[3] = a; + put_membuf (mb, tmp, 4); +} + + + +/* Store a value in the fixup list */ +static void +add_fixup (KEYBOXBLOB blob, u32 off, u32 val) +{ + struct fixup_list *fl; + + if (blob->fixup_out_of_core) + return; + + fl = xtrycalloc(1, sizeof *fl); + if (!fl) + blob->fixup_out_of_core = 1; + else + { + fl->off = off; + fl->val = val; + fl->next = blob->fixups; + blob->fixups = fl; + } +} + + + +/* + OpenPGP specific stuff +*/ + + +/* We must store the keyid at some place because we can't calculate + the offset yet. This is only used for v3 keyIDs. Function returns + an index value for later fixup or -1 for out of core. The value + must be a non-zero value. */ +static int +pgp_temp_store_kid (KEYBOXBLOB blob, struct _keybox_openpgp_key_info *kinfo) +{ + struct keyid_list *k, *r; + + k = xtrymalloc (sizeof *k); + if (!k) + return -1; + memcpy (k->kid, kinfo->keyid, 8); + k->seqno = 0; + k->next = blob->temp_kids; + blob->temp_kids = k; + for (r=k; r; r = r->next) + k->seqno++; + + return k->seqno; +} + + +/* Helper for pgp_create_key_part. */ +static gpg_error_t +pgp_create_key_part_single (KEYBOXBLOB blob, int n, + struct _keybox_openpgp_key_info *kinfo) +{ + size_t fprlen; + int off; + + fprlen = kinfo->fprlen; + if (fprlen > 20) + fprlen = 20; + memcpy (blob->keys[n].fpr, kinfo->fpr, fprlen); + if (fprlen != 20) /* v3 fpr - shift right and fill with zeroes. */ + { + memmove (blob->keys[n].fpr + 20 - fprlen, blob->keys[n].fpr, fprlen); + memset (blob->keys[n].fpr, 0, 20 - fprlen); + off = pgp_temp_store_kid (blob, kinfo); + if (off == -1) + return gpg_error_from_syserror (); + blob->keys[n].off_kid = off; + } + else + blob->keys[n].off_kid = 0; /* Will be fixed up later */ + blob->keys[n].flags = 0; + return 0; +} + + +static gpg_error_t +pgp_create_key_part (KEYBOXBLOB blob, keybox_openpgp_info_t info) +{ + gpg_error_t err; + int n = 0; + struct _keybox_openpgp_key_info *kinfo; + + err = pgp_create_key_part_single (blob, n++, &info->primary); + if (err) + return err; + if (info->nsubkeys) + for (kinfo = &info->subkeys; kinfo; kinfo = kinfo->next) + if ((err=pgp_create_key_part_single (blob, n++, kinfo))) + return err; + + assert (n == blob->nkeys); + return 0; +} + + +static void +pgp_create_uid_part (KEYBOXBLOB blob, keybox_openpgp_info_t info) +{ + int n = 0; + struct _keybox_openpgp_uid_info *u; + + if (info->nuids) + { + for (u = &info->uids; u; u = u->next) + { + blob->uids[n].off = u->off; + blob->uids[n].len = u->len; + blob->uids[n].flags = 0; + blob->uids[n].validity = 0; + n++; + } + } + + assert (n == blob->nuids); +} + + +static void +pgp_create_sig_part (KEYBOXBLOB blob, u32 *sigstatus) +{ + int n; + + for (n=0; n < blob->nsigs; n++) + { + blob->sigs[n] = sigstatus? sigstatus[n+1] : 0; + } +} + + +static int +pgp_create_blob_keyblock (KEYBOXBLOB blob, + const unsigned char *image, size_t imagelen) +{ + struct membuf *a = blob->buf; + int n; + u32 kbstart = a->len; + + add_fixup (blob, 8, kbstart); + + for (n = 0; n < blob->nuids; n++) + add_fixup (blob, blob->uids[n].off_addr, kbstart + blob->uids[n].off); + + put_membuf (a, image, imagelen); + + add_fixup (blob, 12, a->len - kbstart); + return 0; +} + + + +#ifdef KEYBOX_WITH_X509 +/* + X.509 specific stuff + */ + +/* Write the raw certificate out */ +static int +x509_create_blob_cert (KEYBOXBLOB blob, ksba_cert_t cert) +{ + struct membuf *a = blob->buf; + const unsigned char *image; + size_t length; + u32 kbstart = a->len; + + /* Store our offset for later fixup */ + add_fixup (blob, 8, kbstart); + + image = ksba_cert_get_image (cert, &length); + if (!image) + return gpg_error (GPG_ERR_GENERAL); + put_membuf (a, image, length); + + add_fixup (blob, 12, a->len - kbstart); + return 0; +} + +#endif /*KEYBOX_WITH_X509*/ + +/* Write a stored keyID out to the buffer */ +static void +write_stored_kid (KEYBOXBLOB blob, int seqno) +{ + struct keyid_list *r; + + for ( r = blob->temp_kids; r; r = r->next ) + { + if (r->seqno == seqno ) + { + put_membuf (blob->buf, r->kid, 8); + return; + } + } + never_reached (); +} + +/* Release a list of key IDs */ +static void +release_kid_list (struct keyid_list *kl) +{ + struct keyid_list *r, *r2; + + for ( r = kl; r; r = r2 ) + { + r2 = r->next; + xfree (r); + } +} + + + +static int +create_blob_header (KEYBOXBLOB blob, int blobtype, int as_ephemeral) +{ + struct membuf *a = blob->buf; + int i; + + put32 ( a, 0 ); /* blob length, needs fixup */ + put8 ( a, blobtype); + put8 ( a, 1 ); /* blob type version */ + put16 ( a, as_ephemeral? 2:0 ); /* blob flags */ + + put32 ( a, 0 ); /* offset to the raw data, needs fixup */ + put32 ( a, 0 ); /* length of the raw data, needs fixup */ + + put16 ( a, blob->nkeys ); + put16 ( a, 20 + 4 + 2 + 2 ); /* size of key info */ + for ( i=0; i < blob->nkeys; i++ ) + { + put_membuf (a, blob->keys[i].fpr, 20); + blob->keys[i].off_kid_addr = a->len; + put32 ( a, 0 ); /* offset to keyid, fixed up later */ + put16 ( a, blob->keys[i].flags ); + put16 ( a, 0 ); /* reserved */ + } + + put16 (a, blob->seriallen); /*fixme: check that it fits into 16 bits*/ + if (blob->serial) + put_membuf (a, blob->serial, blob->seriallen); + + put16 ( a, blob->nuids ); + put16 ( a, 4 + 4 + 2 + 1 + 1 ); /* size of uid info */ + for (i=0; i < blob->nuids; i++) + { + blob->uids[i].off_addr = a->len; + put32 ( a, 0 ); /* offset to userid, fixed up later */ + put32 ( a, blob->uids[i].len ); + put16 ( a, blob->uids[i].flags ); + put8 ( a, 0 ); /* validity */ + put8 ( a, 0 ); /* reserved */ + } + + put16 ( a, blob->nsigs ); + put16 ( a, 4 ); /* size of sig info */ + for (i=0; i < blob->nsigs; i++) + { + put32 ( a, blob->sigs[i]); + } + + put8 ( a, 0 ); /* assigned ownertrust */ + put8 ( a, 0 ); /* validity of all user IDs */ + put16 ( a, 0 ); /* reserved */ + put32 ( a, 0 ); /* time of next recheck */ + put32 ( a, 0 ); /* newest timestamp (none) */ + put32 ( a, make_timestamp() ); /* creation time */ + put32 ( a, 0 ); /* size of reserved space */ + /* reserved space (which is currently of size 0) */ + + /* space where we write keyIDs and other stuff so that the + pointers can actually point to somewhere */ + if (blobtype == KEYBOX_BLOBTYPE_PGP) + { + /* We need to store the keyids for all pgp v3 keys because those key + IDs are not part of the fingerprint. While we are doing that, we + fixup all the keyID offsets */ + for (i=0; i < blob->nkeys; i++ ) + { + if (blob->keys[i].off_kid) + { /* this is a v3 one */ + add_fixup (blob, blob->keys[i].off_kid_addr, a->len); + write_stored_kid (blob, blob->keys[i].off_kid); + } + else + { /* the better v4 key IDs - just store an offset 8 bytes back */ + add_fixup (blob, blob->keys[i].off_kid_addr, + blob->keys[i].off_kid_addr - 8); + } + } + } + + if (blobtype == KEYBOX_BLOBTYPE_X509) + { + /* We don't want to point to ASN.1 encoded UserIDs (DNs) but to + the utf-8 string represenation of them */ + for (i=0; i < blob->nuids; i++ ) + { + if (blob->uids[i].name) + { /* this is a v3 one */ + add_fixup (blob, blob->uids[i].off_addr, a->len); + put_membuf (blob->buf, blob->uids[i].name, blob->uids[i].len); + } + } + } + + return 0; +} + + + +static int +create_blob_trailer (KEYBOXBLOB blob) +{ + (void)blob; + return 0; +} + + +static int +create_blob_finish (KEYBOXBLOB blob) +{ + struct membuf *a = blob->buf; + unsigned char *p; + unsigned char *pp; + size_t n; + + /* Write a placeholder for the checksum */ + put_membuf (a, NULL, 20); + + /* get the memory area */ + n = 0; /* (Just to avoid compiler warning.) */ + p = get_membuf (a, &n); + if (!p) + return gpg_error (GPG_ERR_ENOMEM); + assert (n >= 20); + + /* fixup the length */ + add_fixup (blob, 0, n); + + /* do the fixups */ + if (blob->fixup_out_of_core) + { + xfree (p); + return gpg_error (GPG_ERR_ENOMEM); + } + + { + struct fixup_list *fl, *next; + for (fl = blob->fixups; fl; fl = next) + { + assert (fl->off+4 <= n); + p[fl->off+0] = fl->val >> 24; + p[fl->off+1] = fl->val >> 16; + p[fl->off+2] = fl->val >> 8; + p[fl->off+3] = fl->val; + next = fl->next; + xfree (fl); + } + blob->fixups = NULL; + } + + /* Compute and store the SHA-1 checksum. */ + gcry_md_hash_buffer (GCRY_MD_SHA1, p + n - 20, p, n - 20); + + pp = xtrymalloc (n); + if ( !pp ) + { + xfree (p); + return gpg_error_from_syserror (); + } + memcpy (pp , p, n); + xfree (p); + blob->blob = pp; + blob->bloblen = n; + + return 0; +} + + + +gpg_error_t +_keybox_create_openpgp_blob (KEYBOXBLOB *r_blob, + keybox_openpgp_info_t info, + const unsigned char *image, + size_t imagelen, + int as_ephemeral) +{ + gpg_error_t err; + KEYBOXBLOB blob; + + *r_blob = NULL; + + blob = xtrycalloc (1, sizeof *blob); + if (!blob) + return gpg_error_from_syserror (); + + blob->nkeys = 1 + info->nsubkeys; + blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys ); + if (!blob->keys) + { + err = gpg_error_from_syserror (); + goto leave; + } + + blob->nuids = info->nuids; + if (blob->nuids) + { + blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids ); + if (!blob->uids) + { + err = gpg_error_from_syserror (); + goto leave; + } + } + + blob->nsigs = info->nsigs; + if (blob->nsigs) + { + blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs ); + if (!blob->sigs) + { + err = gpg_error_from_syserror (); + goto leave; + } + } + + err = pgp_create_key_part (blob, info); + if (err) + goto leave; + pgp_create_uid_part (blob, info); + pgp_create_sig_part (blob, NULL); + + init_membuf (&blob->bufbuf, 1024); + blob->buf = &blob->bufbuf; + err = create_blob_header (blob, KEYBOX_BLOBTYPE_PGP, as_ephemeral); + if (err) + goto leave; + err = pgp_create_blob_keyblock (blob, image, imagelen); + if (err) + goto leave; + err = create_blob_trailer (blob); + if (err) + goto leave; + err = create_blob_finish (blob); + if (err) + goto leave; + + leave: + release_kid_list (blob->temp_kids); + blob->temp_kids = NULL; + if (err) + _keybox_release_blob (blob); + else + *r_blob = blob; + return err; +} + + +#ifdef KEYBOX_WITH_X509 + +/* Return an allocated string with the email address extracted from a + DN. Note hat we use this code also in ../sm/keylist.c. */ +static char * +x509_email_kludge (const char *name) +{ + const char *p, *string; + unsigned char *buf; + int n; + + string = name; + for (;;) + { + p = strstr (string, "1.2.840.113549.1.9.1=#"); + if (!p) + return NULL; + if (p == name || (p > string+1 && p[-1] == ',' && p[-2] != '\\')) + { + name = p + 22; + break; + } + string = p + 22; + } + + + /* This looks pretty much like an email address in the subject's DN + we use this to add an additional user ID entry. This way, + OpenSSL generated keys get a nicer and usable listing. */ + for (n=0, p=name; hexdigitp (p) && hexdigitp (p+1); p +=2, n++) + ; + if (!n) + return NULL; + buf = xtrymalloc (n+3); + if (!buf) + return NULL; /* oops, out of core */ + *buf = '<'; + for (n=1, p=name; hexdigitp (p); p +=2, n++) + buf[n] = xtoi_2 (p); + buf[n++] = '>'; + buf[n] = 0; + return (char*)buf; +} + + + +/* Note: We should move calculation of the digest into libksba and + remove that parameter */ +int +_keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert, + unsigned char *sha1_digest, int as_ephemeral) +{ + int i, rc = 0; + KEYBOXBLOB blob; + unsigned char *sn; + char *p; + char **names = NULL; + size_t max_names; + + *r_blob = NULL; + blob = xtrycalloc (1, sizeof *blob); + if( !blob ) + return gpg_error_from_syserror (); + + sn = ksba_cert_get_serial (cert); + if (sn) + { + size_t n, len; + n = gcry_sexp_canon_len (sn, 0, NULL, NULL); + if (n < 2) + { + xfree (sn); + return gpg_error (GPG_ERR_GENERAL); + } + blob->serialbuf = sn; + sn++; n--; /* skip '(' */ + for (len=0; n && *sn && *sn != ':' && digitp (sn); n--, sn++) + len = len*10 + atoi_1 (sn); + if (*sn != ':') + { + xfree (blob->serialbuf); + blob->serialbuf = NULL; + return gpg_error (GPG_ERR_GENERAL); + } + sn++; + blob->serial = sn; + blob->seriallen = len; + } + + blob->nkeys = 1; + + /* create list of names */ + blob->nuids = 0; + max_names = 100; + names = xtrymalloc (max_names * sizeof *names); + if (!names) + { + rc = gpg_error_from_syserror (); + goto leave; + } + + p = ksba_cert_get_issuer (cert, 0); + if (!p) + { + rc = gpg_error (GPG_ERR_MISSING_VALUE); + goto leave; + } + names[blob->nuids++] = p; + for (i=0; (p = ksba_cert_get_subject (cert, i)); i++) + { + if (blob->nuids >= max_names) + { + char **tmp; + + max_names += 100; + tmp = xtryrealloc (names, max_names * sizeof *names); + if (!tmp) + { + rc = gpg_error_from_syserror (); + goto leave; + } + names = tmp; + } + names[blob->nuids++] = p; + if (!i && (p=x509_email_kludge (p))) + names[blob->nuids++] = p; /* due to !i we don't need to check bounds*/ + } + + /* space for signature information */ + blob->nsigs = 1; + + blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys ); + blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids ); + blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs ); + if (!blob->keys || !blob->uids || !blob->sigs) + { + rc = gpg_error (GPG_ERR_ENOMEM); + goto leave; + } + + memcpy (blob->keys[0].fpr, sha1_digest, 20); + blob->keys[0].off_kid = 0; /* We don't have keyids */ + blob->keys[0].flags = 0; + + /* issuer and subject names */ + for (i=0; i < blob->nuids; i++) + { + blob->uids[i].name = names[i]; + blob->uids[i].len = strlen(names[i]); + names[i] = NULL; + blob->uids[i].flags = 0; + blob->uids[i].validity = 0; + } + xfree (names); + names = NULL; + + /* signatures */ + blob->sigs[0] = 0; /* not yet checked */ + + /* Create a temporary buffer for further processing */ + init_membuf (&blob->bufbuf, 1024); + blob->buf = &blob->bufbuf; + /* write out what we already have */ + rc = create_blob_header (blob, KEYBOX_BLOBTYPE_X509, as_ephemeral); + if (rc) + goto leave; + rc = x509_create_blob_cert (blob, cert); + if (rc) + goto leave; + rc = create_blob_trailer (blob); + if (rc) + goto leave; + rc = create_blob_finish ( blob ); + if (rc) + goto leave; + + + leave: + release_kid_list (blob->temp_kids); + blob->temp_kids = NULL; + if (names) + { + for (i=0; i < blob->nuids; i++) + xfree (names[i]); + xfree (names); + } + if (rc) + { + _keybox_release_blob (blob); + *r_blob = NULL; + } + else + { + *r_blob = blob; + } + return rc; +} +#endif /*KEYBOX_WITH_X509*/ + + + +int +_keybox_new_blob (KEYBOXBLOB *r_blob, + unsigned char *image, size_t imagelen, off_t off) +{ + KEYBOXBLOB blob; + + *r_blob = NULL; + blob = xtrycalloc (1, sizeof *blob); + if (!blob) + return gpg_error_from_syserror (); + + blob->blob = image; + blob->bloblen = imagelen; + blob->fileoffset = off; + *r_blob = blob; + return 0; +} + + +void +_keybox_release_blob (KEYBOXBLOB blob) +{ + int i; + if (!blob) + return; + if (blob->buf) + { + size_t len; + xfree (get_membuf (blob->buf, &len)); + } + xfree (blob->keys ); + xfree (blob->serialbuf); + for (i=0; i < blob->nuids; i++) + xfree (blob->uids[i].name); + xfree (blob->uids ); + xfree (blob->sigs ); + xfree (blob->blob ); + xfree (blob ); +} + + + +const unsigned char * +_keybox_get_blob_image ( KEYBOXBLOB blob, size_t *n ) +{ + *n = blob->bloblen; + return blob->blob; +} + +off_t +_keybox_get_blob_fileoffset (KEYBOXBLOB blob) +{ + return blob->fileoffset; +} + + + +void +_keybox_update_header_blob (KEYBOXBLOB blob, int for_openpgp) +{ + if (blob->bloblen >= 32 && blob->blob[4] == KEYBOX_BLOBTYPE_HEADER) + { + u32 val = make_timestamp (); + + /* Update the last maintenance run times tamp. */ + blob->blob[20] = (val >> 24); + blob->blob[20+1] = (val >> 16); + blob->blob[20+2] = (val >> 8); + blob->blob[20+3] = (val ); + + if (for_openpgp) + blob->blob[7] |= 0x02; /* OpenPGP data may be available. */ + } +} diff --git a/kbx/keybox-defs.h b/kbx/keybox-defs.h new file mode 100644 index 0000000..2751b4b --- /dev/null +++ b/kbx/keybox-defs.h @@ -0,0 +1,210 @@ +/* keybox-defs.h - internal Keybox definitions + * Copyright (C) 2001, 2004 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG 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 3 of the License, or + * (at your option) any later version. + * + * GnuPG 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, see <https://www.gnu.org/licenses/>. + */ + +#ifndef KEYBOX_DEFS_H +#define KEYBOX_DEFS_H 1 + +#ifdef GPG_ERR_SOURCE_DEFAULT +# if GPG_ERR_SOURCE_DEFAULT != GPG_ERR_SOURCE_KEYBOX +# error GPG_ERR_SOURCE_DEFAULT already defined +# endif +#else +# define GPG_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_KEYBOX +#endif +#include <gpg-error.h> +#define map_assuan_err(a) \ + map_assuan_err_with_source (GPG_ERR_SOURCE_DEFAULT, (a)) + +#include <sys/types.h> /* off_t */ + +#include "../common/util.h" +#include "keybox.h" + + +typedef struct keyboxblob *KEYBOXBLOB; + + +typedef struct keybox_name *KB_NAME; +struct keybox_name +{ + /* Link to the next resources, so that we can walk all + resources. */ + KB_NAME next; + + /* True if this is a keybox with secret keys. */ + int secret; + + /* A table with all the handles accessing this resources. + HANDLE_TABLE_SIZE gives the allocated length of this table unused + entrues are set to NULL. HANDLE_TABLE may be NULL. */ + KEYBOX_HANDLE *handle_table; + size_t handle_table_size; + + /* The lock handle or NULL it not yet initialized. */ + dotlock_t lockhd; + + /* Not yet used. */ + int is_locked; + + /* Not yet used. */ + int did_full_scan; + + /* The name of the resource file. */ + char fname[1]; +}; + + +struct keybox_found_s +{ + KEYBOXBLOB blob; + size_t pk_no; + size_t uid_no; +}; + +struct keybox_handle { + KB_NAME kb; + int secret; /* this is for a secret keybox */ + estream_t fp; + int eof; + int error; + int ephemeral; + int for_openpgp; /* Used by gpg. */ + struct keybox_found_s found; + struct keybox_found_s saved_found; + struct { + char *name; + char *pattern; + } word_match; +}; + + +/* OpenPGP helper structures. */ +struct _keybox_openpgp_key_info +{ + struct _keybox_openpgp_key_info *next; + int algo; + unsigned char grip[20]; + unsigned char keyid[8]; + int fprlen; /* Either 16 or 20 */ + unsigned char fpr[20]; +}; + +struct _keybox_openpgp_uid_info +{ + struct _keybox_openpgp_uid_info *next; + size_t off; + size_t len; +}; + +struct _keybox_openpgp_info +{ + int is_secret; /* True if this is a secret key. */ + unsigned int nsubkeys;/* Total number of subkeys. */ + unsigned int nuids; /* Total number of user IDs in the keyblock. */ + unsigned int nsigs; /* Total number of signatures in the keyblock. */ + + /* Note, we use 2 structs here to better cope with the most common + use of having one primary and one subkey - this allows us to + statically allocate this structure and only malloc stuff for more + than one subkey. */ + struct _keybox_openpgp_key_info primary; + struct _keybox_openpgp_key_info subkeys; + struct _keybox_openpgp_uid_info uids; +}; +typedef struct _keybox_openpgp_info *keybox_openpgp_info_t; + + +/* Don't know whether this is needed: */ +/* static struct { */ +/* int dry_run; */ +/* int quiet; */ +/* int verbose; */ +/* int preserve_permissions; */ +/* } keybox_opt; */ + +/*-- keybox-init.c --*/ +void _keybox_close_file (KEYBOX_HANDLE hd); + + +/*-- keybox-blob.c --*/ +gpg_error_t _keybox_create_openpgp_blob (KEYBOXBLOB *r_blob, + keybox_openpgp_info_t info, + const unsigned char *image, + size_t imagelen, + int as_ephemeral); +#ifdef KEYBOX_WITH_X509 +int _keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert, + unsigned char *sha1_digest, int as_ephemeral); +#endif /*KEYBOX_WITH_X509*/ + +int _keybox_new_blob (KEYBOXBLOB *r_blob, + unsigned char *image, size_t imagelen, + off_t off); +void _keybox_release_blob (KEYBOXBLOB blob); +const unsigned char *_keybox_get_blob_image (KEYBOXBLOB blob, size_t *n); +off_t _keybox_get_blob_fileoffset (KEYBOXBLOB blob); +void _keybox_update_header_blob (KEYBOXBLOB blob, int for_openpgp); + +/*-- keybox-openpgp.c --*/ +gpg_error_t _keybox_parse_openpgp (const unsigned char *image, size_t imagelen, + size_t *nparsed, + keybox_openpgp_info_t info); +void _keybox_destroy_openpgp_info (keybox_openpgp_info_t info); + + +/*-- keybox-file.c --*/ +int _keybox_read_blob (KEYBOXBLOB *r_blob, estream_t fp, int *skipped_deleted); +int _keybox_write_blob (KEYBOXBLOB blob, estream_t fp, FILE *outfp); + +/*-- keybox-search.c --*/ +gpg_err_code_t _keybox_get_flag_location (const unsigned char *buffer, + size_t length, + int what, + size_t *flag_off, size_t *flag_size); + +static inline int +blob_get_type (KEYBOXBLOB blob) +{ + const unsigned char *buffer; + size_t length; + + buffer = _keybox_get_blob_image (blob, &length); + if (length < 32) + return -1; /* blob too short */ + + return buffer[4]; +} + + +/*-- keybox-dump.c --*/ +int _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp); +int _keybox_dump_file (const char *filename, int stats_only, FILE *outfp); +int _keybox_dump_find_dups (const char *filename, int print_them, FILE *outfp); +int _keybox_dump_cut_records (const char *filename, unsigned long from, + unsigned long to, FILE *outfp); + + +/*-- keybox-util.c --*/ + +/* + * A couple of handy macros + */ + + +#endif /*KEYBOX_DEFS_H*/ diff --git a/kbx/keybox-dump.c b/kbx/keybox-dump.c new file mode 100644 index 0000000..3e66b72 --- /dev/null +++ b/kbx/keybox-dump.c @@ -0,0 +1,915 @@ +/* keybox-dump.c - Debug helpers + * Copyright (C) 2001, 2003 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG 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 3 of the License, or + * (at your option) any later version. + * + * GnuPG 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, see <https://www.gnu.org/licenses/>. + */ + +#include <config.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> + +#include "keybox-defs.h" +#include <gcrypt.h> +#include "../common/host2net.h" + +/* Argg, we can't include ../common/util.h */ +char *bin2hexcolon (const void *buffer, size_t length, char *stringbuf); + +#define get32(a) buf32_to_ulong ((a)) +#define get16(a) buf16_to_ulong ((a)) + + +void +print_string (FILE *fp, const byte *p, size_t n, int delim) +{ + for ( ; n; n--, p++ ) + { + if (*p < 0x20 || (*p >= 0x7f && *p < 0xa0) || *p == delim) + { + putc('\\', fp); + if( *p == '\n' ) + putc('n', fp); + else if( *p == '\r' ) + putc('r', fp); + else if( *p == '\f' ) + putc('f', fp); + else if( *p == '\v' ) + putc('v', fp); + else if( *p == '\b' ) + putc('b', fp); + else if( !*p ) + putc('0', fp); + else + fprintf(fp, "x%02x", *p ); + } + else + putc(*p, fp); + } +} + + +static int +print_checksum (const byte *buffer, size_t length, size_t unhashed, FILE *fp) +{ + const byte *p; + int i; + int hashlen; + unsigned char digest[20]; + + fprintf (fp, "Checksum: "); + if (unhashed && unhashed < 20) + { + fputs ("[specified unhashed sized too short]\n", fp); + return 0; + } + if (!unhashed) + { + unhashed = 16; + hashlen = 16; + } + else + hashlen = 20; + + if (length < 5+unhashed) + { + fputs ("[blob too short for a checksum]\n", fp); + return 0; + } + + p = buffer + length - hashlen; + for (i=0; i < hashlen; p++, i++) + fprintf (fp, "%02x", *p); + + if (hashlen == 16) /* Compatibility method. */ + { + gcry_md_hash_buffer (GCRY_MD_MD5, digest, buffer, length - 16); + if (!memcmp (buffer + length - 16, digest, 16)) + fputs (" [valid]\n", fp); + else + fputs (" [bad]\n", fp); + } + else + { + gcry_md_hash_buffer (GCRY_MD_SHA1, digest, buffer, length - unhashed); + if (!memcmp (buffer + length - hashlen, digest, hashlen)) + fputs (" [valid]\n", fp); + else + fputs (" [bad]\n", fp); + } + return 0; +} + + +static int +dump_header_blob (const byte *buffer, size_t length, FILE *fp) +{ + unsigned long n; + + if (length < 32) + { + fprintf (fp, "[blob too short]\n"); + return -1; + } + fprintf (fp, "Version: %d\n", buffer[5]); + + n = get16 (buffer + 6); + fprintf( fp, "Flags: %04lX", n); + if (n) + { + int any = 0; + + fputs (" (", fp); + if ((n & 2)) + { + if (any) + putc (',', fp); + fputs ("openpgp", fp); + any++; + } + putc (')', fp); + } + putc ('\n', fp); + + if ( memcmp (buffer+8, "KBXf", 4)) + fprintf (fp, "[Error: invalid magic number]\n"); + + n = get32 (buffer+16); + fprintf( fp, "created-at: %lu\n", n ); + n = get32 (buffer+20); + fprintf( fp, "last-maint: %lu\n", n ); + + return 0; +} + + +/* Dump one block to FP */ +int +_keybox_dump_blob (KEYBOXBLOB blob, FILE *fp) +{ + const byte *buffer; + size_t length; + int type, i; + ulong n, nkeys, keyinfolen; + ulong nuids, uidinfolen; + ulong nsigs, siginfolen; + ulong rawdata_off, rawdata_len; + ulong nserial; + ulong unhashed; + const byte *p; + const byte *pend; + int is_fpr32; /* blob version 2 */ + + buffer = _keybox_get_blob_image (blob, &length); + + if (length < 32) + { + fprintf (fp, "[blob too short]\n"); + return -1; + } + + n = get32( buffer ); + if (n > length) + fprintf (fp, "[blob larger than length - output truncated]\n"); + else + length = n; /* ignore the rest */ + + fprintf (fp, "Length: %lu\n", n ); + type = buffer[4]; + switch (type) + { + case KEYBOX_BLOBTYPE_EMPTY: + fprintf (fp, "Type: Empty\n"); + return 0; + + case KEYBOX_BLOBTYPE_HEADER: + fprintf (fp, "Type: Header\n"); + return dump_header_blob (buffer, length, fp); + case KEYBOX_BLOBTYPE_PGP: + fprintf (fp, "Type: OpenPGP\n"); + break; + case KEYBOX_BLOBTYPE_X509: + fprintf (fp, "Type: X.509\n"); + break; + default: + fprintf (fp, "Type: %d\n", type); + fprintf (fp, "[can't dump this blob type]\n"); + return 0; + } + /* Here we have either BLOGTYPE_X509 or BLOBTYPE_OPENPGP */ + fprintf (fp, "Version: %d\n", buffer[5]); + is_fpr32 = buffer[5] == 2; + + if (length < 40) + { + fprintf (fp, "[blob too short]\n"); + return -1; + } + + n = get16 (buffer + 6); + fprintf( fp, "Blob-Flags: %04lX", n); + if (n) + { + int any = 0; + + fputs (" (", fp); + if ((n & 1)) + { + fputs ("secret", fp); + any++; + } + if ((n & 2)) + { + if (any) + putc (',', fp); + fputs ("ephemeral", fp); + any++; + } + putc (')', fp); + } + putc ('\n', fp); + + rawdata_off = get32 (buffer + 8); + rawdata_len = get32 (buffer + 12); + + fprintf( fp, "Data-Offset: %lu\n", rawdata_off ); + fprintf( fp, "Data-Length: %lu\n", rawdata_len ); + if (rawdata_off > length || rawdata_len > length + || rawdata_off+rawdata_len > length + || rawdata_len + 4 > length + || rawdata_off+rawdata_len + 4 > length) + { + fprintf (fp, "[Error: raw data larger than blob]\n"); + return -1; + } + + if (rawdata_off > length + || rawdata_len > length + || rawdata_off + rawdata_len > length) + { + fprintf (fp, "[Error: unhashed data larger than blob]\n"); + return -1; + } + unhashed = length - rawdata_off - rawdata_len; + fprintf (fp, "Unhashed: %lu\n", unhashed); + + nkeys = get16 (buffer + 16); + fprintf (fp, "Key-Count: %lu\n", nkeys ); + if (!nkeys) + fprintf (fp, "[Error: no keys]\n"); + if (nkeys > 1 && type == KEYBOX_BLOBTYPE_X509) + fprintf (fp, "[Error: only one key allowed for X509]\n"); + + keyinfolen = get16 (buffer + 18 ); + fprintf (fp, "Key-Info-Length: %lu\n", keyinfolen); + p = buffer + 20; + pend = buffer + length; + for (n=0; n < nkeys; n++, p += keyinfolen) + { + ulong kidoff, kflags; + + if (p + keyinfolen >= pend) + { + fprintf (fp, "[Error: key data larger than blob]\n"); + return -1; + } + + fprintf (fp, "Key-Fpr[%lu]: ", n ); + if (is_fpr32) + { + if (p + 32 + 2 >= pend) + { + fprintf (fp, "[Error: fingerprint data larger than blob]\n"); + return -1; + } + kflags = get16 (p + 32 ); + for (i=0; i < ((kflags & 0x80)?32:20); i++ ) + fprintf (fp, "%02X", p[i]); + } + else + { + if (p + 20 + 4 >= pend) + { + fprintf (fp, "[Error: fingerprint data larger than blob]\n"); + return -1; + } + for (i=0; i < 20; i++ ) + fprintf (fp, "%02X", p[i]); + kidoff = get32 (p + 20); + fprintf (fp, "\nKey-Kid-Off[%lu]: %lu\n", n, kidoff ); + fprintf (fp, "Key-Kid[%lu]: ", n ); + + if (p + kidoff + 8 >= pend) + { + fprintf (fp, "[Error: fingerprint data larger than blob]\n"); + return -1; + } + for (i=0; i < 8; i++ ) + fprintf (fp, "%02X", buffer[kidoff+i] ); + if (p + 24 >= pend) + { + fprintf (fp, "[Error: fingerprint data larger than blob]\n"); + return -1; + } + kflags = get16 (p + 24); + } + fprintf( fp, "\nKey-Flags[%lu]: %04lX\n", n, kflags); + } + + /* serial number */ + if (p + 2 >= pend) + { + fprintf (fp, "[Error: data larger than blob]\n"); + return -1; + } + fputs ("Serial-No: ", fp); + nserial = get16 (p); + p += 2; + if (!nserial) + fputs ("none", fp); + else + { + if (p + nserial >= pend) + { + fprintf (fp, "[Error: data larger than blob]\n"); + return -1; + } + for (; nserial; nserial--, p++) + fprintf (fp, "%02X", *p); + } + putc ('\n', fp); + + /* user IDs */ + if (p + 4 >= pend) + { + fprintf (fp, "[Error: data larger than blob]\n"); + return -1; + } + nuids = get16 (p); + fprintf (fp, "Uid-Count: %lu\n", nuids ); + uidinfolen = get16 (p + 2); + fprintf (fp, "Uid-Info-Length: %lu\n", uidinfolen); + p += 4; + for (n=0; n < nuids; n++, p += uidinfolen) + { + ulong uidoff, uidlen, uflags; + + if (p + uidinfolen >= pend || uidinfolen < 8) + { + fprintf (fp, "[Error: data larger than blob]\n"); + return -1; + } + + uidoff = get32( p ); + uidlen = get32( p+4 ); + if (type == KEYBOX_BLOBTYPE_X509 && !n) + { + fprintf (fp, "Issuer-Off: %lu\n", uidoff ); + fprintf (fp, "Issuer-Len: %lu\n", uidlen ); + fprintf (fp, "Issuer: \""); + } + else if (type == KEYBOX_BLOBTYPE_X509 && n == 1) + { + fprintf (fp, "Subject-Off: %lu\n", uidoff ); + fprintf (fp, "Subject-Len: %lu\n", uidlen ); + fprintf (fp, "Subject: \""); + } + else + { + fprintf (fp, "Uid-Off[%lu]: %lu\n", n, uidoff ); + fprintf (fp, "Uid-Len[%lu]: %lu\n", n, uidlen ); + fprintf (fp, "Uid[%lu]: \"", n ); + } + + if (uidoff + uidlen > length + || uidoff + uidlen < uidoff + || uidoff + uidlen < uidlen) + { + fprintf (fp, "[Error: data larger than blob]\n"); + return -1; + } + print_string (fp, buffer+uidoff, uidlen, '\"'); + fputs ("\"\n", fp); + if (p + 8 + 2 + 1 >= pend) + { + fprintf (fp, "[Error: data larger than blob]\n"); + return -1; + } + uflags = get16 (p + 8); + if (type == KEYBOX_BLOBTYPE_X509 && !n) + { + fprintf (fp, "Issuer-Flags: %04lX\n", uflags ); + fprintf (fp, "Issuer-Validity: %d\n", p[10] ); + } + else if (type == KEYBOX_BLOBTYPE_X509 && n == 1) + { + fprintf (fp, "Subject-Flags: %04lX\n", uflags ); + fprintf (fp, "Subject-Validity: %d\n", p[10] ); + } + else + { + fprintf (fp, "Uid-Flags[%lu]: %04lX\n", n, uflags ); + fprintf (fp, "Uid-Validity[%lu]: %d\n", n, p[10] ); + } + } + + if (p + 2 + 2 >= pend) + { + fprintf (fp, "[Error: data larger than blob]\n"); + return -1; + } + nsigs = get16 (p); + fprintf (fp, "Sig-Count: %lu\n", nsigs ); + siginfolen = get16 (p + 2); + fprintf (fp, "Sig-Info-Length: %lu\n", siginfolen ); + p += 4; + { + int in_range = 0; + ulong first = 0; + + for (n=0; n < nsigs; n++, p += siginfolen) + { + ulong sflags; + + if (p + siginfolen >= pend || siginfolen < 4) + { + fprintf (fp, "[Error: data larger than blob]\n"); + return -1; + } + sflags = get32 (p); + if (!in_range && !sflags) + { + in_range = 1; + first = n; + continue; + } + if (in_range && !sflags) + continue; + if (in_range) + { + fprintf (fp, "Sig-Expire[%lu-%lu]: [not checked]\n", first, n-1); + in_range = 0; + } + + fprintf (fp, "Sig-Expire[%lu]: ", n ); + if (!sflags) + fputs ("[not checked]", fp); + else if (sflags == 1 ) + fputs ("[missing key]", fp); + else if (sflags == 2 ) + fputs ("[bad signature]", fp); + else if (sflags < 0x10000000) + fprintf (fp, "[bad flag %0lx]", sflags); + else if (sflags == (ulong)(-1)) + fputs ("[good - does not expire]", fp ); + else + fprintf (fp, "[good - expires at %lu]", sflags); + putc ('\n', fp ); + } + if (in_range) + fprintf (fp, "Sig-Expire[%lu-%lu]: [not checked]\n", first, n-1); + } + + if (p + 16 >= pend) + { + fprintf (fp, "[Error: data larger than blob]\n"); + return -1; + } + fprintf (fp, "Ownertrust: %d\n", p[0] ); + fprintf (fp, "All-Validity: %d\n", p[1] ); + p += 4; + n = get32 (p); + p += 4; + fprintf (fp, "Recheck-After: %lu\n", n ); + n = get32 (p ); + p += 4; + fprintf( fp, "Latest-Timestamp: %lu\n", n ); + n = get32 (p ); + p += 4; + fprintf (fp, "Created-At: %lu\n", n ); + + if (p + 4 >= pend) + { + fprintf (fp, "[Error: data larger than blob]\n"); + return -1; + } + n = get32 (p ); + fprintf (fp, "Reserved-Space: %lu\n", n ); + + if (n >= 4 && unhashed >= 24) + { + n = get32 ( buffer + length - unhashed); + fprintf (fp, "Storage-Flags: %08lx\n", n ); + } + print_checksum (buffer, length, unhashed, fp); + return 0; +} + + +/* Compute the SHA-1 checksum of the rawdata in BLOB and put it into + DIGEST. */ +static int +hash_blob_rawdata (KEYBOXBLOB blob, unsigned char *digest) +{ + const unsigned char *buffer; + size_t n, length; + int type; + ulong rawdata_off, rawdata_len; + + buffer = _keybox_get_blob_image (blob, &length); + + if (length < 32) + return -1; + n = get32 (buffer); + if (n < length) + length = n; /* Blob larger than length in header - ignore the rest. */ + + type = buffer[4]; + switch (type) + { + case KEYBOX_BLOBTYPE_PGP: + case KEYBOX_BLOBTYPE_X509: + break; + + case KEYBOX_BLOBTYPE_EMPTY: + case KEYBOX_BLOBTYPE_HEADER: + default: + memset (digest, 0, 20); + return 0; + } + + if (length < 40) + return -1; + + rawdata_off = get32 (buffer + 8); + rawdata_len = get32 (buffer + 12); + + if (rawdata_off > length || rawdata_len > length + || rawdata_off+rawdata_off > length) + return -1; /* Out of bounds. */ + + gcry_md_hash_buffer (GCRY_MD_SHA1, digest, buffer+rawdata_off, rawdata_len); + return 0; +} + + +struct file_stats_s +{ + unsigned long too_short_blobs; + unsigned long too_large_blobs; + unsigned long total_blob_count; + unsigned long empty_blob_count; + unsigned long header_blob_count; + unsigned long pgp_blob_count; + unsigned long x509_blob_count; + unsigned long unknown_blob_count; + unsigned long non_flagged; + unsigned long secret_flagged; + unsigned long ephemeral_flagged; + unsigned long skipped_long_blobs; +}; + +static int +update_stats (KEYBOXBLOB blob, struct file_stats_s *s) +{ + const unsigned char *buffer; + size_t length; + int type; + unsigned long n; + + buffer = _keybox_get_blob_image (blob, &length); + if (length < 32) + { + s->too_short_blobs++; + return -1; + } + + n = get32( buffer ); + if (n > length) + s->too_large_blobs++; + else + length = n; /* ignore the rest */ + + s->total_blob_count++; + type = buffer[4]; + switch (type) + { + case KEYBOX_BLOBTYPE_EMPTY: + s->empty_blob_count++; + return 0; + case KEYBOX_BLOBTYPE_HEADER: + s->header_blob_count++; + return 0; + case KEYBOX_BLOBTYPE_PGP: + s->pgp_blob_count++; + break; + case KEYBOX_BLOBTYPE_X509: + s->x509_blob_count++; + break; + default: + s->unknown_blob_count++; + return 0; + } + + if (length < 40) + { + s->too_short_blobs++; + return -1; + } + + n = get16 (buffer + 6); + if (n) + { + if ((n & 1)) + s->secret_flagged++; + if ((n & 2)) + s->ephemeral_flagged++; + } + else + s->non_flagged++; + + return 0; +} + + + +static estream_t +open_file (const char **filename, FILE *outfp) +{ + estream_t fp; + + if (!*filename) + { + *filename = "-"; + fp = es_stdin; + } + else + fp = es_fopen (*filename, "rb"); + if (!fp) + { + int save_errno = errno; + fprintf (outfp, "can't open '%s': %s\n", *filename, strerror(errno)); + gpg_err_set_errno (save_errno); + } + return fp; +} + + + +int +_keybox_dump_file (const char *filename, int stats_only, FILE *outfp) +{ + estream_t fp; + KEYBOXBLOB blob; + int rc; + unsigned long count = 0; + struct file_stats_s stats; + int skipped_deleted; + + memset (&stats, 0, sizeof stats); + + if (!(fp = open_file (&filename, outfp))) + return gpg_error_from_syserror (); + + for (;;) + { + rc = _keybox_read_blob (&blob, fp, &skipped_deleted); + if (gpg_err_code (rc) == GPG_ERR_TOO_LARGE + && gpg_err_source (rc) == GPG_ERR_SOURCE_KEYBOX) + { + if (stats_only) + stats.skipped_long_blobs++; + else + { + fprintf (outfp, "BEGIN-RECORD: %lu\n", count ); + fprintf (outfp, "# Record too large\nEND-RECORD\n"); + } + count++; + continue; + } + if (rc) + break; + + count += skipped_deleted; + + if (stats_only) + { + stats.total_blob_count += skipped_deleted; + stats.empty_blob_count += skipped_deleted; + update_stats (blob, &stats); + } + else + { + fprintf (outfp, "BEGIN-RECORD: %lu\n", count ); + _keybox_dump_blob (blob, outfp); + fprintf (outfp, "END-RECORD\n"); + } + _keybox_release_blob (blob); + count++; + } + if (rc == -1) + rc = 0; + if (rc) + fprintf (outfp, "# error reading '%s': %s\n", filename, gpg_strerror (rc)); + + if (fp != es_stdin) + es_fclose (fp); + + if (stats_only) + { + fprintf (outfp, + "Total number of blobs: %8lu\n" + " header: %8lu\n" + " empty: %8lu\n" + " openpgp: %8lu\n" + " x509: %8lu\n" + " non flagged: %8lu\n" + " secret flagged: %8lu\n" + " ephemeral flagged: %8lu\n", + stats.total_blob_count, + stats.header_blob_count, + stats.empty_blob_count, + stats.pgp_blob_count, + stats.x509_blob_count, + stats.non_flagged, + stats.secret_flagged, + stats.ephemeral_flagged); + if (stats.skipped_long_blobs) + fprintf (outfp, " skipped long blobs: %8lu\n", + stats.skipped_long_blobs); + if (stats.unknown_blob_count) + fprintf (outfp, " unknown blob types: %8lu\n", + stats.unknown_blob_count); + if (stats.too_short_blobs) + fprintf (outfp, " too short blobs: %8lu (error)\n", + stats.too_short_blobs); + if (stats.too_large_blobs) + fprintf (outfp, " too large blobs: %8lu (error)\n", + stats.too_large_blobs); + } + + return rc; +} + + + +struct dupitem_s +{ + unsigned long recno; + unsigned char digest[20]; +}; + + +static int +cmp_dupitems (const void *arg_a, const void *arg_b) +{ + struct dupitem_s *a = (struct dupitem_s *)arg_a; + struct dupitem_s *b = (struct dupitem_s *)arg_b; + + return memcmp (a->digest, b->digest, 20); +} + + +int +_keybox_dump_find_dups (const char *filename, int print_them, FILE *outfp) +{ + estream_t fp; + KEYBOXBLOB blob; + int rc; + unsigned long recno = 0; + unsigned char zerodigest[20]; + struct dupitem_s *dupitems; + size_t dupitems_size, dupitems_count, lastn, n; + char fprbuf[3*20+1]; + + (void)print_them; + + memset (zerodigest, 0, sizeof zerodigest); + + if (!(fp = open_file (&filename, outfp))) + return gpg_error_from_syserror (); + + dupitems_size = 1000; + dupitems = malloc (dupitems_size * sizeof *dupitems); + if (!dupitems) + { + gpg_error_t tmperr = gpg_error_from_syserror (); + fprintf (outfp, "error allocating array for '%s': %s\n", + filename, strerror(errno)); + return tmperr; + } + dupitems_count = 0; + + while ( !(rc = _keybox_read_blob (&blob, fp, NULL)) ) + { + unsigned char digest[20]; + + if (hash_blob_rawdata (blob, digest)) + fprintf (outfp, "error in blob %ld of '%s'\n", recno, filename); + else if (memcmp (digest, zerodigest, 20)) + { + if (dupitems_count >= dupitems_size) + { + struct dupitem_s *tmp; + + dupitems_size += 1000; + tmp = realloc (dupitems, dupitems_size * sizeof *dupitems); + if (!tmp) + { + gpg_error_t tmperr = gpg_error_from_syserror (); + fprintf (outfp, "error reallocating array for '%s': %s\n", + filename, strerror(errno)); + free (dupitems); + return tmperr; + } + dupitems = tmp; + } + dupitems[dupitems_count].recno = recno; + memcpy (dupitems[dupitems_count].digest, digest, 20); + dupitems_count++; + } + _keybox_release_blob (blob); + recno++; + } + if (rc == -1) + rc = 0; + if (rc) + fprintf (outfp, "error reading '%s': %s\n", filename, gpg_strerror (rc)); + if (fp != es_stdin) + es_fclose (fp); + + qsort (dupitems, dupitems_count, sizeof *dupitems, cmp_dupitems); + + for (lastn=0, n=1; n < dupitems_count; lastn=n, n++) + { + if (!memcmp (dupitems[lastn].digest, dupitems[n].digest, 20)) + { + bin2hexcolon (dupitems[lastn].digest, 20, fprbuf); + fprintf (outfp, "fpr=%s recno=%lu", fprbuf, dupitems[lastn].recno); + do + fprintf (outfp, " %lu", dupitems[n].recno); + while (++n < dupitems_count + && !memcmp (dupitems[lastn].digest, dupitems[n].digest, 20)); + putc ('\n', outfp); + n--; + } + } + + free (dupitems); + + return rc; +} + + +/* Print records with record numbers FROM to TO to OUTFP. */ +int +_keybox_dump_cut_records (const char *filename, unsigned long from, + unsigned long to, FILE *outfp) +{ + estream_t fp; + KEYBOXBLOB blob; + int rc; + unsigned long recno = 0; + + if (!(fp = open_file (&filename, stderr))) + return gpg_error_from_syserror (); + + while ( !(rc = _keybox_read_blob (&blob, fp, NULL)) ) + { + if (recno > to) + break; /* Ready. */ + if (recno >= from) + { + if ((rc = _keybox_write_blob (blob, NULL, outfp))) + { + fprintf (stderr, "error writing output: %s\n", + gpg_strerror (rc)); + goto leave; + } + } + _keybox_release_blob (blob); + recno++; + } + if (rc == -1) + rc = 0; + if (rc) + fprintf (stderr, "error reading '%s': %s\n", filename, gpg_strerror (rc)); + leave: + if (fp != es_stdin) + es_fclose (fp); + return rc; +} diff --git a/kbx/keybox-file.c b/kbx/keybox-file.c new file mode 100644 index 0000000..c36f5be --- /dev/null +++ b/kbx/keybox-file.c @@ -0,0 +1,190 @@ +/* keybox-file.c - File operations + * Copyright (C) 2001, 2003 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG 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 3 of the License, or + * (at your option) any later version. + * + * GnuPG 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, see <https://www.gnu.org/licenses/>. + */ + +#include <config.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <time.h> + +#include "keybox-defs.h" + + +#define IMAGELEN_LIMIT (5*1024*1024) + + +#if !defined(HAVE_FTELLO) && !defined(ftello) +static off_t +ftello (FILE *stream) +{ + long int off; + + off = ftell (stream); + if (off == -1) + return (off_t)-1; + return off; +} +#endif /* !defined(HAVE_FTELLO) && !defined(ftello) */ + + + +/* Read a block at the current position and return it in R_BLOB. + R_BLOB may be NULL to simply skip the current block. */ +int +_keybox_read_blob (KEYBOXBLOB *r_blob, estream_t fp, int *skipped_deleted) +{ + unsigned char *image; + size_t imagelen = 0; + int c1, c2, c3, c4, type; + int rc; + off_t off; + + if (skipped_deleted) + *skipped_deleted = 0; + again: + if (r_blob) + *r_blob = NULL; + off = es_ftello (fp); + if (off == (off_t)-1) + return gpg_error_from_syserror (); + + if ((c1 = es_getc (fp)) == EOF + || (c2 = es_getc (fp)) == EOF + || (c3 = es_getc (fp)) == EOF + || (c4 = es_getc (fp)) == EOF + || (type = es_getc (fp)) == EOF) + { + if ( c1 == EOF && !es_ferror (fp) ) + return -1; /* eof */ + if (!es_ferror (fp)) + return gpg_error (GPG_ERR_TOO_SHORT); + return gpg_error_from_syserror (); + } + + imagelen = ((unsigned int) c1 << 24) | (c2 << 16) | (c3 << 8 ) | c4; + if (imagelen < 5) + return gpg_error (GPG_ERR_TOO_SHORT); + + if (!type) + { + /* Special treatment for empty blobs. */ + if (es_fseek (fp, imagelen-5, SEEK_CUR)) + return gpg_error_from_syserror (); + if (skipped_deleted) + *skipped_deleted = 1; + goto again; + } + + if (imagelen > IMAGELEN_LIMIT) /* Sanity check. */ + { + /* Seek forward so that the caller may choose to ignore this + record. */ + if (es_fseek (fp, imagelen-5, SEEK_CUR)) + return gpg_error_from_syserror (); + return gpg_error (GPG_ERR_TOO_LARGE); + } + + if (!r_blob) + { + /* This blob shall be skipped. */ + if (es_fseek (fp, imagelen-5, SEEK_CUR)) + return gpg_error_from_syserror (); + return 0; + } + + image = xtrymalloc (imagelen); + if (!image) + return gpg_error_from_syserror (); + + image[0] = c1; image[1] = c2; image[2] = c3; image[3] = c4; image[4] = type; + if (es_fread (image+5, imagelen-5, 1, fp) != 1) + { + gpg_error_t tmperr = gpg_error_from_syserror (); + xfree (image); + return tmperr; + } + + rc = _keybox_new_blob (r_blob, image, imagelen, off); + if (rc) + xfree (image); + return rc; +} + + +/* Write the block to the current file position */ +int +_keybox_write_blob (KEYBOXBLOB blob, estream_t fp, FILE *outfp) +{ + const unsigned char *image; + size_t length; + + image = _keybox_get_blob_image (blob, &length); + + if (length > IMAGELEN_LIMIT) + return gpg_error (GPG_ERR_TOO_LARGE); + + if (fp) + { + if (es_fwrite (image, length, 1, fp) != 1) + return gpg_error_from_syserror (); + } + else + { + if (fwrite (image, length, 1, outfp) != 1) + return gpg_error_from_syserror (); + } + + return 0; +} + + +/* Write a fresh header type blob. */ +int +_keybox_write_header_blob (estream_t fp, int for_openpgp) +{ + unsigned char image[32]; + u32 val; + + memset (image, 0, sizeof image); + /* Length of this blob. */ + image[3] = 32; + + image[4] = KEYBOX_BLOBTYPE_HEADER; + image[5] = 1; /* Version */ + if (for_openpgp) + image[7] = 0x02; /* OpenPGP data may be available. */ + + memcpy (image+8, "KBXf", 4); + val = time (NULL); + /* created_at and last maintenance run. */ + image[16] = (val >> 24); + image[16+1] = (val >> 16); + image[16+2] = (val >> 8); + image[16+3] = (val ); + image[20] = (val >> 24); + image[20+1] = (val >> 16); + image[20+2] = (val >> 8); + image[20+3] = (val ); + + if (es_fwrite (image, 32, 1, fp) != 1) + return gpg_error_from_syserror (); + + return 0; +} diff --git a/kbx/keybox-init.c b/kbx/keybox-init.c new file mode 100644 index 0000000..6cabaea --- /dev/null +++ b/kbx/keybox-init.c @@ -0,0 +1,332 @@ +/* keybox-init.c - Initialization of the library + * Copyright (C) 2001 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG 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 3 of the License, or + * (at your option) any later version. + * + * GnuPG 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, see <https://www.gnu.org/licenses/>. + */ + +#include <config.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <assert.h> + +#include "keybox-defs.h" +#include "../common/sysutils.h" +#include "../common/mischelp.h" + +static KB_NAME kb_names; + + +/* Register a filename for plain keybox files. Returns 0 on success, + * GPG_ERR_EEXIST if it has already been registered, or another error + * code. On success or with error code GPG_ERR_EEXIST a token usable + * to access the keybox handle is stored at R_TOKEN, NULL is stored + * for all other errors. */ +gpg_error_t +keybox_register_file (const char *fname, int secret, void **r_token) +{ + KB_NAME kr; + + *r_token = NULL; + + for (kr=kb_names; kr; kr = kr->next) + { + if (same_file_p (kr->fname, fname) ) + { + *r_token = kr; + return gpg_error (GPG_ERR_EEXIST); /* Already registered. */ + } + } + + kr = xtrymalloc (sizeof *kr + strlen (fname)); + if (!kr) + return gpg_error_from_syserror (); + strcpy (kr->fname, fname); + kr->secret = !!secret; + + kr->handle_table = NULL; + kr->handle_table_size = 0; + + kr->lockhd = NULL; + kr->is_locked = 0; + kr->did_full_scan = 0; + /* keep a list of all issued pointers */ + kr->next = kb_names; + kb_names = kr; + + /* create the offset table the first time a function here is used */ +/* if (!kb_offtbl) */ +/* kb_offtbl = new_offset_hash_table (); */ + + *r_token = kr; + return 0; +} + +int +keybox_is_writable (void *token) +{ + KB_NAME r = token; + + return r? !gnupg_access (r->fname, W_OK) : 0; +} + + + +static KEYBOX_HANDLE +do_keybox_new (KB_NAME resource, int secret, int for_openpgp) +{ + KEYBOX_HANDLE hd; + int idx; + + assert (resource && !resource->secret == !secret); + hd = xtrycalloc (1, sizeof *hd); + if (hd) + { + hd->kb = resource; + hd->secret = !!secret; + hd->for_openpgp = for_openpgp; + if (!resource->handle_table) + { + resource->handle_table_size = 3; + resource->handle_table = xtrycalloc (resource->handle_table_size, + sizeof *resource->handle_table); + if (!resource->handle_table) + { + resource->handle_table_size = 0; + xfree (hd); + return NULL; + } + } + for (idx=0; idx < resource->handle_table_size; idx++) + if (!resource->handle_table[idx]) + { + resource->handle_table[idx] = hd; + break; + } + if (!(idx < resource->handle_table_size)) + { + KEYBOX_HANDLE *tmptbl; + size_t newsize; + + newsize = resource->handle_table_size + 5; + tmptbl = xtryrealloc (resource->handle_table, + newsize * sizeof (*tmptbl)); + if (!tmptbl) + { + xfree (hd); + return NULL; + } + resource->handle_table = tmptbl; + resource->handle_table_size = newsize; + resource->handle_table[idx] = hd; + for (idx++; idx < resource->handle_table_size; idx++) + resource->handle_table[idx] = NULL; + } + } + return hd; +} + + +/* Create a new handle for the resource associated with TOKEN. SECRET + is just a cross-check. This is the OpenPGP version. The returned + handle must be released using keybox_release. */ +KEYBOX_HANDLE +keybox_new_openpgp (void *token, int secret) +{ + KB_NAME resource = token; + + return do_keybox_new (resource, secret, 1); +} + +/* Create a new handle for the resource associated with TOKEN. SECRET + is just a cross-check. This is the X.509 version. The returned + handle must be released using keybox_release. */ +KEYBOX_HANDLE +keybox_new_x509 (void *token, int secret) +{ + KB_NAME resource = token; + + return do_keybox_new (resource, secret, 0); +} + + +void +keybox_release (KEYBOX_HANDLE hd) +{ + if (!hd) + return; + if (hd->kb->handle_table) + { + int idx; + for (idx=0; idx < hd->kb->handle_table_size; idx++) + if (hd->kb->handle_table[idx] == hd) + hd->kb->handle_table[idx] = NULL; + } + _keybox_release_blob (hd->found.blob); + _keybox_release_blob (hd->saved_found.blob); + if (hd->fp) + { + es_fclose (hd->fp); + hd->fp = NULL; + } + xfree (hd->word_match.name); + xfree (hd->word_match.pattern); + xfree (hd); +} + + +/* Save the current found state in HD for later retrieval by + keybox_restore_found_state. Only one state may be saved. */ +void +keybox_push_found_state (KEYBOX_HANDLE hd) +{ + if (hd->saved_found.blob) + { + _keybox_release_blob (hd->saved_found.blob); + hd->saved_found.blob = NULL; + } + hd->saved_found = hd->found; + hd->found.blob = NULL; +} + + +/* Restore the saved found state in HD. */ +void +keybox_pop_found_state (KEYBOX_HANDLE hd) +{ + if (hd->found.blob) + { + _keybox_release_blob (hd->found.blob); + hd->found.blob = NULL; + } + hd->found = hd->saved_found; + hd->saved_found.blob = NULL; +} + + +const char * +keybox_get_resource_name (KEYBOX_HANDLE hd) +{ + if (!hd || !hd->kb) + return NULL; + return hd->kb->fname; +} + +int +keybox_set_ephemeral (KEYBOX_HANDLE hd, int yes) +{ + if (!hd) + return gpg_error (GPG_ERR_INV_HANDLE); + hd->ephemeral = yes; + return 0; +} + + +/* Close the file of the resource identified by HD. For consistent + results this function closes the files of all handles pointing to + the resource identified by HD. */ +void +_keybox_close_file (KEYBOX_HANDLE hd) +{ + int idx; + KEYBOX_HANDLE roverhd; + + if (!hd || !hd->kb || !hd->kb->handle_table) + return; + + for (idx=0; idx < hd->kb->handle_table_size; idx++) + if ((roverhd = hd->kb->handle_table[idx])) + { + if (roverhd->fp) + { + es_fclose (roverhd->fp); + roverhd->fp = NULL; + } + } + log_assert (!hd->fp); +} + + +/* + * Lock the keybox at handle HD, or unlock if YES is false. + * Lock the keybox at handle HD, or unlock if YES is false. TIMEOUT + * is the value used for dotlock_take. In general -1 should be used + * when taking a lock; use 0 when releasing a lock. + */ +gpg_error_t +keybox_lock (KEYBOX_HANDLE hd, int yes, long timeout) +{ + gpg_error_t err = 0; + KB_NAME kb = hd->kb; + + if (!keybox_is_writable (kb)) + return 0; + + /* Make sure the lock handle has been created. */ + if (!kb->lockhd) + { + kb->lockhd = dotlock_create (kb->fname, 0); + if (!kb->lockhd) + { + err = gpg_error_from_syserror (); + log_info ("can't allocate lock for '%s'\n", kb->fname ); + return err; + } + } + + if (yes) /* Take the lock. */ + { + if (!kb->is_locked) + { +#ifdef HAVE_W32_SYSTEM + /* Under Windows we need to close the file before we try + * to lock it. This is because another process might have + * taken the lock and is using keybox_file_rename to + * rename the base file. Now if our dotlock_take below is + * waiting for the lock but we have the base file still + * open, keybox_file_rename will never succeed as we are + * in a deadlock. */ + _keybox_close_file (hd); +#endif /*HAVE_W32_SYSTEM*/ + if (dotlock_take (kb->lockhd, timeout)) + { + err = gpg_error_from_syserror (); + if (!timeout && gpg_err_code (err) == GPG_ERR_EACCES) + ; /* No diagnostic if we only tried to lock. */ + else + log_info ("can't lock '%s'\n", kb->fname ); + } + else + kb->is_locked = 1; + } + } + else /* Release the lock. */ + { + if (kb->is_locked) + { + if (dotlock_release (kb->lockhd)) + { + err = gpg_error_from_syserror (); + log_info ("can't unlock '%s'\n", kb->fname ); + } + else + kb->is_locked = 0; + } + } + + return err; +} diff --git a/kbx/keybox-openpgp.c b/kbx/keybox-openpgp.c new file mode 100644 index 0000000..8ded683 --- /dev/null +++ b/kbx/keybox-openpgp.c @@ -0,0 +1,643 @@ +/* keybox-openpgp.c - OpenPGP key parsing + * Copyright (C) 2001, 2003, 2011 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG 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 3 of the License, or + * (at your option) any later version. + * + * GnuPG 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, see <https://www.gnu.org/licenses/>. + */ + +/* This is a simple OpenPGP parser suitable for all OpenPGP key + material. It just provides the functionality required to build and + parse an KBX OpenPGP key blob. Thus it is not a complete parser. + However it is self-contained and optimized for fast in-memory + parsing. Note that we don't support old ElGamal v3 keys + anymore. */ + +#include <config.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <assert.h> + +#include "keybox-defs.h" + +#include <gcrypt.h> + +#include "../common/openpgpdefs.h" +#include "../common/host2net.h" + +struct keyparm_s +{ + const char *mpi; + int len; /* int to avoid a cast in gcry_sexp_build. */ +}; + + +/* Assume a valid OpenPGP packet at the address pointed to by BUFBTR + which has a maximum length as stored at BUFLEN. Return the header + information of that packet and advance the pointer stored at BUFPTR + to the next packet; also adjust the length stored at BUFLEN to + match the remaining bytes. If there are no more packets, store NULL + at BUFPTR. Return an non-zero error code on failure or the + following data on success: + + R_DATAPKT = Pointer to the begin of the packet data. + R_DATALEN = Length of this data. This has already been checked to fit + into the buffer. + R_PKTTYPE = The packet type. + R_NTOTAL = The total number of bytes of this packet + + Note that these values are only updated on success. +*/ +static gpg_error_t +next_packet (unsigned char const **bufptr, size_t *buflen, + unsigned char const **r_data, size_t *r_datalen, int *r_pkttype, + size_t *r_ntotal) +{ + const unsigned char *buf = *bufptr; + size_t len = *buflen; + int c, ctb, pkttype; + unsigned long pktlen; + + if (!len) + return gpg_error (GPG_ERR_NO_DATA); + + ctb = *buf++; len--; + if ( !(ctb & 0x80) ) + return gpg_error (GPG_ERR_INV_PACKET); /* Invalid CTB. */ + + if ((ctb & 0x40)) /* New style (OpenPGP) CTB. */ + { + pkttype = (ctb & 0x3f); + if (!len) + return gpg_error (GPG_ERR_INV_PACKET); /* No 1st length byte. */ + c = *buf++; len--; + if (pkttype == PKT_COMPRESSED) + return gpg_error (GPG_ERR_UNEXPECTED); /* ... packet in a keyblock. */ + if ( c < 192 ) + pktlen = c; + else if ( c < 224 ) + { + pktlen = (c - 192) * 256; + if (!len) + return gpg_error (GPG_ERR_INV_PACKET); /* No 2nd length byte. */ + c = *buf++; len--; + pktlen += c + 192; + } + else if (c == 255) + { + if (len <4 ) + return gpg_error (GPG_ERR_INV_PACKET); /* No length bytes. */ + pktlen = buf32_to_ulong (buf); + buf += 4; + len -= 4; + } + else /* Partial length encoding is not allowed for key packets. */ + return gpg_error (GPG_ERR_UNEXPECTED); + } + else /* Old style CTB. */ + { + int lenbytes; + + pktlen = 0; + pkttype = (ctb>>2)&0xf; + lenbytes = ((ctb&3)==3)? 0 : (1<<(ctb & 3)); + if (!lenbytes) /* Not allowed in key packets. */ + return gpg_error (GPG_ERR_UNEXPECTED); + if (len < lenbytes) + return gpg_error (GPG_ERR_INV_PACKET); /* Not enough length bytes. */ + for (; lenbytes; lenbytes--) + { + pktlen <<= 8; + pktlen |= *buf++; len--; + } + } + + /* Do some basic sanity check. */ + switch (pkttype) + { + case PKT_SIGNATURE: + case PKT_SECRET_KEY: + case PKT_PUBLIC_KEY: + case PKT_SECRET_SUBKEY: + case PKT_MARKER: + case PKT_RING_TRUST: + case PKT_USER_ID: + case PKT_PUBLIC_SUBKEY: + case PKT_OLD_COMMENT: + case PKT_ATTRIBUTE: + case PKT_COMMENT: + case PKT_GPG_CONTROL: + break; /* Okay these are allowed packets. */ + default: + return gpg_error (GPG_ERR_UNEXPECTED); + } + + if (pkttype == 63 && pktlen == 0xFFFFFFFF) + /* Sometimes the decompressing layer enters an error state in + which it simply outputs 0xff for every byte read. If we have a + stream of 0xff bytes, then it will be detected as a new format + packet with type 63 and a 4-byte encoded length that is 4G-1. + Since packets with type 63 are private and we use them as a + control packet, which won't be 4 GB, we reject such packets as + invalid. */ + return gpg_error (GPG_ERR_INV_PACKET); + + if (pktlen > len) + return gpg_error (GPG_ERR_INV_PACKET); /* Packet length header too long. */ + + *r_data = buf; + *r_datalen = pktlen; + *r_pkttype = pkttype; + *r_ntotal = (buf - *bufptr) + pktlen; + + *bufptr = buf + pktlen; + *buflen = len - pktlen; + if (!*buflen) + *bufptr = NULL; + + return 0; +} + + +/* Take a list of key parameters KP for the OpenPGP ALGO and compute + * the keygrip which will be stored at GRIP. GRIP needs to be a + * buffer of 20 bytes. */ +static gpg_error_t +keygrip_from_keyparm (int algo, struct keyparm_s *kp, unsigned char *grip) +{ + gpg_error_t err; + gcry_sexp_t s_pkey = NULL; + + switch (algo) + { + case PUBKEY_ALGO_DSA: + err = gcry_sexp_build (&s_pkey, NULL, + "(public-key(dsa(p%b)(q%b)(g%b)(y%b)))", + kp[0].len, kp[0].mpi, + kp[1].len, kp[1].mpi, + kp[2].len, kp[2].mpi, + kp[3].len, kp[3].mpi); + break; + + case PUBKEY_ALGO_ELGAMAL: + case PUBKEY_ALGO_ELGAMAL_E: + err = gcry_sexp_build (&s_pkey, NULL, + "(public-key(elg(p%b)(g%b)(y%b)))", + kp[0].len, kp[0].mpi, + kp[1].len, kp[1].mpi, + kp[2].len, kp[2].mpi); + break; + + case PUBKEY_ALGO_RSA: + case PUBKEY_ALGO_RSA_S: + case PUBKEY_ALGO_RSA_E: + err = gcry_sexp_build (&s_pkey, NULL, + "(public-key(rsa(n%b)(e%b)))", + kp[0].len, kp[0].mpi, + kp[1].len, kp[1].mpi); + break; + + case PUBKEY_ALGO_EDDSA: + case PUBKEY_ALGO_ECDSA: + case PUBKEY_ALGO_ECDH: + { + char *curve = openpgp_oidbuf_to_str (kp[0].mpi, kp[0].len); + if (!curve) + err = gpg_error_from_syserror (); + else + { + err = gcry_sexp_build + (&s_pkey, NULL, + (algo == PUBKEY_ALGO_EDDSA)? + "(public-key(ecc(curve%s)(flags eddsa)(q%b)))": + (algo == PUBKEY_ALGO_ECDH + && openpgp_oidbuf_is_cv25519 (kp[0].mpi, kp[0].len))? + "(public-key(ecc(curve%s)(flags djb-tweak)(q%b)))": + "(public-key(ecc(curve%s)(q%b)))", + curve, kp[1].len, kp[1].mpi); + xfree (curve); + } + } + break; + + default: + err = gpg_error (GPG_ERR_PUBKEY_ALGO); + break; + } + + if (!err && !gcry_pk_get_keygrip (s_pkey, grip)) + { + /* Some Linux distributions remove certain curves from Libgcrypt + * but not from GnuPG and thus the keygrip can't be computed. + * Emit a better error message for this case. */ + if (!gcry_pk_get_curve (s_pkey, 0, NULL)) + err = gpg_error (GPG_ERR_UNKNOWN_CURVE); + else + { + log_info ("kbx: error computing keygrip\n"); + err = gpg_error (GPG_ERR_GENERAL); + } + } + + gcry_sexp_release (s_pkey); + + if (err) + memset (grip, 0, 20); + return err; +} + + +/* Parse a key packet and store the information in KI. */ +static gpg_error_t +parse_key (const unsigned char *data, size_t datalen, + struct _keybox_openpgp_key_info *ki) +{ + gpg_error_t err; + const unsigned char *data_start = data; + int i, version, algorithm; + size_t n; + int npkey; + unsigned char hashbuffer[768]; + gcry_md_hd_t md; + int is_ecc = 0; + struct keyparm_s keyparm[OPENPGP_MAX_NPKEY]; + unsigned char *helpmpibuf[OPENPGP_MAX_NPKEY] = { NULL }; + + if (datalen < 5) + return gpg_error (GPG_ERR_INV_PACKET); + version = *data++; datalen--; + if (version < 2 || version > 4 ) + return gpg_error (GPG_ERR_INV_PACKET); /* Invalid version. */ + + /*timestamp = ((data[0]<<24)|(data[1]<<16)|(data[2]<<8)|(data[3]));*/ + data +=4; datalen -=4; + + if (version < 4) + { + if (datalen < 2) + return gpg_error (GPG_ERR_INV_PACKET); + data +=2; datalen -= 2; + } + + if (!datalen) + return gpg_error (GPG_ERR_INV_PACKET); + algorithm = *data++; datalen--; + + switch (algorithm) + { + case PUBKEY_ALGO_RSA: + case PUBKEY_ALGO_RSA_E: + case PUBKEY_ALGO_RSA_S: + npkey = 2; + break; + case PUBKEY_ALGO_ELGAMAL_E: + case PUBKEY_ALGO_ELGAMAL: + npkey = 3; + break; + case PUBKEY_ALGO_DSA: + npkey = 4; + break; + case PUBKEY_ALGO_ECDH: + npkey = 3; + is_ecc = 1; + break; + case PUBKEY_ALGO_ECDSA: + case PUBKEY_ALGO_EDDSA: + npkey = 2; + is_ecc = 1; + break; + default: /* Unknown algorithm. */ + return gpg_error (GPG_ERR_UNKNOWN_ALGORITHM); + } + + ki->algo = algorithm; + + for (i=0; i < npkey; i++ ) + { + unsigned int nbits, nbytes; + + if (datalen < 2) + return gpg_error (GPG_ERR_INV_PACKET); + + if (is_ecc && (i == 0 || i == 2)) + { + nbytes = data[0]; + if (nbytes < 2 || nbytes > 254) + return gpg_error (GPG_ERR_INV_PACKET); + nbytes++; /* The size byte itself. */ + if (datalen < nbytes) + return gpg_error (GPG_ERR_INV_PACKET); + + keyparm[i].mpi = data; + keyparm[i].len = nbytes; + } + else + { + nbits = ((data[0]<<8)|(data[1])); + data += 2; + datalen -= 2; + nbytes = (nbits+7) / 8; + if (datalen < nbytes) + return gpg_error (GPG_ERR_INV_PACKET); + + keyparm[i].mpi = data; + keyparm[i].len = nbytes; + } + + data += nbytes; datalen -= nbytes; + } + n = data - data_start; + + + /* Note: Starting here we need to jump to leave on error. */ + + /* Make sure the MPIs are unsigned. */ + for (i=0; i < npkey; i++) + { + if (!keyparm[i].len || (keyparm[i].mpi[0] & 0x80)) + { + helpmpibuf[i] = xtrymalloc (1+keyparm[i].len); + if (!helpmpibuf[i]) + { + err = gpg_error_from_syserror (); + goto leave; + } + helpmpibuf[i][0] = 0; + memcpy (helpmpibuf[i]+1, keyparm[i].mpi, keyparm[i].len); + keyparm[i].mpi = helpmpibuf[i]; + keyparm[i].len++; + } + } + + err = keygrip_from_keyparm (algorithm, keyparm, ki->grip); + if (err) + goto leave; + + if (version < 4) + { + /* We do not support any other algorithm than RSA in v3 + packets. */ + if (algorithm < 1 || algorithm > 3) + return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); + + err = gcry_md_open (&md, GCRY_MD_MD5, 0); + if (err) + return err; /* Oops */ + gcry_md_write (md, keyparm[0].mpi, keyparm[0].len); + gcry_md_write (md, keyparm[1].mpi, keyparm[1].len); + memcpy (ki->fpr, gcry_md_read (md, 0), 16); + gcry_md_close (md); + ki->fprlen = 16; + + if (keyparm[0].len < 8) + { + /* Moduli less than 64 bit are out of the specs scope. Zero + them out because this is what gpg does too. */ + memset (ki->keyid, 0, 8); + } + else + memcpy (ki->keyid, keyparm[0].mpi + keyparm[0].len - 8, 8); + } + else + { + /* Its a pity that we need to prefix the buffer with the tag + and a length header: We can't simply pass it to the fast + hashing function for that reason. It might be a good idea to + have a scatter-gather enabled hash function. What we do here + is to use a static buffer if this one is large enough and + only use the regular hash functions if this buffer is not + large enough. */ + if ( 3 + n < sizeof hashbuffer ) + { + hashbuffer[0] = 0x99; /* CTB */ + hashbuffer[1] = (n >> 8); /* 2 byte length header. */ + hashbuffer[2] = n; + memcpy (hashbuffer + 3, data_start, n); + gcry_md_hash_buffer (GCRY_MD_SHA1, ki->fpr, hashbuffer, 3 + n); + } + else + { + err = gcry_md_open (&md, GCRY_MD_SHA1, 0); + if (err) + return err; /* Oops */ + gcry_md_putc (md, 0x99 ); /* CTB */ + gcry_md_putc (md, (n >> 8) ); /* 2 byte length header. */ + gcry_md_putc (md, n ); + gcry_md_write (md, data_start, n); + memcpy (ki->fpr, gcry_md_read (md, 0), 20); + gcry_md_close (md); + } + ki->fprlen = 20; + memcpy (ki->keyid, ki->fpr+12, 8); + } + + leave: + for (i=0; i < npkey; i++) + xfree (helpmpibuf[i]); + + return err; +} + + + +/* The caller must pass the address of an INFO structure which will + get filled on success with information pertaining to the OpenPGP + keyblock IMAGE of length IMAGELEN. Note that a caller does only + need to release this INFO structure if the function returns + success. If NPARSED is not NULL the actual number of bytes parsed + will be stored at this address. */ +gpg_error_t +_keybox_parse_openpgp (const unsigned char *image, size_t imagelen, + size_t *nparsed, keybox_openpgp_info_t info) +{ + gpg_error_t err = 0; + const unsigned char *image_start, *data; + size_t n, datalen; + int pkttype; + int first = 1; + int read_error = 0; + struct _keybox_openpgp_key_info *k, **ktail = NULL; + struct _keybox_openpgp_uid_info *u, **utail = NULL; + + memset (info, 0, sizeof *info); + if (nparsed) + *nparsed = 0; + + image_start = image; + while (image) + { + err = next_packet (&image, &imagelen, &data, &datalen, &pkttype, &n); + if (err) + { + read_error = 1; + break; + } + + if (first) + { + if (pkttype == PKT_PUBLIC_KEY) + ; + else if (pkttype == PKT_SECRET_KEY) + info->is_secret = 1; + else + { + err = gpg_error (GPG_ERR_UNEXPECTED); + if (nparsed) + *nparsed += n; + break; + } + first = 0; + } + else if (pkttype == PKT_PUBLIC_KEY || pkttype == PKT_SECRET_KEY) + break; /* Next keyblock encountered - ready. */ + + if (nparsed) + *nparsed += n; + + if (pkttype == PKT_SIGNATURE) + { + /* For now we only count the total number of signatures. */ + info->nsigs++; + } + else if (pkttype == PKT_USER_ID) + { + info->nuids++; + if (info->nuids == 1) + { + info->uids.off = data - image_start; + info->uids.len = datalen; + utail = &info->uids.next; + } + else + { + u = xtrycalloc (1, sizeof *u); + if (!u) + { + err = gpg_error_from_syserror (); + break; + } + u->off = data - image_start; + u->len = datalen; + *utail = u; + utail = &u->next; + } + } + else if (pkttype == PKT_PUBLIC_KEY || pkttype == PKT_SECRET_KEY) + { + err = parse_key (data, datalen, &info->primary); + if (err) + break; + } + else if( pkttype == PKT_PUBLIC_SUBKEY && datalen && *data == '#' ) + { + /* Early versions of GnuPG used old PGP comment packets; + * luckily all those comments are prefixed by a hash + * sign - ignore these packets. */ + } + else if (pkttype == PKT_PUBLIC_SUBKEY || pkttype == PKT_SECRET_SUBKEY) + { + info->nsubkeys++; + if (info->nsubkeys == 1) + { + err = parse_key (data, datalen, &info->subkeys); + if (err) + { + info->nsubkeys--; + /* We ignore subkeys with unknown algorithms. */ + if (gpg_err_code (err) == GPG_ERR_UNKNOWN_ALGORITHM + || gpg_err_code (err) == GPG_ERR_UNSUPPORTED_ALGORITHM) + err = 0; + if (err) + break; + } + else + ktail = &info->subkeys.next; + } + else + { + k = xtrycalloc (1, sizeof *k); + if (!k) + { + err = gpg_error_from_syserror (); + break; + } + err = parse_key (data, datalen, k); + if (err) + { + xfree (k); + info->nsubkeys--; + /* We ignore subkeys with unknown algorithms. */ + if (gpg_err_code (err) == GPG_ERR_UNKNOWN_ALGORITHM + || gpg_err_code (err) == GPG_ERR_UNSUPPORTED_ALGORITHM) + err = 0; + if (err) + break; + } + else + { + *ktail = k; + ktail = &k->next; + } + } + } + } + + if (err) + { + _keybox_destroy_openpgp_info (info); + if (!read_error) + { + /* Packet parsing worked, thus we should be able to skip the + rest of the keyblock. */ + while (image) + { + if (next_packet (&image, &imagelen, + &data, &datalen, &pkttype, &n) ) + break; /* Another error - stop here. */ + + if (pkttype == PKT_PUBLIC_KEY || pkttype == PKT_SECRET_KEY) + break; /* Next keyblock encountered - ready. */ + + if (nparsed) + *nparsed += n; + } + } + } + + return err; +} + + +/* Release any malloced data in INFO but not INFO itself! */ +void +_keybox_destroy_openpgp_info (keybox_openpgp_info_t info) +{ + struct _keybox_openpgp_key_info *k, *k2; + struct _keybox_openpgp_uid_info *u, *u2; + + assert (!info->primary.next); + for (k=info->subkeys.next; k; k = k2) + { + k2 = k->next; + xfree (k); + } + + for (u=info->uids.next; u; u = u2) + { + u2 = u->next; + xfree (u); + } +} diff --git a/kbx/keybox-search-desc.h b/kbx/keybox-search-desc.h new file mode 100644 index 0000000..6298994 --- /dev/null +++ b/kbx/keybox-search-desc.h @@ -0,0 +1,86 @@ +/* keybox-search-desc.h - Keybox serch description + * Copyright (C) 2001 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG 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 3 of the License, or + * (at your option) any later version. + * + * GnuPG 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, see <https://www.gnu.org/licenses/>. + */ + +/* + This file is a temporary kludge until we can come up with solution + to share this description between keybox and the application + specific keydb +*/ + +#ifndef KEYBOX_SEARCH_DESC_H +#define KEYBOX_SEARCH_DESC_H 1 + +typedef enum { + KEYDB_SEARCH_MODE_NONE, + KEYDB_SEARCH_MODE_EXACT, + KEYDB_SEARCH_MODE_SUBSTR, + KEYDB_SEARCH_MODE_MAIL, + KEYDB_SEARCH_MODE_MAILSUB, + KEYDB_SEARCH_MODE_MAILEND, + KEYDB_SEARCH_MODE_WORDS, + KEYDB_SEARCH_MODE_SHORT_KID, + KEYDB_SEARCH_MODE_LONG_KID, + KEYDB_SEARCH_MODE_FPR16, + KEYDB_SEARCH_MODE_FPR20, + KEYDB_SEARCH_MODE_FPR, + KEYDB_SEARCH_MODE_ISSUER, + KEYDB_SEARCH_MODE_ISSUER_SN, + KEYDB_SEARCH_MODE_SN, + KEYDB_SEARCH_MODE_SUBJECT, + KEYDB_SEARCH_MODE_KEYGRIP, + KEYDB_SEARCH_MODE_FIRST, + KEYDB_SEARCH_MODE_NEXT +} KeydbSearchMode; + + +/* Forwward declaration. See g10/packet.h. */ +struct gpg_pkt_user_id_s; +typedef struct gpg_pkt_user_id_s *gpg_pkt_user_id_t; + +/* A search descriptor. */ +struct keydb_search_desc +{ + KeydbSearchMode mode; + /* Callback used to filter results. The first parameter is + SKIPFUNCVALUE. The second is the keyid. The third is the + 1-based index of the UID packet that matched the search criteria + (or 0, if none). + + Return non-zero if the result should be skipped. */ + int (*skipfnc)(void *, u32 *, int); + void *skipfncvalue; + const unsigned char *sn; + int snlen; /* -1 := sn is a hex string */ + union { + const char *name; + unsigned char fpr[24]; + u32 kid[2]; /* Note that this is in native endianness. */ + unsigned char grip[20]; + } u; + int exact; /* Use exactly this key ('!' suffix in gpg). */ +}; + + +struct keydb_search_desc; +typedef struct keydb_search_desc KEYDB_SEARCH_DESC; +typedef struct keydb_search_desc KEYBOX_SEARCH_DESC; + + + +#endif /*KEYBOX_SEARCH_DESC_H*/ diff --git a/kbx/keybox-search.c b/kbx/keybox-search.c new file mode 100644 index 0000000..53ed66b --- /dev/null +++ b/kbx/keybox-search.c @@ -0,0 +1,1317 @@ +/* keybox-search.c - Search operations + * Copyright (C) 2001, 2002, 2003, 2004, 2012, + * 2013 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG 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 3 of the License, or + * (at your option) any later version. + * + * GnuPG 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, see <https://www.gnu.org/licenses/>. + */ + +#include <config.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> +#include <errno.h> + +#include "keybox-defs.h" +#include <gcrypt.h> +#include "../common/host2net.h" +#include "../common/mbox-util.h" + +#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ + *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) +#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) + + +struct sn_array_s { + int snlen; + unsigned char *sn; +}; + + +#define get32(a) buf32_to_ulong ((a)) +#define get16(a) buf16_to_ulong ((a)) + + +static inline unsigned int +blob_get_blob_flags (KEYBOXBLOB blob) +{ + const unsigned char *buffer; + size_t length; + + buffer = _keybox_get_blob_image (blob, &length); + if (length < 8) + return 0; /* oops */ + + return get16 (buffer + 6); +} + + +/* Return the first keyid from the blob. Returns true if + available. */ +static int +blob_get_first_keyid (KEYBOXBLOB blob, u32 *kid) +{ + const unsigned char *buffer; + size_t length, nkeys, keyinfolen; + + buffer = _keybox_get_blob_image (blob, &length); + if (length < 48) + return 0; /* blob too short */ + + nkeys = get16 (buffer + 16); + keyinfolen = get16 (buffer + 18); + if (!nkeys || keyinfolen < 28) + return 0; /* invalid blob */ + + kid[0] = get32 (buffer + 32); + kid[1] = get32 (buffer + 36); + + return 1; +} + + +/* Return information on the flag WHAT within the blob BUFFER,LENGTH. + Return the offset and the length (in bytes) of the flag in + FLAGOFF,FLAG_SIZE. */ +gpg_err_code_t +_keybox_get_flag_location (const unsigned char *buffer, size_t length, + int what, size_t *flag_off, size_t *flag_size) +{ + size_t pos; + size_t nkeys, keyinfolen; + size_t nuids, uidinfolen; + size_t nserial; + size_t nsigs, siginfolen, siginfooff; + + switch (what) + { + case KEYBOX_FLAG_BLOB: + if (length < 8) + return GPG_ERR_INV_OBJ; + *flag_off = 6; + *flag_size = 2; + break; + + case KEYBOX_FLAG_OWNERTRUST: + case KEYBOX_FLAG_VALIDITY: + case KEYBOX_FLAG_CREATED_AT: + case KEYBOX_FLAG_SIG_INFO: + if (length < 20) + return GPG_ERR_INV_OBJ; + /* Key info. */ + nkeys = get16 (buffer + 16); + keyinfolen = get16 (buffer + 18 ); + if (keyinfolen < 28) + return GPG_ERR_INV_OBJ; + pos = 20 + keyinfolen*nkeys; + if (pos+2 > length) + return GPG_ERR_INV_OBJ; /* Out of bounds. */ + /* Serial number. */ + nserial = get16 (buffer+pos); + pos += 2 + nserial; + if (pos+4 > length) + return GPG_ERR_INV_OBJ; /* Out of bounds. */ + /* User IDs. */ + nuids = get16 (buffer + pos); pos += 2; + uidinfolen = get16 (buffer + pos); pos += 2; + if (uidinfolen < 12 ) + return GPG_ERR_INV_OBJ; + pos += uidinfolen*nuids; + if (pos+4 > length) + return GPG_ERR_INV_OBJ ; /* Out of bounds. */ + /* Signature info. */ + siginfooff = pos; + nsigs = get16 (buffer + pos); pos += 2; + siginfolen = get16 (buffer + pos); pos += 2; + if (siginfolen < 4 ) + return GPG_ERR_INV_OBJ; + pos += siginfolen*nsigs; + if (pos+1+1+2+4+4+4+4 > length) + return GPG_ERR_INV_OBJ ; /* Out of bounds. */ + *flag_size = 1; + *flag_off = pos; + switch (what) + { + case KEYBOX_FLAG_VALIDITY: + *flag_off += 1; + break; + case KEYBOX_FLAG_CREATED_AT: + *flag_size = 4; + *flag_off += 1+2+4+4+4; + break; + case KEYBOX_FLAG_SIG_INFO: + *flag_size = siginfolen * nsigs; + *flag_off = siginfooff; + break; + default: + break; + } + break; + + default: + return GPG_ERR_INV_FLAG; + } + return 0; +} + + + +/* Return one of the flags WHAT in VALUE from the blob BUFFER of + LENGTH bytes. Return 0 on success or an raw error code. */ +static gpg_err_code_t +get_flag_from_image (const unsigned char *buffer, size_t length, + int what, unsigned int *value) +{ + gpg_err_code_t ec; + size_t pos, size; + + *value = 0; + ec = _keybox_get_flag_location (buffer, length, what, &pos, &size); + if (!ec) + switch (size) + { + case 1: *value = buffer[pos]; break; + case 2: *value = get16 (buffer + pos); break; + case 4: *value = get32 (buffer + pos); break; + default: ec = GPG_ERR_BUG; break; + } + + return ec; +} + + +static int +blob_cmp_sn (KEYBOXBLOB blob, const unsigned char *sn, int snlen) +{ + const unsigned char *buffer; + size_t length; + size_t pos, off; + size_t nkeys, keyinfolen; + size_t nserial; + + buffer = _keybox_get_blob_image (blob, &length); + if (length < 40) + return 0; /* blob too short */ + + /*keys*/ + nkeys = get16 (buffer + 16); + keyinfolen = get16 (buffer + 18 ); + if (keyinfolen < 28) + return 0; /* invalid blob */ + pos = 20 + keyinfolen*nkeys; + if (pos+2 > length) + return 0; /* out of bounds */ + + /*serial*/ + nserial = get16 (buffer+pos); + off = pos + 2; + if (off+nserial > length) + return 0; /* out of bounds */ + + return nserial == snlen && !memcmp (buffer+off, sn, snlen); +} + + +/* Returns 0 if not found or the number of the key which was found. + For X.509 this is always 1, for OpenPGP this is 1 for the primary + key and 2 and more for the subkeys. */ +static int +blob_cmp_fpr (KEYBOXBLOB blob, const unsigned char *fpr) +{ + const unsigned char *buffer; + size_t length; + size_t pos, off; + size_t nkeys, keyinfolen; + int idx; + + buffer = _keybox_get_blob_image (blob, &length); + if (length < 40) + return 0; /* blob too short */ + + /*keys*/ + nkeys = get16 (buffer + 16); + keyinfolen = get16 (buffer + 18 ); + if (keyinfolen < 28) + return 0; /* invalid blob */ + pos = 20; + if (pos + (uint64_t)keyinfolen*nkeys > (uint64_t)length) + return 0; /* out of bounds */ + + for (idx=0; idx < nkeys; idx++) + { + off = pos + idx*keyinfolen; + if (!memcmp (buffer + off, fpr, 20)) + return idx+1; /* found */ + } + return 0; /* not found */ +} + +static int +blob_cmp_fpr_part (KEYBOXBLOB blob, const unsigned char *fpr, + int fproff, int fprlen) +{ + const unsigned char *buffer; + size_t length; + size_t pos, off; + size_t nkeys, keyinfolen; + int idx; + + buffer = _keybox_get_blob_image (blob, &length); + if (length < 40) + return 0; /* blob too short */ + + /*keys*/ + nkeys = get16 (buffer + 16); + keyinfolen = get16 (buffer + 18 ); + if (keyinfolen < 28) + return 0; /* invalid blob */ + pos = 20; + if (pos + (uint64_t)keyinfolen*nkeys > (uint64_t)length) + return 0; /* out of bounds */ + + for (idx=0; idx < nkeys; idx++) + { + off = pos + idx*keyinfolen; + if (!memcmp (buffer + off + fproff, fpr, fprlen)) + return idx+1; /* found */ + } + return 0; /* not found */ +} + + +static int +blob_cmp_name (KEYBOXBLOB blob, int idx, + const char *name, size_t namelen, int substr, int x509) +{ + const unsigned char *buffer; + size_t length; + size_t pos, off, len; + size_t nkeys, keyinfolen; + size_t nuids, uidinfolen; + size_t nserial; + + buffer = _keybox_get_blob_image (blob, &length); + if (length < 40) + return 0; /* blob too short */ + + /*keys*/ + nkeys = get16 (buffer + 16); + keyinfolen = get16 (buffer + 18 ); + if (keyinfolen < 28) + return 0; /* invalid blob */ + pos = 20 + keyinfolen*nkeys; + if ((uint64_t)pos+2 > (uint64_t)length) + return 0; /* out of bounds */ + + /*serial*/ + nserial = get16 (buffer+pos); + pos += 2 + nserial; + if (pos+4 > length) + return 0; /* out of bounds */ + + /* user ids*/ + nuids = get16 (buffer + pos); pos += 2; + uidinfolen = get16 (buffer + pos); pos += 2; + if (uidinfolen < 12 /* should add a: || nuidinfolen > MAX_UIDINFOLEN */) + return 0; /* invalid blob */ + if (pos + uidinfolen*nuids > length) + return 0; /* out of bounds */ + + if (idx < 0) + { /* Compare all names. Note that for X.509 we start with index 1 + so to skip the issuer at index 0. */ + for (idx = !!x509; idx < nuids; idx++) + { + size_t mypos = pos; + + mypos += idx*uidinfolen; + off = get32 (buffer+mypos); + len = get32 (buffer+mypos+4); + if ((uint64_t)off+(uint64_t)len > (uint64_t)length) + return 0; /* error: better stop here out of bounds */ + if (len < 1) + continue; /* empty name */ + if (substr) + { + if (ascii_memcasemem (buffer+off, len, name, namelen)) + return idx+1; /* found */ + } + else + { + if (len == namelen && !memcmp (buffer+off, name, len)) + return idx+1; /* found */ + } + } + } + else + { + if (idx > nuids) + return 0; /* no user ID with that idx */ + pos += idx*uidinfolen; + off = get32 (buffer+pos); + len = get32 (buffer+pos+4); + if (off+len > length) + return 0; /* out of bounds */ + if (len < 1) + return 0; /* empty name */ + + if (substr) + { + if (ascii_memcasemem (buffer+off, len, name, namelen)) + return idx+1; /* found */ + } + else + { + if (len == namelen && !memcmp (buffer+off, name, len)) + return idx+1; /* found */ + } + } + return 0; /* not found */ +} + + +/* Compare all email addresses of the subject. With SUBSTR given as + True a substring search is done in the mail address. The X509 flag + indicated whether the search is done on an X.509 blob. */ +static int +blob_cmp_mail (KEYBOXBLOB blob, const char *name, size_t namelen, int substr, + int x509) +{ + const unsigned char *buffer; + size_t length; + size_t pos, off, len; + size_t nkeys, keyinfolen; + size_t nuids, uidinfolen; + size_t nserial; + int idx; + + /* fixme: this code is common to blob_cmp_mail */ + buffer = _keybox_get_blob_image (blob, &length); + if (length < 40) + return 0; /* blob too short */ + + /*keys*/ + nkeys = get16 (buffer + 16); + keyinfolen = get16 (buffer + 18 ); + if (keyinfolen < 28) + return 0; /* invalid blob */ + pos = 20 + keyinfolen*nkeys; + if (pos+2 > length) + return 0; /* out of bounds */ + + /*serial*/ + nserial = get16 (buffer+pos); + pos += 2 + nserial; + if (pos+4 > length) + return 0; /* out of bounds */ + + /* user ids*/ + nuids = get16 (buffer + pos); pos += 2; + uidinfolen = get16 (buffer + pos); pos += 2; + if (uidinfolen < 12 /* should add a: || nuidinfolen > MAX_UIDINFOLEN */) + return 0; /* invalid blob */ + if (pos + uidinfolen*nuids > length) + return 0; /* out of bounds */ + + if (namelen < 1) + return 0; + + /* Note that for X.509 we start at index 1 because index 0 is used + for the issuer name. */ + for (idx=!!x509 ;idx < nuids; idx++) + { + size_t mypos = pos; + size_t mylen; + + mypos += idx*uidinfolen; + off = get32 (buffer+mypos); + len = get32 (buffer+mypos+4); + if ((uint64_t)off+(uint64_t)len > (uint64_t)length) + return 0; /* error: better stop here - out of bounds */ + if (x509) + { + if (len < 2 || buffer[off] != '<') + continue; /* empty name or trailing 0 not stored */ + len--; /* one back */ + if ( len < 3 || buffer[off+len] != '>') + continue; /* not a proper email address */ + off++; + len--; + } + else /* OpenPGP. */ + { + /* We need to forward to the mailbox part. */ + mypos = off; + mylen = len; + for ( ; len && buffer[off] != '<'; len--, off++) + ; + if (len < 2 || buffer[off] != '<') + { + /* Mailbox not explicitly given or too short. Restore + OFF and LEN and check whether the entire string + resembles a mailbox without the angle brackets. */ + off = mypos; + len = mylen; + if (!is_valid_mailbox_mem (buffer+off, len)) + continue; /* Not a mail address. */ + } + else /* Seems to be standard user id with mail address. */ + { + off++; /* Point to first char of the mail address. */ + len--; + /* Search closing '>'. */ + for (mypos=off; len && buffer[mypos] != '>'; len--, mypos++) + ; + if (!len || buffer[mypos] != '>' || off == mypos) + continue; /* Not a proper mail address. */ + len = mypos - off; + } + + } + + if (substr) + { + if (ascii_memcasemem (buffer+off, len, name, namelen)) + return idx+1; /* found */ + } + else + { + if (len == namelen && !ascii_memcasecmp (buffer+off, name, len)) + return idx+1; /* found */ + } + } + return 0; /* not found */ +} + + +/* Return true if the key in BLOB matches the 20 bytes keygrip GRIP. + * We don't have the keygrips as meta data, thus we need to parse the + * certificate. Fixme: We might want to return proper error codes + * instead of failing a search for invalid certificates etc. */ +static int +blob_openpgp_has_grip (KEYBOXBLOB blob, const unsigned char *grip) +{ + int rc = 0; + const unsigned char *buffer; + size_t length; + size_t cert_off, cert_len; + struct _keybox_openpgp_info info; + struct _keybox_openpgp_key_info *k; + + buffer = _keybox_get_blob_image (blob, &length); + if (length < 40) + return 0; /* Too short. */ + cert_off = get32 (buffer+8); + cert_len = get32 (buffer+12); + if ((uint64_t)cert_off+(uint64_t)cert_len > (uint64_t)length) + return 0; /* Too short. */ + + if (_keybox_parse_openpgp (buffer + cert_off, cert_len, NULL, &info)) + return 0; /* Parse error. */ + + if (!memcmp (info.primary.grip, grip, 20)) + { + rc = 1; + goto leave; + } + + if (info.nsubkeys) + { + k = &info.subkeys; + do + { + if (!memcmp (k->grip, grip, 20)) + { + rc = 1; + goto leave; + } + k = k->next; + } + while (k); + } + + leave: + _keybox_destroy_openpgp_info (&info); + return rc; +} + + +#ifdef KEYBOX_WITH_X509 +/* Return true if the key in BLOB matches the 20 bytes keygrip GRIP. + We don't have the keygrips as meta data, thus we need to parse the + certificate. Fixme: We might want to return proper error codes + instead of failing a search for invalid certificates etc. */ +static int +blob_x509_has_grip (KEYBOXBLOB blob, const unsigned char *grip) +{ + int rc; + const unsigned char *buffer; + size_t length; + size_t cert_off, cert_len; + ksba_reader_t reader = NULL; + ksba_cert_t cert = NULL; + ksba_sexp_t p = NULL; + gcry_sexp_t s_pkey; + unsigned char array[20]; + unsigned char *rcp; + size_t n; + + buffer = _keybox_get_blob_image (blob, &length); + if (length < 40) + return 0; /* Too short. */ + cert_off = get32 (buffer+8); + cert_len = get32 (buffer+12); + if ((uint64_t)cert_off+(uint64_t)cert_len > (uint64_t)length) + return 0; /* Too short. */ + + rc = ksba_reader_new (&reader); + if (rc) + return 0; /* Problem with ksba. */ + rc = ksba_reader_set_mem (reader, buffer+cert_off, cert_len); + if (rc) + goto failed; + rc = ksba_cert_new (&cert); + if (rc) + goto failed; + rc = ksba_cert_read_der (cert, reader); + if (rc) + goto failed; + p = ksba_cert_get_public_key (cert); + if (!p) + goto failed; + n = gcry_sexp_canon_len (p, 0, NULL, NULL); + if (!n) + goto failed; + rc = gcry_sexp_sscan (&s_pkey, NULL, (char*)p, n); + if (rc) + { + gcry_sexp_release (s_pkey); + goto failed; + } + rcp = gcry_pk_get_keygrip (s_pkey, array); + gcry_sexp_release (s_pkey); + if (!rcp) + goto failed; /* Can't calculate keygrip. */ + + xfree (p); + ksba_cert_release (cert); + ksba_reader_release (reader); + return !memcmp (array, grip, 20); + failed: + xfree (p); + ksba_cert_release (cert); + ksba_reader_release (reader); + return 0; +} +#endif /*KEYBOX_WITH_X509*/ + + + +/* + The has_foo functions are used as helpers for search +*/ +static inline int +has_short_kid (KEYBOXBLOB blob, u32 lkid) +{ + unsigned char buf[4]; + buf[0] = lkid >> 24; + buf[1] = lkid >> 16; + buf[2] = lkid >> 8; + buf[3] = lkid; + return blob_cmp_fpr_part (blob, buf, 16, 4); +} + +static inline int +has_long_kid (KEYBOXBLOB blob, u32 mkid, u32 lkid) +{ + unsigned char buf[8]; + buf[0] = mkid >> 24; + buf[1] = mkid >> 16; + buf[2] = mkid >> 8; + buf[3] = mkid; + buf[4] = lkid >> 24; + buf[5] = lkid >> 16; + buf[6] = lkid >> 8; + buf[7] = lkid; + return blob_cmp_fpr_part (blob, buf, 12, 8); +} + +static inline int +has_fingerprint (KEYBOXBLOB blob, const unsigned char *fpr) +{ + return blob_cmp_fpr (blob, fpr); +} + +static inline int +has_keygrip (KEYBOXBLOB blob, const unsigned char *grip) +{ + if (blob_get_type (blob) == KEYBOX_BLOBTYPE_PGP) + return blob_openpgp_has_grip (blob, grip); +#ifdef KEYBOX_WITH_X509 + if (blob_get_type (blob) == KEYBOX_BLOBTYPE_X509) + return blob_x509_has_grip (blob, grip); +#endif + return 0; +} + + +static inline int +has_issuer (KEYBOXBLOB blob, const char *name) +{ + size_t namelen; + + return_val_if_fail (name, 0); + + if (blob_get_type (blob) != KEYBOX_BLOBTYPE_X509) + return 0; + + namelen = strlen (name); + return blob_cmp_name (blob, 0 /* issuer */, name, namelen, 0, 1); +} + +static inline int +has_issuer_sn (KEYBOXBLOB blob, const char *name, + const unsigned char *sn, int snlen) +{ + size_t namelen; + + return_val_if_fail (name, 0); + return_val_if_fail (sn, 0); + + if (blob_get_type (blob) != KEYBOX_BLOBTYPE_X509) + return 0; + + namelen = strlen (name); + + return (blob_cmp_sn (blob, sn, snlen) + && blob_cmp_name (blob, 0 /* issuer */, name, namelen, 0, 1)); +} + +static inline int +has_sn (KEYBOXBLOB blob, const unsigned char *sn, int snlen) +{ + return_val_if_fail (sn, 0); + + if (blob_get_type (blob) != KEYBOX_BLOBTYPE_X509) + return 0; + return blob_cmp_sn (blob, sn, snlen); +} + +static inline int +has_subject (KEYBOXBLOB blob, const char *name) +{ + size_t namelen; + + return_val_if_fail (name, 0); + + if (blob_get_type (blob) != KEYBOX_BLOBTYPE_X509) + return 0; + + namelen = strlen (name); + return blob_cmp_name (blob, 1 /* subject */, name, namelen, 0, 1); +} + + +static inline int +has_username (KEYBOXBLOB blob, const char *name, int substr) +{ + size_t namelen; + int btype; + + return_val_if_fail (name, 0); + + btype = blob_get_type (blob); + if (btype != KEYBOX_BLOBTYPE_PGP && btype != KEYBOX_BLOBTYPE_X509) + return 0; + + namelen = strlen (name); + return blob_cmp_name (blob, -1 /* all subject/user names */, name, + namelen, substr, (btype == KEYBOX_BLOBTYPE_X509)); +} + + +static inline int +has_mail (KEYBOXBLOB blob, const char *name, int substr) +{ + size_t namelen; + int btype; + + return_val_if_fail (name, 0); + + btype = blob_get_type (blob); + if (btype != KEYBOX_BLOBTYPE_PGP && btype != KEYBOX_BLOBTYPE_X509) + return 0; + + if (btype == KEYBOX_BLOBTYPE_PGP && *name == '<') + name++; /* Hack to remove the leading '<' for gpg. */ + + namelen = strlen (name); + if (namelen && name[namelen-1] == '>') + namelen--; + return blob_cmp_mail (blob, name, namelen, substr, + (btype == KEYBOX_BLOBTYPE_X509)); +} + + +static void +release_sn_array (struct sn_array_s *array, size_t size) +{ + size_t n; + + for (n=0; n < size; n++) + xfree (array[n].sn); + xfree (array); +} + + +/* Helper to open the file. */ +static gpg_error_t +open_file (KEYBOX_HANDLE hd) +{ + + hd->fp = es_fopen (hd->kb->fname, "rb"); + if (!hd->fp) + { + hd->error = gpg_error_from_syserror (); + return hd->error; + } + + return 0; +} + + + +/* + + The search API + +*/ + +gpg_error_t +keybox_search_reset (KEYBOX_HANDLE hd) +{ + if (!hd) + return gpg_error (GPG_ERR_INV_VALUE); + + if (hd->found.blob) + { + _keybox_release_blob (hd->found.blob); + hd->found.blob = NULL; + } + + if (hd->fp) + { + if (es_fseeko (hd->fp, 0, SEEK_SET)) + { + /* Ooops. Seek did not work. Close so that the search will + * open the file again. */ + es_fclose (hd->fp); + hd->fp = NULL; + } + } + hd->error = 0; + hd->eof = 0; + return 0; +} + + +/* Note: When in ephemeral mode the search function does visit all + blobs but in standard mode, blobs flagged as ephemeral are ignored. + If WANT_BLOBTYPE is not 0 only blobs of this type are considered. + The value at R_SKIPPED is updated by the number of skipped long + records (counts PGP and X.509). */ +gpg_error_t +keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc, + keybox_blobtype_t want_blobtype, + size_t *r_descindex, unsigned long *r_skipped) +{ + gpg_error_t rc; + size_t n; + int need_words, any_skip; + KEYBOXBLOB blob = NULL; + struct sn_array_s *sn_array = NULL; + int pk_no, uid_no; + off_t lastfoundoff; + + if (!hd) + return gpg_error (GPG_ERR_INV_VALUE); + + /* Clear last found result but reord the offset of the last found + * blob which we may need later. */ + if (hd->found.blob) + { + lastfoundoff = _keybox_get_blob_fileoffset (hd->found.blob); + _keybox_release_blob (hd->found.blob); + hd->found.blob = NULL; + } + else + lastfoundoff = 0; + + if (hd->error) + return hd->error; /* still in error state */ + if (hd->eof) + return -1; /* still EOF */ + + /* figure out what information we need */ + need_words = any_skip = 0; + for (n=0; n < ndesc; n++) + { + switch (desc[n].mode) + { + case KEYDB_SEARCH_MODE_WORDS: + need_words = 1; + break; + case KEYDB_SEARCH_MODE_FIRST: + /* always restart the search in this mode */ + keybox_search_reset (hd); + lastfoundoff = 0; + break; + default: + break; + } + if (desc[n].skipfnc) + any_skip = 1; + if (desc[n].snlen == -1 && !sn_array) + { + sn_array = xtrycalloc (ndesc, sizeof *sn_array); + if (!sn_array) + return (hd->error = gpg_error_from_syserror ()); + } + } + + (void)need_words; /* Not yet implemented. */ + + if (!hd->fp) + { + rc = open_file (hd); + if (rc) + { + xfree (sn_array); + return rc; + } + /* log_debug ("%s: re-opened file\n", __func__); */ + if (ndesc && desc[0].mode != KEYDB_SEARCH_MODE_FIRST && lastfoundoff) + { + /* Search mode is not first and the last search operation + * returned a blob which also was not the first one. We now + * need to skip over that blob and hope that the file has + * not changed. */ + if (es_fseeko (hd->fp, lastfoundoff, SEEK_SET)) + { + rc = gpg_error_from_syserror (); + log_debug ("%s: seeking to last found offset failed: %s\n", + __func__, gpg_strerror (rc)); + xfree (sn_array); + return gpg_error (GPG_ERR_NOTHING_FOUND); + } + /* log_debug ("%s: re-opened file and sought to last offset\n", */ + /* __func__); */ + rc = _keybox_read_blob (NULL, hd->fp, NULL); + if (rc) + { + log_debug ("%s: skipping last found blob failed: %s\n", + __func__, gpg_strerror (rc)); + xfree (sn_array); + return gpg_error (GPG_ERR_NOTHING_FOUND); + } + } + } + + /* Kludge: We need to convert an SN given as hexstring to its binary + representation - in some cases we are not able to store it in the + search descriptor, because due to the way we use it, it is not + possible to free allocated memory. */ + if (sn_array) + { + const unsigned char *s; + int i, odd; + size_t snlen; + + for (n=0; n < ndesc; n++) + { + if (!desc[n].sn) + ; + else if (desc[n].snlen == -1) + { + unsigned char *sn; + + s = desc[n].sn; + for (i=0; *s && *s != '/'; s++, i++) + ; + odd = (i & 1); + snlen = (i+1)/2; + sn_array[n].sn = xtrymalloc (snlen); + if (!sn_array[n].sn) + { + hd->error = gpg_error_from_syserror (); + release_sn_array (sn_array, n); + return hd->error; + } + sn_array[n].snlen = snlen; + sn = sn_array[n].sn; + s = desc[n].sn; + if (odd) + { + *sn++ = xtoi_1 (s); + s++; + } + for (; *s && *s != '/'; s += 2) + *sn++ = xtoi_2 (s); + } + else + { + const unsigned char *sn; + + sn = desc[n].sn; + snlen = desc[n].snlen; + sn_array[n].sn = xtrymalloc (snlen); + if (!sn_array[n].sn) + { + hd->error = gpg_error_from_syserror (); + release_sn_array (sn_array, n); + return hd->error; + } + sn_array[n].snlen = snlen; + memcpy (sn_array[n].sn, sn, snlen); + } + } + } + + + pk_no = uid_no = 0; + for (;;) + { + unsigned int blobflags; + int blobtype; + + _keybox_release_blob (blob); blob = NULL; + rc = _keybox_read_blob (&blob, hd->fp, NULL); + if (gpg_err_code (rc) == GPG_ERR_TOO_LARGE + && gpg_err_source (rc) == GPG_ERR_SOURCE_KEYBOX) + { + ++*r_skipped; + continue; /* Skip too large records. */ + } + + if (rc) + break; + + blobtype = blob_get_type (blob); + if (blobtype == KEYBOX_BLOBTYPE_HEADER) + continue; + if (want_blobtype && blobtype != want_blobtype) + continue; + + blobflags = blob_get_blob_flags (blob); + if (!hd->ephemeral && (blobflags & 2)) + continue; /* Not in ephemeral mode but blob is flagged ephemeral. */ + + for (n=0; n < ndesc; n++) + { + switch (desc[n].mode) + { + case KEYDB_SEARCH_MODE_NONE: + never_reached (); + break; + case KEYDB_SEARCH_MODE_EXACT: + uid_no = has_username (blob, desc[n].u.name, 0); + if (uid_no) + goto found; + break; + case KEYDB_SEARCH_MODE_MAIL: + uid_no = has_mail (blob, desc[n].u.name, 0); + if (uid_no) + goto found; + break; + case KEYDB_SEARCH_MODE_MAILSUB: + uid_no = has_mail (blob, desc[n].u.name, 1); + if (uid_no) + goto found; + break; + case KEYDB_SEARCH_MODE_SUBSTR: + uid_no = has_username (blob, desc[n].u.name, 1); + if (uid_no) + goto found; + break; + case KEYDB_SEARCH_MODE_MAILEND: + case KEYDB_SEARCH_MODE_WORDS: + /* not yet implemented */ + break; + case KEYDB_SEARCH_MODE_ISSUER: + if (has_issuer (blob, desc[n].u.name)) + goto found; + break; + case KEYDB_SEARCH_MODE_ISSUER_SN: + if (has_issuer_sn (blob, desc[n].u.name, + sn_array? sn_array[n].sn : desc[n].sn, + sn_array? sn_array[n].snlen : desc[n].snlen)) + goto found; + break; + case KEYDB_SEARCH_MODE_SN: + if (has_sn (blob, sn_array? sn_array[n].sn : desc[n].sn, + sn_array? sn_array[n].snlen : desc[n].snlen)) + goto found; + break; + case KEYDB_SEARCH_MODE_SUBJECT: + if (has_subject (blob, desc[n].u.name)) + goto found; + break; + case KEYDB_SEARCH_MODE_SHORT_KID: + pk_no = has_short_kid (blob, desc[n].u.kid[1]); + if (pk_no) + goto found; + break; + case KEYDB_SEARCH_MODE_LONG_KID: + pk_no = has_long_kid (blob, desc[n].u.kid[0], desc[n].u.kid[1]); + if (pk_no) + goto found; + break; + case KEYDB_SEARCH_MODE_FPR: + case KEYDB_SEARCH_MODE_FPR20: + pk_no = has_fingerprint (blob, desc[n].u.fpr); + if (pk_no) + goto found; + break; + case KEYDB_SEARCH_MODE_KEYGRIP: + if (has_keygrip (blob, desc[n].u.grip)) + goto found; + break; + case KEYDB_SEARCH_MODE_FIRST: + goto found; + break; + case KEYDB_SEARCH_MODE_NEXT: + goto found; + break; + default: + rc = gpg_error (GPG_ERR_INV_VALUE); + goto found; + } + } + continue; + found: + /* Record which DESC we matched on. Note this value is only + meaningful if this function returns with no errors. */ + if(r_descindex) + *r_descindex = n; + for (n=any_skip?0:ndesc; n < ndesc; n++) + { + u32 kid[2]; + + if (desc[n].skipfnc + && blob_get_first_keyid (blob, kid) + && desc[n].skipfnc (desc[n].skipfncvalue, kid, uid_no)) + break; + } + if (n == ndesc) + break; /* got it */ + } + + if (!rc) + { + hd->found.blob = blob; + hd->found.pk_no = pk_no; + hd->found.uid_no = uid_no; + } + else if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF) + { + _keybox_release_blob (blob); + hd->eof = 1; + } + else + { + _keybox_release_blob (blob); + hd->error = rc; + } + + if (sn_array) + release_sn_array (sn_array, ndesc); + + return rc; +} + + + + +/* + Functions to return a certificate or a keyblock. To be used after + a successful search operation. +*/ + + +/* Return the last found keyblock. Returns 0 on success and stores a + * new iobuf at R_IOBUF. R_UID_NO and R_PK_NO are used to retun the + * number of the key or user id which was matched the search criteria; + * if not known they are set to 0. */ +gpg_error_t +keybox_get_keyblock (KEYBOX_HANDLE hd, iobuf_t *r_iobuf, + int *r_pk_no, int *r_uid_no) +{ + gpg_error_t err; + const unsigned char *buffer; + size_t length; + size_t image_off, image_len; + size_t siginfo_off, siginfo_len; + + *r_iobuf = NULL; + + if (!hd) + return gpg_error (GPG_ERR_INV_VALUE); + if (!hd->found.blob) + return gpg_error (GPG_ERR_NOTHING_FOUND); + + if (blob_get_type (hd->found.blob) != KEYBOX_BLOBTYPE_PGP) + return gpg_error (GPG_ERR_WRONG_BLOB_TYPE); + + buffer = _keybox_get_blob_image (hd->found.blob, &length); + if (length < 40) + return gpg_error (GPG_ERR_TOO_SHORT); + image_off = get32 (buffer+8); + image_len = get32 (buffer+12); + if ((uint64_t)image_off+(uint64_t)image_len > (uint64_t)length) + return gpg_error (GPG_ERR_TOO_SHORT); + + err = _keybox_get_flag_location (buffer, length, KEYBOX_FLAG_SIG_INFO, + &siginfo_off, &siginfo_len); + if (err) + return err; + + *r_pk_no = hd->found.pk_no; + *r_uid_no = hd->found.uid_no; + *r_iobuf = iobuf_temp_with_content (buffer+image_off, image_len); + return 0; +} + + +#ifdef KEYBOX_WITH_X509 +/* + Return the last found cert. Caller must free it. + */ +int +keybox_get_cert (KEYBOX_HANDLE hd, ksba_cert_t *r_cert) +{ + const unsigned char *buffer; + size_t length; + size_t cert_off, cert_len; + ksba_reader_t reader = NULL; + ksba_cert_t cert = NULL; + int rc; + + if (!hd) + return gpg_error (GPG_ERR_INV_VALUE); + if (!hd->found.blob) + return gpg_error (GPG_ERR_NOTHING_FOUND); + + if (blob_get_type (hd->found.blob) != KEYBOX_BLOBTYPE_X509) + return gpg_error (GPG_ERR_WRONG_BLOB_TYPE); + + buffer = _keybox_get_blob_image (hd->found.blob, &length); + if (length < 40) + return gpg_error (GPG_ERR_TOO_SHORT); + cert_off = get32 (buffer+8); + cert_len = get32 (buffer+12); + if ((uint64_t)cert_off+(uint64_t)cert_len > (uint64_t)length) + return gpg_error (GPG_ERR_TOO_SHORT); + + rc = ksba_reader_new (&reader); + if (rc) + return rc; + rc = ksba_reader_set_mem (reader, buffer+cert_off, cert_len); + if (rc) + { + ksba_reader_release (reader); + /* fixme: need to map the error codes */ + return gpg_error (GPG_ERR_GENERAL); + } + + rc = ksba_cert_new (&cert); + if (rc) + { + ksba_reader_release (reader); + return rc; + } + + rc = ksba_cert_read_der (cert, reader); + if (rc) + { + ksba_cert_release (cert); + ksba_reader_release (reader); + /* fixme: need to map the error codes */ + return gpg_error (GPG_ERR_GENERAL); + } + + *r_cert = cert; + ksba_reader_release (reader); + return 0; +} + +#endif /*KEYBOX_WITH_X509*/ + +/* Return the flags named WHAT at the address of VALUE. IDX is used + only for certain flags and should be 0 if not required. */ +int +keybox_get_flags (KEYBOX_HANDLE hd, int what, int idx, unsigned int *value) +{ + const unsigned char *buffer; + size_t length; + gpg_err_code_t ec; + + (void)idx; /* Not yet used. */ + + if (!hd) + return gpg_error (GPG_ERR_INV_VALUE); + if (!hd->found.blob) + return gpg_error (GPG_ERR_NOTHING_FOUND); + + buffer = _keybox_get_blob_image (hd->found.blob, &length); + ec = get_flag_from_image (buffer, length, what, value); + return ec? gpg_error (ec):0; +} + +off_t +keybox_offset (KEYBOX_HANDLE hd) +{ + if (!hd->fp) + return 0; + return es_ftello (hd->fp); +} + +gpg_error_t +keybox_seek (KEYBOX_HANDLE hd, off_t offset) +{ + gpg_error_t err; + + if (hd->error) + return hd->error; /* still in error state */ + + if (! hd->fp) + { + if (!offset) + { + /* No need to open the file. An unopened file is effectively at + offset 0. */ + return 0; + } + + err = open_file (hd); + if (err) + return err; + } + + err = es_fseeko (hd->fp, offset, SEEK_SET); + hd->error = gpg_error_from_errno (err); + + return hd->error; +} diff --git a/kbx/keybox-update.c b/kbx/keybox-update.c new file mode 100644 index 0000000..ddda52a --- /dev/null +++ b/kbx/keybox-update.c @@ -0,0 +1,799 @@ +/* keybox-update.c - keybox update operations + * Copyright (C) 2001, 2003, 2004, 2012 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG 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 3 of the License, or + * (at your option) any later version. + * + * GnuPG 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, see <https://www.gnu.org/licenses/>. + */ + +#include <config.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <time.h> +#include <unistd.h> +#include <assert.h> + +#include "keybox-defs.h" +#include "../common/sysutils.h" +#include "../common/host2net.h" +#include "../common/utilproto.h" + +#define EXTSEP_S "." + +#define FILECOPY_INSERT 1 +#define FILECOPY_DELETE 2 +#define FILECOPY_UPDATE 3 + + +#if !defined(HAVE_FSEEKO) && !defined(fseeko) + +#ifdef HAVE_LIMITS_H +# include <limits.h> +#endif +#ifndef LONG_MAX +# define LONG_MAX ((long) ((unsigned long) -1 >> 1)) +#endif +#ifndef LONG_MIN +# define LONG_MIN (-1 - LONG_MAX) +#endif + +/**************** + * A substitute for fseeko, for hosts that don't have it. + */ +static int +fseeko (FILE * stream, off_t newpos, int whence) +{ + while (newpos != (long) newpos) + { + long pos = newpos < 0 ? LONG_MIN : LONG_MAX; + if (fseek (stream, pos, whence) != 0) + return -1; + newpos -= pos; + whence = SEEK_CUR; + } + return fseek (stream, (long) newpos, whence); +} +#endif /* !defined(HAVE_FSEEKO) && !defined(fseeko) */ + + +static int +create_tmp_file (const char *template, + char **r_bakfname, char **r_tmpfname, estream_t *r_fp) +{ + gpg_error_t err; + + err = keybox_tmp_names (template, 0, r_bakfname, r_tmpfname); + if (!err) + { + *r_fp = es_fopen (*r_tmpfname, "wb"); + if (!*r_fp) + { + err = gpg_error_from_syserror (); + xfree (*r_tmpfname); + *r_tmpfname = NULL; + xfree (*r_bakfname); + *r_bakfname = NULL; + } + } + + return err; +} + + +static int +rename_tmp_file (const char *bakfname, const char *tmpfname, + const char *fname, int secret ) +{ + int rc=0; + int block = 0; + + /* restrict the permissions for secret keyboxs */ +#ifndef HAVE_DOSISH_SYSTEM +/* if (secret && !opt.preserve_permissions) */ +/* { */ +/* if (chmod (tmpfname, S_IRUSR | S_IWUSR) ) */ +/* { */ +/* log_debug ("chmod of '%s' failed: %s\n", */ +/* tmpfname, strerror(errno) ); */ +/* return KEYBOX_Write_File; */ +/* } */ +/* } */ +#endif + + /* fixme: invalidate close caches (not used with stdio)*/ +/* iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char*)tmpfname ); */ +/* iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char*)bakfname ); */ +/* iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char*)fname ); */ + + /* First make a backup file except for secret keyboxes. */ + if (!secret) + { + block = 1; + rc = gnupg_rename_file (fname, bakfname, &block); + if (rc) + goto leave; + } + + /* Then rename the file. */ + rc = gnupg_rename_file (tmpfname, fname, NULL); + if (block) + { + gnupg_unblock_all_signals (); + block = 0; + } + /* if (rc) */ + /* { */ + /* if (secret) */ + /* { */ + /* log_info ("WARNING: 2 files with confidential" */ + /* " information exists.\n"); */ + /* log_info ("%s is the unchanged one\n", fname ); */ + /* log_info ("%s is the new one\n", tmpfname ); */ + /* log_info ("Please fix this possible security flaw\n"); */ + /* } */ + /* } */ + + leave: + if (block) + gnupg_unblock_all_signals (); + return rc; +} + + + +/* Perform insert/delete/update operation. MODE is one of + FILECOPY_INSERT, FILECOPY_DELETE, FILECOPY_UPDATE. FOR_OPENPGP + indicates that this is called due to an OpenPGP keyblock change. */ +static int +blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob, + int secret, int for_openpgp, off_t start_offset) +{ + gpg_err_code_t ec; + estream_t fp, newfp; + int rc = 0; + char *bakfname = NULL; + char *tmpfname = NULL; + char buffer[4096]; /* (Must be at least 32 bytes) */ + int nread, nbytes; + + /* Open the source file. Because we do a rename, we have to check the + permissions of the file */ + if ((ec = gnupg_access (fname, W_OK))) + return gpg_error (ec); + + fp = es_fopen (fname, "rb"); + if (mode == FILECOPY_INSERT && !fp && errno == ENOENT) + { + /* Insert mode but file does not exist: + Create a new keybox file. */ + newfp = es_fopen (fname, "wb"); + if (!newfp ) + return gpg_error_from_syserror (); + + rc = _keybox_write_header_blob (newfp, for_openpgp); + if (rc) + { + es_fclose (newfp); + return rc; + } + + rc = _keybox_write_blob (blob, newfp, NULL); + if (rc) + { + es_fclose (newfp); + return rc; + } + + if ( es_fclose (newfp) ) + return gpg_error_from_syserror (); + +/* if (chmod( fname, S_IRUSR | S_IWUSR )) */ +/* { */ +/* log_debug ("%s: chmod failed: %s\n", fname, strerror(errno) ); */ +/* return KEYBOX_File_Error; */ +/* } */ + return 0; /* Ready. */ + } + + if (!fp) + { + rc = gpg_error_from_syserror (); + goto leave; + } + + /* Create the new file. On success NEWFP is initialized. */ + rc = create_tmp_file (fname, &bakfname, &tmpfname, &newfp); + if (rc) + { + es_fclose (fp); + goto leave; + } + + /* prepare for insert */ + if (mode == FILECOPY_INSERT) + { + int first_record = 1; + + /* Copy everything to the new file. If this is for OpenPGP, we + make sure that the openpgp flag is set in the header. (We + failsafe the blob type.) */ + while ( (nread = es_fread (buffer, 1, DIM(buffer), fp)) > 0 ) + { + if (first_record && for_openpgp + && buffer[4] == KEYBOX_BLOBTYPE_HEADER) + { + first_record = 0; + buffer[7] |= 0x02; /* OpenPGP data may be available. */ + } + + if (es_fwrite (buffer, nread, 1, newfp) != 1) + { + rc = gpg_error_from_syserror (); + es_fclose (fp); + es_fclose (newfp); + goto leave; + } + } + if (es_ferror (fp)) + { + rc = gpg_error_from_syserror (); + es_fclose (fp); + es_fclose (newfp); + goto leave; + } + } + + /* Prepare for delete or update. */ + if ( mode == FILECOPY_DELETE || mode == FILECOPY_UPDATE ) + { + off_t current = 0; + + /* Copy first part to the new file. */ + while ( current < start_offset ) + { + nbytes = DIM(buffer); + if (current + nbytes > start_offset) + nbytes = start_offset - current; + nread = es_fread (buffer, 1, nbytes, fp); + if (!nread) + break; + current += nread; + + if (es_fwrite (buffer, nread, 1, newfp) != 1) + { + rc = gpg_error_from_syserror (); + es_fclose (fp); + es_fclose (newfp); + goto leave; + } + } + if (es_ferror (fp)) + { + rc = gpg_error_from_syserror (); + es_fclose (fp); + es_fclose (newfp); + goto leave; + } + + /* Skip this blob. */ + rc = _keybox_read_blob (NULL, fp, NULL); + if (rc) + { + es_fclose (fp); + es_fclose (newfp); + return rc; + } + } + + /* Do an insert or update. */ + if ( mode == FILECOPY_INSERT || mode == FILECOPY_UPDATE ) + { + rc = _keybox_write_blob (blob, newfp, NULL); + if (rc) + { + es_fclose (fp); + es_fclose (newfp); + return rc; + } + } + + /* Copy the rest of the packet for an delete or update. */ + if (mode == FILECOPY_DELETE || mode == FILECOPY_UPDATE) + { + while ( (nread = es_fread (buffer, 1, DIM(buffer), fp)) > 0 ) + { + if (es_fwrite (buffer, nread, 1, newfp) != 1) + { + rc = gpg_error_from_syserror (); + es_fclose (fp); + es_fclose (newfp); + goto leave; + } + } + if (es_ferror (fp)) + { + rc = gpg_error_from_syserror (); + es_fclose (fp); + es_fclose (newfp); + goto leave; + } + } + + /* Close both files. */ + if (es_fclose(fp)) + { + rc = gpg_error_from_syserror (); + es_fclose (newfp); + goto leave; + } + if (es_fclose(newfp)) + { + rc = gpg_error_from_syserror (); + goto leave; + } + + rc = rename_tmp_file (bakfname, tmpfname, fname, secret); + + leave: + xfree(bakfname); + xfree(tmpfname); + return rc; +} + + +/* Insert the OpenPGP keyblock {IMAGE,IMAGELEN} into HD. */ +gpg_error_t +keybox_insert_keyblock (KEYBOX_HANDLE hd, const void *image, size_t imagelen) +{ + gpg_error_t err; + const char *fname; + KEYBOXBLOB blob; + size_t nparsed; + struct _keybox_openpgp_info info; + + if (!hd) + return gpg_error (GPG_ERR_INV_HANDLE); + if (!hd->kb) + return gpg_error (GPG_ERR_INV_HANDLE); + fname = hd->kb->fname; + if (!fname) + return gpg_error (GPG_ERR_INV_HANDLE); + + + /* Close this one otherwise we will mess up the position for a next + search. Fixme: it would be better to adjust the position after + the write operation. */ + _keybox_close_file (hd); + + err = _keybox_parse_openpgp (image, imagelen, &nparsed, &info); + if (err) + return err; + assert (nparsed <= imagelen); + err = _keybox_create_openpgp_blob (&blob, &info, image, imagelen, + hd->ephemeral); + _keybox_destroy_openpgp_info (&info); + if (!err) + { + err = blob_filecopy (FILECOPY_INSERT, fname, blob, hd->secret, 1, 0); + _keybox_release_blob (blob); + /* if (!rc && !hd->secret && kb_offtbl) */ + /* { */ + /* update_offset_hash_table_from_kb (kb_offtbl, kb, 0); */ + /* } */ + } + return err; +} + + +/* Update the current key at HD with the given OpenPGP keyblock in + {IMAGE,IMAGELEN}. */ +gpg_error_t +keybox_update_keyblock (KEYBOX_HANDLE hd, const void *image, size_t imagelen) +{ + gpg_error_t err; + const char *fname; + off_t off; + KEYBOXBLOB blob; + size_t nparsed; + struct _keybox_openpgp_info info; + + if (!hd || !image || !imagelen) + return gpg_error (GPG_ERR_INV_VALUE); + if (!hd->found.blob) + return gpg_error (GPG_ERR_NOTHING_FOUND); + if (blob_get_type (hd->found.blob) != KEYBOX_BLOBTYPE_PGP) + return gpg_error (GPG_ERR_WRONG_BLOB_TYPE); + fname = hd->kb->fname; + if (!fname) + return gpg_error (GPG_ERR_INV_HANDLE); + + off = _keybox_get_blob_fileoffset (hd->found.blob); + if (off == (off_t)-1) + return gpg_error (GPG_ERR_GENERAL); + + /* Close the file so that we do no mess up the position for a + next search. */ + _keybox_close_file (hd); + + /* Build a new blob. */ + err = _keybox_parse_openpgp (image, imagelen, &nparsed, &info); + if (err) + return err; + assert (nparsed <= imagelen); + err = _keybox_create_openpgp_blob (&blob, &info, image, imagelen, + hd->ephemeral); + _keybox_destroy_openpgp_info (&info); + + /* Update the keyblock. */ + if (!err) + { + err = blob_filecopy (FILECOPY_UPDATE, fname, blob, hd->secret, 1, off); + _keybox_release_blob (blob); + } + return err; +} + + + +#ifdef KEYBOX_WITH_X509 +int +keybox_insert_cert (KEYBOX_HANDLE hd, ksba_cert_t cert, + unsigned char *sha1_digest) +{ + int rc; + const char *fname; + KEYBOXBLOB blob; + + if (!hd) + return gpg_error (GPG_ERR_INV_HANDLE); + if (!hd->kb) + return gpg_error (GPG_ERR_INV_HANDLE); + fname = hd->kb->fname; + if (!fname) + return gpg_error (GPG_ERR_INV_HANDLE); + + /* Close this one otherwise we will mess up the position for a next + search. Fixme: it would be better to adjust the position after + the write operation. */ + _keybox_close_file (hd); + + rc = _keybox_create_x509_blob (&blob, cert, sha1_digest, hd->ephemeral); + if (!rc) + { + rc = blob_filecopy (FILECOPY_INSERT, fname, blob, hd->secret, 0, 0); + _keybox_release_blob (blob); + /* if (!rc && !hd->secret && kb_offtbl) */ + /* { */ + /* update_offset_hash_table_from_kb (kb_offtbl, kb, 0); */ + /* } */ + } + return rc; +} + +int +keybox_update_cert (KEYBOX_HANDLE hd, ksba_cert_t cert, + unsigned char *sha1_digest) +{ + (void)hd; + (void)cert; + (void)sha1_digest; + return -1; +} + + +#endif /*KEYBOX_WITH_X509*/ + +/* Note: We assume that the keybox has been locked before the current + search was executed. This is needed so that we can depend on the + offset information of the flags. */ +int +keybox_set_flags (KEYBOX_HANDLE hd, int what, int idx, unsigned int value) +{ + off_t off; + const char *fname; + estream_t fp; + gpg_err_code_t ec; + size_t flag_pos, flag_size; + const unsigned char *buffer; + size_t length; + + (void)idx; /* Not yet used. */ + + if (!hd) + return gpg_error (GPG_ERR_INV_VALUE); + if (!hd->found.blob) + return gpg_error (GPG_ERR_NOTHING_FOUND); + if (!hd->kb) + return gpg_error (GPG_ERR_INV_HANDLE); + if (!hd->found.blob) + return gpg_error (GPG_ERR_NOTHING_FOUND); + fname = hd->kb->fname; + if (!fname) + return gpg_error (GPG_ERR_INV_HANDLE); + + off = _keybox_get_blob_fileoffset (hd->found.blob); + if (off == (off_t)-1) + return gpg_error (GPG_ERR_GENERAL); + + buffer = _keybox_get_blob_image (hd->found.blob, &length); + ec = _keybox_get_flag_location (buffer, length, what, &flag_pos, &flag_size); + if (ec) + return gpg_error (ec); + + off += flag_pos; + + _keybox_close_file (hd); + fp = es_fopen (hd->kb->fname, "r+b"); + if (!fp) + return gpg_error_from_syserror (); + + ec = 0; + if (es_fseeko (fp, off, SEEK_SET)) + ec = gpg_err_code_from_syserror (); + else + { + unsigned char tmp[4]; + + tmp[0] = value >> 24; + tmp[1] = value >> 16; + tmp[2] = value >> 8; + tmp[3] = value; + + switch (flag_size) + { + case 1: + case 2: + case 4: + if (es_fwrite (tmp+4-flag_size, flag_size, 1, fp) != 1) + ec = gpg_err_code_from_syserror (); + break; + default: + ec = GPG_ERR_BUG; + break; + } + } + + if (es_fclose (fp)) + { + if (!ec) + ec = gpg_err_code_from_syserror (); + } + + return gpg_error (ec); +} + + + +int +keybox_delete (KEYBOX_HANDLE hd) +{ + off_t off; + const char *fname; + estream_t fp; + int rc; + + if (!hd) + return gpg_error (GPG_ERR_INV_VALUE); + if (!hd->found.blob) + return gpg_error (GPG_ERR_NOTHING_FOUND); + if (!hd->kb) + return gpg_error (GPG_ERR_INV_HANDLE); + fname = hd->kb->fname; + if (!fname) + return gpg_error (GPG_ERR_INV_HANDLE); + + off = _keybox_get_blob_fileoffset (hd->found.blob); + if (off == (off_t)-1) + return gpg_error (GPG_ERR_GENERAL); + off += 4; + + _keybox_close_file (hd); + fp = es_fopen (hd->kb->fname, "r+b"); + if (!fp) + return gpg_error_from_syserror (); + + if (es_fseeko (fp, off, SEEK_SET)) + rc = gpg_error_from_syserror (); + else if (es_fputc (0, fp) == EOF) + rc = gpg_error_from_syserror (); + else + rc = 0; + + if (es_fclose (fp)) + { + if (!rc) + rc = gpg_error_from_syserror (); + } + + return rc; +} + + +/* Compress the keybox file. This should be run with the file + locked. */ +int +keybox_compress (KEYBOX_HANDLE hd) +{ + gpg_err_code_t ec; + int read_rc, rc; + const char *fname; + estream_t fp, newfp; + char *bakfname = NULL; + char *tmpfname = NULL; + int first_blob; + KEYBOXBLOB blob = NULL; + u32 cut_time; + int any_changes = 0; + int skipped_deleted; + + if (!hd) + return gpg_error (GPG_ERR_INV_HANDLE); + if (!hd->kb) + return gpg_error (GPG_ERR_INV_HANDLE); + if (hd->secret) + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); + fname = hd->kb->fname; + if (!fname) + return gpg_error (GPG_ERR_INV_HANDLE); + + _keybox_close_file (hd); + + /* Open the source file. Because we do a rename, we have to check the + permissions of the file */ + if ((ec = gnupg_access (fname, W_OK))) + return gpg_error (ec); + + fp = es_fopen (fname, "rb"); + if (!fp && errno == ENOENT) + return 0; /* Ready. File has been deleted right after the access above. */ + if (!fp) + { + rc = gpg_error_from_syserror (); + return rc; + } + + /* A quick test to see if we need to compress the file at all. We + schedule a compress run after 3 hours. */ + if ( !_keybox_read_blob (&blob, fp, NULL) ) + { + const unsigned char *buffer; + size_t length; + + buffer = _keybox_get_blob_image (blob, &length); + if (length > 4 && buffer[4] == KEYBOX_BLOBTYPE_HEADER) + { + u32 last_maint = buf32_to_u32 (buffer+20); + + if ( (last_maint + 3*3600) > make_timestamp () ) + { + es_fclose (fp); + _keybox_release_blob (blob); + return 0; /* Compress run not yet needed. */ + } + } + _keybox_release_blob (blob); + es_fseek (fp, 0, SEEK_SET); + es_clearerr (fp); + } + + /* Create the new file. */ + rc = create_tmp_file (fname, &bakfname, &tmpfname, &newfp); + if (rc) + { + es_fclose (fp); + return rc;; + } + + + /* Processing loop. By reading using _keybox_read_blob we + automagically skip any blobs flagged as deleted. Thus what we + only have to do is to check all ephemeral flagged blocks whether + their time has come and write out all other blobs. */ + cut_time = make_timestamp () - 86400; + first_blob = 1; + skipped_deleted = 0; + for (rc=0; !(read_rc = _keybox_read_blob (&blob, fp, &skipped_deleted)); + _keybox_release_blob (blob), blob = NULL ) + { + unsigned int blobflags; + const unsigned char *buffer; + size_t length, pos, size; + u32 created_at; + + if (skipped_deleted) + any_changes = 1; + buffer = _keybox_get_blob_image (blob, &length); + if (first_blob) + { + first_blob = 0; + if (length > 4 && buffer[4] == KEYBOX_BLOBTYPE_HEADER) + { + /* Write out the blob with an updated maintenance time + stamp and if needed (ie. used by gpg) set the openpgp + flag. */ + _keybox_update_header_blob (blob, hd->for_openpgp); + rc = _keybox_write_blob (blob, newfp, NULL); + if (rc) + break; + continue; + } + + /* The header blob is missing. Insert it. */ + rc = _keybox_write_header_blob (newfp, hd->for_openpgp); + if (rc) + break; + any_changes = 1; + } + else if (length > 4 && buffer[4] == KEYBOX_BLOBTYPE_HEADER) + { + /* Oops: There is another header record - remove it. */ + any_changes = 1; + continue; + } + + if (_keybox_get_flag_location (buffer, length, + KEYBOX_FLAG_BLOB, &pos, &size) + || size != 2) + { + rc = gpg_error (GPG_ERR_BUG); + break; + } + blobflags = buf16_to_uint (buffer+pos); + if ((blobflags & KEYBOX_FLAG_BLOB_EPHEMERAL)) + { + /* This is an ephemeral blob. */ + if (_keybox_get_flag_location (buffer, length, + KEYBOX_FLAG_CREATED_AT, &pos, &size) + || size != 4) + created_at = 0; /* oops. */ + else + created_at = buf32_to_u32 (buffer+pos); + + if (created_at && created_at < cut_time) + { + any_changes = 1; + continue; /* Skip this blob. */ + } + } + + rc = _keybox_write_blob (blob, newfp, NULL); + if (rc) + break; + } + if (skipped_deleted) + any_changes = 1; + _keybox_release_blob (blob); blob = NULL; + if (!rc && read_rc == -1) + rc = 0; + else if (!rc) + rc = read_rc; + + /* Close both files. */ + if (es_fclose(fp) && !rc) + rc = gpg_error_from_syserror (); + if (es_fclose(newfp) && !rc) + rc = gpg_error_from_syserror (); + + /* Rename or remove the temporary file. */ + if (rc || !any_changes) + gnupg_remove (tmpfname); + else + rc = rename_tmp_file (bakfname, tmpfname, fname, hd->secret); + + xfree(bakfname); + xfree(tmpfname); + return rc; +} diff --git a/kbx/keybox-util.c b/kbx/keybox-util.c new file mode 100644 index 0000000..3ce5162 --- /dev/null +++ b/kbx/keybox-util.c @@ -0,0 +1,102 @@ +/* keybox-util.c - Utility functions for Keybox + * Copyright (C) 2001 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG 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 3 of the License, or + * (at your option) any later version. + * + * GnuPG 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, see <https://www.gnu.org/licenses/>. + */ + +#include <config.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#ifdef HAVE_DOSISH_SYSTEM +# define WIN32_LEAN_AND_MEAN /* We only need the OS core stuff. */ +# include <windows.h> +#endif + +#include "keybox-defs.h" + + +/* Store the two malloced temporary file names used for keybox updates + of file FILENAME at R_BAKNAME and R_TMPNAME. On error an error + code is returned and NULL stored at R_BAKNAME and R_TMPNAME. If + FOR_KEYRING is true the returned names match those used by GnuPG's + keyring code. */ +gpg_error_t +keybox_tmp_names (const char *filename, int for_keyring, + char **r_bakname, char **r_tmpname) +{ + gpg_error_t err; + char *bak_name, *tmp_name; + + *r_bakname = NULL; + *r_tmpname = NULL; + +# ifdef USE_ONLY_8DOT3 + /* Here is another Windoze bug?: + * you can't rename("pubring.kbx.tmp", "pubring.kbx"); + * but rename("pubring.kbx.tmp", "pubring.aaa"); + * works. So we replace ".kbx" by ".kb_" or ".k__". Note that we + * can't use ".bak" and ".tmp", because these suffixes are used by + * gpg's keyrings and would lead to a sharing violation or data + * corruption. If the name does not end in ".kbx" we assume working + * on a modern file system and append the suffix. */ + { + const char *ext = for_keyring? EXTSEP_S GPGEXT_GPG : EXTSEP_S "kbx"; + const char *b_ext = for_keyring? EXTSEP_S "bak" : EXTSEP_S "kb_"; + const char *t_ext = for_keyring? EXTSEP_S "tmp" : EXTSEP_S "k__"; + int repl; + + if (strlen (ext) != 4 || strlen (b_ext) != 4) + BUG (); + repl = (strlen (filename) > 4 + && !strcmp (filename + strlen (filename) - 4, ext)); + bak_name = xtrymalloc (strlen (filename) + (repl?0:4) + 1); + if (!bak_name) + return gpg_error_from_syserror (); + strcpy (bak_name, filename); + strcpy (bak_name + strlen (filename) - (repl?4:0), b_ext); + + tmp_name = xtrymalloc (strlen (filename) + (repl?0:4) + 1); + if (!tmp_name) + { + err = gpg_error_from_syserror (); + xfree (bak_name); + return err; + } + strcpy (tmp_name, filename); + strcpy (tmp_name + strlen (filename) - (repl?4:0), t_ext); + } +# else /* Posix file names */ + (void)for_keyring; + bak_name = xtrymalloc (strlen (filename) + 2); + if (!bak_name) + return gpg_error_from_syserror (); + strcpy (stpcpy (bak_name, filename), "~"); + + tmp_name = xtrymalloc (strlen (filename) + 5); + if (!tmp_name) + { + err = gpg_error_from_syserror (); + xfree (bak_name); + return err; + } + strcpy (stpcpy (tmp_name,filename), EXTSEP_S "tmp"); +# endif /* Posix filename */ + + *r_bakname = bak_name; + *r_tmpname = tmp_name; + return 0; +} diff --git a/kbx/keybox.h b/kbx/keybox.h new file mode 100644 index 0000000..c5f9b57 --- /dev/null +++ b/kbx/keybox.h @@ -0,0 +1,137 @@ +/* keybox.h - Keybox operations + * Copyright (C) 2001, 2003, 2012 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG 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 3 of the License, or + * (at your option) any later version. + * + * GnuPG 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, see <https://www.gnu.org/licenses/>. + */ + +#ifndef KEYBOX_H +#define KEYBOX_H 1 +#ifdef __cplusplus +extern "C" { +#if 0 + } +#endif +#endif + +#include "../common/iobuf.h" +#include "keybox-search-desc.h" + +#ifdef KEYBOX_WITH_X509 +# include <ksba.h> +#endif + +typedef struct keybox_handle *KEYBOX_HANDLE; + + +typedef enum + { + KEYBOX_FLAG_BLOB, /* The blob flags. */ + KEYBOX_FLAG_VALIDITY, /* The validity of the entire key. */ + KEYBOX_FLAG_OWNERTRUST, /* The assigned ownertrust. */ + KEYBOX_FLAG_KEY, /* The key flags; requires a key index. */ + KEYBOX_FLAG_UID, /* The user ID flags; requires an uid index. */ + KEYBOX_FLAG_UID_VALIDITY,/* The validity of a specific uid, requires + an uid index. */ + KEYBOX_FLAG_CREATED_AT, /* The date the block was created. */ + KEYBOX_FLAG_SIG_INFO, /* The signature info block. */ + } keybox_flag_t; + +/* Flag values used with KEYBOX_FLAG_BLOB. */ +#define KEYBOX_FLAG_BLOB_SECRET 1 +#define KEYBOX_FLAG_BLOB_EPHEMERAL 2 + +/* The keybox blob types. */ +typedef enum + { + KEYBOX_BLOBTYPE_EMPTY = 0, + KEYBOX_BLOBTYPE_HEADER = 1, + KEYBOX_BLOBTYPE_PGP = 2, + KEYBOX_BLOBTYPE_X509 = 3 + } keybox_blobtype_t; + + +/*-- keybox-init.c --*/ +gpg_error_t keybox_register_file (const char *fname, int secret, + void **r_token); +int keybox_is_writable (void *token); + +KEYBOX_HANDLE keybox_new_openpgp (void *token, int secret); +KEYBOX_HANDLE keybox_new_x509 (void *token, int secret); +void keybox_release (KEYBOX_HANDLE hd); +void keybox_push_found_state (KEYBOX_HANDLE hd); +void keybox_pop_found_state (KEYBOX_HANDLE hd); +const char *keybox_get_resource_name (KEYBOX_HANDLE hd); +int keybox_set_ephemeral (KEYBOX_HANDLE hd, int yes); + +gpg_error_t keybox_lock (KEYBOX_HANDLE hd, int yes, long timeout); + +/*-- keybox-file.c --*/ +/* Fixme: This function does not belong here: Provide a better + interface to create a new keybox file. */ +int _keybox_write_header_blob (estream_t fp, int openpgp_flag); + +/*-- keybox-search.c --*/ +gpg_error_t keybox_get_keyblock (KEYBOX_HANDLE hd, iobuf_t *r_iobuf, + int *r_uid_no, int *r_pk_no); +#ifdef KEYBOX_WITH_X509 +int keybox_get_cert (KEYBOX_HANDLE hd, ksba_cert_t *ret_cert); +#endif /*KEYBOX_WITH_X509*/ +int keybox_get_flags (KEYBOX_HANDLE hd, int what, int idx, unsigned int *value); + +gpg_error_t keybox_search_reset (KEYBOX_HANDLE hd); +gpg_error_t keybox_search (KEYBOX_HANDLE hd, + KEYBOX_SEARCH_DESC *desc, size_t ndesc, + keybox_blobtype_t want_blobtype, + size_t *r_descindex, unsigned long *r_skipped); + +off_t keybox_offset (KEYBOX_HANDLE hd); +gpg_error_t keybox_seek (KEYBOX_HANDLE hd, off_t offset); + +/*-- keybox-update.c --*/ +gpg_error_t keybox_insert_keyblock (KEYBOX_HANDLE hd, + const void *image, size_t imagelen); +gpg_error_t keybox_update_keyblock (KEYBOX_HANDLE hd, + const void *image, size_t imagelen); + +#ifdef KEYBOX_WITH_X509 +int keybox_insert_cert (KEYBOX_HANDLE hd, ksba_cert_t cert, + unsigned char *sha1_digest); +int keybox_update_cert (KEYBOX_HANDLE hd, ksba_cert_t cert, + unsigned char *sha1_digest); +#endif /*KEYBOX_WITH_X509*/ +int keybox_set_flags (KEYBOX_HANDLE hd, int what, int idx, unsigned int value); + +int keybox_delete (KEYBOX_HANDLE hd); +int keybox_compress (KEYBOX_HANDLE hd); + + +/*-- --*/ + +#if 0 +int keybox_locate_writable (KEYBOX_HANDLE hd); +int keybox_rebuild_cache (void *); +#endif + + +/*-- keybox-util.c --*/ +gpg_error_t keybox_tmp_names (const char *filename, int for_keyring, + char **r_bakname, char **r_tmpname); + + +#ifdef __cplusplus +} +#endif +#endif /*KEYBOX_H*/ diff --git a/kbx/mkerrors b/kbx/mkerrors new file mode 100755 index 0000000..629485a --- /dev/null +++ b/kbx/mkerrors @@ -0,0 +1,70 @@ +#!/bin/sh +# mkerrors - Extract error strings from assuan.h +# and create C source for assuan_strerror +# Copyright (C) 2001 Free Software Foundation, Inc. +# +# This file is part of GnuPG. +# +# GnuPG 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 3 of the License, or +# (at your option) any later version. +# +# GnuPG 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, see <http://www.gnu.org/licenses/>. + +cat <<EOF +/* Generated automatically by mkerrors */ +/* Do not edit! */ + +#include <stdio.h> +#include "keybox-defs.h" + +/** + * keybox_strerror: + * @err: Error code + * + * This function returns a textual representaion of the given + * errorcode. If this is an unknown value, a string with the value + * is returned (Beware: it is hold in a static buffer). + * + * Return value: String with the error description. + **/ +const char * +keybox_strerror (KeyboxError err) +{ + const char *s; + static char buf[25]; + + switch (err) + { +EOF + +awk ' +/KEYBOX_No_Error/ { okay=1 } +!okay {next} +/}/ { exit 0 } +/KEYBOX_[A-Za-z_]*/ { print_code($1) } + + +function print_code( s ) +{ +printf " case %s: s=\"", s ; +gsub(/_/, " ", s ); +printf "%s\"; break;\n", tolower(substr(s,8)); +} +' + +cat <<EOF + default: sprintf (buf, "ec=%d", err ); s=buf; break; + } + + return s; +} + +EOF |